@nuskin/ns-shop 7.1.0-brw-988.1 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -4
- package/src/cart/cart.js +12 -1
- package/src/cart/cartService.js +35 -5
- package/src/cart/csProductHelper.js +274 -0
- package/src/cart/equinoxCartService.js +25 -14
- package/src/cart/productService.js +54 -46
- package/src/order/orderAdapter.js +17 -7
- package/src/payment/externalPaymentService.js +7 -1
- package/src/product/SolrQueryService.js +181 -218
- package/src/product/productSearchService.js +1 -8
- package/src/salesEventService.js +60 -72
- package/src/shipping/pickupUtil.js +96 -2
- package/src/product/productSearchAPIQueryService.js +0 -389
package/src/salesEventService.js
CHANGED
|
@@ -139,69 +139,32 @@ function getActiveTicketEvents() {
|
|
|
139
139
|
return events;
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
async function getEventStatus(eventsToCheck = []
|
|
142
|
+
async function getEventStatus(eventsToCheck = []) {
|
|
143
143
|
const eventStatus = {};
|
|
144
144
|
const promises = [];
|
|
145
145
|
|
|
146
146
|
eventsToCheck.forEach((toCheck) => {
|
|
147
|
-
promises.push(
|
|
147
|
+
promises.push(_checkForMissingTicket(toCheck));
|
|
148
148
|
});
|
|
149
149
|
|
|
150
|
-
|
|
150
|
+
await Promise.allSettled(promises);
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
eventsToCheck.forEach((eventName) => {
|
|
153
153
|
let activeStatus = false;
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
const ticketInfo = eventTicketInfoMap[eventName];
|
|
155
|
+
if (ticketInfo && ticketInfo.ticket) {
|
|
156
|
+
const status = _decodeStatus(ticketInfo.ticket.status);
|
|
156
157
|
if ((status.eventStatus === PRE_EVENT && status.preWaitTime <= 30000) ||
|
|
157
158
|
status.eventStatus === IN_EVENT) {
|
|
158
159
|
activeStatus = true;
|
|
159
160
|
}
|
|
160
|
-
eventStatus[response.value.eventName] = activeStatus;
|
|
161
161
|
}
|
|
162
|
+
eventStatus[eventName] = activeStatus;
|
|
162
163
|
});
|
|
163
164
|
|
|
164
165
|
return eventStatus;
|
|
165
166
|
}
|
|
166
167
|
|
|
167
|
-
/**
|
|
168
|
-
* Either requests a new ticket or an updated event ticket from the AWS service
|
|
169
|
-
*
|
|
170
|
-
* @param eventTicketInfo - contains informatino about the ticket.
|
|
171
|
-
*
|
|
172
|
-
* @returns {Promise<*>} a new or updated ticket for the specified event
|
|
173
|
-
* @private
|
|
174
|
-
*/
|
|
175
|
-
async function _getTempTicket(eventName, externalId) {
|
|
176
|
-
let ticket;
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
let method = 'POST',
|
|
180
|
-
seParams = _getSeParams(eventName, false),
|
|
181
|
-
response = await axios({
|
|
182
|
-
method: method,
|
|
183
|
-
url: `${_getAwsUrl(eventName, null)}?orderEventCheck=${externalId}${seParams}`,
|
|
184
|
-
headers: _getHeaders(),
|
|
185
|
-
timeout: 7000
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
ticket = response.data.salesEventResponse;
|
|
189
|
-
} catch (err) {
|
|
190
|
-
if (err.response && err.response.data.status === 404) {
|
|
191
|
-
console.error(`getTempTicket - unable to get a temporary ticket for ${eventName}`);
|
|
192
|
-
throw err;
|
|
193
|
-
} else {
|
|
194
|
-
console.error(`getTempTicket error or timeout - waiting to try again for ${eventName}`);
|
|
195
|
-
// Timed out or some other error
|
|
196
|
-
// Wait and then call again.
|
|
197
|
-
await _wait(3000);
|
|
198
|
-
ticket = await _getTempTicket(eventName);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
return ticket;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
168
|
function logAnalyticInfo(tag, eventName, data = {}) {
|
|
206
169
|
const user = UserService.getUser();
|
|
207
170
|
const eventTicketInfo = eventTicketInfoMap[eventName];
|
|
@@ -297,7 +260,7 @@ function _checkStatus(eventTicketInfo, useServerWaitTime) {
|
|
|
297
260
|
[ticket.eventName, eventTicketInfo.paused, {fromServer: useServerWaitTime, waitTime: actualWait}]
|
|
298
261
|
);
|
|
299
262
|
|
|
300
|
-
eventInfo.timerId = setTimeout(
|
|
263
|
+
eventInfo.timerId = setTimeout(_timerCallback(ticket.eventName), timerWait);
|
|
301
264
|
if (useServerWaitTime && timerWait < 30000) {
|
|
302
265
|
// if the wait time is base off of what the server passed back then
|
|
303
266
|
// don't call the server to update the ticket at the end of this timer
|
|
@@ -317,7 +280,7 @@ function _checkStatus(eventTicketInfo, useServerWaitTime) {
|
|
|
317
280
|
[ticket.eventName, eventTicketInfo.paused, {fromServer: useServerWaitTime, waitTime: actualWait}]
|
|
318
281
|
);
|
|
319
282
|
logAnalyticInfo('in-event', ticket.eventName);
|
|
320
|
-
eventInfo.timerId = setTimeout(
|
|
283
|
+
eventInfo.timerId = setTimeout(_timerCallback(ticket.eventName), timerWait);
|
|
321
284
|
} else {
|
|
322
285
|
_changeStatus(eventTicketInfo, POST_EVENT);
|
|
323
286
|
_checkStatus(eventTicketInfo, false); // to send post event and clear ticket.
|
|
@@ -563,7 +526,7 @@ async function _getRemoteTicket(eventTicketInfo) {
|
|
|
563
526
|
response = await axios({
|
|
564
527
|
method: method,
|
|
565
528
|
url: `${_getAwsUrl(eventName, ticketId)}${seParams}`,
|
|
566
|
-
headers: _getHeaders(),
|
|
529
|
+
headers: _getHeaders(method === 'GET' ? true : false),
|
|
567
530
|
timeout: 7000
|
|
568
531
|
});
|
|
569
532
|
|
|
@@ -678,14 +641,26 @@ function _getAwsUrl(eventName, ticketId) {
|
|
|
678
641
|
* @returns {{Accept: string, "Content-Type": string, client_id: *}}
|
|
679
642
|
* @private
|
|
680
643
|
*/
|
|
681
|
-
function _getHeaders() {
|
|
644
|
+
function _getHeaders(noCache = false) {
|
|
682
645
|
return {
|
|
683
646
|
'Accept': 'application/json',
|
|
684
647
|
'Content-Type': 'application/json',
|
|
685
|
-
'client_id': RunConfigService.getRunConfig().clientId
|
|
648
|
+
'client_id': RunConfigService.getRunConfig().clientId,
|
|
649
|
+
...(noCache && {'Cache-Control': 'no-cache'}),
|
|
650
|
+
...(noCache && {'Pragma': 'no-cache'}),
|
|
651
|
+
...(noCache && {'Expires': '0'})
|
|
686
652
|
};
|
|
687
653
|
}
|
|
688
654
|
|
|
655
|
+
async function _getActiveEvents() {
|
|
656
|
+
let response = await axios({
|
|
657
|
+
method: 'GET',
|
|
658
|
+
url: `${_getAwsUrl()}?activeWithin=${ACTIVE_EVENT_WITHIN}`,
|
|
659
|
+
headers: _getHeaders(true)
|
|
660
|
+
});
|
|
661
|
+
return response.data.salesEventResponse
|
|
662
|
+
}
|
|
663
|
+
|
|
689
664
|
//=========================================================================================================//
|
|
690
665
|
//
|
|
691
666
|
// Misc functions
|
|
@@ -762,7 +737,7 @@ async function _loadMarketEventConfig(force, country=undefined) {
|
|
|
762
737
|
const response = await axios({
|
|
763
738
|
method: 'GET',
|
|
764
739
|
url: `${_getAwsUrl()}`,
|
|
765
|
-
headers: _getHeaders()
|
|
740
|
+
headers: _getHeaders(true)
|
|
766
741
|
});
|
|
767
742
|
const salesEvents = response.data.salesEventResponse || [];
|
|
768
743
|
mktEventConfigMap = {};
|
|
@@ -804,6 +779,12 @@ function getStorageItem(key) {
|
|
|
804
779
|
return item;
|
|
805
780
|
}
|
|
806
781
|
|
|
782
|
+
async function _checkForMissingTicket(eventName) {
|
|
783
|
+
if (mktEventConfigMap[eventName] && !eventTicketInfoMap[eventName]) {
|
|
784
|
+
await _initEventTicketInfo(eventName);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
807
788
|
/**
|
|
808
789
|
* This initializes an interval timer which checks to see if the browser (computer)
|
|
809
790
|
* went to sleep. It's intention is to update the wait timer if it has.
|
|
@@ -815,17 +796,18 @@ async function _initializePolling() {
|
|
|
815
796
|
intervalCnt = 1;
|
|
816
797
|
|
|
817
798
|
intervalId = setInterval(async () => {
|
|
818
|
-
|
|
799
|
+
const now = Date.now();
|
|
800
|
+
const slept = now > (lastTime + TIMEOUT + 3000)
|
|
819
801
|
|
|
820
802
|
// if polling market config, only reload it every 30 seconds
|
|
821
|
-
if (pollMarketConfig && intervalCnt %
|
|
803
|
+
if (slept || pollMarketConfig && intervalCnt % 6 === 0) {
|
|
822
804
|
await _loadMarketEventConfig(true);
|
|
823
805
|
_marketStatusCheck();
|
|
824
806
|
}
|
|
825
807
|
intervalCnt++;
|
|
826
808
|
|
|
827
809
|
// if been to sleep for more then 3 seconds then check all ticket statuses.
|
|
828
|
-
if (
|
|
810
|
+
if (slept) {
|
|
829
811
|
// Went to sleep for 3 seconds or more
|
|
830
812
|
Object.values(eventTicketInfoMap).forEach(eventTicketInfo => {
|
|
831
813
|
// A new timer needs to be set, clear current one if exists
|
|
@@ -838,6 +820,17 @@ async function _initializePolling() {
|
|
|
838
820
|
_checkStatus(eventTicketInfo, false);
|
|
839
821
|
});
|
|
840
822
|
|
|
823
|
+
if (window.location.pathname === '/static/checkout/checkout.html' ||
|
|
824
|
+
window.location.pathname === '/static/cart/cart.html'
|
|
825
|
+
) {
|
|
826
|
+
// check for missing tickets. Only perform on checkout screen
|
|
827
|
+
const activeEvents = await _getActiveEvents();
|
|
828
|
+
|
|
829
|
+
for (const eventInfo of activeEvents) {
|
|
830
|
+
await _checkForMissingTicket(eventInfo.eventName);
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
|
|
841
834
|
lastTime = now;
|
|
842
835
|
}, TIMEOUT);
|
|
843
836
|
}
|
|
@@ -963,7 +956,7 @@ function _removeWaitCheck(value) {
|
|
|
963
956
|
*/
|
|
964
957
|
async function _loadAwsActiveEvents(country) {
|
|
965
958
|
let activeEventsName = `${ACTIVE_EVENTS}-${country? country: RunConfigService.getRunConfig().country}`,
|
|
966
|
-
storageObj =
|
|
959
|
+
storageObj = null,
|
|
967
960
|
ttl = storageObj ? storageObj.ttl - Date.now() : ACTIVE_EVENT_TTL,
|
|
968
961
|
eventInfos = {},
|
|
969
962
|
ok = true;
|
|
@@ -989,12 +982,7 @@ async function _loadAwsActiveEvents(country) {
|
|
|
989
982
|
storageObj = {events: []};
|
|
990
983
|
storage.setItem(activeEventsName, storageObj, {ttl: 250}); // to prevent multiple calls.
|
|
991
984
|
try {
|
|
992
|
-
|
|
993
|
-
method: 'GET',
|
|
994
|
-
url: `${_getAwsUrl()}?activeWithin=${ACTIVE_EVENT_WITHIN}`,
|
|
995
|
-
headers: _getHeaders()
|
|
996
|
-
});
|
|
997
|
-
addEvents(response.data.salesEventResponse);
|
|
985
|
+
addEvents(await _getActiveEvents());
|
|
998
986
|
} catch (e) {
|
|
999
987
|
// an error occurred with the call, clear active events
|
|
1000
988
|
// so it won't wait 30 minutes to try again
|
|
@@ -1027,6 +1015,14 @@ async function initActiveEvents(country = undefined) {
|
|
|
1027
1015
|
if (Object.values(mktEventConfigMap).find(mktEvent => {return mktEvent.status !== 'off'})) {
|
|
1028
1016
|
let awsEvents = await _loadAwsActiveEvents(country);
|
|
1029
1017
|
|
|
1018
|
+
// if a ticket exists in localStorage for an event the is not active, remove it.
|
|
1019
|
+
Object.keys(eventTicketInfoMap).forEach((key) => {
|
|
1020
|
+
if (!awsEvents[key]) {
|
|
1021
|
+
storage.removeItem(_getTicketName(key));
|
|
1022
|
+
delete eventTicketInfoMap[key];
|
|
1023
|
+
}
|
|
1024
|
+
})
|
|
1025
|
+
|
|
1030
1026
|
eventTicketInfoMap = Object.assign({}, awsEvents, eventTicketInfoMap);
|
|
1031
1027
|
Object.keys(eventTicketInfoMap).forEach(eventName => {
|
|
1032
1028
|
if (mktEventConfigMap[eventName] && eventTicketInfoMap[eventName].eventName) {
|
|
@@ -1036,12 +1032,10 @@ async function initActiveEvents(country = undefined) {
|
|
|
1036
1032
|
}
|
|
1037
1033
|
|
|
1038
1034
|
return Promise.all(promises).then(async () => {
|
|
1035
|
+
|
|
1039
1036
|
events.setValue(events.salesevent.INITIAL_ACTIVE_EVENTS, [Object.keys(activeEventMap)]);
|
|
1040
1037
|
|
|
1041
|
-
|
|
1042
|
-
if (Object.keys(eventTicketInfoMap).length > 0 && !country) {
|
|
1043
|
-
await _initializePolling();
|
|
1044
|
-
}
|
|
1038
|
+
await _initializePolling();
|
|
1045
1039
|
_removeWaitCheck(INITIALIZING);
|
|
1046
1040
|
});
|
|
1047
1041
|
}
|
|
@@ -1097,13 +1091,7 @@ async function _init(force = true) {
|
|
|
1097
1091
|
* If there are, make sure polling is happening, otherwise, stop polling.
|
|
1098
1092
|
*/
|
|
1099
1093
|
events.subscribe(events.salesevent.ACTIVE_EVENTS, (/*activeEvents*/) => {
|
|
1100
|
-
|
|
1101
|
-
if (Object.keys(eventTicketInfoMap).length > 0) {
|
|
1102
|
-
_initializePolling().then(() => console.log('Polling initialized'));
|
|
1103
|
-
} else {
|
|
1104
|
-
_clearPollingInterval();
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1094
|
+
_initializePolling().then(() => console.log('Polling initialized'));
|
|
1107
1095
|
});
|
|
1108
1096
|
|
|
1109
1097
|
// persistentCartService needs to wait until the following configMaps are loaded
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
import {getCachedConfiguration} from '@nuskin/configuration-sdk';
|
|
2
|
+
import {Order} from '@nuskin/order-model';
|
|
3
|
+
import {RunConfigService} from '@nuskin/ns-util';
|
|
4
|
+
import {OrderManager, CartService, OrderType, OrderAdapter} from '../shop';
|
|
5
|
+
import axios from 'axios';
|
|
6
|
+
|
|
1
7
|
let PickupUtil = function() {
|
|
2
8
|
'use strict';
|
|
3
9
|
const SERVICE_GROUP = 'SERVICE_GROUP',
|
|
@@ -15,6 +21,10 @@ let PickupUtil = function() {
|
|
|
15
21
|
UNIT = 'UNIT',
|
|
16
22
|
CARRIER_CODE = 'CARRIER_CODE';
|
|
17
23
|
|
|
24
|
+
let promise = Promise.resolve();
|
|
25
|
+
let shipMethods = [];
|
|
26
|
+
let pickupPoints = [];
|
|
27
|
+
|
|
18
28
|
/**
|
|
19
29
|
* Pickup Point shipping methods.
|
|
20
30
|
* Values are shipping method codes.
|
|
@@ -69,7 +79,7 @@ let PickupUtil = function() {
|
|
|
69
79
|
distance: distances && distances[i] ? distances[i].Value : undefined,
|
|
70
80
|
locker: lockers && lockers[i] ? lockers[i].Value : undefined,
|
|
71
81
|
unit: units && units[i] ? units[i].Value : undefined,
|
|
72
|
-
openingHours: openHours && openHours[i] ? openHours[i].Value
|
|
82
|
+
openingHours: openHours && openHours[i] ? openHours[i].Value : undefined,
|
|
73
83
|
latitude: latitudes && latitudes[i] ? parseFloat(latitudes[i].Value) : undefined,
|
|
74
84
|
longitude: longitudes && longitudes[i] ? parseFloat(longitudes[i].Value) : undefined,
|
|
75
85
|
carrierCode: carrierCodes && carrierCodes[i] ? carrierCodes[i].Value : undefined
|
|
@@ -130,12 +140,96 @@ let PickupUtil = function() {
|
|
|
130
140
|
return markers;
|
|
131
141
|
}
|
|
132
142
|
|
|
143
|
+
function getOrderValue() {
|
|
144
|
+
let value = 0;
|
|
145
|
+
const orderType = OrderManager.getOrder().orderType;
|
|
146
|
+
const cartInfo = CartService.getCartInfo();
|
|
147
|
+
|
|
148
|
+
if (orderType === OrderType.SINGLE_ORDER) {
|
|
149
|
+
value = cartInfo.totalOrderPrice;
|
|
150
|
+
} else {
|
|
151
|
+
value = cartInfo.totalOrderPrice + cartInfo.totalAdrPrice;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function getUrl() {
|
|
158
|
+
switch (RunConfigService.getEnvironmentCode()) {
|
|
159
|
+
case 'dev':
|
|
160
|
+
return 'https://ship-methods.api.dev.nuskin.com/v1';
|
|
161
|
+
case 'test':
|
|
162
|
+
return 'https://ship-methods.api.test.nuskin.com/v1';
|
|
163
|
+
case 'stage':
|
|
164
|
+
return 'https://ship-methods.api.dev.nuskin.com/v1';
|
|
165
|
+
case 'prod':
|
|
166
|
+
return 'https://ship-methods.api.nuskin.com/v1';
|
|
167
|
+
default:
|
|
168
|
+
return 'https://ship-methods.api.test.nuskin.com/v1';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function loadShipMethods() {
|
|
173
|
+
const order = Order.fromSalesOrderRequest(OrderAdapter.populateSalesOrder('SIMULATE'));
|
|
174
|
+
|
|
175
|
+
const postalCode = order.shippingPostalCode;
|
|
176
|
+
const {metapackMarket, metapackZipExclusions} = getCachedConfiguration('Checkout');
|
|
177
|
+
|
|
178
|
+
if (metapackMarket) {
|
|
179
|
+
let includePickupPoints = true;
|
|
180
|
+
for (const zipRegEx of metapackZipExclusions || []) {
|
|
181
|
+
const regEx = new RegExp(zipRegEx);
|
|
182
|
+
includePickupPoints = includePickupPoints && !postalCode.match(regEx);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const runConfig = RunConfigService.getRunConfig();
|
|
186
|
+
promise = axios.post(
|
|
187
|
+
getUrl(),
|
|
188
|
+
{
|
|
189
|
+
order,
|
|
190
|
+
pudo: includePickupPoints,
|
|
191
|
+
orderValue: getOrderValue(),
|
|
192
|
+
dangerousGoods: CartService.hasDangerousGoods(),
|
|
193
|
+
language: runConfig.language,
|
|
194
|
+
country: runConfig.country
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
headers: {
|
|
198
|
+
'Content-Type': 'application/json; charset=UTF-8'
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
).then((results) => {
|
|
202
|
+
shipMethods = results.data.shipMethods;
|
|
203
|
+
pickupPoints = results.data.pickupPoints;
|
|
204
|
+
}).catch((err) => {
|
|
205
|
+
console.log(err);
|
|
206
|
+
shipMethods = [];
|
|
207
|
+
pickupPoints = [];
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async function getShipMethods() {
|
|
213
|
+
await promise;
|
|
214
|
+
|
|
215
|
+
return shipMethods;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function getPickupPoints() {
|
|
219
|
+
await promise;
|
|
220
|
+
|
|
221
|
+
return pickupPoints;
|
|
222
|
+
}
|
|
223
|
+
|
|
133
224
|
return {
|
|
134
225
|
allMethods: shippingMethods,
|
|
135
226
|
supports: isPickupPointShippingMethod,
|
|
136
227
|
parse: parsePickupPoints,
|
|
137
228
|
bounds: getBounds,
|
|
138
|
-
markers: generateMarkers
|
|
229
|
+
markers: generateMarkers,
|
|
230
|
+
loadShipMethods,
|
|
231
|
+
getShipMethods,
|
|
232
|
+
getPickupPoints
|
|
139
233
|
}
|
|
140
234
|
}();
|
|
141
235
|
|