fix(medusa,medusa-fulfillment-webshipper): Item to Webshipper line mapping (#3879)
* fix(medusa): Add missing variant relation on items * fix: Webshipper fulfillment service * Create kind-singers-travel.md * Only add props if present * add tests
This commit is contained in:
committed by
GitHub
parent
2be144ff05
commit
7e213f2106
6
.changeset/kind-singers-travel.md
Normal file
6
.changeset/kind-singers-travel.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"medusa-fulfillment-webshipper": patch
|
||||
"@medusajs/medusa": patch
|
||||
---
|
||||
|
||||
fix(medusa,medusa-fulfillment-webshipper): Add missing variant + product relation on items
|
||||
@@ -11,6 +11,19 @@ describe("WebshipperFulfillmentService", () => {
|
||||
createShipment: jest.fn(),
|
||||
}
|
||||
|
||||
const totalsService = {
|
||||
getLineItemTotals: jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
unit_price: 1000,
|
||||
tax_lines: [
|
||||
{
|
||||
rate: 20,
|
||||
},
|
||||
],
|
||||
}
|
||||
}),
|
||||
}
|
||||
|
||||
describe("handleWebhook", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
@@ -208,4 +221,107 @@ describe("WebshipperFulfillmentService", () => {
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("buildWebshipperItem", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
const medusaItem = {
|
||||
id: "item_id",
|
||||
title: "item_title",
|
||||
quantity: 1,
|
||||
}
|
||||
|
||||
const order = {
|
||||
currency_code: "dkk",
|
||||
}
|
||||
|
||||
it("builds a webshipper item", async () => {
|
||||
const webshipper = new WebshipperFulfillmentService(
|
||||
{
|
||||
totalsService,
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
let item
|
||||
try {
|
||||
item = await webshipper.buildWebshipperItem(medusaItem, 1, order)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
expect(item).toEqual({
|
||||
ext_ref: "item_id",
|
||||
description: "item_title",
|
||||
quantity: 1,
|
||||
unit_price: 10,
|
||||
vat_percent: 20,
|
||||
})
|
||||
})
|
||||
|
||||
it("builds a webshipper item with additional props from variant", async () => {
|
||||
const webshipper = new WebshipperFulfillmentService(
|
||||
{
|
||||
totalsService,
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
medusaItem.variant = {}
|
||||
medusaItem.variant.origin_country = "DK"
|
||||
medusaItem.variant.sku = "sku"
|
||||
medusaItem.variant.hs_code = "hs"
|
||||
|
||||
let item
|
||||
try {
|
||||
item = await webshipper.buildWebshipperItem(medusaItem, 1, order)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
expect(item).toEqual({
|
||||
ext_ref: "item_id",
|
||||
description: "item_title",
|
||||
quantity: 1,
|
||||
unit_price: 10,
|
||||
vat_percent: 20,
|
||||
country_of_origin: "DK",
|
||||
sku: "sku",
|
||||
tarif_number: "hs",
|
||||
})
|
||||
})
|
||||
|
||||
it("builds a webshipper item with additional props from product", async () => {
|
||||
const webshipper = new WebshipperFulfillmentService(
|
||||
{
|
||||
totalsService,
|
||||
},
|
||||
{}
|
||||
)
|
||||
|
||||
medusaItem.variant = {}
|
||||
medusaItem.variant.product = {}
|
||||
medusaItem.variant.product.origin_country = "DK"
|
||||
medusaItem.variant.product.hs_code = "test"
|
||||
|
||||
let item
|
||||
try {
|
||||
item = await webshipper.buildWebshipperItem(medusaItem, 1, order)
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
expect(item).toEqual({
|
||||
ext_ref: "item_id",
|
||||
description: "item_title",
|
||||
quantity: 1,
|
||||
unit_price: 10,
|
||||
vat_percent: 20,
|
||||
country_of_origin: "DK",
|
||||
tarif_number: "test",
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -173,32 +173,14 @@ class WebshipperFulfillmentService extends FulfillmentService {
|
||||
},
|
||||
customs_lines: await Promise.all(
|
||||
returnOrder.items.map(async ({ item, quantity }) => {
|
||||
const totals = await this.totalsService_.getLineItemTotals(
|
||||
const customLine = await this.buildWebshipperItem(
|
||||
item,
|
||||
fromOrder,
|
||||
{
|
||||
include_tax: true,
|
||||
use_tax_lines: true,
|
||||
}
|
||||
quantity,
|
||||
fromOrder
|
||||
)
|
||||
|
||||
return {
|
||||
ext_ref: item.id,
|
||||
sku: item.variant.sku,
|
||||
description: item.title,
|
||||
quantity: quantity,
|
||||
country_of_origin:
|
||||
item.variant.origin_country ||
|
||||
item.variant.product.origin_country,
|
||||
tarif_number:
|
||||
item.variant.hs_code || item.variant.product.hs_code,
|
||||
unit_price: humanizeAmount(
|
||||
totals.unit_price,
|
||||
fromOrder.currency_code
|
||||
),
|
||||
vat_percent: totals.tax_lines.reduce(
|
||||
(acc, next) => acc + next.rate,
|
||||
0
|
||||
),
|
||||
...customLine,
|
||||
currency: fromOrder.currency_code.toUpperCase(),
|
||||
}
|
||||
})
|
||||
@@ -350,34 +332,13 @@ class WebshipperFulfillmentService extends FulfillmentService {
|
||||
visible_ref,
|
||||
order_lines: await Promise.all(
|
||||
fulfillmentItems.map(async (item) => {
|
||||
const totals = await this.totalsService_.getLineItemTotals(
|
||||
const orderLine = await this.buildWebshipperItem(
|
||||
item,
|
||||
fromOrder,
|
||||
{
|
||||
include_tax: true,
|
||||
use_tax_lines: true,
|
||||
}
|
||||
item.quantity,
|
||||
fromOrder
|
||||
)
|
||||
|
||||
return {
|
||||
ext_ref: item.id,
|
||||
sku: item.variant.sku,
|
||||
description: item.title,
|
||||
quantity: item.quantity,
|
||||
country_of_origin:
|
||||
item.variant.origin_country ||
|
||||
item.variant.product.origin_country,
|
||||
tarif_number:
|
||||
item.variant.hs_code || item.variant.product.hs_code,
|
||||
unit_price: humanizeAmount(
|
||||
totals.unit_price,
|
||||
fromOrder.currency_code
|
||||
),
|
||||
vat_percent: totals.tax_lines.reduce(
|
||||
(acc, next) => acc + next.rate,
|
||||
0
|
||||
),
|
||||
}
|
||||
return orderLine
|
||||
})
|
||||
),
|
||||
delivery_address: {
|
||||
@@ -637,6 +598,41 @@ class WebshipperFulfillmentService extends FulfillmentService {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async buildWebshipperItem(item, quantity, order) {
|
||||
const totals = await this.totalsService_.getLineItemTotals(item, order, {
|
||||
include_tax: true,
|
||||
use_tax_lines: true,
|
||||
})
|
||||
|
||||
const webShipperItem = {
|
||||
ext_ref: item.id,
|
||||
description: item.title,
|
||||
quantity: quantity,
|
||||
unit_price: humanizeAmount(totals.unit_price, order.currency_code),
|
||||
vat_percent: totals.tax_lines.reduce((acc, next) => acc + next.rate, 0),
|
||||
}
|
||||
|
||||
const coo =
|
||||
item?.variant?.origin_country || item?.variant?.product?.origin_country
|
||||
const sku = item?.variant?.sku
|
||||
const tarifNumber =
|
||||
item?.variant?.hs_code || item?.variant?.product?.hs_code
|
||||
|
||||
if (coo) {
|
||||
webShipperItem.country_of_origin = coo
|
||||
}
|
||||
|
||||
if (sku) {
|
||||
webShipperItem.sku = sku
|
||||
}
|
||||
|
||||
if (tarifNumber) {
|
||||
webShipperItem.tarif_number = tarifNumber
|
||||
}
|
||||
|
||||
return webShipperItem
|
||||
}
|
||||
}
|
||||
|
||||
export default WebshipperFulfillmentService
|
||||
|
||||
@@ -9,13 +9,13 @@ import {
|
||||
} from "class-validator"
|
||||
import { defaultStoreSwapFields, defaultStoreSwapRelations } from "."
|
||||
|
||||
import { Type } from "class-transformer"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { EntityManager } from "typeorm"
|
||||
import IdempotencyKeyService from "../../../../services/idempotency-key"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import OrderService from "../../../../services/order"
|
||||
import ReturnService from "../../../../services/return"
|
||||
import SwapService from "../../../../services/swap"
|
||||
import { Type } from "class-transformer"
|
||||
import { validator } from "../../../../utils/validator"
|
||||
|
||||
/**
|
||||
@@ -145,6 +145,7 @@ export default async (req, res) => {
|
||||
"swaps",
|
||||
"swaps.additional_items",
|
||||
"swaps.additional_items.variant",
|
||||
"swaps.additional_items.variant.product",
|
||||
"swaps.additional_items.tax_lines",
|
||||
],
|
||||
})
|
||||
|
||||
@@ -527,6 +527,8 @@ export default class ClaimService extends TransactionBaseService {
|
||||
relations: [
|
||||
"additional_items",
|
||||
"additional_items.tax_lines",
|
||||
"additional_items.variant",
|
||||
"additional_items.variant.product",
|
||||
"shipping_methods",
|
||||
"shipping_methods.tax_lines",
|
||||
"shipping_address",
|
||||
|
||||
@@ -913,6 +913,8 @@ class SwapService extends TransactionBaseService {
|
||||
"shipping_address",
|
||||
"additional_items",
|
||||
"additional_items.tax_lines",
|
||||
"additional_items.variant",
|
||||
"additional_items.variant.product",
|
||||
"shipping_methods",
|
||||
"shipping_methods.tax_lines",
|
||||
"order",
|
||||
|
||||
Reference in New Issue
Block a user