fix(flex): deduct PaiedOutFlex from SumFlexEnd on UseOneMinuteIntervals sites - #1692
Merged
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes paid-out flex (PaiedOutFlex) not being deducted from SumFlexEnd on UseOneMinuteIntervals=true sites by adding a seconds-column fallback on the read-time flex chain and keeping seconds fields updated in the “set flex” endpoint, with regression tests covering the production scenario and Excel export output.
Changes:
- Add
PaiedOutFlexSecondsWithFallbackand use it inApplyRunningFlexChainso flag-on sites deduct paid-out flex even whenPaiedOutFlexInSecondsis unpopulated. - Update
TimePlanningFlexService.UpdatePlanningto updatePaiedOutFlexInSecondsand adjustSumFlexEndInSecondsalongside legacy double fields. - Add E2E regression tests for the fallback behavior and for the exported Dashboard sheet
SumFlexEndcell value.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/TimePlanningWorkingHoursService/TimePlanningWorkingHoursService.cs | Adds a paid-out-flex seconds fallback and applies it in the running flex chain for one-minute-interval sites. |
| eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/TimePlanningFlexService/TimePlanningFlexService.cs | Keeps PaiedOutFlexInSeconds / SumFlexEndInSeconds in sync when updating paid-out flex. |
| eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/WorkingHoursExcelExportE2ETests.cs | Adds regression tests validating fallback behavior and Excel export SumFlexEnd output. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+975
to
+978
| return string.IsNullOrEmpty(model.PaidOutFlex) | ||
| ? 0 | ||
| : (int)Math.Round( | ||
| double.Parse(model.PaidOutFlex.Replace(",", "."), CultureInfo.InvariantCulture) * 3600); |
Comment on lines
+251
to
+265
| // PaiedOutFlexInSeconds is the source the flag-on flex chain | ||
| // (PlanRegistrationHelper.ApplyNettoFlexChainSecondPrecision / | ||
| // TimePlanningWorkingHoursService.ApplyRunningFlexChain) subtracts. Only ever | ||
| // updating the legacy double below would leave that column stale, so keep it | ||
| // in lockstep here too. Old value falls back to the double the same way those | ||
| // chains do, since this row may itself have only ever had the double set. | ||
| var oldPaiedOutFlexSeconds = planRegistration.PaiedOutFlexInSeconds != 0 | ||
| ? planRegistration.PaiedOutFlexInSeconds | ||
| : (int)Math.Round(planRegistration.PaiedOutFlex * 3600); | ||
| var newPaiedOutFlexSeconds = (int)Math.Round(model.PaidOutFlex * 3600); | ||
|
|
||
| planRegistration.SumFlexEnd += planRegistration.PaiedOutFlex - model.PaidOutFlex; | ||
| planRegistration.SumFlexEndInSeconds += oldPaiedOutFlexSeconds - newPaiedOutFlexSeconds; | ||
| planRegistration.PaiedOutFlex = model.PaidOutFlex; | ||
| planRegistration.PaiedOutFlexInSeconds = newPaiedOutFlexSeconds; |
…ls sites On sites with UseOneMinuteIntervals=true, the Excel export, dashboard, and mobile period-status hero all render SumFlexEnd via TimePlanningWorkingHoursService.ApplyRunningFlexChain, which subtracted PaiedOutFlexInSeconds directly. No production writer ever populates that int column -- only the legacy double PaiedOutFlex/PaidOutFlex fields get written -- so it stayed 0 forever and a user-set PaiedOutFlex silently stopped reducing SumFlexEnd on flag-on sites. PlanRegistrationHelper.ApplyNettoFlexChainSecondPrecision (the write-time sibling of this chain) already carried a tested fallback for exactly this case. Add the same fallback to the read-time chain via a shared PaiedOutFlexSecondsWithFallback helper, and keep TimePlanningFlexService.UpdatePlanning's PaiedOutFlexInSeconds / SumFlexEndInSeconds columns in lockstep with the doubles it already updated, so the "set flex" endpoint doesn't leave those columns stale. Add regression coverage to the existing, CI-wired WorkingHoursExcelExportE2ETests: two tests on the read-time chain via Index() (fallback path, and confirming a populated PaiedOutFlexInSeconds still wins over the double), plus one exercising the real export path via OpenXml to assert the exported SumFlexEnd cell value, not just its column position. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WYHEYf7V1oJyPrLRLAWg6e
renemadsen
force-pushed
the
fix/paidoutflex-sumflexend-deduction
branch
from
August 28, 2026 07:54
63483eb to
a47f6e2
Compare
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
UseOneMinuteIntervals=truesites, the Excel export / dashboard / mobile period-status hero all renderSumFlexEndviaTimePlanningWorkingHoursService.ApplyRunningFlexChain, which subtractedPaiedOutFlexInSecondsdirectly. No production writer ever populates that int column — only the legacy doublePaiedOutFlex/PaidOutFlexfields get written — so it stayed0forever, and a user-setPaiedOutFlexsilently stopped reducingSumFlexEndon flag-on sites.PlanRegistrationHelper.ApplyNettoFlexChainSecondPrecision(the write-time sibling of this chain) already had a tested fallback for exactly this case (PaiedOutFlexInSeconds != 0 ? that : PaiedOutFlex * 3600). This PR adds the same fallback to the read-time chain via a sharedPaiedOutFlexSecondsWithFallbackhelper.TimePlanningFlexService.UpdatePlanning(the dedicated "set flex" endpoint), which only updated the legacy double fields and leftPaiedOutFlexInSeconds/SumFlexEndInSecondspermanently stale — now kept in lockstep using the same fallback-based delta.Test plan
WorkingHoursExcelExportE2ETestsclass:Index_FlagOn_PaiedOutFlexInSecondsZero_FallsBackToPaidOutFlexDouble— the production scenario (double set, seconds column at its DB default of 0); would have failed pre-fix.Index_FlagOn_PaiedOutFlexInSecondsSet_UsesStoredSecondsOverDouble— confirms a populated seconds column still wins over the double.GenerateExcelDashboard_FlagOn_PaiedOutFlexSet_SumFlexEndCellDeductsIt— exercises the real export path via OpenXml, asserting the exportedSumFlexEndcell value, not just column position (the existing export tests only ever asserted column layout).dotnet buildclean on both the plugin project and the test project (no new warnings).dotnet testwas run per instruction; relying on CI to execute the new tests.🤖 Generated with Claude Code
https://claude.ai/code/session_01WYHEYf7V1oJyPrLRLAWg6e