94 lines
3.7 KiB
JavaScript
94 lines
3.7 KiB
JavaScript
import * as mssqlArticle from '../../providers/mssql/queries/article.js';
|
|
import * as sqliteArticle from '../../providers/sqlite3/queries/article.js';
|
|
import { GET_CHILD_COUNT as MSSQL_GET_CHILD_COUNT } from '../../providers/mssql/queries/articleDelete.js';
|
|
import { GET_CHILD_COUNT as SQLITE_GET_CHILD_COUNT } from '../../providers/sqlite3/queries/articleDelete.js';
|
|
import * as mssqlAttr from '../../providers/mssql/queries/attributename.js';
|
|
import * as sqliteAttr from '../../providers/sqlite3/queries/attributename.js';
|
|
import resolveArticleBySku from './resolveArticleBySku.js';
|
|
import getBySku from './getBySku.js';
|
|
import makeRunner from '../runner.js';
|
|
|
|
export default function toggleFather(provider) {
|
|
const resolve = resolveArticleBySku(provider);
|
|
const load = getBySku(provider);
|
|
const isSqlite = provider?.dialect === 'sqlite3';
|
|
|
|
const queries = isSqlite ? sqliteArticle : mssqlArticle;
|
|
const getChildCountSql = isSqlite ? SQLITE_GET_CHILD_COUNT : MSSQL_GET_CHILD_COUNT;
|
|
const attrQueries = isSqlite ? sqliteAttr : mssqlAttr;
|
|
|
|
/**
|
|
* Toggles an article into or out of father mode.
|
|
*
|
|
* @param {number} googleAuthId - The id of the Google auth user.
|
|
* @param {string} sku - The article SKU.
|
|
* @param {object} options
|
|
* @param {boolean} options.isFather - Whether the article should be a father article.
|
|
* @param {number} [options.attributeNameId] - The attribute name id required when enabling father mode.
|
|
* @param {number} [options.fatherAttributeNameId] - Alias for attributeNameId.
|
|
* @param {object} [tx] - Optional transaction.
|
|
* @returns {Promise<object>} The updated article detail.
|
|
*/
|
|
return async (googleAuthId, sku, { isFather, attributeNameId, fatherAttributeNameId } = {}, tx) => {
|
|
const run = async (runner) => {
|
|
const { articleId, companyId } = await resolve(googleAuthId, sku, runner);
|
|
|
|
const targetIsFather = Boolean(isFather);
|
|
const targetAttrId = attributeNameId ?? fatherAttributeNameId;
|
|
|
|
if (targetIsFather) {
|
|
if (!targetAttrId || Number(targetAttrId) <= 0) {
|
|
throw new Error('attributeNameId is required to become a father article');
|
|
}
|
|
|
|
// Verify article is not a child of another article
|
|
const currentRes = await runner.query(
|
|
'SELECT fatherarticle_id FROM article WHERE id = @articleId',
|
|
{ articleId },
|
|
);
|
|
if (currentRes.rows[0]?.fatherarticle_id != null) {
|
|
throw new Error('A child article cannot become a father');
|
|
}
|
|
|
|
// Verify attribute exists and belongs to company
|
|
const attrRes = await runner.query(attrQueries.GET_BY_COMPANY_AND_ID, {
|
|
id: Number(targetAttrId),
|
|
companyId,
|
|
});
|
|
if (!attrRes.rows[0]) {
|
|
throw new Error('Attribute name not found');
|
|
}
|
|
|
|
await runner.query(queries.TOGGLE_FATHER, {
|
|
articleId,
|
|
isFather: 1,
|
|
fatherAttributeNameId: Number(targetAttrId),
|
|
});
|
|
} else {
|
|
// Disabling father: verify zero children
|
|
const childCountRes = await runner.query(getChildCountSql, { articleId });
|
|
const childCount = childCountRes.rows[0]?.count ?? 0;
|
|
if (childCount > 0) {
|
|
throw new Error('Cannot disable father mode on an article that still has children');
|
|
}
|
|
|
|
await runner.query(queries.TOGGLE_FATHER, {
|
|
articleId,
|
|
isFather: 0,
|
|
fatherAttributeNameId: null,
|
|
});
|
|
}
|
|
|
|
return load(googleAuthId, sku, runner);
|
|
};
|
|
|
|
if (tx) {
|
|
return run(makeRunner(provider, tx));
|
|
}
|
|
if (typeof provider?.transaction === 'function') {
|
|
return provider.transaction(run);
|
|
}
|
|
return run(makeRunner(provider));
|
|
};
|
|
}
|