@nuskin/product-components 3.17.0 → 3.18.0-cx24-6773.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/.releaserc +1 -1
- package/docs/CHANGELOG.md +1 -1
- package/gl-sbom-npm-yarn.cdx.json +2 -2
- package/mixins/NsProductMixin.js +48 -2
- package/package.json +1 -1
- package/services/EQPromotionService.js +138 -0
package/.releaserc
CHANGED
package/docs/CHANGELOG.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
# [3.
|
|
1
|
+
# [3.18.0-cx24-6773.1](https://code.tls.nuskin.io/ns-am/ux/product-components/compare/v3.17.0...v3.18.0-cx24-6773.1) (2024-06-11)
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bomFormat": "CycloneDX",
|
|
3
3
|
"specVersion": "1.4",
|
|
4
|
-
"serialNumber": "urn:uuid:
|
|
4
|
+
"serialNumber": "urn:uuid:457a32ad-5106-4c24-b156-5fa71061dc21",
|
|
5
5
|
"version": 1,
|
|
6
6
|
"metadata": {
|
|
7
|
-
"timestamp": "2024-06-
|
|
7
|
+
"timestamp": "2024-06-11T05:48:06Z",
|
|
8
8
|
"tools": [
|
|
9
9
|
{
|
|
10
10
|
"vendor": "GitLab",
|
package/mixins/NsProductMixin.js
CHANGED
|
@@ -32,9 +32,11 @@ import { getProp, getFullUrl } from "@nuskin/ns-common-lib";
|
|
|
32
32
|
import { PriceType } from "@nuskin/ns-product-lib";
|
|
33
33
|
import { ProductDataService } from "@nuskin/ns-product";
|
|
34
34
|
import { waitForConfig } from "../services/configHelper";
|
|
35
|
+
import { fetchPromotionalPrices } from "../services/EQPromotionService";
|
|
35
36
|
|
|
36
37
|
const PENDING_FAVORITE = "pendingFavorite";
|
|
37
38
|
const KEY_BREADCRUMB_BACK = "breadcrumbBack";
|
|
39
|
+
const BUNDLE = "BUNDLE";
|
|
38
40
|
|
|
39
41
|
let flagsPromise = null;
|
|
40
42
|
let featureFlags = false;
|
|
@@ -216,6 +218,8 @@ const NsProductMixin = {
|
|
|
216
218
|
* Active poduct data
|
|
217
219
|
*/
|
|
218
220
|
product: undefined,
|
|
221
|
+
promotionPrice: null,
|
|
222
|
+
promotionOriginalPrice: null,
|
|
219
223
|
/**
|
|
220
224
|
* Quantity of product selected
|
|
221
225
|
*/
|
|
@@ -550,7 +554,7 @@ const NsProductMixin = {
|
|
|
550
554
|
/**
|
|
551
555
|
* Sets product to new selection
|
|
552
556
|
*/
|
|
553
|
-
setActiveProduct() {
|
|
557
|
+
async setActiveProduct() {
|
|
554
558
|
if (this.baseProduct && this.baseProduct.isBase()) {
|
|
555
559
|
let activeProduct = this.variants.find(
|
|
556
560
|
variantProduct => variantProduct.sku === this.activeSku
|
|
@@ -619,6 +623,30 @@ const NsProductMixin = {
|
|
|
619
623
|
//console.error(err);
|
|
620
624
|
}
|
|
621
625
|
|
|
626
|
+
let isBundle = false;
|
|
627
|
+
if (this.product.childSkus && this.product.childSkus.length) {
|
|
628
|
+
this.product.childSkus.forEach(product => {
|
|
629
|
+
if (product.type === BUNDLE) {
|
|
630
|
+
isBundle = true;
|
|
631
|
+
}
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
if (isBundle) {
|
|
635
|
+
const promotion = await fetchPromotionalPrices(this.product);
|
|
636
|
+
if (promotion) {
|
|
637
|
+
if (promotion.price) {
|
|
638
|
+
this.promotionPrice = promotion.price;
|
|
639
|
+
this.price = promotion.price;
|
|
640
|
+
this.product.setPrice(promotion.price);
|
|
641
|
+
}
|
|
642
|
+
if (promotion.originalPrice) {
|
|
643
|
+
this.promotionOriginalPrice = promotion.originalPrice;
|
|
644
|
+
this.originalPrice = promotion.originalPrice;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
//this.$emit("quantity-select", this.selectedQuantity);
|
|
648
|
+
}
|
|
649
|
+
|
|
622
650
|
this.setProductPricingAndAvailability();
|
|
623
651
|
this.$emit("product-update", this.product);
|
|
624
652
|
},
|
|
@@ -840,7 +868,7 @@ const NsProductMixin = {
|
|
|
840
868
|
/**
|
|
841
869
|
* Sets sales event pricing if there is an active event for this sku, or normal pricing if not
|
|
842
870
|
*/
|
|
843
|
-
setProductPricing() {
|
|
871
|
+
async setProductPricing() {
|
|
844
872
|
const equinoxMarketsConfig = getCachedConfiguration("Equinox_Markets");
|
|
845
873
|
const isEquinoxEnabled =
|
|
846
874
|
equinoxLocalStorage.isEquinoxEnabled() && equinoxMarketsConfig.active;
|
|
@@ -934,6 +962,24 @@ const NsProductMixin = {
|
|
|
934
962
|
this.isSale = false;
|
|
935
963
|
this.setStandardPricing();
|
|
936
964
|
}
|
|
965
|
+
|
|
966
|
+
let isBundle = false;
|
|
967
|
+
if (this.product.childSkus && this.product.childSkus.length) {
|
|
968
|
+
this.product.childSkus.forEach(product => {
|
|
969
|
+
if (product.type === BUNDLE) {
|
|
970
|
+
isBundle = true;
|
|
971
|
+
}
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
if (isBundle && isEquinoxEnabled) {
|
|
975
|
+
if (this.promotionPrice) {
|
|
976
|
+
this.price = this.promotionPrice;
|
|
977
|
+
this.product.setPrice(this.promotionPrice);
|
|
978
|
+
}
|
|
979
|
+
if (this.promotionOriginalPrice) {
|
|
980
|
+
this.originalPrice = this.promotionOriginalPrice;
|
|
981
|
+
}
|
|
982
|
+
}
|
|
937
983
|
},
|
|
938
984
|
|
|
939
985
|
/**
|
package/package.json
CHANGED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { UrlService } from "@nuskin/ns-util";
|
|
3
|
+
import { getConfiguration } from "@nuskin/configuration-sdk";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* To get the promontional prices from equinox storefront
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export const fetchPromotionalPrices = async product => {
|
|
11
|
+
try {
|
|
12
|
+
const payload = buildPayload(product);
|
|
13
|
+
const options = {
|
|
14
|
+
method: "POST",
|
|
15
|
+
endpoint: `catalogs/products/${product.sku}/promotions`,
|
|
16
|
+
data: payload
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const { data } = await _equinoxRequest(options);
|
|
20
|
+
return {
|
|
21
|
+
price: data.unitValue.priceAfterDiscount,
|
|
22
|
+
originalPrice: data.unitValue.originalPrice
|
|
23
|
+
};
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.log("Error while fetching promotional prices");
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const buildPayload = product => {
|
|
31
|
+
const payload = {
|
|
32
|
+
productId: product.sku,
|
|
33
|
+
categoryId: ["all_products"],
|
|
34
|
+
quantity: 1,
|
|
35
|
+
skus: [],
|
|
36
|
+
isSubscriptionIncludedInPromotion: false,
|
|
37
|
+
isFromBrowse: true
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
let personalOffer = sessionStorage.getItem("personalOffer");
|
|
42
|
+
if (personalOffer !== null) {
|
|
43
|
+
personalOffer = JSON.parse(personalOffer);
|
|
44
|
+
}
|
|
45
|
+
const matchedProduct = personalOffer.products.filter(
|
|
46
|
+
offerProduct => offerProduct.sku === product.sku
|
|
47
|
+
);
|
|
48
|
+
const selectedVariants =
|
|
49
|
+
matchedProduct &&
|
|
50
|
+
matchedProduct.length > 0 &&
|
|
51
|
+
matchedProduct[0].variantSelected
|
|
52
|
+
? matchedProduct[0].variantSelected
|
|
53
|
+
: null;
|
|
54
|
+
|
|
55
|
+
const skus = [];
|
|
56
|
+
if (product && product.childSkus) {
|
|
57
|
+
product.childSkus.forEach(childSku => {
|
|
58
|
+
if (childSku.type === "MANDATORY") {
|
|
59
|
+
skus.push({
|
|
60
|
+
skuId:
|
|
61
|
+
selectedVariants !== null && selectedVariants[childSku.productId]
|
|
62
|
+
? selectedVariants[childSku.productId]
|
|
63
|
+
: childSku.skuId,
|
|
64
|
+
productId: childSku.productId,
|
|
65
|
+
quantity: childSku.skuQuantity,
|
|
66
|
+
type: "bundle"
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
payload.skus = skus;
|
|
73
|
+
payload.quantity =
|
|
74
|
+
matchedProduct && matchedProduct.qty ? matchedProduct.qty : 1;
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.log("Error while building payload");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return payload;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const _equinoxRequest = async options => {
|
|
83
|
+
const {
|
|
84
|
+
marketLocale,
|
|
85
|
+
storeId,
|
|
86
|
+
storefrontURL,
|
|
87
|
+
headers
|
|
88
|
+
} = await getEquinoxRequestConfiguration();
|
|
89
|
+
const equinoxParams = {
|
|
90
|
+
locale: marketLocale,
|
|
91
|
+
storeId: storeId
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
let axiosRequest = {
|
|
95
|
+
method: options.method,
|
|
96
|
+
url: `${storefrontURL}/orchestrationservices/storefront/${options.endpoint}`,
|
|
97
|
+
headers: headers,
|
|
98
|
+
withCredentials: options.method !== "DELETE",
|
|
99
|
+
params: equinoxParams
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
if (options.data) {
|
|
103
|
+
axiosRequest.data = options.data;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return axios(axiosRequest);
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
const getEquinoxRequestConfiguration = async () => {
|
|
110
|
+
const marketLocale = UrlService.getLocale();
|
|
111
|
+
const config = (await getConfiguration(["Equinox_Markets"])).Equinox_Markets;
|
|
112
|
+
const storefrontURL = config.API_Base_URLs;
|
|
113
|
+
|
|
114
|
+
const sessionData = sessionStorage.getItem("oktaTokens");
|
|
115
|
+
const parsedSessionData = JSON.parse(sessionData);
|
|
116
|
+
const sessionOktaToken =
|
|
117
|
+
parsedSessionData && parsedSessionData.accessToken
|
|
118
|
+
? parsedSessionData.accessToken
|
|
119
|
+
: "";
|
|
120
|
+
const localStorageOktaToken = localStorage.getItem("equinox-okta-token");
|
|
121
|
+
|
|
122
|
+
let oktaToken = localStorageOktaToken
|
|
123
|
+
? localStorageOktaToken
|
|
124
|
+
: sessionOktaToken;
|
|
125
|
+
|
|
126
|
+
const headers = {
|
|
127
|
+
Accept: "*",
|
|
128
|
+
"Content-Type": "application/json",
|
|
129
|
+
Authorization: `Bearer ${oktaToken}`
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
marketLocale,
|
|
134
|
+
storeId: config.store_id,
|
|
135
|
+
storefrontURL,
|
|
136
|
+
headers
|
|
137
|
+
};
|
|
138
|
+
};
|