* feat(parties): name the company inside a voucher text, and stop asking SCB about foreign ones
The registry picker searched SCB on the whole display name, which for an
assistant-written voucher is a sentence, so "1511768101 · Visma Spcs AB,
faktura ..." never matched and foreign suppliers produced an empty list
with no explanation.
- lib/parties/name-extract.ts: name candidates read out of the text,
anchored on legal-form words (AB, AB (publ), Inc., Ltd, B.V., GmbH, Oy,
...) and on country words, plus EU VAT numbers. Every candidate is a
substring of the text; foreign forms and countries mark the candidate
as one SCB cannot hold.
- Suggestions: the display name prefers the legal person named in the
text ("TIC identity" becomes "The Intelligence Company AB (publ)"),
the voucher texts are stored as a ledger fact for the picker, the
country is stored when the text says, and a single foreign VAT number
in the text becomes the party's VAT number.
- GET .../enrich/candidates plans the search: Swedish legal person first,
cleaned head last, at most three queries, stopping at the first hit;
no SCB call when the best reading is foreign, the response says which
company it read and where.
- Picker: "X ser ut att vara ett utländskt bolag (Irland). SCB:s register
täcker bara svenska företag." with a hint to save by name and VAT
number; alternate readings offered as one-click searches when the
first found nothing.
- nameQuery strips stacked legal-form suffixes ("AB (publ)").
- The queue builds itself whenever the books hold counterparts it has
not seen, not only on a first visit; the toast only appears when
something was created.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix(parties): take a text-derived VAT number only on the expense side
A customer's VAT number steers reverse charge on outgoing invoices, so it
must come from a document or a person, never from a text heuristic. A
supplier's is informational and may still be read from the voucher text.
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>
47 lines
2.0 KiB
TypeScript
47 lines
2.0 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { planRegistryQueries } from '../registry-search'
|
|
|
|
describe('planRegistryQueries', () => {
|
|
it('asks for the Swedish legal person before the bank memo head', () => {
|
|
const plan = planRegistryQueries({
|
|
legalName: null,
|
|
displayName: 'TIC identity',
|
|
voucherTexts: ['TIC identity BG 0000005786439 Bg-bet. via internet · Faktura 20250746, The Intelligence Company AB (publ). TIC Identity-abonnemang.'],
|
|
})
|
|
expect(plan.queries).toEqual(['The Intelligence Company', 'TIC identity'])
|
|
expect(plan.foreign).toBeNull()
|
|
})
|
|
|
|
it('plans no SCB query for a foreign company and says which one it read', () => {
|
|
const plan = planRegistryQueries({
|
|
legalName: null,
|
|
displayName: 'Framer B.V.',
|
|
voucherTexts: ['Utlägg Framer · Framer B.V. (NL), webbdesignverktyg.'],
|
|
})
|
|
expect(plan.queries).toEqual([])
|
|
expect(plan.foreign).toEqual({ name: 'Framer B.V.', legalForm: 'B.V.', country: 'NL' })
|
|
})
|
|
|
|
it('reads the country anchor when the head is a card memo', () => {
|
|
const plan = planRegistryQueries({
|
|
legalName: null,
|
|
displayName: 'Claude Maj H',
|
|
voucherTexts: ['Claude Maj H Överföring via internet · Anthropic Ireland, faktura 22,5 EUR inkl 4,5 EUR VAT-Sweden 25% via OSS.'],
|
|
})
|
|
expect(plan.queries).toEqual([])
|
|
expect(plan.foreign).toEqual({ name: 'Anthropic Ireland', country: 'IE' })
|
|
})
|
|
|
|
it('uses the plain name when nothing points abroad, and caps at three queries', () => {
|
|
const plan = planRegistryQueries({ legalName: 'Adobe Systems Software', displayName: 'ADOBE SYSTEMS', voucherTexts: [] })
|
|
expect(plan.queries).toEqual(['Adobe Systems Software', 'ADOBE SYSTEMS'])
|
|
expect(plan.foreign).toBeNull()
|
|
const many = planRegistryQueries({
|
|
legalName: null,
|
|
displayName: 'Acme',
|
|
voucherTexts: ['Alfa AB · x', 'Beta AB · y', 'Gamma AB · z', 'Delta AB · w'],
|
|
})
|
|
expect(many.queries).toHaveLength(3)
|
|
})
|
|
})
|