fix: 员工排班移除mock与兜底逻辑
All checks were successful
Build and Deploy TenantApi / build-and-deploy (push) Successful in 43s

This commit is contained in:
2026-02-20 09:02:52 +08:00
parent 145be01bfc
commit 069d7de05e
2 changed files with 74 additions and 136 deletions

View File

@@ -154,7 +154,15 @@ public sealed class StoreStaffScheduleDto
/// <summary> /// <summary>
/// Templates。 /// Templates。
/// </summary> /// </summary>
public StoreShiftTemplatesDto Templates { get; set; } = new(); public StoreShiftTemplatesDto? Templates { get; set; }
/// <summary>
/// IsTemplateConfigured。
/// </summary>
public bool IsTemplateConfigured { get; set; }
/// <summary>
/// IsScheduleConfigured。
/// </summary>
public bool IsScheduleConfigured { get; set; }
/// <summary> /// <summary>
/// Schedules。 /// Schedules。
/// </summary> /// </summary>

View File

@@ -135,9 +135,6 @@ public sealed class StoreStaffController(
await dbContext.SaveChangesAsync(cancellationToken); await dbContext.SaveChangesAsync(cancellationToken);
var template = await GetOrCreateTemplateDtoAsync(tenantId, parsedStoreId, cancellationToken);
await EnsureStaffScheduleAsync(tenantId, parsedStoreId, entity, template, cancellationToken);
return ApiResponse<StoreStaffItemDto>.Ok(MapStaff(entity)); return ApiResponse<StoreStaffItemDto>.Ok(MapStaff(entity));
} }
@@ -186,7 +183,7 @@ public sealed class StoreStaffController(
var (tenantId, merchantId) = StoreApiHelpers.GetTenantMerchantContext(storeContextService); var (tenantId, merchantId) = StoreApiHelpers.GetTenantMerchantContext(storeContextService);
await StoreApiHelpers.EnsureStoreAccessibleAsync(dbContext, tenantId, merchantId, parsedStoreId, cancellationToken); await StoreApiHelpers.EnsureStoreAccessibleAsync(dbContext, tenantId, merchantId, parsedStoreId, cancellationToken);
var template = await GetOrCreateTemplateDtoAsync(tenantId, parsedStoreId, cancellationToken); var template = await GetTemplateDtoAsync(tenantId, parsedStoreId, cancellationToken);
var staffs = await dbContext.MerchantStaff var staffs = await dbContext.MerchantStaff
.AsNoTracking() .AsNoTracking()
.Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId) .Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId)
@@ -205,8 +202,10 @@ public sealed class StoreStaffController(
var schedules = staffs.Select(staff => var schedules = staffs.Select(staff =>
{ {
var shifts = scheduleMap.TryGetValue(staff.Id, out var rows) var shifts = scheduleMap.TryGetValue(staff.Id, out var rows)
? NormalizeRowsToShifts(rows, staff, template) ? template is null
: CreateDefaultWeekByRole(staff.RoleType, template); ? []
: NormalizeRowsToShifts(rows, template)
: [];
if (staff.Status == StaffStatus.Resigned) if (staff.Status == StaffStatus.Resigned)
{ {
@@ -225,6 +224,8 @@ public sealed class StoreStaffController(
StoreId = parsedStoreId.ToString(), StoreId = parsedStoreId.ToString(),
WeekStartDate = StoreApiHelpers.ResolveWeekStartDate(weekStartDate), WeekStartDate = StoreApiHelpers.ResolveWeekStartDate(weekStartDate),
Templates = template, Templates = template,
IsTemplateConfigured = template is not null,
IsScheduleConfigured = scheduleRows.Count > 0,
Schedules = schedules Schedules = schedules
}); });
} }
@@ -298,19 +299,23 @@ public sealed class StoreStaffController(
throw new BusinessException(ErrorCodes.BadRequest, "员工不存在"); throw new BusinessException(ErrorCodes.BadRequest, "员工不存在");
} }
var template = await GetOrCreateTemplateDtoAsync(tenantId, parsedStoreId, cancellationToken); var template = await GetTemplateDtoAsync(tenantId, parsedStoreId, cancellationToken);
if (template is null)
{
throw new BusinessException(ErrorCodes.BadRequest, "请先配置班次模板");
}
var existingRows = await dbContext.StoreStaffWeeklySchedules var existingRows = await dbContext.StoreStaffWeeklySchedules
.Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId && x.StaffId == parsedStaffId) .Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId && x.StaffId == parsedStaffId)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
var fallback = NormalizeRowsToShifts(existingRows, staff, template); var fallback = NormalizeRowsToShifts(existingRows, template);
var shifts = staff.Status == StaffStatus.Resigned var shifts = staff.Status == StaffStatus.Resigned
? CreateOffWeekShifts() ? CreateOffWeekShifts()
: NormalizeShifts(request.Shifts, fallback, template); : NormalizeShifts(request.Shifts, fallback, template);
dbContext.StoreStaffWeeklySchedules.RemoveRange(existingRows); dbContext.StoreStaffWeeklySchedules.RemoveRange(existingRows);
await dbContext.StoreStaffWeeklySchedules.AddRangeAsync( await dbContext.StoreStaffWeeklySchedules.AddRangeAsync(
ToWeeklyEntities(parsedStoreId, parsedStaffId, shifts), ToWeeklyEntities(parsedStoreId, parsedStaffId, shifts, template),
cancellationToken); cancellationToken);
await dbContext.SaveChangesAsync(cancellationToken); await dbContext.SaveChangesAsync(cancellationToken);
@@ -343,7 +348,11 @@ public sealed class StoreStaffController(
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
var staffMap = staffs.ToDictionary(x => x.Id); var staffMap = staffs.ToDictionary(x => x.Id);
var template = await GetOrCreateTemplateDtoAsync(tenantId, parsedStoreId, cancellationToken); var template = await GetTemplateDtoAsync(tenantId, parsedStoreId, cancellationToken);
if (template is null)
{
throw new BusinessException(ErrorCodes.BadRequest, "请先配置班次模板");
}
var existingRows = await dbContext.StoreStaffWeeklySchedules var existingRows = await dbContext.StoreStaffWeeklySchedules
.Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId) .Where(x => x.TenantId == tenantId && x.StoreId == parsedStoreId)
.ToListAsync(cancellationToken); .ToListAsync(cancellationToken);
@@ -351,7 +360,7 @@ public sealed class StoreStaffController(
.GroupBy(x => x.StaffId) .GroupBy(x => x.StaffId)
.ToDictionary( .ToDictionary(
x => x.Key, x => x.Key,
x => NormalizeRowsToShifts(x.ToList(), staffMap.GetValueOrDefault(x.Key), template)); x => NormalizeRowsToShifts(x.ToList(), template));
var incomingMap = new Dictionary<long, List<StaffDayShiftDto>>(); var incomingMap = new Dictionary<long, List<StaffDayShiftDto>>();
foreach (var schedule in request.Schedules ?? []) foreach (var schedule in request.Schedules ?? [])
@@ -367,7 +376,7 @@ public sealed class StoreStaffController(
continue; continue;
} }
var fallback = existingMap.GetValueOrDefault(staffId.Value) ?? CreateDefaultWeekByRole(staff.RoleType, template); var fallback = existingMap.GetValueOrDefault(staffId.Value) ?? [];
incomingMap[staffId.Value] = NormalizeShifts(schedule.Shifts, fallback, template); incomingMap[staffId.Value] = NormalizeShifts(schedule.Shifts, fallback, template);
} }
@@ -385,7 +394,7 @@ public sealed class StoreStaffController(
} }
else else
{ {
shifts = existingMap.GetValueOrDefault(staff.Id) ?? CreateDefaultWeekByRole(staff.RoleType, template); shifts = existingMap.GetValueOrDefault(staff.Id) ?? [];
} }
finalSchedules.Add(new StaffScheduleDto finalSchedules.Add(new StaffScheduleDto
@@ -397,7 +406,7 @@ public sealed class StoreStaffController(
dbContext.StoreStaffWeeklySchedules.RemoveRange(existingRows); dbContext.StoreStaffWeeklySchedules.RemoveRange(existingRows);
var entities = finalSchedules var entities = finalSchedules
.SelectMany(x => ToWeeklyEntities(parsedStoreId, long.Parse(x.StaffId), x.Shifts)) .SelectMany(x => ToWeeklyEntities(parsedStoreId, long.Parse(x.StaffId), x.Shifts, template))
.ToList(); .ToList();
await dbContext.StoreStaffWeeklySchedules.AddRangeAsync(entities, cancellationToken); await dbContext.StoreStaffWeeklySchedules.AddRangeAsync(entities, cancellationToken);
await dbContext.SaveChangesAsync(cancellationToken); await dbContext.SaveChangesAsync(cancellationToken);
@@ -407,6 +416,8 @@ public sealed class StoreStaffController(
StoreId = parsedStoreId.ToString(), StoreId = parsedStoreId.ToString(),
WeekStartDate = StoreApiHelpers.ResolveWeekStartDate(null), WeekStartDate = StoreApiHelpers.ResolveWeekStartDate(null),
Templates = template, Templates = template,
IsTemplateConfigured = true,
IsScheduleConfigured = entities.Count > 0,
Schedules = finalSchedules Schedules = finalSchedules
}); });
} }
@@ -451,7 +462,11 @@ public sealed class StoreStaffController(
}); });
} }
var sourceTemplate = await GetOrCreateTemplateDtoAsync(tenantId, sourceStoreId, cancellationToken); var sourceTemplate = await GetTemplateDtoAsync(tenantId, sourceStoreId, cancellationToken);
if (sourceTemplate is null)
{
throw new BusinessException(ErrorCodes.BadRequest, "源门店未配置班次模板,无法复制");
}
var sourceRows = await dbContext.StoreStaffWeeklySchedules var sourceRows = await dbContext.StoreStaffWeeklySchedules
.AsNoTracking() .AsNoTracking()
.Where(x => x.TenantId == tenantId && x.StoreId == sourceStoreId) .Where(x => x.TenantId == tenantId && x.StoreId == sourceStoreId)
@@ -465,14 +480,14 @@ public sealed class StoreStaffController(
.GroupBy(x => x.StaffId) .GroupBy(x => x.StaffId)
.ToDictionary( .ToDictionary(
x => x.Key, x => x.Key,
x => NormalizeRowsToShifts(x.ToList(), sourceStaffMap.GetValueOrDefault(x.Key), sourceTemplate)); x => NormalizeRowsToShifts(x.ToList(), sourceTemplate));
var sourceScheduleSequence = sourceStaffs var sourceScheduleSequence = sourceStaffs
.OrderBy(x => x.CreatedAt) .OrderBy(x => x.CreatedAt)
.ThenBy(x => x.Name) .ThenBy(x => x.Name)
.ThenBy(x => x.Id) .ThenBy(x => x.Id)
.Select(staff => staff.Status == StaffStatus.Resigned .Select(staff => staff.Status == StaffStatus.Resigned
? CreateOffWeekShifts() ? CreateOffWeekShifts()
: sourceScheduleMap.GetValueOrDefault(staff.Id) ?? CreateDefaultWeekByRole(staff.RoleType, sourceTemplate)) : sourceScheduleMap.GetValueOrDefault(staff.Id) ?? [])
.ToList(); .ToList();
var targetTemplates = await dbContext.StoreStaffTemplates var targetTemplates = await dbContext.StoreStaffTemplates
@@ -526,9 +541,9 @@ public sealed class StoreStaffController(
? CreateOffWeekShifts() ? CreateOffWeekShifts()
: sourceScheduleSequence.Count > 0 : sourceScheduleSequence.Count > 0
? sourceScheduleSequence[index % sourceScheduleSequence.Count] ? sourceScheduleSequence[index % sourceScheduleSequence.Count]
: CreateDefaultWeekByRole(staff.RoleType, sourceTemplate); : [];
entities.AddRange(ToWeeklyEntities(targetStoreId, staff.Id, shifts)); entities.AddRange(ToWeeklyEntities(targetStoreId, staff.Id, shifts, sourceTemplate));
} }
} }
@@ -602,7 +617,7 @@ public sealed class StoreStaffController(
return normalized; return normalized;
} }
private async Task<StoreShiftTemplatesDto> GetOrCreateTemplateDtoAsync(long tenantId, long storeId, CancellationToken cancellationToken) private async Task<StoreShiftTemplatesDto?> GetTemplateDtoAsync(long tenantId, long storeId, CancellationToken cancellationToken)
{ {
var entity = await dbContext.StoreStaffTemplates var entity = await dbContext.StoreStaffTemplates
.AsNoTracking() .AsNoTracking()
@@ -610,7 +625,7 @@ public sealed class StoreStaffController(
if (entity is null) if (entity is null)
{ {
return CreateDefaultTemplate(); return null;
} }
return new StoreShiftTemplatesDto return new StoreShiftTemplatesDto
@@ -633,83 +648,44 @@ public sealed class StoreStaffController(
}; };
} }
private async Task EnsureStaffScheduleAsync(
long tenantId,
long storeId,
MerchantStaff staff,
StoreShiftTemplatesDto template,
CancellationToken cancellationToken)
{
var existingRows = await dbContext.StoreStaffWeeklySchedules
.Where(x => x.TenantId == tenantId && x.StoreId == storeId && x.StaffId == staff.Id)
.ToListAsync(cancellationToken);
if (existingRows.Count == 0)
{
var initialShifts = staff.Status == StaffStatus.Resigned
? CreateOffWeekShifts()
: CreateDefaultWeekByRole(staff.RoleType, template);
await dbContext.StoreStaffWeeklySchedules.AddRangeAsync(
ToWeeklyEntities(storeId, staff.Id, initialShifts),
cancellationToken);
}
else if (staff.Status == StaffStatus.Resigned)
{
dbContext.StoreStaffWeeklySchedules.RemoveRange(existingRows);
await dbContext.StoreStaffWeeklySchedules.AddRangeAsync(
ToWeeklyEntities(storeId, staff.Id, CreateOffWeekShifts()),
cancellationToken);
}
await dbContext.SaveChangesAsync(cancellationToken);
}
private static StoreShiftTemplatesDto NormalizeTemplate(StoreShiftTemplatesDto source) private static StoreShiftTemplatesDto NormalizeTemplate(StoreShiftTemplatesDto source)
{ {
var fallback = CreateDefaultTemplate(); source ??= new StoreShiftTemplatesDto();
return new StoreShiftTemplatesDto return new StoreShiftTemplatesDto
{ {
Morning = new ShiftTemplateItemDto Morning = new ShiftTemplateItemDto
{ {
StartTime = NormalizeTime(source.Morning.StartTime, fallback.Morning.StartTime), StartTime = NormalizeTime(source.Morning.StartTime, string.Empty),
EndTime = NormalizeTime(source.Morning.EndTime, fallback.Morning.EndTime) EndTime = NormalizeTime(source.Morning.EndTime, string.Empty)
}, },
Evening = new ShiftTemplateItemDto Evening = new ShiftTemplateItemDto
{ {
StartTime = NormalizeTime(source.Evening.StartTime, fallback.Evening.StartTime), StartTime = NormalizeTime(source.Evening.StartTime, string.Empty),
EndTime = NormalizeTime(source.Evening.EndTime, fallback.Evening.EndTime) EndTime = NormalizeTime(source.Evening.EndTime, string.Empty)
}, },
Full = new ShiftTemplateItemDto Full = new ShiftTemplateItemDto
{ {
StartTime = NormalizeTime(source.Full.StartTime, fallback.Full.StartTime), StartTime = NormalizeTime(source.Full.StartTime, string.Empty),
EndTime = NormalizeTime(source.Full.EndTime, fallback.Full.EndTime) EndTime = NormalizeTime(source.Full.EndTime, string.Empty)
} }
}; };
} }
private static List<StaffDayShiftDto> NormalizeRowsToShifts( private static List<StaffDayShiftDto> NormalizeRowsToShifts(
List<StoreStaffWeeklySchedule> rows, List<StoreStaffWeeklySchedule> rows,
MerchantStaff? staff,
StoreShiftTemplatesDto template) StoreShiftTemplatesDto template)
{ {
var fallback = staff is null ? CreateOffWeekShifts() : CreateDefaultWeekByRole(staff.RoleType, template);
var rowMap = rows.ToDictionary(x => x.DayOfWeek, x => x);
var results = new List<StaffDayShiftDto>(); var results = new List<StaffDayShiftDto>();
foreach (var row in rows
for (var day = 0; day < 7; day++) .Where(x => x.DayOfWeek is >= 0 and <= 6)
.OrderBy(x => x.DayOfWeek))
{ {
if (!rowMap.TryGetValue(day, out var row))
{
results.Add(fallback[day]);
continue;
}
var shiftType = StoreApiHelpers.ToShiftTypeText(row.ShiftType); var shiftType = StoreApiHelpers.ToShiftTypeText(row.ShiftType);
if (row.ShiftType == StoreStaffShiftType.Off) if (row.ShiftType == StoreStaffShiftType.Off)
{ {
results.Add(new StaffDayShiftDto results.Add(new StaffDayShiftDto
{ {
DayOfWeek = day, DayOfWeek = row.DayOfWeek,
ShiftType = shiftType, ShiftType = shiftType,
StartTime = string.Empty, StartTime = string.Empty,
EndTime = string.Empty EndTime = string.Empty
@@ -720,7 +696,7 @@ public sealed class StoreStaffController(
var (defaultStart, defaultEnd) = ResolveShiftTimeRange(row.ShiftType, template); var (defaultStart, defaultEnd) = ResolveShiftTimeRange(row.ShiftType, template);
results.Add(new StaffDayShiftDto results.Add(new StaffDayShiftDto
{ {
DayOfWeek = day, DayOfWeek = row.DayOfWeek,
ShiftType = shiftType, ShiftType = shiftType,
StartTime = StoreApiHelpers.ToHHmm(row.StartTime ?? defaultStart ?? TimeSpan.Zero), StartTime = StoreApiHelpers.ToHHmm(row.StartTime ?? defaultStart ?? TimeSpan.Zero),
EndTime = StoreApiHelpers.ToHHmm(row.EndTime ?? defaultEnd ?? TimeSpan.Zero) EndTime = StoreApiHelpers.ToHHmm(row.EndTime ?? defaultEnd ?? TimeSpan.Zero)
@@ -743,16 +719,11 @@ public sealed class StoreStaffController(
var normalized = new List<StaffDayShiftDto>(); var normalized = new List<StaffDayShiftDto>();
for (var day = 0; day < 7; day++) for (var day = 0; day < 7; day++)
{ {
var fallbackShift = fallback.FirstOrDefault(x => x.DayOfWeek == day) ?? new StaffDayShiftDto var fallbackShift = fallback.FirstOrDefault(x => x.DayOfWeek == day);
{
DayOfWeek = day,
ShiftType = "off",
StartTime = string.Empty,
EndTime = string.Empty
};
if (!inputMap.TryGetValue(day, out var input)) if (!inputMap.TryGetValue(day, out var input))
{ {
if (fallbackShift is null) continue;
normalized.Add(new StaffDayShiftDto normalized.Add(new StaffDayShiftDto
{ {
DayOfWeek = day, DayOfWeek = day,
@@ -781,8 +752,16 @@ public sealed class StoreStaffController(
{ {
DayOfWeek = day, DayOfWeek = day,
ShiftType = StoreApiHelpers.ToShiftTypeText(shiftType), ShiftType = StoreApiHelpers.ToShiftTypeText(shiftType),
StartTime = NormalizeTime(input.StartTime, defaultStart.HasValue ? StoreApiHelpers.ToHHmm(defaultStart.Value) : fallbackShift.StartTime), StartTime = NormalizeTime(
EndTime = NormalizeTime(input.EndTime, defaultEnd.HasValue ? StoreApiHelpers.ToHHmm(defaultEnd.Value) : fallbackShift.EndTime) input.StartTime,
defaultStart.HasValue
? StoreApiHelpers.ToHHmm(defaultStart.Value)
: fallbackShift?.StartTime ?? string.Empty),
EndTime = NormalizeTime(
input.EndTime,
defaultEnd.HasValue
? StoreApiHelpers.ToHHmm(defaultEnd.Value)
: fallbackShift?.EndTime ?? string.Empty)
}); });
} }
@@ -792,21 +771,22 @@ public sealed class StoreStaffController(
private static IEnumerable<StoreStaffWeeklySchedule> ToWeeklyEntities( private static IEnumerable<StoreStaffWeeklySchedule> ToWeeklyEntities(
long storeId, long storeId,
long staffId, long staffId,
IEnumerable<StaffDayShiftDto> shifts) IEnumerable<StaffDayShiftDto> shifts,
StoreShiftTemplatesDto template)
{ {
foreach (var shift in shifts) foreach (var shift in shifts)
{ {
var shiftType = StoreApiHelpers.ToShiftType(shift.ShiftType); var shiftType = StoreApiHelpers.ToShiftType(shift.ShiftType);
var (defaultStart, defaultEnd) = ResolveShiftTimeRange(shiftType, CreateDefaultTemplate()); var (defaultStart, defaultEnd) = ResolveShiftTimeRange(shiftType, template);
var startTime = shiftType == StoreStaffShiftType.Off var startTime = shiftType == StoreStaffShiftType.Off
? null ? null
: (TimeSpan?)StoreApiHelpers.ParseRequiredTime( : (TimeSpan?)StoreApiHelpers.ParseRequiredTime(
NormalizeTime(shift.StartTime, defaultStart.HasValue ? StoreApiHelpers.ToHHmm(defaultStart.Value) : "09:00"), NormalizeTime(shift.StartTime, defaultStart.HasValue ? StoreApiHelpers.ToHHmm(defaultStart.Value) : string.Empty),
"shift.startTime"); "shift.startTime");
var endTime = shiftType == StoreStaffShiftType.Off var endTime = shiftType == StoreStaffShiftType.Off
? null ? null
: (TimeSpan?)StoreApiHelpers.ParseRequiredTime( : (TimeSpan?)StoreApiHelpers.ParseRequiredTime(
NormalizeTime(shift.EndTime, defaultEnd.HasValue ? StoreApiHelpers.ToHHmm(defaultEnd.Value) : "21:00"), NormalizeTime(shift.EndTime, defaultEnd.HasValue ? StoreApiHelpers.ToHHmm(defaultEnd.Value) : string.Empty),
"shift.endTime"); "shift.endTime");
yield return new StoreStaffWeeklySchedule yield return new StoreStaffWeeklySchedule
@@ -821,34 +801,6 @@ public sealed class StoreStaffController(
} }
} }
private static List<StaffDayShiftDto> CreateDefaultWeekByRole(StaffRoleType roleType, StoreShiftTemplatesDto template)
{
var pattern = roleType switch
{
StaffRoleType.Admin or StaffRoleType.Operator => new[] { "full", "full", "full", "full", "full", "morning", "off" },
StaffRoleType.FrontDesk => new[] { "morning", "morning", "off", "morning", "evening", "full", "full" },
StaffRoleType.Courier => new[] { "morning", "evening", "morning", "evening", "morning", "evening", "off" },
StaffRoleType.Kitchen => new[] { "full", "full", "evening", "off", "full", "full", "morning" },
_ => new[] { "morning", "morning", "off", "morning", "evening", "full", "full" }
};
var results = new List<StaffDayShiftDto>();
for (var day = 0; day < 7; day++)
{
var shiftType = StoreApiHelpers.ToShiftType(pattern[day]);
var (start, end) = ResolveShiftTimeRange(shiftType, template);
results.Add(new StaffDayShiftDto
{
DayOfWeek = day,
ShiftType = StoreApiHelpers.ToShiftTypeText(shiftType),
StartTime = start.HasValue ? StoreApiHelpers.ToHHmm(start.Value) : string.Empty,
EndTime = end.HasValue ? StoreApiHelpers.ToHHmm(end.Value) : string.Empty
});
}
return results;
}
private static List<StaffDayShiftDto> CreateOffWeekShifts() private static List<StaffDayShiftDto> CreateOffWeekShifts()
{ {
return Enumerable.Range(0, 7).Select(day => new StaffDayShiftDto return Enumerable.Range(0, 7).Select(day => new StaffDayShiftDto
@@ -883,26 +835,4 @@ public sealed class StoreStaffController(
? StoreApiHelpers.ToHHmm(parsed) ? StoreApiHelpers.ToHHmm(parsed)
: fallback; : fallback;
} }
private static StoreShiftTemplatesDto CreateDefaultTemplate()
{
return new StoreShiftTemplatesDto
{
Morning = new ShiftTemplateItemDto
{
StartTime = "09:00",
EndTime = "14:00"
},
Evening = new ShiftTemplateItemDto
{
StartTime = "14:00",
EndTime = "21:00"
},
Full = new ShiftTemplateItemDto
{
StartTime = "09:00",
EndTime = "21:00"
}
};
}
} }