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 }, }.AddRange(Dimensions.GetLinks()); public override Filter Filter => new Filter(x => x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue); } public class StockSummaryMinimumStockAggregate : CoreAggregate { public override Expression> Aggregate => x => x.MinimumStockLevel; public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Product.ID, summary => summary.Product.ID }, { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Style.ID, summary => summary.Style.ID }, }.AddRange(Dimensions.GetLinks()); } public class StockSummaryIssuedAggregate : CoreAggregate { public override Expression> Aggregate => x => x.Issued; public override Filter Filter => new Filter(x => x.Type).IsEqualTo(StockMovementType.Issue) .And(x => x.Job.ID).IsNotEqualTo(Guid.Empty); 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 }, }.AddRange(Dimensions.GetLinks()); } public class StockSummaryTotalRequiredFormula : IFormula { public Expression> Value => x => x.BillOfMaterials; public Expression>[] Modifiers => new Expression>[] { x => x.Issued }; public FormulaOperator Operator => FormulaOperator.Subtract; public FormulaType Type => FormulaType.Virtual; } public class StockSummaryNettRequiredFormula : IFormula { public Expression> Value => x => x.TotalRequired; public Expression>[] Modifiers => new Expression>[] { x => 0.0 }; public FormulaOperator Operator => FormulaOperator.Maximum; 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.Product.ID, summary => summary.Product.ID }, { StockMovement => StockMovement.Style.ID, summary => summary.Style.ID }, }.AddRange(Dimensions.GetLinks()); } 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.Product.ID, summary => summary.Product.ID }, { PurchaseOrderItem => PurchaseOrderItem.Style.ID, summary => summary.Style.ID }, }.AddRange(Dimensions.GetLinks()); public override Filter Filter => new Filter(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue); } public class StockSummaryTotalStockFormula : IFormula { public Expression> Value => x => x.AllStock; public Expression>[] Modifiers => new Expression>[] { 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.MinimumStockLevel, x => x.NettRequired }; public FormulaOperator Operator => FormulaOperator.Subtract; public FormulaType Type => FormulaType.Virtual; } public class StockSummaryUnionGenerator : AutoEntityUnionGenerator { protected override void Configure() { // AddTable() .AddConstant(x => x.Job.ID, null); // BOM AddTable(new Filter(x => x.Job.ID).IsNotEqualTo(Guid.Empty)); // Stock Issues AddTable(new Filter(x => x.Job.ID).IsNotEqualTo(Guid.Empty).And(x=>x.Type).IsEqualTo(StockMovementType.Issue)); // Stock Holdings AddTable(); // On Order AddTable(new Filter(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue)); } 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 class StockSummaryCalculatedField : IFormula { public Expression> Value => x => 0.0; public Expression>[] Modifiers => new Expression>[] { }; public FormulaOperator Operator => FormulaOperator.Constant; public FormulaType Type => FormulaType.Virtual; } public class StockSummaryCalculatedStringField : IFormula { public Expression> Value => x => ""; public Expression>[] Modifiers => new Expression>[] { }; public FormulaOperator Operator => FormulaOperator.Constant; public FormulaType Type => FormulaType.Virtual; } [UserTracking(typeof(Product))] [AutoEntity(typeof(StockSummaryUnionGenerator))] public class StockSummary : StockEntity, IJobMaterial, IRemotable, IPersistent, ILicense { [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))] public override StockDimensions Dimensions { get; set; } [EditorSequence(4)] [DoubleEditor] [Aggregate(typeof(StockSummaryBOMAggregate))] public double BillOfMaterials { get; set; } [EditorSequence(5)] [IntegerEditor] [Aggregate(typeof(StockSummaryMinimumStockAggregate))] public int MinimumStockLevel { get; set; } [EditorSequence(6)] [Aggregate(typeof(StockSummaryIssuedAggregate))] [DoubleEditor] public double Issued { get; set; } [EditorSequence(7)] [Formula(typeof(StockSummaryTotalRequiredFormula))] public double TotalRequired { get; set; } [EditorSequence(8)] [Formula(typeof(StockSummaryNettRequiredFormula))] public double NettRequired { get; set; } [EditorSequence(9)] [Aggregate(typeof(StockSummaryAllStockAggregate))] [DoubleEditor] public double AllStock { get; set; } [EditorSequence(10)] [DoubleEditor] [Aggregate(typeof(StockSummaryOrderAggregate))] public double OnOrder { get; set; } [EditorSequence(11)] [Formula(typeof(StockSummaryTotalStockFormula))] [DoubleEditor] public double TotalStock { get; set; } [EditorSequence(12)] [DoubleEditor] [Formula(typeof(StockSummaryCalculatedField))] public double BalanceAvailable { get; set; } //[EditorSequence(13)] //[DoubleEditor] //[Formula(typeof(StockSummaryCalculatedField))] //public double JobBOM { get; set; } [EditorSequence(14)] [NullEditor] [Formula(typeof(StockSummaryCalculatedStringField))] public string Issues { get; set; } } }