RosterUtils.cs 6.1 KB

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