feat: sync all-day events for shifts without time (Frei, holidays, etc.)
Both Google Calendar and Nextcloud CalDAV now create all-day events for shifts that have no MorningTime or AfternoonTime configured, instead of silently skipping them. Fixes month-boundary crash on day 31 by using DateOnly.AddDays(1) for the end date. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0520ce3847
commit
d00f5ea8b7
2 changed files with 49 additions and 0 deletions
|
|
@ -84,7 +84,12 @@ public class GoogleCalendarService(IHttpContextAccessor httpContextAccessor, ICo
|
||||||
var date = shiftWithTransport.Date;
|
var date = shiftWithTransport.Date;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(shift.MorningTime) && string.IsNullOrEmpty(shift.AfternoonTime))
|
if (string.IsNullOrEmpty(shift.MorningTime) && string.IsNullOrEmpty(shift.AfternoonTime))
|
||||||
|
{
|
||||||
|
var eventData = CalendarEventBuilder.BuildEventContent(shift, null);
|
||||||
|
var allDayEvent = CreateAllDayGoogleEvent(eventData, DateOnly.FromDateTime(date));
|
||||||
|
await CalendarEventBuilder.ExecuteWithRetryAsync(async () => await service.Events.Insert(allDayEvent, calendarId).ExecuteAsync());
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(shift.MorningTime))
|
if (!string.IsNullOrEmpty(shift.MorningTime))
|
||||||
{
|
{
|
||||||
|
|
@ -103,6 +108,26 @@ public class GoogleCalendarService(IHttpContextAccessor httpContextAccessor, ICo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Event CreateAllDayGoogleEvent(CalendarEventData eventData, DateOnly date)
|
||||||
|
{
|
||||||
|
var dateStr = date.ToString("yyyy-MM-dd");
|
||||||
|
var nextDateStr = date.AddDays(1).ToString("yyyy-MM-dd");
|
||||||
|
return new Event
|
||||||
|
{
|
||||||
|
Summary = eventData.Summary,
|
||||||
|
Start = new EventDateTime { Date = dateStr },
|
||||||
|
End = new EventDateTime { Date = nextDateStr },
|
||||||
|
ExtendedProperties = new Event.ExtendedPropertiesData
|
||||||
|
{
|
||||||
|
Private__ = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["shiftSchedulerEvent"] = "true",
|
||||||
|
["shiftName"] = eventData.Summary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static Event CreateGoogleEvent(CalendarEventData eventData, DateTimeOffset startTime, DateTimeOffset endTime)
|
private static Event CreateGoogleEvent(CalendarEventData eventData, DateTimeOffset startTime, DateTimeOffset endTime)
|
||||||
{
|
{
|
||||||
return new Event
|
return new Event
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,16 @@ public class NextcloudCalendarService(
|
||||||
var date = shiftWithTransport.Date;
|
var date = shiftWithTransport.Date;
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(shift.MorningTime) && string.IsNullOrEmpty(shift.AfternoonTime))
|
if (string.IsNullOrEmpty(shift.MorningTime) && string.IsNullOrEmpty(shift.AfternoonTime))
|
||||||
|
{
|
||||||
|
var uid = $"shift-{SanitizeForUid(shift.Name)}-{date:yyyyMMdd}-allday";
|
||||||
|
var eventData = CalendarEventBuilder.BuildEventContent(shift, null);
|
||||||
|
var icsContent = BuildAllDayIcsContent(uid, eventData, DateOnly.FromDateTime(date));
|
||||||
|
var putRequest = CreateRequest(HttpMethod.Put, $"{calendarId}{Uri.EscapeDataString(uid)}.ics");
|
||||||
|
putRequest.Content = new StringContent(icsContent, Encoding.UTF8, "text/calendar");
|
||||||
|
(await client.SendAsync(putRequest)).EnsureSuccessStatusCode();
|
||||||
|
await Task.Delay(300);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(shift.MorningTime))
|
if (!string.IsNullOrEmpty(shift.MorningTime))
|
||||||
{
|
{
|
||||||
|
|
@ -194,6 +203,21 @@ public class NextcloudCalendarService(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string BuildAllDayIcsContent(string uid, CalendarEventData eventData, DateOnly date)
|
||||||
|
{
|
||||||
|
var calendar = new Calendar();
|
||||||
|
var vevent = new CalendarEvent
|
||||||
|
{
|
||||||
|
Uid = uid,
|
||||||
|
Summary = eventData.Summary,
|
||||||
|
DtStart = new CalDateTime(date.Year, date.Month, date.Day),
|
||||||
|
DtEnd = new CalDateTime(date.AddDays(1).Year, date.AddDays(1).Month, date.AddDays(1).Day)
|
||||||
|
};
|
||||||
|
vevent.Properties.Add(new Ical.Net.CalendarProperty("X-SHIFT-SCHEDULER", "TRUE"));
|
||||||
|
calendar.Events.Add(vevent);
|
||||||
|
return new CalendarSerializer().SerializeToString(calendar)!;
|
||||||
|
}
|
||||||
|
|
||||||
private static string BuildIcsContent(string uid, CalendarEventData eventData, DateTimeOffset startTime, DateTimeOffset endTime)
|
private static string BuildIcsContent(string uid, CalendarEventData eventData, DateTimeOffset startTime, DateTimeOffset endTime)
|
||||||
{
|
{
|
||||||
var calendar = new Calendar();
|
var calendar = new Calendar();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue