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:
Oliver Windall Juhl
2023-04-20 11:36:39 +02:00
committed by GitHub
parent 2be144ff05
commit 7e213f2106
6 changed files with 173 additions and 50 deletions

View File

@@ -0,0 +1,6 @@
---
"medusa-fulfillment-webshipper": patch
"@medusajs/medusa": patch
---
fix(medusa,medusa-fulfillment-webshipper): Add missing variant + product relation on items

View File

@@ -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",
})
})
})
})

View File

@@ -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

View File

@@ -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",
],
})

View File

@@ -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",

View File

@@ -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",