feat(mcp): currency param on create_article and update_article (#1184)

Fixes #1168. articles.currency exists in the DB and REST API, but the
staged-operation schemas and the two MCP tools had no currency param,
so agent-created articles were always SEK and an agent asked to create
an EUR-priced article could not.

- CreateArticleParamsSchema/UpdateArticleParamsSchema accept an
  optional ISO 4217 code (normalized to upper case; empty/null =
  unset). The currencies-table FK stays the allow-list: a 23503 on the
  currency FK maps to a clear 400 instead of a raw 500.
- commitCreateArticle inserts currency ?? 'SEK'; the sparse update
  executor passes it through only when staged.
- gnubok_create_article / gnubok_update_article expose the param.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Jakob Wennberg
2026-07-25 12:59:32 +02:00
committed by GitHub
co-authored by Claude Fable 5
parent 36a1df4f6b
commit d012d40b18
4 changed files with 62 additions and 2 deletions
+4 -1
View File
@@ -3911,6 +3911,7 @@ export const tools: McpTool[] = [
type: { type: 'string', enum: ['vara', 'tjanst'], description: 'Good (vara) or service (tjanst). Default tjanst.' },
unit: { type: 'string', description: 'Unit, e.g. st, tim, kg. Default st.' },
price_excl_vat: { type: 'number', description: 'Unit price EXCLUDING VAT.' },
currency: { type: 'string', description: 'Price currency as ISO 4217 code (e.g. EUR). Default SEK. Pre-fills the invoice currency when the article is added.' },
vat_rate: { type: 'number', enum: [0, 6, 12, 25], description: 'VAT rate percent. Default 25.' },
revenue_account: { type: 'string', description: 'Optional BAS class-3 revenue account (e.g. 3041). Omit to derive from VAT.' },
cost_price: { type: 'number', description: 'Optional cost price (margin only; never booked).' },
@@ -3942,6 +3943,7 @@ export const tools: McpTool[] = [
type: (args.type as string) || 'tjanst',
unit: (args.unit as string) || undefined,
price_excl_vat: args.price_excl_vat,
currency: (args.currency as string) || undefined,
vat_rate: typeof args.vat_rate === 'number' ? args.vat_rate : 25,
revenue_account: (args.revenue_account as string) || null,
cost_price: typeof args.cost_price === 'number' ? args.cost_price : null,
@@ -3983,6 +3985,7 @@ export const tools: McpTool[] = [
type: { type: 'string', enum: ['vara', 'tjanst'] },
unit: { type: 'string' },
price_excl_vat: { type: 'number' },
currency: { type: 'string', description: 'Price currency as ISO 4217 code (e.g. EUR), or omit to leave unchanged.' },
vat_rate: { type: 'number', enum: [0, 6, 12, 25] },
revenue_account: { type: 'string', description: 'BAS class-3 revenue account, or omit to leave unchanged.' },
cost_price: { type: 'number' },
@@ -4008,7 +4011,7 @@ export const tools: McpTool[] = [
const params: Record<string, unknown> = { article_id: articleId }
for (const key of [
'name', 'type', 'unit', 'price_excl_vat', 'vat_rate', 'revenue_account',
'name', 'type', 'unit', 'price_excl_vat', 'currency', 'vat_rate', 'revenue_account',
'cost_price', 'ean', 'housework_type', 'name_en', 'notes', 'active',
]) {
if (args[key] !== undefined) params[key] = args[key]