Files
accounted/lib/invoices/voucher-matching-shared.ts
T
f266c386f3 chore: repo-wide bloat sweep, remove dead code and fold duplicate helpers (#2150)
* chore: repo-wide bloat sweep, remove dead code and fold duplicate helpers

Remove 33 dead files, ~270 unreferenced exports/types, 13 dead i18n
namespaces and 4 unused dependencies; fold byte-identical helper copies
into one canonical home each (lib/utils chunk/sleep/utcDateStamp,
lib/dates/iso, lib/invariants/uuid, lib/xml/escape, lib/reports/sru/format,
lib/pdf/number-text, lib/browser/panel-request, lib/api/v1/body +
v1ValidationError rolled out to ~55 v1 routes, booking-template schemas).

No behaviour change: v1 bodies and status codes, MCP tool schemas, DB
writes and money math are untouched. Naive ore rounding was deliberately
not swapped for roundOre; see DECISIONS.md 2026-09-02 for the full list
of things left alone on purpose.

tsc, lint, 19588 unit tests and check:guards green; antipattern baseline
ratcheted (naive-ore-round 622 -> 620, hand-rolled-invariant 115 -> 113).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* test(transactions): import RawTransaction from @/types after the ingest re-export removal

CI's type ratchet (check:types, full tsconfig) caught the one test file
that still imported the type through lib/transactions/ingest.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Jakob Wennberg <311770904+jakobwennberg-oss@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-02 11:51:16 +02:00

63 lines
2.1 KiB
TypeScript

/**
* Row shapes, tolerances and helpers shared by the customer-side
* (voucher-matching.ts) and supplier-side (supplier-voucher-matching.ts)
* "link an existing verifikat as the payment" flows. Both files read the same
* journal tables and rank candidates the same way; only the account side
* (151x credits vs 244x debits) and the invoice type differ.
*/
/** ±90 days from the invoice's due_date as the default search window. */
export const DEFAULT_DATE_WINDOW_DAYS = 90
/** Tolerance for floating-point comparisons on monetary amounts (0.5 öre). */
export const AMOUNT_TOLERANCE = 0.005
/** Date-proximity bump applied when entry_date is within ±7 days of due_date. */
export const DATE_PROXIMITY_BUMP = 0.05
export interface VoucherMatchLineRow {
id: string
journal_entry_id: string
account_number: string
debit_amount: number | null
credit_amount: number | null
/** Labels the DOCUMENT, NOT the unit of debit_amount/credit_amount. */
currency: string | null
/** The line's amount in `currency`: the only non-SEK figure on the row. */
amount_in_currency: number | string | null
}
export interface VoucherRow {
id: string
voucher_series: string | null
voucher_number: number | null
entry_date: string
description: string
status: string
source_type: string | null
fiscal_period_id: string
}
/** `fiscal_periods` has no `status` column: open/locked/closed is derived from
* `is_closed` + `locked_at`, exactly as the `enforce_period_lock` trigger
* (migration 017) and `resolvePeriodStatusForDate()` do it. */
export interface FiscalPeriodRow {
id: string
is_closed: boolean | null
locked_at: string | null
}
/** SQL-side filter for posted, non-storno, non-opening entries. */
export const EXCLUDED_SOURCE_TYPES = ['opening_balance', 'storno']
export function round2(n: number): number {
return Math.round(n * 100) / 100
}
export function isDateWithinDays(a: string, b: string, days: number): boolean {
const ad = new Date(a).getTime()
const bd = new Date(b).getTime()
if (Number.isNaN(ad) || Number.isNaN(bd)) return false
return Math.abs(ad - bd) <= days * 24 * 3600 * 1000
}