feat(shift): confirm-before-close with X-report + split tickets vs subscriptions; fix dark <select>
CI / check (push) Failing after 31s
CI / check (push) Failing after 31s
Three changes: 1. Confirm-before-close. The header shift button closed the shift directly — a stray click would sign the irreversible Z-report. It now opens a confirm modal showing the live X-report (takings split by source + expected drawer) with Cancel / End-shift. Opening a shift stays immediate (no such risk). 2. Split takings by SOURCE. The report separates Tickets (transient) from Subscriptions (monthly sales + a subscriber's out-of-window charge), so the operator sees subscriber money apart from ticket money. Buckets are derived from the signed payment payload flags (subscriptionSale / subscriptionWindowCharge) and always reconcile to cash + card (a payment with neither flag is a ticket). Computed in #summariseWindow, carried on the signed shift_z_report payload, and shown in the X-report, the close modal, the shift history detail, and the printed Z-report. Reports predating the fields default subscription to 0 (ticket absorbs the whole take), so old shifts still reconcile. 3. Fix dark-theme native <select> popups rendering WHITE on WebKitGTK (the Tauri Linux WebView): set color-scheme dark/light on <html> per theme + explicit <option> colours, so the OS-drawn dropdown list follows the theme. Verified the split on a read-only DB copy: tickets 0, subscriptions 10,200 (10,000 sale + 200 out-of-window), reconciles to cash+card. build+lint 14/14, i18n parity (sq+en). Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
This commit is contained in:
+13
-3
@@ -690,7 +690,17 @@ export interface ShiftStatus {
|
||||
drawerMinor: number;
|
||||
currency: string | null;
|
||||
}
|
||||
export interface ShiftReport {
|
||||
/** Takings split by SOURCE — transient tickets vs subscriber money (monthly sales +
|
||||
* out-of-window charges). Cash+card combined; the per-tender totals stay separate for
|
||||
* the drawer. Shared by the X-report, the close Z-report, and the history summary. */
|
||||
export interface ShiftSourceSplit {
|
||||
ticketTotalMinor: number;
|
||||
subscriptionTotalMinor: number;
|
||||
subscriptionSalesMinor: number;
|
||||
subscriptionWindowMinor: number;
|
||||
}
|
||||
|
||||
export interface ShiftReport extends ShiftSourceSplit {
|
||||
operator: string;
|
||||
startedAt: string;
|
||||
endedAt: string;
|
||||
@@ -719,7 +729,7 @@ export function closeShift(): Promise<ShiftReport> {
|
||||
/** Mid-shift X-report: the open shift's takings + drawer "so far" (read-only — no
|
||||
* event is appended). Same figures the Z-report will print at close. `asOf` is the
|
||||
* snapshot instant. */
|
||||
export interface XReport {
|
||||
export interface XReport extends ShiftSourceSplit {
|
||||
operator: string;
|
||||
startedAt: string;
|
||||
endedAt: string; // = asOf
|
||||
@@ -762,7 +772,7 @@ export function recordCashVoucher(args: {
|
||||
}
|
||||
|
||||
/** A completed shift (reconstructed from its signed Z-report). */
|
||||
export interface ShiftSummary {
|
||||
export interface ShiftSummary extends ShiftSourceSplit {
|
||||
id: string;
|
||||
index: number;
|
||||
operator: string;
|
||||
|
||||
Reference in New Issue
Block a user