AssignmentStore.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using Comal.Classes;
  4. using InABox.Core;
  5. using System;
  6. namespace Comal.Stores
  7. {
  8. internal class AssignmentStore : BaseStore<Assignment>
  9. {
  10. private void CheckActivityForms(Assignment assignment)
  11. {
  12. if (!assignment.ActivityLink.HasOriginalValue(x => x.ID))
  13. {
  14. return;
  15. }
  16. List<AssignmentForm> assignmentForms;
  17. if(assignment.ID != Guid.Empty)
  18. {
  19. assignmentForms = Provider.Query(
  20. Filter<AssignmentForm>.Where(x => x.Parent.ID).IsEqualTo(assignment.ID),
  21. Columns.None<AssignmentForm>().Add(x => x.ID, x => x.FormData)
  22. ).Rows.Select(x => x.ToObject<AssignmentForm>()).ToList();
  23. }
  24. else
  25. {
  26. assignmentForms = new();
  27. }
  28. var toDelete = assignmentForms.Where(x => string.IsNullOrWhiteSpace(x.FormData));
  29. Provider.Delete(toDelete, UserID);
  30. var activityForms = Provider.Query(
  31. Filter<ActivityForm>.Where(x => x.Activity.ID).IsEqualTo(assignment.ActivityLink.ID)
  32. .And(x => x.Form.AppliesTo).IsEqualTo(nameof(Assignment)));
  33. var newForms = new List<AssignmentForm>();
  34. foreach (var row in activityForms.Rows)
  35. {
  36. var formID = row.Get<ActivityForm, Guid>(x => x.Form.ID);
  37. if (!(assignmentForms.Any(x => x.Form.ID == formID) && !toDelete.Any(x => x.Form.ID == formID)))
  38. {
  39. var assignmentForm = new AssignmentForm();
  40. assignmentForm.Form.ID = formID;
  41. assignmentForm.Parent.ID = assignment.ID;
  42. newForms.Add(assignmentForm);
  43. }
  44. }
  45. Provider.Save(newForms);
  46. }
  47. protected override void AfterSave(Assignment entity)
  48. {
  49. base.AfterSave(entity);
  50. CheckActivityForms(entity);
  51. CheckAssignmentCosts(entity);
  52. }
  53. private void CheckAssignmentCosts(Assignment entity)
  54. {
  55. var changedEmployee = entity.TryGetOriginalValue(x => x.EmployeeLink.ID, out var employeeID);
  56. if (!changedEmployee)
  57. {
  58. employeeID = entity.EmployeeLink.ID;
  59. }
  60. var changedDate = entity.TryGetOriginalValue(x => x.Date, out var date);
  61. if (!changedDate)
  62. {
  63. date = entity.Date;
  64. }
  65. if(changedEmployee || changedDate)
  66. {
  67. CheckAssignmentCosts(date, employeeID);
  68. }
  69. CheckAssignmentCosts(entity.Date, entity.EmployeeLink.ID);
  70. }
  71. private void CheckAssignmentCosts(DateTime date, Guid employeeID)
  72. {
  73. if (employeeID == Guid.Empty) return;
  74. var assignments = Provider.Query(
  75. Filter<Assignment>.Where(x => x.Date).IsEqualTo(date)
  76. .And(x => x.EmployeeLink.ID).IsEqualTo(employeeID),
  77. Columns.None<Assignment>()
  78. .Add(x => x.ID)
  79. .Add(x => x.Actual.Start)
  80. .Add(x => x.Actual.Finish)
  81. .Add(x => x.Actual.Duration)
  82. .Add(x => x.Booked.Start)
  83. .Add(x => x.Booked.Finish)
  84. .Add(x => x.Booked.Duration))
  85. .ToArray<Assignment>();
  86. var employee = Provider.Query(
  87. Filter<Employee>.Where(x => x.ID).IsEqualTo(employeeID),
  88. Columns.None<Employee>()
  89. .Add(x => x.RosterStart)
  90. .Add(x => x.HourlyRate))
  91. .ToObjects<Employee>().FirstOrDefault();
  92. if (employee is null) return;
  93. var rosterItems = Provider.Query(
  94. Filter<EmployeeRosterItem>.Where(x => x.Employee.ID).IsEqualTo(employeeID),
  95. Columns.None<EmployeeRosterItem>()
  96. .Add(x => x.Overtime.ID),
  97. new SortOrder<EmployeeRosterItem>(x => x.Day))
  98. .ToArray<EmployeeRosterItem>();
  99. var overtimeID = RosterUtils.GetRoster(rosterItems, employee.RosterStart, date)?.Overtime.ID ?? Guid.Empty;
  100. if(overtimeID == Guid.Empty) return;
  101. var overtime = Provider.Query(
  102. Filter<OvertimeInterval>.Where(x => x.Overtime.ID).IsEqualTo(overtimeID),
  103. Columns.None<OvertimeInterval>()
  104. .Add(x => x.Interval)
  105. .Add(x => x.IntervalType)
  106. .Add(x => x.Multiplier),
  107. new SortOrder<OvertimeInterval>(x => x.Sequence))
  108. .ToArray<OvertimeInterval>();
  109. assignments.SortBy(x => x.EffectiveStartTime());
  110. var totalHours = new Dictionary<Assignment, double>();
  111. OvertimeUtils.EvaluateOvertime(assignments, overtime, x => x.EffectiveFinishTime() - x.EffectiveStartTime(), (assignment, interval, duration) =>
  112. {
  113. totalHours[assignment] = totalHours.GetValueOrAdd(assignment)
  114. + duration.TotalHours * (interval?.Multiplier ?? 1);
  115. });
  116. foreach(var assignment in assignments)
  117. {
  118. assignment.Cost = totalHours.GetValueOrDefault(assignment) * employee.HourlyRate;
  119. }
  120. Provider.Save(assignments.Where(x => x.IsChanged()));
  121. }
  122. }
  123. }