diff --git a/LeanderShiftPlannerV2/Model/Person.cs b/LeanderShiftPlannerV2/Model/Person.cs index 3635582..d75acb1 100644 --- a/LeanderShiftPlannerV2/Model/Person.cs +++ b/LeanderShiftPlannerV2/Model/Person.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Xml.Serialization; +using LeanderShiftPlannerV2.Util; namespace LeanderShiftPlannerV2.Model { @@ -127,5 +128,15 @@ namespace LeanderShiftPlannerV2.Model { return _firstFirstName; } + + public Timesheet GetTimeSheetByMonth(string month) + { + foreach (Timesheet timesheet in _timesheets) + { + if (timesheet.Month == month) return timesheet; + } + + return null; + } } } \ No newline at end of file diff --git a/LeanderShiftPlannerV2/Service/PersonService.cs b/LeanderShiftPlannerV2/Service/PersonService.cs index 76c5f5e..497256e 100644 --- a/LeanderShiftPlannerV2/Service/PersonService.cs +++ b/LeanderShiftPlannerV2/Service/PersonService.cs @@ -158,5 +158,13 @@ namespace LeanderShiftPlannerV2.Service RemoveShiftFromPerson(person, shift); } } + + public void ClearTimeSheets() + { + foreach (Person person in _persons) + { + person.Timesheets.Clear(); + } + } } } \ No newline at end of file diff --git a/LeanderShiftPlannerV2/Service/TimesheetService.cs b/LeanderShiftPlannerV2/Service/TimesheetService.cs index 482f027..39bedb7 100644 --- a/LeanderShiftPlannerV2/Service/TimesheetService.cs +++ b/LeanderShiftPlannerV2/Service/TimesheetService.cs @@ -12,6 +12,7 @@ using LeanderShiftPlannerV2.Util; using Google.Apis.Auth.OAuth2; using Google.Apis.Calendar.v3; using Google.Apis.Services; +using Newtonsoft.Json.Linq; namespace LeanderShiftPlannerV2.Service; @@ -28,7 +29,7 @@ public class TimesheetService _appService = appService; } - public async Task GenerateGoogleTimeSheets(List persons) + public async Task GenerateGoogleTimeSheets(List persons, bool randomize) { string[] scopes = { CalendarService.Scope.CalendarReadonly }; const string applicationName = "LeanderShiftPlanner"; @@ -98,16 +99,20 @@ public class TimesheetService person.Timesheets.Add(new Timesheet(month, timesheetValue)); } + + if (randomize) + { + CheckForTooMuchHours(person); + await CheckForNotEnoughHours(person); + } } } public async Task GenerateRandomTimeSheets(List persons) { - //List persons = _appService.PersonService.GetPersonList().ToList(); - foreach (Person person in persons) { - List pattern = GetPattern(person); + List pattern = GetPattern(person.Hours); if (pattern.Count == 0) continue; List holidays = await GetHolidays(); List weekends = GetWeekends(); @@ -233,33 +238,33 @@ public class TimesheetService return holidays; } - private List GetPattern(Person person) + private List GetPattern(int personHours) { int hours = 0; List pattern = new List(); - while (hours < person.Hours) + while (hours < personHours) { - if (hours + 6 <= person.Hours) + if (hours + 6 <= personHours) { pattern.Add(6); hours += 6; } - else if (hours + 4 <= person.Hours) + else if (hours + 4 <= personHours) { pattern.Add(4); hours += 4; } - else if (hours + 2 <= person.Hours) + else if (hours + 2 <= personHours) { pattern.Add(2); hours += 2; } - else if (hours + 1 <= person.Hours) + else if (hours + 1 <= personHours) { pattern.Add(1); hours += 1; } - else if (hours + 2 > person.Hours) + else if (hours + 2 > personHours) { return new List(); } @@ -267,4 +272,114 @@ public class TimesheetService return pattern; } + + private void CheckForTooMuchHours(Person person) + { + foreach (Timesheet timesheet in person.Timesheets) + { + while (person.Hours * 4 < CalcHours(timesheet)) + { + timesheet.Value.RemoveAt(timesheet.Value.Count - 1); + } + } + } + + private int CalcHours(Timesheet timesheet) + { + double hours = 0; + + foreach ((DateTime, DateTime, bool) tuple in timesheet.Value) + { + if (tuple.Item3) + { + hours += (tuple.Item2 - tuple.Item1).TotalHours - 1; + } + else + { + hours += (tuple.Item2 - tuple.Item1).TotalHours; + } + } + + return (int) hours; + } + + private async Task CheckForNotEnoughHours(Person person) + { + List holidays = await GetHolidays(); + List weekends = GetWeekends(); + + int monthHours = person.Hours * 4; + foreach (string month in Constants.Months) + { + if (month == Constants.Months[0]) continue; + Timesheet timesheet = person.GetTimeSheetByMonth(month); + List<(DateTime, DateTime, bool)> timesheetValue = timesheet.Value; + + int currentPersonHours = CalcHours(timesheet); + List pattern = GetPattern((person.Hours * 4) - currentPersonHours); + + int currentPatternIndex = 0; + int dayOfMonth = 1; + int lastDayOfMonth = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth).AddMonths(1).AddDays(-1).Day; + while (currentPersonHours != monthHours) + { + DateTime currentDay = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth); + if (holidays.Contains(currentDay) || weekends.Contains(currentDay) || CheckForDayIsNotEmpty(currentDay, timesheetValue)) + { + dayOfMonth++; + continue; + } + + switch (pattern[currentPatternIndex]) + { + case 6: + { + DateTime dayStart = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 9, 0, 0); + DateTime dayEnd = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 16, 0, 0); + timesheetValue.Add((dayStart, dayEnd, true)); + currentPersonHours += 6; + break; + } + case 4: + { + DateTime dayStart = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 9, 0, 0); + DateTime dayEnd = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 13, 0, 0); + timesheetValue.Add((dayStart, dayEnd, false)); + currentPersonHours += 4; + break; + } + case 2: + { + DateTime dayStart = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 14, 0, 0); + DateTime dayEnd = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 16, 0, 0); + timesheetValue.Add((dayStart, dayEnd, false)); + currentPersonHours += 2; + break; + } + case 1: + { + DateTime dayStart = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 9, 0, 0); + DateTime dayEnd = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 10, 0, 0); + timesheetValue.Add((dayStart, dayEnd, false)); + currentPersonHours += 1; + break; + } + } + + dayOfMonth++; + if (dayOfMonth > lastDayOfMonth) throw new Exception($"Too many hours for Person {person.FirstName}!"); + currentPatternIndex = (currentPatternIndex + 1) % pattern.Count; + } + } + } + + private bool CheckForDayIsNotEmpty(DateTime currentDay, List<(DateTime, DateTime, bool)> timesheetValue) + { + foreach ((DateTime, DateTime, bool) tuple in timesheetValue) + { + if (tuple.Item1.Date.Day == currentDay.Day) return true; + } + + return false; + } } \ No newline at end of file diff --git a/LeanderShiftPlannerV2/View/LeanderShiftPlannerView/LeanderShiftPlannerMainWindow.axaml.cs b/LeanderShiftPlannerV2/View/LeanderShiftPlannerView/LeanderShiftPlannerMainWindow.axaml.cs index 779a867..f9348a4 100644 --- a/LeanderShiftPlannerV2/View/LeanderShiftPlannerView/LeanderShiftPlannerMainWindow.axaml.cs +++ b/LeanderShiftPlannerV2/View/LeanderShiftPlannerView/LeanderShiftPlannerMainWindow.axaml.cs @@ -129,8 +129,11 @@ public partial class LeanderShiftPlannerMainWindow : Window { try { + _appService.PersonService.ClearTimeSheets(); + ProgressbarCalculaion.IsIndeterminate = true; - await _appService.TimesheetService.GenerateGoogleTimeSheets(_appService.PersonService.GetGoogleTimeSheetList()); + await _appService.TimesheetService.GenerateGoogleTimeSheets(_appService.PersonService.GetGoogleTimeSheetList(), false); + await _appService.TimesheetService.GenerateGoogleTimeSheets(_appService.PersonService.GetRandomGoogleTimeSheetList(), true); await _appService.TimesheetService.GenerateRandomTimeSheets(_appService.PersonService.GetRandomTimeSheetList()); ProgressbarCalculaion.IsIndeterminate = false;