@dotdev/harmony-sdk 1.16.1 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,7 +33,7 @@ export class ApiHelper {
33
33
  });
34
34
  break;
35
35
  }
36
- console.debug(`Harmony response (success) - size [${+response?.headers?.['content-length']}]: `, { response });
36
+ console.debug(`Harmony response (success) - size [${+response?.headers?.['content-length']}]: `, { response: response?.data });
37
37
  const result = (await parseXml(response?.data)); // fix type
38
38
  return result["S:Envelope"]["S:Body"][0];
39
39
  }
@@ -1,5 +1,5 @@
1
1
  import { AxiosInstance } from "axios";
2
- import { Carrier, CarrierShipment, GetCarrierShipmentByTimeQueryParams } from "./types";
2
+ import { Carrier, CarrierShipment, DispatchData, GetCarrierShipmentByTimeQueryParams, GetDispatchDataByTimeQueryParams } from "./types";
3
3
  export declare class CarrierModule {
4
4
  private axiosInstance;
5
5
  private readonly SERVICE_URL;
@@ -7,4 +7,6 @@ export declare class CarrierModule {
7
7
  getCarrier(sessionId: string): Promise<Carrier[]>;
8
8
  getCarrierShipmentByOrderNumber(orderNo: string, sessionId: string): Promise<CarrierShipment[]>;
9
9
  getCarrierShipmentBySysTime(params: GetCarrierShipmentByTimeQueryParams, sessionId: string): Promise<CarrierShipment[]>;
10
+ getDispatchDataByOrderNumber(orderNo: string, sessionId: string): Promise<DispatchData[]>;
11
+ getDispatchDataByTime(params: GetDispatchDataByTimeQueryParams, sessionId: string): Promise<DispatchData[]>;
10
12
  }
@@ -1,6 +1,6 @@
1
1
  import { ApiHelper } from "../../helpers";
2
2
  import { ServiceAlias } from "../shared";
3
- import { mapCarrier, mapCarrierShipment, mapGetCarrierShipmentByOrderNumber, mapGetCarrierShipmentByTimeQueryParams, } from "./mappings";
3
+ import { mapCarrier, mapCarrierQueryByTimeParams, mapCarrierShipment, mapDispatchData, mapGetCarrierShipmentByOrderNumber, mapGetDispatchDataByOrderNoQueryParams, mapGetDispatchDataByTimeQueryParams, } from "./mappings";
4
4
  export class CarrierModule {
5
5
  axiosInstance;
6
6
  SERVICE_URL = `CarrierShipmentService/CarrierShipmentService`;
@@ -28,7 +28,7 @@ export class CarrierModule {
28
28
  }
29
29
  async getCarrierShipmentBySysTime(params, sessionId) {
30
30
  try {
31
- const bodyStr = mapGetCarrierShipmentByTimeQueryParams(params);
31
+ const bodyStr = mapCarrierQueryByTimeParams(params);
32
32
  const response = await ApiHelper.sendServiceRequest(this.SERVICE_URL, ["GetCarrierShipmentBySysModTime", "Request"], sessionId, ServiceAlias.CARRIER, this.axiosInstance, bodyStr);
33
33
  return response?.CarrierShipment?.map(mapCarrierShipment);
34
34
  }
@@ -36,4 +36,24 @@ export class CarrierModule {
36
36
  throw await ApiHelper.parseError(error);
37
37
  }
38
38
  }
39
+ async getDispatchDataByOrderNumber(orderNo, sessionId) {
40
+ const bodyStr = mapGetDispatchDataByOrderNoQueryParams(orderNo);
41
+ try {
42
+ const response = await ApiHelper.sendServiceRequest(this.SERVICE_URL, ["GetDispatchDataByOrderNumber", "Request"], sessionId, ServiceAlias.CARRIER, this.axiosInstance, bodyStr);
43
+ return response?.DispatchData?.map(mapDispatchData) ?? [];
44
+ }
45
+ catch (error) {
46
+ throw await ApiHelper.parseError(error);
47
+ }
48
+ }
49
+ async getDispatchDataByTime(params, sessionId) {
50
+ const bodyStr = mapGetDispatchDataByTimeQueryParams(params);
51
+ try {
52
+ const response = await ApiHelper.sendServiceRequest(this.SERVICE_URL, ["GetDispatchDataBySysModTime", "Request"], sessionId, ServiceAlias.CARRIER, this.axiosInstance, bodyStr);
53
+ return response?.DispatchData?.map(mapDispatchData) ?? [];
54
+ }
55
+ catch (error) {
56
+ throw await ApiHelper.parseError(error);
57
+ }
58
+ }
39
59
  }
@@ -185,3 +185,175 @@ describe("CarrierModule.getCarrierShipmentBySysTime()", () => {
185
185
  mAxios.post.mockReset();
186
186
  });
187
187
  });
