fix(billing): gate invoicing on timesheet approval (PMS-144) #114
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/pms-144-billing-approval-gate"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Closes PMS-42 AC4 ("Approved billable entries surface as
ready_to_billfor PMS-33"). Re-verifying PMS-42 turned up that this criterion was not implemented:src/ever setbilling_status='ready_to_bill'-approve_timesheetonly touchedapproval_status, so the status was dead.create_invoice_from_time_entriesselectedbilling_status IN ('ready_to_bill','not_billed')with no approval predicate, so any billable entry - includingpendingorrejected- was invoiceable.Fix
time_tracking::approve_timesheet: in the same statement that setsapproval_status='approved', flip billablenot_billedrows toready_to_bill(non-billable / already-invoiced rows untouched).billing::create_invoice_from_time_entries: consume onlybilling_status='ready_to_bill'. Approval is now the gate; unapproved time cannot be invoiced.Tests (pass against the dev DB)
tests/time_tracking.rs: asserts the billable entry isready_to_billafter the manager approves.tests/billing.rs: adds a billable-but-unapproved (not_billed) negative control and asserts invoice generation skips it; the existinglines.len() == 2check also now guards it.cargo fmt --checkclean;cargo clippy --test billing --test time_tracking -- -D warningsclean.🤖 Generated with Claude Code
Closes PMS-42 AC4. Approved billable time entries are meant to "surface as ready_to_bill for PMS-33", but nothing produced that status and billing ignored approval entirely: create_invoice_from_time_entries consumed billing_status IN ('ready_to_bill','not_billed') with no approval predicate, so pending or even rejected billable time was invoiceable, and ready_to_bill was dead status. Make approval the billing gate. approve_timesheet now flips billable, not-yet-billed entries to billing_status='ready_to_bill' in the same UPDATE that sets approval_status='approved' (non-billable and already-invoiced rows untouched). create_invoice_from_time_entries consumes only billing_status='ready_to_bill', so unapproved time can no longer be invoiced. Tests: tests/time_tracking.rs asserts the billable entry becomes ready_to_bill after the manager approves; tests/billing.rs adds a billable-but-unapproved (not_billed) negative control and asserts it is skipped by invoice generation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>