washday-sdk 1.6.66 → 1.6.69

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.
@@ -136,6 +136,7 @@ export const payAndCollect = function (params) {
136
136
  headers: { Authorization: `Bearer ${this.apiToken}` }
137
137
  };
138
138
  return yield this.axiosInstance.post(PAY_AND_COLLECT(params.sequence, params.storeId), {
139
+ orderId: params.orderId,
139
140
  paymentMethod: params.paymentMethod,
140
141
  cashierBoxId: params.cashierBoxId,
141
142
  amount: params.amount,
@@ -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.69",
4
4
  "description": "Washday utilities functions and API",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -138,6 +138,7 @@ export const setOrderUncollected = async function (this: WashdayClientInstance,
138
138
  };
139
139
 
140
140
  export const payAndCollect = async function (this: WashdayClientInstance, params: {
141
+ orderId?: string;
141
142
  sequence: string;
142
143
  storeId: string;
143
144
  paymentMethod: string;
@@ -156,6 +157,7 @@ export const payAndCollect = async function (this: WashdayClientInstance, params
156
157
  return await this.axiosInstance.post(
157
158
  PAY_AND_COLLECT(params.sequence, params.storeId),
158
159
  {
160
+ orderId: params.orderId,
159
161
  paymentMethod: params.paymentMethod,
160
162
  cashierBoxId: params.cashierBoxId,
161
163
  amount: params.amount,
@@ -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}` }
@@ -57,6 +36,7 @@ export const updatePaymentLineById = async function (this: WashdayClientInstance
57
36
  };
58
37
 
59
38
  export const setOrderCancelledBySequence = async function (this: WashdayClientInstance, sequence: string, storeId: string, data: {
39
+ orderId?: string,
60
40
  cancelledDateTime: string
61
41
  }): Promise<any> {
62
42
  try {
@@ -103,6 +83,7 @@ export const setOrderCleanedBySequence = async function (this: WashdayClientInst
103
83
  };
104
84
 
105
85
  export const setOrderCollectedBySequence = async function (this: WashdayClientInstance, sequence: string, storeId: string, data: {
86
+ orderId?: string,
106
87
  collectedDateTime: string;
107
88
  collectWithAmountDue?: boolean,
108
89
  pinUserId?: string
@@ -221,4 +202,4 @@ export const bulkCollect = async function (this: WashdayClientInstance, storeId:
221
202
  console.error('Error fetching bulkCollect:', error);
222
203
  throw error;
223
204
  }
224
- };
205
+ };
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,49 @@
1
+ import { payAndCollect } from "../src/api/order/post";
2
+ import { setOrderCancelledBySequence } from "../src/api/order/put";
3
+
4
+ describe("orders orderId body fallback", () => {
5
+ it("sends orderId in payAndCollect body while keeping sequence/store route", async () => {
6
+ const post = jest.fn().mockResolvedValue({ data: { ok: true } });
7
+ const client = {
8
+ apiToken: "token-123",
9
+ axiosInstance: { post },
10
+ } as any;
11
+
12
+ await payAndCollect.call(client, {
13
+ orderId: "order-1",
14
+ sequence: "4",
15
+ storeId: "store-1",
16
+ paymentMethod: "card",
17
+ amount: 25,
18
+ });
19
+
20
+ expect(post).toHaveBeenCalledWith(
21
+ "/api/v2/order/4/store-1/pay-and-collect",
22
+ expect.objectContaining({ orderId: "order-1" }),
23
+ {
24
+ headers: { Authorization: "Bearer token-123" },
25
+ }
26
+ );
27
+ });
28
+
29
+ it("sends orderId in setOrderCancelledBySequence body", async () => {
30
+ const put = jest.fn().mockResolvedValue({ data: { data: true } });
31
+ const client = {
32
+ apiToken: "token-123",
33
+ axiosInstance: { put },
34
+ } as any;
35
+
36
+ await setOrderCancelledBySequence.call(client, "4", "store-1", {
37
+ orderId: "order-1",
38
+ cancelledDateTime: "2026-06-05T00:00:00.000Z",
39
+ });
40
+
41
+ expect(put).toHaveBeenCalledWith(
42
+ "api/order/4/store-1/cancelled",
43
+ expect.objectContaining({ orderId: "order-1" }),
44
+ {
45
+ headers: { Authorization: "Bearer token-123" },
46
+ }
47
+ );
48
+ });
49
+ });
@@ -0,0 +1,27 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+
4
+ const repoRoot = path.resolve(__dirname, "../../..");
5
+ const workflowPath = path.join(repoRoot, ".github/workflows/sdk-publish.yml");
6
+
7
+ describe("sdk publish workflow", () => {
8
+ it("is manually runnable and bumps patch before publishing", () => {
9
+ expect(fs.existsSync(workflowPath)).toBe(true);
10
+
11
+ const workflow = fs.readFileSync(workflowPath, "utf8");
12
+
13
+ expect(workflow).toContain("workflow_dispatch:");
14
+ expect(workflow).not.toContain("push:");
15
+ expect(workflow).toContain("contents: write");
16
+ expect(workflow).toContain("id-token: write");
17
+ expect(workflow).toContain("working-directory: packages/sdk");
18
+ expect(workflow).toContain("registry-url: https://registry.npmjs.org");
19
+ expect(workflow).toContain('npm view "$PACKAGE_NAME@$CURRENT_VERSION" version');
20
+ expect(workflow).toContain("npm version patch --no-git-tag-version");
21
+ expect(workflow).toContain("git commit -m \"chore(sdk): bump patch version for publish\"");
22
+ expect(workflow).toContain("git push origin HEAD:main");
23
+ expect(workflow).toContain("npm publish --access public --no-provenance");
24
+ expect(workflow).not.toContain("NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}");
25
+ expect(workflow).not.toContain('NPM_CONFIG_PROVENANCE: "false"');
26
+ });
27
+ });
@@ -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
+ });
@@ -1,58 +0,0 @@
1
- name: Bump Version on PR
2
-
3
- on:
4
- pull_request:
5
- types: [opened, synchronize, reopened]
6
- branches:
7
- - main
8
-
9
- permissions:
10
- contents: write
11
-
12
- jobs:
13
- bump-version:
14
- runs-on: ubuntu-latest
15
- if: github.event.pull_request.base.ref == 'main'
16
- steps:
17
- - name: Checkout repository
18
- uses: actions/checkout@v4
19
- with:
20
- ref: ${{ github.head_ref }}
21
- token: ${{ secrets.GITHUB_TOKEN }}
22
-
23
- - name: Use Node.js 24
24
- uses: actions/setup-node@v4
25
- with:
26
- node-version: 24
27
-
28
- - name: Configure git identity
29
- run: |
30
- git config --global user.name "washday-bot"
31
- git config --global user.email "ci@washday.dev"
32
-
33
- - name: Fetch main branch
34
- run: git fetch origin main:main
35
-
36
- - name: Check if version already bumped
37
- id: check_version
38
- run: |
39
- CURRENT_VERSION=$(node -p "require('./package.json').version")
40
- git show main:package.json > /tmp/main-package.json
41
- MAIN_VERSION=$(node -p "require('/tmp/main-package.json').version")
42
- echo "Current PR version: $CURRENT_VERSION"
43
- echo "Main branch version: $MAIN_VERSION"
44
- if [ "$CURRENT_VERSION" != "$MAIN_VERSION" ]; then
45
- echo "already_bumped=true" >> $GITHUB_OUTPUT
46
- echo "✅ Version already bumped in this PR"
47
- else
48
- echo "already_bumped=false" >> $GITHUB_OUTPUT
49
- echo "⚠️ Version needs bumping"
50
- fi
51
-
52
- - name: Bump version patch
53
- if: steps.check_version.outputs.already_bumped == 'false'
54
- run: |
55
- npm version patch --no-git-tag-version
56
- git add package.json package-lock.json
57
- git commit -m "chore: bump version [skip ci]"
58
- git push origin ${{ github.head_ref }}
@@ -1,35 +0,0 @@
1
- name: Publish SDK on Merge
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
-
8
- permissions:
9
- contents: read
10
- id-token: write # Required for OIDC
11
-
12
- jobs:
13
- publish:
14
- runs-on: ubuntu-latest
15
- environment: publish
16
- steps:
17
- - name: Checkout
18
- uses: actions/checkout@v4
19
-
20
- - name: Use Node.js 24
21
- uses: actions/setup-node@v4
22
- with:
23
- node-version: 24
24
-
25
- - name: Install dependencies
26
- run: npm ci
27
-
28
- - name: Clear NODE_AUTH_TOKEN for OIDC
29
- run: |
30
- unset NODE_AUTH_TOKEN || true
31
-
32
- - name: Build and publish
33
- run: npm run build && npm publish --access public --no-provenance --verbose
34
- env:
35
- NODE_AUTH_TOKEN: ""