Assignment.cs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. using System;
  2. using System.Linq;
  3. using System.Linq.Expressions;
  4. using InABox.Core;
  5. namespace Comal.Classes
  6. {
  7. /// <summary>
  8. /// An assignment represents an anticipated booking for an employee, much like a diary entry
  9. /// <exclude />
  10. /// </summary>
  11. [UserTracking("Assignments")]
  12. [Caption("Assignments")]
  13. public class Assignment : Entity, IPersistent, IRemotable, INumericAutoIncrement<Assignment>, IOneToMany<Employee>, IOneToMany<Job>,
  14. IOneToMany<Kanban>, ILicense<SchedulingControlLicense>, IJobActivity, IOneToMany<Invoice>, IJobScopedItem
  15. {
  16. [IntegerEditor(Editable = Editable.Hidden)]
  17. [EditorSequence(1)]
  18. public int Number { get; set; }
  19. [DateEditor]
  20. [EditorSequence(2)]
  21. public DateTime Date { get; set; }
  22. [EntityRelationship(DeleteAction.Cascade)]
  23. [EditorSequence(3)]
  24. public EmployeeLink EmployeeLink { get; set; }
  25. // [EntityRelationship(DeleteAction.Cascade)]
  26. // [EditorSequence(4)]
  27. // public EquipmentLink Equipment { get; set; }
  28. [TextBoxEditor]
  29. [EditorSequence(5)]
  30. public string Title { get; set; }
  31. [MemoEditor]
  32. [EditorSequence(6)]
  33. public string Description { get; set; }
  34. [EditorSequence(7)]
  35. public AssignmentActivityLink ActivityLink { get; set; }
  36. private class KanbanLookup : LookupDefinitionGenerator<Kanban, Assignment>
  37. {
  38. public override Filter<Kanban> DefineFilter(Assignment[] items)
  39. {
  40. if (items == null || !items.Any())
  41. return LookupFactory.DefineFilter<Kanban>();
  42. return new Filter<Kanban>(x => x.Closed).IsEqualTo(DateTime.MinValue).And(x => x.EmployeeLink.ID)
  43. .IsEqualTo(items.First().EmployeeLink.ID);
  44. }
  45. public override Columns<Assignment> DefineFilterColumns()
  46. => Columns.None<Assignment>().Add(x => x.EmployeeLink.ID);
  47. }
  48. [LookupDefinition(typeof(KanbanLookup))]
  49. [EditorSequence(8)]
  50. [EntityRelationship(DeleteAction.SetNull)]
  51. public KanbanLink Task { get; set; }
  52. [EditorSequence(9)]
  53. public JobLink JobLink { get; set; }
  54. private class JobITPLookup : LookupDefinitionGenerator<JobITP, Assignment>
  55. {
  56. public override Filter<JobITP> DefineFilter(Assignment[] items)
  57. {
  58. if (items.Length == 1)
  59. return new Filter<JobITP>(x => x.Job.ID).IsEqualTo(items.First().JobLink.ID);
  60. return LookupFactory.DefineFilter<JobITP>();
  61. }
  62. public override Columns<Assignment> DefineFilterColumns()
  63. => Columns.None<Assignment>().Add(x => x.JobLink.ID);
  64. }
  65. [LookupDefinition(typeof(JobITPLookup))]
  66. [EditorSequence(10)]
  67. public JobITPLink ITP { get; set; }
  68. [NullEditor]
  69. [Obsolete("Replaced with Actual.Start", true)]
  70. public TimeSpan Start { get; set; }
  71. [NullEditor]
  72. [Obsolete("Replaced with Actual.Duration", true)]
  73. public TimeSpan Duration { get; set; }
  74. [NullEditor]
  75. [Obsolete("Replaced with Actual.Finish", true)]
  76. public TimeSpan Finish { get; set; }
  77. [EditorSequence(11)]
  78. [CoreTimeEditor]
  79. public TimeBlock Booked { get; set; }
  80. [EditorSequence(12)]
  81. [CoreTimeEditor]
  82. public TimeBlock Actual { get; set; }
  83. [TimestampEditor]
  84. [RequiredColumn]
  85. [EditorSequence(13)]
  86. public DateTime Completed { get; set; }
  87. [EditorSequence("Processing",1)]
  88. public ActualCharge Charge { get; set; }
  89. [TimestampEditor]
  90. [EditorSequence("Processing",2)]
  91. public DateTime Processed { get; set; }
  92. [NullEditor]
  93. [EntityRelationship(DeleteAction.Cascade)]
  94. public LeaveRequestLink LeaveRequestLink { get; set; }
  95. [NullEditor]
  96. public DeliveryLink Delivery { get; set; }
  97. [NullEditor]
  98. [EntityRelationship(DeleteAction.SetNull)]
  99. public InvoiceLink Invoice { get; set; }
  100. [NullEditor]
  101. public MeetingDetails Meeting { get; set; }
  102. private class JobScopeLookup : LookupDefinitionGenerator<JobScope, Assignment>
  103. {
  104. public override Filter<JobScope> DefineFilter(Assignment[] items)
  105. {
  106. var item = items?.Length == 1 ? items[0] : null;
  107. if (item != null)
  108. return new Filter<JobScope>(x => x.Job.ID).IsEqualTo(item.JobLink.ID).And(x => x.Status.Approved).IsEqualTo(true);
  109. return new Filter<JobScope>(x => x.ID).None();
  110. }
  111. public override Columns<Assignment> DefineFilterColumns()
  112. => Columns.None<Assignment>().Add(x => x.JobLink.ID);
  113. }
  114. [LookupDefinition(typeof(JobScopeLookup))]
  115. public JobScopeLink JobScope { get; set; }
  116. public Expression<Func<Assignment, int>> AutoIncrementField()
  117. {
  118. return x => x.Number;
  119. }
  120. public Filter<Assignment> AutoIncrementFilter()
  121. {
  122. return null;
  123. }
  124. public static TimeSpan EffectiveTime(TimeSpan actual, TimeSpan booked) => actual.Ticks != 0L ? actual : booked;
  125. public TimeSpan EffectiveStartTime()
  126. {
  127. return EffectiveTime(Actual.Start, Booked.Start);
  128. }
  129. public DateTime EffectiveStart()
  130. {
  131. return Date.Add(EffectiveStartTime());
  132. }
  133. public TimeSpan EffectiveFinishTime()
  134. {
  135. // If we have an actual finish, always use that
  136. // otherwise use EffectiveStart() + booked.duration
  137. return EffectiveTime(
  138. Actual.Finish,
  139. EffectiveTime(Actual.Start, Booked.Start)
  140. .Add(Booked.Duration)
  141. );
  142. }
  143. public DateTime EffectiveFinish()
  144. {
  145. return Date.Add(
  146. EffectiveFinishTime()
  147. );
  148. }
  149. static Assignment()
  150. {
  151. LinkedProperties.Register<Assignment, ActivityCharge, bool>(ass => ass.ActivityLink.Charge, chg => chg.Chargeable, ass => ass.Charge.Chargeable);
  152. Classes.JobScope.LinkScopeProperties<Assignment>();
  153. }
  154. }
  155. }