@endora-commerce/contracts 0.100.0
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/LICENSE +21 -0
- package/README.md +34 -0
- package/dist/actor.d.ts +79 -0
- package/dist/actor.d.ts.map +1 -0
- package/dist/actor.js +41 -0
- package/dist/actor.js.map +1 -0
- package/dist/addresses.d.ts +134 -0
- package/dist/addresses.d.ts.map +1 -0
- package/dist/addresses.js +16 -0
- package/dist/addresses.js.map +1 -0
- package/dist/admin-actions.d.ts +367 -0
- package/dist/admin-actions.d.ts.map +1 -0
- package/dist/admin-actions.js +287 -0
- package/dist/admin-actions.js.map +1 -0
- package/dist/admin-contributions.d.ts +518 -0
- package/dist/admin-contributions.d.ts.map +1 -0
- package/dist/admin-contributions.js +495 -0
- package/dist/admin-contributions.js.map +1 -0
- package/dist/admin-i18n.d.ts +135 -0
- package/dist/admin-i18n.d.ts.map +1 -0
- package/dist/admin-i18n.js +72 -0
- package/dist/admin-i18n.js.map +1 -0
- package/dist/admin-notifications.d.ts +55 -0
- package/dist/admin-notifications.d.ts.map +1 -0
- package/dist/admin-notifications.js +16 -0
- package/dist/admin-notifications.js.map +1 -0
- package/dist/admin-roles.d.ts +125 -0
- package/dist/admin-roles.d.ts.map +1 -0
- package/dist/admin-roles.js +2 -0
- package/dist/admin-roles.js.map +1 -0
- package/dist/admin-users.d.ts +178 -0
- package/dist/admin-users.d.ts.map +1 -0
- package/dist/admin-users.js +14 -0
- package/dist/admin-users.js.map +1 -0
- package/dist/admin.d.ts +243 -0
- package/dist/admin.d.ts.map +1 -0
- package/dist/admin.js +246 -0
- package/dist/admin.js.map +1 -0
- package/dist/analytics.d.ts +123 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +68 -0
- package/dist/analytics.js.map +1 -0
- package/dist/api-keys.d.ts +97 -0
- package/dist/api-keys.d.ts.map +1 -0
- package/dist/api-keys.js +64 -0
- package/dist/api-keys.js.map +1 -0
- package/dist/assets-library.d.ts +684 -0
- package/dist/assets-library.d.ts.map +1 -0
- package/dist/assets-library.js +181 -0
- package/dist/assets-library.js.map +1 -0
- package/dist/audit-logs.d.ts +141 -0
- package/dist/audit-logs.d.ts.map +1 -0
- package/dist/audit-logs.js +31 -0
- package/dist/audit-logs.js.map +1 -0
- package/dist/auth.d.ts +174 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +27 -0
- package/dist/auth.js.map +1 -0
- package/dist/blog.d.ts +669 -0
- package/dist/blog.d.ts.map +1 -0
- package/dist/blog.js +360 -0
- package/dist/blog.js.map +1 -0
- package/dist/capabilities.d.ts +40 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +38 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/carts.d.ts +1367 -0
- package/dist/carts.d.ts.map +1 -0
- package/dist/carts.js +405 -0
- package/dist/carts.js.map +1 -0
- package/dist/catalog.d.ts +2855 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +1543 -0
- package/dist/catalog.js.map +1 -0
- package/dist/cms.d.ts +872 -0
- package/dist/cms.d.ts.map +1 -0
- package/dist/cms.js +468 -0
- package/dist/cms.js.map +1 -0
- package/dist/common.d.ts +82 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +72 -0
- package/dist/common.js.map +1 -0
- package/dist/comparisons.d.ts +487 -0
- package/dist/comparisons.d.ts.map +1 -0
- package/dist/comparisons.js +221 -0
- package/dist/comparisons.js.map +1 -0
- package/dist/credentials.d.ts +292 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +142 -0
- package/dist/credentials.js.map +1 -0
- package/dist/credit-limits.d.ts +111 -0
- package/dist/credit-limits.d.ts.map +1 -0
- package/dist/credit-limits.js +35 -0
- package/dist/credit-limits.js.map +1 -0
- package/dist/currencies.d.ts +127 -0
- package/dist/currencies.d.ts.map +1 -0
- package/dist/currencies.js +20 -0
- package/dist/currencies.js.map +1 -0
- package/dist/custom-fields.d.ts +345 -0
- package/dist/custom-fields.d.ts.map +1 -0
- package/dist/custom-fields.js +185 -0
- package/dist/custom-fields.js.map +1 -0
- package/dist/customer-accounts.d.ts +690 -0
- package/dist/customer-accounts.d.ts.map +1 -0
- package/dist/customer-accounts.js +41 -0
- package/dist/customer-accounts.js.map +1 -0
- package/dist/customers.d.ts +305 -0
- package/dist/customers.d.ts.map +1 -0
- package/dist/customers.js +158 -0
- package/dist/customers.js.map +1 -0
- package/dist/dictionary.d.ts +580 -0
- package/dist/dictionary.d.ts.map +1 -0
- package/dist/dictionary.js +297 -0
- package/dist/dictionary.js.map +1 -0
- package/dist/email-address.d.ts +62 -0
- package/dist/email-address.d.ts.map +1 -0
- package/dist/email-address.js +64 -0
- package/dist/email-address.js.map +1 -0
- package/dist/email.d.ts +175 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +45 -0
- package/dist/email.js.map +1 -0
- package/dist/envelopes.d.ts +15 -0
- package/dist/envelopes.d.ts.map +1 -0
- package/dist/envelopes.js +16 -0
- package/dist/envelopes.js.map +1 -0
- package/dist/environment-inputs.d.ts +306 -0
- package/dist/environment-inputs.d.ts.map +1 -0
- package/dist/environment-inputs.js +277 -0
- package/dist/environment-inputs.js.map +1 -0
- package/dist/erp-connector.d.ts +52 -0
- package/dist/erp-connector.d.ts.map +1 -0
- package/dist/erp-connector.js +34 -0
- package/dist/erp-connector.js.map +1 -0
- package/dist/errors.d.ts +455 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +532 -0
- package/dist/errors.js.map +1 -0
- package/dist/google-analytics.d.ts +181 -0
- package/dist/google-analytics.d.ts.map +1 -0
- package/dist/google-analytics.js +176 -0
- package/dist/google-analytics.js.map +1 -0
- package/dist/google-tag-manager.d.ts +111 -0
- package/dist/google-tag-manager.d.ts.map +1 -0
- package/dist/google-tag-manager.js +129 -0
- package/dist/google-tag-manager.js.map +1 -0
- package/dist/i18n.d.ts +69 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +59 -0
- package/dist/i18n.js.map +1 -0
- package/dist/import-export.d.ts +63 -0
- package/dist/import-export.d.ts.map +1 -0
- package/dist/import-export.js +37 -0
- package/dist/import-export.js.map +1 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +126 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +673 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +412 -0
- package/dist/inventory.js.map +1 -0
- package/dist/invoice-ledger.d.ts +366 -0
- package/dist/invoice-ledger.d.ts.map +1 -0
- package/dist/invoice-ledger.js +114 -0
- package/dist/invoice-ledger.js.map +1 -0
- package/dist/invoices.d.ts +845 -0
- package/dist/invoices.d.ts.map +1 -0
- package/dist/invoices.js +314 -0
- package/dist/invoices.js.map +1 -0
- package/dist/kernel.d.ts +49 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +19 -0
- package/dist/kernel.js.map +1 -0
- package/dist/languages.d.ts +122 -0
- package/dist/languages.d.ts.map +1 -0
- package/dist/languages.js +24 -0
- package/dist/languages.js.map +1 -0
- package/dist/linkedin-ads.d.ts +167 -0
- package/dist/linkedin-ads.d.ts.map +1 -0
- package/dist/linkedin-ads.js +156 -0
- package/dist/linkedin-ads.js.map +1 -0
- package/dist/megamenu.d.ts +556 -0
- package/dist/megamenu.d.ts.map +1 -0
- package/dist/megamenu.js +186 -0
- package/dist/megamenu.js.map +1 -0
- package/dist/meta-ads.d.ts +126 -0
- package/dist/meta-ads.d.ts.map +1 -0
- package/dist/meta-ads.js +112 -0
- package/dist/meta-ads.js.map +1 -0
- package/dist/mfa.d.ts +274 -0
- package/dist/mfa.d.ts.map +1 -0
- package/dist/mfa.js +187 -0
- package/dist/mfa.js.map +1 -0
- package/dist/modules.d.ts +1706 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +1390 -0
- package/dist/modules.js.map +1 -0
- package/dist/newsletter.d.ts +611 -0
- package/dist/newsletter.d.ts.map +1 -0
- package/dist/newsletter.js +345 -0
- package/dist/newsletter.js.map +1 -0
- package/dist/orders.d.ts +1175 -0
- package/dist/orders.d.ts.map +1 -0
- package/dist/orders.js +630 -0
- package/dist/orders.js.map +1 -0
- package/dist/organizations.d.ts +938 -0
- package/dist/organizations.d.ts.map +1 -0
- package/dist/organizations.js +418 -0
- package/dist/organizations.js.map +1 -0
- package/dist/pagination.d.ts +21 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +22 -0
- package/dist/pagination.js.map +1 -0
- package/dist/payment-methods.d.ts +472 -0
- package/dist/payment-methods.d.ts.map +1 -0
- package/dist/payment-methods.js +175 -0
- package/dist/payment-methods.js.map +1 -0
- package/dist/payment-return-url.d.ts +53 -0
- package/dist/payment-return-url.d.ts.map +1 -0
- package/dist/payment-return-url.js +35 -0
- package/dist/payment-return-url.js.map +1 -0
- package/dist/payments.d.ts +386 -0
- package/dist/payments.d.ts.map +1 -0
- package/dist/payments.js +84 -0
- package/dist/payments.js.map +1 -0
- package/dist/pim-connector.d.ts +60 -0
- package/dist/pim-connector.d.ts.map +1 -0
- package/dist/pim-connector.js +43 -0
- package/dist/pim-connector.js.map +1 -0
- package/dist/pim-field-path.d.ts +6 -0
- package/dist/pim-field-path.d.ts.map +1 -0
- package/dist/pim-field-path.js +101 -0
- package/dist/pim-field-path.js.map +1 -0
- package/dist/platform-language.d.ts +20 -0
- package/dist/platform-language.d.ts.map +1 -0
- package/dist/platform-language.js +22 -0
- package/dist/platform-language.js.map +1 -0
- package/dist/price-lists.d.ts +685 -0
- package/dist/price-lists.d.ts.map +1 -0
- package/dist/price-lists.js +330 -0
- package/dist/price-lists.js.map +1 -0
- package/dist/product-feeds.d.ts +2837 -0
- package/dist/product-feeds.d.ts.map +1 -0
- package/dist/product-feeds.js +1504 -0
- package/dist/product-feeds.js.map +1 -0
- package/dist/product-scope-overrides.d.ts +134 -0
- package/dist/product-scope-overrides.d.ts.map +1 -0
- package/dist/product-scope-overrides.js +82 -0
- package/dist/product-scope-overrides.js.map +1 -0
- package/dist/product-value-resolver.d.ts +88 -0
- package/dist/product-value-resolver.d.ts.map +1 -0
- package/dist/product-value-resolver.js +128 -0
- package/dist/product-value-resolver.js.map +1 -0
- package/dist/promotions.d.ts +678 -0
- package/dist/promotions.d.ts.map +1 -0
- package/dist/promotions.js +479 -0
- package/dist/promotions.js.map +1 -0
- package/dist/prompt-actions.d.ts +582 -0
- package/dist/prompt-actions.d.ts.map +1 -0
- package/dist/prompt-actions.js +221 -0
- package/dist/prompt-actions.js.map +1 -0
- package/dist/pwa.d.ts +293 -0
- package/dist/pwa.d.ts.map +1 -0
- package/dist/pwa.js +204 -0
- package/dist/pwa.js.map +1 -0
- package/dist/quick-order.d.ts +340 -0
- package/dist/quick-order.d.ts.map +1 -0
- package/dist/quick-order.js +177 -0
- package/dist/quick-order.js.map +1 -0
- package/dist/quote-requests.d.ts +538 -0
- package/dist/quote-requests.d.ts.map +1 -0
- package/dist/quote-requests.js +308 -0
- package/dist/quote-requests.js.map +1 -0
- package/dist/returns.d.ts +774 -0
- package/dist/returns.d.ts.map +1 -0
- package/dist/returns.js +389 -0
- package/dist/returns.js.map +1 -0
- package/dist/sales-channels.d.ts +392 -0
- package/dist/sales-channels.d.ts.map +1 -0
- package/dist/sales-channels.js +285 -0
- package/dist/sales-channels.js.map +1 -0
- package/dist/scope-notice.d.ts +60 -0
- package/dist/scope-notice.d.ts.map +1 -0
- package/dist/scope-notice.js +56 -0
- package/dist/scope-notice.js.map +1 -0
- package/dist/search.d.ts +321 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +160 -0
- package/dist/search.js.map +1 -0
- package/dist/seo.d.ts +113 -0
- package/dist/seo.d.ts.map +1 -0
- package/dist/seo.js +63 -0
- package/dist/seo.js.map +1 -0
- package/dist/settings.d.ts +453 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +337 -0
- package/dist/settings.js.map +1 -0
- package/dist/shipments.d.ts +140 -0
- package/dist/shipments.d.ts.map +1 -0
- package/dist/shipments.js +14 -0
- package/dist/shipments.js.map +1 -0
- package/dist/shipping-methods.d.ts +350 -0
- package/dist/shipping-methods.d.ts.map +1 -0
- package/dist/shipping-methods.js +99 -0
- package/dist/shipping-methods.js.map +1 -0
- package/dist/shopping-lists.d.ts +122 -0
- package/dist/shopping-lists.d.ts.map +1 -0
- package/dist/shopping-lists.js +92 -0
- package/dist/shopping-lists.js.map +1 -0
- package/dist/taxes.d.ts +106 -0
- package/dist/taxes.d.ts.map +1 -0
- package/dist/taxes.js +80 -0
- package/dist/taxes.js.map +1 -0
- package/dist/text-normalization.d.ts +199 -0
- package/dist/text-normalization.d.ts.map +1 -0
- package/dist/text-normalization.js +205 -0
- package/dist/text-normalization.js.map +1 -0
- package/dist/transactional-emails.d.ts +459 -0
- package/dist/transactional-emails.d.ts.map +1 -0
- package/dist/transactional-emails.js +212 -0
- package/dist/transactional-emails.js.map +1 -0
- package/dist/webhooks.d.ts +69 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +53 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const ruleCriterionTypeSchema: z.ZodEnum<{
|
|
3
|
+
currency: "currency";
|
|
4
|
+
category: "category";
|
|
5
|
+
organization: "organization";
|
|
6
|
+
salesChannel: "salesChannel";
|
|
7
|
+
customerGroup: "customerGroup";
|
|
8
|
+
}>;
|
|
9
|
+
export type RuleCriterionType = z.infer<typeof ruleCriterionTypeSchema>;
|
|
10
|
+
export type RuleAllNode = {
|
|
11
|
+
kind: 'all';
|
|
12
|
+
};
|
|
13
|
+
export type RuleCriterionNode = {
|
|
14
|
+
kind: 'criterion';
|
|
15
|
+
type: RuleCriterionType;
|
|
16
|
+
values: string[];
|
|
17
|
+
};
|
|
18
|
+
export type RuleGroupNode = {
|
|
19
|
+
kind: 'group';
|
|
20
|
+
op: 'AND' | 'OR';
|
|
21
|
+
children: ApplicationRule[];
|
|
22
|
+
};
|
|
23
|
+
export type ApplicationRule = RuleAllNode | RuleCriterionNode | RuleGroupNode;
|
|
24
|
+
export declare const applicationRuleSchema: z.ZodType<ApplicationRule, unknown, z.core.$ZodTypeInternals<ApplicationRule, unknown>>;
|
|
25
|
+
export declare const priceListTypeSchema: z.ZodEnum<{
|
|
26
|
+
base: "base";
|
|
27
|
+
sale: "sale";
|
|
28
|
+
}>;
|
|
29
|
+
export type PriceListType = z.infer<typeof priceListTypeSchema>;
|
|
30
|
+
export declare const priceListStatusSchema: z.ZodEnum<{
|
|
31
|
+
active: "active";
|
|
32
|
+
draft: "draft";
|
|
33
|
+
expired: "expired";
|
|
34
|
+
scheduled: "scheduled";
|
|
35
|
+
}>;
|
|
36
|
+
export type PriceListStatus = z.infer<typeof priceListStatusSchema>;
|
|
37
|
+
export declare const priceListEngineSchema: z.ZodObject<{
|
|
38
|
+
id: z.ZodString;
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
type: z.ZodEnum<{
|
|
41
|
+
base: "base";
|
|
42
|
+
sale: "sale";
|
|
43
|
+
}>;
|
|
44
|
+
status: z.ZodEnum<{
|
|
45
|
+
active: "active";
|
|
46
|
+
draft: "draft";
|
|
47
|
+
expired: "expired";
|
|
48
|
+
scheduled: "scheduled";
|
|
49
|
+
}>;
|
|
50
|
+
startsAt: z.ZodNullable<z.ZodString>;
|
|
51
|
+
endsAt: z.ZodNullable<z.ZodString>;
|
|
52
|
+
applicationRule: z.ZodType<ApplicationRule, unknown, z.core.$ZodTypeInternals<ApplicationRule, unknown>>;
|
|
53
|
+
isSystem: z.ZodBoolean;
|
|
54
|
+
modifiedAt: z.ZodString;
|
|
55
|
+
createdAt: z.ZodString;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
export type PriceListEngine = z.infer<typeof priceListEngineSchema>;
|
|
58
|
+
export declare const createPriceListEngineRequestSchema: z.ZodObject<{
|
|
59
|
+
name: z.ZodString;
|
|
60
|
+
type: z.ZodEnum<{
|
|
61
|
+
base: "base";
|
|
62
|
+
sale: "sale";
|
|
63
|
+
}>;
|
|
64
|
+
startsAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
65
|
+
endsAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
66
|
+
applicationRule: z.ZodOptional<z.ZodType<ApplicationRule, unknown, z.core.$ZodTypeInternals<ApplicationRule, unknown>>>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
export declare const patchPriceListEngineRequestSchema: z.ZodObject<{
|
|
69
|
+
name: z.ZodOptional<z.ZodString>;
|
|
70
|
+
type: z.ZodOptional<z.ZodEnum<{
|
|
71
|
+
base: "base";
|
|
72
|
+
sale: "sale";
|
|
73
|
+
}>>;
|
|
74
|
+
startsAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
75
|
+
endsAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
76
|
+
applicationRule: z.ZodOptional<z.ZodType<ApplicationRule, unknown, z.core.$ZodTypeInternals<ApplicationRule, unknown>>>;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
export declare const priceListBracketSchema: z.ZodObject<{
|
|
79
|
+
priceListId: z.ZodString;
|
|
80
|
+
productId: z.ZodString;
|
|
81
|
+
currencyCode: z.ZodString;
|
|
82
|
+
minQuantity: z.ZodNumber;
|
|
83
|
+
maxQuantity: z.ZodNullable<z.ZodNumber>;
|
|
84
|
+
amount: z.ZodString;
|
|
85
|
+
}, z.core.$strip>;
|
|
86
|
+
export type PriceListBracket = z.infer<typeof priceListBracketSchema>;
|
|
87
|
+
export declare const replaceBracketsRequestSchema: z.ZodObject<{
|
|
88
|
+
bracketsByCurrency: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
|
|
89
|
+
minQuantity: z.ZodNumber;
|
|
90
|
+
maxQuantity: z.ZodNullable<z.ZodNumber>;
|
|
91
|
+
amount: z.ZodString;
|
|
92
|
+
}, z.core.$strip>>>;
|
|
93
|
+
}, z.core.$strip>;
|
|
94
|
+
export declare const productAssignmentSchema: z.ZodObject<{
|
|
95
|
+
priceListId: z.ZodString;
|
|
96
|
+
productId: z.ZodString;
|
|
97
|
+
bracketsByCurrency: z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
|
|
98
|
+
priceListId: z.ZodString;
|
|
99
|
+
productId: z.ZodString;
|
|
100
|
+
currencyCode: z.ZodString;
|
|
101
|
+
minQuantity: z.ZodNumber;
|
|
102
|
+
maxQuantity: z.ZodNullable<z.ZodNumber>;
|
|
103
|
+
amount: z.ZodString;
|
|
104
|
+
}, z.core.$strip>>>;
|
|
105
|
+
}, z.core.$strip>;
|
|
106
|
+
export type ProductAssignment = z.infer<typeof productAssignmentSchema>;
|
|
107
|
+
export declare const replaceProductsRequestSchema: z.ZodObject<{
|
|
108
|
+
productIds: z.ZodArray<z.ZodString>;
|
|
109
|
+
}, z.core.$strip>;
|
|
110
|
+
export declare const displayModeSchema: z.ZodEnum<{
|
|
111
|
+
both: "both";
|
|
112
|
+
none: "none";
|
|
113
|
+
gross_only: "gross_only";
|
|
114
|
+
net_only: "net_only";
|
|
115
|
+
}>;
|
|
116
|
+
export type DisplayMode = z.infer<typeof displayModeSchema>;
|
|
117
|
+
export declare const displayModeOverrideScopeSchema: z.ZodEnum<{
|
|
118
|
+
category: "category";
|
|
119
|
+
product: "product";
|
|
120
|
+
organization: "organization";
|
|
121
|
+
}>;
|
|
122
|
+
export type DisplayModeOverrideScope = z.infer<typeof displayModeOverrideScopeSchema>;
|
|
123
|
+
export declare const displayModeOverrideSchema: z.ZodObject<{
|
|
124
|
+
scope: z.ZodEnum<{
|
|
125
|
+
category: "category";
|
|
126
|
+
product: "product";
|
|
127
|
+
organization: "organization";
|
|
128
|
+
}>;
|
|
129
|
+
targetId: z.ZodString;
|
|
130
|
+
mode: z.ZodEnum<{
|
|
131
|
+
both: "both";
|
|
132
|
+
none: "none";
|
|
133
|
+
gross_only: "gross_only";
|
|
134
|
+
net_only: "net_only";
|
|
135
|
+
}>;
|
|
136
|
+
updatedAt: z.ZodString;
|
|
137
|
+
}, z.core.$strip>;
|
|
138
|
+
export type DisplayModeOverride = z.infer<typeof displayModeOverrideSchema>;
|
|
139
|
+
export declare const upsertDisplayModeOverrideRequestSchema: z.ZodObject<{
|
|
140
|
+
mode: z.ZodUnion<[z.ZodEnum<{
|
|
141
|
+
both: "both";
|
|
142
|
+
none: "none";
|
|
143
|
+
gross_only: "gross_only";
|
|
144
|
+
net_only: "net_only";
|
|
145
|
+
}>, z.ZodLiteral<"inherit">]>;
|
|
146
|
+
}, z.core.$strip>;
|
|
147
|
+
export declare const resolvedPriceEngineSchema: z.ZodObject<{
|
|
148
|
+
baseListId: z.ZodString;
|
|
149
|
+
basePrice: z.ZodObject<{
|
|
150
|
+
amount: z.ZodNumber;
|
|
151
|
+
currency: z.ZodString;
|
|
152
|
+
}, z.core.$strip>;
|
|
153
|
+
saleListId: z.ZodNullable<z.ZodString>;
|
|
154
|
+
salePrice: z.ZodNullable<z.ZodObject<{
|
|
155
|
+
amount: z.ZodNumber;
|
|
156
|
+
currency: z.ZodString;
|
|
157
|
+
}, z.core.$strip>>;
|
|
158
|
+
displayMode: z.ZodEnum<{
|
|
159
|
+
both: "both";
|
|
160
|
+
none: "none";
|
|
161
|
+
gross_only: "gross_only";
|
|
162
|
+
net_only: "net_only";
|
|
163
|
+
}>;
|
|
164
|
+
currencyCode: z.ZodString;
|
|
165
|
+
quantityBracket: z.ZodObject<{
|
|
166
|
+
minQuantity: z.ZodNumber;
|
|
167
|
+
maxQuantity: z.ZodNullable<z.ZodNumber>;
|
|
168
|
+
}, z.core.$strip>;
|
|
169
|
+
}, z.core.$strip>;
|
|
170
|
+
export type ResolvedPriceEngine = z.infer<typeof resolvedPriceEngineSchema>;
|
|
171
|
+
/**
|
|
172
|
+
* What a catalogue listing may show as a product's price — issue #132.
|
|
173
|
+
*
|
|
174
|
+
* There is always one default price list, so the first arm is the path a
|
|
175
|
+
* listing normally takes. The product ruling names the whole chain and this
|
|
176
|
+
* union is that chain, one arm each:
|
|
177
|
+
*
|
|
178
|
+
* `price_list` — an applicable list priced this product for this buyer;
|
|
179
|
+
* `product` — no list applied, so the price assigned directly to the
|
|
180
|
+
* Product stands in (the legacy `defaultPrice` attribute);
|
|
181
|
+
* `none` — neither exists, and the listing renders no price.
|
|
182
|
+
*
|
|
183
|
+
* The `none` arm carries **no `amount` field**, following the `ResolvedTax`
|
|
184
|
+
* precedent (issue #124): a listing showing nothing and a listing offering a
|
|
185
|
+
* free product are different pages, so a caller has to narrow on `source`
|
|
186
|
+
* before it can read a figure. A product priced at zero comes back as
|
|
187
|
+
* `{ source: 'price_list' | 'product', amount: '0.00' }` and renders as zero —
|
|
188
|
+
* `amount` is never a falsy sentinel for absence.
|
|
189
|
+
*
|
|
190
|
+
* As with `ResolvedTax`, "the `price_lists` module is absent" is deliberately
|
|
191
|
+
* not an arm: absence is not a value, and the port gate throws
|
|
192
|
+
* `MODULE_DISABLED` before a resolution runs.
|
|
193
|
+
*/
|
|
194
|
+
export declare const listingPriceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
195
|
+
source: z.ZodLiteral<"price_list">;
|
|
196
|
+
amount: z.ZodString;
|
|
197
|
+
currency: z.ZodString;
|
|
198
|
+
priceListId: z.ZodString;
|
|
199
|
+
isSale: z.ZodBoolean;
|
|
200
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
201
|
+
source: z.ZodLiteral<"product">;
|
|
202
|
+
amount: z.ZodString;
|
|
203
|
+
currency: z.ZodString;
|
|
204
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
205
|
+
source: z.ZodLiteral<"none">;
|
|
206
|
+
}, z.core.$strip>], "source">;
|
|
207
|
+
export type ListingPrice = z.infer<typeof listingPriceSchema>;
|
|
208
|
+
/**
|
|
209
|
+
* The money a listing renders for one resolved chain answer, or `null` when the
|
|
210
|
+
* chain ended in `none`.
|
|
211
|
+
*
|
|
212
|
+
* The narrowing is the point: `null` here means "there is no price", which the
|
|
213
|
+
* `ProductSummary.price` wire field already spells `null`. A resolved `0` comes
|
|
214
|
+
* back as `{ amount: 0 }` and survives every caller, because nothing on this
|
|
215
|
+
* path tests an amount for truthiness.
|
|
216
|
+
*/
|
|
217
|
+
export declare function listingPriceMoney(price: ListingPrice): {
|
|
218
|
+
amount: number;
|
|
219
|
+
currency: string;
|
|
220
|
+
} | null;
|
|
221
|
+
/** The little of a Product a listing resolution reads. */
|
|
222
|
+
export interface ListingPriceProduct {
|
|
223
|
+
id: string;
|
|
224
|
+
attributeValues: Record<string, unknown>;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Container name: `pricingService`. Owner: `price_lists`.
|
|
228
|
+
*
|
|
229
|
+
* The slice of the `pricingService` port a catalogue listing path resolves.
|
|
230
|
+
*
|
|
231
|
+
* Declared here rather than in each consumer so the catalogue, search,
|
|
232
|
+
* comparisons and product links ask for the same thing in the same words, and
|
|
233
|
+
* declared as a *shape* rather than imported from `price_lists` so none of them
|
|
234
|
+
* reaches into the owning module (Principle I). The owner's
|
|
235
|
+
* `PricingServiceContract` is a superset and satisfies it structurally.
|
|
236
|
+
*
|
|
237
|
+
* **`organization` is the viewer, and it is optional because the viewer may
|
|
238
|
+
* have none.** Every caller supplies it *conditionally* — the asking buyer's
|
|
239
|
+
* own organisation for a signed-in reader, nothing at all for an anonymous one
|
|
240
|
+
* — so the field is absent in the case it describes rather than absent because
|
|
241
|
+
* a caller forgot it, which is the distinction an always-supplied optional
|
|
242
|
+
* parameter fails.
|
|
243
|
+
*
|
|
244
|
+
* The catalogue listing, the product detail, the search results and the
|
|
245
|
+
* product-link strip omitted it until the owner ruled otherwise: an anonymous
|
|
246
|
+
* visitor sees the channel price, a signed-in buyer sees their organisation's.
|
|
247
|
+
* The ruling waited on MR !793, which batched this resolution — a 50-item page
|
|
248
|
+
* went from 502 statements to 158 — because the argument against
|
|
249
|
+
* personalisation had been the pricing cache, whose hit rate per-organisation
|
|
250
|
+
* pricing largely destroys (99.0% anonymous, 5.3% at 50 organisations,
|
|
251
|
+
* measured). Once the page no longer needs that cache to absorb a per-card
|
|
252
|
+
* loop, the cost of missing it is four statements.
|
|
253
|
+
*
|
|
254
|
+
* **What that costs the *page* cache is the caller's problem, not this port's,
|
|
255
|
+
* and it is not nothing.** A priced response that names an organisation is
|
|
256
|
+
* private: it must not enter a shared cache, and
|
|
257
|
+
* `markPersonalisedPricing` in `backend/src/http/product-audience.ts` is where
|
|
258
|
+
* the storefront routes say so. The anonymous answer is unchanged, uncached-by-
|
|
259
|
+
* this-change and still the one a crawler indexes (Principle VII).
|
|
260
|
+
*
|
|
261
|
+
* Widening this slice rather than publishing a second one is deliberate: the
|
|
262
|
+
* engine's own `ListingPricesInput` has carried an organisation all along, and
|
|
263
|
+
* the whole point of issue #132 was that the listing chain has **one**
|
|
264
|
+
* implementation — a second port over the same container method is the second
|
|
265
|
+
* chain arriving by another door.
|
|
266
|
+
*
|
|
267
|
+
* **Owner off:** the seam fails closed — resolving the port throws
|
|
268
|
+
* `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`. A listing
|
|
269
|
+
* that invented a figure would be worse than one that refuses, which is the
|
|
270
|
+
* same reasoning {@link LinePricePort} states for a cart line.
|
|
271
|
+
*/
|
|
272
|
+
export interface ListingPricePort {
|
|
273
|
+
resolveListingPrices(input: {
|
|
274
|
+
products: readonly ListingPriceProduct[];
|
|
275
|
+
context: {
|
|
276
|
+
salesChannel: {
|
|
277
|
+
id: string;
|
|
278
|
+
defaultCurrency: string;
|
|
279
|
+
};
|
|
280
|
+
currencyCode?: string;
|
|
281
|
+
/** The buying organisation, when the viewer has one. */
|
|
282
|
+
organization?: PriceOrganization | null;
|
|
283
|
+
};
|
|
284
|
+
}): Promise<Map<string, ListingPrice>>;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* The buying organisation, as a price resolution reads it: the id, which is a
|
|
288
|
+
* rule dimension and part of the cache key, and the group it belongs to, which
|
|
289
|
+
* a customer's own group overrides. The same two fields the engine's own
|
|
290
|
+
* `PricingOrganizationRef` names.
|
|
291
|
+
*
|
|
292
|
+
* Both slices take it. A cart line always has a buyer; a listing has one only
|
|
293
|
+
* where the surface knows who is reading — today, the comparison — and the
|
|
294
|
+
* *same* two fields have to travel either way, or a buyer's comparison column
|
|
295
|
+
* and their cart line would resolve against different price lists and disagree
|
|
296
|
+
* on the same product.
|
|
297
|
+
*/
|
|
298
|
+
export interface PriceOrganization {
|
|
299
|
+
id: string;
|
|
300
|
+
customerGroupId?: string | null;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Container name: `pricingService`. Owner: `price_lists`.
|
|
304
|
+
*
|
|
305
|
+
* The slice a **listing ordering** asks for (feature 086): the catalogue in
|
|
306
|
+
* resolved-unit-price order, for one viewer, one chunk at a time.
|
|
307
|
+
*
|
|
308
|
+
* A slice of the same container `ListingPricePort` and `LinePricePort` are
|
|
309
|
+
* slices of, rather than a second registration, and that is the design decision
|
|
310
|
+
* here. `catalog` already resolves `pricingService` and already acknowledges the
|
|
311
|
+
* edge; a second port over the same relation would be the second implementation
|
|
312
|
+
* of the resolution chain arriving by another door — the failure
|
|
313
|
+
* `listingPriceFrom` was extracted to end (issue #132, four listing paths
|
|
314
|
+
* rendering a figure no price list supported).
|
|
315
|
+
*
|
|
316
|
+
* ## What the ordering is
|
|
317
|
+
*
|
|
318
|
+
* For each product in scope the row is the resolution the card renders at
|
|
319
|
+
* quantity 1: the sale partition when it wins, else the base partition, from the
|
|
320
|
+
* highest-priority applicable price list that has a quantity-1 bracket in the
|
|
321
|
+
* response currency. "Applicable" and "highest-priority" mean exactly what
|
|
322
|
+
* `resolveListingPrices` means by them, including the FR-031 fall-through to the
|
|
323
|
+
* next candidate when a list has no usable bracket. That is a **contract
|
|
324
|
+
* obligation, not an implementation note**: the provider's own test asserts,
|
|
325
|
+
* product by product, that this port lists exactly what resolving every product
|
|
326
|
+
* with `resolveListingPrices` and sorting the amounts lists.
|
|
327
|
+
*
|
|
328
|
+
* The order is **total**: `(amount, productId)` ascending for `'asc'`, both
|
|
329
|
+
* descending for `'desc'`, so a keyset walk can neither repeat nor skip.
|
|
330
|
+
*
|
|
331
|
+
* ## What is not in the relation
|
|
332
|
+
*
|
|
333
|
+
* A product no candidate list prices has **no row** here. It is not returned
|
|
334
|
+
* with a null amount and it is not returned last. The caller learns the priced
|
|
335
|
+
* stream is over from `exhausted` and composes the unpriced tail itself, from
|
|
336
|
+
* data it owns — "there is no price for this viewer" is `catalog`'s question to
|
|
337
|
+
* answer about `catalog`'s products, and a placeholder row would be this
|
|
338
|
+
* provider making a listing decision it cannot see the consequences of.
|
|
339
|
+
*
|
|
340
|
+
* ## What this port does **not** do
|
|
341
|
+
*
|
|
342
|
+
* It does not filter by sales channel, product visibility, organisation
|
|
343
|
+
* allow-list, product status, archival, soft-deletion, category or attribute
|
|
344
|
+
* value. Those are `catalog`'s facts about `catalog`'s rows, in `catalog`'s
|
|
345
|
+
* tables, and `price_lists` may not name them — `check:module-boundary` reads a
|
|
346
|
+
* table identifier out of a SQL statement and out of a knex builder, not only
|
|
347
|
+
* out of an import specifier (D-87), so "it is only raw SQL" is not an escape.
|
|
348
|
+
*
|
|
349
|
+
* **The consequence, stated so it cannot be forgotten:** a chunk from this port
|
|
350
|
+
* may name products the viewer must never see. The caller MUST intersect every
|
|
351
|
+
* chunk with its own visibility and channel predicates **before** any row
|
|
352
|
+
* reaches a page, a cursor, a count or a log line.
|
|
353
|
+
*
|
|
354
|
+
* **Owner off:** the seam fails closed, exactly as {@link ListingPricePort}'s
|
|
355
|
+
* does — the port gate throws and the call answers 503 `MODULE_DISABLED`. A
|
|
356
|
+
* listing that invented an ordering would be worse than one that refuses, and a
|
|
357
|
+
* consumer must not wrap a call to it in a bare `catch`
|
|
358
|
+
* (`check:port-catches`): swallowing `ModuleDisabledError` would turn a
|
|
359
|
+
* fail-closed seam into a sort control that silently does nothing.
|
|
360
|
+
*/
|
|
361
|
+
export interface ListingPriceOrderPort {
|
|
362
|
+
orderByUnitPrice(input: ListingPriceOrderQuery): Promise<ListingPriceOrderChunk>;
|
|
363
|
+
/**
|
|
364
|
+
* Which of `productIds` the viewer's candidate lists price at quantity 1.
|
|
365
|
+
*
|
|
366
|
+
* It exists for one purpose: so the caller can compose the unpriced tail
|
|
367
|
+
* without asking "is this priced?" one product at a time. It is a set
|
|
368
|
+
* membership answer, not a price.
|
|
369
|
+
*/
|
|
370
|
+
pricedProductIds(input: {
|
|
371
|
+
context: ListingPriceViewerContext;
|
|
372
|
+
productIds: readonly string[];
|
|
373
|
+
}): Promise<ReadonlySet<string>>;
|
|
374
|
+
/**
|
|
375
|
+
* The display mode a page resolves to for this viewer with **no product in
|
|
376
|
+
* hand** — the Organization → Settings tail of the FR-039 chain, with the
|
|
377
|
+
* per-product and per-category steps deliberately absent.
|
|
378
|
+
*
|
|
379
|
+
* Feature 086 / FR-016 needs it: a price ordering or a price range is refused
|
|
380
|
+
* where the page may not show prices at all, and `none` is the supported
|
|
381
|
+
* "hide prices until login" configuration. The condition is page-level on
|
|
382
|
+
* purpose — a single product overridden to `none` keeps its position rather
|
|
383
|
+
* than withdrawing the control, or the control would appear and disappear as
|
|
384
|
+
* a buyer walks the catalogue.
|
|
385
|
+
*
|
|
386
|
+
* It is on this port rather than on a fourth one because it answers a
|
|
387
|
+
* question about the same viewer, on the same container, behind the same
|
|
388
|
+
* gate: a caller that may not order by price may not be told the ordering is
|
|
389
|
+
* unavailable by a port that is itself unreachable.
|
|
390
|
+
*/
|
|
391
|
+
pageDisplayMode(input: {
|
|
392
|
+
context: ListingPriceViewerContext;
|
|
393
|
+
}): Promise<DisplayMode>;
|
|
394
|
+
}
|
|
395
|
+
/** Who the ordering is resolved for — the rule dimensions, and nothing else. */
|
|
396
|
+
export interface ListingPriceViewerContext {
|
|
397
|
+
salesChannel: {
|
|
398
|
+
id: string;
|
|
399
|
+
defaultCurrency: string;
|
|
400
|
+
};
|
|
401
|
+
currencyCode?: string;
|
|
402
|
+
/** The buying organisation, when the viewer has one. `null` is the anonymous case. */
|
|
403
|
+
organization?: PriceOrganization | null;
|
|
404
|
+
/** Feature 040 — a customer's direct group overrides the organisation's. */
|
|
405
|
+
customerGroupId?: string | null;
|
|
406
|
+
}
|
|
407
|
+
export interface ListingPriceOrderQuery {
|
|
408
|
+
context: ListingPriceViewerContext;
|
|
409
|
+
direction: 'asc' | 'desc';
|
|
410
|
+
/** Keyset resume point; `null` starts at the extreme of `direction`. */
|
|
411
|
+
after: ListingPriceOrderCursor | null;
|
|
412
|
+
/** How many rows the caller wants back. The provider MAY return fewer. */
|
|
413
|
+
limit: number;
|
|
414
|
+
/**
|
|
415
|
+
* Opaque product ids the ordering is restricted to. `undefined` means the
|
|
416
|
+
* whole catalogue; an empty array means nothing and answers an empty,
|
|
417
|
+
* exhausted chunk.
|
|
418
|
+
*
|
|
419
|
+
* The provider does not interpret the ids, does not know why they were chosen
|
|
420
|
+
* and does not check that they exist. It exists so a caller that has already
|
|
421
|
+
* narrowed the catalogue — by category tree, or by a relevance-matched set —
|
|
422
|
+
* can have the ordering run over that narrowing instead of over everything.
|
|
423
|
+
*
|
|
424
|
+
* **It is not a visibility mechanism.** A caller that omits it gets the whole
|
|
425
|
+
* priced catalogue ordered, including products the viewer may not see.
|
|
426
|
+
*/
|
|
427
|
+
restrictToProductIds?: readonly string[] | undefined;
|
|
428
|
+
/** Inclusive bounds on the resolved amount, as decimal strings. */
|
|
429
|
+
amountRange?: {
|
|
430
|
+
min?: string;
|
|
431
|
+
max?: string;
|
|
432
|
+
} | undefined;
|
|
433
|
+
}
|
|
434
|
+
export interface ListingPriceOrderCursor {
|
|
435
|
+
amount: string;
|
|
436
|
+
productId: string;
|
|
437
|
+
}
|
|
438
|
+
export interface ListingPriceOrderRow {
|
|
439
|
+
productId: string;
|
|
440
|
+
/** Decimal string, verbatim from `numeric(14,4)`. Never a number on this path. */
|
|
441
|
+
amount: string;
|
|
442
|
+
currency: string;
|
|
443
|
+
priceListId: string;
|
|
444
|
+
isSale: boolean;
|
|
445
|
+
}
|
|
446
|
+
export interface ListingPriceOrderChunk {
|
|
447
|
+
rows: ListingPriceOrderRow[];
|
|
448
|
+
/**
|
|
449
|
+
* `true` when the provider reached the end of the priced relation for this
|
|
450
|
+
* query. The caller uses it to move to the unpriced tail; it is NOT inferable
|
|
451
|
+
* from a short `rows`, because the provider may stop early on its own scan
|
|
452
|
+
* bound.
|
|
453
|
+
*/
|
|
454
|
+
exhausted: boolean;
|
|
455
|
+
/**
|
|
456
|
+
* How many source rows the provider read to produce `rows`. The caller
|
|
457
|
+
* subtracts it from its own page budget, so FR-019's bound is enforced across
|
|
458
|
+
* chunks rather than per chunk.
|
|
459
|
+
*/
|
|
460
|
+
sourceRowsRead: number;
|
|
461
|
+
}
|
|
462
|
+
/** What a resolved line price is, once the whole chain has run. */
|
|
463
|
+
export interface LinePriceResult {
|
|
464
|
+
/** Decimal string — it lands verbatim on the cart line and then the order. */
|
|
465
|
+
amount: string;
|
|
466
|
+
currency: string;
|
|
467
|
+
priceListId: string;
|
|
468
|
+
isSale: boolean;
|
|
469
|
+
bracketStartQuantity: number;
|
|
470
|
+
displayMode: DisplayMode;
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Container name: `pricingService`. Owner: `price_lists`.
|
|
474
|
+
*
|
|
475
|
+
* The slice of the `pricingService` port a **line** resolution asks for —
|
|
476
|
+
* `ListingPricePort`'s sibling, and declared here for the same reasons: one
|
|
477
|
+
* wording for every caller, and a *shape* rather than an import of
|
|
478
|
+
* `price_lists/services/pricing-service.interface.ts`, so a consumer does not
|
|
479
|
+
* reach into the owning module (Principle I). The owner's
|
|
480
|
+
* `PricingServiceContract` is a superset and satisfies it structurally.
|
|
481
|
+
*
|
|
482
|
+
* The difference from the listing slice is the *quantity* and the *buyer*: a
|
|
483
|
+
* cart line is priced at its own quantity, against the buying organisation's
|
|
484
|
+
* resolved list, so both are in the context and neither is optional in the way
|
|
485
|
+
* an anonymous catalogue card's are.
|
|
486
|
+
*
|
|
487
|
+
* `null` is the resolver's own documented answer for "nothing applies", and it
|
|
488
|
+
* is not the same thing as an absent `price_lists`. With the module off the
|
|
489
|
+
* gate throws `ModuleDisabledError` — issue #124: a cart must refuse rather
|
|
490
|
+
* than invent a figure, and the absent arm of {@link ListingPrice} carries no
|
|
491
|
+
* `amount` for exactly the same reason.
|
|
492
|
+
*/
|
|
493
|
+
export interface LinePricePort {
|
|
494
|
+
resolveLinePrice(input: {
|
|
495
|
+
product: ListingPriceProduct;
|
|
496
|
+
variantId?: string | null;
|
|
497
|
+
context: {
|
|
498
|
+
quantity: number;
|
|
499
|
+
organization?: PriceOrganization | null;
|
|
500
|
+
/** Feature 040 — a customer's direct group overrides the org's. */
|
|
501
|
+
customerGroupId?: string | null;
|
|
502
|
+
salesChannel: {
|
|
503
|
+
id: string;
|
|
504
|
+
defaultCurrency: string;
|
|
505
|
+
};
|
|
506
|
+
currencyCode?: string;
|
|
507
|
+
};
|
|
508
|
+
}): Promise<LinePriceResult | null>;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Container name: `pricingService`. Owner: `price_lists`.
|
|
512
|
+
*
|
|
513
|
+
* `LinePricePort` plus the bracket ladder — the surface `catalog`'s external
|
|
514
|
+
* namespace prices a bound organisation's request with. Same container name,
|
|
515
|
+
* same owner, one method more, and the same fail-closed answer when the owner
|
|
516
|
+
* is off.
|
|
517
|
+
*
|
|
518
|
+
* **An extension rather than two more methods on `LinePricePort`**, and that is
|
|
519
|
+
* the whole design decision here. Every consumer of a published port types a
|
|
520
|
+
* structural stub against it in tests; widening `LinePricePort` broke one in
|
|
521
|
+
* `carts` that has no interest in brackets, and would break the next one too.
|
|
522
|
+
* A caller that needs both asks for both by name.
|
|
523
|
+
*
|
|
524
|
+
* It had to be published somewhere for feature 075's `catalog` cut, because
|
|
525
|
+
* `listBracketMinQuantities` was declared **only** on
|
|
526
|
+
* `price_lists/services/pricing-service.interface.ts` — and that file is
|
|
527
|
+
* deliberately not in this package, because it is the target of the
|
|
528
|
+
* feature-057 overlay decoration and moving it would move the contract gate.
|
|
529
|
+
* The alternative was `catalog` declaring the shape on its own side, where
|
|
530
|
+
* `lazyPort<T>`'s unchecked cast would leave nothing verifying that
|
|
531
|
+
* `price_lists` still satisfies it (D-77's rejected alternative, same
|
|
532
|
+
* reasoning). `PricingServiceContract` is a superset and satisfies this
|
|
533
|
+
* structurally, so no implementation changed.
|
|
534
|
+
*/
|
|
535
|
+
export interface OrgLinePricePort extends LinePricePort {
|
|
536
|
+
/**
|
|
537
|
+
* Feature 062 — the distinct bracket start quantities (ascending) across
|
|
538
|
+
* every ACTIVE price list for a (product, currency). The caller probes
|
|
539
|
+
* `resolveLinePrice` at each one to build the buying organisation's effective
|
|
540
|
+
* tier ladder without re-implementing resolution.
|
|
541
|
+
*/
|
|
542
|
+
listBracketMinQuantities(productId: string, currencyCode: string): Promise<number[]>;
|
|
543
|
+
}
|
|
544
|
+
export declare const PRICING_SETTING_CODES: {
|
|
545
|
+
readonly DEFAULT_DISPLAY_MODE: "pricing.default_display_mode";
|
|
546
|
+
readonly UNAUTHENTICATED_DISPLAY_MODE: "pricing.unauthenticated_display_mode";
|
|
547
|
+
};
|
|
548
|
+
/** A price list as a module outside `price_lists` sees it. */
|
|
549
|
+
export interface PriceListRecord {
|
|
550
|
+
id: string;
|
|
551
|
+
code: string;
|
|
552
|
+
name: string;
|
|
553
|
+
currency: string;
|
|
554
|
+
isDefault: boolean;
|
|
555
|
+
priority: number;
|
|
556
|
+
type: 'base' | 'sale';
|
|
557
|
+
status: 'draft' | 'active' | 'scheduled' | 'expired';
|
|
558
|
+
startsAt: Date | null;
|
|
559
|
+
endsAt: Date | null;
|
|
560
|
+
applicationRule: ApplicationRule;
|
|
561
|
+
isSystem: boolean;
|
|
562
|
+
modifiedAt: Date;
|
|
563
|
+
createdAt: Date;
|
|
564
|
+
updatedAt: Date;
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Container name: `priceListReadPort`. Owner: `price_lists`.
|
|
568
|
+
*
|
|
569
|
+
* `organizations` resolves which lists apply to an org, `product_feeds` reads
|
|
570
|
+
* the list a feed prices from. Both read the row; neither should own the
|
|
571
|
+
* question of what "active" means, which is why `listActive` is here rather
|
|
572
|
+
* than a status filter in each caller.
|
|
573
|
+
*
|
|
574
|
+
* **Owner off:** the seam fails closed — resolving this port throws
|
|
575
|
+
* `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`, so nothing
|
|
576
|
+
* half-executes. Whether `price_lists` has an off state at all is its manifest's
|
|
577
|
+
* `activation` to say, not this line's: a module declaring
|
|
578
|
+
* `nonDeactivatable` never enters one.
|
|
579
|
+
*/
|
|
580
|
+
export interface PriceListReadPort {
|
|
581
|
+
findById(id: string): Promise<PriceListRecord | null>;
|
|
582
|
+
findByIds(ids: readonly string[]): Promise<PriceListRecord[]>;
|
|
583
|
+
findByCode(code: string): Promise<PriceListRecord | null>;
|
|
584
|
+
/** Every list, ordered by priority then code. */
|
|
585
|
+
listAll(): Promise<PriceListRecord[]>;
|
|
586
|
+
/** Only `status === 'active'`, ordered by priority then code. */
|
|
587
|
+
listActive(): Promise<PriceListRecord[]>;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* One quantity bracket of a product's price on a list.
|
|
591
|
+
*
|
|
592
|
+
* `amount` is a decimal **string** — the storage shape on
|
|
593
|
+
* `price_list_price_brackets`. A `number` cannot round-trip a price, and this
|
|
594
|
+
* value comes in from a PIM import and goes out to a checkout.
|
|
595
|
+
*/
|
|
596
|
+
export interface PriceBracketInput {
|
|
597
|
+
minQuantity: number;
|
|
598
|
+
maxQuantity: number | null;
|
|
599
|
+
amount: string;
|
|
600
|
+
}
|
|
601
|
+
/** One list's brackets for a product, as the admin summary renders them. */
|
|
602
|
+
export interface PriceListBracketSummary {
|
|
603
|
+
list: {
|
|
604
|
+
id: string;
|
|
605
|
+
name: string;
|
|
606
|
+
type: 'base' | 'sale';
|
|
607
|
+
status: 'draft' | 'active' | 'scheduled' | 'expired';
|
|
608
|
+
modifiedAt: Date;
|
|
609
|
+
};
|
|
610
|
+
summary: Array<{
|
|
611
|
+
currencyCode: string;
|
|
612
|
+
summary: string;
|
|
613
|
+
}>;
|
|
614
|
+
deepLinkPath: string;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Container name: `priceListAdminPort`. Owner: `price_lists`.
|
|
618
|
+
*
|
|
619
|
+
* `pim_ergonode` writes prices as part of an import run: it resolves the list,
|
|
620
|
+
* adds the product to it if it is not there, replaces the brackets, and reads
|
|
621
|
+
* back the summary its field-protection rules compare against. That is the
|
|
622
|
+
* whole of what it needs, and publishing more would be publishing the class.
|
|
623
|
+
*
|
|
624
|
+
* **Owner off:** the seam fails closed — resolving this port throws
|
|
625
|
+
* `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`, so nothing
|
|
626
|
+
* half-executes. Whether `price_lists` has an off state at all is its manifest's
|
|
627
|
+
* `activation` to say, not this line's: a module declaring
|
|
628
|
+
* `nonDeactivatable` never enters one.
|
|
629
|
+
*/
|
|
630
|
+
export interface PriceListAdminPort {
|
|
631
|
+
getById(id: string): Promise<PriceListRecord>;
|
|
632
|
+
listProducts(priceListId: string): Promise<Array<{
|
|
633
|
+
productId: string;
|
|
634
|
+
bracketsByCurrency: Record<string, PriceBracketInput[]>;
|
|
635
|
+
}>>;
|
|
636
|
+
addProduct(priceListId: string, productId: string): Promise<void>;
|
|
637
|
+
replaceBrackets(priceListId: string, productId: string, bracketsByCurrency: Record<string, readonly PriceBracketInput[]>): Promise<Record<string, PriceBracketInput[]>>;
|
|
638
|
+
summarizeBracketsForProduct(productId: string): Promise<PriceListBracketSummary[]>;
|
|
639
|
+
}
|
|
640
|
+
/** What a rule is evaluated against. */
|
|
641
|
+
export interface PriceListResolutionContext {
|
|
642
|
+
organizationId: string | null;
|
|
643
|
+
/**
|
|
644
|
+
* Feature 056 — the acting org's inheritance chain, nearest-first
|
|
645
|
+
* (`[orgId, ...ancestorIds]`). When present, the `organization` criterion
|
|
646
|
+
* matches ANY org in the chain, and the resolver ranks by nearness so a list
|
|
647
|
+
* naming a nearer org outranks one naming a farther ancestor (R5). When
|
|
648
|
+
* absent, it defaults to `[organizationId]` (flat behaviour, byte-for-byte).
|
|
649
|
+
*/
|
|
650
|
+
organizationChain?: readonly string[];
|
|
651
|
+
customerGroupId: string | null;
|
|
652
|
+
salesChannelId: string;
|
|
653
|
+
currencyCode: string;
|
|
654
|
+
productCategoryIds: ReadonlySet<string>;
|
|
655
|
+
}
|
|
656
|
+
export interface PriceListRuleEvaluation {
|
|
657
|
+
matched: boolean;
|
|
658
|
+
explicitOn: ReadonlySet<RuleCriterionType>;
|
|
659
|
+
/**
|
|
660
|
+
* Feature 056 — index of the NEAREST org (in the resolution chain) that this
|
|
661
|
+
* rule explicitly names, or `undefined` when the rule names no org in the
|
|
662
|
+
* chain. Lower = nearer = higher price-list priority within the
|
|
663
|
+
* `organization` level (R5). A direct-org match (flat) is rank 0.
|
|
664
|
+
*/
|
|
665
|
+
organizationRank?: number;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Pure rule evaluator (feature 011 / FR-022, FR-023, FR-026, FR-029).
|
|
669
|
+
*
|
|
670
|
+
* Walks the discriminated-union AST and returns:
|
|
671
|
+
* - `matched`: the overall AST truth value against the resolution context.
|
|
672
|
+
* - `explicitOn`: the criterion types that contributed to the match AND had
|
|
673
|
+
* non-empty value lists. The resolver's priority chain consults this to
|
|
674
|
+
* award the per-step boost (FR-026 steps 1..4).
|
|
675
|
+
*
|
|
676
|
+
* Notes:
|
|
677
|
+
* - The `category` criterion is product-driven (FR-029): it matches when the
|
|
678
|
+
* product belongs to any category named in the rule's value list.
|
|
679
|
+
* - The `currency` criterion never appears in the priority chain even when
|
|
680
|
+
* explicit; it is purely a matching criterion.
|
|
681
|
+
* - `{ kind: 'all' }` and any criterion with `values: []` are treated as
|
|
682
|
+
* always-true and contribute nothing to `explicitOn` (FR-022).
|
|
683
|
+
*/
|
|
684
|
+
export declare function evaluateApplicationRule(rule: ApplicationRule, ctx: PriceListResolutionContext): PriceListRuleEvaluation;
|
|
685
|
+
//# sourceMappingURL=price-lists.d.ts.map
|