Files
accounted/supabase/migrations/20260519120000_get_unlinked_gl_lines.sql
T
Mattsson 8a6ce7093e feat: implement skattekonto drift detection and alerting (#525)
* feat: implement skattekonto drift detection and alerting

- Add skattekonto drift computation logic to compare Skatteverket's saldo with GL 1630 sum.
- Implement alerting mechanism for significant drift changes, with throttling to prevent alert spamming.
- Introduce database functions to sum GL 1630 entries and list unbooked skattekonto rows.

feat: create own account transfer detection

- Develop logic to detect transfers between a company's own cash accounts based on counterparty IBAN.
- Implement tests to validate detection logic under various scenarios, including matching and non-matching IBANs.

feat: establish cash accounts as a first-class entity

- Create cash_accounts table to manage routable cash accounts, replacing ad-hoc JSONB structures.
- Implement functions for listing, upserting, and managing cash accounts, including primary account designation.

feat: enhance GL line reconciliation functionality

- Modify get_unlinked_1930_lines RPC to accept any account number for reconciliation, improving flexibility for different currencies.
- Update related functions to ensure compatibility with the new cash_accounts structure.

feat: capture counterparty IBAN in transactions

- Add counterparty_iban column to transactions table to facilitate intra-account transfer detection.
- Create index for efficient lookups based on counterparty IBAN.

* feat: Enhance cash account handling and reconciliation processes

- Updated reconciliation routes to enforce cash account validation for all account numbers, including '1930'.
- Improved error handling for unknown cash accounts in reconciliation status and unmatched entries routes.
- Changed CashAccountSelector to use sessionStorage instead of localStorage for better data privacy.
- Fixed mapping for employer payroll taxes to route to the correct account (2730 instead of 2731).
- Added safety checks for company IDs in the guessCounterAccount function to prevent injection vulnerabilities.
- Introduced atomic RPC for setting primary cash accounts to avoid intermediate states during updates.
- Seeded default cash accounts for new companies to ensure reconciliation routes are accessible from day one.
- Updated email notifications for drift detection to avoid exposing sensitive financial data.
- Enhanced bank reconciliation logic to handle multi-currency transactions correctly.
- Renamed and updated tests to reflect changes in the underlying RPCs and ensure accurate coverage.
- Migrated existing cash account rules to correct mappings in compliance with Swedish accounting standards.
2026-05-19 16:10:18 +02:00

73 lines
2.5 KiB
PL/PgSQL

-- Migration: parametrise the unmatched-GL-lines RPC so reconciliation works on
-- any settlement account, not just 1930.
--
-- Why: until now `get_unlinked_1930_lines` hardcoded the bank-side BAS account.
-- EUR/USD customers can't self-reconcile their 1932/1933 accounts and the
-- skattekonto, payment-provider clearing, and BG/PG flows have no path. Now that
-- cash_accounts exists, the RPC accepts an account number parameter and the UI
-- can offer an account selector populated from that table.
--
-- The old function is dropped (no backwards-compatibility shim): the two
-- in-repo callers (lib/reconciliation/bank-reconciliation.ts and
-- app/api/reconciliation/bank/unmatched-entries/route.ts) are updated in the
-- same PR. Anyone calling the RPC over the REST surface must switch to the new
-- name + parameter at the same time.
DROP FUNCTION IF EXISTS public.get_unlinked_1930_lines(uuid, date, date);
CREATE FUNCTION public.get_unlinked_gl_lines(
p_company_id UUID,
p_account_number TEXT DEFAULT '1930',
p_date_from DATE DEFAULT NULL,
p_date_to DATE DEFAULT NULL
)
RETURNS TABLE (
line_id UUID,
journal_entry_id UUID,
debit_amount NUMERIC,
credit_amount NUMERIC,
line_description TEXT,
entry_date DATE,
voucher_number INT,
voucher_series TEXT,
entry_description TEXT,
source_type TEXT
)
LANGUAGE sql
STABLE
SECURITY DEFINER
SET search_path = public
AS $$
SELECT
jel.id AS line_id,
je.id AS journal_entry_id,
jel.debit_amount,
jel.credit_amount,
jel.line_description,
je.entry_date,
je.voucher_number,
je.voucher_series,
je.description AS entry_description,
je.source_type
FROM public.journal_entry_lines jel
JOIN public.journal_entries je ON je.id = jel.journal_entry_id
WHERE jel.account_number = p_account_number
AND je.company_id = p_company_id
AND je.status = 'posted'
-- IB lines never have a counterpart in the bank feed — the bank statement
-- starts at IB and accumulates from there. Keep them excluded from the
-- unmatched set so reconciliation doesn't surface a phantom voucher.
AND je.source_type IS DISTINCT FROM 'opening_balance'
AND (p_date_from IS NULL OR je.entry_date >= p_date_from)
AND (p_date_to IS NULL OR je.entry_date <= p_date_to)
AND NOT EXISTS (
SELECT 1
FROM public.transactions t
WHERE t.journal_entry_id = je.id
AND t.company_id = p_company_id
)
ORDER BY je.entry_date, je.voucher_number;
$$;
NOTIFY pgrst, 'reload schema';