import { GET_BY_ID as MSSQL_GET_BY_ID, SET_OFF as MSSQL_SET_OFF, LIST_CATEGORY_IDS as MSSQL_LIST_CATEGORY_IDS, } from '../../providers/mssql/queries/posterminal.js'; import { GET_BY_ID as SQLITE_GET_BY_ID, SET_OFF as SQLITE_SET_OFF, LIST_CATEGORY_IDS as SQLITE_LIST_CATEGORY_IDS, } from '../../providers/sqlite3/queries/posterminal.js'; import resolveSelectedCompanyAccess from '../companyuser/resolveSelectedCompanyAccess.js'; import makeRunner from '../runner.js'; export default function setOff(provider) { const access = resolveSelectedCompanyAccess(provider); const isSqlite = provider?.dialect === 'sqlite3'; const getByIdSql = isSqlite ? SQLITE_GET_BY_ID : MSSQL_GET_BY_ID; const setOffSql = isSqlite ? SQLITE_SET_OFF : MSSQL_SET_OFF; const listCatIdsSql = isSqlite ? SQLITE_LIST_CATEGORY_IDS : MSSQL_LIST_CATEGORY_IDS; const touchSql = isSqlite ? `WITH RECURSIVE cats AS ( SELECT id FROM category WHERE id = @categoryId UNION ALL SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id ) UPDATE category SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id IN (SELECT id FROM cats)` : `;WITH cats AS ( SELECT id FROM category WHERE id = @categoryId UNION ALL SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id ) UPDATE category SET updated_at = SYSUTCDATETIME() WHERE id IN (SELECT id FROM cats)`; const touchArticlesSql = isSqlite ? `WITH RECURSIVE cats AS ( SELECT id FROM category WHERE id = @categoryId UNION ALL SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id ) UPDATE article SET updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now') WHERE id IN ( SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats) UNION SELECT child.id FROM article child WHERE child.parentarticle_id IN ( SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats) ) UNION SELECT parent.parentarticle_id FROM article parent WHERE parent.id IN ( SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats) ) AND parent.parentarticle_id IS NOT NULL )` : `;WITH cats AS ( SELECT id FROM category WHERE id = @categoryId UNION ALL SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id ) UPDATE article SET updated_at = SYSUTCDATETIME() WHERE id IN ( SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats) UNION SELECT child.id FROM article child WHERE child.parentarticle_id IN ( SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats) ) UNION SELECT parent.parentarticle_id FROM article parent WHERE parent.id IN ( SELECT ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats) ) AND parent.parentarticle_id IS NOT NULL )`; const addCategoryObituarySql = isSqlite ? `WITH RECURSIVE cats AS ( SELECT id FROM category WHERE id = @categoryId UNION ALL SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id ) INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id) SELECT pc.posterminal_id, 'category', pc.category_id FROM posterminalcategory pc WHERE pc.posterminal_id = @posterminalId AND pc.category_id IN (SELECT id FROM cats)` : `;WITH cats AS ( SELECT id FROM category WHERE id = @categoryId UNION ALL SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id ) INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id) SELECT pc.posterminal_id, 'category', pc.category_id FROM posterminalcategory pc WHERE pc.posterminal_id = @posterminalId AND pc.category_id IN (SELECT id FROM cats)`; const addArticleObituariesSql = isSqlite ? `WITH RECURSIVE cats AS ( SELECT id FROM category WHERE id = @categoryId UNION ALL SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id ) INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id) SELECT DISTINCT @posterminalId, 'article', ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats) AND NOT EXISTS ( SELECT 1 FROM categoryarticle ca2 INNER JOIN posterminalcategory pc ON pc.category_id = ca2.category_id WHERE ca2.article_id = ca.article_id AND pc.posterminal_id = @posterminalId AND pc.category_id NOT IN (SELECT id FROM cats) )` : `;WITH cats AS ( SELECT id FROM category WHERE id = @categoryId UNION ALL SELECT c.id FROM category c INNER JOIN cats ON c.parent_id = cats.id ) INSERT INTO posterminalobituary (posterminal_id, entity_type, entity_id) SELECT DISTINCT @posterminalId, 'article', ca.article_id FROM categoryarticle ca WHERE ca.category_id IN (SELECT id FROM cats) AND NOT EXISTS ( SELECT 1 FROM categoryarticle ca2 INNER JOIN posterminalcategory pc ON pc.category_id = ca2.category_id WHERE ca2.article_id = ca.article_id AND pc.posterminal_id = @posterminalId AND pc.category_id NOT IN (SELECT id FROM cats) )`; /** * Removes a category assignment from a posterminal (turns it off). * * @param {number} googleAuthId - The id of the Google auth user. * @param {number} posterminalId - The id of the posterminal. * @param {number} categoryId - The id of the category to remove. * @param {object} [tx] - Optional transaction to run within. * @returns {Promise<{id: number, categoryIds: Array}>} The posterminal with its remaining category ids. * @throws {Error} If the posterminal is not found. * * @example * const result = await store.posterminal.setOff(42, 5, 9); * // => { id, categoryIds: [...] } */ return async (googleAuthId, posterminalId, categoryId, tx) => { if (!Number.isFinite(posterminalId) || !Number.isFinite(categoryId)) { throw new Error('Invalid posterminal or category'); } const runner = makeRunner(provider, tx); const { companyId } = await access(googleAuthId, tx); const existing = await runner.query(getByIdSql, { id: posterminalId }); if (!existing.rows[0] || existing.rows[0].companyId !== companyId) { throw new Error('Posterminal not found'); } await runner.query(addCategoryObituarySql, { posterminalId, categoryId, }); await runner.query(addArticleObituariesSql, { posterminalId, categoryId, }); await runner.query(setOffSql, { posterminalId, categoryId, }); await runner.query(touchSql, { categoryId }); await runner.query(touchArticlesSql, { categoryId }); const result = await runner.query(listCatIdsSql, { posterminalId }); return { id: posterminalId, categoryIds: result.rows.map((r) => r.categoryId), }; }; }