@floristcloud/api-lib 1.2.177 → 1.2.179

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.
Files changed (47) hide show
  1. package/build/commands/order/get-order-delivery-pricing.query.js +10 -0
  2. package/build/commands/order/index.js +1 -0
  3. package/build/enum/delivery-pricing-in-transit-mode.enum.js +8 -0
  4. package/build/enum/delivery-pricing-rule-scope.enum.js +9 -0
  5. package/build/enum/index.js +2 -0
  6. package/build/helpers/canonical-money-key.helper.js +9 -0
  7. package/build/helpers/normalize-delivery-pricing-value.helper.js +5 -0
  8. package/build/helpers/validate-unique-delivery-pricing-rules.helper.js +16 -0
  9. package/build/helpers/validate-unique-delivery-pricing-thresholds.helper.js +14 -0
  10. package/build/schemas/index.js +4 -0
  11. package/build/schemas/order/delivery-pricing.schema.js +13 -0
  12. package/build/schemas/order/get-order-delivery-pricing-request.schema.js +5 -0
  13. package/build/schemas/order/get-order-delivery-pricing-response.schema.js +9 -0
  14. package/build/schemas/order/index.js +3 -0
  15. package/build/schemas/order/order-extended-for-client.schema.js +4 -2
  16. package/build/schemas/settings/city-delivery-pricing-rule.schema.js +11 -0
  17. package/build/schemas/settings/default-delivery-pricing-rule.schema.js +11 -0
  18. package/build/schemas/settings/delivery-pricing-rule.schema.js +12 -0
  19. package/build/schemas/settings/delivery-pricing-rules.schema.js +7 -0
  20. package/build/schemas/settings/delivery-pricing-tier.schema.js +10 -0
  21. package/build/schemas/settings/delivery-pricing-tiers.schema.js +7 -0
  22. package/build/schemas/settings/group-delivery-pricing-rule.schema.js +11 -0
  23. package/build/schemas/settings/settings.schema.js +18 -12
  24. package/commands/order/get-order-delivery-pricing.query.ts +10 -0
  25. package/commands/order/index.ts +2 -0
  26. package/enum/delivery-pricing-in-transit-mode.enum.ts +4 -0
  27. package/enum/delivery-pricing-rule-scope.enum.ts +5 -0
  28. package/enum/index.ts +3 -0
  29. package/helpers/canonical-money-key.helper.ts +5 -0
  30. package/helpers/normalize-delivery-pricing-value.helper.ts +1 -0
  31. package/helpers/validate-unique-delivery-pricing-rules.helper.ts +18 -0
  32. package/helpers/validate-unique-delivery-pricing-thresholds.helper.ts +13 -0
  33. package/package.json +1 -1
  34. package/schemas/index.ts +4 -0
  35. package/schemas/order/delivery-pricing.schema.ts +11 -0
  36. package/schemas/order/get-order-delivery-pricing-request.schema.ts +3 -0
  37. package/schemas/order/get-order-delivery-pricing-response.schema.ts +7 -0
  38. package/schemas/order/index.ts +4 -0
  39. package/schemas/order/order-extended-for-client.schema.ts +4 -2
  40. package/schemas/settings/city-delivery-pricing-rule.schema.ts +9 -0
  41. package/schemas/settings/default-delivery-pricing-rule.schema.ts +9 -0
  42. package/schemas/settings/delivery-pricing-rule.schema.ts +10 -0
  43. package/schemas/settings/delivery-pricing-rules.schema.ts +5 -0
  44. package/schemas/settings/delivery-pricing-tier.schema.ts +8 -0
  45. package/schemas/settings/delivery-pricing-tiers.schema.ts +5 -0
  46. package/schemas/settings/group-delivery-pricing-rule.schema.ts +9 -0
  47. package/schemas/settings/settings.schema.ts +14 -11
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetOrderDeliveryPricingContractQuery = void 0;
4
+ const get_order_delivery_pricing_request_schema_1 = require("../../schemas/order/get-order-delivery-pricing-request.schema");
5
+ const get_order_delivery_pricing_response_schema_1 = require("../../schemas/order/get-order-delivery-pricing-response.schema");
6
+ var GetOrderDeliveryPricingContractQuery;
7
+ (function (GetOrderDeliveryPricingContractQuery) {
8
+ GetOrderDeliveryPricingContractQuery.RequestSchema = get_order_delivery_pricing_request_schema_1.GetOrderDeliveryPricingRequestSchema;
9
+ GetOrderDeliveryPricingContractQuery.ResponseSchema = get_order_delivery_pricing_response_schema_1.GetOrderDeliveryPricingResponseSchema;
10
+ })(GetOrderDeliveryPricingContractQuery || (exports.GetOrderDeliveryPricingContractQuery = GetOrderDeliveryPricingContractQuery = {}));
@@ -41,3 +41,4 @@ __exportStar(require("./webshop/create-cart.command"), exports);
41
41
  __exportStar(require("./webshop/get-order-list-for-client.query"), exports);
42
42
  __exportStar(require("./webshop/update-cart.command"), exports);
43
43
  __exportStar(require("./webshop/get-order-sales-by-month.query"), exports);
