Skip to content

fix: honor UseOneMinuteIntervals when aggregating PauseMinutes#1566

Merged
renemadsen merged 1 commit intostablefrom
feat/pause-aggregate-one-minute
May 7, 2026
Merged

fix: honor UseOneMinuteIntervals when aggregating PauseMinutes#1566
renemadsen merged 1 commit intostablefrom
feat/pause-aggregate-one-minute

Conversation

@renemadsen
Copy link
Copy Markdown
Member

Summary

Customer 855 with AssignedSite.UseOneMinuteIntervals=true was seeing "Samlet pause" displayed in 5-minute increments on both Angular web and Flutter device — a 3-minute pause showed as "0" on both clients.

Root cause

PauseMinutes aggregation in PlanRegistrationHelper.UpdatePlanRegistrationsInPeriod used the legacy 5-min-tick formula (Pause*Id * 5) - 5 regardless of the flag. The legacy storage formula Pause*Id = (minutes / 5) + 1 makes a 3-min pause become Pause1Id=1, and display becomes (1*5)-5 = 0. The Phase 2 rollout (ac2730a5) wired second-precision into NettoHours/Flex but missed pause display.

Fix

  • New helper AggregatePauseMinutes(PlanRegistration pr, bool useOneMinuteIntervals) in PlanRegistrationHelper. Flag-on: sums Pause*StoppedAt - Pause*StartedAt DateTime deltas in seconds across all 5 slots, rounds down to whole minutes. Flag-off: legacy formula.
  • Single call site at UpdatePlanRegistrationsInPeriod (one line replaces five ternaries) passes dbAssignedSite.UseOneMinuteIntervals.
  • 5 new unit tests in PlanRegistrationHelperTests.

What didn't change

  • No client changes — Flutter (personal_view_widget.dart) and Angular both already correctly display the number from the backend.
  • Full-day handover, partial handover, NettoHours/Flex computation — all untouched.
  • No eform-timeplanning-base edits.

Test plan

  • CI green
  • Deploy to 855
  • Worker on a UseOneMinuteIntervals=true site records a 3-min pause; verify "Samlet pause" displays as 3 (not 0) on both web admin and Flutter device
  • Worker on a UseOneMinuteIntervals=false site records a 15-min pause via legacy Pause1Id=4; verify it still displays as 15 (no regression on legacy path)

🤖 Generated with Claude Code

Customer 855 with AssignedSite.UseOneMinuteIntervals=true was seeing
"Samlet pause" displayed in 5-minute increments on both the Angular
web admin UI and the Flutter device app. A 3-minute pause showed as
"0" on both clients.

Root cause: PauseMinutes aggregation in
PlanRegistrationHelper.UpdatePlanRegistrationsInPeriod used the legacy
5-min-tick formula `(Pause*Id * 5) - 5` for each Pause1Id..Pause5Id,
with no fork on UseOneMinuteIntervals. The legacy storage formula is
`Pause*Id = (minutes / 5) + 1`, so a 3-min pause becomes Pause1Id=1
and the display formula returns `(1*5)-5 = 0`.

The Phase 2 rollout (commit ac2730a) wired second-precision into
NettoHours / Flex via ComputeNettoSecondsFromDateTimeShifts but
left the pause-display path on the legacy formula.

Fix:

* New public static helper AggregatePauseMinutes(PlanRegistration,
  bool useOneMinuteIntervals) in PlanRegistrationHelper. When the
  flag is on, sums Pause1..5StartedAt/StoppedAt DateTime deltas in
  seconds across the 5 pause slots that have BOTH stamps populated,
  rounds down to whole minutes. When off, falls back to the legacy
  (Pause*Id * 5) - 5 formula. Mirrors the existing
  ComputeNettoSecondsFromDateTimeShifts pattern.

* Replaces the 5 ternary `+=` expressions in
  UpdatePlanRegistrationsInPeriod with a single call passing
  dbAssignedSite.UseOneMinuteIntervals.

* Five new tests in PlanRegistrationHelperTests covering: 3-min
  flag-on round-trip (the actual fix), 3-min flag-off → 0 (documents
  intentional lossy legacy behavior), multi-slot summation, canonical
  15-min legacy formula, null-stamps-under-flag-on returning 0.

No client changes — Flutter and Angular already correctly display
whatever number the backend sends.

Plugin repo only — no edits to eform-timeplanning-base.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 7, 2026 15:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes pause-minute aggregation so sites with AssignedSite.UseOneMinuteIntervals=true display “Samlet pause” using the precise Pause*StartedAt/Pause*StoppedAt timestamps instead of the legacy 5-minute tick Pause*Id formula.

Changes:

  • Added PlanRegistrationHelper.AggregatePauseMinutes(pr, useOneMinuteIntervals) to compute pause minutes using timestamp deltas when one-minute intervals are enabled, otherwise using the legacy tick formula.
  • Updated UpdatePlanRegistrationsInPeriod to use the new helper instead of per-pause inline tick math.
  • Added unit tests covering flag-on precise pause aggregation and legacy behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Infrastructure/Helpers/PlanRegistrationHelper.cs Introduces AggregatePauseMinutes and switches pause aggregation in UpdatePlanRegistrationsInPeriod to honor UseOneMinuteIntervals.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/PlanRegistrationHelperTests.cs Adds unit tests for precise vs. legacy pause aggregation behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +466 to +475
if (useOneMinuteIntervals)
{
long totalSeconds = 0;
totalSeconds += PauseSpanSeconds(pr.Pause1StartedAt, pr.Pause1StoppedAt);
totalSeconds += PauseSpanSeconds(pr.Pause2StartedAt, pr.Pause2StoppedAt);
totalSeconds += PauseSpanSeconds(pr.Pause3StartedAt, pr.Pause3StoppedAt);
totalSeconds += PauseSpanSeconds(pr.Pause4StartedAt, pr.Pause4StoppedAt);
totalSeconds += PauseSpanSeconds(pr.Pause5StartedAt, pr.Pause5StoppedAt);
return (int)(totalSeconds / 60); // round down to whole minutes
}
Comment on lines +981 to +985
[Test]
public void AggregatePauseMinutes_OneMinuteInterval_NullStampsContributeZero()
{
// Arrange
var pr = new PlanRegistration
@renemadsen renemadsen merged commit 78cc057 into stable May 7, 2026
39 of 41 checks passed
@renemadsen renemadsen deleted the feat/pause-aggregate-one-minute branch May 7, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants