BillLine.cs 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. using System;
  2. using System.Linq;
  3. using InABox.Core;
  4. namespace Comal.Classes
  5. {
  6. public class BillLineLink : EntityLink<BillLine>
  7. {
  8. [NullEditor]
  9. public override Guid ID { get; set; }
  10. [RequiredColumn]
  11. public BillLink BillLink { get; set; }
  12. }
  13. [UserTracking(typeof(Bill))]
  14. public class BillLine : Entity, IPersistent, IRemotable, IOneToMany<Bill>, ITaxable, ILicense<AccountsPayableLicense>, IPostableFragment<Bill>
  15. {
  16. [RequiredColumn]
  17. [EntityRelationship(DeleteAction.Cascade)]
  18. [NullEditor]
  19. public BillLink BillLink { get; set; }
  20. private class PurchaseOrderItemLookup : LookupDefinitionGenerator<PurchaseOrderItem, BillLine>
  21. {
  22. public override Filter<PurchaseOrderItem> DefineFilter(BillLine[] items)
  23. {
  24. if (!items.Any())
  25. return new Filter<PurchaseOrderItem>().None();
  26. var supplierID = items.Select(x => x.BillLink.SupplierLink.ID).Distinct().SingleOrDefault();
  27. if(supplierID == Guid.Empty)
  28. return new Filter<PurchaseOrderItem>().None();
  29. return new Filter<PurchaseOrderItem>(x => x.PurchaseOrderLink.SupplierLink.ID).IsEqualTo(supplierID)
  30. .And(x=>x.BillLine.ID).IsEqualTo(Guid.Empty);
  31. }
  32. public override Columns<BillLine> DefineFilterColumns()
  33. {
  34. return Columns.None<BillLine>().Add(x => x.BillLink.SupplierLink.ID);
  35. }
  36. }
  37. [LookupDefinition(typeof(PurchaseOrderItemLookup))]
  38. [EntityRelationship(DeleteAction.SetNull)]
  39. [EditorSequence(1)]
  40. public PurchaseOrderItemLink OrderItem { get; set; }
  41. private class ConsignmentLookup : LookupDefinitionGenerator<Consignment, BillLine>
  42. {
  43. public override Filter<Consignment> DefineFilter(BillLine[] items)
  44. {
  45. if (!items.Any())
  46. return new Filter<Consignment>().None();
  47. var supplierID = items.Select(x => x.BillLink.SupplierLink.ID).Distinct().SingleOrDefault();
  48. if(supplierID == Guid.Empty)
  49. return new Filter<Consignment>().None();
  50. return new Filter<Consignment>(x => x.Supplier.ID).IsEqualTo(supplierID)
  51. .And(x=>x.BillLine.ID).IsEqualTo(Guid.Empty);
  52. }
  53. public override Columns<BillLine> DefineFilterColumns()
  54. {
  55. return Columns.None<BillLine>().Add(x => x.BillLink.SupplierLink.ID);
  56. }
  57. }
  58. [LookupDefinition(typeof(ConsignmentLookup))]
  59. [EntityRelationship(DeleteAction.SetNull)]
  60. [EditorSequence(2)]
  61. public ConsignmentLink Consignment { get; set; }
  62. private class ProductLookupGenerator : LookupDefinitionGenerator<Product, BillLine>
  63. {
  64. public override Filter<Product>? DefineFilter(BillLine[] items)
  65. => new Filter<Product>(x => x.NonStock).IsEqualTo(true);
  66. }
  67. [EditorSequence(3)]
  68. [LookupDefinition(typeof(ProductLookupGenerator))]
  69. public ProductLink Product { get; set; }
  70. [EditorSequence(4)]
  71. public JobLink Job { get; set; }
  72. [MemoEditor]
  73. [EditorSequence(5)]
  74. public string Description { get; set; }
  75. [CurrencyEditor(Summary=Summary.Sum)]
  76. [EditorSequence(6)]
  77. public double ForeignCurrencyCost { get; set; }
  78. [CurrencyEditor(Summary = Summary.Sum)]
  79. [EditorSequence(7)]
  80. public double ExTax { get; set; }
  81. [RequiredColumn]
  82. [EditorSequence(8)]
  83. public TaxCodeLink TaxCode { get; set; }
  84. [CurrencyEditor(Summary = Summary.Sum)]
  85. [EditorSequence(9)]
  86. public double Tax { get; set; }
  87. [CurrencyEditor(Summary = Summary.Sum)]
  88. [EditorSequence(10)]
  89. public double IncTax { get; set; }
  90. [EditorSequence(11)]
  91. public PurchaseGLCodeLink PurchaseGL { get; set; }
  92. [EditorSequence(12)]
  93. public CostCentreLink CostCentre { get; set; }
  94. [NullEditor]
  95. public double TaxRate { get; set; }
  96. [NullEditor]
  97. public string PostedReference { get; set; }
  98. static BillLine()
  99. {
  100. // If we select a product for this bill line
  101. LinkedProperties.Register<BillLine, ProductLink, String>(x => x.Product, x => x.Name, x => x.Description);
  102. LinkedProperties.Register<BillLine, PurchaseOrderItemLink, double>(x => x.OrderItem, x => x.ExTax,
  103. x => x.ExTax);
  104. LinkedProperties.Register<BillLine, PurchaseGLCodeLink, Guid>(x => x.OrderItem.PurchaseGL, x => x.ID,
  105. x => x.PurchaseGL.ID);
  106. LinkedProperties.Register<BillLine, CostCentreLink, Guid>(x => x.OrderItem.CostCentre, x => x.ID,
  107. x => x.CostCentre.ID);
  108. LinkedProperties.Register<BillLine, TaxCodeLink, Guid>(x => x.OrderItem.TaxCode, x => x.ID,
  109. x => x.TaxCode.ID);
  110. LinkedProperties.Register<BillLine, TaxCodeLink, String>(x => x.OrderItem.TaxCode, x => x.Code,
  111. x => x.TaxCode.Code);
  112. LinkedProperties.Register<BillLine, TaxCodeLink, String>(x => x.OrderItem.TaxCode, x => x.Description,
  113. x => x.TaxCode.Description);
  114. LinkedProperties.Register<BillLine, TaxCodeLink, double>(x => x.OrderItem.TaxCode, x => x.Rate,
  115. x => x.TaxCode.Rate);
  116. LinkedProperties.Register<BillLine, PurchaseOrderItemLink, double>(x => x.OrderItem, x => x.Tax,
  117. x => x.Tax);
  118. LinkedProperties.Register<BillLine, PurchaseOrderItemLink, double>(x => x.OrderItem, x => x.IncTax,
  119. x => x.IncTax);
  120. LinkedProperties.Register<BillLine, TaxCodeLink, double>(x => x.TaxCode, x => x.Rate, x => x.TaxRate);
  121. LinkedProperties.Register<BillLine, PurchaseGLCodeLink, Guid>(x => x.Product.PurchaseGL, x => x.ID, x => x.PurchaseGL.ID);
  122. LinkedProperties.Register<BillLine, CostCentreLink, Guid>(x => x.Product.CostCentre, x => x.ID, x => x.CostCentre.ID);
  123. LinkedProperties.Register<BillLine, TaxCodeLink, Guid>(x => x.Product.TaxCode, x => x.ID, x => x.TaxCode.ID);
  124. LinkedProperties.Register<BillLine, TaxCodeLink, string>(x => x.Product.TaxCode, x => x.Code, x => x.TaxCode.Code);
  125. LinkedProperties.Register<BillLine, TaxCodeLink, string>(x => x.Product.TaxCode, x => x.Description, x => x.TaxCode.Description);
  126. LinkedProperties.Register<BillLine, TaxCodeLink, double>(x => x.Product.TaxCode, x => x.Rate, x => x.TaxCode.Rate);
  127. }
  128. private static readonly Column<BillLine> OrderItemColumn = new Column<BillLine>(x => x.OrderItem.ID);
  129. private static readonly Column<BillLine> ProductColumn = new Column<BillLine>(x => x.Product.ID);
  130. private static readonly Column<BillLine> JobColumn = new Column<BillLine>(x => x.Job.ID);
  131. private static readonly Column<BillLine> ForeignCurrencyColumn = new Column<BillLine>(x => x.ForeignCurrencyCost);
  132. private static readonly Column<BillLine> ExTaxColumn = new Column<BillLine>(x => x.ExTax);
  133. private static readonly Column<BillLine> IncTaxColumn = new Column<BillLine>(x => x.ExTax);
  134. private bool bChanging = false;
  135. protected override void DoPropertyChanged(string name, object? before, object? after)
  136. {
  137. if (bChanging)
  138. return;
  139. bChanging = true;
  140. try
  141. {
  142. base.DoPropertyChanged(name, before, after);
  143. if (OrderItemColumn.IsEqualTo(name) && after is Guid orderItemID && orderItemID != Guid.Empty)
  144. {
  145. Product.ID = Guid.Empty;
  146. Product.Clear();
  147. Job.ID = Guid.Empty;
  148. Job.Clear();
  149. }
  150. else if((ProductColumn.IsEqualTo(name) && after is Guid productID && productID != Guid.Empty)
  151. || (JobColumn.IsEqualTo(name) && after is Guid jobID && jobID != Guid.Empty))
  152. {
  153. OrderItem.ID = Guid.Empty;
  154. OrderItem.Clear();
  155. }
  156. else if (ForeignCurrencyColumn.IsEqualTo(name) && after is double fcc)
  157. {
  158. ExTax = fcc / (BillLink.SupplierLink.Currency.ExchangeRate.IsEffectivelyEqual(0.0) ? 1.0 : BillLink.SupplierLink.Currency.ExchangeRate);
  159. Tax = ExTax * TaxRate / 100.0;
  160. IncTax = ExTax + Tax;
  161. }
  162. else if (ExTaxColumn.IsEqualTo(name) && after is double etc)
  163. {
  164. ForeignCurrencyCost = etc * (BillLink.SupplierLink.Currency.ExchangeRate.IsEffectivelyEqual(0.0) ? 1.0 : BillLink.SupplierLink.Currency.ExchangeRate);
  165. }
  166. else if (IncTaxColumn.IsEqualTo(name) && after is double itc)
  167. {
  168. ForeignCurrencyCost = ExTax * (BillLink.SupplierLink.Currency.ExchangeRate.IsEffectivelyEqual(0.0) ? 1.0 : BillLink.SupplierLink.Currency.ExchangeRate);
  169. }
  170. }
  171. finally
  172. {
  173. bChanging = false;
  174. }
  175. }
  176. }
  177. }