This commit is contained in:
seb
2026-09-29 18:26:42 +02:00
parent 30820ba8c7
commit 69bd0935cc
14 changed files with 710 additions and 20 deletions

View File

@@ -0,0 +1,105 @@
import * as mssqlArticle from '../../providers/mssql/queries/article.js';
import * as sqliteArticle 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 resolveArticleBySku from './resolveArticleBySku.js';
import articleDelete from './delete.js';
import makeRunner from '../runner.js';
export default function removeChild(provider) {
const resolve = resolveArticleBySku(provider);
const del = articleDelete(provider);
const isSqlite = provider?.dialect === 'sqlite3';
const queries = isSqlite ? sqliteArticle : mssqlArticle;
const insertHistorySql = isSqlite ? SQLITE_INSERT_HISTORY : MSSQL_INSERT_HISTORY;
/**
* Removes a child article from a father article, either by unlinking or deleting it.
*
* @param {number} googleAuthId - The id of the Google auth user.
* @param {string} fatherSku - The father article SKU.
* @param {string} childSku - The child article SKU.
* @param {object} [options]
* @param {boolean} [options.deleteArticle=false] - Whether to delete the child article entity entirely.
* @param {object} [tx] - Optional transaction.
* @returns {Promise<{success: boolean, fatherSku: string, childSku: string, deleted: boolean}>}
*/
return async (googleAuthId, fatherSku, childSku, options = {}, tx) => {
const run = async (runner) => {
const { articleId: fatherId, companyuserId } = await resolve(
googleAuthId,
fatherSku,
runner,
);
const { articleId: childId } = await resolve(googleAuthId, childSku, runner);
// Verify child relationship
const childRes = await runner.query(
'SELECT fatherarticle_id FROM article WHERE id = @childId',
{ childId },
);
const child = childRes.rows[0];
if (!child || child.fatherarticle_id !== fatherId) {
throw new Error('Child article does not belong to this father');
}
if (options.deleteArticle) {
await del(googleAuthId, childSku, runner);
return {
success: true,
fatherSku,
childSku,
deleted: true,
};
}
// Fetch father's attribute name id
const fatherRes = await runner.query(
'SELECT fatherattributename_id FROM article WHERE id = @fatherId',
{ fatherId },
);
const fatherAttributeNameId = fatherRes.rows[0]?.fatherattributename_id;
// Unlink child from father
await runner.query(queries.UNLINK_CHILD, {
articleId: childId,
fatherArticleId: fatherId,
});
// Remove the child's attribute value link for the father's attribute
if (fatherAttributeNameId) {
await runner.query(
`DELETE FROM articleattributevalue
WHERE article_id = @childId
AND attributevalue_id IN (
SELECT id FROM attributevalue WHERE attribute_id = @fatherAttributeNameId
)`,
{ childId, fatherAttributeNameId },
);
}
// Add history
await runner.query(insertHistorySql, {
articleId: childId,
companyuserId,
text: `Artikel "${childSku}" von Vaterartikel "${fatherSku}" getrennt`,
});
return {
success: true,
fatherSku,
childSku,
deleted: false,
};
};
if (tx) {
return run(makeRunner(provider, tx));
}
if (typeof provider?.transaction === 'function') {
return provider.transaction(run);
}
return run(makeRunner(provider));
};
}