import { GET_BRAND_BY_COMPANY_AND_ID as MSSQL_GET_BRAND, UPDATE_BRAND as MSSQL_UPDATE_BRAND, } from '../../providers/mssql/queries/article.js'; import { GET_BRAND_BY_COMPANY_AND_ID as SQLITE_GET_BRAND, UPDATE_BRAND as SQLITE_UPDATE_BRAND, } from '../../providers/sqlite3/queries/article.js'; import { INSERT as MSSQL_INSERT_HISTORY } from '../../providers/mssql/queries/articlehistory.js'; import { INSERT as SQLITE_INSERT_HISTORY } from '../../providers/sqlite3/queries/articlehistory.js'; import queryBySku from './queryBySku.js'; import resolveArticleBySku from './resolveArticleBySku.js'; import makeRunner from '../runner.js'; export default function setBrandIdBySku(provider) { const resolve = resolveArticleBySku(provider); const load = queryBySku(provider); const isSqlite = provider?.dialect === 'sqlite3'; const getBrandSql = isSqlite ? SQLITE_GET_BRAND : MSSQL_GET_BRAND; const updateBrandSql = isSqlite ? SQLITE_UPDATE_BRAND : MSSQL_UPDATE_BRAND; const insertHistorySql = isSqlite ? SQLITE_INSERT_HISTORY : MSSQL_INSERT_HISTORY; /** * Sets (or clears) the brand of an article by its SKU. * * @param {number} googleAuthId - The id of the Google auth user. * @param {string} sku - The article SKU. * @param {number|null} brandId - The brand id, or `null` to clear the brand. * @param {object} [tx] - Optional transaction. * @returns {Promise} The updated article. * @throws {Error} If the brand or article is not found. * * @example * const article = await store.article.setBrandIdBySku(42, 'SKU-1', 3); * // => { id, sku, name, ... } */ return async (googleAuthId, sku, brandId, tx) => { const runner = makeRunner(provider, tx); const { articleId, languageId, companyId, companyuserId } = await resolve( googleAuthId, sku, runner, ); if (brandId !== null && (typeof brandId !== 'number' || !Number.isInteger(brandId) || brandId <= 0)) { throw new Error('Invalid brandId'); } // Read old brand name (null = no brand assigned) const oldBrandRes = await runner.query( `SELECT b.name FROM article a LEFT JOIN brand b ON b.id = a.brand_id WHERE a.id = @articleId`, { articleId }, ); const oldBrandName = oldBrandRes.rows[0]?.name ?? null; let resolvedBrandId = null; let newBrandName = null; if (brandId !== null) { // Verify brand belongs to this company const brandCheck = await runner.query(getBrandSql, { brandId, companyId }); if (!brandCheck.rows[0]) { throw new Error('Brand not found'); } resolvedBrandId = brandId; // GET_BRAND_BY_COMPANY_AND_ID only selects `id`, so fetch name separately const brandNameRes = await runner.query( 'SELECT name FROM brand WHERE id = @brandId', { brandId }, ); newBrandName = brandNameRes.rows[0]?.name ?? null; } const result = await runner.query(updateBrandSql, { articleId, brandId: resolvedBrandId, }); if (!result.rowsAffected) { throw new Error('Article not found'); } // null = no brand; treat as distinct sentinel so first assignment is logged if (oldBrandName !== newBrandName) { await runner.query(insertHistorySql, { articleId, companyuserId, text: `Marke ge\u00e4ndert von "${oldBrandName ?? ''}" auf "${newBrandName ?? ''}"`, }); } const article = await load(articleId, languageId, runner); if (!article) { throw new Error('Article not found'); } return article; }; }