44
+ __exportStar(require("./get-order-delivery-pricing.query"), exports);
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeliveryPricingInTransitModeEnum = void 0;
4
+ var DeliveryPricingInTransitModeEnum;
5
+ (function (DeliveryPricingInTransitModeEnum) {
6
+ DeliveryPricingInTransitModeEnum["FREE"] = "FREE";
7
+ DeliveryPricingInTransitModeEnum["SAME_RULES"] = "SAME_RULES";
8
+ })(DeliveryPricingInTransitModeEnum || (exports.DeliveryPricingInTransitModeEnum = DeliveryPricingInTransitModeEnum = {}));
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeliveryPricingRuleScopeEnum = void 0;
4
+ var DeliveryPricingRuleScopeEnum;
5
+ (function (DeliveryPricingRuleScopeEnum) {
6
+ DeliveryPricingRuleScopeEnum["DEFAULT"] = "DEFAULT";
7
+ DeliveryPricingRuleScopeEnum["CITY"] = "CITY";
8
+ DeliveryPricingRuleScopeEnum["GROUP"] = "GROUP";
9
+ })(DeliveryPricingRuleScopeEnum || (exports.DeliveryPricingRuleScopeEnum = DeliveryPricingRuleScopeEnum = {}));
@@ -174,3 +174,5 @@ __exportStar(require("./pre-order-conversion-remainder-reason.enum"), exports);
174
174
  __exportStar(require("./pre-order-conversion-difference-field.enum"), exports);
175
175
  __exportStar(require("./pre-order-conversion-skip-reason.enum"), exports);
176
176
  __exportStar(require("./pre-order-fulfillment-status.enum"), exports);
177
+ __exportStar(require("./delivery-pricing-rule-scope.enum"), exports);
178
+ __exportStar(require("./delivery-pricing-in-transit-mode.enum"), exports);
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canonicalMoneyKey = void 0;
4
+ /** Input has already passed MoneySchema. Compare decimal strings without floating point arithmetic. */
5
+ const canonicalMoneyKey = (value) => {
6
+ const [integer, fraction = ''] = value.split('.');
7
+ return `${integer.replace(/^0+(?=\d)/, '')}.${(fraction + '00').slice(0, 2)}`;
8
+ };
9
+ exports.canonicalMoneyKey = canonicalMoneyKey;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeDeliveryPricingValue = void 0;
4
+ const normalizeDeliveryPricingValue = (value) => value.trim().toLowerCase();
5
+ exports.normalizeDeliveryPricingValue = normalizeDeliveryPricingValue;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateUniqueDeliveryPricingRules = validateUniqueDeliveryPricingRules;
4
+ const normalize_delivery_pricing_value_helper_1 = require("./normalize-delivery-pricing-value.helper");
5
+ function validateUniqueDeliveryPricingRules(rules, ctx) {
6
+ const seen = new Set();
7
+ rules.forEach((rule, index) => {
8
+ var _a;
9
+ const value = (0, normalize_delivery_pricing_value_helper_1.normalizeDeliveryPricingValue)((_a = rule.value) !== null && _a !== void 0 ? _a : '');
10
+ const key = `${rule.scope}:${value}`;
11
+ if (seen.has(key)) {
12
+ ctx.addIssue({ code: 'custom', path: [index, 'value'], message: 'Duplicate delivery pricing rule' });
13
+ }
14
+ seen.add(key);
15
+ });
16
+ }
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateUniqueDeliveryPricingThresholds = validateUniqueDeliveryPricingThresholds;
4
+ const canonical_money_key_helper_1 = require("./canonical-money-key.helper");
5
+ function validateUniqueDeliveryPricingThresholds(tiers, ctx) {
6
+ const thresholds = new Set();
7
+ tiers.forEach((tier, index) => {
8
+ const key = (0, canonical_money_key_helper_1.canonicalMoneyKey)(tier.minSubtotal);
9
+ if (thresholds.has(key)) {
10
+ ctx.addIssue({ code: 'custom', path: [index, 'minSubtotal'], message: 'Duplicate delivery pricing threshold' });
11
+ }
12
+ thresholds.add(key);
13
+ });
14
+ }
@@ -123,6 +123,10 @@ __exportStar(require("./report/user-activity-summary-row.schema"), exports);
123
123
  __exportStar(require("./report/user-activity-timeline-row.schema"), exports);
124
124
  __exportStar(require("./service/service.schema"), exports);
125
125
  __exportStar(require("./settings/settings.schema"), exports);
126
+ __exportStar(require("./settings/city-delivery-pricing-rule.schema"), exports);
127
+ __exportStar(require("./settings/default-delivery-pricing-rule.schema"), exports);
128
+ __exportStar(require("./settings/group-delivery-pricing-rule.schema"), exports);
129
+ __exportStar(require("./settings/delivery-pricing-tiers.schema"), exports);
126
130
  __exportStar(require("./transaction"), exports);
127
131
  __exportStar(require("./transaction/transaction-list.schema"), exports);
