rerobe-js-orm 4.9.4 → 4.9.5
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/lib/factories/Merchant/MerchantFromFormState.js +0 -1
- package/lib/form-states/Merchant/MerchantFormState.js +0 -1
- package/lib/helpers/OrderHelpers.js +17 -10
- package/lib/helpers/ReturnPolicyHelpers.d.ts +40 -0
- package/lib/helpers/ReturnPolicyHelpers.js +186 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +3 -1
- package/lib/models/Merchant.d.ts +4 -1
- package/lib/models/Merchant.js +17 -0
- package/lib/types/merchant-types.d.ts +10 -2
- package/package.json +1 -1
|
@@ -22,7 +22,6 @@ class MerchantFromFormState extends MerchantFactory_1.default {
|
|
|
22
22
|
primaryDomain: fs.fields.primaryDomain.inputValue,
|
|
23
23
|
socialLinks: fs.fields.socialLinks.selectedValue,
|
|
24
24
|
organizationNumber: fs.fields.organizationNumber.inputValue,
|
|
25
|
-
returnPolicy: fs.fields.returnPolicy.inputValue,
|
|
26
25
|
};
|
|
27
26
|
// Include organizationNumbers if it has entries
|
|
28
27
|
const orgNumbers = (_a = fs.fields.organizationNumbers) === null || _a === void 0 ? void 0 : _a.selectedValue;
|
|
@@ -16,7 +16,6 @@ class MerchantFormState extends FormState_1.default {
|
|
|
16
16
|
this.fields.legalName = this.fieldFactory('textInput', 'legalName');
|
|
17
17
|
this.fields.organizationNumber = this.fieldFactory('textInput', 'organizationNumber');
|
|
18
18
|
this.fields.organizationNumbers = this.fieldFactory('singleSelect', 'organizationNumbers');
|
|
19
|
-
this.fields.returnPolicy = this.fieldFactory('textInput', 'returnPolicy');
|
|
20
19
|
this.fields.phone = this.fieldFactory('textInput', 'phone');
|
|
21
20
|
this.fields.address = this.fieldFactory('singleSelect', 'address');
|
|
22
21
|
this.fields.currency = this.fieldFactory('singleSelect', 'currency', options_1.currencyOptions);
|
|
@@ -6,6 +6,7 @@ const order_constants_1 = require("../constants/order-constants");
|
|
|
6
6
|
const translations_1 = require("../translations");
|
|
7
7
|
const CryptoPolyfill_1 = require("./CryptoPolyfill");
|
|
8
8
|
const PricingHelpers_1 = require("./PricingHelpers");
|
|
9
|
+
const ReturnPolicyHelpers_1 = require("./ReturnPolicyHelpers");
|
|
9
10
|
const MarketplaceLineDisplayHelpers_1 = require("./marketplace/MarketplaceLineDisplayHelpers");
|
|
10
11
|
class OrderHelpers {
|
|
11
12
|
// Frozen-rate pricing snapshot for a single order line item. Reads
|
|
@@ -594,7 +595,7 @@ class OrderHelpers {
|
|
|
594
595
|
};
|
|
595
596
|
}
|
|
596
597
|
buildReceiptObjFromOrder({ order, merchant, merchantLogoUrl = '', receiptNumber = '', additionalInfo = '', isRefund = false, refundId = null, originalReceiptNumber = null, includeMarketplaceSellerPrefix = false, }) {
|
|
597
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
|
|
598
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
|
|
598
599
|
const { address: merchantAddress, legalName, name, contactEmail, phone = '', organizationNumber = '', primaryDomain, currency: storeCurrencyCode, returnPolicy, } = merchant;
|
|
599
600
|
const currencyCode = ((_a = order.totalPricePresentment) === null || _a === void 0 ? void 0 : _a.currencyCode) || storeCurrencyCode;
|
|
600
601
|
const presentmentLocale = (0, Utilities_1.getPresentmentLocaleByCurrencyCode)(currencyCode);
|
|
@@ -691,8 +692,14 @@ class OrderHelpers {
|
|
|
691
692
|
translations_1.refundPurchaseTranslations[presentmentLocale] || translations_1.refundPurchaseTranslations['en-US'];
|
|
692
693
|
}
|
|
693
694
|
let info = additionalInfo;
|
|
694
|
-
|
|
695
|
-
|
|
695
|
+
// Derive the return-policy line from the structured policy for the order's
|
|
696
|
+
// sales channel (legacy free-text policies pass through unchanged). Never
|
|
697
|
+
// shown on refund receipts.
|
|
698
|
+
const returnPolicyText = isRefund
|
|
699
|
+
? ''
|
|
700
|
+
: ReturnPolicyHelpers_1.default.returnPolicyReceiptText(returnPolicy, (_d = order.salesChannel) !== null && _d !== void 0 ? _d : undefined);
|
|
701
|
+
if (returnPolicyText) {
|
|
702
|
+
info = returnPolicyText;
|
|
696
703
|
if (additionalInfo) {
|
|
697
704
|
info = `${info}\n\n${additionalInfo}`;
|
|
698
705
|
}
|
|
@@ -708,29 +715,29 @@ class OrderHelpers {
|
|
|
708
715
|
organizationNumber,
|
|
709
716
|
primaryDomain, storeUrl: `https://${primaryDomain}`, orderDate: (0, Utilities_1.getFormattedTimestamp)(presentmentLocale, order === null || order === void 0 ? void 0 : order.createdAtTimestamp), receiptNumber, additionalInfo: info, isRefund, originalReceiptNumber: originalReceiptNumber || null, originalReceiptLabel: translations_1.originalReceiptTranslations[presentmentLocale] || translations_1.originalReceiptTranslations['en-US'], lineItems: buildLineItems(), subTotal: (0, Utilities_1.formatPrice)({
|
|
710
717
|
currencyCode,
|
|
711
|
-
amount: (
|
|
718
|
+
amount: (_g = negateForRefund((_f = (_e = order.subtotalPricePresentment) === null || _e === void 0 ? void 0 : _e.amount) !== null && _f !== void 0 ? _f : '')) !== null && _g !== void 0 ? _g : '',
|
|
712
719
|
fractionDigits: 2,
|
|
713
720
|
}), total: (0, Utilities_1.formatPrice)({
|
|
714
721
|
currencyCode,
|
|
715
|
-
amount: (
|
|
722
|
+
amount: (_k = negateForRefund((_j = (_h = order.totalPricePresentment) === null || _h === void 0 ? void 0 : _h.amount) !== null && _j !== void 0 ? _j : '')) !== null && _k !== void 0 ? _k : '',
|
|
716
723
|
fractionDigits: 2,
|
|
717
724
|
}), amountPaid: (0, Utilities_1.formatPrice)({
|
|
718
725
|
currencyCode,
|
|
719
|
-
amount: (
|
|
726
|
+
amount: (_o = negateForRefund((_m = (_l = order.totalPricePresentment) === null || _l === void 0 ? void 0 : _l.amount) !== null && _m !== void 0 ? _m : '')) !== null && _o !== void 0 ? _o : '',
|
|
720
727
|
fractionDigits: 2,
|
|
721
728
|
}), tax: (0, Utilities_1.formatPrice)({
|
|
722
729
|
currencyCode,
|
|
723
|
-
amount: (
|
|
730
|
+
amount: (_r = negateForRefund((_q = (_p = order.totalTaxPresentment) === null || _p === void 0 ? void 0 : _p.amount) !== null && _q !== void 0 ? _q : '')) !== null && _r !== void 0 ? _r : '',
|
|
724
731
|
fractionDigits: 2,
|
|
725
|
-
}), taxRates: formattedTaxRates }, paymentTerminalInfo), receiptLabels), (Number(((
|
|
732
|
+
}), taxRates: formattedTaxRates }, paymentTerminalInfo), receiptLabels), (Number(((_s = order.totalRefundedPresentment) === null || _s === void 0 ? void 0 : _s.amount) || 0) > 0 && {
|
|
726
733
|
totalRefunded: (0, Utilities_1.formatPrice)({
|
|
727
734
|
currencyCode,
|
|
728
|
-
amount: (
|
|
735
|
+
amount: (_u = (_t = order.totalRefundedPresentment) === null || _t === void 0 ? void 0 : _t.amount) !== null && _u !== void 0 ? _u : '',
|
|
729
736
|
fractionDigits: 2,
|
|
730
737
|
}),
|
|
731
738
|
netPayment: (0, Utilities_1.formatPrice)({
|
|
732
739
|
currencyCode,
|
|
733
|
-
amount: Number((
|
|
740
|
+
amount: Number((_w = (_v = order.totalPricePresentment) === null || _v === void 0 ? void 0 : _v.amount) !== null && _w !== void 0 ? _w : 0) - Number((_y = (_x = order.totalRefundedPresentment) === null || _x === void 0 ? void 0 : _x.amount) !== null && _y !== void 0 ? _y : 0),
|
|
734
741
|
fractionDigits: 2,
|
|
735
742
|
}),
|
|
736
743
|
refundLineItems: (order.refunds || []).flatMap((refund) => (refund.refundLineItems || []).map((item) => {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
type ReturnEvaluation = {
|
|
2
|
+
allowed: boolean;
|
|
3
|
+
reason: string;
|
|
4
|
+
windowEndMillis?: number;
|
|
5
|
+
};
|
|
6
|
+
export default class ReturnPolicyHelpers {
|
|
7
|
+
static CHANNELS: {
|
|
8
|
+
inStore: string;
|
|
9
|
+
online: string;
|
|
10
|
+
};
|
|
11
|
+
static REASONS: {
|
|
12
|
+
noPolicy: string;
|
|
13
|
+
noChannelMapping: string;
|
|
14
|
+
noSoldTimestamp: string;
|
|
15
|
+
returnsNotAllowed: string;
|
|
16
|
+
windowExpired: string;
|
|
17
|
+
withinWindow: string;
|
|
18
|
+
};
|
|
19
|
+
private static normChannel;
|
|
20
|
+
static parse(raw: any): ReturnPolicy | null;
|
|
21
|
+
static isConfigured(raw: any): boolean;
|
|
22
|
+
static defaultPolicy(): ReturnPolicy;
|
|
23
|
+
static channelKeyForSalesChannel(salesChannel: string): string | null;
|
|
24
|
+
static getChannelPolicy(raw: any, salesChannel: string): ReturnPolicyChannel | null;
|
|
25
|
+
static resolveSoldState(raw: any, salesChannel: string): string;
|
|
26
|
+
static getReturnWindowEndMillis(raw: any, salesChannel: string, soldAtMillis: number): number | null;
|
|
27
|
+
static evaluateReturn({ raw, salesChannel, soldAtMillis, nowMillis, }: {
|
|
28
|
+
raw: any;
|
|
29
|
+
salesChannel: string;
|
|
30
|
+
soldAtMillis?: number;
|
|
31
|
+
nowMillis?: number;
|
|
32
|
+
}): ReturnEvaluation;
|
|
33
|
+
static returnPolicyReceiptText(raw: any, salesChannel?: string): string;
|
|
34
|
+
static resolveEffectiveReturnPolicy({ ownPolicyRaw, marketplaceDefaultRaw, isManaged, }: {
|
|
35
|
+
ownPolicyRaw?: any;
|
|
36
|
+
marketplaceDefaultRaw?: any;
|
|
37
|
+
isManaged?: boolean;
|
|
38
|
+
}): ReturnPolicy | null;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Return-policy business logic — the single home for everything that reads a
|
|
3
|
+
// merchant's `returnPolicy`:
|
|
4
|
+
// (a) parse/normalize the stored value (tolerant of legacy free-text strings
|
|
5
|
+
// and partial/malformed objects),
|
|
6
|
+
// (b) resolve the product sold-state for a sale (drives seller-payout hold),
|
|
7
|
+
// (c) enforce the return window on a refund/return,
|
|
8
|
+
// (d) derive human-readable receipt text,
|
|
9
|
+
// (e) resolve the *effective* policy for a managed (marketplace) merchant.
|
|
10
|
+
//
|
|
11
|
+
// Pure + dependency-free (constants only) so backend, web, and mobile share one
|
|
12
|
+
// rule instead of each reimplementing the channel join and the sold-state
|
|
13
|
+
// branch. Channel keys are the RETURN_POLICY_TYPES values (IN_STORE / ONLINE);
|
|
14
|
+
// SALES_CHANNEL_TO_RETURN_POLICY_MAPPING maps a sale's salesChannel onto them.
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
const product_constants_1 = require("../constants/product-constants");
|
|
17
|
+
const order_constants_1 = require("../constants/order-constants");
|
|
18
|
+
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
19
|
+
// Why a refund/return was allowed or blocked. Stable strings so callers can
|
|
20
|
+
// switch on them to build user-facing messages.
|
|
21
|
+
const REASONS = {
|
|
22
|
+
noPolicy: 'NO_POLICY', // merchant never configured a policy -> no enforcement
|
|
23
|
+
noChannelMapping: 'NO_CHANNEL_MAPPING', // unknown sales channel -> no enforcement
|
|
24
|
+
noSoldTimestamp: 'NO_SOLD_TIMESTAMP', // can't determine sale time -> don't block
|
|
25
|
+
returnsNotAllowed: 'RETURNS_NOT_ALLOWED', // channel explicitly disallows returns
|
|
26
|
+
windowExpired: 'RETURN_WINDOW_EXPIRED', // past returnPeriodDays from the sale
|
|
27
|
+
withinWindow: 'WITHIN_WINDOW', // ok: inside the window
|
|
28
|
+
};
|
|
29
|
+
class ReturnPolicyHelpers {
|
|
30
|
+
// Normalize a single raw channel entry. An absent/invalid entry becomes a
|
|
31
|
+
// concrete "returns off" channel. A present object defaults `allowed` to true
|
|
32
|
+
// when the flag is missing (faithful to the legacy `allowed !== false` rule);
|
|
33
|
+
// the settings UI always writes the flag explicitly.
|
|
34
|
+
static normChannel(ch) {
|
|
35
|
+
if (!ch || typeof ch !== 'object' || Array.isArray(ch)) {
|
|
36
|
+
return { allowed: false, returnPeriodDays: 0 };
|
|
37
|
+
}
|
|
38
|
+
const days = Number(ch.returnPeriodDays);
|
|
39
|
+
return {
|
|
40
|
+
allowed: ch.allowed !== false,
|
|
41
|
+
returnPeriodDays: days > 0 ? Math.floor(days) : 0,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Parse a raw stored value into a structured ReturnPolicy, or null when the
|
|
45
|
+
// merchant has not configured a (structured) policy. Returns null for:
|
|
46
|
+
// undefined/null, '', legacy free-text strings, and objects that carry
|
|
47
|
+
// neither IN_STORE nor ONLINE. Idempotent on an already-parsed policy.
|
|
48
|
+
static parse(raw) {
|
|
49
|
+
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
const hasInStore = Object.prototype.hasOwnProperty.call(raw, order_constants_1.RETURN_POLICY_TYPES.inStore);
|
|
53
|
+
const hasOnline = Object.prototype.hasOwnProperty.call(raw, order_constants_1.RETURN_POLICY_TYPES.online);
|
|
54
|
+
if (!hasInStore && !hasOnline) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
IN_STORE: this.normChannel(raw[order_constants_1.RETURN_POLICY_TYPES.inStore]),
|
|
59
|
+
ONLINE: this.normChannel(raw[order_constants_1.RETURN_POLICY_TYPES.online]),
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// Is a raw value a configured (structured) policy?
|
|
63
|
+
static isConfigured(raw) {
|
|
64
|
+
return this.parse(raw) !== null;
|
|
65
|
+
}
|
|
66
|
+
// A fully-shaped "everything off" policy — a sensible starting point for the
|
|
67
|
+
// settings UI (merchant opts in per channel).
|
|
68
|
+
static defaultPolicy() {
|
|
69
|
+
return {
|
|
70
|
+
IN_STORE: { allowed: false, returnPeriodDays: 0 },
|
|
71
|
+
ONLINE: { allowed: false, returnPeriodDays: 0 },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// Map a sale's salesChannel to its policy channel key (IN_STORE | ONLINE), or
|
|
75
|
+
// null when the channel isn't mapped.
|
|
76
|
+
static channelKeyForSalesChannel(salesChannel) {
|
|
77
|
+
return order_constants_1.SALES_CHANNEL_TO_RETURN_POLICY_MAPPING[salesChannel] || null;
|
|
78
|
+
}
|
|
79
|
+
// The normalized channel policy that applies to a sale, or null when there's
|
|
80
|
+
// no configured policy / no channel mapping.
|
|
81
|
+
static getChannelPolicy(raw, salesChannel) {
|
|
82
|
+
const policy = this.parse(raw);
|
|
83
|
+
if (!policy)
|
|
84
|
+
return null;
|
|
85
|
+
const key = this.channelKeyForSalesChannel(salesChannel);
|
|
86
|
+
if (!key)
|
|
87
|
+
return null;
|
|
88
|
+
return policy[key] || null;
|
|
89
|
+
}
|
|
90
|
+
// Decide a sold product's state for a sale. Mirrors the legacy inline rule:
|
|
91
|
+
// no policy / unmapped channel -> SOLD (backwards compatible)
|
|
92
|
+
// returns disallowed OR 0-day -> SOLD_SELLER_PAYOUT_PROCESSING (pay now)
|
|
93
|
+
// returns allowed WITH a window -> SOLD (payout held through the window)
|
|
94
|
+
static resolveSoldState(raw, salesChannel) {
|
|
95
|
+
const channel = this.getChannelPolicy(raw, salesChannel);
|
|
96
|
+
if (!channel)
|
|
97
|
+
return product_constants_1.PRODUCT_STATES.sold;
|
|
98
|
+
if (!channel.allowed || channel.returnPeriodDays <= 0) {
|
|
99
|
+
return product_constants_1.PRODUCT_STATES.soldSellerPayoutProcessing;
|
|
100
|
+
}
|
|
101
|
+
return product_constants_1.PRODUCT_STATES.sold;
|
|
102
|
+
}
|
|
103
|
+
// The instant (ms) a return window closes for a sale, or null when there's no
|
|
104
|
+
// applicable window (no policy / not allowed / 0-day / no sale time).
|
|
105
|
+
static getReturnWindowEndMillis(raw, salesChannel, soldAtMillis) {
|
|
106
|
+
const channel = this.getChannelPolicy(raw, salesChannel);
|
|
107
|
+
if (!channel || !channel.allowed || channel.returnPeriodDays <= 0)
|
|
108
|
+
return null;
|
|
109
|
+
const soldAt = Number(soldAtMillis);
|
|
110
|
+
if (!(soldAt > 0))
|
|
111
|
+
return null;
|
|
112
|
+
return soldAt + channel.returnPeriodDays * MS_PER_DAY;
|
|
113
|
+
}
|
|
114
|
+
// Evaluate whether a return/refund should be permitted under the policy.
|
|
115
|
+
// Conservative by design: when nothing is configured (no policy, unmapped
|
|
116
|
+
// channel, or unknown sale time) it ALLOWS, so adding enforcement never
|
|
117
|
+
// breaks refunds for merchants who haven't opted in. It only blocks when the
|
|
118
|
+
// merchant's configured policy says so (disallowed channel or expired window).
|
|
119
|
+
static evaluateReturn({ raw, salesChannel, soldAtMillis, nowMillis, }) {
|
|
120
|
+
const policy = this.parse(raw);
|
|
121
|
+
if (!policy)
|
|
122
|
+
return { allowed: true, reason: REASONS.noPolicy };
|
|
123
|
+
const key = this.channelKeyForSalesChannel(salesChannel);
|
|
124
|
+
if (!key)
|
|
125
|
+
return { allowed: true, reason: REASONS.noChannelMapping };
|
|
126
|
+
const channel = policy[key];
|
|
127
|
+
if (!channel.allowed)
|
|
128
|
+
return { allowed: false, reason: REASONS.returnsNotAllowed };
|
|
129
|
+
if (channel.returnPeriodDays <= 0) {
|
|
130
|
+
// Allowed but no window configured -> nothing qualifies after the sale.
|
|
131
|
+
return { allowed: false, reason: REASONS.windowExpired, windowEndMillis: Number(soldAtMillis) || 0 };
|
|
132
|
+
}
|
|
133
|
+
const soldAt = Number(soldAtMillis);
|
|
134
|
+
if (!(soldAt > 0))
|
|
135
|
+
return { allowed: true, reason: REASONS.noSoldTimestamp };
|
|
136
|
+
const windowEndMillis = soldAt + channel.returnPeriodDays * MS_PER_DAY;
|
|
137
|
+
const now = Number(nowMillis) > 0 ? Number(nowMillis) : Date.now();
|
|
138
|
+
if (now <= windowEndMillis)
|
|
139
|
+
return { allowed: true, reason: REASONS.withinWindow, windowEndMillis };
|
|
140
|
+
return { allowed: false, reason: REASONS.windowExpired, windowEndMillis };
|
|
141
|
+
}
|
|
142
|
+
// Human-readable line for a receipt. Legacy free-text strings pass through
|
|
143
|
+
// unchanged. For a structured policy, prefer the sale's channel; without a
|
|
144
|
+
// channel, summarize whichever channel(s) accept returns. Returns '' when
|
|
145
|
+
// there's nothing meaningful to print (no policy, or returns not accepted).
|
|
146
|
+
static returnPolicyReceiptText(raw, salesChannel) {
|
|
147
|
+
if (typeof raw === 'string')
|
|
148
|
+
return raw.trim();
|
|
149
|
+
const policy = this.parse(raw);
|
|
150
|
+
if (!policy)
|
|
151
|
+
return '';
|
|
152
|
+
const lineFor = (ch) => {
|
|
153
|
+
if (!ch || !ch.allowed || ch.returnPeriodDays <= 0)
|
|
154
|
+
return '';
|
|
155
|
+
return `${ch.returnPeriodDays} day return policy`;
|
|
156
|
+
};
|
|
157
|
+
if (salesChannel) {
|
|
158
|
+
const key = this.channelKeyForSalesChannel(salesChannel);
|
|
159
|
+
if (key)
|
|
160
|
+
return lineFor(policy[key]);
|
|
161
|
+
}
|
|
162
|
+
const inStore = lineFor(policy.IN_STORE);
|
|
163
|
+
const online = lineFor(policy.ONLINE);
|
|
164
|
+
if (inStore && online) {
|
|
165
|
+
return inStore === online ? inStore : `In-store: ${inStore}\nOnline: ${online}`;
|
|
166
|
+
}
|
|
167
|
+
return inStore || online || '';
|
|
168
|
+
}
|
|
169
|
+
// Resolve the policy that actually governs a merchant. For a managed
|
|
170
|
+
// (marketplace) merchant the marketplace-wide default governs, falling back to
|
|
171
|
+
// the merchant's own policy only when the marketplace hasn't set one. For a
|
|
172
|
+
// standalone merchant, their own policy governs.
|
|
173
|
+
//
|
|
174
|
+
// FUTURE (per-merchant override): to let managed merchants override the
|
|
175
|
+
// marketplace default, flip the managed branch to
|
|
176
|
+
// `this.parse(ownPolicyRaw) || this.parse(marketplaceDefaultRaw)`.
|
|
177
|
+
static resolveEffectiveReturnPolicy({ ownPolicyRaw, marketplaceDefaultRaw, isManaged, }) {
|
|
178
|
+
if (isManaged) {
|
|
179
|
+
return this.parse(marketplaceDefaultRaw) || this.parse(ownPolicyRaw);
|
|
180
|
+
}
|
|
181
|
+
return this.parse(ownPolicyRaw);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
ReturnPolicyHelpers.CHANNELS = order_constants_1.RETURN_POLICY_TYPES; // { inStore: 'IN_STORE', online: 'ONLINE' }
|
|
185
|
+
ReturnPolicyHelpers.REASONS = REASONS;
|
|
186
|
+
exports.default = ReturnPolicyHelpers;
|
package/lib/index.d.ts
CHANGED
|
@@ -51,11 +51,12 @@ import TaxHelpers from './helpers/TaxHelpers';
|
|
|
51
51
|
import PricingHelpers from './helpers/PricingHelpers';
|
|
52
52
|
import ProductSkuHelpers, { DEFAULT_SKU_LENGTH, SKU_ALPHABET } from './helpers/ProductSkuHelpers';
|
|
53
53
|
import ProductVariantHelpers from './helpers/ProductVariantHelpers';
|
|
54
|
+
import ReturnPolicyHelpers from './helpers/ReturnPolicyHelpers';
|
|
54
55
|
import ProductInventoryHelpers, { PLACEHOLDER_VARIANT_ID } from './helpers/ProductInventoryHelpers';
|
|
55
56
|
import RetailProductFactory from './factories/Product/RetailProductFactory';
|
|
56
57
|
import { FALLBACK_TAX_COUNTRY_CODE, TAX_CATEGORIES, TAX_CATEGORY_ALIASES, TAX_CATEGORY_BASE_LABELS, TAX_CATEGORY_RATES } from './constants/tax-constants';
|
|
57
58
|
import { ADMIN_SIMPLIFIED_STATES, ADMIN_STATES, PRODUCT_CLASS_VALUES, PRODUCT_STATES, PRODUCT_STATE_LABELS, RETAIL_EDITABLE_PRODUCT_STATES, getProductStateLabel, getRetailEditableProductStateOptions } from './constants/product-constants';
|
|
58
|
-
export { RibbnFile, ProductFromAlgoliaJSONDoc, ProductFromShopifyWebhookJSONDoc, ProductFromShopifyJSClientJSONDoc, ProductFormStateFactory, ProductCollectionFormStateFactory, ProductCollectionHelpers, SellRequestFormStateFactory, PickUpFormStateFactory, AddressFormStateFactory, UserFormStateFactory, UserFromShopifyWebhookJSONDoc, UserFromAuthTemplateMethod, DraftOrderFromMirakl, DraftOrderFromApp, ChatRoomFromNewUserSignUp, KlarnaSessionFactory, Product, ProductStateManager, Order, OrderFromShopifyWebhook, OrderFromShopifyAdminApi, OrderFromShopifyStorefrontApi, OrderFromApp, OrderFromTraderaEmail, OrderFormStateFactory, RefundFormStateFactory, PayoutAccount, PayoutAccountFormState, Merchant, MERCHANT_ACCOUNT_MODES, MERCHANT_ACCOUNT_CLASSES, MERCHANT_RELATIONSHIP_TYPES, MARKETPLACE_SELLER_CAPABILITIES, DEFAULT_MARKETPLACE_SELLER_CAPABILITIES, MerchantFormState, MerchantFormStateFactory, MerchantConfigAutomatedPayouts, MerchantConfigAutomatedPayoutsFormState, ReRobeProductHelpers, MarketplaceProductHelpers, MarketplaceLedgerHelpers, MarketplaceLegacyAdapters, MarketplaceLineDisplayHelpers, MarketplaceOrderHelpers, MARKETPLACE_LISTING_STATUSES, MARKETPLACE_COMMISSION_BASES, MARKETPLACE_RELATIONSHIP_TYPES, MARKETPLACE_FEE_TYPES, MARKETPLACE_FEE_ALLOCATION_BASES, MARKETPLACE_LEDGER_STATUSES, MARKETPLACE_INVENTORY_POLICY_KINDS, MARKETPLACE_SELLER_DEFAULT_COMMISSION, STOCK_STATUSES, DEFAULT_MARKETPLACE_LISTING_STATUS, DEFAULT_MARKETPLACE_COMMISSION_BASIS, DEFAULT_MARKETPLACE_RELATIONSHIP_TYPE, DEFAULT_STRIPE_FEE_ALLOCATION_BASIS, DEFAULT_RIBBN_FEE_ALLOCATION_BASIS, DEFAULT_MARKETPLACE_LEDGER_STATUS, User, AnalyticsHelpers, OrderHelpers, WebhookFormState, MerchantWebPage, ShopifyMerchantAccount, CustomerNotification, TaxHelpers, PricingHelpers, ProductSkuHelpers, ProductVariantHelpers, ProductInventoryHelpers, RetailProductFactory, SKU_ALPHABET, DEFAULT_SKU_LENGTH, PLACEHOLDER_VARIANT_ID, TAX_CATEGORIES, TAX_CATEGORY_RATES, TAX_CATEGORY_BASE_LABELS, TAX_CATEGORY_ALIASES, FALLBACK_TAX_COUNTRY_CODE, PRODUCT_STATES, PRODUCT_STATE_LABELS, PRODUCT_CLASS_VALUES, ADMIN_STATES, ADMIN_SIMPLIFIED_STATES, RETAIL_EDITABLE_PRODUCT_STATES, getProductStateLabel, getRetailEditableProductStateOptions, };
|
|
59
|
+
export { RibbnFile, ProductFromAlgoliaJSONDoc, ProductFromShopifyWebhookJSONDoc, ProductFromShopifyJSClientJSONDoc, ProductFormStateFactory, ProductCollectionFormStateFactory, ProductCollectionHelpers, SellRequestFormStateFactory, PickUpFormStateFactory, AddressFormStateFactory, UserFormStateFactory, UserFromShopifyWebhookJSONDoc, UserFromAuthTemplateMethod, DraftOrderFromMirakl, DraftOrderFromApp, ChatRoomFromNewUserSignUp, KlarnaSessionFactory, Product, ProductStateManager, Order, OrderFromShopifyWebhook, OrderFromShopifyAdminApi, OrderFromShopifyStorefrontApi, OrderFromApp, OrderFromTraderaEmail, OrderFormStateFactory, RefundFormStateFactory, PayoutAccount, PayoutAccountFormState, Merchant, MERCHANT_ACCOUNT_MODES, MERCHANT_ACCOUNT_CLASSES, MERCHANT_RELATIONSHIP_TYPES, MARKETPLACE_SELLER_CAPABILITIES, DEFAULT_MARKETPLACE_SELLER_CAPABILITIES, MerchantFormState, MerchantFormStateFactory, MerchantConfigAutomatedPayouts, MerchantConfigAutomatedPayoutsFormState, ReRobeProductHelpers, MarketplaceProductHelpers, MarketplaceLedgerHelpers, MarketplaceLegacyAdapters, MarketplaceLineDisplayHelpers, MarketplaceOrderHelpers, MARKETPLACE_LISTING_STATUSES, MARKETPLACE_COMMISSION_BASES, MARKETPLACE_RELATIONSHIP_TYPES, MARKETPLACE_FEE_TYPES, MARKETPLACE_FEE_ALLOCATION_BASES, MARKETPLACE_LEDGER_STATUSES, MARKETPLACE_INVENTORY_POLICY_KINDS, MARKETPLACE_SELLER_DEFAULT_COMMISSION, STOCK_STATUSES, DEFAULT_MARKETPLACE_LISTING_STATUS, DEFAULT_MARKETPLACE_COMMISSION_BASIS, DEFAULT_MARKETPLACE_RELATIONSHIP_TYPE, DEFAULT_STRIPE_FEE_ALLOCATION_BASIS, DEFAULT_RIBBN_FEE_ALLOCATION_BASIS, DEFAULT_MARKETPLACE_LEDGER_STATUS, User, AnalyticsHelpers, OrderHelpers, WebhookFormState, MerchantWebPage, ShopifyMerchantAccount, CustomerNotification, TaxHelpers, PricingHelpers, ProductSkuHelpers, ProductVariantHelpers, ReturnPolicyHelpers, ProductInventoryHelpers, RetailProductFactory, SKU_ALPHABET, DEFAULT_SKU_LENGTH, PLACEHOLDER_VARIANT_ID, TAX_CATEGORIES, TAX_CATEGORY_RATES, TAX_CATEGORY_BASE_LABELS, TAX_CATEGORY_ALIASES, FALLBACK_TAX_COUNTRY_CODE, PRODUCT_STATES, PRODUCT_STATE_LABELS, PRODUCT_CLASS_VALUES, ADMIN_STATES, ADMIN_SIMPLIFIED_STATES, RETAIL_EDITABLE_PRODUCT_STATES, getProductStateLabel, getRetailEditableProductStateOptions, };
|
|
59
60
|
export type { PlaceholderVariantInput, PlaceholderVariantInventory, PlaceholderVariantLocation, } from './helpers/ProductInventoryHelpers';
|
|
60
61
|
export type { RetailOwnershipInput, RetailAccountingInput, RetailLocationInput, ClothingDetailsInput, NonClothingDetailsInput, OneOfAKindClothingInput, MultivariantClothingInput, TrackedRetailInput, UntrackedRetailInput, } from './factories/Product/RetailProductFactory';
|
|
61
62
|
export type { TaxCategoryValue } from './constants/tax-constants';
|
package/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MARKETPLACE_FEE_ALLOCATION_BASES = exports.MARKETPLACE_FEE_TYPES = exports.MARKETPLACE_RELATIONSHIP_TYPES = exports.MARKETPLACE_COMMISSION_BASES = exports.MARKETPLACE_LISTING_STATUSES = exports.MarketplaceOrderHelpers = exports.MarketplaceLineDisplayHelpers = exports.MarketplaceLegacyAdapters = exports.MarketplaceLedgerHelpers = exports.MarketplaceProductHelpers = exports.ReRobeProductHelpers = exports.MerchantConfigAutomatedPayoutsFormState = exports.MerchantConfigAutomatedPayouts = exports.MerchantFormStateFactory = exports.MerchantFormState = exports.DEFAULT_MARKETPLACE_SELLER_CAPABILITIES = exports.MARKETPLACE_SELLER_CAPABILITIES = exports.MERCHANT_RELATIONSHIP_TYPES = exports.MERCHANT_ACCOUNT_CLASSES = exports.MERCHANT_ACCOUNT_MODES = exports.Merchant = exports.PayoutAccountFormState = exports.PayoutAccount = exports.RefundFormStateFactory = exports.OrderFormStateFactory = exports.OrderFromTraderaEmail = exports.OrderFromApp = exports.OrderFromShopifyStorefrontApi = exports.OrderFromShopifyAdminApi = exports.OrderFromShopifyWebhook = exports.Order = exports.ProductStateManager = exports.Product = exports.KlarnaSessionFactory = exports.ChatRoomFromNewUserSignUp = exports.DraftOrderFromApp = exports.DraftOrderFromMirakl = exports.UserFromAuthTemplateMethod = exports.UserFromShopifyWebhookJSONDoc = exports.UserFormStateFactory = exports.AddressFormStateFactory = exports.PickUpFormStateFactory = exports.SellRequestFormStateFactory = exports.ProductCollectionHelpers = exports.ProductCollectionFormStateFactory = exports.ProductFormStateFactory = exports.ProductFromShopifyJSClientJSONDoc = exports.ProductFromShopifyWebhookJSONDoc = exports.ProductFromAlgoliaJSONDoc = exports.RibbnFile = void 0;
|
|
4
|
-
exports.getRetailEditableProductStateOptions = exports.getProductStateLabel = exports.RETAIL_EDITABLE_PRODUCT_STATES = exports.ADMIN_SIMPLIFIED_STATES = exports.ADMIN_STATES = exports.PRODUCT_CLASS_VALUES = exports.PRODUCT_STATE_LABELS = exports.PRODUCT_STATES = exports.FALLBACK_TAX_COUNTRY_CODE = exports.TAX_CATEGORY_ALIASES = exports.TAX_CATEGORY_BASE_LABELS = exports.TAX_CATEGORY_RATES = exports.TAX_CATEGORIES = exports.PLACEHOLDER_VARIANT_ID = exports.DEFAULT_SKU_LENGTH = exports.SKU_ALPHABET = exports.RetailProductFactory = exports.ProductInventoryHelpers = exports.ProductVariantHelpers = exports.ProductSkuHelpers = exports.PricingHelpers = exports.TaxHelpers = exports.CustomerNotification = exports.ShopifyMerchantAccount = exports.MerchantWebPage = exports.WebhookFormState = exports.OrderHelpers = exports.AnalyticsHelpers = exports.User = exports.DEFAULT_MARKETPLACE_LEDGER_STATUS = exports.DEFAULT_RIBBN_FEE_ALLOCATION_BASIS = exports.DEFAULT_STRIPE_FEE_ALLOCATION_BASIS = exports.DEFAULT_MARKETPLACE_RELATIONSHIP_TYPE = exports.DEFAULT_MARKETPLACE_COMMISSION_BASIS = exports.DEFAULT_MARKETPLACE_LISTING_STATUS = exports.STOCK_STATUSES = exports.MARKETPLACE_SELLER_DEFAULT_COMMISSION = exports.MARKETPLACE_INVENTORY_POLICY_KINDS = exports.MARKETPLACE_LEDGER_STATUSES = void 0;
|
|
4
|
+
exports.getRetailEditableProductStateOptions = exports.getProductStateLabel = exports.RETAIL_EDITABLE_PRODUCT_STATES = exports.ADMIN_SIMPLIFIED_STATES = exports.ADMIN_STATES = exports.PRODUCT_CLASS_VALUES = exports.PRODUCT_STATE_LABELS = exports.PRODUCT_STATES = exports.FALLBACK_TAX_COUNTRY_CODE = exports.TAX_CATEGORY_ALIASES = exports.TAX_CATEGORY_BASE_LABELS = exports.TAX_CATEGORY_RATES = exports.TAX_CATEGORIES = exports.PLACEHOLDER_VARIANT_ID = exports.DEFAULT_SKU_LENGTH = exports.SKU_ALPHABET = exports.RetailProductFactory = exports.ProductInventoryHelpers = exports.ReturnPolicyHelpers = exports.ProductVariantHelpers = exports.ProductSkuHelpers = exports.PricingHelpers = exports.TaxHelpers = exports.CustomerNotification = exports.ShopifyMerchantAccount = exports.MerchantWebPage = exports.WebhookFormState = exports.OrderHelpers = exports.AnalyticsHelpers = exports.User = exports.DEFAULT_MARKETPLACE_LEDGER_STATUS = exports.DEFAULT_RIBBN_FEE_ALLOCATION_BASIS = exports.DEFAULT_STRIPE_FEE_ALLOCATION_BASIS = exports.DEFAULT_MARKETPLACE_RELATIONSHIP_TYPE = exports.DEFAULT_MARKETPLACE_COMMISSION_BASIS = exports.DEFAULT_MARKETPLACE_LISTING_STATUS = exports.STOCK_STATUSES = exports.MARKETPLACE_SELLER_DEFAULT_COMMISSION = exports.MARKETPLACE_INVENTORY_POLICY_KINDS = exports.MARKETPLACE_LEDGER_STATUSES = void 0;
|
|
5
5
|
const ProductFromShopifyJSClientJSONDoc_1 = require("./factories/Product/ProductFromShopifyJSClientJSONDoc");
|
|
6
6
|
exports.ProductFromShopifyJSClientJSONDoc = ProductFromShopifyJSClientJSONDoc_1.default;
|
|
7
7
|
const ProductFromAlgoliaJSONDoc_1 = require("./factories/Product/ProductFromAlgoliaJSONDoc");
|
|
@@ -128,6 +128,8 @@ Object.defineProperty(exports, "DEFAULT_SKU_LENGTH", { enumerable: true, get: fu
|
|
|
128
128
|
Object.defineProperty(exports, "SKU_ALPHABET", { enumerable: true, get: function () { return ProductSkuHelpers_1.SKU_ALPHABET; } });
|
|
129
129
|
const ProductVariantHelpers_1 = require("./helpers/ProductVariantHelpers");
|
|
130
130
|
exports.ProductVariantHelpers = ProductVariantHelpers_1.default;
|
|
131
|
+
const ReturnPolicyHelpers_1 = require("./helpers/ReturnPolicyHelpers");
|
|
132
|
+
exports.ReturnPolicyHelpers = ReturnPolicyHelpers_1.default;
|
|
131
133
|
const ProductInventoryHelpers_1 = require("./helpers/ProductInventoryHelpers");
|
|
132
134
|
exports.ProductInventoryHelpers = ProductInventoryHelpers_1.default;
|
|
133
135
|
Object.defineProperty(exports, "PLACEHOLDER_VARIANT_ID", { enumerable: true, get: function () { return ProductInventoryHelpers_1.PLACEHOLDER_VARIANT_ID; } });
|
package/lib/models/Merchant.d.ts
CHANGED
|
@@ -190,7 +190,8 @@ export default class Merchant extends Base {
|
|
|
190
190
|
hasStripeBluetoothReader?: boolean;
|
|
191
191
|
organizationNumber?: string;
|
|
192
192
|
organizationNumbers?: Record<string, string>;
|
|
193
|
-
returnPolicy?: string;
|
|
193
|
+
returnPolicy?: ReturnPolicy | string;
|
|
194
|
+
managedReturnPolicyDefault?: ReturnPolicy;
|
|
194
195
|
stripeRegion?: string;
|
|
195
196
|
hasAutomatedPayouts?: boolean;
|
|
196
197
|
hasAIQuickList?: boolean;
|
|
@@ -210,6 +211,8 @@ export default class Merchant extends Base {
|
|
|
210
211
|
isMarketplaceSeller?: boolean;
|
|
211
212
|
constructor(props?: any);
|
|
212
213
|
static normalizeLabelPrinterConfig(input?: Partial<LabelPrinterConfig> | Record<string, any> | null): LabelPrinterConfig;
|
|
214
|
+
getReturnPolicy(): ReturnPolicy | null;
|
|
215
|
+
getManagedReturnPolicyDefault(): ReturnPolicy | null;
|
|
213
216
|
toObj(): MerchantObj;
|
|
214
217
|
toMerchantMutableData(): MerchantMutableData;
|
|
215
218
|
isManagedMarketplaceMerchant(): boolean;
|
package/lib/models/Merchant.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const Base_1 = require("../Base");
|
|
4
4
|
const merchant_constants_1 = require("../constants/merchant-constants");
|
|
5
|
+
const ReturnPolicyHelpers_1 = require("../helpers/ReturnPolicyHelpers");
|
|
5
6
|
class Merchant extends Base_1.default {
|
|
6
7
|
constructor(props) {
|
|
7
8
|
super();
|
|
@@ -53,6 +54,9 @@ class Merchant extends Base_1.default {
|
|
|
53
54
|
this.organizationNumbers = props.organizationNumbers;
|
|
54
55
|
}
|
|
55
56
|
this.returnPolicy = (props === null || props === void 0 ? void 0 : props.returnPolicy) || '';
|
|
57
|
+
if ((props === null || props === void 0 ? void 0 : props.managedReturnPolicyDefault) && typeof props.managedReturnPolicyDefault === 'object') {
|
|
58
|
+
this.managedReturnPolicyDefault = props.managedReturnPolicyDefault;
|
|
59
|
+
}
|
|
56
60
|
this.subscriptionStatus = (props === null || props === void 0 ? void 0 : props.subscriptionStatus) || merchant_constants_1.SUBSCRIPTION_STATUSES.trialing;
|
|
57
61
|
this.hasActiveWebshop = (props === null || props === void 0 ? void 0 : props.hasActiveWebshop) || false;
|
|
58
62
|
this.accountMode = (props === null || props === void 0 ? void 0 : props.accountMode) || Merchant.MERCHANT_ACCOUNT_MODES.standalone;
|
|
@@ -167,6 +171,16 @@ class Merchant extends Base_1.default {
|
|
|
167
171
|
layout,
|
|
168
172
|
};
|
|
169
173
|
}
|
|
174
|
+
// This merchant's own return policy, parsed/normalized (null when unset or a
|
|
175
|
+
// legacy free-text string). See ReturnPolicyHelpers for the resolution rules.
|
|
176
|
+
getReturnPolicy() {
|
|
177
|
+
return ReturnPolicyHelpers_1.default.parse(this.returnPolicy);
|
|
178
|
+
}
|
|
179
|
+
// The marketplace-wide default this merchant (as a marketplace/parent) applies
|
|
180
|
+
// to its managed merchants, parsed/normalized (null when unset).
|
|
181
|
+
getManagedReturnPolicyDefault() {
|
|
182
|
+
return ReturnPolicyHelpers_1.default.parse(this.managedReturnPolicyDefault);
|
|
183
|
+
}
|
|
170
184
|
toObj() {
|
|
171
185
|
const mObj = {
|
|
172
186
|
name: this.name,
|
|
@@ -209,6 +223,9 @@ class Merchant extends Base_1.default {
|
|
|
209
223
|
if (this.managedByMerchantId) {
|
|
210
224
|
mObj.managedByMerchantId = this.managedByMerchantId;
|
|
211
225
|
}
|
|
226
|
+
if (this.managedReturnPolicyDefault) {
|
|
227
|
+
mObj.managedReturnPolicyDefault = this.managedReturnPolicyDefault;
|
|
228
|
+
}
|
|
212
229
|
if (typeof this.canUpgradeToStandalone === 'boolean') {
|
|
213
230
|
mObj.canUpgradeToStandalone = this.canUpgradeToStandalone;
|
|
214
231
|
}
|
|
@@ -6,6 +6,14 @@ type SocialLinksType = {
|
|
|
6
6
|
pinterest: string;
|
|
7
7
|
tiktok: string;
|
|
8
8
|
};
|
|
9
|
+
type ReturnPolicyChannel = {
|
|
10
|
+
allowed: boolean;
|
|
11
|
+
returnPeriodDays: number;
|
|
12
|
+
};
|
|
13
|
+
type ReturnPolicy = {
|
|
14
|
+
IN_STORE: ReturnPolicyChannel;
|
|
15
|
+
ONLINE: ReturnPolicyChannel;
|
|
16
|
+
};
|
|
9
17
|
type MerchantMutableData = {
|
|
10
18
|
name: string;
|
|
11
19
|
type: MerchantTypes | string;
|
|
@@ -30,7 +38,8 @@ type MerchantMutableData = {
|
|
|
30
38
|
featureAccess?: MerchantFeatureAccess | null;
|
|
31
39
|
organizationNumber?: string;
|
|
32
40
|
organizationNumbers?: Record<string, string>;
|
|
33
|
-
returnPolicy?: string;
|
|
41
|
+
returnPolicy?: ReturnPolicy | string;
|
|
42
|
+
managedReturnPolicyDefault?: ReturnPolicy;
|
|
34
43
|
};
|
|
35
44
|
type MerchantSystemOnlyMutableData = {
|
|
36
45
|
paymentTier: RibbnPaymentTiers | string;
|
|
@@ -129,7 +138,6 @@ type MerchantFormFields = {
|
|
|
129
138
|
legalName: TextInputFormField<string>;
|
|
130
139
|
organizationNumber: TextInputFormField<string>;
|
|
131
140
|
organizationNumbers: SingleSelectFormField<Record<string, string>>;
|
|
132
|
-
returnPolicy: TextInputFormField<string>;
|
|
133
141
|
phone: TextInputFormField<string>;
|
|
134
142
|
address: SingleSelectFormField<AddressInput>;
|
|
135
143
|
currency: SingleSelectFormField<string>;
|