@nuskin/ns-shop 7.0.11-CodeFix.1 → 7.0.11-pur-813.2
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuskin/ns-shop",
|
|
3
|
-
"version": "7.0.11-
|
|
3
|
+
"version": "7.0.11-pur-813.2",
|
|
4
4
|
"description": "The description that will amaze and astound your audience when they read it",
|
|
5
5
|
"main": "src/shop.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,8 +26,10 @@
|
|
|
26
26
|
"@nuskin/ns-common-lib": "1.4.7",
|
|
27
27
|
"@nuskin/ns-feature-flags": "1.4.7",
|
|
28
28
|
"@nuskin/ns-loyalty-web": "1.5.6",
|
|
29
|
-
"@nuskin/ns-product-lib": "2.
|
|
29
|
+
"@nuskin/ns-product-lib": "2.19.1-pur-816.1",
|
|
30
30
|
"@nuskin/nuskinjquery": "2.3.1",
|
|
31
|
+
"@nuskin/order-model": "3.1.3",
|
|
32
|
+
"@nuskin/product-lib": "2.2.1",
|
|
31
33
|
"axios": "1.6.5",
|
|
32
34
|
"decimal.js": "10.4.3",
|
|
33
35
|
"jp-conversion": "0.0.7",
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
import {productLib} from '@nuskin/product-lib';
|
|
2
|
+
import {RunConfigService, events, UrlService, BrowserDetection} from '@nuskin/ns-util';
|
|
3
|
+
import { getConfiguration } from '@nuskin/configuration-sdk';
|
|
4
|
+
import {AccountManager} from '@nuskin/ns-account';
|
|
5
|
+
import {PriceType, Product} from '@nuskin/ns-product-lib';
|
|
6
|
+
|
|
7
|
+
const extractProductData = (data, sku) => {
|
|
8
|
+
let retVal;
|
|
9
|
+
|
|
10
|
+
if (Array.isArray(data.variants) && data.variants.length > 0) {
|
|
11
|
+
retVal = data.variants.find((variant) => variant.sku === sku);
|
|
12
|
+
} else if (data.bundle) {
|
|
13
|
+
retVal = data.bundle;
|
|
14
|
+
retVal.title = data.title;
|
|
15
|
+
retVal.productImages = data.productImages;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return retVal;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const addPrice = (productData, priceTypeKey, subKey, priceValue) => {
|
|
22
|
+
if (!['Points', 'cv', 'price', 'pv'].includes(priceTypeKey)) {
|
|
23
|
+
// if the priceTypeKey is not one of these, then we don't want it to show.
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (priceTypeKey === 'pv') {
|
|
27
|
+
priceTypeKey = 'psv';
|
|
28
|
+
}
|
|
29
|
+
if (priceTypeKey === 'cv') {
|
|
30
|
+
priceTypeKey = 'csv';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (productData[priceTypeKey] === undefined) {
|
|
34
|
+
if (priceTypeKey === 'Points') {
|
|
35
|
+
if (!productData.price) {
|
|
36
|
+
productData.price = {};
|
|
37
|
+
}
|
|
38
|
+
productData.price.PTS = priceValue;
|
|
39
|
+
return;
|
|
40
|
+
} else {
|
|
41
|
+
productData[priceTypeKey] = {};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
productData[priceTypeKey][subKey] = priceValue;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const convertPricing = (pricing, productData) => {
|
|
48
|
+
if (pricing) {
|
|
49
|
+
Object.keys(pricing).forEach((channelKey) => {
|
|
50
|
+
Object.keys(pricing[channelKey]).forEach((contextKey) => {
|
|
51
|
+
Object.keys(pricing[channelKey][contextKey]).forEach((priceTypeKey) => {
|
|
52
|
+
const priceValue = pricing[channelKey][contextKey][priceTypeKey];
|
|
53
|
+
switch (channelKey) {
|
|
54
|
+
case 'wholesale':
|
|
55
|
+
switch (contextKey) {
|
|
56
|
+
case 'webOrder':
|
|
57
|
+
addPrice(productData, priceTypeKey, 'WWHL', priceValue);
|
|
58
|
+
break;
|
|
59
|
+
case 'webAdr':
|
|
60
|
+
case 'WADW':
|
|
61
|
+
case 'ADR5':
|
|
62
|
+
addPrice(productData, priceTypeKey, 'WADW', priceValue);
|
|
63
|
+
break;
|
|
64
|
+
case 'order':
|
|
65
|
+
case 'WHL':
|
|
66
|
+
addPrice(productData, priceTypeKey, 'WHL', priceValue);
|
|
67
|
+
break;
|
|
68
|
+
case 'adr':
|
|
69
|
+
addPrice(productData, priceTypeKey, 'ADW', priceValue);
|
|
70
|
+
break;
|
|
71
|
+
case 'ADR10':
|
|
72
|
+
case 'WADWD':
|
|
73
|
+
addPrice(productData, priceTypeKey, 'WADWD', priceValue);
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
addPrice(
|
|
77
|
+
productData,
|
|
78
|
+
priceTypeKey,
|
|
79
|
+
`${contextKey}-WWHL`,
|
|
80
|
+
priceValue
|
|
81
|
+
);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
case 'retail':
|
|
86
|
+
switch (contextKey) {
|
|
87
|
+
case 'webOrder':
|
|
88
|
+
addPrice(productData, priceTypeKey, 'WRTL', priceValue);
|
|
89
|
+
break;
|
|
90
|
+
case 'webAdr':
|
|
91
|
+
addPrice(productData, priceTypeKey, 'WADR', priceValue);
|
|
92
|
+
break;
|
|
93
|
+
case 'order':
|
|
94
|
+
case 'RTL':
|
|
95
|
+
addPrice(productData, priceTypeKey, 'RTL', priceValue);
|
|
96
|
+
break;
|
|
97
|
+
case 'adr':
|
|
98
|
+
addPrice(productData, priceTypeKey, 'ADR', priceValue);
|
|
99
|
+
break;
|
|
100
|
+
default:
|
|
101
|
+
addPrice(
|
|
102
|
+
productData,
|
|
103
|
+
priceTypeKey,
|
|
104
|
+
`${contextKey}-WRTL`,
|
|
105
|
+
priceValue
|
|
106
|
+
);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const createDataFromSkuSearch = (searchData, options) => {
|
|
118
|
+
if (!searchData) {
|
|
119
|
+
return new Product();
|
|
120
|
+
}
|
|
121
|
+
let product = new Product(),
|
|
122
|
+
langObj = null, //getLangObj(searchData['contents']['language'], options.language),
|
|
123
|
+
marketObj = null; //searchData['market'];
|
|
124
|
+
// if (Array.isArray(marketObj)) {
|
|
125
|
+
// marketObj = getMarketObj(searchData['market'], options.country);
|
|
126
|
+
// }
|
|
127
|
+
let {orderType: mktOrderTypes, custType: mktCustTypes, restrictedMarket: restrictedMarkets, addOns} = {}; //marketObj;
|
|
128
|
+
|
|
129
|
+
if (searchData) {
|
|
130
|
+
product.sku = options.sku;
|
|
131
|
+
product.lang = options.language;
|
|
132
|
+
product.isExclusive = searchData.isExclusive;
|
|
133
|
+
if (Array.isArray(searchData.productImages) && searchData.productImages.length > 0) {
|
|
134
|
+
product.setFullImage(searchData.productImages[0].url);
|
|
135
|
+
product.setThumbnail(searchData.productImages[0].thumbnail);
|
|
136
|
+
// product.setProductCarouselImages(???searchData.contents.imageCarousel);
|
|
137
|
+
}
|
|
138
|
+
// product.productLabels = ???
|
|
139
|
+
product.title = searchData.title;
|
|
140
|
+
product.shortDescr = searchData.description;
|
|
141
|
+
|
|
142
|
+
const pricing = JSON.parse(searchData.pricingJson);
|
|
143
|
+
const orderTypes = [];
|
|
144
|
+
if (searchData.purchaseTypes.buyOnce) orderTypes.push('order');
|
|
145
|
+
if (searchData.purchaseTypes.subscription) orderTypes.push('adr');
|
|
146
|
+
let status = {
|
|
147
|
+
sku: options.sku,
|
|
148
|
+
globalProductId: searchData.globalId,
|
|
149
|
+
status: searchData.status.status === 'sellable' ? 'RELEASED_FOR_SALE' : 'NOT_RELEASED_FOR_SALE',
|
|
150
|
+
availableQuantity: searchData.availableQuantity,
|
|
151
|
+
maxQuantity: searchData.maxQuantity,
|
|
152
|
+
locallyProduced: searchData.locallyProduced, // ???
|
|
153
|
+
backorderedAvailableDate: searchData.status.isBackordered > 0 ? searchData.status.backorderedAvailableDate : null,
|
|
154
|
+
orderType: orderTypes, // searchData.channels.map((channel) => channel.toLowerCase()),
|
|
155
|
+
childSkus: null // ???
|
|
156
|
+
};
|
|
157
|
+
convertPricing(pricing, status);
|
|
158
|
+
product.addPricingFromStatus(status);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
if (marketObj !== null) {
|
|
163
|
+
// product.sku = searchData.sku;
|
|
164
|
+
// product.isExclusive = Object.hasOwn(searchData, 'isExclusive') ? searchData.isExclusive : false;
|
|
165
|
+
if (Object.hasOwn(searchData, 'contents')) {
|
|
166
|
+
// product.setFullImage(searchData.contents.fullImage);
|
|
167
|
+
// product.setThumbnail(searchData.contents.fullImage.replace(/\.img\.[0-9]+\.[0-9]+\.png/i, '.img.160.160.png'));
|
|
168
|
+
// if (Object.hasOwn(searchData.contents, 'imageCarousel')) {
|
|
169
|
+
// product.setProductCarouselImages(searchData.contents.imageCarousel);
|
|
170
|
+
// }
|
|
171
|
+
}
|
|
172
|
+
// AEM-8320 - it returns two BP (08007070 and 08129080), 08129080 does not have any translation yet.
|
|
173
|
+
// Note that langObj can be null (have a BP that does not have any translation)
|
|
174
|
+
|
|
175
|
+
// product.productLabels = marketObj['populateProductLabels'];
|
|
176
|
+
if (langObj) {
|
|
177
|
+
// product.lang = langObj['languageCode'];
|
|
178
|
+
// product.title = langObj['name'];
|
|
179
|
+
// product.shortDescr = langObj['shortDescription'];
|
|
180
|
+
product.longDescr = langObj['longDescription'];
|
|
181
|
+
product.ingredients = langObj['ingredients'];
|
|
182
|
+
product.benefits = langObj['benefits'];
|
|
183
|
+
product.usage = langObj['usage'];
|
|
184
|
+
product.resources = langObj['resources'];
|
|
185
|
+
product.videos = langObj['videos'];
|
|
186
|
+
product.contentSection = langObj['contentSection'];
|
|
187
|
+
product.sizeWeight = langObj['size_weight'];
|
|
188
|
+
product.nettoWeight = langObj['netto_weight'];
|
|
189
|
+
product.salesLabel = langObj['salesLabel'];
|
|
190
|
+
product.movie = langObj['movie'];
|
|
191
|
+
product.youtube = langObj['youtube'];
|
|
192
|
+
product.salesEventText = langObj['tdc_salesEventText'];
|
|
193
|
+
if (langObj.variantInfo) {
|
|
194
|
+
if (langObj.variantInfo.tdc_dropdownLabel) {
|
|
195
|
+
product.variantDropdownLabel = langObj.variantInfo.tdc_dropdownLabel
|
|
196
|
+
}
|
|
197
|
+
if (langObj.variantInfo.tdc_dropdownPlaceholder) {
|
|
198
|
+
product.variantDropdownPlaceholder = langObj.variantInfo.tdc_dropdownPlaceholder;
|
|
199
|
+
}
|
|
200
|
+
if (langObj.variantInfo.tdc_variantsLabel) {
|
|
201
|
+
product.variantsLabel = langObj.variantInfo.tdc_variantsLabel;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
product.setImageAltText(searchData['contents']['altText']);
|
|
206
|
+
product.country = marketObj['countryCode'];
|
|
207
|
+
product.scanQualified = marketObj['scanQualified'];
|
|
208
|
+
product.division = searchData['division'];
|
|
209
|
+
|
|
210
|
+
if (mktOrderTypes) {
|
|
211
|
+
product.orderTypes = mktOrderTypes;
|
|
212
|
+
}
|
|
213
|
+
if (mktCustTypes) {
|
|
214
|
+
product.custTypes = mktCustTypes;
|
|
215
|
+
}
|
|
216
|
+
if (restrictedMarkets) {
|
|
217
|
+
product.restrictedMarkets = restrictedMarkets;
|
|
218
|
+
}
|
|
219
|
+
if (addOns) {
|
|
220
|
+
product.addOns = addOns;
|
|
221
|
+
} else {
|
|
222
|
+
product.addOns = [];
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (options.isGroupOffer)
|
|
226
|
+
product.isGroupOffer = options.isGroupOffer;
|
|
227
|
+
if (options.isPersonalOffer)
|
|
228
|
+
product.isPersonalOffer = options.isPersonalOffer;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if (searchData.variantConfig) {
|
|
232
|
+
if (searchData.variantConfig.variantType) {
|
|
233
|
+
product.variantType = searchData.variantConfig.variantType;
|
|
234
|
+
}
|
|
235
|
+
if (searchData.variantConfig.variants) {
|
|
236
|
+
searchData.variantConfig.variants.forEach((variant) => {
|
|
237
|
+
product.setVariant(createDataFromSkuSearch(variant, options));
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (searchData.variantConfig.swatchColor) {
|
|
241
|
+
product.shade = searchData.variantConfig.swatchColor;
|
|
242
|
+
}
|
|
243
|
+
if (searchData.variantConfig.baseSku) {
|
|
244
|
+
product.baseSku = searchData.variantConfig.baseSku;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return product;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const handleDetailResponse = async (responseData, options) => {
|
|
252
|
+
let retVal = {success: true},
|
|
253
|
+
dataForProduct = createDataFromSkuSearch(responseData, options);
|
|
254
|
+
|
|
255
|
+
if (dataForProduct.sku) {
|
|
256
|
+
retVal.product = new Product(dataForProduct);
|
|
257
|
+
|
|
258
|
+
const siteUrl = UrlService.getSiteUrl();
|
|
259
|
+
const isEdge = BrowserDetection.isEdge();
|
|
260
|
+
const isFirefox = BrowserDetection.isFirefox();
|
|
261
|
+
|
|
262
|
+
// set the base url for images, etc
|
|
263
|
+
retVal.product.setBaseUrl(siteUrl);
|
|
264
|
+
|
|
265
|
+
// fix image paths for non-edge/firefox
|
|
266
|
+
if (!isEdge && !isFirefox) {
|
|
267
|
+
retVal.product.fullImage = retVal.product.fullImage
|
|
268
|
+
? `${retVal.product.fullImage.split("?")[0]}?format=pjpg`
|
|
269
|
+
: undefined;
|
|
270
|
+
retVal.product.thumbnail = retVal.product.thumbnail
|
|
271
|
+
? `${retVal.product.thumbnail.split("?")[0]}?format=pjpg`
|
|
272
|
+
: undefined;
|
|
273
|
+
}
|
|
274
|
+
} else {
|
|
275
|
+
retVal.success = false;
|
|
276
|
+
retVal.failedSku = options.sku;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (retVal.product && options.priceType) {
|
|
280
|
+
const {Cart: cartCfg} = await getConfiguration(['Cart']);
|
|
281
|
+
const priceType = cartCfg.showWholeSalePricing && !AccountManager.isLoggedIn()
|
|
282
|
+
? PriceType.WWHL
|
|
283
|
+
: options.priceType;
|
|
284
|
+
retVal.product.setPriceAndPvFromType(priceType);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return retVal;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const getProductDetail = async (options) => {
|
|
291
|
+
let response;
|
|
292
|
+
|
|
293
|
+
// Hit the PMD and get all the data for the product including the price information.
|
|
294
|
+
try {
|
|
295
|
+
response = await productLib.getProduct({
|
|
296
|
+
fromId: options.sku,
|
|
297
|
+
env: RunConfigService.getEnvironmentCode(),
|
|
298
|
+
market: options.country,
|
|
299
|
+
language: options.language
|
|
300
|
+
})
|
|
301
|
+
} catch (e) {
|
|
302
|
+
throw {error: e, failedSku: options.sku, type: events.errors.PRODUCT_LOOKUP};
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return extractProductData(response.data, options.sku);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const getProductBySku = async (options) => {
|
|
309
|
+
const data = await getProductDetail(options);
|
|
310
|
+
|
|
311
|
+
let result = await handleDetailResponse(data, options);
|
|
312
|
+
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
export {
|
|
317
|
+
getProductBySku
|
|
318
|
+
}
|
|
@@ -404,7 +404,7 @@ function _assembleChildSkus(requestData, options) {
|
|
|
404
404
|
if(personalOffer != null && productWithVariant.length > 0 && productWithVariant[0].variantSelected){
|
|
405
405
|
selectedVariants = productWithVariant[0].variantSelected;
|
|
406
406
|
}
|
|
407
|
-
if (personalOffer != null && selectedVariants && cs.skuId != selectedVariants[cs.productId] && (cs.type !== "BUNDLE" && cs.type !== "OPTIONAL"
|
|
407
|
+
if (personalOffer != null && selectedVariants && cs.skuId != selectedVariants[cs.productId] && (cs.type !== "BUNDLE" && cs.type !== "OPTIONAL")) return null
|
|
408
408
|
const childSku =
|
|
409
409
|
(personalOffer != null && selectedVariants && selectedVariants[cs.productId] && config.MySite_graphql_active)
|
|
410
410
|
? {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import $ from '@nuskin/nuskinjquery';
|
|
2
2
|
import {PriceType, Product} from '@nuskin/ns-product-lib';
|
|
3
|
-
import {RunConfigService,
|
|
3
|
+
import {RunConfigService, events, util, BrowserDetection, UrlService} from '@nuskin/ns-util';
|
|
4
4
|
import {UserService, AccountManager} from '@nuskin/ns-account';
|
|
5
5
|
import ProductStatusService from '../product/ProductStatusService.js';
|
|
6
6
|
import _ from 'lodash';
|
|
7
7
|
import { getConfiguration } from '@nuskin/configuration-sdk';
|
|
8
|
+
import { getProductBySku as getCsProductBySku } from './csProductHelper.js';
|
|
8
9
|
import axios from 'axios';
|
|
9
10
|
|
|
10
11
|
let ProductService = function() {
|
|
@@ -21,24 +22,13 @@ let ProductService = function() {
|
|
|
21
22
|
* @returns {null}
|
|
22
23
|
*/
|
|
23
24
|
getProductBySku: async function(_options) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
let values = await Promise.all(promises);
|
|
30
|
-
|
|
31
|
-
let result = await handleDetailResponse(values[0], options);
|
|
32
|
-
|
|
33
|
-
if (values[1] && values[1][0]) {
|
|
34
|
-
handleStatusResponse(result.product, values[1][0], options);
|
|
25
|
+
const options = verifyLocaleFields(_options)
|
|
26
|
+
const {Cart: cartCfg} = await getConfiguration(['Cart']);
|
|
27
|
+
if (cartCfg.useContentStackProductData) {
|
|
28
|
+
return await getCsProductBySku(options)
|
|
35
29
|
} else {
|
|
36
|
-
|
|
37
|
-
// This is done to prevent the product detail component from locking up unnecessarily.
|
|
38
|
-
result.product.availableQuantity = 10000;
|
|
30
|
+
return await legacyGetProductBySku(options);
|
|
39
31
|
}
|
|
40
|
-
|
|
41
|
-
return result;
|
|
42
32
|
},
|
|
43
33
|
|
|
44
34
|
/**
|
|
@@ -84,6 +74,26 @@ let ProductService = function() {
|
|
|
84
74
|
// Private Methods
|
|
85
75
|
//
|
|
86
76
|
// ---------------------------------------------
|
|
77
|
+
async function legacyGetProductBySku(options) {
|
|
78
|
+
const promises = [getProductDetail(options)];
|
|
79
|
+
|
|
80
|
+
promises.push(getProductStatus(options));
|
|
81
|
+
|
|
82
|
+
let values = await Promise.all(promises);
|
|
83
|
+
|
|
84
|
+
let result = await handleDetailResponse(values[0], options);
|
|
85
|
+
|
|
86
|
+
if (values[1] && values[1][0]) {
|
|
87
|
+
handleStatusResponse(result.product, values[1][0], options);
|
|
88
|
+
} else {
|
|
89
|
+
// Fallback for product quantity on a failed product status call.
|
|
90
|
+
// This is done to prevent the product detail component from locking up unnecessarily.
|
|
91
|
+
result.product.availableQuantity = 10000;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
|
|
87
97
|
async function getProductDetail(_options) {
|
|
88
98
|
let options = _options;
|
|
89
99
|
let url = await getSkuSearchUrl(options);
|
|
@@ -5,6 +5,7 @@ import {RunConfigService, events, util, PersonalOfferStorageService, BrowserDete
|
|
|
5
5
|
import {getCachedConfigField} from '@nuskin/configuration-sdk';
|
|
6
6
|
import {UserService} from "@nuskin/ns-account";
|
|
7
7
|
import PaymentAdapter from '../payment/PaymentAdapter';
|
|
8
|
+
import pickupUtil from '../shipping/pickupUtil';
|
|
8
9
|
|
|
9
10
|
let splitLineItems = [];
|
|
10
11
|
|
|
@@ -865,13 +866,14 @@ let setSelectedShipMethod = function(order, matchMethod = {}) {
|
|
|
865
866
|
|
|
866
867
|
/**
|
|
867
868
|
* Parses pickup points from SAP response, in case shipping method is set to pickup points!
|
|
868
|
-
* @param {Object[]}
|
|
869
|
+
* @param {Object[]} oldPup The Custom array on the salesorderrequest
|
|
870
|
+
* @param {Object[]} newPup The Custom array on the salesorderrequest
|
|
869
871
|
* @param {Object} order
|
|
870
872
|
*/
|
|
871
|
-
function setPickupPoints(
|
|
872
|
-
const pupLocations =
|
|
873
|
+
function setPickupPoints(oldPup, newPup, order) {
|
|
874
|
+
const pupLocations = oldPup || [];
|
|
873
875
|
if (order.selectedShippingMethod && PickupUtil.supports(order.selectedShippingMethod.Code)) {
|
|
874
|
-
order.pickupPoints = PickupUtil.parse(pupLocations);
|
|
876
|
+
order.pickupPoints = newPup ? newPup : PickupUtil.parse(pupLocations);
|
|
875
877
|
if (order.selectedPickupPoint) {
|
|
876
878
|
order.selectedPickupPoint = order.pickupPoints.find(pickupPoint => order.selectedPickupPoint.id === pickupPoint.id);
|
|
877
879
|
}
|
|
@@ -1090,13 +1092,19 @@ const toOrder = async (salesOrderDetail, adr, createResponse) => {
|
|
|
1090
1092
|
}
|
|
1091
1093
|
|
|
1092
1094
|
if (salesOrderDetail.ShippingAvailableMethods && salesOrderDetail.ShippingAvailableMethods.length > 0) {
|
|
1093
|
-
|
|
1095
|
+
const useShipMethodsApi = getCachedConfigField('useShipMethodsApi');
|
|
1096
|
+
const shipMethods = useShipMethodsApi ? await pickupUtil.getShipMethods() : salesOrderDetail.ShippingAvailableMethods;
|
|
1097
|
+
order.shippingAvailableMethods = sortShippingAvailableMethods(shipMethods);
|
|
1094
1098
|
setShippingAvailableMethodsPickupInfo(order.shippingAvailableMethods);
|
|
1095
1099
|
setSelectedShipMethod(order, salesOrderDetail.Shipping.ShippingMethod);
|
|
1096
1100
|
// When an order or ADR is created. The response from the create call is missing the list of pickup locations
|
|
1097
1101
|
// The list isn't needed in this case since the user has already created the order so we don't need to update the pickup points
|
|
1098
1102
|
if (!createResponse) {
|
|
1099
|
-
|
|
1103
|
+
let oldPup = null;
|
|
1104
|
+
if (!useShipMethodsApi) oldPup = salesOrderDetail.Custom;
|
|
1105
|
+
let newPup = null;
|
|
1106
|
+
if (useShipMethodsApi) newPup = await pickupUtil.getPickupPoints();
|
|
1107
|
+
setPickupPoints(oldPup, newPup, order);
|
|
1100
1108
|
}
|
|
1101
1109
|
}
|
|
1102
1110
|
shippingHack(order, salesOrderDetail.OrderTotals.Shipping, salesOrderDetail.Currency);
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import OrderAdapter from '../order/orderAdapter';
|
|
2
|
+
import {getCachedConfiguration} from '@nuskin/configuration-sdk';
|
|
3
|
+
import {Order} from '@nuskin/order-model';
|
|
4
|
+
import {RunConfigService} from '@nuskin/ns-util';
|
|
5
|
+
// import {CartService} from '@nuskin/ns-shop';
|
|
6
|
+
import axios from 'axios';
|
|
7
|
+
import { OrderManager } from '../shop';
|
|
8
|
+
|
|
1
9
|
let PickupUtil = function() {
|
|
2
10
|
'use strict';
|
|
3
11
|
const SERVICE_GROUP = 'SERVICE_GROUP',
|
|
@@ -15,6 +23,10 @@ let PickupUtil = function() {
|
|
|
15
23
|
UNIT = 'UNIT',
|
|
16
24
|
CARRIER_CODE = 'CARRIER_CODE';
|
|
17
25
|
|
|
26
|
+
let promise = Promise.resolve();
|
|
27
|
+
let shipMethods = [];
|
|
28
|
+
let pickupPoints = [];
|
|
29
|
+
|
|
18
30
|
/**
|
|
19
31
|
* Pickup Point shipping methods.
|
|
20
32
|
* Values are shipping method codes.
|
|
@@ -130,12 +142,75 @@ let PickupUtil = function() {
|
|
|
130
142
|
return markers;
|
|
131
143
|
}
|
|
132
144
|
|
|
145
|
+
function getUrl() {
|
|
146
|
+
switch (RunConfigService.getEnvironmentCode()) {
|
|
147
|
+
case 'dev':
|
|
148
|
+
return 'https://ship-methods.api.dev.nuskin.com/v1';
|
|
149
|
+
case 'test':
|
|
150
|
+
return 'https://ship-methods.api.test.nuskin.com/v1';
|
|
151
|
+
case 'stage':
|
|
152
|
+
return 'https://ship-methods.api.dev.nuskin.com/v1';
|
|
153
|
+
case 'prod':
|
|
154
|
+
return 'https://ship-methods.api.dev.nuskin.com/v1';
|
|
155
|
+
default:
|
|
156
|
+
return 'https://ship-methods.api.dev.nuskin.com/v1';
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function loadShipMethods() {
|
|
161
|
+
const order = Order.fromSalesOrderRequest(OrderAdapter.populateSalesOrder('SIMULATE'));
|
|
162
|
+
|
|
163
|
+
const postalCode = order.shippingPostalCode;
|
|
164
|
+
const {metapackMarket, metapackZipExclusions} = getCachedConfiguration('Checkout');
|
|
165
|
+
|
|
166
|
+
if (metapackMarket) {
|
|
167
|
+
const order = OrderManager.getOrder();
|
|
168
|
+
let includePickupPoints = true;
|
|
169
|
+
for (const zipRegEx of metapackZipExclusions || []) {
|
|
170
|
+
const regEx = new RegExp(zipRegEx);
|
|
171
|
+
includePickupPoints = includePickupPoints && !postalCode.match(regEx);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
promise = axios.post(
|
|
175
|
+
getUrl(),
|
|
176
|
+
{
|
|
177
|
+
order,
|
|
178
|
+
pudo: includePickupPoints,
|
|
179
|
+
orderValue: order && order.orderTotals && order.orderTotals.grandTotal || 0.0
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
headers: {
|
|
183
|
+
'Content-Type': 'application/json; charset=UTF-8'
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
).then((results) => {
|
|
187
|
+
shipMethods = results.data.shipMethods;
|
|
188
|
+
pickupPoints = results.data.pickupPoints;
|
|
189
|
+
})
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
async function getShipMethods() {
|
|
194
|
+
await promise;
|
|
195
|
+
|
|
196
|
+
return shipMethods;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function getPickupPoints() {
|
|
200
|
+
await promise;
|
|
201
|
+
|
|
202
|
+
return pickupPoints;
|
|
203
|
+
}
|
|
204
|
+
|
|
133
205
|
return {
|
|
134
206
|
allMethods: shippingMethods,
|
|
135
207
|
supports: isPickupPointShippingMethod,
|
|
136
208
|
parse: parsePickupPoints,
|
|
137
209
|
bounds: getBounds,
|
|
138
|
-
markers: generateMarkers
|
|
210
|
+
markers: generateMarkers,
|
|
211
|
+
loadShipMethods,
|
|
212
|
+
getShipMethods,
|
|
213
|
+
getPickupPoints
|
|
139
214
|
}
|
|
140
215
|
}();
|
|
141
216
|
|