diff --git a/src/providers/mssql/queries/article.js b/src/providers/mssql/queries/article.js index a8bb969..613d4b7 100644 --- a/src/providers/mssql/queries/article.js +++ b/src/providers/mssql/queries/article.js @@ -222,6 +222,12 @@ SET unit_id = @unitId, unitamount = @unitamount, updated_at = SYSUTCDATETIME() WHERE id = @articleId `; +export const TOUCH_UPDATED_AT = ` +UPDATE article +SET updated_at = SYSUTCDATETIME() +WHERE id = @articleId +`; + export const CREATE = ` INSERT INTO article (company_id, sku, unit_id, unitamount, weight, track_stock) OUTPUT INSERTED.id diff --git a/src/providers/sqlite3/queries/article.js b/src/providers/sqlite3/queries/article.js index eff91e3..55168c4 100644 --- a/src/providers/sqlite3/queries/article.js +++ b/src/providers/sqlite3/queries/article.js @@ -9,7 +9,7 @@ export const { GET_CATEGORY_ID_BY_SKU, GET_CATEGORY_TREE_FLAT, GET_ID_BY_SKU, LIST_CHILDREN_BY_PARENT_ID, SET_PARENT_SORT, - SET_IS_PARENT, TOGGLE_PARENT, UNLINK_CHILD, UPDATE_BRAND, UPDATE_PARENT_BY_SKU, UPDATE_TRACK_STOCK, UPDATE_UNIT, + SET_IS_PARENT, TOGGLE_PARENT, TOUCH_UPDATED_AT, UNLINK_CHILD, UPDATE_BRAND, UPDATE_PARENT_BY_SKU, UPDATE_TRACK_STOCK, UPDATE_UNIT, UPDATE_UNITAMOUNT, UPDATE_UNIT_AND_AMOUNT, UPDATE_WEIGHT, } = queries; diff --git a/src/store/article/addImage.js b/src/store/article/addImage.js index e3baec2..8a9eee5 100644 --- a/src/store/article/addImage.js +++ b/src/store/article/addImage.js @@ -8,6 +8,8 @@ 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 processAvifImage from '../../util/processAvifImage.js'; import newFullHash from '../../util/newFullHash.js'; import resolveArticleBySku from './resolveArticleBySku.js'; @@ -21,6 +23,7 @@ export default function addImage(provider) { const getSortSql = isSqlite ? SQLITE_GET_NEXT_SORT : MSSQL_GET_NEXT_SORT; 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; /** * Adds an image to an article by its SKU, processing full, thumb, and 32px-edge small-thumb AVIF variants. @@ -107,6 +110,8 @@ export default function addImage(provider) { }); } + await runner.query(touchArticleSql, { articleId }); + return { picId, sort: effectiveSort, diff --git a/src/store/article/deleteImage.js b/src/store/article/deleteImage.js index 7c4dc44..1b30557 100644 --- a/src/store/article/deleteImage.js +++ b/src/store/article/deleteImage.js @@ -2,6 +2,8 @@ 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 resolveArticleBySku from './resolveArticleBySku.js'; import { recordImageDeleteHistory } from '../articlehistory/record.js'; import makeRunner from '../runner.js'; @@ -9,6 +11,7 @@ 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; /** * Deletes an image from an article by its SKU and full image hash. @@ -95,6 +98,8 @@ export default function deleteImage(provider) { fullHash, skelehash, }); + + await runner.query(touchArticleSql, { articleId }); }; if (tx) { diff --git a/src/store/article/orderImages.js b/src/store/article/orderImages.js index 7888989..725cd01 100644 --- a/src/store/article/orderImages.js +++ b/src/store/article/orderImages.js @@ -1,5 +1,7 @@ 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 resolveArticleBySku from './resolveArticleBySku.js'; import { recordImageOrderHistory } from '../articlehistory/record.js'; import makeRunner from '../runner.js'; @@ -8,6 +10,7 @@ export default function orderImages(provider) { const resolve = resolveArticleBySku(provider); const isSqlite = provider?.dialect === 'sqlite3'; const queries = isSqlite ? sqlitePic : mssqlPic; + const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH; /** * Reorders the images of an article by its SKU. @@ -69,6 +72,7 @@ export default function orderImages(provider) { companyuserId, fullHashes, }); + await runner.query(touchArticleSql, { articleId }); } return { fullHashes }; diff --git a/src/store/article/setCategoryIdsBySku.js b/src/store/article/setCategoryIdsBySku.js index 7ba2963..1bc4f49 100644 --- a/src/store/article/setCategoryIdsBySku.js +++ b/src/store/article/setCategoryIdsBySku.js @@ -1,10 +1,12 @@ import { ADD_CATEGORY as MSSQL_ADD_CATEGORY, DELETE_CATEGORIES_BY_ARTICLE as MSSQL_DELETE_CATEGORIES, + TOUCH_UPDATED_AT as MSSQL_TOUCH, } from '../../providers/mssql/queries/article.js'; import { ADD_CATEGORY as SQLITE_ADD_CATEGORY, DELETE_CATEGORIES_BY_ARTICLE as SQLITE_DELETE_CATEGORIES, + TOUCH_UPDATED_AT as SQLITE_TOUCH, } from '../../providers/sqlite3/queries/article.js'; import resolveCategoryAccess from '../category/resolveCategoryAccess.js'; import queryBySku from './queryBySku.js'; @@ -20,6 +22,7 @@ export default function setCategoryIdsBySku(provider) { const addCategorySql = isSqlite ? SQLITE_ADD_CATEGORY : MSSQL_ADD_CATEGORY; const deleteCategoriesSql = isSqlite ? SQLITE_DELETE_CATEGORIES : MSSQL_DELETE_CATEGORIES; + const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH; /** * Replaces the category membership of an article by its SKU. @@ -91,6 +94,9 @@ export default function setCategoryIdsBySku(provider) { newCategoryIds: normalized, }); + // Touch article updated_at so POS and other consumers pick up category assignment changes + await runner.query(touchArticleSql, { articleId }); + const article = await load(articleId, languageId, runner); if (!article) { throw new Error('Article not found'); diff --git a/src/store/article/setEansBySku.js b/src/store/article/setEansBySku.js index ef6ce94..0ce177d 100644 --- a/src/store/article/setEansBySku.js +++ b/src/store/article/setEansBySku.js @@ -2,11 +2,13 @@ import { ADD_EAN as MSSQL_ADD_EAN, DELETE_EANS_BY_ARTICLE as MSSQL_DELETE_EANS, EAN_EXISTS_FOR_OTHER_ARTICLE as MSSQL_CHECK_CONFLICT, + TOUCH_UPDATED_AT as MSSQL_TOUCH, } 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, } from '../../providers/sqlite3/queries/article.js'; import { isUniqueConstraintError } from '../../providers/provider.js'; import queryBySku from './queryBySku.js'; @@ -22,6 +24,7 @@ export default function setEansBySku(provider) { const addEanSql = isSqlite ? SQLITE_ADD_EAN : MSSQL_ADD_EAN; 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; /** * Replaces the EAN list of an article by its SKU. @@ -98,6 +101,9 @@ export default function setEansBySku(provider) { newEans: normalized, }); + // Touch article updated_at so POS and other consumers pick up the barcode change + await runner.query(touchArticleSql, { articleId }); + const article = await load(articleId, languageId, runner); if (!article) { throw new Error('Article not found'); diff --git a/src/store/article/setPricesBySku.js b/src/store/article/setPricesBySku.js index 2666325..2e02fec 100644 --- a/src/store/article/setPricesBySku.js +++ b/src/store/article/setPricesBySku.js @@ -6,6 +6,8 @@ import { CREATE as SQLITE_CREATE_PRICE, DELETE_BY_ARTICLE_AND_CUSTOMERGROUP as SQLITE_DELETE_PRICE, } from '../../providers/sqlite3/queries/price.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 taxEnsure from '../tax/ensure.js'; import queryBySku from './queryBySku.js'; import resolveArticleBySku from './resolveArticleBySku.js'; @@ -65,6 +67,7 @@ export default function setPricesBySku(provider) { const createPriceSql = isSqlite ? SQLITE_CREATE_PRICE : MSSQL_CREATE_PRICE; const deletePriceSql = isSqlite ? SQLITE_DELETE_PRICE : MSSQL_DELETE_PRICE; + const touchArticleSql = isSqlite ? SQLITE_TOUCH : MSSQL_TOUCH; /** * Replaces the price list of an article by its SKU. @@ -141,6 +144,9 @@ export default function setPricesBySku(provider) { newPrices: normalized, }); + // Touch article updated_at so POS and other consumers pick up the price change + await runner.query(touchArticleSql, { articleId }); + const article = await load(articleId, languageId, runner); if (!article) { throw new Error('Article not found'); diff --git a/src/store/article/updateBySku.js b/src/store/article/updateBySku.js index e5644d3..304ad9c 100644 --- a/src/store/article/updateBySku.js +++ b/src/store/article/updateBySku.js @@ -232,6 +232,9 @@ export default function updateBySku(provider) { }); } + // Touch article updated_at so all consumers pick up changes + await runner.query(articleQueries.TOUCH_UPDATED_AT, { articleId }); + const article = await load(articleId, languageId, runner); if (!article) { throw new Error('Article not found');