Production allows edc and delivery payment methods through a payment_methods_type_check changed outside the migrations, and has rows of both. 000094 rewrote the constraint with only cash, card, digital_wallet and point, so it failed on production (in its transaction, leaving the database dirty at 94 with nothing applied). 000094 now keeps edc and delivery, down included, and also allows qr, which the code accepts but no constraint did. 000098 sets the same list where the old 000094 already ran, as on staging. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
47 lines
2.1 KiB
PL/PgSQL
47 lines
2.1 KiB
PL/PgSQL
-- Paying with EnakPoint (docs/prd-point-coin.md F9, §8, §10.5).
|
|
|
|
-- A new payment method type, next to the existing ones (edc and delivery were added to
|
|
-- the constraint outside the migrations). Every organization has exactly one method of it, made by
|
|
-- the system, which cannot be deleted or change type.
|
|
ALTER TABLE payment_methods DROP CONSTRAINT IF EXISTS payment_methods_type_check;
|
|
ALTER TABLE payment_methods ADD CONSTRAINT payment_methods_type_check
|
|
CHECK (type IN ('cash', 'card', 'digital_wallet', 'qr', 'edc', 'delivery', 'point'));
|
|
|
|
CREATE UNIQUE INDEX uq_payment_methods_point_per_organization ON payment_methods(organization_id)
|
|
WHERE type = 'point';
|
|
|
|
INSERT INTO payment_methods (organization_id, name, type, is_active)
|
|
SELECT id, 'EnakPoint', 'point', TRUE FROM organizations
|
|
ON CONFLICT (organization_id) WHERE type = 'point' DO NOTHING;
|
|
|
|
-- New organizations get theirs the same way they get their walk-in customer, whatever
|
|
-- code path creates them.
|
|
CREATE OR REPLACE FUNCTION create_point_payment_method()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
INSERT INTO payment_methods (organization_id, name, type, is_active)
|
|
VALUES (NEW.id, 'EnakPoint', 'point', TRUE)
|
|
ON CONFLICT (organization_id) WHERE type = 'point' DO NOTHING;
|
|
RETURN NEW;
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
CREATE TRIGGER trigger_create_point_payment_method
|
|
AFTER INSERT ON organizations
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION create_point_payment_method();
|
|
|
|
-- A payment made with EnakPoint records how many were used and the rupiah value of one
|
|
-- at that moment. The value is frozen so a refund returns exactly the EnakPoint used,
|
|
-- whatever the value is by then.
|
|
--
|
|
-- Written so it never evaluates to NULL: the form in the PRD, (both NULL) OR (both
|
|
-- > 0), is NULL for points_used = 1000 with point_value NULL, and a CHECK only rejects
|
|
-- FALSE, so a payment could lose its frozen value.
|
|
ALTER TABLE payments
|
|
ADD COLUMN points_used BIGINT,
|
|
ADD COLUMN point_value DECIMAL(10,2),
|
|
ADD CONSTRAINT chk_payments_point_pair CHECK (
|
|
(points_used IS NULL) = (point_value IS NULL)
|
|
AND (points_used IS NULL OR (points_used > 0 AND point_value > 0)));
|