@nuskin/ns-product-lib 2.7.0-cx24-337701.1 → 2.7.0-cx24-337703.1

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/CHANGELOG.md CHANGED
@@ -1,125 +1,52 @@
1
- # [2.7.0-cx24-337701.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.15...v2.7.0-cx24-337701.1) (2023-03-22)
1
+ # [2.7.0-cx24-337703.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.2-cx24-337703.1...v2.7.0-cx24-337703.1) (2023-03-22)
2
2
 
3
3
 
4
- ### Fix
5
-
6
- * Lint Errors after merge ([86f07a8](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/86f07a8b27e5f772d364ec40c1c0014f534f0312))
7
-
8
4
  ### Update
9
5
 
10
- * Merge CX24-3563 changes to CX24-337701 ([9daed9a](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/9daed9a062d42b0de11fcc0a56d65f37cfd6ec17))
11
-
12
- ## [2.6.1-cx24-337701.15](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.14...v2.6.1-cx24-337701.15) (2023-03-21)
13
-
14
-
15
- ### Fix
16
-
17
- * Show dropdown for variants ([8edac62](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/8edac62b88fe058fe232e9c8c9da557351c10338))
18
-
19
- ## [2.6.1-cx24-337701.14](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.13...v2.6.1-cx24-337701.14) (2023-03-21)
20
-
21
-
22
- ### Fix
23
-
24
- * Show dropdown for variants ([cf5e6a6](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/cf5e6a600008465d32b0d77ed46f8518802f4295))
25
- * Show dropdown for variants ([8c29f14](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/8c29f14e20e9f674c8942274607abd1dd4f82964))
26
-
27
- ## [2.6.1-cx24-337701.13](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.12...v2.6.1-cx24-337701.13) (2023-03-20)
28
-
29
-
30
- ### Fix
31
-
32
- * multi variant drop down ([4c61780](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/4c617806a2934b1aca7b5280810107cf0356b29b))
33
-
34
- ## [2.6.1-cx24-337701.12](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.11...v2.6.1-cx24-337701.12) (2023-03-20)
35
-
36
-
37
- ### Fix
38
-
39
- * The variant drop down label ([235a252](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/235a252cd59a94704400743e51d043d2ca2b9074))
40
- * The variant drop down label ([e43614e](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/e43614ece7f3bb7d8c0d12743ab02b90427cbbb9))
41
-
42
- ## [2.6.1-cx24-337701.11](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.10...v2.6.1-cx24-337701.11) (2023-03-20)
43
-
44
-
45
- ### Fix
46
-
47
- * The variant drop down label ([de58922](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/de589221aee054cbfb765117a44cd2fca4575468))
48
-
49
- ## [2.6.1-cx24-337701.10](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.9...v2.6.1-cx24-337701.10) (2023-03-20)
50
-
51
-
52
- ### Fix
53
-
54
- * The variant drop down label ([a93900f](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/a93900f43e880b52383ea22df8d496f97be21535))
55
- * The variant drop down label ([20bc315](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/20bc315ba14213d5e18101c9016d3d07da14843a))
56
- * The variant drop down label ([8bb8f1c](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/8bb8f1c11626645d2cd4ca1a4db29f75b99dff7b))
57
-
58
- ## [2.6.1-cx24-337701.9](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.8...v2.6.1-cx24-337701.9) (2023-03-20)
59
-
60
-
61
- ### Fix
62
-
63
- * The variant drop down label ([a35121b](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/a35121b96fb7d0e62119e4bebea9d513cd2e8814))
64
-
65
- ## [2.6.1-cx24-337701.8](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.7...v2.6.1-cx24-337701.8) (2023-03-20)
66
-
67
-
68
- ### Fix
69
-
70
- * The variant drop down label ([226e964](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/226e96475b26ef4eda94ac63028285f27c9a81ba))
71
-
72
- ## [2.6.1-cx24-337701.7](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.6...v2.6.1-cx24-337701.7) (2023-03-20)
73
-
74
-
75
- ### Fix
76
-
77
- * The variant drop down label ([0406e11](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/0406e11e1fa9aa71313b80fae06c9e8bd8d406d8))
6
+ * Merge CX24-3563 changes to CX24-337703 ([9e6ca40](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/9e6ca40c35252c24394351275a234e9847f70bfc))
78
7
 
79
- ## [2.6.1-cx24-337701.6](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.5...v2.6.1-cx24-337701.6) (2023-03-20)
8
+ ## [2.6.2-cx24-337703.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1...v2.6.2-cx24-337703.1) (2023-03-22)
80
9
 
81
10
 
82
11
  ### Fix
83
12
 
84
- * The variant drop down label ([738b2a4](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/738b2a41ab2fc2900529234b3fa860f9102fc36d))
85
- * The variant drop down label ([58af789](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/58af78921e2eff83beffd6b5665aff6d60bbb21b))
13
+ * Show dropdown for variants ([85cdf69](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/85cdf69cc2bbf6700ec5c9bcacc7222cf2ddf674))
86
14
 
87
- ## [2.6.1-cx24-337701.5](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.4...v2.6.1-cx24-337701.5) (2023-03-19)
15
+ ## [2.6.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.0...v2.6.1) (2023-03-16)
88
16
 
89
17
 
90
18
  ### Fix
91
19
 
92
- * The variant drop down label ([2e175c1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/2e175c12f24b789f913e64fff5e26b3257ccd087))
20
+ * (equinox-enabled) skip product mapping when an error occurs in PLP #CX24-3607 ([454eaf3](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/454eaf3b899e27f1feaeda383553eb13dcb8b205)), closes [#CX24-3607](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3607)
93
21
 
