|
@@ -15,6 +15,7 @@ using System.Windows;
|
|
|
using System.Windows.Controls;
|
|
|
using System.Windows.Media;
|
|
|
using System.Windows.Media.Imaging;
|
|
|
+using StockMovement = Comal.Classes.StockMovement;
|
|
|
|
|
|
namespace PRSDesktop;
|
|
|
|
|
@@ -52,7 +53,7 @@ public class StockForecastItem : BaseObject
|
|
|
public void AddJobBOM(Guid jobID, double quantity)
|
|
|
{
|
|
|
var item = JobInfo.GetValueOrAdd(jobID);
|
|
|
- item.BOM += quantity;
|
|
|
+ item.BOM = Math.Max(0.0, item.BOM + quantity);
|
|
|
}
|
|
|
public void AddJobPO(Guid jobID, double quantity)
|
|
|
{
|
|
@@ -388,8 +389,31 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
|
|
|
return "";
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- private void ShowDetailGrid<TEntity>(
|
|
|
+
|
|
|
+ private void ShowDetailGrid(String title, params Func<IDynamicDataGrid?>[] gridfuncs)
|
|
|
+ {
|
|
|
+ var _window = new ThemableWindow { Title = title };
|
|
|
+ var _tabcontrol = new DynamicTabControl() { TabStripPlacement = Dock.Bottom, Margin = new Thickness(5) };
|
|
|
+ _window.Content = _tabcontrol;
|
|
|
+ foreach (var gridfunc in gridfuncs)
|
|
|
+ {
|
|
|
+ var _grid = gridfunc();
|
|
|
+ if (_grid != null)
|
|
|
+ {
|
|
|
+ _tabcontrol.Items.Add(
|
|
|
+ new DynamicTabItem()
|
|
|
+ {
|
|
|
+ Header = CoreUtils.Neatify(_grid.DataType.Name.Split('.').Last()),
|
|
|
+ Content = _grid
|
|
|
+ }
|
|
|
+ );
|
|
|
+ _grid.Refresh(true,true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ _window.ShowDialog();
|
|
|
+ }
|
|
|
+
|
|
|
+ private IDynamicDataGrid BuildDetailGrid<TEntity>(
|
|
|
String tag,
|
|
|
Expression<Func<TEntity,object?>> productcol,
|
|
|
Guid productid,
|
|
@@ -402,41 +426,38 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
|
|
|
Func<CoreRow,bool>? rowfilter
|
|
|
)
|
|
|
{
|
|
|
- var grid = (Activator.CreateInstance(typeof(DynamicDataGrid<>).MakeGenericType(typeof(TEntity))) as IDynamicDataGrid);
|
|
|
- if (grid == null)
|
|
|
+ var _grid = (Activator.CreateInstance(typeof(DynamicDataGrid<>).MakeGenericType(typeof(TEntity))) as IDynamicDataGrid);
|
|
|
+ if (_grid == null)
|
|
|
{
|
|
|
MessageWindow.ShowError($"Cannot create Grid for [{typeof(TEntity).Name}]", "", shouldLog: false);
|
|
|
- return;
|
|
|
+ return null;
|
|
|
}
|
|
|
- grid.ColumnsTag = $"{ColumnsTag}.{tag}";
|
|
|
- grid.Reconfigure(options =>
|
|
|
+ _grid.ColumnsTag = $"{ColumnsTag}.{tag}";
|
|
|
+ _grid.Reconfigure(options =>
|
|
|
{
|
|
|
options.Clear();
|
|
|
options.FilterRows = true;
|
|
|
options.SelectColumns = true;
|
|
|
});
|
|
|
- grid.OnDefineFilter += t =>
|
|
|
+ _grid.OnDefineFilter += t =>
|
|
|
{
|
|
|
- var filter = new Filter<TEntity>(productcol).IsEqualTo(productid);
|
|
|
+ var _filter = new Filter<TEntity>(productcol).IsEqualTo(productid);
|
|
|
if(dimensions is not null)
|
|
|
- {
|
|
|
- filter = filter.And(CoreUtils.GetFullPropertyName(dimcol, ".")).DimensionEquals(dimensions);
|
|
|
- }
|
|
|
+ _filter = _filter.And(CoreUtils.GetFullPropertyName(dimcol, ".")).DimensionEquals(dimensions);
|
|
|
|
|
|
if (styleid.HasValue)
|
|
|
- filter = filter.And(stylecol).IsEqualTo(styleid);
|
|
|
+ _filter = _filter.And(stylecol).IsEqualTo(styleid);
|
|
|
|
|
|
if (jobcol != null)
|
|
|
- filter = filter.And(new Filter<TEntity>(jobcol).InList(JobIDs));
|
|
|
+ _filter = _filter.And(new Filter<TEntity>(jobcol).InList(JobIDs));
|
|
|
|
|
|
if (extrafilter != null)
|
|
|
- filter = filter.And(extrafilter);
|
|
|
+ _filter = _filter.And(extrafilter);
|
|
|
|
|
|
- return filter;
|
|
|
+ return _filter;
|
|
|
};
|
|
|
- grid.OnFilterRecord += row => rowfilter?.Invoke(row) ?? true;
|
|
|
- var window = DynamicGridUtils.CreateGridWindow($"Viewing {CoreUtils.Neatify(tag)} Calculation", grid);
|
|
|
- window.ShowDialog();
|
|
|
+ _grid.OnFilterRecord += row => rowfilter?.Invoke(row) ?? true;
|
|
|
+ return _grid;
|
|
|
}
|
|
|
|
|
|
protected override void DoDoubleClick(object sender, DynamicGridCellClickEventArgs args)
|
|
@@ -451,70 +472,103 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
|
|
|
switch (tag)
|
|
|
{
|
|
|
case ColumnTag.GeneralStockHoldings:
|
|
|
- ShowDetailGrid<StockHolding>(
|
|
|
- ColumnTag.GeneralStockHoldings.ToString(),
|
|
|
- x => x.Product.ID,
|
|
|
- item.Product.ID,
|
|
|
- x => x.Style.ID,
|
|
|
- styleid,
|
|
|
- x => x.Dimensions,
|
|
|
- item.Dimensions,
|
|
|
- null,
|
|
|
- new Filter<StockHolding>(x=>x.Job.ID).IsEqualTo(Guid.Empty),
|
|
|
- null);
|
|
|
+ ShowDetailGrid(
|
|
|
+ "Stock Holdings",
|
|
|
+ () => BuildDetailGrid<StockHolding>(
|
|
|
+ ColumnTag.GeneralStockHoldings.ToString(),
|
|
|
+ x => x.Product.ID,
|
|
|
+ item.Product.ID,
|
|
|
+ x => x.Style.ID,
|
|
|
+ styleid,
|
|
|
+ x => x.Dimensions,
|
|
|
+ item.Dimensions,
|
|
|
+ null,
|
|
|
+ new Filter<StockHolding>(x=>x.Job.ID).IsEqualTo(Guid.Empty),
|
|
|
+ null
|
|
|
+ )
|
|
|
+ );
|
|
|
break;
|
|
|
case ColumnTag.GeneralPurchaseOrders:
|
|
|
- ShowDetailGrid<PurchaseOrderItem>(
|
|
|
- ColumnTag.GeneralPurchaseOrders.ToString(),
|
|
|
- x => x.Product.ID,
|
|
|
- item.Product.ID,
|
|
|
- x => x.Style.ID,
|
|
|
- styleid,
|
|
|
- x => x.Dimensions,
|
|
|
- item.Dimensions,
|
|
|
- null,
|
|
|
- new Filter<PurchaseOrderItem>(x=>x.Job.ID).IsEqualTo(Guid.Empty)
|
|
|
- .And(x=>x.ReceivedDate).IsEqualTo(DateTime.MinValue),
|
|
|
- null);
|
|
|
+ ShowDetailGrid(
|
|
|
+ "Purchase Orders",
|
|
|
+ () => BuildDetailGrid<PurchaseOrderItem>(
|
|
|
+ ColumnTag.GeneralPurchaseOrders.ToString(),
|
|
|
+ x => x.Product.ID,
|
|
|
+ item.Product.ID,
|
|
|
+ x => x.Style.ID,
|
|
|
+ styleid,
|
|
|
+ x => x.Dimensions,
|
|
|
+ item.Dimensions,
|
|
|
+ null,
|
|
|
+ new Filter<PurchaseOrderItem>(x=>x.Job.ID).IsEqualTo(Guid.Empty)
|
|
|
+ .And(x=>x.ReceivedDate).IsEqualTo(DateTime.MinValue),
|
|
|
+ null
|
|
|
+ )
|
|
|
+ );
|
|
|
break;
|
|
|
case ColumnTag.JobStockRequired:
|
|
|
- ShowDetailGrid<JobBillOfMaterialsItem>(
|
|
|
- ColumnTag.JobStockRequired.ToString(),
|
|
|
- x => x.Product.ID,
|
|
|
- item.Product.ID,
|
|
|
- x => x.Style.ID,
|
|
|
- styleid,
|
|
|
- x => x.Dimensions,
|
|
|
- item.Dimensions,
|
|
|
- x => x.Job.ID,
|
|
|
- new Filter<JobBillOfMaterialsItem>(x=>x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue),
|
|
|
- null);
|
|
|
+ ShowDetailGrid(
|
|
|
+ "Bills Of Materials",
|
|
|
+ () => BuildDetailGrid<JobBillOfMaterialsItem>(
|
|
|
+ ColumnTag.JobStockRequired.ToString(),
|
|
|
+ x => x.Product.ID,
|
|
|
+ item.Product.ID,
|
|
|
+ x => x.Style.ID,
|
|
|
+ styleid,
|
|
|
+ x => x.Dimensions,
|
|
|
+ item.Dimensions,
|
|
|
+ x => x.Job.ID,
|
|
|
+ new Filter<JobBillOfMaterialsItem>(x=>x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue),
|
|
|
+ null
|
|
|
+ ),
|
|
|
+ () => BuildDetailGrid<StockMovement>(
|
|
|
+ "JobStockIssued",
|
|
|
+ x => x.Product.ID,
|
|
|
+ item.Product.ID,
|
|
|
+ x => x.Style.ID,
|
|
|
+ styleid,
|
|
|
+ x => x.Dimensions,
|
|
|
+ item.Dimensions,
|
|
|
+ x => x.Job.ID,
|
|
|
+ new Filter<StockMovement>(x=>x.Type).IsEqualTo(StockMovementType.Issue),
|
|
|
+ null
|
|
|
+ )
|
|
|
+
|
|
|
+ );
|
|
|
break;
|
|
|
case ColumnTag.JobStockHoldings:
|
|
|
- ShowDetailGrid<StockHolding>(
|
|
|
- ColumnTag.JobStockHoldings.ToString(),
|
|
|
- x => x.Product.ID,
|
|
|
- item.Product.ID,
|
|
|
- x => x.Style.ID,
|
|
|
- styleid,
|
|
|
- x => x.Dimensions,
|
|
|
- item.Dimensions,
|
|
|
- x => x.Job.ID,
|
|
|
- null,
|
|
|
- null);
|
|
|
+ ShowDetailGrid(
|
|
|
+ "Stock Holdings",
|
|
|
+ () => BuildDetailGrid<StockHolding>(
|
|
|
+ ColumnTag.JobStockHoldings.ToString(),
|
|
|
+ x => x.Product.ID,
|
|
|
+ item.Product.ID,
|
|
|
+ x => x.Style.ID,
|
|
|
+ styleid,
|
|
|
+ x => x.Dimensions,
|
|
|
+ item.Dimensions,
|
|
|
+ x => x.Job.ID,
|
|
|
+ null,
|
|
|
+ null
|
|
|
+ )
|
|
|
+ );
|
|
|
break;
|
|
|
case ColumnTag.JobPurchaseOrders:
|
|
|
- ShowDetailGrid<PurchaseOrderItem>(
|
|
|
- ColumnTag.GeneralPurchaseOrders.ToString(),
|
|
|
- x => x.Product.ID,
|
|
|
- item.Product.ID,
|
|
|
- x => x.Style.ID,
|
|
|
- styleid,
|
|
|
- x => x.Dimensions,
|
|
|
- item.Dimensions,
|
|
|
- x => x.Job.ID,
|
|
|
- new Filter<PurchaseOrderItem>(x=>x.ReceivedDate).IsEqualTo(DateTime.MinValue),
|
|
|
- null);
|
|
|
+ ShowDetailGrid(
|
|
|
+ "Purchase Orders",
|
|
|
+ () => BuildDetailGrid<PurchaseOrderItem>(
|
|
|
+ ColumnTag.GeneralPurchaseOrders.ToString(),
|
|
|
+ x => x.Product.ID,
|
|
|
+ item.Product.ID,
|
|
|
+ x => x.Style.ID,
|
|
|
+ styleid,
|
|
|
+ x => x.Dimensions,
|
|
|
+ item.Dimensions,
|
|
|
+ x => x.Job.ID,
|
|
|
+ new Filter<PurchaseOrderItem>(x=>x.ReceivedDate).IsEqualTo(DateTime.MinValue),
|
|
|
+ null
|
|
|
+ )
|
|
|
+ );
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
@@ -690,6 +744,7 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
|
|
|
filter: new Filter<PurchaseOrderItem>(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue),
|
|
|
columns: Columns.None<PurchaseOrderItem>().Add(x => x.Qty)),
|
|
|
GetQuery<JobBillOfMaterialsItem>(
|
|
|
+ filter: new Filter<JobBillOfMaterialsItem>(x=>x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue),
|
|
|
columns: Columns.None<JobBillOfMaterialsItem>().Add(x => x.Quantity)),
|
|
|
GetQuery<StockMovement>(
|
|
|
filter: new Filter<StockMovement>(x => x.Type).IsEqualTo(StockMovementType.Issue),
|
|
@@ -769,20 +824,21 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
|
|
|
var jobBOMItems = results.Get<JobBillOfMaterialsItem>();
|
|
|
foreach(var bomItem in jobBOMItems.Rows)
|
|
|
{
|
|
|
- var item = GetItem(GetKey(bomItem));
|
|
|
+ var key = GetKey(bomItem);
|
|
|
+ var item = GetItem(key);
|
|
|
|
|
|
- item.JobBOM += bomItem.Get<JobBillOfMaterialsItem, double>(x => x.Quantity);
|
|
|
+ item.JobBOM = Math.Max(0.0, item.JobBOM + bomItem.Get<JobBillOfMaterialsItem, double>(x => x.Quantity));
|
|
|
item.AddJobBOM(bomItem.Get<JobBillOfMaterialsItem, Guid>(x => x.Job.ID), bomItem.Get<JobBillOfMaterialsItem, double>(x => x.Quantity));
|
|
|
}
|
|
|
|
|
|
- var movements = results.Get<StockMovement>();
|
|
|
- foreach(var mvt in movements.Rows)
|
|
|
- {
|
|
|
- var item = GetItem(GetKey(mvt));
|
|
|
-
|
|
|
- item.JobBOM -= mvt.Get<StockMovement, double>(x => x.Units);
|
|
|
- item.AddJobBOM(mvt.Get<StockMovement, Guid>(x => x.Job.ID), -mvt.Get<StockMovement, double>(x => x.Units));
|
|
|
- }
|
|
|
+ // var movements = results.Get<StockMovement>();
|
|
|
+ // foreach(var mvt in movements.Rows)
|
|
|
+ // {
|
|
|
+ // var item = GetItem(GetKey(mvt));
|
|
|
+ //
|
|
|
+ // item.JobBOM = Math.Max(0.0, item.JobBOM + mvt.Get<StockMovement, double>(x => x.Units));
|
|
|
+ // item.AddJobBOM(mvt.Get<StockMovement, Guid>(x => x.Job.ID), mvt.Get<StockMovement, double>(x => x.Units));
|
|
|
+ // }
|
|
|
|
|
|
_supplierProducts = results.GetArray<SupplierProduct>();
|
|
|
|