rerobe-js-orm 4.9.10 → 4.9.11
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/helpers/FiscalHelpers.d.ts +11 -0
- package/lib/helpers/FiscalHelpers.js +42 -0
- package/lib/helpers/OrderHelpers.d.ts +7 -0
- package/lib/helpers/OrderHelpers.js +24 -10
- package/lib/helpers/marketplace/MarketplaceReceiptHelpers.d.ts +125 -0
- package/lib/helpers/marketplace/MarketplaceReceiptHelpers.js +351 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.js +6 -2
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Country-fiscal validators. Pure + framework-agnostic so backend (srv4pos
|
|
3
|
+
* activation), web (activation UI), and onboarding all share one source.
|
|
4
|
+
*
|
|
5
|
+
* A Swedish organisationsnummer (and personnummer) is 10 digits whose last digit
|
|
6
|
+
* is a Luhn check digit; Skatteverket / srv4pos reject any corporateId that
|
|
7
|
+
* fails it (SHOULD_MATCH_CORPORATE_ID_VALIDATION_LUHN).
|
|
8
|
+
*/
|
|
9
|
+
export declare function passesLuhn(value: string | number): boolean;
|
|
10
|
+
export declare function normalizeSwedishOrgNumber(value: string | number | null | undefined): string;
|
|
11
|
+
export declare function isValidSwedishOrgNumber(value: string | number | null | undefined): boolean;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Country-fiscal validators. Pure + framework-agnostic so backend (srv4pos
|
|
4
|
+
* activation), web (activation UI), and onboarding all share one source.
|
|
5
|
+
*
|
|
6
|
+
* A Swedish organisationsnummer (and personnummer) is 10 digits whose last digit
|
|
7
|
+
* is a Luhn check digit; Skatteverket / srv4pos reject any corporateId that
|
|
8
|
+
* fails it (SHOULD_MATCH_CORPORATE_ID_VALIDATION_LUHN).
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.passesLuhn = passesLuhn;
|
|
12
|
+
exports.normalizeSwedishOrgNumber = normalizeSwedishOrgNumber;
|
|
13
|
+
exports.isValidSwedishOrgNumber = isValidSwedishOrgNumber;
|
|
14
|
+
// Standard Luhn checksum over a string of digits.
|
|
15
|
+
function passesLuhn(value) {
|
|
16
|
+
const digits = String(value);
|
|
17
|
+
if (!/^\d+$/.test(digits))
|
|
18
|
+
return false;
|
|
19
|
+
let sum = 0;
|
|
20
|
+
let alternate = false;
|
|
21
|
+
for (let i = digits.length - 1; i >= 0; i -= 1) {
|
|
22
|
+
let n = Number(digits[i]);
|
|
23
|
+
if (alternate) {
|
|
24
|
+
n *= 2;
|
|
25
|
+
if (n > 9)
|
|
26
|
+
n -= 9;
|
|
27
|
+
}
|
|
28
|
+
sum += n;
|
|
29
|
+
alternate = !alternate;
|
|
30
|
+
}
|
|
31
|
+
return sum % 10 === 0;
|
|
32
|
+
}
|
|
33
|
+
// Strip non-digits to the 10-digit form srv4pos/Stripe expect (no hyphen).
|
|
34
|
+
function normalizeSwedishOrgNumber(value) {
|
|
35
|
+
return String(value !== null && value !== void 0 ? value : '').replace(/\D/g, '');
|
|
36
|
+
}
|
|
37
|
+
// True when `value` is a valid Swedish organisationsnummer: exactly 10 digits
|
|
38
|
+
// (hyphens/spaces ignored) satisfying the Luhn checksum.
|
|
39
|
+
function isValidSwedishOrgNumber(value) {
|
|
40
|
+
const digits = normalizeSwedishOrgNumber(value);
|
|
41
|
+
return /^\d{10}$/.test(digits) && passesLuhn(digits);
|
|
42
|
+
}
|
|
@@ -7,6 +7,13 @@ export default class OrderHelpers {
|
|
|
7
7
|
getSalesChannelUsingTags(tags: string | null | undefined): string | null;
|
|
8
8
|
buildLineItemFromProduct(product: CompleteProduct, currencyCode: string, quantity?: number, taxProps?: RibbnTaxProps, marketplace?: MarketplaceLineSnapshot): ReRobeOrderLineItem;
|
|
9
9
|
toFixedPointPrice(price: number | string): string;
|
|
10
|
+
static getReturnedLineAmounts(refundLineItem: any, { presentment }?: {
|
|
11
|
+
presentment?: boolean;
|
|
12
|
+
}): {
|
|
13
|
+
quantity: number;
|
|
14
|
+
net: number;
|
|
15
|
+
currencyCode: string;
|
|
16
|
+
};
|
|
10
17
|
getAmountSumByField(array: OrderRefund[] | ReRobeOrderLineItem[], fieldKey: string): number;
|
|
11
18
|
getOrderInfoWithRefundsAndFulfillments(order: CompleteOrder): OrderWithRefundsAndFulfillmentsInfoObj;
|
|
12
19
|
getUpdatedOrderObjWithRefunds(orderObj: CompleteOrder, refundObj: OrderRefund): CompleteOrder;
|
|
@@ -138,6 +138,25 @@ class OrderHelpers {
|
|
|
138
138
|
toFixedPointPrice(price) {
|
|
139
139
|
return Number(price).toFixed(2);
|
|
140
140
|
}
|
|
141
|
+
// Units + net amount returned for a stored RefundLineItem — refunded
|
|
142
|
+
// (fulfilled) + canceled (unfulfilled), since a cancellation of unfulfilled
|
|
143
|
+
// units still returns money. Net is taken from subtotalRefund + subtotalCanceled
|
|
144
|
+
// (the presentment variants when `presentment` is set), net of tax. The single
|
|
145
|
+
// source of truth for "how much of a line was returned" — used by the inline
|
|
146
|
+
// RETUR section here and the per-partner RETUR receipts (MarketplaceReceiptHelpers).
|
|
147
|
+
static getReturnedLineAmounts(refundLineItem, { presentment = false } = {}) {
|
|
148
|
+
const rli = refundLineItem || {};
|
|
149
|
+
const lineItem = rli.lineItem || {};
|
|
150
|
+
const quantity = Number(rli.quantityRefund || 0) + Number(rli.quantityCancel || 0);
|
|
151
|
+
const refundAmt = presentment ? rli.subtotalRefundPresentment : rli.subtotalRefund;
|
|
152
|
+
const cancelAmt = presentment ? rli.subtotalCanceledPresentment : rli.subtotalCanceled;
|
|
153
|
+
const net = Number((Number((refundAmt && refundAmt.amount) || 0) + Number((cancelAmt && cancelAmt.amount) || 0)).toFixed(2));
|
|
154
|
+
const currencyCode = (lineItem.originalTotalPrice && lineItem.originalTotalPrice.currencyCode) ||
|
|
155
|
+
(refundAmt && refundAmt.currencyCode) ||
|
|
156
|
+
(cancelAmt && cancelAmt.currencyCode) ||
|
|
157
|
+
'SEK';
|
|
158
|
+
return { quantity, net, currencyCode };
|
|
159
|
+
}
|
|
141
160
|
getAmountSumByField(array, fieldKey) {
|
|
142
161
|
return array.map((item) => { var _a; return Number(((_a = item[fieldKey]) === null || _a === void 0 ? void 0 : _a.amount) || 0); }).reduce((a, b) => a + b, 0);
|
|
143
162
|
}
|
|
@@ -742,17 +761,12 @@ class OrderHelpers {
|
|
|
742
761
|
fractionDigits: 2,
|
|
743
762
|
}),
|
|
744
763
|
refundLineItems: (order.refunds || []).flatMap((refund) => (refund.refundLineItems || []).map((item) => {
|
|
745
|
-
|
|
746
|
-
//
|
|
747
|
-
// quantityCancel, subtotalRefund(Presentment), subtotalCanceled(
|
|
748
|
-
// Presentment) } — the title/amount live on `lineItem`, not flat on
|
|
749
|
-
// the item. Returned units = refunded + canceled (a cancellation of
|
|
750
|
-
// unfulfilled units still returns money). The subtotals are net of
|
|
751
|
-
// tax (originalUnitPrice basis), so gross them up for the receipt.
|
|
764
|
+
// Returned units + net come from the canonical helper (refunded +
|
|
765
|
+
// canceled; subtotals are net of tax, so gross them up here).
|
|
752
766
|
const lineItem = item.lineItem || {};
|
|
753
|
-
const quantity =
|
|
754
|
-
|
|
755
|
-
|
|
767
|
+
const { quantity, net } = OrderHelpers.getReturnedLineAmounts(item, {
|
|
768
|
+
presentment: true,
|
|
769
|
+
});
|
|
756
770
|
const taxRate = Number(lineItem.taxRate || 0);
|
|
757
771
|
const gross = lineItem.isTaxable && taxRate ? net * (1 + taxRate) : net;
|
|
758
772
|
return {
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-partner fiscal receipt logic for the managed marketplace: split a
|
|
3
|
+
* mixed-partner order into per-seller (per-company) groups, resolve which
|
|
4
|
+
* company's Control Unit signs each receipt (active seller vs channel-partner
|
|
5
|
+
* backup), and build the per-seller order views + receipt-log descriptors —
|
|
6
|
+
* including RETUR (refund) receipts.
|
|
7
|
+
*
|
|
8
|
+
* Pure + framework-agnostic (no Firebase / Express): the backend order-completion
|
|
9
|
+
* wiring and the admin receipt simulator both consume these, and the live fiscal
|
|
10
|
+
* recording maps each seller subset to the CU that records it.
|
|
11
|
+
*/
|
|
12
|
+
export declare function toOre(amount: string | number | null | undefined): number;
|
|
13
|
+
export declare function lineItemGrossOre(lineItem: any): number;
|
|
14
|
+
export declare function lineItemsGrossOre(lineItems: any[]): number;
|
|
15
|
+
export declare function oreToSekString(ore: number): string;
|
|
16
|
+
export declare function resolveLineSellerId(lineItem: any, channelPartnerMerchantId: string): string;
|
|
17
|
+
export type SellerGroup = {
|
|
18
|
+
sellerMerchantId: string;
|
|
19
|
+
isChannelPartnerOwn: boolean;
|
|
20
|
+
lineItems: any[];
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Group an order's line items by the seller (company) responsible for them.
|
|
24
|
+
* One group per distinct seller, in first-seen order.
|
|
25
|
+
*/
|
|
26
|
+
export declare function groupOrderLineItemsBySeller(order: any): SellerGroup[];
|
|
27
|
+
/**
|
|
28
|
+
* Build a receipt line for a single refunded item, from a stored refund line
|
|
29
|
+
* item (`order.refunds[].refundLineItems[]`). Reuses the original line item so
|
|
30
|
+
* the title, variant label, tax rate, and marketplace attribution are preserved,
|
|
31
|
+
* and narrows the amount + quantity to the RETURNED portion (refunded + canceled,
|
|
32
|
+
* via OrderHelpers.getReturnedLineAmounts). The stale display `price` is dropped
|
|
33
|
+
* so ReceiptBuilder recomputes a consistent, negated amount.
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildRefundLineItemView(refundLineItem: any): any;
|
|
36
|
+
export type RefundSellerGroup = {
|
|
37
|
+
sellerMerchantId: string;
|
|
38
|
+
isChannelPartnerOwn: boolean;
|
|
39
|
+
refundIndex: number;
|
|
40
|
+
refundLineItems: any[];
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Group an order's returned line items into per-seller groups, one set per refund
|
|
44
|
+
* EVENT — each refund is its own return transaction, so it yields its own RETUR
|
|
45
|
+
* receipt. A line is included when it returns any units (refunded OR canceled).
|
|
46
|
+
*/
|
|
47
|
+
export declare function groupRefundsBySeller(order: any): RefundSellerGroup[];
|
|
48
|
+
/**
|
|
49
|
+
* Number of receipts an order will produce — one per distinct seller group.
|
|
50
|
+
* Independent of compliance status, which only affects which CU signs each
|
|
51
|
+
* receipt, not how many there are.
|
|
52
|
+
*/
|
|
53
|
+
export declare function plannedReceiptCount(order: any): number;
|
|
54
|
+
export type FiscalEntity = {
|
|
55
|
+
fiscalMerchantId: string;
|
|
56
|
+
organizationNumber: string;
|
|
57
|
+
name: string;
|
|
58
|
+
isBackup: boolean;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Decide which company's fiscal credentials/identity sign a seller group's
|
|
62
|
+
* receipt: channel partner's own goods -> the CP; active marketplace seller ->
|
|
63
|
+
* the seller's own company; pending seller -> the CP, flagged as backup.
|
|
64
|
+
*/
|
|
65
|
+
export declare function resolveFiscalEntity({ group, channelPartner, seller, sellerComplianceActive, }: {
|
|
66
|
+
group: {
|
|
67
|
+
isChannelPartnerOwn: boolean;
|
|
68
|
+
};
|
|
69
|
+
channelPartner: any;
|
|
70
|
+
seller: any;
|
|
71
|
+
sellerComplianceActive: boolean;
|
|
72
|
+
}): FiscalEntity;
|
|
73
|
+
/**
|
|
74
|
+
* Build the order-shaped object that ReceiptBuilder / recordFiscalTransaction
|
|
75
|
+
* consume for a single seller group: the seller's line-item subset plus the
|
|
76
|
+
* SELLER's own identity. The receipt header always carries the seller's company
|
|
77
|
+
* (they are the legal seller of their goods) regardless of which CU signs it.
|
|
78
|
+
*/
|
|
79
|
+
export declare function buildSellerOrderView({ order, group, seller, fiscalEntity, channelPartner, }: {
|
|
80
|
+
order: any;
|
|
81
|
+
group: any;
|
|
82
|
+
seller: any;
|
|
83
|
+
fiscalEntity: FiscalEntity;
|
|
84
|
+
channelPartner?: any;
|
|
85
|
+
}): any;
|
|
86
|
+
/**
|
|
87
|
+
* Reconcile the per-seller split against the order's recorded total: the sum of
|
|
88
|
+
* every seller group's gross should equal order.totalPrice. A non-zero
|
|
89
|
+
* difference means money would be lost or double-counted in the split.
|
|
90
|
+
*/
|
|
91
|
+
export declare function reconcileReceiptTotals(order: any): {
|
|
92
|
+
orderTotalOre: number;
|
|
93
|
+
sellersTotalOre: number;
|
|
94
|
+
differenceOre: number;
|
|
95
|
+
balanced: boolean;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Compose the full per-partner receipt plan for an order: purchase receipts
|
|
99
|
+
* (one per seller group) + RETUR receipts (one per refund event per seller),
|
|
100
|
+
* plus the receipt count and reconciliation. Shared by the simulator (dry-run)
|
|
101
|
+
* and the live order-completion wiring.
|
|
102
|
+
*/
|
|
103
|
+
export declare function buildPerPartnerReceiptPlan({ order, channelPartner, sellersById, complianceBySeller, }: {
|
|
104
|
+
order: any;
|
|
105
|
+
channelPartner: any;
|
|
106
|
+
sellersById?: Record<string, any>;
|
|
107
|
+
complianceBySeller?: Record<string, boolean>;
|
|
108
|
+
}): any;
|
|
109
|
+
/**
|
|
110
|
+
* Map a per-partner receipt plan + fiscal results into the descriptors needed to
|
|
111
|
+
* write one receiptLog entry per seller. PURE — the live wiring builds the ESC/POS
|
|
112
|
+
* receiptData from `view` and persists.
|
|
113
|
+
*
|
|
114
|
+
* Control-code rule (Skatteverket): a receipt may only carry the kontrollkod of
|
|
115
|
+
* the Control Unit that actually signed it. Phase B records each seller subset
|
|
116
|
+
* under the CU responsible for it and passes the per-seller results in via
|
|
117
|
+
* `fiscalResultsBySeller` (keyed by sellerMerchantId -> {controlCode,
|
|
118
|
+
* receiptNumber, fiscalRecordId}). `cpFiscalResult` is the legacy/whole-order
|
|
119
|
+
* channel-partner result, used as a fallback for the CP's own goods.
|
|
120
|
+
*/
|
|
121
|
+
export declare function buildPerPartnerReceiptLogEntries({ plan, cpFiscalResult, fiscalResultsBySeller, }?: {
|
|
122
|
+
plan?: any;
|
|
123
|
+
cpFiscalResult?: any;
|
|
124
|
+
fiscalResultsBySeller?: Record<string, any>;
|
|
125
|
+
}): any[];
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Per-partner fiscal receipt logic for the managed marketplace: split a
|
|
4
|
+
* mixed-partner order into per-seller (per-company) groups, resolve which
|
|
5
|
+
* company's Control Unit signs each receipt (active seller vs channel-partner
|
|
6
|
+
* backup), and build the per-seller order views + receipt-log descriptors —
|
|
7
|
+
* including RETUR (refund) receipts.
|
|
8
|
+
*
|
|
9
|
+
* Pure + framework-agnostic (no Firebase / Express): the backend order-completion
|
|
10
|
+
* wiring and the admin receipt simulator both consume these, and the live fiscal
|
|
11
|
+
* recording maps each seller subset to the CU that records it.
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.toOre = toOre;
|
|
15
|
+
exports.lineItemGrossOre = lineItemGrossOre;
|
|
16
|
+
exports.lineItemsGrossOre = lineItemsGrossOre;
|
|
17
|
+
exports.oreToSekString = oreToSekString;
|
|
18
|
+
exports.resolveLineSellerId = resolveLineSellerId;
|
|
19
|
+
exports.groupOrderLineItemsBySeller = groupOrderLineItemsBySeller;
|
|
20
|
+
exports.buildRefundLineItemView = buildRefundLineItemView;
|
|
21
|
+
exports.groupRefundsBySeller = groupRefundsBySeller;
|
|
22
|
+
exports.plannedReceiptCount = plannedReceiptCount;
|
|
23
|
+
exports.resolveFiscalEntity = resolveFiscalEntity;
|
|
24
|
+
exports.buildSellerOrderView = buildSellerOrderView;
|
|
25
|
+
exports.reconcileReceiptTotals = reconcileReceiptTotals;
|
|
26
|
+
exports.buildPerPartnerReceiptPlan = buildPerPartnerReceiptPlan;
|
|
27
|
+
exports.buildPerPartnerReceiptLogEntries = buildPerPartnerReceiptLogEntries;
|
|
28
|
+
const OrderHelpers_1 = require("../OrderHelpers");
|
|
29
|
+
// --- Money helpers. Amounts are SEK; öre = round(SEK * 100). ---
|
|
30
|
+
// SEK amount (string like "80.00" or number) -> integer öre.
|
|
31
|
+
function toOre(amount) {
|
|
32
|
+
if (amount === null || amount === undefined)
|
|
33
|
+
return 0;
|
|
34
|
+
const numAmount = typeof amount === 'string' ? parseFloat(amount) : Number(amount);
|
|
35
|
+
if (Number.isNaN(numAmount))
|
|
36
|
+
return 0;
|
|
37
|
+
return Math.round(numAmount * 100);
|
|
38
|
+
}
|
|
39
|
+
// Per-line gross total in öre = net * (1 + taxRate), matching ReceiptBuilder.
|
|
40
|
+
function lineItemGrossOre(lineItem) {
|
|
41
|
+
const netPrice = (lineItem && lineItem.originalTotalPrice && lineItem.originalTotalPrice.amount) || 0;
|
|
42
|
+
const taxRate = (lineItem && lineItem.taxRate) || 0;
|
|
43
|
+
return toOre(Math.abs(Number(netPrice) * (1 + Number(taxRate))));
|
|
44
|
+
}
|
|
45
|
+
// Sum of gross totals (öre) across a set of line items.
|
|
46
|
+
function lineItemsGrossOre(lineItems) {
|
|
47
|
+
return (lineItems || []).reduce((sum, lineItem) => sum + lineItemGrossOre(lineItem), 0);
|
|
48
|
+
}
|
|
49
|
+
// Integer öre -> SEK string with 2 decimals.
|
|
50
|
+
function oreToSekString(ore) {
|
|
51
|
+
return (ore / 100).toFixed(2);
|
|
52
|
+
}
|
|
53
|
+
// A line item belongs to a managed seller only when it is explicitly flagged as
|
|
54
|
+
// a marketplace item AND carries the seller's merchant id. Anything else (the
|
|
55
|
+
// channel partner's own goods, or malformed marketplace metadata) is attributed
|
|
56
|
+
// to the channel partner that owns the order.
|
|
57
|
+
function resolveLineSellerId(lineItem, channelPartnerMerchantId) {
|
|
58
|
+
const marketplace = lineItem && lineItem.marketplace;
|
|
59
|
+
if (marketplace && marketplace.isMarketplaceItem === true && marketplace.managedMerchantId) {
|
|
60
|
+
return marketplace.managedMerchantId;
|
|
61
|
+
}
|
|
62
|
+
return channelPartnerMerchantId;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Group an order's line items by the seller (company) responsible for them.
|
|
66
|
+
* One group per distinct seller, in first-seen order.
|
|
67
|
+
*/
|
|
68
|
+
function groupOrderLineItemsBySeller(order) {
|
|
69
|
+
const channelPartnerMerchantId = order && order.merchantId;
|
|
70
|
+
const lineItems = (order && order.lineItems) || [];
|
|
71
|
+
const groupsBySeller = new Map();
|
|
72
|
+
lineItems.forEach((lineItem) => {
|
|
73
|
+
const sellerMerchantId = resolveLineSellerId(lineItem, channelPartnerMerchantId);
|
|
74
|
+
if (!groupsBySeller.has(sellerMerchantId)) {
|
|
75
|
+
groupsBySeller.set(sellerMerchantId, {
|
|
76
|
+
sellerMerchantId,
|
|
77
|
+
isChannelPartnerOwn: sellerMerchantId === channelPartnerMerchantId,
|
|
78
|
+
lineItems: [],
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
groupsBySeller.get(sellerMerchantId).lineItems.push(lineItem);
|
|
82
|
+
});
|
|
83
|
+
return Array.from(groupsBySeller.values());
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Build a receipt line for a single refunded item, from a stored refund line
|
|
87
|
+
* item (`order.refunds[].refundLineItems[]`). Reuses the original line item so
|
|
88
|
+
* the title, variant label, tax rate, and marketplace attribution are preserved,
|
|
89
|
+
* and narrows the amount + quantity to the RETURNED portion (refunded + canceled,
|
|
90
|
+
* via OrderHelpers.getReturnedLineAmounts). The stale display `price` is dropped
|
|
91
|
+
* so ReceiptBuilder recomputes a consistent, negated amount.
|
|
92
|
+
*/
|
|
93
|
+
function buildRefundLineItemView(refundLineItem) {
|
|
94
|
+
const lineItem = (refundLineItem && refundLineItem.lineItem) || {};
|
|
95
|
+
const { quantity, net, currencyCode } = OrderHelpers_1.default.getReturnedLineAmounts(refundLineItem);
|
|
96
|
+
const taxRate = Number(lineItem.taxRate || 0);
|
|
97
|
+
const view = Object.assign(Object.assign({}, lineItem), { quantity, originalTotalPrice: Object.assign(Object.assign({}, lineItem.originalTotalPrice), { amount: net, currencyCode }),
|
|
98
|
+
// Prorated to the returned quantity so the RETUR VAT line is correct even on
|
|
99
|
+
// a partial return (the original line's tax covers the full quantity).
|
|
100
|
+
taxAmountWithDiscount: {
|
|
101
|
+
amount: Number((net * taxRate).toFixed(2)),
|
|
102
|
+
currencyCode,
|
|
103
|
+
} });
|
|
104
|
+
// Let ReceiptBuilder recompute the (negated) display price.
|
|
105
|
+
delete view.price;
|
|
106
|
+
return view;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Group an order's returned line items into per-seller groups, one set per refund
|
|
110
|
+
* EVENT — each refund is its own return transaction, so it yields its own RETUR
|
|
111
|
+
* receipt. A line is included when it returns any units (refunded OR canceled).
|
|
112
|
+
*/
|
|
113
|
+
function groupRefundsBySeller(order) {
|
|
114
|
+
const channelPartnerMerchantId = order && order.merchantId;
|
|
115
|
+
const refunds = (order && order.refunds) || [];
|
|
116
|
+
const groups = [];
|
|
117
|
+
refunds.forEach((refund, refundIndex) => {
|
|
118
|
+
const bySeller = new Map();
|
|
119
|
+
const refundLineItems = (refund && refund.refundLineItems) || [];
|
|
120
|
+
refundLineItems.forEach((refundLineItem) => {
|
|
121
|
+
if (!refundLineItem) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const quantityReturned = Number(refundLineItem.quantityRefund || 0) + Number(refundLineItem.quantityCancel || 0);
|
|
125
|
+
if (quantityReturned <= 0) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const sellerMerchantId = resolveLineSellerId(refundLineItem.lineItem, channelPartnerMerchantId);
|
|
129
|
+
if (!bySeller.has(sellerMerchantId)) {
|
|
130
|
+
bySeller.set(sellerMerchantId, {
|
|
131
|
+
sellerMerchantId,
|
|
132
|
+
isChannelPartnerOwn: sellerMerchantId === channelPartnerMerchantId,
|
|
133
|
+
refundIndex,
|
|
134
|
+
refundLineItems: [],
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
bySeller.get(sellerMerchantId).refundLineItems.push(refundLineItem);
|
|
138
|
+
});
|
|
139
|
+
groups.push(...Array.from(bySeller.values()));
|
|
140
|
+
});
|
|
141
|
+
return groups;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Number of receipts an order will produce — one per distinct seller group.
|
|
145
|
+
* Independent of compliance status, which only affects which CU signs each
|
|
146
|
+
* receipt, not how many there are.
|
|
147
|
+
*/
|
|
148
|
+
function plannedReceiptCount(order) {
|
|
149
|
+
return groupOrderLineItemsBySeller(order).length;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Decide which company's fiscal credentials/identity sign a seller group's
|
|
153
|
+
* receipt: channel partner's own goods -> the CP; active marketplace seller ->
|
|
154
|
+
* the seller's own company; pending seller -> the CP, flagged as backup.
|
|
155
|
+
*/
|
|
156
|
+
function resolveFiscalEntity({ group, channelPartner, seller, sellerComplianceActive, }) {
|
|
157
|
+
const useSellerOwn = !group.isChannelPartnerOwn && sellerComplianceActive;
|
|
158
|
+
const entity = useSellerOwn ? seller : channelPartner;
|
|
159
|
+
return {
|
|
160
|
+
fiscalMerchantId: entity.documentId,
|
|
161
|
+
organizationNumber: entity.organizationNumber,
|
|
162
|
+
name: entity.name,
|
|
163
|
+
isBackup: !group.isChannelPartnerOwn && !sellerComplianceActive,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Build the order-shaped object that ReceiptBuilder / recordFiscalTransaction
|
|
168
|
+
* consume for a single seller group: the seller's line-item subset plus the
|
|
169
|
+
* SELLER's own identity. The receipt header always carries the seller's company
|
|
170
|
+
* (they are the legal seller of their goods) regardless of which CU signs it.
|
|
171
|
+
*/
|
|
172
|
+
function buildSellerOrderView({ order, group, seller, fiscalEntity, channelPartner, }) {
|
|
173
|
+
const grossOre = lineItemsGrossOre(group.lineItems);
|
|
174
|
+
const currencyCode = (group.lineItems &&
|
|
175
|
+
group.lineItems[0] &&
|
|
176
|
+
group.lineItems[0].originalTotalPrice &&
|
|
177
|
+
group.lineItems[0].originalTotalPrice.currencyCode) ||
|
|
178
|
+
(order.totalPrice && order.totalPrice.currencyCode) ||
|
|
179
|
+
'SEK';
|
|
180
|
+
const sellerName = (seller && seller.name) || '';
|
|
181
|
+
const sellerOrganizationNumber = (seller && seller.organizationNumber) || '';
|
|
182
|
+
// Return policy governing this receipt: the channel partner's own goods follow
|
|
183
|
+
// the partner's own policy; managed sellers' goods follow the marketplace-wide
|
|
184
|
+
// managed default, falling back to the seller's own.
|
|
185
|
+
const returnPolicy = group.isChannelPartnerOwn
|
|
186
|
+
? channelPartner && channelPartner.returnPolicy
|
|
187
|
+
: (channelPartner && channelPartner.managedReturnPolicyDefault) || (seller && seller.returnPolicy);
|
|
188
|
+
return Object.assign(Object.assign({}, order), { orderId: order.documentId || order.id, orderNumber: order.orderNumber, lineItems: group.lineItems,
|
|
189
|
+
// Per-seller brutto from the seller's OWN line items — never the whole
|
|
190
|
+
// order's totalPrice.
|
|
191
|
+
totalPrice: { amount: oreToSekString(grossOre), currencyCode }, merchantName: sellerName, organizationNumber: sellerOrganizationNumber, sellerMerchantId: group.sellerMerchantId, sellerDisplayName: sellerName, isFiscalBackup: fiscalEntity.isBackup, returnPolicy });
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Reconcile the per-seller split against the order's recorded total: the sum of
|
|
195
|
+
* every seller group's gross should equal order.totalPrice. A non-zero
|
|
196
|
+
* difference means money would be lost or double-counted in the split.
|
|
197
|
+
*/
|
|
198
|
+
function reconcileReceiptTotals(order) {
|
|
199
|
+
const groups = groupOrderLineItemsBySeller(order);
|
|
200
|
+
const sellersTotalOre = groups.reduce((sum, group) => sum + lineItemsGrossOre(group.lineItems), 0);
|
|
201
|
+
const orderTotalOre = toOre(order && order.totalPrice && order.totalPrice.amount);
|
|
202
|
+
return {
|
|
203
|
+
orderTotalOre,
|
|
204
|
+
sellersTotalOre,
|
|
205
|
+
differenceOre: orderTotalOre - sellersTotalOre,
|
|
206
|
+
balanced: orderTotalOre === sellersTotalOre,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
// Resolve the seller identity, compliance status, and signing fiscal entity for
|
|
210
|
+
// a single seller group — shared by purchase and refund receipts.
|
|
211
|
+
function resolveReceiptParties({ group, channelPartner, sellersById, complianceBySeller, }) {
|
|
212
|
+
const seller = group.isChannelPartnerOwn
|
|
213
|
+
? channelPartner
|
|
214
|
+
: sellersById[group.sellerMerchantId] || {
|
|
215
|
+
documentId: group.sellerMerchantId,
|
|
216
|
+
organizationNumber: '',
|
|
217
|
+
name: '',
|
|
218
|
+
};
|
|
219
|
+
const sellerComplianceActive = group.isChannelPartnerOwn
|
|
220
|
+
? false
|
|
221
|
+
: Boolean(complianceBySeller[group.sellerMerchantId]);
|
|
222
|
+
const fiscalEntity = resolveFiscalEntity({
|
|
223
|
+
group,
|
|
224
|
+
channelPartner,
|
|
225
|
+
seller,
|
|
226
|
+
sellerComplianceActive,
|
|
227
|
+
});
|
|
228
|
+
return { seller, fiscalEntity, sellerDisplayName: seller.name || '' };
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Compose the full per-partner receipt plan for an order: purchase receipts
|
|
232
|
+
* (one per seller group) + RETUR receipts (one per refund event per seller),
|
|
233
|
+
* plus the receipt count and reconciliation. Shared by the simulator (dry-run)
|
|
234
|
+
* and the live order-completion wiring.
|
|
235
|
+
*/
|
|
236
|
+
function buildPerPartnerReceiptPlan({ order, channelPartner, sellersById = {}, complianceBySeller = {}, }) {
|
|
237
|
+
const groups = groupOrderLineItemsBySeller(order);
|
|
238
|
+
const receipts = groups.map((group) => {
|
|
239
|
+
const { seller, fiscalEntity, sellerDisplayName } = resolveReceiptParties({
|
|
240
|
+
group,
|
|
241
|
+
channelPartner,
|
|
242
|
+
sellersById,
|
|
243
|
+
complianceBySeller,
|
|
244
|
+
});
|
|
245
|
+
const view = buildSellerOrderView({
|
|
246
|
+
order,
|
|
247
|
+
group,
|
|
248
|
+
seller,
|
|
249
|
+
fiscalEntity,
|
|
250
|
+
channelPartner,
|
|
251
|
+
});
|
|
252
|
+
return {
|
|
253
|
+
sellerMerchantId: group.sellerMerchantId,
|
|
254
|
+
isChannelPartnerOwn: group.isChannelPartnerOwn,
|
|
255
|
+
sellerDisplayName,
|
|
256
|
+
totalOre: lineItemsGrossOre(group.lineItems),
|
|
257
|
+
fiscalEntity,
|
|
258
|
+
// Control code only when the seller's OWN Control Unit signs it (their own
|
|
259
|
+
// goods, or an srv4pos-active partner). Pending partners are backed by the
|
|
260
|
+
// channel partner's CU.
|
|
261
|
+
showControlCode: !fiscalEntity.isBackup,
|
|
262
|
+
view,
|
|
263
|
+
};
|
|
264
|
+
});
|
|
265
|
+
// RETUR receipts for any refunded line items — one per refund event per seller,
|
|
266
|
+
// mirroring the validated single-merchant refund receipt (RETURKVITTO). Same
|
|
267
|
+
// fiscal split as purchase: active seller carries its own kontrollkod; pending
|
|
268
|
+
// is backed by the channel partner's CU.
|
|
269
|
+
const refundGroups = groupRefundsBySeller(order);
|
|
270
|
+
const refundReceipts = refundGroups.map((group) => {
|
|
271
|
+
const { seller, fiscalEntity, sellerDisplayName } = resolveReceiptParties({
|
|
272
|
+
group,
|
|
273
|
+
channelPartner,
|
|
274
|
+
sellersById,
|
|
275
|
+
complianceBySeller,
|
|
276
|
+
});
|
|
277
|
+
const refundLineItemViews = group.refundLineItems.map(buildRefundLineItemView);
|
|
278
|
+
const lineGroup = {
|
|
279
|
+
sellerMerchantId: group.sellerMerchantId,
|
|
280
|
+
isChannelPartnerOwn: group.isChannelPartnerOwn,
|
|
281
|
+
lineItems: refundLineItemViews,
|
|
282
|
+
};
|
|
283
|
+
const view = Object.assign(Object.assign({}, buildSellerOrderView({
|
|
284
|
+
order,
|
|
285
|
+
group: lineGroup,
|
|
286
|
+
seller,
|
|
287
|
+
fiscalEntity,
|
|
288
|
+
channelPartner,
|
|
289
|
+
})), {
|
|
290
|
+
// Drives RETURKVITTO / RETUR labels + negative amounts in ReceiptBuilder.
|
|
291
|
+
isRefund: true });
|
|
292
|
+
return {
|
|
293
|
+
kind: 'refund',
|
|
294
|
+
sellerMerchantId: group.sellerMerchantId,
|
|
295
|
+
isChannelPartnerOwn: group.isChannelPartnerOwn,
|
|
296
|
+
sellerDisplayName,
|
|
297
|
+
totalOre: lineItemsGrossOre(refundLineItemViews),
|
|
298
|
+
fiscalEntity,
|
|
299
|
+
showControlCode: !fiscalEntity.isBackup,
|
|
300
|
+
view,
|
|
301
|
+
};
|
|
302
|
+
});
|
|
303
|
+
return {
|
|
304
|
+
receiptCount: groups.length,
|
|
305
|
+
reconciliation: reconcileReceiptTotals(order),
|
|
306
|
+
receipts,
|
|
307
|
+
refundReceiptCount: refundReceipts.length,
|
|
308
|
+
refundReceipts,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Map a per-partner receipt plan + fiscal results into the descriptors needed to
|
|
313
|
+
* write one receiptLog entry per seller. PURE — the live wiring builds the ESC/POS
|
|
314
|
+
* receiptData from `view` and persists.
|
|
315
|
+
*
|
|
316
|
+
* Control-code rule (Skatteverket): a receipt may only carry the kontrollkod of
|
|
317
|
+
* the Control Unit that actually signed it. Phase B records each seller subset
|
|
318
|
+
* under the CU responsible for it and passes the per-seller results in via
|
|
319
|
+
* `fiscalResultsBySeller` (keyed by sellerMerchantId -> {controlCode,
|
|
320
|
+
* receiptNumber, fiscalRecordId}). `cpFiscalResult` is the legacy/whole-order
|
|
321
|
+
* channel-partner result, used as a fallback for the CP's own goods.
|
|
322
|
+
*/
|
|
323
|
+
function buildPerPartnerReceiptLogEntries({ plan, cpFiscalResult = null, fiscalResultsBySeller = {}, } = {}) {
|
|
324
|
+
if (!plan || !Array.isArray(plan.receipts))
|
|
325
|
+
return [];
|
|
326
|
+
const cpControlCode = cpFiscalResult && cpFiscalResult.controlCode ? cpFiscalResult.controlCode : null;
|
|
327
|
+
const bySeller = fiscalResultsBySeller && typeof fiscalResultsBySeller === 'object' ? fiscalResultsBySeller : {};
|
|
328
|
+
return plan.receipts.map((receipt) => {
|
|
329
|
+
const isFiscalBackup = Boolean(receipt.fiscalEntity && receipt.fiscalEntity.isBackup);
|
|
330
|
+
// Prefer the result of the CU that actually recorded THIS seller's subset.
|
|
331
|
+
const perSeller = bySeller[receipt.sellerMerchantId] || null;
|
|
332
|
+
let controlCode = perSeller && perSeller.controlCode ? perSeller.controlCode : null;
|
|
333
|
+
// Fall back to the CP whole-order result only for the CP's own goods.
|
|
334
|
+
if (!controlCode && receipt.isChannelPartnerOwn) {
|
|
335
|
+
controlCode = cpControlCode;
|
|
336
|
+
}
|
|
337
|
+
const receiptNumber = perSeller && perSeller.receiptNumber !== undefined ? perSeller.receiptNumber : null;
|
|
338
|
+
return {
|
|
339
|
+
sellerMerchantId: receipt.sellerMerchantId,
|
|
340
|
+
isChannelPartnerOwn: receipt.isChannelPartnerOwn,
|
|
341
|
+
isFiscalBackup,
|
|
342
|
+
sellerDisplayName: receipt.sellerDisplayName,
|
|
343
|
+
showControlCode: receipt.showControlCode,
|
|
344
|
+
controlCode,
|
|
345
|
+
receiptNumber,
|
|
346
|
+
fiscalRecordId: perSeller && perSeller.fiscalRecordId ? perSeller.fiscalRecordId : null,
|
|
347
|
+
totalOre: receipt.totalOre,
|
|
348
|
+
view: receipt.view,
|
|
349
|
+
};
|
|
350
|
+
});
|
|
351
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -47,6 +47,8 @@ import * as MarketplaceLedgerHelpers from './helpers/marketplace/MarketplaceLedg
|
|
|
47
47
|
import * as MarketplaceLegacyAdapters from './helpers/marketplace/MarketplaceLegacyAdapters';
|
|
48
48
|
import * as MarketplaceLineDisplayHelpers from './helpers/marketplace/MarketplaceLineDisplayHelpers';
|
|
49
49
|
import * as MarketplaceOrderHelpers from './helpers/marketplace/MarketplaceOrderHelpers';
|
|
50
|
+
import * as MarketplaceReceiptHelpers from './helpers/marketplace/MarketplaceReceiptHelpers';
|
|
51
|
+
import * as FiscalHelpers from './helpers/FiscalHelpers';
|
|
50
52
|
import TaxHelpers from './helpers/TaxHelpers';
|
|
51
53
|
import PricingHelpers from './helpers/PricingHelpers';
|
|
52
54
|
import ProductSkuHelpers, { DEFAULT_SKU_LENGTH, SKU_ALPHABET } from './helpers/ProductSkuHelpers';
|
|
@@ -57,7 +59,7 @@ import ProductInventoryHelpers, { PLACEHOLDER_VARIANT_ID } from './helpers/Produ
|
|
|
57
59
|
import RetailProductFactory from './factories/Product/RetailProductFactory';
|
|
58
60
|
import { FALLBACK_TAX_COUNTRY_CODE, TAX_CATEGORIES, TAX_CATEGORY_ALIASES, TAX_CATEGORY_BASE_LABELS, TAX_CATEGORY_RATES } from './constants/tax-constants';
|
|
59
61
|
import { ADMIN_SIMPLIFIED_STATES, ADMIN_STATES, PRODUCT_CLASS_VALUES, PRODUCT_STATES, PRODUCT_STATE_LABELS, RETAIL_EDITABLE_PRODUCT_STATES, getProductStateLabel, getRetailEditableProductStateOptions } from './constants/product-constants';
|
|
60
|
-
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, ReceiptXmlHelpers, 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, };
|
|
62
|
+
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, MarketplaceReceiptHelpers, FiscalHelpers, 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, ReceiptXmlHelpers, 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, };
|
|
61
63
|
export type { PlaceholderVariantInput, PlaceholderVariantInventory, PlaceholderVariantLocation, } from './helpers/ProductInventoryHelpers';
|
|
62
64
|
export type { RetailOwnershipInput, RetailAccountingInput, RetailLocationInput, ClothingDetailsInput, NonClothingDetailsInput, OneOfAKindClothingInput, MultivariantClothingInput, TrackedRetailInput, UntrackedRetailInput, } from './factories/Product/RetailProductFactory';
|
|
63
65
|
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
|
-
exports.
|
|
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.ReceiptXmlHelpers = 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;
|
|
3
|
+
exports.MARKETPLACE_RELATIONSHIP_TYPES = exports.MARKETPLACE_COMMISSION_BASES = exports.MARKETPLACE_LISTING_STATUSES = exports.FiscalHelpers = exports.MarketplaceReceiptHelpers = 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.ReceiptXmlHelpers = 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 = exports.MARKETPLACE_FEE_ALLOCATION_BASES = exports.MARKETPLACE_FEE_TYPES = 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");
|
|
@@ -118,6 +118,10 @@ const MarketplaceLineDisplayHelpers = require("./helpers/marketplace/Marketplace
|
|
|
118
118
|
exports.MarketplaceLineDisplayHelpers = MarketplaceLineDisplayHelpers;
|
|
119
119
|
const MarketplaceOrderHelpers = require("./helpers/marketplace/MarketplaceOrderHelpers");
|
|
120
120
|
exports.MarketplaceOrderHelpers = MarketplaceOrderHelpers;
|
|
121
|
+
const MarketplaceReceiptHelpers = require("./helpers/marketplace/MarketplaceReceiptHelpers");
|
|
122
|
+
exports.MarketplaceReceiptHelpers = MarketplaceReceiptHelpers;
|
|
123
|
+
const FiscalHelpers = require("./helpers/FiscalHelpers");
|
|
124
|
+
exports.FiscalHelpers = FiscalHelpers;
|
|
121
125
|
const TaxHelpers_1 = require("./helpers/TaxHelpers");
|
|
122
126
|
exports.TaxHelpers = TaxHelpers_1.default;
|
|
123
127
|
const PricingHelpers_1 = require("./helpers/PricingHelpers");
|