@floristcloud/api-lib 1.2.137 → 1.2.138
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/build/commands/order-product/group/price-correction-analyze.command.js +4 -0
- package/build/commands/order-product/group/price-correction-execute.command.js +26 -3
- package/build/constant/error.js +19 -0
- package/build/schemas/index.js +1 -0
- package/build/schemas/order-product/price-correction-execute-order-item.schema.js +12 -0
- package/commands/order-product/group/price-correction-analyze.command.ts +4 -0
- package/commands/order-product/group/price-correction-execute.command.ts +32 -5
- package/constant/error.ts +19 -0
- package/package.json +1 -1
- package/schemas/index.ts +1 -0
- package/schemas/order-product/price-correction-execute-order-item.schema.ts +10 -0
|
@@ -7,6 +7,10 @@ const PriceCorrectionAnalyzeRequestSchema = zod_1.z
|
|
|
7
7
|
.object({
|
|
8
8
|
productUUIDList: zod_1.z.array(zod_1.z.string().uuid()).optional(),
|
|
9
9
|
consignmentUUID: zod_1.z.string().uuid().optional(),
|
|
10
|
+
// Поставка на сотни товаров даёт десятки тысяч позиций, из которых после правки прайса
|
|
11
|
+
// меняются единицы. По умолчанию отдаём только те, где цена реально расходится; полный
|
|
12
|
+
// список — режим «показать всё».
|
|
13
|
+
onlyChanged: zod_1.z.boolean().optional().default(true),
|
|
10
14
|
})
|
|
11
15
|
.refine(data => { var _a; return ((_a = data.productUUIDList) === null || _a === void 0 ? void 0 : _a.length) || data.consignmentUUID; }, {
|
|
12
16
|
message: 'validation.productListOrConsignment',
|
|
@@ -4,14 +4,37 @@ exports.PriceCorrectionExecuteContractCommand = void 0;
|
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
const schemas_1 = require("../../../schemas");
|
|
6
6
|
const PRICE_CORRECTION_BATCH_LIMIT = 50;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Две формы адресации, ровно одна на запрос.
|
|
9
|
+
*
|
|
10
|
+
* `orderProductUUIDList` — точечная правка выбранных позиций (экран заказа), лимит остаётся.
|
|
11
|
+
* Scope (`consignmentUUID` / `productUUIDList` + `excludeOrderProductUUIDList`) — «выровнять всё,
|
|
12
|
+
* кроме снятого»: набор собирает сервер тем же правилом, что и analyze, поэтому размер запроса не
|
|
13
|
+
* зависит от числа позиций и нарезка на пачки на клиенте не нужна.
|
|
14
|
+
*/
|
|
15
|
+
const PriceCorrectionExecuteRequestSchema = zod_1.z
|
|
16
|
+
.object({
|
|
17
|
+
orderProductUUIDList: zod_1.z.array(zod_1.z.string().uuid()).min(1).max(PRICE_CORRECTION_BATCH_LIMIT).optional(),
|
|
18
|
+
consignmentUUID: zod_1.z.string().uuid().optional(),
|
|
19
|
+
productUUIDList: zod_1.z.array(zod_1.z.string().uuid()).min(1).optional(),
|
|
20
|
+
excludeOrderProductUUIDList: zod_1.z.array(zod_1.z.string().uuid()).optional(),
|
|
21
|
+
onlyChanged: zod_1.z.boolean().optional().default(true),
|
|
9
22
|
withDiscount: zod_1.z.boolean(),
|
|
10
|
-
})
|
|
23
|
+
})
|
|
24
|
+
.refine(data => {
|
|
25
|
+
var _a, _b;
|
|
26
|
+
const isListForm = Boolean((_a = data.orderProductUUIDList) === null || _a === void 0 ? void 0 : _a.length);
|
|
27
|
+
const isScopeForm = Boolean(data.consignmentUUID) || Boolean((_b = data.productUUIDList) === null || _b === void 0 ? void 0 : _b.length);
|
|
28
|
+
return isListForm !== isScopeForm;
|
|
29
|
+
}, { message: 'validation.orderProductListOrScope' });
|
|
11
30
|
const PriceCorrectionExecuteResponseSchema = zod_1.z.object({
|
|
12
31
|
message: zod_1.z.string().optional(),
|
|
13
32
|
data: zod_1.z.object({
|
|
33
|
+
// Форма `orderProductUUIDList` — строка на каждую позицию запроса. Scope-форма — только
|
|
34
|
+
// строки, потребовавшие внимания (ошибки и пропуски): успешных там тысячи, и клиент всё
|
|
35
|
+
// равно перезапрашивает analyze, чтобы обновить таблицу.
|
|
14
36
|
results: zod_1.z.array(schemas_1.PriceCorrectionExecuteResultItemSchema),
|
|
37
|
+
orders: zod_1.z.array(schemas_1.PriceCorrectionExecuteOrderItemSchema),
|
|
15
38
|
successCount: zod_1.z.number(),
|
|
16
39
|
skippedCount: zod_1.z.number(),
|
|
17
40
|
}),
|
package/build/constant/error.js
CHANGED
|
@@ -552,6 +552,25 @@ exports.ERRORS = {
|
|
|
552
552
|
message: 'Source and destination orders must differ',
|
|
553
553
|
httpCode: 400,
|
|
554
554
|
},
|
|
555
|
+
// Статус заказа проверяется до отправки пакета и ещё раз внутри транзакции под блокировкой.
|
|
556
|
+
// Этот код — про вторую проверку: статус сменили, пока пакет ждал строку заказа.
|
|
557
|
+
ORDER_PRODUCT_PRICE_APPLY_ORDER_STATUS_CHANGED: {
|
|
558
|
+
code: 'OP026',
|
|
559
|
+
message: 'Order status changed and no longer allows price change',
|
|
560
|
+
httpCode: 409,
|
|
561
|
+
},
|
|
562
|
+
ORDER_PRODUCT_PRICE_CORRECTION_ALREADY_RUNNING: {
|
|
563
|
+
code: 'OP027',
|
|
564
|
+
message: 'Price correction for this consignment is already in progress',
|
|
565
|
+
httpCode: 409,
|
|
566
|
+
},
|
|
567
|
+
// Redis недоступен, то есть исключительность прогона гарантировать нечем. Коррекция поставки
|
|
568
|
+
// переписывает цены во всех заказах партии — тут отказ безопаснее, чем прогон вслепую.
|
|
569
|
+
ORDER_PRODUCT_PRICE_CORRECTION_LOCK_UNAVAILABLE: {
|
|
570
|
+
code: 'OP028',
|
|
571
|
+
message: 'Cannot guarantee exclusive price correction right now, try again later',
|
|
572
|
+
httpCode: 503,
|
|
573
|
+
},
|
|
555
574
|
//TRANSACTION
|
|
556
575
|
TRANSACTION_NOT_CREATED: { code: 'TR001', message: 'Failed to transaction product', httpCode: 500 },
|
|
557
576
|
TRANSACTION_FETCH_FAILED: { code: 'TR002', message: 'Error when retrieving a transaction', httpCode: 500 },
|
package/build/schemas/index.js
CHANGED
|
@@ -30,6 +30,7 @@ __exportStar(require("./order-product/order-product-list.schema"), exports);
|
|
|
30
30
|
__exportStar(require("./order-product/order-product-multiplicity-optiom.schema"), exports);
|
|
31
31
|
__exportStar(require("./order-product/price-correction-analyze-item.schema"), exports);
|
|
32
32
|
__exportStar(require("./order-product/price-correction-execute-result-item.schema"), exports);
|
|
33
|
+
__exportStar(require("./order-product/price-correction-execute-order-item.schema"), exports);
|
|
33
34
|
__exportStar(require("./transaction/transaction.schema"), exports);
|
|
34
35
|
__exportStar(require("./transaction/transaction-list.schema"), exports);
|
|
35
36
|
__exportStar(require("./cash-flow-item/cash-flow-item.schema"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PriceCorrectionExecuteOrderItemSchema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
// Итог коррекции по одному заказу. Ради него ответ scope-формы не обязан нести строку на позицию:
|
|
6
|
+
// на тысяче позиций постраничный разбор клиенту не нужен, нужна сводка «в каком заказе что вышло».
|
|
7
|
+
exports.PriceCorrectionExecuteOrderItemSchema = zod_1.z.object({
|
|
8
|
+
orderUUID: zod_1.z.string(),
|
|
9
|
+
orderNumber: zod_1.z.number(),
|
|
10
|
+
successCount: zod_1.z.number(),
|
|
11
|
+
skippedCount: zod_1.z.number(),
|
|
12
|
+
});
|
|
@@ -5,6 +5,10 @@ const PriceCorrectionAnalyzeRequestSchema = z
|
|
|
5
5
|
.object({
|
|
6
6
|
productUUIDList: z.array(z.string().uuid()).optional(),
|
|
7
7
|
consignmentUUID: z.string().uuid().optional(),
|
|
8
|
+
// Поставка на сотни товаров даёт десятки тысяч позиций, из которых после правки прайса
|
|
9
|
+
// меняются единицы. По умолчанию отдаём только те, где цена реально расходится; полный
|
|
10
|
+
// список — режим «показать всё».
|
|
11
|
+
onlyChanged: z.boolean().optional().default(true),
|
|
8
12
|
})
|
|
9
13
|
.refine(data => data.productUUIDList?.length || data.consignmentUUID, {
|
|
10
14
|
message: 'validation.productListOrConsignment',
|
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { PriceCorrectionExecuteResultItemSchema } from '../../../schemas';
|
|
2
|
+
import { PriceCorrectionExecuteOrderItemSchema, PriceCorrectionExecuteResultItemSchema } from '../../../schemas';
|
|
3
3
|
|
|
4
4
|
const PRICE_CORRECTION_BATCH_LIMIT = 50;
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Две формы адресации, ровно одна на запрос.
|
|
8
|
+
*
|
|
9
|
+
* `orderProductUUIDList` — точечная правка выбранных позиций (экран заказа), лимит остаётся.
|
|
10
|
+
* Scope (`consignmentUUID` / `productUUIDList` + `excludeOrderProductUUIDList`) — «выровнять всё,
|
|
11
|
+
* кроме снятого»: набор собирает сервер тем же правилом, что и analyze, поэтому размер запроса не
|
|
12
|
+
* зависит от числа позиций и нарезка на пачки на клиенте не нужна.
|
|
13
|
+
*/
|
|
14
|
+
const PriceCorrectionExecuteRequestSchema = z
|
|
15
|
+
.object({
|
|
16
|
+
orderProductUUIDList: z.array(z.string().uuid()).min(1).max(PRICE_CORRECTION_BATCH_LIMIT).optional(),
|
|
17
|
+
|
|
18
|
+
consignmentUUID: z.string().uuid().optional(),
|
|
19
|
+
productUUIDList: z.array(z.string().uuid()).min(1).optional(),
|
|
20
|
+
excludeOrderProductUUIDList: z.array(z.string().uuid()).optional(),
|
|
21
|
+
onlyChanged: z.boolean().optional().default(true),
|
|
22
|
+
|
|
23
|
+
withDiscount: z.boolean(),
|
|
24
|
+
})
|
|
25
|
+
.refine(
|
|
26
|
+
data => {
|
|
27
|
+
const isListForm = Boolean(data.orderProductUUIDList?.length);
|
|
28
|
+
const isScopeForm = Boolean(data.consignmentUUID) || Boolean(data.productUUIDList?.length);
|
|
29
|
+
return isListForm !== isScopeForm;
|
|
30
|
+
},
|
|
31
|
+
{ message: 'validation.orderProductListOrScope' },
|
|
32
|
+
);
|
|
10
33
|
|
|
11
34
|
const PriceCorrectionExecuteResponseSchema = z.object({
|
|
12
35
|
message: z.string().optional(),
|
|
13
36
|
data: z.object({
|
|
37
|
+
// Форма `orderProductUUIDList` — строка на каждую позицию запроса. Scope-форма — только
|
|
38
|
+
// строки, потребовавшие внимания (ошибки и пропуски): успешных там тысячи, и клиент всё
|
|
39
|
+
// равно перезапрашивает analyze, чтобы обновить таблицу.
|
|
14
40
|
results: z.array(PriceCorrectionExecuteResultItemSchema),
|
|
41
|
+
orders: z.array(PriceCorrectionExecuteOrderItemSchema),
|
|
15
42
|
successCount: z.number(),
|
|
16
43
|
skippedCount: z.number(),
|
|
17
44
|
}),
|
package/constant/error.ts
CHANGED
|
@@ -570,6 +570,25 @@ export const ERRORS = {
|
|
|
570
570
|
message: 'Source and destination orders must differ',
|
|
571
571
|
httpCode: 400,
|
|
572
572
|
},
|
|
573
|
+
// Статус заказа проверяется до отправки пакета и ещё раз внутри транзакции под блокировкой.
|
|
574
|
+
// Этот код — про вторую проверку: статус сменили, пока пакет ждал строку заказа.
|
|
575
|
+
ORDER_PRODUCT_PRICE_APPLY_ORDER_STATUS_CHANGED: {
|
|
576
|
+
code: 'OP026',
|
|
577
|
+
message: 'Order status changed and no longer allows price change',
|
|
578
|
+
httpCode: 409,
|
|
579
|
+
},
|
|
580
|
+
ORDER_PRODUCT_PRICE_CORRECTION_ALREADY_RUNNING: {
|
|
581
|
+
code: 'OP027',
|
|
582
|
+
message: 'Price correction for this consignment is already in progress',
|
|
583
|
+
httpCode: 409,
|
|
584
|
+
},
|
|
585
|
+
// Redis недоступен, то есть исключительность прогона гарантировать нечем. Коррекция поставки
|
|
586
|
+
// переписывает цены во всех заказах партии — тут отказ безопаснее, чем прогон вслепую.
|
|
587
|
+
ORDER_PRODUCT_PRICE_CORRECTION_LOCK_UNAVAILABLE: {
|
|
588
|
+
code: 'OP028',
|
|
589
|
+
message: 'Cannot guarantee exclusive price correction right now, try again later',
|
|
590
|
+
httpCode: 503,
|
|
591
|
+
},
|
|
573
592
|
|
|
574
593
|
//TRANSACTION
|
|
575
594
|
TRANSACTION_NOT_CREATED: { code: 'TR001', message: 'Failed to transaction product', httpCode: 500 },
|
package/package.json
CHANGED
package/schemas/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ export * from './order-product/order-product-list.schema';
|
|
|
14
14
|
export * from './order-product/order-product-multiplicity-optiom.schema';
|
|
15
15
|
export * from './order-product/price-correction-analyze-item.schema';
|
|
16
16
|
export * from './order-product/price-correction-execute-result-item.schema';
|
|
17
|
+
export * from './order-product/price-correction-execute-order-item.schema';
|
|
17
18
|
export * from './transaction/transaction.schema';
|
|
18
19
|
export * from './transaction/transaction-list.schema';
|
|
19
20
|
export * from './cash-flow-item/cash-flow-item.schema';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// Итог коррекции по одному заказу. Ради него ответ scope-формы не обязан нести строку на позицию:
|
|
4
|
+
// на тысяче позиций постраничный разбор клиенту не нужен, нужна сводка «в каком заказе что вышло».
|
|
5
|
+
export const PriceCorrectionExecuteOrderItemSchema = z.object({
|
|
6
|
+
orderUUID: z.string(),
|
|
7
|
+
orderNumber: z.number(),
|
|
8
|
+
successCount: z.number(),
|
|
9
|
+
skippedCount: z.number(),
|
|
10
|
+
});
|