@floristcloud/api-lib 1.2.98 → 1.2.100

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.
@@ -9,6 +9,24 @@ const GroupCreateOrdersFromPreOrdersRequestSchema = zod_1.z.object({
9
9
  matchingConfig: schemas_1.MatchingConfigSchema.optional().nullable(),
10
10
  isProportionalAllocation: zod_1.z.coerce.boolean().optional(),
11
11
  orderProductTag: zod_1.z.string().nullable().optional(),
12
+ /**
13
+ * The conversion the user confirmed in the preview. Without it the server re-runs the analysis
14
+ * and converts whatever it finds at that moment; with it the analysis is skipped and exactly
15
+ * these allocations are created. Carries product choice and quantity only — prices always stay
16
+ * server-side (product price + discount rules).
17
+ */
18
+ plan: zod_1.z
19
+ .object({
20
+ preOrderUUID: zod_1.z.uuid(),
21
+ lines: zod_1.z
22
+ .object({
23
+ preOrderProductUUID: zod_1.z.uuid(),
24
+ allocations: zod_1.z.object({ productUUID: zod_1.z.uuid(), quantity: zod_1.z.number().int().positive() }).array(),
25
+ })
26
+ .array(),
27
+ })
28
+ .array()
29
+ .optional(),
12
30
  });
