
Jakob WennbergandClaude Opus 4.8
c0b006fcc1
feat(invoicing): artikelregister (product/article catalog) with per-article revenue account (#703)
* feat(invoicing): artikelregister (product/article catalog) with per-article revenue account
Add a lean, non-inventory article catalog (artikelregister) so users can define
reusable invoice-line presets (name, unit, price excl VAT, VAT rate) with an
optional per-article BAS class-3 revenue-account override.
- DB: articles table (RLS via user_company_ids(), audit + updated_at triggers,
unique-per-company article_number), generate_article_number RPC (atomic +
idempotent), company_settings counter, nullable invoice_items.revenue_account
+ article_id, pending_operations CHECK expansion.
- Engine: generatePerRateLines groups revenue by (vat_rate, account) —
byte-identical with no override, balance-safe when split (last account absorbs
the rounding remainder), reverse_charge/export still force 3308/3305.
- API: /api/articles CRUD (soft-deactivate); override validated against
chart_of_accounts (active class-3) and frozen onto invoice lines at create.
- Propagation: override carried through send/mark-sent/credit/convert/cash and
the staged commit paths (recurring deferred — documented inline).
- MCP: gnubok_list/create/update_article (staged, scoped, risk-tiered).
- UI: articles register (list/detail/form) + nav + bilingual i18n + invoice-line
article picker & "Spara som artikel" quick-create.
- Tests: engine regression, route, and pg-real (RPC/RLS/triggers).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(mcp): strip ILIKE _ wildcard from gnubok_list_articles search
Underscore is a single-character ILIKE wildcard; stripping it (alongside the
existing %,()\* set) keeps a stray char in the article search from matching
every row. Read-only + RLS-scoped, so no security impact — addresses PR #703
reviewer + compliance-swarm CC6.3 notes.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-09 21:05:37 +02:00
..
2026-05-26 22:29:41 +02:00
2026-05-28 13:19:41 +02:00
2026-06-09 21:05:37 +02:00
2026-05-26 22:29:41 +02:00
2026-04-24 11:24:45 +02:00
2026-06-08 20:41:30 +02:00
2026-04-11 17:06:32 +02:00
2026-05-19 16:10:18 +02:00
2026-06-05 17:26:40 +02:00
2026-05-28 13:19:41 +02:00
2026-05-22 15:21:05 +02:00
2026-05-06 11:12:02 +02:00
2026-06-05 09:37:26 +02:00
2026-06-05 15:47:13 +02:00
2026-05-19 16:10:18 +02:00
2026-05-19 17:52:11 +02:00
2026-05-06 11:12:02 +02:00
2026-06-08 20:41:30 +02:00
2026-06-09 21:05:37 +02:00
2026-04-11 17:06:32 +02:00
2026-06-03 18:06:14 +02:00
2026-05-20 13:39:02 +02:00
2026-06-06 10:05:48 +02:00
2026-06-03 10:52:01 +02:00
2026-06-02 13:25:48 +02:00
2026-06-08 15:25:27 +02:00
2026-06-06 11:47:21 +02:00
2026-06-06 11:13:35 +02:00
2026-05-09 12:41:16 +02:00
2026-06-08 07:37:24 +02:00
2026-05-08 15:42:06 +02:00
2026-04-29 16:32:26 +02:00
2026-05-06 11:12:02 +02:00
2026-04-13 16:15:20 +02:00
2026-06-09 19:09:39 +02:00
2026-05-21 21:33:22 +02:00
2026-06-09 21:05:37 +02:00
2026-05-28 13:19:41 +02:00
2026-05-15 14:00:04 +02:00
2026-06-05 10:11:37 +02:00