Skip to content

Commit 0729881

Browse files
authored
feat: add support for add delivery action (#373)
1 parent f75bfc0 commit 0729881

File tree

3 files changed

+279
-10
lines changed

3 files changed

+279
-10
lines changed

.changeset/modern-hands-ask.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@labdigital/commercetools-mock": patch
3+
---
4+
5+
Added support for addDelivery order update action

src/repositories/order/actions.ts

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import type {
22
CustomLineItemReturnItem,
3+
Delivery,
34
GeneralError,
45
LineItemReturnItem,
56
Order,
7+
OrderAddDeliveryAction,
68
OrderAddPaymentAction,
79
OrderAddReturnInfoAction,
810
OrderChangeOrderStateAction,
@@ -25,6 +27,7 @@ import type {
2527
OrderTransitionStateAction,
2628
OrderUpdateAction,
2729
OrderUpdateSyncInfoAction,
30+
Parcel,
2831
ReturnInfo,
2932
State,
3033
Store,
@@ -35,7 +38,7 @@ import { getBaseResourceProperties } from "#src/helpers.ts";
3538
import type { Writable } from "#src/types.ts";
3639
import type { RepositoryContext, UpdateHandlerInterface } from "../abstract.ts";
3740
import { AbstractUpdateHandler } from "../abstract.ts";
38-
import { createAddress } from "../helpers.ts";
41+
import { createAddress, createCustomFields } from "../helpers.ts";
3942

4043
export class OrderUpdateHandler
4144
extends AbstractUpdateHandler
@@ -193,6 +196,50 @@ export class OrderUpdateHandler
193196
}
194197
}
195198

199+
addDelivery(
200+
context: RepositoryContext,
201+
resource: Writable<Order>,
202+
{ action, items, ...deliveryDraft }: OrderAddDeliveryAction,
203+
) {
204+
if (!resource.shippingInfo) {
205+
throw new Error("Resource has no shipping info");
206+
}
207+
208+
if (!items) {
209+
throw new Error("Delivery items are required");
210+
}
211+
212+
if (!resource.shippingInfo.deliveries) {
213+
resource.shippingInfo.deliveries = [];
214+
}
215+
216+
const parcels: Parcel[] =
217+
deliveryDraft.parcels?.map((p) => ({
218+
...getBaseResourceProperties(),
219+
...p,
220+
custom: createCustomFields(p.custom, context.projectKey, this._storage),
221+
})) ?? [];
222+
223+
const delivery: Delivery = {
224+
...getBaseResourceProperties(),
225+
...deliveryDraft,
226+
parcels,
227+
items,
228+
address: createAddress(
229+
deliveryDraft.address,
230+
context.projectKey,
231+
this._storage,
232+
),
233+
custom: createCustomFields(
234+
deliveryDraft.custom,
235+
context.projectKey,
236+
this._storage,
237+
),
238+
};
239+
240+
resource.shippingInfo.deliveries.push(delivery);
241+
}
242+
196243
setDeliveryCustomField(
197244
context: RepositoryContext,
198245
resource: Writable<Order>,
@@ -212,13 +259,7 @@ export class OrderUpdateHandler
212259
setLineItemCustomField(
213260
context: RepositoryContext,
214261
resource: Order,
215-
{
216-
lineItemId,
217-
lineItemKey,
218-
name,
219-
value,
220-
action,
221-
}: OrderSetLineItemCustomFieldAction,
262+
{ lineItemId, lineItemKey, name, value }: OrderSetLineItemCustomFieldAction,
222263
) {
223264
const lineItem = resource.lineItems.find(
224265
(x) =>

src/services/order.test.ts

Lines changed: 225 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import assert from "node:assert";
2-
import type { Order, Payment, State } from "@commercetools/platform-sdk";
2+
import type {
3+
DeliveryDraft,
4+
Order,
5+
Payment,
6+
State,
7+
} from "@commercetools/platform-sdk";
38
import supertest from "supertest";
4-
import { afterEach, beforeEach, describe, expect, test } from "vitest";
9+
import { afterEach, beforeEach, describe, expect, it, test } from "vitest";
510
import { generateRandomString } from "#src/helpers.ts";
611
import { CommercetoolsMock, getBaseResourceProperties } from "../index.ts";
712

@@ -1024,6 +1029,224 @@ describe("Order Update Actions", () => {
10241029
},
10251030
]);
10261031
});
1032+
1033+
describe("addDelivery", () => {
1034+
const order: Order = {
1035+
...getBaseResourceProperties(),
1036+
customLineItems: [],
1037+
lineItems: [
1038+
{
1039+
id: "d70b14c8-72cf-4cab-82ba-6339cebe1e79",
1040+
productId: "06028a97-d622-47ac-a194-a3d90baa2b3c",
1041+
productSlug: { "nl-NL": "test-product" },
1042+
productType: { typeId: "product-type", id: "some-uuid" },
1043+
name: { "nl-NL": "test product" },
1044+
custom: {
1045+
type: {
1046+
typeId: "type",
1047+
id: "a493b7bb-d415-450c-b421-e128a8b26569",
1048+
},
1049+
fields: {},
1050+
},
1051+
variant: {
1052+
id: 1,
1053+
sku: "1337",
1054+
attributes: [{ name: "test", value: "test" }],
1055+
prices: [],
1056+
assets: [],
1057+
images: [],
1058+
},
1059+
price: {
1060+
id: "2f59a6c9-6a86-48d3-87f9-fabb3b12fd93",
1061+
value: {
1062+
type: "centPrecision",
1063+
centAmount: 14900,
1064+
currencyCode: "EUR",
1065+
fractionDigits: 2,
1066+
},
1067+
},
1068+
totalPrice: {
1069+
type: "centPrecision",
1070+
currencyCode: "EUR",
1071+
fractionDigits: 2,
1072+
centAmount: 14900,
1073+
},
1074+
taxedPricePortions: [],
1075+
perMethodTaxRate: [],
1076+
quantity: 1,
1077+
discountedPricePerQuantity: [],
1078+
lineItemMode: "Standard",
1079+
priceMode: "Platform",
1080+
state: [],
1081+
},
1082+
],
1083+
orderNumber: "7777",
1084+
orderState: "Open",
1085+
origin: "Customer",
1086+
paymentInfo: {
1087+
payments: [
1088+
{
1089+
typeId: "payment",
1090+
id: generateRandomString(10),
1091+
},
1092+
],
1093+
},
1094+
refusedGifts: [],
1095+
shippingInfo: {
1096+
shippingMethodName: "Home delivery (package)",
1097+
price: {
1098+
type: "centPrecision",
1099+
currencyCode: "EUR",
1100+
centAmount: 999,
1101+
fractionDigits: 2,
1102+
},
1103+
shippingRate: {
1104+
price: {
1105+
type: "centPrecision",
1106+
currencyCode: "EUR",
1107+
centAmount: 999,
1108+
fractionDigits: 2,
1109+
},
1110+
tiers: [
1111+
{
1112+
type: "CartScore",
1113+
score: 24,
1114+
price: {
1115+
type: "centPrecision",
1116+
currencyCode: "EUR",
1117+
centAmount: 1998,
1118+
fractionDigits: 2,
1119+
},
1120+
},
1121+
{
1122+
type: "CartScore",
1123+
score: 47,
1124+
price: {
1125+
type: "centPrecision",
1126+
currencyCode: "EUR",
1127+
centAmount: 2997,
1128+
fractionDigits: 2,
1129+
},
1130+
},
1131+
{
1132+
type: "CartScore",
1133+
score: 70,
1134+
price: {
1135+
type: "centPrecision",
1136+
currencyCode: "EUR",
1137+
centAmount: 3996,
1138+
fractionDigits: 2,
1139+
},
1140+
},
1141+
{
1142+
type: "CartScore",
1143+
score: 93,
1144+
price: {
1145+
type: "centPrecision",
1146+
currencyCode: "EUR",
1147+
centAmount: 4995,
1148+
fractionDigits: 2,
1149+
},
1150+
},
1151+
],
1152+
},
1153+
deliveries: [
1154+
{
1155+
id: "6a458cad-dd46-4f5f-8b73-debOede6a17d",
1156+
key: "CT-Z243002",
1157+
createdAt: "2024-07-29T13:37:48.047Z",
1158+
items: [
1159+
{
1160+
id: "d70b14c8-72cf-4cab-82ba-6339cebe1e79",
1161+
quantity: 1,
1162+
},
1163+
],
1164+
parcels: [
1165+
{
1166+
id: "7a458cad-dd46-4f5f-8b73-debOede6a17d",
1167+
createdAt: "2024-07-29T13:37:48.047Z",
1168+
items: [
1169+
{
1170+
id: "d70b14c8-72cf-4cab-82ba-6339cebe1e79",
1171+
quantity: 1,
1172+
},
1173+
],
1174+
custom: {
1175+
type: {
1176+
typeId: "type",
1177+
id: "c493b7bb-d415-450c-b421-e128a8b26569",
1178+
},
1179+
fields: {
1180+
status: "created",
1181+
},
1182+
},
1183+
},
1184+
],
1185+
},
1186+
],
1187+
shippingMethodState: "MatchesCart",
1188+
},
1189+
shipping: [],
1190+
shippingMode: "Single",
1191+
syncInfo: [],
1192+
totalPrice: {
1193+
type: "centPrecision",
1194+
fractionDigits: 2,
1195+
centAmount: 2000,
1196+
currencyCode: "EUR",
1197+
},
1198+
};
1199+
if (!order.shippingInfo) {
1200+
throw new Error("Order shippingInfo is required");
1201+
}
1202+
const { deliveries: _, ...shippingInfoWithoutDeliveries } =
1203+
order.shippingInfo;
1204+
const orderWithoutDeliveries = {
1205+
...order,
1206+
...getBaseResourceProperties(),
1207+
orderNumber: "7778",
1208+
shippingInfo: shippingInfoWithoutDeliveries,
1209+
};
1210+
1211+
ctMock.project("dummy").add("order", order);
1212+
ctMock.project("dummy").add("order", orderWithoutDeliveries);
1213+
1214+
const deliveryDraft: DeliveryDraft = {
1215+
key: `${order.orderNumber}-2`,
1216+
items: [
1217+
{
1218+
id: order.lineItems[0].id,
1219+
quantity: order.lineItems[0].quantity,
1220+
},
1221+
],
1222+
};
1223+
1224+
it.each([
1225+
[order, 1],
1226+
[orderWithoutDeliveries, 0],
1227+
])("should add to deliveries", async (order, index) => {
1228+
const response = await supertest(ctMock.app).get(
1229+
`/dummy/orders/order-number=${order.orderNumber}`,
1230+
);
1231+
const _updateResponse = await supertest(ctMock.app)
1232+
.post(`/dummy/orders/${response.body.id}`)
1233+
.send({
1234+
version: 0,
1235+
actions: [
1236+
{
1237+
action: "addDelivery",
1238+
...deliveryDraft,
1239+
},
1240+
],
1241+
});
1242+
1243+
expect(_updateResponse.status).toBe(200);
1244+
expect(_updateResponse.body.version).toBe(1);
1245+
expect(_updateResponse.body.shippingInfo.deliveries[index].key).toBe(
1246+
deliveryDraft.key,
1247+
);
1248+
});
1249+
});
10271250
});
10281251

10291252
describe("Order Import", () => {

0 commit comments

Comments
 (0)