F-201 F-202 F-203: POS cash close report + email + PIN admin

F-201: GET /pos/reports/cash-close/:id with financial summary, sales
  by state, payments breakdown, items sold. Extended /pos/sessions/:id.

F-202: Cash close email sent on session close to smtpReportEmail
  (best-effort). smtpReportEmail field added to admin SMTP settings.

F-203: Admin POS terminal config: selfpayMode, closeSessionRequiresPin,
  closeSessionPin (4-6 digits) with dedicated settings section.
This commit is contained in:
chattie
2026-08-23 09:24:37 +02:00
parent 4b3a506166
commit 18a518e58b
100 changed files with 1704 additions and 284 deletions

View File

@@ -41,6 +41,14 @@ export const posApi = {
method: 'POST',
body: JSON.stringify({ openingCashCents }),
}),
/** Close the daily cash session. */
closeSession: (sessionId: string, actualCashCents: number, pin?: string) =>
apiFetch<{ id: string; status: 'CLOSED' }>(`/pos/sessions/${sessionId}/close`, {
method: 'POST',
body: JSON.stringify(pin
? { closingCashCents: actualCashCents, actualCashCents, pin }
: { closingCashCents: actualCashCents, actualCashCents }),
}),
/** Load touch category navigation and eight terminal quick products. */
touchCatalog: <T>() => apiFetch<T>('/pos/catalog/touch'),
/** List products by query. */
@@ -76,10 +84,12 @@ export const posApi = {
listOrderItems: <T>(orderId: string) =>
apiFetch<T>(`/pos/sales/${encodeURIComponent(orderId)}/items`),
/** List POS sales for the session, optionally filtered by state. */
listSales: <T>(params?: { state?: 'PENDING' | 'COMPLETED'; sessionId?: string }) => {
// FEAT-200: terminalId enables cross-day pending sales
listSales: <T>(params?: { state?: 'PENDING' | 'COMPLETED'; sessionId?: string; terminalId?: string }) => {
const qs = new URLSearchParams();
if (params?.state) qs.set('state', params.state);
if (params?.sessionId) qs.set('sessionId', params.sessionId);
if (params?.terminalId) qs.set('terminalId', params.terminalId);
const tail = qs.toString();
return apiFetch<T>(`/pos/sales${tail ? `?${tail}` : ''}`);
},