101 lines
3.5 KiB
JavaScript
101 lines
3.5 KiB
JavaScript
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<object>} 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;
|
|
};
|
|
}
|