rerobe-js-orm 4.7.1 → 4.7.3
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/constants/order-constants.d.ts +2 -0
- package/lib/constants/order-constants.js +2 -0
- package/lib/factories/Order/OrderFromTraderaEmail.d.ts +9 -0
- package/lib/factories/Order/OrderFromTraderaEmail.js +143 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.js +3 -1
- package/lib/models/Order.d.ts +2 -0
- package/package.json +1 -1
|
@@ -11,6 +11,7 @@ export namespace PAYMENT_TYPES {
|
|
|
11
11
|
let cash: string;
|
|
12
12
|
let mobilePayment: string;
|
|
13
13
|
let shopifyPayment: string;
|
|
14
|
+
let traderaPayment: string;
|
|
14
15
|
}
|
|
15
16
|
export namespace ORDER_STATES {
|
|
16
17
|
let draft: string;
|
|
@@ -23,6 +24,7 @@ export namespace SALES_CHANNELS {
|
|
|
23
24
|
let onlineStore: string;
|
|
24
25
|
let thirdParty: string;
|
|
25
26
|
let shopify: string;
|
|
27
|
+
let tradera: string;
|
|
26
28
|
let ahlens: string;
|
|
27
29
|
let ribbnMobilePOS: string;
|
|
28
30
|
let ribbnWebPOS: string;
|
|
@@ -14,6 +14,7 @@ exports.PAYMENT_TYPES = {
|
|
|
14
14
|
cash: 'CASH',
|
|
15
15
|
mobilePayment: 'MOBILE_PAYMENT',
|
|
16
16
|
shopifyPayment: 'SHOPIFY_PAYMENT',
|
|
17
|
+
traderaPayment: 'TRADERA_PAYMENT',
|
|
17
18
|
};
|
|
18
19
|
exports.ORDER_STATES = {
|
|
19
20
|
draft: 'DRAFT',
|
|
@@ -26,6 +27,7 @@ exports.SALES_CHANNELS = {
|
|
|
26
27
|
onlineStore: 'ONLINE_STORE',
|
|
27
28
|
thirdParty: 'THIRD_PARTY',
|
|
28
29
|
shopify: 'SHOPIFY',
|
|
30
|
+
tradera: 'TRADERA',
|
|
29
31
|
ahlens: 'AHLENS',
|
|
30
32
|
ribbnMobilePOS: 'RIBBN_MOBILE_POS',
|
|
31
33
|
ribbnWebPOS: 'RIBBN_WEB_POS',
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Utilities from '../../helpers/Utilities';
|
|
2
|
+
export default class OrderFromTraderaEmail {
|
|
3
|
+
utilities: Utilities;
|
|
4
|
+
getObjectNumbers(emailHtml: any): string[];
|
|
5
|
+
createOrderFromLineItems(emailHtml: any, providedLineItems?: ReRobeOrderLineItem[]): ReRobeOrderObj;
|
|
6
|
+
private normalizeEmailHtml;
|
|
7
|
+
private getMatch;
|
|
8
|
+
private parseAmount;
|
|
9
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const Order_1 = require("../../models/Order");
|
|
4
|
+
const order_constants_1 = require("../../constants/order-constants");
|
|
5
|
+
const Utilities_1 = require("../../helpers/Utilities");
|
|
6
|
+
class OrderFromTraderaEmail {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.utilities = new Utilities_1.default();
|
|
9
|
+
}
|
|
10
|
+
// Extracts all Tradera listing ids ("Object No") from the email HTML
|
|
11
|
+
getObjectNumbers(emailHtml) {
|
|
12
|
+
const html = typeof emailHtml === 'string' ? emailHtml : String((emailHtml === null || emailHtml === void 0 ? void 0 : emailHtml.html) || emailHtml || '');
|
|
13
|
+
const normalized = this.normalizeEmailHtml(html);
|
|
14
|
+
const results = [];
|
|
15
|
+
const regex = /Object\s+No\s+(\d+)/gi;
|
|
16
|
+
for (const m of normalized.matchAll(regex)) {
|
|
17
|
+
const id = (m && m[1]) || '';
|
|
18
|
+
if (id && !results.includes(id))
|
|
19
|
+
results.push(id);
|
|
20
|
+
}
|
|
21
|
+
return results;
|
|
22
|
+
}
|
|
23
|
+
// Builds an order from raw email HTML and provided ReRobe line items (does not derive line items from email)
|
|
24
|
+
// Uses fixed shopper identity (email + customerName) for Tradera orders created via this method
|
|
25
|
+
createOrderFromLineItems(emailHtml, providedLineItems = []) {
|
|
26
|
+
const html = typeof emailHtml === 'string' ? emailHtml : String((emailHtml === null || emailHtml === void 0 ? void 0 : emailHtml.html) || emailHtml || '');
|
|
27
|
+
const normalized = this.normalizeEmailHtml(html);
|
|
28
|
+
const currencyCode = 'SEK';
|
|
29
|
+
// Extract listing id from email for traceability tag
|
|
30
|
+
const listingId = this.getMatch(/Object\s+No\s+(\d+)/i, normalized);
|
|
31
|
+
// Total amount and shipping (from email)
|
|
32
|
+
const totalAmountFromEmail = this.parseAmount(this.getMatch(/Total\s+amount:[\s\S]*?SEK\s*([0-9][0-9\s,.]*)/i, normalized));
|
|
33
|
+
// Shipping block parsing (from email)
|
|
34
|
+
const shippingBlockIdx = normalized.search(/>\s*Shipping\s*</i);
|
|
35
|
+
const shippingSlice = shippingBlockIdx >= 0 ? normalized.slice(shippingBlockIdx, shippingBlockIdx + 2000) : normalized;
|
|
36
|
+
const shippingAmount = this.parseAmount(this.getMatch(/SEK\s*([0-9][0-9\s,.]*)/i, shippingSlice));
|
|
37
|
+
const shippingTitle = this.getMatch(/SEK\s*[0-9][0-9\s,.]*\s*([^<\n\r]+)/i, shippingSlice).trim() || 'Shipping';
|
|
38
|
+
// Status URL (contact info, contains purchaseOrderId) if available
|
|
39
|
+
const statusUrl = this.getMatch(/href\s*=\s*"([^"']+buyer-info[^"']+)"/i, normalized) ||
|
|
40
|
+
this.getMatch(/href\s*=\s*"([^"']+purchaseOrderId=[^"']+)"/i, normalized) ||
|
|
41
|
+
'';
|
|
42
|
+
// Use provided line items as-is
|
|
43
|
+
const lineItems = Array.isArray(providedLineItems) ? providedLineItems : [];
|
|
44
|
+
// Compute subtotal: prefer email-derived (total - shipping) if present, otherwise sum line items
|
|
45
|
+
const subtotalFromEmail = Number.isFinite(totalAmountFromEmail) && totalAmountFromEmail > 0
|
|
46
|
+
? Math.max(0, (totalAmountFromEmail || 0) - (shippingAmount || 0))
|
|
47
|
+
: 0;
|
|
48
|
+
const subtotalFromItems = (lineItems || []).reduce((sum, li) => { var _a; return sum + Number(((_a = li === null || li === void 0 ? void 0 : li.originalTotalPrice) === null || _a === void 0 ? void 0 : _a.amount) || 0); }, 0);
|
|
49
|
+
const subtotalAmount = subtotalFromEmail || subtotalFromItems || 0;
|
|
50
|
+
const totalPriceAmount = Number.isFinite(totalAmountFromEmail) && totalAmountFromEmail > 0
|
|
51
|
+
? totalAmountFromEmail
|
|
52
|
+
: subtotalAmount + (shippingAmount || 0);
|
|
53
|
+
const shippingLine = {
|
|
54
|
+
id: '',
|
|
55
|
+
title: shippingTitle,
|
|
56
|
+
source: order_constants_1.SALES_CHANNELS.tradera,
|
|
57
|
+
discountedPrice: { amount: shippingAmount || 0, currencyCode },
|
|
58
|
+
originalPrice: { amount: shippingAmount || 0, currencyCode },
|
|
59
|
+
taxLines: [],
|
|
60
|
+
};
|
|
61
|
+
const nowIso = new Date().toISOString();
|
|
62
|
+
const order = new Order_1.default({
|
|
63
|
+
id: this.utilities.makeRandId(28),
|
|
64
|
+
documentId: this.utilities.makeRandId(28),
|
|
65
|
+
name: '',
|
|
66
|
+
currencyCode,
|
|
67
|
+
statusUrl,
|
|
68
|
+
email: 'traderashopper@myribbn.com',
|
|
69
|
+
financialStatus: Order_1.default.FINANCIAL_TYPES.pending,
|
|
70
|
+
fulfillmentStatus: Order_1.default.FULFILLMENT_TYPES.unfulfilled,
|
|
71
|
+
processedAt: nowIso,
|
|
72
|
+
orderNumber: '',
|
|
73
|
+
shippingAddress: null,
|
|
74
|
+
lineItems,
|
|
75
|
+
subtotalPrice: { amount: subtotalAmount, currencyCode },
|
|
76
|
+
totalPrice: { amount: totalPriceAmount, currencyCode },
|
|
77
|
+
totalTax: { amount: 0, currencyCode },
|
|
78
|
+
totalShippingPrice: { amount: shippingAmount || 0, currencyCode },
|
|
79
|
+
totalDiscount: { amount: 0, currencyCode },
|
|
80
|
+
taxLines: [],
|
|
81
|
+
discountApplications: [],
|
|
82
|
+
fulfillments: [],
|
|
83
|
+
refunds: [],
|
|
84
|
+
totalRefunded: { amount: 0, currencyCode },
|
|
85
|
+
shippingLine,
|
|
86
|
+
tags: ['source:tradera', listingId ? `objectNo:${listingId}` : null].filter(Boolean),
|
|
87
|
+
state: Order_1.default.ORDER_STATES.completed,
|
|
88
|
+
shippingType: order_constants_1.SHIPPING_TYPES.shipping,
|
|
89
|
+
paymentType: order_constants_1.PAYMENT_TYPES.traderaPayment,
|
|
90
|
+
salesChannel: order_constants_1.SALES_CHANNELS.tradera,
|
|
91
|
+
customerName: 'Tradera Shopper',
|
|
92
|
+
});
|
|
93
|
+
return order.toObj();
|
|
94
|
+
}
|
|
95
|
+
normalizeEmailHtml(input) {
|
|
96
|
+
if (!input)
|
|
97
|
+
return '';
|
|
98
|
+
return (String(input)
|
|
99
|
+
// remove quoted-printable soft line breaks
|
|
100
|
+
.replace(/=\r?\n/g, '')
|
|
101
|
+
// decode common QP equals
|
|
102
|
+
.replace(/=3D/g, '=')
|
|
103
|
+
.replace(/=20/g, ' ')
|
|
104
|
+
// collapse excessive whitespace
|
|
105
|
+
.replace(/[\t\r]+/g, ' '));
|
|
106
|
+
}
|
|
107
|
+
getMatch(regex, source) {
|
|
108
|
+
const m = source.match(regex);
|
|
109
|
+
return (m && m[1]) || '';
|
|
110
|
+
}
|
|
111
|
+
parseAmount(val) {
|
|
112
|
+
if (val === null || val === undefined)
|
|
113
|
+
return 0;
|
|
114
|
+
if (typeof val === 'number')
|
|
115
|
+
return Number.isFinite(val) ? Math.round((val + Number.EPSILON) * 100) / 100 : 0;
|
|
116
|
+
let s = String(val)
|
|
117
|
+
.replace(/[^0-9.,\s]/g, '')
|
|
118
|
+
.trim();
|
|
119
|
+
// Remove spaces used as thousand separators
|
|
120
|
+
s = s.replace(/\s+/g, '');
|
|
121
|
+
const hasComma = s.includes(',');
|
|
122
|
+
const hasDot = s.includes('.');
|
|
123
|
+
if (hasComma && hasDot) {
|
|
124
|
+
// Assume comma is thousands, dot is decimal
|
|
125
|
+
s = s.replace(/,/g, '');
|
|
126
|
+
}
|
|
127
|
+
else if (hasComma && !hasDot) {
|
|
128
|
+
const lastComma = s.lastIndexOf(',');
|
|
129
|
+
const decimalsLen = s.length - lastComma - 1;
|
|
130
|
+
if (decimalsLen === 2) {
|
|
131
|
+
// Comma as decimal separator
|
|
132
|
+
s = s.replace(/,/g, '.');
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
// Comma as thousands
|
|
136
|
+
s = s.replace(/,/g, '');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const num = Number(s);
|
|
140
|
+
return Number.isFinite(num) ? Math.round((num + Number.EPSILON) * 100) / 100 : 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
exports.default = OrderFromTraderaEmail;
|
package/lib/index.d.ts
CHANGED
|
@@ -19,6 +19,7 @@ import OrderFromShopifyWebhook from './factories/Order/OrderFromShopifyWebhook';
|
|
|
19
19
|
import OrderFromShopifyAdminApi from './factories/Order/OrderFromShopifyAdminApi';
|
|
20
20
|
import OrderFromShopifyStorefrontApi from './factories/Order/OrderFromShopifyStorefrontApi';
|
|
21
21
|
import OrderFromApp from './factories/Order/OrderFromApp';
|
|
22
|
+
import OrderFromTraderaEmail from './factories/Order/OrderFromTraderaEmail';
|
|
22
23
|
import OrderFormStateFactory from './factories/FormState/Order/OrderFormStateFactory';
|
|
23
24
|
import RefundFormStateFactory from './factories/FormState/Order/RefundFormStateFactory';
|
|
24
25
|
import Product from './models/Product';
|
|
@@ -39,4 +40,4 @@ import MerchantConfigAutomatedPayoutsFormState from './form-states/Merchant/Merc
|
|
|
39
40
|
import ReRobeProductHelpers from './helpers/ReRobeProductHelpers';
|
|
40
41
|
import AnalyticsHelpers from './helpers/AnalyticsHelpers';
|
|
41
42
|
import OrderHelpers from './helpers/OrderHelpers';
|
|
42
|
-
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, OrderFormStateFactory, RefundFormStateFactory, PayoutAccount, PayoutAccountFormState, Merchant, MerchantFormState, MerchantFormStateFactory, MerchantConfigAutomatedPayouts, MerchantConfigAutomatedPayoutsFormState, ReRobeProductHelpers, User, AnalyticsHelpers, OrderHelpers, WebhookFormState, MerchantWebPage, ShopifyMerchantAccount, CustomerNotification, };
|
|
43
|
+
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, MerchantFormState, MerchantFormStateFactory, MerchantConfigAutomatedPayouts, MerchantConfigAutomatedPayoutsFormState, ReRobeProductHelpers, User, AnalyticsHelpers, OrderHelpers, WebhookFormState, MerchantWebPage, ShopifyMerchantAccount, CustomerNotification, };
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CustomerNotification = exports.ShopifyMerchantAccount = exports.MerchantWebPage = exports.WebhookFormState = exports.OrderHelpers = exports.AnalyticsHelpers = exports.User = exports.ReRobeProductHelpers = exports.MerchantConfigAutomatedPayoutsFormState = exports.MerchantConfigAutomatedPayouts = exports.MerchantFormStateFactory = exports.MerchantFormState = exports.Merchant = exports.PayoutAccountFormState = exports.PayoutAccount = exports.RefundFormStateFactory = exports.OrderFormStateFactory = 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;
|
|
3
|
+
exports.CustomerNotification = exports.ShopifyMerchantAccount = exports.MerchantWebPage = exports.WebhookFormState = exports.OrderHelpers = exports.AnalyticsHelpers = exports.User = exports.ReRobeProductHelpers = exports.MerchantConfigAutomatedPayoutsFormState = exports.MerchantConfigAutomatedPayouts = exports.MerchantFormStateFactory = exports.MerchantFormState = 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
4
|
const ProductFromShopifyJSClientJSONDoc_1 = require("./factories/Product/ProductFromShopifyJSClientJSONDoc");
|
|
5
5
|
exports.ProductFromShopifyJSClientJSONDoc = ProductFromShopifyJSClientJSONDoc_1.default;
|
|
6
6
|
const ProductFromAlgoliaJSONDoc_1 = require("./factories/Product/ProductFromAlgoliaJSONDoc");
|
|
@@ -43,6 +43,8 @@ const OrderFromShopifyStorefrontApi_1 = require("./factories/Order/OrderFromShop
|
|
|
43
43
|
exports.OrderFromShopifyStorefrontApi = OrderFromShopifyStorefrontApi_1.default;
|
|
44
44
|
const OrderFromApp_1 = require("./factories/Order/OrderFromApp");
|
|
45
45
|
exports.OrderFromApp = OrderFromApp_1.default;
|
|
46
|
+
const OrderFromTraderaEmail_1 = require("./factories/Order/OrderFromTraderaEmail");
|
|
47
|
+
exports.OrderFromTraderaEmail = OrderFromTraderaEmail_1.default;
|
|
46
48
|
const OrderFormStateFactory_1 = require("./factories/FormState/Order/OrderFormStateFactory");
|
|
47
49
|
exports.OrderFormStateFactory = OrderFormStateFactory_1.default;
|
|
48
50
|
const RefundFormStateFactory_1 = require("./factories/FormState/Order/RefundFormStateFactory");
|
package/lib/models/Order.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export default class Order extends Base {
|
|
|
13
13
|
cash: string;
|
|
14
14
|
mobilePayment: string;
|
|
15
15
|
shopifyPayment: string;
|
|
16
|
+
traderaPayment: string;
|
|
16
17
|
};
|
|
17
18
|
static ORDER_STATES: {
|
|
18
19
|
draft: string;
|
|
@@ -25,6 +26,7 @@ export default class Order extends Base {
|
|
|
25
26
|
onlineStore: string;
|
|
26
27
|
thirdParty: string;
|
|
27
28
|
shopify: string;
|
|
29
|
+
tradera: string;
|
|
28
30
|
ahlens: string;
|
|
29
31
|
ribbnMobilePOS: string;
|
|
30
32
|
ribbnWebPOS: string;
|