- add GenerateRandomTimeSheets function to generate TimeSheets with Google Calendar and fix them with rnd entry's to fit person hours

This commit is contained in:
leander19961
2025-11-16 03:47:01 +01:00
parent d668890370
commit 7c34192b18
4 changed files with 149 additions and 12 deletions

View File

@@ -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;
}
}
}

View File

@@ -158,5 +158,13 @@ namespace LeanderShiftPlannerV2.Service
RemoveShiftFromPerson(person, shift);
}
}
public void ClearTimeSheets()
{
foreach (Person person in _persons)
{
person.Timesheets.Clear();
}
}
}
}

View File

@@ -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<Person> persons)
public async Task GenerateGoogleTimeSheets(List<Person> 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<Person> persons)
{
//List<Person> persons = _appService.PersonService.GetPersonList().ToList();
foreach (Person person in persons)
{
List<int> pattern = GetPattern(person);
List<int> pattern = GetPattern(person.Hours);
if (pattern.Count == 0) continue;
List<DateTime> holidays = await GetHolidays();
List<DateTime> weekends = GetWeekends();
@@ -233,33 +238,33 @@ public class TimesheetService
return holidays;
}
private List<int> GetPattern(Person person)
private List<int> GetPattern(int personHours)
{
int hours = 0;
List<int> pattern = new List<int>();
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<int>();
}
@@ -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<DateTime> holidays = await GetHolidays();
List<DateTime> 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<int> 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;
}
}

View File

@@ -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;