feat(attendance): add SetCountsAsync to set all three age groups for a date

This commit is contained in:
Chris Chen
2026-06-24 11:14:09 -07:00
parent 182f8bf74c
commit 8d91bbeb31
3 changed files with 85 additions and 0 deletions
@@ -22,6 +22,13 @@ public interface IMealAttendanceService
/// </summary>
Task<AttendanceCountsDto> SetAsync(DateOnly date, string category, int value);
/// <summary>
/// Overwrites all three age-group columns for <paramref name="date"/> with absolute
/// values (each clamped at zero), creating the row if it does not exist, and returns
/// the resulting authoritative counts. Used by the back-office Sunday-attendance editor.
/// </summary>
Task<AttendanceCountsDto> SetCountsAsync(DateOnly date, int adult, int youth, int kid);
/// <summary>Returns the daily counts within the inclusive date range, ordered by date (for the dashboard).</summary>
Task<IReadOnlyList<AttendanceCountsDto>> GetRangeAsync(DateOnly from, DateOnly to);
}
@@ -82,6 +82,24 @@ public class MealAttendanceService : IMealAttendanceService
return await ReadAsync(date);
}
public async Task<AttendanceCountsDto> SetCountsAsync(DateOnly date, int adult, int youth, int kid)
{
var row = await _db.MealAttendances.FirstOrDefaultAsync(a => a.AttendanceDate == date);
if (row is null)
{
row = new MealAttendance { AttendanceDate = date };
_db.MealAttendances.Add(row);
}
// Counts can never be negative; clamp before writing.
row.AdultCount = adult < 0 ? 0 : adult;
row.YouthCount = youth < 0 ? 0 : youth;
row.KidCount = kid < 0 ? 0 : kid;
await _db.SaveChangesAsync();
return ToDto(row);
}
public async Task<IReadOnlyList<AttendanceCountsDto>> GetRangeAsync(DateOnly from, DateOnly to)
{
var rows = await _db.MealAttendances.AsNoTracking()