StockSummary.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using System.Runtime.CompilerServices;
  6. using InABox.Core;
  7. namespace Comal.Classes
  8. {
  9. public class StockSummaryBOMAggregate : CoreAggregate<StockSummary, JobBillOfMaterialsItem, double>
  10. {
  11. public override Expression<Func<JobBillOfMaterialsItem, double>> Aggregate => x => x.Quantity;
  12. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  13. public override Dictionary<Expression<Func<JobBillOfMaterialsItem, object?>>, Expression<Func<StockSummary, object?>>> Links =>
  14. new Dictionary<Expression<Func<JobBillOfMaterialsItem, object?>>, Expression<Func<StockSummary, object?>>>()
  15. {
  16. { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Job.ID, summary => summary.Job.ID },
  17. { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Product.ID, summary => summary.Product.ID },
  18. { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Style.ID, summary => summary.Style.ID },
  19. }.AddRange(Dimensions.GetLinks<JobBillOfMaterialsItem, StockSummary>());
  20. public override Filter<JobBillOfMaterialsItem> Filter =>
  21. new Filter<JobBillOfMaterialsItem>(x => x.BillOfMaterials.Approved).IsNotEqualTo(DateTime.MinValue);
  22. }
  23. public class StockSummaryMinimumStockAggregate : CoreAggregate<StockSummary, ProductInstance, int>
  24. {
  25. public override Expression<Func<ProductInstance, int>> Aggregate => x => x.MinimumStockLevel;
  26. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  27. public override Dictionary<Expression<Func<ProductInstance, object?>>, Expression<Func<StockSummary, object?>>> Links =>
  28. new Dictionary<Expression<Func<ProductInstance, object?>>, Expression<Func<StockSummary, object?>>>()
  29. {
  30. { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Product.ID, summary => summary.Product.ID },
  31. { JobBillOfMaterialsItem => JobBillOfMaterialsItem.Style.ID, summary => summary.Style.ID },
  32. }.AddRange(Dimensions.GetLinks<ProductInstance, StockSummary>());
  33. }
  34. public class StockSummaryIssuedAggregate : CoreAggregate<StockSummary, StockMovement, double>
  35. {
  36. public override Expression<Func<StockMovement, double>> Aggregate => x => x.Issued;
  37. public override Filter<StockMovement> Filter => new Filter<StockMovement>(x => x.Type).IsEqualTo(StockMovementType.Issue)
  38. .And(x => x.Job.ID).IsNotEqualTo(Guid.Empty);
  39. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  40. public override Dictionary<Expression<Func<StockMovement, object?>>, Expression<Func<StockSummary, object?>>> Links =>
  41. new Dictionary<Expression<Func<StockMovement, object?>>, Expression<Func<StockSummary, object?>>>()
  42. {
  43. { StockMovement => StockMovement.Job.ID, summary => summary.Job.ID },
  44. { StockMovement => StockMovement.Product.ID, summary => summary.Product.ID },
  45. { StockMovement => StockMovement.Style.ID, summary => summary.Style.ID },
  46. }.AddRange(Dimensions.GetLinks<StockMovement, StockSummary>());
  47. }
  48. public class StockSummaryTotalRequiredFormula : IFormula<StockSummary, double>
  49. {
  50. public Expression<Func<StockSummary, double>> Value => x => x.BillOfMaterials;
  51. public Expression<Func<StockSummary, double>>[] Modifiers => new Expression<Func<StockSummary, double>>[]
  52. {
  53. x => x.Issued
  54. };
  55. public FormulaOperator Operator => FormulaOperator.Subtract;
  56. public FormulaType Type => FormulaType.Virtual;
  57. }
  58. public class StockSummaryNettRequiredFormula : IFormula<StockSummary, double>
  59. {
  60. public Expression<Func<StockSummary, double>> Value => x => x.TotalRequired;
  61. public Expression<Func<StockSummary, double>>[] Modifiers => new Expression<Func<StockSummary, double>>[]
  62. {
  63. x => 0.0
  64. };
  65. public FormulaOperator Operator => FormulaOperator.Maximum;
  66. public FormulaType Type => FormulaType.Virtual;
  67. }
  68. public class StockSummaryAllStockAggregate : CoreAggregate<StockSummary, StockMovement, double>
  69. {
  70. public override Expression<Func<StockMovement, double>> Aggregate => x => x.Units;
  71. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  72. public override Dictionary<Expression<Func<StockMovement, object?>>, Expression<Func<StockSummary, object?>>> Links =>
  73. new Dictionary<Expression<Func<StockMovement, object?>>, Expression<Func<StockSummary, object?>>>()
  74. {
  75. { StockMovement => StockMovement.Product.ID, summary => summary.Product.ID },
  76. { StockMovement => StockMovement.Style.ID, summary => summary.Style.ID },
  77. }.AddRange(Dimensions.GetLinks<StockMovement, StockSummary>());
  78. }
  79. public class StockSummaryOrderAggregate : CoreAggregate<StockSummary, PurchaseOrderItem, double>
  80. {
  81. public override Expression<Func<PurchaseOrderItem, double>> Aggregate => x => x.Qty;
  82. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  83. public override Dictionary<Expression<Func<PurchaseOrderItem, object?>>, Expression<Func<StockSummary, object?>>> Links =>
  84. new Dictionary<Expression<Func<PurchaseOrderItem, object?>>, Expression<Func<StockSummary, object?>>>()
  85. {
  86. { PurchaseOrderItem => PurchaseOrderItem.Product.ID, summary => summary.Product.ID },
  87. { PurchaseOrderItem => PurchaseOrderItem.Style.ID, summary => summary.Style.ID },
  88. }.AddRange(Dimensions.GetLinks<PurchaseOrderItem, StockSummary>());
  89. public override Filter<PurchaseOrderItem> Filter => new Filter<PurchaseOrderItem>(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue);
  90. }
  91. public class StockSummaryTotalStockFormula : IFormula<StockSummary, double>
  92. {
  93. public Expression<Func<StockSummary, double>> Value => x => x.AllStock;
  94. public Expression<Func<StockSummary, double>>[] Modifiers => new Expression<Func<StockSummary, double>>[]
  95. {
  96. x => x.OnOrder
  97. };
  98. public FormulaOperator Operator => FormulaOperator.Add;
  99. public FormulaType Type => FormulaType.Virtual;
  100. }
  101. public class StockSummaryBalanceAvailableFormula : IFormula<StockSummary, double>
  102. {
  103. public Expression<Func<StockSummary, double>> Value => x => x.TotalStock;
  104. public Expression<Func<StockSummary, double>>[] Modifiers => new Expression<Func<StockSummary, double>>[]
  105. {
  106. x => x.MinimumStockLevel,
  107. x => x.NettRequired
  108. };
  109. public FormulaOperator Operator => FormulaOperator.Subtract;
  110. public FormulaType Type => FormulaType.Virtual;
  111. }
  112. public class StockSummaryUnionGenerator : AutoEntityUnionGenerator<IJobMaterial>
  113. {
  114. protected override void Configure()
  115. {
  116. //
  117. AddTable<ProductInstance>()
  118. .AddConstant<object?>(x => x.Job.ID, null);
  119. // BOM
  120. AddTable<JobBillOfMaterialsItem>(new Filter<JobBillOfMaterialsItem>(x => x.Job.ID).IsNotEqualTo(Guid.Empty));
  121. // Stock Issues
  122. AddTable<StockMovement>(new Filter<StockMovement>(x => x.Job.ID).IsNotEqualTo(Guid.Empty).And(x=>x.Type).IsEqualTo(StockMovementType.Issue));
  123. // Stock Holdings
  124. AddTable<StockHolding>();
  125. // On Order
  126. AddTable<PurchaseOrderItem>(new Filter<PurchaseOrderItem>(x => x.ReceivedDate).IsEqualTo(DateTime.MinValue));
  127. }
  128. public override bool Distinct => true;
  129. public override Column<IJobMaterial>[] IDColumns => new Column<IJobMaterial>[]
  130. {
  131. new Column<IJobMaterial>(x => x.Job.ID),
  132. new Column<IJobMaterial>(x => x.Product.ID),
  133. new Column<IJobMaterial>(x => x.Style.ID),
  134. new Column<IJobMaterial>(x => x.Dimensions.Unit.ID),
  135. new Column<IJobMaterial>(x => x.Dimensions.Quantity),
  136. new Column<IJobMaterial>(x => x.Dimensions.Length),
  137. new Column<IJobMaterial>(x => x.Dimensions.Width),
  138. new Column<IJobMaterial>(x => x.Dimensions.Height),
  139. new Column<IJobMaterial>(x => x.Dimensions.Weight)
  140. };
  141. }
  142. public class StockSummaryCalculatedField : IFormula<StockSummary, double>
  143. {
  144. public Expression<Func<StockSummary, double>> Value => x => 0.0;
  145. public Expression<Func<StockSummary, double>>[] Modifiers => new Expression<Func<StockSummary, double>>[] { };
  146. public FormulaOperator Operator => FormulaOperator.Constant;
  147. public FormulaType Type => FormulaType.Virtual;
  148. }
  149. public class StockSummaryCalculatedStringField : IFormula<StockSummary, string>
  150. {
  151. public Expression<Func<StockSummary, string>> Value => x => "";
  152. public Expression<Func<StockSummary, string>>[] Modifiers => new Expression<Func<StockSummary, string>>[] { };
  153. public FormulaOperator Operator => FormulaOperator.Constant;
  154. public FormulaType Type => FormulaType.Virtual;
  155. }
  156. [UserTracking(typeof(Product))]
  157. [AutoEntity(typeof(StockSummaryUnionGenerator))]
  158. public class StockSummary : StockEntity, IJobMaterial, IRemotable, IPersistent, ILicense<WarehouseLicense>
  159. {
  160. [NullEditor]
  161. public JobLink Job { get; set; }
  162. [EditorSequence(1)]
  163. public override ProductLink Product { get; set; }
  164. [EditorSequence(2)]
  165. public ProductStyleLink Style { get; set; }
  166. [EditorSequence(3)]
  167. [RequiredColumn]
  168. [DimensionsEditor(typeof(StockDimensions))]
  169. public override StockDimensions Dimensions { get; set; }
  170. [EditorSequence(4)]
  171. [DoubleEditor]
  172. [Aggregate(typeof(StockSummaryBOMAggregate))]
  173. public double BillOfMaterials { get; set; }
  174. [EditorSequence(5)]
  175. [IntegerEditor]
  176. [Aggregate(typeof(StockSummaryMinimumStockAggregate))]
  177. public int MinimumStockLevel { get; set; }
  178. [EditorSequence(6)]
  179. [Aggregate(typeof(StockSummaryIssuedAggregate))]
  180. [DoubleEditor]
  181. public double Issued { get; set; }
  182. [EditorSequence(7)]
  183. [Formula(typeof(StockSummaryTotalRequiredFormula))]
  184. public double TotalRequired { get; set; }
  185. [EditorSequence(8)]
  186. [Formula(typeof(StockSummaryNettRequiredFormula))]
  187. public double NettRequired { get; set; }
  188. [EditorSequence(9)]
  189. [Aggregate(typeof(StockSummaryAllStockAggregate))]
  190. [DoubleEditor]
  191. public double AllStock { get; set; }
  192. [EditorSequence(10)]
  193. [DoubleEditor]
  194. [Aggregate(typeof(StockSummaryOrderAggregate))]
  195. public double OnOrder { get; set; }
  196. [EditorSequence(11)]
  197. [Formula(typeof(StockSummaryTotalStockFormula))]
  198. [DoubleEditor]
  199. public double TotalStock { get; set; }
  200. [EditorSequence(12)]
  201. [DoubleEditor]
  202. [Formula(typeof(StockSummaryCalculatedField))]
  203. public double BalanceAvailable { get; set; }
  204. //[EditorSequence(13)]
  205. //[DoubleEditor]
  206. //[Formula(typeof(StockSummaryCalculatedField))]
  207. //public double JobBOM { get; set; }
  208. [EditorSequence(14)]
  209. [NullEditor]
  210. [Formula(typeof(StockSummaryCalculatedStringField))]
  211. public string Issues { get; set; }
  212. }
  213. }