fix: honor UseOneMinuteIntervals when aggregating PauseMinutes#1566
Merged
renemadsen merged 1 commit intostablefrom May 7, 2026
Merged
fix: honor UseOneMinuteIntervals when aggregating PauseMinutes#1566renemadsen merged 1 commit intostablefrom
renemadsen merged 1 commit intostablefrom
Conversation
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>
There was a problem hiding this comment.
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
UpdatePlanRegistrationsInPeriodto 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Customer 855 with
AssignedSite.UseOneMinuteIntervals=truewas 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
PauseMinutesaggregation inPlanRegistrationHelper.UpdatePlanRegistrationsInPeriodused the legacy 5-min-tick formula(Pause*Id * 5) - 5regardless of the flag. The legacy storage formulaPause*Id = (minutes / 5) + 1makes a 3-min pause becomePause1Id=1, and display becomes(1*5)-5 = 0. The Phase 2 rollout (ac2730a5) wired second-precision into NettoHours/Flex but missed pause display.Fix
AggregatePauseMinutes(PlanRegistration pr, bool useOneMinuteIntervals)inPlanRegistrationHelper. Flag-on: sumsPause*StoppedAt - Pause*StartedAtDateTime deltas in seconds across all 5 slots, rounds down to whole minutes. Flag-off: legacy formula.UpdatePlanRegistrationsInPeriod(one line replaces five ternaries) passesdbAssignedSite.UseOneMinuteIntervals.PlanRegistrationHelperTests.What didn't change
personal_view_widget.dart) and Angular both already correctly display the number from the backend.eform-timeplanning-baseedits.Test plan
UseOneMinuteIntervals=truesite records a 3-min pause; verify "Samlet pause" displays as3(not0) on both web admin and Flutter deviceUseOneMinuteIntervals=falsesite records a 15-min pause via legacyPause1Id=4; verify it still displays as15(no regression on legacy path)🤖 Generated with Claude Code