washday-sdk 1.6.66 → 1.6.67

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.
@@ -18,6 +18,21 @@ export var PaymentMethodsEnum;
18
18
  PaymentMethodsEnum["Delivery"] = "delivery";
19
19
  PaymentMethodsEnum["Transfer"] = "transfer";
20
20
  })(PaymentMethodsEnum || (PaymentMethodsEnum = {}));
21
+ export var OrderStatusEnum;
22
+ (function (OrderStatusEnum) {
23
+ OrderStatusEnum["CREATED"] = "created";
24
+ OrderStatusEnum["REQUESTED"] = "requested";
25
+ OrderStatusEnum["PICKUP"] = "pickup";
26
+ OrderStatusEnum["PICKINGUP"] = "pickingup";
27
+ OrderStatusEnum["PENDING_STORE_RECEPTION_VALIDATION"] = "pending_store_reception_validation";
28
+ OrderStatusEnum["CLEANING"] = "cleaning";
29
+ OrderStatusEnum["READY"] = "ready";
30
+ OrderStatusEnum["DELIVERY"] = "delivery";
31
+ OrderStatusEnum["DELIVERING"] = "delivering";
32
+ OrderStatusEnum["COLLECTED"] = "collected";
33
+ OrderStatusEnum["CANCELLED"] = "cancelled";
34
+ OrderStatusEnum["UNCOLLECTED"] = "uncollected";
35
+ })(OrderStatusEnum || (OrderStatusEnum = {}));
21
36
  export var OrderProductLineStatus;