128
132
  __exportStar(require("./transaction/transaction.schema"), exports);
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeliveryPricingSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const money_schema_1 = require("../money.schema");
6
+ const delivery_pricing_tier_schema_1 = require("../settings/delivery-pricing-tier.schema");
7
+ const delivery_pricing_in_transit_mode_enum_1 = require("../../enum/delivery-pricing-in-transit-mode.enum");
8
+ exports.DeliveryPricingSchema = zod_1.z.object({
9
+ cost: money_schema_1.MoneySchema,
10
+ inStockSubtotal: money_schema_1.MoneySchema,
11
+ tiers: zod_1.z.array(delivery_pricing_tier_schema_1.DeliveryPricingTierSchema),
12
+ inTransitMode: zod_1.z.nativeEnum(delivery_pricing_in_transit_mode_enum_1.DeliveryPricingInTransitModeEnum),
13
+ });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetOrderDeliveryPricingRequestSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.GetOrderDeliveryPricingRequestSchema = zod_1.z.object({ orderUUID: zod_1.z.string().uuid() });
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GetOrderDeliveryPricingResponseSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const delivery_pricing_schema_1 = require("./delivery-pricing.schema");
6
+ exports.GetOrderDeliveryPricingResponseSchema = zod_1.z.object({
7
+ message: zod_1.z.string().optional(),
8
+ data: delivery_pricing_schema_1.DeliveryPricingSchema.nullable(),
9
+ });
@@ -28,3 +28,6 @@ __exportStar(require("./order.schema"), exports);
28
28
  __exportStar(require("./update-cart-delivery-request.schema"), exports);
29
29
  __exportStar(require("./update-cart-request.schema"), exports);
30
30
  __exportStar(require("./update-cart-response.schema"), exports);
31
+ __exportStar(require("./delivery-pricing.schema"), exports);
32
+ __exportStar(require("./get-order-delivery-pricing-request.schema"), exports);
33
+ __exportStar(require("./get-order-delivery-pricing-response.schema"), exports);
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OrderExtendedForClientSchema = void 0;
4
+ const delivery_pricing_schema_1 = require("./delivery-pricing.schema");
4
5
  const zod_1 = require("zod");
5
6
  const order_for_client_schema_1 = require("./order-for-client.schema");
6
7
  const client_for_client_schema_1 = require("../client/client-for-client.schema");
@@ -13,7 +14,8 @@ exports.OrderExtendedForClientSchema = order_for_client_schema_1.OrderForClientS
13
14
  delivery: order_delivery_schema_1.OrderDeliverySchema.nullable(),
14
15
  writeOffSum: money_schema_1.MoneySchema,
15
16
  consignmentDeliveryDates: zod_1.z.union([zod_1.z.date(), zod_1.z.literal('in-stock')]).array(),
16
- // Server-computed delivery cost for the current subtotal when the tier rule is on (null when off).
17
- // Convenience preview for the cart page; the storefront still recomputes locally on the delivery/pickup toggle.
17
+ // Server quote for the current cart; transit products do not contribute to the stock threshold.
18
+ deliveryPricing: delivery_pricing_schema_1.DeliveryPricingSchema.nullable(),
19
+ /** @deprecated One-release compatibility alias for deliveryPricing.cost. */
18
20
  deliveryCostPreview: money_schema_1.MoneySchema.nullable(),
