@nuskin/ns-product-lib 2.7.0-cx24-3702.1 → 2.7.0-cx24-3682.7
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +34 -11
- package/package.json +2 -2
- package/src/equinox-helpers/index.js +158 -29
- package/src/equinox-helpers/interceptors/index.js +5 -0
- package/src/equinox-helpers/interceptors/productNotFound.js +71 -0
- package/src/equinox-helpers/mappers/index.js +5 -0
- package/src/equinox-helpers/mappers/properties.js +182 -0
- package/src/equinox-helpers/models/index.js +5 -0
- package/src/equinox-helpers/models/productNotFound.js +32 -0
- package/src/productData.js +26 -42
package/CHANGELOG.md
CHANGED
@@ -1,30 +1,53 @@
|
|
1
|
-
# [2.7.0-cx24-
|
1
|
+
# [2.7.0-cx24-3682.7](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.7.0-cx24-3682.6...v2.7.0-cx24-3682.7) (2023-03-25)
|
2
2
|
|
3
3
|
|
4
4
|
### New
|
5
5
|
|
6
|
-
*
|
6
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([a8f0331](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/a8f0331970ed4631ceba029d48e246b83627a046)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
7
7
|
|
8
|
-
|
8
|
+
# [2.7.0-cx24-3682.6](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.7.0-cx24-3682.5...v2.7.0-cx24-3682.6) (2023-03-25)
|
9
9
|
|
10
10
|
|
11
|
-
###
|
11
|
+
### New
|
12
12
|
|
13
|
-
*
|
13
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([13f2b76](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/13f2b76990dd2e4f4226367332212dcc7bd19977)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
14
14
|
|
15
|
-
# [2.7.0-cx24-
|
15
|
+
# [2.7.0-cx24-3682.5](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.7.0-cx24-3682.4...v2.7.0-cx24-3682.5) (2023-03-25)
|
16
16
|
|
17
17
|
|
18
|
-
###
|
18
|
+
### New
|
19
19
|
|
20
|
-
*
|
20
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([588161d](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/588161d54fa2e97f6bee2fe33523f3f1bdcb1ed2)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
21
21
|
|
22
|
-
|
22
|
+
# [2.7.0-cx24-3682.4](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.7.0-cx24-3682.3...v2.7.0-cx24-3682.4) (2023-03-24)
|
23
23
|
|
24
24
|
|
25
|
-
###
|
25
|
+
### New
|
26
|
+
|
27
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([f55854a](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/f55854ad4abb17dbd373fe5e36a38deb2bb8fc53)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
28
|
+
|
29
|
+
# [2.7.0-cx24-3682.3](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.7.0-cx24-3682.2...v2.7.0-cx24-3682.3) (2023-03-24)
|
30
|
+
|
31
|
+
|
32
|
+
### New
|
33
|
+
|
34
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([3ce010e](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/3ce010e162034d2cc49619f553baf7b8b7fcd4e0)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
35
|
+
|
36
|
+
# [2.7.0-cx24-3682.2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.7.0-cx24-3682.1...v2.7.0-cx24-3682.2) (2023-03-24)
|
37
|
+
|
38
|
+
|
39
|
+
### New
|
40
|
+
|
41
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([219fbd5](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/219fbd59b96ed9cbbc3ea94a24d886f0e8ca563f)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
42
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([b86a1d2](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/b86a1d2610892564c643bd851d873e507efedd49)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
43
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([60d61cc](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/60d61ccd38e9b971b7ac53cf4224a9897a63fef4)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
44
|
+
|
45
|
+
# [2.7.0-cx24-3682.1](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/compare/v2.6.1...v2.7.0-cx24-3682.1) (2023-03-24)
|
46
|
+
|
47
|
+
|
48
|
+
### New
|
26
49
|
|
27
|
-
*
|
50
|
+
* MySite product cards show blank data when users have setup AEM Base SKU's(55) in Admin #CX24-3682 ([99cc11a](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/commit/99cc11a7a274d97c03efc0a4bcdd0e03eb7b552a)), closes [#CX24-3682](https://code.tls.nuskin.io/ns-am/product/js-libs/ns-product-lib/issues/CX24-3682)
|
28
51
|
|
29
52
|
## [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)
|
30
53
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nuskin/ns-product-lib",
|
3
|
-
"version": "2.7.0-cx24-
|
3
|
+
"version": "2.7.0-cx24-3682.7",
|
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.
|
36
|
+
"@nuskin/ns-util": "4.2.5",
|
37
37
|
"axios": "0.27.2",
|
38
38
|
"qs": "6.11.0"
|
39
39
|
},
|
@@ -4,7 +4,9 @@
|
|
4
4
|
* @type {object}
|
5
5
|
* @property {ProductChildSku[]} childSkus
|
6
6
|
* @property {Inventory} [inventoryProperties]
|
7
|
-
|
7
|
+
*/
|
8
|
+
|
9
|
+
/**
|
8
10
|
* @typedef ProductChildSku
|
9
11
|
* @type {object}
|
10
12
|
* @property {string} productId
|
@@ -13,43 +15,170 @@
|
|
13
15
|
* @property {number} skuQuantity
|
14
16
|
* @property {string} availableChannels
|
15
17
|
* @property {Inventory} [inventory]
|
16
|
-
|
17
|
-
|
18
|
-
|
18
|
+
*/
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Types common to Product model and Equinox Product model
|
22
|
+
* @typedef Inventory
|
23
|
+
* @type {object}
|
24
|
+
* @property {number} atpQty
|
25
|
+
* @property {boolean} backOrdered
|
26
|
+
*/
|
27
|
+
|
28
|
+
/**
|
29
|
+
* @description This model represents the error response.
|
30
|
+
* @typedef EquinoxErrorResponse
|
31
|
+
* @type {object}
|
32
|
+
* @property {string} code e.g., SFOSER002
|
33
|
+
* @property {string} message e.g., No Results Found dot Search Term null
|
34
|
+
* @property {number} timestamp e.g., 1679715447962
|
35
|
+
*/
|
36
|
+
|
37
|
+
/**
|
38
|
+
* @description This model represents the response.
|
39
|
+
* @typedef EquinoxResponse
|
40
|
+
* @type {object}
|
41
|
+
* @property {EquinoxProduct[]} product
|
42
|
+
*/
|
43
|
+
|
44
|
+
/**
|
19
45
|
* @description This model represents a product within an Equinox response.
|
20
46
|
* @typedef EquinoxProduct
|
21
47
|
* @type {object}
|
22
|
-
* @property {string} identifier
|
23
|
-
* @property {
|
24
|
-
* @property {
|
25
|
-
*
|
26
|
-
|
48
|
+
* @property {string} identifier E.g., Normal - "blt8b757df6dcaa199c" | Kit - "02001076"
|
49
|
+
* @property {EquinoxProductProperties} properties
|
50
|
+
* @property {EquinoxProductVariant[]} [sku] or varaints - available only when product is a normal product.
|
51
|
+
* @property {"kit"|"bundle"} [type] available only when product is type of kit.
|
52
|
+
*/
|
53
|
+
|
54
|
+
/**
|
55
|
+
* @typedef {(
|
56
|
+
* EquinoxProductCommonProperties & EquinoxNormalProductProperties
|
57
|
+
* )} EquinoxProductProperties
|
58
|
+
*/
|
59
|
+
|
60
|
+
/**
|
61
|
+
* @description These are the properties unique to Normal product type.
|
62
|
+
* @typedef EquinoxNormalProductProperties
|
63
|
+
* @type {object}
|
64
|
+
* @property {string} ingredients
|
65
|
+
* @property {string} benefits
|
66
|
+
* @property {string} usage
|
67
|
+
* @property {string} resources
|
68
|
+
* @property {string} scanQualifiedCount E.g., "0"
|
69
|
+
* @property {string} status E.g., "active"
|
70
|
+
* @property {string} size E.g., "30 mL / 1 fl.oz"
|
71
|
+
* @property {string} productDetailsDescription E.g., "[]"
|
72
|
+
*/
|
73
|
+
|
74
|
+
/**
|
75
|
+
* @description These are the properties unique to Kit product type.
|
76
|
+
* @typedef EquinoxKitProductProperties
|
77
|
+
* @type {object}
|
78
|
+
* @property {string} skukits E.g., "02002145~1,02002146~1,02002147~1,02002148~1,02002142~1,02002143~1"
|
79
|
+
* @property {string} productStatus E.g., "Sellable"
|
80
|
+
* @property {string} availableChannels E.g., "subscription,arsPhone,kiosk,mobile,web"
|
81
|
+
*/
|
82
|
+
|
83
|
+
/**
|
84
|
+
* @description These are the common properties between Normal and Kit product types
|
85
|
+
* @typedef EquinoxProductCommonProperties
|
86
|
+
* @type {object}
|
87
|
+
* @property {string} name E.g., "180° Cell Renewal Fluid"
|
88
|
+
* @property {string} imageURL E.g., "https://nuskin.com/content/dam/global/...ule-refreshed.jpg"
|
89
|
+
* @property {string} market E.g., "CA"
|
90
|
+
* @property {string} description E.g., "180° Ampoule"
|
91
|
+
* @property {string} customerTypes E.g., "BrandAffiliate,Preferred,Retail"
|
92
|
+
* @property {string} division E.g., "Nu Skin"
|
93
|
+
*/
|
94
|
+
|
95
|
+
/**
|
96
|
+
* @typedef EquinoxProductVariant
|
27
97
|
* @type {object}
|
28
|
-
* @property {
|
29
|
-
*
|
98
|
+
* @property {string} identifier E.g., "02002145"
|
99
|
+
* @property {string} inventory E.g., "IN STOCK"
|
100
|
+
* @property {EquinoxProductVariantProperties} properties
|
101
|
+
* @property {any[]} promotion E.g., ???
|
102
|
+
* @property {EquinoxProductPriceFacets} priceFacets
|
103
|
+
* @property {EquinoxProductInventoryProperties} inventoryProperties
|
104
|
+
* @property {EquinxProductTotalValue} totalValue
|
105
|
+
* @property {boolean} [default] For multi-variant products, this indicates that this is the searched SKU
|
30
106
|
* when using catalogs/search endpoint.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
*
|
35
|
-
* @typedef EquinoxProductProperties
|
107
|
+
*/
|
108
|
+
|
109
|
+
/**
|
110
|
+
* @typedef EquinoxProductVariantProperties
|
36
111
|
* @type {object}
|
37
|
-
* @property {string} availableChannels
|
38
|
-
*
|
39
|
-
*
|
40
|
-
*
|
41
|
-
*
|
42
|
-
*
|
43
|
-
* @
|
112
|
+
* @property {string} availableChannels E.g., "subscription,arsPhone,kiosk,mobile,web"
|
113
|
+
* @property {string} imageURL E.g., "https://nuskin.com/cont...21/ca-180-Ampoule-refreshed.jpg"
|
114
|
+
* @property {string} name E.g., "180° Cell Renewal Fluid"
|
115
|
+
* @property {string} market E.g., "CA"
|
116
|
+
* @property {string} description E.g., "180° Ampoule"
|
117
|
+
* @property {string} ingredients
|
118
|
+
* @property {string} benefits
|
119
|
+
* @property {string} usage
|
120
|
+
* @property {string} resources
|
121
|
+
* @property {string} scanQualifiedCount E.g., "0"
|
122
|
+
* @property {string} customerTypes E.g., "BrandAffiliate,Preferred,Retail"
|
123
|
+
* @property {string} division E.g., "Nu Skin"
|
124
|
+
* @property {string} status E.g., "active"
|
125
|
+
* @property {string} size E.g., "30 mL / 1 fl.oz"
|
126
|
+
* @property {string} [variantLabel]
|
127
|
+
* @property {string} [isExclusive] E.g., "false" - Why is this a string??
|
128
|
+
*/
|
129
|
+
|
130
|
+
/**
|
131
|
+
* @description Why are properties not camelCase and type of string instead of number? Super weird!
|
132
|
+
* @typedef EquinoxProductPriceFacets
|
44
133
|
* @type {object}
|
45
|
-
* @property {
|
46
|
-
* @property {
|
47
|
-
*
|
48
|
-
*
|
49
|
-
*
|
134
|
+
* @property {string} CV E.g., "76.0"
|
135
|
+
* @property {string} Regular Price E.g., "76.0"
|
136
|
+
* @property {string} PV E.g., "54.15"
|
137
|
+
* @property {string} Wholesale Price E.g., "88.0"
|
138
|
+
* @property {string} SB E.g., "4.25"
|
139
|
+
*/
|
140
|
+
|
141
|
+
/**
|
142
|
+
* @description
|
143
|
+
* @typedef EquinoxProductInventoryProperties
|
144
|
+
* @type {object}
|
145
|
+
* @property {boolean} available E.g., true
|
146
|
+
* @property {boolean} lowStock E.g., false
|
147
|
+
* @property {string} binName E.g., "1046_CA01"
|
148
|
+
* @property {boolean} backOrdered E.g., false
|
149
|
+
* @property {number} expectedBackOrderAvailabilityDate E.g., 0
|
150
|
+
* @property {boolean} preOrdered E.g., false
|
151
|
+
* @property {number} expectedPreOrderAvailabilityDate E.g., 0
|
152
|
+
* @property {number} atpQty E.g., 49882
|
153
|
+
* @property {number} preOrderedQty E.g., 0
|
154
|
+
* @property {number} backOrderedQty E.g., 0
|
155
|
+
* @property {number|null} lowStockThreshold E.g., null
|
156
|
+
* @property {number|null} outOfStockThreshold E.g., null
|
157
|
+
*/
|
158
|
+
|
159
|
+
/**
|
160
|
+
* @description
|
161
|
+
* @typedef EquinxProductTotalValue
|
162
|
+
* @type {object}
|
163
|
+
* @property {number} priceAfterDiscount E.g., 2
|
164
|
+
* @property {number} originalPrice E.g., 2
|
165
|
+
* @property {number} totaldiscount E.g., 0
|
166
|
+
* @property {{
|
167
|
+
* CV: { CV: number },
|
168
|
+
* "Regular Price": {
|
169
|
+
* "Regular Price": number
|
170
|
+
* },
|
171
|
+
* PV: { PV: number },
|
172
|
+
* "Wholesale Price": {
|
173
|
+
* "Wholesale Price": number
|
174
|
+
* },
|
175
|
+
* SB: { SB: number },
|
176
|
+
* }} priceFacets
|
177
|
+
*/
|
178
|
+
|
179
|
+
/**
|
50
180
|
* Standalone types. These are types not related to Product
|
51
181
|
* and Equinox Product models.
|
52
|
-
*
|
53
182
|
* @typedef KitSKUQuantity
|
54
183
|
* @type {object}
|
55
184
|
* @property {string} sku
|
@@ -0,0 +1,71 @@
|
|
1
|
+
const { productNotFound } = require('../models');
|
2
|
+
|
3
|
+
// httpStatus codes
|
4
|
+
const httpStatus = { notFound: 404 };
|
5
|
+
|
6
|
+
/**
|
7
|
+
* productNotFoundInterceptor returns a model "ProductNotFound" when the status code is Not Found.
|
8
|
+
* Note: Do not polute this file. Create a new file for new interceptor.
|
9
|
+
*
|
10
|
+
* @param {import('axios').AxiosError} error
|
11
|
+
* @returns {import('axios').AxiosError<import('../').EquinoxResponse>}
|
12
|
+
*/
|
13
|
+
function productNotFoundInterceptor(error) {
|
14
|
+
const segments = 'catalogs/search';
|
15
|
+
const { config, response } = error;
|
16
|
+
|
17
|
+
if (response.status === httpStatus.notFound && config.url.includes(segments)) {
|
18
|
+
const params = new URLSearchParams(config.url);
|
19
|
+
const filterParam = Array.from(params.values())[0];
|
20
|
+
const sku = getSKU(filterParam);
|
21
|
+
|
22
|
+
if (sku !== null) {
|
23
|
+
return {
|
24
|
+
...error,
|
25
|
+
response: {
|
26
|
+
...error.response,
|
27
|
+
data: {
|
28
|
+
product: [
|
29
|
+
productNotFound(sku)
|
30
|
+
]
|
31
|
+
},
|
32
|
+
statusText: getStatusText(error.response)
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
console.error('Unable to detect SKU from the given parameter', filterParam);
|
38
|
+
}
|
39
|
+
|
40
|
+
return Promise.reject(error);
|
41
|
+
}
|
42
|
+
|
43
|
+
/**
|
44
|
+
* getSKU returns the SKU from the given parameter.
|
45
|
+
* @param {string} param '\\''index_key_productId="02010489" OR index_key_skuId="02010489"'''
|
46
|
+
* @returns {string|null} SKU
|
47
|
+
*/
|
48
|
+
function getSKU(param) {
|
49
|
+
const result = param.match(/\d{8}/);
|
50
|
+
|
51
|
+
if (result === null) {
|
52
|
+
return null;
|
53
|
+
}
|
54
|
+
|
55
|
+
return result[0];
|
56
|
+
}
|
57
|
+
|
58
|
+
/**
|
59
|
+
* @param {import('axios').AxiosResponse<import('../').EquinoxErrorResponse>} [response]
|
60
|
+
* @returns {string}
|
61
|
+
*/
|
62
|
+
function getStatusText(response) {
|
63
|
+
if (response) {
|
64
|
+
const { code, message, timestamp } = response.data;
|
65
|
+
return `Floating product found -- ${timestamp} ${code}: ${message}`;
|
66
|
+
}
|
67
|
+
|
68
|
+
return '';
|
69
|
+
}
|
70
|
+
|
71
|
+
module.exports = productNotFoundInterceptor;
|
@@ -0,0 +1,182 @@
|
|
1
|
+
// @ts-check
|
2
|
+
/**
|
3
|
+
* mapProperties maps the properties of a product.
|
4
|
+
* @param {import('../').EquinoxProductProperties} props
|
5
|
+
*/
|
6
|
+
function mapProperties(props) {
|
7
|
+
/** @type {import('../').EquinoxProductProperties} */
|
8
|
+
const properties = {};
|
9
|
+
properties.name = mapName(props.name);
|
10
|
+
properties.description = mapDescription(props.description);
|
11
|
+
properties.productDetailsDescription = mapProductDetailsDescription(props.productDetailsDescription);
|
12
|
+
properties.ingredients = mapIngredients(props.ingredients);
|
13
|
+
properties.benefits = mapBenefits(props.benefits);
|
14
|
+
properties.usage = mapUsage(props.usage);
|
15
|
+
properties.scanQualifiedCount = mapScanQualifiedCount(props.scanQualifiedCount);
|
16
|
+
properties.division = mapDivision(props.division);
|
17
|
+
properties.imageURL = mapImageURL(props.imageURL);
|
18
|
+
properties.market = mapMarket(props.market);
|
19
|
+
properties.resources = mapResources(props.resources);
|
20
|
+
properties.customerTypes = mapCustomerTypes(props.customerTypes);
|
21
|
+
properties.size = mapSize(props.size);
|
22
|
+
|
23
|
+
return properties;
|
24
|
+
}
|
25
|
+
|
26
|
+
/**
|
27
|
+
* @param {string|undefined} name
|
28
|
+
* @returns {string}
|
29
|
+
*/
|
30
|
+
function mapName(name) {
|
31
|
+
if (name) {
|
32
|
+
return name;
|
33
|
+
}
|
34
|
+
|
35
|
+
return '';
|
36
|
+
}
|
37
|
+
|
38
|
+
/**
|
39
|
+
* @param {string|undefined} description
|
40
|
+
* @returns {string}
|
41
|
+
*/
|
42
|
+
function mapDescription(description) {
|
43
|
+
if (description) {
|
44
|
+
return description;
|
45
|
+
}
|
46
|
+
|
47
|
+
return '';
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* @param {string} productDetailsDescription
|
52
|
+
* @returns {string}
|
53
|
+
*/
|
54
|
+
function mapProductDetailsDescription(productDetailsDescription) {
|
55
|
+
if (productDetailsDescription) {
|
56
|
+
return productDetailsDescription;
|
57
|
+
}
|
58
|
+
|
59
|
+
return '';
|
60
|
+
}
|
61
|
+
|
62
|
+
/**
|
63
|
+
* @param {string|undefined} ingredients
|
64
|
+
* @returns {string}
|
65
|
+
*/
|
66
|
+
function mapIngredients(ingredients) {
|
67
|
+
if (ingredients) {
|
68
|
+
return ingredients;
|
69
|
+
}
|
70
|
+
|
71
|
+
return '';
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
* @param {string|undefined} benefits
|
76
|
+
* @returns {string}
|
77
|
+
*/
|
78
|
+
function mapBenefits(benefits) {
|
79
|
+
if (benefits) {
|
80
|
+
return benefits;
|
81
|
+
}
|
82
|
+
|
83
|
+
return '';
|
84
|
+
}
|
85
|
+
|
86
|
+
/**
|
87
|
+
* @param {string|undefined} usage
|
88
|
+
* @returns {string}
|
89
|
+
*/
|
90
|
+
function mapUsage(usage) {
|
91
|
+
if (usage) {
|
92
|
+
return usage;
|
93
|
+
}
|
94
|
+
|
95
|
+
return '';
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* @param {string|undefined} scanQualifiedCount
|
100
|
+
* @returns {string}
|
101
|
+
*/
|
102
|
+
function mapScanQualifiedCount(scanQualifiedCount) {
|
103
|
+
if (scanQualifiedCount) {
|
104
|
+
return scanQualifiedCount;
|
105
|
+
}
|
106
|
+
|
107
|
+
return '';
|
108
|
+
}
|
109
|
+
|
110
|
+
/**
|
111
|
+
* @param {string|undefined} division
|
112
|
+
* @returns {string}
|
113
|
+
*/
|
114
|
+
function mapDivision(division) {
|
115
|
+
if (division) {
|
116
|
+
return division;
|
117
|
+
}
|
118
|
+
|
119
|
+
return '';
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* @param {string|undefined} imageURL
|
124
|
+
* @returns {string}
|
125
|
+
*/
|
126
|
+
function mapImageURL(imageURL) {
|
127
|
+
if (imageURL) {
|
128
|
+
return imageURL;
|
129
|
+
}
|
130
|
+
|
131
|
+
return '';
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* @param {string|undefined} market
|
136
|
+
* @returns {string}
|
137
|
+
*/
|
138
|
+
function mapMarket(market) {
|
139
|
+
if (market) {
|
140
|
+
return market;
|
141
|
+
}
|
142
|
+
|
143
|
+
return '';
|
144
|
+
}
|
145
|
+
|
146
|
+
/**
|
147
|
+
* @param {string|undefined} resources
|
148
|
+
* @returns {string}
|
149
|
+
*/
|
150
|
+
function mapResources(resources) {
|
151
|
+
if (resources) {
|
152
|
+
return resources;
|
153
|
+
}
|
154
|
+
|
155
|
+
return '';
|
156
|
+
}
|
157
|
+
|
158
|
+
/**
|
159
|
+
* @param {string|undefined} customerTypes
|
160
|
+
* @returns {string}
|
161
|
+
*/
|
162
|
+
function mapCustomerTypes(customerTypes) {
|
163
|
+
if (customerTypes) {
|
164
|
+
return customerTypes;
|
165
|
+
}
|
166
|
+
|
167
|
+
return '';
|
168
|
+
}
|
169
|
+
|
170
|
+
/**
|
171
|
+
* @param {string|undefined} size
|
172
|
+
* @returns {string}
|
173
|
+
*/
|
174
|
+
function mapSize(size) {
|
175
|
+
if (size) {
|
176
|
+
return size;
|
177
|
+
}
|
178
|
+
|
179
|
+
return '';
|
180
|
+
}
|
181
|
+
|
182
|
+
module.exports = mapProperties;
|
@@ -0,0 +1,32 @@
|
|
1
|
+
// @ts-check
|
2
|
+
const { mapProperties } = require('../mappers');
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @param {string} sku
|
6
|
+
* @returns {import('../').EquinoxProduct}
|
7
|
+
*/
|
8
|
+
function productNotFound(sku) {
|
9
|
+
/** @type {import('../').EquinoxProduct} */
|
10
|
+
const model = {};
|
11
|
+
model.identifier = sku || '';
|
12
|
+
model.properties = mapProperties({
|
13
|
+
name: '',
|
14
|
+
imageURL: '',
|
15
|
+
market: '',
|
16
|
+
description: '',
|
17
|
+
customerTypes: '',
|
18
|
+
division: '',
|
19
|
+
ingredients: '',
|
20
|
+
benefits: '',
|
21
|
+
usage: '',
|
22
|
+
resources: '',
|
23
|
+
scanQualifiedCount: '',
|
24
|
+
status: '',
|
25
|
+
size: '',
|
26
|
+
productDetailsDescription: ''
|
27
|
+
});
|
28
|
+
|
29
|
+
return model;
|
30
|
+
}
|
31
|
+
|
32
|
+
module.exports = productNotFound;
|
package/src/productData.js
CHANGED
@@ -6,6 +6,7 @@ const Product = require("./product");
|
|
6
6
|
const CustomerTypes = require('./models/customerTypes');
|
7
7
|
const ProductStatus = require("./models/productStatus");
|
8
8
|
const { mapAvailableQuantity, mapChildSKU } = require('./equinox-helpers');
|
9
|
+
const { productNotFoundInterceptor } = require('./equinox-helpers/interceptors');
|
9
10
|
|
10
11
|
const productTypes = {
|
11
12
|
kit: 'kit'
|
@@ -66,9 +67,11 @@ const ProductData = {
|
|
66
67
|
}
|
67
68
|
|
68
69
|
const filter = skuFilter.join(" OR ")
|
70
|
+
//axios.defaults.withCredentials = true;
|
69
71
|
|
70
72
|
const url = `${config.API_Base_URLs}/orchestrationservices/storefront/catalogs/search/`;
|
71
73
|
const href = `${url}?filter='\\\\''${encodeURI(filter)}'\\''`;
|
74
|
+
axios.interceptors.response.use((res) => res, productNotFoundInterceptor);
|
72
75
|
const response = await axios.request({
|
73
76
|
method: 'get',
|
74
77
|
url: href,
|
@@ -81,6 +84,7 @@ const ProductData = {
|
|
81
84
|
withCredentials: true
|
82
85
|
});
|
83
86
|
|
87
|
+
axios.interceptors.response.eject(productNotFoundInterceptor);
|
84
88
|
return response;
|
85
89
|
},
|
86
90
|
|
@@ -132,11 +136,9 @@ const ProductData = {
|
|
132
136
|
let thumbnailImage = imageURL ? imageURL + '?width=40' : ''
|
133
137
|
|
134
138
|
|
135
|
-
const { eventName, eventLabels, computedPrice, defaultProductPrice
|
139
|
+
const { eventName, eventLabels, computedPrice, defaultProductPrice } = this.getEqProductPromotions(eqVariant);
|
136
140
|
const productPrice = eventName ? defaultProductPrice : eqVariant.priceFacets["Regular Price"];
|
137
141
|
const discountedPrice = eventName ? computedPrice : eqVariant.priceFacets["Regular Price"];
|
138
|
-
const productCVPrice = eventName ? CVPrice : eqVariant.priceFacets.CV;
|
139
|
-
const productPVPrice = eventName ? PVPrice : eqVariant.priceFacets.PV;
|
140
142
|
|
141
143
|
return {
|
142
144
|
"sku": eqVariant.identifier,
|
@@ -243,8 +245,8 @@ const ProductData = {
|
|
243
245
|
"availableQuantity": eqVariant.inventoryProperties.atpQty,
|
244
246
|
"maxQuantity": 999,
|
245
247
|
"points": "",
|
246
|
-
"cv":
|
247
|
-
"pv":
|
248
|
+
"cv": (eqVariant.priceFacets.CV) ? eqVariant.priceFacets.CV : '',
|
249
|
+
"pv": eqVariant.priceFacets.PV,
|
248
250
|
"priceType": "WRTL",
|
249
251
|
"price": discountedPrice,
|
250
252
|
"priceMap": {
|
@@ -257,14 +259,14 @@ const ProductData = {
|
|
257
259
|
"WHL": eqVariant.priceFacets["Wholesale Price"]
|
258
260
|
},
|
259
261
|
"cvMap": {
|
260
|
-
"WWHL":
|
261
|
-
"WADW":
|
262
|
-
"WHL":
|
262
|
+
"WWHL": (eqVariant.priceFacets.CV) ? eqVariant.priceFacets.CV : '',
|
263
|
+
"WADW": (eqVariant.priceFacets.CV) ? eqVariant.priceFacets.CV : '',
|
264
|
+
"WHL": (eqVariant.priceFacets.CV) ? eqVariant.priceFacets.CV : ''
|
263
265
|
},
|
264
266
|
"pvMap": {
|
265
|
-
"WWHL":
|
266
|
-
"WADW":
|
267
|
-
"WHL":
|
267
|
+
"WWHL": eqVariant.priceFacets.PV,
|
268
|
+
"WADW": eqVariant.priceFacets.PV,
|
269
|
+
"WHL": eqVariant.priceFacets.PV
|
268
270
|
},
|
269
271
|
"orderTypes": this._setOrderType(eqVariant.properties),
|
270
272
|
"custTypes": this.switchCustType(eqVariant.properties.customerTypes),
|
@@ -297,8 +299,7 @@ const ProductData = {
|
|
297
299
|
},
|
298
300
|
"restrictedMarkets": [],
|
299
301
|
"addOns": [],
|
300
|
-
"equinoxProductId": eqVariant.identifier
|
301
|
-
"properties": eqVariant.properties
|
302
|
+
"equinoxProductId": eqVariant.identifier
|
302
303
|
};
|
303
304
|
},
|
304
305
|
|
@@ -322,16 +323,6 @@ const ProductData = {
|
|
322
323
|
const computedPrice = product.totalValue && product.totalValue.priceAfterDiscount
|
323
324
|
? product.totalValue.priceAfterDiscount
|
324
325
|
: 0;
|
325
|
-
|
326
|
-
let CVPrice = 0,
|
327
|
-
PVPrice = 0;
|
328
|
-
|
329
|
-
if (product.totalValue && product.totalValue.priceFacets) {
|
330
|
-
const productPriceFacets = product.totalValue.priceFacets;
|
331
|
-
CVPrice = productPriceFacets.CV && productPriceFacets.CV.CVAfterDiscount ? productPriceFacets.CV.CVAfterDiscount : 0;
|
332
|
-
PVPrice = productPriceFacets.PV && productPriceFacets.PV.PVAfterDiscount ? productPriceFacets.PV.PVAfterDiscount : 0;
|
333
|
-
}
|
334
|
-
|
335
326
|
let eventName = "";
|
336
327
|
const eventLabels = [];
|
337
328
|
|
@@ -345,19 +336,17 @@ const ProductData = {
|
|
345
336
|
eventLabels: eventLabels.join(','),
|
346
337
|
defaultProductPrice,
|
347
338
|
computedPrice,
|
348
|
-
eventName
|
349
|
-
CVPrice,
|
350
|
-
PVPrice
|
339
|
+
eventName
|
351
340
|
}
|
352
341
|
},
|
353
342
|
|
354
343
|
eqProductMapper: async function (productDataResponse, skus) {
|
355
344
|
let count = 0;
|
345
|
+
let variants = {};
|
356
346
|
const products = [];
|
357
347
|
|
358
348
|
for (const productData of productDataResponse) {
|
359
349
|
try {
|
360
|
-
let variants = {};
|
361
350
|
let product = (productData.type && productData.type === "kit") ? productData : productData.sku[count];
|
362
351
|
let imageURL = product.properties.imageURL ? product.properties.imageURL : '';
|
363
352
|
let thumbnailImage = imageURL ? imageURL + '?width=40' : ''
|
@@ -375,14 +364,10 @@ const ProductData = {
|
|
375
364
|
eventName,
|
376
365
|
eventLabels,
|
377
366
|
computedPrice,
|
378
|
-
defaultProductPrice
|
379
|
-
CVPrice,
|
380
|
-
PVPrice
|
367
|
+
defaultProductPrice
|
381
368
|
} = this.getEqProductPromotions(product);
|
382
369
|
const productPrice = eventName ? defaultProductPrice : product.priceFacets["Regular Price"];
|
383
370
|
const discountedPrice = eventName ? computedPrice : product.priceFacets["Regular Price"];
|
384
|
-
const productCVPrice = eventName ? CVPrice : product.priceFacets.CV;
|
385
|
-
const productPVPrice = eventName ? PVPrice : product.priceFacets.PV;
|
386
371
|
|
387
372
|
product.childSkus = await this.fetchChildSkus(product);
|
388
373
|
product.availableQuantity = mapAvailableQuantity(product);
|
@@ -421,8 +406,8 @@ const ProductData = {
|
|
421
406
|
"scanQualified": productData.properties.scanQualifiedCount,
|
422
407
|
"maxQuantity": 999,
|
423
408
|
"points": "",
|
424
|
-
"cv":
|
425
|
-
"pv":
|
409
|
+
"cv": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
410
|
+
"pv": product.priceFacets.PV,
|
426
411
|
"priceType": "WRTL",
|
427
412
|
"price": discountedPrice,
|
428
413
|
"priceMap": {
|
@@ -435,14 +420,14 @@ const ProductData = {
|
|
435
420
|
"WWHL": product.priceFacets["Wholesale Price"]
|
436
421
|
},
|
437
422
|
"cvMap": {
|
438
|
-
"WWHL":
|
439
|
-
"WADW":
|
440
|
-
"WHL":
|
423
|
+
"WWHL": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
424
|
+
"WADW": (product.priceFacets.CV) ? product.priceFacets.CV : '',
|
425
|
+
"WHL": (product.priceFacets.CV) ? product.priceFacets.CV : ''
|
441
426
|
},
|
442
427
|
"pvMap": {
|
443
|
-
"WWHL":
|
444
|
-
"WADW":
|
445
|
-
"WHL":
|
428
|
+
"WWHL": product.priceFacets.PV,
|
429
|
+
"WADW": product.priceFacets.PV,
|
430
|
+
"WHL": product.priceFacets.PV
|
446
431
|
},
|
447
432
|
"orderTypes": this._setOrderType(product.properties),
|
448
433
|
"custTypes": this.switchCustType(product.properties.customerTypes),
|
@@ -477,8 +462,7 @@ const ProductData = {
|
|
477
462
|
"restrictedMarkets": [],
|
478
463
|
"addOns": [],
|
479
464
|
"inventory": product.inventory || "", //inventory label
|
480
|
-
"equinoxProductId": productData.identifier
|
481
|
-
"properties": product.properties
|
465
|
+
"equinoxProductId": productData.identifier
|
482
466
|
};
|
483
467
|
|
484
468
|
products.push(new Product(product));
|