RosterUtils.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Comal.Classes;
  5. using InABox.Core;
  6. namespace Comal.Classes
  7. {
  8. public class RosterBlock
  9. {
  10. public DateTime Date { get; }
  11. public TimeSpan Start { get; }
  12. public TimeSpan Finish { get; }
  13. public TimeSpan Duration { get; }
  14. public RosterBlock(DateTime date, TimeSpan start, TimeSpan finish)
  15. {
  16. Date = date;
  17. Start = start;
  18. Finish = finish;
  19. Duration = TimeSpan.FromTicks(Math.Max(0L, finish.Ticks - start.Ticks));
  20. }
  21. }
  22. public static class RosterUtils
  23. {
  24. public static RosterBlock[] GetBlocks(this EmployeeRosterItem roster, DateTime date, TimeSpan start, TimeSpan finish)
  25. {
  26. var result = new List<RosterBlock>();
  27. if (roster.Enabled && (roster.Finish > start) && (roster.Start <= finish))
  28. {
  29. result.Add(new RosterBlock(
  30. date,
  31. start < roster.Start ? roster.Start : start,
  32. finish > roster.Finish ? roster.Finish : finish
  33. ));
  34. }
  35. if ( roster.Enabled && roster.SplitShift && (roster.Finish2 > start) && (roster.Start2 <= finish))
  36. {
  37. result.Add(new RosterBlock(
  38. date,
  39. start < roster.Start2 ? roster.Start2 : start,
  40. finish > roster.Finish2 ? roster.Finish2 : finish
  41. ));
  42. }
  43. return result.ToArray();
  44. }
  45. /// <summary>
  46. ///
  47. /// </summary>
  48. /// <remarks>
  49. /// Returns <see langword="null"/> if and only if <paramref name="startdate"/> > <paramref name="currentdate"/>
  50. /// </remarks>
  51. public static EmployeeRosterItem? GetRoster(IList<EmployeeRosterItem>? roster, DateTime startdate, DateTime currentdate)
  52. {
  53. if (startdate > currentdate)
  54. return null;
  55. if ((roster == null) || !roster.Any())
  56. roster = DefaultRoster();
  57. if (startdate.IsEmpty())
  58. startdate = currentdate.StartOfWeek(DayOfWeek.Monday);
  59. while (startdate.AddDays(roster.Count) <= currentdate)
  60. startdate = startdate.AddDays(roster.Count);
  61. int rosterday = (int)((currentdate.Date - startdate.Date).TotalDays) % roster.Count;
  62. return roster[rosterday];
  63. }
  64. private static readonly EmployeeRosterItem[] DEFAULT_ROSTER = new EmployeeRosterItem[]
  65. {
  66. new EmployeeRosterItem()
  67. { Day = 1, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true },
  68. new EmployeeRosterItem()
  69. { Day = 2, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true },
  70. new EmployeeRosterItem()
  71. { Day = 3, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true },
  72. new EmployeeRosterItem()
  73. { Day = 4, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true },
  74. new EmployeeRosterItem()
  75. { Day = 5, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true },
  76. new EmployeeRosterItem()
  77. { Day = 6, Enabled = false },
  78. new EmployeeRosterItem()
  79. { Day = 7, Enabled = false },
  80. };
  81. public static EmployeeRosterItem[] DefaultRoster() => DEFAULT_ROSTER;
  82. public static TimeSheet[] CreateLeaveTimesheets(Employee employee, EmployeeRosterItem[]? roster, DateTime from, TimeSpan fromtime, DateTime to, TimeSpan totime, Guid activityid, Action<TimeSheet> customise)
  83. {
  84. var result = new List<TimeSheet>();
  85. DateTime currentdate = from;
  86. while (currentdate <= to)
  87. {
  88. if (
  89. (employee.StartDate.IsEmpty() || (employee.StartDate <= currentdate))
  90. && (employee.FinishDate.IsEmpty() || (employee.FinishDate >= currentdate))
  91. )
  92. {
  93. var currentroster = GetRoster(roster, employee.RosterStart, currentdate);
  94. if (currentroster?.Enabled == true)
  95. {
  96. var currentfrom = (currentdate.Date == from.Date) ? fromtime : new TimeSpan(0);
  97. var currentto = (currentdate.Date == to.Date) ? totime : new TimeSpan(1, 0, 0, 0);
  98. var shifts = currentroster.GetBlocks(currentdate, currentfrom, currentto);
  99. foreach (var shift in shifts)
  100. {
  101. DateTime now = DateTime.Now;
  102. var timesheet = new TimeSheet();
  103. timesheet.EmployeeLink.ID = employee.ID;
  104. timesheet.Date = currentdate;
  105. timesheet.Start = shift.Start;
  106. timesheet.Finish = shift.Finish;
  107. //timesheet.Duration = shift.Item2 - shift.Item1;
  108. timesheet.ApprovedStart = timesheet.Start;
  109. timesheet.ApprovedFinish = timesheet.Finish;
  110. //timesheet.ApprovedDuration = timesheet.Finish - timesheet.Start;
  111. timesheet.Confirmed = now;
  112. timesheet.Approved = now;
  113. timesheet.ActivityLink.ID = activityid;
  114. customise?.Invoke(timesheet);
  115. result.Add(timesheet);
  116. }
  117. }
  118. }
  119. currentdate = currentdate.AddDays(1);
  120. }
  121. return result.ToArray();
  122. }
  123. }
  124. }