washday-sdk 1.6.39 → 1.6.41

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.
@@ -20,10 +20,10 @@ jobs:
20
20
  ref: ${{ github.head_ref }}
21
21
  token: ${{ secrets.GITHUB_TOKEN }}
22
22
 
23
- - name: Use Node.js 22
23
+ - name: Use Node.js 24
24
24
  uses: actions/setup-node@v4
25
25
  with:
26
- node-version: 22
26
+ node-version: 24
27
27
 
28
28
  - name: Configure git identity
29
29
  run: |
@@ -17,13 +17,10 @@ jobs:
17
17
  - name: Checkout
18
18
  uses: actions/checkout@v4
19
19
 
20
- - name: Use Node.js 22
20
+ - name: Use Node.js 24
21
21
  uses: actions/setup-node@v4
22
22
  with:
23
- node-version: 22
24
-
25
- - name: Update npm to latest
26
- run: npm install -g npm@latest
23
+ node-version: 24
27
24
 
28
25
  - name: Install dependencies
29
26
  run: npm ci
package/dist/api/index.js CHANGED
@@ -151,7 +151,8 @@ const WashdayClient = function WashdayClient(apiToken, env = 'PROD', clientId, c
151
151
  bulkCancel: ordersEndpoints.putModule.bulkCancel,
152
152
  bulkClean: ordersEndpoints.putModule.bulkClean,
153
153
  bulkCollect: ordersEndpoints.putModule.bulkCollect,
154
- cancelOrderByIdCustomersApp: ordersEndpoints.deleteModule.cancelOrderByIdCustomersApp
154
+ cancelOrderByIdCustomersApp: ordersEndpoints.deleteModule.cancelOrderByIdCustomersApp,
155
+ updateLineStatuses: ordersEndpoints.patchModule.updateLineStatuses,
155
156
  });
156
157
  this.customers = bindMethods(this, {
157
158
  getCustomers: customersEndpoints.getModule.getList,
@@ -321,6 +322,7 @@ const WashdayClient = function WashdayClient(apiToken, env = 'PROD', clientId, c
321
322
  getDiscountCodesReport: reportsExportEndpoints.getModule.getDiscountCodesReport,
322
323
  getStaffReport: reportsExportEndpoints.getModule.getStaffReport,
323
324
  getProductSalesReport: reportsExportEndpoints.getModule.getProductSalesReport,
325
+ getProductSalesDrillDown: reportsExportEndpoints.getModule.getProductSalesDrillDown,
324
326
  getPaymentLinesReport: reportsExportEndpoints.getModule.getPaymentLinesReport,
325
327
  getCashierBoxMovementsReport: reportsExportEndpoints.getModule.getCashierBoxMovementsReport,
326
328
  getUnpaidOrdersReport: reportsExportEndpoints.getModule.getUnpaidOrdersReport,
@@ -1,4 +1,5 @@
1
1
  export * as deleteModule from './delete';
2
2
  export * as getModule from './get';
3
+ export * as patchModule from './patch';
3
4
  export * as postModule from './post';
4
5
  export * as putModule from './put';
@@ -0,0 +1,28 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ const ORDER_LINE_STATUSES = (orderId) => `/api/v2/order/${orderId}/line-statuses`;
11
+ /**
12
+ * Batch update of line-level statuses for a single order.
13
+ *
14
+ * - Validates all transitions server-side before applying any.
15
+ * - Does NOT modify the order's own status.
16
+ * - Returns the full updated order.
17
+ *
18
+ * Actor: Staff / POS (requires valid auth token)
19
+ * Endpoint: PATCH /api/v2/order/:id/line-statuses
20
+ */
21
+ export const updateLineStatuses = function (orderId, dto) {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const config = {
24
+ headers: { Authorization: `Bearer ${this.apiToken}` },
25
+ };
26
+ return yield this.axiosInstance.patch(ORDER_LINE_STATUSES(orderId), dto, config);
27
+ });
28
+ };
@@ -164,6 +164,26 @@ export const getProductSalesReport = function (storeId, params) {
164
164
  }
165
165
  });
166
166
  };
