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 JobMaterialBOMAggregate : 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, JobMaterial => JobMaterial.Job.ID }, { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Product.ID, JobMaterial => JobMaterial.Product.ID }, { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Style.ID, JobMaterial => JobMaterial.Style.ID }, { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Dimensions.UnitSize, JobMaterial => JobMaterial.Dimensions.UnitSize } }; public override Filter Filter => new Filter(x => x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue); } public class JobMaterialTotalRequiredAggregate : CoreAggregate { public override Expression> Aggregate => x => x.Qty; public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { JobMaterialRequisitionItem => JobMaterialRequisitionItem.Requisition.Job.ID, JobMaterial => JobMaterial.Job.ID }, { JobMaterialRequisitionItem => JobMaterialRequisitionItem.Product.ID, JobMaterial => JobMaterial.Product.ID }, { JobMaterialRequisitionItem => JobMaterialRequisitionItem.Style.ID, JobMaterial => JobMaterial.Style.ID }, { JobMaterialRequisitionItem => JobMaterialRequisitionItem.Dimensions.UnitSize, JobMaterial => JobMaterial.Dimensions.UnitSize } }; public override Filter Filter => new Filter(x => x.Requisition.Approved).IsNotEqualTo(DateTime.MinValue); } public class JobMaterialOrderAggregate : 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, JobMaterial => JobMaterial.Job.ID }, { PurchaseOrderItem => PurchaseOrderItem.Product.ID, JobMaterial => JobMaterial.Product.ID }, { PurchaseOrderItem => PurchaseOrderItem.Style.ID, JobMaterial => JobMaterial.Style.ID }, { PurchaseOrderItem => PurchaseOrderItem.Dimensions.UnitSize, JobMaterial => JobMaterial.Dimensions.UnitSize } }; public override Filter Filter => new Filter(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue); } public class JobMaterialOrderValue : CoreAggregate { public override Expression> Aggregate => x => x.ExTax; public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { PurchaseOrderItem => PurchaseOrderItem.Job.ID, JobMaterial => JobMaterial.Job.ID }, { PurchaseOrderItem => PurchaseOrderItem.Product.ID, JobMaterial => JobMaterial.Product.ID }, { PurchaseOrderItem => PurchaseOrderItem.Style.ID, JobMaterial => JobMaterial.Style.ID }, { PurchaseOrderItem => PurchaseOrderItem.Dimensions.UnitSize, JobMaterial => JobMaterial.Dimensions.UnitSize } }; public override Filter Filter => new Filter(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue); } public class JobMaterialReceivedAggregate : CoreAggregate { public override Expression> Aggregate => x => x.Received; 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, JobMaterial => JobMaterial.Job.ID }, { StockMovement => StockMovement.Product.ID, JobMaterial => JobMaterial.Product.ID }, { StockMovement => StockMovement.Style.ID, JobMaterial => JobMaterial.Style.ID }, { StockMovement => StockMovement.Dimensions.UnitSize, JobMaterial => JobMaterial.Dimensions.UnitSize } }; } public class JobMaterialIssuedAggregate : 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, JobMaterial => JobMaterial.Job.ID }, { StockMovement => StockMovement.Product.ID, JobMaterial => JobMaterial.Product.ID }, { StockMovement => StockMovement.Style.ID, JobMaterial => JobMaterial.Style.ID }, { StockMovement => StockMovement.Dimensions.UnitSize, JobMaterial => JobMaterial.Dimensions.UnitSize } }; } public class JobMaterialBalanceRequiredFormula : 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 JobMaterialReservedStockAggregate : 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, JobMaterial => JobMaterial.Job.ID }, { StockMovement => StockMovement.Product.ID, JobMaterial => JobMaterial.Product.ID }, { StockMovement => StockMovement.Style.ID, JobMaterial => JobMaterial.Style.ID }, { StockMovement => StockMovement.Dimensions.UnitSize, JobMaterial => JobMaterial.Dimensions.UnitSize } }; } public class JobMaterialFreeStockAggregate : CoreAggregate { public override Expression> Aggregate => x => x.Units; public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Filter Filter => new Filter(x => x.Job).NotLinkValid().Or(x=>x.Job.JobStatus.Active).IsEqualTo(false); public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { StockMovement => StockMovement.Product.ID, JobMaterial => JobMaterial.Product.ID }, //{ StockMovement => StockMovement.Style.ID, JobMaterial => JobMaterial.Style.ID }, //{ StockMovement => StockMovement.Dimensions.UnitSize, JobMaterial => JobMaterial.Dimensions.UnitSize } }; } public class JobMaterialUnionGenerator : 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) }; } [UserTracking(typeof(Job))] [AutoEntity(typeof(JobMaterialUnionGenerator))] public class JobMaterial : DimensionedEntity, IJobMaterial, IRemotable, IPersistent, IManyToMany, ILicense/* , IDimensioned */ { [NullEditor] public JobLink Job { get; set; } [EditorSequence(1)] public ProductLink Product { get; set; } [EditorSequence(2)] public ProductStyleLink Style { get; set; } [NullEditor] [Obsolete("Replaced with Dimensions", true)] public double UnitSize { get; set; } [EditorSequence(3)] [RequiredColumn] public override StockDimensions Dimensions { get; set; } [EditorSequence(4)] [DoubleEditor] [Aggregate(typeof(JobMaterialBOMAggregate))] public double BillOfMaterials { get; set; } [EditorSequence(5)] [DoubleEditor] [Aggregate(typeof(JobMaterialTotalRequiredAggregate))] public double TotalRequired { get; set; } [EditorSequence(6)] [DoubleEditor] [Aggregate(typeof(JobMaterialOrderAggregate))] public double OnOrder { get; set; } [EditorSequence(7)] [DoubleEditor] [Aggregate(typeof(JobMaterialOrderValue))] public double OrderValue { get; set; } [EditorSequence(8)] [Aggregate(typeof(JobMaterialReceivedAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double Received { get; set; } [EditorSequence(9)] [Aggregate(typeof(JobMaterialIssuedAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double Issued { get; set; } [EditorSequence(10)] [DoubleEditor] [Formula(typeof(JobMaterialBalanceRequiredFormula))] public double BalanceRequired { get; set; } [EditorSequence(11)] [Aggregate(typeof(JobMaterialReservedStockAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double ReservedStock { get; set; } [EditorSequence(12)] [Aggregate(typeof(JobMaterialFreeStockAggregate))] [DoubleEditor(Editable = Editable.Hidden)] public double FreeStock { get; set; } protected override void Init() { base.Init(); Job = new JobLink(); Product = new ProductLink(); Style = new ProductStyleLink(); Dimensions = new StockDimensions(); } private static Column dimensions = new Column(x => x.Product.Dimensions); private bool bChanging; protected override void DoPropertyChanged(string name, object before, object after) { if (bChanging) return; if (dimensions.IsParentOf(name)) { bChanging = true; String col = String.Join(".", name.Split('.').Skip(1)); CoreUtils.SetPropertyValue(this, col, after); bChanging = false; } else base.DoPropertyChanged(name, before, after); } } }