fix: convert planning-line quantities to hours on the project list#201
Merged
Conversation
The project list's "Planned" column summed BCJobPlanningLine.quantity directly, with no UoM conversion. Resources entered in DAYs (e.g. 31.5 days for Cairn Homes – Support & Maintenance) showed up as 31.5 raw quantity in a column labelled "h", which then made the Remaining cell go strongly negative (276% spent of a 61h budget that should have been 237h). The project details page already converted via the per-resource UoM map, so the two views disagreed. - Add `sumPlannedHours(planningLines, uomMap)` and `isBudgetPlanningLine` helpers in utils/unitConversion.ts. They mirror the rule used on the details page: Resource Budget lines only, quantity → hours via the UoM conversion factor. - projectService.getProjectBudgets now fetches the resource UoM table once per call and reuses sumPlannedHours, matching the details page. - projectDetailsService delegates to the same helper, replacing its local copy of the rule, so the two stay in sync going forward. Fixes #192 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes incorrect “Planned (h)” values on the projects list by converting Job Planning Line quantities to hours using the per-resource unit-of-measure (UoM) conversion data, matching the logic already used on the project details page (fixes #192).
Changes:
- Added shared helpers in
unitConversion.tsto identify budget planning lines and sum planned hours with UoM conversion. - Updated
projectService.getProjectBudgetsto fetch resource UoMs once and compute planned hours via the shared helper. - Refactored
projectDetailsServiceto use the shared helper (removing the local budget-line predicate) so list/details stay consistent.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/utils/unitConversion.ts | Adds isBudgetPlanningLine and sumPlannedHours to centralize budget-line filtering + quantity→hours conversion. |
| src/services/bc/projectService.ts | Uses UoM conversion + shared summation logic when computing project “Planned” hours for the list view. |
| src/services/bc/projectDetailsService.ts | Delegates planned-hours computation (and budget line checks) to shared utilities to keep behavior consistent. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Widen `BCJobPlanningLine.lineType` (and the matching field on `PlanAllocation` in usePlanStore) to include the `_x0020_`-encoded variant of "Both Budget and Billable". Six call sites already special- cased this form at runtime; the type now matches reality so future narrowing comparisons can't silently miss it. - Add unit tests for `isBudgetPlanningLine` and `sumPlannedHours` in tests/unit/utils/unitConversion.test.ts, matching the coverage style of the other helpers in the same module (Budget vs Billable vs Both, encoded form, Resource vs Item vs G/L, UoM conversion + summation). - `getProjectBudgets` returns an empty map immediately when called with no project codes, skipping the `getResourceUnitsOfMeasure` round-trip for the empty-input case. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BenGWeeks
approved these changes
May 5, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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
The project list's Planned column was summing

BCJobPlanningLine.quantitydirectly with no UoM conversion. Projects whose resources are configured in DAYs therefore showed raw days against a column labelled "h" — for Cairn Homes – Support & Maintenance, 31.5d was rendered as 61h (planned), which then made Remaining go strongly negative (-107h (276%)). The project details page already converts via the per-resource UoM map, so the list and details views disagreed for the same project.sumPlannedHours(planningLines, uomMap)andisBudgetPlanningLinehelpers inutils/unitConversion.ts. Same rule as the details page: only Resource Budget lines (or Both Budget and Billable, including the_x0020_-encoded variant), with each quantity converted to hours via the UoM map.projectService.getProjectBudgetsnow fetches the resource UoM table once per call and usessumPlannedHours, so the list matches the details page.projectDetailsServicedelegates to the same shared helper instead of carrying its own copy, so the two stay in sync going forward.Test plan
Fixes #192
🤖 Generated with Claude Code