Skip to content

fix(flex): deduct PaiedOutFlex from SumFlexEnd on UseOneMinuteIntervals sites - #1692

Merged
renemadsen merged 1 commit into
stablefrom
fix/paidoutflex-sumflexend-deduction
Aug 28, 2026
Merged

fix(flex): deduct PaiedOutFlex from SumFlexEnd on UseOneMinuteIntervals sites#1692
renemadsen merged 1 commit into
stablefrom
fix/paidoutflex-sumflexend-deduction

Conversation

@renemadsen

Copy link
Copy Markdown
Member

Summary

  • On UseOneMinuteIntervals=true sites, the Excel export / dashboard / 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 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 shared PaiedOutFlexSecondsWithFallback helper.
  • Also fixes TimePlanningFlexService.UpdatePlanning (the dedicated "set flex" endpoint), which only updated the legacy double fields and left PaiedOutFlexInSeconds/SumFlexEndInSeconds permanently stale — now kept in lockstep using the same fallback-based delta.
  • Root-caused via git history + parallel code-path tracing (two research subagents) and verified with a code-review pass before commit; see [PR discussion] for the investigation writeup.

Test plan

  • Added 3 regression tests to the existing, CI-wired WorkingHoursExcelExportE2ETests class:
    • 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 exported SumFlexEnd cell value, not just column position (the existing export tests only ever asserted column layout).
  • dotnet build clean on both the plugin project and the test project (no new warnings).
  • CI run on this PR — no local dotnet test was run per instruction; relying on CI to execute the new tests.

🤖 Generated with Claude Code

https://claude.ai/code/session_01WYHEYf7V1oJyPrLRLAWg6e

Copilot AI lite review requested due to automatic review settings August 28, 2026 07:30

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 PaiedOutFlexSecondsWithFallback and use it in ApplyRunningFlexChain so flag-on sites deduct paid-out flex even when PaiedOutFlexInSeconds is unpopulated.
  • Update TimePlanningFlexService.UpdatePlanning to update PaiedOutFlexInSeconds and adjust SumFlexEndInSeconds alongside legacy double fields.
  • Add E2E regression tests for the fallback behavior and for the exported Dashboard sheet SumFlexEnd cell 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
renemadsen force-pushed the fix/paidoutflex-sumflexend-deduction branch from 63483eb to a47f6e2 Compare August 28, 2026 07:54
@renemadsen
renemadsen merged commit 5918b18 into stable Aug 28, 2026
76 of 77 checks passed
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