using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Runtime.CompilerServices; using InABox.Core; namespace Comal.Classes { public class StockSummaryBOMAggregate : CoreAggregate { public override Expression> Aggregate => x => x.Quantity; public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Job.ID, summary => summary.Job.ID }, { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Product.ID, summary => summary.Product.ID }, { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Style.ID, summary => summary.Style.ID }, { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Dimensions.UnitSize, summary => summary.Dimensions.UnitSize } }; public override Filter Filter => new Filter(x => x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue); } public class StockSummaryIssuedAggregate : CoreAggregate { public override Expression> Aggregate => x => x.Issued; public override Filter Filter => new Filter(x => x.IsTransfer).IsEqualTo(false); public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { StockMovement => StockMovement.Job.ID, summary => summary.Job.ID }, { StockMovement => StockMovement.Product.ID, summary => summary.Product.ID }, { StockMovement => StockMovement.Style.ID, summary => summary.Style.ID }, { StockMovement => StockMovement.Dimensions.UnitSize, summary => summary.Dimensions.UnitSize } }; } public class StockSummaryTotalRequiredFormula : IFormula { public Expression> Value => x => x.Product.MinimumStockLevel; public Expression>[] Modifiers => new Expression>[] { x => x.BillOfMaterials }; public FormulaOperator Operator => FormulaOperator.Add; public FormulaType Type => FormulaType.Virtual; } public class StockSummaryNettRequiredFormula : IFormula { public Expression> Value => x => x.TotalRequired; public Expression>[] Modifiers => new Expression>[] { x => x.Issued }; public FormulaOperator Operator => FormulaOperator.Subtract; public FormulaType Type => FormulaType.Virtual; } public class StockSummaryAllStockAggregate : CoreAggregate { public override Expression> Aggregate => x => x.Units; public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { StockMovement => StockMovement.Job.ID, summary => summary.Job.ID }, { StockMovement => StockMovement.Product.ID, summary => summary.Product.ID }, { StockMovement => StockMovement.Style.ID, summary => summary.Style.ID }, { StockMovement => StockMovement.Dimensions.UnitSize, summary => summary.Dimensions.UnitSize } }; } public class StockSummaryOrderAggregate : CoreAggregate { public override Expression> Aggregate => x => x.Qty; public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { PurchaseOrderItem => PurchaseOrderItem.Job.ID, summary => summary.Job.ID }, { PurchaseOrderItem => PurchaseOrderItem.Product.ID, summary => summary.Product.ID }, { PurchaseOrderItem => PurchaseOrderItem.Style.ID, summary => summary.Style.ID }, { PurchaseOrderItem => PurchaseOrderItem.Dimensions.UnitSize, summary => summary.Dimensions.UnitSize } }; public override Filter Filter => new Filter(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue); } public class StockSummaryTotalStockFormula : IFormula { public Expression> Value => x => x.Issued; public Expression>[] Modifiers => new Expression>[] { x => x.AllStock, x => x.OnOrder }; public FormulaOperator Operator => FormulaOperator.Add; public FormulaType Type => FormulaType.Virtual; } public class StockSummaryBalanceAvailableFormula : IFormula { public Expression> Value => x => x.TotalStock; public Expression>[] Modifiers => new Expression>[] { x => x.TotalRequired }; public FormulaOperator Operator => FormulaOperator.Subtract; public FormulaType Type => FormulaType.Virtual; } public class StockSummaryUnionGenerator : AutoEntityUnionGenerator { protected override void Configure() { AddTable(); AddTable(); AddTable(); AddTable(); } public override bool Distinct => true; public override Column[] IDColumns => new Column[] { new Column(x => x.Job.ID), new Column(x => x.Product.ID), new Column(x => x.Style.ID), new Column(x => x.Dimensions.Unit.ID), new Column(x => x.Dimensions.Quantity), new Column(x => x.Dimensions.Length), new Column(x => x.Dimensions.Width), new Column(x => x.Dimensions.Height), new Column(x => x.Dimensions.Weight) }; } public interface IStockSummary { JobLink Job { get; set; } ProductLink Product { get; set; } ProductStyleLink Style { get; set; } StockDimensions Dimensions { get; set; } } [UserTracking(typeof(Product))] [AutoEntity(typeof(StockSummaryUnionGenerator))] public class StockSummary : StockEntity, IStockSummary, IRemotable, IPersistent { [NullEditor] public JobLink Job { get; set; } [EditorSequence(1)] public override ProductLink Product { get; set; } [EditorSequence(2)] public ProductStyleLink Style { get; set; } [EditorSequence(3)] [RequiredColumn] [DimensionsEditor(typeof(StockDimensions), AllowEditingUnit = false)] public override StockDimensions Dimensions { get; set; } [EditorSequence(4)] [DoubleEditor] [Aggregate(typeof(StockSummaryBOMAggregate))] public double BillOfMaterials { get; set; } [NullEditor] [Formula(typeof(StockSummaryTotalRequiredFormula))] public double TotalRequired { get; set; } [EditorSequence(5)] [Aggregate(typeof(StockSummaryIssuedAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double Issued { get; set; } [NullEditor] [Formula(typeof(StockSummaryNettRequiredFormula))] public double NettRequired { get; set; } [EditorSequence(6)] [Aggregate(typeof(StockSummaryAllStockAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double AllStock { get; set; } [EditorSequence(7)] [DoubleEditor] [Aggregate(typeof(StockSummaryOrderAggregate))] public double OnOrder { get; set; } [NullEditor] [Formula(typeof(StockSummaryTotalStockFormula))] public double TotalStock { get; set; } [EditorSequence(8)] [DoubleEditor] [Formula(typeof(StockSummaryBalanceAvailableFormula))] public double BalanceAvailable { get; set; } protected override void Init() { base.Init(); Job = new JobLink(); Style = new ProductStyleLink(); } } }