22
37
  (function (OrderProductLineStatus) {
23
38
  OrderProductLineStatus["Created"] = "created";
package/dist/index.js CHANGED
@@ -8,4 +8,9 @@ export * from './interfaces/Customer';
8
8
  export * from './interfaces/DomainUrls';
9
9
  export * from './interfaces/GoogleMaps';
10
10
  export * from './interfaces/Attendance';
11
+ export * from './interfaces/Order';
12
+ export * from './interfaces/Store';
13
+ export * from './interfaces/Permission';
14
+ export * from './interfaces/Route';
15
+ export * from './enum';
11
16
  export { WashdayClient, utils };
@@ -0,0 +1,62 @@
1
+ var _a, _b, _c;
2
+ import { OrderStatusEnum } from "../index";
3
+ const updatePayload = {
4
+ notes: "Peso confirmado en sucursal",
5
+ updateMode: "store_reception_validation",
6
+ };
7
+ const order = {
8
+ status: OrderStatusEnum.PENDING_STORE_RECEPTION_VALIDATION,
9
+ storeReceptionValidation: {
10
+ validatedAt: "2026-06-01T18:00:00.000Z",
11
+ validatedBy: "user-1",
12
+ source: "store_reception",
13
+ notes: "Validado en mostrador",
14
+ },
15
+ };
16
+ const permission = {
17
+ validateStoreReception: {
18
+ canMutate: true,
19
+ },
20
+ };
21
+ const store = {
22
+ storeReceptionValidationConfig: {
23
+ enabled: true,
24
+ restrictCloseRouteUntilStoreValidation: false,
25
+ },
26
+ };
27
+ const preview = {
28
+ routeId: "route-1",
29
+ canClose: true,
30
+ summary: {
31
+ confirmed: 0,
32
+ failed: 0,
33
+ cancelled: 0,
34
+ pendingActive: 0,
35
+ },
36
+ pendingActiveOrders: [],
37
+ requiresExplicitConfirmation: false,
38
+ hasPendingStoreReceptionValidations: true,
39
+ pendingStoreReceptionValidationOrdersCount: 1,
40
+ restrictCloseRouteUntilStoreValidation: false,
41
+ warnings: [
42
+ "Esta ruta tiene pedidos pendientes de validar en sucursal.",
43
+ ],
44
+ };
45
+ if (OrderStatusEnum.PENDING_STORE_RECEPTION_VALIDATION !== "pending_store_reception_validation") {
46
+ throw new Error("Pending store reception validation order status is not exported");
47
+ }
48
+ if (updatePayload.updateMode !== "store_reception_validation") {
49
+ throw new Error("Store reception validation update mode is not accepted");
50
+ }
51
+ if (((_a = order.storeReceptionValidation) === null || _a === void 0 ? void 0 : _a.source) !== "store_reception") {
52
+ throw new Error("Order store reception validation source was not preserved");
53
+ }
54
+ if (((_b = permission.validateStoreReception) === null || _b === void 0 ? void 0 : _b.canMutate) !== true) {
55
+ throw new Error("Validate store reception permission was not preserved");
56
+ }
57
+ if (((_c = store.storeReceptionValidationConfig) === null || _c === void 0 ? void 0 : _c.enabled) !== true) {
58
+ throw new Error("Store reception validation config was not preserved");
59
+ }
60
+ if (preview.pendingStoreReceptionValidationOrdersCount !== 1) {
61
+ throw new Error("Route close preview pending validation count was not preserved");
62
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "washday-sdk",
3
- "version": "1.6.66",
3
+ "version": "1.6.67",
4
4
  "description": "Washday utilities functions and API",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -1,34 +1,13 @@
1
1
  import { AxiosResponse } from "axios";
2
2
  import { WashdayClientInstance } from "../../interfaces/Api";
3
+ import { IUpdateOrderByIdDto } from "../../interfaces/Order";
3
4
  import axiosInstance from "../axiosInstance";
4
5
  import { generateQueryParamsStr } from "../../utils/apiUtils";
5
6
  const GET_SET_ORDER = 'api/v2/order';
6
7
  const GET_SET_ORDER_OLD = 'api/order';
7
8
  const GET_SET_ORDER_PAYMENTLINES = (orderId: string) => `/api/v2/order/${orderId}/paymentLines`;
8
9
 
9
- export const updateById = async function (this: WashdayClientInstance, id: string, data: {
10
- status?: string,
11
- products?: any[],
12
- buyAndGetProducts?: any[],
13
- customer?: string,
14
- discountCode?: string | null,
15
- notes?: string,
16
- privateNotes?: string,
17
- delivery?: boolean,
18
- pickup?: boolean,
19
- express?: boolean,
20
- deliveryInfo?: {
21
- date: Date,
22
- fromTime: string,
23
- toTime?: string
24
- },
25
- pickupInfo?: {
26
- date: Date,
27
- fromTime: string,
28
- toTime?: string
29
- },
30
- notifyBy?: string,
31
- }): Promise<any> {
10
+ export const updateById = async function (this: WashdayClientInstance, id: string, data: IUpdateOrderByIdDto): Promise<any> {
32
11
  try {
33
12
  const config = {
34
13
  headers: { Authorization: `Bearer ${this.apiToken}` }
@@ -221,4 +200,4 @@ export const bulkCollect = async function (this: WashdayClientInstance, storeId:
221
200
  console.error('Error fetching bulkCollect:', error);
222
201
  throw error;
223
202
  }
224
- };
203
+ };
package/src/enum/index.ts CHANGED
@@ -18,6 +18,21 @@ export enum PaymentMethodsEnum {
18
18
  Transfer = "transfer",
19
19
  }
20
20
 
21
+ export enum OrderStatusEnum {
22
+ CREATED = 'created',
23
+ REQUESTED = 'requested',
24
+ PICKUP = 'pickup',
25
+ PICKINGUP = 'pickingup',
26
+ PENDING_STORE_RECEPTION_VALIDATION = 'pending_store_reception_validation',
27
+ CLEANING = 'cleaning',
28
+ READY = 'ready',
29
+ DELIVERY = 'delivery',
30
+ DELIVERING = 'delivering',
31
+ COLLECTED = 'collected',
32
+ CANCELLED = 'cancelled',
33
+ UNCOLLECTED = 'uncollected',
34
+ }
35
+
21
36
  export enum OrderProductLineStatus {
22
37
  Created = 'created',
23
38
  Cleaning = 'cleaning',
@@ -25,4 +40,4 @@ export enum OrderProductLineStatus {
25
40
  Collected = 'collected',
26
41
  Uncollected = 'uncollected',
27
42
  Cancelled = 'cancelled',
28
- }
43
+ }
package/src/index.ts CHANGED
@@ -8,13 +8,11 @@ export * from './interfaces/Customer';
8
8
  export * from './interfaces/DomainUrls';
9
9
  export * from './interfaces/GoogleMaps';
10
10
  export * from './interfaces/Attendance';
11
- export type {
12
- IOrderPricingSnapshot,
13
- IOrderPricingSnapshotLine,
14
- IOrderPricingSnapshotTotals,
15
- ITaxBreakdownItem,
16
- TaxBreakdownKey,
17
- } from './interfaces/Order';
11
+ export * from './interfaces/Order';
12
+ export * from './interfaces/Store';
13
+ export * from './interfaces/Permission';
14
+ export * from './interfaces/Route';
15
+ export * from './enum';
18
16
  export type { StartMPOAuthFlowRequest } from './api/integrations/post';
19
17
  export type {
20
18
  CreateCFDISubscriptionCheckoutSessionRequest,
@@ -2,7 +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
+ import { OrderProductLineStatus, OrderStatusEnum } from "../enum";
6
6
  import { RouteOrderCompletionSource } from "./Route";
7
7
 
8
8
  interface IDeliveryInfo {
@@ -34,6 +34,20 @@ export interface IFailedServiceAttemptPayload {
34
34
  images?: string[];
35
35
  }
36
36
 
37
+ export type OrderStatus = OrderStatusEnum | (string & {});
38
+
39
+ export type StoreReceptionValidationSource =
40
+ | "store_reception"
41
+ | "route_pickup_handoff"
42
+ | "legacy_unknown";
43
+
44
+ export interface IOrderStoreReceptionValidation {
45
+ validatedAt?: string | Date | null;
46
+ validatedBy?: string | null;
47
+ source?: StoreReceptionValidationSource | null;
48
+ notes?: string;
49
+ }
50
+
37
51
  export interface IOrderPaymentLines {
38
52
  _id?: any,
39
53
  amountPaid: number,
@@ -161,11 +175,12 @@ export interface IOrder {
161
175
  paidDateTime: Date | null,
162
176
  paymentMethod: string | null
163
177
  prepaidPaymentMethod: string | null
164
- status: string,
178
+ status: OrderStatus,
165
179
  pickupRoute: string | null,
166
180
  deliveryRoute: string | null,
167
181
  pickupCompletion?: IOrderPhaseCompletion | null,
168
182
  deliveryCompletion?: IOrderPhaseCompletion | null,
183
+ storeReceptionValidation?: IOrderStoreReceptionValidation,
169
184
  sequence?: string | null,
170
185
  notifyBy: string,
171
186
  stripePaymentIntentId?: string | null,
@@ -180,6 +195,33 @@ export interface IOrder {
180
195
  pricingSnapshot?: IOrderPricingSnapshot | null,
181
196
  }
182
197
 
198
+ export type OrderUpdateMode = "store_reception_validation";
199
+
200
+ export interface IUpdateOrderByIdDto {
201
+ status?: OrderStatus,
202
+ products?: any[],
203
+ buyAndGetProducts?: any[],
204
+ customer?: string,
205
+ discountCode?: string | null,
206
+ notes?: string,
207
+ privateNotes?: string,
208
+ delivery?: boolean,
209
+ pickup?: boolean,
210
+ express?: boolean,
211
+ deliveryInfo?: {
212
+ date: Date,
213
+ fromTime: string,
214
+ toTime?: string
215
+ },
216
+ pickupInfo?: {
217
+ date: Date,
218
+ fromTime: string,
219
+ toTime?: string
220
+ },
221
+ notifyBy?: string,
222
+ updateMode?: OrderUpdateMode,
223
+ }
224
+
183
225
 
184
226
  /**
185
227
  * A single line status update within a batch request.
@@ -230,7 +272,7 @@ export interface OrderDto {
230
272
  collectedDateTime: Date | null,
231
273
  cancelledDateTime: Date | null,
232
274
  paidDateTime: Date | null,
233
- status: string,
275
+ status: OrderStatus,
234
276
  store: string,
235
277
  paymentMethod: string | null,
236
278
  prepaidAmount: number | null,
@@ -15,6 +15,7 @@ export interface IPermission {
15
15
  canEditOrders: IPermissionMutationType,
16
16
  canManageAttendance: IPermissionMutationType,
17
17
  mutateOrderPayments: IPermissionMutationType,
18
+ validateStoreReception?: IPermissionMutationType,
18
19
  markOrderAsCollectedWithPendingAmount: IPermissionMutationType,
19
20
  markOrderAsUncollected: IPermissionMutationType,
20
21
  cancelOrders: IPermissionMutationType,
@@ -1,6 +1,6 @@
1
- import { IOrder } from "./Order";
2
- import { IStore } from "./Store";
3
- import { IUser } from "./User";
1
+ import type { IOrder, OrderStatus } from "./Order";
2
+ import type { IStore } from "./Store";
3
+ import type { IUser } from "./User";
4
4
 
5
5
  export type RouteStatus = "created" | "in_progress" | "finished" | "cancelled";
6
6
  export type RouteOrderType = "pickup" | "delivery" | "legacy_unknown";
@@ -54,8 +54,8 @@ export interface IRouteClosePreviewPendingOrder {
54
54
  orderId: string;
55
55
  type: RouteOrderType;
56
56
  sequence?: string | number | null;
57
- status?: string | null;
58
- willBecome?: string | null;
57
+ status?: OrderStatus | null;
58
+ willBecome?: OrderStatus | null;
59
59
  }
60
60
 
61
61
  export interface IRouteClosePreview {
@@ -69,4 +69,8 @@ export interface IRouteClosePreview {
69
69
  };
70
70
  pendingActiveOrders: IRouteClosePreviewPendingOrder[];
71
71
  requiresExplicitConfirmation: boolean;
72
+ hasPendingStoreReceptionValidations?: boolean;
73
+ pendingStoreReceptionValidationOrdersCount?: number;
74
+ restrictCloseRouteUntilStoreValidation?: boolean;
75
+ warnings?: string[];
72
76
  }
@@ -52,6 +52,11 @@ export interface IPublicReceiptConfig {
52
52
  showEvidence?: boolean
53
53
  }
54
54
 
55
+ export interface IStoreReceptionValidationConfig {
56
+ enabled: boolean,
57
+ restrictCloseRouteUntilStoreValidation: boolean,
58
+ }
59
+
55
60
  export interface IStore {
56
61
  name: string,
57
62
  streetAddress?: string,
@@ -90,6 +95,7 @@ export interface IStore {
90
95
  ticketForLaundryStructure?: ITicketForLaundryStructure | null,
91
96
  labelTicketStructure?: ILabelTicketStructure | null,
92
97
  publicReceiptConfig?: IPublicReceiptConfig,
98
+ storeReceptionValidationConfig?: IStoreReceptionValidationConfig,
93
99
  ticketScanMode?: 'order' | 'customer',
94
100
  storeDiscounts: IStoreDiscount | null,
95
101
  discountCodes: IDiscountCode | null,
@@ -0,0 +1,79 @@
1
+ import { OrderStatusEnum } from "../index";
2
+ import type {
3
+ IOrder,
4
+ IPermission,
5
+ IRouteClosePreview,
6
+ IStore,
7
+ IUpdateOrderByIdDto,
8
+ } from "../index";
9
+
10
+ const updatePayload: IUpdateOrderByIdDto = {
11
+ notes: "Peso confirmado en sucursal",
12
+ updateMode: "store_reception_validation",
13
+ };
14
+
15
+ const order: Partial<IOrder> = {
16
+ status: OrderStatusEnum.PENDING_STORE_RECEPTION_VALIDATION,
17
+ storeReceptionValidation: {
18
+ validatedAt: "2026-06-01T18:00:00.000Z",
19
+ validatedBy: "user-1",
20
+ source: "store_reception",
21
+ notes: "Validado en mostrador",
22
+ },
23
+ };
24
+
25
+ const permission: Partial<IPermission> = {
26
+ validateStoreReception: {
27
+ canMutate: true,
28
+ },
29
+ };
30
+
31
+ const store: Partial<IStore> = {
32
+ storeReceptionValidationConfig: {
33
+ enabled: true,
34
+ restrictCloseRouteUntilStoreValidation: false,
35
+ },
36
+ };
37
+
38
+ const preview: IRouteClosePreview = {
39
+ routeId: "route-1",
40
+ canClose: true,
41
+ summary: {
42
+ confirmed: 0,
43
+ failed: 0,
44
+ cancelled: 0,
45
+ pendingActive: 0,
46
+ },
47
+ pendingActiveOrders: [],
48
+ requiresExplicitConfirmation: false,
49
+ hasPendingStoreReceptionValidations: true,
50
+ pendingStoreReceptionValidationOrdersCount: 1,
51
+ restrictCloseRouteUntilStoreValidation: false,
52
+ warnings: [
53
+ "Esta ruta tiene pedidos pendientes de validar en sucursal.",
54
+ ],
55
+ };
56
+
57
+ if (OrderStatusEnum.PENDING_STORE_RECEPTION_VALIDATION !== "pending_store_reception_validation") {
58
+ throw new Error("Pending store reception validation order status is not exported");
59
+ }
60
+
61
+ if (updatePayload.updateMode !== "store_reception_validation") {
62
+ throw new Error("Store reception validation update mode is not accepted");
63
+ }
64
+
65
+ if (order.storeReceptionValidation?.source !== "store_reception") {
66
+ throw new Error("Order store reception validation source was not preserved");
67
+ }
68
+
69
+ if (permission.validateStoreReception?.canMutate !== true) {
70
+ throw new Error("Validate store reception permission was not preserved");
71
+ }
72
+
73
+ if (store.storeReceptionValidationConfig?.enabled !== true) {
74
+ throw new Error("Store reception validation config was not preserved");
75
+ }
76
+
77
+ if (preview.pendingStoreReceptionValidationOrdersCount !== 1) {
78
+ throw new Error("Route close preview pending validation count was not preserved");
79
+ }
@@ -0,0 +1,89 @@
1
+ import { updateById } from "../src/api/order/put";
2
+ import { OrderStatusEnum } from "../src";
3
+ import type {
4
+ IOrder,
5
+ IPermission,
6
+ IRouteClosePreview,
7
+ IStore,
8
+ IUpdateOrderByIdDto,
9
+ } from "../src";
10
+
11
+ describe("store reception validation SDK contract", () => {
12
+ it("exposes store reception validation contracts from the root package", () => {
13
+ const updatePayload: IUpdateOrderByIdDto = {
14
+ notes: "Peso confirmado en sucursal",
15
+ updateMode: "store_reception_validation",
16
+ };
17
+ const order: Partial<IOrder> = {
18
+ status: OrderStatusEnum.PENDING_STORE_RECEPTION_VALIDATION,
19
+ storeReceptionValidation: {
20
+ validatedAt: "2026-06-01T18:00:00.000Z",
21
+ validatedBy: "user-1",
22
+ source: "store_reception",
23
+ notes: "Validado en mostrador",
24
+ },
25
+ };
26
+ const permission: Partial<IPermission> = {
27
+ validateStoreReception: {
28
+ canMutate: true,
29
+ },
30
+ };
31
+ const store: Partial<IStore> = {
32
+ storeReceptionValidationConfig: {
33
+ enabled: true,
34
+ restrictCloseRouteUntilStoreValidation: false,
35
+ },
36
+ };
37
+ const preview: IRouteClosePreview = {
38
+ routeId: "route-1",
39
+ canClose: true,
40
+ summary: {
41
+ confirmed: 0,
42
+ failed: 0,
43
+ cancelled: 0,
44
+ pendingActive: 0,
45
+ },
46
+ pendingActiveOrders: [],
47
+ requiresExplicitConfirmation: false,
48
+ hasPendingStoreReceptionValidations: true,
49
+ pendingStoreReceptionValidationOrdersCount: 1,
50
+ restrictCloseRouteUntilStoreValidation: false,
51
+ warnings: [
52
+ "Esta ruta tiene pedidos pendientes de validar en sucursal.",
53
+ ],
54
+ };
55
+
56
+ expect(OrderStatusEnum.PENDING_STORE_RECEPTION_VALIDATION).toBe(
57
+ "pending_store_reception_validation"
58
+ );
59
+ expect(updatePayload.updateMode).toBe("store_reception_validation");
60
+ expect(order.storeReceptionValidation?.source).toBe("store_reception");
61
+ expect(permission.validateStoreReception?.canMutate).toBe(true);
62
+ expect(store.storeReceptionValidationConfig?.enabled).toBe(true);
63
+ expect(preview.pendingStoreReceptionValidationOrdersCount).toBe(1);
64
+ });
65
+
66
+ it("passes store reception validation update mode through updateById unchanged", async () => {
67
+ const put = jest.fn().mockResolvedValue({
68
+ data: {
69
+ data: {
70
+ _id: "order-1",
71
+ },
72
+ },
73
+ });
74
+ const client = {
75
+ apiToken: "token-123",
76
+ axiosInstance: { put },
77
+ } as any;
78
+ const payload: IUpdateOrderByIdDto = {
79
+ notes: "Peso ajustado",
80
+ updateMode: "store_reception_validation",
81
+ };
82
+
83
+ await updateById.call(client, "order-1", payload);
84
+
85
+ expect(put).toHaveBeenCalledWith("api/v2/order/order-1", payload, {
86
+ headers: { Authorization: "Bearer token-123" },
87
+ });
88
+ });
89
+ });