13
31
  const GroupCreateOrdersFromPreOrdersResponseSchema = zod_1.z.object({
14
32
  message: zod_1.z.string().optional(),
@@ -42,6 +42,15 @@ exports.ErrorI18nKey = {
42
42
  preOrderConvertProductNotFound: 'preOrderConvert.productNotFound',
43
43
  preOrderConvertNotDistributed: 'preOrderConvert.notDistributed',
44
44
  preOrderConvertAlreadyExists: 'preOrderConvert.alreadyExists',
45
+ // Pre-order → order conversion plan validation
46
+ preOrderPlanMismatch: 'preOrderPlan.mismatch',
47
+ preOrderPlanDuplicatePreOrder: 'preOrderPlan.duplicatePreOrder',
48
+ preOrderPlanDuplicateItem: 'preOrderPlan.duplicateItem',
49
+ preOrderPlanDuplicateProduct: 'preOrderPlan.duplicateProduct',
50
+ preOrderPlanItemNotInPreOrder: 'preOrderPlan.itemNotInPreOrder',
51
+ preOrderPlanProductNotAvailable: 'preOrderPlan.productNotAvailable',
52
+ preOrderPlanQuantityMultiplicity: 'preOrderPlan.quantityMultiplicity',
53
+ preOrderPlanQuantityExceedsItem: 'preOrderPlan.quantityExceedsItem',
45
54
  // Category determination (import)
46
55
  categoryNotDetermined: 'category.notDetermined',
47
56
  // Standing-order import
@@ -750,6 +750,36 @@ exports.ERRORS = {
750
750
  PRE_ORDER_MERGE_HAS_EMPTY: { code: 'PO021', message: 'Some pre-orders are empty and will be deleted', httpCode: 400 },
751
751
  PRE_ORDER_MERGE_TAGS_CONCATENATE: { code: 'PO022', message: 'Pre-orders have different tags', httpCode: 400 },
752
752
  PRE_ORDER_MERGE_COMMENTS_CONCATENATE: { code: 'PO023', message: 'Pre-orders have different comments', httpCode: 400 },
753
+ PRE_ORDER_PLAN_MISMATCH: {
754
+ code: 'PO038',
755
+ message: 'Conversion plan must cover exactly the requested pre-orders',
756
+ httpCode: 400,
757
+ },
758
+ PRE_ORDER_PLAN_DUPLICATE_ENTRY: {
759
+ code: 'PO039',
760
+ message: 'Conversion plan contains duplicate entries',
761
+ httpCode: 400,
762
+ },
763
+ PRE_ORDER_PLAN_ITEM_NOT_IN_PRE_ORDER: {
764
+ code: 'PO040',
765
+ message: 'Planned item does not belong to its pre-order',
766
+ httpCode: 400,
767
+ },
768
+ PRE_ORDER_PLAN_PRODUCT_NOT_AVAILABLE: {
769
+ code: 'PO041',
770
+ message: 'Planned product does not belong to the selected consignments',
771
+ httpCode: 400,
772
+ },
773
+ PRE_ORDER_PLAN_QUANTITY_MULTIPLICITY: {
774
+ code: 'PO042',
775
+ message: 'Planned quantity does not respect product multiplicity',
776
+ httpCode: 400,
777
+ },
778
+ PRE_ORDER_PLAN_QUANTITY_EXCEEDS_ITEM: {
779
+ code: 'PO043',
780
+ message: 'Planned quantity exceeds the pre-order item quantity',
781
+ httpCode: 400,
782
+ },
753
783
  STANDING_ORDER_CLIENT_NAME_REQUIRED: {
754
784
  code: 'SO001',
755
785
  message: 'Standing order client name is required',
@@ -1286,6 +1316,11 @@ exports.ERRORS = {
1286
1316
  message: 'MoySklad sync lock is held by another job for this company; will retry shortly',
1287
1317
  httpCode: 409,
1288
1318
  },
1319
+ MOYSKLAD_ORDER_CREATE_LOCK_BUSY: {
1320
+ code: 'MS022',
1321
+ message: 'Another order is being created in MoySklad for this account; will retry shortly',
1322
+ httpCode: 409,
1323
+ },
1289
1324
  // 1C COMMERCEML INTEGRATION
1290
1325
  ONE_C_NOT_CONNECTED: { code: 'OC001', message: '1C integration is not connected for this company', httpCode: 404 },
1291
1326
  ONE_C_CONNECT_FAILED: { code: 'OC002', message: 'Failed to connect 1C integration', httpCode: 500 },
@@ -7,6 +7,24 @@ const GroupCreateOrdersFromPreOrdersRequestSchema = z.object({
7
7
  matchingConfig: MatchingConfigSchema.optional().nullable(),
8
8
  isProportionalAllocation: z.coerce.boolean().optional(),
9
9
  orderProductTag: z.string().nullable().optional(),
10
+ /**
11
+ * The conversion the user confirmed in the preview. Without it the server re-runs the analysis
12
+ * and converts whatever it finds at that moment; with it the analysis is skipped and exactly
13
+ * these allocations are created. Carries product choice and quantity only — prices always stay
14
+ * server-side (product price + discount rules).
15
+ */
16
+ plan: z
17
+ .object({
18
+ preOrderUUID: z.uuid(),
19
+ lines: z
20
+ .object({
21
+ preOrderProductUUID: z.uuid(),
22
+ allocations: z.object({ productUUID: z.uuid(), quantity: z.number().int().positive() }).array(),
23
+ })
24
+ .array(),
25
+ })
26
+ .array()
27
+ .optional(),
10
28
  });
11
29
 
12
30
  const GroupCreateOrdersFromPreOrdersResponseSchema = z.object({
@@ -42,6 +42,16 @@ export const ErrorI18nKey = {
42
42
  preOrderConvertNotDistributed: 'preOrderConvert.notDistributed',
43
43
  preOrderConvertAlreadyExists: 'preOrderConvert.alreadyExists',
44
44
 
45
+ // Pre-order → order conversion plan validation
46
+ preOrderPlanMismatch: 'preOrderPlan.mismatch',
47
+ preOrderPlanDuplicatePreOrder: 'preOrderPlan.duplicatePreOrder',
48
+ preOrderPlanDuplicateItem: 'preOrderPlan.duplicateItem',
49
+ preOrderPlanDuplicateProduct: 'preOrderPlan.duplicateProduct',
50
+ preOrderPlanItemNotInPreOrder: 'preOrderPlan.itemNotInPreOrder',
51
+ preOrderPlanProductNotAvailable: 'preOrderPlan.productNotAvailable',
52
+ preOrderPlanQuantityMultiplicity: 'preOrderPlan.quantityMultiplicity',
53
+ preOrderPlanQuantityExceedsItem: 'preOrderPlan.quantityExceedsItem',
54
+
45
55
  // Category determination (import)
46
56
  categoryNotDetermined: 'category.notDetermined',
47
57
 
package/constant/error.ts CHANGED
@@ -785,6 +785,36 @@ export const ERRORS = {
785
785
  PRE_ORDER_MERGE_HAS_EMPTY: { code: 'PO021', message: 'Some pre-orders are empty and will be deleted', httpCode: 400 },
786
786
  PRE_ORDER_MERGE_TAGS_CONCATENATE: { code: 'PO022', message: 'Pre-orders have different tags', httpCode: 400 },
787
787
  PRE_ORDER_MERGE_COMMENTS_CONCATENATE: { code: 'PO023', message: 'Pre-orders have different comments', httpCode: 400 },
788
+ PRE_ORDER_PLAN_MISMATCH: {
789
+ code: 'PO038',
790
+ message: 'Conversion plan must cover exactly the requested pre-orders',
791
+ httpCode: 400,
792
+ },
793
+ PRE_ORDER_PLAN_DUPLICATE_ENTRY: {
794
+ code: 'PO039',
795
+ message: 'Conversion plan contains duplicate entries',
796
+ httpCode: 400,
797
+ },
798
+ PRE_ORDER_PLAN_ITEM_NOT_IN_PRE_ORDER: {
799
+ code: 'PO040',
800
+ message: 'Planned item does not belong to its pre-order',
801
+ httpCode: 400,
802
+ },
803
+ PRE_ORDER_PLAN_PRODUCT_NOT_AVAILABLE: {
804
+ code: 'PO041',
805
+ message: 'Planned product does not belong to the selected consignments',
806
+ httpCode: 400,
807
+ },
808
+ PRE_ORDER_PLAN_QUANTITY_MULTIPLICITY: {
809
+ code: 'PO042',
810
+ message: 'Planned quantity does not respect product multiplicity',
811
+ httpCode: 400,
812
+ },
813
+ PRE_ORDER_PLAN_QUANTITY_EXCEEDS_ITEM: {
814
+ code: 'PO043',
815
+ message: 'Planned quantity exceeds the pre-order item quantity',
816
+ httpCode: 400,
817
+ },
788
818
  STANDING_ORDER_CLIENT_NAME_REQUIRED: {
789
819
  code: 'SO001',
790
820
  message: 'Standing order client name is required',
@@ -1352,6 +1382,11 @@ export const ERRORS = {
1352
1382
  message: 'MoySklad sync lock is held by another job for this company; will retry shortly',
1353
1383
  httpCode: 409,
1354
1384
  },
1385
+ MOYSKLAD_ORDER_CREATE_LOCK_BUSY: {
1386
+ code: 'MS022',
1387
+ message: 'Another order is being created in MoySklad for this account; will retry shortly',
1388
+ httpCode: 409,
1389
+ },
1355
1390
 
1356
1391
  // 1C COMMERCEML INTEGRATION
1357
1392
  ONE_C_NOT_CONNECTED: { code: 'OC001', message: '1C integration is not connected for this company', httpCode: 404 },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floristcloud/api-lib",
3
- "version": "1.2.98",
3
+ "version": "1.2.100",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {