washday-sdk 1.6.50 → 1.6.52

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.
@@ -22,6 +22,7 @@ export const getList = function (params, options) {
22
22
  const queryParams = generateQueryParamsStr([
23
23
  'store',
24
24
  'storeId',
25
+ 'storeIds',
25
26
  'status',
26
27
  'name',
27
28
  'phone',
@@ -97,7 +97,8 @@ export const getRoutesByDriver = function (query) {
97
97
  };
98
98
  const queryParams = generateQueryParamsStr([
99
99
  'status',
100
- ], query);
100
+ 'scope',
101
+ ], Object.assign(Object.assign({}, query), { scope: "driver" }));
101
102
  return yield this.axiosInstance.get(`${GET_ROUTE}?${queryParams}`, config);
102
103
  }
103
104
  catch (error) {
@@ -106,3 +107,25 @@ export const getRoutesByDriver = function (query) {
106
107
  }
107
108
  });
108
109
  };
110
+ export const getRoutes = function () {
111
+ return __awaiter(this, arguments, void 0, function* (query = {}) {
112
+ try {
113
+ const config = {
114
+ headers: { Authorization: `Bearer ${this.apiToken}` }
115
+ };
116
+ const queryParams = generateQueryParamsStr([
117
+ 'scope',
118
+ 'storeIds',
119
+ 'status',
120
+ 'driver',
121
+ 'createdFrom',
122
+ 'createdTo',
123
+ ], query);
124
+ return yield this.axiosInstance.get(`${GET_ROUTE}?${queryParams}`, config);
125
+ }
126
+ catch (error) {
127
+ console.error('Error fetching getRoutes:', error);
128
+ throw error;
129
+ }
130
+ });
131
+ };
@@ -7,17 +7,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- var __rest = (this && this.__rest) || function (s, e) {
11
- var t = {};
12
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
13
- t[p] = s[p];
14
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
15
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
16
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
17
- t[p[i]] = s[p[i]];
18
- }
19
- return t;
20
- };
21
10
  const GET_SET_ROUTES = 'api/routes';
22
11
  const GET_STORE_ROUTES_BY_ID = 'api/stores/:id/routes';
23
12
  //@deprecated
@@ -41,8 +30,18 @@ export const createRouteV2 = function (data) {
41
30
  const config = {
42
31
  headers: { Authorization: `Bearer ${this.apiToken}` }
43
32
  };
44
- const { storeId } = data, rest = __rest(data, ["storeId"]);
45
- return yield this.axiosInstance.post(GET_STORE_ROUTES_BY_ID.replace(':id', storeId), rest, config);
33
+ const { storeId, storeIds, driver, orders } = data;
34
+ if (storeIds) {
35
+ return yield this.axiosInstance.post(GET_SET_ROUTES, {
36
+ storeIds,
37
+ driver,
38
+ orders,
39
+ }, config);
40
+ }
41
+ return yield this.axiosInstance.post(GET_STORE_ROUTES_BY_ID.replace(':id', storeId), {
42
+ driver,
43
+ orders,
44
+ }, config);
46
45
  }