94
- ## [2.6.1-cx24-337701.4](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.3...v2.6.1-cx24-337701.4) (2023-03-19)
22
+ ## [2.6.1-cx24-3607.4](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-3607.3...v2.6.1-cx24-3607.4) (2023-03-16)
95
23
 
96
24
 
97
25
  ### Fix
98
26
 
99
- * The variant drop down label ([71faac8](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/71faac8db3a4a03d1addcda266b21616c5b0f044))
27
+ * The variant drop down label ([3e6b9f5](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/3e6b9f5e422b71c3e5f73d5a62f0491343ed7afb))
100
28
 
101
- ## [2.6.1-cx24-337701.3](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.2...v2.6.1-cx24-337701.3) (2023-03-19)
29
+ ## [2.6.1-cx24-3607.3](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-3607.2...v2.6.1-cx24-3607.3) (2023-03-16)
102
30
 
103
31
 
104
32
  ### Fix
105
33
 
106
- * The variant drop down label ([707ddb3](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/707ddb37391363059c86460e5da575b78409e250))
34
+ * check for imageURL ([5d56bae](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/5d56baeb4c148cc667cc3c9321fb72e87216c921))
107
35
 
108
- ## [2.6.1-cx24-337701.2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-337701.1...v2.6.1-cx24-337701.2) (2023-03-19)
36
+ ## [2.6.1-cx24-3607.2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1-cx24-3607.1...v2.6.1-cx24-3607.2) (2023-03-16)
109
37
 
110
38
 
111
39
  ### Fix
112
40
 
113
- * The variant drop down label ([973f145](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/973f1455a91127d575a8fc7d26e7e78d05f1f0a4))
41
+ * (equinox-enabled) skip product mapping when an error occurs in PLP #CX24-3607 ([49fa749](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/49fa7499b390aa84cc887fc631037363421d252a)), closes [#CX24-3607](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3607)
114
42
 
115
- ## [2.6.1-cx24-337701.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.0...v2.6.1-cx24-337701.1) (2023-03-19)
43
+ ## [2.6.1-cx24-3607.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.0...v2.6.1-cx24-3607.1) (2023-03-15)
116
44
 
117
45
 
118
46
  ### Fix
119
47
 
120
- * The variant drop down label ([bd60148](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/bd60148d1a50e895d36139932740fe4ee7f9f50a))
121
- * The variant drop down label ([749b476](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/749b47605995405886460b29f20411a21e45fb68))
122
- * The variant drop down label ([bc555ab](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/bc555abec97bca95fc0ba18a0eb4f0a0c9cd537a))
48
+ * (equinox-enabled) skip product mapping when an error occurs in PLP #CX24-3607 ([950c165](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/950c1650115f92badc5b898b5df722568b034afe)), closes [#CX24-3607](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3607)
49
+ * Cannot read properties of undefined (reading 'qty') in PLP #CX24-3607 ([8cde88f](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/8cde88f2f61279d20794a0e43696187c4326ca28)), closes [#CX24-3607](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3607)
123
50
 
124
51
  # [2.6.0](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.5.2...v2.6.0) (2023-03-13)
125
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/ns-product-lib",
3
- "version": "2.7.0-cx24-337701.1",
3
+ "version": "2.7.0-cx24-337703.1",
4
4
  "description": "This project contains shared Product models and code between the backend and frontend.",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -33,7 +33,7 @@
33
33
  "dependencies": {
34
34
  "@nuskin/configuration-sdk": "2.2.3",
35
35
  "@nuskin/ns-common-lib": "1.4.5",
36
- "@nuskin/ns-util": "4.2.5",
36
+ "@nuskin/ns-util": "4.2.7",
37
37
  "axios": "0.27.2",
38
38
  "qs": "6.11.0"
39
39
  },
