rerobe-js-orm 4.8.8 → 4.9.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.
Files changed (67) hide show
  1. package/lib/constants/marketplace-constants.d.ts +52 -0
  2. package/lib/constants/marketplace-constants.js +82 -0
  3. package/lib/constants/product-constants.d.ts +6 -0
  4. package/lib/constants/product-constants.js +43 -1
  5. package/lib/constants/tax-constants.d.ts +19 -0
  6. package/lib/constants/tax-constants.js +70 -0
  7. package/lib/factories/Product/RetailProductFactory.d.ts +102 -0
  8. package/lib/factories/Product/RetailProductFactory.js +260 -0
  9. package/lib/form-states/Product/ProductFormState.d.ts +9 -0
  10. package/lib/form-states/Product/ProductFormState.js +46 -0
  11. package/lib/helpers/MarketplaceProductHelpers.d.ts +181 -0
  12. package/lib/helpers/MarketplaceProductHelpers.js +555 -0
  13. package/lib/helpers/OrderHelpers.d.ts +5 -2
  14. package/lib/helpers/OrderHelpers.js +18 -4
  15. package/lib/helpers/PricingHelpers.d.ts +29 -0
  16. package/lib/helpers/PricingHelpers.js +215 -0
  17. package/lib/helpers/ProductInventoryHelpers.d.ts +31 -0
  18. package/lib/helpers/ProductInventoryHelpers.js +66 -0
  19. package/lib/helpers/ProductSkuHelpers.d.ts +13 -0
  20. package/lib/helpers/ProductSkuHelpers.js +70 -0
  21. package/lib/helpers/TaxHelpers.d.ts +15 -0
  22. package/lib/helpers/TaxHelpers.js +76 -0
  23. package/lib/helpers/marketplace/CommissionPolicy.d.ts +20 -0
  24. package/lib/helpers/marketplace/CommissionPolicy.js +9 -0
  25. package/lib/helpers/marketplace/CommissionPolicyRegistry.d.ts +4 -0
  26. package/lib/helpers/marketplace/CommissionPolicyRegistry.js +21 -0
  27. package/lib/helpers/marketplace/EvenPerSellerStripeFeePolicy.d.ts +5 -0
  28. package/lib/helpers/marketplace/EvenPerSellerStripeFeePolicy.js +46 -0
  29. package/lib/helpers/marketplace/FeeAllocationPolicy.d.ts +10 -0
  30. package/lib/helpers/marketplace/FeeAllocationPolicy.js +36 -0
  31. package/lib/helpers/marketplace/FeeAllocationPolicyRegistry.d.ts +6 -0
  32. package/lib/helpers/marketplace/FeeAllocationPolicyRegistry.js +26 -0
  33. package/lib/helpers/marketplace/InventoryPolicy.d.ts +18 -0
  34. package/lib/helpers/marketplace/InventoryPolicy.js +7 -0
  35. package/lib/helpers/marketplace/InventoryPolicyRegistry.d.ts +4 -0
  36. package/lib/helpers/marketplace/InventoryPolicyRegistry.js +29 -0
  37. package/lib/helpers/marketplace/LineNetCommissionPolicy.d.ts +5 -0
  38. package/lib/helpers/marketplace/LineNetCommissionPolicy.js +25 -0
  39. package/lib/helpers/marketplace/MarketplaceErrors.d.ts +6 -0
  40. package/lib/helpers/marketplace/MarketplaceErrors.js +21 -0
  41. package/lib/helpers/marketplace/MarketplaceLedgerHelpers.d.ts +40 -0
  42. package/lib/helpers/marketplace/MarketplaceLedgerHelpers.js +120 -0
  43. package/lib/helpers/marketplace/MarketplaceLegacyAdapters.d.ts +53 -0
  44. package/lib/helpers/marketplace/MarketplaceLegacyAdapters.js +99 -0
  45. package/lib/helpers/marketplace/MarketplaceLineDisplayHelpers.d.ts +40 -0
  46. package/lib/helpers/marketplace/MarketplaceLineDisplayHelpers.js +125 -0
  47. package/lib/helpers/marketplace/MarketplaceOrderHelpers.d.ts +15 -0
  48. package/lib/helpers/marketplace/MarketplaceOrderHelpers.js +77 -0
  49. package/lib/helpers/marketplace/MultivariantLocationInventoryPolicy.d.ts +9 -0
  50. package/lib/helpers/marketplace/MultivariantLocationInventoryPolicy.js +60 -0
  51. package/lib/helpers/marketplace/OneOfAKindInventoryPolicy.d.ts +9 -0
  52. package/lib/helpers/marketplace/OneOfAKindInventoryPolicy.js +55 -0
  53. package/lib/helpers/marketplace/OriginalCommissionShareCommissionPolicy.d.ts +5 -0
  54. package/lib/helpers/marketplace/OriginalCommissionShareCommissionPolicy.js +26 -0
  55. package/lib/helpers/marketplace/ProportionalToLineNetPolicy.d.ts +5 -0
  56. package/lib/helpers/marketplace/ProportionalToLineNetPolicy.js +35 -0
  57. package/lib/helpers/marketplace/UntrackedStockInventoryPolicy.d.ts +7 -0
  58. package/lib/helpers/marketplace/UntrackedStockInventoryPolicy.js +23 -0
  59. package/lib/index.d.ts +18 -1
  60. package/lib/index.js +56 -1
  61. package/lib/models/Product.d.ts +16 -0
  62. package/lib/models/Product.js +140 -0
  63. package/lib/types/pricing-types.d.ts +85 -0
  64. package/lib/types/pricing-types.js +5 -0
  65. package/lib/types/rerobe-order-types.d.ts +86 -0
  66. package/lib/types/rerobe-product-types.d.ts +19 -0
  67. package/package.json +1 -1