47
46
  catch (error) {
48
47
  console.error('Error fetching createRouteV2:', error);
@@ -7,6 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
+ import { generateQueryParamsStr } from "../../utils/apiUtils";
10
11
  const GET_SET_STAFF = (storeId) => `api/store/${storeId}/staff`;
11
12
  const GET_ASSIGNABLE_STAFF = (storeId) => `api/store/${storeId}/assignable-staffs`;
12
13
  export const getStoreStaff = function (storeId, queryParams) {
@@ -30,7 +31,13 @@ export const getStoreAssignableStaffs = function (storeId, queryParams) {
30
31
  const config = {
31
32
  headers: { Authorization: `Bearer ${this.apiToken}` }
32
33
  };
33
- const suffix = queryParams ? `?${queryParams}` : "";
34
+ const normalizedQueryParams = typeof queryParams === "string"
35
+ ? queryParams
36
+ : generateQueryParamsStr([
37
+ "appendAdmin",
38
+ "storeIds",
39
+ ], queryParams || {});
40
+ const suffix = normalizedQueryParams ? `?${normalizedQueryParams}` : "";
34
41
  const response = yield this.axiosInstance.get(`${GET_ASSIGNABLE_STAFF(storeId)}${suffix}`, config);
35
42
  return response;
36
43
  }
@@ -22,6 +22,8 @@ const ticketStructure = {
22
22
  orderFolioFontSizePreset: folioPreset,
23
23
  ticketLineSpacingPreset: spacingPreset,
24
24
  ticketPrintFormat: "escpos",
25
+ tax_id: "J-507138330",
26
+ tax_id_label: "RIF",
25
27
  };
26
28
  const labelTicketStructure = Object.assign({}, ticketStructure);
27
29
  const ticketForLaundryStructure = {
@@ -47,6 +49,8 @@ const ticketForLaundryStructure = {
47
49
  orderFolioFontSizePreset: "large",
48
50
  ticketLineSpacingPreset: "small",
49
51
  ticketPrintFormat: "html",
52
+ tax_id: "ABC123",
53
+ tax_id_label: "RFC",
50
54
  };
51
55
  if (ticketStructure.orderFolioFontSizePreset !== "large") {
52
56
  throw new Error("Ticket structure folio preset was not preserved");
@@ -57,4 +61,13 @@ if (labelTicketStructure.ticketLineSpacingPreset !== "medium") {
57
61
  if (ticketForLaundryStructure.customerNameFontSize !== "medium") {
58
62
  throw new Error("Laundry ticket structure customer font size was not preserved");
59
63
  }
64
+ if (ticketStructure.tax_id_label !== "RIF") {
65
+ throw new Error("Ticket structure tax ID label was not preserved");
66
+ }
67
+ if (labelTicketStructure.tax_id !== "J-507138330") {
68
+ throw new Error("Label ticket structure tax ID value was not preserved");
69
+ }
70
+ if (ticketForLaundryStructure.tax_id_label !== "RFC") {
71
+ throw new Error("Laundry ticket structure tax ID label was not preserved");
72
+ }
60
73
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "washday-sdk",
3
- "version": "1.6.50",
3
+ "version": "1.6.52",
4
4
  "description": "Washday utilities functions and API",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -11,6 +11,7 @@ const GET_SET_ORDER_CUSTOMERS_APP = 'api/v2/washdayapp/orders';
11
11
  export const getList = async function (this: WashdayClientInstance, params: {
12
12
  store: string | undefined,
13
13
  storeId: string | undefined,
14
+ storeIds?: string[] | string,
14
15
  status: string | undefined,
15
16
  name: string | undefined,
16
17
  phone: string | undefined,
@@ -43,6 +44,7 @@ export const getList = async function (this: WashdayClientInstance, params: {
43
44
  const queryParams = generateQueryParamsStr([
44
45
  'store',
45
46
  'storeId',
47
+ 'storeIds',
46
48
  'status',
47
49
  'name',
48
50
  'phone',
@@ -7,6 +7,17 @@ const GET_STORE_ROUTES = 'api/storeRoutes';
7
7
  const GET_STORE_ROUTES_BY_ID = 'api/stores/:id/routes';
8
8
  const GET_ROUTE = 'api/routes';
9
9
 
10
+ export type RouteListScope = "driver" | "company";
11
+
12
+ export type RouteListQuery = {
13
+ scope?: RouteListScope,
14
+ storeIds?: string[] | string,
15
+ status?: string,
16
+ driver?: string,
17
+ createdFrom?: string,
18
+ createdTo?: string,
19
+ };
20
+
10
21
  //@deprecated
11
22
  export const getOrdersForRoute = async function (this: WashdayClientInstance, params: {
12
23
  store: string | undefined,
@@ -87,7 +98,11 @@ export const getRoutesByDriver = async function (this: WashdayClientInstance, qu
87
98
  };
88
99
  const queryParams = generateQueryParamsStr([
89
100
  'status',
90
- ], query);
101
+ 'scope',
102
+ ], {
103
+ ...query,
104
+ scope: "driver",
105
+ });
91
106
  return await this.axiosInstance.get(`${GET_ROUTE}?${queryParams}`, config);
92
107
  } catch (error) {
93
108
  console.error('Error fetching getRoutesByDriver:', error);
@@ -95,3 +110,22 @@ export const getRoutesByDriver = async function (this: WashdayClientInstance, qu
95
110
  }
96
111
  };
97
112
 
113
+ export const getRoutes = async function (this: WashdayClientInstance, query: RouteListQuery = {}): Promise<{ data: { data: IRoute[] } }> {
114
+ try {
115
+ const config = {
116
+ headers: { Authorization: `Bearer ${this.apiToken}` }
117
+ };
118
+ const queryParams = generateQueryParamsStr([
119
+ 'scope',
120
+ 'storeIds',
121
+ 'status',
122
+ 'driver',
123
+ 'createdFrom',
124
+ 'createdTo',
125
+ ], query);
126
+ return await this.axiosInstance.get(`${GET_ROUTE}?${queryParams}`, config);
127
+ } catch (error) {
128
+ console.error('Error fetching getRoutes:', error);
129
+ throw error;
130
+ }
131
+ };
@@ -30,7 +30,8 @@ export const createRoute = async function (this: WashdayClientInstance, data: {
30
30
 
31
31
 
32
32
  export const createRouteV2 = async function (this: WashdayClientInstance, data: {
33
- storeId: string,
33
+ storeId?: string,
34
+ storeIds?: string[],
34
35
  driver: string,
35
36
  orders: Array<string>,
36
37
  }): Promise<any> {
@@ -38,8 +39,18 @@ export const createRouteV2 = async function (this: WashdayClientInstance, data:
38
39
  const config = {
39
40
  headers: { Authorization: `Bearer ${this.apiToken}` }
40
41
  };
41
- const { storeId, ...rest } = data;
42
- return await this.axiosInstance.post(GET_STORE_ROUTES_BY_ID.replace(':id', storeId), rest, config);
42
+ const { storeId, storeIds, driver, orders } = data;
43
+ if (storeIds) {
44
+ return await this.axiosInstance.post(GET_SET_ROUTES, {
45
+ storeIds,
46
+ driver,
47
+ orders,
48
+ }, config);
49
+ }
50
+ return await this.axiosInstance.post(GET_STORE_ROUTES_BY_ID.replace(':id', storeId as string), {
51
+ driver,
52
+ orders,
53
+ }, config);
43
54
  } catch (error) {
44
55
  console.error('Error fetching createRouteV2:', error);
45
56
  throw error;
@@ -57,4 +68,4 @@ export const startRoute = async function (this: WashdayClientInstance, routeId:
57
68
  console.error('Error fetching startRoute:', error);
58
69
  throw error;
59
70
  }
60
- };
71
+ };
@@ -1,4 +1,5 @@
1
1
  import { WashdayClientInstance } from "../../interfaces/Api";
2
+ import { generateQueryParamsStr } from "../../utils/apiUtils";
2
3
  import axiosInstance from "../axiosInstance";
3
4
 
4
5
  const GET_SET_STAFF = (storeId: string) => `api/store/${storeId}/staff`;
@@ -17,12 +18,25 @@ export const getStoreStaff = async function (this: WashdayClientInstance, storeI
17
18
  }
18
19
  };
19
20
 
20
- export const getStoreAssignableStaffs = async function (this: WashdayClientInstance, storeId: string, queryParams?: string): Promise<any> {
21
+ export const getStoreAssignableStaffs = async function (
22
+ this: WashdayClientInstance,
23
+ storeId: string,
24
+ queryParams?: string | {
25
+ appendAdmin?: string,
26
+ storeIds?: string[] | string,
27
+ }
28
+ ): Promise<any> {
21
29
  try {
22
30
  const config = {
23
31
  headers: { Authorization: `Bearer ${this.apiToken}` }
24
32
  };
25
- const suffix = queryParams ? `?${queryParams}` : "";
33
+ const normalizedQueryParams = typeof queryParams === "string"
34
+ ? queryParams
35
+ : generateQueryParamsStr([
36
+ "appendAdmin",
37
+ "storeIds",
38
+ ], queryParams || {});
39
+ const suffix = normalizedQueryParams ? `?${normalizedQueryParams}` : "";
26
40
  const response = await this.axiosInstance.get(`${GET_ASSIGNABLE_STAFF(storeId)}${suffix}`, config);
27
41
  return response;
28
42
  } catch (error) {
@@ -34,7 +34,9 @@ export interface IRouteOrder {
34
34
 
35
35
  export interface IRoute {
36
36
  _id: string;
37
+ company: string | { _id: string; [key: string]: any };
37
38
  routeSequence?: number;
39
+ legacyStoreRouteSequence?: number;
38
40
  closedDate?: Date | string | null;
39
41
  createdBy: IUser | string;
40
42
  createdDate?: Date | string;
@@ -43,6 +45,7 @@ export interface IRoute {
43
45
  orders: IRouteOrder[];
44
46
  status: RouteStatus | string;
45
47
  store: IStore | string;
48
+ stores?: Array<IStore | string>;
46
49
  startedDate?: Date | string | null;
47
50
  }
48
51
 
@@ -30,6 +30,8 @@ const ticketStructure: ITicketStructure = {
30
30
  orderFolioFontSizePreset: folioPreset,
31
31
  ticketLineSpacingPreset: spacingPreset,
32
32
  ticketPrintFormat: "escpos",
33
+ tax_id: "J-507138330",
34
+ tax_id_label: "RIF",
33
35
  };
34
36
 
35
37
  const labelTicketStructure: ILabelTicketStructure = {
@@ -59,6 +61,8 @@ const ticketForLaundryStructure: ITicketForLaundryStructure = {
59
61
  orderFolioFontSizePreset: "large",
60
62
  ticketLineSpacingPreset: "small",
61
63
  ticketPrintFormat: "html",
64
+ tax_id: "ABC123",
65
+ tax_id_label: "RFC",
62
66
  };
63
67
 
64
68
  if (ticketStructure.orderFolioFontSizePreset !== "large") {
@@ -72,3 +76,15 @@ if (labelTicketStructure.ticketLineSpacingPreset !== "medium") {
72
76
  if (ticketForLaundryStructure.customerNameFontSize !== "medium") {
73
77
  throw new Error("Laundry ticket structure customer font size was not preserved");
74
78
  }
79
+
80
+ if (ticketStructure.tax_id_label !== "RIF") {
81
+ throw new Error("Ticket structure tax ID label was not preserved");
82
+ }
83
+
84
+ if (labelTicketStructure.tax_id !== "J-507138330") {
85
+ throw new Error("Label ticket structure tax ID value was not preserved");
86
+ }
87
+
88
+ if (ticketForLaundryStructure.tax_id_label !== "RFC") {
89
+ throw new Error("Laundry ticket structure tax ID label was not preserved");
90
+ }
@@ -300,6 +300,8 @@ export interface ITicketStructure {
300
300
  showLegend: Boolean,
301
301
  showPaymentMethod: Boolean,
302
302
  showStorePhone: Boolean,
303
+ tax_id?: string,
304
+ tax_id_label?: string,
303
305
  showCustomerPoints: Boolean,
304
306
  showDeliveryDate: Boolean,
305
307
  showDeliveryTime: Boolean,
@@ -325,6 +327,8 @@ export interface ITicketForLaundryStructure {
325
327
  showLegend: Boolean,
326
328
  showPaymentMethod: Boolean,
327
329
  showStorePhone: Boolean,
330
+ tax_id?: string,
331
+ tax_id_label?: string,
328
332
  showCustomerPoints: Boolean,
329
333
  showDeliveryDate: Boolean,
330
334
  showDeliveryTime: Boolean,
@@ -53,4 +53,50 @@ describe("orders.getList assignedEmployee filter", () => {
53
53
  },
54
54
  });
55
55
  });
56
+
57
+ it("passes storeIds through the order list query string", async () => {
58
+ const get = jest.fn().mockResolvedValue({
59
+ data: {
60
+ data: {
61
+ orders: [],
62
+ },
63
+ },
64
+ });
65
+ const client = {
66
+ apiToken: "token-123",
67
+ axiosInstance: { get },
68
+ } as any;
69
+
70
+ await getList.call(client, {
71
+ store: undefined,
72
+ storeId: undefined,
73
+ storeIds: ["store-a", "store-b"],
74
+ status: undefined,
75
+ name: undefined,
76
+ phone: undefined,
77
+ email: undefined,
78
+ fromDate: undefined,
79
+ toDate: undefined,
80
+ sequence: undefined,
81
+ pageNum: "0",
82
+ limit: "20",
83
+ sequenceSort: "-1",
84
+ cleanedDateTime: undefined,
85
+ readyDateTime: undefined,
86
+ collectedDateTime: undefined,
87
+ q: undefined,
88
+ pickupFromDate: undefined,
89
+ pickupToDate: undefined,
90
+ deliveryFromDate: undefined,
91
+ deliveryToDate: undefined,
92
+ } as any);
93
+
94
+ expect(get).toHaveBeenCalledWith(
95
+ "api/v2/order?store=undefined&storeId=undefined&storeIds=store-a,store-b&status=undefined&name=undefined&phone=undefined&email=undefined&fromDate=undefined&toDate=undefined&sequence=undefined&pageNum=0&limit=20&sequenceSort=-1&cleanedDateTime=undefined&readyDateTime=undefined&collectedDateTime=undefined&q=undefined&pickupFromDate=undefined&pickupToDate=undefined&deliveryFromDate=undefined&deliveryToDate=undefined",
96
+ {
97
+ headers: { Authorization: "Bearer token-123" },
98
+ signal: undefined,
99
+ }
100
+ );
101
+ });
56
102
  });
@@ -0,0 +1,96 @@
1
+ import { getRoutes, getRoutesByDriver } from "../src/api/routes/get";
2
+ import { createRouteV2 } from "../src/api/routes/post";
3
+
4
+ describe("routes multi-store api", () => {
5
+ it("creates multi-store routes through the root routes endpoint", async () => {
6
+ const post = jest.fn().mockResolvedValue({ data: { data: { _id: "route-1" } } });
7
+ const client = {
8
+ apiToken: "token-123",
9
+ axiosInstance: { post },
10
+ } as any;
11
+
12
+ await createRouteV2.call(client, {
13
+ storeIds: ["store-a", "store-b"],
14
+ driver: "driver-1",
15
+ orders: ["order-1"],
16
+ });
17
+
18
+ expect(post).toHaveBeenCalledWith(
19
+ "api/routes",
20
+ {
21
+ storeIds: ["store-a", "store-b"],
22
+ driver: "driver-1",
23
+ orders: ["order-1"],
24
+ },
25
+ {
26
+ headers: { Authorization: "Bearer token-123" },
27
+ }
28
+ );
29
+ });
30
+
31
+ it("keeps the legacy store route create endpoint when only storeId is provided", async () => {
32
+ const post = jest.fn().mockResolvedValue({ data: { data: { _id: "route-1" } } });
33
+ const client = {
34
+ apiToken: "token-123",
35
+ axiosInstance: { post },
36
+ } as any;
37
+
38
+ await createRouteV2.call(client, {
39
+ storeId: "store-a",
40
+ driver: "driver-1",
41
+ orders: ["order-1"],
42
+ });
43
+
44
+ expect(post).toHaveBeenCalledWith(
45
+ "api/stores/store-a/routes",
46
+ {
47
+ driver: "driver-1",
48
+ orders: ["order-1"],
49
+ },
50
+ {
51
+ headers: { Authorization: "Bearer token-123" },
52
+ }
53
+ );
54
+ });
55
+
56
+ it("requests driver routes with explicit driver scope", async () => {
57
+ const get = jest.fn().mockResolvedValue({ data: { data: [] } });
58
+ const client = {
59
+ apiToken: "token-123",
60
+ axiosInstance: { get },
61
+ } as any;
62
+
63
+ await getRoutesByDriver.call(client, { status: "created,in_progress" });
64
+
65
+ expect(get).toHaveBeenCalledWith(
66
+ "api/routes?status=created,in_progress&scope=driver",
67
+ {
68
+ headers: { Authorization: "Bearer token-123" },
69
+ }
70
+ );
71
+ });
72
+
73
+ it("lists company routes with filters through the root routes endpoint", async () => {
74
+ const get = jest.fn().mockResolvedValue({ data: { data: [] } });
75
+ const client = {
76
+ apiToken: "token-123",
77
+ axiosInstance: { get },
78
+ } as any;
79
+
80
+ await getRoutes.call(client, {
81
+ scope: "company",
82
+ storeIds: ["store-a", "store-b"],
83
+ status: "created,in_progress",
84
+ driver: "driver-1",
85
+ createdFrom: "2026-05-01T00:00:00.000Z",
86
+ createdTo: "2026-05-02T00:00:00.000Z",
87
+ });
88
+
89
+ expect(get).toHaveBeenCalledWith(
90
+ "api/routes?scope=company&storeIds=store-a,store-b&status=created,in_progress&driver=driver-1&createdFrom=2026-05-01T00:00:00.000Z&createdTo=2026-05-02T00:00:00.000Z",
91
+ {
92
+ headers: { Authorization: "Bearer token-123" },
93
+ }
94
+ );
95
+ });
96
+ });
@@ -34,4 +34,34 @@ describe("getStoreAssignableStaffs", () => {
34
34
  },
35
35
  });
36
36
  });
37
+
38
+ it("builds storeIds query params for assignable staff", async () => {
39
+ const get = jest.fn().mockResolvedValue({
40
+ data: {
41
+ data: {
42
+ staffs: [],
43
+ },
44
+ },
45
+ });
46
+ const client = {
47
+ apiToken: "token-123",
48
+ axiosInstance: { get },
49
+ } as any;
50
+
51
+ await getStoreAssignableStaffs.call(
52
+ client,
53
+ "store-1",
54
+ {
55
+ appendAdmin: "true",
56
+ storeIds: ["store-1", "store-2"],
57
+ }
58
+ );
59
+
60
+ expect(get).toHaveBeenCalledWith(
61
+ "api/store/store-1/assignable-staffs?appendAdmin=true&storeIds=store-1,store-2",
62
+ {
63
+ headers: { Authorization: "Bearer token-123" },
64
+ }
65
+ );
66
+ });
37
67
  });
@@ -0,0 +1,26 @@
1
+ import {
2
+ ILabelTicketStructure,
3
+ ITicketForLaundryStructure,
4
+ ITicketStructure,
5
+ } from "../src/interfaces/Store";
6
+
7
+ describe("ticket structure tax ID fields", () => {
8
+ it("accepts tax_id and tax_id_label on all ticket structure variants", () => {
9
+ const ticketStructure: Partial<ITicketStructure> = {
10
+ tax_id: "J-507138330",
11
+ tax_id_label: "RIF",
12
+ };
13
+ const labelTicketStructure: Partial<ILabelTicketStructure> = {
14
+ tax_id: "ABC123",
15
+ tax_id_label: "RFC",
16
+ };
17
+ const ticketForLaundryStructure: Partial<ITicketForLaundryStructure> = {
18
+ tax_id: "J-507138330",
19
+ tax_id_label: "RIF",
20
+ };
21
+
22
+ expect(ticketStructure.tax_id_label).toBe("RIF");
23
+ expect(labelTicketStructure.tax_id).toBe("ABC123");
24
+ expect(ticketForLaundryStructure.tax_id_label).toBe("RIF");
25
+ });
26
+ });