-
+
-
+
diff --git a/client/src/components/parts-receive-modal/parts-receive-modal.container.jsx b/client/src/components/parts-receive-modal/parts-receive-modal.container.jsx
index 1de8feb68..a2d7ae870 100644
--- a/client/src/components/parts-receive-modal/parts-receive-modal.container.jsx
+++ b/client/src/components/parts-receive-modal/parts-receive-modal.container.jsx
@@ -37,39 +37,85 @@ export function PartsReceiveModalContainer({ partsReceiveModal, toggleModalVisib
const handleFinish = async (values) => {
logImEXEvent("parts_order_receive");
setLoading(true);
- const result = await Promise.all(
- values.partsorderlines.map((li) => {
- return receivePartsLine({
- variables: {
- lineId: li.joblineid,
- line: {
- location: li.location,
- status: bodyshop.md_order_statuses.default_received || "Received*"
- },
- orderLineId: li.id,
- orderLine: {
- status: bodyshop.md_order_statuses.default_received || "Received*"
- }
- }
- });
- })
- );
- result.forEach((jobLinesResult) => {
- if (jobLinesResult.errors) {
+ try {
+ const submittedLines = values.partsorderlines ?? [];
+
+ // Preserve ids from modal context, merge editable fields from form submission (e.g. location)
+ const mergedLines = (partsorderlines ?? []).map((ctxLine, idx) => ({
+ ...ctxLine,
+ ...submittedLines[idx]
+ }));
+
+ // Optional: hard guard to catch the exact failure early with a better message
+ const missing = mergedLines
+ .map((l, idx) => ({
+ idx,
+ orderLineId: l?.id,
+ jobLineId: l?.joblineid // adjust if your ctx uses job_line_id instead
+ }))
+ .filter((x) => !x.orderLineId || !x.jobLineId);
+
+ if (missing.length) {
notification.error({
title: t("parts_orders.errors.creating"),
- description: JSON.stringify(jobLinesResult.errors)
+ description: `Missing required ids for lines: ${missing
+ .map((m) => `#${m.idx + 1} (orderLineId=${m.orderLineId}, jobLineId=${m.jobLineId})`)
+ .join(", ")}`
});
+ return;
}
- });
- notification.success({
- title: t("parts_orders.successes.received")
- });
- setLoading(false);
- if (refetch) refetch();
- toggleModalVisible();
+ const results = await Promise.allSettled(
+ mergedLines.map((li) =>
+ receivePartsLine({
+ variables: {
+ lineId: li.joblineid,
+ line: {
+ location: li.location,
+ status: bodyshop.md_order_statuses.default_received || "Received*"
+ },
+ orderLineId: li.id,
+ orderLine: {
+ status: bodyshop.md_order_statuses.default_received || "Received*"
+ }
+ },
+ // Ensures GraphQL errors come back on the result when possible (instead of only throwing)
+ errorPolicy: "all"
+ })
+ )
+ );
+
+ const errors = [];
+ results.forEach((r, idx) => {
+ if (r.status === "rejected") {
+ errors.push({ idx, message: r.reason?.message ?? String(r.reason) });
+ return;
+ }
+ if (r.value?.errors?.length) {
+ errors.push({
+ idx,
+ message: r.value.errors.map((e) => e.message).join(" | ")
+ });
+ }
+ });
+
+ if (errors.length) {
+ errors.forEach((e) =>
+ notification.error({
+ title: t("parts_orders.errors.creating"),
+ description: `Line ${e.idx + 1}: ${e.message}`
+ })
+ );
+ return; // keep modal open so user can retry
+ }
+
+ notification.success({ title: t("parts_orders.successes.received") });
+ if (refetch) refetch();
+ toggleModalVisible();
+ } finally {
+ setLoading(false);
+ }
};
const initialValues = {
diff --git a/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.component.jsx b/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.component.jsx
index c8f44a81b..a947f7d1c 100644
--- a/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.component.jsx
+++ b/client/src/components/shop-info/shop-info.responsibilitycenters.taxes.component.jsx
@@ -1500,7 +1500,7 @@ export function ShopInfoResponsibilityCenters({ bodyshop, form }) {
diff --git a/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx b/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx
index 3897d3674..a8d5a3384 100644
--- a/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx
+++ b/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx
@@ -184,13 +184,7 @@ export function TimeTicketModalComponent({
}}
-
+