Selaa lähdekoodia

Some neatening up and fixes to issues

Kenric Nugteren 10 kuukautta sitten
vanhempi
commit
3657583d2c

+ 24 - 34
prs.classes/Entities/Job/Materials/JobMaterials.cs

@@ -97,32 +97,6 @@ namespace Comal.Classes
         public override Filter<PurchaseOrderItemAllocation> Filter => new Filter<PurchaseOrderItemAllocation>(x => x.Item.ReceivedDate).IsEqualTo(DateTime.MinValue);
     }
     
-    public class JobMaterialIssuedAggregate : CoreAggregate<JobMaterial, StockMovement, double>
-    {
-        public override Expression<Func<StockMovement, double>> Aggregate => x => x.Issued;
-
-        public override Filter<StockMovement> Filter => new Filter<StockMovement>(x => x.Type).IsEqualTo(StockMovementType.Issue);
-
-        public override AggregateCalculation Calculation => AggregateCalculation.Sum;
-
-        public override Dictionary<Expression<Func<StockMovement, object?>>, Expression<Func<JobMaterial, object?>>> Links =>
-            new Dictionary<Expression<Func<StockMovement, object?>>, Expression<Func<JobMaterial, object?>>>()
-            {
-                { StockMovement => StockMovement.Job.ID, JobMaterial => JobMaterial.Job.ID },
-                { StockMovement => StockMovement.Product.ID, JobMaterial => JobMaterial.Product.ID },
-                { StockMovement => StockMovement.Style.ID, JobMaterial => JobMaterial.Style.ID },
-            }.AddRange(Dimensions.GetLinks<StockMovement, JobMaterial>());
-    }
-    
-    public class JobMaterialCalculatedField : IFormula<JobMaterial, double>
-    {
-        public Expression<Func<JobMaterial, double>> Value => x => 0.0;
-        public Expression<Func<JobMaterial, double>>[] Modifiers => new Expression<Func<JobMaterial, double>>[] {  };
-        public FormulaOperator Operator => FormulaOperator.Constant;
-        public FormulaType Type => FormulaType.Virtual;
-    }
-    
-    
     public class JobMaterialUnionGenerator : AutoEntityUnionGenerator<IJobMaterial>
     {
         protected override void Configure()
@@ -199,9 +173,20 @@ namespace Comal.Classes
         [Aggregate(typeof(JobMaterialPickingListsAggregate))]
         public double PickingLists { get; set; }
 
-
+        private class IssuedAggregate : ComplexFormulaGenerator<JobMaterial, double>
+        {
+            public override IComplexFormulaNode<JobMaterial, double> GetFormula() =>
+                Aggregate<StockMovement>(
+                    AggregateCalculation.Sum,
+                    x => x.Property(x => x.Issued),
+                    new Filter<StockMovement>(x => x.Type).IsEqualTo(StockMovementType.Issue))
+                .WithLink(x => x.Job.ID, x => x.Job.ID)
+                .WithLink(x => x.Product.ID, x => x.Product.ID)
+                .WithLink(x => x.Style.ID, x => x.Style.ID)
+                .WithLinks(Classes.Dimensions.GetLinks<StockMovement, JobMaterial>());
+        }
         [EditorSequence(7)]
-        [Aggregate(typeof(JobMaterialIssuedAggregate))]
+        [ComplexFormula(typeof(IssuedAggregate))]
         [DoubleEditor(Editable = Editable.Hidden)]
         public double Issued { get; set; }
         
@@ -217,28 +202,33 @@ namespace Comal.Classes
 
         [EditorSequence(10)]
         [DoubleEditor]
-        [Formula(typeof(JobMaterialCalculatedField))]
+        [ComplexFormula(typeof(CalculatedField))]
         public double JobShortage { get; set; }
         
         [EditorSequence(11)]
         [DoubleEditor]
-        [Formula(typeof(JobMaterialCalculatedField))]
+        [ComplexFormula(typeof(CalculatedField))]
         public double FreeOnHand { get; set; }
         
         [EditorSequence(12)]
         [DoubleEditor]
-        [Formula(typeof(JobMaterialCalculatedField))]
+        [ComplexFormula(typeof(CalculatedField))]
         public double FreeOnOrder { get; set; }
         
         [EditorSequence(13)]
         [DoubleEditor]
-        [Formula(typeof(JobMaterialCalculatedField))]
+        [ComplexFormula(typeof(CalculatedField))]
         public double FreeStockTotal { get; set; }
         
         [EditorSequence(14)]
         [DoubleEditor]
-        [Formula(typeof(JobMaterialCalculatedField))]
+        [ComplexFormula(typeof(CalculatedField))]
         public double FreeStockShortage { get; set; }
-        
+
+        private class CalculatedField : ComplexFormulaGenerator<JobMaterial, double>
+        {
+            public override IComplexFormulaNode<JobMaterial, double> GetFormula()
+                => Constant(0.0);
+        }
     }
 }

