This commit is contained in:
seb
2026-10-22 23:33:00 +02:00
parent d6e5da93cb
commit e31566e6ee
4 changed files with 121 additions and 2 deletions

View File

@@ -1,11 +1,17 @@
import {
ADD_CATEGORY as MSSQL_ADD_CATEGORY,
CLEAR_POSTERMINAL_OBITUARY as MSSQL_CLEAR_OBITUARY,
DELETE_CATEGORIES_BY_ARTICLE as MSSQL_DELETE_CATEGORIES,
INSERT_POSTERMINAL_OBITUARY as MSSQL_INSERT_OBITUARY,
LIST_PAIRED_POSTERMINAL_IDS_BY_ARTICLE as MSSQL_LIST_TERMINALS,
TOUCH_UPDATED_AT as MSSQL_TOUCH,
} from '../../providers/mssql/queries/article.js';
import {
ADD_CATEGORY as SQLITE_ADD_CATEGORY,
CLEAR_POSTERMINAL_OBITUARY as SQLITE_CLEAR_OBITUARY,
DELETE_CATEGORIES_BY_ARTICLE as SQLITE_DELETE_CATEGORIES,
INSERT_POSTERMINAL_OBITUARY as SQLITE_INSERT_OBITUARY,
LIST_PAIRED_POSTERMINAL_IDS_BY_ARTICLE as SQLITE_LIST_TERMINALS,
TOUCH_UPDATED_AT as SQLITE_TOUCH,
} from '../../providers/sqlite3/queries/article.js';
import resolveCategoryAccess from '../category/resolveCategoryAccess.js';
@@ -23,6 +29,9 @@ export default function setCategoryIdsBySku(provider) {
const addCategorySql = isSqlite ? SQLITE_ADD_CATEGORY : MSSQL_ADD_CATEGORY;
const deleteCategoriesSql = isSqlite ? SQLITE_DELETE_CATEGORIES : MSSQL_DELETE_CATEGORIES;
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
const listTerminalsSql = isSqlite ? SQLITE_LIST_TERMINALS : MSSQL_LIST_TERMINALS;
const insertObituarySql = isSqlite ? SQLITE_INSERT_OBITUARY : MSSQL_INSERT_OBITUARY;
const clearObituarySql = isSqlite ? SQLITE_CLEAR_OBITUARY : MSSQL_CLEAR_OBITUARY;
/**
* Replaces the category membership of an article by its SKU.
@@ -77,6 +86,15 @@ export default function setCategoryIdsBySku(provider) {
}
}
// Find paired POS terminals where this article was visible before the category change
const terminalsBeforeRes = await runner.query(listTerminalsSql, {
articleId,
companyId,
});
const terminalsBefore = new Set(
terminalsBeforeRes.rows.map((r) => r.posterminal_id),
);
await runner.query(deleteCategoriesSql, { articleId });
for (const categoryId of normalized) {
@@ -86,6 +104,42 @@ export default function setCategoryIdsBySku(provider) {
});
}
// Find paired POS terminals where this article is visible after the category change
const terminalsAfterRes = await runner.query(listTerminalsSql, {
articleId,
companyId,
});
const terminalsAfter = new Set(
terminalsAfterRes.rows.map((r) => r.posterminal_id),
);
// 1. Terminals that had the article enabled before, but no longer have it in any enabled category:
// Record an obituary so POS sync removes the orphaned product.
for (const posterminalId of terminalsBefore) {
if (!terminalsAfter.has(posterminalId)) {
await runner.query(clearObituarySql, {
posterminalId,
entityType: 'article',
entityId: articleId,
});
await runner.query(insertObituarySql, {
posterminalId,
entityType: 'article',
entityId: articleId,
});
}
}
// 2. Terminals where the article IS enabled now:
// Clear any pending obituary so POS sync does not delete the active product.
for (const posterminalId of terminalsAfter) {
await runner.query(clearObituarySql, {
posterminalId,
entityType: 'article',
entityId: articleId,
});
}
// Write history if categories changed
await recordCategoryChangeHistory(runner, {
articleId,