270 lines
11 KiB
C#
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;
|
|
}
|
|
} |