Files
LeanderShiftPlannerV2/LeanderShiftPlannerV2/Service/TimesheetService.cs
2025-10-10 11:18:00 +02:00

270 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading;
using System.Threading.Tasks;
using LeanderShiftPlannerV2.Model;
using LeanderShiftPlannerV2.Util;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Calendar.v3;
using Google.Apis.Services;
namespace LeanderShiftPlannerV2.Service;
public class TimesheetService
{
private readonly AppService _appService;
private const string HolidayApiUriPart1 = "https://feiertage-api.de/api/?jahr=";
private const string HolidayApiUriPart2 = "&nur_land=";
private const string GoogleClientId = "823920428427-ub5n9a9dkfpuvjlut4eneg2058so49o3.apps.googleusercontent.com";
private const string GoogleClientSecret = "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";
public TimesheetService(AppService appService)
{
_appService = appService;
}
public async Task GenerateGoogleTimeSheets(List<Person> persons)
{
string[] scopes = { CalendarService.Scope.CalendarReadonly };
const string applicationName = "LeanderShiftPlanner";
ClientSecrets clientSecrets = new ClientSecrets();
clientSecrets.ClientId = GoogleClientId;
clientSecrets.ClientSecret = GoogleClientSecret;
UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(clientSecrets, scopes, "user", CancellationToken.None);
// Erstelle den CalendarService
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = applicationName,
});
foreach (Person person in persons)
{
foreach (string month in Constants.Months)
{
if (month == Constants.Months[0]) continue;
List<(DateTime, DateTime, bool)> timesheetValue = new List<(DateTime, DateTime, bool)>();
// Aktuelles Datum
DateTime now = DateTime.Now;
// Erster Tag des aktuellen Monats (00:00:00 Uhr)
DateTime firstDayOfMonth = new DateTime(now.Year, Constants.Months.IndexOf(month), 1, 0, 0, 0);
// Letzter Tag des aktuellen Monats (23:59:59 Uhr)
DateTime lastDayOfMonth = new DateTime(now.Year, Constants.Months.IndexOf(month), DateTime.DaysInMonth(now.Year, Constants.Months.IndexOf(month)),
23, 59, 59);
// Beispiel: Liste die nächsten 10 Ereignisse im ITM Kalender auf
var requestItm = service.Events.List("on089es7kq4ugi3rqvslkn7720@group.calendar.google.com");
requestItm.TimeMinDateTimeOffset = firstDayOfMonth;
requestItm.TimeMaxDateTimeOffset = lastDayOfMonth;
requestItm.SingleEvents = true;
var requestWebService = service.Events.List("s4rdo3uk2on8ualv1goaktbiec@group.calendar.google.com");
requestWebService.TimeMinDateTimeOffset = firstDayOfMonth;
requestWebService.TimeMaxDateTimeOffset = lastDayOfMonth;
requestWebService.SingleEvents = true;
var eventsItm = await requestItm.ExecuteAsync();
var eventsWebService = await requestWebService.ExecuteAsync();
foreach (var eventItem in eventsItm.Items)
{
if (eventItem.Start.DateTime == null || eventItem.End.DateTime == null) continue;
if (eventItem.Summary.Contains(person.FirstName))
{
DateTime dayStart = (DateTime) eventItem.Start.DateTime;
DateTime dayEnd = (DateTime) eventItem.End.DateTime;
timesheetValue.Add((dayStart, dayEnd, (dayEnd.Hour > 13)));
}
}
foreach (var eventItem in eventsWebService.Items)
{
if (eventItem.Start.DateTime == null || eventItem.End.DateTime == null) continue;
if (eventItem.Summary.Contains(person.FirstName))
{
DateTime dayStart = (DateTime) eventItem.Start.DateTime;
DateTime dayEnd = (DateTime) eventItem.End.DateTime;
timesheetValue.Add((dayStart, dayEnd, false));
}
}
person.Timesheets.Add(new Timesheet(month, timesheetValue));
}
}
}
public async Task GenerateRandomTimeSheets(List<Person> persons)
{
//List<Person> persons = _appService.PersonService.GetPersonList().ToList();
foreach (Person person in persons)
{
List<int> pattern = GetPattern(person);
if (pattern.Count == 0) continue;
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;
List<(DateTime, DateTime, bool)> timesheetValue = new List<(DateTime, DateTime, bool)>();
int currentPersonHours = 0;
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))
{
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!");
currentPatternIndex = (currentPatternIndex + 1) % pattern.Count;
}
person.Timesheets.Add(new Timesheet(month, timesheetValue));
}
}
}
private List<DateTime> GetWeekends()
{
List<DateTime> weekends = new List<DateTime>();
DateTime firstDayOfYear = new DateTime(DateTime.Now.Year, 1, 1);
DateTime lastDayOfYear = new DateTime(DateTime.Now.Year, 12, 31);
int daysInYear = lastDayOfYear.DayOfYear;
for (int i = 0; i <= daysInYear; i++)
{
DateTime currentDay = firstDayOfYear.AddDays(i);
if (currentDay.DayOfWeek == DayOfWeek.Saturday || currentDay.DayOfWeek == DayOfWeek.Sunday) weekends.Add(currentDay);
}
return weekends;
}
private async Task<List<DateTime>> GetHolidays()
{
List<DateTime> holidays = new List<DateTime>();
string url = $"{HolidayApiUriPart1}{DateTime.Now.Year}{HolidayApiUriPart2}HE";
using HttpClient client = new HttpClient();
try
{
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode();
string jsonResponse = await response.Content.ReadAsStringAsync();
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
JsonObject? data = JsonSerializer.Deserialize<JsonObject>(jsonResponse, options);
foreach (KeyValuePair<string, JsonNode> item in data)
{
string test = item.Value.Deserialize<JsonObject>().First().Value.ToString();
string[] dateSplit = test.Split("-");
holidays.Add(new DateTime(int.Parse(dateSplit[0]),
int.Parse(dateSplit[1]), int.Parse(dateSplit[2])));
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return holidays;
}
private List<int> GetPattern(Person person)
{
int hours = 0;
List<int> pattern = new List<int>();
while (hours < person.Hours)
{
if (hours + 6 <= person.Hours)
{
pattern.Add(6);
hours += 6;
}
else if (hours + 4 <= person.Hours)
{
pattern.Add(4);
hours += 4;
}
else if (hours + 2 <= person.Hours)
{
pattern.Add(2);
hours += 2;
}
else if (hours + 1 <= person.Hours)
{
pattern.Add(1);
hours += 1;
}
else if (hours + 2 > person.Hours)
{
return new List<int>();
}
}
return pattern;
}
}