This commit is contained in:
seb
2026-10-01 07:12:39 +02:00
parent 9c770d765e
commit 62c3e69ed4
11 changed files with 273 additions and 13 deletions

View File

@@ -6,6 +6,8 @@ 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';
@@ -17,6 +19,7 @@ export default function setBrandIdBySku(provider) {
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.
@@ -34,7 +37,7 @@ export default function setBrandIdBySku(provider) {
*/
return async (googleAuthId, sku, brandId, tx) => {
const runner = makeRunner(provider, tx);
const { articleId, languageId, companyId } = await resolve(
const { articleId, languageId, companyId, companyuserId } = await resolve(
googleAuthId,
sku,
runner,
@@ -44,7 +47,15 @@ export default function setBrandIdBySku(provider) {
throw new Error('Invalid brandId');
}
// Read old brand for history
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 ?? '';
let resolvedBrandId = null;
let newBrandName = '';
if (brandId !== null) {
const brand = await runner.query(getBrandSql, {
brandId,
@@ -54,6 +65,7 @@ export default function setBrandIdBySku(provider) {
throw new Error('Brand not found');
}
resolvedBrandId = brandId;
newBrandName = brand.rows[0].name ?? '';
}
const result = await runner.query(updateBrandSql, {
@@ -65,6 +77,15 @@ export default function setBrandIdBySku(provider) {
throw new Error('Article not found');
}
// Write history if brand changed
if (oldBrandName !== newBrandName) {
await runner.query(insertHistorySql, {
articleId,
companyuserId,
text: `Marke geändert von "${oldBrandName}" auf "${newBrandName}"`,
});
}
const article = await load(articleId, languageId, runner);
if (!article) {
throw new Error('Article not found');

View File

@@ -6,6 +6,8 @@ import {
ADD_CATEGORY as SQLITE_ADD_CATEGORY,
DELETE_CATEGORIES_BY_ARTICLE as SQLITE_DELETE_CATEGORIES,
} 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 resolveCategoryAccess from '../category/resolveCategoryAccess.js';
import queryBySku from './queryBySku.js';
import resolveArticleBySku from './resolveArticleBySku.js';
@@ -19,6 +21,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 insertHistorySql = isSqlite ? SQLITE_INSERT_HISTORY : MSSQL_INSERT_HISTORY;
/**
* Replaces the category membership of an article by its SKU.
@@ -52,12 +55,19 @@ export default function setCategoryIdsBySku(provider) {
}
const runSet = async (runner) => {
const { articleId, languageId, companyId } = await resolve(
const { articleId, languageId, companyId, companyuserId } = await resolve(
googleAuthId,
sku,
runner,
);
// Read old category IDs for history
const oldCatRes = await runner.query(
'SELECT category_id FROM categoryarticle WHERE article_id = @articleId ORDER BY category_id',
{ articleId },
);
const oldCategoryIds = oldCatRes.rows.map((r) => r.category_id);
for (const categoryId of normalized) {
// Ensures the category belongs to the same company as the article.
const access = await categoryAccess(googleAuthId, categoryId, runner);
@@ -75,6 +85,17 @@ export default function setCategoryIdsBySku(provider) {
});
}
// Write history if categories changed
const oldStr = oldCategoryIds.join(', ');
const newStr = [...normalized].sort((a, b) => a - b).join(', ');
if (oldStr !== newStr) {
await runner.query(insertHistorySql, {
articleId,
companyuserId,
text: `Kategorien geändert von [${oldStr}] auf [${newStr}]`,
});
}
const article = await load(articleId, languageId, runner);
if (!article) {
throw new Error('Article not found');

View File

@@ -6,6 +6,8 @@ import {
ADD_EAN as SQLITE_ADD_EAN,
DELETE_EANS_BY_ARTICLE as SQLITE_DELETE_EANS,
} 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 { isUniqueConstraintError } from '../../providers/provider.js';
import queryBySku from './queryBySku.js';
import resolveArticleBySku from './resolveArticleBySku.js';
@@ -18,6 +20,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 insertHistorySql = isSqlite ? SQLITE_INSERT_HISTORY : MSSQL_INSERT_HISTORY;
/**
* Replaces the EAN list of an article by its SKU.
@@ -52,7 +55,14 @@ export default function setEansBySku(provider) {
}
const runSet = async (runner) => {
const { articleId, languageId } = await resolve(googleAuthId, sku, runner);
const { articleId, languageId, companyuserId } = await resolve(googleAuthId, sku, runner);
// Read old EANs for history
const oldEanRes = await runner.query(
'SELECT ean FROM articleean WHERE article_id = @articleId ORDER BY ean',
{ articleId },
);
const oldEans = oldEanRes.rows.map((r) => r.ean);
await runner.query(deleteEansSql, { articleId });
@@ -67,6 +77,17 @@ export default function setEansBySku(provider) {
throw err;
}
// Write history if EANs changed
const oldStr = oldEans.join(', ');
const newStr = [...normalized].sort().join(', ');
if (oldStr !== newStr) {
await runner.query(insertHistorySql, {
articleId,
companyuserId,
text: `EANs geändert von "${oldStr}" auf "${newStr}"`,
});
}
const article = await load(articleId, languageId, runner);
if (!article) {
throw new Error('Article not found');

View File

@@ -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 { INSERT as MSSQL_INSERT_HISTORY } from '../../providers/mssql/queries/articlehistory.js';
import { INSERT as SQLITE_INSERT_HISTORY } from '../../providers/sqlite3/queries/articlehistory.js';
import taxEnsure from '../tax/ensure.js';
import queryBySku from './queryBySku.js';
import resolveArticleBySku from './resolveArticleBySku.js';
@@ -55,6 +57,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 insertHistorySql = isSqlite ? SQLITE_INSERT_HISTORY : MSSQL_INSERT_HISTORY;
/**
* Replaces the price list of an article by its SKU.
@@ -74,7 +77,7 @@ export default function setPricesBySku(provider) {
const normalized = normalizePrices(prices);
const runSet = async (runner) => {
const { articleId, languageId, posCustomerGroupId } = await resolve(
const { articleId, languageId, posCustomerGroupId, companyuserId } = await resolve(
googleAuthId,
sku,
runner,
@@ -88,6 +91,17 @@ export default function setPricesBySku(provider) {
throw new Error('A father article cannot have prices');
}
// Read old prices for history
const oldPriceRes = await runner.query(
`SELECT p.net, t.rate AS taxRate, p.minmultiplier
FROM price p
LEFT JOIN tax t ON t.id = p.tax_id
WHERE p.article_id = @articleId AND p.customergroup_id = @posCustomerGroupId
ORDER BY p.minmultiplier ASC`,
{ articleId, posCustomerGroupId },
);
const oldPrices = oldPriceRes.rows;
const taxIds = new Map();
for (const entry of normalized) {
if (!taxIds.has(entry.tax)) {
@@ -110,6 +124,18 @@ export default function setPricesBySku(provider) {
});
}
// Write history if prices changed
const fmtPrice = (p) => `${p.net}@${p.taxRate ?? 0}%`;
const oldStr = oldPrices.map(fmtPrice).join(', ');
const newStr = normalized.map((e) => `${e.price}@${e.tax}%`).join(', ');
if (oldStr !== newStr) {
await runner.query(insertHistorySql, {
articleId,
companyuserId,
text: `Preise geändert von [${oldStr}] auf [${newStr}]`,
});
}
const article = await load(articleId, languageId, runner);
if (!article) {
throw new Error('Article not found');

View File

@@ -1,5 +1,7 @@
import { UPDATE_TRACK_STOCK as MSSQL_UPDATE_TRACK_STOCK } from '../../providers/mssql/queries/article.js';
import { UPDATE_TRACK_STOCK as SQLITE_UPDATE_TRACK_STOCK } 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';
@@ -11,6 +13,7 @@ export default function setTrackStockBySku(provider) {
provider?.dialect === 'sqlite3'
? SQLITE_UPDATE_TRACK_STOCK
: MSSQL_UPDATE_TRACK_STOCK;
const insertHistorySql = provider?.dialect === 'sqlite3' ? SQLITE_INSERT_HISTORY : MSSQL_INSERT_HISTORY;
/**
* Sets the track_stock flag of an article by its SKU.
@@ -32,7 +35,15 @@ export default function setTrackStockBySku(provider) {
}
const runner = makeRunner(provider, tx);
const { articleId, languageId } = await resolve(googleAuthId, sku, runner);
const { articleId, languageId, companyuserId } = await resolve(googleAuthId, sku, runner);
// Read old track_stock for history
const oldRes = await runner.query(
'SELECT track_stock FROM article WHERE id = @articleId',
{ articleId },
);
const oldTrack = Boolean(oldRes.rows[0]?.track_stock ?? 1);
const newTrack = Boolean(trackStock);
const result = await runner.query(sql, {
articleId,
@@ -43,6 +54,15 @@ export default function setTrackStockBySku(provider) {
throw new Error('Article not found');
}
// Write history if track_stock changed
if (oldTrack !== newTrack) {
await runner.query(insertHistorySql, {
articleId,
companyuserId,
text: `Bestandsführung geändert von "${oldTrack ? 'Ja' : 'Nein'}" auf "${newTrack ? 'Ja' : 'Nein'}"`,
});
}
const article = await load(articleId, languageId, runner);
if (!article) {
throw new Error('Article not found');

View File

@@ -1,5 +1,7 @@
import { UPDATE_WEIGHT as MSSQL_UPDATE_WEIGHT } from '../../providers/mssql/queries/article.js';
import { UPDATE_WEIGHT as SQLITE_UPDATE_WEIGHT } 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';
@@ -8,6 +10,7 @@ export default function setWeightBySku(provider) {
const resolve = resolveArticleBySku(provider);
const load = queryBySku(provider);
const sql = provider?.dialect === 'sqlite3' ? SQLITE_UPDATE_WEIGHT : MSSQL_UPDATE_WEIGHT;
const insertHistorySql = provider?.dialect === 'sqlite3' ? SQLITE_INSERT_HISTORY : MSSQL_INSERT_HISTORY;
/**
* Sets the weight of an article by its SKU.
@@ -29,7 +32,14 @@ export default function setWeightBySku(provider) {
}
const runner = makeRunner(provider, tx);
const { articleId, languageId } = await resolve(googleAuthId, sku, runner);
const { articleId, languageId, companyuserId } = await resolve(googleAuthId, sku, runner);
// Read old weight for history
const oldRes = await runner.query(
'SELECT weight FROM article WHERE id = @articleId',
{ articleId },
);
const oldWeight = oldRes.rows[0]?.weight ?? 0;
const result = await runner.query(sql, {
articleId,
@@ -40,6 +50,15 @@ export default function setWeightBySku(provider) {
throw new Error('Article not found');
}
// Write history if weight changed
if (Number(oldWeight) !== weight) {
await runner.query(insertHistorySql, {
articleId,
companyuserId,
text: `Gewicht geändert von "${oldWeight}" auf "${weight}"`,
});
}
const article = await load(articleId, languageId, runner);
if (!article) {
throw new Error('Article not found');