chore(checkpoint): save club core backend and pending pos fixes

This commit is contained in:
Deploy
2026-08-26 17:58:45 +02:00
parent cf3c906ed2
commit 49dfd00406
44 changed files with 2241 additions and 219 deletions

View File

@@ -11,6 +11,7 @@ interface ReturnedItemRow {
unit_price_cents: number;
discount_cents: number;
tax_cents: number;
vat_rate: 'general' | 'reduced' | 'super-reduced' | null;
name: string;
sku: string;
is_free_item: boolean;
@@ -47,6 +48,7 @@ interface ReceiptItemRow {
unit_price_cents: number;
discount_cents: number;
tax_cents: number;
vat_rate: 'general' | 'reduced' | 'super-reduced' | null;
is_free_item: boolean;
}
@@ -80,7 +82,7 @@ export async function buildPosReceipt(queryable: Queryable, orderId: string): Pr
const [itemResult, paymentResult] = await Promise.all([
queryable.query<ReceiptItemRow>(
`SELECT name, sku, quantity, unit_price_cents, discount_cents, tax_cents, is_free_item
`SELECT name, sku, quantity, unit_price_cents, discount_cents, tax_cents, vat_rate, is_free_item
FROM orders_items WHERE order_id = $1 ORDER BY created_at, id`,
[orderId],
),
@@ -124,18 +126,25 @@ export async function buildPosReceipt(queryable: Queryable, orderId: string): Pr
sessionId: order.cash_session_id,
customerEmail: order.customer_email,
items: itemResult.rows.map((item) => {
const subtotalCents = Number(item.unit_price_cents) * Number(item.quantity);
const discountCents = Number(item.discount_cents) * Number(item.quantity);
const taxCents = Number(item.tax_cents) * Number(item.quantity);
const quantity = Number(item.quantity);
const unitNetCents = Number(item.unit_price_cents);
const unitTaxCents = Number(item.tax_cents);
const unitGrossCents = item.is_free_item
? unitNetCents
: grossFromNet(unitNetCents, item.vat_rate);
const totalCents = (unitNetCents - Number(item.discount_cents) + unitTaxCents) * quantity;
const subtotalCents = unitGrossCents * quantity;
const discountCents = Math.max(0, subtotalCents - totalCents);
const taxCents = unitTaxCents * quantity;
return {
name: item.name,
sku: item.sku,
quantity: Number(item.quantity),
unitPriceCents: Number(item.unit_price_cents),
quantity,
unitPriceCents: unitGrossCents,
subtotalCents,
discountCents,
taxCents,
totalCents: subtotalCents - discountCents + taxCents,
totalCents,
freeItem: item.is_free_item,
};
}),
@@ -152,6 +161,15 @@ export async function buildPosReceipt(queryable: Queryable, orderId: string): Pr
};
}
function grossFromNet(
netUnitAmountCents: number,
vatRate: 'general' | 'reduced' | 'super-reduced' | null,
): number {
if (!vatRate) return netUnitAmountCents;
const basisPoints = vatRate === 'general' ? 2100 : vatRate === 'reduced' ? 1000 : 400;
return Math.round(netUnitAmountCents * (1 + basisPoints / 10_000));
}
function isPaymentKind(value: unknown): value is PosPaymentKind {
return value === 'cash' || value === 'card' || value === 'other';
}
@@ -196,7 +214,7 @@ export async function buildPosReturnReceipt(
const original = await buildPosReceipt(queryable, orderId);
const itemResult = await queryable.query<ReturnedItemRow>(
`SELECT id, quantity, returned_quantity, unit_price_cents, discount_cents, tax_cents,
name, sku, is_free_item
vat_rate, name, sku, is_free_item
FROM orders_items WHERE order_id = $1 ORDER BY created_at, id`,
[orderId],
);
@@ -204,18 +222,20 @@ export async function buildPosReturnReceipt(
.filter((row) => row.returned_quantity > 0)
.map((row) => {
const returnedQuantity = Number(row.returned_quantity);
const unitPrice = Number(row.unit_price_cents);
const discount = Number(row.discount_cents);
const tax = Number(row.tax_cents);
const subtotal = unitPrice * returnedQuantity;
const discountCents = discount * returnedQuantity;
const taxCents = tax * returnedQuantity;
const total = subtotal - discountCents + taxCents;
const unitNetCents = Number(row.unit_price_cents);
const unitTaxCents = Number(row.tax_cents);
const unitGrossCents = row.is_free_item
? unitNetCents
: grossFromNet(unitNetCents, row.vat_rate);
const total = (unitNetCents - Number(row.discount_cents) + unitTaxCents) * returnedQuantity;
const subtotal = unitGrossCents * returnedQuantity;
const discountCents = Math.max(0, subtotal - total);
const taxCents = unitTaxCents * returnedQuantity;
return {
name: row.name,
sku: row.sku,
quantity: returnedQuantity,
unitPriceCents: unitPrice,
unitPriceCents: unitGrossCents,
subtotalCents: subtotal,
discountCents,
taxCents,