19
21
  });
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CityDeliveryPricingRuleSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const delivery_pricing_rule_scope_enum_1 = require("../../enum/delivery-pricing-rule-scope.enum");
6
+ const delivery_pricing_tiers_schema_1 = require("./delivery-pricing-tiers.schema");
7
+ exports.CityDeliveryPricingRuleSchema = zod_1.z.object({
8
+ scope: zod_1.z.literal(delivery_pricing_rule_scope_enum_1.DeliveryPricingRuleScopeEnum.CITY),
9
+ value: zod_1.z.string().trim().min(1),
10
+ tiers: delivery_pricing_tiers_schema_1.DeliveryPricingTiersSchema,
11
+ });
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultDeliveryPricingRuleSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const delivery_pricing_rule_scope_enum_1 = require("../../enum/delivery-pricing-rule-scope.enum");
6
+ const delivery_pricing_tiers_schema_1 = require("./delivery-pricing-tiers.schema");
7
+ exports.DefaultDeliveryPricingRuleSchema = zod_1.z.object({
8
+ scope: zod_1.z.literal(delivery_pricing_rule_scope_enum_1.DeliveryPricingRuleScopeEnum.DEFAULT),
9
+ value: zod_1.z.null(),
10
+ tiers: delivery_pricing_tiers_schema_1.DeliveryPricingTiersSchema,
11
+ });
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeliveryPricingRuleSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const city_delivery_pricing_rule_schema_1 = require("./city-delivery-pricing-rule.schema");
6
+ const default_delivery_pricing_rule_schema_1 = require("./default-delivery-pricing-rule.schema");
7
+ const group_delivery_pricing_rule_schema_1 = require("./group-delivery-pricing-rule.schema");
8
+ exports.DeliveryPricingRuleSchema = zod_1.z.discriminatedUnion('scope', [
9
+ default_delivery_pricing_rule_schema_1.DefaultDeliveryPricingRuleSchema,
10
+ city_delivery_pricing_rule_schema_1.CityDeliveryPricingRuleSchema,
11
+ group_delivery_pricing_rule_schema_1.GroupDeliveryPricingRuleSchema,
12
+ ]);
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeliveryPricingRulesSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const validate_unique_delivery_pricing_rules_helper_1 = require("../../helpers/validate-unique-delivery-pricing-rules.helper");
6
+ const delivery_pricing_rule_schema_1 = require("./delivery-pricing-rule.schema");
7
+ exports.DeliveryPricingRulesSchema = zod_1.z.array(delivery_pricing_rule_schema_1.DeliveryPricingRuleSchema).superRefine(validate_unique_delivery_pricing_rules_helper_1.validateUniqueDeliveryPricingRules);
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeliveryPricingTierSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const non_negative_money_schema_1 = require("../non-negative-money.schema");
6
+ // JSON tiers follow the same decimal-string precision as monetary database columns.
7
+ exports.DeliveryPricingTierSchema = zod_1.z.object({
8
+ minSubtotal: non_negative_money_schema_1.NonNegativeMoneySchema,
9
+ cost: non_negative_money_schema_1.NonNegativeMoneySchema,
10
+ });
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeliveryPricingTiersSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const validate_unique_delivery_pricing_thresholds_helper_1 = require("../../helpers/validate-unique-delivery-pricing-thresholds.helper");
6
+ const delivery_pricing_tier_schema_1 = require("./delivery-pricing-tier.schema");
7
+ exports.DeliveryPricingTiersSchema = zod_1.z.array(delivery_pricing_tier_schema_1.DeliveryPricingTierSchema).superRefine(validate_unique_delivery_pricing_thresholds_helper_1.validateUniqueDeliveryPricingThresholds);
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GroupDeliveryPricingRuleSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const delivery_pricing_rule_scope_enum_1 = require("../../enum/delivery-pricing-rule-scope.enum");
6
+ const delivery_pricing_tiers_schema_1 = require("./delivery-pricing-tiers.schema");
7
+ exports.GroupDeliveryPricingRuleSchema = zod_1.z.object({
8
+ scope: zod_1.z.literal(delivery_pricing_rule_scope_enum_1.DeliveryPricingRuleScopeEnum.GROUP),
9
+ value: zod_1.z.string().trim().min(1),
10
+ tiers: delivery_pricing_tiers_schema_1.DeliveryPricingTiersSchema,
11
+ });
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.UpdateSettingsRequestSchema = exports.CreateSettingsSchema = exports.SettingsForAdminSchema = exports.SettingsSchema = exports.DeliveryPricingTierSchema = exports.DisableOrdersMessageSchema = exports.ContactPhoneListSchema = exports.ContactPhoneSchema = exports.ContactMessengerLinkSchema = exports.ImportantMessageSchema = exports.SettingsWorkingHoursSchema = void 0;
3
+ exports.UpdateSettingsRequestSchema = exports.CreateSettingsSchema = exports.SettingsForAdminSchema = exports.SettingsSchema = exports.DisableOrdersMessageSchema = exports.ContactPhoneListSchema = exports.ContactPhoneSchema = exports.ContactMessengerLinkSchema = exports.ImportantMessageSchema = exports.SettingsWorkingHoursSchema = exports.DeliveryPricingTierSchema = exports.DeliveryPricingRulesSchema = exports.DeliveryPricingRuleSchema = void 0;
4
4
  const zod_1 = require("zod");
5
5
  const enum_1 = require("../../enum");
6
6
  const contact_phone_constant_1 = require("../../constant/contact-phone.constant");
@@ -8,7 +8,16 @@ const settings_constant_1 = require("../../constant/settings.constant");
8
8
  const validation_i18n_key_1 = require("../../constant/validation-i18n-key");
9
9
  const webshop_main_display_mode_enum_1 = require("../../enum/webshop-main-display-mode.enum");
10
10
  const menu_items_url_enum_1 = require("../../enum/menu-items-url.enum");
