|
@@ -0,0 +1,220 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Windows.Media;
|
|
|
+using Comal.Classes;
|
|
|
+using InABox.Clients;
|
|
|
+using InABox.Core;
|
|
|
+using InABox.DynamicGrid;
|
|
|
+
|
|
|
+namespace PRSDesktop.Panels.Requisitions;
|
|
|
+
|
|
|
+public class JobBOMSummary : BaseObject
|
|
|
+{
|
|
|
+
|
|
|
+ public ProductLink Product { get; set; }
|
|
|
+
|
|
|
+ public ProductStyleLink Style { get; set; }
|
|
|
+
|
|
|
+ public StockDimensions Dimensions { get; set; }
|
|
|
+
|
|
|
+
|
|
|
+ [DoubleEditor(Editable = Editable.Disabled)]
|
|
|
+ public double BOM { get; set; }
|
|
|
+
|
|
|
+ [DoubleEditor(Editable = Editable.Disabled)]
|
|
|
+ public double Issued { get; set; }
|
|
|
+
|
|
|
+ [DoubleEditor]
|
|
|
+ public double Quantity { get; set; }
|
|
|
+}
|
|
|
+
|
|
|
+public class RequisitionItemBillOfMaterialsPage : DynamicItemsListGrid<JobBOMSummary>, ISpecificGrid
|
|
|
+{
|
|
|
+
|
|
|
+ public RequisitionItem Item { get; set; }
|
|
|
+
|
|
|
+ private class RequisitionItemBillOfMaterialsPageUI : DynamicGridGridUIComponent<JobBOMSummary>
|
|
|
+ {
|
|
|
+ protected override Brush? GetCellBackground(CoreRow row, DynamicColumnBase column)
|
|
|
+ {
|
|
|
+ if (!row.Get<JobBOMSummary, double>(c => c.Quantity).IsEffectivelyEqual(0.0))
|
|
|
+ return new SolidColorBrush(Colors.LightGreen);
|
|
|
+ return base.GetCellBackground(row, column);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override IDynamicGridUIComponent<JobBOMSummary> CreateUIComponent() => new RequisitionItemBillOfMaterialsPageUI() { Parent = this };
|
|
|
+
|
|
|
+ protected override void Init()
|
|
|
+ {
|
|
|
+ base.Init();
|
|
|
+ HiddenColumns.Add(x=>x.Product.ID);
|
|
|
+ HiddenColumns.Add(x => x.Product.Group.ID);
|
|
|
+ HiddenColumns.Add(x=>x.Style.ID);
|
|
|
+ HiddenColumns.Add(x=>x.Dimensions.Unit.ID);
|
|
|
+ HiddenColumns.Add(x=>x.Dimensions.UnitSize);
|
|
|
+ HiddenColumns.Add(x=>x.Quantity);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void DoReconfigure(FluentList<DynamicGridOption> options)
|
|
|
+ {
|
|
|
+ base.DoReconfigure(options);
|
|
|
+ options.BeginUpdate()
|
|
|
+ .Clear()
|
|
|
+ .Add(DynamicGridOption.FilterRows)
|
|
|
+ .Add(DynamicGridOption.DirectEdit)
|
|
|
+ .Add(DynamicGridOption.HideDirectEditButton)
|
|
|
+ .EndUpdate();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void Reload(Filters<JobBOMSummary> criteria, Columns<JobBOMSummary> columns, ref SortOrder<JobBOMSummary>? sort, Action<CoreTable?, Exception?> action)
|
|
|
+ {
|
|
|
+ Items.Clear();
|
|
|
+ var table = new CoreTable();
|
|
|
+ table.LoadColumns(columns);
|
|
|
+
|
|
|
+ Filters<JobBillOfMaterialsItem> itemfilters = new Filters<JobBillOfMaterialsItem>();
|
|
|
+ itemfilters.Add(
|
|
|
+ new Filter<JobBillOfMaterialsItem>(x => x.Job.ID).IsEqualTo(Item.RequisitionLink.JobLink.ID));
|
|
|
+ foreach (var filter in criteria.Items)
|
|
|
+ {
|
|
|
+ var itemfilter = Serialization.Deserialize<Filter<JobBillOfMaterialsItem>>(Serialization.Serialize(filter));
|
|
|
+ if (itemfilter is not null)
|
|
|
+ itemfilters.Add(itemfilter);
|
|
|
+ }
|
|
|
+
|
|
|
+ Columns<JobBillOfMaterialsItem> itemcolumns = new Columns<JobBillOfMaterialsItem>();
|
|
|
+ foreach (var column in columns)
|
|
|
+ itemcolumns.Add(column.Property);
|
|
|
+
|
|
|
+ SortOrder<JobBillOfMaterialsItem>? itemsort =
|
|
|
+ Serialization.Deserialize<SortOrder<JobBillOfMaterialsItem>>(Serialization.Serialize(sort));
|
|
|
+
|
|
|
+ MultiQuery query = new();
|
|
|
+ query.Add<JobBillOfMaterialsItem>(
|
|
|
+ itemfilters.Combine(),
|
|
|
+ itemcolumns,
|
|
|
+ itemsort
|
|
|
+ );
|
|
|
+ query.Add<StockMovement>(
|
|
|
+ new Filter<StockMovement>(x=>x.Job.ID).IsEqualTo(Item.RequisitionLink.JobLink.ID)
|
|
|
+ .And(x=>x.Type).IsEqualTo(StockMovementType.Issue),
|
|
|
+ new Columns<StockMovement>(x=>x.Product.ID)
|
|
|
+ .Add(x=>x.Style.ID)
|
|
|
+ .Add(x=>x.Dimensions.Unit.ID)
|
|
|
+ .Add(x=>x.Dimensions.UnitSize)
|
|
|
+ .Add(x=>x.Issued)
|
|
|
+ );
|
|
|
+
|
|
|
+ query.Query(q =>
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ var mvmts = q.Get<StockMovement>()?.Rows.Select(r => r.ToObject<StockMovement>()).ToArray();
|
|
|
+ var bomItems = q.Get<JobBillOfMaterialsItem>()?.Rows.Select(r => r.ToObject<JobBillOfMaterialsItem>()).ToArray();
|
|
|
+
|
|
|
+ if (mvmts is not null && bomItems is not null)
|
|
|
+ {
|
|
|
+
|
|
|
+ var bomGroups = bomItems?.GroupBy<JobBillOfMaterialsItem, Tuple<Guid, Guid, Guid, String>>(x =>
|
|
|
+ new Tuple<Guid, Guid, Guid, String>(x.Product.ID, x.Style.ID, x.Dimensions.Unit.ID,
|
|
|
+ x.Dimensions.UnitSize));
|
|
|
+
|
|
|
+ foreach (var group in bomGroups)
|
|
|
+ {
|
|
|
+
|
|
|
+ JobBOMSummary summary = new JobBOMSummary();
|
|
|
+ summary.Product.ID = group.Key.Item1;
|
|
|
+ summary.Product.Synchronise(group.First().Product);
|
|
|
+ summary.Style.ID = group.Key.Item2;
|
|
|
+ summary.Style.Synchronise(group.First().Style);
|
|
|
+ summary.Dimensions.CopyFrom(group.First().Dimensions);
|
|
|
+
|
|
|
+ var issues = mvmts.Where(x =>
|
|
|
+ x.Product.ID == group.Key.Item1
|
|
|
+ && x.Style.ID == group.Key.Item2
|
|
|
+ && x.Dimensions.Unit.ID == group.Key.Item3
|
|
|
+ && Equals(x.Dimensions.UnitSize, group.Key.Item4)
|
|
|
+ );
|
|
|
+
|
|
|
+ summary.BOM = group.Sum(x => x.Quantity);
|
|
|
+ summary.Issued = issues.Sum(x=>x.Issued);
|
|
|
+
|
|
|
+ if (summary.Product.ID == Item.Product.ID
|
|
|
+ && summary.Style.ID == Item.Style.ID
|
|
|
+ && summary.Dimensions.Unit.ID == Item.Dimensions.Unit.ID
|
|
|
+ && summary.Dimensions.UnitSize.Equals(Item.Dimensions.UnitSize)
|
|
|
+ )
|
|
|
+ summary.Quantity = Item.Quantity;
|
|
|
+
|
|
|
+
|
|
|
+ Items.Add(summary);
|
|
|
+ }
|
|
|
+
|
|
|
+ table.LoadRows(Items);
|
|
|
+ }
|
|
|
+
|
|
|
+ action(table, null);
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ Console.WriteLine(e);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool bFirst = true;
|
|
|
+
|
|
|
+ protected override void OnAfterRefresh()
|
|
|
+ {
|
|
|
+ base.OnAfterRefresh();
|
|
|
+ if (!bFirst)
|
|
|
+ return;
|
|
|
+ bFirst = false;
|
|
|
+
|
|
|
+ SelectedRows = Data.Rows.Where(r =>
|
|
|
+ r.Get<JobBOMSummary, Guid>(c => c.Product.ID) == Item.Product.ID
|
|
|
+ && r.Get<JobBOMSummary, Guid>(c => c.Style.ID) == Item.Style.ID
|
|
|
+ && r.Get<JobBOMSummary, Guid>(c => c.Dimensions.Unit.ID) == Item.Dimensions.Unit.ID
|
|
|
+ && r.Get<JobBOMSummary, String>(c => c.Dimensions.UnitSize).Equals(Item.Dimensions.UnitSize)
|
|
|
+ ).ToArray();
|
|
|
+ if (SelectedRows.Any())
|
|
|
+ ScrollIntoView(SelectedRows.First());
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override DynamicGridColumns LoadColumns()
|
|
|
+ {
|
|
|
+ var columns = new DynamicGridColumns();
|
|
|
+ columns.Add<JobBOMSummary, string>(x => x.Product.Group.Code, 120, "Group", "", Alignment.MiddleCenter);
|
|
|
+ columns.Add<JobBOMSummary, string>(x => x.Product.Code, 120, "Code", "", Alignment.MiddleCenter);
|
|
|
+ columns.Add<JobBOMSummary, string>(x => x.Product.Name, 0, "Name", "", Alignment.MiddleLeft);
|
|
|
+ columns.Add<JobBOMSummary, string>(x => x.Dimensions.UnitSize, 120, "Size", "", Alignment.MiddleCenter);
|
|
|
+ columns.Add<JobBOMSummary, string>(x => x.Style.Description, 150, "Style", "", Alignment.MiddleCenter);
|
|
|
+ columns.Add<JobBOMSummary, double>(x => x.BOM, 100, "BOM", "F2", Alignment.MiddleCenter);
|
|
|
+ columns.Add<JobBOMSummary, double>(x => x.Issued, 100, "Issued", "F2", Alignment.MiddleCenter);
|
|
|
+ columns.Add<JobBOMSummary, double>(x => x.Quantity, 100, "Quantity", "F2", Alignment.MiddleCenter);
|
|
|
+ return columns;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override void Changed()
|
|
|
+ {
|
|
|
+ base.Changed();
|
|
|
+ if (Item.ID != Guid.Empty && SelectedRows.Any())
|
|
|
+ {
|
|
|
+ foreach (var row in Data.Rows.Where(x=>x.Index != SelectedRows[0].Index))
|
|
|
+ {
|
|
|
+ if (!Items[row.Index].Quantity.IsEffectivelyEqual(0.0))
|
|
|
+ {
|
|
|
+ row.Set<JobBOMSummary, double>(x => x.Quantity, 0.0);
|
|
|
+ Items[row.Index].Quantity = 0.0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ InvalidateGrid();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|