x
This commit is contained in:
@@ -143,6 +143,7 @@ import posterminalGetCompositeProductCount from './store/posterminal/getComposit
|
||||
import posterminalGetDeletedEntityCount from './store/posterminal/getDeletedEntityCount.js';
|
||||
import posterminalGetDeletedEntityList from './store/posterminal/getDeletedEntityList.js';
|
||||
import posterminalRecordObituary from './store/posterminal/recordObituary.js';
|
||||
import posterminalRecordSyncQueue from './store/posterminal/recordSyncQueue.js';
|
||||
import posterminalGetMaxOrderIdCount from './store/posterminal/getMaxOrderIdCount.js';
|
||||
import posterminalGetCategoryList from './store/posterminal/getCategoryList.js';
|
||||
import posterminalGetProductList from './store/posterminal/getProductList.js';
|
||||
@@ -528,6 +529,7 @@ export default class LibDashStore {
|
||||
getDeletedEntityCount: posterminalGetDeletedEntityCount(provider),
|
||||
getDeletedEntityList: posterminalGetDeletedEntityList(provider),
|
||||
recordObituary: posterminalRecordObituary(provider),
|
||||
recordSyncQueue: posterminalRecordSyncQueue(provider),
|
||||
getMaxOrderIdCount: posterminalGetMaxOrderIdCount(provider),
|
||||
getCategoryList: posterminalGetCategoryList(provider),
|
||||
getProductList: posterminalGetProductList(provider),
|
||||
|
||||
@@ -24,6 +24,8 @@ export const TABLES = [
|
||||
'modelconversation',
|
||||
'companyuser',
|
||||
'companysetting',
|
||||
'posterminalsyncqueue',
|
||||
'posterminalobituary',
|
||||
'posterminalcategory',
|
||||
'posterminal',
|
||||
'printer',
|
||||
|
||||
@@ -249,6 +249,38 @@ WHERE articlelist_id IN (
|
||||
)
|
||||
`;
|
||||
|
||||
export const ENQUEUE_SYNC_BY_ARTICLE = `
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'article', a.id
|
||||
FROM article a
|
||||
INNER JOIN posterminal pt ON pt.company_id = a.company_id
|
||||
WHERE a.id = @articleId
|
||||
`;
|
||||
|
||||
export const ENQUEUE_OPTION_PARENT_ARTICLES_SYNC = `
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'article', a.id
|
||||
FROM article a
|
||||
INNER JOIN posterminal pt ON pt.company_id = a.company_id
|
||||
WHERE a.optionslist_id IN (
|
||||
SELECT ola.optionslist_id
|
||||
FROM optionslistarticle ola
|
||||
WHERE ola.article_id = @articleId
|
||||
)
|
||||
`;
|
||||
|
||||
export const ENQUEUE_STUECKLISTE_ARTICLES_SYNC = `
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'article', a.id
|
||||
FROM article a
|
||||
INNER JOIN posterminal pt ON pt.company_id = a.company_id
|
||||
WHERE a.articlelist_id IN (
|
||||
SELECT ala.articlelist_id
|
||||
FROM articlelistarticle ala
|
||||
WHERE ala.article_id = @articleId
|
||||
)
|
||||
`;
|
||||
|
||||
|
||||
export const CREATE = `
|
||||
INSERT INTO article (company_id, sku, unit_id, unitamount, weight, track_stock)
|
||||
|
||||
@@ -240,3 +240,40 @@ WHERE id IN (
|
||||
)
|
||||
`;
|
||||
|
||||
export const ENQUEUE_SUBTREE_CATEGORIES_SYNC = `
|
||||
;WITH cats AS (
|
||||
SELECT id FROM category WHERE id = @id
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
)
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'category', cats.id
|
||||
FROM cats
|
||||
INNER JOIN posterminal pt ON pt.company_id = @companyId
|
||||
`;
|
||||
|
||||
export const ENQUEUE_SUBTREE_ARTICLES_SYNC = `
|
||||
;WITH cats AS (
|
||||
SELECT id FROM category WHERE id = @id
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
),
|
||||
arts AS (
|
||||
SELECT ca.article_id AS 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 AS 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
|
||||
)
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'article', arts.id
|
||||
FROM arts
|
||||
INNER JOIN posterminal pt ON pt.company_id = @companyId
|
||||
`;
|
||||
|
||||
|
||||
@@ -136,6 +136,12 @@ WHERE id = @id
|
||||
AND customergroup_id = @customergroupId
|
||||
`;
|
||||
|
||||
export const TOUCH_UPDATED_AT = `
|
||||
UPDATE entity
|
||||
SET updated_at = SYSUTCDATETIME()
|
||||
WHERE id = @id
|
||||
`;
|
||||
|
||||
export const DELETE_BY_COMPANY_AND_ID = `
|
||||
DELETE e
|
||||
FROM entity e
|
||||
|
||||
@@ -172,66 +172,100 @@ WHERE token = @token
|
||||
`;
|
||||
|
||||
export const COUNT_PRODUCTS = `
|
||||
SELECT COUNT(DISTINCT a.id) AS count
|
||||
FROM article a
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = a.company_id
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM categoryarticle ca
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = ca.category_id
|
||||
WHERE ca.article_id = a.id
|
||||
AND pc.posterminal_id = @posterminalId
|
||||
)
|
||||
AND (DATEDIFF_BIG(second, '1970-01-01', a.updated_at) * 1000000 + (a.id % 1000000)) > @cursor
|
||||
SELECT COUNT(*) AS count
|
||||
FROM (
|
||||
SELECT MAX(q.id) AS syncId, a.id
|
||||
FROM posterminalsyncqueue q
|
||||
INNER JOIN article a ON a.id = q.entity_id
|
||||
INNER JOIN posterminal pt ON pt.id = q.posterminal_id AND pt.company_id = a.company_id
|
||||
WHERE q.posterminal_id = @posterminalId
|
||||
AND q.entity_type = 'article'
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM categoryarticle ca
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = ca.category_id
|
||||
WHERE ca.article_id = a.id
|
||||
AND pc.posterminal_id = @posterminalId
|
||||
)
|
||||
GROUP BY a.id
|
||||
HAVING MAX(q.id) > @cursor
|
||||
) t
|
||||
`;
|
||||
|
||||
export const COUNT_CATEGORIES = `
|
||||
SELECT COUNT(*) AS count
|
||||
FROM category c
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = c.id
|
||||
INNER JOIN posterminal pt ON pt.id = pc.posterminal_id
|
||||
INNER JOIN company co ON co.id = pt.company_id
|
||||
WHERE pc.posterminal_id = @posterminalId
|
||||
AND (co.root_category_id IS NULL OR c.id <> co.root_category_id)
|
||||
AND DATEDIFF_BIG(second, '1970-01-01', c.updated_at) > @cursor
|
||||
FROM (
|
||||
SELECT MAX(q.id) AS syncId, c.id
|
||||
FROM posterminalsyncqueue q
|
||||
INNER JOIN category c ON c.id = q.entity_id
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = c.id AND pc.posterminal_id = q.posterminal_id
|
||||
INNER JOIN posterminal pt ON pt.id = pc.posterminal_id
|
||||
INNER JOIN company co ON co.id = pt.company_id
|
||||
WHERE q.posterminal_id = @posterminalId
|
||||
AND q.entity_type = 'category'
|
||||
AND (co.root_category_id IS NULL OR c.id <> co.root_category_id)
|
||||
GROUP BY c.id
|
||||
HAVING MAX(q.id) > @cursor
|
||||
) t
|
||||
`;
|
||||
|
||||
export const COUNT_CUSTOMERS = `
|
||||
SELECT COUNT(*) AS count
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = cg.company_id
|
||||
WHERE cg.name <> 'Lieferanten'
|
||||
AND DATEDIFF_BIG(second, '1970-01-01', e.updated_at) > @cursor
|
||||
FROM (
|
||||
SELECT MAX(q.id) AS syncId, e.id
|
||||
FROM posterminalsyncqueue q
|
||||
INNER JOIN entity e ON e.id = q.entity_id
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
INNER JOIN posterminal pt ON pt.id = q.posterminal_id AND pt.company_id = cg.company_id
|
||||
WHERE q.posterminal_id = @posterminalId
|
||||
AND q.entity_type = 'customer'
|
||||
AND cg.name <> 'Lieferanten'
|
||||
GROUP BY e.id
|
||||
HAVING MAX(q.id) > @cursor
|
||||
) t
|
||||
`;
|
||||
|
||||
|
||||
export const COUNT_CUSTOMER_GROUPS = `
|
||||
SELECT COUNT(*) AS count
|
||||
FROM customergroup cg
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = cg.company_id
|
||||
WHERE cg.name <> 'Lieferanten'
|
||||
AND DATEDIFF_BIG(second, '1970-01-01', cg.updated_at) > @cursor
|
||||
FROM (
|
||||
SELECT MAX(q.id) AS syncId, cg.id
|
||||
FROM posterminalsyncqueue q
|
||||
INNER JOIN customergroup cg ON cg.id = q.entity_id
|
||||
INNER JOIN posterminal pt ON pt.id = q.posterminal_id AND pt.company_id = cg.company_id
|
||||
WHERE q.posterminal_id = @posterminalId
|
||||
AND q.entity_type = 'customergroup'
|
||||
AND cg.name <> 'Lieferanten'
|
||||
GROUP BY cg.id
|
||||
HAVING MAX(q.id) > @cursor
|
||||
) t
|
||||
`;
|
||||
|
||||
export const COUNT_COMPOSITE_PRODUCTS = `
|
||||
SELECT COUNT(DISTINCT a.id) AS count
|
||||
FROM article a
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = a.company_id
|
||||
WHERE a.articlelist_id IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM articlelistarticle ala
|
||||
WHERE ala.articlelist_id = a.articlelist_id
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM categoryarticle ca
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = ca.category_id
|
||||
WHERE ca.article_id = a.id
|
||||
AND pc.posterminal_id = @posterminalId
|
||||
)
|
||||
AND (DATEDIFF_BIG(second, '1970-01-01', a.updated_at) * 1000000 + (a.id % 1000000)) > @cursor
|
||||
SELECT COUNT(*) AS count
|
||||
FROM (
|
||||
SELECT MAX(q.id) AS syncId, a.id
|
||||
FROM posterminalsyncqueue q
|
||||
INNER JOIN article a ON a.id = q.entity_id
|
||||
INNER JOIN posterminal pt ON pt.id = q.posterminal_id AND pt.company_id = a.company_id
|
||||
WHERE q.posterminal_id = @posterminalId
|
||||
AND q.entity_type = 'article'
|
||||
AND a.articlelist_id IS NOT NULL
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM articlelistarticle ala
|
||||
WHERE ala.articlelist_id = a.articlelist_id
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM categoryarticle ca
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = ca.category_id
|
||||
WHERE ca.article_id = a.id
|
||||
AND pc.posterminal_id = @posterminalId
|
||||
)
|
||||
GROUP BY a.id
|
||||
HAVING MAX(q.id) > @cursor
|
||||
) t
|
||||
`;
|
||||
|
||||
export const MAX_ORDER_ID = `
|
||||
@@ -255,16 +289,21 @@ SELECT TOP (@limit)
|
||||
WHERE cp.category_id = c.id
|
||||
ORDER BY cp.sort ASC, cp.id ASC
|
||||
) AS imgHash,
|
||||
DATEDIFF_BIG(second, '1970-01-01', c.updated_at) AS lastChanged
|
||||
FROM category c
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = c.id
|
||||
sq.syncId AS lastChanged
|
||||
FROM (
|
||||
SELECT entity_id, MAX(id) AS syncId
|
||||
FROM posterminalsyncqueue
|
||||
WHERE posterminal_id = @posterminalId AND entity_type = 'category'
|
||||
GROUP BY entity_id
|
||||
HAVING MAX(id) > @cursor
|
||||
) sq
|
||||
INNER JOIN category c ON c.id = sq.entity_id
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = c.id AND pc.posterminal_id = @posterminalId
|
||||
INNER JOIN posterminal pt ON pt.id = pc.posterminal_id
|
||||
INNER JOIN company co ON co.id = pt.company_id
|
||||
LEFT JOIN categorytext ct ON ct.category_id = c.id AND ct.language_id = co.default_language_id
|
||||
WHERE pc.posterminal_id = @posterminalId
|
||||
AND (co.root_category_id IS NULL OR c.id <> co.root_category_id)
|
||||
AND DATEDIFF_BIG(second, '1970-01-01', c.updated_at) > @cursor
|
||||
ORDER BY DATEDIFF_BIG(second, '1970-01-01', c.updated_at) ASC, c.id ASC
|
||||
WHERE (co.root_category_id IS NULL OR c.id <> co.root_category_id)
|
||||
ORDER BY sq.syncId ASC
|
||||
`;
|
||||
|
||||
export const LIST_POS_PRODUCTS = `
|
||||
@@ -275,7 +314,7 @@ SELECT TOP (@limit)
|
||||
COALESCE(pr.net, 0) AS netPrice,
|
||||
COALESCE(ptax.rate, ctax.rate, 0) AS taxRate,
|
||||
a.created_at AS createdAt,
|
||||
(DATEDIFF_BIG(second, '1970-01-01', a.updated_at) * 1000000 + (a.id % 1000000)) AS lastChanged,
|
||||
sq.syncId AS lastChanged,
|
||||
COALESCE(
|
||||
(
|
||||
SELECT TOP 1 p.hash
|
||||
@@ -374,7 +413,14 @@ SELECT TOP (@limit)
|
||||
co.id AS companyId,
|
||||
co.root_category_id AS rootCategoryId,
|
||||
co.poscustomergroup_id AS posCustomerGroupId
|
||||
FROM article a
|
||||
FROM (
|
||||
SELECT entity_id, MAX(id) AS syncId
|
||||
FROM posterminalsyncqueue
|
||||
WHERE posterminal_id = @posterminalId AND entity_type = 'article'
|
||||
GROUP BY entity_id
|
||||
HAVING MAX(id) > @cursor
|
||||
) sq
|
||||
INNER JOIN article a ON a.id = sq.entity_id
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = a.company_id
|
||||
INNER JOIN company co ON co.id = a.company_id
|
||||
LEFT JOIN articletext at ON at.article_id = a.id AND at.language_id = co.default_language_id
|
||||
@@ -388,8 +434,7 @@ WHERE EXISTS (
|
||||
WHERE ca.article_id = a.id
|
||||
AND pc.posterminal_id = @posterminalId
|
||||
)
|
||||
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) * 1000000 + (a.id % 1000000)) ASC
|
||||
ORDER BY sq.syncId ASC
|
||||
`;
|
||||
|
||||
export const LIST_POS_PRODUCT_CATEGORIES = `
|
||||
@@ -411,13 +456,19 @@ SELECT TOP (@limit)
|
||||
cg.name,
|
||||
CASE WHEN cg.id = co.poscustomergroup_id THEN '1' ELSE '0' END AS standard,
|
||||
'0.000000' AS discountPercent,
|
||||
DATEDIFF_BIG(second, '1970-01-01', cg.updated_at) AS lastChanged
|
||||
FROM customergroup cg
|
||||
sq.syncId AS lastChanged
|
||||
FROM (
|
||||
SELECT entity_id, MAX(id) AS syncId
|
||||
FROM posterminalsyncqueue
|
||||
WHERE posterminal_id = @posterminalId AND entity_type = 'customergroup'
|
||||
GROUP BY entity_id
|
||||
HAVING MAX(id) > @cursor
|
||||
) sq
|
||||
INNER JOIN customergroup cg ON cg.id = sq.entity_id
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = cg.company_id
|
||||
INNER JOIN company co ON co.id = pt.company_id
|
||||
WHERE cg.name <> 'Lieferanten'
|
||||
AND DATEDIFF_BIG(second, '1970-01-01', cg.updated_at) > @cursor
|
||||
ORDER BY DATEDIFF_BIG(second, '1970-01-01', cg.updated_at) ASC, cg.id ASC
|
||||
ORDER BY sq.syncId ASC
|
||||
`;
|
||||
|
||||
export const LIST_POS_CUSTOMERS = `
|
||||
@@ -469,13 +520,19 @@ SELECT TOP (@limit)
|
||||
WHERE ec.entity_id = e.id AND ec.contacttype IN ('email', 'mail')
|
||||
ORDER BY ec.sort ASC, ec.id ASC
|
||||
) AS email,
|
||||
DATEDIFF_BIG(second, '1970-01-01', e.updated_at) AS lastChanged
|
||||
FROM entity e
|
||||
sq.syncId AS lastChanged
|
||||
FROM (
|
||||
SELECT entity_id, MAX(id) AS syncId
|
||||
FROM posterminalsyncqueue
|
||||
WHERE posterminal_id = @posterminalId AND entity_type = 'customer'
|
||||
GROUP BY entity_id
|
||||
HAVING MAX(id) > @cursor
|
||||
) sq
|
||||
INNER JOIN entity e ON e.id = sq.entity_id
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = cg.company_id
|
||||
WHERE cg.name <> 'Lieferanten'
|
||||
AND DATEDIFF_BIG(second, '1970-01-01', e.updated_at) > @cursor
|
||||
ORDER BY DATEDIFF_BIG(second, '1970-01-01', e.updated_at) ASC, e.id ASC
|
||||
ORDER BY sq.syncId ASC
|
||||
`;
|
||||
|
||||
|
||||
@@ -541,6 +598,34 @@ FROM posterminal pt
|
||||
WHERE pt.company_id = @companyId AND pt.token IS NOT NULL
|
||||
`;
|
||||
|
||||
export const RECORD_SYNC_QUEUE = `
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, @entityType, @entityId
|
||||
FROM posterminal pt
|
||||
WHERE pt.company_id = @companyId
|
||||
`;
|
||||
|
||||
export const SEED_SYNC_QUEUE_FOR_TERMINAL = `
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT @posterminalId, 'customergroup', cg.id
|
||||
FROM customergroup cg
|
||||
WHERE cg.company_id = @companyId
|
||||
UNION ALL
|
||||
SELECT @posterminalId, 'customer', e.id
|
||||
FROM entity e
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
WHERE cg.company_id = @companyId
|
||||
UNION ALL
|
||||
SELECT @posterminalId, 'category', c.id
|
||||
FROM category c
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = c.id
|
||||
WHERE pc.posterminal_id = @posterminalId
|
||||
UNION ALL
|
||||
SELECT @posterminalId, 'article', a.id
|
||||
FROM article a
|
||||
WHERE a.company_id = @companyId
|
||||
`;
|
||||
|
||||
export const COUNT_DELETED_ENTITIES = `
|
||||
SELECT COUNT(*) AS count
|
||||
FROM posterminalobituary
|
||||
|
||||
@@ -417,6 +417,23 @@ BEGIN
|
||||
END
|
||||
`;
|
||||
|
||||
export const INIT_POSTERMINALSYNCQUEUE = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'posterminalsyncqueue')
|
||||
BEGIN
|
||||
CREATE TABLE posterminalsyncqueue (
|
||||
id INT IDENTITY(1,1) PRIMARY KEY,
|
||||
posterminal_id INT NOT NULL,
|
||||
entity_type NVARCHAR(50) NOT NULL,
|
||||
entity_id INT NOT NULL,
|
||||
CONSTRAINT CK_posterminalsyncqueue_entity_type CHECK (entity_type IN ('article', 'category', 'customer', 'customergroup')),
|
||||
CONSTRAINT FK_posterminalsyncqueue_posterminal FOREIGN KEY (posterminal_id) REFERENCES posterminal(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IX_posterminalsyncqueue_posterminal_id
|
||||
ON posterminalsyncqueue (posterminal_id, id);
|
||||
END
|
||||
`;
|
||||
|
||||
|
||||
export const INIT_ARTICLEEAN = `
|
||||
IF NOT EXISTS (SELECT * FROM sys.tables WHERE name = 'articleean')
|
||||
@@ -1642,6 +1659,7 @@ export const SCHEMA_SCRIPTS = [
|
||||
INIT_POSTERMINAL,
|
||||
INIT_POSTERMINALCATEGORY,
|
||||
INIT_POSTERMINALOBITUARY,
|
||||
INIT_POSTERMINALSYNCQUEUE,
|
||||
INIT_PRINTER,
|
||||
INIT_LABELTEMPLATE,
|
||||
INIT_FILE,
|
||||
|
||||
@@ -13,6 +13,7 @@ export const {
|
||||
SET_PARENT_SORT,
|
||||
SET_IS_PARENT, TOGGLE_PARENT, TOUCH_UPDATED_AT, TOUCH_OPTION_PARENT_ARTICLES_UPDATED_AT,
|
||||
TOUCH_STUECKLISTE_ARTICLES_UPDATED_AT,
|
||||
ENQUEUE_SYNC_BY_ARTICLE, ENQUEUE_OPTION_PARENT_ARTICLES_SYNC, ENQUEUE_STUECKLISTE_ARTICLES_SYNC,
|
||||
UNLINK_CHILD, UPDATE_BRAND, UPDATE_PARENT_BY_SKU, UPDATE_TRACK_STOCK, UPDATE_UNIT,
|
||||
UPDATE_UNITAMOUNT, UPDATE_UNIT_AND_AMOUNT, UPDATE_WEIGHT,
|
||||
} = queries;
|
||||
|
||||
@@ -163,4 +163,41 @@ WHERE 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
|
||||
)
|
||||
`;
|
||||
|
||||
export const ENQUEUE_SUBTREE_CATEGORIES_SYNC = `
|
||||
WITH RECURSIVE cats AS (
|
||||
SELECT id FROM category WHERE id = @id
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
)
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'category', cats.id
|
||||
FROM cats
|
||||
INNER JOIN posterminal pt ON pt.company_id = @companyId
|
||||
`;
|
||||
|
||||
export const ENQUEUE_SUBTREE_ARTICLES_SYNC = `
|
||||
WITH RECURSIVE cats AS (
|
||||
SELECT id FROM category WHERE id = @id
|
||||
UNION ALL
|
||||
SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id
|
||||
),
|
||||
arts AS (
|
||||
SELECT ca.article_id AS 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 AS 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
|
||||
)
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'article', arts.id
|
||||
FROM arts
|
||||
INNER JOIN posterminal pt ON pt.company_id = @companyId
|
||||
`;
|
||||
@@ -7,8 +7,8 @@ export const {
|
||||
GET_BY_COMPANY_AND_ID, GET_CUSTOMER_BY_ID, GET_GROUP_ID_FOR_SUPPLIER,
|
||||
GET_SUPPLIER_BY_ID, LIST_BY_COMPANY, LIST_BY_COMPANY_AND_GROUP,
|
||||
LIST_CUSTOMERS_BY_COMPANY, LIST_SUPPLIERS_BY_COMPANY,
|
||||
NUMBER_TAKEN_IN_COMPANY, POS_GROUP_NAME, SUPPLIER_GROUP_NAME, UPDATE,
|
||||
UPDATE_NAME,
|
||||
NUMBER_TAKEN_IN_COMPANY, POS_GROUP_NAME, SUPPLIER_GROUP_NAME,
|
||||
TOUCH_UPDATED_AT, UPDATE, UPDATE_NAME,
|
||||
} = queries;
|
||||
|
||||
export const DELETE_BY_COMPANY_AND_ID = `
|
||||
|
||||
@@ -10,7 +10,8 @@ export const {
|
||||
COUNT_CUSTOMER_GROUPS, COUNT_COMPOSITE_PRODUCTS, MAX_ORDER_ID,
|
||||
LIST_POS_PRODUCT_CATEGORIES, LIST_POS_CUSTOMER_GROUP_IDS, LIST_POS_PRODUCT_PRICES,
|
||||
LIST_POS_MANDATED_OPTIONS, LIST_POS_PARENT_OPTIONS,
|
||||
TOUCH_LASTSEEN, RECORD_OBITUARY, COUNT_DELETED_ENTITIES,
|
||||
TOUCH_LASTSEEN, RECORD_OBITUARY, RECORD_SYNC_QUEUE, SEED_SYNC_QUEUE_FOR_TERMINAL,
|
||||
COUNT_DELETED_ENTITIES,
|
||||
} = queries;
|
||||
|
||||
export const SET_ON = `
|
||||
@@ -50,13 +51,19 @@ SELECT
|
||||
cg.name,
|
||||
CASE WHEN cg.id = co.poscustomergroup_id THEN '1' ELSE '0' END AS standard,
|
||||
'0.000000' AS discountPercent,
|
||||
CAST(strftime('%s', cg.updated_at) AS INTEGER) AS lastChanged
|
||||
FROM customergroup cg
|
||||
sq.syncId AS lastChanged
|
||||
FROM (
|
||||
SELECT entity_id, MAX(id) AS syncId
|
||||
FROM posterminalsyncqueue
|
||||
WHERE posterminal_id = @posterminalId AND entity_type = 'customergroup'
|
||||
GROUP BY entity_id
|
||||
HAVING MAX(id) > @cursor
|
||||
) sq
|
||||
INNER JOIN customergroup cg ON cg.id = sq.entity_id
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = cg.company_id
|
||||
INNER JOIN company co ON co.id = pt.company_id
|
||||
WHERE cg.name <> 'Lieferanten'
|
||||
AND CAST(strftime('%s', cg.updated_at) AS INTEGER) > @cursor
|
||||
ORDER BY lastChanged ASC, cg.id ASC
|
||||
ORDER BY sq.syncId ASC
|
||||
LIMIT @limit
|
||||
`;
|
||||
|
||||
@@ -116,13 +123,19 @@ SELECT
|
||||
ORDER BY ec.sort ASC, ec.id ASC
|
||||
LIMIT 1
|
||||
) AS email,
|
||||
CAST(strftime('%s', e.updated_at) AS INTEGER) AS lastChanged
|
||||
FROM entity e
|
||||
sq.syncId AS lastChanged
|
||||
FROM (
|
||||
SELECT entity_id, MAX(id) AS syncId
|
||||
FROM posterminalsyncqueue
|
||||
WHERE posterminal_id = @posterminalId AND entity_type = 'customer'
|
||||
GROUP BY entity_id
|
||||
HAVING MAX(id) > @cursor
|
||||
) sq
|
||||
INNER JOIN entity e ON e.id = sq.entity_id
|
||||
INNER JOIN customergroup cg ON cg.id = e.customergroup_id
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = cg.company_id
|
||||
WHERE cg.name <> 'Lieferanten'
|
||||
AND CAST(strftime('%s', e.updated_at) AS INTEGER) > @cursor
|
||||
ORDER BY lastChanged ASC, e.id ASC
|
||||
ORDER BY sq.syncId ASC
|
||||
LIMIT @limit
|
||||
`;
|
||||
|
||||
@@ -141,16 +154,21 @@ SELECT
|
||||
ORDER BY cp.sort ASC, cp.id ASC
|
||||
LIMIT 1
|
||||
) AS imgHash,
|
||||
CAST(strftime('%s', c.updated_at) AS INTEGER) AS lastChanged
|
||||
FROM category c
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = c.id
|
||||
sq.syncId AS lastChanged
|
||||
FROM (
|
||||
SELECT entity_id, MAX(id) AS syncId
|
||||
FROM posterminalsyncqueue
|
||||
WHERE posterminal_id = @posterminalId AND entity_type = 'category'
|
||||
GROUP BY entity_id
|
||||
HAVING MAX(id) > @cursor
|
||||
) sq
|
||||
INNER JOIN category c ON c.id = sq.entity_id
|
||||
INNER JOIN posterminalcategory pc ON pc.category_id = c.id AND pc.posterminal_id = @posterminalId
|
||||
INNER JOIN posterminal pt ON pt.id = pc.posterminal_id
|
||||
INNER JOIN company co ON co.id = pt.company_id
|
||||
LEFT JOIN categorytext ct ON ct.category_id = c.id AND ct.language_id = co.default_language_id
|
||||
WHERE pc.posterminal_id = @posterminalId
|
||||
AND (co.root_category_id IS NULL OR c.id <> co.root_category_id)
|
||||
AND CAST(strftime('%s', c.updated_at) AS INTEGER) > @cursor
|
||||
ORDER BY lastChanged ASC, c.id ASC
|
||||
WHERE (co.root_category_id IS NULL OR c.id <> co.root_category_id)
|
||||
ORDER BY sq.syncId ASC
|
||||
LIMIT @limit
|
||||
`;
|
||||
|
||||
@@ -162,7 +180,7 @@ SELECT
|
||||
COALESCE(pr.net, 0) AS netPrice,
|
||||
COALESCE(ptax.rate, ctax.rate, 0) AS taxRate,
|
||||
a.created_at AS createdAt,
|
||||
(CAST(strftime('%s', a.updated_at) AS INTEGER) * 1000000 + (a.id % 1000000)) AS lastChanged,
|
||||
sq.syncId AS lastChanged,
|
||||
COALESCE(
|
||||
(
|
||||
SELECT p.hash
|
||||
@@ -265,7 +283,14 @@ SELECT
|
||||
co.id AS companyId,
|
||||
co.root_category_id AS rootCategoryId,
|
||||
co.poscustomergroup_id AS posCustomerGroupId
|
||||
FROM article a
|
||||
FROM (
|
||||
SELECT entity_id, MAX(id) AS syncId
|
||||
FROM posterminalsyncqueue
|
||||
WHERE posterminal_id = @posterminalId AND entity_type = 'article'
|
||||
GROUP BY entity_id
|
||||
HAVING MAX(id) > @cursor
|
||||
) sq
|
||||
INNER JOIN article a ON a.id = sq.entity_id
|
||||
INNER JOIN posterminal pt ON pt.id = @posterminalId AND pt.company_id = a.company_id
|
||||
INNER JOIN company co ON co.id = a.company_id
|
||||
LEFT JOIN articletext at ON at.article_id = a.id AND at.language_id = co.default_language_id
|
||||
@@ -279,8 +304,7 @@ WHERE EXISTS (
|
||||
WHERE ca.article_id = a.id
|
||||
AND pc.posterminal_id = @posterminalId
|
||||
)
|
||||
AND (CAST(strftime('%s', a.updated_at) AS INTEGER) * 1000000 + (a.id % 1000000)) > @cursor
|
||||
ORDER BY (CAST(strftime('%s', a.updated_at) AS INTEGER) * 1000000 + (a.id % 1000000)) ASC
|
||||
ORDER BY sq.syncId ASC
|
||||
LIMIT @limit
|
||||
`;
|
||||
|
||||
|
||||
@@ -660,6 +660,18 @@ CREATE INDEX IF NOT EXISTS IX_posterminalobituary_posterminal_id
|
||||
ON posterminalobituary (posterminal_id, id);
|
||||
`;
|
||||
|
||||
export const INIT_POSTERMINALSYNCQUEUE = `
|
||||
CREATE TABLE IF NOT EXISTS posterminalsyncqueue (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
posterminal_id INTEGER NOT NULL,
|
||||
entity_type TEXT NOT NULL CHECK (entity_type IN ('article', 'category', 'customer', 'customergroup')),
|
||||
entity_id INTEGER NOT NULL,
|
||||
FOREIGN KEY (posterminal_id) REFERENCES posterminal(id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS IX_posterminalsyncqueue_posterminal_id
|
||||
ON posterminalsyncqueue (posterminal_id, id);
|
||||
`;
|
||||
|
||||
export const INIT_PRINTER = `
|
||||
CREATE TABLE IF NOT EXISTS printer (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -1206,6 +1218,7 @@ export const SCHEMA_SCRIPTS = [
|
||||
INIT_POSTERMINAL,
|
||||
INIT_POSTERMINALCATEGORY,
|
||||
INIT_POSTERMINALOBITUARY,
|
||||
INIT_POSTERMINALSYNCQUEUE,
|
||||
INIT_PRINTER,
|
||||
INIT_LABELTEMPLATE,
|
||||
INIT_FILE,
|
||||
|
||||
@@ -273,6 +273,8 @@ export default function addChild(provider) {
|
||||
|
||||
// Touch parent article updated_at so POS and other consumers refresh parent options
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: parentId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: childId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: parentId });
|
||||
|
||||
return load(googleAuthId, childSku, runner);
|
||||
};
|
||||
|
||||
@@ -8,8 +8,14 @@ import {
|
||||
} from '../../providers/sqlite3/queries/articlepic.js';
|
||||
import { CREATE as MSSQL_CREATE_PIC } from '../../providers/mssql/queries/pic.js';
|
||||
import { CREATE as SQLITE_CREATE_PIC } from '../../providers/sqlite3/queries/pic.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH } from '../../providers/mssql/queries/article.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH } from '../../providers/sqlite3/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import processAvifImage from '../../util/processAvifImage.js';
|
||||
import newFullHash from '../../util/newFullHash.js';
|
||||
import resolveArticleBySku from './resolveArticleBySku.js';
|
||||
@@ -24,6 +30,7 @@ export default function addImage(provider) {
|
||||
const createPicSql = isSqlite ? SQLITE_CREATE_PIC : MSSQL_CREATE_PIC;
|
||||
const addArticlePicSql = isSqlite ? SQLITE_ADD_ARTICLEPIC : MSSQL_ADD_ARTICLEPIC;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Adds an image to an article by its SKU, processing full, thumb, and 32px-edge small-thumb AVIF variants.
|
||||
@@ -107,6 +114,7 @@ export default function addImage(provider) {
|
||||
}
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
return {
|
||||
picId,
|
||||
|
||||
@@ -173,6 +173,8 @@ export default function attachChild(provider) {
|
||||
});
|
||||
}
|
||||
}
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: prevParentId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: prevParentId });
|
||||
}
|
||||
|
||||
// Assign parentsort if not already child of this parent
|
||||
@@ -305,6 +307,11 @@ export default function attachChild(provider) {
|
||||
});
|
||||
}
|
||||
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: child.id });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: child.id });
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: parentId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: parentId });
|
||||
|
||||
const updated = await load(googleAuthId, childSku, runner);
|
||||
const children = await list(googleAuthId, parentSku, runner);
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import {
|
||||
CREATE as MSSQL_CREATE_ARTICLE,
|
||||
CHECK_HAS_WAREHOUSE as MSSQL_CHECK_HAS_WAREHOUSE,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
CREATE as SQLITE_CREATE_ARTICLE,
|
||||
CHECK_HAS_WAREHOUSE as SQLITE_CHECK_HAS_WAREHOUSE,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import { ADD as MSSQL_ADD_CATEGORYARTICLE } from '../../providers/mssql/queries/categoryarticle.js';
|
||||
import { ADD as SQLITE_ADD_CATEGORYARTICLE } from '../../providers/sqlite3/queries/categoryarticle.js';
|
||||
@@ -30,6 +32,7 @@ export default function createUnderParent(provider) {
|
||||
const checkHasWarehouseSql = isSqlite ? SQLITE_CHECK_HAS_WAREHOUSE : MSSQL_CHECK_HAS_WAREHOUSE;
|
||||
const addCategoryArticleSql = isSqlite ? SQLITE_ADD_CATEGORYARTICLE : MSSQL_ADD_CATEGORYARTICLE;
|
||||
const createArticleTextSql = isSqlite ? SQLITE_CREATE_ARTICLETEXT : MSSQL_CREATE_ARTICLETEXT;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Creates a new article under a given parent category, allocating a SKU and
|
||||
@@ -118,6 +121,8 @@ export default function createUnderParent(provider) {
|
||||
await initArticleWarehouseSummary(runner, { companyId, articleId: id });
|
||||
}
|
||||
|
||||
await runner.query(enqueueSyncSql, { articleId: id });
|
||||
|
||||
return {
|
||||
id,
|
||||
parentId,
|
||||
|
||||
@@ -51,6 +51,7 @@ export default function del(provider) {
|
||||
|
||||
// Touch any parent articles that used this article as an option before deleting it
|
||||
await runner.query(articleQueries.TOUCH_OPTION_PARENT_ARTICLES_UPDATED_AT, { articleId: id });
|
||||
await runner.query(articleQueries.ENQUEUE_OPTION_PARENT_ARTICLES_SYNC, { articleId: id });
|
||||
|
||||
const deleted = await runner.query(queries.DELETE_BY_ID, { articleId: id });
|
||||
if (!deleted.rowsAffected) {
|
||||
|
||||
@@ -2,16 +2,24 @@ import sharp from 'sharp';
|
||||
import { encodeRGBA } from 'skelehash-wasm';
|
||||
import { DELETE_BY_ARTICLE_AND_HASH as MSSQL_QUERY } from '../../providers/mssql/queries/pic.js';
|
||||
import { DELETE_BY_ARTICLE_AND_HASH as SQLITE_QUERY } from '../../providers/sqlite3/queries/pic.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH } from '../../providers/mssql/queries/article.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH } from '../../providers/sqlite3/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from './resolveArticleBySku.js';
|
||||
import { recordImageDeleteHistory } from '../articlehistory/record.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function deleteImage(provider) {
|
||||
const resolve = resolveArticleBySku(provider);
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_QUERY : MSSQL_QUERY;
|
||||
const touchArticleSql = provider?.dialect === 'sqlite3' ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const sql = isSqlite ? SQLITE_QUERY : MSSQL_QUERY;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Deletes an image from an article by its SKU and full image hash.
|
||||
@@ -86,6 +94,7 @@ export default function deleteImage(provider) {
|
||||
});
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
};
|
||||
|
||||
if (tx) {
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import * as mssqlPic from '../../providers/mssql/queries/articlepic.js';
|
||||
import * as sqlitePic from '../../providers/sqlite3/queries/articlepic.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH } from '../../providers/mssql/queries/article.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH } from '../../providers/sqlite3/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from './resolveArticleBySku.js';
|
||||
import { recordImageOrderHistory } from '../articlehistory/record.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -11,6 +17,7 @@ export default function orderImages(provider) {
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const queries = isSqlite ? sqlitePic : mssqlPic;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Reorders the images of an article by its SKU.
|
||||
@@ -73,6 +80,7 @@ export default function orderImages(provider) {
|
||||
fullHashes,
|
||||
});
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
}
|
||||
|
||||
return { fullHashes };
|
||||
|
||||
@@ -88,6 +88,7 @@ export default function removeChild(provider) {
|
||||
|
||||
// Touch parent article updated_at so POS and other consumers refresh parent options
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: parentId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: parentId });
|
||||
|
||||
return {
|
||||
success: true,
|
||||
@@ -134,8 +135,11 @@ export default function removeChild(provider) {
|
||||
parentSku,
|
||||
});
|
||||
|
||||
// Touch parent article updated_at so POS and other consumers refresh parent options
|
||||
// Touch child and parent article updated_at so POS and other consumers refresh parent options
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: childId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: childId });
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: parentId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: parentId });
|
||||
|
||||
return {
|
||||
success: true,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import {
|
||||
GET_BRAND_BY_COMPANY_AND_ID as MSSQL_GET_BRAND,
|
||||
UPDATE_BRAND as MSSQL_UPDATE_BRAND,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
GET_BRAND_BY_COMPANY_AND_ID as SQLITE_GET_BRAND,
|
||||
UPDATE_BRAND as SQLITE_UPDATE_BRAND,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import queryBySku from './queryBySku.js';
|
||||
import resolveArticleBySku from './resolveArticleBySku.js';
|
||||
@@ -18,6 +20,7 @@ export default function setBrandIdBySku(provider) {
|
||||
|
||||
const getBrandSql = isSqlite ? SQLITE_GET_BRAND : MSSQL_GET_BRAND;
|
||||
const updateBrandSql = isSqlite ? SQLITE_UPDATE_BRAND : MSSQL_UPDATE_BRAND;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Sets (or clears) the brand of an article by its SKU.
|
||||
@@ -79,6 +82,8 @@ export default function setBrandIdBySku(provider) {
|
||||
throw new Error('Article not found');
|
||||
}
|
||||
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
// null = no brand; treat as distinct sentinel so first assignment is logged
|
||||
await recordBrandChangeHistory(runner, {
|
||||
articleId,
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
INSERT_POSTERMINAL_OBITUARY as MSSQL_INSERT_OBITUARY,
|
||||
LIST_PAIRED_POSTERMINAL_IDS_BY_ARTICLE as MSSQL_LIST_TERMINALS,
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
ADD_CATEGORY as SQLITE_ADD_CATEGORY,
|
||||
@@ -13,6 +14,7 @@ import {
|
||||
INSERT_POSTERMINAL_OBITUARY as SQLITE_INSERT_OBITUARY,
|
||||
LIST_PAIRED_POSTERMINAL_IDS_BY_ARTICLE as SQLITE_LIST_TERMINALS,
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveCategoryAccess from '../category/resolveCategoryAccess.js';
|
||||
import queryBySku from './queryBySku.js';
|
||||
@@ -32,6 +34,7 @@ export default function setCategoryIdsBySku(provider) {
|
||||
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;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Replaces the category membership of an article by its SKU.
|
||||
@@ -150,6 +153,7 @@ export default function setCategoryIdsBySku(provider) {
|
||||
|
||||
// Touch article updated_at so POS and other consumers pick up category assignment changes
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
const article = await load(articleId, languageId, runner);
|
||||
if (!article) {
|
||||
|
||||
@@ -3,12 +3,14 @@ import {
|
||||
DELETE_EANS_BY_ARTICLE as MSSQL_DELETE_EANS,
|
||||
EAN_EXISTS_FOR_OTHER_ARTICLE as MSSQL_CHECK_CONFLICT,
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
ADD_EAN as SQLITE_ADD_EAN,
|
||||
DELETE_EANS_BY_ARTICLE as SQLITE_DELETE_EANS,
|
||||
EAN_EXISTS_FOR_OTHER_ARTICLE as SQLITE_CHECK_CONFLICT,
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import { isUniqueConstraintError } from '../../providers/provider.js';
|
||||
import queryBySku from './queryBySku.js';
|
||||
@@ -25,6 +27,7 @@ export default function setEansBySku(provider) {
|
||||
const deleteEansSql = isSqlite ? SQLITE_DELETE_EANS : MSSQL_DELETE_EANS;
|
||||
const checkConflictSql = isSqlite ? SQLITE_CHECK_CONFLICT : MSSQL_CHECK_CONFLICT;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Replaces the EAN list of an article by its SKU.
|
||||
@@ -103,6 +106,7 @@ export default function setEansBySku(provider) {
|
||||
|
||||
// Touch article updated_at so POS and other consumers pick up the barcode change
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
const article = await load(articleId, languageId, runner);
|
||||
if (!article) {
|
||||
|
||||
@@ -56,6 +56,9 @@ export default function setParentBySku(provider) {
|
||||
parentArticleId: null,
|
||||
});
|
||||
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId });
|
||||
|
||||
if (prevParentId) {
|
||||
const prevParentTextRes = await runner.query(
|
||||
'SELECT sku FROM article WHERE id = @prevParentId',
|
||||
@@ -74,6 +77,9 @@ export default function setParentBySku(provider) {
|
||||
companyuserId,
|
||||
text: `Variante "${childName}" (${sku}) getrennt`,
|
||||
});
|
||||
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: prevParentId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: prevParentId });
|
||||
}
|
||||
|
||||
const unlinked = await load(articleId, languageId, runner);
|
||||
@@ -141,6 +147,11 @@ export default function setParentBySku(provider) {
|
||||
parentSku,
|
||||
});
|
||||
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId });
|
||||
await runner.query(queries.TOUCH_UPDATED_AT, { articleId: parentId });
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId: parentId });
|
||||
|
||||
const article = await load(articleId, languageId, runner);
|
||||
if (!article) {
|
||||
throw new Error('Article not found');
|
||||
|
||||
@@ -9,10 +9,14 @@ import {
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
TOUCH_OPTION_PARENT_ARTICLES_UPDATED_AT as MSSQL_TOUCH_OPTION_PARENTS,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
ENQUEUE_OPTION_PARENT_ARTICLES_SYNC as MSSQL_ENQUEUE_OPTION_PARENTS,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
TOUCH_OPTION_PARENT_ARTICLES_UPDATED_AT as SQLITE_TOUCH_OPTION_PARENTS,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
ENQUEUE_OPTION_PARENT_ARTICLES_SYNC as SQLITE_ENQUEUE_OPTION_PARENTS,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import taxEnsure from '../tax/ensure.js';
|
||||
import queryBySku from './queryBySku.js';
|
||||
@@ -75,6 +79,8 @@ export default function setPricesBySku(provider) {
|
||||
const deletePriceSql = isSqlite ? SQLITE_DELETE_PRICE : MSSQL_DELETE_PRICE;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const touchOptionParentsSql = isSqlite ? SQLITE_TOUCH_OPTION_PARENTS : MSSQL_TOUCH_OPTION_PARENTS;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
const enqueueOptionParentsSql = isSqlite ? SQLITE_ENQUEUE_OPTION_PARENTS : MSSQL_ENQUEUE_OPTION_PARENTS;
|
||||
|
||||
/**
|
||||
* Replaces the price list of an article by its SKU.
|
||||
@@ -153,9 +159,11 @@ export default function setPricesBySku(provider) {
|
||||
|
||||
// Touch article updated_at so POS and other consumers pick up the price change
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
// Touch any parent articles using this article as an option so their deposit price updates
|
||||
await runner.query(touchOptionParentsSql, { articleId });
|
||||
await runner.query(enqueueOptionParentsSql, { articleId });
|
||||
|
||||
const article = await load(articleId, languageId, runner);
|
||||
if (!article) {
|
||||
|
||||
@@ -2,11 +2,13 @@ import {
|
||||
UPDATE_TRACK_STOCK as MSSQL_UPDATE_TRACK_STOCK,
|
||||
CHECK_HAS_WAREHOUSE as MSSQL_CHECK_HAS_WAREHOUSE,
|
||||
CHECK_ARTICLE_WAREHOUSE_STOCKS as MSSQL_CHECK_ARTICLE_WAREHOUSE_STOCKS,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
UPDATE_TRACK_STOCK as SQLITE_UPDATE_TRACK_STOCK,
|
||||
CHECK_HAS_WAREHOUSE as SQLITE_CHECK_HAS_WAREHOUSE,
|
||||
CHECK_ARTICLE_WAREHOUSE_STOCKS as SQLITE_CHECK_ARTICLE_WAREHOUSE_STOCKS,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import queryBySku from './queryBySku.js';
|
||||
import resolveArticleBySku from './resolveArticleBySku.js';
|
||||
@@ -26,6 +28,7 @@ export default function setTrackStockBySku(provider) {
|
||||
const sql = isSqlite ? SQLITE_UPDATE_TRACK_STOCK : MSSQL_UPDATE_TRACK_STOCK;
|
||||
const checkHasWarehouseSql = isSqlite ? SQLITE_CHECK_HAS_WAREHOUSE : MSSQL_CHECK_HAS_WAREHOUSE;
|
||||
const checkStocksSql = isSqlite ? SQLITE_CHECK_ARTICLE_WAREHOUSE_STOCKS : MSSQL_CHECK_ARTICLE_WAREHOUSE_STOCKS;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Sets the track_stock flag of an article by its SKU.
|
||||
@@ -96,6 +99,8 @@ export default function setTrackStockBySku(provider) {
|
||||
throw new Error('Article not found');
|
||||
}
|
||||
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
// Write history if track_stock changed
|
||||
if (oldTrack !== newTrack) {
|
||||
if (!newTrack) {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { UPDATE_WEIGHT as MSSQL_UPDATE_WEIGHT } from '../../providers/mssql/queries/article.js';
|
||||
import { UPDATE_WEIGHT as SQLITE_UPDATE_WEIGHT } from '../../providers/sqlite3/queries/article.js';
|
||||
import {
|
||||
UPDATE_WEIGHT as MSSQL_UPDATE_WEIGHT,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
UPDATE_WEIGHT as SQLITE_UPDATE_WEIGHT,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import queryBySku from './queryBySku.js';
|
||||
import resolveArticleBySku from './resolveArticleBySku.js';
|
||||
import { recordWeightChangeHistory } from '../articlehistory/record.js';
|
||||
@@ -8,7 +14,9 @@ import makeRunner from '../runner.js';
|
||||
export default function setWeightBySku(provider) {
|
||||
const resolve = resolveArticleBySku(provider);
|
||||
const load = queryBySku(provider);
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_UPDATE_WEIGHT : MSSQL_UPDATE_WEIGHT;
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const sql = isSqlite ? SQLITE_UPDATE_WEIGHT : MSSQL_UPDATE_WEIGHT;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Sets the weight of an article by its SKU.
|
||||
@@ -48,6 +56,8 @@ export default function setWeightBySku(provider) {
|
||||
throw new Error('Article not found');
|
||||
}
|
||||
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
// Write history if weight changed
|
||||
await recordWeightChangeHistory(runner, {
|
||||
articleId,
|
||||
|
||||
@@ -171,6 +171,8 @@ export default function toggleParent(provider) {
|
||||
});
|
||||
}
|
||||
|
||||
await runner.query(queries.ENQUEUE_SYNC_BY_ARTICLE, { articleId });
|
||||
|
||||
return load(googleAuthId, sku, runner);
|
||||
};
|
||||
|
||||
|
||||
@@ -234,9 +234,11 @@ export default function updateBySku(provider) {
|
||||
|
||||
// Touch article updated_at so all consumers pick up changes
|
||||
await runner.query(articleQueries.TOUCH_UPDATED_AT, { articleId });
|
||||
await runner.query(articleQueries.ENQUEUE_SYNC_BY_ARTICLE, { articleId });
|
||||
|
||||
// Touch any parent articles that use this article as an option so their deposit name/details update on POS
|
||||
await runner.query(articleQueries.TOUCH_OPTION_PARENT_ARTICLES_UPDATED_AT, { articleId });
|
||||
await runner.query(articleQueries.ENQUEUE_OPTION_PARENT_ARTICLES_SYNC, { articleId });
|
||||
|
||||
const article = await load(articleId, languageId, runner);
|
||||
if (!article) {
|
||||
|
||||
@@ -8,6 +8,14 @@ import {
|
||||
INSERT_ROW as SQLITE_INSERT,
|
||||
GET_VALUE_DETAIL as SQLITE_GET_DETAIL,
|
||||
} from '../../providers/sqlite3/queries/articleattributevalue.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import { recordAttributeChangeHistory } from '../articlehistory/record.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -18,6 +26,8 @@ export default function setByArticleSku(provider) {
|
||||
const deleteSql = isSqlite ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const insertSql = isSqlite ? SQLITE_INSERT : MSSQL_INSERT;
|
||||
const getDetailSql = isSqlite ? SQLITE_GET_DETAIL : MSSQL_GET_DETAIL;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Replaces all attribute values for an article by its SKU.
|
||||
@@ -187,6 +197,13 @@ export default function setByArticleSku(provider) {
|
||||
newAttrs: validated,
|
||||
});
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
if (article?.parentarticle_id != null) {
|
||||
await runner.query(touchArticleSql, { articleId: article.parentarticle_id });
|
||||
await runner.query(enqueueSyncSql, { articleId: article.parentarticle_id });
|
||||
}
|
||||
|
||||
return inserted;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import * as mssqlQueries from '../../providers/mssql/queries/articlelist.js';
|
||||
import * as sqliteQueries from '../../providers/sqlite3/queries/articlelist.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import getItemsByArticleSku from './getItemsByArticleSku.js';
|
||||
import {
|
||||
@@ -46,6 +54,8 @@ export default function setItemsByArticleSku(provider) {
|
||||
const getItems = getItemsByArticleSku(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const queries = isSqlite ? sqliteQueries : mssqlQueries;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Sets or clears the Stückliste (bundle items) for an article.
|
||||
@@ -108,6 +118,8 @@ export default function setItemsByArticleSku(provider) {
|
||||
type: 'articlelist_cleared',
|
||||
});
|
||||
}
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
}
|
||||
return [];
|
||||
}
|
||||
@@ -229,6 +241,9 @@ export default function setItemsByArticleSku(provider) {
|
||||
items: result,
|
||||
});
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,14 @@ import {
|
||||
import {
|
||||
DELETE_BY_ARTICLE_AND_PROPERTY_ID as SQLITE_DELETE,
|
||||
} from '../../providers/sqlite3/queries/articleproperty.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import { recordPropertyDeleteHistory } from '../articlehistory/record.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -12,6 +20,8 @@ export default function deleteArticleProperty(provider) {
|
||||
const resolve = resolveArticleBySku(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const deleteSql = isSqlite ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Deletes a property from an article by SKU and propertyId.
|
||||
@@ -45,6 +55,8 @@ export default function deleteArticleProperty(provider) {
|
||||
name: prop.name,
|
||||
value: prop.value,
|
||||
});
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,6 +12,14 @@ import {
|
||||
import {
|
||||
GET_BY_COMPANY_AND_ID as SQLITE_GET_PROP,
|
||||
} from '../../providers/sqlite3/queries/propertyname.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import { recordPropertyChangeHistory } from '../articlehistory/record.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -22,6 +30,8 @@ export default function setByArticleSku(provider) {
|
||||
const deleteSql = isSqlite ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const insertSql = isSqlite ? SQLITE_INSERT : MSSQL_INSERT;
|
||||
const getPropSql = isSqlite ? SQLITE_GET_PROP : MSSQL_GET_PROP;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Replaces all properties for an article by its SKU.
|
||||
@@ -124,6 +134,9 @@ export default function setByArticleSku(provider) {
|
||||
newProps: validated,
|
||||
});
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
return inserted;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import * as mssqlQueries from '../../providers/mssql/queries/articlesupplier.js';
|
||||
import * as sqliteQueries from '../../providers/sqlite3/queries/articlesupplier.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import taxEnsure from '../tax/ensure.js';
|
||||
import {
|
||||
@@ -17,6 +25,8 @@ export default function create(provider) {
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
|
||||
const queries = isSqlite ? sqliteQueries : mssqlQueries;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Assigns a supplier to an article, optionally creating a purchase price.
|
||||
@@ -161,6 +171,9 @@ export default function create(provider) {
|
||||
pu: actualPu,
|
||||
});
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
return shapeArticleSupplier(supplierRow);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import * as mssqlQueries from '../../providers/mssql/queries/articlesupplier.js';
|
||||
import * as sqliteQueries from '../../providers/sqlite3/queries/articlesupplier.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import { recordSupplierDeleteHistory } from '../articlehistory/record.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -8,6 +16,8 @@ export default function del(provider) {
|
||||
const resolve = resolveArticleBySku(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const queries = isSqlite ? sqliteQueries : mssqlQueries;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Deletes a supplier assignment and cleans up its associated purchase price.
|
||||
@@ -59,6 +69,9 @@ export default function del(provider) {
|
||||
supplierName,
|
||||
supplierSku: existing.sku,
|
||||
});
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
};
|
||||
|
||||
if (tx) {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import * as mssqlQueries from '../../providers/mssql/queries/articlesupplier.js';
|
||||
import * as sqliteQueries from '../../providers/sqlite3/queries/articlesupplier.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
@@ -7,6 +15,8 @@ export default function order(provider) {
|
||||
const resolve = resolveArticleBySku(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const queries = isSqlite ? sqliteQueries : mssqlQueries;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Reorders the supplier assignments of an article by its SKU.
|
||||
@@ -65,6 +75,9 @@ export default function order(provider) {
|
||||
}
|
||||
}
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
return { ids };
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
import * as mssqlQueries from '../../providers/mssql/queries/articlesupplier.js';
|
||||
import * as sqliteQueries from '../../providers/sqlite3/queries/articlesupplier.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import taxEnsure from '../tax/ensure.js';
|
||||
import {
|
||||
@@ -16,6 +24,8 @@ export default function update(provider) {
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
|
||||
const queries = isSqlite ? sqliteQueries : mssqlQueries;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Updates an existing supplier assignment and its associated purchase price.
|
||||
@@ -218,6 +228,9 @@ export default function update(provider) {
|
||||
supplierName,
|
||||
});
|
||||
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
const loadRes = await runner.query(queries.GET_BY_ID_AND_ARTICLE_ID, {
|
||||
id,
|
||||
articleId,
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
TOUCH_STUECKLISTE_ARTICLES_UPDATED_AT as MSSQL_TOUCH_STUECKLISTE,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
ENQUEUE_STUECKLISTE_ARTICLES_SYNC as MSSQL_ENQUEUE_STUECKLISTE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
TOUCH_STUECKLISTE_ARTICLES_UPDATED_AT as SQLITE_TOUCH_STUECKLISTE,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
ENQUEUE_STUECKLISTE_ARTICLES_SYNC as SQLITE_ENQUEUE_STUECKLISTE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
|
||||
/**
|
||||
@@ -154,8 +158,12 @@ export async function syncArticleWarehouseSummaryForLedger(runner, { companyId,
|
||||
|
||||
const touchSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const touchStuecklisteSql = isSqlite ? SQLITE_TOUCH_STUECKLISTE : MSSQL_TOUCH_STUECKLISTE;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
const enqueueStuecklisteSyncSql = isSqlite ? SQLITE_ENQUEUE_STUECKLISTE_SYNC : MSSQL_ENQUEUE_STUECKLISTE_SYNC;
|
||||
await runner.query(touchSql, { articleId });
|
||||
await runner.query(touchStuecklisteSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
await runner.query(enqueueStuecklisteSyncSql, { articleId });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,51 @@ export default function update(provider) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (value !== existing.rows[0].value || sort !== existing.rows[0].sort) {
|
||||
const touchSql = isSqlite
|
||||
? `UPDATE article SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
||||
WHERE company_id = @companyId
|
||||
AND (
|
||||
id IN (SELECT article_id FROM articleattributevalue WHERE attributevalue_id = @valId)
|
||||
OR id IN (
|
||||
SELECT a.parentarticle_id
|
||||
FROM article a
|
||||
INNER JOIN articleattributevalue aav ON aav.article_id = a.id
|
||||
WHERE aav.attributevalue_id = @valId AND a.parentarticle_id IS NOT NULL
|
||||
)
|
||||
)`
|
||||
: `UPDATE article SET updated_at = SYSUTCDATETIME()
|
||||
WHERE company_id = @companyId
|
||||
AND (
|
||||
id IN (SELECT article_id FROM articleattributevalue WHERE attributevalue_id = @valId)
|
||||
OR id IN (
|
||||
SELECT a.parentarticle_id
|
||||
FROM article a
|
||||
INNER JOIN articleattributevalue aav ON aav.article_id = a.id
|
||||
WHERE aav.attributevalue_id = @valId AND a.parentarticle_id IS NOT NULL
|
||||
)
|
||||
)`;
|
||||
await runner.query(touchSql, { valId, companyId });
|
||||
|
||||
const enqueueSql = `
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'article', a.id
|
||||
FROM article a
|
||||
INNER JOIN posterminal pt ON pt.company_id = a.company_id
|
||||
WHERE a.company_id = @companyId
|
||||
AND (
|
||||
a.id IN (SELECT article_id FROM articleattributevalue WHERE attributevalue_id = @valId)
|
||||
OR a.id IN (
|
||||
SELECT child.parentarticle_id
|
||||
FROM article child
|
||||
INNER JOIN articleattributevalue aav ON aav.article_id = child.id
|
||||
WHERE aav.attributevalue_id = @valId AND child.parentarticle_id IS NOT NULL
|
||||
)
|
||||
)
|
||||
`;
|
||||
await runner.query(enqueueSql, { valId, companyId });
|
||||
}
|
||||
|
||||
return {
|
||||
id: valId,
|
||||
attributeId: existing.rows[0].attributeId,
|
||||
|
||||
@@ -78,6 +78,15 @@ export default function update(provider) {
|
||||
: 'UPDATE article SET updated_at = SYSUTCDATETIME() WHERE brand_id = @brandId AND company_id = @companyId';
|
||||
const touched = await runner.query(touchSql, { brandId: numericId, companyId });
|
||||
touchedArticleCount = touched.rowsAffected ?? 0;
|
||||
|
||||
const enqueueSql = `
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'article', a.id
|
||||
FROM article a
|
||||
INNER JOIN posterminal pt ON pt.company_id = a.company_id
|
||||
WHERE a.brand_id = @brandId AND a.company_id = @companyId
|
||||
`;
|
||||
await runner.query(enqueueSql, { brandId: numericId, companyId });
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -11,10 +11,12 @@ import { CREATE as SQLITE_CREATE_PIC } from '../../providers/sqlite3/queries/pic
|
||||
import processAvifImage from '../../util/processAvifImage.js';
|
||||
import newFullHash from '../../util/newFullHash.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function addImage(provider) {
|
||||
const access = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
|
||||
const getSortSql = isSqlite ? SQLITE_GET_NEXT_SORT : MSSQL_GET_NEXT_SORT;
|
||||
@@ -42,7 +44,7 @@ export default function addImage(provider) {
|
||||
const fullHash = newFullHash(processed.full.buffer);
|
||||
|
||||
const runAdd = async (runner) => {
|
||||
await access(googleAuthId, categoryId, runner);
|
||||
const { companyId } = await access(googleAuthId, categoryId, runner);
|
||||
|
||||
const sortResult = await runner.query(getSortSql, { categoryId });
|
||||
const sort = sortResult.rows[0].sort;
|
||||
@@ -95,6 +97,7 @@ export default function addImage(provider) {
|
||||
}
|
||||
|
||||
await runner.query(touchSql, { categoryId });
|
||||
await recordSync({ companyId, entityType: 'category', entityId: categoryId }, runner);
|
||||
|
||||
return {
|
||||
id: categoryId,
|
||||
|
||||
@@ -9,11 +9,13 @@ import {
|
||||
import { CREATE as MSSQL_CREATE_CATEGORYTEXT } from '../../providers/mssql/queries/categorytext.js';
|
||||
import { CREATE as SQLITE_CREATE_CATEGORYTEXT } from '../../providers/sqlite3/queries/categorytext.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import slugify from '../slugify.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function createUnderParent(provider) {
|
||||
const access = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
|
||||
const getSortSql = isSqlite
|
||||
@@ -40,7 +42,7 @@ export default function createUnderParent(provider) {
|
||||
*/
|
||||
return async ({ googleAuthId, parentId, name }, tx) => {
|
||||
const runCreate = async (runner) => {
|
||||
const { languageId } = await access(googleAuthId, parentId, runner);
|
||||
const { languageId, companyId } = await access(googleAuthId, parentId, runner);
|
||||
|
||||
const sortResult = await runner.query(getSortSql, { parentId });
|
||||
const sort = sortResult.rows[0].sort;
|
||||
@@ -60,6 +62,8 @@ export default function createUnderParent(provider) {
|
||||
slug,
|
||||
});
|
||||
|
||||
await recordSync({ companyId, entityType: 'category', entityId: id }, runner);
|
||||
|
||||
return {
|
||||
id,
|
||||
parentId,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { DELETE_BY_CATEGORY as MSSQL_DELETE } from '../../providers/mssql/queries/categorypic.js';
|
||||
import { DELETE_BY_CATEGORY as SQLITE_DELETE } from '../../providers/sqlite3/queries/categorypic.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function deleteImage(provider) {
|
||||
const access = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const touchSql = isSqlite
|
||||
@@ -26,7 +28,7 @@ export default function deleteImage(provider) {
|
||||
*/
|
||||
return async (googleAuthId, categoryId, tx) => {
|
||||
const runner = makeRunner(provider, tx);
|
||||
await access(googleAuthId, categoryId, runner);
|
||||
const { companyId } = await access(googleAuthId, categoryId, runner);
|
||||
|
||||
const result = await runner.query(sql, { categoryId });
|
||||
|
||||
@@ -35,6 +37,7 @@ export default function deleteImage(provider) {
|
||||
}
|
||||
|
||||
await runner.query(touchSql, { categoryId });
|
||||
await recordSync({ companyId, entityType: 'category', entityId: categoryId }, runner);
|
||||
|
||||
return {
|
||||
id: categoryId,
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
import { CREATE as MSSQL_CREATE_CATEGORYTEXT } from '../../providers/mssql/queries/categorytext.js';
|
||||
import { CREATE as SQLITE_CREATE_CATEGORYTEXT } from '../../providers/sqlite3/queries/categorytext.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import slugify from '../slugify.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
@@ -25,6 +26,7 @@ export function splitPath(path) {
|
||||
|
||||
export default function ensureByPath(provider) {
|
||||
const access = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
|
||||
const getSortSql = isSqlite
|
||||
@@ -61,7 +63,7 @@ export default function ensureByPath(provider) {
|
||||
|
||||
let currentId = parentId;
|
||||
|
||||
const createCategory = async (runner, parentId, name, languageId) => {
|
||||
const createCategory = async (runner, parentId, name, languageId, companyId) => {
|
||||
const sortResult = await runner.query(getSortSql, { parentId });
|
||||
const sort = sortResult.rows[0].sort;
|
||||
const slug = slugify(name);
|
||||
@@ -79,11 +81,13 @@ export default function ensureByPath(provider) {
|
||||
slug,
|
||||
});
|
||||
|
||||
await recordSync({ companyId, entityType: 'category', entityId: id }, runner);
|
||||
|
||||
return id;
|
||||
};
|
||||
|
||||
for (const name of names) {
|
||||
const { languageId } = await access(googleAuthId, currentId, tx);
|
||||
const { languageId, companyId } = await access(googleAuthId, currentId, tx);
|
||||
|
||||
const existing = await makeRunner(provider, tx).query(getByNameSql, {
|
||||
parentId: currentId,
|
||||
@@ -98,17 +102,17 @@ export default function ensureByPath(provider) {
|
||||
|
||||
if (tx) {
|
||||
// Run within the caller's transaction (e.g. article import row).
|
||||
currentId = await createCategory(makeRunner(provider, tx), currentId, name, languageId);
|
||||
currentId = await createCategory(makeRunner(provider, tx), currentId, name, languageId, companyId);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Standalone use: own transaction per created category.
|
||||
if (typeof provider?.transaction === 'function') {
|
||||
currentId = await provider.transaction((runner) =>
|
||||
createCategory(runner, currentId, name, languageId),
|
||||
createCategory(runner, currentId, name, languageId, companyId),
|
||||
);
|
||||
} else {
|
||||
currentId = await createCategory(makeRunner(provider), currentId, name, languageId);
|
||||
currentId = await createCategory(makeRunner(provider), currentId, name, languageId, companyId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import {
|
||||
MOVE as MSSQL_MOVE,
|
||||
TOUCH_SUBTREE_CATEGORIES as MSSQL_TOUCH_SUBTREE_CATEGORIES,
|
||||
TOUCH_SUBTREE_ARTICLES as MSSQL_TOUCH_SUBTREE_ARTICLES,
|
||||
ENQUEUE_SUBTREE_CATEGORIES_SYNC as MSSQL_ENQUEUE_SUBTREE_CATEGORIES,
|
||||
ENQUEUE_SUBTREE_ARTICLES_SYNC as MSSQL_ENQUEUE_SUBTREE_ARTICLES,
|
||||
} from '../../providers/mssql/queries/category.js';
|
||||
import {
|
||||
GET_NEXT_SIBLING_SORT as SQLITE_GET_NEXT_SIBLING_SORT,
|
||||
@@ -11,6 +13,8 @@ import {
|
||||
MOVE as SQLITE_MOVE,
|
||||
TOUCH_SUBTREE_CATEGORIES as SQLITE_TOUCH_SUBTREE_CATEGORIES,
|
||||
TOUCH_SUBTREE_ARTICLES as SQLITE_TOUCH_SUBTREE_ARTICLES,
|
||||
ENQUEUE_SUBTREE_CATEGORIES_SYNC as SQLITE_ENQUEUE_SUBTREE_CATEGORIES,
|
||||
ENQUEUE_SUBTREE_ARTICLES_SYNC as SQLITE_ENQUEUE_SUBTREE_ARTICLES,
|
||||
} from '../../providers/sqlite3/queries/category.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -30,6 +34,12 @@ export default function move(provider) {
|
||||
const touchArticlesSql = isSqlite
|
||||
? SQLITE_TOUCH_SUBTREE_ARTICLES
|
||||
: MSSQL_TOUCH_SUBTREE_ARTICLES;
|
||||
const enqueueCategoriesSql = isSqlite
|
||||
? SQLITE_ENQUEUE_SUBTREE_CATEGORIES
|
||||
: MSSQL_ENQUEUE_SUBTREE_CATEGORIES;
|
||||
const enqueueArticlesSql = isSqlite
|
||||
? SQLITE_ENQUEUE_SUBTREE_ARTICLES
|
||||
: MSSQL_ENQUEUE_SUBTREE_ARTICLES;
|
||||
|
||||
/**
|
||||
* Moves a category to a new parent, preventing cycles and cross-company moves.
|
||||
@@ -82,6 +92,8 @@ export default function move(provider) {
|
||||
|
||||
await runner.query(touchCategoriesSql, { id });
|
||||
await runner.query(touchArticlesSql, { id });
|
||||
await runner.query(enqueueCategoriesSql, { id, companyId: source.companyId });
|
||||
await runner.query(enqueueArticlesSql, { id, companyId: source.companyId });
|
||||
|
||||
return { id, parentId, sort };
|
||||
};
|
||||
|
||||
@@ -7,10 +7,12 @@ import {
|
||||
UPDATE_SORT as SQLITE_UPDATE_SORT,
|
||||
} from '../../providers/sqlite3/queries/category.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function order(provider) {
|
||||
const access = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const listChildIdsSql = isSqlite
|
||||
? SQLITE_LIST_CHILD_IDS
|
||||
@@ -39,7 +41,7 @@ export default function order(provider) {
|
||||
|
||||
const runOrder = async (runner) => {
|
||||
// Auth + ensures parentId is a real category of the user's company.
|
||||
await access(googleAuthId, parentId, runner);
|
||||
const { companyId } = await access(googleAuthId, parentId, runner);
|
||||
|
||||
const children = await runner.query(listChildIdsSql, { parentId });
|
||||
|
||||
@@ -63,6 +65,7 @@ export default function order(provider) {
|
||||
parentId,
|
||||
sort,
|
||||
});
|
||||
await recordSync({ companyId, entityType: 'category', entityId: categoryIds[sort] }, runner);
|
||||
}
|
||||
|
||||
return { categoryIds };
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import { UPDATE_BY_CATEGORY_AND_LANGUAGE as MSSQL_UPDATE } from '../../providers/mssql/queries/categorytext.js';
|
||||
import { UPDATE_BY_CATEGORY_AND_LANGUAGE as SQLITE_UPDATE } from '../../providers/sqlite3/queries/categorytext.js';
|
||||
import resolveCategoryAccess from './resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import slugify from '../slugify.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function rename(provider) {
|
||||
const access = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_UPDATE : MSSQL_UPDATE;
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const touchSql = isSqlite
|
||||
@@ -33,7 +35,7 @@ export default function rename(provider) {
|
||||
}
|
||||
const cleaned = name.trim();
|
||||
|
||||
const { languageId } = await access(googleAuthId, id, tx);
|
||||
const { languageId, companyId } = await access(googleAuthId, id, tx);
|
||||
|
||||
const slug = slugify(cleaned);
|
||||
|
||||
@@ -50,6 +52,7 @@ export default function rename(provider) {
|
||||
}
|
||||
|
||||
await runner.query(touchSql, { categoryId: id });
|
||||
await recordSync({ companyId, entityType: 'category', entityId: id }, runner);
|
||||
|
||||
return { id, name: cleaned, slug };
|
||||
};
|
||||
|
||||
@@ -9,10 +9,12 @@ import {
|
||||
GET_VALUE_DETAIL as SQLITE_GET_DETAIL,
|
||||
} from '../../providers/sqlite3/queries/categoryattributevalue.js';
|
||||
import resolveCategoryAccess from '../category/resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function setByCategoryId(provider) {
|
||||
const resolve = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const deleteSql = isSqlite ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const insertSql = isSqlite ? SQLITE_INSERT : MSSQL_INSERT;
|
||||
@@ -140,6 +142,7 @@ export default function setByCategoryId(provider) {
|
||||
? "UPDATE category SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = @categoryId"
|
||||
: 'UPDATE category SET updated_at = SYSUTCDATETIME() WHERE id = @categoryId';
|
||||
await runner.query(touchSql, { categoryId });
|
||||
await recordSync({ companyId, entityType: 'category', entityId: categoryId }, runner);
|
||||
|
||||
return inserted;
|
||||
};
|
||||
|
||||
@@ -5,10 +5,12 @@ import {
|
||||
DELETE_BY_CATEGORY_AND_PROPERTY_ID as SQLITE_DELETE,
|
||||
} from '../../providers/sqlite3/queries/categoryproperty.js';
|
||||
import resolveCategoryAccess from '../category/resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function deleteCategoryProperty(provider) {
|
||||
const resolve = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const deleteSql = isSqlite ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
|
||||
@@ -23,7 +25,7 @@ export default function deleteCategoryProperty(provider) {
|
||||
*/
|
||||
return async (googleAuthId, categoryId, propertyId, tx) => {
|
||||
const runner = makeRunner(provider, tx);
|
||||
await resolve(googleAuthId, categoryId, runner);
|
||||
const { companyId } = await resolve(googleAuthId, categoryId, runner);
|
||||
|
||||
await runner.query(deleteSql, { categoryId, propertyId });
|
||||
|
||||
@@ -32,5 +34,6 @@ export default function deleteCategoryProperty(provider) {
|
||||
? "UPDATE category SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = @categoryId"
|
||||
: 'UPDATE category SET updated_at = SYSUTCDATETIME() WHERE id = @categoryId';
|
||||
await runner.query(touchSql, { categoryId });
|
||||
await recordSync({ companyId, entityType: 'category', entityId: categoryId }, runner);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,10 +13,12 @@ import {
|
||||
GET_BY_COMPANY_AND_ID as SQLITE_GET_PROP,
|
||||
} from '../../providers/sqlite3/queries/propertyname.js';
|
||||
import resolveCategoryAccess from '../category/resolveCategoryAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function setByCategoryId(provider) {
|
||||
const resolve = resolveCategoryAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const deleteSql = isSqlite ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const insertSql = isSqlite ? SQLITE_INSERT : MSSQL_INSERT;
|
||||
@@ -102,6 +104,7 @@ export default function setByCategoryId(provider) {
|
||||
? "UPDATE category SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id = @categoryId"
|
||||
: 'UPDATE category SET updated_at = SYSUTCDATETIME() WHERE id = @categoryId';
|
||||
await runner.query(touchSql, { categoryId });
|
||||
await recordSync({ companyId, entityType: 'category', entityId: categoryId }, runner);
|
||||
|
||||
return inserted;
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from '../../providers/sqlite3/queries/customergroup.js';
|
||||
import { POS_GROUP_NAME, SUPPLIER_GROUP_NAME } from '../../providers/mssql/queries/entity.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
const RESERVED_NAMES = new Set([POS_GROUP_NAME, SUPPLIER_GROUP_NAME]);
|
||||
@@ -18,6 +19,7 @@ function shape(row) {
|
||||
|
||||
export default function create(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const getSortSql = isSqlite ? SQLITE_GET_NEXT_SORT : MSSQL_GET_NEXT_SORT;
|
||||
const createSql = isSqlite ? SQLITE_CREATE : MSSQL_CREATE;
|
||||
@@ -58,6 +60,7 @@ export default function create(provider) {
|
||||
});
|
||||
|
||||
const row = result.rows[0] ?? { id: result.insertId, name: cleaned, sort };
|
||||
await recordSync({ companyId, entityType: 'customergroup', entityId: row.id }, runner);
|
||||
return shape(row);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -7,10 +7,12 @@ import {
|
||||
UPDATE_SORT as SQLITE_UPDATE_SORT,
|
||||
} from '../../providers/sqlite3/queries/customergroup.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function order(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const listIdsSql = isSqlite
|
||||
? SQLITE_LIST_IDS_BY_COMPANY
|
||||
@@ -65,6 +67,7 @@ export default function order(provider) {
|
||||
companyId,
|
||||
sort,
|
||||
});
|
||||
await recordSync({ companyId, entityType: 'customergroup', entityId: customergroupIds[sort] }, runner);
|
||||
}
|
||||
|
||||
return { customergroupIds };
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from '../../providers/sqlite3/queries/customergroup.js';
|
||||
import { POS_GROUP_NAME, SUPPLIER_GROUP_NAME } from '../../providers/mssql/queries/entity.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
const LOCKED_NAMES = new Set([POS_GROUP_NAME, SUPPLIER_GROUP_NAME]);
|
||||
@@ -18,6 +19,7 @@ function shape(row) {
|
||||
|
||||
export default function update(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const getSql = isSqlite
|
||||
? SQLITE_GET_BY_COMPANY_AND_ID
|
||||
@@ -70,6 +72,7 @@ export default function update(provider) {
|
||||
});
|
||||
|
||||
const row = result.rows[0] ?? { id, name: cleaned, sort: current.sort };
|
||||
await recordSync({ companyId, entityType: 'customergroup', entityId: id }, runner);
|
||||
return shape(row);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import { INSERT as SQLITE_INSERT_HISTORY } from '../../providers/sqlite3/queries
|
||||
import { isUniqueConstraintError } from '../../providers/provider.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveCustomerGroupAccess from '../customergroup/resolveCustomerGroupAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import nextNumber from '../numbers/nextNumber.js';
|
||||
import shape from './shape.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -12,6 +13,7 @@ import makeRunner from '../runner.js';
|
||||
export default function create(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const groupAccess = resolveCustomerGroupAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const allocateNumber = nextNumber(provider);
|
||||
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
@@ -82,6 +84,8 @@ export default function create(provider) {
|
||||
text: 'Erstellt',
|
||||
});
|
||||
|
||||
await recordSync({ companyId, entityType: 'customer', entityId: row.id }, runner);
|
||||
|
||||
return shape(row);
|
||||
} catch (err) {
|
||||
if (isUniqueConstraintError(err)) {
|
||||
|
||||
@@ -10,11 +10,13 @@ import { INSERT as MSSQL_INSERT_HISTORY } from '../../providers/mssql/queries/en
|
||||
import { INSERT as SQLITE_INSERT_HISTORY } from '../../providers/sqlite3/queries/entityhistory.js';
|
||||
import { isUniqueConstraintError } from '../../providers/provider.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import shape from './shape.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function update(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const getSql = isSqlite
|
||||
? SQLITE_GET_BY_COMPANY_AND_ID
|
||||
@@ -134,6 +136,8 @@ export default function update(provider) {
|
||||
text: historyLines.join('\n'),
|
||||
});
|
||||
|
||||
await recordSync({ companyId, entityType: 'customer', entityId: id }, runner);
|
||||
|
||||
return shape(row);
|
||||
} catch (err) {
|
||||
if (isUniqueConstraintError(err)) {
|
||||
|
||||
@@ -6,8 +6,11 @@ import {
|
||||
CREATE as SQLITE_CREATE,
|
||||
GET_NEXT_SORT as SQLITE_GET_NEXT_SORT,
|
||||
} from '../../providers/sqlite3/queries/entityaddress.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH_ENTITY } from '../../providers/mssql/queries/entity.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH_ENTITY } from '../../providers/sqlite3/queries/entity.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveEntityAccess from '../entity/resolveEntityAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function shape(row) {
|
||||
@@ -35,9 +38,11 @@ function optionalString(value) {
|
||||
export default function create(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const entityAccess = resolveEntityAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const getSortSql = isSqlite ? SQLITE_GET_NEXT_SORT : MSSQL_GET_NEXT_SORT;
|
||||
const createSql = isSqlite ? SQLITE_CREATE : MSSQL_CREATE;
|
||||
const touchEntitySql = isSqlite ? SQLITE_TOUCH_ENTITY : MSSQL_TOUCH_ENTITY;
|
||||
|
||||
/**
|
||||
* Creates a new address for an entity.
|
||||
@@ -109,6 +114,9 @@ export default function create(provider) {
|
||||
sort,
|
||||
};
|
||||
|
||||
await runner.query(touchEntitySql, { id: entityId });
|
||||
await recordSync({ companyId, entityType: 'customer', entityId }, runner);
|
||||
|
||||
return shape(row);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import { DELETE_BY_ENTITY_AND_ID as MSSQL_DELETE } from '../../providers/mssql/queries/entityaddress.js';
|
||||
import { DELETE_BY_ENTITY_AND_ID as SQLITE_DELETE } from '../../providers/sqlite3/queries/entityaddress.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH_ENTITY } from '../../providers/mssql/queries/entity.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH_ENTITY } from '../../providers/sqlite3/queries/entity.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveEntityAccess from '../entity/resolveEntityAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function del(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const entityAccess = resolveEntityAccess(provider);
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const sql = isSqlite ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const touchEntitySql = isSqlite ? SQLITE_TOUCH_ENTITY : MSSQL_TOUCH_ENTITY;
|
||||
|
||||
/**
|
||||
* Deletes an address of an entity.
|
||||
@@ -39,5 +45,8 @@ export default function del(provider) {
|
||||
if (!result.rowsAffected) {
|
||||
throw new Error('Address not found');
|
||||
}
|
||||
|
||||
await runner.query(touchEntitySql, { id: entityId });
|
||||
await recordSync({ companyId, entityType: 'customer', entityId }, runner);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import {
|
||||
GET_BY_ENTITY_AND_ID as SQLITE_GET_BY_ENTITY_AND_ID,
|
||||
UPDATE as SQLITE_UPDATE,
|
||||
} from '../../providers/sqlite3/queries/entityaddress.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH_ENTITY } from '../../providers/mssql/queries/entity.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH_ENTITY } from '../../providers/sqlite3/queries/entity.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveEntityAccess from '../entity/resolveEntityAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function shape(row) {
|
||||
@@ -35,11 +38,13 @@ function optionalString(value) {
|
||||
export default function update(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const entityAccess = resolveEntityAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const getSql = isSqlite
|
||||
? SQLITE_GET_BY_ENTITY_AND_ID
|
||||
: MSSQL_GET_BY_ENTITY_AND_ID;
|
||||
const updateSql = isSqlite ? SQLITE_UPDATE : MSSQL_UPDATE;
|
||||
const touchEntitySql = isSqlite ? SQLITE_TOUCH_ENTITY : MSSQL_TOUCH_ENTITY;
|
||||
|
||||
/**
|
||||
* Updates an address of an entity.
|
||||
@@ -152,6 +157,9 @@ export default function update(provider) {
|
||||
sort,
|
||||
};
|
||||
|
||||
await runner.query(touchEntitySql, { id: entityId });
|
||||
await recordSync({ companyId, entityType: 'customer', entityId }, runner);
|
||||
|
||||
return shape(row);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import {
|
||||
CREATE as SQLITE_CREATE,
|
||||
GET_NEXT_SORT as SQLITE_GET_NEXT_SORT,
|
||||
} from '../../providers/sqlite3/queries/entitycontact.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH_ENTITY } from '../../providers/mssql/queries/entity.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH_ENTITY } from '../../providers/sqlite3/queries/entity.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveEntityAccess from '../entity/resolveEntityAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function shape(row) {
|
||||
@@ -23,9 +26,11 @@ function shape(row) {
|
||||
export default function create(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const entityAccess = resolveEntityAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const getSortSql = isSqlite ? SQLITE_GET_NEXT_SORT : MSSQL_GET_NEXT_SORT;
|
||||
const createSql = isSqlite ? SQLITE_CREATE : MSSQL_CREATE;
|
||||
const touchEntitySql = isSqlite ? SQLITE_TOUCH_ENTITY : MSSQL_TOUCH_ENTITY;
|
||||
|
||||
/**
|
||||
* Creates a new contact for an entity.
|
||||
@@ -80,6 +85,9 @@ export default function create(provider) {
|
||||
sort,
|
||||
};
|
||||
|
||||
await runner.query(touchEntitySql, { id: entityId });
|
||||
await recordSync({ companyId, entityType: 'customer', entityId }, runner);
|
||||
|
||||
return shape(row);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import { DELETE_BY_ENTITY_AND_ID as MSSQL_DELETE } from '../../providers/mssql/queries/entitycontact.js';
|
||||
import { DELETE_BY_ENTITY_AND_ID as SQLITE_DELETE } from '../../providers/sqlite3/queries/entitycontact.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH_ENTITY } from '../../providers/mssql/queries/entity.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH_ENTITY } from '../../providers/sqlite3/queries/entity.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveEntityAccess from '../entity/resolveEntityAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function del(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const entityAccess = resolveEntityAccess(provider);
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const sql = isSqlite ? SQLITE_DELETE : MSSQL_DELETE;
|
||||
const touchEntitySql = isSqlite ? SQLITE_TOUCH_ENTITY : MSSQL_TOUCH_ENTITY;
|
||||
|
||||
/**
|
||||
* Deletes a contact of an entity.
|
||||
@@ -39,5 +45,8 @@ export default function del(provider) {
|
||||
if (!result.rowsAffected) {
|
||||
throw new Error('Contact not found');
|
||||
}
|
||||
|
||||
await runner.query(touchEntitySql, { id: entityId });
|
||||
await recordSync({ companyId, entityType: 'customer', entityId }, runner);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import {
|
||||
GET_BY_ENTITY_AND_ID as SQLITE_GET_BY_ENTITY_AND_ID,
|
||||
UPDATE as SQLITE_UPDATE,
|
||||
} from '../../providers/sqlite3/queries/entitycontact.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH_ENTITY } from '../../providers/mssql/queries/entity.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH_ENTITY } from '../../providers/sqlite3/queries/entity.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import resolveEntityAccess from '../entity/resolveEntityAccess.js';
|
||||
import recordSyncQueue from '../posterminal/recordSyncQueue.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
function shape(row) {
|
||||
@@ -23,11 +26,13 @@ function shape(row) {
|
||||
export default function update(provider) {
|
||||
const access = resolveSelectedCompanyAccess(provider);
|
||||
const entityAccess = resolveEntityAccess(provider);
|
||||
const recordSync = recordSyncQueue(provider);
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const getSql = isSqlite
|
||||
? SQLITE_GET_BY_ENTITY_AND_ID
|
||||
: MSSQL_GET_BY_ENTITY_AND_ID;
|
||||
const updateSql = isSqlite ? SQLITE_UPDATE : MSSQL_UPDATE;
|
||||
const touchEntitySql = isSqlite ? SQLITE_TOUCH_ENTITY : MSSQL_TOUCH_ENTITY;
|
||||
|
||||
/**
|
||||
* Updates a contact of an entity.
|
||||
@@ -100,6 +105,9 @@ export default function update(provider) {
|
||||
sort,
|
||||
};
|
||||
|
||||
await runner.query(touchEntitySql, { id: entityId });
|
||||
await recordSync({ companyId, entityType: 'customer', entityId }, runner);
|
||||
|
||||
return shape(row);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,10 +14,14 @@ import makeRunner from '../runner.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
TOUCH_STUECKLISTE_ARTICLES_UPDATED_AT as MSSQL_TOUCH_STUECKLISTE,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
ENQUEUE_STUECKLISTE_ARTICLES_SYNC as MSSQL_ENQUEUE_STUECKLISTE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
TOUCH_STUECKLISTE_ARTICLES_UPDATED_AT as SQLITE_TOUCH_STUECKLISTE,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
ENQUEUE_STUECKLISTE_ARTICLES_SYNC as SQLITE_ENQUEUE_STUECKLISTE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
|
||||
export const INIT_HASH = 'TODO_TSE_BASED_INITHASH';
|
||||
@@ -218,6 +222,12 @@ export default function add(provider) {
|
||||
const touchStuecklisteSql = isSqlite ? SQLITE_TOUCH_STUECKLISTE : MSSQL_TOUCH_STUECKLISTE;
|
||||
await runner.query(touchSql, { articleId: match.id });
|
||||
await runner.query(touchStuecklisteSql, { articleId: match.id });
|
||||
if (!isTracked) {
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
const enqueueStuecklisteSyncSql = isSqlite ? SQLITE_ENQUEUE_STUECKLISTE_SYNC : MSSQL_ENQUEUE_STUECKLISTE_SYNC;
|
||||
await runner.query(enqueueSyncSql, { articleId: match.id });
|
||||
await runner.query(enqueueStuecklisteSyncSql, { articleId: match.id });
|
||||
}
|
||||
await recordAcceptanceHistory(runner, {
|
||||
articleId: match.id,
|
||||
companyuserId,
|
||||
@@ -312,6 +322,12 @@ export default function add(provider) {
|
||||
const touchStuecklisteSql = isSqlite ? SQLITE_TOUCH_STUECKLISTE : MSSQL_TOUCH_STUECKLISTE;
|
||||
await runner.query(touchSql, { articleId: match.id });
|
||||
await runner.query(touchStuecklisteSql, { articleId: match.id });
|
||||
if (!isTracked) {
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
const enqueueStuecklisteSyncSql = isSqlite ? SQLITE_ENQUEUE_STUECKLISTE_SYNC : MSSQL_ENQUEUE_STUECKLISTE_SYNC;
|
||||
await runner.query(enqueueSyncSql, { articleId: match.id });
|
||||
await runner.query(enqueueStuecklisteSyncSql, { articleId: match.id });
|
||||
}
|
||||
await recordShipmentHistory(runner, {
|
||||
articleId: match.id,
|
||||
companyuserId,
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import * as mssqlQueries from '../../providers/mssql/queries/optionslist.js';
|
||||
import * as sqliteQueries from '../../providers/sqlite3/queries/optionslist.js';
|
||||
import { TOUCH_UPDATED_AT as MSSQL_TOUCH } from '../../providers/mssql/queries/article.js';
|
||||
import { TOUCH_UPDATED_AT as SQLITE_TOUCH } from '../../providers/sqlite3/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as MSSQL_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as MSSQL_ENQUEUE_SYNC,
|
||||
} from '../../providers/mssql/queries/article.js';
|
||||
import {
|
||||
TOUCH_UPDATED_AT as SQLITE_TOUCH,
|
||||
ENQUEUE_SYNC_BY_ARTICLE as SQLITE_ENQUEUE_SYNC,
|
||||
} from '../../providers/sqlite3/queries/article.js';
|
||||
import resolveArticleBySku from '../article/resolveArticleBySku.js';
|
||||
import getOptionsByArticleSku from './getOptionsByArticleSku.js';
|
||||
import {
|
||||
@@ -49,6 +55,7 @@ export default function setOptionsByArticleSku(provider) {
|
||||
const isSqlite = provider?.dialect === 'sqlite3';
|
||||
const queries = isSqlite ? sqliteQueries : mssqlQueries;
|
||||
const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH;
|
||||
const enqueueSyncSql = isSqlite ? SQLITE_ENQUEUE_SYNC : MSSQL_ENQUEUE_SYNC;
|
||||
|
||||
/**
|
||||
* Sets or clears the options list for an article.
|
||||
@@ -112,6 +119,7 @@ export default function setOptionsByArticleSku(provider) {
|
||||
});
|
||||
}
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
}
|
||||
return [];
|
||||
}
|
||||
@@ -242,6 +250,7 @@ export default function setOptionsByArticleSku(provider) {
|
||||
|
||||
// Touch article updated_at so POS and other consumers pick up options/deposit changes
|
||||
await runner.query(touchArticleSql, { articleId });
|
||||
await runner.query(enqueueSyncSql, { articleId });
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
@@ -4,19 +4,18 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
export default function getCategoryCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts categories assigned to the POS terminal updated after the given unix timestamp cursor.
|
||||
* Counts categories assigned to the POS terminal queued after the given sync queue cursor ID.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
|
||||
@@ -4,19 +4,18 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
export default function getCategoryList(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Lists categories for a POS terminal modified after the cursor.
|
||||
* Lists categories for a POS terminal queued after the sync queue cursor ID.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {number} [input.limit=20] - Max items to return.
|
||||
* @param {object} [tx] - Optional transaction.
|
||||
* @returns {Promise<Array<object>>}
|
||||
|
||||
@@ -4,21 +4,18 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
if (n < 1e11) return Math.floor(n * 1000000);
|
||||
if (n < 1e14) return Math.floor((n / 1000) * 1000000);
|
||||
return Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
export default function getCompositeProductCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts composite products (Stücklisten) assigned to the POS terminal updated after the given unix timestamp cursor.
|
||||
* Counts composite products (Stücklisten) assigned to the POS terminal queued after the given sync queue cursor ID.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
|
||||
@@ -4,19 +4,18 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
export default function getCustomerCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts customers of the POS terminal company updated after the given unix timestamp cursor.
|
||||
* Counts customers of the POS terminal company queued after the given sync queue cursor ID.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
|
||||
@@ -4,19 +4,18 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
export default function getCustomerGroupCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts customer groups of the POS terminal company updated after the given unix timestamp cursor.
|
||||
* Counts customer groups of the POS terminal company queued after the given sync queue cursor ID.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
|
||||
@@ -4,19 +4,18 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
export default function getCustomerGroupList(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Lists customer groups for a POS terminal modified after the cursor, excluding 'Lieferanten'.
|
||||
* Lists customer groups for a POS terminal queued after the sync queue cursor ID, excluding 'Lieferanten'.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {number} [input.limit=50] - Max items to return.
|
||||
* @param {object} [tx] - Optional transaction.
|
||||
* @returns {Promise<Array<{customerGroupId: string, name: string, standard: string, discountPercent: string, lastChanged: string}>>}
|
||||
|
||||
@@ -4,19 +4,18 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
return n >= 1e11 ? Math.floor(n / 1000) : Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
export default function getCustomerList(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Lists customers for a POS terminal modified after the cursor, excluding 'Lieferanten'.
|
||||
* Lists customers for a POS terminal queued after the sync queue cursor ID, excluding 'Lieferanten'.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {number} [input.limit=20] - Max items to return.
|
||||
* @param {object} [tx] - Optional transaction.
|
||||
* @returns {Promise<Array<object>>}
|
||||
|
||||
@@ -4,21 +4,18 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
if (n < 1e11) return Math.floor(n * 1000000);
|
||||
if (n < 1e14) return Math.floor((n / 1000) * 1000000);
|
||||
return Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
export default function getProductCount(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Counts products assigned to the POS terminal updated after the given unix timestamp cursor.
|
||||
* Counts products assigned to the POS terminal queued after the given sync queue cursor ID.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor of last update.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {object} [tx] - Optional transaction to run within.
|
||||
* @returns {Promise<number>} The count of changed records.
|
||||
*/
|
||||
|
||||
@@ -18,10 +18,7 @@ import makeRunner from '../runner.js';
|
||||
|
||||
function normalizeCursor(cursor) {
|
||||
const n = Number(cursor) || 0;
|
||||
if (n <= 0) return 0;
|
||||
if (n < 1e11) return Math.floor(n * 1000000);
|
||||
if (n < 1e14) return Math.floor((n / 1000) * 1000000);
|
||||
return Math.floor(n);
|
||||
return n > 0 ? Math.floor(n) : 0;
|
||||
}
|
||||
|
||||
function formatDateTime(value) {
|
||||
@@ -46,11 +43,11 @@ export default function getProductList(provider) {
|
||||
const parentOptionsSql = isSqlite ? SQLITE_PARENT_OPTIONS : MSSQL_PARENT_OPTIONS;
|
||||
|
||||
/**
|
||||
* Lists products for a POS terminal modified after the cursor.
|
||||
* Lists products for a POS terminal queued after the sync queue cursor ID.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.posterminalId - The POS terminal id.
|
||||
* @param {number} [input.cursor=0] - Unix timestamp cursor.
|
||||
* @param {number} [input.cursor=0] - Sequential ID cursor of last synced posterminalsyncqueue entry.
|
||||
* @param {number} [input.limit=20] - Max items to return.
|
||||
* @param {object} [tx] - Optional transaction.
|
||||
* @returns {Promise<Array<object>>}
|
||||
|
||||
28
src/store/posterminal/recordSyncQueue.js
Normal file
28
src/store/posterminal/recordSyncQueue.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import { RECORD_SYNC_QUEUE as MSSQL_SQL } from '../../providers/mssql/queries/posterminal.js';
|
||||
import { RECORD_SYNC_QUEUE as SQLITE_SQL } from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
export default function recordSyncQueue(provider) {
|
||||
const sql = provider?.dialect === 'sqlite3' ? SQLITE_SQL : MSSQL_SQL;
|
||||
|
||||
/**
|
||||
* Enqueues a sync notification for all POS terminals of a company.
|
||||
*
|
||||
* @param {object} input
|
||||
* @param {number} input.companyId - The company id.
|
||||
* @param {string} input.entityType - 'category' | 'article' | 'customer' | 'customergroup'
|
||||
* @param {number} input.entityId - The entity's id.
|
||||
* @param {object} [tx] - Optional transaction/runner.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
return async ({ companyId, entityType, entityId }, tx) => {
|
||||
if (!companyId || !entityType || !entityId) return;
|
||||
const runner = makeRunner(provider, tx);
|
||||
await runner.query(sql, {
|
||||
companyId: Number(companyId),
|
||||
entityType: String(entityType).toLowerCase().trim(),
|
||||
entityId: Number(entityId),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,14 @@ import {
|
||||
SET_OFF as SQLITE_SET_OFF,
|
||||
LIST_CATEGORY_IDS as SQLITE_LIST_CATEGORY_IDS,
|
||||
} from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import {
|
||||
ENQUEUE_SUBTREE_CATEGORIES_SYNC as MSSQL_ENQUEUE_SUBTREE_CATEGORIES,
|
||||
ENQUEUE_SUBTREE_ARTICLES_SYNC as MSSQL_ENQUEUE_SUBTREE_ARTICLES,
|
||||
} from '../../providers/mssql/queries/category.js';
|
||||
import {
|
||||
ENQUEUE_SUBTREE_CATEGORIES_SYNC as SQLITE_ENQUEUE_SUBTREE_CATEGORIES,
|
||||
ENQUEUE_SUBTREE_ARTICLES_SYNC as SQLITE_ENQUEUE_SUBTREE_ARTICLES,
|
||||
} from '../../providers/sqlite3/queries/category.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
@@ -20,6 +28,12 @@ export default function setOff(provider) {
|
||||
const listCatIdsSql = isSqlite
|
||||
? SQLITE_LIST_CATEGORY_IDS
|
||||
: MSSQL_LIST_CATEGORY_IDS;
|
||||
const enqueueCategoriesSql = isSqlite
|
||||
? SQLITE_ENQUEUE_SUBTREE_CATEGORIES
|
||||
: MSSQL_ENQUEUE_SUBTREE_CATEGORIES;
|
||||
const enqueueArticlesSql = isSqlite
|
||||
? SQLITE_ENQUEUE_SUBTREE_ARTICLES
|
||||
: MSSQL_ENQUEUE_SUBTREE_ARTICLES;
|
||||
|
||||
const touchSql = isSqlite
|
||||
? `WITH RECURSIVE cats AS (
|
||||
@@ -182,6 +196,8 @@ export default function setOff(provider) {
|
||||
|
||||
await runner.query(touchSql, { categoryId });
|
||||
await runner.query(touchArticlesSql, { categoryId });
|
||||
await runner.query(enqueueCategoriesSql, { id: categoryId, companyId });
|
||||
await runner.query(enqueueArticlesSql, { id: categoryId, companyId });
|
||||
|
||||
const result = await runner.query(listCatIdsSql, { posterminalId });
|
||||
|
||||
|
||||
@@ -8,6 +8,14 @@ import {
|
||||
SET_ON as SQLITE_SET_ON,
|
||||
LIST_CATEGORY_IDS as SQLITE_LIST_CATEGORY_IDS,
|
||||
} from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import {
|
||||
ENQUEUE_SUBTREE_CATEGORIES_SYNC as MSSQL_ENQUEUE_SUBTREE_CATEGORIES,
|
||||
ENQUEUE_SUBTREE_ARTICLES_SYNC as MSSQL_ENQUEUE_SUBTREE_ARTICLES,
|
||||
} from '../../providers/mssql/queries/category.js';
|
||||
import {
|
||||
ENQUEUE_SUBTREE_CATEGORIES_SYNC as SQLITE_ENQUEUE_SUBTREE_CATEGORIES,
|
||||
ENQUEUE_SUBTREE_ARTICLES_SYNC as SQLITE_ENQUEUE_SUBTREE_ARTICLES,
|
||||
} from '../../providers/sqlite3/queries/category.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
@@ -20,6 +28,12 @@ export default function setOn(provider) {
|
||||
const listCatIdsSql = isSqlite
|
||||
? SQLITE_LIST_CATEGORY_IDS
|
||||
: MSSQL_LIST_CATEGORY_IDS;
|
||||
const enqueueCategoriesSql = isSqlite
|
||||
? SQLITE_ENQUEUE_SUBTREE_CATEGORIES
|
||||
: MSSQL_ENQUEUE_SUBTREE_CATEGORIES;
|
||||
const enqueueArticlesSql = isSqlite
|
||||
? SQLITE_ENQUEUE_SUBTREE_ARTICLES
|
||||
: MSSQL_ENQUEUE_SUBTREE_ARTICLES;
|
||||
const touchSql = isSqlite
|
||||
? `WITH RECURSIVE cats AS (
|
||||
SELECT id FROM category WHERE id = @categoryId
|
||||
@@ -166,6 +180,8 @@ export default function setOn(provider) {
|
||||
|
||||
await runner.query(touchSql, { categoryId });
|
||||
await runner.query(touchArticlesSql, { categoryId });
|
||||
await runner.query(enqueueCategoriesSql, { id: categoryId, companyId });
|
||||
await runner.query(enqueueArticlesSql, { id: categoryId, companyId });
|
||||
|
||||
const result = await runner.query(listCatIdsSql, { posterminalId });
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
} from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import { GET_COMPANY_ROOT_CATEGORY as MSSQL_ROOT } from '../../providers/mssql/queries/company.js';
|
||||
import { GET_COMPANY_ROOT_CATEGORY as SQLITE_ROOT } from '../../providers/sqlite3/queries/company.js';
|
||||
import { ENQUEUE_SUBTREE_CATEGORIES_SYNC as MSSQL_ENQUEUE_SUBTREE_CATEGORIES } from '../../providers/mssql/queries/category.js';
|
||||
import { ENQUEUE_SUBTREE_CATEGORIES_SYNC as SQLITE_ENQUEUE_SUBTREE_CATEGORIES } from '../../providers/sqlite3/queries/category.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import makeRunner from '../runner.js';
|
||||
|
||||
@@ -23,6 +25,16 @@ export default function setOnAll(provider) {
|
||||
? SQLITE_LIST_CATEGORY_IDS
|
||||
: MSSQL_LIST_CATEGORY_IDS;
|
||||
const rootSql = isSqlite ? SQLITE_ROOT : MSSQL_ROOT;
|
||||
const enqueueCategoriesSql = isSqlite
|
||||
? SQLITE_ENQUEUE_SUBTREE_CATEGORIES
|
||||
: MSSQL_ENQUEUE_SUBTREE_CATEGORIES;
|
||||
const enqueueAllArticlesSql = `
|
||||
INSERT INTO posterminalsyncqueue (posterminal_id, entity_type, entity_id)
|
||||
SELECT pt.id, 'article', a.id
|
||||
FROM article a
|
||||
INNER JOIN posterminal pt ON pt.company_id = a.company_id
|
||||
WHERE a.company_id = @companyId
|
||||
`;
|
||||
const touchAllSql = isSqlite
|
||||
? `WITH RECURSIVE cats AS (
|
||||
SELECT id FROM category WHERE id = @rootCategoryId
|
||||
@@ -100,6 +112,8 @@ export default function setOnAll(provider) {
|
||||
|
||||
await runner.query(touchAllSql, { rootCategoryId });
|
||||
await runner.query(touchAllArticlesSql, { companyId });
|
||||
await runner.query(enqueueCategoriesSql, { id: rootCategoryId, companyId });
|
||||
await runner.query(enqueueAllArticlesSql, { companyId });
|
||||
|
||||
const result = await runner.query(listCatIdsSql, { posterminalId });
|
||||
|
||||
|
||||
@@ -2,11 +2,13 @@ import {
|
||||
GET_BY_ID as MSSQL_GET_BY_ID,
|
||||
CREATE as MSSQL_CREATE,
|
||||
UPDATE as MSSQL_UPDATE,
|
||||
SEED_SYNC_QUEUE_FOR_TERMINAL as MSSQL_SEED_SYNC_QUEUE,
|
||||
} from '../../providers/mssql/queries/posterminal.js';
|
||||
import {
|
||||
GET_BY_ID as SQLITE_GET_BY_ID,
|
||||
CREATE as SQLITE_CREATE,
|
||||
UPDATE as SQLITE_UPDATE,
|
||||
SEED_SYNC_QUEUE_FOR_TERMINAL as SQLITE_SEED_SYNC_QUEUE,
|
||||
} from '../../providers/sqlite3/queries/posterminal.js';
|
||||
import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js';
|
||||
import makeRunner from '../runner.js';
|
||||
@@ -18,6 +20,7 @@ export default function upsert(provider) {
|
||||
const getByIdSql = isSqlite ? SQLITE_GET_BY_ID : MSSQL_GET_BY_ID;
|
||||
const createSql = isSqlite ? SQLITE_CREATE : MSSQL_CREATE;
|
||||
const updateSql = isSqlite ? SQLITE_UPDATE : MSSQL_UPDATE;
|
||||
const seedSyncQueueSql = isSqlite ? SQLITE_SEED_SYNC_QUEUE : MSSQL_SEED_SYNC_QUEUE;
|
||||
|
||||
/**
|
||||
* Creates or updates a posterminal for the user's selected company.
|
||||
@@ -143,6 +146,11 @@ export default function upsert(provider) {
|
||||
lastseenAt,
|
||||
};
|
||||
|
||||
await runner.query(seedSyncQueueSql, {
|
||||
posterminalId: row.id,
|
||||
companyId,
|
||||
});
|
||||
|
||||
return {
|
||||
id: row.id,
|
||||
name: row.name,
|
||||
|
||||
Reference in New Issue
Block a user