u
This commit is contained in:
@@ -240,6 +240,47 @@ async function run() {
|
|||||||
console.log('Obituaries after setOnAll:', obituariesAfterSetOnAll);
|
console.log('Obituaries after setOnAll:', obituariesAfterSetOnAll);
|
||||||
assert.equal(obituariesAfterSetOnAll.length, 0);
|
assert.equal(obituariesAfterSetOnAll.length, 0);
|
||||||
|
|
||||||
|
// 14. Test setCategoryIdsBySku generates obituary when removed from POS-enabled category
|
||||||
|
console.log('14. Testing setCategoryIdsBySku obituary generation and clearing...');
|
||||||
|
// Setup terminal: only has Cat A enabled
|
||||||
|
await store.posterminal.setOffAll(googleAuthId, terminal.id);
|
||||||
|
// Clear obituaries from setOffAll to start clean
|
||||||
|
provider.db.prepare('DELETE FROM posterminalobituary WHERE posterminal_id = ?').run(terminal.id);
|
||||||
|
await store.posterminal.setOn(googleAuthId, terminal.id, catA.id);
|
||||||
|
|
||||||
|
// Create article in Cat A
|
||||||
|
const artMoving = await store.article.createUnderParent({
|
||||||
|
googleAuthId,
|
||||||
|
parentId: catA.id,
|
||||||
|
name: 'Moving Article',
|
||||||
|
});
|
||||||
|
// Should have 0 obituaries on terminal
|
||||||
|
let obits = provider.db
|
||||||
|
.prepare('SELECT entity_type, entity_id FROM posterminalobituary WHERE posterminal_id = ?')
|
||||||
|
.all(terminal.id);
|
||||||
|
assert.equal(obits.length, 0);
|
||||||
|
|
||||||
|
// Move article from Cat A to Cat B (which is not enabled on terminal)
|
||||||
|
console.log('Moving article to Cat B (not on terminal)...');
|
||||||
|
await store.article.setCategoryIdsBySku(googleAuthId, artMoving.sku, [catB.id]);
|
||||||
|
|
||||||
|
obits = provider.db
|
||||||
|
.prepare('SELECT entity_type, entity_id FROM posterminalobituary WHERE posterminal_id = ?')
|
||||||
|
.all(terminal.id);
|
||||||
|
console.log('Obituaries after moving to Cat B:', obits);
|
||||||
|
assert.equal(obits.length, 1);
|
||||||
|
assert.deepEqual(obits[0], { entity_type: 'article', entity_id: artMoving.id });
|
||||||
|
|
||||||
|
// Move article back to Cat A (enabled on terminal)
|
||||||
|
console.log('Moving article back to Cat A (on terminal)...');
|
||||||
|
await store.article.setCategoryIdsBySku(googleAuthId, artMoving.sku, [catA.id]);
|
||||||
|
|
||||||
|
obits = provider.db
|
||||||
|
.prepare('SELECT entity_type, entity_id FROM posterminalobituary WHERE posterminal_id = ?')
|
||||||
|
.all(terminal.id);
|
||||||
|
console.log('Obituaries after moving back to Cat A:', obits);
|
||||||
|
assert.equal(obits.length, 0);
|
||||||
|
|
||||||
console.log('✅ ALL POSTERMINALOBITUARY TESTS PASSED');
|
console.log('✅ ALL POSTERMINALOBITUARY TESTS PASSED');
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -254,6 +254,28 @@ INSERT INTO categoryarticle (category_id, article_id)
|
|||||||
VALUES (@categoryId, @articleId)
|
VALUES (@categoryId, @articleId)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const LIST_PAIRED_POSTERMINAL_IDS_BY_ARTICLE = `
|
||||||
|
SELECT DISTINCT pt.id AS posterminal_id
|
||||||
|
FROM posterminal pt
|
||||||
|
INNER JOIN posterminalcategory pc ON pc.posterminal_id = pt.id
|
||||||
|
INNER JOIN categoryarticle ca ON ca.category_id = pc.category_id
|
||||||
|
WHERE ca.article_id = @articleId
|
||||||
|
AND pt.company_id = @companyId
|
||||||
|
AND pt.token IS NOT NULL
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const INSERT_POSTERMINAL_OBITUARY = `
|
||||||
|
INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id)
|
||||||
|
VALUES (@posterminalId, @entityType, @entityId)
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const CLEAR_POSTERMINAL_OBITUARY = `
|
||||||
|
DELETE FROM posterminalobituary
|
||||||
|
WHERE posterminal_id = @posterminalId
|
||||||
|
AND entity_type = @entityType
|
||||||
|
AND entity_id = @entityId
|
||||||
|
`;
|
||||||
|
|
||||||
export const GET_BRAND_BY_COMPANY_AND_ID = `
|
export const GET_BRAND_BY_COMPANY_AND_ID = `
|
||||||
SELECT id
|
SELECT id
|
||||||
FROM brand
|
FROM brand
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ import { translateQueries } from './translate.js';
|
|||||||
|
|
||||||
const queries = translateQueries(source, 'article');
|
const queries = translateQueries(source, 'article');
|
||||||
export const {
|
export const {
|
||||||
ADD_CATEGORY, ADD_EAN, ARTICLE_LIST_COLUMNS, CHECK_ARTICLE_WAREHOUSE_STOCKS, CHECK_HAS_WAREHOUSE, CREATE, CREATE_CHILD,
|
ADD_CATEGORY, ADD_EAN, ARTICLE_LIST_COLUMNS, CHECK_ARTICLE_WAREHOUSE_STOCKS, CHECK_HAS_WAREHOUSE,
|
||||||
|
CLEAR_POSTERMINAL_OBITUARY, CREATE, CREATE_CHILD,
|
||||||
DELETE_CATEGORIES_BY_ARTICLE, DELETE_EANS_BY_ARTICLE, EAN_EXISTS, EAN_EXISTS_FOR_OTHER_ARTICLE,
|
DELETE_CATEGORIES_BY_ARTICLE, DELETE_EANS_BY_ARTICLE, EAN_EXISTS, EAN_EXISTS_FOR_OTHER_ARTICLE,
|
||||||
GET_BRAND_BY_COMPANY_AND_ID,
|
GET_BRAND_BY_COMPANY_AND_ID,
|
||||||
GET_CATEGORY_ID_BY_SKU, GET_CATEGORY_TREE_FLAT, GET_ID_BY_SKU,
|
GET_CATEGORY_ID_BY_SKU, GET_CATEGORY_TREE_FLAT, GET_ID_BY_SKU,
|
||||||
LIST_CHILDREN_BY_PARENT_ID,
|
INSERT_POSTERMINAL_OBITUARY,
|
||||||
|
LIST_CHILDREN_BY_PARENT_ID, LIST_PAIRED_POSTERMINAL_IDS_BY_ARTICLE,
|
||||||
SET_PARENT_SORT,
|
SET_PARENT_SORT,
|
||||||
SET_IS_PARENT, TOGGLE_PARENT, TOUCH_UPDATED_AT, UNLINK_CHILD, UPDATE_BRAND, UPDATE_PARENT_BY_SKU, UPDATE_TRACK_STOCK, UPDATE_UNIT,
|
SET_IS_PARENT, TOGGLE_PARENT, TOUCH_UPDATED_AT, UNLINK_CHILD, UPDATE_BRAND, UPDATE_PARENT_BY_SKU, UPDATE_TRACK_STOCK, UPDATE_UNIT,
|
||||||
UPDATE_UNITAMOUNT, UPDATE_UNIT_AND_AMOUNT, UPDATE_WEIGHT,
|
UPDATE_UNITAMOUNT, UPDATE_UNIT_AND_AMOUNT, UPDATE_WEIGHT,
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
import {
|
import {
|
||||||
ADD_CATEGORY as MSSQL_ADD_CATEGORY,
|
ADD_CATEGORY as MSSQL_ADD_CATEGORY,
|
||||||
|
CLEAR_POSTERMINAL_OBITUARY as MSSQL_CLEAR_OBITUARY,
|
||||||
DELETE_CATEGORIES_BY_ARTICLE as MSSQL_DELETE_CATEGORIES,
|
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,
|
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||||
} from '../../providers/mssql/queries/article.js';
|
} from '../../providers/mssql/queries/article.js';
|
||||||
import {
|
import {
|
||||||
ADD_CATEGORY as SQLITE_ADD_CATEGORY,
|
ADD_CATEGORY as SQLITE_ADD_CATEGORY,
|
||||||
|
CLEAR_POSTERMINAL_OBITUARY as SQLITE_CLEAR_OBITUARY,
|
||||||
DELETE_CATEGORIES_BY_ARTICLE as SQLITE_DELETE_CATEGORIES,
|
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,
|
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||||
} from '../../providers/sqlite3/queries/article.js';
|
} from '../../providers/sqlite3/queries/article.js';
|
||||||
import resolveCategoryAccess from '../category/resolveCategoryAccess.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 addCategorySql = isSqlite ? SQLITE_ADD_CATEGORY : MSSQL_ADD_CATEGORY;
|
||||||
const deleteCategoriesSql = isSqlite ? SQLITE_DELETE_CATEGORIES : MSSQL_DELETE_CATEGORIES;
|
const deleteCategoriesSql = isSqlite ? SQLITE_DELETE_CATEGORIES : MSSQL_DELETE_CATEGORIES;
|
||||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
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.
|
* 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 });
|
await runner.query(deleteCategoriesSql, { articleId });
|
||||||
|
|
||||||
for (const categoryId of normalized) {
|
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
|
// Write history if categories changed
|
||||||
await recordCategoryChangeHistory(runner, {
|
await recordCategoryChangeHistory(runner, {
|
||||||
articleId,
|
articleId,
|
||||||
|
|||||||
Reference in New Issue
Block a user