feat: BAS data overhaul, currency revaluation, expenses, UI polish, and cleanup
- Update BAS account catalog with comprehensive SRU codes and K2 flags - Add currency revaluation service with tests and API route - Add expenses page and account deletion API - Enhance booking templates with new patterns and improved tests - Improve transaction categorization with template picker and description matching - Polish dashboard, onboarding, import, and transaction UIs - Refactor year-end service for multi-step closing - Move SRU generator to ne-bilaga, remove standalone SRU export - Remove unused dev docs, mock data, and extension hooks - Add invoice delivery note sequences migration Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
a9bf24ce0b
commit
66a4027f1e
@@ -0,0 +1,17 @@
|
||||
-- Migration 49: Add currency_revaluation source type
|
||||
-- ÅRL 4 kap. 13 § requires period-end revaluation of foreign currency items
|
||||
|
||||
ALTER TABLE public.journal_entries
|
||||
DROP CONSTRAINT IF EXISTS journal_entries_source_type_check;
|
||||
|
||||
ALTER TABLE public.journal_entries
|
||||
ADD CONSTRAINT journal_entries_source_type_check
|
||||
CHECK (source_type IN (
|
||||
'manual', 'bank_transaction', 'invoice_created',
|
||||
'invoice_paid', 'invoice_cash_payment', 'credit_note', 'salary_payment',
|
||||
'opening_balance', 'year_end',
|
||||
'storno', 'correction', 'import', 'system',
|
||||
'supplier_invoice_registered', 'supplier_invoice_paid',
|
||||
'supplier_invoice_cash_payment', 'supplier_credit_note',
|
||||
'currency_revaluation'
|
||||
));
|
||||
@@ -0,0 +1,76 @@
|
||||
-- Migration 50: Separate invoice and delivery note number sequences
|
||||
-- BFL requires sequential, gap-free numbering within each document series.
|
||||
-- Separate series per document type is standard Swedish practice.
|
||||
|
||||
-- =============================================================================
|
||||
-- 1. Add delivery note sequence column to company_settings
|
||||
-- =============================================================================
|
||||
ALTER TABLE public.company_settings
|
||||
ADD COLUMN IF NOT EXISTS next_delivery_note_number INTEGER DEFAULT 1;
|
||||
|
||||
-- =============================================================================
|
||||
-- 2. Create generate_invoice_number RPC
|
||||
-- Atomically reads invoice_prefix + next_invoice_number, increments, returns
|
||||
-- formatted number. Uses UPDATE ... RETURNING for concurrent safety.
|
||||
-- =============================================================================
|
||||
CREATE OR REPLACE FUNCTION public.generate_invoice_number(p_user_id UUID)
|
||||
RETURNS TEXT
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
v_prefix TEXT;
|
||||
v_number INTEGER;
|
||||
v_year TEXT;
|
||||
BEGIN
|
||||
UPDATE public.company_settings
|
||||
SET next_invoice_number = next_invoice_number + 1,
|
||||
updated_at = now()
|
||||
WHERE user_id = p_user_id
|
||||
RETURNING invoice_prefix, next_invoice_number - 1
|
||||
INTO v_prefix, v_number;
|
||||
|
||||
IF v_number IS NULL THEN
|
||||
RAISE EXCEPTION 'Company settings not found for user %', p_user_id;
|
||||
END IF;
|
||||
|
||||
v_year := EXTRACT(YEAR FROM CURRENT_DATE)::TEXT;
|
||||
|
||||
RETURN COALESCE(v_prefix, '') || v_year || LPAD(v_number::TEXT, 3, '0');
|
||||
END;
|
||||
$$;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION public.generate_invoice_number(UUID) TO authenticated;
|
||||
|
||||
-- =============================================================================
|
||||
-- 3. Create generate_delivery_note_number RPC
|
||||
-- Same pattern as invoice numbers but uses next_delivery_note_number.
|
||||
-- Returns FS-{year}{padded_number} format.
|
||||
-- =============================================================================
|
||||
CREATE OR REPLACE FUNCTION public.generate_delivery_note_number(p_user_id UUID)
|
||||
RETURNS TEXT
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
v_number INTEGER;
|
||||
v_year TEXT;
|
||||
BEGIN
|
||||
UPDATE public.company_settings
|
||||
SET next_delivery_note_number = next_delivery_note_number + 1,
|
||||
updated_at = now()
|
||||
WHERE user_id = p_user_id
|
||||
RETURNING next_delivery_note_number - 1
|
||||
INTO v_number;
|
||||
|
||||
IF v_number IS NULL THEN
|
||||
RAISE EXCEPTION 'Company settings not found for user %', p_user_id;
|
||||
END IF;
|
||||
|
||||
v_year := EXTRACT(YEAR FROM CURRENT_DATE)::TEXT;
|
||||
|
||||
RETURN 'FS-' || v_year || LPAD(v_number::TEXT, 3, '0');
|
||||
END;
|
||||
$$;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION public.generate_delivery_note_number(UUID) TO authenticated;
|
||||
Reference in New Issue
Block a user