feat: repair-POS integration, receipt formats, manager overrides, price adjustments
- Add thermal/full-page receipt format toggle (per-device, localStorage) - Full-page receipt uses clean invoice layout matching repair PDF style - Settings page reorganized into tabbed sections (Store, Locations, Modules, Receipt, POS Security, Advanced) - Manager override system: configurable PIN prompt for void, refund, discount, cash in/out - Discount threshold setting: require manager approval above X% - Consumable product type: tracked for internal job costing, excluded from POS search, receipts, and customer-facing totals - Repair line item dialog: product picker dropdown for parts/consumables from inventory - Repair → POS checkout: load ready-for-pickup tickets into repair_payment transactions with proper tax categories (labor=service, parts=goods) - Transaction completion auto-updates repair ticket status to picked_up - POS Repairs dialog with Pickup and New Intake tabs, customer account lookup - Inline price adjustment on cart items: % off, $ off, or set price with live preview - Order-level discount button with same three input modes - Backend: migration 0043 (consumable enum + is_consumable flag), createFromRepairTicket service, ready-for-pickup endpoint - Fix: backend dev script uses --env-file for turbo compatibility Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -174,6 +174,25 @@ export const RepairTicketService = {
|
||||
return paginatedResponse(data, total, params.page, params.limit)
|
||||
},
|
||||
|
||||
async listReadyForPickup(db: PostgresJsDatabase<any>, params: PaginationInput) {
|
||||
const baseWhere = eq(repairTickets.status, 'ready')
|
||||
const searchCondition = params.q
|
||||
? buildSearchCondition(params.q, [repairTickets.ticketNumber, repairTickets.customerName, repairTickets.customerPhone])
|
||||
: undefined
|
||||
const where = searchCondition ? and(baseWhere, searchCondition) : baseWhere
|
||||
|
||||
let query = db.select().from(repairTickets).where(where).$dynamic()
|
||||
query = withSort(query, params.sort, params.order, { ticket_number: repairTickets.ticketNumber, customer_name: repairTickets.customerName, created_at: repairTickets.createdAt }, repairTickets.createdAt)
|
||||
query = withPagination(query, params.page, params.limit)
|
||||
|
||||
const [data, [{ total }]] = await Promise.all([
|
||||
query,
|
||||
db.select({ total: count() }).from(repairTickets).where(where),
|
||||
])
|
||||
|
||||
return paginatedResponse(data, total, params.page, params.limit)
|
||||
},
|
||||
|
||||
async update(db: PostgresJsDatabase<any>, id: string, input: RepairTicketUpdateInput) {
|
||||
const values: Record<string, unknown> = { ...input, updatedAt: new Date() }
|
||||
if (input.estimatedCost !== undefined) values.estimatedCost = input.estimatedCost.toString()
|
||||
|
||||
Reference in New Issue
Block a user