fix: closing the week early should count properly
This commit is contained in:
@@ -197,9 +197,11 @@ func (s *WeekService) CloseWeek(ctx context.Context, weekKey string) (*domain.Cl
|
|||||||
// Compute expected ms for the week (from settings frozen at week start)
|
// Compute expected ms for the week (from settings frozen at week start)
|
||||||
expectedMs := int64(set.HoursPerWeek * 3_600_000)
|
expectedMs := int64(set.HoursPerWeek * 3_600_000)
|
||||||
|
|
||||||
// Verify all past workdays that have entries are closed; collect worked ms.
|
// Collect worked ms across all workdays in the week.
|
||||||
// Past workdays with no entries at all are skipped (they contribute 0h).
|
// A workday is included if it has a closed_days record — whether past or future
|
||||||
// Future workdays in the week are always skipped.
|
// (future days can be pre-marked as holiday/vacation before closing the week early).
|
||||||
|
// Past workdays with open entries require an explicit close before the week can close.
|
||||||
|
// Past workdays with no record and no entries contribute 0h.
|
||||||
todayKey := s.clock.Now().In(s.tz).Format("2006-01-02")
|
todayKey := s.clock.Now().In(s.tz).Format("2006-01-02")
|
||||||
var totalWorkedMs int64
|
var totalWorkedMs int64
|
||||||
for _, dk := range dayKeys {
|
for _, dk := range dayKeys {
|
||||||
@@ -207,18 +209,20 @@ func (s *WeekService) CloseWeek(ctx context.Context, weekKey string) (*domain.Cl
|
|||||||
if !set.IsWorkday(int(t.Weekday())) {
|
if !set.IsWorkday(int(t.Weekday())) {
|
||||||
continue // weekend or non-workday — skip
|
continue // weekend or non-workday — skip
|
||||||
}
|
}
|
||||||
if dk > todayKey {
|
|
||||||
continue // future workday — skip
|
|
||||||
}
|
|
||||||
cd, err := s.closedDays.GetByDayKey(ctx, dk)
|
cd, err := s.closedDays.GetByDayKey(ctx, dk)
|
||||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if cd != nil {
|
if cd != nil {
|
||||||
|
// Already closed (past or pre-marked future) — count it.
|
||||||
totalWorkedMs += cd.WorkedMs
|
totalWorkedMs += cd.WorkedMs
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// No closed_days record — check whether the day has any entries.
|
if dk > todayKey {
|
||||||
|
// Future workday with no closed record — entries are impossible, skip.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Past/today workday with no closed record — check whether entries exist.
|
||||||
dayEntries, err := s.entries.ListByDayKey(ctx, dk)
|
dayEntries, err := s.entries.ListByDayKey(ctx, dk)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ func TestCloseWeekMidWeek(t *testing.T) {
|
|||||||
t.Errorf("expected_ms: want %s, got %s", wantExpected, time.Duration(cw.ExpectedMs)*time.Millisecond)
|
t.Errorf("expected_ms: want %s, got %s", wantExpected, time.Duration(cw.ExpectedMs)*time.Millisecond)
|
||||||
}
|
}
|
||||||
const wantDelta = wantWorked - wantExpected // −11.5h
|
const wantDelta = wantWorked - wantExpected // −11.5h
|
||||||
if cw.DeltaMs != int64(wantDelta) {
|
if cw.DeltaMs != int64(wantDelta/time.Millisecond) {
|
||||||
t.Errorf("delta_ms: want %s, got %s", wantDelta, time.Duration(cw.DeltaMs)*time.Millisecond)
|
t.Errorf("delta_ms: want %s, got %s", wantDelta, time.Duration(cw.DeltaMs)*time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user