diff --git a/.changeset/polite-zoos-hammer.md b/.changeset/polite-zoos-hammer.md new file mode 100644 index 0000000000..bf02e0ca6f --- /dev/null +++ b/.changeset/polite-zoos-hammer.md @@ -0,0 +1,6 @@ +--- +"@medusajs/medusa": patch +"medusa-fulfillment-webshipper": patch +--- + +feat(medusa-fulfillment-webshipper): Create webshipper return order diff --git a/packages/medusa-fulfillment-webshipper/src/services/webshipper-fulfillment.js b/packages/medusa-fulfillment-webshipper/src/services/webshipper-fulfillment.js index 0f13e15b6b..c4ba118f0a 100644 --- a/packages/medusa-fulfillment-webshipper/src/services/webshipper-fulfillment.js +++ b/packages/medusa-fulfillment-webshipper/src/services/webshipper-fulfillment.js @@ -97,6 +97,75 @@ class WebshipperFulfillmentService extends AbstractFulfillmentService { // Calculate prices } + /** + * Creates a return order in webshipper and links it to an existing shipment. + */ + async createReturnOrder(shipment, fromOrder) { + const fulfillmentData = fromOrder.fulfillments[0]?.data + + if (!shipment?.id || !fulfillmentData?.id) { + return + } + + const customsLines = shipment.attributes?.packages?.[0]?.customs_lines + + if (!customsLines?.length) { + return + } + + const returnOrderData = { + type: "returns", + attributes: { + status: "pending", + return_lines: customsLines.map(({ ext_ref, quantity }) => ({ + order_line_id: fulfillmentData.attributes?.order_lines?.find( + (order_line) => order_line.ext_ref === ext_ref + )?.id, + cause_id: this.options_.return_portal?.cause_id || "1", + quantity: quantity, + })), + }, + relationships: { + order: { + data: { + id: fulfillmentData.id, + type: "orders", + }, + }, + portal: { + data: { + id: this.options_.return_portal.id || "1", + type: "return_portals", + }, + }, + refund_method: { + data: { + id: this.options_.return_portal.refund_method_id || "1", + type: "return_refund_methods", + }, + }, + shipping_method: { + data: { + id: shipment.shipping_method?.data?.webshipper_id || "1", + type: "return_shipping_methods", + }, + }, + shipment: { + data: { + id: shipment.id, + type: "shipments", + }, + }, + }, + } + + this.client_.returns.create(returnOrderData) + } + + /** + * Creates a return shipment in webshipper using the given method data, and + * return lines. + */ async createReturn(returnOrder) { let orderId if (returnOrder.order_id) { @@ -109,7 +178,13 @@ class WebshipperFulfillmentService extends AbstractFulfillmentService { const fromOrder = await this.orderService_.retrieve(orderId, { select: ["total"], - relations: ["discounts", "discounts.rule", "shipping_address", "returns"], + relations: [ + "discounts", + "discounts.rule", + "shipping_address", + "returns", + "fulfillments", + ], }) const methodData = returnOrder.shipping_method.data @@ -204,6 +279,10 @@ class WebshipperFulfillmentService extends AbstractFulfillmentService { return this.client_.shipments .create(returnShipment) .then((result) => { + if (this.options_.return_portal?.id) { + this.createReturnOrder(result.data, fromOrder) + } + return result.data }) .catch((err) => { diff --git a/packages/medusa-fulfillment-webshipper/src/utils/webshipper.js b/packages/medusa-fulfillment-webshipper/src/utils/webshipper.js index e93b2d2204..6c8955c571 100644 --- a/packages/medusa-fulfillment-webshipper/src/utils/webshipper.js +++ b/packages/medusa-fulfillment-webshipper/src/utils/webshipper.js @@ -16,6 +16,7 @@ class Webshipper { this.shippingRates = this.buildShippingRateEndpoints_() this.orders = this.buildOrderEndpoints_() this.shipments = this.buildShipmentEndpoints_() + this.returns = this.buildReturnEndpoints_() } async request(data) { @@ -124,6 +125,21 @@ class Webshipper { }, } } + + buildReturnEndpoints_ = () => { + return { + create: async (data) => { + const path = `/v2/returns` + return this.client_({ + method: "POST", + url: path, + data: { + data, + }, + }).then(({ data }) => data) + }, + } + } } export default Webshipper