@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.
@@ -139,69 +139,32 @@ function getActiveTicketEvents() {
139
139
  return events;
140
140
  }
141
141
 
142
- async function getEventStatus(eventsToCheck = [], externalId = 'none') {
142
+ async function getEventStatus(eventsToCheck = []) {
143
143
  const eventStatus = {};
144
144
  const promises = [];
145
145
 
146
146
  eventsToCheck.forEach((toCheck) => {
147
- promises.push(_getTempTicket(toCheck, externalId));
147
+ promises.push(_checkForMissingTicket(toCheck));
148
148
  });
149
149
 
150
- const responses = await Promise.allSettled(promises);
150
+ await Promise.allSettled(promises);
151
151
 
152
- responses.forEach((response) => {
152
+ eventsToCheck.forEach((eventName) => {
153
153
  let activeStatus = false;
154
- if (response.status === 'fulfilled' && response.value) {
155
- const status = _decodeStatus(response.value.status);
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(() => _timerCallback(ticket.eventName), timerWait);
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(() => _timerCallback(ticket.eventName), timerWait);
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
- let now = Date.now();
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 % 3 === 0) {
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 (now > (lastTime + TIMEOUT + 3000)) {
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 = getStorageItem(activeEventsName),
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
- let response = await axios({
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
- // If there are event tickets then initialize polling
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
- if (eventTicketInfoMap) {
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.split(/\s*;\s*/) : undefined,
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