chore(checkpoint): save club core backend and pending pos fixes
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user