4 Commits

Author SHA1 Message Date
leander19961 7ff3cecf3a Full-Doc.md aktualisiert 2026-05-22 09:59:28 +02:00
leander19961 e83d5e9e0f Full-Doc.md aktualisiert 2026-04-28 14:27:27 +02:00
leander19961 c6776503e3 Dateien nach "/" hochladen
-add license
2026-04-28 13:47:37 +02:00
leander19961 69f8565a61 -make google api user friendly 2026-04-28 13:41:22 +02:00
7 changed files with 167 additions and 46 deletions
+22 -2
View File
@@ -1,6 +1,6 @@
# LeanderShiftPlannerV2 Technische Dokumentation # LeanderShiftPlannerV2 Technische Dokumentation
**Version:** 2.0.1 **Version:** 2.0.2
**Sprache:** C# / .NET 9.0 **Sprache:** C# / .NET 9.0
**Framework:** Avalonia UI 11.2.1 **Framework:** Avalonia UI 11.2.1
**Repository:** https://gitea.leanderserver.de/leander19961/LeanderShiftPlannerV2 **Repository:** https://gitea.leanderserver.de/leander19961/LeanderShiftPlannerV2
@@ -343,4 +343,24 @@ Die Oberfläche ist mit **Avalonia UI** und dem **Fluent Theme** umgesetzt. Sie
--- ---
*Dokumentation erstellt am 22.04.2026* **Google API Zugangsdaten einrichten**
Da das Programm über deinen persönlichen Google Account auf den Kalender zugreift, musst du einmalig eigene OAuth-Zugangsdaten in der Google Cloud Console erstellen und in der Datei Resources/templates/googleapi.txt hinterlegen.
Schritt-für-Schritt-Anleitung:
- Öffne die [Google Cloud Console](https://console.cloud.google.com/) und melde dich mit deinem Google-Konto an.
- Erstelle ein neues Projekt oder wähle ein bestehendes aus.
- Navigiere zu „APIs & Dienste" → „Bibliothek" und suche nach „Google Calendar API". Klicke auf „Aktivieren".
- Gehe zu „APIs & Dienste" → „Anmeldedaten" und klicke auf „Anmeldedaten erstellen" → „OAuth-Client-ID".
- Falls noch nicht geschehen, wirst du aufgefordert, den OAuth-Zustimmungsbildschirm zu konfigurieren. Wähle dort „Extern" und fülle die Pflichtfelder (App-Name, Support-E-Mail) aus. Alle anderen Felder können leer bleiben.
- Als Anwendungstyp wähle „Desktop-App" und vergib einen beliebigen Namen.
- Nach der Erstellung siehst du deine Client-ID und dein Client-Secret. Trage beide Werte in die Datei Resources/templates/googleapi.txt ein:
`ClientId=deine-client-id`
`ClientSecret=dein-client-secret`
Beim ersten Programmstart öffnet sich einmalig ein Browser-Fenster, in dem du den Zugriff für dein Google-Konto bestätigst. Danach wird das Zugriffstoken lokal gespeichert und der Dialog erscheint nicht mehr.
**Wichtig ist:** Es muss am Ende ein OAuth2-Client für die Google Calendar API des eigenen Kontos freigegeben sein, die ClientID und das ClientSecret werden vom Programm für den Kalenderzugriff benötigt.
*Dokumentation erstellt am 28.04.2026*
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2026 leander19961
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -7,7 +7,7 @@ namespace LeanderShiftPlannerV2.FileIO;
public static class GoogleApiLoader public static class GoogleApiLoader
{ {
public static bool CheckFileSystem() public static bool CheckFileSystem_ReadFile()
{ {
if (!Directory.Exists(Constants.DataPath)) if (!Directory.Exists(Constants.DataPath))
Directory.CreateDirectory(Constants.DataPath); Directory.CreateDirectory(Constants.DataPath);
@@ -20,10 +20,22 @@ public static class GoogleApiLoader
} }
return true; return true;
} }
public static bool CheckFileSystem_ReadToken()
{
if (!Directory.Exists(Constants.DataPath))
Directory.CreateDirectory(Constants.DataPath);
if (!File.Exists(Constants.DataPath + Constants.GoogleApiTokenPath))
{
File.Create(Constants.DataPath + Constants.GoogleApiTokenPath);
return false;
}
return true;
}
public static Dictionary<string, string> ReadFile() public static Dictionary<string, string> ReadFile()
{ {
if (!CheckFileSystem()) return new Dictionary<string, string>(); if (!CheckFileSystem_ReadFile()) return new Dictionary<string, string>();
Dictionary<string, string> apiSecrets = new Dictionary<string, string>(); Dictionary<string, string> apiSecrets = new Dictionary<string, string>();
try try
@@ -51,4 +63,30 @@ public static class GoogleApiLoader
return apiSecrets; return apiSecrets;
} }
public static void WriteToken(string token)
{
if (File.Exists(Constants.DataPath + Constants.GoogleApiTokenPath))
File.Delete(Constants.DataPath + Constants.GoogleApiTokenPath);
File.Create(Constants.DataPath + Constants.GoogleApiTokenPath).Close();
File.WriteAllText(Constants.DataPath + Constants.GoogleApiTokenPath, token);
}
public static string? ReadToken()
{
if (!CheckFileSystem_ReadToken()) return null;
string tokenString = null;
try
{
tokenString = File.ReadAllText(Constants.DataPath + Constants.GoogleApiTokenPath);
}
catch (Exception ex)
{
//TODO
Console.WriteLine($"Fehler beim Lesen der Datei: {ex.Message}");
}
return (tokenString.Equals(String.Empty) ? null : tokenString);
}
} }
@@ -8,10 +8,10 @@
<ApplicationIcon>Resources/icon/ShiftPlannerIcon.ico</ApplicationIcon> <ApplicationIcon>Resources/icon/ShiftPlannerIcon.ico</ApplicationIcon>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<PackageIcon>Resources\icon\ShiftPlannerIcon.png</PackageIcon> <PackageIcon>Resources\icon\ShiftPlannerIcon.png</PackageIcon>
<AssemblyVersion>1.0.5</AssemblyVersion> <AssemblyVersion>2.0.2</AssemblyVersion>
<FileVersion>1.0.5</FileVersion> <FileVersion>2.0.2</FileVersion>
<NeutralLanguage>en</NeutralLanguage> <NeutralLanguage>en</NeutralLanguage>
<Version>1.0.5</Version> <Version>2.0.2</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -10,6 +10,8 @@ using System.Threading.Tasks;
using LeanderShiftPlannerV2.Model; using LeanderShiftPlannerV2.Model;
using LeanderShiftPlannerV2.Util; using LeanderShiftPlannerV2.Util;
using Google.Apis.Auth.OAuth2; using Google.Apis.Auth.OAuth2;
using Google.Apis.Auth.OAuth2.Flows;
using Google.Apis.Auth.OAuth2.Responses;
using Google.Apis.Calendar.v3; using Google.Apis.Calendar.v3;
using Google.Apis.Services; using Google.Apis.Services;
using LeanderShiftPlannerV2.FileIO; using LeanderShiftPlannerV2.FileIO;
@@ -30,51 +32,81 @@ public class TimesheetService
public async Task GenerateGoogleTimeSheets(List<Person> persons, bool randomize) public async Task GenerateGoogleTimeSheets(List<Person> persons, bool randomize)
{ {
string[] scopes = { CalendarService.Scope.CalendarReadonly };
const string applicationName = "LeanderShiftPlanner"; const string applicationName = "LeanderShiftPlanner";
Dictionary<string, string> secrets = GoogleApiLoader.ReadFile(); Dictionary<string, string> secrets = GoogleApiLoader.ReadFile();
if (!secrets.ContainsKey(Constants.GoogleClientId) || !secrets.ContainsKey(Constants.GoogleClientSecret)) if (!secrets.ContainsKey(Constants.GoogleClientId) || !secrets.ContainsKey(Constants.GoogleClientSecret))
return; return;
if (secrets[Constants.GoogleClientId].Equals(string.Empty) || secrets[Constants.GoogleClientSecret].Equals(string.Empty)) if (secrets[Constants.GoogleClientId].Equals(string.Empty) ||
secrets[Constants.GoogleClientSecret].Equals(string.Empty))
return; return;
UserCredential credential;
string[] scopes = { CalendarService.Scope.CalendarReadonly };
ClientSecrets clientSecrets = new ClientSecrets(); ClientSecrets clientSecrets = new ClientSecrets();
clientSecrets.ClientId = secrets[Constants.GoogleClientId]; clientSecrets.ClientId = secrets[Constants.GoogleClientId];
clientSecrets.ClientSecret = secrets[Constants.GoogleClientSecret]; clientSecrets.ClientSecret = secrets[Constants.GoogleClientSecret];
//clientSecrets.ClientId = "823920428427-ub5n9a9dkfpuvjlut4eneg2058so49o3.apps.googleusercontent.com"; string? tokenString = GoogleApiLoader.ReadToken();
//clientSecrets.ClientSecret = "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";
UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(clientSecrets, scopes, "user", CancellationToken.None);
try
{
TokenResponse token = new TokenResponse { RefreshToken = tokenString };
credential = new UserCredential(
new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer
{
ClientSecrets = clientSecrets
}),
"user",
token
);
if (!await credential.RefreshTokenAsync(CancellationToken.None))
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(clientSecrets, scopes, "user",
CancellationToken.None);
GoogleApiLoader.WriteToken(credential.Token.RefreshToken);
}
}
catch (Exception e)
{
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(clientSecrets, scopes, "user",
CancellationToken.None);
GoogleApiLoader.WriteToken(credential.Token.RefreshToken);
}
// Erstelle den CalendarService // Erstelle den CalendarService
var service = new CalendarService(new BaseClientService.Initializer() CalendarService service = new CalendarService(new BaseClientService.Initializer()
{ {
HttpClientInitializer = credential, HttpClientInitializer = credential,
ApplicationName = applicationName, ApplicationName = applicationName,
}); });
foreach (Person person in persons) foreach (Person person in persons)
{ {
foreach (string month in Constants.Months) foreach (string month in Constants.Months)
{ {
if (month == Constants.Months[0]) continue; if (month == Constants.Months[0]) continue;
List<(DateTime, DateTime, bool)> timesheetValue = new List<(DateTime, DateTime, bool)>(); List<(DateTime, DateTime, bool)> timesheetValue = new List<(DateTime, DateTime, bool)>();
// Aktuelles Datum // Aktuelles Datum
DateTime now = DateTime.Now; DateTime now = DateTime.Now;
// Erster Tag des aktuellen Monats (00:00:00 Uhr) // Erster Tag des aktuellen Monats (00:00:00 Uhr)
DateTime firstDayOfMonth = new DateTime(now.Year, Constants.Months.IndexOf(month), 1, 0, 0, 0); DateTime firstDayOfMonth = new DateTime(now.Year, Constants.Months.IndexOf(month), 1, 0, 0, 0);
// Letzter Tag des aktuellen Monats (23:59:59 Uhr) // 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)), DateTime lastDayOfMonth = new DateTime(now.Year, Constants.Months.IndexOf(month),
DateTime.DaysInMonth(now.Year, Constants.Months.IndexOf(month)),
23, 59, 59); 23, 59, 59);
// Beispiel: Liste die nächsten 10 Ereignisse im ITM Kalender auf // Beispiel: Liste die nächsten 10 Ereignisse im ITM Kalender auf
var requestItm = service.Events.List("on089es7kq4ugi3rqvslkn7720@group.calendar.google.com"); var requestItm = service.Events.List("on089es7kq4ugi3rqvslkn7720@group.calendar.google.com");
requestItm.TimeMinDateTimeOffset = firstDayOfMonth; requestItm.TimeMinDateTimeOffset = firstDayOfMonth;
requestItm.TimeMaxDateTimeOffset = lastDayOfMonth; requestItm.TimeMaxDateTimeOffset = lastDayOfMonth;
requestItm.SingleEvents = true; requestItm.SingleEvents = true;
var requestWebService = service.Events.List("s4rdo3uk2on8ualv1goaktbiec@group.calendar.google.com"); var requestWebService = service.Events.List("s4rdo3uk2on8ualv1goaktbiec@group.calendar.google.com");
requestWebService.TimeMinDateTimeOffset = firstDayOfMonth; requestWebService.TimeMinDateTimeOffset = firstDayOfMonth;
requestWebService.TimeMaxDateTimeOffset = lastDayOfMonth; requestWebService.TimeMaxDateTimeOffset = lastDayOfMonth;
@@ -82,14 +114,14 @@ public class TimesheetService
var eventsItm = await requestItm.ExecuteAsync(); var eventsItm = await requestItm.ExecuteAsync();
var eventsWebService = await requestWebService.ExecuteAsync(); var eventsWebService = await requestWebService.ExecuteAsync();
foreach (var eventItem in eventsItm.Items) foreach (var eventItem in eventsItm.Items)
{ {
if (eventItem.Start.DateTime == null || eventItem.End.DateTime == null) continue; if (eventItem.Start.DateTime == null || eventItem.End.DateTime == null) continue;
if (eventItem.Summary.Contains(person.FirstName)) if (eventItem.Summary.Contains(person.FirstName))
{ {
DateTime dayStart = (DateTime) eventItem.Start.DateTime; DateTime dayStart = (DateTime)eventItem.Start.DateTime;
DateTime dayEnd = (DateTime) eventItem.End.DateTime; DateTime dayEnd = (DateTime)eventItem.End.DateTime;
timesheetValue.Add((dayStart, dayEnd, (dayEnd.Hour > 13))); timesheetValue.Add((dayStart, dayEnd, (dayEnd.Hour > 13)));
} }
} }
@@ -99,12 +131,12 @@ public class TimesheetService
if (eventItem.Start.DateTime == null || eventItem.End.DateTime == null) continue; if (eventItem.Start.DateTime == null || eventItem.End.DateTime == null) continue;
if (eventItem.Summary.Contains(person.FirstName)) if (eventItem.Summary.Contains(person.FirstName))
{ {
DateTime dayStart = (DateTime) eventItem.Start.DateTime; DateTime dayStart = (DateTime)eventItem.Start.DateTime;
DateTime dayEnd = (DateTime) eventItem.End.DateTime; DateTime dayEnd = (DateTime)eventItem.End.DateTime;
timesheetValue.Add((dayStart, dayEnd, false)); timesheetValue.Add((dayStart, dayEnd, false));
} }
} }
person.Timesheets.Add(new Timesheet(month, timesheetValue)); person.Timesheets.Add(new Timesheet(month, timesheetValue));
} }
@@ -124,17 +156,18 @@ public class TimesheetService
if (pattern.Count == 0) continue; if (pattern.Count == 0) continue;
List<DateTime> holidays = await GetHolidays(); List<DateTime> holidays = await GetHolidays();
List<DateTime> weekends = GetWeekends(); List<DateTime> weekends = GetWeekends();
int monthHours = person.Hours * 4; int monthHours = person.Hours * 4;
foreach (string month in Constants.Months) foreach (string month in Constants.Months)
{ {
if (month == Constants.Months[0]) continue; if (month == Constants.Months[0]) continue;
List<(DateTime, DateTime, bool)> timesheetValue = new List<(DateTime, DateTime, bool)>(); List<(DateTime, DateTime, bool)> timesheetValue = new List<(DateTime, DateTime, bool)>();
int currentPersonHours = 0; int currentPersonHours = 0;
int currentPatternIndex = 0; int currentPatternIndex = 0;
int dayOfMonth = 1; int dayOfMonth = 1;
int lastDayOfMonth = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth).AddMonths(1).AddDays(-1).Day; int lastDayOfMonth = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth)
.AddMonths(1).AddDays(-1).Day;
while (currentPersonHours != monthHours) while (currentPersonHours != monthHours)
{ {
DateTime currentDay = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth); DateTime currentDay = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth);
@@ -148,7 +181,8 @@ public class TimesheetService
{ {
case 6: case 6:
{ {
DateTime dayStart = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 9, 0, 0); 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); DateTime dayEnd = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 16, 0, 0);
timesheetValue.Add((dayStart, dayEnd, true)); timesheetValue.Add((dayStart, dayEnd, true));
currentPersonHours += 6; currentPersonHours += 6;
@@ -156,7 +190,8 @@ public class TimesheetService
} }
case 4: case 4:
{ {
DateTime dayStart = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 9, 0, 0); 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); DateTime dayEnd = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 13, 0, 0);
timesheetValue.Add((dayStart, dayEnd, false)); timesheetValue.Add((dayStart, dayEnd, false));
currentPersonHours += 4; currentPersonHours += 4;
@@ -164,7 +199,8 @@ public class TimesheetService
} }
case 2: case 2:
{ {
DateTime dayStart = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 14, 0, 0); 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); DateTime dayEnd = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 16, 0, 0);
timesheetValue.Add((dayStart, dayEnd, false)); timesheetValue.Add((dayStart, dayEnd, false));
currentPersonHours += 2; currentPersonHours += 2;
@@ -172,14 +208,15 @@ public class TimesheetService
} }
case 1: case 1:
{ {
DateTime dayStart = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 9, 0, 0); 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); DateTime dayEnd = new DateTime(currentDay.Year, currentDay.Month, currentDay.Day, 10, 0, 0);
timesheetValue.Add((dayStart, dayEnd, false)); timesheetValue.Add((dayStart, dayEnd, false));
currentPersonHours += 1; currentPersonHours += 1;
break; break;
} }
} }
dayOfMonth++; dayOfMonth++;
if (dayOfMonth > lastDayOfMonth) throw new Exception("Too many hours!"); if (dayOfMonth > lastDayOfMonth) throw new Exception("Too many hours!");
currentPatternIndex = (currentPatternIndex + 1) % pattern.Count; currentPatternIndex = (currentPatternIndex + 1) % pattern.Count;
@@ -202,7 +239,8 @@ public class TimesheetService
for (int i = 0; i <= daysInYear; i++) for (int i = 0; i <= daysInYear; i++)
{ {
DateTime currentDay = firstDayOfYear.AddDays(i); DateTime currentDay = firstDayOfYear.AddDays(i);
if (currentDay.DayOfWeek == DayOfWeek.Saturday || currentDay.DayOfWeek == DayOfWeek.Sunday) weekends.Add(currentDay); if (currentDay.DayOfWeek == DayOfWeek.Saturday || currentDay.DayOfWeek == DayOfWeek.Sunday)
weekends.Add(currentDay);
} }
return weekends; return weekends;
@@ -295,7 +333,7 @@ public class TimesheetService
private int CalcHours(Timesheet timesheet) private int CalcHours(Timesheet timesheet)
{ {
double hours = 0; double hours = 0;
foreach ((DateTime, DateTime, bool) tuple in timesheet.Value) foreach ((DateTime, DateTime, bool) tuple in timesheet.Value)
{ {
if (tuple.Item3) if (tuple.Item3)
@@ -307,32 +345,34 @@ public class TimesheetService
hours += (tuple.Item2 - tuple.Item1).TotalHours; hours += (tuple.Item2 - tuple.Item1).TotalHours;
} }
} }
return (int) hours; return (int)hours;
} }
private async Task CheckForNotEnoughHours(Person person) private async Task CheckForNotEnoughHours(Person person)
{ {
List<DateTime> holidays = await GetHolidays(); List<DateTime> holidays = await GetHolidays();
List<DateTime> weekends = GetWeekends(); List<DateTime> weekends = GetWeekends();
int monthHours = person.Hours * 4; int monthHours = person.Hours * 4;
foreach (string month in Constants.Months) foreach (string month in Constants.Months)
{ {
if (month == Constants.Months[0]) continue; if (month == Constants.Months[0]) continue;
Timesheet timesheet = person.GetTimeSheetByMonth(month); Timesheet timesheet = person.GetTimeSheetByMonth(month);
List<(DateTime, DateTime, bool)> timesheetValue = timesheet.Value; List<(DateTime, DateTime, bool)> timesheetValue = timesheet.Value;
int currentPersonHours = CalcHours(timesheet); int currentPersonHours = CalcHours(timesheet);
List<int> pattern = GetPattern((person.Hours * 4) - currentPersonHours); List<int> pattern = GetPattern((person.Hours * 4) - currentPersonHours);
int currentPatternIndex = 0; int currentPatternIndex = 0;
int dayOfMonth = 1; int dayOfMonth = 1;
int lastDayOfMonth = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth).AddMonths(1).AddDays(-1).Day; int lastDayOfMonth = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth)
.AddMonths(1).AddDays(-1).Day;
while (currentPersonHours != monthHours) while (currentPersonHours != monthHours)
{ {
DateTime currentDay = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth); DateTime currentDay = new DateTime(DateTime.Now.Year, Constants.Months.IndexOf(month), dayOfMonth);
if (holidays.Contains(currentDay) || weekends.Contains(currentDay) || CheckForDayIsNotEmpty(currentDay, timesheetValue)) if (holidays.Contains(currentDay) || weekends.Contains(currentDay) ||
CheckForDayIsNotEmpty(currentDay, timesheetValue))
{ {
dayOfMonth++; dayOfMonth++;
continue; continue;
@@ -373,7 +413,7 @@ public class TimesheetService
break; break;
} }
} }
dayOfMonth++; dayOfMonth++;
if (dayOfMonth > lastDayOfMonth) throw new Exception($"Too many hours for Person {person.FirstName}!"); if (dayOfMonth > lastDayOfMonth) throw new Exception($"Too many hours for Person {person.FirstName}!");
currentPatternIndex = (currentPatternIndex + 1) % pattern.Count; currentPatternIndex = (currentPatternIndex + 1) % pattern.Count;
@@ -387,7 +427,7 @@ public class TimesheetService
{ {
if (tuple.Item1.Date.Day == currentDay.Day) return true; if (tuple.Item1.Date.Day == currentDay.Day) return true;
} }
return false; return false;
} }
} }
+1
View File
@@ -21,6 +21,7 @@ namespace LeanderShiftPlannerV2.Util
public const string GoogleClientId = "GoogleClientId"; public const string GoogleClientId = "GoogleClientId";
public const string GoogleClientSecret = "GoogleClientSecret"; public const string GoogleClientSecret = "GoogleClientSecret";
public const string GoogleApiFileResource = @"Resources/templates/googleapi.txt"; public const string GoogleApiFileResource = @"Resources/templates/googleapi.txt";
public const string GoogleApiTokenPath = @"/googleapitoken.txt";
// TimeSheets // TimeSheets
public static readonly string TimeSheetSourceRandom = "Random"; public static readonly string TimeSheetSourceRandom = "Random";
@@ -47,7 +47,8 @@ public partial class LeanderShiftPlannerMainWindow : Window
private void CreateApiFile() private void CreateApiFile()
{ {
GoogleApiLoader.CheckFileSystem(); GoogleApiLoader.CheckFileSystem_ReadFile();
GoogleApiLoader.CheckFileSystem_ReadToken();
} }
// ------------------------------------------------------UI-Interactions------------------------------------------------------ // ------------------------------------------------------UI-Interactions------------------------------------------------------