feat(db): add till_sales VAT and voucher_type_at_purchase to gift_cards

Retrospectively apply VAT to till sales in enable_vat_registration function. Add voucher_type_at_purchase column to gift_cards for SPV/MPV per-card tracking.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-06-22 17:05:25 +01:00
co-authored by Sisyphus
parent bb7de6640c
commit 818f9ead4e
+41 -4
View File
@@ -1548,17 +1548,20 @@ CREATE OR REPLACE FUNCTION enable_vat_registration(
)
RETURNS TABLE (
payments_updated INT,
till_sales_updated INT,
total_vat_calculated NUMERIC(12,2),
total_net_calculated NUMERIC(12,2),
registration_effective_date DATE,
settings_updated BOOLEAN
) AS $$
DECLARE
updated_count INT;
pay_updated_count INT;
till_updated_count INT;
total_vat NUMERIC(12,2);
total_net NUMERIC(12,2);
settings_ok BOOLEAN := FALSE;
BEGIN
-- Retrospectively apply VAT to completed payments
UPDATE payments
SET
vat_rate = enable_vat_registration.vat_rate,
@@ -1570,8 +1573,23 @@ BEGIN
AND created_at::date >= registration_date
AND vat_amount IS NULL;
GET DIAGNOSTICS updated_count = ROW_COUNT;
GET DIAGNOSTICS pay_updated_count = ROW_COUNT;
-- Retrospectively apply VAT to completed till sales (gift card purchases etc.)
UPDATE till_sales
SET
vat_rate = enable_vat_registration.vat_rate,
vat_amount = ROUND(total_amount - (total_amount / (1 + enable_vat_registration.vat_rate / 100)), 2),
net_amount = ROUND(total_amount / (1 + enable_vat_registration.vat_rate / 100), 2),
is_vat_applicable = TRUE,
updated_at = NOW()
WHERE status = 'completed'
AND created_at::date >= registration_date
AND vat_amount IS NULL;
GET DIAGNOSTICS till_updated_count = ROW_COUNT;
-- Aggregate totals
SELECT
COALESCE(SUM(p.vat_amount), 0),
COALESCE(SUM(p.net_amount), 0)
@@ -1581,6 +1599,17 @@ BEGIN
AND created_at::date >= registration_date
AND vat_amount IS NOT NULL;
-- Also include till_sales in the aggregate totals
SELECT
total_vat + COALESCE(SUM(ts.vat_amount), 0),
total_net + COALESCE(SUM(ts.net_amount), 0)
INTO total_vat, total_net
FROM till_sales ts
WHERE status = 'completed'
AND created_at::date >= registration_date
AND vat_amount IS NOT NULL;
-- Update business_settings record
UPDATE business_settings
SET
is_vat_registered = TRUE,
@@ -1594,7 +1623,8 @@ BEGIN
END IF;
RETURN QUERY SELECT
updated_count,
pay_updated_count,
till_updated_count,
total_vat,
total_net,
registration_date,
@@ -2038,7 +2068,11 @@ CREATE TABLE gift_cards (
is_inventory BOOLEAN NOT NULL DEFAULT FALSE,
expiry_date TIMESTAMPTZ,
-- Rolling expiry: 24 months from last usage (redeem, topup, balance check)
last_used_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
last_used_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- Voucher type at time of purchase ('SPV' or 'MPV'). Read at redemption to
-- determine whether VAT was already paid at sale (SPV) or must be applied
-- now (MPV). NULL if the card was created before this column was added.
voucher_type_at_purchase VARCHAR(3)
);
CREATE INDEX idx_gift_cards_last_used_at ON gift_cards(last_used_at)
@@ -2360,3 +2394,6 @@ CREATE TABLE IF NOT EXISTS refresh_tokens (
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens (user_id);
CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires_at ON refresh_tokens (expires_at);
-- Migration: add voucher_type_at_purchase to gift_cards (for SPV/MPV per-card tracking)
ALTER TABLE gift_cards ADD COLUMN IF NOT EXISTS voucher_type_at_purchase VARCHAR(3);