feat(time-tracking): split billable from worked minutes per entry (PMS-395) #384
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/PMS-395-billable-minutes-split"
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?
A time entry carried one
duration_minutesthat was both the worked time and the billing basis, and rounding mutated that single figure to match the billing increment. Billable time can legitimately exceed worked time (minimum increments, one update billed across several clients) or fall below it (internal absorption); the single-field model could not represent this.Split the concept into two persisted columns on
time_entries:worked_minutes(actual time, canonical, never rounded) andbillable_minutes(time billed, independent).duration_minutesis retained for one release and tracksworked_minutes.worked_minutesandbillable_minuteson create/update requests and the response. Omittingbillable_minuteson create defaults it to the rounded worked time for billable entries (pre-change behavior); the worked figure is stored unrounded.create_time_entry/update_time_entrystop rounding the worked figure; rounding now derives only billable minutes, andtotal_amountis priced on billable minutes. The per-day cap is enforced on worked time.list_timesheetsreports total_minutes = SUM(worked) and billable_minutes = SUM(billable), each falling back to duration for legacy rows.Integration tests cover billable > worked round-tripping and the omitted-billable default.
#PMS-395