rerobe-js-orm 4.8.7 → 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 (72) 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/merchant-constants.d.ts +35 -0
  4. package/lib/constants/merchant-constants.js +35 -1
  5. package/lib/constants/product-constants.d.ts +6 -0
  6. package/lib/constants/product-constants.js +43 -1
  7. package/lib/constants/tax-constants.d.ts +19 -0
  8. package/lib/constants/tax-constants.js +70 -0
  9. package/lib/factories/Product/RetailProductFactory.d.ts +102 -0
  10. package/lib/factories/Product/RetailProductFactory.js +260 -0
  11. package/lib/form-states/Product/ProductFormState.d.ts +9 -0
  12. package/lib/form-states/Product/ProductFormState.js +46 -0
  13. package/lib/helpers/MarketplaceProductHelpers.d.ts +181 -0
  14. package/lib/helpers/MarketplaceProductHelpers.js +555 -0
  15. package/lib/helpers/OrderHelpers.d.ts +5 -2
  16. package/lib/helpers/OrderHelpers.js +18 -4
  17. package/lib/helpers/PricingHelpers.d.ts +29 -0
  18. package/lib/helpers/PricingHelpers.js +215 -0
  19. package/lib/helpers/ProductInventoryHelpers.d.ts +31 -0
  20. package/lib/helpers/ProductInventoryHelpers.js +66 -0
  21. package/lib/helpers/ProductSkuHelpers.d.ts +13 -0
  22. package/lib/helpers/ProductSkuHelpers.js +70 -0
  23. package/lib/helpers/TaxHelpers.d.ts +15 -0
  24. package/lib/helpers/TaxHelpers.js +76 -0
  25. package/lib/helpers/marketplace/CommissionPolicy.d.ts +20 -0
  26. package/lib/helpers/marketplace/CommissionPolicy.js +9 -0
  27. package/lib/helpers/marketplace/CommissionPolicyRegistry.d.ts +4 -0
  28. package/lib/helpers/marketplace/CommissionPolicyRegistry.js +21 -0
  29. package/lib/helpers/marketplace/EvenPerSellerStripeFeePolicy.d.ts +5 -0
  30. package/lib/helpers/marketplace/EvenPerSellerStripeFeePolicy.js +46 -0
  31. package/lib/helpers/marketplace/FeeAllocationPolicy.d.ts +10 -0
  32. package/lib/helpers/marketplace/FeeAllocationPolicy.js +36 -0
  33. package/lib/helpers/marketplace/FeeAllocationPolicyRegistry.d.ts +6 -0
  34. package/lib/helpers/marketplace/FeeAllocationPolicyRegistry.js +26 -0
  35. package/lib/helpers/marketplace/InventoryPolicy.d.ts +18 -0
  36. package/lib/helpers/marketplace/InventoryPolicy.js +7 -0
  37. package/lib/helpers/marketplace/InventoryPolicyRegistry.d.ts +4 -0
  38. package/lib/helpers/marketplace/InventoryPolicyRegistry.js +29 -0
  39. package/lib/helpers/marketplace/LineNetCommissionPolicy.d.ts +5 -0
  40. package/lib/helpers/marketplace/LineNetCommissionPolicy.js +25 -0
  41. package/lib/helpers/marketplace/MarketplaceErrors.d.ts +6 -0
  42. package/lib/helpers/marketplace/MarketplaceErrors.js +21 -0
  43. package/lib/helpers/marketplace/MarketplaceLedgerHelpers.d.ts +40 -0
  44. package/lib/helpers/marketplace/MarketplaceLedgerHelpers.js +120 -0
  45. package/lib/helpers/marketplace/MarketplaceLegacyAdapters.d.ts +53 -0
  46. package/lib/helpers/marketplace/MarketplaceLegacyAdapters.js +99 -0
  47. package/lib/helpers/marketplace/MarketplaceLineDisplayHelpers.d.ts +40 -0
  48. package/lib/helpers/marketplace/MarketplaceLineDisplayHelpers.js +125 -0
  49. package/lib/helpers/marketplace/MarketplaceOrderHelpers.d.ts +15 -0
  50. package/lib/helpers/marketplace/MarketplaceOrderHelpers.js +77 -0
  51. package/lib/helpers/marketplace/MultivariantLocationInventoryPolicy.d.ts +9 -0
  52. package/lib/helpers/marketplace/MultivariantLocationInventoryPolicy.js +60 -0
  53. package/lib/helpers/marketplace/OneOfAKindInventoryPolicy.d.ts +9 -0
  54. package/lib/helpers/marketplace/OneOfAKindInventoryPolicy.js +55 -0
  55. package/lib/helpers/marketplace/OriginalCommissionShareCommissionPolicy.d.ts +5 -0
  56. package/lib/helpers/marketplace/OriginalCommissionShareCommissionPolicy.js +26 -0
  57. package/lib/helpers/marketplace/ProportionalToLineNetPolicy.d.ts +5 -0
  58. package/lib/helpers/marketplace/ProportionalToLineNetPolicy.js +35 -0
  59. package/lib/helpers/marketplace/UntrackedStockInventoryPolicy.d.ts +7 -0
  60. package/lib/helpers/marketplace/UntrackedStockInventoryPolicy.js +23 -0
  61. package/lib/index.d.ts +18 -1
  62. package/lib/index.js +56 -1
  63. package/lib/models/Merchant.d.ts +86 -0
  64. package/lib/models/Merchant.js +86 -0
  65. package/lib/models/Product.d.ts +16 -0
  66. package/lib/models/Product.js +151 -0
  67. package/lib/types/merchant-types.d.ts +28 -0
  68. package/lib/types/pricing-types.d.ts +85 -0
  69. package/lib/types/pricing-types.js +5 -0
  70. package/lib/types/rerobe-order-types.d.ts +86 -0
  71. package/lib/types/rerobe-product-types.d.ts +19 -0
  72. package/package.json +1 -1
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ // Strategy interface for distributing a basket-level fee across marketplace
3
+ // line items. Concrete implementations live in sibling files. Callers should
4
+ // depend on this abstraction (and the registered `basis` string) rather than
5
+ // any concrete class so new bases can be added without modifying existing
6
+ // fee-allocation call sites.
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.reconcileAllocationsToTotal = exports.roundFeeAmount = void 0;
9
+ // Pure money rounding to two decimals matches the rest of the marketplace
10
+ // helpers and keeps allocations comparable to currency display values.
11
+ const roundFeeAmount = (value) => Number(Number(value || 0).toFixed(2));
12
+ exports.roundFeeAmount = roundFeeAmount;
13
+ // Aligns the sum of allocations with the requested fee amount. Rounding can
14
+ // drift cents, so the largest-share line absorbs the residual to keep the
15
+ // invariant `sum(allocations) === requested fee` whenever possible.
16
+ const reconcileAllocationsToTotal = (allocations, totalFeeAmount) => {
17
+ if (!Array.isArray(allocations) || allocations.length === 0) {
18
+ return [];
19
+ }
20
+ const total = (0, exports.roundFeeAmount)(totalFeeAmount);
21
+ const sum = (0, exports.roundFeeAmount)(allocations.reduce((acc, alloc) => acc + Number((alloc === null || alloc === void 0 ? void 0 : alloc.amount) || 0), 0));
22
+ const drift = (0, exports.roundFeeAmount)(total - sum);
23
+ if (drift === 0) {
24
+ return allocations;
25
+ }
26
+ // Apply the residual to the line with the largest absolute allocation.
27
+ let targetIdx = 0;
28
+ for (let i = 1; i < allocations.length; i += 1) {
29
+ if (Math.abs(Number(allocations[i].amount || 0)) > Math.abs(Number(allocations[targetIdx].amount || 0))) {
30
+ targetIdx = i;
31
+ }
32
+ }
33
+ return allocations.map((alloc, idx) => idx === targetIdx
34
+ ? Object.assign(Object.assign({}, alloc), { amount: (0, exports.roundFeeAmount)(Number(alloc.amount || 0) + drift) }) : alloc);
35
+ };
36
+ exports.reconcileAllocationsToTotal = reconcileAllocationsToTotal;
@@ -0,0 +1,6 @@
1
+ import { FeeAllocationPolicy } from './FeeAllocationPolicy';
2
+ export declare const register: (policy: FeeAllocationPolicy) => void;
3
+ export declare const get: (basis: string) => FeeAllocationPolicy;
4
+ export declare const has: (basis: string) => boolean;
5
+ export declare const getStripeFeePolicy: () => FeeAllocationPolicy;
6
+ export declare const getRibbnFeePolicy: () => FeeAllocationPolicy;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getRibbnFeePolicy = exports.getStripeFeePolicy = exports.has = exports.get = exports.register = void 0;
4
+ const marketplace_constants_1 = require("../../constants/marketplace-constants");
5
+ const EvenPerSellerStripeFeePolicy_1 = require("./EvenPerSellerStripeFeePolicy");
6
+ const ProportionalToLineNetPolicy_1 = require("./ProportionalToLineNetPolicy");
7
+ // Process-wide registry for marketplace fee-allocation strategies. Built-in
8
+ // strategies are registered eagerly. Bring-your-own bases (e.g. tier-based
9
+ // fees) can be added at runtime via `register(policy)` to satisfy OCP.
10
+ const REGISTRY = {};
11
+ const register = (policy) => {
12
+ REGISTRY[policy.basis] = policy;
13
+ };
14
+ exports.register = register;
15
+ const get = (basis) => REGISTRY[basis] || REGISTRY[marketplace_constants_1.DEFAULT_STRIPE_FEE_ALLOCATION_BASIS];
16
+ exports.get = get;
17
+ const has = (basis) => Boolean(REGISTRY[basis]);
18
+ exports.has = has;
19
+ // Convenience accessors so backend callers don't need to remember which
20
+ // basis is the canonical default for each fee bucket.
21
+ const getStripeFeePolicy = () => (0, exports.get)(marketplace_constants_1.DEFAULT_STRIPE_FEE_ALLOCATION_BASIS);
22
+ exports.getStripeFeePolicy = getStripeFeePolicy;
23
+ const getRibbnFeePolicy = () => (0, exports.get)(marketplace_constants_1.DEFAULT_RIBBN_FEE_ALLOCATION_BASIS);
24
+ exports.getRibbnFeePolicy = getRibbnFeePolicy;
25
+ (0, exports.register)(new EvenPerSellerStripeFeePolicy_1.default());
26
+ (0, exports.register)(new ProportionalToLineNetPolicy_1.default());
@@ -0,0 +1,18 @@
1
+ export type InventoryAdjustmentParams = {
2
+ variantId?: string;
3
+ locationId?: string;
4
+ defaultLocationId?: string;
5
+ quantity?: number;
6
+ };
7
+ export type InventoryAdjustmentResult = {
8
+ variantInventory?: VariantInventory[];
9
+ inventoryLocations?: InventoryLocation[];
10
+ quantity?: number;
11
+ stockStatus?: string;
12
+ };
13
+ export interface InventoryPolicy {
14
+ readonly kind: string;
15
+ canHandle(product: CompleteProduct | null | undefined): boolean;
16
+ decrement(product: CompleteProduct, params: InventoryAdjustmentParams): InventoryAdjustmentResult;
17
+ restore(product: CompleteProduct, params: InventoryAdjustmentParams): InventoryAdjustmentResult;
18
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ // Strategy interface for adjusting inventory in response to a marketplace
3
+ // sale or refund. Concrete implementations are dispatched by the registry
4
+ // based on `canHandle(product)`. Callers (backend triggers, web flows) ask
5
+ // the registry for the right policy and apply it without branching on
6
+ // product class or stock status.
7
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ import { InventoryPolicy } from './InventoryPolicy';
2
+ export declare const register: (policy: InventoryPolicy, position?: "append" | "prepend") => void;
3
+ export declare const list: () => InventoryPolicy[];
4
+ export declare const find: (product: CompleteProduct | null | undefined) => InventoryPolicy | null;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.find = exports.list = exports.register = void 0;
4
+ const MultivariantLocationInventoryPolicy_1 = require("./MultivariantLocationInventoryPolicy");
5
+ const OneOfAKindInventoryPolicy_1 = require("./OneOfAKindInventoryPolicy");
6
+ const UntrackedStockInventoryPolicy_1 = require("./UntrackedStockInventoryPolicy");
7
+ // Order matters: the first policy whose `canHandle` returns true wins.
8
+ // Untracked stock takes precedence so a multivariant product flagged as
9
+ // indefinite stock is treated as untracked.
10
+ const REGISTRY = [];
11
+ const register = (policy, position = 'append') => {
12
+ if (position === 'prepend') {
13
+ REGISTRY.unshift(policy);
14
+ return;
15
+ }
16
+ REGISTRY.push(policy);
17
+ };
18
+ exports.register = register;
19
+ const list = () => [...REGISTRY];
20
+ exports.list = list;
21
+ const find = (product) => {
22
+ if (!product)
23
+ return null;
24
+ return REGISTRY.find((policy) => policy.canHandle(product)) || null;
25
+ };
26
+ exports.find = find;
27
+ (0, exports.register)(new UntrackedStockInventoryPolicy_1.default());
28
+ (0, exports.register)(new MultivariantLocationInventoryPolicy_1.default());
29
+ (0, exports.register)(new OneOfAKindInventoryPolicy_1.default());
@@ -0,0 +1,5 @@
1
+ import { CommissionPolicy, CommissionPolicyContext, CommissionPolicyFeeContext, CommissionPolicyResult } from './CommissionPolicy';
2
+ export default class LineNetCommissionPolicy implements CommissionPolicy {
3
+ readonly basis: "LINE_NET_EXCLUDING_TAX";
4
+ calculate({ taxableAmount, originalRate, marketplaceRate }: CommissionPolicyContext, { stripeFee, ribbnFee }: CommissionPolicyFeeContext): CommissionPolicyResult;
5
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const marketplace_constants_1 = require("../../constants/marketplace-constants");
4
+ const CommissionPolicy_1 = require("./CommissionPolicy");
5
+ // Marketplace commission is computed on the line tax-exclusive net. The
6
+ // original product commission still applies on top, so the marketplace cut
7
+ // does not erode the seller's payout. Used as the default policy.
8
+ class LineNetCommissionPolicy {
9
+ constructor() {
10
+ this.basis = marketplace_constants_1.MARKETPLACE_COMMISSION_BASES.lineNetExcludingTax;
11
+ }
12
+ calculate({ taxableAmount, originalRate, marketplaceRate }, { stripeFee, ribbnFee }) {
13
+ const originalProductCommissionAmount = (0, CommissionPolicy_1.roundCommissionAmount)(taxableAmount * originalRate);
14
+ const marketplaceCommissionAmount = (0, CommissionPolicy_1.roundCommissionAmount)(taxableAmount * marketplaceRate);
15
+ const managedMerchantProceedsAmount = (0, CommissionPolicy_1.roundCommissionAmount)(Math.max(0, originalProductCommissionAmount));
16
+ const sellerProceedsAmount = (0, CommissionPolicy_1.roundCommissionAmount)(Math.max(0, taxableAmount - originalProductCommissionAmount - marketplaceCommissionAmount - stripeFee - ribbnFee));
17
+ return {
18
+ originalProductCommissionAmount,
19
+ marketplaceCommissionAmount,
20
+ managedMerchantProceedsAmount,
21
+ sellerProceedsAmount,
22
+ };
23
+ }
24
+ }
25
+ exports.default = LineNetCommissionPolicy;
@@ -0,0 +1,6 @@
1
+ export declare class MarketplaceCommissionRateError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class MarketplaceOwnershipError extends Error {
5
+ constructor(message: string);
6
+ }
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ // Typed errors thrown by MarketplaceProductHelpers and adjacent strategies.
3
+ // Living in their own module satisfies the tslint max-classes-per-file rule
4
+ // while keeping error semantics encapsulated.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.MarketplaceOwnershipError = exports.MarketplaceCommissionRateError = void 0;
7
+ /* tslint:disable:max-classes-per-file */
8
+ class MarketplaceCommissionRateError extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = 'MarketplaceCommissionRateError';
12
+ }
13
+ }
14
+ exports.MarketplaceCommissionRateError = MarketplaceCommissionRateError;
15
+ class MarketplaceOwnershipError extends Error {
16
+ constructor(message) {
17
+ super(message);
18
+ this.name = 'MarketplaceOwnershipError';
19
+ }
20
+ }
21
+ exports.MarketplaceOwnershipError = MarketplaceOwnershipError;
@@ -0,0 +1,40 @@
1
+ import { MarketplaceLedgerStatusValue } from '../../constants/marketplace-constants';
2
+ export declare class MarketplaceLedgerTransitionError extends Error {
3
+ constructor(currentStatus: string, nextStatus: string);
4
+ }
5
+ type BuildEntryFromSnapshotParams = {
6
+ snapshot: MarketplaceLineSnapshot;
7
+ parentOrderId: string;
8
+ parentOrderLineItemId?: string;
9
+ documentId?: string;
10
+ returnDeadlineTimestamp?: number | null;
11
+ status?: MarketplaceLedgerStatusValue;
12
+ at?: number;
13
+ };
14
+ export declare const buildEntryFromSnapshot: ({ snapshot, parentOrderId, parentOrderLineItemId, documentId, returnDeadlineTimestamp, status, at, }: BuildEntryFromSnapshotParams) => MarketplaceLedgerEntry;
15
+ export declare const isTransitionAllowed: (current: string, next: string) => boolean;
16
+ export declare const transitionStatus: (entry: MarketplaceLedgerEntry, nextStatus: MarketplaceLedgerStatusValue, options?: {
17
+ at?: number;
18
+ }) => MarketplaceLedgerEntry;
19
+ type ApplyReturnParams = {
20
+ entry: MarketplaceLedgerEntry;
21
+ quantityReturned?: number;
22
+ at?: number;
23
+ };
24
+ export declare const applyReturn: ({ entry, quantityReturned, at, }: ApplyReturnParams) => {
25
+ entry: MarketplaceLedgerEntry;
26
+ adjustment: MarketplaceReturnAdjustment;
27
+ };
28
+ declare const _default: {
29
+ buildEntryFromSnapshot: ({ snapshot, parentOrderId, parentOrderLineItemId, documentId, returnDeadlineTimestamp, status, at, }: BuildEntryFromSnapshotParams) => MarketplaceLedgerEntry;
30
+ transitionStatus: (entry: MarketplaceLedgerEntry, nextStatus: MarketplaceLedgerStatusValue, options?: {
31
+ at?: number;
32
+ }) => MarketplaceLedgerEntry;
33
+ isTransitionAllowed: (current: string, next: string) => boolean;
34
+ applyReturn: ({ entry, quantityReturned, at, }: ApplyReturnParams) => {
35
+ entry: MarketplaceLedgerEntry;
36
+ adjustment: MarketplaceReturnAdjustment;
37
+ };
38
+ MarketplaceLedgerTransitionError: typeof MarketplaceLedgerTransitionError;
39
+ };
40
+ export default _default;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.applyReturn = exports.transitionStatus = exports.isTransitionAllowed = exports.buildEntryFromSnapshot = exports.MarketplaceLedgerTransitionError = void 0;
4
+ const marketplace_constants_1 = require("../../constants/marketplace-constants");
5
+ const MarketplaceProductHelpers_1 = require("../MarketplaceProductHelpers");
6
+ const STATUS_TIMESTAMP_KEYS = {
7
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.pendingReturnPeriod]: 'pendingReturnPeriodAtTimestamp',
8
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.payable]: 'payableAtTimestamp',
9
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.paidOut]: 'paidOutAtTimestamp',
10
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.returnedBeforePayout]: 'returnedBeforePayoutAtTimestamp',
11
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.refundedAfterPayout]: 'refundedAfterPayoutAtTimestamp',
12
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.transferReversed]: 'transferReversedAtTimestamp',
13
+ };
14
+ // Allowed transitions encode the marketplace ledger lifecycle. Returns are
15
+ // terminal in their respective branches; cross-branch hops are rejected.
16
+ const ALLOWED_TRANSITIONS = {
17
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.pendingReturnPeriod]: [
18
+ marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.payable,
19
+ marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.returnedBeforePayout,
20
+ ],
21
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.payable]: [
22
+ marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.paidOut,
23
+ marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.returnedBeforePayout,
24
+ ],
25
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.paidOut]: [
26
+ marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.refundedAfterPayout,
27
+ marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.transferReversed,
28
+ ],
29
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.refundedAfterPayout]: [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.transferReversed],
30
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.returnedBeforePayout]: [],
31
+ [marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.transferReversed]: [],
32
+ };
33
+ class MarketplaceLedgerTransitionError extends Error {
34
+ constructor(currentStatus, nextStatus) {
35
+ super(`Marketplace ledger transition not allowed: ${currentStatus} -> ${nextStatus}`);
36
+ this.name = 'MarketplaceLedgerTransitionError';
37
+ }
38
+ }
39
+ exports.MarketplaceLedgerTransitionError = MarketplaceLedgerTransitionError;
40
+ const now = () => Date.now();
41
+ const buildEntryFromSnapshot = ({ snapshot, parentOrderId, parentOrderLineItemId, documentId, returnDeadlineTimestamp, status = marketplace_constants_1.DEFAULT_MARKETPLACE_LEDGER_STATUS, at, }) => {
42
+ if (!snapshot) {
43
+ throw new Error('snapshot is required to build a marketplace ledger entry');
44
+ }
45
+ if (!parentOrderId) {
46
+ throw new Error('parentOrderId is required to build a marketplace ledger entry');
47
+ }
48
+ const ts = typeof at === 'number' ? at : now();
49
+ const lifecycle = {
50
+ createdAtTimestamp: ts,
51
+ updatedAtTimestamp: ts,
52
+ };
53
+ const tsKey = STATUS_TIMESTAMP_KEYS[status];
54
+ if (tsKey)
55
+ lifecycle[tsKey] = ts;
56
+ return {
57
+ documentId,
58
+ parentOrderId,
59
+ parentOrderLineItemId,
60
+ parentMerchantId: snapshot.parentMerchantId,
61
+ managedMerchantId: snapshot.managedMerchantId,
62
+ relationshipId: snapshot.relationshipId,
63
+ productId: snapshot.productId,
64
+ variantId: snapshot.variantId,
65
+ status,
66
+ snapshot,
67
+ returnDeadlineTimestamp: returnDeadlineTimestamp === undefined ? null : returnDeadlineTimestamp,
68
+ lifecycle,
69
+ };
70
+ };
71
+ exports.buildEntryFromSnapshot = buildEntryFromSnapshot;
72
+ const isTransitionAllowed = (current, next) => {
73
+ if (!current || !next)
74
+ return false;
75
+ if (current === next)
76
+ return true;
77
+ const allowed = ALLOWED_TRANSITIONS[current];
78
+ return Array.isArray(allowed) && allowed.includes(next);
79
+ };
80
+ exports.isTransitionAllowed = isTransitionAllowed;
81
+ const transitionStatus = (entry, nextStatus, options = {}) => {
82
+ if (!entry) {
83
+ throw new Error('entry is required to transition status');
84
+ }
85
+ if (!(0, exports.isTransitionAllowed)(entry.status, nextStatus)) {
86
+ throw new MarketplaceLedgerTransitionError(String(entry.status), String(nextStatus));
87
+ }
88
+ if (entry.status === nextStatus) {
89
+ return entry;
90
+ }
91
+ const ts = typeof options.at === 'number' ? options.at : now();
92
+ const lifecycle = Object.assign(Object.assign({}, entry.lifecycle), { updatedAtTimestamp: ts });
93
+ const tsKey = STATUS_TIMESTAMP_KEYS[nextStatus];
94
+ if (tsKey)
95
+ lifecycle[tsKey] = ts;
96
+ return Object.assign(Object.assign({}, entry), { status: nextStatus, lifecycle });
97
+ };
98
+ exports.transitionStatus = transitionStatus;
99
+ const applyReturn = ({ entry, quantityReturned, at, }) => {
100
+ if (!entry) {
101
+ throw new Error('entry is required to apply a return');
102
+ }
103
+ const adjustment = MarketplaceProductHelpers_1.default.buildReturnAdjustment({
104
+ snapshot: entry.snapshot,
105
+ quantityReturned,
106
+ });
107
+ const targetStatus = entry.status === marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.paidOut
108
+ ? marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.refundedAfterPayout
109
+ : marketplace_constants_1.MARKETPLACE_LEDGER_STATUSES.returnedBeforePayout;
110
+ const transitioned = (0, exports.transitionStatus)(entry, targetStatus, { at });
111
+ return { entry: transitioned, adjustment };
112
+ };
113
+ exports.applyReturn = applyReturn;
114
+ exports.default = {
115
+ buildEntryFromSnapshot: exports.buildEntryFromSnapshot,
116
+ transitionStatus: exports.transitionStatus,
117
+ isTransitionAllowed: exports.isTransitionAllowed,
118
+ applyReturn: exports.applyReturn,
119
+ MarketplaceLedgerTransitionError,
120
+ };
@@ -0,0 +1,53 @@
1
+ export declare const isLegacyDuplicateProduct: (product: any) => boolean;
2
+ export declare const parseRibbnIdTag: (tagsLike: any) => string | null;
3
+ type FromLegacyDuplicateLineParams = {
4
+ lineItem: ReRobeOrderLineItem;
5
+ originalProduct: CompleteProduct;
6
+ relationship: {
7
+ documentId?: string;
8
+ parentMerchantId?: string;
9
+ marketplaceCommission?: string | number;
10
+ };
11
+ parentMerchantId?: string;
12
+ stripeFeeAllocatedAmount?: number;
13
+ ribbnFeeAllocatedAmount?: number;
14
+ };
15
+ type BuildCanonicalMigrationPlanParams = {
16
+ duplicateProduct: any;
17
+ originalProduct: CompleteProduct;
18
+ relationship: {
19
+ documentId?: string;
20
+ parentMerchantId?: string;
21
+ childMerchantId?: string;
22
+ };
23
+ at?: number;
24
+ };
25
+ export declare const fromLegacyDuplicateLine: ({ lineItem, originalProduct, relationship, parentMerchantId, stripeFeeAllocatedAmount, ribbnFeeAllocatedAmount, }: FromLegacyDuplicateLineParams) => MarketplaceLineSnapshot;
26
+ export declare const getOriginalProductIdFromDuplicate: (duplicateProduct: any) => string | null;
27
+ export declare const buildCanonicalMigrationPlan: ({ duplicateProduct, originalProduct, relationship, at, }: BuildCanonicalMigrationPlanParams) => {
28
+ duplicateProductId: any;
29
+ originalProductId: string | null;
30
+ parentMerchantId: any;
31
+ childMerchantId: string;
32
+ patch: {
33
+ marketplace: ProductMarketplace;
34
+ } | null;
35
+ alreadyCanonical: boolean;
36
+ };
37
+ declare const _default: {
38
+ isLegacyDuplicateProduct: (product: any) => boolean;
39
+ parseRibbnIdTag: (tagsLike: any) => string | null;
40
+ fromLegacyDuplicateLine: ({ lineItem, originalProduct, relationship, parentMerchantId, stripeFeeAllocatedAmount, ribbnFeeAllocatedAmount, }: FromLegacyDuplicateLineParams) => MarketplaceLineSnapshot;
41
+ getOriginalProductIdFromDuplicate: (duplicateProduct: any) => string | null;
42
+ buildCanonicalMigrationPlan: ({ duplicateProduct, originalProduct, relationship, at, }: BuildCanonicalMigrationPlanParams) => {
43
+ duplicateProductId: any;
44
+ originalProductId: string | null;
45
+ parentMerchantId: any;
46
+ childMerchantId: string;
47
+ patch: {
48
+ marketplace: ProductMarketplace;
49
+ } | null;
50
+ alreadyCanonical: boolean;
51
+ };
52
+ };
53
+ export default _default;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ // Backwards-compatibility helpers for orders/products created under the
3
+ // duplicate-based marketplace model. The new canonical model exposes
4
+ // `lineItem.marketplace` snapshots directly; these adapters lift legacy
5
+ // data into the same shape so payouts, refunds, and reporting do not need
6
+ // to branch on era. All helpers are pure and accept already-loaded data.
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.buildCanonicalMigrationPlan = exports.getOriginalProductIdFromDuplicate = exports.fromLegacyDuplicateLine = exports.parseRibbnIdTag = exports.isLegacyDuplicateProduct = void 0;
9
+ const marketplace_constants_1 = require("../../constants/marketplace-constants");
10
+ const MarketplaceProductHelpers_1 = require("../MarketplaceProductHelpers");
11
+ const LEGACY_DUPLICATE_SYSTEM_TAG = 'marketplaceSellerProduct';
12
+ const RIBBN_ID_TAG_PREFIX = 'ribbnId:';
13
+ const stringArray = (value) => Array.isArray(value) ? value.filter((v) => typeof v === 'string' && v.length > 0) : [];
14
+ const findRibbnIdInTags = (tags) => {
15
+ const tag = tags.find((t) => typeof t === 'string' && t.indexOf(RIBBN_ID_TAG_PREFIX) === 0);
16
+ if (!tag)
17
+ return null;
18
+ const value = tag.slice(RIBBN_ID_TAG_PREFIX.length);
19
+ return value || null;
20
+ };
21
+ const isLegacyDuplicateProduct = (product) => {
22
+ if (!product)
23
+ return false;
24
+ const systemTags = stringArray(product.systemTags);
25
+ return systemTags.includes(LEGACY_DUPLICATE_SYSTEM_TAG);
26
+ };
27
+ exports.isLegacyDuplicateProduct = isLegacyDuplicateProduct;
28
+ const parseRibbnIdTag = (tagsLike) => {
29
+ if (Array.isArray(tagsLike)) {
30
+ return findRibbnIdInTags(stringArray(tagsLike));
31
+ }
32
+ if (tagsLike && typeof tagsLike === 'object') {
33
+ const merged = [...stringArray(tagsLike.systemTags), ...stringArray(tagsLike.tags)];
34
+ return findRibbnIdInTags(merged);
35
+ }
36
+ return null;
37
+ };
38
+ exports.parseRibbnIdTag = parseRibbnIdTag;
39
+ // Produces a `MarketplaceLineSnapshot` for an old duplicate-tagged line item
40
+ // using the same line-net commission policy as new orders so payout/refund
41
+ // math stays consistent across eras. The original product's owner is used
42
+ // as `managedMerchantId`; the relationship contributes the marketplace rate
43
+ // and parent id.
44
+ const fromLegacyDuplicateLine = ({ lineItem, originalProduct, relationship, parentMerchantId, stripeFeeAllocatedAmount = 0, ribbnFeeAllocatedAmount = 0, }) => {
45
+ var _a, _b, _c, _d, _e;
46
+ const quantity = Number(lineItem === null || lineItem === void 0 ? void 0 : lineItem.quantity) > 0 ? Number(lineItem.quantity) : 1;
47
+ const discountedAmount = Number((_a = lineItem === null || lineItem === void 0 ? void 0 : lineItem.discountedPrice) === null || _a === void 0 ? void 0 : _a.amount);
48
+ const originalAmount = Number((_b = lineItem === null || lineItem === void 0 ? void 0 : lineItem.originalTotalPrice) === null || _b === void 0 ? void 0 : _b.amount);
49
+ const safeOriginal = Number.isFinite(originalAmount) ? originalAmount : 0;
50
+ const safeDiscounted = Number.isFinite(discountedAmount) ? discountedAmount : safeOriginal;
51
+ const discountAmount = Math.max(0, safeOriginal - safeDiscounted);
52
+ const taxAmount = Number((_c = lineItem === null || lineItem === void 0 ? void 0 : lineItem.taxAmount) === null || _c === void 0 ? void 0 : _c.amount) || 0;
53
+ const currencyCode = ((_d = lineItem === null || lineItem === void 0 ? void 0 : lineItem.originalTotalPrice) === null || _d === void 0 ? void 0 : _d.currencyCode) || ((_e = lineItem === null || lineItem === void 0 ? void 0 : lineItem.discountedPrice) === null || _e === void 0 ? void 0 : _e.currencyCode) || '';
54
+ return MarketplaceProductHelpers_1.default.buildLineSnapshot({
55
+ product: originalProduct,
56
+ parentMerchantId: String(parentMerchantId || (relationship === null || relationship === void 0 ? void 0 : relationship.parentMerchantId) || ''),
57
+ managedMerchantId: String((originalProduct === null || originalProduct === void 0 ? void 0 : originalProduct.merchantId) || (originalProduct === null || originalProduct === void 0 ? void 0 : originalProduct.vendorId) || ''),
58
+ relationshipId: String((relationship === null || relationship === void 0 ? void 0 : relationship.documentId) || ''),
59
+ marketplaceCommissionRate: (relationship === null || relationship === void 0 ? void 0 : relationship.marketplaceCommission) === undefined || (relationship === null || relationship === void 0 ? void 0 : relationship.marketplaceCommission) === null
60
+ ? '0'
61
+ : relationship.marketplaceCommission,
62
+ marketplaceCommissionBasis: marketplace_constants_1.DEFAULT_MARKETPLACE_COMMISSION_BASIS,
63
+ quantity,
64
+ currencyCode,
65
+ discountAmount,
66
+ taxAmount,
67
+ stripeFeeAllocatedAmount,
68
+ ribbnFeeAllocatedAmount,
69
+ });
70
+ };
71
+ exports.fromLegacyDuplicateLine = fromLegacyDuplicateLine;
72
+ const getOriginalProductIdFromDuplicate = (duplicateProduct) => (0, exports.parseRibbnIdTag)(duplicateProduct);
73
+ exports.getOriginalProductIdFromDuplicate = getOriginalProductIdFromDuplicate;
74
+ const buildCanonicalMigrationPlan = ({ duplicateProduct, originalProduct, relationship, at, }) => {
75
+ const originalProductId = (originalProduct === null || originalProduct === void 0 ? void 0 : originalProduct.documentId) || (0, exports.getOriginalProductIdFromDuplicate)(duplicateProduct);
76
+ const parentMerchantId = (relationship === null || relationship === void 0 ? void 0 : relationship.parentMerchantId) || (duplicateProduct === null || duplicateProduct === void 0 ? void 0 : duplicateProduct.merchantId) || '';
77
+ const patch = MarketplaceProductHelpers_1.default.buildCanonicalMarketplaceListingPatch({
78
+ product: Object.assign(Object.assign({}, originalProduct), { documentId: originalProductId }),
79
+ parentMerchantId,
80
+ relationshipId: (relationship === null || relationship === void 0 ? void 0 : relationship.documentId) || '',
81
+ at,
82
+ });
83
+ return {
84
+ duplicateProductId: (duplicateProduct === null || duplicateProduct === void 0 ? void 0 : duplicateProduct.documentId) || '',
85
+ originalProductId,
86
+ parentMerchantId,
87
+ childMerchantId: (relationship === null || relationship === void 0 ? void 0 : relationship.childMerchantId) || (originalProduct === null || originalProduct === void 0 ? void 0 : originalProduct.merchantId) || (originalProduct === null || originalProduct === void 0 ? void 0 : originalProduct.vendorId) || '',
88
+ patch,
89
+ alreadyCanonical: !patch,
90
+ };
91
+ };
92
+ exports.buildCanonicalMigrationPlan = buildCanonicalMigrationPlan;
93
+ exports.default = {
94
+ isLegacyDuplicateProduct: exports.isLegacyDuplicateProduct,
95
+ parseRibbnIdTag: exports.parseRibbnIdTag,
96
+ fromLegacyDuplicateLine: exports.fromLegacyDuplicateLine,
97
+ getOriginalProductIdFromDuplicate: exports.getOriginalProductIdFromDuplicate,
98
+ buildCanonicalMigrationPlan: exports.buildCanonicalMigrationPlan,
99
+ };
@@ -0,0 +1,40 @@
1
+ export type MarketplaceLineDisplayMode = 'customer' | 'staff' | 'receipt';
2
+ type MarketplaceVariantOptionsInput = Record<string, any> | {
3
+ name?: any;
4
+ key?: any;
5
+ label?: any;
6
+ value?: any;
7
+ }[];
8
+ export type MarketplaceLineDisplayTitleInput = {
9
+ lineItem?: ReRobeOrderLineItem | null;
10
+ title?: string | null;
11
+ brand?: string | null;
12
+ sellerDisplayName?: string | null;
13
+ variantOptions?: MarketplaceVariantOptionsInput | null;
14
+ variantSku?: string | null;
15
+ };
16
+ export type MarketplaceLineDisplayTitleOptions = {
17
+ mode?: MarketplaceLineDisplayMode;
18
+ includeSellerPrefix?: boolean;
19
+ prefixSeparator?: string;
20
+ appendVariantLabel?: boolean;
21
+ };
22
+ export type MarketplaceLineDisplayTitleResult = {
23
+ baseTitle: string;
24
+ displayTitle: string;
25
+ sellerDisplayName: string;
26
+ variantLabel: string;
27
+ };
28
+ export declare const getMarketplaceLineSellerDisplayName: (lineItem?: ReRobeOrderLineItem | null, fallbackSellerDisplayName?: string | null) => string;
29
+ export declare const getMarketplaceLineVariantLabel: (input: MarketplaceLineDisplayTitleInput) => string;
30
+ export declare const stripMarketplaceSellerPrefix: (title: string | null | undefined, sellerDisplayName: string | null | undefined, prefixSeparator?: string) => string;
31
+ export declare const buildMarketplaceLineDisplayTitle: (input: MarketplaceLineDisplayTitleInput, options?: MarketplaceLineDisplayTitleOptions) => MarketplaceLineDisplayTitleResult;
32
+ export declare const formatMarketplaceLineDisplayTitle: (input: MarketplaceLineDisplayTitleInput, options?: MarketplaceLineDisplayTitleOptions) => string;
33
+ declare const _default: {
34
+ buildMarketplaceLineDisplayTitle: (input: MarketplaceLineDisplayTitleInput, options?: MarketplaceLineDisplayTitleOptions) => MarketplaceLineDisplayTitleResult;
35
+ formatMarketplaceLineDisplayTitle: (input: MarketplaceLineDisplayTitleInput, options?: MarketplaceLineDisplayTitleOptions) => string;
36
+ getMarketplaceLineSellerDisplayName: (lineItem?: ReRobeOrderLineItem | null, fallbackSellerDisplayName?: string | null) => string;
37
+ getMarketplaceLineVariantLabel: (input: MarketplaceLineDisplayTitleInput) => string;
38
+ stripMarketplaceSellerPrefix: (title: string | null | undefined, sellerDisplayName: string | null | undefined, prefixSeparator?: string) => string;
39
+ };
40
+ export default _default;