using Comal.Classes; using InABox.Core; using InABox.Database; using System.Linq; using System; using MathNet.Numerics; namespace Comal.Stores; // using HoldingDictionary = Dictionary<(Guid product, Guid style, Guid location, Guid job, StockDimensions dimensions), StockHolding>; public class StockHoldingStore : BaseStore { // public enum Action // { // Increase, // Decrease // } // // public static StockMovement[] LoadMovementData(IStore store, Guid[] ids) // { // return store.Provider.Query( // new Filter(x => x.ID).InList(ids), // Columns.None().Add(x => x.ID) // .Add(x => x.Location.ID) // .Add(x => x.Product.ID) // .Add(x => x.Style.ID) // .Add(x => x.Job.ID) // .Add(x => x.Dimensions.Unit.ID) // .Add(x => x.Dimensions.Quantity) // .Add(x => x.Dimensions.Height) // .Add(x => x.Dimensions.Width) // .Add(x => x.Dimensions.Length) // .Add(x => x.Dimensions.Weight) // .Add(x => x.Dimensions.UnitSize) // .Add(x => x.Dimensions.Value) // .Add(x => x.JobRequisitionItem.ID) // .Add(x => x.Units) // .Add(x => x.Cost) // ).ToArray(); // } // // public static HoldingDictionary LoadStockHoldings(IStore store, StockMovement[] mvts, HoldingDictionary? holdings = null) // { // return StockHoldingExtensions.LoadStockHoldings( // mvts, // Columns.None() // .Add(x => x.Units) // .Add(x => x.Qty) // .Add(x => x.Value) // .Add(x => x.Available) // .Add(x => x.Weight) // .Add(x => x.AverageValue), // holdings, store.QueryProvider()); // } // public static void ModifyHoldings(StockMovement[] mvts, HoldingDictionary holdings, Action action) // { // foreach(var mvt in mvts) // { // var key = (mvt.Product.ID, mvt.Style.ID, mvt.Location.ID, mvt.Job.ID, mvt.Dimensions); // if(!holdings.TryGetValue(key, out var holding)) // { // holding = new(); // holding.Location.ID = mvt.Location.ID; // holding.Product.ID = mvt.Product.ID; // holding.Style.ID = mvt.Style.ID; // holding.Job.ID = mvt.Job.ID; // holding.Dimensions.CopyFrom(mvt.Dimensions); // holdings[key] = holding; // } // // var multiplier = action == Action.Increase ? 1F : -1F; // holding.Units += (multiplier * mvt.Units); // holding.Qty += (multiplier * mvt.Units * mvt.Dimensions.Value); // holding.Value += (multiplier * mvt.Units * mvt.Cost); // holding.Available += (multiplier * (mvt.JobRequisitionItem.ID == Guid.Empty ? mvt.Units : 0.0)); // // holding.Weight = holding.Qty * holding.Dimensions.Weight; // holding.AverageValue = holding.Units != 0 ? holding.Value / holding.Units : 0.0F; // } // } // public static void SaveHoldings(IStore store, HoldingDictionary holdings) // { // var holdingStore = store.FindSubStore(); // holdingStore.Delete( // holdings.Values.Where(x => x.ID != Guid.Empty && x.Units.IsEffectivelyEqual(0.0) && x.Available.IsEffectivelyEqual(0.0)), ""); // holdingStore.Save( // holdings.Values.Where(x => x.IsChanged() && (!x.Units.IsEffectivelyEqual(0.0) || !x.Available.IsEffectivelyEqual(0.0))), ""); // } // // public static void UpdateStockHoldings(IStore store, Guid[] ids, Action action) // { // var movements = LoadMovementData(store, ids); // var holdings = LoadStockHoldings(store, movements); // ModifyHoldings(movements, holdings, action); // SaveHoldings(store, holdings); // } // /// // /// Maintains the Stock Holding Table when manipulating Stock Movements // /// We only accept an ID, because the rest of the movement is pulled from the database // /// (slower, but more reliable) // /// // /// The id of the Stock Movement to query // /// The action to perform (increase / decrease) // public static void UpdateStockHolding(IStore store, Guid id, Action action) // { // var movement = store.Provider.Query( // new Filter(x => x.ID).IsEqualTo(id), // Columns.None().Add(x => x.ID) // .Add(x => x.Location.ID) // .Add(x => x.Product.ID) // .Add(x => x.Style.ID) // .Add(x => x.Job.ID) // .Add(x => x.Dimensions.Unit.ID) // .Add(x => x.Dimensions.Quantity) // .Add(x => x.Dimensions.Height) // .Add(x => x.Dimensions.Width) // .Add(x => x.Dimensions.Length) // .Add(x => x.Dimensions.Weight) // .Add(x => x.Dimensions.UnitSize) // .Add(x => x.Dimensions.Value) // .Add(x => x.JobRequisitionItem.ID) // .Add(x => x.Units) // .Add(x => x.Cost) // ).Rows // .FirstOrDefault()? // .ToObject(); // if (movement == null) // return; // // var holding = store.Provider.Query(new Filter(x => x.Product.ID).IsEqualTo(movement.Product.ID) // .And(x => x.Location.ID).IsEqualTo(movement.Location.ID) // .And(x => x.Style.ID).IsEqualTo(movement.Style.ID) // .And(x => x.Job.ID).IsEqualTo(movement.Job.ID) // .And(x => x.Dimensions).DimensionEquals(movement.Dimensions), // Columns.None().Add(x => x.ID) // .Add(x => x.Units) // .Add(x => x.Qty) // .Add(x => x.Value) // .Add(x => x.Available) // ).Rows // .FirstOrDefault()? // .ToObject(); // if (holding == null) // { // holding = new(); // holding.Location.ID = movement.Location.ID; // holding.Product.ID = movement.Product.ID; // holding.Style.ID = movement.Style.ID; // holding.Job.ID = movement.Job.ID; // holding.Dimensions.CopyFrom(movement.Dimensions); // } // // double multiplier = action == Action.Increase ? 1F : -1F; // holding.Units += (multiplier * movement.Units); // holding.Qty += (multiplier * movement.Units * movement.Dimensions.Value); // holding.Value += (multiplier * movement.Units * movement.Cost); // holding.Available += (multiplier * (movement.JobRequisitionItem.ID == Guid.Empty ? movement.Units : 0.0)); // // holding.Weight = holding.Qty * holding.Dimensions.Weight; // holding.AverageValue = holding.Units != 0 ? holding.Value / holding.Units : 0.0F; // // // Automagically clean up empty holdings // if (holding.Units.IsEffectivelyEqual(0.0) && holding.Available.IsEffectivelyEqual(0.0)) // { // if (holding.ID != Guid.Empty) // DbFactory.NewProvider(Logger.Main).Delete(holding, ""); // } // else // DbFactory.NewProvider(Logger.Main).Save(holding); // } }