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

@@ -82,6 +82,28 @@ async function resolveStoreIdForReceipt(
return id;
}
const POS_GROSS_PRICE_SQL = `COALESCE(
pp.offer_cents,
ROUND(
pp.net_unit_amount_cents * CASE pp.vat_rate
WHEN 'general' THEN 1.21
WHEN 'reduced' THEN 1.10
WHEN 'super-reduced' THEN 1.04
ELSE 1.21
END
)::int,
0
)`;
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));
}
export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps) {
const { pool, authenticate } = deps;
@@ -295,7 +317,7 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
const result = variantIds.length > 0
? await pool.query(
`SELECT v.id AS "variantId", p.id AS "productId", p.name, v.sku, v.ean,
COALESCE(pp.offer_cents, pp.net_unit_amount_cents, 0) AS "priceCents"
${POS_GROSS_PRICE_SQL} AS "priceCents"
FROM catalog_product_variants v
JOIN catalog_products p ON p.id = v.product_id
LEFT JOIN pricing_variant_prices pp ON pp.variant_id = v.id AND pp.currency = 'EUR'
@@ -305,7 +327,7 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
)
: await pool.query(
`SELECT v.id AS "variantId", p.id AS "productId", p.name, v.sku, v.ean,
COALESCE(pp.offer_cents, pp.net_unit_amount_cents, 0) AS "priceCents"
${POS_GROSS_PRICE_SQL} AS "priceCents"
FROM catalog_product_variants v
JOIN catalog_products p ON p.id = v.product_id
LEFT JOIN pricing_variant_prices pp ON pp.variant_id = v.id AND pp.currency = 'EUR'
@@ -942,7 +964,7 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
pool.query(
`SELECT v.id AS "variantId", p.id AS "productId", p.name, v.sku, v.ean,
pc.category_id AS "categoryId", COALESCE(stock.quantity, 0) AS stock,
COALESCE(pp.offer_cents, pp.net_unit_amount_cents, 0) AS "priceCents"
${POS_GROSS_PRICE_SQL} AS "priceCents"
FROM catalog_product_variants v
JOIN catalog_products p ON p.id = v.product_id
LEFT JOIN catalog_product_categories pc ON pc.product_id = p.id
@@ -1008,7 +1030,7 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
const result = await pool.query(
`SELECT v.id AS variant_id, v.product_id, p.name, v.sku, v.ean,
COALESCE(s.quantity, 0) AS stock,
COALESCE(pp.offer_cents, pp.net_unit_amount_cents, 0) AS price_cents,
${POS_GROSS_PRICE_SQL} AS price_cents,
c.name AS category, b.name AS brand
FROM catalog_product_variants v
JOIN catalog_products p ON p.id = v.product_id
@@ -1064,7 +1086,7 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
const result = await pool.query(
`SELECT v.id AS variant_id, v.product_id, p.name, v.sku, v.ean,
COALESCE(s.quantity, 0) AS stock,
COALESCE(pp.offer_cents, pp.net_unit_amount_cents, 0) AS price_cents
${POS_GROSS_PRICE_SQL} AS price_cents
FROM catalog_product_variants v
JOIN catalog_products p ON p.id = v.product_id
LEFT JOIN LATERAL (
@@ -1106,7 +1128,7 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
const result = await pool.query(
`SELECT v.id AS variant_id, v.product_id, p.name, v.sku, v.ean,
COALESCE(s.quantity, 0) AS stock,
COALESCE(pp.offer_cents, pp.net_unit_amount_cents, 0) AS price_cents
${POS_GROSS_PRICE_SQL} AS price_cents
FROM catalog_product_variants v
JOIN catalog_products p ON p.id = v.product_id
LEFT JOIN LATERAL (
@@ -2145,23 +2167,36 @@ export async function registerPosRoutes(app: FastifyInstance, deps: PosRouteDeps
is_free_item: boolean;
unit_price_cents: number;
discount_cents: number;
tax_cents: number;
vat_rate: 'general' | 'reduced' | 'super-reduced' | null;
}>(
`SELECT id, name, sku, quantity, returned_quantity, is_free_item,
unit_price_cents, discount_cents
unit_price_cents, discount_cents, tax_cents, vat_rate
FROM orders_items WHERE order_id = $1 ORDER BY created_at, id`,
[id],
);
return reply.send({
items: itemRows.rows.map((row) => ({
id: row.id,
name: row.name,
sku: row.sku,
quantity: Number(row.quantity),
returnedQuantity: Number(row.returned_quantity),
freeItem: row.is_free_item,
unitPriceCents: Number(row.unit_price_cents),
discountCents: Number(row.discount_cents),
})),
items: itemRows.rows.map((row) => {
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 discountGrossCents = Math.max(
0,
unitGrossCents - (unitNetCents - Number(row.discount_cents) + unitTaxCents),
);
return {
id: row.id,
name: row.name,
sku: row.sku,
quantity: Number(row.quantity),
returnedQuantity: Number(row.returned_quantity),
freeItem: row.is_free_item,
unitPriceCents: unitGrossCents,
discountCents: discountGrossCents,
};
}),
});
},
);