@floristcloud/api-lib 1.2.123 → 1.2.125

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.
@@ -8,6 +8,9 @@ const OptionUpdateSchema = zod_1.z.object({
8
8
  title: zod_1.z.string().nullable().optional(),
9
9
  optionMultiplicity: zod_1.z.number().nullable().optional(),
10
10
  optionPrice: money_schema_1.MoneySchema.nullable().optional(),
11
+ // Отсутствие поля — флаг не меняем; у создаваемой кратности берётся умолчание (скидки разрешены).
12
+ // Пустая ячейка в файле сюда не доезжает: разбор превращает её в отсутствие поля, а не в `false`.
13
+ isDiscountAllowed: zod_1.z.boolean().optional(),
11
14
  });
12
15
  const ConsignmentProductPositionUpdateSchema = zod_1.z.object({
13
16
  name: zod_1.z.string().nullable().optional(),
@@ -31,8 +34,11 @@ const ConsignmentProductPositionUpdateSchema = zod_1.z.object({
31
34
  description: zod_1.z.string().nullable().optional(),
32
35
  quality: zod_1.z.string().nullable().optional(),
33
36
  grower: zod_1.z.string().nullable().optional(),
34
- option1: OptionUpdateSchema.optional(),
35
- option2: OptionUpdateSchema.optional(),
37
+ // `null` — слот кратности очищен, кратность надо удалить; отсутствие поля — слотом не управляем.
38
+ // Различие существенное: обновление по схеме импорта видит только те колонки, что она отображает,
39
+ // и не должно сносить кратность, которую просто не читает.
40
+ option1: OptionUpdateSchema.nullable().optional(),
41
+ option2: OptionUpdateSchema.nullable().optional(),
36
42
  });
37
43
  const UpdateBatchRequestSchema = zod_1.z.object({
38
44
  updates: zod_1.z.record(zod_1.z.string(), ConsignmentProductPositionUpdateSchema),
@@ -3,13 +3,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SetConsignmentDiscountContractCommand = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const schemas_1 = require("../../schemas");
6
- const SetConsignmentDiscountBodySchema = zod_1.z
7
- .object({
6
+ const enum_1 = require("../../enum");
7
+ const ConsignmentTargetSchema = zod_1.z.object({
8
8
  consignmentUUID: zod_1.z.uuid().optional(),
9
9
  productUUIDs: zod_1.z.uuid().array().optional().default([]),
10
10
  onlyInStock: zod_1.z.boolean().optional().default(false),
11
- })
12
- .and(schemas_1.discountRulesModeSchema)
11
+ });
12
+ /**
13
+ * Тело операции над скидками партии: либо скидка величиной, либо запрет скидок.
14
+ *
15
+ * Разделено объединением, а не одним объектом с необязательной величиной, потому что величина
16
+ * обязательна ровно тогда, когда тип — скидка. Иначе «запрет со скидкой 10 %» был бы валидным
17
+ * телом запроса, и решать, что с ним делать, пришлось бы обработчику.
18
+ *
19
+ * `ruleType` необязателен и по умолчанию `ITEM_DISCOUNT`: до появления запрета тело состояло только
20
+ * из области действия и режима, и старые клиенты должны продолжать работать без правок.
21
+ */
22
+ const ItemDiscountBodySchema = ConsignmentTargetSchema.extend({
23
+ ruleType: zod_1.z.literal(enum_1.DiscountRulesTypeEnum.ITEM_DISCOUNT).optional(),
24
+ }).and(schemas_1.discountRulesModeSchema);
25
+ const ProhibitedBodySchema = ConsignmentTargetSchema.extend({
26
+ ruleType: zod_1.z.literal(enum_1.DiscountRulesTypeEnum.DISCOUNT_PROHIBITED),
27
+ });
28
+ const SetConsignmentDiscountBodySchema = zod_1.z
29
+ .union([ProhibitedBodySchema, ItemDiscountBodySchema])
13
30
  .refine(data => Boolean(data.consignmentUUID) || data.productUUIDs.length > 0, {
14
31
  message: 'validation.consignmentOrProducts',
15
32
  });
@@ -269,6 +269,13 @@ exports.ERRORS = {
269
269
  httpCode: 400,
270
270
  },
271
271
  CONSIGNMENT_PRODUCT_UPDATE_ITEM_FAILED: { code: 'CON028', message: 'Product update failed', httpCode: 400 },
272
+ // Товары загрузились, а кратности — нет. Отдельный код, потому что состояние частичное:
273
+ // повторять весь импорт не нужно, нужно поправить колонки кратностей и завести их заново.
274
+ CONSIGNMENT_IMPORT_MULTIPLICITY_OPTIONS_FAILED: {
275
+ code: 'CON029',
276
+ message: 'Products were imported, but their multiplicity options were not created',
277
+ httpCode: 500,
278
+ },
272
279
  // CONSIGNMENT-IMPORT-SCHEME
273
280
  CONSIGNMENT_IMPORT_SCHEME_NOT_CREATED: { code: 'CS001', message: 'Failed to create consignment import scheme', httpCode: 500 },
274
281
  CONSIGNMENT_IMPORT_SCHEME_FETCH_FAILED: { code: 'CS002', message: 'Error when retrieving a consignment import scheme', httpCode: 500 },
@@ -34,6 +34,11 @@ var ConsignmentImportSchemaRelationEntityPropertyEnum;
34
34
  ConsignmentImportSchemaRelationEntityPropertyEnum["OPTION1_TITLE"] = "OPTION1_TITLE";
35
35
  ConsignmentImportSchemaRelationEntityPropertyEnum["OPTION1_MULTIPLICITY"] = "OPTION1_MULTIPLICITY";
36
36
  ConsignmentImportSchemaRelationEntityPropertyEnum["OPTION1_PRICE"] = "OPTION1_PRICE";
37
+ ConsignmentImportSchemaRelationEntityPropertyEnum["OPTION1_DISCOUNT_ALLOWED"] = "OPTION1_DISCOUNT_ALLOWED";
38
+ ConsignmentImportSchemaRelationEntityPropertyEnum["OPTION2_TITLE"] = "OPTION2_TITLE";
39
+ ConsignmentImportSchemaRelationEntityPropertyEnum["OPTION2_MULTIPLICITY"] = "OPTION2_MULTIPLICITY";
40
+ ConsignmentImportSchemaRelationEntityPropertyEnum["OPTION2_PRICE"] = "OPTION2_PRICE";
41
+ ConsignmentImportSchemaRelationEntityPropertyEnum["OPTION2_DISCOUNT_ALLOWED"] = "OPTION2_DISCOUNT_ALLOWED";
37
42
  ConsignmentImportSchemaRelationEntityPropertyEnum["SALES_UNIT"] = "SALES_UNIT";
38
43
  ConsignmentImportSchemaRelationEntityPropertyEnum["UUID"] = "UUID";
39
44
  ConsignmentImportSchemaRelationEntityPropertyEnum["MULTIPLICITY_DESCRIPTION"] = "MULTIPLICITY_DESCRIPTION";
@@ -6,6 +6,9 @@ const OptionUpdateSchema = z.object({
6
6
  title: z.string().nullable().optional(),
7
7
  optionMultiplicity: z.number().nullable().optional(),
8
8
  optionPrice: MoneySchema.nullable().optional(),
9
+ // Отсутствие поля — флаг не меняем; у создаваемой кратности берётся умолчание (скидки разрешены).
10
+ // Пустая ячейка в файле сюда не доезжает: разбор превращает её в отсутствие поля, а не в `false`.
11
+ isDiscountAllowed: z.boolean().optional(),
9
12
  });
10
13
 
11
14
  const ConsignmentProductPositionUpdateSchema = z.object({
@@ -30,8 +33,11 @@ const ConsignmentProductPositionUpdateSchema = z.object({
30
33
  description: z.string().nullable().optional(),
31
34
  quality: z.string().nullable().optional(),
32
35
  grower: z.string().nullable().optional(),
33
- option1: OptionUpdateSchema.optional(),
34
- option2: OptionUpdateSchema.optional(),
36
+ // `null` — слот кратности очищен, кратность надо удалить; отсутствие поля — слотом не управляем.
37
+ // Различие существенное: обновление по схеме импорта видит только те колонки, что она отображает,
38
+ // и не должно сносить кратность, которую просто не читает.
39
+ option1: OptionUpdateSchema.nullable().optional(),
40
+ option2: OptionUpdateSchema.nullable().optional(),
35
41
  });
36
42
 
37
43
  const UpdateBatchRequestSchema = z.object({
@@ -1,13 +1,33 @@
1
1
  import { z } from 'zod';
2
2
  import { discountRulesModeSchema } from '../../schemas';
3
+ import { DiscountRulesTypeEnum } from '../../enum';
4
+
5
+ const ConsignmentTargetSchema = z.object({
6
+ consignmentUUID: z.uuid().optional(),
7
+ productUUIDs: z.uuid().array().optional().default([]),
8
+ onlyInStock: z.boolean().optional().default(false),
9
+ });
10
+
11
+ /**
12
+ * Тело операции над скидками партии: либо скидка величиной, либо запрет скидок.
13
+ *
14
+ * Разделено объединением, а не одним объектом с необязательной величиной, потому что величина
15
+ * обязательна ровно тогда, когда тип — скидка. Иначе «запрет со скидкой 10 %» был бы валидным
16
+ * телом запроса, и решать, что с ним делать, пришлось бы обработчику.
17
+ *
18
+ * `ruleType` необязателен и по умолчанию `ITEM_DISCOUNT`: до появления запрета тело состояло только
19
+ * из области действия и режима, и старые клиенты должны продолжать работать без правок.
20
+ */
21
+ const ItemDiscountBodySchema = ConsignmentTargetSchema.extend({
22
+ ruleType: z.literal(DiscountRulesTypeEnum.ITEM_DISCOUNT).optional(),
23
+ }).and(discountRulesModeSchema);
24
+
25
+ const ProhibitedBodySchema = ConsignmentTargetSchema.extend({
26
+ ruleType: z.literal(DiscountRulesTypeEnum.DISCOUNT_PROHIBITED),
27
+ });
3
28
 
4
29
  const SetConsignmentDiscountBodySchema = z
5
- .object({
6
- consignmentUUID: z.uuid().optional(),
7
- productUUIDs: z.uuid().array().optional().default([]),
8
- onlyInStock: z.boolean().optional().default(false),
9
- })
10
- .and(discountRulesModeSchema)
30
+ .union([ProhibitedBodySchema, ItemDiscountBodySchema])
11
31
  .refine(data => Boolean(data.consignmentUUID) || data.productUUIDs.length > 0, {
12
32
  message: 'validation.consignmentOrProducts',
13
33
  });
package/constant/error.ts CHANGED
@@ -278,6 +278,13 @@ export const ERRORS = {
278
278
  httpCode: 400,
279
279
  },
280
280
  CONSIGNMENT_PRODUCT_UPDATE_ITEM_FAILED: { code: 'CON028', message: 'Product update failed', httpCode: 400 },
281
+ // Товары загрузились, а кратности — нет. Отдельный код, потому что состояние частичное:
282
+ // повторять весь импорт не нужно, нужно поправить колонки кратностей и завести их заново.
283
+ CONSIGNMENT_IMPORT_MULTIPLICITY_OPTIONS_FAILED: {
284
+ code: 'CON029',
285
+ message: 'Products were imported, but their multiplicity options were not created',
286
+ httpCode: 500,
287
+ },
281
288
 
282
289
  // CONSIGNMENT-IMPORT-SCHEME
283
290
  CONSIGNMENT_IMPORT_SCHEME_NOT_CREATED: { code: 'CS001', message: 'Failed to create consignment import scheme', httpCode: 500 },
@@ -30,6 +30,11 @@ export enum ConsignmentImportSchemaRelationEntityPropertyEnum {
30
30
  OPTION1_TITLE = 'OPTION1_TITLE',
31
31
  OPTION1_MULTIPLICITY = 'OPTION1_MULTIPLICITY',
32
32
  OPTION1_PRICE = 'OPTION1_PRICE',
33
+ OPTION1_DISCOUNT_ALLOWED = 'OPTION1_DISCOUNT_ALLOWED',
34
+ OPTION2_TITLE = 'OPTION2_TITLE',
35
+ OPTION2_MULTIPLICITY = 'OPTION2_MULTIPLICITY',
36
+ OPTION2_PRICE = 'OPTION2_PRICE',
37
+ OPTION2_DISCOUNT_ALLOWED = 'OPTION2_DISCOUNT_ALLOWED',
33
38
  SALES_UNIT = 'SALES_UNIT',
34
39
  UUID = 'UUID',
35
40
  MULTIPLICITY_DESCRIPTION = 'MULTIPLICITY_DESCRIPTION',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floristcloud/api-lib",
3
- "version": "1.2.123",
3
+ "version": "1.2.125",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {