This commit is contained in:
seb
2026-10-13 13:21:11 +02:00
parent a5886b7c92
commit 8a626b17fc
15 changed files with 541 additions and 83 deletions

View File

@@ -17,6 +17,7 @@ import taxEnsure from '../tax/ensure.js';
import { insertLines, normalizeLines, parseDate } from '../manifestLines.js';
import { assertCustomerEntity, loadDoc } from '../manifestDoc/helpers.js';
import { recordOrderHistory } from '../articlehistory/record.js';
import { syncOrderSummary } from './syncSummary.js';
import makeRunner from '../runner.js';
export default function create(provider) {
@@ -129,6 +130,8 @@ export default function create(provider) {
id: manifestId,
});
await syncOrderSummary(runner, { companyId, manifestId });
return doc;
};

View File

@@ -124,97 +124,19 @@ export default function list(provider) {
// Only unpaid (strictly boolean true; overpaid orders also count as unpaid)
if (opts?.onlyUnpaid === true) {
conditions.push(`(
COALESCE((
SELECT SUM(ma.amount * (ma.net * (1.0 - ma.rebate / 100.0)) * (1.0 + ma.taxrate / 100.0))
FROM manifestarticle ma
WHERE ma.manifest_id = m.id
), 0) = 0
OR
ABS(
COALESCE((
SELECT SUM(p.amount)
FROM payment p
WHERE p.manifest_id = m.id
), 0)
-
COALESCE((
SELECT SUM(ma.amount * (ma.net * (1.0 - ma.rebate / 100.0)) * (1.0 + ma.taxrate / 100.0))
FROM manifestarticle ma
WHERE ma.manifest_id = m.id
), 0)
) >= 0.01
)`);
conditions.push('COALESCE(os.is_paid, 0) = 0');
}
// Only undelivered (strictly boolean true)
if (opts?.onlyUndelivered === true) {
const prefixRes = await runner.query(sqlShipmentPrefix, { companyId });
params.shipmentPrefix = prefixRes.rows[0]?.prefix?.trim?.() || '-L-';
if (isSqlite) {
conditions.push(`NOT (
(
COALESCE((SELECT SUM(ma.amount) FROM manifestarticle ma WHERE ma.manifest_id = m.id), 0) > 0
AND
COALESCE((
SELECT SUM(ma_s.amount)
FROM manifest m_s
JOIN manifestarticle ma_s ON ma_s.manifest_id = m_s.id
WHERE m_s.company_id = m.company_id
AND m_s."type" = 'shipment'
AND m_s."number" LIKE (m."number" || @shipmentPrefix || '%')
), 0) >= (SELECT SUM(ma.amount) FROM manifestarticle ma WHERE ma.manifest_id = m.id) - 0.001
)
OR EXISTS (
SELECT 1 FROM shipping s
WHERE (
s.manifest_id = m.id
OR s.manifest_id IN (
SELECT m_s.id FROM manifest m_s
WHERE m_s.company_id = m.company_id
AND m_s."type" = 'shipment'
AND m_s."number" LIKE (m."number" || @shipmentPrefix || '%')
)
)
AND LOWER(s."state") IN ('shipped', 'delivered')
)
)`);
} else {
conditions.push(`NOT (
(
COALESCE((SELECT SUM(ma.amount) FROM manifestarticle ma WHERE ma.manifest_id = m.id), 0) > 0
AND
COALESCE((
SELECT SUM(ma_s.amount)
FROM manifest m_s
JOIN manifestarticle ma_s ON ma_s.manifest_id = m_s.id
WHERE m_s.company_id = m.company_id
AND m_s.[type] = 'shipment'
AND m_s.[number] LIKE (m.[number] + @shipmentPrefix + '%')
), 0) >= (SELECT SUM(ma.amount) FROM manifestarticle ma WHERE ma.manifest_id = m.id) - 0.001
)
OR EXISTS (
SELECT 1 FROM shipping s
WHERE (
s.manifest_id = m.id
OR s.manifest_id IN (
SELECT m_s.id FROM manifest m_s
WHERE m_s.company_id = m.company_id
AND m_s.[type] = 'shipment'
AND m_s.[number] LIKE (m.[number] + @shipmentPrefix + '%')
)
)
AND LOWER(s.[state]) IN ('shipped', 'delivered')
)
)`);
}
conditions.push('COALESCE(os.is_shipped, 0) = 0');
}
const whereClause = conditions.join('\n AND ');
const sqlCount = `
SELECT COUNT(*) AS total
FROM manifest m
LEFT JOIN ordersummary os ON os.manifest_id = m.id
LEFT JOIN entity e ON e.id = m.entity_id
WHERE ${whereClause}
`;
@@ -229,8 +151,17 @@ export default function list(provider) {
m.entity_id AS entityId,
m.external_number AS externalNumber,
m."date",
m.created_at AS createdAt
m.created_at AS createdAt,
os.positions,
os.gross_total AS grossTotal,
os.paid_total AS paidTotal,
os.ordered_quantity AS orderedQuantity,
os.shipped_quantity AS shippedQuantity,
os.is_paid AS isPaid,
os.is_shipped AS isShipped,
os.customer_name AS customerName
FROM manifest m
LEFT JOIN ordersummary os ON os.manifest_id = m.id
LEFT JOIN entity e ON e.id = m.entity_id
WHERE ${whereClause}
ORDER BY m."date" DESC, m.id DESC
@@ -245,8 +176,17 @@ export default function list(provider) {
m.entity_id AS entityId,
m.external_number AS externalNumber,
m.[date],
m.created_at AS createdAt
m.created_at AS createdAt,
os.positions,
os.gross_total AS grossTotal,
os.paid_total AS paidTotal,
os.ordered_quantity AS orderedQuantity,
os.shipped_quantity AS shippedQuantity,
os.is_paid AS isPaid,
os.is_shipped AS isShipped,
os.customer_name AS customerName
FROM manifest m
LEFT JOIN ordersummary os ON os.manifest_id = m.id
LEFT JOIN entity e ON e.id = m.entity_id
WHERE ${whereClause}
ORDER BY m.[date] DESC, m.id DESC
@@ -292,6 +232,14 @@ export default function list(provider) {
const orders = manifestRows.map((row) => ({
...shapeSummary(orderType, row),
lines: linesByManifestId.get(row.id) ?? [],
positions: row.positions !== undefined && row.positions !== null ? Number(row.positions) : undefined,
grossTotal: row.grossTotal !== undefined && row.grossTotal !== null ? Number(row.grossTotal) : undefined,
paidTotal: row.paidTotal !== undefined && row.paidTotal !== null ? Number(row.paidTotal) : undefined,
orderedQuantity: row.orderedQuantity !== undefined && row.orderedQuantity !== null ? Number(row.orderedQuantity) : undefined,
shippedQuantity: row.shippedQuantity !== undefined && row.shippedQuantity !== null ? Number(row.shippedQuantity) : undefined,
isPaid: row.isPaid !== undefined && row.isPaid !== null ? Boolean(row.isPaid) : undefined,
isShipped: row.isShipped !== undefined && row.isShipped !== null ? Boolean(row.isShipped) : undefined,
customerName: row.customerName ?? undefined,
}));
if (isPaged) {

View File

@@ -0,0 +1,19 @@
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
import makeRunner from '../runner.js';
import { rebuildOrderSummaries } from './syncSummary.js';
/**
* Rebuilds the `ordersummary` table for the user's selected company.
*
* @param {import('../../providers/provider.js').DatabaseProvider} provider
*/
export default function rebuildSummaries(provider) {
const access = resolveSelectedCompanyAccess(provider);
return async (googleAuthId, tx) => {
const runner = makeRunner(provider, tx);
const { companyId } = await access(googleAuthId, runner);
await rebuildOrderSummaries(runner, companyId);
return { ok: true, companyId };
};
}

View File

@@ -0,0 +1,364 @@
/**
* Centralized sync and rebuild logic for the materialized `ordersummary` table.
*/
const SQL_GET_SHIPMENT_PREFIX = `
SELECT prefix FROM numbers WHERE company_id = @companyId AND [type] = 'shipment'
`;
const SQL_GET_ORDER_BY_ID_SQLITE = `
SELECT m.id, m.company_id, m."number", m."date", m.created_at, m.entity_id
FROM manifest m
WHERE m.id = @manifestId AND m.company_id = @companyId AND m."type" = 'order'
`;
const SQL_GET_ORDER_BY_ID_MSSQL = `
SELECT m.id, m.company_id, m.[number], m.[date], m.created_at, m.entity_id
FROM manifest m
WHERE m.id = @manifestId AND m.company_id = @companyId AND m.[type] = 'order'
`;
const SQL_GET_ORDER_BY_NUMBER_SQLITE = `
SELECT m.id, m.company_id, m."number", m."date", m.created_at, m.entity_id
FROM manifest m
WHERE m."number" = @number AND m.company_id = @companyId AND m."type" = 'order'
`;
const SQL_GET_ORDER_BY_NUMBER_MSSQL = `
SELECT m.id, m.company_id, m.[number], m.[date], m.created_at, m.entity_id
FROM manifest m
WHERE m.[number] = @number AND m.company_id = @companyId AND m.[type] = 'order'
`;
const SQL_LINE_TOTALS = `
SELECT
COUNT(*) AS positions,
COALESCE(SUM(amount), 0) AS ordered_quantity,
COALESCE(SUM(amount * (net * (1.0 - rebate / 100.0)) * (1.0 + taxrate / 100.0)), 0) AS gross_total
FROM manifestarticle
WHERE manifest_id = @manifestId
`;
const SQL_PAYMENT_TOTAL = `
SELECT COALESCE(SUM(amount), 0) AS paid_total
FROM payment
WHERE manifest_id = @manifestId
`;
const SQL_SHIPPED_QTY_SQLITE = `
SELECT COALESCE(SUM(ma_s.amount), 0) AS shipped_quantity
FROM manifest m_s
JOIN manifestarticle ma_s ON ma_s.manifest_id = m_s.id
WHERE m_s.company_id = @companyId
AND m_s."type" = 'shipment'
AND m_s."number" >= (@orderNumber || @shipmentPrefix)
AND m_s."number" < (@orderNumber || @shipmentPrefix || char(127))
`;
const SQL_SHIPPED_QTY_MSSQL = `
SELECT COALESCE(SUM(ma_s.amount), 0) AS shipped_quantity
FROM manifest m_s
JOIN manifestarticle ma_s ON ma_s.manifest_id = m_s.id
WHERE m_s.company_id = @companyId
AND m_s.[type] = 'shipment'
AND m_s.[number] >= (@orderNumber + @shipmentPrefix)
AND m_s.[number] < (@orderNumber + @shipmentPrefix + NCHAR(127))
`;
const SQL_CUSTOMER_NAME_SQLITE = `
SELECT TRIM(COALESCE(first_name || ' ', '') || COALESCE(name, '')) AS customer_name
FROM entity
WHERE id = @entityId
`;
const SQL_CUSTOMER_NAME_MSSQL = `
SELECT LTRIM(RTRIM(ISNULL(first_name + ' ', '') + ISNULL(name, ''))) AS customer_name
FROM entity
WHERE id = @entityId
`;
const SQL_UPSERT_SUMMARY_SQLITE = `
INSERT INTO ordersummary (
company_id, manifest_id, order_number, order_date, created_at,
entity_id, customer_name, positions, gross_total, paid_total,
ordered_quantity, shipped_quantity, is_paid, is_shipped
) VALUES (
@companyId, @manifestId, @orderNumber, @orderDate, @createdAt,
@entityId, @customerName, @positions, @grossTotal, @paidTotal,
@orderedQuantity, @shippedQuantity, @isPaid, @isShipped
)
ON CONFLICT(manifest_id) DO UPDATE SET
order_number = excluded.order_number,
order_date = excluded.order_date,
created_at = excluded.created_at,
entity_id = excluded.entity_id,
customer_name = excluded.customer_name,
positions = excluded.positions,
gross_total = excluded.gross_total,
paid_total = excluded.paid_total,
ordered_quantity = excluded.ordered_quantity,
shipped_quantity = excluded.shipped_quantity,
is_paid = excluded.is_paid,
is_shipped = excluded.is_shipped
`;
const SQL_UPSERT_SUMMARY_MSSQL = `
MERGE INTO ordersummary AS target
USING (SELECT @manifestId AS manifest_id) AS source
ON (target.manifest_id = source.manifest_id)
WHEN MATCHED THEN
UPDATE SET
order_number = @orderNumber,
order_date = @orderDate,
created_at = @createdAt,
entity_id = @entityId,
customer_name = @customerName,
positions = @positions,
gross_total = @grossTotal,
paid_total = @paidTotal,
ordered_quantity = @orderedQuantity,
shipped_quantity = @shippedQuantity,
is_paid = @isPaid,
is_shipped = @isShipped
WHEN NOT MATCHED THEN
INSERT (
company_id, manifest_id, order_number, order_date, created_at,
entity_id, customer_name, positions, gross_total, paid_total,
ordered_quantity, shipped_quantity, is_paid, is_shipped
) VALUES (
@companyId, @manifestId, @orderNumber, @orderDate, @createdAt,
@entityId, @customerName, @positions, @grossTotal, @paidTotal,
@orderedQuantity, @shippedQuantity, @isPaid, @isShipped
);
`;
/**
* Recalculates and upserts a single order summary into `ordersummary`.
*
* @param {object} runner - Database runner.
* @param {object} opts
* @param {number} opts.companyId
* @param {number} [opts.manifestId] - Order manifest id.
* @param {string} [opts.orderNumber] - Order number (if manifestId not given).
*/
export async function syncOrderSummary(runner, { companyId, manifestId, orderNumber }) {
const isSqlite = runner.dialect === 'sqlite3';
let orderRow;
if (manifestId) {
const res = await runner.query(
isSqlite ? SQL_GET_ORDER_BY_ID_SQLITE : SQL_GET_ORDER_BY_ID_MSSQL,
{ manifestId, companyId },
);
orderRow = res.rows[0];
} else if (orderNumber) {
const res = await runner.query(
isSqlite ? SQL_GET_ORDER_BY_NUMBER_SQLITE : SQL_GET_ORDER_BY_NUMBER_MSSQL,
{ number: orderNumber, companyId },
);
orderRow = res.rows[0];
}
if (!orderRow) {
if (manifestId) {
await runner.query('DELETE FROM ordersummary WHERE manifest_id = @manifestId', { manifestId });
}
return;
}
const orderId = orderRow.id;
const num = orderRow.number;
const prefixRes = await runner.query(SQL_GET_SHIPMENT_PREFIX, { companyId });
const shipmentPrefix = prefixRes.rows[0]?.prefix?.trim?.() || '-L-';
const [lineRes, payRes, shipRes] = await Promise.all([
runner.query(SQL_LINE_TOTALS, { manifestId: orderId }),
runner.query(SQL_PAYMENT_TOTAL, { manifestId: orderId }),
runner.query(isSqlite ? SQL_SHIPPED_QTY_SQLITE : SQL_SHIPPED_QTY_MSSQL, {
companyId,
orderNumber: num,
shipmentPrefix,
}),
]);
let customerName = null;
if (orderRow.entity_id) {
const custRes = await runner.query(
isSqlite ? SQL_CUSTOMER_NAME_SQLITE : SQL_CUSTOMER_NAME_MSSQL,
{ entityId: orderRow.entity_id },
);
customerName = custRes.rows[0]?.customer_name || null;
}
const positions = Number(lineRes.rows[0]?.positions || 0);
const orderedQuantity = Math.round(Number(lineRes.rows[0]?.ordered_quantity || 0) * 1000) / 1000;
const grossTotal = Math.round(Number(lineRes.rows[0]?.gross_total || 0) * 100) / 100;
const paidTotal = Math.round(Number(payRes.rows[0]?.paid_total || 0) * 100) / 100;
const shippedQuantity = Math.round(Number(shipRes.rows[0]?.shipped_quantity || 0) * 1000) / 1000;
const isPaid = grossTotal > 0 && Math.abs(paidTotal - grossTotal) < 0.01 ? 1 : 0;
const isShipped = orderedQuantity > 0 && Math.abs(shippedQuantity - orderedQuantity) < 0.001 ? 1 : 0;
await runner.query(isSqlite ? SQL_UPSERT_SUMMARY_SQLITE : SQL_UPSERT_SUMMARY_MSSQL, {
companyId,
manifestId: orderId,
orderNumber: num,
orderDate: orderRow.date,
createdAt: orderRow.created_at,
entityId: orderRow.entity_id ?? null,
customerName,
positions,
grossTotal,
paidTotal,
orderedQuantity,
shippedQuantity,
isPaid,
isShipped,
});
}
/**
* Full rebuild of all orders in `ordersummary` for a given company.
*
* @param {object} runner
* @param {number} companyId
*/
export async function rebuildOrderSummaries(runner, companyId) {
const isSqlite = runner.dialect === 'sqlite3';
const prefixRes = await runner.query(SQL_GET_SHIPMENT_PREFIX, { companyId });
const shipmentPrefix = prefixRes.rows[0]?.prefix?.trim?.() || '-L-';
if (isSqlite) {
const sqlRebuildSqlite = `
WITH
order_articles AS (
SELECT
manifest_id,
COUNT(*) AS positions,
SUM(amount) AS ordered_quantity,
SUM(amount * (net * (1.0 - rebate / 100.0)) * (1.0 + taxrate / 100.0)) AS gross_total
FROM manifestarticle
GROUP BY manifest_id
),
order_payments AS (
SELECT
manifest_id,
SUM(amount) AS paid_total
FROM payment
GROUP BY manifest_id
),
shipment_totals AS (
SELECT
SUBSTR(m_s."number", 1, INSTR(m_s."number", @shipmentPrefix) - 1) AS order_number,
SUM(ma_s.amount) AS shipped_quantity
FROM manifest m_s
JOIN manifestarticle ma_s ON ma_s.manifest_id = m_s.id
WHERE m_s.company_id = @companyId
AND m_s."type" = 'shipment'
AND INSTR(m_s."number", @shipmentPrefix) > 0
GROUP BY SUBSTR(m_s."number", 1, INSTR(m_s."number", @shipmentPrefix) - 1)
)
INSERT INTO ordersummary (
company_id, manifest_id, order_number, order_date, created_at,
entity_id, customer_name, positions, gross_total, paid_total,
ordered_quantity, shipped_quantity, is_paid, is_shipped
)
SELECT
m.company_id,
m.id AS manifest_id,
m."number" AS order_number,
m."date" AS order_date,
m.created_at,
m.entity_id,
TRIM(COALESCE(e.first_name || ' ', '') || COALESCE(e.name, '')) AS customer_name,
COALESCE(oa.positions, 0) AS positions,
ROUND(COALESCE(oa.gross_total, 0), 2) AS gross_total,
ROUND(COALESCE(op.paid_total, 0), 2) AS paid_total,
ROUND(COALESCE(oa.ordered_quantity, 0), 3) AS ordered_quantity,
ROUND(COALESCE(st.shipped_quantity, 0), 3) AS shipped_quantity,
CASE WHEN COALESCE(oa.gross_total, 0) > 0 AND ABS(COALESCE(op.paid_total, 0) - oa.gross_total) < 0.01 THEN 1 ELSE 0 END AS is_paid,
CASE WHEN COALESCE(oa.ordered_quantity, 0) > 0 AND ABS(COALESCE(st.shipped_quantity, 0) - oa.ordered_quantity) < 0.001 THEN 1 ELSE 0 END AS is_shipped
FROM manifest m
LEFT JOIN entity e ON e.id = m.entity_id
LEFT JOIN order_articles oa ON oa.manifest_id = m.id
LEFT JOIN order_payments op ON op.manifest_id = m.id
LEFT JOIN shipment_totals st ON st.order_number = m."number"
WHERE m.company_id = @companyId AND m."type" = 'order'
ON CONFLICT(manifest_id) DO UPDATE SET
order_number = excluded.order_number,
order_date = excluded.order_date,
created_at = excluded.created_at,
entity_id = excluded.entity_id,
customer_name = excluded.customer_name,
positions = excluded.positions,
gross_total = excluded.gross_total,
paid_total = excluded.paid_total,
ordered_quantity = excluded.ordered_quantity,
shipped_quantity = excluded.shipped_quantity,
is_paid = excluded.is_paid,
is_shipped = excluded.is_shipped;
`;
await runner.query(sqlRebuildSqlite, { companyId, shipmentPrefix });
} else {
await runner.query('DELETE FROM ordersummary WHERE company_id = @companyId', { companyId });
const sqlRebuildMssql = `
WITH
order_articles AS (
SELECT
manifest_id,
COUNT(*) AS positions,
SUM(amount) AS ordered_quantity,
SUM(amount * (net * (1.0 - rebate / 100.0)) * (1.0 + taxrate / 100.0)) AS gross_total
FROM manifestarticle
GROUP BY manifest_id
),
order_payments AS (
SELECT
manifest_id,
SUM(amount) AS paid_total
FROM payment
GROUP BY manifest_id
),
shipment_totals AS (
SELECT
SUBSTRING(m_s.[number], 1, CHARINDEX(@shipmentPrefix, m_s.[number]) - 1) AS order_number,
SUM(ma_s.amount) AS shipped_quantity
FROM manifest m_s
JOIN manifestarticle ma_s ON ma_s.manifest_id = m_s.id
WHERE m_s.company_id = @companyId
AND m_s.[type] = 'shipment'
AND CHARINDEX(@shipmentPrefix, m_s.[number]) > 0
GROUP BY SUBSTRING(m_s.[number], 1, CHARINDEX(@shipmentPrefix, m_s.[number]) - 1)
)
INSERT INTO ordersummary (
company_id, manifest_id, order_number, order_date, created_at,
entity_id, customer_name, positions, gross_total, paid_total,
ordered_quantity, shipped_quantity, is_paid, is_shipped
)
SELECT
m.company_id,
m.id AS manifest_id,
m.[number] AS order_number,
m.[date] AS order_date,
m.created_at,
m.entity_id,
LTRIM(RTRIM(ISNULL(e.first_name + ' ', '') + ISNULL(e.name, ''))) AS customer_name,
COALESCE(oa.positions, 0) AS positions,
ROUND(COALESCE(oa.gross_total, 0), 2) AS gross_total,
ROUND(COALESCE(op.paid_total, 0), 2) AS paid_total,
ROUND(COALESCE(oa.ordered_quantity, 0), 3) AS ordered_quantity,
ROUND(COALESCE(st.shipped_quantity, 0), 3) AS shipped_quantity,
CASE WHEN COALESCE(oa.gross_total, 0) > 0 AND ABS(COALESCE(op.paid_total, 0) - oa.gross_total) < 0.01 THEN 1 ELSE 0 END AS is_paid,
CASE WHEN COALESCE(oa.ordered_quantity, 0) > 0 AND ABS(COALESCE(st.shipped_quantity, 0) - oa.ordered_quantity) < 0.001 THEN 1 ELSE 0 END AS is_shipped
FROM manifest m
LEFT JOIN entity e ON e.id = m.entity_id
LEFT JOIN order_articles oa ON oa.manifest_id = m.id
LEFT JOIN order_payments op ON op.manifest_id = m.id
LEFT JOIN shipment_totals st ON st.order_number = m.[number]
WHERE m.company_id = @companyId AND m.[type] = 'order';
`;
await runner.query(sqlRebuildMssql, { companyId, shipmentPrefix });
}
}

View File

@@ -14,6 +14,7 @@ import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyA
import taxEnsure from '../tax/ensure.js';
import { insertLines, normalizeLines, parseDate } from '../manifestLines.js';
import { assertCustomerEntity, loadDoc, shapeSummary } from '../manifestDoc/helpers.js';
import { syncOrderSummary } from './syncSummary.js';
import makeRunner from '../runner.js';
export default function update(provider) {
@@ -146,6 +147,7 @@ export default function update(provider) {
}
const doc = await loadDoc(runner, { type: orderType, companyId, id });
await syncOrderSummary(runner, { companyId, manifestId: id });
return doc;
};

View File

@@ -1,6 +1,7 @@
import { queriesFor, requireId, requireText } from '../logistics/helpers.js';
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
import resolveManifestAccess from '../manifestattachment/resolveManifestAccess.js';
import { syncOrderSummary } from '../order/syncSummary.js';
import makeRunner from '../runner.js';
function shape(row) {
@@ -64,6 +65,7 @@ export default function create(provider) {
type,
amount: input.amount,
};
await syncOrderSummary(runner, { companyId, manifestId });
return shape(row);
};

View File

@@ -1,5 +1,6 @@
import { queriesFor, requireId } from '../logistics/helpers.js';
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
import { syncOrderSummary } from '../order/syncSummary.js';
import makeRunner from '../runner.js';
/**
@@ -21,6 +22,17 @@ export default function del(provider) {
const paymentId = requireId(id, 'Payment');
const runner = makeRunner(provider, tx);
const { companyId } = await access(googleAuthId, runner);
const paymentRow = await runner.query(
'SELECT manifest_id FROM payment WHERE id = @id',
{ id: paymentId },
);
const manifestId = paymentRow.rows[0]?.manifest_id;
await runner.query(q.PAYMENT_DELETE, { id: paymentId, companyId });
if (manifestId) {
await syncOrderSummary(runner, { companyId, manifestId });
}
};
}

View File

@@ -3,6 +3,7 @@ import taxEnsure from '../tax/ensure.js';
import { insertLines, parseDate } from '../manifestLines.js';
import makeRunner from '../runner.js';
import { loadShipment, queriesFor } from './helpers.js';
import { syncOrderSummary } from '../order/syncSummary.js';
function requireId(val, name) {
const n = Number(val);
@@ -181,6 +182,8 @@ export default function create(provider) {
ensureTax,
});
await syncOrderSummary(runner, { companyId, manifestId: orderId });
return loadShipment(runner, q, companyId, manifestId);
};

View File

@@ -1,6 +1,7 @@
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
import makeRunner from '../runner.js';
import { queriesFor } from './helpers.js';
import { syncOrderSummary } from '../order/syncSummary.js';
function requireId(val, name) {
const n = Number(val);
@@ -52,9 +53,19 @@ export default function del(provider) {
throw new Error('Shipped shipment cannot be deleted');
}
const shipmentNumber = String(check.rows[0].number || '');
const prefixRes = await runner.query(q.GET_SHIPMENT_PREFIX, { companyId });
const shipmentPrefix = prefixRes.rows[0]?.prefix?.trim?.() || '-L-';
const pIdx = shipmentNumber.indexOf(shipmentPrefix);
const orderNumber = pIdx > 0 ? shipmentNumber.slice(0, pIdx) : null;
await runner.query(q.DELETE_SHIPMENT, {
id: shipmentId,
companyId,
});
if (orderNumber) {
await syncOrderSummary(runner, { companyId, orderNumber });
}
};
}