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) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Mv83a29B4eFv5ixoj6PoE1
This commit is contained in:
@@ -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<ReceiptResult> {
|
||||
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)
|
||||
? `<p style="margin:16px 0 0;"><a href="${escM(params.orderUrl)}" style="display:inline-block;padding:10px 18px;background:#1a1a1a;color:#fff;text-decoration:none;border-radius:8px;font-size:14px;font-weight:600;">Apri l'ordine</a></p>`
|
||||
|
||||
@@ -356,6 +356,9 @@ export async function getShopInfo(admin: AdminApiContext): Promise<ShopInfo> {
|
||||
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<unknown> | 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;
|
||||
|
||||
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user