From 0d726c76f8685f69072326d121be629bc2bd5671 Mon Sep 17 00:00:00 2001 From: seb Date: Thu, 15 Oct 2026 22:49:14 +0200 Subject: [PATCH] u --- src/store/shipment/create.js | 7 ++++++- src/store/shipment/helpers.js | 4 +++- src/store/shipment/syncSummary.js | 8 ++++++++ src/store/shipping/create.js | 3 +++ src/store/shipping/delete.js | 5 +++++ src/store/shipping/update.js | 3 +++ 6 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/store/shipment/create.js b/src/store/shipment/create.js index 026c239..81d8dbb 100644 --- a/src/store/shipment/create.js +++ b/src/store/shipment/create.js @@ -34,6 +34,7 @@ export default function create(provider) { * @param {object} input - The shipment input. * @param {number} input.orderId - The parent order manifest id. * @param {string|Date} [input.date] - Optional shipment date (defaults to current date). + * @param {'new'|'delivered'|'returned'} [input.state='new'] - Optional delivery state (defaults to 'new'). * @param {string} [input.externalNumber] - Optional external delivery note number (defaults to order.externalNumber or order.number). * @param {Array<{sku: string, amount?: number, name?: string, pu?: number, net?: number, rebate?: number, taxrate?: number, comment?: string}>} [input.lines] - The shipment positions (optional). * @param {object} [tx] - Optional transaction. @@ -232,12 +233,16 @@ export default function create(provider) { // 9. Synchronize order summary row and shipment summary row await syncOrderSummary(runner, { companyId, manifestId: orderId }); + const validState = input.state && ['new', 'delivered', 'returned'].includes(String(input.state).trim().toLowerCase()) + ? String(input.state).trim().toLowerCase() + : 'new'; + await syncShipmentSummary(runner, { companyId, manifestId, orderId, orderNumber: order.number, - state: 'new', + state: validState, }); return loadShipment(runner, q, companyId, manifestId); diff --git a/src/store/shipment/helpers.js b/src/store/shipment/helpers.js index 6c79607..6499edd 100644 --- a/src/store/shipment/helpers.js +++ b/src/store/shipment/helpers.js @@ -39,9 +39,10 @@ export async function loadShipment(runner, q, companyId, id) { const row = headerRes.rows[0]; if (!row) return null; - const [linesRes, shippingsRes] = await Promise.all([ + const [linesRes, shippingsRes, summaryRes] = await Promise.all([ runner.query(q.GET_MANIFEST_LINES, { manifestId: id }), runner.query(q.SHIPPING_LIST_BY_MANIFEST, { manifestId: id }), + runner.query('SELECT state FROM shipmentsummary WHERE manifest_id = @manifestId', { manifestId: id }).catch(() => ({ rows: [] })), ]); const lines = linesRes.rows.map(shapeLine); @@ -57,6 +58,7 @@ export async function loadShipment(runner, q, companyId, id) { createdAt: row.createdAt ?? null, lineCount: lines.length, packageCount: shippings.length, + state: summaryRes.rows[0]?.state || 'new', lines, shippings, }; diff --git a/src/store/shipment/syncSummary.js b/src/store/shipment/syncSummary.js index 3f51d5a..a8dbb71 100644 --- a/src/store/shipment/syncSummary.js +++ b/src/store/shipment/syncSummary.js @@ -214,6 +214,14 @@ export async function syncShipmentSummary(runner, { companyId, manifestId, order const existingState = existingRes.rows[0]?.state; if (existingState && VALID_STATES.has(existingState)) { resolvedState = existingState; + } else { + const hasShippedPackage = await runner.query( + "SELECT 1 FROM shipping WHERE manifest_id = @manifestId AND LOWER(state) = 'shipped'", + { manifestId }, + ); + if (hasShippedPackage.rows[0]) { + resolvedState = 'delivered'; + } } } diff --git a/src/store/shipping/create.js b/src/store/shipping/create.js index 0e55e35..335d5bc 100644 --- a/src/store/shipping/create.js +++ b/src/store/shipping/create.js @@ -3,6 +3,7 @@ import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyA import nextNumber from '../numbers/nextNumber.js'; import ledgerAdd from '../ledger/add.js'; import makeRunner from '../runner.js'; +import { syncShipmentSummary } from '../shipment/syncSummary.js'; function shape(row) { return { @@ -176,6 +177,8 @@ export default function create(provider) { } } + await syncShipmentSummary(runner, { companyId, manifestId }); + return shape(row); }; diff --git a/src/store/shipping/delete.js b/src/store/shipping/delete.js index ca470b0..052a49f 100644 --- a/src/store/shipping/delete.js +++ b/src/store/shipping/delete.js @@ -1,6 +1,7 @@ import { queriesFor, requireId } from '../logistics/helpers.js'; import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js'; import makeRunner from '../runner.js'; +import { syncShipmentSummary } from '../shipment/syncSummary.js'; /** * Deletes a shipping of the user's selected company. Its packages are removed by cascade. @@ -37,5 +38,9 @@ export default function del(provider) { } await runner.query(q.SHIPPING_DELETE, { id: shippingId, companyId }); + await syncShipmentSummary(runner, { + companyId, + manifestId: shipping.manifestId ?? shipping.manifest_id, + }); }; } diff --git a/src/store/shipping/update.js b/src/store/shipping/update.js index bfa6761..2ce5c9c 100644 --- a/src/store/shipping/update.js +++ b/src/store/shipping/update.js @@ -2,6 +2,7 @@ import { queriesFor, requireId, requireText } from '../logistics/helpers.js'; import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js'; import ledgerAdd from '../ledger/add.js'; import makeRunner from '../runner.js'; +import { syncShipmentSummary } from '../shipment/syncSummary.js'; function shape(row) { return { @@ -196,6 +197,8 @@ export default function update(provider) { state: nextState, }; + await syncShipmentSummary(runner, { companyId, manifestId: current.manifestId }); + return shape(updatedRow); };