|
@@ -5,10 +5,12 @@ using System.Linq.Expressions;
|
|
|
using System.Reflection;
|
|
|
using System.Windows;
|
|
|
using System.Windows.Controls;
|
|
|
+using System.Windows.Media;
|
|
|
using Comal.Classes;
|
|
|
using InABox.Clients;
|
|
|
using InABox.Core;
|
|
|
using InABox.DynamicGrid;
|
|
|
+using InABox.WPF;
|
|
|
|
|
|
|
|
|
namespace PRSDesktop
|
|
@@ -22,6 +24,9 @@ namespace PRSDesktop
|
|
|
|
|
|
public JobSummaryGrid() : base()
|
|
|
{
|
|
|
+
|
|
|
+ ColumnsTag = nameof(JobSummaryGrid);
|
|
|
+
|
|
|
Options.AddRange(
|
|
|
DynamicGridOption.RecordCount,
|
|
|
DynamicGridOption.SelectColumns,
|
|
@@ -72,8 +77,9 @@ namespace PRSDesktop
|
|
|
columns.Add<JobMaterial, double>(x => x.Issued, 80, "Issued", "", Alignment.MiddleCenter);
|
|
|
columns.Add<JobMaterial, double>(x => x.ReservedStock, 80, "Reserved", "", Alignment.MiddleCenter);
|
|
|
columns.Add<JobMaterial, double>(x => x.OnOrder, 80, "Ordered", "", Alignment.MiddleCenter);
|
|
|
- columns.Add<JobMaterial, double>(x => x.JobShortage, 80, "Shortage", "", Alignment.MiddleCenter);
|
|
|
+ columns.Add<JobMaterial, double>(x => x.JobShortage, 80, "Job Short", "", Alignment.MiddleCenter);
|
|
|
columns.Add<JobMaterial, double>(x => x.FreeStockTotal, 80, "Free Stock", "", Alignment.MiddleCenter);
|
|
|
+ columns.Add<JobMaterial, double>(x => x.FreeStockShortage, 80, "Stk Short", "", Alignment.MiddleCenter);
|
|
|
}
|
|
|
|
|
|
private void ShowDetailGrid<TEntity>(
|
|
@@ -295,7 +301,7 @@ namespace PRSDesktop
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- private CoreRow[] GetRows<TSource>(IEnumerable<CoreRow> rows, Columns<TSource> columns, Guid? jobid, Guid productid, Guid? styleid, String unitsize) where TSource : IJobMaterial
|
|
|
+ private CoreRow[] GetRows<TSource>(IEnumerable<CoreRow> rows, Columns<TSource> columns, Guid? jobid, Guid productid, Guid? styleid, String unitsize, Func<CoreRow,bool>? extrafilter = null) where TSource : IJobMaterial
|
|
|
{
|
|
|
int jobcol = columns.IndexOf(x => x.Job.ID);
|
|
|
int productcol = columns.IndexOf(x => x.Product.ID);
|
|
@@ -308,6 +314,7 @@ namespace PRSDesktop
|
|
|
&& Guid.Equals(r.Values[productcol], productid)
|
|
|
&& (!styleid.HasValue || Guid.Equals(r.Values[stylecol], styleid))
|
|
|
&& String.Equals(r.Values[unitcol], unitsize)
|
|
|
+ && ((extrafilter == null) || extrafilter(r) )
|
|
|
);
|
|
|
|
|
|
return subset.ToArray();
|
|
@@ -334,104 +341,108 @@ namespace PRSDesktop
|
|
|
? new Filter<JobMaterial>().None()
|
|
|
: new Filter<JobMaterial>(x => x.Job.ID).IsEqualTo(ParentID)
|
|
|
.And(x => x.Product.ID).IsNotEqualTo(Guid.Empty);
|
|
|
-
|
|
|
- var orderby = sort != null ? Serialization.Deserialize<SortOrder<JobMaterial>>(Serialization.Serialize(sort)) : null;
|
|
|
|
|
|
- new Client<JobMaterial>().Query(filter,columns,orderby, (o,e) =>
|
|
|
- {
|
|
|
-
|
|
|
- var pids = o.ExtractValues<JobMaterial, Guid>(x => x.Product.ID).ToArray();
|
|
|
-
|
|
|
- MultiQuery query = new MultiQuery();
|
|
|
-
|
|
|
- query.Add<StockHolding>(
|
|
|
- new Filter<StockHolding>(x => x.Product.ID).InList(pids)
|
|
|
- .And(x=>x.Units).IsNotEqualTo(0.0F)
|
|
|
- .And(
|
|
|
- IncludeReserves
|
|
|
- ? new Filter<StockHolding>(x => x.Job.ID).IsNotEqualTo(ParentID)
|
|
|
- : new Filter<StockHolding>(x => x.Job.JobStatus.Active).IsEqualTo(false)
|
|
|
- ),
|
|
|
- new Columns<StockHolding>(x => x.Product.ID)
|
|
|
- .Add(x => x.Style.ID)
|
|
|
- .Add(x => x.Dimensions.UnitSize)
|
|
|
- .Add(x => x.Units)
|
|
|
- .Add(x=>x.Job.ID)
|
|
|
- );
|
|
|
-
|
|
|
- query.Add<PurchaseOrderItem>(
|
|
|
- new Filter<PurchaseOrderItem>(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue)
|
|
|
- .And(x => x.Product.ID).InList(pids)
|
|
|
- .And(
|
|
|
- IncludeReserves
|
|
|
- ? new Filter<PurchaseOrderItem>(x => x.Job.ID).IsNotEqualTo(ParentID)
|
|
|
- : new Filter<PurchaseOrderItem>(x => x.Job.JobStatus.Active).IsEqualTo(false)
|
|
|
- ),
|
|
|
- new Columns<PurchaseOrderItem>(x => x.Product.ID)
|
|
|
- .Add(x => x.Style.ID)
|
|
|
- .Add(x => x.Dimensions.UnitSize)
|
|
|
- .Add(x => x.Qty)
|
|
|
- );
|
|
|
-
|
|
|
- query.Query();
|
|
|
-
|
|
|
- var freestock = query.Get<StockHolding>();
|
|
|
- Columns<StockHolding> freestockcolumns = new Columns<StockHolding>(freestock.Columns.Select(x => x.ColumnName));
|
|
|
-
|
|
|
- var freeorders = query.Get<PurchaseOrderItem>();
|
|
|
- Columns<PurchaseOrderItem> freeordercolumns = new Columns<PurchaseOrderItem>(freeorders.Columns.Select(x => x.ColumnName));
|
|
|
-
|
|
|
- CoreTable table = new CoreTable();
|
|
|
- table.LoadColumns(columns);
|
|
|
-
|
|
|
- if (o != null)
|
|
|
+ var orderby = sort;
|
|
|
+
|
|
|
+ Progress.ShowModal("Loading Data",
|
|
|
+ (progress) =>
|
|
|
{
|
|
|
+ CoreTable table = new CoreTable();
|
|
|
+ table.LoadColumns(columns);
|
|
|
|
|
|
+ var data = new Client<JobMaterial>().Query(filter, columns, orderby);
|
|
|
+ var pids = data.ExtractValues<JobMaterial, Guid>(x => x.Product.ID).ToArray();
|
|
|
|
|
|
- var keys = GetKeys(o.Rows, columns, _stylecolumnVisible);
|
|
|
-
|
|
|
- foreach (var key in keys)
|
|
|
+ if (pids.Any())
|
|
|
{
|
|
|
+
|
|
|
+ MultiQuery query = new MultiQuery();
|
|
|
+
|
|
|
+ query.Add<StockHolding>(
|
|
|
+ new Filter<StockHolding>(x => x.Product.ID).InList(pids)
|
|
|
+ .And(x => x.Units).IsNotEqualTo(0.0F)
|
|
|
+ .And(new Filter<StockHolding>(x => x.Job.ID).IsEqualTo(Guid.Empty).Or(x=>x.Job.ID).IsNotEqualTo(ParentID)),
|
|
|
+ new Columns<StockHolding>(x => x.Product.ID)
|
|
|
+ .Add(x => x.Style.ID)
|
|
|
+ .Add(x => x.Dimensions.UnitSize)
|
|
|
+ .Add(x => x.Units)
|
|
|
+ .Add(x => x.Job.ID)
|
|
|
+ .Add(x => x.Job.JobStatus.Active)
|
|
|
+ );
|
|
|
+
|
|
|
+ query.Add<PurchaseOrderItem>(
|
|
|
+ new Filter<PurchaseOrderItem>(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue)
|
|
|
+ .And(x => x.Product.ID).InList(pids)
|
|
|
+ .And(new Filter<PurchaseOrderItem>(x => x.Job.ID).IsEqualTo(Guid.Empty).Or(x=>x.Job.ID).IsNotEqualTo(ParentID)),
|
|
|
+ new Columns<PurchaseOrderItem>(x => x.Product.ID)
|
|
|
+ .Add(x => x.Style.ID)
|
|
|
+ .Add(x => x.Dimensions.UnitSize)
|
|
|
+ .Add(x => x.Qty)
|
|
|
+ .Add(x => x.Job.ID)
|
|
|
+ .Add(x => x.Job.JobStatus.Active)
|
|
|
+ );
|
|
|
+
|
|
|
+ query.Query();
|
|
|
+
|
|
|
+ var freestock = query.Get<StockHolding>();
|
|
|
+ Columns<StockHolding> freestockcolumns = new Columns<StockHolding>(freestock.Columns.Select(x => x.ColumnName));
|
|
|
+
|
|
|
+ var freeorders = query.Get<PurchaseOrderItem>();
|
|
|
+ Columns<PurchaseOrderItem> freeordercolumns = new Columns<PurchaseOrderItem>(freeorders.Columns.Select(x => x.ColumnName));
|
|
|
|
|
|
- var rows = GetRows(o.Rows, columns, key.Item1, key.Item2, key.Item3, key.Item4);
|
|
|
- if (rows.Any())
|
|
|
+ var keys = GetKeys(data.Rows, columns, _stylecolumnVisible);
|
|
|
+
|
|
|
+ foreach (var key in keys)
|
|
|
{
|
|
|
-
|
|
|
- CoreRow newrow = table.NewRow();
|
|
|
- newrow.LoadValues(rows.First().Values);
|
|
|
-
|
|
|
- var bom = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.BillOfMaterials, newrow, x => x.BillOfMaterials);
|
|
|
- var requi = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.Requisitions, newrow, x => x.Requisitions);
|
|
|
- var picklist = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.PickingLists, newrow, x => x.PickingLists);
|
|
|
- var issued = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.Issued, newrow, x => x.Issued);
|
|
|
-
|
|
|
- var reserved = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.ReservedStock, newrow, x => x.ReservedStock);
|
|
|
- var ordered = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.OnOrder, newrow, x => x.OnOrder);
|
|
|
-
|
|
|
- var shortage = Math.Max(0, Math.Max(0,(requi - issued)) - (reserved + ordered));
|
|
|
- newrow.Set<JobMaterial, double>(x => x.JobShortage, shortage);
|
|
|
-
|
|
|
- var freestockrows = GetRows(freestock.Rows, freestockcolumns, null, key.Item2, key.Item3, key.Item4);
|
|
|
- var freeonhand = Aggregate(freestockrows, freestockcolumns, _stylecolumnVisible, false, x => x.Units, newrow, x => x.FreeOnHand);
|
|
|
- newrow.Set<JobMaterial, double>(x => x.FreeOnHand, freeonhand);
|
|
|
-
|
|
|
- var freeorderrows = GetRows(freeorders.Rows, freeordercolumns, null, key.Item2, key.Item3, key.Item4);
|
|
|
- var freeonorder = Aggregate(freeorderrows, freeordercolumns, _stylecolumnVisible, false, x => x.Qty, newrow, x => x.FreeOnOrder);
|
|
|
- newrow.Set<JobMaterial, double>(x => x.FreeOnOrder, freeonorder);
|
|
|
-
|
|
|
- newrow.Set<JobMaterial, double>(x => x.FreeStockTotal, freeonhand+freeonorder);
|
|
|
- newrow.Set<JobMaterial, double>(x => x.FreeStockShortage, Math.Max(0,shortage-(freeonhand+freeonorder)));
|
|
|
- table.Rows.Add(newrow);
|
|
|
- }
|
|
|
-
|
|
|
|
|
|
+ var rows = GetRows(data.Rows, columns, key.Item1, key.Item2, key.Item3, key.Item4);
|
|
|
+ if (rows.Any())
|
|
|
+ {
|
|
|
+
|
|
|
+ CoreRow newrow = table.NewRow();
|
|
|
+ newrow.LoadValues(rows.First().Values);
|
|
|
|
|
|
+ var bom = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.BillOfMaterials, newrow,
|
|
|
+ x => x.BillOfMaterials);
|
|
|
+ var requi = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.Requisitions, newrow, x => x.Requisitions);
|
|
|
+ var picklist = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.PickingLists, newrow,
|
|
|
+ x => x.PickingLists);
|
|
|
+ var issued = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.Issued, newrow, x => x.Issued);
|
|
|
+
|
|
|
+ var reserved = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.ReservedStock, newrow,
|
|
|
+ x => x.ReservedStock);
|
|
|
+ var ordered = Aggregate(rows, columns, _stylecolumnVisible, true, x => x.OnOrder, newrow, x => x.OnOrder);
|
|
|
+
|
|
|
+ var shortage = Math.Max(0, Math.Max(0, (requi - issued)) - (reserved + ordered));
|
|
|
+ newrow.Set<JobMaterial, double>(x => x.JobShortage, shortage);
|
|
|
+
|
|
|
+ var freestockrows = GetRows(freestock.Rows, freestockcolumns, null, key.Item2, key.Item3, key.Item4,
|
|
|
+ IncludeReserves ? null : (r) => !r.Get<StockHolding,bool>(x=>x.Job.JobStatus.Active));
|
|
|
+ var freeonhand = Aggregate(freestockrows, freestockcolumns, _stylecolumnVisible, false, x => x.Units, newrow,
|
|
|
+ x => x.FreeOnHand);
|
|
|
+ newrow.Set<JobMaterial, double>(x => x.FreeOnHand, freeonhand);
|
|
|
+
|
|
|
+ var freeorderrows = GetRows(freeorders.Rows, freeordercolumns, null, key.Item2, key.Item3, key.Item4,
|
|
|
+ IncludeReserves ? null : (r) => !r.Get<PurchaseOrderItem,bool>(x=>x.Job.JobStatus.Active));
|
|
|
+ var freeonorder = Aggregate(freeorderrows, freeordercolumns, _stylecolumnVisible, false, x => x.Qty, newrow,
|
|
|
+ x => x.FreeOnOrder);
|
|
|
+ newrow.Set<JobMaterial, double>(x => x.FreeOnOrder, freeonorder);
|
|
|
+
|
|
|
+ newrow.Set<JobMaterial, double>(x => x.FreeStockTotal, freeonhand + freeonorder);
|
|
|
+ newrow.Set<JobMaterial, double>(x => x.FreeStockShortage, Math.Max(0, shortage - (freeonhand + freeonorder)));
|
|
|
+ table.Rows.Add(newrow);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ action?.Invoke(table, null);
|
|
|
+
|
|
|
}
|
|
|
- action?.Invoke(table, e);
|
|
|
- });
|
|
|
+ );
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
protected override bool FilterRecord(CoreRow row)
|
|
|
{
|
|
|
var result = base.FilterRecord(row)
|
|
@@ -445,5 +456,19 @@ namespace PRSDesktop
|
|
|
);
|
|
|
return result;
|
|
|
}
|
|
|
+
|
|
|
+ private String _jobshortage = CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.JobShortage, ".");
|
|
|
+ private String _stockshortage = CoreUtils.GetFullPropertyName<JobMaterial, double>(x => x.FreeStockShortage, ".");
|
|
|
+
|
|
|
+ protected override Brush? GetCellBackground(CoreRow row, string columnname)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+ if (String.Equals(columnname, _jobshortage))
|
|
|
+ return row.Get<JobMaterial, double>(x => x.JobShortage) > 0.0F ? new SolidColorBrush(Colors.LightSalmon) { Opacity = 0.5 } : null;
|
|
|
+ if (String.Equals(columnname, _stockshortage))
|
|
|
+ return row.Get<JobMaterial, double>(x => x.FreeStockShortage) > 0.0F ? new SolidColorBrush(Colors.LightSalmon) { Opacity = 0.5 } : null;
|
|
|
+ return null;
|
|
|
+ }
|
|
|
}
|
|
|
}
|