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.
- package/dist/api/order/post.js +1 -0
- package/dist/enum/index.js +15 -0
- package/dist/index.js +5 -0
- package/dist/interfaces/StoreReceptionValidation.contract.test.js +62 -0
- package/package.json +1 -1
- package/src/api/order/post.ts +2 -0
- package/src/api/order/put.ts +5 -24
- package/src/enum/index.ts +16 -1
- package/src/index.ts +5 -7
- package/src/interfaces/Order.ts +45 -3
- package/src/interfaces/Permission.ts +1 -0
- package/src/interfaces/Route.ts +9 -5
- package/src/interfaces/Store.ts +6 -0
- package/src/interfaces/StoreReceptionValidation.contract.test.ts +79 -0
- package/test/orders.orderIdFallbackBody.test.ts +49 -0
- package/test/sdk.publishWorkflow.test.ts +27 -0
- package/test/storeReceptionValidation.contract.test.ts +89 -0
- package/.github/workflows/bump-version-pr.yml +0 -58
- package/.github/workflows/publish-on-merge.yml +0 -35
package/dist/api/order/post.js
CHANGED
|
@@ -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,
|
package/dist/enum/index.js
CHANGED
|
@@ -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
package/src/api/order/post.ts
CHANGED
|
@@ -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,
|
package/src/api/order/put.ts
CHANGED
|
@@ -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
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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,
|
package/src/interfaces/Order.ts
CHANGED
|
@@ -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:
|
|
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:
|
|
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,
|
package/src/interfaces/Route.ts
CHANGED
|
@@ -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?:
|
|
58
|
-
willBecome?:
|
|
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
|
}
|
package/src/interfaces/Store.ts
CHANGED
|
@@ -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: ""
|