瀏覽代碼

Removed many references to JRI.Status and POI.Job

Kenric Nugteren 8 月之前
父節點
當前提交
c7e4e87d0d

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

@@ -13,7 +13,8 @@ namespace Comal.Classes
     {
         NotChecked, // Default
         /// <summary>
-        /// All required stock has been received, and is in the correct <see cref="ProductStyle"/>.
+        /// All required stock has been received, and is in the correct <see cref="ProductStyle"/>.<br/>
+        /// <code>Allocated + Issued >= Qty</code>
         /// </summary>
         /// <remarks>
         /// This can be set even if there are unreceived <see cref="JobRequisitionItemPurchaseOrderItem"/>,
@@ -22,6 +23,7 @@ namespace Comal.Classes
         Allocated,
         /// <summary>
         /// All required stock has been received, but some is not in the correct <see cref="ProductStyle"/>, meaning a treatment is required.
+        /// <code>InStock + Issued >= Qty</code>
         /// </summary>
         /// <remarks>
         /// This can be set even if there are unreceived <see cref="JobRequisitionItemPurchaseOrderItem"/>,
@@ -55,6 +57,7 @@ namespace Comal.Classes
         Cancelled,
         /// <summary>
         /// The <see cref="JobRequisitionItem/"> has been archived, meaning it has a non-empty <see cref="JobRequisitionItem.Archived"/>.
+        /// <code>Issued >= Qty</code>
         /// </summary>
         Archived,
 

+ 1 - 1
prs.desktop/Panels/Jobs/Summary/JobSummaryGrid.cs

@@ -570,7 +570,7 @@ internal class JobSummaryGrid : DynamicDataGrid<JobMaterial>, IMasterDetailContr
             null,
 
             IncludeReserves
-                ? new Filter<PurchaseOrderItemAllocation>(x => x.Item.Job.ID).IsNotEqualTo(Master?.ID ?? Guid.Empty)
+                ? new Filter<PurchaseOrderItemAllocation>(x => x.Job.ID).IsNotEqualTo(Master?.ID ?? Guid.Empty)
                 : new Filter<PurchaseOrderItemAllocation>(x => x.Job.JobStatus.Active).IsEqualTo(false),
             null
         );

+ 7 - 6
prs.desktop/Panels/Reservation Management/ReservationManagementItemGrid.cs

@@ -141,7 +141,6 @@ public class ReservationManagementItemGrid : DynamicDataGrid<JobRequisitionItem>
         HiddenColumns.Add(x => x.Style.ID);
         HiddenColumns.Add(x => x.Style.Code);
         HiddenColumns.Add(x => x.Style.Description);
-        HiddenColumns.Add(x => x.Status);
         HiddenColumns.Add(x => x.Requisition.ID);
         HiddenColumns.Add(x => x.Requisition.Job.ID);
         HiddenColumns.Add(x => x.Requisition.Job.JobNumber);
@@ -407,8 +406,10 @@ public class ReservationManagementItemGrid : DynamicDataGrid<JobRequisitionItem>
         return true;
     }
 
+    #endregion
+
     #region CreatePickingList
