Wie im Belegeditor werden bei mode=normal/service fehlende Beschreibung, Name, Einheit, Preis, USt-Satz und Kostenstelle aus Artikel bzw. Leistung übernommen. descriptionText wird als description gespeichert, weil der Editor nur description liest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
3.4 KiB
TypeScript
64 lines
3.4 KiB
TypeScript
const nullableText = { type: ["string", "null"] }
|
|
|
|
export const outgoingAddressSchema = {
|
|
type: "object",
|
|
description: "Abweichende Empfängeradresse; Feldnamen entsprechen dem Belegeditor.",
|
|
properties: { street: nullableText, special: nullableText, zip: nullableText, city: nullableText },
|
|
additionalProperties: true,
|
|
}
|
|
|
|
export const outgoingRowsSchema = {
|
|
type: "array",
|
|
description: "Belegpositionen als Objekte. Beträge numerisch in EUR, unit als Einheiten-ID. Mengen und Preise dürfen für Korrekturpositionen negativ sein.",
|
|
items: {
|
|
type: "object",
|
|
properties: {
|
|
id: { type: "string", format: "uuid", description: "Optionale Positions-ID; wird sonst erzeugt." },
|
|
pos: { type: "string", description: "Positionsnummer, z. B. 1.1; wird sonst erzeugt." },
|
|
mode: { type: "string", enum: ["free", "normal", "service", "title", "text", "pagebreak"], default: "free" },
|
|
text: { type: "string" },
|
|
description: { type: "string", description: "Positionsbeschreibung. Ohne Angabe wird sie bei mode=normal/service aus Artikel bzw. Leistung übernommen, ebenso fehlender Name, Einheit, Preis und USt-Satz." },
|
|
descriptionText: { type: "string", description: "Veraltet; wird als description übernommen, wenn description fehlt." },
|
|
product: { type: "integer", minimum: 1, description: "Artikel-ID bei mode=normal." },
|
|
service: { type: "integer", minimum: 1, description: "Leistungs-ID bei mode=service." },
|
|
quantity: { type: "number", default: 1 },
|
|
unit: { type: "integer", minimum: 1 },
|
|
price: { type: "number", description: "Netto-Einzelpreis vor Positionsrabatt." },
|
|
inputPrice: { type: "number", description: "Eingegebener Einzelpreis; wird ohne price auch als price verwendet." },
|
|
purchasePrice: { type: "number" },
|
|
taxPercent: { type: "number", minimum: 0, maximum: 100 },
|
|
discountPercent: { type: "number", minimum: 0, maximum: 100, default: 0 },
|
|
costCentre: { type: ["string", "null"], format: "uuid", description: "Positionskostenstelle (abweichende Schreibweise zum Belegfeld costcentre)." },
|
|
optional: { type: "boolean" },
|
|
alternative: { type: "boolean" },
|
|
titleLevel: { type: "integer", minimum: 1, maximum: 3 },
|
|
linkedEntitys: {
|
|
type: "array",
|
|
items: { type: "object", properties: { type: { type: "string" }, subtype: { type: "string" }, id: { type: "integer", minimum: 1 } } },
|
|
},
|
|
},
|
|
// Preserve module-specific position fields used by existing callers.
|
|
additionalProperties: true,
|
|
},
|
|
}
|
|
|
|
export const outgoingReportSchema = {
|
|
type: "object",
|
|
description: "Optionale, vom Aufrufer berechnete Kalkulationswerte. Diese Felder werden gespeichert, nicht durch MCP berechnet.",
|
|
properties: {
|
|
totalProductsPurchasePrice: { type: "number" },
|
|
totalProductsFromServicesPurchasePrice: { type: "number" },
|
|
totalMargin: { type: "number" },
|
|
totalHoursSellingPrice: { type: "number" },
|
|
totalHoursFromServices: {
|
|
type: "object",
|
|
properties: {
|
|
total: { type: "number" },
|
|
totalPurchasePrice: { type: "number" },
|
|
byName: { type: "object", additionalProperties: { type: "number" } },
|
|
},
|
|
},
|
|
},
|
|
additionalProperties: true,
|
|
}
|