188
+ describe("CarrierModule.getDispatchDataByOrderNo()", () => {
189
+ const token = "test-sid"; // process.env.SESSION_ID as string;
190
+ let carrierModule;
191
+ let mockApiHelperSendRequest;
192
+ beforeAll(() => {
193
+ carrierModule = new CarrierModule(mAxios);
194
+ mockApiHelperSendRequest = jest.spyOn(ApiHelper, "sendSoapRequest");
195
+ });
196
+ it("should send correct request for getting dispatch data by order number and return a dispatch data object corresponding to the specified order", async () => {
197
+ const orderNo = "TEST";
198
+ const expectedPayload = `
199
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:discs="http://discs.ws.fbsaust.com.au">
200
+ <S:Header>
201
+ <discs:SessionId>${token}</discs:SessionId>
202
+ </S:Header>
203
+ <S:Body>
204
+
205
+ <discs:GetDispatchDataByOrderNumberRequest>
206
+ <parameter>
207
+ <OrderNo>${orderNo}</OrderNo>
208
+ </parameter>
209
+ </discs:GetDispatchDataByOrderNumberRequest>
210
+
211
+ </S:Body>
212
+ </S:Envelope>
213
+ `;
214
+ const mockedResp = {
215
+ data: `
216
+ <?xml version='1.0' encoding='UTF-8'?>
217
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
218
+ <S:Body>
219
+ <ns2:GetDispatchDataByOrderNumberResponse xmlns:ns2="http://discs.ws.fbsaust.com.au">
220
+ <DispatchData>
221
+ <customer_order_no>ORDER</customer_order_no>
222
+ <order_no>${orderNo}</order_no>
223
+ <reference>IFX0001103</reference>
224
+ <carrier>APOST</carrier>
225
+ <consignment_no>UTG1347015</consignment_no>
226
+ <carrier_tracking_no></carrier_tracking_no>
227
+ <dispatch_date_time>23-08-2024 16:11:00</dispatch_date_time>
228
+ <dispatch_location>050</dispatch_location>
229
+ <stock>5552001.KHAK</stock>
230
+ <size>6</size>
231
+ <qdp>0</qdp>
232
+ <pdp>2</pdp>
233
+ <price>90.00</price>
234
+ <shipped_qty>1.0</shipped_qty>
235
+ <sys_mod_time>23-08-2024 16:11:24</sys_mod_time>
236
+ </DispatchData>
237
+ </ns2:GetDispatchDataByOrderNumberResponse>
238
+ </S:Body>
239
+ </S:Envelope>
240
+ `,
241
+ };
242
+ const expectedResult = {
243
+ orderNo: orderNo,
244
+ customerOrderNo: 'ORDER',
245
+ reference: 'IFX0001103',
246
+ carrier: 'APOST',
247
+ consignmentNo: 'UTG1347015',
248
+ carrierTrackingNo: '',
249
+ dispatchDateTime: '23-08-2024 16:11:00',
250
+ dispatchLocation: '050',
251
+ stock: '5552001.KHAK',
252
+ size: '6',
253
+ qdp: 0,
254
+ pdp: 2,
255
+ price: 90,
256
+ shippedQty: 1,
257
+ sysModTime: '23-08-2024 16:11:24'
258
+ };
259
+ mAxios.post.mockResolvedValueOnce(mockedResp);
260
+ const response = await carrierModule.getDispatchDataByOrderNumber(orderNo, token);
261
+ // Test that expected response is correct
262
+ expect(Array.isArray(response)).toBe(true);
263
+ expect(response.length).toBe(1);
264
+ expect(response[0]).toEqual(expectedResult);
265
+ const actualPayload = mAxios.post.mock.calls[0][1];
266
+ // Test that actual payload sent in the API matches expected payload
267
+ expect(Utils.removeEmptySpaces(actualPayload)).toEqual(Utils.removeEmptySpaces(expectedPayload));
268
+ mAxios.post.mockReset();
269
+ });
270
+ });
271
+ describe("CarrierModule.getDispatchDataByTime()", () => {
272
+ const token = "test-sid"; // process.env.SESSION_ID as string;
273
+ let carrierModule;
274
+ let mockApiHelperSendRequest;
275
+ beforeAll(() => {
276
+ carrierModule = new CarrierModule(mAxios);
277
+ mockApiHelperSendRequest = jest.spyOn(ApiHelper, "sendSoapRequest");
278
+ });
279
+ it("should send correct request for get dispatch data by time and return a list of dispatch data objects", async () => {
280
+ const params = {
281
+ sysModTimeFr: "01-01-2020 00:00:00",
282
+ sysModTimeTo: "01-01-2021 00:00:00",
283
+ };
284
+ const orderNo = "TEST";
285
+ const expectedPayload = `
286
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:discs="http://discs.ws.fbsaust.com.au">
287
+ <S:Header>
288
+ <discs:SessionId>${token}</discs:SessionId>
289
+ </S:Header>
290
+ <S:Body>
291
+
292
+ <discs:GetDispatchDataBySysModTimeRequest>
293
+ <parameter>
294
+ <SysModTimeFr>${params.sysModTimeFr}</SysModTimeFr>
295
+ <SysModTimeTo>${params.sysModTimeTo}</SysModTimeTo>
296
+ </parameter>
297
+ </discs:GetDispatchDataBySysModTimeRequest>
298
+
299
+ </S:Body>
300
+ </S:Envelope>
301
+ `;
302
+ const mockedResp = {
303
+ data: `
304
+ <?xml version='1.0' encoding='UTF-8'?>
305
+ <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
306
+ <S:Body>
307
+ <ns2:GetDispatchDataBySysModTimeResponse xmlns:ns2="http://discs.ws.fbsaust.com.au">
308
+ <SystemTime>07-04-2025 10:34:45</SystemTime>
309
+ <DispatchData>
310
+ <customer_order_no>ORDER</customer_order_no>
311
+ <order_no>${orderNo}</order_no>
312
+ <reference>IFX0001103</reference>
313
+ <carrier>APOST</carrier>
314
+ <consignment_no>UTG1347015</consignment_no>
315
+ <carrier_tracking_no></carrier_tracking_no>
316
+ <dispatch_date_time>23-08-2024 16:11:00</dispatch_date_time>
317
+ <dispatch_location>050</dispatch_location>
318
+ <stock>5552001.KHAK</stock>
319
+ <size>6</size>
320
+ <qdp>0</qdp>
321
+ <pdp>2</pdp>
322
+ <price>90.00</price>
323
+ <shipped_qty>1.0</shipped_qty>
324
+ <sys_mod_time>23-08-2024 16:11:24</sys_mod_time>
325
+ </DispatchData>
326
+ </ns2:GetDispatchDataBySysModTimeResponse>
327
+ </S:Body>
328
+ </S:Envelope>
329
+ `,
330
+ };
331
+ const expectedResult = {
332
+ orderNo: orderNo,
333
+ customerOrderNo: 'ORDER',
334
+ reference: 'IFX0001103',
335
+ carrier: 'APOST',
336
+ consignmentNo: 'UTG1347015',
337
+ carrierTrackingNo: '',
338
+ dispatchDateTime: '23-08-2024 16:11:00',
339
+ dispatchLocation: '050',
340
+ stock: '5552001.KHAK',
341
+ size: '6',
342
+ qdp: 0,
343
+ pdp: 2,
344
+ price: 90,
345
+ shippedQty: 1,
346
+ sysModTime: '23-08-2024 16:11:24'
347
+ };
348
+ mAxios.post.mockResolvedValueOnce(mockedResp);
349
+ const response = await carrierModule.getDispatchDataByTime(params, token);
350
+ // Test that expected response is correct
351
+ expect(Array.isArray(response)).toBe(true);
352
+ expect(response.length).toBe(1);
353
+ expect(response[0]).toEqual(expectedResult);
354
+ const actualPayload = mAxios.post.mock.calls[0][1];
355
+ // Test that actual payload sent in the API matches expected payload
356
+ expect(Utils.removeEmptySpaces(actualPayload)).toEqual(Utils.removeEmptySpaces(expectedPayload));
357
+ mAxios.post.mockReset();
358
+ });
359
+ });
@@ -1,5 +1,8 @@
1
- import { Carrier, CarrierRaw, CarrierShipment, CarrierShipmentRaw, GetCarrierShipmentByTimeQueryParams } from "../types";
1
+ import { Carrier, CarrierRaw, CarrierShipment, CarrierShipmentRaw, DispatchData, DispatchDataRaw, GetCarrierShipmentByTimeQueryParams, GetDispatchDataByTimeQueryParams } from "../types";
2
2
  export declare function mapCarrier(src: CarrierRaw): Carrier;