167
+ export const getProductSalesDrillDown = function (storeId, params) {
168
+ return __awaiter(this, void 0, void 0, function* () {
169
+ try {
170
+ const config = {
171
+ headers: { Authorization: `Bearer ${this.apiToken}` }
172
+ };
173
+ const queryParams = generateQueryParamsStr([
174
+ 'storeProductId',
175
+ 'fromDate',
176
+ 'toDate',
177
+ 'timezone',
178
+ ], params);
179
+ return yield this.axiosInstance.get(`${GET_SET_REPORTS}/${storeId}/productSales/drill-down?${queryParams}`, config);
180
+ }
181
+ catch (error) {
182
+ console.error('Error fetching getProductSalesDrillDown:', error);
183
+ throw error;
184
+ }
185
+ });
186
+ };
167
187
  export const getPaymentLinesReport = function (storeId, params) {
168
188
  return __awaiter(this, void 0, void 0, function* () {
169
189
  try {
@@ -18,3 +18,12 @@ export var PaymentMethodsEnum;
18
18
  PaymentMethodsEnum["Delivery"] = "delivery";
19
19
  PaymentMethodsEnum["Transfer"] = "transfer";
20
20
  })(PaymentMethodsEnum || (PaymentMethodsEnum = {}));
21
+ export var OrderProductLineStatus;
22
+ (function (OrderProductLineStatus) {
23
+ OrderProductLineStatus["Created"] = "created";
24
+ OrderProductLineStatus["Cleaning"] = "cleaning";
25
+ OrderProductLineStatus["Ready"] = "ready";
26
+ OrderProductLineStatus["Collected"] = "collected";
27
+ OrderProductLineStatus["Uncollected"] = "uncollected";
28
+ OrderProductLineStatus["Cancelled"] = "cancelled";
29
+ })(OrderProductLineStatus || (OrderProductLineStatus = {}));
@@ -0,0 +1,60 @@
1
+ const folioPreset = "large";
2
+ const spacingPreset = "medium";
3
+ const ticketStructure = {
4
+ showTotalPieces: false,
5
+ showEmisionDate: true,
6
+ showEmisionTime: true,
7
+ showLegend: true,
8
+ showPaymentMethod: true,
9
+ showStorePhone: true,
10
+ showCustomerPoints: false,
11
+ showDeliveryDate: true,
12
+ showDeliveryTime: true,
13
+ ticketLegendText: "Gracias",
14
+ showStoreName: true,
15
+ showCustomerName: true,
16
+ showCreatedByName: true,
17
+ showOrderNotes: false,
18
+ showTaxes: false,
19
+ showDiscounts: true,
20
+ showCredit: true,
21
+ customerNameFontSize: "small",
22
+ orderFolioFontSizePreset: folioPreset,
23
+ ticketLineSpacingPreset: spacingPreset,
24
+ ticketPrintFormat: "escpos",
25
+ };
26
+ const labelTicketStructure = Object.assign({}, ticketStructure);
27
+ const ticketForLaundryStructure = {
28
+ showTotalPieces: false,
29
+ showEmisionDate: true,
30
+ showEmisionTime: true,
31
+ showLegend: true,
32
+ showPaymentMethod: true,
33
+ showStorePhone: true,
34
+ showCustomerPoints: false,
35
+ showDeliveryDate: true,
36
+ showDeliveryTime: true,
37
+ ticketLegendText: "Gracias",
38
+ printLogoOnTicket: false,
39
+ showStoreName: true,
40
+ showCustomerName: true,
41
+ showCreatedByName: true,
42
+ showOrderNotes: false,
43
+ showTaxes: false,
44
+ showDiscounts: true,
45
+ showCredit: true,
46
+ customerNameFontSize: "medium",
47
+ orderFolioFontSizePreset: "large",
48
+ ticketLineSpacingPreset: "small",
49
+ ticketPrintFormat: "html",
50
+ };
51
+ if (ticketStructure.orderFolioFontSizePreset !== "large") {
52
+ throw new Error("Ticket structure folio preset was not preserved");
53
+ }
54
+ if (labelTicketStructure.ticketLineSpacingPreset !== "medium") {
55
+ throw new Error("Label ticket structure spacing preset was not preserved");
56
+ }
57
+ if (ticketForLaundryStructure.customerNameFontSize !== "medium") {
58
+ throw new Error("Laundry ticket structure customer font size was not preserved");
59
+ }
60
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "washday-sdk",
3
- "version": "1.6.39",
3
+ "version": "1.6.41",
4
4
  "description": "Washday utilities functions and API",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
package/src/api/index.ts CHANGED
@@ -158,7 +158,8 @@ const WashdayClient: WashdayClientConstructor = function WashdayClient(this: Was
158
158
  bulkCancel: ordersEndpoints.putModule.bulkCancel,
159
159
  bulkClean: ordersEndpoints.putModule.bulkClean,
160
160
  bulkCollect: ordersEndpoints.putModule.bulkCollect,
161
- cancelOrderByIdCustomersApp: ordersEndpoints.deleteModule.cancelOrderByIdCustomersApp
161
+ cancelOrderByIdCustomersApp: ordersEndpoints.deleteModule.cancelOrderByIdCustomersApp,
162
+ updateLineStatuses: ordersEndpoints.patchModule.updateLineStatuses,
162
163
  });
163
164
  this.customers = bindMethods(this, {
164
165
  getCustomers: customersEndpoints.getModule.getList,
@@ -328,6 +329,7 @@ const WashdayClient: WashdayClientConstructor = function WashdayClient(this: Was
328
329
  getDiscountCodesReport: reportsExportEndpoints.getModule.getDiscountCodesReport,
329
330
  getStaffReport: reportsExportEndpoints.getModule.getStaffReport,
330
331
  getProductSalesReport: reportsExportEndpoints.getModule.getProductSalesReport,
332
+ getProductSalesDrillDown: reportsExportEndpoints.getModule.getProductSalesDrillDown,
331
333
  getPaymentLinesReport: reportsExportEndpoints.getModule.getPaymentLinesReport,
332
334
  getCashierBoxMovementsReport: reportsExportEndpoints.getModule.getCashierBoxMovementsReport,
333
335
  getUnpaidOrdersReport: reportsExportEndpoints.getModule.getUnpaidOrdersReport,
@@ -1,4 +1,5 @@
1
1
  export * as deleteModule from './delete';
2
2
  export * as getModule from './get';
3
+ export * as patchModule from './patch';
3
4
  export * as postModule from './post';
4
5
  export * as putModule from './put';
@@ -0,0 +1,25 @@
1
+ import { WashdayClientInstance } from '../../interfaces/Api';
2
+ import { IUpdateOrderLineStatusesDto } from '../../interfaces/Order';
3
+
4
+ const ORDER_LINE_STATUSES = (orderId: string) => `/api/v2/order/${orderId}/line-statuses`;
5
+
6
+ /**
7
+ * Batch update of line-level statuses for a single order.
8
+ *
9
+ * - Validates all transitions server-side before applying any.
10
+ * - Does NOT modify the order's own status.
11
+ * - Returns the full updated order.
12
+ *
13
+ * Actor: Staff / POS (requires valid auth token)
14
+ * Endpoint: PATCH /api/v2/order/:id/line-statuses
15
+ */
16
+ export const updateLineStatuses = async function (
17
+ this: WashdayClientInstance,
18
+ orderId: string,
19
+ dto: IUpdateOrderLineStatusesDto
20
+ ): Promise<any> {
21
+ const config = {
22
+ headers: { Authorization: `Bearer ${this.apiToken}` },
23
+ };
24
+ return await this.axiosInstance.patch(ORDER_LINE_STATUSES(orderId), dto, config);
25
+ };
@@ -175,6 +175,29 @@ export const getProductSalesReport = async function (this: WashdayClientInstance
175
175
  }
176
176
  };
177
177
 
178
+ export const getProductSalesDrillDown = async function (this: WashdayClientInstance, storeId: string, params: {
179
+ storeProductId: string
180
+ fromDate?: string
181
+ toDate?: string
182
+ timezone?: string
183
+ }): Promise<any> {
184
+ try {
185
+ const config = {
186
+ headers: { Authorization: `Bearer ${this.apiToken}` }
187
+ };
188
+ const queryParams = generateQueryParamsStr([
189
+ 'storeProductId',
190
+ 'fromDate',
191
+ 'toDate',
192
+ 'timezone',
193
+ ], params);
194
+ return await this.axiosInstance.get(`${GET_SET_REPORTS}/${storeId}/productSales/drill-down?${queryParams}`, config);
195
+ } catch (error) {
196
+ console.error('Error fetching getProductSalesDrillDown:', error);
197
+ throw error;
198
+ }
199
+ };
200
+
178
201
  export const getPaymentLinesReport = async function (this: WashdayClientInstance, storeId: string, params: {
179
202
  fromDate?: string
180
203
  toDate?: string
package/src/enum/index.ts CHANGED
@@ -16,4 +16,13 @@ export enum PaymentMethodsEnum {
16
16
  Card = "card",
17
17
  Delivery = "delivery",
18
18
  Transfer = "transfer",
19
+ }
20
+
21
+ export enum OrderProductLineStatus {
22
+ Created = 'created',
23
+ Cleaning = 'cleaning',
24
+ Ready = 'ready',
25
+ Collected = 'collected',
26
+ Uncollected = 'uncollected',
27
+ Cancelled = 'cancelled',
19
28
  }
@@ -144,6 +144,7 @@ export interface WashdayClientInstance {
144
144
  bulkClean: typeof ordersEndpoints.putModule.bulkClean,
145
145
  bulkCollect: typeof ordersEndpoints.putModule.bulkCollect,
146
146
  cancelOrderByIdCustomersApp: typeof ordersEndpoints.deleteModule.cancelOrderByIdCustomersApp;
147
+ updateLineStatuses: typeof ordersEndpoints.patchModule.updateLineStatuses;
147
148
  };
148
149
  customers: {
149
150
  getCustomers: typeof customersEndpoints.getModule.getList;
@@ -313,6 +314,7 @@ export interface WashdayClientInstance {
313
314
  getDiscountCodesReport: typeof reportsExportEndpoints.getModule.getDiscountCodesReport;
314
315
  getStaffReport: typeof reportsExportEndpoints.getModule.getStaffReport;
315
316
  getProductSalesReport: typeof reportsExportEndpoints.getModule.getProductSalesReport;
317
+ getProductSalesDrillDown: typeof reportsExportEndpoints.getModule.getProductSalesDrillDown;
316
318
  getPaymentLinesReport: typeof reportsExportEndpoints.getModule.getPaymentLinesReport;
317
319
  getCashierBoxMovementsReport: typeof reportsExportEndpoints.getModule.getCashierBoxMovementsReport;
318
320
  getUnpaidOrdersReport: typeof reportsExportEndpoints.getModule.getUnpaidOrdersReport;
@@ -2,6 +2,7 @@ import { ICustomer } from "./Customer";
2
2
  import { IOrderProduct, IProduct } from "./Product";
3
3
  import { ICashierBox, IStore, IStoreDiscount, ITaxConfig } from "./Store";
4
4
  import { IUser } from "./User";
5
+ import { OrderProductLineStatus } from "../enum";
5
6
 
6
7
  interface IDeliveryInfo {
7
8
  date: Date,
@@ -102,6 +103,22 @@ export interface IOrder {
102
103
  }
103
104
 
104
105
 
106
+ /**
107
+ * A single line status update within a batch request.
108
+ * `status` cannot be 'created' — lines cannot be reset to initial state.
109
+ */
110
+ export interface IOrderLineStatusUpdate {
111
+ lineId: string;
112
+ status: Exclude<OrderProductLineStatus, OrderProductLineStatus.Created>;
113
+ }
114
+
115
+ /**
116
+ * Request body for PATCH /api/v2/order/:id/line-statuses
117
+ */
118
+ export interface IUpdateOrderLineStatusesDto {
119
+ updates: IOrderLineStatusUpdate[];
120
+ }
121
+
105
122
  export interface IOrderInfo {
106
123
  topProducts: IProduct[];
107
124
  sales: number;
@@ -1,6 +1,7 @@
1
1
  import { IStore } from "./Store"
2
2
  import { IStoreImage } from "./StoreImage"
3
3
  import { IUser } from "./User"
4
+ import { OrderProductLineStatus } from "../enum"
4
5
 
5
6
  export interface ProductLineTotals {
6
7
  product: IOrderProduct,
@@ -71,4 +72,17 @@ export interface IOrderProduct extends IProduct {
71
72
  isBuyAndGetProduct: boolean,
72
73
  storeProductId: IStoreProduct | string
73
74
  qty?: number
75
+
76
+ // Operational line-level status fields (added 2026-04-04)
77
+ status?: OrderProductLineStatus,
78
+ cleanedDateTime?: Date | null,
79
+ readyDateTime?: Date | null,
80
+ collectedDateTime?: Date | null,
81
+ uncollectedDateTime?: Date | null,
82
+ cancelledDateTime?: Date | null,
83
+ markedCleanedBy?: IUser | string | null,
84
+ markedReadyBy?: IUser | string | null,
85
+ markedCollectedBy?: IUser | string | null,
86
+ markedUncollectedBy?: IUser | string | null,
87
+ markedCancelledBy?: IUser | string | null,
74
88
  }
@@ -0,0 +1,74 @@
1
+ import {
2
+ ILabelTicketStructure,
3
+ ITicketForLaundryStructure,
4
+ ITicketStructure,
5
+ TicketVisualPreset,
6
+ } from "./Store";
7
+
8
+ const folioPreset: TicketVisualPreset = "large";
9
+ const spacingPreset: TicketVisualPreset = "medium";
10
+
11
+ const ticketStructure: ITicketStructure = {
12
+ showTotalPieces: false,
13
+ showEmisionDate: true,
14
+ showEmisionTime: true,
15
+ showLegend: true,
16
+ showPaymentMethod: true,
17
+ showStorePhone: true,
18
+ showCustomerPoints: false,
19
+ showDeliveryDate: true,
20
+ showDeliveryTime: true,
21
+ ticketLegendText: "Gracias",
22
+ showStoreName: true,
23
+ showCustomerName: true,
24
+ showCreatedByName: true,
25
+ showOrderNotes: false,
26
+ showTaxes: false,
27
+ showDiscounts: true,
28
+ showCredit: true,
29
+ customerNameFontSize: "small",
30
+ orderFolioFontSizePreset: folioPreset,
31
+ ticketLineSpacingPreset: spacingPreset,
32
+ ticketPrintFormat: "escpos",
33
+ };
34
+
35
+ const labelTicketStructure: ILabelTicketStructure = {
36
+ ...ticketStructure,
37
+ };
38
+
39
+ const ticketForLaundryStructure: ITicketForLaundryStructure = {
40
+ showTotalPieces: false,
41
+ showEmisionDate: true,
42
+ showEmisionTime: true,
43
+ showLegend: true,
44
+ showPaymentMethod: true,
45
+ showStorePhone: true,
46
+ showCustomerPoints: false,
47
+ showDeliveryDate: true,
48
+ showDeliveryTime: true,
49
+ ticketLegendText: "Gracias",
50
+ printLogoOnTicket: false,
51
+ showStoreName: true,
52
+ showCustomerName: true,
53
+ showCreatedByName: true,
54
+ showOrderNotes: false,
55
+ showTaxes: false,
56
+ showDiscounts: true,
57
+ showCredit: true,
58
+ customerNameFontSize: "medium",
59
+ orderFolioFontSizePreset: "large",
60
+ ticketLineSpacingPreset: "small",
61
+ ticketPrintFormat: "html",
62
+ };
63
+
64
+ if (ticketStructure.orderFolioFontSizePreset !== "large") {
65
+ throw new Error("Ticket structure folio preset was not preserved");
66
+ }
67
+
68
+ if (labelTicketStructure.ticketLineSpacingPreset !== "medium") {
69
+ throw new Error("Label ticket structure spacing preset was not preserved");
70
+ }
71
+
72
+ if (ticketForLaundryStructure.customerNameFontSize !== "medium") {
73
+ throw new Error("Laundry ticket structure customer font size was not preserved");
74
+ }
@@ -291,6 +291,7 @@ export interface IOrderPageConfig {
291
291
  }
292
292
 
293
293
  export type TicketPrintFormat = 'html' | 'escpos';
294
+ export type TicketVisualPreset = 'small' | 'medium' | 'large';
294
295
 
295
296
  export interface ITicketStructure {
296
297
  showTotalPieces: Boolean,
@@ -310,6 +311,9 @@ export interface ITicketStructure {
310
311
  showTaxes: Boolean,
311
312
  showDiscounts: Boolean,
312
313
  showCredit: Boolean,
314
+ customerNameFontSize?: TicketVisualPreset,
315
+ orderFolioFontSizePreset?: TicketVisualPreset,
316
+ ticketLineSpacingPreset?: TicketVisualPreset,
313
317
  ticketPrintFormat?: TicketPrintFormat,
314
318
  }
315
319
 
@@ -333,6 +337,9 @@ export interface ITicketForLaundryStructure {
333
337
  showTaxes: Boolean,
334
338
  showDiscounts: Boolean,
335
339
  showCredit: Boolean,
340
+ customerNameFontSize?: TicketVisualPreset,
341
+ orderFolioFontSizePreset?: TicketVisualPreset,
342
+ ticketLineSpacingPreset?: TicketVisualPreset,
336
343
  ticketPrintFormat?: TicketPrintFormat,
337
344
  }
338
345