|
@@ -25,6 +25,29 @@ using Columns = InABox.Core.Columns;
|
|
|
|
|
|
namespace PRSDesktop.Panels.StockForecast.OrderScreen;
|
|
|
|
|
|
+public class StockForecastOrderData
|
|
|
+{
|
|
|
+ public ProductLink Product { get; set; }
|
|
|
+
|
|
|
+ public ProductStyleLink Style { get; set; }
|
|
|
+
|
|
|
+ public StockDimensions Dimensions { get; set; }
|
|
|
+
|
|
|
+ public double RequiredQuantity { get; set; }
|
|
|
+
|
|
|
+ private Dictionary<Guid, double> JobRequiredQuantities { get; set; } = [];
|
|
|
+
|
|
|
+ public Dictionary<Guid, double> GetJobRequiredQuantities()
|
|
|
+ {
|
|
|
+ return JobRequiredQuantities;
|
|
|
+ }
|
|
|
+ public void SetJobRequiredQuantity(Guid jobID, double requiredQty)
|
|
|
+ {
|
|
|
+ JobRequiredQuantities[jobID] = requiredQty;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
public enum StockForecastOrderingType
|
|
|
{
|
|
|
StockOrder,
|
|
@@ -35,29 +58,32 @@ public class StockForecastOrderingItemQuantity
|
|
|
{
|
|
|
public event Action? Changed;
|
|
|
|
|
|
- private double _stockTotal;
|
|
|
- public double StockTotal
|
|
|
+ private double _total;
|
|
|
+ public double Total
|
|
|
{
|
|
|
- get => _stockTotal;
|
|
|
+ get => _total;
|
|
|
set
|
|
|
{
|
|
|
- _stockTotal = value;
|
|
|
+ _total = value;
|
|
|
Changed?.Invoke();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public Dictionary<Guid, double> JobTotals { get; init; } = [];
|
|
|
+ private SupplierProduct? _supplierProduct;
|
|
|
+ public SupplierProduct? SupplierProduct
|
|
|
+ {
|
|
|
+ get => _supplierProduct;
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _supplierProduct = value;
|
|
|
+ Changed?.Invoke();
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
public void DoChanged()
|
|
|
{
|
|
|
Changed?.Invoke();
|
|
|
}
|
|
|
-
|
|
|
- public double JobTotal => JobTotals.Sum(x => x.Value);
|
|
|
-
|
|
|
- public double GetTotal(StockForecastOrderingType type) => type == StockForecastOrderingType.StockOrder
|
|
|
- ? StockTotal
|
|
|
- : JobTotal;
|
|
|
}
|
|
|
|
|
|
public class StockForecastOrderingItem : BaseObject
|
|
@@ -72,19 +98,15 @@ public class StockForecastOrderingItem : BaseObject
|
|
|
public StockDimensions Dimensions { get; set; }
|
|
|
|
|
|
[EditorSequence(4)]
|
|
|
+ public JobLink Job { get; set; }
|
|
|
+
|
|
|
+ [EditorSequence(5)]
|
|
|
[DoubleEditor]
|
|
|
public double RequiredQuantity { get; set; }
|
|
|
|
|
|
- private Dictionary<Guid, double> JobRequiredQuantities { get; set; } = [];
|
|
|
-
|
|
|
- public Dictionary<Guid, double> GetJobRequiredQuantities()
|
|
|
- {
|
|
|
- return JobRequiredQuantities;
|
|
|
- }
|
|
|
- public void SetJobRequiredQuantity(Guid jobID, double requiredQty)
|
|
|
- {
|
|
|
- JobRequiredQuantities[jobID] = requiredQty;
|
|
|
- }
|
|
|
+ [EditorSequence(6)]
|
|
|
+ [EnumLookupEditor(typeof(SupplierProductOrderStrategy))]
|
|
|
+ public SupplierProductOrderStrategy OrderStrategy { get; set; }
|
|
|
|
|
|
private StockForecastOrderingItemQuantity[] Quantities = [];
|
|
|
|
|
@@ -127,8 +149,11 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
|
|
|
private List<SupplierProduct> SupplierProducts = [];
|
|
|
private SupplierLink[] Suppliers = [];
|
|
|
|
|
|
+ public IList<StockForecastOrderData> OrderData { get; set; }
|
|
|
+
|
|
|
public double TotalQuantity => Items.Sum(x => x.GetTotalQuantity(OrderType));
|
|
|
|
|
|
+ private DynamicActionColumn[] SupplierProductColumns = [];
|
|
|
private DynamicActionColumn[] QuantityColumns = [];
|
|
|
private DynamicActionColumn[] CostColumns = [];
|
|
|
|
|
@@ -291,7 +316,7 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
|
|
|
.Add(x => x.SupplierLink.Code);
|
|
|
|
|
|
SupplierProducts = Client.Query(
|
|
|
- new Filter<SupplierProduct>(x => x.Product.ID).InList(Items.Select(x => x.Product.ID).ToArray())
|
|
|
+ new Filter<SupplierProduct>(x => x.Product.ID).InList(OrderData.Select(x => x.Product.ID).ToArray())
|
|
|
.And(x => x.SupplierLink.ID).IsNotEqualTo(Guid.Empty),
|
|
|
supplierColumns,
|
|
|
new SortOrder<SupplierProduct>(x => x.SupplierLink.Code))
|
|
@@ -299,16 +324,6 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
|
|
|
|
|
|
Suppliers = SupplierProducts.Select(x => x.SupplierLink).DistinctBy(x => x.ID).ToArray();
|
|
|
|
|
|
- foreach(var (itemIdx, item) in Items.WithIndex())
|
|
|
- {
|
|
|
- var quantities = new StockForecastOrderingItemQuantity[Suppliers.Length];
|
|
|
- for(int i = 0; i < Suppliers.Length; ++i)
|
|
|
- {
|
|
|
- quantities[i] = CreateQuantity(itemIdx);
|
|
|
- }
|
|
|
-
|
|
|
- item.SetQuantities(quantities);
|
|
|
- }
|
|
|
|
|
|
CalculateQuantities();
|
|
|
|
|
@@ -330,42 +345,72 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
|
|
|
private void CalculateQuantities()
|
|
|
{
|
|
|
SetObserving(false);
|
|
|
+
|
|
|
+ Items.Clear();
|
|
|
+ foreach(var dataItem in OrderData)
|
|
|
+ {
|
|
|
+ if(OrderType == StockForecastOrderingType.StockOrder)
|
|
|
+ {
|
|
|
+ var item = new StockForecastOrderingItem();
|
|
|
+ item.Product.CopyFrom(dataItem.Product);
|
|
|
+ item.Style.CopyFrom(dataItem.Style);
|
|
|
+ item.Dimensions.CopyFrom(dataItem.Dimensions);
|
|
|
+ item.RequiredQuantity = dataItem.RequiredQuantity;
|
|
|
+ item.OrderStrategy = item.Product.OrderStrategy;
|
|
|
+ Items.Add(item);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ foreach(var (id, q) in dataItem.GetJobRequiredQuantities())
|
|
|
+ {
|
|
|
+ var item = new StockForecastOrderingItem();
|
|
|
+ item.Product.CopyFrom(dataItem.Product);
|
|
|
+ item.Style.CopyFrom(dataItem.Style);
|
|
|
+ item.Dimensions.CopyFrom(dataItem.Dimensions);
|
|
|
+ item.Job.ID = id;
|
|
|
+ item.RequiredQuantity = q;
|
|
|
+ item.OrderStrategy = item.Product.OrderStrategy;
|
|
|
+
|
|
|
+ Items.Add(item);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach(var (itemIdx, item) in Items.WithIndex())
|
|
|
+ {
|
|
|
+ var quantities = new StockForecastOrderingItemQuantity[Suppliers.Length];
|
|
|
+ for(int i = 0; i < Suppliers.Length; ++i)
|
|
|
+ {
|
|
|
+ quantities[i] = CreateQuantity(itemIdx);
|
|
|
+ }
|
|
|
+
|
|
|
+ item.SetQuantities(quantities);
|
|
|
+ }
|
|
|
+
|
|
|
foreach(var item in Items)
|
|
|
{
|
|
|
- var supplierProduct = GetSupplierProduct(item);
|
|
|
+ var selectedSupplierProducts = new List<SupplierProduct>();
|
|
|
for(int i = 0; i < Suppliers.Length; ++i)
|
|
|
{
|
|
|
+ var supplierProduct = SelectSupplierProduct(SupplierProducts.Where(x => x.Product.ID == item.Product.ID && x.Style.ID == item.Style.ID && x.SupplierLink.ID == Suppliers[i].ID), item);
|
|
|
+
|
|
|
var qty = item.GetQuantity(i);
|
|
|
+ qty.SupplierProduct = supplierProduct;
|
|
|
+ qty.Total = 0;
|
|
|
|
|
|
- var supplier = Suppliers[i];
|
|
|
- if(supplierProduct is not null && supplier.ID == supplierProduct.SupplierLink.ID)
|
|
|
+ if(supplierProduct is not null)
|
|
|
{
|
|
|
- if(OrderType == StockForecastOrderingType.StockOrder)
|
|
|
- {
|
|
|
- qty.StockTotal = qty.JobTotal;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- qty.JobTotals.Clear();
|
|
|
- foreach(var (id, q) in item.GetJobRequiredQuantities())
|
|
|
- {
|
|
|
- qty.JobTotals[id] = q;
|
|
|
- }
|
|
|
- }
|
|
|
+ selectedSupplierProducts.Add(supplierProduct);
|
|
|
}
|
|
|
- else
|
|
|
+ }
|
|
|
+
|
|
|
+ var selectedSupplierProduct = SelectSupplierProduct(selectedSupplierProducts, item);
|
|
|
+ if(selectedSupplierProduct is not null)
|
|
|
+ {
|
|
|
+ var supplierIdx = Suppliers.WithIndex().FirstOrDefault(x => x.Value.ID == selectedSupplierProduct.SupplierLink.ID, new KeyValuePair<int, SupplierLink>(-1, null)).Key;
|
|
|
+ if(supplierIdx != -1)
|
|
|
{
|
|
|
- if(OrderType == StockForecastOrderingType.StockOrder)
|
|
|
- {
|
|
|
- qty.StockTotal = 0;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- foreach(var id in item.GetJobRequiredQuantities().Keys)
|
|
|
- {
|
|
|
- qty.JobTotals[id] = 0;
|
|
|
- }
|
|
|
- }
|
|
|
+ item.GetQuantity(supplierIdx).Total = GetRequiredQuantity(item, selectedSupplierProduct);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -375,6 +420,16 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
|
|
|
InvalidateGrid();
|
|
|
}
|
|
|
|
|
|
+ private SupplierProduct? SelectSupplierProduct(IEnumerable<SupplierProduct> supplierProducts, StockForecastOrderingItem item)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private double GetRequiredQuantity(StockForecastOrderingItem item, SupplierProduct supplierProduct)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
protected override DynamicGridColumns LoadColumns()
|
|
|
{
|
|
|
if (!_loadedData)
|
|
@@ -393,6 +448,16 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
|
|
|
columns.Add<StockForecastOrderingItem, string>(x => x.Dimensions.UnitSize, 80, "Size", "", Alignment.MiddleCenter);
|
|
|
columns.Add<StockForecastOrderingItem, double>(x => x.RequiredQuantity, 80, "Required", "", Alignment.MiddleCenter);
|
|
|
|
|
|
+ ActionColumns.Add(new DynamicTemplateColumn(row =>
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ })
|
|
|
+ {
|
|
|
+ HeaderText = "Order Strategy.",
|
|
|
+ Width = 120
|
|
|
+ });
|
|
|
+
|
|
|
+ SupplierProductColumns = new DynamicActionColumn[Suppliers.Length];
|
|
|
QuantityColumns = new DynamicActionColumn[Suppliers.Length];
|
|
|
CostColumns = new DynamicActionColumn[Suppliers.Length];
|
|
|
QuantityControls.Clear();
|
|
@@ -671,8 +736,15 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
|
|
|
return menu;
|
|
|
};
|
|
|
|
|
|
- // Making local copy of index so that the lambda can use it, and not the changed value of 'i'.
|
|
|
var qtyColumn = new Tuple<DynamicActionColumn, QuantityControl?>(null!, null);
|
|
|
+ SupplierProductColumns[idx] = new DynamicTemplateColumn(row =>
|
|
|
+ {
|
|
|
+ return null;
|
|
|
+ })
|
|
|
+ {
|
|
|
+ HeaderText = "Supplier Product.",
|
|
|
+ Width = 80
|
|
|
+ };
|
|
|
QuantityColumns[idx] = new DynamicTemplateColumn(row =>
|
|
|
{
|
|
|
var instance = LoadItem(row);
|
|
@@ -721,6 +793,7 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
|
|
|
return summary;
|
|
|
}
|
|
|
};
|
|
|
+ ActionColumns.Add(SupplierProductColumns[idx]);
|
|
|
ActionColumns.Add(QuantityColumns[idx]);
|
|
|
ActionColumns.Add(CostColumns[idx]);
|
|
|
}
|