using System.Collections.Generic; using System.Linq; using Comal.Classes; using InABox.Core; namespace PRS.Shared { public class RosterBlock { public DateTime Date { get; } public TimeSpan Start { get; } public TimeSpan Finish { get; } public TimeSpan Duration { get; } public RosterBlock(DateTime date, TimeSpan start, TimeSpan finish) { Date = date; Start = start; Finish = finish; Duration = TimeSpan.FromTicks(Math.Max(0L, finish.Ticks - start.Ticks)); } } public static class RosterUtils { public static RosterBlock[] GetBlocks(this EmployeeRosterItem roster, DateTime date, TimeSpan start, TimeSpan finish) { var result = new List(); if (roster.Enabled && (roster.Finish > start) && (roster.Start <= finish)) { result.Add(new RosterBlock( date, start < roster.Start ? roster.Start : start, finish > roster.Finish ? roster.Finish : finish )); } if ( roster.Enabled && roster.SplitShift && (roster.Finish2 > start) && (roster.Start2 <= finish)) { result.Add(new RosterBlock( date, start < roster.Start2 ? roster.Start2 : start, finish > roster.Finish2 ? roster.Finish2 : finish )); } return result.ToArray(); } public static EmployeeRosterItem? GetRoster(IList? roster, DateTime? startdate, DateTime currentdate) { if (startdate > currentdate) return null; if ((roster == null) || !roster.Any()) roster = DefaultRoster(); if ((startdate == null) || startdate.Value.IsEmpty()) startdate = currentdate.StartOfWeek(DayOfWeek.Monday); while (startdate.Value.AddDays(roster.Count) <= currentdate) startdate = startdate.Value.AddDays(roster.Count); int rosterday = (int)((currentdate.Date - startdate.Value.Date).TotalDays) % roster.Count; return roster[rosterday]; } private static readonly EmployeeRosterItem[] DEFAULT_ROSTER = new EmployeeRosterItem[] { new EmployeeRosterItem() { Day = 1, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true }, new EmployeeRosterItem() { Day = 2, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true }, new EmployeeRosterItem() { Day = 3, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true }, new EmployeeRosterItem() { Day = 4, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true }, new EmployeeRosterItem() { Day = 5, Start = new TimeSpan(8, 0, 0), Finish = new TimeSpan(16, 30, 0), Break = new TimeSpan(0, 30, 0), Enabled = true }, new EmployeeRosterItem() { Day = 6, Enabled = false }, new EmployeeRosterItem() { Day = 7, Enabled = false }, }; public static EmployeeRosterItem[] DefaultRoster() => DEFAULT_ROSTER; public static TimeSheet[] CreateLeaveTimesheets(Employee employee, EmployeeRosterItem[]? roster, DateTime from, TimeSpan fromtime, DateTime to, TimeSpan totime, Guid activityid, Action customise) { var result = new List(); DateTime rosterstart = employee.RosterStart.IsEmpty() ? from.StartOfWeek(DayOfWeek.Monday) : employee.RosterStart; if ((roster == null) || !roster.Any()) roster = DefaultRoster(); while (rosterstart.AddDays(roster.Length) <= from) rosterstart = rosterstart.AddDays(roster.Length); DateTime currentdate = from; while (currentdate <= to) { if ( (employee.StartDate.IsEmpty() || (employee.StartDate <= currentdate)) && (employee.FinishDate.IsEmpty() || (employee.FinishDate >= currentdate)) ) { var currentroster = GetRoster(roster, rosterstart, currentdate); if (currentroster?.Enabled == true) { TimeSpan currentfrom = (currentdate.Date == from.Date) ? fromtime : new TimeSpan(0); TimeSpan currentto = (currentdate.Date == to.Date) ? totime : new TimeSpan(1, 0, 0, 0); var shifts = currentroster.GetBlocks(currentdate, currentfrom, currentto); foreach (var shift in shifts) { DateTime now = DateTime.Now; var timesheet = new TimeSheet(); timesheet.EmployeeLink.ID = employee.ID; timesheet.Date = currentdate; timesheet.Start = shift.Start; timesheet.Finish = shift.Finish; //timesheet.Duration = shift.Item2 - shift.Item1; timesheet.ApprovedStart = timesheet.Start; timesheet.ApprovedFinish = timesheet.Finish; //timesheet.ApprovedDuration = timesheet.Finish - timesheet.Start; timesheet.Confirmed = now; timesheet.Approved = now; timesheet.ActivityLink.ID = activityid; customise?.Invoke(timesheet); result.Add(timesheet); } } } currentdate = currentdate.AddDays(1); } return result.ToArray(); } } }