86 lines
2.9 KiB
MySQL
86 lines
2.9 KiB
MySQL
|
|
-- Migration 177: Supplier invoice reminders
|
||
|
|
-- Created: 2026-04-13
|
||
|
|
|
||
|
|
CREATE TABLE IF NOT EXISTS supplier_invoice_reminders (
|
||
|
|
id BIGSERIAL PRIMARY KEY,
|
||
|
|
supplier_invoice_id INTEGER NOT NULL REFERENCES supplier_invoices(id) ON DELETE CASCADE,
|
||
|
|
reminder_type VARCHAR(30) NOT NULL,
|
||
|
|
remind_at TIMESTAMP NOT NULL,
|
||
|
|
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||
|
|
sent_at TIMESTAMP,
|
||
|
|
channel VARCHAR(20) NOT NULL DEFAULT 'in_app',
|
||
|
|
payload_json JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||
|
|
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
|
|
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||
|
|
);
|
||
|
|
|
||
|
|
DO $$
|
||
|
|
BEGIN
|
||
|
|
IF NOT EXISTS (
|
||
|
|
SELECT 1
|
||
|
|
FROM pg_constraint
|
||
|
|
WHERE conname = 'chk_supplier_invoice_reminders_type'
|
||
|
|
) THEN
|
||
|
|
ALTER TABLE supplier_invoice_reminders
|
||
|
|
ADD CONSTRAINT chk_supplier_invoice_reminders_type
|
||
|
|
CHECK (reminder_type IN ('due_soon', 'overdue', 'manual'));
|
||
|
|
END IF;
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
DO $$
|
||
|
|
BEGIN
|
||
|
|
IF NOT EXISTS (
|
||
|
|
SELECT 1
|
||
|
|
FROM pg_constraint
|
||
|
|
WHERE conname = 'chk_supplier_invoice_reminders_status'
|
||
|
|
) THEN
|
||
|
|
ALTER TABLE supplier_invoice_reminders
|
||
|
|
ADD CONSTRAINT chk_supplier_invoice_reminders_status
|
||
|
|
CHECK (status IN ('pending', 'sent', 'cancelled', 'failed'));
|
||
|
|
END IF;
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
DO $$
|
||
|
|
BEGIN
|
||
|
|
IF NOT EXISTS (
|
||
|
|
SELECT 1
|
||
|
|
FROM pg_constraint
|
||
|
|
WHERE conname = 'chk_supplier_invoice_reminders_channel'
|
||
|
|
) THEN
|
||
|
|
ALTER TABLE supplier_invoice_reminders
|
||
|
|
ADD CONSTRAINT chk_supplier_invoice_reminders_channel
|
||
|
|
CHECK (channel IN ('in_app', 'email'));
|
||
|
|
END IF;
|
||
|
|
END $$;
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_supplier_invoice_reminders_supplier_invoice_id
|
||
|
|
ON supplier_invoice_reminders(supplier_invoice_id);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_supplier_invoice_reminders_remind_at
|
||
|
|
ON supplier_invoice_reminders(remind_at);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_supplier_invoice_reminders_status
|
||
|
|
ON supplier_invoice_reminders(status);
|
||
|
|
|
||
|
|
CREATE INDEX IF NOT EXISTS idx_supplier_invoice_reminders_payload_json
|
||
|
|
ON supplier_invoice_reminders USING GIN (payload_json);
|
||
|
|
|
||
|
|
CREATE OR REPLACE FUNCTION update_supplier_invoice_reminders_updated_at()
|
||
|
|
RETURNS TRIGGER AS $$
|
||
|
|
BEGIN
|
||
|
|
NEW.updated_at = CURRENT_TIMESTAMP;
|
||
|
|
RETURN NEW;
|
||
|
|
END;
|
||
|
|
$$ LANGUAGE plpgsql;
|
||
|
|
|
||
|
|
DROP TRIGGER IF EXISTS trg_supplier_invoice_reminders_updated_at ON supplier_invoice_reminders;
|
||
|
|
CREATE TRIGGER trg_supplier_invoice_reminders_updated_at
|
||
|
|
BEFORE UPDATE ON supplier_invoice_reminders
|
||
|
|
FOR EACH ROW
|
||
|
|
EXECUTE FUNCTION update_supplier_invoice_reminders_updated_at();
|
||
|
|
|
||
|
|
COMMENT ON TABLE supplier_invoice_reminders IS 'Scheduled reminders for supplier invoice follow-up';
|
||
|
|
COMMENT ON COLUMN supplier_invoice_reminders.reminder_type IS 'due_soon, overdue, or manual';
|
||
|
|
COMMENT ON COLUMN supplier_invoice_reminders.status IS 'pending, sent, cancelled, or failed';
|
||
|
|
COMMENT ON COLUMN supplier_invoice_reminders.channel IS 'Delivery channel: in_app or email';
|