feat(medusa-fulfillment-webshipper): Create webshipper return order (#4846)
Adds option to create a webshipper return order if return_portal is defined through webshipper options. Return order allows additional features in webshipper, such as marking the return as "Arrived" or "Processed" which enables us to create a webhook and automatically mark return as received in medusa. Note: Return portal is a "required" relationship in webshipper when doing a return order POST request, hence it should be defined in options prior to using this feature. Co-authored-by: Oli Juhl <59018053+olivermrbl@users.noreply.github.com>
This commit is contained in:
6
.changeset/polite-zoos-hammer.md
Normal file
6
.changeset/polite-zoos-hammer.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@medusajs/medusa": patch
|
||||
"medusa-fulfillment-webshipper": patch
|
||||
---
|
||||
|
||||
feat(medusa-fulfillment-webshipper): Create webshipper return order
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user