This commit is contained in:
seb
2026-09-21 07:43:15 +02:00
parent 1b6e3ec7e2
commit 98080f0514
4 changed files with 123 additions and 1 deletions

View File

@@ -1,5 +1,5 @@
import { Automat } from 'react-automat';
import { supplier as supplierApi } from '../api';
import { article as articleApi, supplier as supplierApi } from '../api';
/**
* @typedef {Object} DeliveryLine
@@ -43,6 +43,7 @@ import { supplier as supplierApi } from '../api';
* @property {Object<string, SupplierArticle|null>} supplierArticlesByLineKey Matched article per line.
* @property {boolean} supplierArticlesLoading Whether any supplier article request is pending.
* @property {Object<string, boolean>} loadingLineKeys Pending lookup state per line.
* @property {Object<string, boolean>} busySupplierArticleLineKeys Lines with a pending unlink request.
* @property {string|null} supplierArticlesError Last supplier article error.
* @property {string|null} unmatchedSupplierName Parsed supplier name without a matching entity.
*/
@@ -130,6 +131,7 @@ export const initialDelivery = {
supplierArticlesByLineKey: {},
supplierArticlesLoading: false,
loadingLineKeys: {},
busySupplierArticleLineKeys: {},
supplierArticlesError: null,
unmatchedSupplierName: null,
};
@@ -482,6 +484,70 @@ export function createDeliveryEditorAutomat(options = {}) {
}
},
/**
* Removes the supplier-article assignment behind a matched line by
* `DELETE /api/article/{sku}/supplier/{id}`, then re-resolves the line.
*
* @param {string|number} internalSku Internal article SKU.
* @param {string|number} assignmentId Article-supplier assignment ID.
* @param {string|number} [lineKey] Editor line key showing the match.
* @returns {Promise<void>}
*/
async unlinkSupplierArticle(internalSku, assignmentId, lineKey) {
const entityId = automat.state.deliveryEntity ?? automat.state.partyId;
const sku = internalSku != null ? String(internalSku).trim() : '';
if (!sku || assignmentId == null) {
throw new Error('Artikelsku und Zuordnungs-ID sind erforderlich.');
}
if (lineKey != null) {
automat.setState({
busySupplierArticleLineKeys: {
...(automat.state.busySupplierArticleLineKeys || {}),
[lineKey]: true,
},
});
}
try {
await articleApi.deleteSupplier(sku, assignmentId);
const clearedMap = { ...(automat.state.supplierArticlesMap || {}) };
for (const [mapKey, item] of Object.entries(clearedMap)) {
if (item != null && String(item.id) === String(assignmentId)) {
delete clearedMap[mapKey];
}
}
const nextList = (automat.state.supplierArticles || []).filter(
(item) => item != null && String(item.id) !== String(assignmentId),
);
const byLineKey = { ...(automat.state.supplierArticlesByLineKey || {}) };
if (lineKey != null) byLineKey[lineKey] = null;
automat.setState({
supplierArticles: nextList,
supplierArticlesMap: clearedMap,
supplierArticlesByLineKey: byLineKey,
});
if (lineKey != null && entityId) {
const line = (automat.state.lines || []).find((l) => l.key === lineKey);
const rawSku = line?.sku != null ? String(line.sku).trim() : '';
if (rawSku) {
await automat.actions.fetchSupplierArticleForSku(rawSku, lineKey);
}
}
} finally {
if (lineKey != null) {
const nextBusy = { ...(automat.state.busySupplierArticleLineKeys || {}) };
delete nextBusy[lineKey];
automat.setState({ busySupplierArticleLineKeys: nextBusy });
}
}
},
/** @param {Object} attachment @returns {void} */
addAttachment(attachment) {
const id = attachment.id ?? `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
@@ -594,6 +660,7 @@ export const {
removeLine,
fetchSupplierArticles,
fetchSupplierArticleForSku,
unlinkSupplierArticle,
addAttachment,
setAttachments,
updateAttachment,
@@ -637,5 +704,8 @@ export const selectSupplierArticlesByLineKey = (state = deliveryEditorAutomat.st
export const selectSupplierArticlesLoading = (state = deliveryEditorAutomat.state) => state.supplierArticlesLoading;
/** @param {DeliveryEditorState} [state] @returns {Object<string, boolean>} */
export const selectLoadingLineKeys = (state = deliveryEditorAutomat.state) => state.loadingLineKeys;
/** @param {DeliveryEditorState} [state] @returns {Object<string, boolean>} */
export const selectBusySupplierArticleLineKeys = (state = deliveryEditorAutomat.state) =>
state.busySupplierArticleLineKeys;
export default deliveryEditorAutomat;