@@ -0,0 +1,31 @@
1
+ /**
2
+ * childSKU maps a product variant. Used mainly in subscription.
3
+ *
4
+ * @param {import('.').KitSKUQuantity[]} kits
5
+ * @param {import('.').EquinoxProduct} product
6
+ */
7
+ function childSKU(kits, product) {
8
+ const sku = product.sku.filter(sku => sku.default)[0];
9
+ if (!sku) {
10
+ throw Error('Unable to find the default SKU.');
11
+ }
12
+
13
+ const kit = kits.filter(k => k.sku === sku.identifier)[0];
14
+ if (!kit) {
15
+ throw Error('SKU kit does not exist in the list of available variants.');
16
+ }
17
+
18
+ return {
19
+ productId: product.identifier,
20
+ skuId: sku.identifier,
21
+ type: 'MANDATORY',
22
+ skuQuantity: kit.qty,
23
+ availableChannels: sku.properties.availableChannels,
24
+ inventory: {
25
+ atpQty: sku.inventoryProperties.atpQty,
26
+ backOrdered: sku.inventoryProperties.backOrdered
27
+ }
28
+ }
29
+ }
30
+
31
+ module.exports = childSKU;
@@ -1,10 +1,11 @@
1
1
  /**
2
+ * @description This model represents the mapped values of a product
2
3
  * @typedef Product
3
4
  * @type {object}
4
- * @property {ChildSku[]} childSkus
5
+ * @property {ProductChildSku[]} childSkus
5
6
  * @property {Inventory} [inventoryProperties]
6
- *
7
- * @typedef ChildSku
7
+ *
8
+ * @typedef ProductChildSku
8
9
  * @type {object}
9
10
  * @property {string} productId
10
11
  * @property {string} skuId
@@ -12,14 +13,52 @@
12
13
  * @property {number} skuQuantity
13
14
  * @property {string} availableChannels
14
15
  * @property {Inventory} [inventory]
16
+ *
17
+ * ---
18
+ *
19
+ * @description This model represents a product within an Equinox response.
20
+ * @typedef EquinoxProduct
21
+ * @type {object}
22
+ * @property {string} identifier
23
+ * @property {EquinoxProductSKU[]} sku
24
+ * @property {"kit"|"bundle"} [type]
25
+ *
26
+ * @typedef EquinoxProductSKU
27
+ * @type {object}
28
+ * @property {boolean} default
29
+ * For multi-variant products, this indicates that this is the searched SKU
30
+ * when using catalogs/search endpoint.
31
+ * @property {string} identifier
32
+ * @property {Inventory} inventoryProperties
33
+ * @property {EquinoxProductProperties} properties
34
+ *
35
+ * @typedef EquinoxProductProperties
36
+ * @type {object}
37
+ * @property {string} availableChannels
38
+ *
39
+ * ---
40
+ *
41
+ * Types common to Product model and Equinox Product model
15
42
  *
16
43
  * @typedef Inventory
17
44
  * @type {object}
18
45
  * @property {number} atpQty
19
46
  * @property {boolean} backOrdered
47
+ *
48
+ * ---
49
+ *
50
+ * Standalone types. These are types not related to Product
51
+ * and Equinox Product models.
52
+ *
53
+ * @typedef KitSKUQuantity
54
+ * @type {object}
55
+ * @property {string} sku
56
+ * @property {number} qty
20
57
  */
21
58
  const availableQuantity = require('./availableQuantity');
59
+ const childSKU = require('./childSKU');
22
60
 
23
61
  module.exports = {
24
- mapAvailableQuantity: availableQuantity
62
+ mapAvailableQuantity: availableQuantity,
63
+ mapChildSKU: childSKU
25
64
  };
package/src/product.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
 
3
- const { isTrue } = require("@nuskin/ns-common-lib");
3
+ const { isTrue } = require("@nuskin/ns-common-lib");
4
4
 
5
5
  const ProductUtils = require("./productUtils.js");
6
6
 
@@ -8,7 +8,7 @@ const Agelocme = require("./agelocme.js");
8
8
  const PriceType = require("./models/priceType.js");
9
9
  const ProductStatus = require("./models/productStatus.js");
10
10
 
