From ce36f1a6579373e4a9f21af3e39c641b01ed911b Mon Sep 17 00:00:00 2001 From: tommaso Date: Tue, 7 Jul 2026 16:54:43 +0200 Subject: [PATCH] Fix: reso gia' esistente -> stato 'exists' + messaggio corretto al merchant Se l'ordine ha gia' un reso (order.returns), createShopifyReturn ritorna 'exists' invece di fallire: la notifica dice 'esiste gia' un reso, gestiscilo dall'ordine' al posto del fuorviante 'reso non creato, fallo manualmente'. Audit shopify_return_exists. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01Mv83a29B4eFv5ixoj6PoE1 --- app/app/lib/mailer.server.ts | 10 ++++++---- app/app/lib/recesso.server.ts | 9 +++++++++ app/app/routes/proxy.tsx | 11 ++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/app/app/lib/mailer.server.ts b/app/app/lib/mailer.server.ts index bfa14e9..7623c90 100644 --- a/app/app/lib/mailer.server.ts +++ b/app/app/lib/mailer.server.ts @@ -118,7 +118,7 @@ export async function sendMerchantNotification(params: { customerEmail: string; orderUrl: string; transmittedAt: string; - returnStatus: "created" | "no_returnable" | "error"; + returnStatus: "created" | "no_returnable" | "exists" | "error"; }): Promise { const transport = buildTransport(); if (!transport) { @@ -128,9 +128,11 @@ export async function sendMerchantNotification(params: { const actionLine = params.returnStatus === "created" ? "E' stato creato un reso nell'ordine: gestiscilo dalla pagina dell'ordine." - : params.returnStatus === "no_returnable" - ? "L'ordine non risulta evaso: valuta annullamento o rimborso." - : "Reso non creato automaticamente: verifica manualmente l'ordine."; + : params.returnStatus === "exists" + ? "Esiste gia' un reso per questo ordine: gestiscilo dalla pagina dell'ordine." + : params.returnStatus === "no_returnable" + ? "L'ordine non risulta evaso: valuta annullamento o rimborso." + : "Reso non creato automaticamente: verifica manualmente l'ordine."; const orderBtn = /^https?:\/\//i.test(params.orderUrl) ? `

Apri l'ordine

` diff --git a/app/app/lib/recesso.server.ts b/app/app/lib/recesso.server.ts index cca9e56..0725b29 100644 --- a/app/app/lib/recesso.server.ts +++ b/app/app/lib/recesso.server.ts @@ -356,6 +356,9 @@ export async function getShopInfo(admin: AdminApiContext): Promise { const RETURNABLE_QUERY = `#graphql query recessoOrderFulfillments($orderId: ID!) { order(id: $orderId) { + returns(first: 1) { + edges { node { id } } + } fulfillments(first: 10) { fulfillmentLineItems(first: 50) { edges { @@ -380,6 +383,7 @@ const RETURN_CREATE_MUTATION = `#graphql interface ReturnableGraphQL { data?: { order?: { + returns?: { edges?: Array | null } | null; fulfillments?: Array<{ fulfillmentLineItems?: { edges?: Array<{ @@ -402,6 +406,7 @@ interface ReturnCreateGraphQL { export type ReturnCreation = | { status: "created"; returnId: string } | { status: "no_returnable" } + | { status: "exists" } // esiste gia' un reso per l'ordine | { status: "error"; error: string }; /** @@ -418,6 +423,10 @@ export async function createShopifyReturn( variables: { orderId: orderGid }, }); const qBody = (await qRes.json()) as ReturnableGraphQL; + // Se esiste gia' un reso per l'ordine, non crearne un altro (evita errore fuorviante). + if ((qBody.data?.order?.returns?.edges ?? []).length > 0) { + return { status: "exists" }; + } const returnLineItems: Array<{ fulfillmentLineItemId: string; quantity: number; diff --git a/app/app/routes/proxy.tsx b/app/app/routes/proxy.tsx index 1c6aae5..7cc8f19 100644 --- a/app/app/routes/proxy.tsx +++ b/app/app/routes/proxy.tsx @@ -426,7 +426,8 @@ export const action = async ({ request }: ActionFunctionArgs) => { // (best-effort; il recesso legale e' gia' registrato). Ordini annullati/ // rimborsati -> skip (G5: evita doppio reso/rimborso). Non evaso -> il // merchant gestisce annullo/rimborso. - let returnStatus: "created" | "no_returnable" | "error" = "error"; + let returnStatus: "created" | "no_returnable" | "exists" | "error" = + "error"; const orderClosed = !!match.cancelledAt || match.financialStatus === "REFUNDED" || @@ -464,6 +465,14 @@ export const action = async ({ request }: ActionFunctionArgs) => { detail: "ordine non evaso o nulla da rendere", }, }); + } else if (ret.status === "exists") { + await db.auditLog.create({ + data: { + shop, + event: "shopify_return_exists", + detail: match.orderName, + }, + }); } else { console.error("[recesso] returnCreate:", ret.error); await db.auditLog.create({