Skip to content

fix(export): per-worker pay-code columns in the all-workers report#1604

Merged
renemadsen merged 1 commit into
stablefrom
fix/per-worker-paycode-columns
Jun 10, 2026
Merged

fix(export): per-worker pay-code columns in the all-workers report#1604
renemadsen merged 1 commit into
stablefrom
fix/per-worker-paycode-columns

Conversation

@renemadsen

Copy link
Copy Markdown
Member

The bug

In the all-workers Excel export, each per-site (per-worker) sheet showed pay-code columns for the global union of pay codes across all workers — so whenever any worker had an active pay-rule-set, every worker's sheet got every pay code (filled 0 for codes that weren't theirs).

The fix

Each per-site sheet now shows only the pay codes declared in that worker's own pay-rule-set (none if the worker has no rule-set). Workers with different pay-rule-sets get different columns.

  • New internal static GetDeclaredPayCodes(PayRuleSet) — collects a rule-set's declared codes (day-rule tiers by Order, day-type default + time-band codes, holiday code), de-duplicated, skipping null/empty, empty for null.
  • The all-workers per-site loop uses these per-site codes for the sheet header, per-day cells, and totals row (via GetValueOrDefault for declared codes with no hours this period).

Unchanged (by design)

  • The Total summary sheet keeps the union of codes (one shared grid; each row fills only its own, 0 elsewhere) — its allPayCodes/siteTotalsByPayCode are untouched, so it's byte-identical.
  • The single-worker export (already correct).

Tests

  • Unit (PlanRegistrationHelperTests, shard f): GetDeclaredPayCodes across all four sources, dedup, tier ordering, null/empty.
  • Export E2E (DagsoversigtWorksheetExportTests, shard g): seeds two sites with different pay-rule-sets + one with none; asserts each per-site sheet has only its own code, the no-rule-set sheet has none, and the Total sheet keeps the union. Verified it fails under the old global-union behavior.

🤖 Generated with Claude Code

In the all-workers Excel export, each per-site (per-worker) sheet showed pay-code
columns for the GLOBAL union of pay codes across all workers — so whenever any
worker had an active pay-rule-set, every worker's sheet got every pay code
(filled 0 for codes that weren't theirs).

Now each per-site sheet shows only the pay codes DECLARED in that worker's own
pay-rule-set (none if the worker has no rule-set). The Total summary sheet is
unchanged (keeps the union), and the single-worker export was already correct.

- New internal static GetDeclaredPayCodes(PayRuleSet) collects a rule-set's
  declared codes (day-rule tiers by Order, day-type default + time-band codes,
  holiday code), de-duplicated, skipping null/empty, empty for null.
- The all-workers per-site loop now uses these per-site codes for the sheet
  header, per-day cells, and totals row (via GetValueOrDefault for declared
  codes with no hours). The global allPayCodes and siteTotalsByPayCode that
  feed the Total sheet are untouched.

Tests: unit tests for GetDeclaredPayCodes (PlanRegistrationHelperTests, shard f);
an all-workers export test seeding two sites with different pay-rule-sets + one
with none, asserting each per-site sheet has only its own codes and the Total
sheet keeps the union (DagsoversigtWorksheetExportTests, shard g).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 10, 2026 13:15

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 the all-workers Excel export so each per-site (per-worker) worksheet only includes pay-code columns declared by that worker’s own pay-rule-set (or none when no rule-set), while keeping the Total summary sheet behavior unchanged.

Changes:

  • Updated the all-workers per-site sheet generation to use per-site sitePayCodes for header, daily cells, and totals row.
  • Added GetDeclaredPayCodes(PayRuleSet) helper to extract declared pay codes in a stable structural order with de-duplication.
  • Added unit and E2E export tests to lock in per-site vs Total-sheet pay-code column behavior; added supporting design/plan docs.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/TimePlanningWorkingHoursService/TimePlanningWorkingHoursService.cs Adds declared-pay-code extraction helper and switches per-site sheets to per-worker pay-code columns.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/PlanRegistrationHelperTests.cs Unit tests for GetDeclaredPayCodes (sources, ordering, dedup, null/empty handling).
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/DagsoversigtWorksheetExportTests.cs E2E regression test ensuring per-site sheets differ by rule-set while Total sheet keeps union.
docs/superpowers/specs/2026-06-10-per-worker-paycode-columns-design.md Design spec documenting intended behavior and constraints (Total sheet unchanged).
docs/superpowers/plans/2026-06-10-per-worker-paycode-columns.md Implementation plan capturing verified facts, steps, and test strategy.

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

Comment on lines +3949 to +3963
internal static List<string> GetDeclaredPayCodes(PayRuleSet payRuleSet)
{
var codes = new List<string>();
if (payRuleSet == null)
{
return codes;
}

void Add(string code)
{
if (!string.IsNullOrWhiteSpace(code) && !codes.Contains(code))
{
codes.Add(code);
}
}
@renemadsen renemadsen merged commit 98f1892 into stable Jun 10, 2026
74 of 76 checks passed
@renemadsen renemadsen deleted the fix/per-worker-paycode-columns branch June 10, 2026 14:55
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