+ 1 - 1
prs.classes/Entities/Job/Requisitions/JobRequisitionItem.cs

@@ -64,7 +64,6 @@ namespace Comal.Classes
         Issued
     }
 
-    
     public interface IJobRequisitionItem : IEntity
     {
 
@@ -133,6 +132,7 @@ namespace Comal.Classes
         [EditorSequence(9)]
         [LoggableProperty]
         [RequiredColumn]
+        [Obsolete("", true)]
         public JobRequisitionItemStatus Status { get; set; } = JobRequisitionItemStatus.NotChecked;
 
         private class InStockFormula : ComplexFormulaGenerator<JobRequisitionItem, double>

+ 0 - 58
prs.classes/Entities/Job/Requisitions/JobRequisitionItemPurchaseOrderItem.cs

@@ -10,14 +10,12 @@ namespace Comal.Classes
     public class PurchaseOrderItemAllocation : Entity, IRemotable, IPersistent, ILicense<ProjectManagementLicense>
     , IOneToMany<JobRequisitionItem>, IOneToMany<Job>, IOneToMany<PurchaseOrderItem>
     {
-        [RequiredColumn]
         [EntityRelationship(DeleteAction.Cascade)]
         public PurchaseOrderItemLink Item { get; set; }
         
         /// <summary>
         /// This may not be blank.
         /// </summary>
-        [RequiredColumn]
         [EntityRelationship(DeleteAction.Cascade)]
         public JobLink Job { get; set; }
         
@@ -25,65 +23,9 @@ namespace Comal.Classes
         /// This may be an empty link. The interface is as such: if there is no JRI, then we are creating a reserve and allocation just against the job. If there is a JRI,
         /// then received stock is reserved and allocated for the JRI.
         /// </summary>
-        [RequiredColumn]
         [EntityRelationship(DeleteAction.Cascade)]
         public JobRequisitionItemLink JobRequisitionItem { get; set; }
         
-        [RequiredColumn]
         public double Quantity { get; set; }
     }
-    
-    [Caption("Requisition / PO Item Links")]
-    [Obsolete("Replaced with PurchaseOrderItemAllocation", true)]
-    public class JobRequisitionItemPurchaseOrderItem : Entity, IRemotable, IPersistent, IOneToMany<JobRequisitionItem>, IOneToMany<PurchaseOrderItem>, ILicense<ProjectManagementLicense>
-    {
-        
-        private class JobRequisitionItemLookup : LookupDefinitionGenerator<JobRequisitionItem, JobRequisitionItemPurchaseOrderItem>
-        {
-            public override Filter<JobRequisitionItem>? DefineFilter(JobRequisitionItemPurchaseOrderItem[] items)
-            {
-                var jobs = items.Select(x => x.PurchaseOrderItem.Job.ID).Distinct().ToArray();
-                var products = items.Select(x => x.PurchaseOrderItem.Product.ID).Distinct().ToArray();
-                if(jobs.Length == 1 && products.Length == 1)
-                {
-                    return new Filter<JobRequisitionItem>(x => x.Job.ID).IsEqualTo(jobs.First())
-                        .And(x => x.Product.ID).IsEqualTo(products.First());
-                }
-                {
-                    return new Filter<JobRequisitionItem>().None();
-                }
-            }
-
-            public override Columns<JobRequisitionItemPurchaseOrderItem> DefineFilterColumns()
-                => Columns.None<JobRequisitionItemPurchaseOrderItem>().Add(x => x.PurchaseOrderItem.Job.ID)
-                    .Add(x => x.PurchaseOrderItem.Product.ID);
-        }
-        [LookupDefinition(typeof(JobRequisitionItemLookup))]
-        [EntityRelationship(DeleteAction.Cascade)]
-        public JobRequisitionItemLink JobRequisitionItem { get; set; }
-
-        private class PurchaseOrderItemLookup : LookupDefinitionGenerator<PurchaseOrderItem, JobRequisitionItemPurchaseOrderItem>
-        {
-            public override Filter<PurchaseOrderItem>? DefineFilter(JobRequisitionItemPurchaseOrderItem[] items)
-            {
-                var jobs = items.Select(x => x.JobRequisitionItem.Job.ID).Distinct().ToArray();
-                var products = items.Select(x => x.JobRequisitionItem.Product.ID).Distinct().ToArray();
-                if(jobs.Length == 1 && products.Length == 1)
-                {
-                    return new Filter<PurchaseOrderItem>(x => x.Job.ID).IsEqualTo(jobs.First())
-                        .And(x => x.Product.ID).IsEqualTo(products.First());
-                }
-                {
-                    return new Filter<PurchaseOrderItem>().None();
-                }
-            }
-
-            public override Columns<JobRequisitionItemPurchaseOrderItem> DefineFilterColumns()
-                => Columns.None<JobRequisitionItemPurchaseOrderItem>().Add(x => x.JobRequisitionItem.Job.ID)
-                .Add(x => x.JobRequisitionItem.Product.ID);
-        }
-        [LookupDefinition(typeof(PurchaseOrderItemLookup))]
-        [EntityRelationship(DeleteAction.Cascade)]
-        public PurchaseOrderItemLink PurchaseOrderItem { get; set; }
-    }
 }

+ 10 - 3
prs.classes/Entities/PurchaseOrder/PurchaseOrder.cs

@@ -271,8 +271,15 @@ namespace Comal.Classes
             LinkedProperties.Register<PurchaseOrder, SupplierLink, String>(x => x.SupplierLink, x => x.Name, x => x.SupplierName);
         }
         
+        /// <summary>
+        /// Recalculate the cost of each PurchaseOrderItem in <paramref name="items"/>, by finding a <see cref="SupplierProduct"/> that matches.
+        /// </summary>
+        /// <param name="items"></param>
+        /// <param name="supplierid"></param>
+        /// <param name="changes"></param>
         public static void UpdateCosts(IEnumerable<PurchaseOrderItem> items, Guid supplierid, Dictionary<String,object?> changes)
         {
+            var itemsList = items.AsIList();
 
             void UpdateValue<TType>(PurchaseOrderItem item,Expression<Func<PurchaseOrderItem, TType>> property, TType value)
             {
@@ -283,7 +290,7 @@ namespace Comal.Classes
                 );
             }
             
-            var productids = items.Where(x => x.Product.ID != Guid.Empty).Select(x => x.Product.ID).ToArray();
+            var productids = itemsList.Where(x => x.Product.ID != Guid.Empty).Select(x => x.Product.ID).ToArray();
             MultiQuery query = new MultiQuery();
             query.Add(
                 new Filter<SupplierProduct>(x=>x.SupplierLink.ID).IsEqualTo(supplierid)
@@ -307,7 +314,7 @@ namespace Comal.Classes
             );
             
             query.Add(
-                new Filter<PurchaseOrderItemAllocation>(x=>x.Item.ID).InList(items.Select(x => x.ID).ToArray()),
+                new Filter<PurchaseOrderItemAllocation>(x=>x.Item.ID).InList(itemsList.ToArray(x => x.ID)),
                 Columns.None<PurchaseOrderItemAllocation>()
                     .Add(x=>x.Job.ID)
                     .Add(x=>x.Item.ID)
@@ -319,7 +326,7 @@ namespace Comal.Classes
             var productInstances = query.Get<ProductInstance>().ToArray<ProductInstance>();
             var allocations = query.Get<PurchaseOrderItemAllocation>().ToArray<PurchaseOrderItemAllocation>();
             
-            foreach (var item in items)
+            foreach (var item in itemsList)
             {
                 //Check Supplier / Job Specific Pricing
                 var supplierProduct = supplierProducts.FirstOrDefault(x =>

+ 0 - 1
prs.classes/Entities/PurchaseOrder/PurchaseOrderItemLookups.cs

@@ -51,7 +51,6 @@ namespace Comal.Classes
                 .Add(x => x.Cost)
                 .Add(x => x.Product.ID)
                 .Add(x => x.Style.ID)
-                //.Add(x => x.Job.ID)
                 .Add(x=>x.ReceivedDate)
                 .Add(x => x.Consignment.ID)
                 .Add(x => x.Consignment.ExTax)

+ 0 - 1
prs.desktop/Panels/Jobs/BillOfMaterials/JobBillOfMaterialsItemsGrid.cs

@@ -296,7 +296,6 @@ public class JobBillOfMaterialsItemGrid : DynamicDataGrid<JobBillOfMaterialsItem
                 {
                     bomItem.PurchaseOrderItem.ID = item.ID;
                     bomItem.PurchaseOrderItem.DueDate = item.DueDate;
-                    bomItem.BillOfMaterials.Job.ID = Job?.ID ?? Guid.Empty;
                     bomItems.Add(bomItem);
                 }
             }

+ 0 - 1
prs.desktop/Panels/Jobs/Requisitions/JobRequisitionItemGrid.cs

@@ -119,7 +119,6 @@ internal class JobRequisitionItemGrid : DynamicDataGrid<JobRequisitionItem>, IMa
                     _poi.Style.ID = _jri.Style.ID;
                     _poi.Style.Code = _jri.Style.Code;
                     _poi.Style.Description = _jri.Style.Description;
-                    //_poi.Job.ID = _jri.Job.ID;
                     _poi.Dimensions.UnitSize = _jri.Dimensions.UnitSize;
                     _poi.Description = _jri.Product.Name + " (" + _jri.Dimensions.ToString() + ")";
                     _poi.Cost = _jri.UnitCost;

+ 1 - 1
prs.desktop/Panels/PurchaseOrders/SupplierPurchaseOrderItemOneToMany.cs

@@ -710,7 +710,7 @@ public class SupplierPurchaseOrderItemOneToMany : DynamicOneToManyGrid<PurchaseO
     protected override void OnAfterEditorValueChanged(DynamicEditorGrid? grid, PurchaseOrderItem[] items, AfterEditorValueChangedArgs args, Dictionary<string, object?> changes)
     {
         base.OnAfterEditorValueChanged(grid, items, args, changes);
-        if (args.ColumnName.Equals("Product.ID") || args.ColumnName.Equals("Job.ID") || args.ColumnName.Equals("Dimensions") || args.ColumnName.StartsWith("Dimensions.") || args.ColumnName.Equals("Style.ID"))
+        if (args.ColumnName.Equals("Product.ID") || args.ColumnName.Equals("Job.ID") || args.ColumnName.StartsWith("Dimensions.") || args.ColumnName.Equals("Style.ID"))
         {
             PurchaseOrder.UpdateCosts(
                 items, 

+ 9 - 80
prs.desktop/Panels/Reservation Management/ReservationManagementItemGrid.cs

@@ -436,9 +436,6 @@ public class ReservationManagementItemGrid : DynamicDataGrid<JobRequisitionItem>
                 LookupFactory.DoLookups<PurchaseOrderItem, ProductStyle, ProductStyleLink>(
                     orderItems.Values.Select(x => new Tuple<PurchaseOrderItem, Guid>(x, x.Style.ID)),
                     x => x.Style);
-                //LookupFactory.DoLookups<PurchaseOrderItem, Job, JobLink>(
-                //    orderItems.Values.Select(x => new Tuple<PurchaseOrderItem, Guid>(x, x.Job.ID)),
-                //    x => x.Job);
                 LookupFactory.DoLookups<PurchaseOrderItem, TaxCode, TaxCodeLink>(
                     orderItems.Values.Select(x => new Tuple<PurchaseOrderItem, Guid>(x, x.TaxCode.ID)),
                     x => x.TaxCode);
@@ -464,97 +461,29 @@ public class ReservationManagementItemGrid : DynamicDataGrid<JobRequisitionItem>
             }
             Client.Save(orders.SelectMany(x => x.Item2.Values), "Created from Reservation Management screen");
 
-            List<PurchaseOrderItemAllocation> allocations = new();
+            var allocations = new List<PurchaseOrderItemAllocation>();
             progress.Report($"Processing Breakups");
             foreach(var (order, orderItems) in orders)
             {
-                foreach(var pair in orderItems)
+                foreach(var (result, poi) in orderItems)
                 {
-                    foreach (var breakup in pair.Key.Breakups)
+                    foreach (var breakup in result.Breakups)
                     {
                         var alloc = new PurchaseOrderItemAllocation();
-                        alloc.Item.ID = pair.Value.ID;
-                        alloc.Job.ID = breakup.Item1;
-                        alloc.JobRequisitionItem.ID = breakup.Item2;
-                        alloc.Quantity = breakup.Item4;
+                        alloc.Item.ID = poi.ID;
+                        alloc.Job.ID = breakup.JobID;
+                        alloc.JobRequisitionItem.ID = breakup.JobRequiItemID;
+                        alloc.Quantity = breakup.Quantity;
                         allocations.Add(alloc);
                     }
                 }
             }
-            if (allocations.Any())
-                Client.Save(allocations,"Created from Reservation Management Screen");
+            if (allocations.Count != 0)
+                Client.Save(allocations, "Created from Reservation Management Screen");
         });
         MessageWindow.ShowMessage($"The following orders were created:\n- {string.Join("\n- ",orders.Select(x=>x.Item1.PONumber))}", $"Created {orders.Count} orders");
         return true;
     }
-    
-    // private bool DoCreatePurchaseOrder(Button button, CoreRow[]? rows)
-    // {
-    //     if (rows?.Any() != true)
-    //         return false;
-    //
-    //     MultiSelectDialog<Supplier> dlg = new MultiSelectDialog<Supplier>(
-    //         LookupFactory.DefineFilter<Supplier>(),
-    //         Columns.None<Supplier>()
-    //             .Add(x => x.ID)
-    //             .Add(x => x.Code)
-    //             .Add(x => x.Name),
-    //         false
-    //     );
-    //     
-    //     var _po = new PurchaseOrder();
-    //     if (dlg.ShowDialog())
-    //     {
-    //         Progress.ShowModal("Creating Purchase Order", progress =>
-    //         {
-    //             
-    //             _po.Description = "Created from Job Requisition Screen" + System.Environment.NewLine;
-    //             _po.RaisedBy.ID = App.EmployeeID;
-    //             _po.SupplierLink.ID = dlg.IDs().First();
-    //             Client.Save(_po, "Created From Requisition Screen");
-    //             
-    //             progress.Report("Creating Order Items");
-    //             Dictionary<Guid,PurchaseOrderItem> _pois = new Dictionary<Guid,PurchaseOrderItem>();
-    //             foreach (CoreRow row in SelectedRows)
-    //             {
-    //                 JobRequisitionItem _jri = row.ToObject<JobRequisitionItem>();
-    //                 PurchaseOrderItem _poi = new PurchaseOrderItem();
-    //                 _poi.PurchaseOrderLink.ID = _po.ID;
-    //                 _poi.Product.ID = _jri.Product.ID;
-    //                 _poi.Product.Code = _jri.Product.Code;
-    //                 _poi.Product.Name = _jri.Product.Name;               
-    //                 _poi.Qty = _jri.Qty;
-    //                 _poi.Dimensions.CopyFrom(_jri.Dimensions);
-    //                 _poi.Dimensions.Value = _jri.Dimensions.Value;
-    //                 _poi.Style.ID = _jri.Style.ID;
-    //                 _poi.Style.Code = _jri.Style.Code;
-    //                 _poi.Style.Description = _jri.Style.Description;
-    //                 _poi.Job.ID = _jri.Job.ID;
-    //                 _poi.Dimensions.UnitSize = _jri.Dimensions.UnitSize;
-    //                 _poi.Description = _jri.Product.Name + " (" + _jri.Dimensions.ToString() + ")";
-    //                 _poi.Cost = _jri.UnitCost;
-    //                 _pois[_jri.ID] = _poi;
-    //             }
-    //             Client.Save(_pois.Values, "Created From Requisition Screen");
-    //
-    //             List<JobRequisitionItemPurchaseOrderItem> _jripois = new();
-    //             foreach (var _poi in _pois)
-    //             {
-    //                 var _jripoi = new JobRequisitionItemPurchaseOrderItem();
-    //                 _jripoi.JobRequisitionItem.ID = _poi.Key;
-    //                 _jripoi.PurchaseOrderItem.ID = _poi.Value.ID;
-    //                 _jripois.Add(_jripoi);
-    //             }
-    //             Client.Save(_jripois, "Created From Requisition Screen");
-    //
-    //         });
-    //
-    //     }
-    //     new SupplierPurchaseOrders().EditItems(new[] { _po });
-    //     return true;
-    // }
-    //
-    #endregion
 
     #region CreatePickingList
     

+ 1 - 3
prs.desktop/Panels/Reservation Management/ReservationManagementPanel.xaml.cs

@@ -565,9 +565,6 @@ public partial class ReservationManagementPanel : UserControl, IPanel<JobRequisi
                 LookupFactory.DoLookups<PurchaseOrderItem, Product, ProductLink>(
                     orderItems.Select(x => new Tuple<PurchaseOrderItem, Guid>(x.Item1, x.Item1.Product.ID)),
                     x => x.Product);
-                //LookupFactory.DoLookups<PurchaseOrderItem, Job, JobLink>(
-                //    orderItems.Select(x => new Tuple<PurchaseOrderItem, Guid>(x.Item1, x.Item1.Job.ID)),
-                //    x => x.Job);
                 LookupFactory.DoLookups<PurchaseOrderItem, TaxCode, TaxCodeLink>(
                     orderItems.WithIndex().Select(x => new Tuple<PurchaseOrderItem, Guid>(x.Value.Item1, perSupplier[x.Key].SupplierProduct.TaxCode.ID)),
                     x => x.TaxCode);
@@ -658,6 +655,7 @@ public partial class ReservationManagementPanel : UserControl, IPanel<JobRequisi
             Client.Save(orders.SelectMany(x => x.Item2).Select(x =>
             {
                 var jriPOI = new PurchaseOrderItemAllocation();
+                jriPOI.Job.ID = x.Item2.Job.ID;
                 jriPOI.JobRequisitionItem.ID = x.Item2.ID;
                 jriPOI.Item.ID = x.Item1.ID;
                 jriPOI.Quantity = x.Item1.Qty;

+ 0 - 2
prs.desktop/Panels/Reservation Management/Treatment PO/ReservationManagementTreatmentOrderGrid.cs

@@ -383,9 +383,7 @@ public class ReservationManagementTreatmentOrderGrid: DynamicItemsListGrid<Reser
 
             var supplierProduct = new SupplierProduct();
             LookupFactory.DoLookup<SupplierProduct, Product, ProductLink>(supplierProduct, x => x.Product, item.TreatmentProduct.ID);
-            //LookupFactory.DoLookup<SupplierProduct, ProductStyle, ProductStyleLink>(supplierProduct, x => x.Style, item.Style.ID);
             supplierProduct.SupplierLink.CopyFrom(supplier);
-            //supplierProduct.Dimensions.Quantity = 1.0;
 
             if (DynamicGridUtils.EditEntity(supplierProduct, customiseGrid: EditSupplierProductGrid))
             {

+ 27 - 21
prs.desktop/Panels/Stock Forecast/OrderScreen/StockForecastOrderingGrid.cs

@@ -34,10 +34,21 @@ public class StockForecastOrderData(ProductLink product, ProductStyleLink style,
     public StockDimensions Dimensions { get; set; } = dimensions;
 
     public double RequiredQuantity { get; set; }
+
+    public class QuantityBreakup(Guid jobID, Guid requiID, string description, double qty)
+    {
+        public Guid JobID { get; set; } = jobID;
+
+        public Guid JobRequiItemID { get; set; } = requiID;
+
+        public string Description { get; set; } = description;
+
+        public double Quantity { get; set; } = qty;
+    }
     
-    private List<Tuple<Guid, Guid, string, double>> RequiredQuantities { get; set; } = [];
+    private List<QuantityBreakup> RequiredQuantities { get; set; } = [];
 
-    public List<Tuple<Guid, Guid, string, double>> GetRequiredQuantities() => RequiredQuantities;
+    public List<QuantityBreakup> GetRequiredQuantities() => RequiredQuantities;
     
     public void SetRequiredQuantity(Guid jobid, Guid requiid, string description, double qty)
     {
@@ -97,7 +108,7 @@ public class StockForecastOrderingItem : BaseObject
     [EditorSequence(3)]
     public StockDimensions Dimensions { get; set; }
     
-    public List<Tuple<Guid, Guid, string, double>> Breakups { get; } = [];
+    public List<StockForecastOrderData.QuantityBreakup> Breakups { get; } = [];
     
     [EditorSequence(5)]
     [DoubleEditor]
@@ -123,26 +134,22 @@ public class StockForecastOrderingItem : BaseObject
     }
 }
 
-public class StockForecastOrderingResult
+public class StockForecastOrderingResult(
+    SupplierLink supplier,
+    List<StockForecastOrderData.QuantityBreakup> breakups,
+    StockForecastOrderingItem item,
+    double quantity,
+    SupplierProduct supplierProduct)
 {
-    public SupplierLink Supplier { get; set; }
+    public SupplierLink Supplier { get; set; } = supplier;
 
-    public StockForecastOrderingItem Item { get; set; }
+    public StockForecastOrderingItem Item { get; set; } = item;
 
-    public SupplierProduct SupplierProduct { get; set; }
+    public SupplierProduct SupplierProduct { get; set; } = supplierProduct;
 
-    public double Quantity { get; set; }
+    public double Quantity { get; set; } = quantity;
 
-    public List<Tuple<Guid,Guid, string,double>> Breakups { get; set; }
-    
-    public StockForecastOrderingResult(SupplierLink supplier, List<Tuple<Guid,Guid,String,double>> breakups, StockForecastOrderingItem item, double quantity, SupplierProduct supplierProduct)
-    {
-        Supplier = supplier;
-        Breakups= breakups;
-        Item = item;
-        Quantity = quantity;
-        SupplierProduct = supplierProduct;
-    }
+    public List<StockForecastOrderData.QuantityBreakup> Breakups { get; set; } = breakups;
 }
 
 public enum StockForecastOrderingStrategy
@@ -245,7 +252,7 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
                     {
                         if(OrderType == StockForecastOrderingType.StockOrder && qty.Total > 0)
                         {
-                            yield return new(supplier, new List<Tuple<Guid, Guid,string,double>>() , item, qty.Total, qty.SupplierProduct);
+                            yield return new(supplier, new List<StockForecastOrderData.QuantityBreakup>() , item, qty.Total, qty.SupplierProduct);
                         }
                         else
                         {
@@ -444,13 +451,12 @@ public class StockForecastOrderingGrid : DynamicItemsListGrid<StockForecastOrder
                 if(OrderType == StockForecastOrderingType.StockOrder)
                 {
                     item.RequiredQuantity = dataItem.RequiredQuantity;
-                    //item.Breakups.Add(new(Guid.Empty, Guid.Empty, "", dataItem.RequiredQuantity));
                 }
                 else
                 {
                     foreach(var breakup in dataItem.GetRequiredQuantities())
                     {
-                        item.RequiredQuantity += breakup.Item4;
+                        item.RequiredQuantity += breakup.Quantity;
                         item.Breakups.Add(breakup);
                     }
                 }

+ 0 - 63
prs.shared/Database Update Scripts/Utils/JobRequisitionItemUtils.cs

@@ -1,63 +0,0 @@
-// using Comal.Classes;
-// using Comal.Stores;
-// using InABox.Core;
-// using InABox.Database;
-// using PRSStores;
-// using System;
-// using System.Collections.Generic;
-// using System.Linq;
-// using System.Text;
-// using System.Threading.Tasks;
-//
-// namespace PRS.Shared.Database_Update_Scripts.Utils;
-//
-// public static class JobRequisitionItemUtils
-// {
-//     public static void RefreshStatuses(IStore store)
-//     {
-//         Logger.Send(LogType.Information, "", $"Refreshing JobRequisitionItem statuses");
-//         var jobRequiItems = store.Provider.Query(
-//             null,
-//             JobRequisitionItemStore.StatusRequiredColumns().Add(x => x.Status))
-//             .ToObjects<JobRequisitionItem>()
-//             .ToList();
-//
-//         var statusUpdates = new Dictionary<Tuple<JobRequisitionItemStatus, JobRequisitionItemStatus>, List<Guid>>();
-//
-//         var i = 0;
-//         foreach(var item in jobRequiItems)
-//         {
-//             if(i % 50 == 0)
-//             {
-//                 Logger.Send(LogType.Information, "", $"Refreshing statuses: {(((double)i) / (double)jobRequiItems.Count * 100):F0}%");
-//             }
-//             if (JobRequisitionItemStore.CalculateStatus(store, item))
-//             {
-//                 var key = new Tuple<JobRequisitionItemStatus, JobRequisitionItemStatus>(item.GetOriginalValue(x=>x.Status), item.Status);
-//                 if(!statusUpdates.TryGetValue(key, out var list))
-//                 {
-//                     list = new List<Guid>();
-//                     statusUpdates.Add(key, list);
-//                 }
-//                 list.Add(item.ID);
-//                 //item.Issues += $"Updated status from {item.GetOriginalValue(x=>x.Status)} to {item.Status}";
-//                 
-//             }
-//             ++i;
-//         }
-//
-//         foreach(var ((from, to), list) in statusUpdates)
-//         {
-//             Logger.Send(LogType.Information, "", $"{from} -> {to}: {list.Count} entries");
-//         }
-//
-//         new BaseStore<JobRequisitionItem>
-//         {
-//             UserGuid = Guid.Empty,
-//             UserID = "",
-//             Platform = Platform.Server,
-//             Version = CoreUtils.GetVersion(),
-//             Provider = DbFactory.NewProvider(Logger.Main)
-//         }.Save(jobRequiItems, "");
-//     }
-// }

+ 0 - 26
prs.stores/JobRequisitionItemPurchaseOrderItemStore.cs

@@ -1,26 +0,0 @@
-using Comal.Classes;
-using Comal.Stores;
-using InABox.Core;
-using System.Collections.Generic;
-using System.Text;
-
-namespace PRSStores;
-
-// public class JobRequisitionItemPurchaseOrderItemStore : BaseStore<JobRequisitionItemPurchaseOrderItem>
-// {
-//     protected override void AfterSave(JobRequisitionItemPurchaseOrderItem entity)
-//     {
-//         base.AfterSave(entity);
-//
-//         if(entity.PurchaseOrderItem.HasOriginalValue(x => x.ID) || entity.JobRequisitionItem.HasOriginalValue(x => x.ID))
-//         {
-//             JobRequisitionItemStore.UpdateStatus(this, entity.JobRequisitionItem.ID, JobRequisitionItemAction.Created);
-//         }
-//     }
-//
-//     protected override void AfterDelete(JobRequisitionItemPurchaseOrderItem entity)
-//     {
-//         JobRequisitionItemStore.UpdateStatus(this, entity.JobRequisitionItem.ID, JobRequisitionItemAction.Deleted);
-//         base.AfterDelete(entity);
-//     }
-// }