Fix/m sprint fixes (#613)
* fix(dashboard): exclude ignored and already-triaged transactions from stale count The "Gamla transaktioner" widget counted transactions that had been ignored or already marked as is_business=true but not yet booked, so users saw a nag for a row they had already dealt with — and the /transactions inbox correctly hid it. Align the count with the inbox criterion (is_business IS NULL, is_ignored = false) so the widget clears when the row leaves the inbox. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(transactions): read entity_type from settings response wrapper The transactions page read entityRes.entity_type directly, but /api/settings returns { data: { entity_type, ... } }. The expression was always undefined, so setEntityType never fired and entityType stayed at its initial 'enskild_firma'. The template picker's entity_type filter then dropped every aktiebolag-tagged user template for AB customers — only entity_type='all' templates made it through. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * stale templates bank sync journal entry from transaction * fixed pr comments * fixed pr comment --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
fc7a46c3f2
commit
ea1bf01f1e
@@ -0,0 +1,38 @@
|
||||
-- Extend the active-import partial unique index to also release the
|
||||
-- (company_id, file_hash) slot when a row is marked 'undone'.
|
||||
--
|
||||
-- Background: 20260528120100_undo_sie_import.sql introduced the 'undone'
|
||||
-- status (set by undo_sie_import RPC) but the partial unique index from
|
||||
-- 20260517150000_sie_imports_active_partial_unique.sql still only
|
||||
-- excluded 'replaced' and 'failed'. Net effect: a clean undo left the
|
||||
-- file_hash slot held, so the caller could not re-import the same file
|
||||
-- afterwards without going through replace_sie_import. Add 'undone' to
|
||||
-- the predicate so undo + retry works.
|
||||
--
|
||||
-- Backfill: prior to this migration, the executor would mark an import
|
||||
-- 'completed' even when journal_entries_created=0 (see Lookma AB support
|
||||
-- case 2026-05-28). Those rows hold the slot and block any retry. The
|
||||
-- companion code change in finalizeImportRecord prevents new occurrences;
|
||||
-- this backfill heals existing data by flipping every 'completed' row
|
||||
-- that produced literally zero entries to 'failed' (which the partial
|
||||
-- index already excludes). Safe by construction — no journal entries
|
||||
-- were ever created for these rows, so nothing downstream depends on
|
||||
-- their 'completed' status.
|
||||
|
||||
DROP INDEX IF EXISTS public.sie_imports_company_id_file_hash_active_idx;
|
||||
|
||||
CREATE UNIQUE INDEX sie_imports_company_id_file_hash_active_idx
|
||||
ON public.sie_imports (company_id, file_hash)
|
||||
WHERE status <> ALL (ARRAY['replaced'::text, 'failed'::text, 'undone'::text]);
|
||||
|
||||
UPDATE public.sie_imports
|
||||
SET status = 'failed',
|
||||
error_message = COALESCE(error_message || '; ', '')
|
||||
|| 'Backfill 2026-05-29: importen markerades som '
|
||||
|| '''completed'' men skapade 0 verifikationer. '
|
||||
|| 'Slot frigjord så filen kan importeras om med korrekta mappningar.'
|
||||
WHERE status = 'completed'
|
||||
AND transactions_count = 0
|
||||
AND opening_balance_entry_id IS NULL;
|
||||
|
||||
NOTIFY pgrst, 'reload schema';
|
||||
@@ -0,0 +1,12 @@
|
||||
-- Remember the last BAS account a user picked when paying a supplier invoice,
|
||||
-- so the next mark-paid dialog can default to it instead of forcing the user
|
||||
-- to re-pick 1930 / 1940 / 2018 / 2893 each time.
|
||||
--
|
||||
-- Free-text TEXT column — the existing chart_of_accounts CHECK constraint
|
||||
-- (4 ASCII digits per BAS standard) is enforced upstream by the Zod schema
|
||||
-- (accountNumber primitive in lib/api/schemas.ts).
|
||||
|
||||
ALTER TABLE company_settings
|
||||
ADD COLUMN last_supplier_payment_account TEXT;
|
||||
|
||||
NOTIFY pgrst, 'reload schema';
|
||||
@@ -0,0 +1,37 @@
|
||||
-- Migration: transactions.is_ignored
|
||||
--
|
||||
-- Adds an "ignore" flag for bank transactions the user has chosen to suppress
|
||||
-- from the bank reconciliation view (Rapporter → Bankavstämning) without
|
||||
-- booking them. Use case: small ränteintäkter, opening-balance adjustments,
|
||||
-- rounding noise — the user wants the row off the unmatched list but doesn't
|
||||
-- want to fabricate a verifikation.
|
||||
--
|
||||
-- The flag is intentionally orthogonal to `is_business`:
|
||||
-- - is_business=null → not yet triaged
|
||||
-- - is_business=true → bokförd som affärstransaktion (has journal_entry_id)
|
||||
-- - is_business=false → privat uttag (has journal_entry_id, 2013 in EF)
|
||||
-- - is_ignored=true → "hide from reconciliation, never going to book it"
|
||||
--
|
||||
-- An ignored transaction MUST NOT have a journal_entry_id. The check
|
||||
-- enforces that — once booked, the row has a verifikation and "ignored" is
|
||||
-- meaningless. Unignoring is just `is_ignored=false`; safe because we never
|
||||
-- created an entry to reverse.
|
||||
|
||||
ALTER TABLE public.transactions
|
||||
ADD COLUMN IF NOT EXISTS is_ignored BOOLEAN NOT NULL DEFAULT false;
|
||||
|
||||
-- An ignored transaction has no journal entry. Without this constraint a
|
||||
-- categorize → ignore race could leave the row both booked AND hidden from
|
||||
-- the reconciliation list, which is exactly the silent-divergence pattern
|
||||
-- bank reconciliation exists to prevent.
|
||||
ALTER TABLE public.transactions
|
||||
ADD CONSTRAINT transactions_is_ignored_no_journal_entry
|
||||
CHECK (is_ignored = false OR journal_entry_id IS NULL);
|
||||
|
||||
-- Partial index — most rows will be is_ignored=false, only the small slice
|
||||
-- of intentionally-skipped transactions need to be looked up by this flag.
|
||||
CREATE INDEX IF NOT EXISTS idx_transactions_is_ignored
|
||||
ON public.transactions (company_id, is_ignored)
|
||||
WHERE is_ignored = true;
|
||||
|
||||
NOTIFY pgrst, 'reload schema';
|
||||
@@ -0,0 +1,53 @@
|
||||
-- =============================================================================
|
||||
-- Salary absence: add 'unpaid_leave' (tjänstledighet utan lön)
|
||||
-- =============================================================================
|
||||
--
|
||||
-- The salary engine treats unpaid_leave as a per-day gross deduction (one
|
||||
-- daily rate per day) and excludes it from semestergrundande tid (SemL 17 §
|
||||
-- only paid leave types accrue vacation). It complements the existing partial-
|
||||
-- month employment_start/employment_end proration: that handles new hires and
|
||||
-- terminations; unpaid_leave handles sabbaticals/leave mid-employment.
|
||||
|
||||
ALTER TABLE public.salary_absence_days
|
||||
DROP CONSTRAINT salary_absence_days_absence_type_check;
|
||||
|
||||
ALTER TABLE public.salary_absence_days
|
||||
ADD CONSTRAINT salary_absence_days_absence_type_check
|
||||
CHECK (absence_type IN (
|
||||
'sick', -- sjukfrånvaro
|
||||
'vab', -- vård av barn (tillfällig föräldrapenning)
|
||||
'parental', -- föräldraledighet (föräldrapenning)
|
||||
'pregnancy', -- graviditetspenning
|
||||
'care_relative', -- närståendepenning
|
||||
'study', -- studieledig
|
||||
'unpaid_leave', -- tjänstledighet utan lön
|
||||
'other_leave'
|
||||
));
|
||||
|
||||
-- The derived absence line items (sick_karens, vab, parental_leave, …) are
|
||||
-- inserted into salary_line_items by the calculator. unpaid_leave follows the
|
||||
-- same pattern, so the line-item CHECK must accept it too.
|
||||
ALTER TABLE public.salary_line_items
|
||||
DROP CONSTRAINT salary_line_items_item_type_check;
|
||||
|
||||
ALTER TABLE public.salary_line_items
|
||||
ADD CONSTRAINT salary_line_items_item_type_check
|
||||
CHECK (item_type IN (
|
||||
'monthly_salary', 'hourly_salary',
|
||||
'overtime', 'overtime_50', 'overtime_100',
|
||||
'ob_weekday_evening', 'ob_weekend', 'ob_night', 'ob_holiday',
|
||||
'bonus', 'commission',
|
||||
'gross_deduction_pension', 'gross_deduction_other',
|
||||
'benefit_car', 'benefit_housing', 'benefit_meals',
|
||||
'benefit_wellness', 'benefit_bike', 'benefit_other',
|
||||
'sick_karens', 'sick_day2_14', 'sick_day15_plus',
|
||||
'vab', 'parental_leave', 'unpaid_leave',
|
||||
'vacation', 'semesterersattning',
|
||||
'traktamente_taxfree', 'traktamente_taxable',
|
||||
'mileage_taxfree', 'mileage_taxable',
|
||||
'net_deduction_advance', 'net_deduction_union',
|
||||
'net_deduction_benefit_payment', 'net_deduction_other',
|
||||
'correction', 'other'
|
||||
));
|
||||
|
||||
NOTIFY pgrst, 'reload schema';
|
||||
Reference in New Issue
Block a user