Fix parsing shift times

This commit is contained in:
Claudio Schaad 2025-09-03 22:09:14 +02:00
parent 803c390c81
commit 85a4ecb2aa
5 changed files with 99 additions and 49 deletions

View file

@ -15,7 +15,7 @@ namespace ShiftScheduler.Client.Pages
private Dictionary<DateTime, string> SelectedSchedule { get; set; } = new();
private Dictionary<DateTime, ShiftWithTransport> SelectedShiftsWithTransport { get; set; } = new();
private bool _isCurrentMonth = false;
private bool _isCurrentMonth = true;
private bool _isLoadingTransport = false;
private bool _isLoadingInitial = false;
private bool _showConfigDialog = false;

View file

@ -45,14 +45,15 @@ namespace ShiftScheduler.Server.Controllers
var transportConfig = _configurationService.GetTransportConfiguration();
TransportConnection? morningTransport = null;
TransportConnection? afternoonTransport = null;
var shifTimes = _configurationService.ParseShiftTimes(request.Date, shift);
// Get transport for morning shift if it has morning time
if (!string.IsNullOrEmpty(shift.MorningTime))
{
var morningStartTime = ParseShiftTime(request.Date, shift.MorningTime);
if (morningStartTime.HasValue)
if (shifTimes.MorningStart.HasValue)
{
morningTransport = await _transportService.GetConnectionAsync(morningStartTime.Value);
morningTransport = await _transportService.GetConnectionAsync(shifTimes.MorningStart.Value);
}
}
@ -65,22 +66,18 @@ namespace ShiftScheduler.Server.Controllers
// If both morning and afternoon shifts exist, check break duration
if (!string.IsNullOrEmpty(shift.MorningTime) && !string.IsNullOrEmpty(shift.AfternoonTime))
{
var morningEndTime = ParseShiftEndTime(request.Date, shift.MorningTime);
var afternoonStartTime = ParseShiftTime(request.Date, shift.AfternoonTime);
if (morningEndTime.HasValue && afternoonStartTime.HasValue)
if (shifTimes.MorningEnd.HasValue && shifTimes.AfternoonStart.HasValue)
{
var breakDurationMinutes = (afternoonStartTime.Value - morningEndTime.Value).TotalMinutes;
var breakDurationMinutes = (shifTimes.AfternoonStart.Value - shifTimes.MorningEnd.Value).TotalMinutes;
shouldLoadAfternoonTransport = breakDurationMinutes >= transportConfig.MinBreakMinutes;
}
}
if (shouldLoadAfternoonTransport)
{
var afternoonStartTime = ParseShiftTime(request.Date, shift.AfternoonTime);
if (afternoonStartTime.HasValue)
if (shifTimes.AfternoonStart.HasValue)
{
afternoonTransport = await _transportService.GetConnectionAsync(afternoonStartTime.Value);
afternoonTransport = await _transportService.GetConnectionAsync(shifTimes.AfternoonStart.Value);
}
}
}
@ -96,40 +93,6 @@ namespace ShiftScheduler.Server.Controllers
return Ok(shiftWithTransport);
}
private static DateTime? ParseShiftTime(DateTime date, string timeRange)
{
try
{
var times = timeRange.Split('-');
if (times.Length > 0 && TimeSpan.TryParse(times[0], out var startTime))
{
return date.Add(startTime);
}
}
catch
{
// Ignore parsing errors
}
return null;
}
private static DateTime? ParseShiftEndTime(DateTime date, string timeRange)
{
try
{
var times = timeRange.Split('-');
if (times.Length > 1 && TimeSpan.TryParse(times[1], out var endTime))
{
return date.Add(endTime);
}
}
catch
{
// Ignore parsing errors
}
return null;
}
[HttpPost("export_ics")]
public IActionResult ExportIcsWithTransport([FromBody] List<ShiftWithTransport> shiftsWithTransport)
{

View file

@ -12,12 +12,15 @@ namespace ShiftScheduler.Services
List<Shift> GetShifts();
TransportConfiguration GetTransportConfiguration();
// Schedule persistence methods
Task SaveScheduleAsync(int year, int month, Dictionary<DateTime, string> schedule);
Task<Dictionary<DateTime, string>> LoadScheduleAsync(int year, int month);
Task DeleteScheduleAsync(int year, int month);
ShiftTimes ParseShiftTimes(DateTime date, Shift shift);
}
public record ShiftTimes(DateTimeOffset? MorningStart, DateTimeOffset? MorningEnd, DateTimeOffset? AfternoonStart, DateTimeOffset? AfternoonEnd);
public class ConfigurationService : IConfigurationService
{
private ApplicationConfiguration _configuration;
@ -201,7 +204,45 @@ namespace ShiftScheduler.Services
// Log error if needed, but don't throw
}
}
public ShiftTimes ParseShiftTimes(DateTime date, Shift shift)
{
DateTimeOffset? morningStart = null;
DateTimeOffset? morningEnd = null;
DateTimeOffset? afternoonStart = null;
DateTimeOffset? afternoonEnd = null;
if (!string.IsNullOrEmpty(shift.MorningTime))
{
var times = shift.MorningTime.Split('-');
if (times.Length == 2)
{
var start = $"{date:yyyy-MM-dd}T{times[0]}:00";
var end = $"{date:yyyy-MM-dd}T{times[1]}:00";
morningStart = DateTimeOffset.Parse(start);
morningEnd = DateTimeOffset.Parse(end);
}
}
if (!string.IsNullOrEmpty(shift.AfternoonTime))
{
var times = shift.AfternoonTime.Split('-');
if (times.Length == 2)
{
var start = $"{date:yyyy-MM-dd}T{times[0]}:00";
var end = $"{date:yyyy-MM-dd}T{times[1]}:00";
afternoonStart = DateTimeOffset.Parse(start);
afternoonEnd = DateTimeOffset.Parse(end);
}
}
return new ShiftTimes(
MorningStart: morningStart,
MorningEnd: morningEnd,
AfternoonStart: afternoonStart,
AfternoonEnd: afternoonEnd);
}
private ApplicationConfiguration LoadConfigurationFromFiles(ApplicationConfiguration fallbackConfiguration)
{
try

View file

@ -0,0 +1,47 @@
using ShiftScheduler.Shared;
using Shouldly;
namespace ShiftScheduler.Services.Tests;
public class ConfigurationServiceTests
{
[Fact]
public void ParseShiftTimes_WithMorningAndAfternoon_ShouldReturnValid()
{
var applicationConfig = new ApplicationConfiguration();
var configurationService = new ConfigurationService(applicationConfig);
var shift = new Shift
{
MorningTime = "06:00-12:30",
AfternoonTime = "13:00-17:30"
};
var shiftTimes = configurationService.ParseShiftTimes(DateTime.Parse("2025-07-13T13:00:00"), shift);
shiftTimes.MorningStart.ShouldBe(T("2025-07-13T06:00:00+02:00"));
shiftTimes.MorningEnd.ShouldBe(T("2025-07-13T12:30:00+02:00"));
shiftTimes.AfternoonStart.ShouldBe(T("2025-07-13T13:00:00+02:00"));
shiftTimes.AfternoonEnd.ShouldBe(T("2025-07-13T17:30:00+02:00"));
}
[Fact]
public void ParseShiftTimes_WithMorning_ShouldReturnValid()
{
var applicationConfig = new ApplicationConfiguration();
var configurationService = new ConfigurationService(applicationConfig);
var shift = new Shift
{
MorningTime = "06:00-12:30"
};
var shiftTimes = configurationService.ParseShiftTimes(DateTime.Parse("2025-07-13T13:00:00"), shift);
shiftTimes.MorningStart.ShouldBe(T("2025-07-13T06:00:00+02:00"));
shiftTimes.MorningEnd.ShouldBe(T("2025-07-13T12:30:00+02:00"));
shiftTimes.AfternoonStart.ShouldBeNull();
shiftTimes.AfternoonEnd.ShouldBeNull();
}
private DateTimeOffset T(string dateTimeString)
{
return DateTimeOffset.Parse(dateTimeString);
}
}

View file

@ -9,7 +9,6 @@ public class TransportConnectionCalculatorTests
{
private readonly Mock<ILogger> loggerMock = new();
// Tests for new enhanced logic
[Fact]
public void FindBestConnectionEnhanced_WithGoodTimingConnection_ShouldReturnLatestValidConnection()
{