-    
+
     private bool DoCreatePickingList(Button button, CoreRow[]? rows)
     {
         if (rows?.Any() != true)
@@ -598,12 +599,12 @@ public class ReservationManagementItemGrid : DynamicDataGrid<JobRequisitionItem>
     private bool CheckValidAction(JobRequisitionItem item)
     {
         bool valid = true;
-        if (item.Status == JobRequisitionItemStatus.Allocated)
+        if (item.Allocated + item.Issued >= item.Qty)
         {
             MessageWindow.ShowMessage("Item has already been reserved!", "Error", image: MessageWindow.WarningImage);
             return false;
         }
-        else if (item.Status == JobRequisitionItemStatus.OnOrder)
+        else if (item.OnOrder >= 0)
         {
             MessageWindow.ShowMessage("Item is already on order!", "Error", image: MessageWindow.WarningImage);
             return false;
@@ -669,11 +670,11 @@ public class ReservationManagementItemGrid : DynamicDataGrid<JobRequisitionItem>
         var toChange = new List<JobRequisitionItem>();
         foreach(var item in itemsList)
         {
-            if (item.Status != JobRequisitionItemStatus.Allocated)
+            if (item.Allocated + item.Issued < item.Qty)
             {
                 var win = MessageWindow.New()
                     .Message($"Requisition item for requisition {item.Requisition.Number} is not fully allocated; " +
-                    $"its current status is {item.Status}. Are you sure you wish to archive this item?")
+                    $"Are you sure you wish to archive this item?")
                     .Title("Confirm Archive")
                     .AddYesButton("Archive");
                 if(itemsList.Count > 1)

+ 38 - 22
prs.desktop/Panels/Stock Forecast/StockForecastGrid.cs

@@ -491,18 +491,18 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
                 break;
             case ColumnTag.GeneralPurchaseOrders:
                 ShowDetailGrid(
-                    "Purchase Orders", 
-                    () => BuildDetailGrid<PurchaseOrderItem>(
+                    "Purchase Order Allocations", 
+                    () => BuildDetailGrid<PurchaseOrderItemAllocation>(
                         ColumnTag.GeneralPurchaseOrders.ToString(), 
-                        x => x.Product.ID, 
+                        x => x.Item.Product.ID, 
                         item.Product.ID, 
-                        x => x.Style.ID, 
+                        x => x.Item.Style.ID, 
                         styleid, 
-                        x => x.Dimensions,
+                        x => x.Item.Dimensions,
                         item.Dimensions,
                         null,
-                        new Filter<PurchaseOrderItem>(x=>x.Job.ID).IsEqualTo(Guid.Empty)
-                            .And(x=>x.ReceivedDate).IsEqualTo(DateTime.MinValue),
+                        new Filter<PurchaseOrderItemAllocation>(x=>x.Job.ID).IsEqualTo(Guid.Empty)
+                            .And(x=>x.Item.ReceivedDate).IsEqualTo(DateTime.MinValue),
                         null
                     )
                 );
@@ -557,16 +557,16 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
             case ColumnTag.JobPurchaseOrders:
                 ShowDetailGrid(
                     "Purchase Orders", 
-                    () => BuildDetailGrid<PurchaseOrderItem>(
+                    () => BuildDetailGrid<PurchaseOrderItemAllocation>(
                         ColumnTag.GeneralPurchaseOrders.ToString(), 
-                        x => x.Product.ID, 
+                        x => x.Item.Product.ID, 
                         item.Product.ID, 
-                        x => x.Style.ID, 
+                        x => x.Item.Style.ID, 
                         styleid, 
-                        x => x.Dimensions,
+                        x => x.Item.Dimensions,
                         item.Dimensions,
                         x => x.Job.ID,
-                        new Filter<PurchaseOrderItem>(x=>x.ReceivedDate).IsEqualTo(DateTime.MinValue),
+                        new Filter<PurchaseOrderItemAllocation>(x => x.Item.ReceivedDate).IsEqualTo(DateTime.MinValue),
                         null
                     )
                 );                  
@@ -741,9 +741,19 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
                     .Add(x => x.MinimumStockLevel)),
             GetQuery<StockHolding>(
                 columns: Columns.None<StockHolding>().Add(x => x.Units)),
-            GetQuery<PurchaseOrderItem>(
-                filter: new Filter<PurchaseOrderItem>(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue),
-                columns: Columns.None<PurchaseOrderItem>().Add(x => x.Qty)),
+            new KeyedQueryDef<PurchaseOrderItemAllocation>(
+                new Filter<PurchaseOrderItemAllocation>(x => x.Item.ReceivedDate).IsEqualTo(DateTime.MinValue)
+                    .And(x => x.Item.Product.Group.ID).InList(GroupIDs)
+                    .And(new Filter<PurchaseOrderItemAllocation>(x => x.Job.ID).InList(JobIDs)
+                        .Or(x => x.Job.ID).IsEqualTo(Guid.Empty)),
+                Columns.None<PurchaseOrderItemAllocation>()
+                    .Add(x => x.Quantity)
+                    .Add(x => x.Job.ID)
+                    .Add(x => x.Item.Product.ID)
+                    .Add(x => x.Item.Style.ID)
+                    .AddDimensionsColumns(x => x.Item.Dimensions, Dimensions.ColumnsType.Local)
+                    .Add(x => x.Item.Dimensions.UnitSize)
+                    .Add(x => x.Item.Dimensions.Value)),
             GetQuery<JobBillOfMaterialsItem>(
                 filter: new Filter<JobBillOfMaterialsItem>(x=>x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue),
                 columns: Columns.None<JobBillOfMaterialsItem>().Add(x => x.Quantity)),
@@ -806,19 +816,25 @@ public class StockForecastGrid : DynamicItemsListGrid<StockForecastItem>, IDataM
                     }
                 }
 
-                var poItems = results.Get<PurchaseOrderItem>();
-                foreach(var poItem in poItems.Rows)
+                var allocations = results.Get<PurchaseOrderItemAllocation>();
+                foreach(var allocation in allocations.Rows)
                 {
-                    var item = GetItem(GetKey(poItem));
-                    var jobID = poItem.Get<PurchaseOrderItem, Guid>(x => x.Job.ID);
+                    var key = new ItemKey(
+                        allocation.Get<PurchaseOrderItemAllocation, Guid>(x => x.Item.Product.ID),
+                        allocation.Get<PurchaseOrderItemAllocation, Guid>(x => x.Item.Style.ID),
+                        allocation.ToDimensions<PurchaseOrderItemAllocation, StockDimensions>(x => x.Item.Dimensions));
+                    var item = GetItem(key);
+                    var jobID = allocation.Get<PurchaseOrderItemAllocation, Guid>(x => x.Job.ID);
+
+                    var qty = allocation.Get<PurchaseOrderItemAllocation, double>(x => x.Quantity);
                     if(jobID == Guid.Empty)
                     {
-                        item.GenPO += poItem.Get<PurchaseOrderItem, double>(x => x.Qty);
+                        item.GenPO += qty;
                     }
                     else
                     {
-                        item.JobPO += poItem.Get<PurchaseOrderItem, double>(x => x.Qty);
-                        item.AddJobPO(jobID, poItem.Get<PurchaseOrderItem, double>(x => x.Qty));
+                        item.JobPO += qty;
+                        item.AddJobPO(jobID, qty);
                     }
                 }
 

+ 1 - 1
prs.shared/Database Update Scripts/DatabaseUpdateScripts.cs

@@ -39,7 +39,7 @@ public static class DatabaseUpdateScripts
         DataUpdater.RegisterUpdateScript<Update_7_43>();
         DataUpdater.RegisterUpdateScript<Update_7_48_ProductInstances>();
         DataUpdater.RegisterUpdateScript<Update_7_48_RequisitionActualQuantity>();
-        DataUpdater.RegisterUpdateScript<Update_7_52>();
+        //DataUpdater.RegisterUpdateScript<Update_7_52>();
         DataUpdater.RegisterUpdateScript<Update_7_54>();
         DataUpdater.RegisterUpdateScript<Update_7_55>();
         DataUpdater.RegisterUpdateScript<Update_7_56>();

+ 160 - 160
prs.shared/Database Update Scripts/Update_7_52.cs

@@ -1,160 +1,160 @@
-using Comal.Classes;
-using Comal.Stores;
-using InABox.Core;
-using InABox.Database;
-using PRS.Shared.Database_Update_Scripts.Utils;
-using PRSStores;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using static ICSharpCode.AvalonEdit.Document.TextDocumentWeakEventManager;
-
-namespace PRS.Shared;
-
-public class Update_7_52 : DatabaseUpdateScript
-{
-    
-    private Type jripoiType = null;
-    
-    public Update_7_52()
-    {
-        jripoiType = CoreUtils.GetEntity("Comal.Classes.JobRequisitionItemPurchaseOrderItem");
-    } 
-
-    
-    public override VersionNumber Version => new VersionNumber(7, 52);
-
-    private IStore<JobRequisitionItem>? _store;
-
-    private IStore<JobRequisitionItem> Store
-    {
-        get
-        {
-            _store ??= DbFactory.FindStore<JobRequisitionItem>(Guid.Empty, "", Platform.Server, CoreUtils.GetVersion(), Logger.New());
-            return _store;
-        }
-    }
-
-    private void UpdateStockMovements()
-    {
-        var jobRequiItems = DbFactory.NewProvider(Logger.Main).Query(
-            new Filter<JobRequisitionItem>(x => x.PurchaseOrderItem.ID).IsNotEqualTo(null),
-            Columns.None<JobRequisitionItem>().Add(x => x.ID)
-                .Add(x => x.PurchaseOrderItem.ID))
-            .ToObjects<JobRequisitionItem>()
-            .ToList();
-
-        var _poiIDs = DbFactory.NewProvider(Logger.Main).GetTable(jripoiType).ExtractValues<Guid>("PurchaseOrderItem.ID").Distinct().ToArray();
-        
-        var mvts = DbFactory.NewProvider(Logger.Main).Query(
-            new Filter<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(null)
-                .And(x => x.OrderItem.ID).IsNotEqualTo(null)
-                .And(new Filter<StockMovement>(x => x.OrderItem.ID).InList(_poiIDs) //<JobRequisitionItemPurchaseOrderItem>(null, x => x.PurchaseOrderItem.ID)
-                    .Or(x => x.OrderItem.ID).InQuery<JobRequisitionItem>(null, x => x.PurchaseOrderItem.ID)),
-            Columns.None<StockMovement>().Add(x => x.ID)
-                .Add(x => x.OrderItem.ID))
-            .ToObjects<StockMovement>()
-            .ToList();
-
-        Logger.Send(LogType.Information, "", $"Updating JobRequisitionItem.ID for {mvts.Count} StockMovements");
-
-        var orderItemIDs = mvts.Select(x => x.OrderItem.ID).ToArray();
-
-        var jriPois = DbFactory.NewProvider(Logger.Main).Query(
-            jripoiType, Filter.Create(jripoiType,"PurchaseOrderItem.ID",Operator.InList, orderItemIDs),
-            Columns.None(jripoiType).Add("JobRequisitionItem.ID").Add("PurchaseOrderItem.ID")
-        );
-
-        var _jris = DbFactory.NewProvider(Logger.Main).Query(
-            new Filter<JobRequisitionItem>(x => x.PurchaseOrderItem.ID).InList(orderItemIDs),
-            Columns.None<JobRequisitionItem>().Add(x => x.ID).Add(x => x.PurchaseOrderItem.ID))
-            .ToObjects<JobRequisitionItem>();
-
-        var requiIDs = new Dictionary<Guid, Guid>();
-        foreach(var _row in jriPois.Rows)
-        {
-            requiIDs.TryAdd(_row.Get<Guid>("PurchaseOrderItem.ID"), _row.Get<Guid>("JobRequisitionItem.ID"));
-        }
-        foreach (var _jri in _jris)
-        {
-            requiIDs.TryAdd(_jri.PurchaseOrderItem.ID, _jri.ID);
-        }
-
-        foreach(var mvt in mvts)
-        {
-            if(requiIDs.TryGetValue(mvt.OrderItem.ID, out var requiItemID))
-            {
-                mvt.JobRequisitionItem.ID = requiItemID;
-            }
-            else
-            {
-                Logger.Send(LogType.Error, "", $"StockMovement which didn't have an associated JobRequisitionItem: {mvt.ID}");
-            }
-        }
-
-        var changed = mvts.Where(x => x.IsChanged()).ToList();
-
-        // Not going through the store otherwise the JobRequisitionItem Status will be updated incorrectly.
-        DbFactory.NewProvider(Logger.Main).Save(changed);
-
-        Logger.Send(LogType.Information, "", $"Updated {changed.Count} StockMovements");
-    }
-
-    private void UpdateOrderStatus()
-    {
-        var jobRequiItems = DbFactory.NewProvider(Logger.Main).Query(
-            new Filter<JobRequisitionItem>(x => x.OrderRequired).IsEqualTo(DateTime.MinValue)
-                .And(new Filter<JobRequisitionItem>(x => x.Status).IsEqualTo(JobRequisitionItemStatus.OrderRequired)
-                    .Or(x => x.Status).IsEqualTo(JobRequisitionItemStatus.OnOrder)
-                    .Or(x => x.Status).IsEqualTo(JobRequisitionItemStatus.Received)),
-            Columns.None<JobRequisitionItem>().Add(x => x.ID)
-                .Add(x => x.LastUpdate))
-            .ToObjects<JobRequisitionItem>()
-            .ToList();
-
-        foreach (var jri in jobRequiItems)
-        {
-            jri.OrderRequired = jri.LastUpdate;
-        }
-
-        DbFactory.NewProvider(Logger.Main).Save(jobRequiItems);
-    }
-
-    private void CreateJobRequisitionItemPurchaseOrderItems()
-    {
-        
-        var _poiIDs = DbFactory.NewProvider(Logger.Main).GetTable(jripoiType).ExtractValues<Guid>("PurchaseOrderItem.ID").Distinct().ToArray();
-
-        var jobRequiItems = DbFactory.NewProvider(Logger.Main).Query(
-            new Filter<JobRequisitionItem>(x => x.PurchaseOrderItem.ID).IsNotEqualTo(null)
-                .And(x => x.ID).NotInList(_poiIDs),
-            Columns.None<JobRequisitionItem>().Add(x => x.ID)
-                .Add(x => x.PurchaseOrderItem.ID)
-                .Add(x => x.Status))
-            .ToObjects<JobRequisitionItem>()
-            .ToList();
-        Logger.Send(LogType.Information, "", $"Creating JobRequisitionPurchaseOrderItems for {jobRequiItems.Count} JobRequisitionItems");
-
-        var newJRIPois = new List<Entity>();
-        foreach (var jri in jobRequiItems)
-        {
-            var jriPoi = Activator.CreateInstance(jripoiType) as Entity;
-            CoreUtils.SetPropertyValue(jriPoi,"JobRequisitionItem.ID",jri.ID);
-            CoreUtils.SetPropertyValue(jriPoi,"PurchaseOrderItem.ID",jri.PurchaseOrderItem.ID);
-            newJRIPois.Add(jriPoi);
-        }
-        DbFactory.NewProvider(Logger.Main).Save(jripoiType,newJRIPois);
-        DbFactory.NewProvider(Logger.Main).Save(jobRequiItems);
-    }
-
-    public override bool Update()
-    {
-        UpdateStockMovements();
-        UpdateOrderStatus();
-        CreateJobRequisitionItemPurchaseOrderItems();
-        //JobRequisitionItemUtils.RefreshStatuses(Store);
-
-        return true;
-    }
-}
+//using Comal.Classes;
+//using Comal.Stores;
+//using InABox.Core;
+//using InABox.Database;
+//using PRS.Shared.Database_Update_Scripts.Utils;
+//using PRSStores;
+//using System.Collections.Generic;
+//using System.Linq;
+//using System.Text;
+//using System.Threading.Tasks;
+//using static ICSharpCode.AvalonEdit.Document.TextDocumentWeakEventManager;
+//
+//namespace PRS.Shared;
+//
+//public class Update_7_52 : DatabaseUpdateScript
+//{
+//    
+//    private Type jripoiType = null;
+//    
+//    public Update_7_52()
+//    {
+//        jripoiType = CoreUtils.GetEntity("Comal.Classes.JobRequisitionItemPurchaseOrderItem");
+//    } 
+//
+//    
+//    public override VersionNumber Version => new VersionNumber(7, 52);
+//
+//    private IStore<JobRequisitionItem>? _store;
+//
+//    private IStore<JobRequisitionItem> Store
+//    {
+//        get
+//        {
+//            _store ??= DbFactory.FindStore<JobRequisitionItem>(Guid.Empty, "", Platform.Server, CoreUtils.GetVersion(), Logger.New());
+//            return _store;
+//        }
+//    }
+//
+//    private void UpdateStockMovements()
+//    {
+//        var jobRequiItems = DbFactory.NewProvider(Logger.Main).Query(
+//            new Filter<JobRequisitionItem>(x => x.PurchaseOrderItem.ID).IsNotEqualTo(null),
+//            Columns.None<JobRequisitionItem>().Add(x => x.ID)
+//                .Add(x => x.PurchaseOrderItem.ID))
+//            .ToObjects<JobRequisitionItem>()
+//            .ToList();
+//
+//        var _poiIDs = DbFactory.NewProvider(Logger.Main).GetTable(jripoiType).ExtractValues<Guid>("PurchaseOrderItem.ID").Distinct().ToArray();
+//        
+//        var mvts = DbFactory.NewProvider(Logger.Main).Query(
+//            new Filter<StockMovement>(x => x.JobRequisitionItem.ID).IsEqualTo(null)
+//                .And(x => x.OrderItem.ID).IsNotEqualTo(null)
+//                .And(new Filter<StockMovement>(x => x.OrderItem.ID).InList(_poiIDs) //<JobRequisitionItemPurchaseOrderItem>(null, x => x.PurchaseOrderItem.ID)
+//                    .Or(x => x.OrderItem.ID).InQuery<JobRequisitionItem>(null, x => x.PurchaseOrderItem.ID)),
+//            Columns.None<StockMovement>().Add(x => x.ID)
+//                .Add(x => x.OrderItem.ID))
+//            .ToObjects<StockMovement>()
+//            .ToList();
+//
+//        Logger.Send(LogType.Information, "", $"Updating JobRequisitionItem.ID for {mvts.Count} StockMovements");
+//
+//        var orderItemIDs = mvts.Select(x => x.OrderItem.ID).ToArray();
+//
+//        var jriPois = DbFactory.NewProvider(Logger.Main).Query(
+//            jripoiType, Filter.Create(jripoiType,"PurchaseOrderItem.ID",Operator.InList, orderItemIDs),
+//            Columns.None(jripoiType).Add("JobRequisitionItem.ID").Add("PurchaseOrderItem.ID")
+//        );
+//
+//        var _jris = DbFactory.NewProvider(Logger.Main).Query(
+//            new Filter<JobRequisitionItem>(x => x.PurchaseOrderItem.ID).InList(orderItemIDs),
+//            Columns.None<JobRequisitionItem>().Add(x => x.ID).Add(x => x.PurchaseOrderItem.ID))
+//            .ToObjects<JobRequisitionItem>();
+//
+//        var requiIDs = new Dictionary<Guid, Guid>();
+//        foreach(var _row in jriPois.Rows)
+//        {
+//            requiIDs.TryAdd(_row.Get<Guid>("PurchaseOrderItem.ID"), _row.Get<Guid>("JobRequisitionItem.ID"));
+//        }
+//        foreach (var _jri in _jris)
+//        {
+//            requiIDs.TryAdd(_jri.PurchaseOrderItem.ID, _jri.ID);
+//        }
+//
+//        foreach(var mvt in mvts)
+//        {
+//            if(requiIDs.TryGetValue(mvt.OrderItem.ID, out var requiItemID))
+//            {
+//                mvt.JobRequisitionItem.ID = requiItemID;
+//            }
+//            else
+//            {
+//                Logger.Send(LogType.Error, "", $"StockMovement which didn't have an associated JobRequisitionItem: {mvt.ID}");
+//            }
+//        }
+//
+//        var changed = mvts.Where(x => x.IsChanged()).ToList();
+//
+//        // Not going through the store otherwise the JobRequisitionItem Status will be updated incorrectly.
+//        DbFactory.NewProvider(Logger.Main).Save(changed);
+//
+//        Logger.Send(LogType.Information, "", $"Updated {changed.Count} StockMovements");
+//    }
+//
+//    private void UpdateOrderStatus()
+//    {
+//        var jobRequiItems = DbFactory.NewProvider(Logger.Main).Query(
+//            new Filter<JobRequisitionItem>(x => x.OrderRequired).IsEqualTo(DateTime.MinValue)
+//                .And(new Filter<JobRequisitionItem>(x => x.Status).IsEqualTo(JobRequisitionItemStatus.OrderRequired)
+//                    .Or(x => x.Status).IsEqualTo(JobRequisitionItemStatus.OnOrder)
+//                    .Or(x => x.Status).IsEqualTo(JobRequisitionItemStatus.Received)),
+//            Columns.None<JobRequisitionItem>().Add(x => x.ID)
+//                .Add(x => x.LastUpdate))
+//            .ToObjects<JobRequisitionItem>()
+//            .ToList();
+//
+//        foreach (var jri in jobRequiItems)
+//        {
+//            jri.OrderRequired = jri.LastUpdate;
+//        }
+//
+//        DbFactory.NewProvider(Logger.Main).Save(jobRequiItems);
+//    }
+//
+//    private void CreateJobRequisitionItemPurchaseOrderItems()
+//    {
+//        
+//        var _poiIDs = DbFactory.NewProvider(Logger.Main).GetTable(jripoiType).ExtractValues<Guid>("PurchaseOrderItem.ID").Distinct().ToArray();
+//
+//        var jobRequiItems = DbFactory.NewProvider(Logger.Main).Query(
+//            new Filter<JobRequisitionItem>(x => x.PurchaseOrderItem.ID).IsNotEqualTo(null)
+//                .And(x => x.ID).NotInList(_poiIDs),
+//            Columns.None<JobRequisitionItem>().Add(x => x.ID)
+//                .Add(x => x.PurchaseOrderItem.ID)
+//                .Add(x => x.Status))
+//            .ToObjects<JobRequisitionItem>()
+//            .ToList();
+//        Logger.Send(LogType.Information, "", $"Creating JobRequisitionPurchaseOrderItems for {jobRequiItems.Count} JobRequisitionItems");
+//
+//        var newJRIPois = new List<Entity>();
+//        foreach (var jri in jobRequiItems)
+//        {
+//            var jriPoi = Activator.CreateInstance(jripoiType) as Entity;
+//            CoreUtils.SetPropertyValue(jriPoi,"JobRequisitionItem.ID",jri.ID);
+//            CoreUtils.SetPropertyValue(jriPoi,"PurchaseOrderItem.ID",jri.PurchaseOrderItem.ID);
+//            newJRIPois.Add(jriPoi);
+//        }
+//        DbFactory.NewProvider(Logger.Main).Save(jripoiType,newJRIPois);
+//        DbFactory.NewProvider(Logger.Main).Save(jobRequiItems);
+//    }
+//
+//    public override bool Update()
+//    {
+//        UpdateStockMovements();
+//        UpdateOrderStatus();
+//        CreateJobRequisitionItemPurchaseOrderItems();
+//        //JobRequisitionItemUtils.RefreshStatuses(Store);
+//
+//        return true;
+//    }
+//}

+ 44 - 41
prs.stores/PurchaseOrderItemStore.cs

@@ -209,46 +209,6 @@ internal class PurchaseOrderItemStore : BaseStore<PurchaseOrderItem>
         
         TransformDimensions(entity);
 
-        if (entity.Job.ID == Guid.Empty)
-        {
-            var instance = instancerow?.ToObject<ProductInstance>();
-            if (instance == null)
-            {
-                instance = new ProductInstance();
-                instance.Product.ID = entity.Product.ID;
-                instance.Style.ID = entity.Style.ID;
-                instance.Dimensions.CopyFrom(entity.Dimensions);
-            }
-
-            instance.LastCost = entity.Cost;
-
-            var freeqty = instance.FreeStock;
-            var freeavg = instance.AverageCost;
-            var freecost = instance.FreeStock * freeavg;
-
-            var poqty = entity.Qty * (Math.Abs(entity.Dimensions.Value) > 0.0001F ? entity.Dimensions.Value : 1.0F);
-            var pocost = entity.Cost * poqty;
-            
-            if (!consigntask.Result.IsEffectivelyEqual(0.0) && !entity.Qty.IsEffectivelyEqual(0.0))
-                pocost += entity.Qty * entity.Cost * entity.Consignment.ExTax / consigntask.Result;
-            
-            var totalqty = freeqty + poqty;
-            var totalcost = freecost + pocost;
-
-            var averagecost = Math.Abs(totalqty) > 0.0001F
-                ? totalcost / totalqty
-                : pocost;
-
-            if (Math.Abs(averagecost - freeavg) > 0.0001F)
-            {
-                instance.AverageCost = averagecost;
-                FindSubStore<ProductInstance>().Save(instance,
-                    $"Updated Average Cost: " +
-                    $"({freeqty} @ {freeavg:C2}) + ({poqty} @ {entity.Cost:C2}) = {totalcost:C2} / {totalqty}"
-                );
-            }
-        }
-
         // Actual logic begins here.
 
         var batch = new StockMovementBatch
@@ -285,10 +245,11 @@ internal class PurchaseOrderItemStore : BaseStore<PurchaseOrderItem>
         }
 
         var totalAllocations = allocations.Sum(x => x.Quantity);
+        var freeQty = entity.Qty - totalAllocations;
         
         // If there is any left over (ie over/under-ordered), now we can create
         // a second transaction to receive the unallocated stock
-        CreateMovement(entity, locationid, movements, null, null, entity.Qty - totalAllocations, poCost);
+        CreateMovement(entity, locationid, movements, null, null, freeQty, poCost);
 
         FindSubStore<StockMovementBatch>().Save(batch, "Received on PO");
         foreach(var mvt in movements)
@@ -297,6 +258,48 @@ internal class PurchaseOrderItemStore : BaseStore<PurchaseOrderItem>
         }
         
         FindSubStore<StockMovement>().Save(movements, "Updated by Purchase Order Modification");
+
+        // Update the AverageCost on the instance
+        if (!freeQty.IsEffectivelyEqual(0.0))
+        {
+            var instance = instancerow?.ToObject<ProductInstance>();
+            if (instance == null)
+            {
+                instance = new ProductInstance();
+                instance.Product.ID = entity.Product.ID;
+                instance.Style.ID = entity.Style.ID;
+                instance.Dimensions.CopyFrom(entity.Dimensions);
+            }
+
+            instance.LastCost = entity.Cost;
+
+            var freeqty = instance.FreeStock;
+            var freeavg = instance.AverageCost;
+            var freecost = instance.FreeStock * freeavg;
+
+            var poqty = freeQty * (Math.Abs(entity.Dimensions.Value) > 0.0001F ? entity.Dimensions.Value : 1.0F);
+            var pocost = entity.Cost * poqty;
+            
+            if (!consigntask.Result.IsEffectivelyEqual(0.0))
+                pocost += freeQty * entity.Cost * entity.Consignment.ExTax / consigntask.Result;
+            
+            var totalqty = freeqty + poqty;
+            var totalcost = freecost + pocost;
+
+            var averagecost = Math.Abs(totalqty) > 0.0001F
+                ? totalcost / totalqty
+                : pocost;
+
+            if (Math.Abs(averagecost - freeavg) > 0.0001F)
+            {
+                instance.AverageCost = averagecost;
+                FindSubStore<ProductInstance>().Save(instance,
+                    $"Updated Average Cost: " +
+                    $"({freeqty} @ {freeavg:C2}) + ({poqty} @ {entity.Cost:C2}) = {totalcost:C2} / {totalqty}"
+                );
+            }
+        }
+
         entity.CancelChanges();
     }