@nuskin/ns-shop 5.20.13 → 5.20.14
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 +2 -2
- package/src/cart/cartItem.js +1 -2
- package/src/cart/cartService.js +7 -23
- package/src/cart/persistentCartService.js +1 -1
- package/src/cart/productService.js +11 -20
- package/src/order/orderAdapter.js +24 -26
- package/src/payment/paymentService.js +3 -9
- package/src/payment/paymentType.js +5 -2
- package/src/shipping/ShippingService.js +8 -18
- package/src/shop.js +0 -6
- package/src/firebase/fireBaseProductService.js +0 -724
- package/src/firebase/firebaseHealthUtil.js +0 -253
- package/src/firebase/firebaseProduct.js +0 -449
- package/src/firebase/firebaseProductCallbackUtil.js +0 -72
- package/src/firebase/firebaseProductDetail.js +0 -310
- package/src/firebase/firebaseProductParser.js +0 -289
|
@@ -1,724 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
import FirebaseProduct from './firebaseProduct.js';
|
|
3
|
-
import FirebaseProductParser from './firebaseProductParser.js';
|
|
4
|
-
import FirebaseProductCallbackUtil from './firebaseProductCallbackUtil.js';
|
|
5
|
-
import {ConfigService, LocalStorageUtil, nuskin} from '@nuskin/ns-util';
|
|
6
|
-
import {UserService} from '@nuskin/ns-account';
|
|
7
|
-
import ShopContextService from '../shopContext.js';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* FireBaseProductService
|
|
12
|
-
*
|
|
13
|
-
* @namespace FireBaseProductService
|
|
14
|
-
*/
|
|
15
|
-
let FireBaseProductService = function(){
|
|
16
|
-
let PRODUCT_MARKET_STORAGE_KEY = 'products';
|
|
17
|
-
let PRODUCT_DATA_STORED_VERSION = 'version';
|
|
18
|
-
let MIN_SKU_LENGTH_FOR_SEARCH = 4;
|
|
19
|
-
let MAX_SKU_LENGTH = 8;
|
|
20
|
-
let MAX_MARKETS_TO_STORE = 2;
|
|
21
|
-
let MIN_LOCAL_STORAGE_TO_MAINTAIN_BYTES = 20842;
|
|
22
|
-
|
|
23
|
-
let loadedFromApache = false;
|
|
24
|
-
let productDataInMemory;
|
|
25
|
-
let synonyms;
|
|
26
|
-
let isSynonymsBusy = false;
|
|
27
|
-
nuskin.firebaseProductService = {};
|
|
28
|
-
|
|
29
|
-
// ---------------------------------------------
|
|
30
|
-
//
|
|
31
|
-
// Public Methods
|
|
32
|
-
//
|
|
33
|
-
// ---------------------------------------------
|
|
34
|
-
var publicMethods = {
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Returns the required endpoint headers for service calls
|
|
38
|
-
* @memberof FireBaseProductService
|
|
39
|
-
* @example
|
|
40
|
-
* FireBaseProductService.clearStoredProductData()
|
|
41
|
-
*/
|
|
42
|
-
clearStoredProductData: function(){
|
|
43
|
-
localStorage.removeItem(PRODUCT_MARKET_STORAGE_KEY);
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Returns the required endpoint headers for service calls
|
|
48
|
-
* @memberof FireBaseProductService
|
|
49
|
-
* @example
|
|
50
|
-
* FireBaseProductService.clearStoredProductDataForMarket(market)
|
|
51
|
-
* @param {string} market
|
|
52
|
-
*/
|
|
53
|
-
clearStoredProductDataForMarket: function(market){
|
|
54
|
-
let productData = localStorage.getItem(PRODUCT_MARKET_STORAGE_KEY);
|
|
55
|
-
if (productData){
|
|
56
|
-
let product = JSON.parse(productData);
|
|
57
|
-
if (product[market]) {
|
|
58
|
-
delete product[market];
|
|
59
|
-
localStorage.setItem(PRODUCT_MARKET_STORAGE_KEY, JSON.stringify(product));
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Read Firebase product data from Firebase and store the data into local storage
|
|
66
|
-
* @memberof FireBaseProductService
|
|
67
|
-
* @example
|
|
68
|
-
* FireBaseProductService.loadProducts(market, language, callBack)
|
|
69
|
-
* @param {string} market
|
|
70
|
-
*/
|
|
71
|
-
loadProducts: function(market, language, callBack){
|
|
72
|
-
updateProductData(market, language, callBack);
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Return all firebase products for a market from local storage.
|
|
77
|
-
* @memberof FireBaseProductService
|
|
78
|
-
* @example
|
|
79
|
-
* FireBaseProductService.getProducts(market, language)
|
|
80
|
-
* @returns {object} productList
|
|
81
|
-
*/
|
|
82
|
-
getProducts: function(market, language) {
|
|
83
|
-
return getFilteredProducts(market, language);
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Return all firebase product from local storage that match the search term, then call a callback function.
|
|
88
|
-
* This method is used by the cart search drop down.
|
|
89
|
-
* @memberof FireBaseProductService
|
|
90
|
-
* @example
|
|
91
|
-
* FireBaseProductService.getProductsBySearchTerm(searchTerm, market, language, callbackFn)
|
|
92
|
-
* @param {string} searchTerm
|
|
93
|
-
*/
|
|
94
|
-
getProductsBySearchTerm: function(searchTerm, market, language, callbackFn) {
|
|
95
|
-
let throwOutFreeProducts = true;
|
|
96
|
-
let synonymCallback = function () {
|
|
97
|
-
callbackFn({
|
|
98
|
-
success: true,
|
|
99
|
-
products: getFilteredProducts(market, language, searchTerm, throwOutFreeProducts)
|
|
100
|
-
});
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
if (!isProductDataStoredForMarketAndLanguage(market, language)){
|
|
104
|
-
let callBack = function(){
|
|
105
|
-
// todo Make sure the synonyms are loaded first.
|
|
106
|
-
insureSynonyms(synonymCallback);
|
|
107
|
-
};
|
|
108
|
-
updateProductData(market, language, callBack);
|
|
109
|
-
}
|
|
110
|
-
else{
|
|
111
|
-
// todo Make sure the synonyms are loaded first.
|
|
112
|
-
insureSynonyms(synonymCallback);
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Return a firebase product for the given sku if it exists. This call may not give you anything if the firebase product data is not populated yet.
|
|
118
|
-
* @memberof FireBaseProductService
|
|
119
|
-
* @example
|
|
120
|
-
* FireBaseProductService.getProductBySku(productSku, market, language)
|
|
121
|
-
* @returns {object} product
|
|
122
|
-
*/
|
|
123
|
-
getProductBySku: function(productSku, market, language){
|
|
124
|
-
let product;
|
|
125
|
-
|
|
126
|
-
if (isProductDataStoredForMarketAndLanguage(market, language)) {
|
|
127
|
-
try {
|
|
128
|
-
let products = JSON.parse(getStoredProductData());
|
|
129
|
-
let marketProducts = products[market];
|
|
130
|
-
|
|
131
|
-
if (marketProducts) {
|
|
132
|
-
let parser = new FirebaseProductParser(productSku, language, marketProducts[productSku]);
|
|
133
|
-
if (parser.doesLanguageExistForProduct(language) && parser.doesMarketDataAndPricingExistForProduct()) {
|
|
134
|
-
let user = UserService.getUser();
|
|
135
|
-
let priceType = ShopContextService.getPriceType(false, user); // used to set the price and formattedPrice on the products.
|
|
136
|
-
|
|
137
|
-
product = new FirebaseProduct(parser, priceType, market, user);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}catch(e){
|
|
141
|
-
console.log("Exception thrown in getProductBySku -> " + e);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return product;
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Get Product By Sku Using CB
|
|
150
|
-
* @memberof FireBaseProductService
|
|
151
|
-
* @example
|
|
152
|
-
* FireBaseProductService.getProductBySkuUsingCB(productSku, market, language, callbackFn)
|
|
153
|
-
* @param {string} productSku
|
|
154
|
-
*/
|
|
155
|
-
getProductBySkuUsingCB: function(productSku, market, language, callbackFn){
|
|
156
|
-
if (!isProductDataStoredForMarketAndLanguage(market, language)){
|
|
157
|
-
let callBack = function(){
|
|
158
|
-
callbackFn(publicMethods.getProductBySku(productSku, market, language));
|
|
159
|
-
};
|
|
160
|
-
updateProductData(market, language, callBack);
|
|
161
|
-
}
|
|
162
|
-
else{
|
|
163
|
-
callbackFn(publicMethods.getProductBySku(productSku, market, language));
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
|
|
167
|
-
getLoadedFromApache: function() {
|
|
168
|
-
return loadedFromApache;
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
// ---------------------------------------------
|
|
173
|
-
//
|
|
174
|
-
// Private Methods
|
|
175
|
-
//
|
|
176
|
-
// ---------------------------------------------
|
|
177
|
-
// Return all firebase products from local storage that match the search term and market. If no search term is
|
|
178
|
-
// specified we return all products for the market.
|
|
179
|
-
function getFilteredProducts(market, language, searchTerm, throwOutFreeProducts) {
|
|
180
|
-
let productList = [];
|
|
181
|
-
if (isProductDataStoredForMarketAndLanguage(market, language)){
|
|
182
|
-
try {
|
|
183
|
-
let products = JSON.parse(getStoredProductData());
|
|
184
|
-
var marketProducts = products[market];
|
|
185
|
-
|
|
186
|
-
if (marketProducts) {
|
|
187
|
-
let user = nuskin.newAccount.UserService.getUser();
|
|
188
|
-
let priceType = ShopContextService.getPriceType(false, user); // priceType is used to set the price to be used on the products.
|
|
189
|
-
let product;
|
|
190
|
-
let parser;
|
|
191
|
-
|
|
192
|
-
// build up product objects for cart product list.
|
|
193
|
-
for (let productSku in marketProducts) {
|
|
194
|
-
// Make sure it is a sku and not the data version.
|
|
195
|
-
if (productSku !== PRODUCT_DATA_STORED_VERSION) {
|
|
196
|
-
parser = new FirebaseProductParser(productSku, language, marketProducts[productSku]);
|
|
197
|
-
if (parser.doesLanguageExistForProduct(language) && parser.doesMarketDataAndPricingExistForProduct()) {
|
|
198
|
-
product = new FirebaseProduct(parser, priceType, market, user);
|
|
199
|
-
|
|
200
|
-
// Only look at adding a product to the result if we are not throwing out free products.
|
|
201
|
-
if (!(throwOutFreeProducts && product.price === 0.00)){
|
|
202
|
-
if (searchTerm){
|
|
203
|
-
if (canDisplayProduct(product, searchTerm, language, user)){
|
|
204
|
-
productList.push(product);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
else{
|
|
208
|
-
productList.push(product);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
} catch(e){
|
|
216
|
-
console.log("Exception thrown in getProductBySku -> " + e);
|
|
217
|
-
productList = [];
|
|
218
|
-
}
|
|
219
|
-
if (productList.length == 0) {
|
|
220
|
-
logNoProductsMatched(marketProducts.version, searchTerm, language);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return sortProductsBasedOnWeightedSkus(productList);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function updateProductData(market, language, callBack){
|
|
227
|
-
try {
|
|
228
|
-
// Get the latest version for the data in Firebase.
|
|
229
|
-
let FIREBASE_DATA_VERSION_URL = ConfigService.getMarketConfig().nsurl_firebase + "/version.json";
|
|
230
|
-
let firebaseDataVersionUrl = FIREBASE_DATA_VERSION_URL.replace('{market}', market.toUpperCase());
|
|
231
|
-
|
|
232
|
-
$.ajax({
|
|
233
|
-
url: firebaseDataVersionUrl,
|
|
234
|
-
type: "GET",
|
|
235
|
-
crossDomain: true,
|
|
236
|
-
async:false,
|
|
237
|
-
success: function (version) {
|
|
238
|
-
if (version !== null) {
|
|
239
|
-
// If we don't have any firebase data in local storage we read the data from firebase and store it.
|
|
240
|
-
if (!isProductDataStoredForMarketAndLanguage(market, language)) {
|
|
241
|
-
writeFirebaseProducts(market, language, version, callBack);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Else we need to make sure the version in firebase is the same version that we have stored locally.
|
|
245
|
-
else {
|
|
246
|
-
let products = JSON.parse(getStoredProductData());
|
|
247
|
-
let marketProducts = products[market];
|
|
248
|
-
|
|
249
|
-
if (marketProducts) {
|
|
250
|
-
let versionOfStoredData = marketProducts[PRODUCT_DATA_STORED_VERSION];
|
|
251
|
-
|
|
252
|
-
// If versions are not equal the stored data is to old.
|
|
253
|
-
if (version !== null && version !== versionOfStoredData) {
|
|
254
|
-
let refreshPageCallback = function(){
|
|
255
|
-
location.reload();
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
// Clear out the old data for the market.
|
|
259
|
-
publicMethods.clearStoredProductDataForMarket(market);
|
|
260
|
-
|
|
261
|
-
// Download and store the updated data.
|
|
262
|
-
writeFirebaseProducts(market, language, version);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
if (callBack) {
|
|
267
|
-
callBack();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// We can't read the Firebase product data version, Firebase might be down.
|
|
273
|
-
else{
|
|
274
|
-
// Try to load data from apache unless we have local storage or local memory.
|
|
275
|
-
console.log("Can't read Firebase product data. Attempting to update from Apache");
|
|
276
|
-
|
|
277
|
-
if (!isProductDataStoredForMarketAndLanguage(market, language)) {
|
|
278
|
-
updateProductDataFromApache(market, language, callBack);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
error: function(xhr) {
|
|
283
|
-
// Firebase had a major error. Try to load data from apache unless we have local storage or local memory.
|
|
284
|
-
if (xhr) {
|
|
285
|
-
console.log("Could not get Firebase version number. Attempting to update from Apache:" + xhr.statusText);
|
|
286
|
-
}
|
|
287
|
-
else {
|
|
288
|
-
console.log("Could not get Firebase version number. Attempting to update from Apache.");
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
if (!isProductDataStoredForMarketAndLanguage(market, language)) {
|
|
292
|
-
updateProductDataFromApache(market, language, callBack);
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
} catch (e) {
|
|
298
|
-
return null;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
function updateProductDataFromApache(market, language, callBack){
|
|
303
|
-
try {
|
|
304
|
-
let APACHE_PRODUCT_DATA_URL = ConfigService.getMarketConfig().nsurl_apache;
|
|
305
|
-
let apacheProductDataUrl = APACHE_PRODUCT_DATA_URL.replace('{market}', market.toUpperCase());
|
|
306
|
-
let loadTime = Date.now();
|
|
307
|
-
|
|
308
|
-
$.ajax({
|
|
309
|
-
url: apacheProductDataUrl,
|
|
310
|
-
type: "GET",
|
|
311
|
-
crossDomain: true,
|
|
312
|
-
async:false,
|
|
313
|
-
success: function (productData) {
|
|
314
|
-
// If we don't have any product data in local storage or local memory we read the data from apache and store it.
|
|
315
|
-
loadTime = Date.now() - loadTime;
|
|
316
|
-
if (productData){
|
|
317
|
-
logProductLoadAnalytics(productData, loadTime, false);
|
|
318
|
-
writeProductDataToLocalStorage(market, language, productData, -1);
|
|
319
|
-
loadedFromApache = true;
|
|
320
|
-
if (callBack) {
|
|
321
|
-
callBack();
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
},
|
|
325
|
-
error: function(xhr) {
|
|
326
|
-
// Accessing Apache product data failed.
|
|
327
|
-
if (xhr){
|
|
328
|
-
console.log("Could not get Apache product data:"+xhr.statusText);
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
console.log("Could not get Apache product data.");
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
} catch (e) {
|
|
337
|
-
return null;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
function isProductDataStoredForMarketAndLanguage(market, language){
|
|
342
|
-
let dataStored = false;
|
|
343
|
-
let localStorageProductData = localStorage.getItem(PRODUCT_MARKET_STORAGE_KEY);
|
|
344
|
-
let productData;
|
|
345
|
-
|
|
346
|
-
// Check to see if the data is stored for the market in local storage.
|
|
347
|
-
if (localStorageProductData && localStorageProductData !== "{}"){
|
|
348
|
-
productData = JSON.parse(localStorageProductData);
|
|
349
|
-
|
|
350
|
-
// Check for the existence of the market and also sku's within the market.
|
|
351
|
-
dataStored = productData[market] !== undefined && Object.keys(productData[market]).length > 1;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
// Check to see if the data is stored for the market in memory.
|
|
355
|
-
if (!dataStored && productDataInMemory){
|
|
356
|
-
productData = JSON.parse(productDataInMemory);
|
|
357
|
-
|
|
358
|
-
// Check for the existence of the market and also sku's within the market.
|
|
359
|
-
dataStored = productData[market] !== undefined && Object.keys(productData[market]).length > 1;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
// Check to see if the data stored for the market is for the correct language.
|
|
363
|
-
if (dataStored){
|
|
364
|
-
let productExistsForLanguage;
|
|
365
|
-
|
|
366
|
-
for (let sku in productData[market]){
|
|
367
|
-
productExistsForLanguage = productData[market][sku].languages[language] !== undefined;
|
|
368
|
-
break;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
dataStored = dataStored && productExistsForLanguage;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
return dataStored;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
function getStoredProductData(){
|
|
378
|
-
let productData = localStorage.getItem(PRODUCT_MARKET_STORAGE_KEY);
|
|
379
|
-
if ((!productData || productData === "{}") && productDataInMemory){
|
|
380
|
-
productData = productDataInMemory;
|
|
381
|
-
}
|
|
382
|
-
return productData;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
function writeFirebaseProducts(market, language, version, callbackFn) {
|
|
386
|
-
// Only write the data if there is a version.
|
|
387
|
-
if (version) {
|
|
388
|
-
try {
|
|
389
|
-
if (!isProductDataStoredForMarketAndLanguage(market, language)) {
|
|
390
|
-
FirebaseProductCallbackUtil.addCallbackForMarket(market, callbackFn);
|
|
391
|
-
|
|
392
|
-
if (!FirebaseProductCallbackUtil.isProductDataDownLoadInProcess(market)) {
|
|
393
|
-
FirebaseProductCallbackUtil.setProductDataDownloadInProcess(market, true);
|
|
394
|
-
|
|
395
|
-
let FIREBASE_DATA_FOR_VERSION_URL = ConfigService.getMarketConfig().nsurl_firebase + ".json?version={version}";
|
|
396
|
-
let firebaseUrl = FIREBASE_DATA_FOR_VERSION_URL.replace('{market}', market.toUpperCase()).replace('{version}', version);
|
|
397
|
-
let loadTime = Date.now();
|
|
398
|
-
|
|
399
|
-
$.ajax({
|
|
400
|
-
url: firebaseUrl,
|
|
401
|
-
type: "GET",
|
|
402
|
-
crossDomain: true,
|
|
403
|
-
success: function (productData) {
|
|
404
|
-
loadTime = Date.now() - loadTime;
|
|
405
|
-
logProductLoadAnalytics(productData, loadTime, true);
|
|
406
|
-
writeProductDataToLocalStorage(market, language, productData, version);
|
|
407
|
-
|
|
408
|
-
FirebaseProductCallbackUtil.setProductDataDownloadInProcess(market, false);
|
|
409
|
-
},
|
|
410
|
-
error: function (xhr) {
|
|
411
|
-
if (xhr){
|
|
412
|
-
console.log("Could not get Firebase product data:" + xhr.statusText);
|
|
413
|
-
}
|
|
414
|
-
else {
|
|
415
|
-
console.log("Could not get Firebase product data.");
|
|
416
|
-
}
|
|
417
|
-
FirebaseProductCallbackUtil.setProductDataDownloadInProcess(market, false);
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
} catch (e) {
|
|
423
|
-
FirebaseProductCallbackUtil.setProductDataDownloadInProcess(market, false);
|
|
424
|
-
return null;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
function logProductLoadAnalytics(products, ajaxTime, fromFirebase) {
|
|
430
|
-
if (ConfigService.getMarketConfig().enableProductDownloadTracking) {
|
|
431
|
-
let productsString = JSON.stringify(products),
|
|
432
|
-
metricName = fromFirebase ? "firebase" : "apache";
|
|
433
|
-
|
|
434
|
-
nuskin.firebaseProductMetrics = {
|
|
435
|
-
requestTime: ajaxTime,
|
|
436
|
-
version: new Date(products.version).toLocaleString(),
|
|
437
|
-
productsSize: LocalStorageUtil.getByteLength(productsString + PRODUCT_MARKET_STORAGE_KEY)
|
|
438
|
-
};
|
|
439
|
-
trackIt(metricName);
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
function logLocalStorageWriteError(version, dataSize) {
|
|
444
|
-
if (ConfigService.getMarketConfig().enableLocalstorageErrorTracking) {
|
|
445
|
-
nuskin.firebaseProductMetrics = {
|
|
446
|
-
version: new Date(version).toLocaleString(),
|
|
447
|
-
productsSize: dataSize
|
|
448
|
-
};
|
|
449
|
-
trackIt('localstorageError');
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function logNoProductsMatched(version, searchTerm, language) {
|
|
454
|
-
if (ConfigService.getMarketConfig().enableEmptySearchTracking) {
|
|
455
|
-
nuskin.firebaseProductMetrics = {
|
|
456
|
-
version: new Date(version).toLocaleString(),
|
|
457
|
-
searchTerm: searchTerm,
|
|
458
|
-
language: language
|
|
459
|
-
};
|
|
460
|
-
trackIt('noSearchResult');
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
function trackIt(name) {
|
|
465
|
-
if (typeof _satellite !== "undefined" && _satellite) {
|
|
466
|
-
_satellite.track(name);
|
|
467
|
-
}
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
function writeProductDataToLocalStorage(market, language, firebaseProductData, version){
|
|
471
|
-
firebaseProductData = removeSuperfluousLanguageNodes(firebaseProductData, language);
|
|
472
|
-
|
|
473
|
-
// Make sure that we will only have the maximum allowed amount of product data stored after the write.
|
|
474
|
-
insureMaxMarketsStoredInLocalStorage(market);
|
|
475
|
-
|
|
476
|
-
// Get all the storage data for all markets stored.
|
|
477
|
-
let storageObject = getStoredProductData();
|
|
478
|
-
|
|
479
|
-
if (storageObject){
|
|
480
|
-
storageObject = JSON.parse(storageObject);
|
|
481
|
-
}
|
|
482
|
-
else{
|
|
483
|
-
storageObject = {};
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// Add the firebase data for a particular market.
|
|
487
|
-
storageObject[market] = firebaseProductData;
|
|
488
|
-
|
|
489
|
-
// Write the version for the data was written.
|
|
490
|
-
storageObject[market][PRODUCT_DATA_STORED_VERSION] = version;
|
|
491
|
-
|
|
492
|
-
// Try to write the products to local storage
|
|
493
|
-
try {
|
|
494
|
-
localStorage.setItem(PRODUCT_MARKET_STORAGE_KEY, JSON.stringify(storageObject));
|
|
495
|
-
|
|
496
|
-
// Make sure we have enough local storage left for the cart to work. If we don't we need to delete the
|
|
497
|
-
// products for all markets and try again.
|
|
498
|
-
if (LocalStorageUtil.getRemainingLocalStorage() < MIN_LOCAL_STORAGE_TO_MAINTAIN_BYTES){
|
|
499
|
-
publicMethods.clearStoredProductData();
|
|
500
|
-
localStorage.setItem(PRODUCT_MARKET_STORAGE_KEY, JSON.stringify(storageObject));
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
catch(e){
|
|
504
|
-
// We don't have enough memory in local storage to write the Firebase products.
|
|
505
|
-
try {
|
|
506
|
-
// Sense there was an error, dump all the product data and try to write it again.
|
|
507
|
-
publicMethods.clearStoredProductData();
|
|
508
|
-
localStorage.setItem(PRODUCT_MARKET_STORAGE_KEY, JSON.stringify(storageObject));
|
|
509
|
-
}
|
|
510
|
-
catch(x){
|
|
511
|
-
// We still can't write the data, store it as a variable and use it from there.
|
|
512
|
-
console.log("Still can't write the data. Using local variable.");
|
|
513
|
-
console.log(x);
|
|
514
|
-
productDataInMemory = JSON.stringify(storageObject);
|
|
515
|
-
logLocalStorageWriteError(firebaseProductData.version, LocalStorageUtil.getByteLength(productDataInMemory + PRODUCT_MARKET_STORAGE_KEY));
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
// Make sure we have enough local storage left for the cart to work. If we don't we need to delete the
|
|
520
|
-
// products for the market we just wrote from local storage and just use RAM as the product store.
|
|
521
|
-
if (LocalStorageUtil.getRemainingLocalStorage() < MIN_LOCAL_STORAGE_TO_MAINTAIN_BYTES){
|
|
522
|
-
publicMethods.clearStoredProductDataForMarket(market);
|
|
523
|
-
|
|
524
|
-
console.log("Not enough local storage for cart and products. Using local variable.");
|
|
525
|
-
productDataInMemory = JSON.stringify(storageObject);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
function canDisplayProduct(product, searchTerm, language, user){
|
|
530
|
-
let canDisplay = false;
|
|
531
|
-
|
|
532
|
-
if (product.available && product.searchable && product.lang === language && testMatchCustomerType(product, user)) {
|
|
533
|
-
if (testMatchString(product.title, searchTerm) || // Match title
|
|
534
|
-
testMatchString(product.shortDescr, searchTerm) || // Match short description
|
|
535
|
-
testMatchSKU(product.sku, searchTerm)) { // Match SKU
|
|
536
|
-
canDisplay = true;
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
return canDisplay;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
function testMatchString(searchString, searchTerm){
|
|
543
|
-
let match;
|
|
544
|
-
|
|
545
|
-
// Check the string first for a match
|
|
546
|
-
match = searchString.toLowerCase().indexOf(searchTerm.toLowerCase()) !== -1;
|
|
547
|
-
|
|
548
|
-
// If no match, try the synonyms.
|
|
549
|
-
if (!match){
|
|
550
|
-
let synonym = synonyms[searchTerm];
|
|
551
|
-
if (synonym) {
|
|
552
|
-
match = searchString.toLowerCase().indexOf(synonym.toLowerCase()) !== -1;
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
return match;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
function testMatchSKU(sku, searchTerm){
|
|
560
|
-
return searchTerm.length >= MIN_SKU_LENGTH_FOR_SEARCH &&
|
|
561
|
-
searchTerm.length <= MAX_SKU_LENGTH &&
|
|
562
|
-
sku.indexOf(searchTerm) === 0;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
function testMatchCustomerType(product, user){
|
|
566
|
-
let match = false;
|
|
567
|
-
|
|
568
|
-
// Here are the rules.
|
|
569
|
-
// 1. Users with customer types of 20's or 30's are treated the same.
|
|
570
|
-
// 2. If the user is not logged in, we show the product if it is not for distributors (10's) only;
|
|
571
|
-
|
|
572
|
-
if (ConfigService.getMarketConfig().ignoreCustomerTypes){
|
|
573
|
-
match = true;
|
|
574
|
-
}
|
|
575
|
-
else if (product.isCustomer() || product.isPreferredCustomer()){
|
|
576
|
-
match = true;
|
|
577
|
-
}
|
|
578
|
-
else if (product.isDistributor()){
|
|
579
|
-
if (user) {
|
|
580
|
-
match = user.isDistributor();
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
else{
|
|
584
|
-
match = true;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
return match;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
function sortProductsBasedOnWeightedSkus(productList){
|
|
591
|
-
let weightedSkuArray = ConfigService.getMarketConfig().weightedSkus;
|
|
592
|
-
|
|
593
|
-
if (weightedSkuArray){
|
|
594
|
-
let weightedProductsHashtable = new $.Hashtable();
|
|
595
|
-
let weightedProducts = [];
|
|
596
|
-
let nonWeightedProducts = [];
|
|
597
|
-
|
|
598
|
-
// Load the sku weighted test hashtable
|
|
599
|
-
let skuWeightedHashtable = new $.Hashtable();
|
|
600
|
-
for (let sortOrder=0;sortOrder<weightedSkuArray.length;sortOrder++){
|
|
601
|
-
skuWeightedHashtable.add(weightedSkuArray[sortOrder], sortOrder);
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
// Sort between weighted and non weighted sku products.
|
|
605
|
-
for (let i=0;i<productList.length;i++){
|
|
606
|
-
if (skuWeightedHashtable.containsKey(productList[i].sku)){
|
|
607
|
-
// Stuff the products in a hashtable for sorting later on.
|
|
608
|
-
weightedProductsHashtable.add(productList[i].sku, productList[i]);
|
|
609
|
-
}
|
|
610
|
-
else{
|
|
611
|
-
nonWeightedProducts.push(productList[i]);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
// Sort the products based on how they are in the weighted sku array.
|
|
616
|
-
let product;
|
|
617
|
-
for (let j=0;j<weightedSkuArray.length;j++){
|
|
618
|
-
product = weightedProductsHashtable.get(weightedSkuArray[j]);
|
|
619
|
-
if (product){
|
|
620
|
-
weightedProducts.push(product);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
// Append the sorted product arrays.
|
|
625
|
-
productList = [];
|
|
626
|
-
productList = productList.concat(weightedProducts, nonWeightedProducts);
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
return productList;
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
function insureMaxMarketsStoredInLocalStorage(market){
|
|
633
|
-
if (market){
|
|
634
|
-
let productData = localStorage.getItem(PRODUCT_MARKET_STORAGE_KEY);
|
|
635
|
-
if (productData && productData !== '{}') {
|
|
636
|
-
let marketsInLocalStorage = Object.keys(JSON.parse(productData));
|
|
637
|
-
|
|
638
|
-
if (marketsInLocalStorage.length === MAX_MARKETS_TO_STORE) {
|
|
639
|
-
// Delete the market key from "markets in local storage" array.
|
|
640
|
-
let indexOfMarket = marketsInLocalStorage.indexOf(market);
|
|
641
|
-
|
|
642
|
-
if (indexOfMarket === 0) {
|
|
643
|
-
publicMethods.clearStoredProductDataForMarket(marketsInLocalStorage[1]);
|
|
644
|
-
}
|
|
645
|
-
else {
|
|
646
|
-
publicMethods.clearStoredProductDataForMarket(marketsInLocalStorage[0]);
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
function insureSynonyms(callback) {
|
|
654
|
-
if (!isSynonymsBusy) {
|
|
655
|
-
if (!synonyms) {
|
|
656
|
-
isSynonymsBusy = true;
|
|
657
|
-
let protocol = nuskin.util.Url.getProtocol(window.location.href);
|
|
658
|
-
let host = nuskin.util.Url.getHost(window.location.href);
|
|
659
|
-
|
|
660
|
-
let url = protocol + '//' + host + "/apps/products/services/synonyms";
|
|
661
|
-
let promise = $.ajax({
|
|
662
|
-
url: url
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
promise.done(function (data) {
|
|
666
|
-
synonyms = data;
|
|
667
|
-
callback();
|
|
668
|
-
isSynonymsBusy = false;
|
|
669
|
-
});
|
|
670
|
-
promise.fail(function () {
|
|
671
|
-
if (typeof firebaseConfig !== "undefined") {
|
|
672
|
-
synonyms = firebaseConfig.synonyms;
|
|
673
|
-
}
|
|
674
|
-
isSynonymsBusy = false;
|
|
675
|
-
});
|
|
676
|
-
}
|
|
677
|
-
else {
|
|
678
|
-
callback();
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
function removeSuperfluousLanguageNodes(productData, language){
|
|
684
|
-
let tempLanguagesNode;
|
|
685
|
-
let tempLanguageNode;
|
|
686
|
-
let tempPricing;
|
|
687
|
-
let sku;
|
|
688
|
-
let skusToBeRemoved = [];
|
|
689
|
-
|
|
690
|
-
for (sku in productData) {
|
|
691
|
-
if (sku !== 'version') {
|
|
692
|
-
// Get the language node for the current selected language
|
|
693
|
-
tempLanguagesNode = productData[sku].languages;
|
|
694
|
-
tempLanguageNode = undefined;
|
|
695
|
-
if (tempLanguagesNode !== undefined){
|
|
696
|
-
tempLanguageNode = productData[sku].languages[language];
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
tempPricing = productData[sku].priceMap;
|
|
700
|
-
|
|
701
|
-
// We only store products in local storage if they have the language of interest and pricing.
|
|
702
|
-
if (tempLanguageNode !== undefined && tempPricing !== undefined) {
|
|
703
|
-
productData[sku].languages = {};
|
|
704
|
-
productData[sku].languages[language] = tempLanguageNode;
|
|
705
|
-
}
|
|
706
|
-
else {
|
|
707
|
-
// Add this sku to the list of sku's to be removed from the product data.
|
|
708
|
-
skusToBeRemoved.push(sku);
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
|
|
713
|
-
// Remove all the skus that don't have the desired language
|
|
714
|
-
for (let i=0; i< skusToBeRemoved.length; i++){
|
|
715
|
-
delete productData[skusToBeRemoved[i]];
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
return productData;
|
|
719
|
-
}
|
|
720
|
-
|
|
721
|
-
return publicMethods;
|
|
722
|
-
}();
|
|
723
|
-
|
|
724
|
-
export default FireBaseProductService;
|