u
This commit is contained in:
171
scratch/test-category-subcategories.js
Normal file
171
scratch/test-category-subcategories.js
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import { mkdtempSync, rmSync } from 'node:fs';
|
||||||
|
import { tmpdir } from 'node:os';
|
||||||
|
import { join } from 'node:path';
|
||||||
|
import LibDashStore from '../src/index.js';
|
||||||
|
import { BetterSqlite3Provider } from '../src/providers/sqlite3/index.js';
|
||||||
|
|
||||||
|
async function test() {
|
||||||
|
console.log('--- Testing setOn and setOff with subcategories ---');
|
||||||
|
|
||||||
|
const tempDir = mkdtempSync(join(tmpdir(), 'test-posterminal-subcats-'));
|
||||||
|
const dbFile = join(tempDir, 'test.db');
|
||||||
|
const storageDir = join(tempDir, 'storage');
|
||||||
|
|
||||||
|
const provider = new BetterSqlite3Provider({
|
||||||
|
filename: dbFile,
|
||||||
|
storageDir,
|
||||||
|
});
|
||||||
|
|
||||||
|
await provider.initialize();
|
||||||
|
const store = await new LibDashStore(provider);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const googleAuthId = await store.google_auth.add('subcat-tester@example.com');
|
||||||
|
const company = await store.company.create({
|
||||||
|
name: 'SubCat Corp',
|
||||||
|
iso639: 'de',
|
||||||
|
taxrate: 19,
|
||||||
|
reducedtaxrate: 7,
|
||||||
|
googleAuthId,
|
||||||
|
});
|
||||||
|
await store.google_auth.setSelectedCompany(googleAuthId, company.id);
|
||||||
|
|
||||||
|
const terminal = await store.posterminal.upsert(googleAuthId, {
|
||||||
|
name: 'POS 1',
|
||||||
|
pairingpin: '1234',
|
||||||
|
});
|
||||||
|
await store.posterminal.pair(terminal.id, {
|
||||||
|
token: 'pos-token-subcat',
|
||||||
|
clientserial: 'SN-001',
|
||||||
|
pairedAt: new Date().toISOString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create Category Tree:
|
||||||
|
// Root -> Cat 4 -> SubCat 41 -> SubCat 411
|
||||||
|
// Root -> Cat 5
|
||||||
|
const cat4 = await store.category.createUnderParent({
|
||||||
|
googleAuthId,
|
||||||
|
parentId: company.rootCategoryId,
|
||||||
|
name: 'Getränke',
|
||||||
|
});
|
||||||
|
const subCat41 = await store.category.createUnderParent({
|
||||||
|
googleAuthId,
|
||||||
|
parentId: cat4.id,
|
||||||
|
name: 'Alkoholfrei',
|
||||||
|
});
|
||||||
|
const subCat411 = await store.category.createUnderParent({
|
||||||
|
googleAuthId,
|
||||||
|
parentId: subCat41.id,
|
||||||
|
name: 'Cola',
|
||||||
|
});
|
||||||
|
const cat5 = await store.category.createUnderParent({
|
||||||
|
googleAuthId,
|
||||||
|
parentId: company.rootCategoryId,
|
||||||
|
name: 'Snacks',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create articles in various categories
|
||||||
|
const artCola = await store.article.createUnderParent({
|
||||||
|
googleAuthId,
|
||||||
|
parentId: subCat411.id,
|
||||||
|
name: 'Cola 0.5L',
|
||||||
|
});
|
||||||
|
|
||||||
|
const artSnack = await store.article.createUnderParent({
|
||||||
|
googleAuthId,
|
||||||
|
parentId: cat5.id,
|
||||||
|
name: 'Chips',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set old timestamps on categories and articles to test updated_at touch
|
||||||
|
provider.db.prepare("UPDATE category SET updated_at = '2020-01-01T00:00:00.000Z'").run();
|
||||||
|
provider.db.prepare("UPDATE article SET updated_at = '2020-01-01T00:00:00.000Z'").run();
|
||||||
|
|
||||||
|
console.log('1. Testing setOn on parent category Cat 4 (should enable Cat 4, SubCat 41, and SubCat 411)...');
|
||||||
|
const onResult = await store.posterminal.setOn(googleAuthId, terminal.id, cat4.id);
|
||||||
|
console.log('Category IDs after setOn(cat4):', onResult.categoryIds);
|
||||||
|
|
||||||
|
assert(onResult.categoryIds.includes(cat4.id), 'Should include cat4');
|
||||||
|
assert(onResult.categoryIds.includes(subCat41.id), 'Should include subCat41');
|
||||||
|
assert(onResult.categoryIds.includes(subCat411.id), 'Should include subCat411');
|
||||||
|
assert(!onResult.categoryIds.includes(cat5.id), 'Should NOT include cat5');
|
||||||
|
|
||||||
|
// Check that categories in the subtree were touched
|
||||||
|
const catsAfterOn = provider.db.prepare('SELECT id, updated_at FROM category WHERE id IN (?, ?, ?)').all(cat4.id, subCat41.id, subCat411.id);
|
||||||
|
for (const c of catsAfterOn) {
|
||||||
|
assert.notEqual(c.updated_at, '2020-01-01T00:00:00.000Z', `Category ${c.id} updated_at should be touched on setOn`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that articles in the subtree were touched
|
||||||
|
const artAfterOn = provider.db.prepare('SELECT id, updated_at FROM article WHERE id = ?').get(artCola.id);
|
||||||
|
assert.notEqual(artAfterOn.updated_at, '2020-01-01T00:00:00.000Z', 'Article updated_at should be touched on setOn');
|
||||||
|
|
||||||
|
// Cat 5 article should NOT be touched
|
||||||
|
const artSnackAfterOn = provider.db.prepare('SELECT id, updated_at FROM article WHERE id = ?').get(artSnack.id);
|
||||||
|
assert.equal(artSnackAfterOn.updated_at, '2020-01-01T00:00:00.000Z', 'Unrelated article updated_at should not be touched');
|
||||||
|
|
||||||
|
console.log('2. Also enabling Cat 5...');
|
||||||
|
await store.posterminal.setOn(googleAuthId, terminal.id, cat5.id);
|
||||||
|
|
||||||
|
// Reset timestamps to test setOff touch
|
||||||
|
provider.db.prepare("UPDATE category SET updated_at = '2020-01-01T00:00:00.000Z'").run();
|
||||||
|
provider.db.prepare("UPDATE article SET updated_at = '2020-01-01T00:00:00.000Z'").run();
|
||||||
|
|
||||||
|
console.log('3. Testing setOff on parent category Cat 4 (should disable Cat 4, SubCat 41, and SubCat 411)...');
|
||||||
|
const offResult = await store.posterminal.setOff(googleAuthId, terminal.id, cat4.id);
|
||||||
|
console.log('Category IDs after setOff(cat4):', offResult.categoryIds);
|
||||||
|
|
||||||
|
assert(!offResult.categoryIds.includes(cat4.id), 'Should NOT include cat4');
|
||||||
|
assert(!offResult.categoryIds.includes(subCat41.id), 'Should NOT include subCat41');
|
||||||
|
assert(!offResult.categoryIds.includes(subCat411.id), 'Should NOT include subCat411');
|
||||||
|
assert(offResult.categoryIds.includes(cat5.id), 'Should still include cat5');
|
||||||
|
|
||||||
|
// Check that categories in the subtree were touched on setOff
|
||||||
|
const catsAfterOff = provider.db.prepare('SELECT id, updated_at FROM category WHERE id IN (?, ?, ?)').all(cat4.id, subCat41.id, subCat411.id);
|
||||||
|
for (const c of catsAfterOff) {
|
||||||
|
assert.notEqual(c.updated_at, '2020-01-01T00:00:00.000Z', `Category ${c.id} updated_at should be touched on setOff`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that article in the subtree was touched on setOff
|
||||||
|
const artAfterOff = provider.db.prepare('SELECT id, updated_at FROM article WHERE id = ?').get(artCola.id);
|
||||||
|
assert.notEqual(artAfterOff.updated_at, '2020-01-01T00:00:00.000Z', 'Article updated_at should be touched on setOff');
|
||||||
|
|
||||||
|
// Verify obituaries generated
|
||||||
|
const obituariesAfter = provider.db
|
||||||
|
.prepare('SELECT entity_type, entity_id FROM posterminalobituary WHERE posterminal_id = ? ORDER BY id ASC')
|
||||||
|
.all(terminal.id);
|
||||||
|
console.log('Obituaries after setOff:', obituariesAfter);
|
||||||
|
|
||||||
|
const catObituaryIds = obituariesAfter.filter(o => o.entity_type === 'category').map(o => o.entity_id);
|
||||||
|
assert(catObituaryIds.includes(cat4.id), 'Should have obituary for cat4');
|
||||||
|
assert(catObituaryIds.includes(subCat41.id), 'Should have obituary for subCat41');
|
||||||
|
assert(catObituaryIds.includes(subCat411.id), 'Should have obituary for subCat411');
|
||||||
|
|
||||||
|
const artObituaryIds = obituariesAfter.filter(o => o.entity_type === 'article').map(o => o.entity_id);
|
||||||
|
assert(artObituaryIds.includes(artCola.id), 'Should have obituary for artCola');
|
||||||
|
assert(!artObituaryIds.includes(artSnack.id), 'Should NOT have obituary for artSnack');
|
||||||
|
|
||||||
|
console.log('4. Testing setOn on an intermediate subcategory (SubCat 41)...');
|
||||||
|
const subOnResult = await store.posterminal.setOn(googleAuthId, terminal.id, subCat41.id);
|
||||||
|
console.log('Category IDs after setOn(subCat41):', subOnResult.categoryIds);
|
||||||
|
assert(!subOnResult.categoryIds.includes(cat4.id), 'Parent cat4 should not be enabled when enabling subCat41');
|
||||||
|
assert(subOnResult.categoryIds.includes(subCat41.id), 'subCat41 should be enabled');
|
||||||
|
assert(subOnResult.categoryIds.includes(subCat411.id), 'Child subCat411 should be enabled');
|
||||||
|
|
||||||
|
console.log('✅ ALL SUBCATEGORY SET_ON / SET_OFF TESTS PASSED');
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
rmSync(tempDir, { recursive: true, force: true });
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test()
|
||||||
|
.then(() => {
|
||||||
|
process.exit(0);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('Test failed:', err);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
@@ -93,20 +93,32 @@ FROM posterminalcategory
|
|||||||
WHERE posterminal_id = @posterminalId
|
WHERE posterminal_id = @posterminalId
|
||||||
`;
|
`;
|
||||||
|
|
||||||
/** setOn: insert if not exists (single terminal + single category). */
|
/** setOn: enable a category and all its subcategories on a terminal. */
|
||||||
export const SET_ON = `
|
export const SET_ON = `
|
||||||
IF NOT EXISTS (
|
;WITH cats AS (
|
||||||
SELECT 1 FROM posterminalcategory
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
WHERE posterminal_id = @posterminalId AND category_id = @categoryId
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
)
|
)
|
||||||
INSERT INTO posterminalcategory (posterminal_id, category_id)
|
INSERT INTO posterminalcategory (posterminal_id, category_id)
|
||||||
VALUES (@posterminalId, @categoryId)
|
SELECT @posterminalId, cats.id
|
||||||
|
FROM cats
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM posterminalcategory pc
|
||||||
|
WHERE pc.posterminal_id = @posterminalId AND pc.category_id = cats.id
|
||||||
|
)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
/** setOff: remove a single category from a single terminal. */
|
/** setOff: remove a category and all its subcategories from a terminal. */
|
||||||
export const SET_OFF = `
|
export const SET_OFF = `
|
||||||
|
;WITH cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
DELETE FROM posterminalcategory
|
DELETE FROM posterminalcategory
|
||||||
WHERE posterminal_id = @posterminalId AND category_id = @categoryId
|
WHERE posterminal_id = @posterminalId
|
||||||
|
AND category_id IN (SELECT id FROM cats)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
/** setOnAll: enable ALL company categories on one terminal. */
|
/** setOnAll: enable ALL company categories on one terminal. */
|
||||||
@@ -170,7 +182,7 @@ WHERE EXISTS (
|
|||||||
WHERE ca.article_id = a.id
|
WHERE ca.article_id = a.id
|
||||||
AND pc.posterminal_id = @posterminalId
|
AND pc.posterminal_id = @posterminalId
|
||||||
)
|
)
|
||||||
AND DATEDIFF_BIG(second, '1970-01-01', a.updated_at) > @cursor
|
AND (DATEDIFF_BIG(second, '1970-01-01', a.updated_at) * 1000000 + (a.id % 1000000)) > @cursor
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const COUNT_CATEGORIES = `
|
export const COUNT_CATEGORIES = `
|
||||||
@@ -219,7 +231,7 @@ WHERE a.articlelist_id IS NOT NULL
|
|||||||
WHERE ca.article_id = a.id
|
WHERE ca.article_id = a.id
|
||||||
AND pc.posterminal_id = @posterminalId
|
AND pc.posterminal_id = @posterminalId
|
||||||
)
|
)
|
||||||
AND DATEDIFF_BIG(second, '1970-01-01', a.updated_at) > @cursor
|
AND (DATEDIFF_BIG(second, '1970-01-01', a.updated_at) * 1000000 + (a.id % 1000000)) > @cursor
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const MAX_ORDER_ID = `
|
export const MAX_ORDER_ID = `
|
||||||
@@ -263,7 +275,7 @@ SELECT TOP (@limit)
|
|||||||
COALESCE(pr.net, 0) AS netPrice,
|
COALESCE(pr.net, 0) AS netPrice,
|
||||||
COALESCE(ptax.rate, ctax.rate, 0) AS taxRate,
|
COALESCE(ptax.rate, ctax.rate, 0) AS taxRate,
|
||||||
a.created_at AS createdAt,
|
a.created_at AS createdAt,
|
||||||
DATEDIFF_BIG(second, '1970-01-01', a.updated_at) AS lastChanged,
|
(DATEDIFF_BIG(second, '1970-01-01', a.updated_at) * 1000000 + (a.id % 1000000)) AS lastChanged,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
(
|
(
|
||||||
SELECT TOP 1 p.hash
|
SELECT TOP 1 p.hash
|
||||||
@@ -321,6 +333,7 @@ SELECT TOP (@limit)
|
|||||||
) AS sort,
|
) AS sort,
|
||||||
a.track_stock AS trackStock,
|
a.track_stock AS trackStock,
|
||||||
CASE
|
CASE
|
||||||
|
WHEN a.track_stock = 0 THEN 0
|
||||||
WHEN a.articlelist_id IS NOT NULL AND EXISTS (
|
WHEN a.articlelist_id IS NOT NULL AND EXISTS (
|
||||||
SELECT 1 FROM articlelistarticle ala WHERE ala.articlelist_id = a.articlelist_id
|
SELECT 1 FROM articlelistarticle ala WHERE ala.articlelist_id = a.articlelist_id
|
||||||
) THEN COALESCE((
|
) THEN COALESCE((
|
||||||
@@ -339,6 +352,7 @@ SELECT TOP (@limit)
|
|||||||
OR ma.sku IN (SELECT asup.sku FROM articlesupplier asup WHERE asup.article_id = ca.id)
|
OR ma.sku IN (SELECT asup.sku FROM articlesupplier asup WHERE asup.article_id = ca.id)
|
||||||
)
|
)
|
||||||
WHERE m.company_id = a.company_id
|
WHERE m.company_id = a.company_id
|
||||||
|
AND l.warehouse_id IS NOT NULL
|
||||||
GROUP BY ca.id
|
GROUP BY ca.id
|
||||||
) comp_stock ON comp_stock.comp_id = ala.article_id
|
) comp_stock ON comp_stock.comp_id = ala.article_id
|
||||||
WHERE ala.articlelist_id = a.articlelist_id
|
WHERE ala.articlelist_id = a.articlelist_id
|
||||||
@@ -350,6 +364,7 @@ SELECT TOP (@limit)
|
|||||||
INNER JOIN manifestarticle ma ON ma.id = l.manifestarticle_id
|
INNER JOIN manifestarticle ma ON ma.id = l.manifestarticle_id
|
||||||
INNER JOIN manifest m ON m.id = ma.manifest_id
|
INNER JOIN manifest m ON m.id = ma.manifest_id
|
||||||
WHERE m.company_id = a.company_id
|
WHERE m.company_id = a.company_id
|
||||||
|
AND l.warehouse_id IS NOT NULL
|
||||||
AND (
|
AND (
|
||||||
ma.sku = a.sku
|
ma.sku = a.sku
|
||||||
OR ma.sku IN (SELECT asup.sku FROM articlesupplier asup WHERE asup.article_id = a.id)
|
OR ma.sku IN (SELECT asup.sku FROM articlesupplier asup WHERE asup.article_id = a.id)
|
||||||
@@ -373,8 +388,8 @@ WHERE EXISTS (
|
|||||||
WHERE ca.article_id = a.id
|
WHERE ca.article_id = a.id
|
||||||
AND pc.posterminal_id = @posterminalId
|
AND pc.posterminal_id = @posterminalId
|
||||||
)
|
)
|
||||||
AND DATEDIFF_BIG(second, '1970-01-01', a.updated_at) > @cursor
|
AND (DATEDIFF_BIG(second, '1970-01-01', a.updated_at) * 1000000 + (a.id % 1000000)) > @cursor
|
||||||
ORDER BY DATEDIFF_BIG(second, '1970-01-01', a.updated_at) ASC, a.id ASC
|
ORDER BY (DATEDIFF_BIG(second, '1970-01-01', a.updated_at) * 1000000 + (a.id % 1000000)) ASC
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const LIST_POS_PRODUCT_CATEGORIES = `
|
export const LIST_POS_PRODUCT_CATEGORIES = `
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { translateQueries } from './translate.js';
|
|||||||
const queries = translateQueries(source, 'posterminal');
|
const queries = translateQueries(source, 'posterminal');
|
||||||
export const {
|
export const {
|
||||||
CREATE, DELETE_BY_COMPANY_AND_ID, GET_BY_ID, LIST_BY_COMPANY,
|
CREATE, DELETE_BY_COMPANY_AND_ID, GET_BY_ID, LIST_BY_COMPANY,
|
||||||
LIST_CATEGORY_IDS, POSTERMINAL_IDS_BY_COMPANY, SET_OFF, SET_OFF_ALL, UPDATE,
|
LIST_CATEGORY_IDS, POSTERMINAL_IDS_BY_COMPANY, SET_OFF_ALL, UPDATE,
|
||||||
FIND_BY_PAIRINGPIN, PAIR, SET_MAX_KNOWN_OBITUARY_ID,
|
FIND_BY_PAIRINGPIN, PAIR, SET_MAX_KNOWN_OBITUARY_ID,
|
||||||
FIND_BY_TOKEN, COUNT_PRODUCTS, COUNT_CATEGORIES, COUNT_CUSTOMERS,
|
FIND_BY_TOKEN, COUNT_PRODUCTS, COUNT_CATEGORIES, COUNT_CUSTOMERS,
|
||||||
COUNT_CUSTOMER_GROUPS, COUNT_COMPOSITE_PRODUCTS, MAX_ORDER_ID,
|
COUNT_CUSTOMER_GROUPS, COUNT_COMPOSITE_PRODUCTS, MAX_ORDER_ID,
|
||||||
@@ -14,9 +14,24 @@ export const {
|
|||||||
} = queries;
|
} = queries;
|
||||||
|
|
||||||
export const SET_ON = `
|
export const SET_ON = `
|
||||||
INSERT INTO posterminalcategory (posterminal_id, category_id)
|
WITH RECURSIVE cats AS (
|
||||||
VALUES (@posterminalId, @categoryId)
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
ON CONFLICT (posterminal_id, category_id) DO NOTHING
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
INSERT OR IGNORE INTO posterminalcategory (posterminal_id, category_id)
|
||||||
|
SELECT @posterminalId, id FROM cats
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const SET_OFF = `
|
||||||
|
WITH RECURSIVE cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
DELETE FROM posterminalcategory
|
||||||
|
WHERE posterminal_id = @posterminalId
|
||||||
|
AND category_id IN (SELECT id FROM cats)
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SET_ON_ALL = `
|
export const SET_ON_ALL = `
|
||||||
@@ -25,9 +40,8 @@ WITH RECURSIVE cats AS (
|
|||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
)
|
)
|
||||||
INSERT INTO posterminalcategory (posterminal_id, category_id)
|
INSERT OR IGNORE INTO posterminalcategory (posterminal_id, category_id)
|
||||||
SELECT @posterminalId, id FROM cats WHERE 1
|
SELECT @posterminalId, id FROM cats
|
||||||
ON CONFLICT (posterminal_id, category_id) DO NOTHING
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const LIST_POS_CUSTOMER_GROUPS = `
|
export const LIST_POS_CUSTOMER_GROUPS = `
|
||||||
@@ -148,7 +162,7 @@ SELECT
|
|||||||
COALESCE(pr.net, 0) AS netPrice,
|
COALESCE(pr.net, 0) AS netPrice,
|
||||||
COALESCE(ptax.rate, ctax.rate, 0) AS taxRate,
|
COALESCE(ptax.rate, ctax.rate, 0) AS taxRate,
|
||||||
a.created_at AS createdAt,
|
a.created_at AS createdAt,
|
||||||
CAST(strftime('%s', a.updated_at) AS INTEGER) AS lastChanged,
|
(CAST(strftime('%s', a.updated_at) AS INTEGER) * 1000000 + (a.id % 1000000)) AS lastChanged,
|
||||||
COALESCE(
|
COALESCE(
|
||||||
(
|
(
|
||||||
SELECT p.hash
|
SELECT p.hash
|
||||||
@@ -210,6 +224,7 @@ SELECT
|
|||||||
) AS sort,
|
) AS sort,
|
||||||
a.track_stock AS trackStock,
|
a.track_stock AS trackStock,
|
||||||
CASE
|
CASE
|
||||||
|
WHEN a.track_stock = 0 THEN 0
|
||||||
WHEN a.articlelist_id IS NOT NULL AND EXISTS (
|
WHEN a.articlelist_id IS NOT NULL AND EXISTS (
|
||||||
SELECT 1 FROM articlelistarticle ala WHERE ala.articlelist_id = a.articlelist_id
|
SELECT 1 FROM articlelistarticle ala WHERE ala.articlelist_id = a.articlelist_id
|
||||||
) THEN COALESCE((
|
) THEN COALESCE((
|
||||||
@@ -228,6 +243,7 @@ SELECT
|
|||||||
OR ma.sku IN (SELECT asup.sku FROM articlesupplier asup WHERE asup.article_id = ca.id)
|
OR ma.sku IN (SELECT asup.sku FROM articlesupplier asup WHERE asup.article_id = ca.id)
|
||||||
)
|
)
|
||||||
WHERE m.company_id = a.company_id
|
WHERE m.company_id = a.company_id
|
||||||
|
AND l.warehouse_id IS NOT NULL
|
||||||
GROUP BY ca.id
|
GROUP BY ca.id
|
||||||
) comp_stock ON comp_stock.comp_id = ala.article_id
|
) comp_stock ON comp_stock.comp_id = ala.article_id
|
||||||
WHERE ala.articlelist_id = a.articlelist_id
|
WHERE ala.articlelist_id = a.articlelist_id
|
||||||
@@ -239,6 +255,7 @@ SELECT
|
|||||||
INNER JOIN manifestarticle ma ON ma.id = l.manifestarticle_id
|
INNER JOIN manifestarticle ma ON ma.id = l.manifestarticle_id
|
||||||
INNER JOIN manifest m ON m.id = ma.manifest_id
|
INNER JOIN manifest m ON m.id = ma.manifest_id
|
||||||
WHERE m.company_id = a.company_id
|
WHERE m.company_id = a.company_id
|
||||||
|
AND l.warehouse_id IS NOT NULL
|
||||||
AND (
|
AND (
|
||||||
ma.sku = a.sku
|
ma.sku = a.sku
|
||||||
OR ma.sku IN (SELECT asup.sku FROM articlesupplier asup WHERE asup.article_id = a.id)
|
OR ma.sku IN (SELECT asup.sku FROM articlesupplier asup WHERE asup.article_id = a.id)
|
||||||
@@ -262,8 +279,8 @@ WHERE EXISTS (
|
|||||||
WHERE ca.article_id = a.id
|
WHERE ca.article_id = a.id
|
||||||
AND pc.posterminal_id = @posterminalId
|
AND pc.posterminal_id = @posterminalId
|
||||||
)
|
)
|
||||||
AND CAST(strftime('%s', a.updated_at) AS INTEGER) > @cursor
|
AND (CAST(strftime('%s', a.updated_at) AS INTEGER) * 1000000 + (a.id % 1000000)) > @cursor
|
||||||
ORDER BY lastChanged ASC, a.id ASC
|
ORDER BY (CAST(strftime('%s', a.updated_at) AS INTEGER) * 1000000 + (a.id % 1000000)) ASC
|
||||||
LIMIT @limit
|
LIMIT @limit
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import makeRunner from '../runner.js';
|
|||||||
function normalizeCursor(cursor) {
|
function normalizeCursor(cursor) {
|
||||||
const n = Number(cursor) || 0;
|
const n = Number(cursor) || 0;
|
||||||
if (n <= 0) return 0;
|
if (n <= 0) return 0;
|
||||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
if (n < 1e11) return Math.floor(n * 1000000);
|
||||||
|
if (n < 1e14) return Math.floor((n / 1000) * 1000000);
|
||||||
|
return Math.floor(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function getCompositeProductCount(provider) {
|
export default function getCompositeProductCount(provider) {
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ import makeRunner from '../runner.js';
|
|||||||
function normalizeCursor(cursor) {
|
function normalizeCursor(cursor) {
|
||||||
const n = Number(cursor) || 0;
|
const n = Number(cursor) || 0;
|
||||||
if (n <= 0) return 0;
|
if (n <= 0) return 0;
|
||||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
if (n < 1e11) return Math.floor(n * 1000000);
|
||||||
|
if (n < 1e14) return Math.floor((n / 1000) * 1000000);
|
||||||
|
return Math.floor(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function getProductCount(provider) {
|
export default function getProductCount(provider) {
|
||||||
|
|||||||
@@ -19,7 +19,9 @@ import makeRunner from '../runner.js';
|
|||||||
function normalizeCursor(cursor) {
|
function normalizeCursor(cursor) {
|
||||||
const n = Number(cursor) || 0;
|
const n = Number(cursor) || 0;
|
||||||
if (n <= 0) return 0;
|
if (n <= 0) return 0;
|
||||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
if (n < 1e11) return Math.floor(n * 1000000);
|
||||||
|
if (n < 1e14) return Math.floor((n / 1000) * 1000000);
|
||||||
|
return Math.floor(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDateTime(value) {
|
function formatDateTime(value) {
|
||||||
|
|||||||
@@ -21,25 +21,121 @@ export default function setOff(provider) {
|
|||||||
? SQLITE_LIST_CATEGORY_IDS
|
? SQLITE_LIST_CATEGORY_IDS
|
||||||
: MSSQL_LIST_CATEGORY_IDS;
|
: MSSQL_LIST_CATEGORY_IDS;
|
||||||
|
|
||||||
const addCategoryObituarySql = `
|
const touchSql = isSqlite
|
||||||
INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id)
|
? `WITH RECURSIVE cats AS (
|
||||||
VALUES (@posterminalId, 'category', @categoryId)
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
`;
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
const addArticleObituariesSql = `
|
|
||||||
INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id)
|
|
||||||
SELECT DISTINCT @posterminalId, 'article', ca.article_id
|
|
||||||
FROM categoryarticle ca
|
|
||||||
WHERE ca.category_id = @categoryId
|
|
||||||
AND NOT EXISTS (
|
|
||||||
SELECT 1
|
|
||||||
FROM categoryarticle ca2
|
|
||||||
INNER JOIN posterminalcategory pc ON pc.category_id = ca2.category_id
|
|
||||||
WHERE ca2.article_id = ca.article_id
|
|
||||||
AND pc.posterminal_id = @posterminalId
|
|
||||||
AND pc.category_id <> @categoryId
|
|
||||||
)
|
)
|
||||||
`;
|
UPDATE category SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
||||||
|
WHERE id IN (SELECT id FROM cats)`
|
||||||
|
: `;WITH cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
UPDATE category SET updated_at = SYSUTCDATETIME()
|
||||||
|
WHERE id IN (SELECT id FROM cats)`;
|
||||||
|
|
||||||
|
const touchArticlesSql = isSqlite
|
||||||
|
? `WITH RECURSIVE cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
UPDATE article
|
||||||
|
SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
UNION
|
||||||
|
SELECT child.id FROM article child
|
||||||
|
WHERE child.parentarticle_id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
)
|
||||||
|
UNION
|
||||||
|
SELECT parent.parentarticle_id FROM article parent
|
||||||
|
WHERE parent.id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
) AND parent.parentarticle_id IS NOT NULL
|
||||||
|
)`
|
||||||
|
: `;WITH cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
UPDATE article
|
||||||
|
SET updated_at = SYSUTCDATETIME()
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
UNION
|
||||||
|
SELECT child.id FROM article child
|
||||||
|
WHERE child.parentarticle_id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
)
|
||||||
|
UNION
|
||||||
|
SELECT parent.parentarticle_id FROM article parent
|
||||||
|
WHERE parent.id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
) AND parent.parentarticle_id IS NOT NULL
|
||||||
|
)`;
|
||||||
|
|
||||||
|
const addCategoryObituarySql = isSqlite
|
||||||
|
? `WITH RECURSIVE cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id)
|
||||||
|
SELECT pc.posterminal_id, 'category', pc.category_id
|
||||||
|
FROM posterminalcategory pc
|
||||||
|
WHERE pc.posterminal_id = @posterminalId
|
||||||
|
AND pc.category_id IN (SELECT id FROM cats)`
|
||||||
|
: `;WITH cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id)
|
||||||
|
SELECT pc.posterminal_id, 'category', pc.category_id
|
||||||
|
FROM posterminalcategory pc
|
||||||
|
WHERE pc.posterminal_id = @posterminalId
|
||||||
|
AND pc.category_id IN (SELECT id FROM cats)`;
|
||||||
|
|
||||||
|
const addArticleObituariesSql = isSqlite
|
||||||
|
? `WITH RECURSIVE cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id)
|
||||||
|
SELECT DISTINCT @posterminalId, 'article', ca.article_id
|
||||||
|
FROM categoryarticle ca
|
||||||
|
WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM categoryarticle ca2
|
||||||
|
INNER JOIN posterminalcategory pc ON pc.category_id = ca2.category_id
|
||||||
|
WHERE ca2.article_id = ca.article_id
|
||||||
|
AND pc.posterminal_id = @posterminalId
|
||||||
|
AND pc.category_id NOT IN (SELECT id FROM cats)
|
||||||
|
)`
|
||||||
|
: `;WITH cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id)
|
||||||
|
SELECT DISTINCT @posterminalId, 'article', ca.article_id
|
||||||
|
FROM categoryarticle ca
|
||||||
|
WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
AND NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM categoryarticle ca2
|
||||||
|
INNER JOIN posterminalcategory pc ON pc.category_id = ca2.category_id
|
||||||
|
WHERE ca2.article_id = ca.article_id
|
||||||
|
AND pc.posterminal_id = @posterminalId
|
||||||
|
AND pc.category_id NOT IN (SELECT id FROM cats)
|
||||||
|
)`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a category assignment from a posterminal (turns it off).
|
* Removes a category assignment from a posterminal (turns it off).
|
||||||
@@ -84,6 +180,9 @@ export default function setOff(provider) {
|
|||||||
categoryId,
|
categoryId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await runner.query(touchSql, { categoryId });
|
||||||
|
await runner.query(touchArticlesSql, { categoryId });
|
||||||
|
|
||||||
const result = await runner.query(listCatIdsSql, { posterminalId });
|
const result = await runner.query(listCatIdsSql, { posterminalId });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -21,30 +21,110 @@ export default function setOn(provider) {
|
|||||||
? SQLITE_LIST_CATEGORY_IDS
|
? SQLITE_LIST_CATEGORY_IDS
|
||||||
: MSSQL_LIST_CATEGORY_IDS;
|
: MSSQL_LIST_CATEGORY_IDS;
|
||||||
const touchSql = isSqlite
|
const touchSql = isSqlite
|
||||||
? "UPDATE category SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = @categoryId"
|
? `WITH RECURSIVE cats AS (
|
||||||
: 'UPDATE category SET updated_at = SYSUTCDATETIME() WHERE id = @categoryId';
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
const touchArticlesSql = isSqlite
|
UNION ALL
|
||||||
? `UPDATE article
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
||||||
WHERE id IN (
|
|
||||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id = @categoryId
|
|
||||||
)`
|
|
||||||
: `UPDATE article
|
|
||||||
SET updated_at = SYSUTCDATETIME()
|
|
||||||
WHERE id IN (
|
|
||||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id = @categoryId
|
|
||||||
)`;
|
|
||||||
|
|
||||||
const clearObituariesSql = `
|
|
||||||
DELETE FROM posterminalobituary
|
|
||||||
WHERE posterminal_id = @posterminalId
|
|
||||||
AND (
|
|
||||||
(entity_type = 'category' AND entity_id = @categoryId)
|
|
||||||
OR (entity_type = 'article' AND entity_id IN (
|
|
||||||
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id = @categoryId
|
|
||||||
))
|
|
||||||
)
|
)
|
||||||
`;
|
UPDATE category SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
||||||
|
WHERE id IN (SELECT id FROM cats)`
|
||||||
|
: `;WITH cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
UPDATE category SET updated_at = SYSUTCDATETIME()
|
||||||
|
WHERE id IN (SELECT id FROM cats)`;
|
||||||
|
|
||||||
|
const touchArticlesSql = isSqlite
|
||||||
|
? `WITH RECURSIVE cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
UPDATE article
|
||||||
|
SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
UNION
|
||||||
|
SELECT child.id FROM article child
|
||||||
|
WHERE child.parentarticle_id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
)
|
||||||
|
UNION
|
||||||
|
SELECT parent.parentarticle_id FROM article parent
|
||||||
|
WHERE parent.id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
) AND parent.parentarticle_id IS NOT NULL
|
||||||
|
)`
|
||||||
|
: `;WITH cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
UPDATE article
|
||||||
|
SET updated_at = SYSUTCDATETIME()
|
||||||
|
WHERE id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
UNION
|
||||||
|
SELECT child.id FROM article child
|
||||||
|
WHERE child.parentarticle_id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
)
|
||||||
|
UNION
|
||||||
|
SELECT parent.parentarticle_id FROM article parent
|
||||||
|
WHERE parent.id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
) AND parent.parentarticle_id IS NOT NULL
|
||||||
|
)`;
|
||||||
|
|
||||||
|
const clearObituariesSql = isSqlite
|
||||||
|
? `WITH RECURSIVE cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
DELETE FROM posterminalobituary
|
||||||
|
WHERE posterminal_id = @posterminalId
|
||||||
|
AND (
|
||||||
|
(entity_type = 'category' AND entity_id IN (SELECT id FROM cats))
|
||||||
|
OR (entity_type = 'article' AND entity_id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
UNION
|
||||||
|
SELECT child.id FROM article child
|
||||||
|
WHERE child.parentarticle_id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
)
|
||||||
|
UNION
|
||||||
|
SELECT parent.parentarticle_id FROM article parent
|
||||||
|
WHERE parent.id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
) AND parent.parentarticle_id IS NOT NULL
|
||||||
|
))
|
||||||
|
)`
|
||||||
|
: `;WITH cats AS (
|
||||||
|
SELECT id FROM category WHERE id = @categoryId
|
||||||
|
UNION ALL
|
||||||
|
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||||
|
)
|
||||||
|
DELETE FROM posterminalobituary
|
||||||
|
WHERE posterminal_id = @posterminalId
|
||||||
|
AND (
|
||||||
|
(entity_type = 'category' AND entity_id IN (SELECT id FROM cats))
|
||||||
|
OR (entity_type = 'article' AND entity_id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
UNION
|
||||||
|
SELECT child.id FROM article child
|
||||||
|
WHERE child.parentarticle_id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
)
|
||||||
|
UNION
|
||||||
|
SELECT parent.parentarticle_id FROM article parent
|
||||||
|
WHERE parent.id IN (
|
||||||
|
SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats)
|
||||||
|
) AND parent.parentarticle_id IS NOT NULL
|
||||||
|
))
|
||||||
|
)`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigns a category to a posterminal (turns it on for that category).
|
* Assigns a category to a posterminal (turns it on for that category).
|
||||||
|
|||||||
Reference in New Issue
Block a user