@@ -0,0 +1,555 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MarketplaceOwnershipError = exports.MarketplaceCommissionRateError = void 0;
4
+ const ReRobeProductHelpers_1 = require("./ReRobeProductHelpers");
5
+ const marketplace_constants_1 = require("../constants/marketplace-constants");
6
+ const CommissionPolicyRegistry = require("./marketplace/CommissionPolicyRegistry");
7
+ const FeeAllocationPolicyRegistry = require("./marketplace/FeeAllocationPolicyRegistry");
8
+ const InventoryPolicyRegistry = require("./marketplace/InventoryPolicyRegistry");
9
+ var MarketplaceErrors_1 = require("./marketplace/MarketplaceErrors");
10
+ Object.defineProperty(exports, "MarketplaceCommissionRateError", { enumerable: true, get: function () { return MarketplaceErrors_1.MarketplaceCommissionRateError; } });
11
+ Object.defineProperty(exports, "MarketplaceOwnershipError", { enumerable: true, get: function () { return MarketplaceErrors_1.MarketplaceOwnershipError; } });
12
+ const MarketplaceErrors_2 = require("./marketplace/MarketplaceErrors");
13
+ const roundMoney = (value) => Number(Number(value || 0).toFixed(2));
14
+ const normalizeVariantOptionsInput = (options) => {
15
+ if (!options)
16
+ return undefined;
17
+ if (Array.isArray(options)) {
18
+ const normalized = options.reduce((acc, option) => {
19
+ const key = (option === null || option === void 0 ? void 0 : option.name) || (option === null || option === void 0 ? void 0 : option.key) || (option === null || option === void 0 ? void 0 : option.label) || '';
20
+ const value = option === null || option === void 0 ? void 0 : option.value;
21
+ if (key && value !== undefined && value !== null && String(value).trim()) {
22
+ acc[String(key)] = String(value);
23
+ }
24
+ return acc;
25
+ }, {});
26
+ return Object.keys(normalized).length ? normalized : undefined;
27
+ }
28
+ if (typeof options === 'object')
29
+ return options;
30
+ return undefined;
31
+ };
32
+ // Pulls a `VariantSelectionInput` out of an order line item, supporting the
33
+ // shapes the backend currently produces:
34
+ // - `lineItem.variant.id` (canonical ReRobe lines)
35
+ // - `lineItem.variantId` (flattened shape some callers emit)
36
+ // - `lineItem.variant.options` (options-map lines used by the form-state)
37
+ // - `lineItem.selectedOptions` (Shopify/storefront shape we ingest)
38
+ // Returns `undefined` when nothing variant-shaped is present so call-sites
39
+ // fall back to product-level pricing/snapshotting without surprises.
40
+ const deriveVariantSelectionFromLineItem = (lineItem) => {
41
+ if (!lineItem || typeof lineItem !== 'object')
42
+ return undefined;
43
+ const variantId = (lineItem.variant && lineItem.variant.id) ||
44
+ lineItem.variantId ||
45
+ (lineItem.variant && lineItem.variant.variantId) ||
46
+ '';
47
+ const options = (lineItem.variant && lineItem.variant.options) || lineItem.variantOptions || lineItem.selectedOptions || undefined;
48
+ const normalizedOptions = normalizeVariantOptionsInput(options);
49
+ if (!variantId && !normalizedOptions)
50
+ return undefined;
51
+ const selection = {};
52
+ if (variantId)
53
+ selection.variantId = String(variantId);
54
+ if (normalizedOptions)
55
+ selection.options = normalizedOptions;
56
+ return selection;
57
+ };
58
+ class MarketplaceProductHelpers {
59
+ static registerCommissionPolicy(policy) {
60
+ CommissionPolicyRegistry.register(policy);
61
+ }
62
+ static getCommissionPolicy(basis) {
63
+ return CommissionPolicyRegistry.get(basis);
64
+ }
65
+ static hasCommissionPolicy(basis) {
66
+ return CommissionPolicyRegistry.has(basis);
67
+ }
68
+ static emptyMarketplace() {
69
+ return {
70
+ visibleToMerchantIds: [],
71
+ listings: {},
72
+ };
73
+ }
74
+ static uniqueStrings(values = []) {
75
+ return Array.from(new Set((Array.isArray(values) ? values : [])
76
+ .filter((v) => v !== undefined && v !== null && String(v).trim())
77
+ .map((v) => String(v))));
78
+ }
79
+ static normalizeMarketplace(input) {
80
+ const visibleToMerchantIds = this.uniqueStrings((input === null || input === void 0 ? void 0 : input.visibleToMerchantIds) || []);
81
+ const rawListings = (input === null || input === void 0 ? void 0 : input.listings) && typeof input.listings === 'object' ? input.listings : {};
82
+ const listings = Object.keys(rawListings).reduce((acc, parentMarketplaceId) => {
83
+ const listing = rawListings[parentMarketplaceId] || {};
84
+ if (!parentMarketplaceId)
85
+ return acc;
86
+ acc[parentMarketplaceId] = {
87
+ relationshipId: String(listing.relationshipId || ''),
88
+ relationshipType: String(listing.relationshipType || ''),
89
+ status: String(listing.status || marketplace_constants_1.DEFAULT_MARKETPLACE_LISTING_STATUS),
90
+ listedAt: listing.listedAt === undefined || listing.listedAt === null ? null : Number(listing.listedAt),
91
+ updatedAt: listing.updatedAt === undefined || listing.updatedAt === null ? null : Number(listing.updatedAt),
92
+ };
93
+ return acc;
94
+ }, {});
95
+ return {
96
+ visibleToMerchantIds,
97
+ listings,
98
+ };
99
+ }
100
+ static buildMarketplace({ productMerchantId = '', listings = [], }) {
101
+ const normalizedListings = listings.reduce((acc, listing) => {
102
+ if (!(listing === null || listing === void 0 ? void 0 : listing.parentMarketplaceId))
103
+ return acc;
104
+ acc[listing.parentMarketplaceId] = {
105
+ relationshipId: String(listing.relationshipId || ''),
106
+ relationshipType: String(listing.relationshipType || marketplace_constants_1.DEFAULT_MARKETPLACE_RELATIONSHIP_TYPE),
107
+ status: String(listing.status || marketplace_constants_1.DEFAULT_MARKETPLACE_LISTING_STATUS),
108
+ listedAt: listing.listedAt === undefined || listing.listedAt === null ? null : Number(listing.listedAt),
109
+ updatedAt: listing.updatedAt === undefined || listing.updatedAt === null ? null : Number(listing.updatedAt),
110
+ };
111
+ return acc;
112
+ }, {});
113
+ const activeParentIds = Object.keys(normalizedListings).filter((parentId) => { var _a; return ((_a = normalizedListings[parentId]) === null || _a === void 0 ? void 0 : _a.status) !== marketplace_constants_1.MARKETPLACE_LISTING_STATUSES.removed; });
114
+ return {
115
+ visibleToMerchantIds: this.uniqueStrings([productMerchantId, ...activeParentIds]),
116
+ listings: normalizedListings,
117
+ };
118
+ }
119
+ static buildTypesenseFields(marketplace) {
120
+ const normalized = this.normalizeMarketplace(marketplace);
121
+ const marketplaceParentMerchantIds = Object.keys(normalized.listings).filter((parentId) => { var _a; return ((_a = normalized.listings[parentId]) === null || _a === void 0 ? void 0 : _a.status) !== marketplace_constants_1.MARKETPLACE_LISTING_STATUSES.removed; });
122
+ const marketplaceRelationshipIds = this.uniqueStrings(marketplaceParentMerchantIds.map((parentId) => { var _a; return (_a = normalized.listings[parentId]) === null || _a === void 0 ? void 0 : _a.relationshipId; }));
123
+ return {
124
+ marketplaceVisibleToMerchantIds: this.uniqueStrings(normalized.visibleToMerchantIds),
125
+ marketplaceParentMerchantIds,
126
+ marketplaceRelationshipIds,
127
+ isMarketplaceVisible: marketplaceParentMerchantIds.length > 0,
128
+ };
129
+ }
130
+ static toRate(value) {
131
+ return Number(ReRobeProductHelpers_1.default.commissionFixer(value === undefined || value === null ? '0' : value));
132
+ }
133
+ static roundMoney(value) {
134
+ return roundMoney(value);
135
+ }
136
+ static lineNetFromProduct(product, quantity = 1, variant) {
137
+ const priceSource = (variant === null || variant === void 0 ? void 0 : variant.isOnSale) === 'yes' && variant.salePrice ? variant.salePrice : variant === null || variant === void 0 ? void 0 : variant.price;
138
+ const productPriceSource = product.isOnSale === 'yes' && Boolean(product.clearanceTimestamp) && product.salePrice
139
+ ? product.salePrice
140
+ : product.price;
141
+ const unitPrice = Number(priceSource || productPriceSource || 0);
142
+ return roundMoney(unitPrice * (quantity || 1));
143
+ }
144
+ static selectVariant(product, selection = {}) {
145
+ const variants = Array.isArray(product.variantInventory) ? product.variantInventory : [];
146
+ if (!variants.length)
147
+ return null;
148
+ const variant = variants.find((v) => selection.variantId && (v === null || v === void 0 ? void 0 : v.id) === selection.variantId) ||
149
+ variants.find((v) => {
150
+ if (!selection.options)
151
+ return false;
152
+ const optionKeys = Object.keys(selection.options);
153
+ return optionKeys.every((key) => { var _a, _b; return ((_a = v === null || v === void 0 ? void 0 : v.options) === null || _a === void 0 ? void 0 : _a[key]) === ((_b = selection.options) === null || _b === void 0 ? void 0 : _b[key]); });
154
+ }) ||
155
+ null;
156
+ if (!variant)
157
+ return null;
158
+ return {
159
+ variantId: String(variant.id || ''),
160
+ sku: String(variant.sku || product.sku || ''),
161
+ options: variant.options || {},
162
+ price: String(variant.price || product.price || ''),
163
+ compareAtPrice: variant.compareAtPrice || null,
164
+ salePrice: variant.salePrice || null,
165
+ isOnSale: variant.isOnSale || null,
166
+ taxable: variant.taxable || (product.isTaxable === 'yes' ? 'yes' : product.isTaxable === 'no' ? 'no' : null),
167
+ taxCategory: String(product.taxCategory || 'STANDARD'),
168
+ locations: Array.isArray(variant.locations)
169
+ ? variant.locations.map((loc) => (Object.assign(Object.assign({}, loc), { availableAmount: Number(loc === null || loc === void 0 ? void 0 : loc.availableAmount) || 0, incomingAmount: Number(loc === null || loc === void 0 ? void 0 : loc.incomingAmount) || 0 })))
170
+ : [],
171
+ };
172
+ }
173
+ static buildLineSnapshot({ product, parentMerchantId, managedMerchantId, relationshipId, sellerDisplayName, lineDisplayTitle, marketplaceCommissionRate, originalProductCommissionRate, marketplaceCommissionBasis = marketplace_constants_1.DEFAULT_MARKETPLACE_COMMISSION_BASIS, quantity = 1, currencyCode = '', discountAmount = 0, taxAmount = 0, stripeFeeAllocatedAmount = 0, ribbnFeeAllocatedAmount = 0, variantSelection = {}, }) {
174
+ const variant = this.selectVariant(product, variantSelection);
175
+ const q = Number(quantity) > 0 ? Number(quantity) : 1;
176
+ const lineNetAmount = this.lineNetFromProduct(product, q, variant || undefined);
177
+ const safeDiscount = roundMoney(Math.max(0, Number(discountAmount) || 0));
178
+ const taxableAmount = roundMoney(Math.max(0, lineNetAmount - safeDiscount));
179
+ const safeTax = roundMoney(Number(taxAmount) || 0);
180
+ const lineGrossAmount = roundMoney(taxableAmount + safeTax);
181
+ const originalRate = this.toRate(originalProductCommissionRate === undefined ? product.reRobeCommission || '0' : originalProductCommissionRate);
182
+ const marketplaceRate = this.toRate(marketplaceCommissionRate);
183
+ const safeStripeFee = roundMoney(Number(stripeFeeAllocatedAmount) || 0);
184
+ const safeRibbnFee = roundMoney(Number(ribbnFeeAllocatedAmount) || 0);
185
+ const policy = this.getCommissionPolicy(marketplaceCommissionBasis);
186
+ const policyResult = policy.calculate({ taxableAmount, originalRate, marketplaceRate }, { stripeFee: safeStripeFee, ribbnFee: safeRibbnFee });
187
+ const marketplaceProceedsAmount = roundMoney(policyResult.marketplaceCommissionAmount + safeStripeFee);
188
+ return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ isMarketplaceItem: true, parentMerchantId: String(parentMerchantId || ''), managedMerchantId: String(managedMerchantId || product.merchantId || product.vendorId || ''), relationshipId: String(relationshipId || ''), productId: String(product.documentId || '') }, ((variant === null || variant === void 0 ? void 0 : variant.variantId) ? { variantId: variant.variantId } : {})), (sellerDisplayName ? { sellerDisplayName: String(sellerDisplayName) } : {})), (lineDisplayTitle ? { lineDisplayTitle: String(lineDisplayTitle) } : {})), { originalProductCommissionRate: String(originalRate), marketplaceCommissionRate: String(marketplaceRate), marketplaceCommissionBasis: policy.basis, quantity: q, currencyCode, amounts: {
189
+ lineNetAmount,
190
+ discountAmount: safeDiscount,
191
+ taxableAmount,
192
+ taxAmount: safeTax,
193
+ lineGrossAmount,
194
+ originalProductCommissionAmount: policyResult.originalProductCommissionAmount,
195
+ marketplaceCommissionAmount: policyResult.marketplaceCommissionAmount,
196
+ stripeFeeAllocatedAmount: safeStripeFee,
197
+ ribbnFeeAllocatedAmount: safeRibbnFee,
198
+ sellerProceedsAmount: policyResult.sellerProceedsAmount,
199
+ managedMerchantProceedsAmount: policyResult.managedMerchantProceedsAmount,
200
+ marketplaceProceedsAmount,
201
+ } }), (variant ? { variant } : {}));
202
+ }
203
+ // Derives a `VariantSelectionInput` from an order line item. Exposed so
204
+ // backend/web callers that load a product separately can resolve variant
205
+ // identity from a line item without re-implementing the shape juggling
206
+ // (canonical `variant.id` vs. flattened `variantId` vs. options maps).
207
+ static deriveVariantSelectionFromLineItem(lineItem) {
208
+ return deriveVariantSelectionFromLineItem(lineItem);
209
+ }
210
+ static buildLineSnapshotFromListing({ product, parentMerchantId, relationship = null, lineItem = {}, quantity, currencyCode, marketplaceCommissionRate, originalProductCommissionRate, marketplaceCommissionBasis, discountAmount, taxAmount, stripeFeeAllocatedAmount = 0, ribbnFeeAllocatedAmount = 0, variantSelection, }) {
211
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
212
+ if (!product || !parentMerchantId)
213
+ return null;
214
+ const managedMerchantId = String(product.merchantId || product.vendorId || '');
215
+ if (!managedMerchantId || managedMerchantId === parentMerchantId)
216
+ return null;
217
+ const marketplace = this.normalizeMarketplace(product.marketplace);
218
+ const listing = marketplace.listings[parentMerchantId];
219
+ if (!listing || listing.status === marketplace_constants_1.MARKETPLACE_LISTING_STATUSES.removed) {
220
+ return null;
221
+ }
222
+ const q = Number(quantity !== null && quantity !== void 0 ? quantity : lineItem === null || lineItem === void 0 ? void 0 : lineItem.quantity) > 0 ? Number(quantity !== null && quantity !== void 0 ? quantity : lineItem === null || lineItem === void 0 ? void 0 : lineItem.quantity) : 1;
223
+ const originalAmount = Number((_a = lineItem === null || lineItem === void 0 ? void 0 : lineItem.originalTotalPrice) === null || _a === void 0 ? void 0 : _a.amount);
224
+ const discountedAmount = Number((_b = lineItem === null || lineItem === void 0 ? void 0 : lineItem.discountedPrice) === null || _b === void 0 ? void 0 : _b.amount);
225
+ const safeOriginal = Number.isFinite(originalAmount) ? originalAmount : this.lineNetFromProduct(product, q);
226
+ const safeDiscounted = Number.isFinite(discountedAmount) ? discountedAmount : safeOriginal;
227
+ const resolvedDiscount = discountAmount === undefined ? Math.max(0, safeOriginal - safeDiscounted) : Number(discountAmount) || 0;
228
+ const resolvedTax = taxAmount === undefined
229
+ ? Number((_f = (_d = (_c = lineItem === null || lineItem === void 0 ? void 0 : lineItem.taxAmount) === null || _c === void 0 ? void 0 : _c.amount) !== null && _d !== void 0 ? _d : (_e = lineItem === null || lineItem === void 0 ? void 0 : lineItem.taxAmountWithDiscount) === null || _e === void 0 ? void 0 : _e.amount) !== null && _f !== void 0 ? _f : 0) || 0
230
+ : Number(taxAmount) || 0;
231
+ const resolvedCurrency = currencyCode ||
232
+ ((_g = lineItem === null || lineItem === void 0 ? void 0 : lineItem.originalTotalPrice) === null || _g === void 0 ? void 0 : _g.currencyCode) ||
233
+ ((_h = lineItem === null || lineItem === void 0 ? void 0 : lineItem.discountedPrice) === null || _h === void 0 ? void 0 : _h.currencyCode) ||
234
+ ((_j = lineItem === null || lineItem === void 0 ? void 0 : lineItem.presentmentTotalPrice) === null || _j === void 0 ? void 0 : _j.currencyCode) ||
235
+ '';
236
+ const resolvedCommission = marketplaceCommissionRate === undefined || marketplaceCommissionRate === null
237
+ ? (_k = relationship === null || relationship === void 0 ? void 0 : relationship.marketplaceCommission) !== null && _k !== void 0 ? _k : '0'
238
+ : marketplaceCommissionRate;
239
+ const resolvedVariantSelection = variantSelection && (variantSelection.variantId || variantSelection.options)
240
+ ? variantSelection
241
+ : deriveVariantSelectionFromLineItem(lineItem) || {};
242
+ return this.buildLineSnapshot({
243
+ product,
244
+ parentMerchantId,
245
+ managedMerchantId,
246
+ relationshipId: String((relationship === null || relationship === void 0 ? void 0 : relationship.documentId) || listing.relationshipId || ''),
247
+ sellerDisplayName: String(product.vendorName || ''),
248
+ lineDisplayTitle: String(product.title || product.brand || ''),
249
+ marketplaceCommissionRate: resolvedCommission,
250
+ originalProductCommissionRate,
251
+ marketplaceCommissionBasis: marketplaceCommissionBasis || (relationship === null || relationship === void 0 ? void 0 : relationship.marketplaceCommissionBasis) || marketplace_constants_1.DEFAULT_MARKETPLACE_COMMISSION_BASIS,
252
+ quantity: q,
253
+ currencyCode: resolvedCurrency,
254
+ discountAmount: resolvedDiscount,
255
+ taxAmount: resolvedTax,
256
+ stripeFeeAllocatedAmount,
257
+ ribbnFeeAllocatedAmount,
258
+ variantSelection: resolvedVariantSelection,
259
+ });
260
+ }
261
+ static prorateAmounts(amounts, ratio) {
262
+ const safeRatio = Math.max(0, Math.min(1, Number(ratio) || 0));
263
+ return Object.keys(amounts).reduce((acc, key) => {
264
+ acc[key] = roundMoney(Number(amounts[key] || 0) * safeRatio);
265
+ return acc;
266
+ }, {});
267
+ }
268
+ static buildReturnAdjustment({ snapshot, quantityReturned }) {
269
+ // Use nullish coalescing so an explicit 0 means "no quantity returned"
270
+ // (zero-amount adjustment), while undefined/null still defaults to the
271
+ // full snapshot quantity (used by the post-payout refund flow).
272
+ const requested = quantityReturned === undefined || quantityReturned === null ? snapshot.quantity : Number(quantityReturned);
273
+ const returned = Math.max(0, Math.min(requested, snapshot.quantity));
274
+ const ratio = snapshot.quantity > 0 ? returned / snapshot.quantity : 0;
275
+ return {
276
+ quantityReturned: returned,
277
+ amounts: this.prorateAmounts(snapshot.amounts, ratio),
278
+ remainingQuantity: snapshot.quantity - returned,
279
+ };
280
+ }
281
+ static transformVariantInventory({ product, variantId, locationId = '', quantity = 1 }, direction) {
282
+ const variants = Array.isArray(product.variantInventory) ? product.variantInventory : [];
283
+ const qty = Math.max(0, Number(quantity) || 0);
284
+ return variants.map((variant) => {
285
+ if (variant.id !== variantId)
286
+ return variant;
287
+ const locations = Array.isArray(variant.locations) ? variant.locations : [];
288
+ const nextLocations = locations.map((loc, index) => {
289
+ if (locationId && loc.id !== locationId)
290
+ return loc;
291
+ if (!locationId && index > 0)
292
+ return loc;
293
+ const availableAmount = Number(loc.availableAmount) || 0;
294
+ return Object.assign(Object.assign({}, loc), { availableAmount: direction === 'restore' ? availableAmount + qty : Math.max(0, availableAmount - qty) });
295
+ });
296
+ return Object.assign(Object.assign({}, variant), { locations: nextLocations });
297
+ });
298
+ }
299
+ static decrementVariantInventory(params) {
300
+ return this.transformVariantInventory(params, 'decrement');
301
+ }
302
+ static restoreVariantInventory(params) {
303
+ return this.transformVariantInventory(params, 'restore');
304
+ }
305
+ // ---------------------------------------------------------------------
306
+ // Inventory dispatch (delegates to the InventoryPolicy registry)
307
+ // ---------------------------------------------------------------------
308
+ static registerInventoryPolicy(policy, position = 'append') {
309
+ InventoryPolicyRegistry.register(policy, position);
310
+ }
311
+ static findInventoryPolicy(product) {
312
+ return InventoryPolicyRegistry.find(product);
313
+ }
314
+ static adjustInventory(product, params, direction) {
315
+ if (!product)
316
+ return {};
317
+ const policy = InventoryPolicyRegistry.find(product);
318
+ if (!policy)
319
+ return {};
320
+ return direction === 'restore' ? policy.restore(product, params) : policy.decrement(product, params);
321
+ }
322
+ // Single entry point backend callers use to adjust inventory for one order
323
+ // line. Resolves `variantId` and `quantity` from the line item itself when
324
+ // not passed explicitly, derives variant identity from the same shapes
325
+ // `buildLineSnapshotFromListing` supports, then dispatches through the
326
+ // policy registry. The `defaultLocationId` (typically a merchant's default
327
+ // fulfillment location) is honored by both the multivariant and
328
+ // one-of-a-kind policies when no explicit `locationId` is supplied.
329
+ static adjustVariantInventoryForLine(product, { lineItem = {}, variantId, locationId, defaultLocationId, quantity, }, direction = 'decrement') {
330
+ if (!product)
331
+ return {};
332
+ const inferred = deriveVariantSelectionFromLineItem(lineItem) || {};
333
+ const inferredVariant = !variantId && !inferred.variantId ? this.selectVariant(product, inferred) : null;
334
+ const resolvedVariantId = String(variantId || inferred.variantId || (inferredVariant === null || inferredVariant === void 0 ? void 0 : inferredVariant.variantId) || '');
335
+ const quantityInput = quantity === undefined ? lineItem === null || lineItem === void 0 ? void 0 : lineItem.quantity : quantity;
336
+ const lineQty = Number(quantityInput);
337
+ const resolvedQuantity = quantityInput === undefined || quantityInput === null || !Number.isFinite(lineQty) ? 1 : Math.max(0, lineQty);
338
+ return this.adjustInventory(product, {
339
+ variantId: resolvedVariantId,
340
+ locationId: locationId || '',
341
+ defaultLocationId: defaultLocationId || '',
342
+ quantity: resolvedQuantity,
343
+ }, direction);
344
+ }
345
+ // ---------------------------------------------------------------------
346
+ // Fee allocation (delegates to the FeeAllocationPolicy registry)
347
+ // ---------------------------------------------------------------------
348
+ static registerFeeAllocationPolicy(policy) {
349
+ FeeAllocationPolicyRegistry.register(policy);
350
+ }
351
+ static getFeeAllocationPolicy(basis) {
352
+ return FeeAllocationPolicyRegistry.get(basis);
353
+ }
354
+ static allocateFee(context, basis = marketplace_constants_1.DEFAULT_STRIPE_FEE_ALLOCATION_BASIS) {
355
+ const policy = FeeAllocationPolicyRegistry.get(basis);
356
+ return policy.allocate(context);
357
+ }
358
+ static allocateStripeFee(context) {
359
+ return this.allocateFee(context, marketplace_constants_1.DEFAULT_STRIPE_FEE_ALLOCATION_BASIS);
360
+ }
361
+ static allocateRibbnFee(context) {
362
+ return this.allocateFee(context, marketplace_constants_1.DEFAULT_RIBBN_FEE_ALLOCATION_BASIS);
363
+ }
364
+ static buildFeeBasketFromProducts({ merchantId, products = [], }) {
365
+ return (Array.isArray(products) ? products : []).map((product, index) => ({
366
+ lineKey: `${String((product === null || product === void 0 ? void 0 : product.documentId) || 'product')}:${index}`,
367
+ sellerMerchantId: String((product === null || product === void 0 ? void 0 : product.vendorId) || (product === null || product === void 0 ? void 0 : product.merchantId) || ''),
368
+ lineNetAmount: (product === null || product === void 0 ? void 0 : product.vendorId) && product.vendorId !== merchantId ? Number((product === null || product === void 0 ? void 0 : product.salePrice) || (product === null || product === void 0 ? void 0 : product.price) || 0) : 0,
369
+ quantity: 1,
370
+ }));
371
+ }
372
+ static applyStripeFeeRecoupBumpToProducts({ merchantId, products = [], totalFeeAmount, basis = marketplace_constants_1.DEFAULT_STRIPE_FEE_ALLOCATION_BASIS, }) {
373
+ if (!merchantId || !Array.isArray(products) || products.length === 0) {
374
+ return products;
375
+ }
376
+ const safeTotal = Number(totalFeeAmount);
377
+ if (!Number.isFinite(safeTotal) || safeTotal <= 0) {
378
+ return products;
379
+ }
380
+ const basket = this.buildFeeBasketFromProducts({ merchantId, products });
381
+ const allocationsByLineKey = this.allocateFee({ totalFeeAmount: safeTotal, basket }, basis).reduce((acc, allocation) => {
382
+ acc[allocation.lineKey] = Number(allocation.amount || 0);
383
+ return acc;
384
+ }, {});
385
+ return products.map((product, index) => {
386
+ const sellerId = String((product === null || product === void 0 ? void 0 : product.vendorId) || (product === null || product === void 0 ? void 0 : product.merchantId) || '');
387
+ if (!sellerId || sellerId === merchantId)
388
+ return product;
389
+ const linePrice = Number((product === null || product === void 0 ? void 0 : product.salePrice) || (product === null || product === void 0 ? void 0 : product.price) || 0);
390
+ if (!Number.isFinite(linePrice) || linePrice <= 0)
391
+ return product;
392
+ const lineKey = `${String((product === null || product === void 0 ? void 0 : product.documentId) || 'product')}:${index}`;
393
+ const allocatedFee = Number(allocationsByLineKey[lineKey] || 0);
394
+ if (!allocatedFee)
395
+ return product;
396
+ const baseCommission = Number((product === null || product === void 0 ? void 0 : product.reRobeCommission) || 0);
397
+ const effective = baseCommission + allocatedFee / linePrice;
398
+ return Object.assign(Object.assign({}, product), { reRobeCommission: String(Number(effective.toFixed(6))) });
399
+ });
400
+ }
401
+ // ---------------------------------------------------------------------
402
+ // Listing transitions (immutable updates that bump updatedAt)
403
+ // ---------------------------------------------------------------------
404
+ static upsertListing(marketplace, parentMarketplaceId, partial = {}, options = {}) {
405
+ var _a, _b, _c, _d, _e, _f, _g;
406
+ if (!parentMarketplaceId) {
407
+ return this.normalizeMarketplace(marketplace);
408
+ }
409
+ const ts = typeof options.at === 'number' ? options.at : Date.now();
410
+ const current = this.normalizeMarketplace(marketplace);
411
+ const existing = current.listings[parentMarketplaceId];
412
+ const ownerMerchantId = partial.ownerMerchantId || '';
413
+ const nextListing = {
414
+ relationshipId: String((_b = (_a = partial.relationshipId) !== null && _a !== void 0 ? _a : existing === null || existing === void 0 ? void 0 : existing.relationshipId) !== null && _b !== void 0 ? _b : ''),
415
+ relationshipType: String((_d = (_c = partial.relationshipType) !== null && _c !== void 0 ? _c : existing === null || existing === void 0 ? void 0 : existing.relationshipType) !== null && _d !== void 0 ? _d : marketplace_constants_1.MARKETPLACE_RELATIONSHIP_TYPES.marketplaceSeller),
416
+ status: String((_f = (_e = partial.status) !== null && _e !== void 0 ? _e : existing === null || existing === void 0 ? void 0 : existing.status) !== null && _f !== void 0 ? _f : marketplace_constants_1.DEFAULT_MARKETPLACE_LISTING_STATUS),
417
+ listedAt: (_g = existing === null || existing === void 0 ? void 0 : existing.listedAt) !== null && _g !== void 0 ? _g : (partial.listedAt === undefined ? ts : partial.listedAt),
418
+ updatedAt: ts,
419
+ };
420
+ const nextListings = Object.assign(Object.assign({}, current.listings), { [parentMarketplaceId]: nextListing });
421
+ const activeParentIds = Object.keys(nextListings).filter((id) => { var _a; return ((_a = nextListings[id]) === null || _a === void 0 ? void 0 : _a.status) !== marketplace_constants_1.MARKETPLACE_LISTING_STATUSES.removed; });
422
+ return {
423
+ visibleToMerchantIds: this.uniqueStrings([ownerMerchantId, ...activeParentIds]),
424
+ listings: nextListings,
425
+ };
426
+ }
427
+ static pauseListing(marketplace, parentMarketplaceId, options = {}) {
428
+ return this.upsertListing(marketplace, parentMarketplaceId, { status: marketplace_constants_1.MARKETPLACE_LISTING_STATUSES.paused, ownerMerchantId: options.ownerMerchantId }, options);
429
+ }
430
+ static resumeListing(marketplace, parentMarketplaceId, options = {}) {
431
+ return this.upsertListing(marketplace, parentMarketplaceId, { status: marketplace_constants_1.MARKETPLACE_LISTING_STATUSES.active, ownerMerchantId: options.ownerMerchantId }, options);
432
+ }
433
+ static removeListing(marketplace, parentMarketplaceId, options = {}) {
434
+ return this.upsertListing(marketplace, parentMarketplaceId, { status: marketplace_constants_1.MARKETPLACE_LISTING_STATUSES.removed, ownerMerchantId: options.ownerMerchantId }, options);
435
+ }
436
+ static buildCanonicalMarketplaceListingPatch({ product, parentMerchantId, relationshipId = '', relationshipType = marketplace_constants_1.MARKETPLACE_RELATIONSHIP_TYPES.marketplaceSeller, listingStatus = marketplace_constants_1.MARKETPLACE_LISTING_STATUSES.active, at = Date.now(), }) {
437
+ if (!(product === null || product === void 0 ? void 0 : product.documentId) || !parentMerchantId)
438
+ return null;
439
+ const ownerMerchantId = String(product.merchantId || product.vendorId || '');
440
+ if (!ownerMerchantId)
441
+ return null;
442
+ const current = this.normalizeMarketplace(product.marketplace);
443
+ const existing = current.listings[parentMerchantId];
444
+ const nextMarketplace = this.upsertListing(current, parentMerchantId, {
445
+ relationshipId,
446
+ relationshipType,
447
+ status: listingStatus,
448
+ ownerMerchantId,
449
+ }, { at });
450
+ const listingUnchanged = existing &&
451
+ existing.relationshipId === relationshipId &&
452
+ existing.relationshipType === relationshipType &&
453
+ existing.status === listingStatus;
454
+ const visibleUnchanged = JSON.stringify(this.uniqueStrings(current.visibleToMerchantIds).sort()) ===
455
+ JSON.stringify(this.uniqueStrings(nextMarketplace.visibleToMerchantIds).sort());
456
+ return listingUnchanged && visibleUnchanged ? null : { marketplace: nextMarketplace };
457
+ }
458
+ // ---------------------------------------------------------------------
459
+ // Shim helpers (replace ad-hoc backend/web logic with one ORM source)
460
+ // ---------------------------------------------------------------------
461
+ // Replaces backend `Procedure.resolveProductsWithEffectiveCommission` for
462
+ // a single product+relationship pair. Backend keeps the Firestore lookup
463
+ // and dispatches the override via this helper.
464
+ static resolveEffectiveCommission(product, relationship, contextMerchantId) {
465
+ const baseCommission = String((product === null || product === void 0 ? void 0 : product.reRobeCommission) || '');
466
+ if (!product || !relationship)
467
+ return baseCommission;
468
+ if (relationship.isActive === false)
469
+ return baseCommission;
470
+ if (relationship.relationshipType &&
471
+ relationship.relationshipType !== marketplace_constants_1.MARKETPLACE_RELATIONSHIP_TYPES.marketplaceSeller) {
472
+ return baseCommission;
473
+ }
474
+ if (contextMerchantId && relationship.parentMerchantId && relationship.parentMerchantId !== contextMerchantId) {
475
+ return baseCommission;
476
+ }
477
+ if (contextMerchantId && product.vendorId && product.vendorId === contextMerchantId) {
478
+ return baseCommission;
479
+ }
480
+ const override = relationship.marketplaceCommission;
481
+ if (override === undefined || override === null || override === '')
482
+ return baseCommission;
483
+ return String(override);
484
+ }
485
+ static applyEffectiveCommissionToProducts({ products = [], relationships = [], contextMerchantId, }) {
486
+ if (!Array.isArray(products) || products.length === 0)
487
+ return products;
488
+ const relationshipsBySellerId = (Array.isArray(relationships) ? relationships : []).reduce((acc, relationship) => {
489
+ const sellerId = String((relationship === null || relationship === void 0 ? void 0 : relationship.childMerchantId) || '');
490
+ if (sellerId)
491
+ acc[sellerId] = relationship;
492
+ return acc;
493
+ }, {});
494
+ return products.map((product) => {
495
+ const relationship = relationshipsBySellerId[String((product === null || product === void 0 ? void 0 : product.vendorId) || (product === null || product === void 0 ? void 0 : product.merchantId) || '')];
496
+ if (!relationship)
497
+ return product;
498
+ const effectiveCommission = this.resolveEffectiveCommission(product, relationship, contextMerchantId);
499
+ if (effectiveCommission === String((product === null || product === void 0 ? void 0 : product.reRobeCommission) || ''))
500
+ return product;
501
+ return Object.assign(Object.assign({}, product), { reRobeCommission: effectiveCommission });
502
+ });
503
+ }
504
+ // Replaces ad-hoc per-component branches in
505
+ // RetailProductQuickEntry / QuickProductUpload / SimplifiedManagedProductDetails.
506
+ // Always returns the canonical seller-owned shape regardless of `isActingAs`.
507
+ // `isActingAs` and `parentMerchantId` are accepted for API compatibility
508
+ // with the call sites being migrated, but ownership is intentionally
509
+ // independent of who initiated the create — marketplace visibility for the
510
+ // parent is derived later via `product.marketplace` and indexed Typesense
511
+ // fields.
512
+ static buildSellerProductOwnership(params) {
513
+ const sellerMerchantId = params === null || params === void 0 ? void 0 : params.sellerMerchantId;
514
+ if (!sellerMerchantId) {
515
+ throw new MarketplaceErrors_2.MarketplaceOwnershipError('sellerMerchantId is required');
516
+ }
517
+ return {
518
+ merchantId: sellerMerchantId,
519
+ vendorId: sellerMerchantId,
520
+ merchants: [sellerMerchantId],
521
+ };
522
+ }
523
+ static defaultSellerCommission() {
524
+ return marketplace_constants_1.MARKETPLACE_SELLER_DEFAULT_COMMISSION;
525
+ }
526
+ // Builds the Typesense filter expression that scopes parent-marketplace
527
+ // act-as searches to a single managed merchant. Returning an empty
528
+ // string allows callers to short-circuit without producing a malformed
529
+ // filter expression like `vendorId:=`.
530
+ static buildActAsTypesenseFilter(managedMerchantId) {
531
+ if (!managedMerchantId)
532
+ return '';
533
+ return `vendorId:=${String(managedMerchantId)}`;
534
+ }
535
+ // Normalizes an arbitrary commission rate input (string / number /
536
+ // comma-decimal) into the canonical `'0'..'1'` string. Throws a typed
537
+ // error for inputs outside the valid range so callers can surface UX
538
+ // copy without re-implementing validation.
539
+ static normalizeCommissionRate(value) {
540
+ if (value === null || value === undefined || value === '') {
541
+ throw new MarketplaceErrors_2.MarketplaceCommissionRateError('commission rate is required');
542
+ }
543
+ const sanitized = String(value).trim().replace(',', '.');
544
+ const numeric = Number(sanitized);
545
+ if (!Number.isFinite(numeric)) {
546
+ throw new MarketplaceErrors_2.MarketplaceCommissionRateError(`commission rate '${value}' is not a finite number`);
547
+ }
548
+ const normalized = numeric > 1 ? numeric / 100 : numeric;
549
+ if (normalized < 0 || normalized > 1) {
550
+ throw new MarketplaceErrors_2.MarketplaceCommissionRateError(`commission rate '${value}' must be between 0 and 1 inclusive`);
551
+ }
552
+ return String(Number(normalized.toFixed(6)));
553
+ }
554
+ }
555
+ exports.default = MarketplaceProductHelpers;
@@ -1,9 +1,11 @@
1
+ import { OrderLinePricing, OrderLinePricingLike } from '../types/pricing-types';
1
2
  export default class OrderHelpers {
3
+ getLinePricing(line: OrderLinePricingLike | null | undefined): OrderLinePricing;
2
4
  getOrderIdFromShopifyObj(order: ShopifyRestApiOrderObj): string | number | null;
3
5
  getShippingTypeFromShopifyObj(shippingLines: ShippingLineRest[] | null | undefined): string;
4
6
  getPaymentTypeUsingTags(tags: string | null | undefined): string | null;
5
7
  getSalesChannelUsingTags(tags: string | null | undefined): string | null;
6
- buildLineItemFromProduct(product: CompleteProduct, currencyCode: string, quantity?: number, taxProps?: RibbnTaxProps): ReRobeOrderLineItem;
8
+ buildLineItemFromProduct(product: CompleteProduct, currencyCode: string, quantity?: number, taxProps?: RibbnTaxProps, marketplace?: MarketplaceLineSnapshot): ReRobeOrderLineItem;
7
9
  toFixedPointPrice(price: number | string): string;
8
10
  getAmountSumByField(array: OrderRefund[] | ReRobeOrderLineItem[], fieldKey: string): number;
9
11
  getOrderInfoWithRefundsAndFulfillments(order: CompleteOrder): OrderWithRefundsAndFulfillmentsInfoObj;
@@ -47,7 +49,7 @@ export default class OrderHelpers {
47
49
  getPaymentTerminalReceiptInfo(payload?: any): PaymentTerminalReceiptInfo;
48
50
  getFormattedFulfillmentLocation(order: ReRobeOrderObj): string;
49
51
  generateReceiptLabels(locale: string, paymentMethod: string, entryMode?: string): ReceiptLabels;
50
- buildReceiptObjFromOrder({ order, merchant, merchantLogoUrl, receiptNumber, additionalInfo, isRefund, refundId, originalReceiptNumber, }: {
52
+ buildReceiptObjFromOrder({ order, merchant, merchantLogoUrl, receiptNumber, additionalInfo, isRefund, refundId, originalReceiptNumber, includeMarketplaceSellerPrefix, }: {
51
53
  order: ReRobeOrderObj;
52
54
  merchant: MerchantObj;
53
55
  merchantLogoUrl: string;
@@ -56,6 +58,7 @@ export default class OrderHelpers {
56
58
  isRefund?: boolean;
57
59
  refundId?: string | null;
58
60
  originalReceiptNumber?: string | null;
61
+ includeMarketplaceSellerPrefix?: boolean;
59
62
  }): ReceiptObj;
60
63
  /**
61
64
  * Generates an idempotency key from a ReRobeOrderObj to prevent duplicate order creation
@@ -5,7 +5,17 @@ const Utilities_1 = require("../helpers/Utilities");
5
5
  const order_constants_1 = require("../constants/order-constants");
6
6
  const translations_1 = require("../translations");
7
7
  const CryptoPolyfill_1 = require("./CryptoPolyfill");
8
+ const PricingHelpers_1 = require("./PricingHelpers");
9
+ const MarketplaceLineDisplayHelpers_1 = require("./marketplace/MarketplaceLineDisplayHelpers");
8
10
  class OrderHelpers {
11
+ // Frozen-rate pricing snapshot for a single order line item. Reads
12
+ // `line.taxRate` (captured at order creation) so the gross display
13
+ // reflects the tax actually charged, not whatever the current catalog
14
+ // says. Non-breaking — `buildReceiptObjFromOrder` continues to compute
15
+ // its own gross math inline; new callers can opt in via this accessor.
16
+ getLinePricing(line) {
17
+ return PricingHelpers_1.default.getOrderLinePricing(line);
18
+ }
9
19
  getOrderIdFromShopifyObj(order) {
10
20
  const { id, tags } = order;
11
21
  if (!tags) {
@@ -66,7 +76,7 @@ class OrderHelpers {
66
76
  }
67
77
  return null;
68
78
  }
69
- buildLineItemFromProduct(product, currencyCode, quantity = 1, taxProps = {}) {
79
+ buildLineItemFromProduct(product, currencyCode, quantity = 1, taxProps = {}, marketplace) {
70
80
  var _a;
71
81
  const q = quantity || 1;
72
82
  const getImgSrc = () => {
@@ -78,7 +88,7 @@ class OrderHelpers {
78
88
  }
79
89
  return '';
80
90
  };
81
- return {
91
+ const lineItem = {
82
92
  title: product.title,
83
93
  quantity: q,
84
94
  variant: {
@@ -119,6 +129,10 @@ class OrderHelpers {
119
129
  },
120
130
  handle: product.handle || '',
121
131
  };
132
+ if (marketplace) {
133
+ lineItem.marketplace = marketplace;
134
+ }
135
+ return lineItem;
122
136
  }
123
137
  toFixedPointPrice(price) {
124
138
  return Number(price).toFixed(2);
@@ -579,7 +593,7 @@ class OrderHelpers {
579
593
  entryModeLabel,
580
594
  };
581
595
  }
582
- buildReceiptObjFromOrder({ order, merchant, merchantLogoUrl = '', receiptNumber = '', additionalInfo = '', isRefund = false, refundId = null, originalReceiptNumber = null, }) {
596
+ buildReceiptObjFromOrder({ order, merchant, merchantLogoUrl = '', receiptNumber = '', additionalInfo = '', isRefund = false, refundId = null, originalReceiptNumber = null, includeMarketplaceSellerPrefix = false, }) {
583
597
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
584
598
  const { address: merchantAddress, legalName, name, contactEmail, phone = '', organizationNumber = '', primaryDomain, currency: storeCurrencyCode, returnPolicy, } = merchant;
585
599
  const currencyCode = ((_a = order.totalPricePresentment) === null || _a === void 0 ? void 0 : _a.currencyCode) || storeCurrencyCode;
@@ -594,7 +608,7 @@ class OrderHelpers {
594
608
  if (isRefund) {
595
609
  totalPrice = -Math.abs(totalPrice);
596
610
  }
597
- let title = l.title || l.brand || '';
611
+ let title = (0, MarketplaceLineDisplayHelpers_1.formatMarketplaceLineDisplayTitle)({ lineItem: l }, { includeSellerPrefix: includeMarketplaceSellerPrefix });
598
612
  if (Number(l === null || l === void 0 ? void 0 : l.quantity) > 1) {
599
613
  const unitPrice = isRefund
600
614
  ? -Math.abs(Number((_c = (_b = l === null || l === void 0 ? void 0 : l.originalUnitPrice) === null || _b === void 0 ? void 0 : _b.amount) !== null && _c !== void 0 ? _c : 0))