11
- const Product = function (productData) {
11
+ const Product = function(productData) {
12
12
  this.priceMap = {};
13
13
  this.pvMap = {};
14
14
  this.cvMap = {};
@@ -76,15 +76,14 @@ const Product = function (productData) {
76
76
  //@example "IN STOCK"
77
77
  this.inventory = "";
78
78
  this.equinoxProductId = "";
79
- this.variantDefault = false;
80
79
 
81
- this.setMarketAttributes = function (productStatus) {
80
+ this.setMarketAttributes = function(productStatus) {
82
81
  if (productStatus.marketAttributes) {
83
82
  this.marketAttributes = productStatus.marketAttributes;
84
83
  }
85
84
  };
86
85
 
87
- this.getAgelocmeKeyPart = function () {
86
+ this.getAgelocmeKeyPart = function() {
88
87
  let keyPart = null;
89
88
  if (this.agelocme) {
90
89
  keyPart =
@@ -98,27 +97,27 @@ const Product = function (productData) {
98
97
  return keyPart;
99
98
  };
100
99
 
101
- this.getHighlightedSku = function () {
100
+ this.getHighlightedSku = function() {
102
101
  let rv = this.sku;
103
102
  if (this.highlightedSku) rv = this.highlightedSku;
104
103
  return rv;
105
104
  };
106
105
 
107
- this.getProductSearchTitle = function () {
106
+ this.getProductSearchTitle = function() {
108
107
  if (this.agelocme && this.agelocme.label) {
109
108
  return this.agelocme.label;
110
109
  }
111
110
  return this.title;
112
111
  };
113
112
 
114
- this.getProductSearchSku = function () {
113
+ this.getProductSearchSku = function() {
115
114
  if (this.agelocme && this.agelocme.code) {
116
115
  return this.agelocme.code;
117
116
  }
118
117
  return this.getHighlightedSku();
119
118
  };
120
119
 
121
- this.getDescription = function () {
120
+ this.getDescription = function() {
122
121
  let description = this.longDescr;
123
122
  if (!description || description.length === 0) {
124
123
  return this.shortDescr;
@@ -126,7 +125,7 @@ const Product = function (productData) {
126
125
  return description;
127
126
  };
128
127
 
129
- this.setFullImage = function (fullImage) {
128
+ this.setFullImage = function(fullImage) {
130
129
  if (fullImage) {
131
130
  this.fullImage = fullImage.replace("http:", "https:");
132
131
  } else {
@@ -134,19 +133,19 @@ const Product = function (productData) {
134
133
  }
135
134
  };
136
135
 
137
- this.getFullImage = function () {
136
+ this.getFullImage = function() {
138
137
  return this.fullImage ? this.fullImage.replace("http:", "https:") : "";
139
138
  };
140
139
 
141
- this.setProductCarouselImages = function (productCarouselImages) {
140
+ this.setProductCarouselImages = function(productCarouselImages) {
142
141
  this.productCarouselImages = productCarouselImages;
143
142
  };
144
143
 
145
- this.getProductCarouselImages = function () {
144
+ this.getProductCarouselImages = function() {
146
145
  return this.productCarouselImages;
147
146
  };
148
147
 
149
- this.setImageAltText = function (altText) {
148
+ this.setImageAltText = function(altText) {
150
149
  if (altText) {
151
150
  this.imageAltText = altText;
152
151
  } else {
@@ -154,11 +153,11 @@ const Product = function (productData) {
154
153
  }
155
154
  };
156
155
 
157
- this.getImageAltText = function () {
156
+ this.getImageAltText = function() {
158
157
  return this.imageAltText || this.title;
159
158
  };
160
159
 
161
- this.setThumbnail = function (thumbnail) {
160
+ this.setThumbnail = function(thumbnail) {
162
161
  if (thumbnail) {
163
162
  this.thumbnail = thumbnail.replace("http:", "https:");
164
163
  } else {
@@ -166,7 +165,7 @@ const Product = function (productData) {
166
165
  }
167
166
  };
168
167
 
169
- this.setThumbnailFromSku = function (sku) {
168
+ this.setThumbnailFromSku = function(sku) {
170
169
  // WARNING: Base URL will need to be handled in the client (call setBaseUrl)
171
170
  // eslint-disable-next-line max-len
172
171
  // this.thumbnail = `${RunConfigService.getBaseUrl()}/content/products/${ProductUtils.getTokenizedSku(sku)}/jcr:content/fullImage.img.100.100.png`;
@@ -176,43 +175,43 @@ const Product = function (productData) {
176
175
  )}/jcr:content/fullImage.img.100.100.png`;
177
176
  };
178
177
 
179
- this.getThumbnail = function () {
178
+ this.getThumbnail = function() {
180
179
  return this.thumbnail ? this.thumbnail.replace("http:", "https:") : "";
181
180
  };
182
181
 
183
- this.hasAvailableQuantity = function (qty = 1) {
182
+ this.hasAvailableQuantity = function(qty = 1) {
184
183
  return Math.min(this.maxQuantity, this.availableQuantity) >= qty;
185
184
  };
186
185
 
187
- this.setPoints = function (points) {
186
+ this.setPoints = function(points) {
188
187
  this.points = ensureFloatVal(points) || "";
189
188
  };
190
189
 
191
- this.getPointsFixed = function () {
190
+ this.getPointsFixed = function() {
192
191
  return parseFloat(this.points).toFixed(2);
193
192
  };
194
193
 
195
- this.setCv = function (cv) {
194
+ this.setCv = function(cv) {
196
195
  this.cv = ensureFloatVal(cv) || "";
197
196
  };
198
197
 
199
- this.getCvFixed = function () {
198
+ this.getCvFixed = function() {
200
199
  return parseFloat(this.cv).toFixed(2);
201
200
  };
202
201
 
203
- this.setPv = function (pv) {
202
+ this.setPv = function(pv) {
204
203
  this.pv = ensureFloatVal(pv) || "";
205
204
  };
206
205
 
207
- this.getPvFixed = function () {
206
+ this.getPvFixed = function() {
208
207
  return parseFloat(this.pv || 0).toFixed(2);
209
208
  };
210
209
 
211
- this.setPrice = function (price) {
210
+ this.setPrice = function(price) {
212
211
  this.price = ensureFloatVal(price, true);
213
212
  };
214
213
 
215
- this.setFormattedPrice = function (formattedPrice) {
214
+ this.setFormattedPrice = function(formattedPrice) {
216
215
  this.formattedPrice = formattedPrice;
217
216
  };
218
217
 
@@ -221,13 +220,13 @@ const Product = function (productData) {
221
220
  * added to the cart the event pricing needs to be remembered if toggling between
222
221
  * pricetypes with event pricing and pricetype without event pricing
223
222
  */
224
- this.lockEventName = function () {
223
+ this.lockEventName = function() {
225
224
  if (!this.savedEventName && this.eventName) {
226
225
  this.savedEventName = this.eventName;
227
226
  }
228
227
  };
229
228
 
230
- this.setPriceAndPvFromType = function (_priceType, _activeEvents = null, option = {}) {
229
+ this.setPriceAndPvFromType = function(_priceType, _activeEvents = null, option = {}) {
231
230
  // WARNING: priceType needs to be handled client-side
232
231
  // const priceType = ConfigService.getMarketConfig().showWholeSalePricing && !AccountManager.isLoggedIn()
233
232
  // ? PriceType.WWHL
@@ -272,11 +271,11 @@ const Product = function (productData) {
272
271
  return changed;
273
272
  };
274
273
 
275
- this.getPrice = function () {
274
+ this.getPrice = function() {
276
275
  return this.price ? this.price : 0;
277
276
  };
278
277
 
279
- this.getPriceFixed = function () {
278
+ this.getPriceFixed = function() {
280
279
  if (typeof this.price === "number") {
281
280
  return parseFloat(this.price.toFixed(2));
282
281
  } else {
@@ -284,15 +283,15 @@ const Product = function (productData) {
284
283
  }
285
284
  };
286
285
 
287
- this.getOriginalPrice = function () {
286
+ this.getOriginalPrice = function() {
288
287
  return this.priceType ? this.priceMap[this.priceType] : null;
289
288
  };
290
289
 
291
- this.addPricing = function (type, price) {
290
+ this.addPricing = function(type, price) {
292
291
  this.priceMap[type] = price;
293
292
  };
294
293
 
295
- this.addPricingFromStatus = function (productStatus, priceType, option = {}) {
294
+ this.addPricingFromStatus = function(productStatus, priceType, option ={}) {
296
295
  let modified = false;
297
296
 
298
297
  if (!priceType) {
@@ -327,7 +326,7 @@ const Product = function (productData) {
327
326
  }, this);
328
327
  }
329
328
  this.orderTypes = ProductUtils.mergeOrderTypes(this.orderTypes, productStatus.orderType);
330
- if (productStatus.childSkus) {
329
+ if(productStatus.childSkus) {
331
330
  this.childSkus = productStatus.childSkus;
332
331
  }
333
332
  this.setPriceAndPvFromType(priceType, null, option);
@@ -347,15 +346,15 @@ const Product = function (productData) {
347
346
  return modified;
348
347
  };
349
348
 
350
- this.addPvWithType = function (type, pv) {
349
+ this.addPvWithType = function(type, pv) {
351
350
  this.pvMap[type] = pv;
352
351
  };
353
352
 
354
- this.addCvWithType = function (type, cv) {
353
+ this.addCvWithType = function(type, cv) {
355
354
  this.cvMap[type] = cv;
356
355
  };
357
356
 
358
- this.getPricing = function (type) {
357
+ this.getPricing = function(type) {
359
358
  let retVal = null;
360
359
 
361
360
  if (type) {
@@ -382,7 +381,7 @@ const Product = function (productData) {
382
381
  return eventPriceTypes;
383
382
  };
384
383
 
385
- this.getPvWithType = function (type) {
384
+ this.getPvWithType = function(type) {
386
385
  let rv = this.pvMap[type];
387
386
  if (rv == null) {
388
387
  // Assumption: we always have WWHL from the service
@@ -392,7 +391,7 @@ const Product = function (productData) {
392
391
  return rv;
393
392
  };
394
393
 
395
- this.getCvWithType = function (type) {
394
+ this.getCvWithType = function(type) {
396
395
  let rv = this.cvMap[type];
397
396
  if (rv == null) {
398
397
  rv = this.cvMap[PriceType.WWHL];
@@ -400,77 +399,77 @@ const Product = function (productData) {
400
399
  return rv;
401
400
  };
402
401
 
403
- this.hasAdrOption = function () {
402
+ this.hasAdrOption = function() {
404
403
  return this.orderTypes["adr"];
405
404
  };
406
405
 
407
- this.isAdrOnly = function () {
406
+ this.isAdrOnly = function() {
408
407
  return this.hasAdrOption() && !this.hasOrderOption();
409
408
  };
410
409
 
411
- this.hasMultipleOrderTypes = function () {
410
+ this.hasMultipleOrderTypes = function() {
412
411
  return this.hasOrderOption() && this.hasAdrOption();
413
412
  };
414
413
 
415
- this.hasOrderOption = function () {
414
+ this.hasOrderOption = function() {
416
415
  return this.orderTypes["order"];
417
416
  };
418
417
 
419
- this.isDistributor = function () {
418
+ this.isDistributor = function() {
420
419
  return this.custTypes.includes("10");
421
420
  };
422
421
 
423
- this.isCustomer = function () {
422
+ this.isCustomer = function() {
424
423
  return this.custTypes.includes("20");
425
424
  };
426
425
 
427
- this.isPreferredCustomer = function () {
426
+ this.isPreferredCustomer = function() {
428
427
  return this.custTypes.includes("30");
429
428
  };
430
429
 
431
- this.isBase = function () {
430
+ this.isBase = function() {
432
431
  return this.sku.substring(2, 4) === "55";
433
432
  };
434
433
 
435
- this.isVariant = function () {
434
+ this.isVariant = function() {
436
435
  return this.baseSku.length > 0 && this.variantSkus().length === 0;
437
436
  };
438
437
 
439
- this.setVariant = function (variantProduct) {
438
+ this.setVariant = function(variantProduct) {
440
439
  if (variantProduct && variantProduct.sku) {
441
440
  this.variants[variantProduct.sku] = variantProduct;
442
441
  }
443
442
  };
444
443
 
445
- this.getVariant = function (sku) {
444
+ this.getVariant = function(sku) {
446
445
  return this.variants[sku];
447
446
  };
448
447
 
449
- this.variantSkus = function () {
448
+ this.variantSkus = function() {
450
449
  return Object.keys(this.variants);
451
450
  };
452
451
 
453
- this.getVariantsList = function () {
452
+ this.getVariantsList = function() {
454
453
  return Object.values(this.variants);
455
454
  };
456
455
 
457
- this.getMinPrice = function () {
456
+ this.getMinPrice = function() {
458
457
  return this.priceMap[`min-${this.priceType}`];
459
458
  };
460
459
 
461
- this.getMaxPrice = function () {
460
+ this.getMaxPrice = function() {
462
461
  return this.priceMap[`max-${this.priceType}`];
463
462
  };
464
463
 
465
- this.getMinPv = function () {
464
+ this.getMinPv = function() {
466
465
  return this.pvMap[`min-${this.priceType}`];
467
466
  };
468
467
 
469
- this.getMaxPv = function () {
468
+ this.getMaxPv = function() {
470
469
  return this.pvMap[`max-${this.priceType}`];
471
470
  };
472
471
 
473
- this.toJSON = function () {
472
+ this.toJSON = function() {
474
473
  let retData = {};
475
474
  retData.sku = this.sku;
476
475
  retData.globalProductID = this.globalProductID;
@@ -539,11 +538,11 @@ const Product = function (productData) {
539
538
  return retData;
540
539
  };
541
540
 
542
- this.setMeCommerceProductData = function (/*productData*/) {
541
+ this.setMeCommerceProductData = function(/*productData*/) {
543
542
  console.error("setMeCommerceProductData is deprecated!");
544
543
  };
545
544
 
546
- this.setBaseUrl = function (baseUrl) {
545
+ this.setBaseUrl = function(baseUrl) {
547
546
  this.thumbnail = ProductUtils.applyBaseUrl(this.thumbnail, baseUrl);
548
547
  this.fullImage = ProductUtils.applyBaseUrl(this.fullImage, baseUrl);
549
548
 
@@ -555,7 +554,7 @@ const Product = function (productData) {
555
554
  }
556
555
  };
557
556
 
558
- this.setProductData = function (productData) {
557
+ this.setProductData = function(productData) {
559
558
  let data;
560
559
 
561
560
  if (productData) {
@@ -663,7 +662,7 @@ const Product = function (productData) {
663
662
  ? data.pvMap
664
663
  : this.pvMap;
665
664
  this.orderTypes = ProductUtils.mergeOrderTypes(this.orderTypes, data.orderTypes);
666
- if (data.childSkus) {
665
+ if(data.childSkus) {
667
666
  this.childSkus = data.childSkus;
668
667
  }
669
668
  this.custTypes = data.custTypes || [];
@@ -679,7 +678,7 @@ const Product = function (productData) {
679
678
  }
680
679
  };
681
680
 
682
- this.isEmpty = function () {
681
+ this.isEmpty = function() {
683
682
  return (
684
683
  isFieldEmpty(this.sku) &&
685
684
  isFieldEmpty(this.title) &&
@@ -5,7 +5,7 @@ const contentstack = require('./contentstack/contentstack');
5
5
  const Product = require("./product");
6
6
  const CustomerTypes = require('./models/customerTypes');
7
7
  const ProductStatus = require("./models/productStatus");
8
- const { mapAvailableQuantity } = require('./equinox-helpers');
8
+ const { mapAvailableQuantity, mapChildSKU } = require('./equinox-helpers');
9
9
 
10
10
  const productTypes = {
11
11
  kit: 'kit'
@@ -66,7 +66,6 @@ const ProductData = {
66
66
  }
67
67
 
68
68
  const filter = skuFilter.join(" OR ")
69
- //axios.defaults.withCredentials = true;
70
69
 
71
70
  const url = `${config.API_Base_URLs}/orchestrationservices/storefront/catalogs/search/`;
72
71
  const href = `${url}?filter='\\\\''${encodeURI(filter)}'\\''`;
@@ -129,15 +128,9 @@ const ProductData = {
129
128
  */
130
129
  eqProductVariantMapper: function (eqVariant) {
131
130
 
132
- let imageURL = eqVariant.properties.imageURL;
133
- const regex = /\d+\.\d+/
134
- let thumbnailImage = ''
131
+ let imageURL = eqVariant.properties.imageURL ? eqVariant.properties.imageURL : '';
132
+ let thumbnailImage = imageURL ? imageURL + '?width=40' : ''
135
133
 
136
- if (imageURL.includes('contentstack')) {
137
- thumbnailImage = imageURL + '?width=40'
138
- } else {
139
- thumbnailImage = imageURL.replace(regex, '40.40')
140
- }
141
134
 
142
135
  const { eventName, eventLabels, computedPrice, defaultProductPrice, CVPrice, PVPrice } = this.getEqProductPromotions(eqVariant);
143
136
  const productPrice = eventName ? defaultProductPrice : eqVariant.priceFacets["Regular Price"];
@@ -304,8 +297,7 @@ const ProductData = {
304
297
  },
305
298
  "restrictedMarkets": [],
306
299
  "addOns": [],
307
- "equinoxProductId": eqVariant.identifier,
308
- "variantDefault": eqVariant.default
300
+ "equinoxProductId": eqVariant.identifier
309
301
  };
310
302
  },
311
303
 
@@ -358,146 +350,141 @@ const ProductData = {
358
350
  }
359
351
  },
360
352
 
361
-
362
353
  eqProductMapper: async function (productDataResponse, skus) {
363
- // console.log(productDataResponse, skus);
364
354
  let count = 0;
365
355
  const products = [];
366
356
 
367
357
  for (const productData of productDataResponse) {
368
- let variants = {};
369
-
370
- let product = (productData.type && productData.type === "kit") ? productData : productData.sku[count];
371
- let imageURL = product.properties.imageURL;
372
- const regex = /\d+\.\d+/
373
- let thumbnailImage = ''
374
-
375
- if (imageURL.includes('contentstack')) {
376
- thumbnailImage = imageURL + '?width=40'
377
- } else {
378
- thumbnailImage = imageURL.replace(regex, '40.40')
379
- }
358
+ try {
359
+ let variants = {};
360
+ let product = (productData.type && productData.type === "kit") ? productData : productData.sku[count];
361
+ let imageURL = product.properties.imageURL ? product.properties.imageURL : '';
362
+ let thumbnailImage = imageURL ? imageURL + '?width=40' : ''
363
+
364
+
365
+ if (productData.sku && productData.sku.length > 1) {
366
+ // exclude base product from variants
367
+ productData.sku.filter(v => v.identifier.substring(2, 4) !== "55").map(variant => {
368
+ variants[variant.identifier] = this.eqProductVariantMapper(variant);
369
+ return variant;
370
+ });
371
+ }
380
372
 
381
- if (productData.sku && productData.sku.length > 1) {
382
- // exclude base product from variants
383
- productData.sku.filter(v => v.identifier.substring(2, 4) !== "55").map(variant => {
384
- variants[variant.identifier] = this.eqProductVariantMapper(variant);
385
- return variant;
386
- });
373
+ const {
374
+ eventName,
375
+ eventLabels,
376
+ computedPrice,
377
+ defaultProductPrice,
378
+ CVPrice,
379
+ PVPrice
380
+ } = this.getEqProductPromotions(product);
381
+ const productPrice = eventName ? defaultProductPrice : product.priceFacets["Regular Price"];
382
+ const discountedPrice = eventName ? computedPrice : product.priceFacets["Regular Price"];
383
+ const productCVPrice = eventName ? CVPrice : product.priceFacets.CV;
384
+ const productPVPrice = eventName ? PVPrice : product.priceFacets.PV;
385
+
386
+ product.childSkus = await this.fetchChildSkus(product);
387
+ product.availableQuantity = mapAvailableQuantity(product);
388
+ product = {
389
+ ...product,
390
+ "sku": product.identifier,
391
+ "globalProductID": productData.identifier,
392
+ "title": productData.properties.name,
393
+ "country": product.properties.market,
394
+ "language": "en",
395
+ "shortDescr": productData.properties.description,
396
+ "longDescr": productData.properties.productDetailsDescription,
397
+ "fullImage": imageURL,
398
+ "imageAltText": productData.properties.name,
399
+ "productCarouselImages": [
400
+ {
401
+ "contentType": "img",
402
+ "src": "/content/products/24/00/35/24003529/jcr:content/fullImage.imgw.1280.1280.png",
403
+ "alt": ""
404
+ }
405
+ ],
406
+ "thumbnail": thumbnailImage,
407
+ "ingredients": productData.properties.ingredients,
408
+ "benefits": productData.properties.benefits,
409
+ "usage": productData.properties.usage,
410
+ "resources": product.properties.resources,
411
+ "videos": "",
412
+ "movie": "",
413
+ "youtube": "",
414
+ "salesEventText": "",
415
+ "contentSection": [
416
+ {
417
+ "sectionContent": "<div class=\"contentSections\"></div>\n"
418
+ }
419
+ ],
420
+ "scanQualified": productData.properties.scanQualifiedCount,
421
+ "maxQuantity": 999,
422
+ "points": "",
423
+ "cv": productCVPrice,
424
+ "pv": productPVPrice,
425
+ "priceType": "WRTL",
426
+ "price": discountedPrice,
427
+ "priceMap": {
428
+ "WRTL": productPrice,
429
+ "WADW-WRTL": product.priceFacets["Regular Price"],
430
+ "WADR": product.priceFacets["Regular Price"],
431
+ "RTL": product.priceFacets["Regular Price"],
432
+ "WADW": product.priceFacets["Wholesale Price"],
433
+ "WHL": product.priceFacets["Wholesale Price"],
434
+ "WWHL": product.priceFacets["Wholesale Price"]
435
+ },
436
+ "cvMap": {
437
+ "WWHL": productCVPrice,
438
+ "WADW": productCVPrice,
439
+ "WHL": productCVPrice
440
+ },
441
+ "pvMap": {
442
+ "WWHL": productPVPrice,
443
+ "WADW": productPVPrice,
444
+ "WHL": productPVPrice
445
+ },
446
+ "orderTypes": this._setOrderType(product.properties),
447
+ "custTypes": this.switchCustType(product.properties.customerTypes),
448
+ "division": productData.properties.division,
449
+ "backOrderDate": null,
450
+ "locallyProduced": false,
451
+ "agelocme": null,
452
+ "count": "",
453
+ "flavor": "",
454
+ "size": product.properties.size,
455
+ "shade": "",
456
+ "status": this.switchStatusFromEquinox(product.properties.productStatus),
457
+ "variantType": "Other",
458
+ "variantDropdownLabel": product.properties.variantLabel || "",
459
+ "variantDropdownPlaceholder": "Select Type",
460
+ "variantsLabel": product.properties.variantLabel || "",
461
+ "groupOffer": false,
462
+ "personalOffer": false,
463
+ "savedEventName": eventName,
464
+ "salesLabel": eventLabels,
465
+ "eventName": eventName,
466
+ "sizeWeight": '',
467
+ "nettoWeight": "",
468
+ "variants": variants,
469
+ "searchScore": 0,
470
+ "isExclusive": product.properties.isExclusive || false,
471
+ "marketAttributes": {
472
+ "discount": true,
473
+ "redeem": true,
474
+ "earn": true
475
+ },
476
+ "restrictedMarkets": [],
477
+ "addOns": [],
478
+ "inventory": product.inventory || "", //inventory label
479
+ "equinoxProductId": productData.identifier
480
+ };
481
+
482
+ products.push(new Product(product));
483
+ } catch (err) {
484
+ console.error('Unable to map the product', productData.identifier, ':', err);
485
+ console.error('Product info:', productDataResponse, skus);
486
+ continue;
387
487
  }
388
-
389
-
390
-
391
- const {
392
- eventName,
393
- eventLabels,
394
- computedPrice,
395
- defaultProductPrice,
396
- CVPrice,
397
- PVPrice
398
- } = this.getEqProductPromotions(product);
399
- const productPrice = eventName ? defaultProductPrice : product.priceFacets["Regular Price"];
400
- const discountedPrice = eventName ? computedPrice : product.priceFacets["Regular Price"];
401
- const productCVPrice = eventName ? CVPrice : product.priceFacets.CV;
402
- const productPVPrice = eventName ? PVPrice : product.priceFacets.PV;
403
-
404
- product.childSkus = await this.fetchChildSkus(product);
405
- product.availableQuantity = mapAvailableQuantity(product);
406
- product = {
407
- ...product,
408
- "sku": product.identifier,
409
- "globalProductID": productData.identifier,
410
- "title": productData.properties.name,
411
- "country": product.properties.market,
412
- "language": "en",
413
- "shortDescr": productData.properties.description,
414
- "longDescr": productData.properties.productDetailsDescription,
415
- "fullImage": imageURL,
416
- "imageAltText": productData.properties.name,
417
- "productCarouselImages": [
418
- {
419
- "contentType": "img",
420
- "src": "/content/products/24/00/35/24003529/jcr:content/fullImage.imgw.1280.1280.png",
421
- "alt": ""
422
- }
423
- ],
424
- "thumbnail": thumbnailImage,
425
- "ingredients": productData.properties.ingredients,
426
- "benefits": productData.properties.benefits,
427
- "usage": productData.properties.usage,
428
- "resources": product.properties.resources,
429
- "videos": "",
430
- "movie": "",
431
- "youtube": "",
432
- "salesEventText": "",
433
- "contentSection": [
434
- {
435
- "sectionContent": "<div class=\"contentSections\"></div>\n"
436
- }
437
- ],
438
- "scanQualified": productData.properties.scanQualifiedCount,
439
- "maxQuantity": 999,
440
- "points": "",
441
- "cv": productCVPrice,
442
- "pv": productPVPrice,
443
- "priceType": "WRTL",
444
- "price": discountedPrice,
445
- "priceMap": {
446
- "WRTL": parseInt(productPrice),
447
- "WADW-WRTL": parseInt(product.priceFacets["Regular Price"]),
448
- "WADR": parseInt(product.priceFacets["Regular Price"]),
449
- "RTL": parseInt(product.priceFacets["Regular Price"]),
450
- "WADW": parseInt(product.priceFacets["Wholesale Price"]),
451
- "WHL": parseInt(product.priceFacets["Wholesale Price"]),
452
- "WWHL": parseInt(product.priceFacets["Wholesale Price"])
453
- },
454
- "cvMap": {
455
- "WWHL": productCVPrice,
456
- "WADW": productCVPrice,
457
- "WHL": productCVPrice
458
- },
459
- "pvMap": {
460
- "WWHL": productPVPrice,
461
- "WADW": productPVPrice,
462
- "WHL": productPVPrice
463
- },
464
- "orderTypes": this._setOrderType(product.properties),
465
- "custTypes": this.switchCustType(product.properties.customerTypes),
466
- "division": productData.properties.division,
467
- "backOrderDate": null,
468
- "locallyProduced": false,
469
- "agelocme": null,
470
- "count": "",
471
- "flavor": "",
472
- "size": product.properties.size,
473
- "shade": "",
474
- "status": this.switchStatusFromEquinox(product.properties.productStatus),
475
- "variantType": "Other",
476
- "variantDropdownLabel": product.properties.variantLabel || "",
477
- "variantDropdownPlaceholder": "Select Type",
478
- "variantsLabel": product.properties.variantLabel || "",
479
- "groupOffer": false,
480
- "personalOffer": false,
481
- "savedEventName": eventName,
482
- "salesLabel": eventLabels,
483
- "eventName": eventName,
484
- "sizeWeight": '',
485
- "nettoWeight": "",
486
- "variants": variants,
487
- "searchScore": 0,
488
- "isExclusive": product.properties.isExclusive || false,
489
- "marketAttributes": {
490
- "discount": true,
491
- "redeem": true,
492
- "earn": true
493
- },
494
- "restrictedMarkets": [],
495
- "addOns": [],
496
- "inventory": product.inventory || "", //inventory label
497
- "equinoxProductId": productData.identifier
498
- };
499
-
500
- products.push(new Product(product));
501
488
  }
502
489
 
503
490
  let data = {
@@ -540,7 +527,7 @@ const ProductData = {
540
527
  type: 'SKUKIT',
541
528
  availableChannels: product.properties.availableChannels
542
529
  },
543
- ...res.data.product.map(p => this.buildChildSkus(kits, p))
530
+ ...res.data.product.map(p => mapChildSKU(kits, p))
544
531
  ];
545
532
 
546
533
  return childSkus;
@@ -549,23 +536,6 @@ const ProductData = {
549
536
  return [];
550
537
  },
551
538
 
552
- buildChildSkus: function (kits, product) {
553
- const sku = product.sku[0];
554
- const kit = kits.filter(k => k.sku === sku.identifier)[0];
555
-
556
- return {
557
- productId: product.identifier,
558
- skuId: sku.identifier,
559
- type: 'MANDATORY',
560
- skuQuantity: kit.qty,
561
- availableChannels: sku.properties.availableChannels,
562
- inventory: {
563
- atpQty: sku.inventoryProperties.atpQty,
564
- backOrdered: sku.inventoryProperties.backOrdered
565
- }
566
- }
567
- },
568
-
569
539
  /**
570
540
  *
571
541
  * Map status from equinox to legacy