Introduce a CashupAmounts transfer object and break down large Cashups
controller methods into focused private helpers. Includes a breaking
change to constructor parameter order.
- Add CashupAmounts (TransferObjects/Cashups) to bundle open/transfer/
closed cash, due, card, and check amounts; reorder constructor params
to cash-before-due sequence
- Replace positional _calculate_total() with calculateTotal(CashupAmounts),
eliminating argument-order errors
- Decompose getView() into buildEmployeeLookup(), normalizeCashupInfo(),
initializeNewCashup(), isPendingClose(), closeCashup(),
buildReportDateRangeInputs(), applyPaymentTotals(), subtractCashExpenses()
- Decompose postSave() with parseCashupDate() and getCashupAmountsFromPost()
helpers; update both CashupAmounts call sites to new param order
- Rename snake_case vars/params to camelCase throughout Cashups controller
- Drop stale TODO comments in OSPOS.php and Cashups::getIndex filter block
- Scope escape => false to cashup_headers() note column rather than a
broad regex exclusion in transform_headers()
- Add CashupFixtureTrait and ExpenseFixtureTrait under tests/Support;
tighten cashup view test to assertSeeInField on specific form fields
BREAKING CHANGE: CashupAmounts constructor positional argument order
changed — closedAmountCash now precedes closedAmountDue; any callers
passing positional args must swap those two arguments.
Signed-off-by: objecttothis <17935339+objecttothis@users.noreply.github.com>
- Require reports_sales grant on postUnsuspend; return 403 on denial
- Reject unsuspend of non-SUSPENDED sales; skip silently on invalid state
- Move clear_all() after validation so an invalid sale_id no longer wipes
the active in-progress cart
- Null-guard get_sale_status() on missing row instead of fatal property
access; widen return type to ?int
- Fix getSaleType null-coalescing — CI4 session default only fires when
key is unset, not when value is null
- Rename get_sale_type → getSaleType, sale_id → saleId (PSR-12 camelCase)
- Extract SaleFixtureTrait with createSale()/createSuspendedSale(); add
regression coverage for auth denial, status gating, and cart preservation