3
3
  export declare function mapCarrierShipment(src: CarrierShipmentRaw): CarrierShipment;
4
4
  export declare function mapGetCarrierShipmentByOrderNumber(orderNo: string): string;
5
- export declare function mapGetCarrierShipmentByTimeQueryParams(src: GetCarrierShipmentByTimeQueryParams): string;
5
+ export declare function mapCarrierQueryByTimeParams(src: GetCarrierShipmentByTimeQueryParams): string;
6
+ export declare function mapGetDispatchDataByTimeQueryParams(src: GetDispatchDataByTimeQueryParams): string;
7
+ export declare function mapGetDispatchDataByOrderNoQueryParams(orderNo: string): string;
8
+ export declare function mapDispatchData(src: DispatchDataRaw): DispatchData;
@@ -20,7 +20,7 @@ export function mapGetCarrierShipmentByOrderNumber(orderNo) {
20
20
  };
21
21
  return mapCarrierShipmentRequestBody(Utils.toXml(params));
22
22
  }
23
- export function mapGetCarrierShipmentByTimeQueryParams(src) {
23
+ export function mapCarrierQueryByTimeParams(src) {
24
24
  const params = {
25
25
  SysModTimeFr: src?.sysModTimeFr,
26
26
  SysModTimeTo: src?.sysModTimeTo,
@@ -34,3 +34,29 @@ function mapCarrierShipmentRequestBody(body) {
34
34
  </parameter>
35
35
  `;
36
36
  }
37
+ // ======================== Dispatch data / Partial shipment ========================
38
+ export function mapGetDispatchDataByTimeQueryParams(src) {
39
+ return mapCarrierQueryByTimeParams(src);
40
+ }
41
+ export function mapGetDispatchDataByOrderNoQueryParams(orderNo) {
42
+ return mapGetCarrierShipmentByOrderNumber(orderNo);
43
+ }
44
+ export function mapDispatchData(src) {
45
+ return {
46
+ customerOrderNo: (src?.customer_order_no ?? [])[0] || '',
47
+ orderNo: (src?.order_no ?? [])[0] || '',
48
+ reference: (src?.reference ?? [])[0] || '',
49
+ carrier: (src?.carrier ?? [])[0] || '',
50
+ consignmentNo: (src?.consignment_no ?? [])[0] || '',
51
+ carrierTrackingNo: (src?.carrier_tracking_no ?? [])[0] || '',
52
+ dispatchDateTime: (src?.dispatch_date_time ?? [])[0] || '',
53
+ dispatchLocation: (src?.dispatch_location ?? [])[0] || '',
54
+ stock: (src?.stock ?? [])[0] || '',
55
+ size: (src?.size ?? [])[0] || '',
56
+ qdp: Utils.toNumber((src?.qdp ?? [])[0] || ''),
57
+ pdp: Utils.toNumber((src?.pdp ?? [])[0] || ''),
58
+ price: Utils.toNumber((src?.price ?? [])[0] || ''),
59
+ shippedQty: Utils.toNumber((src?.shipped_qty ?? [])[0] || ''),
60
+ sysModTime: (src?.sys_mod_time ?? [])[0] || '',
61
+ };
62
+ }
@@ -1,3 +1,4 @@
1
+ import { GenericTimestampQueryParams } from "../../shared";
1
2
  export interface CarrierRaw {
2
3
  namekey: CarrierCode[];
3
4
  name: string[];
@@ -39,17 +40,45 @@ export interface CarrierShipment {
39
40
  export interface CarrierShipmentResponse {
40
41
  CarrierShipment: CarrierShipmentRaw[];
41
42
  }
42
- export interface GetCarrierShipmentByTimeQueryParams {
43
- /**
44
- * From System Modify Time. Value must be in format dd-MM-yyyy hh:mm:SS
45
- *
46
- * @type {string}
47
- */
48
- sysModTimeFr?: string;
49
- /**
50
- * To System Modify Time. Value must be in format dd-MM-yyyy hh:mm:SS
51
- *
52
- * @type {string}
53
- */
54
- sysModTimeTo?: string;
43
+ export type GetCarrierShipmentByTimeQueryParams = GenericTimestampQueryParams;
44
+ export type GetDispatchDataByTimeQueryParams = GenericTimestampQueryParams;
45
+ export interface GetDispatchDataByOrderNoQueryParams {
46
+ orderNo: string;
47
+ }
48
+ export interface DispatchDataResponse {
49
+ DispatchData: DispatchDataRaw[];
50
+ }
51
+ export interface DispatchDataRaw {
52
+ customer_order_no: string;
53
+ order_no: string;
54
+ reference: string;
55
+ carrier: string;
56
+ consignment_no: string;
57
+ carrier_tracking_no: string;
58
+ dispatch_date_time: string;
59
+ dispatch_location: string;
60
+ stock: string;
61
+ size: string;
62
+ qdp: string;
63
+ pdp: string;
64
+ price: string;
65
+ shipped_qty: string;
66
+ sys_mod_time: string;
67
+ }
68
+ export interface DispatchData {
69
+ customerOrderNo: string;
70
+ orderNo: string;
71
+ reference: string;
72
+ carrier: string;
73
+ consignmentNo: string;
74
+ carrierTrackingNo: string;
75
+ dispatchDateTime: string;
76
+ dispatchLocation: string;
77
+ stock: string;
78
+ size: string;
79
+ qdp: number;
80
+ pdp: number;
81
+ price: number;
82
+ shippedQty: number;
83
+ sysModTime: string;
55
84
  }
@@ -25,7 +25,7 @@ export declare enum ServiceAlias {
25
25
  DIARY = "dry",
26
26
  CARRIER = "discs"
27
27
  }
28
- export interface OptionalStockQueryParams {
28
+ export interface OptionalStockQueryParams extends GenericTimestampQueryParams {
29
29
  stockCategoryFr?: string;
30
30
  stockCategoryTo?: string;
31
31
  stockClassFr1?: string;
@@ -44,8 +44,6 @@ export interface OptionalStockQueryParams {
44
44
  stockExtraClassTo4?: string;
45
45
  stockExtraClassFr5?: string;
46
46
  stockExtraClassTo5?: string;
47
- sysModTimeFr?: string;
48
- sysModTimeTo?: string;
49
47
  alternateNamekeyFr?: string;
50
48
  alternateNamekeyTo?: string;
51
49
  stockActive?: StockActive[];
@@ -91,3 +89,20 @@ export declare class OptionalStockRequestBody {
91
89
  export interface BooleanResponse {
92
90
  result: boolean[];
93
91
  }
92
+ /**
93
+ * Generic interface for query parameters of endpoints that support querying using timestamps in Harmony
94
+ */
95
+ export interface GenericTimestampQueryParams {
96
+ /**
97
+ * From System Modify Time. Value must be in format dd-MM-yyyy hh:mm:SS
98
+ *
99
+ * @type {string}
100
+ */
101
+ sysModTimeFr?: string;
102
+ /**
103
+ * To System Modify Time. Value must be in format dd-MM-yyyy hh:mm:SS
104
+ *
105
+ * @type {string}
106
+ */
107
+ sysModTimeTo?: string;
108
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotdev/harmony-sdk",
3
- "version": "1.16.1",
3
+ "version": "1.18.0",
4
4
  "description": "Harmony API SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",