11
- const non_negative_money_schema_1 = require("../non-negative-money.schema");
11
+ const delivery_pricing_in_transit_mode_enum_1 = require("../../enum/delivery-pricing-in-transit-mode.enum");
12
+ const delivery_pricing_rules_schema_1 = require("./delivery-pricing-rules.schema");
13
+ const delivery_pricing_tier_schema_1 = require("./delivery-pricing-tier.schema");
14
+ // Preserve existing direct imports and contracts package exports.
15
+ var delivery_pricing_rule_schema_1 = require("./delivery-pricing-rule.schema");
16
+ Object.defineProperty(exports, "DeliveryPricingRuleSchema", { enumerable: true, get: function () { return delivery_pricing_rule_schema_1.DeliveryPricingRuleSchema; } });
17
+ var delivery_pricing_rules_schema_2 = require("./delivery-pricing-rules.schema");
18
+ Object.defineProperty(exports, "DeliveryPricingRulesSchema", { enumerable: true, get: function () { return delivery_pricing_rules_schema_2.DeliveryPricingRulesSchema; } });
19
+ var delivery_pricing_tier_schema_2 = require("./delivery-pricing-tier.schema");
20
+ Object.defineProperty(exports, "DeliveryPricingTierSchema", { enumerable: true, get: function () { return delivery_pricing_tier_schema_2.DeliveryPricingTierSchema; } });
12
21
  exports.SettingsWorkingHoursSchema = zod_1.z.object({
13
22
  uuid: zod_1.z.string(),
14
23
  settingsUUID: zod_1.z.string(),
@@ -62,13 +71,6 @@ exports.ContactPhoneListSchema = zod_1.z.array(exports.ContactPhoneSchema).max(c
62
71
  // Один потолок на все три схемы настроек: колонка `disable_orders_message` — TEXT, длину держит
63
72
  // только валидация.
64
73
  exports.DisableOrdersMessageSchema = zod_1.z.string().max(settings_constant_1.DISABLE_ORDERS_MESSAGE_MAX_LENGTH);
65
- // Обе величины — деньги: `minSubtotal` сравнивается с суммой заказа, `cost` попадает в
66
- // `order.delivery_cost`. Живут они внутри JSON-колонки, куда ALTER TABLE не достаёт, поэтому
67
- // точность здесь держит не тип колонки, а формат значения — та же десятичная строка, что и на проводе.
68
- exports.DeliveryPricingTierSchema = zod_1.z.object({
69
- minSubtotal: non_negative_money_schema_1.NonNegativeMoneySchema,
70
- cost: non_negative_money_schema_1.NonNegativeMoneySchema,
71
- });
72
74
  exports.SettingsSchema = zod_1.z.object({
73
75
  uuid: zod_1.z.string(),
74
76
  language: zod_1.z.nativeEnum(enum_1.LanguageEnum),
@@ -149,11 +151,13 @@ exports.SettingsSchema = zod_1.z.object({
149
151
  isBalanceVisible: zod_1.z.boolean(),
150
152
  importantMessage: exports.ImportantMessageSchema.nullable(),
151
153
  deliveryPricingEnabled: zod_1.z.boolean(),
152
- deliveryPricingTiers: zod_1.z.array(exports.DeliveryPricingTierSchema).nullable(),
154
+ deliveryPricingTiers: zod_1.z.array(delivery_pricing_tier_schema_1.DeliveryPricingTierSchema).nullable(),
153
155
  employeeClientScopeEnabled: zod_1.z.boolean(),
154
156
  telegramStaffBotName: zod_1.z.string().nullable().optional(),
155
157
  });
156
158
  exports.SettingsForAdminSchema = exports.SettingsSchema.extend({
159
+ deliveryPricingRules: delivery_pricing_rules_schema_1.DeliveryPricingRulesSchema.nullable(),
160
+ deliveryPricingInTransitMode: zod_1.z.nativeEnum(delivery_pricing_in_transit_mode_enum_1.DeliveryPricingInTransitModeEnum),
157
161
  // post terminal settings
158
162
  vatTag: zod_1.z.string().nullable(),
159
163
  taxMode: zod_1.z.string().nullable(),
@@ -248,7 +252,8 @@ exports.CreateSettingsSchema = zod_1.z.object({
248
252
  chatNoManagerMode: zod_1.z.nativeEnum(enum_1.ChatNoManagerModeEnum).default(enum_1.ChatNoManagerModeEnum.ANY_MANAGER),
249
253
  importantMessage: exports.ImportantMessageSchema.nullable().optional(),
250
254
  deliveryPricingEnabled: zod_1.z.coerce.boolean().optional(),
251
- deliveryPricingTiers: zod_1.z.array(exports.DeliveryPricingTierSchema).nullable().optional(),
255
+ deliveryPricingRules: delivery_pricing_rules_schema_1.DeliveryPricingRulesSchema.nullable().optional(),
256
+ deliveryPricingInTransitMode: zod_1.z.nativeEnum(delivery_pricing_in_transit_mode_enum_1.DeliveryPricingInTransitModeEnum).optional(),
252
257
  });
253
258
  exports.UpdateSettingsRequestSchema = zod_1.z.object({
254
259
  language: zod_1.z.nativeEnum(enum_1.LanguageEnum),
@@ -327,7 +332,8 @@ exports.UpdateSettingsRequestSchema = zod_1.z.object({
327
332
  chatNoManagerMode: zod_1.z.nativeEnum(enum_1.ChatNoManagerModeEnum).default(enum_1.ChatNoManagerModeEnum.ANY_MANAGER).optional(),
328
333
  importantMessage: exports.ImportantMessageSchema.nullable().optional(),
329
334
  deliveryPricingEnabled: zod_1.z.coerce.boolean().optional(),
330
- deliveryPricingTiers: zod_1.z.array(exports.DeliveryPricingTierSchema).nullable().optional(),
335
+ deliveryPricingRules: delivery_pricing_rules_schema_1.DeliveryPricingRulesSchema.nullable().optional(),
336
+ deliveryPricingInTransitMode: zod_1.z.nativeEnum(delivery_pricing_in_transit_mode_enum_1.DeliveryPricingInTransitModeEnum).optional(),
331
337
  employeeClientScopeEnabled: zod_1.z.coerce.boolean().optional(),
332
338
  // post terminal settings
333
339
  vatTag: zod_1.z.string().nullable().optional(),
@@ -0,0 +1,10 @@
1
+ import type { z } from 'zod';
2
+ import { GetOrderDeliveryPricingRequestSchema } from '../../schemas/order/get-order-delivery-pricing-request.schema';
3
+ import { GetOrderDeliveryPricingResponseSchema } from '../../schemas/order/get-order-delivery-pricing-response.schema';
4
+
5
+ export namespace GetOrderDeliveryPricingContractQuery {
6
+ export const RequestSchema = GetOrderDeliveryPricingRequestSchema;
7
+ export type Request = z.infer<typeof RequestSchema>;
8
+ export const ResponseSchema = GetOrderDeliveryPricingResponseSchema;
9
+ export type Response = z.infer<typeof ResponseSchema>;
10
+ }
@@ -25,3 +25,5 @@ export * from './webshop/create-cart.command';
25
25
  export * from './webshop/get-order-list-for-client.query';
26
26
  export * from './webshop/update-cart.command';
27
27
  export * from './webshop/get-order-sales-by-month.query';
28
+
29
+ export * from './get-order-delivery-pricing.query';
@@ -0,0 +1,4 @@
1
+ export enum DeliveryPricingInTransitModeEnum {
2
+ FREE = 'FREE',
3
+ SAME_RULES = 'SAME_RULES',
4
+ }
@@ -0,0 +1,5 @@
1
+ export enum DeliveryPricingRuleScopeEnum {
2
+ DEFAULT = 'DEFAULT',
3
+ CITY = 'CITY',
4
+ GROUP = 'GROUP',
5
+ }
package/enum/index.ts CHANGED
@@ -159,3 +159,6 @@ export * from './pre-order-conversion-difference-field.enum';
159
159
  export * from './pre-order-conversion-skip-reason.enum';
160
160
 
161
161
  export * from './pre-order-fulfillment-status.enum';
162
+
163
+ export * from './delivery-pricing-rule-scope.enum';
164
+ export * from './delivery-pricing-in-transit-mode.enum';
@@ -0,0 +1,5 @@
1
+ /** Input has already passed MoneySchema. Compare decimal strings without floating point arithmetic. */
2
+ export const canonicalMoneyKey = (value: string): string => {
3
+ const [integer, fraction = ''] = value.split('.');
4
+ return `${integer.replace(/^0+(?=\d)/, '')}.${(fraction + '00').slice(0, 2)}`;
5
+ };
@@ -0,0 +1 @@
1
+ export const normalizeDeliveryPricingValue = (value: string): string => value.trim().toLowerCase();
@@ -0,0 +1,18 @@
1
+ import type { RefinementCtx } from 'zod';
2
+ import { DeliveryPricingRuleScopeEnum } from '../enum/delivery-pricing-rule-scope.enum';
3
+ import { normalizeDeliveryPricingValue } from './normalize-delivery-pricing-value.helper';
4
+
5
+ export function validateUniqueDeliveryPricingRules(
6
+ rules: { scope: DeliveryPricingRuleScopeEnum; value: string | null }[],
7
+ ctx: RefinementCtx,
8
+ ): void {
9
+ const seen = new Set<string>();
10
+ rules.forEach((rule, index) => {
11
+ const value = normalizeDeliveryPricingValue(rule.value ?? '');
12
+ const key = `${rule.scope}:${value}`;
13
+ if (seen.has(key)) {
14
+ ctx.addIssue({ code: 'custom', path: [index, 'value'], message: 'Duplicate delivery pricing rule' });
15
+ }
16
+ seen.add(key);
17
+ });
18
+ }
@@ -0,0 +1,13 @@
1
+ import type { RefinementCtx } from 'zod';
2
+ import { canonicalMoneyKey } from './canonical-money-key.helper';
3
+
4
+ export function validateUniqueDeliveryPricingThresholds(tiers: { minSubtotal: string }[], ctx: RefinementCtx): void {
5
+ const thresholds = new Set<string>();
6
+ tiers.forEach((tier, index) => {
7
+ const key = canonicalMoneyKey(tier.minSubtotal);
8
+ if (thresholds.has(key)) {
9
+ ctx.addIssue({ code: 'custom', path: [index, 'minSubtotal'], message: 'Duplicate delivery pricing threshold' });
10
+ }
11
+ thresholds.add(key);
12
+ });
13
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floristcloud/api-lib",
3
- "version": "1.2.177",
3
+ "version": "1.2.179",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "scripts": {
package/schemas/index.ts CHANGED
@@ -107,6 +107,10 @@ export * from './report/user-activity-summary-row.schema';
107
107
  export * from './report/user-activity-timeline-row.schema';
108
108
  export * from './service/service.schema';
109
109
  export * from './settings/settings.schema';
110
+ export * from './settings/city-delivery-pricing-rule.schema';
111
+ export * from './settings/default-delivery-pricing-rule.schema';
112
+ export * from './settings/group-delivery-pricing-rule.schema';
113
+ export * from './settings/delivery-pricing-tiers.schema';
110
114
  export * from './transaction';
111
115
  export * from './transaction/transaction-list.schema';
112
116
  export * from './transaction/transaction.schema';
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ import { MoneySchema } from '../money.schema';
3
+ import { DeliveryPricingTierSchema } from '../settings/delivery-pricing-tier.schema';
4
+ import { DeliveryPricingInTransitModeEnum } from '../../enum/delivery-pricing-in-transit-mode.enum';
5
+
6
+ export const DeliveryPricingSchema = z.object({
7
+ cost: MoneySchema,
8
+ inStockSubtotal: MoneySchema,
9
+ tiers: z.array(DeliveryPricingTierSchema),
10
+ inTransitMode: z.nativeEnum(DeliveryPricingInTransitModeEnum),
11
+ });
@@ -0,0 +1,3 @@
1
+ import { z } from 'zod';
2
+
3
+ export const GetOrderDeliveryPricingRequestSchema = z.object({ orderUUID: z.string().uuid() });
@@ -0,0 +1,7 @@
1
+ import { z } from 'zod';
2
+ import { DeliveryPricingSchema } from './delivery-pricing.schema';
3
+
4
+ export const GetOrderDeliveryPricingResponseSchema = z.object({
5
+ message: z.string().optional(),
6
+ data: DeliveryPricingSchema.nullable(),
7
+ });
@@ -12,3 +12,7 @@ export * from './order.schema';
12
12
  export * from './update-cart-delivery-request.schema';
13
13
  export * from './update-cart-request.schema';
14
14
  export * from './update-cart-response.schema';
15
+
16
+ export * from './delivery-pricing.schema';
17
+ export * from './get-order-delivery-pricing-request.schema';
18
+ export * from './get-order-delivery-pricing-response.schema';
@@ -1,3 +1,4 @@
1
+ import { DeliveryPricingSchema } from './delivery-pricing.schema';
1
2
  import { z } from 'zod';
2
3
  import { OrderForClientSchema } from './order-for-client.schema';
3
4
  import { ClientForClientSchema } from '../client/client-for-client.schema';
@@ -11,7 +12,8 @@ export const OrderExtendedForClientSchema = OrderForClientSchema.extend({
11
12
  delivery: OrderDeliverySchema.nullable(),
12
13
  writeOffSum: MoneySchema,
13
14
  consignmentDeliveryDates: z.union([z.date(), z.literal('in-stock')]).array(),
14
- // Server-computed delivery cost for the current subtotal when the tier rule is on (null when off).
15
- // Convenience preview for the cart page; the storefront still recomputes locally on the delivery/pickup toggle.
15
+ // Server quote for the current cart; transit products do not contribute to the stock threshold.
16
+ deliveryPricing: DeliveryPricingSchema.nullable(),
17
+ /** @deprecated One-release compatibility alias for deliveryPricing.cost. */
16
18
  deliveryCostPreview: MoneySchema.nullable(),
17
19
  });
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ import { DeliveryPricingRuleScopeEnum } from '../../enum/delivery-pricing-rule-scope.enum';
3
+ import { DeliveryPricingTiersSchema } from './delivery-pricing-tiers.schema';
4
+
5
+ export const CityDeliveryPricingRuleSchema = z.object({
6
+ scope: z.literal(DeliveryPricingRuleScopeEnum.CITY),
7
+ value: z.string().trim().min(1),
8
+ tiers: DeliveryPricingTiersSchema,
9
+ });
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ import { DeliveryPricingRuleScopeEnum } from '../../enum/delivery-pricing-rule-scope.enum';
3
+ import { DeliveryPricingTiersSchema } from './delivery-pricing-tiers.schema';
4
+
5
+ export const DefaultDeliveryPricingRuleSchema = z.object({
6
+ scope: z.literal(DeliveryPricingRuleScopeEnum.DEFAULT),
7
+ value: z.null(),
8
+ tiers: DeliveryPricingTiersSchema,
9
+ });
@@ -0,0 +1,10 @@
1
+ import { z } from 'zod';
2
+ import { CityDeliveryPricingRuleSchema } from './city-delivery-pricing-rule.schema';
3
+ import { DefaultDeliveryPricingRuleSchema } from './default-delivery-pricing-rule.schema';
4
+ import { GroupDeliveryPricingRuleSchema } from './group-delivery-pricing-rule.schema';
5
+
6
+ export const DeliveryPricingRuleSchema = z.discriminatedUnion('scope', [
7
+ DefaultDeliveryPricingRuleSchema,
8
+ CityDeliveryPricingRuleSchema,
9
+ GroupDeliveryPricingRuleSchema,
10
+ ]);
@@ -0,0 +1,5 @@
1
+ import { z } from 'zod';
2
+ import { validateUniqueDeliveryPricingRules } from '../../helpers/validate-unique-delivery-pricing-rules.helper';
3
+ import { DeliveryPricingRuleSchema } from './delivery-pricing-rule.schema';
4
+
5
+ export const DeliveryPricingRulesSchema = z.array(DeliveryPricingRuleSchema).superRefine(validateUniqueDeliveryPricingRules);
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+ import { NonNegativeMoneySchema } from '../non-negative-money.schema';
3
+
4
+ // JSON tiers follow the same decimal-string precision as monetary database columns.
5
+ export const DeliveryPricingTierSchema = z.object({
6
+ minSubtotal: NonNegativeMoneySchema,
7
+ cost: NonNegativeMoneySchema,
8
+ });
@@ -0,0 +1,5 @@
1
+ import { z } from 'zod';
2
+ import { validateUniqueDeliveryPricingThresholds } from '../../helpers/validate-unique-delivery-pricing-thresholds.helper';
3
+ import { DeliveryPricingTierSchema } from './delivery-pricing-tier.schema';
4
+
5
+ export const DeliveryPricingTiersSchema = z.array(DeliveryPricingTierSchema).superRefine(validateUniqueDeliveryPricingThresholds);
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ import { DeliveryPricingRuleScopeEnum } from '../../enum/delivery-pricing-rule-scope.enum';
3
+ import { DeliveryPricingTiersSchema } from './delivery-pricing-tiers.schema';
4
+
5
+ export const GroupDeliveryPricingRuleSchema = z.object({
6
+ scope: z.literal(DeliveryPricingRuleScopeEnum.GROUP),
7
+ value: z.string().trim().min(1),
8
+ tiers: DeliveryPricingTiersSchema,
9
+ });
@@ -19,7 +19,14 @@ import { DISABLE_ORDERS_MESSAGE_MAX_LENGTH } from '../../constant/settings.const
19
19
  import { ValidationI18nKey } from '../../constant/validation-i18n-key';
20
20
  import { WebshopMainDisplayModeEnum } from '../../enum/webshop-main-display-mode.enum';
21
21
  import { MenuItemsUrlEnum } from '../../enum/menu-items-url.enum';
22
- import { NonNegativeMoneySchema } from '../non-negative-money.schema';
22
+ import { DeliveryPricingInTransitModeEnum } from '../../enum/delivery-pricing-in-transit-mode.enum';
23
+ import { DeliveryPricingRulesSchema } from './delivery-pricing-rules.schema';
24
+ import { DeliveryPricingTierSchema } from './delivery-pricing-tier.schema';
25
+
26
+ // Preserve existing direct imports and contracts package exports.
27
+ export { DeliveryPricingRuleSchema } from './delivery-pricing-rule.schema';
28
+ export { DeliveryPricingRulesSchema } from './delivery-pricing-rules.schema';
29
+ export { DeliveryPricingTierSchema } from './delivery-pricing-tier.schema';
23
30
 
24
31
  export const SettingsWorkingHoursSchema = z.object({
25
32
  uuid: z.string(),
@@ -82,14 +89,6 @@ export const ContactPhoneListSchema = z.array(ContactPhoneSchema).max(CONTACT_PH
82
89
  // только валидация.
83
90
  export const DisableOrdersMessageSchema = z.string().max(DISABLE_ORDERS_MESSAGE_MAX_LENGTH);
84
91
 
85
- // Обе величины — деньги: `minSubtotal` сравнивается с суммой заказа, `cost` попадает в
86
- // `order.delivery_cost`. Живут они внутри JSON-колонки, куда ALTER TABLE не достаёт, поэтому
87
- // точность здесь держит не тип колонки, а формат значения — та же десятичная строка, что и на проводе.
88
- export const DeliveryPricingTierSchema = z.object({
89
- minSubtotal: NonNegativeMoneySchema,
90
- cost: NonNegativeMoneySchema,
91
- });
92
-
93
92
  export const SettingsSchema = z.object({
94
93
  uuid: z.string(),
95
94
  language: z.nativeEnum(LanguageEnum),
@@ -176,6 +175,8 @@ export const SettingsSchema = z.object({
176
175
  });
177
176
 
178
177
  export const SettingsForAdminSchema = SettingsSchema.extend({
178
+ deliveryPricingRules: DeliveryPricingRulesSchema.nullable(),
179
+ deliveryPricingInTransitMode: z.nativeEnum(DeliveryPricingInTransitModeEnum),
179
180
  // post terminal settings
180
181
  vatTag: z.string().nullable(),
181
182
  taxMode: z.string().nullable(),
@@ -273,7 +274,8 @@ export const CreateSettingsSchema = z.object({
273
274
  chatNoManagerMode: z.nativeEnum(ChatNoManagerModeEnum).default(ChatNoManagerModeEnum.ANY_MANAGER),
274
275
  importantMessage: ImportantMessageSchema.nullable().optional(),
275
276
  deliveryPricingEnabled: z.coerce.boolean().optional(),
276
- deliveryPricingTiers: z.array(DeliveryPricingTierSchema).nullable().optional(),
277
+ deliveryPricingRules: DeliveryPricingRulesSchema.nullable().optional(),
278
+ deliveryPricingInTransitMode: z.nativeEnum(DeliveryPricingInTransitModeEnum).optional(),
277
279
  });
278
280
 
279
281
  export const UpdateSettingsRequestSchema = z.object({
@@ -355,7 +357,8 @@ export const UpdateSettingsRequestSchema = z.object({
355
357
  chatNoManagerMode: z.nativeEnum(ChatNoManagerModeEnum).default(ChatNoManagerModeEnum.ANY_MANAGER).optional(),
356
358
  importantMessage: ImportantMessageSchema.nullable().optional(),
357
359
  deliveryPricingEnabled: z.coerce.boolean().optional(),
358
- deliveryPricingTiers: z.array(DeliveryPricingTierSchema).nullable().optional(),
360
+ deliveryPricingRules: DeliveryPricingRulesSchema.nullable().optional(),
361
+ deliveryPricingInTransitMode: z.nativeEnum(DeliveryPricingInTransitModeEnum).optional(),
359
362
  employeeClientScopeEnabled: z.coerce.boolean().optional(),
360
363
  // post terminal settings
361
364
  vatTag: z.string().nullable().optional(),