u
This commit is contained in:
@@ -974,7 +974,7 @@
|
||||
* type: string
|
||||
* ManifestLine:
|
||||
* type: object
|
||||
* required: [id, sku, name, pu, amount, net, rebate, taxrate, comment]
|
||||
* required: [id, sku, name, pu, amount, net, rebate, taxrate, shippable, comment]
|
||||
* description: Line shape for quote and order
|
||||
* properties:
|
||||
* id:
|
||||
@@ -1001,6 +1001,9 @@
|
||||
* comment:
|
||||
* type: string
|
||||
* nullable: true
|
||||
* shippable:
|
||||
* type: boolean
|
||||
* description: false for non-shippable lines (e.g. shipping cost, rounding); excluded from shipment and from order completeness (`isShipped`)
|
||||
* ManifestLineInput:
|
||||
* type: object
|
||||
* required: [amount, net, taxrate]
|
||||
@@ -1030,6 +1033,9 @@
|
||||
* comment:
|
||||
* type: string
|
||||
* nullable: true
|
||||
* shippable:
|
||||
* type: boolean
|
||||
* description: Defaults to true. Set false for non-shippable lines (e.g. shipping cost, rounding); they cannot be shipped and do not make the order incomplete.
|
||||
* QuoteSummary:
|
||||
* type: object
|
||||
* required: [id, number, type, date]
|
||||
|
||||
@@ -151,7 +151,7 @@ export function register(app, basePath = '') {
|
||||
* Creates a sales order with header and lines in one transaction.
|
||||
* `date` is the document date (expected delivery).
|
||||
* `entityId` must be a company customer (not Lieferanten).
|
||||
* Each line requires `sku` or `name`, `amount`, `net`, and `taxrate` (rate); `pu` defaults to `1`; `rebate` defaults to `0`.
|
||||
* Each line requires `sku` or `name`, `amount`, `net`, and `taxrate` (rate); `pu` defaults to `1`; `rebate` defaults to `0`; `shippable` defaults to `true` (`false` = not shippable, excluded from order completeness).
|
||||
* security:
|
||||
* - cookieAuth: []
|
||||
* x-markdown: order/create.md
|
||||
|
||||
@@ -181,11 +181,14 @@ export function register(app, basePath = '') {
|
||||
* description: Positions to ship
|
||||
* items:
|
||||
* type: object
|
||||
* required: [sku]
|
||||
* description: Provide `sku` for order lines with a SKU, or `orderLineId` for SKU-less order lines (exactly one of them).
|
||||
* properties:
|
||||
* sku:
|
||||
* type: string
|
||||
* description: Article SKU
|
||||
* description: Article SKU (omit for SKU-less order lines)
|
||||
* orderLineId:
|
||||
* type: integer
|
||||
* description: Order line id (`lines[].id` of the order); required for SKU-less lines, ignored when `sku` is given
|
||||
* amount:
|
||||
* type: number
|
||||
* description: Quantity to ship. Defaults to remaining unshipped quantity for this SKU.
|
||||
@@ -212,7 +215,7 @@ export function register(app, basePath = '') {
|
||||
* shipment:
|
||||
* $ref: '#/components/schemas/Shipment'
|
||||
* 400:
|
||||
* description: Validation error or article not in order
|
||||
* description: Validation error, article not in order, or article not shippable
|
||||
* content:
|
||||
* application/json:
|
||||
* schema:
|
||||
|
||||
@@ -30,6 +30,7 @@ function calculatePaidTotal(payments = []) {
|
||||
function calculateOrderedQuantity(lines = []) {
|
||||
let qty = 0;
|
||||
for (const line of lines) {
|
||||
if (line.shippable === false) continue;
|
||||
qty += Number(line.amount || 0);
|
||||
}
|
||||
return Math.round(qty * 1000) / 1000;
|
||||
|
||||
@@ -538,6 +538,7 @@ export async function executeCompanyExport({
|
||||
'"net"',
|
||||
'"taxrate"',
|
||||
'"sort"',
|
||||
'"shippable"',
|
||||
];
|
||||
|
||||
const manifestCsvRows = [manifestCsvHeaders.join(';')];
|
||||
@@ -588,6 +589,7 @@ export async function executeCompanyExport({
|
||||
formatCsvField(formatGermanFloat(line.net ?? 0)),
|
||||
formatCsvField(formatGermanFloat(line.taxrate ?? 19)),
|
||||
formatCsvField(line.sort ?? 0),
|
||||
formatCsvField(line.shippable !== false ? '1' : '0'),
|
||||
].join(';'));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,6 +261,14 @@ export async function importOrders({
|
||||
const rebate = parseGermanFloat(it.rebate ?? it.fRabatt, 0);
|
||||
const comment = cleanValue(it.comment ?? it.cHinweis) || null;
|
||||
|
||||
let shippable = true;
|
||||
if (it.shippable !== undefined && it.shippable !== null && String(it.shippable).trim() !== '') {
|
||||
const s = String(it.shippable).trim().toLowerCase();
|
||||
shippable = s !== '0' && s !== 'false';
|
||||
} else if (/^(summe glätten|shippingcost|versandkosten)$/i.test(name.trim())) {
|
||||
shippable = false;
|
||||
}
|
||||
|
||||
return {
|
||||
sku,
|
||||
name,
|
||||
@@ -269,6 +277,7 @@ export async function importOrders({
|
||||
taxrate,
|
||||
rebate,
|
||||
comment,
|
||||
shippable,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -355,9 +364,15 @@ export async function importOrders({
|
||||
const isShipped = String(m.shipped ?? '').trim() === '1';
|
||||
|
||||
if (isShipped || shippingType) {
|
||||
const shippableLines = lines
|
||||
.filter((l) => l.sku)
|
||||
.map((l) => ({ sku: l.sku, amount: l.amount }));
|
||||
const orderLines = createdOrder?.lines || lines;
|
||||
const shippableLines = orderLines
|
||||
.filter((l) => l.shippable !== false)
|
||||
.map((l) => {
|
||||
if (l.sku) return { sku: l.sku, amount: l.amount };
|
||||
if (l.id) return { orderLineId: l.id, amount: l.amount };
|
||||
return null;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
if (shippableLines.length > 0) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user