feat: named registers, X/Z reports, daily rollup, fix drawerSessionId
Registers: - New register table with location association - CRUD service + API routes (POST/GET/PATCH/DELETE /registers) - Drawer sessions now link to a register via registerId - Register ID persisted in localStorage per device X/Z Reports: - ReportService with getDrawerReport() (X or Z depending on session state) - Z report auto-displayed on drawer close in the drawer dialog - X report (Current Shift Report) button on open drawer view - Report shows: sales summary, payment breakdown, discounts, cash accountability, adjustments Daily Rollup: - ReportService.getDailyReport() aggregates all sessions at a location for a date - New /reports/daily endpoint with locationId + date params - Frontend daily report page with date picker, location selector, session breakdown Critical Fix: - drawerSessionId is now populated on transactions when completing (was never set before) - This enables accurate per-drawer reporting and cash accountability Migration 0044: register table, drawer_session.register_id column Tests: 14 new (register CRUD, drawer report X/Z, drawerSessionId population, daily rollup, register-drawer link) Full suite: 367 passed Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -181,6 +181,8 @@ export {
|
||||
DrawerOpenSchema,
|
||||
DrawerCloseSchema,
|
||||
DrawerAdjustmentSchema,
|
||||
RegisterCreateSchema,
|
||||
RegisterUpdateSchema,
|
||||
} from './pos.schema.js'
|
||||
export type {
|
||||
TransactionCreateInput,
|
||||
@@ -192,6 +194,8 @@ export type {
|
||||
DrawerOpenInput,
|
||||
DrawerCloseInput,
|
||||
DrawerAdjustmentInput,
|
||||
RegisterCreateInput,
|
||||
RegisterUpdateInput,
|
||||
} from './pos.schema.js'
|
||||
|
||||
export { LogLevel, AppConfigUpdateSchema } from './config.schema.js'
|
||||
|
||||
@@ -100,6 +100,7 @@ export type DiscountUpdateInput = z.infer<typeof DiscountUpdateSchema>
|
||||
|
||||
export const DrawerOpenSchema = z.object({
|
||||
locationId: opt(z.string().uuid()),
|
||||
registerId: opt(z.string().uuid()),
|
||||
openingBalance: z.coerce.number().min(0),
|
||||
})
|
||||
export type DrawerOpenInput = z.infer<typeof DrawerOpenSchema>
|
||||
@@ -119,3 +120,17 @@ export const DrawerCloseSchema = z.object({
|
||||
notes: opt(z.string()),
|
||||
})
|
||||
export type DrawerCloseInput = z.infer<typeof DrawerCloseSchema>
|
||||
|
||||
// --- Register schemas ---
|
||||
|
||||
export const RegisterCreateSchema = z.object({
|
||||
locationId: z.string().uuid(),
|
||||
name: z.string().min(1).max(100),
|
||||
})
|
||||
export type RegisterCreateInput = z.infer<typeof RegisterCreateSchema>
|
||||
|
||||
export const RegisterUpdateSchema = z.object({
|
||||
name: z.string().min(1).max(100).optional(),
|
||||
isActive: z.boolean().optional(),
|
||||
})
|
||||
export type RegisterUpdateInput = z.infer<typeof RegisterUpdateSchema>
|
||||
|
||||
Reference in New Issue
Block a user