JobScope.cs 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Linq.Expressions;
  5. using InABox.Clients;
  6. using InABox.Core;
  7. namespace Comal.Classes
  8. {
  9. public class JobScopeInvoiceExTax : CoreAggregate<JobScope, InvoiceLine, double>
  10. {
  11. public override Expression<Func<InvoiceLine, double>> Aggregate => x => x.ExTax;
  12. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  13. public override Dictionary<Expression<Func<InvoiceLine, object>>, Expression<Func<JobScope, object>>> Links =>
  14. new Dictionary<Expression<Func<InvoiceLine, object>>, Expression<Func<JobScope, object>>>()
  15. {
  16. { InvoiceLine => InvoiceLine.Scope.ID, JobPrice => JobPrice.ID }
  17. };
  18. }
  19. public class JobScopeInvoiceTax : CoreAggregate<JobScope, InvoiceLine, double>
  20. {
  21. public override Expression<Func<InvoiceLine, double>> Aggregate => x => x.Tax;
  22. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  23. public override Dictionary<Expression<Func<InvoiceLine, object>>, Expression<Func<JobScope, object>>> Links =>
  24. new Dictionary<Expression<Func<InvoiceLine, object>>, Expression<Func<JobScope, object>>>()
  25. {
  26. { InvoiceLine => InvoiceLine.Scope.ID, JobPrice => JobPrice.ID }
  27. };
  28. }
  29. public class JobScopeInvoiceIncTax : CoreAggregate<JobScope, InvoiceLine, double>
  30. {
  31. public override Expression<Func<InvoiceLine, double>> Aggregate => x => x.IncTax;
  32. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  33. public override Dictionary<Expression<Func<InvoiceLine, object>>, Expression<Func<JobScope, object>>> Links =>
  34. new Dictionary<Expression<Func<InvoiceLine, object>>, Expression<Func<JobScope, object>>>()
  35. {
  36. { InvoiceLine => InvoiceLine.Scope.ID, JobPrice => JobPrice.ID }
  37. };
  38. }
  39. public class JobScopeUninvoicedExTax : IFormula<JobScope, double>
  40. {
  41. public Expression<Func<JobScope, double>> Value => x => x.ExTax;
  42. public Expression<Func<JobScope, double>>[] Modifiers => new Expression<Func<JobScope, double>>[] { x => x.InvoiceExTax };
  43. public FormulaOperator Operator => FormulaOperator.Subtract;
  44. public FormulaType Type => FormulaType.Virtual;
  45. }
  46. public class JobScopeUninvoicedMaterialExTax : CoreAggregate<JobScope, StockMovement, double>
  47. {
  48. public override Expression<Func<StockMovement, double>> Aggregate => x => x.Value;
  49. public override Dictionary<Expression<Func<StockMovement, object?>>, Expression<Func<JobScope, object?>>> Links => new Dictionary<Expression<Func<StockMovement, object?>>, Expression<Func<JobScope, object?>>>()
  50. {
  51. { mvt => mvt.JobScope.ID, scope => scope.ID }
  52. };
  53. public override Filter<StockMovement>? Filter => new Filter<StockMovement>(x => x.Invoice.ID).IsEqualTo(Guid.Empty)
  54. .And(x => x.Type).IsEqualTo(StockMovementType.Issue);
  55. public override AggregateCalculation Calculation => AggregateCalculation.Sum;
  56. }
  57. public interface IJobScopedItem
  58. {
  59. JobLink JobLink { get; set; }
  60. JobScopeLink JobScope { get; set; }
  61. }
  62. [UserTracking(typeof(Job))]
  63. public class JobScope : Entity, IRemotable, IPersistent, ITaxable, IStringAutoIncrement<JobScope>, ILicense<ProjectManagementLicense>
  64. {
  65. [NullEditor]
  66. public InternalJobLink Job { get; set; }
  67. [EnumLookupEditor(typeof(JobScopeType), Visible = Visible.Default)]
  68. [EditorSequence(1)]
  69. public JobScopeType Type { get; set; } = JobScopeType.Variation;
  70. [CodeEditor(Visible = Visible.Default, Editable = Editable.Enabled)]
  71. [EditorSequence(2)]
  72. public string Number { get; set; }
  73. [MemoEditor(Visible = Visible.Default)]
  74. [EditorSequence(3)]
  75. public string Description { get; set; }
  76. private class JobScopeLookup : LookupDefinitionGenerator<JobScope, JobScope>
  77. {
  78. public override Filter<JobScope> DefineFilter(JobScope[] items)
  79. {
  80. if (items?.Any() != true)
  81. return Filter.None<JobScope>();
  82. var data = Client.Query(
  83. new Filter<JobScope>(x=>x.Job.ID).IsEqualTo(items.First().Job.ID),
  84. Columns.None<JobScope>().Add(x => x.ID).Add(x => x.Parent.ID));
  85. var nodes = new CoreTreeNodes();
  86. nodes.Load<JobScope>(data, x => x.ID, x => x.Parent.ID);
  87. var exclusions = items.SelectMany(x => nodes.GetChildren(x.ID)).ToArray();
  88. var ids = exclusions.Select(x => x.ID).ToArray();
  89. return new Filter<JobScope>(x=>x.Job.ID).IsEqualTo(items.First().Job.ID).And(x => x.ID).NotInList(ids);
  90. }
  91. public override Columns<JobScope> DefineFilterColumns()
  92. => Columns.None<JobScope>().Add(x => x.ID).Add(x => x.Parent.ID).Add(x => x.Number);
  93. }
  94. [LookupDefinition(typeof(JobScopeLookup))]
  95. [EditorSequence(4)]
  96. public JobScopeLink Parent { get; set; }
  97. [CurrencyEditor(Summary = Summary.Sum, Visible = Visible.Default)]
  98. [EditorSequence(5)]
  99. public double ExTax { get; set; }
  100. [EditorSequence(6)]
  101. public TaxCodeLink TaxCode { get; set; }
  102. [CurrencyEditor(Summary = Summary.Sum, Visible = Visible.Optional)]
  103. [EditorSequence(7)]
  104. public double IncTax { get; set; }
  105. [EditorSequence(8)]
  106. public JobScopeStatusLink Status { get; set; }
  107. [CurrencyEditor(Visible = Visible.Default, Editable = Editable.Hidden, Summary = Summary.Sum)]
  108. [Aggregate(typeof(JobScopeInvoiceExTax))]
  109. public double InvoiceExTax { get; set; }
  110. [CurrencyEditor(Visible = Visible.Optional, Editable = Editable.Hidden, Summary = Summary.Sum)]
  111. [Aggregate(typeof(JobScopeInvoiceTax))]
  112. public double InvoiceTax { get; set; }
  113. [CurrencyEditor(Visible = Visible.Optional, Editable = Editable.Hidden, Summary = Summary.Sum)]
  114. [Aggregate(typeof(JobScopeInvoiceIncTax))]
  115. public double InvoiceIncTax { get; set; }
  116. [CurrencyEditor(Visible = Visible.Optional, Editable = Editable.Hidden, Summary = Summary.Sum)]
  117. [Formula(typeof(JobScopeUninvoicedExTax))]
  118. public double UninvoiceIncTax { get; set; }
  119. [CurrencyEditor(Visible = Visible.Optional, Editable = Editable.Hidden, Summary = Summary.Sum)]
  120. [Aggregate(typeof(JobScopeUninvoicedMaterialExTax))]
  121. public double UninvoicedMaterialsExTax { get; set; }
  122. public Expression<Func<JobScope, string>> AutoIncrementField() => x => x.Number;
  123. public Filter<JobScope> AutoIncrementFilter() => new Filter<JobScope>(x => x.Job.ID).IsEqualTo(Job.ID);
  124. public String AutoIncrementPrefix() => "";
  125. public string AutoIncrementFormat() => "{0:D3}";
  126. [NullEditor]
  127. public double TaxRate { get; set; }
  128. [NullEditor(Summary = Summary.Sum, Visible = Visible.Optional)]
  129. public double Tax { get; set; }
  130. static JobScope()
  131. {
  132. LinkedProperties.Register<JobScope, TaxCodeLink, double>(x=>x.TaxCode, x => x.Rate, x => x.TaxRate);
  133. }
  134. public static void LinkScopeProperties<TScoped>() where TScoped : class, IJobScopedItem
  135. {
  136. LinkedProperties.Register<TScoped, JobScopeLink, Guid>(ass => ass.JobLink.DefaultScope, scope => scope.ID, ass => ass.JobScope.ID);
  137. LinkedProperties.Register<TScoped, JobScopeLink, String>(ass => ass.JobLink.DefaultScope, scope => scope.Number, ass => ass.JobScope.Number);
  138. LinkedProperties.Register<TScoped, JobScopeLink, String>(ass => ass.JobLink.DefaultScope, scope => scope.Description, ass => ass.JobScope.Description);
  139. }
  140. }
  141. }