@mframework/layer-commerce 0.0.3
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/README.md +101 -0
- package/app/cart/useCart.ts +1 -0
- package/app/components/ChevronIcon/ChevronIcon.config.ts +17 -0
- package/app/components/DateSelect/DateSelect.config.ts +15 -0
- package/app/components/Field/Field.config.ts +14 -0
- package/app/components/FieldDate/FieldDate.config.ts +16 -0
- package/app/components/Form/Form.type.ts +8 -0
- package/app/components/Product/Product.config.ts +19 -0
- package/app/components/Product/Stock.config.ts +15 -0
- package/app/components/ProductCustomizableOption/ProductCustomizableOption.config.ts +5 -0
- package/app/components/ProductGallery/ProductGallery.config.ts +15 -0
- package/app/components/ProductReviews/ProductReviews.config.ts +8 -0
- package/app/composables/_types.ts +18 -0
- package/app/composables/adapters/abstract/cartAdapter.ts +0 -0
- package/app/composables/adapters/abstract/categoryAdapter.ts +0 -0
- package/app/composables/adapters/abstract/customerAdapter.ts +0 -0
- package/app/composables/adapters/abstract/inventoryAdapter.ts +0 -0
- package/app/composables/adapters/abstract/orderAdapter.ts +0 -0
- package/app/composables/adapters/abstract/productAdapter.ts +7 -0
- package/app/composables/cart/registry.ts +20 -0
- package/app/composables/cart/types.ts +18 -0
- package/app/composables/cart/useCart.ts +15 -0
- package/app/composables/config.ts +19 -0
- package/app/composables/defs/apiDefinitions.ts +55 -0
- package/app/composables/defs/extension.feature +40 -0
- package/app/composables/defs/extension.mocks.ts +39 -0
- package/app/composables/defs/extension.test.ts +280 -0
- package/app/composables/defs/extension.ts +236 -0
- package/app/composables/defs/index.ts +3 -0
- package/app/composables/defs/typeHelpers.ts +8 -0
- package/app/composables/defs/types.ts +136 -0
- package/app/composables/domain/product.ts +12 -0
- package/app/composables/featured-products.ts +20 -0
- package/app/composables/helpers/contextualizedNormalizers.feature +14 -0
- package/app/composables/helpers/contextualizedNormalizers.test.ts +85 -0
- package/app/composables/helpers/contextualizedNormalizers.ts +20 -0
- package/app/composables/helpers/index.ts +1 -0
- package/app/composables/index.ts +9 -0
- package/app/composables/methods/auth.ts +83 -0
- package/app/composables/methods/cart.ts +119 -0
- package/app/composables/methods/category.ts +27 -0
- package/app/composables/methods/checkout.ts +54 -0
- package/app/composables/methods/customer.ts +52 -0
- package/app/composables/methods/helpers.ts +5 -0
- package/app/composables/methods/index.ts +75 -0
- package/app/composables/methods/order.ts +39 -0
- package/app/composables/methods/product.ts +95 -0
- package/app/composables/methods/settings.ts +16 -0
- package/app/composables/models/cart.ts +95 -0
- package/app/composables/models/category.ts +13 -0
- package/app/composables/models/checkout.ts +17 -0
- package/app/composables/models/customer.ts +16 -0
- package/app/composables/models/facets.ts +25 -0
- package/app/composables/models/index.ts +94 -0
- package/app/composables/models/order.ts +43 -0
- package/app/composables/models/product.ts +73 -0
- package/app/composables/models/shared.ts +75 -0
- package/app/composables/orders.ts +69 -0
- package/app/composables/products/registry.ts +86 -0
- package/app/composables/products/types.ts +8 -0
- package/app/composables/products/useEvents.ts +26 -0
- package/app/composables/products/useGiftCards.ts +29 -0
- package/app/composables/products/useProducts.ts +12 -0
- package/app/composables/products/useSubscriptions.ts +29 -0
- package/app/composables/products.ts +30 -0
- package/app/composables/registry.ts +24 -0
- package/app/composables/useAuth.ts +43 -0
- package/app/composables/useBreakpoints/index.ts +1 -0
- package/app/composables/useBreakpoints/useBreakpoints.ts +28 -0
- package/app/composables/useCache.ts +38 -0
- package/app/composables/useCart/__tests__/useCart.spec.ts +11 -0
- package/app/composables/useCart/index.ts +1 -0
- package/app/composables/useCart/types.ts +17 -0
- package/app/composables/useCart/useCart.ts +46 -0
- package/app/composables/useCartShippingMethods/__tests__/useCartShippingMethods.spec.ts +11 -0
- package/app/composables/useCartShippingMethods/index.ts +1 -0
- package/app/composables/useCartShippingMethods/types.ts +17 -0
- package/app/composables/useCartShippingMethods/useCartShippingMethods.ts +47 -0
- package/app/composables/useCatalog.ts +26 -0
- package/app/composables/useContent.ts +26 -0
- package/app/composables/useCustomer/__tests__/useCustomer.spec.ts +25 -0
- package/app/composables/useCustomer/index.ts +2 -0
- package/app/composables/useCustomer/types.ts +17 -0
- package/app/composables/useCustomer/useCustomer.ts +40 -0
- package/app/composables/useCustomerAddress/__tests__/useCustomerAddress.spec.ts +11 -0
- package/app/composables/useCustomerAddress/index.ts +2 -0
- package/app/composables/useCustomerAddress/types.ts +17 -0
- package/app/composables/useCustomerAddress/useCustomerAddress.ts +55 -0
- package/app/composables/useCustomerOrder/__tests__/useCustomerOrder.spec.ts +11 -0
- package/app/composables/useCustomerOrder/adress.ts +10 -0
- package/app/composables/useCustomerOrder/index.ts +2 -0
- package/app/composables/useCustomerOrder/product.ts +37 -0
- package/app/composables/useCustomerOrder/types.ts +40 -0
- package/app/composables/useCustomerOrder/useCustomerOrder.ts +63 -0
- package/app/composables/useCustomerOrders/__tests__/useCustomerOrders.spec.ts +11 -0
- package/app/composables/useCustomerOrders/index.ts +2 -0
- package/app/composables/useCustomerOrders/types.ts +20 -0
- package/app/composables/useCustomerOrders/useCustomerOrders.ts +56 -0
- package/app/composables/useCustomerReturns/__tests__/useCustomerReturns.spec.ts +11 -0
- package/app/composables/useCustomerReturns/index.ts +2 -0
- package/app/composables/useCustomerReturns/types.ts +17 -0
- package/app/composables/useCustomerReturns/useCustomerReturns.ts +41 -0
- package/app/composables/useHandleError/index.ts +1 -0
- package/app/composables/useHandleError/types.ts +11 -0
- package/app/composables/useHandleError/useHandleError.ts +27 -0
- package/app/composables/useInventory.ts +29 -0
- package/app/composables/useLoading.ts +21 -0
- package/app/composables/useNotification.ts +21 -0
- package/app/composables/usePageTitle.ts +20 -0
- package/app/composables/useProduct/index.ts +2 -0
- package/app/composables/useProduct/types.ts +17 -0
- package/app/composables/useProduct/useProduct.ts +42 -0
- package/app/composables/useProductAttribute/__tests__/useProduct.mock.ts +31 -0
- package/app/composables/useProductAttribute/__tests__/useProductAttribute.spec.ts +14 -0
- package/app/composables/useProductAttribute/index.ts +1 -0
- package/app/composables/useProductAttribute/useProductAttribute.ts +37 -0
- package/app/composables/useProductRecommended/__tests__/useProductRecommended.spec.ts +12 -0
- package/app/composables/useProductRecommended/index.ts +1 -0
- package/app/composables/useProductRecommended/types.ts +17 -0
- package/app/composables/useProductRecommended/useProductRecommended.ts +43 -0
- package/app/composables/useProductReviews/__tests__/productReviews.mock.ts +20 -0
- package/app/composables/useProductReviews/__tests__/useProductReviews.spec.ts +22 -0
- package/app/composables/useProductReviews/index.ts +2 -0
- package/app/composables/useProductReviews/types.ts +17 -0
- package/app/composables/useProductReviews/useProductReviews.ts +46 -0
- package/app/composables/useProducts/__tests__/useProducts.spec.ts +11 -0
- package/app/composables/useProducts/types.ts +22 -0
- package/app/composables/useProducts/useProducts.ts +41 -0
- package/app/composables/useTax.ts +27 -0
- package/app/composables/validationRules/index.ts +1 -0
- package/app/composables/validationRules/password.feature +67 -0
- package/app/composables/validationRules/password.test.ts +89 -0
- package/app/composables/validationRules/password.ts +25 -0
- package/app/normalizers/Cart.query.ts +729 -0
- package/app/normalizers/Cart.type.ts +285 -0
- package/app/normalizers/Category.query.ts +146 -0
- package/app/normalizers/Category.type.ts +55 -0
- package/app/normalizers/CheckEmail.query.ts +28 -0
- package/app/normalizers/Checkout.query.ts +253 -0
- package/app/normalizers/Checkout.type.ts +77 -0
- package/app/normalizers/CmsBlock.query.ts +57 -0
- package/app/normalizers/CmsBlock.type.ts +25 -0
- package/app/normalizers/CmsPage.query.ts +59 -0
- package/app/normalizers/CmsPage.type.ts +26 -0
- package/app/normalizers/Config.query.ts +224 -0
- package/app/normalizers/Config.type.ts +196 -0
- package/app/normalizers/ContactForm.query.ts +49 -0
- package/app/normalizers/CreditMemo.type.ts +49 -0
- package/app/normalizers/GiftCard.type.ts +24 -0
- package/app/normalizers/Invoice.type.ts +58 -0
- package/app/normalizers/Menu.query.ts +54 -0
- package/app/normalizers/Menu.type.ts +22 -0
- package/app/normalizers/MyAccount.query.ts +268 -0
- package/app/normalizers/MyAccount.type.ts +129 -0
- package/app/normalizers/NewsletterSubscription.query.ts +38 -0
- package/app/normalizers/Order.query.ts +741 -0
- package/app/normalizers/Order.type.ts +268 -0
- package/app/normalizers/Payment.type.ts +28 -0
- package/app/normalizers/ProductAlerts.query.ts +23 -0
- package/app/normalizers/ProductCompare.query.ts +226 -0
- package/app/normalizers/ProductCompare.type.ts +90 -0
- package/app/normalizers/ProductList.query.ts +1620 -0
- package/app/normalizers/ProductList.type.ts +726 -0
- package/app/normalizers/Region.query.ts +58 -0
- package/app/normalizers/Region.type.ts +23 -0
- package/app/normalizers/Return.type.ts +50 -0
- package/app/normalizers/Review.query.ts +81 -0
- package/app/normalizers/Review.type.ts +42 -0
- package/app/normalizers/Slider.query.ts +72 -0
- package/app/normalizers/Slider.type.ts +26 -0
- package/app/normalizers/StoreInPickUp.query.ts +54 -0
- package/app/normalizers/StoreInPickUp.type.ts +59 -0
- package/app/normalizers/Subscription.type.ts +25 -0
- package/app/normalizers/Transaction.type.ts +20 -0
- package/app/normalizers/UrlRewrites.query.ts +55 -0
- package/app/normalizers/UrlRewrites.type.ts +25 -0
- package/app/normalizers/Wishlist.query.ts +202 -0
- package/app/normalizers/Wishlist.type.ts +42 -0
- package/app/pages/brand/[...slug].vue +76 -0
- package/app/pages/brands.vue +67 -0
- package/app/pages/cart.vue +142 -0
- package/app/pages/compare.vue +166 -0
- package/app/pages/departments/[...slug].vue +353 -0
- package/app/pages/departments/category/[...slug].vue +114 -0
- package/app/pages/incentive/[...id].vue +66 -0
- package/app/pages/invoice/[id].vue +309 -0
- package/app/pages/order/[id].vue +327 -0
- package/app/pages/product/[...id].vue +309 -0
- package/app/pages/product/showcases/index.vue +86 -0
- package/app/pages/shipment/[...id].vue +176 -0
- package/app/pages/shop/[...slug].vue +158 -0
- package/app/pages/shops.vue +76 -0
- package/app/pages/subscription/[...id].vue +147 -0
- package/app/pages/transaction/[...id].vue +74 -0
- package/app/routes/CategoryPage/CategoryPage.config.ts +28 -0
- package/app/routes/CategoryPage/CategoryPage.type.ts +8 -0
- package/app/routes/Checkout/Checkout.config.ts +3 -0
- package/app/routes/Checkout/Checkout.type.ts +14 -0
- package/app/routes/MyAccount/MyAccount.config.ts +1 -0
- package/app/routes/SearchPage/SearchPage.config.ts +1 -0
- package/app/routes/UrlRewrites/UrlRewrites.config.ts +5 -0
- package/app/stores/Cart/Cart.type.ts +26 -0
- package/app/stores/MyAccount/MyAccount.action.ts +7 -0
- package/app/stores/Notification/Notification.action.ts +40 -0
- package/app/stores/Notification/Notification.type.ts +16 -0
- package/app/stores/Popup/Popup.action.ts +30 -0
- package/app/stores/Product/Product.dispatcher.ts +53 -0
- package/app/stores/Product/Product.reducer.ts +12 -0
- package/app/stores/ProductList/ProductList.dispatcher.ts +35 -0
- package/app/stores/ProductList/ProductList.reducer.ts +13 -0
- package/app/stores/Store.type.ts +31 -0
- package/app/stores/Wishlist/Wishlist.type.ts +12 -0
- package/app/stores/cart.ts +218 -0
- package/app/stores/cartStore.ts +224 -0
- package/app/stores/checkout.ts +18 -0
- package/app/stores/compare.ts +65 -0
- package/app/stores/currency.js +29 -0
- package/app/stores/digital-products.js +11 -0
- package/app/stores/orders.ts +172 -0
- package/app/stores/product.ts +34 -0
- package/app/stores/productList.ts +35 -0
- package/app/stores/productListInfo.ts +0 -0
- package/app/stores/products.ts +118 -0
- package/app/stores/recentlyViewedProducts.ts +56 -0
- package/app/stores/review.ts +33 -0
- package/app/stores/storeInPickUp.ts +21 -0
- package/app/stores/user.ts +20 -0
- package/app/stores/wishlist.ts +46 -0
- package/app/types/Account.type.ts +141 -0
- package/app/types/Breadcrumbs.type.ts +23 -0
- package/app/types/CMS.type.ts +33 -0
- package/app/types/Category.type.ts +67 -0
- package/app/types/Checkout.type.ts +58 -0
- package/app/types/Common.type.ts +77 -0
- package/app/types/Config.type.ts +47 -0
- package/app/types/Device.type.ts +37 -0
- package/app/types/Direction.type.ts +23 -0
- package/app/types/Downloadable.type.ts +24 -0
- package/app/types/Error.type.ts +22 -0
- package/app/types/Field.type.ts +151 -0
- package/app/types/Global.type.ts +156 -0
- package/app/types/Graphql.type.ts +4497 -0
- package/app/types/Layout.type.ts +18 -0
- package/app/types/Menu.type.ts +39 -0
- package/app/types/MiniCart.type.ts +61 -0
- package/app/types/NotificationList.type.ts +34 -0
- package/app/types/Order.type.ts +174 -0
- package/app/types/Price.type.ts +72 -0
- package/app/types/ProductCompare.type.ts +24 -0
- package/app/types/ProductList.type.ts +351 -0
- package/app/types/Rating.type.ts +42 -0
- package/app/types/Router.type.ts +67 -0
- package/app/types/Slider.type.ts +25 -0
- package/app/types/StockStatus.type.ts +21 -0
- package/app/types/domain/index.ts +94 -0
- package/app/types/index.ts +33 -0
- package/app/types/shims.d.ts +52 -0
- package/app/types/tilework-opus.d.ts +48 -0
- package/app/utils/Address/Address.type.ts +28 -0
- package/app/utils/Address/index.ts +325 -0
- package/app/utils/Auth/IsSignedIn.ts +4 -0
- package/app/utils/Auth/Token.ts +9 -0
- package/app/utils/Base64/Base64.ts +16 -0
- package/app/utils/Base64/index.ts +12 -0
- package/app/utils/Browser/Browser.ts +29 -0
- package/app/utils/Browser/index.ts +12 -0
- package/app/utils/BrowserDatabase/BrowserDatabase.ts +70 -0
- package/app/utils/BrowserDatabase/index.ts +12 -0
- package/app/utils/CSS/CSS.ts +65 -0
- package/app/utils/CSS/index.ts +12 -0
- package/app/utils/Cache/Cache.ts +99 -0
- package/app/utils/Cart/Cart.ts +300 -0
- package/app/utils/Cart/Cart.type.ts +76 -0
- package/app/utils/Cart/Token.ts +59 -0
- package/app/utils/Cart/index.ts +13 -0
- package/app/utils/Category/Filters.ts +39 -0
- package/app/utils/Category/index.ts +12 -0
- package/app/utils/Common/index.ts +32 -0
- package/app/utils/Compare/Compare.ts +89 -0
- package/app/utils/Compare/index.ts +12 -0
- package/app/utils/Currency/Currency.ts +84 -0
- package/app/utils/Currency/index.ts +12 -0
- package/app/utils/DynamicReducer/DynamicReducer.type.ts +14 -0
- package/app/utils/DynamicReducer/Helper.ts +30 -0
- package/app/utils/DynamicReducer/index.tsx +35 -0
- package/app/utils/ElementTransition/ElementTransition.ts +100 -0
- package/app/utils/Form/Extract.ts +316 -0
- package/app/utils/Form/Form.ts +46 -0
- package/app/utils/Form/Form.type.ts +60 -0
- package/app/utils/Form/Transform.ts +33 -0
- package/app/utils/FormPortalCollector/index.ts +45 -0
- package/app/utils/History/History.type.ts +31 -0
- package/app/utils/History/index.ts +17 -0
- package/app/utils/Manipulations/Array.ts +18 -0
- package/app/utils/Manipulations/Date.ts +36 -0
- package/app/utils/Manipulations/index.ts +14 -0
- package/app/utils/Media/Media.ts +27 -0
- package/app/utils/Media/index.ts +13 -0
- package/app/utils/Menu/Menu.ts +116 -0
- package/app/utils/Menu/Menu.type.ts +37 -0
- package/app/utils/Menu/index.ts +12 -0
- package/app/utils/Mobile/index.ts +13 -0
- package/app/utils/Mobile/isMobile.ts +34 -0
- package/app/utils/Orders/Orders.ts +71 -0
- package/app/utils/Orders/Orders.type.ts +19 -0
- package/app/utils/Orders/index.ts +13 -0
- package/app/utils/Polyfill/index.ts +336 -0
- package/app/utils/Preload/CategoryPreload.ts +74 -0
- package/app/utils/Preload/ProductPreload.ts +28 -0
- package/app/utils/Preload/index.ts +75 -0
- package/app/utils/Price/Price.config.ts +189 -0
- package/app/utils/Price/Price.ts +63 -0
- package/app/utils/Price/index.ts +12 -0
- package/app/utils/Product/Extract.ts +652 -0
- package/app/utils/Product/Product.ts +575 -0
- package/app/utils/Product/Product.type.ts +260 -0
- package/app/utils/Product/Transform.ts +382 -0
- package/app/utils/Product/index.ts +12 -0
- package/app/utils/Promise/MakeCancelable.ts +44 -0
- package/app/utils/Promise/Promise.type.ts +15 -0
- package/app/utils/Promise/index.ts +13 -0
- package/app/utils/Query/Field.ts +71 -0
- package/app/utils/Query/Fragment.ts +22 -0
- package/app/utils/Query/PrepareDocument.ts +119 -0
- package/app/utils/Query/Query.type.ts +26 -0
- package/app/utils/Query/index.ts +15 -0
- package/app/utils/Request/Config.ts +21 -0
- package/app/utils/Request/DataContainer.ts +102 -0
- package/app/utils/Request/Debounce.ts +48 -0
- package/app/utils/Request/Error.ts +31 -0
- package/app/utils/Request/Hash.ts +88 -0
- package/app/utils/Request/LowPriorityLoad.ts +32 -0
- package/app/utils/Request/LowPriorityRender.ts +55 -0
- package/app/utils/Request/Mutation.ts +25 -0
- package/app/utils/Request/Query.ts +25 -0
- package/app/utils/Request/QueryDispatcher.ts +135 -0
- package/app/utils/Request/Request.ts +310 -0
- package/app/utils/Store/Store.type.ts +26 -0
- package/app/utils/Store/index.ts +71 -0
- package/app/utils/Url/Url.ts +297 -0
- package/app/utils/Url/index.ts +12 -0
- package/app/utils/Validator/Config.ts +96 -0
- package/app/utils/Validator/Validator.ts +268 -0
- package/app/utils/Validator/Validator.type.ts +47 -0
- package/app/utils/Validator/index.ts +12 -0
- package/app/utils/Wishlist/Wishlist.ts +65 -0
- package/app/utils/Wishlist/index.ts +12 -0
- package/app/utils/client.ts +280 -0
- package/app/utils/index.ts +53 -0
- package/app/utils/normalizer.ts +23 -0
- package/app/utils/normalizers/magento.ts +29 -0
- package/app/utils/normalizers/shopify.ts +29 -0
- package/nuxt.config.ts +11 -0
- package/package.json +43 -0
- package/tsconfig.json +45 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M Framework - Flexible backend agnostic framework.
|
|
3
|
+
*
|
|
4
|
+
* Copyright © Meeovi, LTD. All rights reserved.
|
|
5
|
+
* See LICENSE for license details.
|
|
6
|
+
*
|
|
7
|
+
* @license OSL-3.0 (Open Software License ("OSL") v. 3.0)
|
|
8
|
+
* @package mframework/mframework-theme
|
|
9
|
+
* @link https://github.com/meeovi/mframework
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { ImageType } from 'Component/ProductGallery/ProductGallery.config';
|
|
13
|
+
import {
|
|
14
|
+
AttributeWithValue,
|
|
15
|
+
AttributeWithValueOption,
|
|
16
|
+
BundleItem,
|
|
17
|
+
BundleOption,
|
|
18
|
+
ConfigurableProductOptions,
|
|
19
|
+
CustomizableFieldValue,
|
|
20
|
+
CustomizableFileValue,
|
|
21
|
+
CustomizableProductFragmentOptions,
|
|
22
|
+
CustomizableSelectionValue,
|
|
23
|
+
GroupedProductItem,
|
|
24
|
+
PriceRange, ProductItem,
|
|
25
|
+
ProductReview,
|
|
26
|
+
ProductStockItem,
|
|
27
|
+
RatingsBreakdown,
|
|
28
|
+
SwatchData,
|
|
29
|
+
} from '../../normalizers/ProductList.type';
|
|
30
|
+
import { Product as DomainProduct } from '../../types/domain';
|
|
31
|
+
import { WishlistProduct } from '../../stores/Wishlist/Wishlist.type';
|
|
32
|
+
import { Merge } from '../../types/Common.type';
|
|
33
|
+
import { GQLCurrencyEnum, GQLProductStockStatus } from '../../types/Graphql.type';
|
|
34
|
+
import { DateRangeAttribute, YearRangeAttribute } from '../../utils/Form/Form.type';
|
|
35
|
+
|
|
36
|
+
export enum QtyFields {
|
|
37
|
+
SALABLE_QTY = 'salable_qty',
|
|
38
|
+
MIN_SALE_QTY = 'min_sale_qty',
|
|
39
|
+
MAX_SALE_QTY = 'max_sale_qty',
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const DEFAULT_MIN_PRODUCTS = 1;
|
|
43
|
+
|
|
44
|
+
export const DEFAULT_MAX_PRODUCTS = 999;
|
|
45
|
+
|
|
46
|
+
export type IndexedConfigurableOption = Merge<
|
|
47
|
+
Merge<ConfigurableProductOptions, IndexedAttributeWithValue>,
|
|
48
|
+
{
|
|
49
|
+
attribute_values: string[];
|
|
50
|
+
}
|
|
51
|
+
>;
|
|
52
|
+
|
|
53
|
+
export type IndexedConfigurableOptions = Record<string, IndexedConfigurableOption>;
|
|
54
|
+
|
|
55
|
+
export type IndexedVariant = Merge<ProductItem | DomainProduct, {
|
|
56
|
+
attributes: Record<string, IndexedAttributeWithValue>;
|
|
57
|
+
}>;
|
|
58
|
+
|
|
59
|
+
export type CleanCustomizableProductFragmentOptions = Omit<
|
|
60
|
+
CustomizableProductFragmentOptions,
|
|
61
|
+
'CustomizableAreaOption' | 'CustomizableCheckboxOption' | 'CustomizableDateOption' | 'CustomizableDropDownOption'
|
|
62
|
+
| 'CustomizableFieldOption' | 'CustomizableFileOption' | 'CustomizableMultipleOption' | 'CustomizableRadioOption'
|
|
63
|
+
| 'checkboxValues' | 'dropdownValues' | 'fieldValues' | 'areaValues' | 'fileValues'
|
|
64
|
+
>;
|
|
65
|
+
|
|
66
|
+
export type IndexedCustomOptionValue = CustomizableSelectionValue
|
|
67
|
+
| CustomizableFieldValue
|
|
68
|
+
| CustomizableFileValue;
|
|
69
|
+
|
|
70
|
+
export type IndexedCustomOption = Merge<
|
|
71
|
+
CleanCustomizableProductFragmentOptions,
|
|
72
|
+
{
|
|
73
|
+
value: IndexedCustomOptionValue[] | CleanCustomizableProductFragmentOptions;
|
|
74
|
+
}
|
|
75
|
+
>;
|
|
76
|
+
|
|
77
|
+
export interface ReviewSummary {
|
|
78
|
+
rating_summary: number;
|
|
79
|
+
review_count: number;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type IndexedBaseProduct<T> = Merge<T, {
|
|
83
|
+
configurable_options?: IndexedConfigurableOptions;
|
|
84
|
+
variants?: IndexedVariant[];
|
|
85
|
+
options?: IndexedCustomOption[];
|
|
86
|
+
attributes?: Record<string, IndexedAttributeWithValue>;
|
|
87
|
+
reviews?: IndexedReview[];
|
|
88
|
+
review_summary?: ReviewSummary;
|
|
89
|
+
items?: IndexedBundleItem[] | GroupedProductItem[];
|
|
90
|
+
// !FIXME: This prop is alway undefined. Added for compatibility with the legacy code.
|
|
91
|
+
productOptionsData?: Record<string, string | string[]>;
|
|
92
|
+
}>;
|
|
93
|
+
|
|
94
|
+
export type IndexedProduct = IndexedBaseProduct<Partial<ProductItem | DomainProduct>> & {
|
|
95
|
+
parent?: IndexedBaseProduct<Partial<ProductItem>>;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export type IndexedWishlistProduct = IndexedBaseProduct<Partial<WishlistProduct>>;
|
|
99
|
+
|
|
100
|
+
export type IndexedBundleOption = Merge<BundleOption, {
|
|
101
|
+
regularOptionPrice: number;
|
|
102
|
+
regularOptionPriceExclTax: number;
|
|
103
|
+
finalOptionPrice: number;
|
|
104
|
+
finalOptionPriceExclTax: number;
|
|
105
|
+
}>;
|
|
106
|
+
|
|
107
|
+
export type IndexedBundleItem = Merge<BundleItem, {
|
|
108
|
+
options?: IndexedBundleOption[];
|
|
109
|
+
}>;
|
|
110
|
+
|
|
111
|
+
export type IndexedAttributeWithValue = Merge<AttributeWithValue, {
|
|
112
|
+
attribute_options: Record<string, IndexedAttributeWithValueOption>;
|
|
113
|
+
}>;
|
|
114
|
+
|
|
115
|
+
export type IndexedAttributeWithValueOption = Merge<AttributeWithValueOption, {
|
|
116
|
+
swatch_data: SwatchData | null;
|
|
117
|
+
}>;
|
|
118
|
+
|
|
119
|
+
export type IndexedReview = Merge<ProductReview, {
|
|
120
|
+
rating_votes: RatingVote[];
|
|
121
|
+
}>;
|
|
122
|
+
|
|
123
|
+
export interface BuyRequestBundleOptions {
|
|
124
|
+
bundle_option: Record<string, string | Record<string, string>>;
|
|
125
|
+
bundle_option_qty: Record<string, number>;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface BuyRequestCustomizableOptions {
|
|
129
|
+
options: Record<string, string | string[] | Record<string, string>>;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export interface BuyRequestDownloadableOptions {
|
|
133
|
+
links: string[];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface BuyRequestConfigurableOptions {
|
|
137
|
+
super_attribute: Record<string, string>;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export interface PriceLabels {
|
|
141
|
+
baseLabel?: string;
|
|
142
|
+
priceLabel: string;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export interface ProductTransformData {
|
|
146
|
+
sku: string;
|
|
147
|
+
quantity: number;
|
|
148
|
+
selected_options: string[];
|
|
149
|
+
entered_options: ProductOption[];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export interface FormattedMoney {
|
|
153
|
+
value: number;
|
|
154
|
+
currency: GQLCurrencyEnum;
|
|
155
|
+
valueFormatted: string;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export interface ProductExtractBasePrice {
|
|
159
|
+
finalPrice: FormattedMoney;
|
|
160
|
+
finalPriceExclTax: FormattedMoney;
|
|
161
|
+
originalPrice: FormattedMoney;
|
|
162
|
+
originalPriceExclTax: FormattedMoney;
|
|
163
|
+
discount: { percentOff: number };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export interface ProductExtractOriginalPrice {
|
|
167
|
+
minRegularPrice: FormattedMoney;
|
|
168
|
+
minFinalPrice: FormattedMoney;
|
|
169
|
+
minFinalPriceExclTax: FormattedMoney;
|
|
170
|
+
maxRegularPrice: FormattedMoney;
|
|
171
|
+
maxFinalPrice: FormattedMoney;
|
|
172
|
+
maxFinalPriceExclTax: FormattedMoney;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface ProductExtractPriceConfiguration {
|
|
176
|
+
containsOptions: boolean;
|
|
177
|
+
containsOptionsWithPrice: boolean;
|
|
178
|
+
containsRequiredOptions: boolean;
|
|
179
|
+
containsRequiredOptionsWithPrice: boolean;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export interface ProductExtractPrice {
|
|
183
|
+
price: ProductExtractBasePrice;
|
|
184
|
+
originalPrice: ProductExtractOriginalPrice;
|
|
185
|
+
configuration: ProductExtractPriceConfiguration;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export type ProductExtractImage = Record<ImageType, { url?: string } | undefined>;
|
|
189
|
+
|
|
190
|
+
export interface TransformedBundleOption {
|
|
191
|
+
id: string;
|
|
192
|
+
name: string;
|
|
193
|
+
value: string;
|
|
194
|
+
label?: string;
|
|
195
|
+
subLabel: string;
|
|
196
|
+
sort_order: number;
|
|
197
|
+
isAvailable: boolean;
|
|
198
|
+
isDefault: boolean;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export type RatingVote = RatingsBreakdown & { percent: number };
|
|
202
|
+
|
|
203
|
+
export interface NoneRadioOption {
|
|
204
|
+
title: string;
|
|
205
|
+
label: string;
|
|
206
|
+
uid: string;
|
|
207
|
+
price: number;
|
|
208
|
+
finalOptionPrice: number;
|
|
209
|
+
can_change_quantity: boolean;
|
|
210
|
+
priceInclTax: number;
|
|
211
|
+
is_default: boolean;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export interface TransformedCustomizableOptions {
|
|
215
|
+
id: string;
|
|
216
|
+
name: string;
|
|
217
|
+
value: string;
|
|
218
|
+
label?: string;
|
|
219
|
+
subLabel: string;
|
|
220
|
+
sort_order: number;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export type GetYearRangeAttributes<IsYear extends boolean = false> = IsYear extends true
|
|
224
|
+
? YearRangeAttribute
|
|
225
|
+
: DateRangeAttribute;
|
|
226
|
+
|
|
227
|
+
export interface StockCheckProduct {
|
|
228
|
+
type_id: string;
|
|
229
|
+
stock_status: GQLProductStockStatus;
|
|
230
|
+
stock_item?: ProductStockItem;
|
|
231
|
+
items?: Partial<StockCheckProduct>[];
|
|
232
|
+
variants?: Partial<StockCheckProduct>[];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export type ProductQuantity = number | Record<number, number>;
|
|
236
|
+
|
|
237
|
+
export interface ProductOption {
|
|
238
|
+
uid: string;
|
|
239
|
+
value: string;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface AdjustedPrice {
|
|
243
|
+
exclTax: number;
|
|
244
|
+
inclTax: number;
|
|
245
|
+
requiresDiscountCalculations: boolean;
|
|
246
|
+
hasDiscountCalculated: boolean;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
export interface AdjustedPriceMap {
|
|
250
|
+
downloadable: AdjustedPrice;
|
|
251
|
+
bundle: AdjustedPrice;
|
|
252
|
+
config: AdjustedPrice;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
export interface ProductPrice {
|
|
256
|
+
minimum_price: Partial<PriceRange>;
|
|
257
|
+
maximum_price: Partial<PriceRange>;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export type ConfigurableProductSelectedVariantValue = string | number | boolean;
|
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/default-param-last */
|
|
2
|
+
/**
|
|
3
|
+
* M Framework - Flexible backend agnostic framework.
|
|
4
|
+
*
|
|
5
|
+
* Copyright © Meeovi, LTD. All rights reserved.
|
|
6
|
+
* See LICENSE for license details.
|
|
7
|
+
*
|
|
8
|
+
* @license OSL-3.0 (Open Software License ("OSL") v. 3.0)
|
|
9
|
+
* @package mframework/mframework
|
|
10
|
+
* @link https://github.com/meeovi/mframework
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { FieldType } from 'Component/Field/Field.config';
|
|
14
|
+
import { ProductType } from 'Component/Product/Product.config';
|
|
15
|
+
import { NONE_RADIO_OPTION } from 'Component/ProductCustomizableOption/ProductCustomizableOption.config';
|
|
16
|
+
import { CustomizableSelectionValue, GroupedProductItem } from '../../normalizers/ProductList.type';
|
|
17
|
+
import { GQLCurrencyEnum } from '../../types/Graphql.type';
|
|
18
|
+
import { decodeBase64, encodeBase64 } from '../../utils/Base64';
|
|
19
|
+
import { formatPrice } from '../../utils/Price';
|
|
20
|
+
import { ProductOption } from '../../utils/Product/Product.type';
|
|
21
|
+
|
|
22
|
+
import { getProductInStock } from './Extract';
|
|
23
|
+
import { ADD_TO_CART } from './Product';
|
|
24
|
+
import {
|
|
25
|
+
BuyRequestBundleOptions,
|
|
26
|
+
BuyRequestCustomizableOptions,
|
|
27
|
+
BuyRequestDownloadableOptions,
|
|
28
|
+
IndexedAttributeWithValue,
|
|
29
|
+
IndexedBundleOption,
|
|
30
|
+
IndexedProduct,
|
|
31
|
+
NoneRadioOption,
|
|
32
|
+
PriceLabels,
|
|
33
|
+
ProductTransformData,
|
|
34
|
+
StockCheckProduct,
|
|
35
|
+
TransformedBundleOption,
|
|
36
|
+
TransformedCustomizableOptions,
|
|
37
|
+
} from './Product.type';
|
|
38
|
+
|
|
39
|
+
export const PRICE_TYPE_PERCENT = 'PERCENT';
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generates correct UID for bundle with changed quantity
|
|
43
|
+
* UID is encoded in base64, original value is bundle/option_id/item_id/quantity
|
|
44
|
+
*
|
|
45
|
+
* @param uid
|
|
46
|
+
* @param quantity
|
|
47
|
+
* @namespace ../../utils/Product/Transform/getEncodedBundleUid
|
|
48
|
+
*/
|
|
49
|
+
export const getEncodedBundleUid = (uid: string, quantity: number): string => {
|
|
50
|
+
const decoded = decodeBase64(uid);
|
|
51
|
+
const parts = decoded.split('/');
|
|
52
|
+
// eslint-disable-next-line no-magic-numbers
|
|
53
|
+
const newUid = parts.length === 3
|
|
54
|
+
? `bundle/${parts[1]}/${quantity}`
|
|
55
|
+
: `bundle/${parts[1]}/${parts[2]}/${quantity}`;
|
|
56
|
+
|
|
57
|
+
return encodeBase64(newUid);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** @namespace ../../utils/Product/Transform/getBundleOptions */
|
|
61
|
+
export const getBundleOptions = (buyRequest: string): string[] => {
|
|
62
|
+
const { bundle_option = {}, bundle_option_qty = {} }: BuyRequestBundleOptions = JSON.parse(buyRequest);
|
|
63
|
+
|
|
64
|
+
if (!bundle_option) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return Object.entries(bundle_option).reduce((prev: string[], [option, variant]) => {
|
|
69
|
+
const qty = bundle_option_qty[option] || 1;
|
|
70
|
+
|
|
71
|
+
if (Array.isArray(variant) && variant.every((val) => typeof (val) === 'string')) {
|
|
72
|
+
return [...prev, ...variant.map((val) => encodeBase64(`bundle/${option}/${val}/${qty}`))];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return [...prev, ...Object.keys(variant).map((id) => encodeBase64(`bundle/${option}/${id}/${qty}`))];
|
|
76
|
+
}, []);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/** @namespace ../../utils/Product/Transform/getCustomizableOptions */
|
|
80
|
+
export const getCustomizableOptions = (buyRequest: string): string[] => {
|
|
81
|
+
const { options = {} }: BuyRequestCustomizableOptions = JSON.parse(buyRequest);
|
|
82
|
+
|
|
83
|
+
// handle null
|
|
84
|
+
if (!options) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return Object.entries(options).reduce<string[]>(
|
|
89
|
+
(prev, [option, variant]) => {
|
|
90
|
+
if (typeof variant === 'string') {
|
|
91
|
+
return [...prev, encodeBase64(`custom-option/${option}/${variant}`)];
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (Array.isArray(variant)) {
|
|
95
|
+
return [...prev, ...variant.map((id) => encodeBase64(`custom-option/${option}/${id}`))];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (typeof variant === 'object' && (variant.date_internal || variant.date)) {
|
|
99
|
+
const { date_internal, date } = variant;
|
|
100
|
+
|
|
101
|
+
return [...prev, encodeBase64(`custom-option/${option}/${date_internal || date}`)];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Handle case when we need to pass previously uploaded file as selected option
|
|
105
|
+
// Normally files are passed via entered_options, but when customer adds product with attachment from wishlist,
|
|
106
|
+
// we need to reference data of the already uploaded file
|
|
107
|
+
if (typeof variant === 'object' && variant.type === 'application/octet-stream') {
|
|
108
|
+
return [...prev, encodeBase64(`custom-option/${option}/file-${encodeBase64(JSON.stringify(variant))}`)];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return prev;
|
|
112
|
+
},
|
|
113
|
+
[],
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/** @namespace ../../utils/Product/Transform/getDownloadableOptions */
|
|
118
|
+
export const getDownloadableOptions = (buyRequest: string): string[] => {
|
|
119
|
+
const { links }: BuyRequestDownloadableOptions = JSON.parse(buyRequest);
|
|
120
|
+
|
|
121
|
+
if (!links) {
|
|
122
|
+
return [];
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return links.map((link) => encodeBase64(`downloadable/${link}`));
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/** @namespace ../../utils/Product/Transform/getConfigurableOptions */
|
|
129
|
+
export const getConfigurableOptions = (buyRequest: string): string[] => {
|
|
130
|
+
const { super_attribute } = JSON.parse(buyRequest);
|
|
131
|
+
|
|
132
|
+
if (!super_attribute) {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return Object.entries(super_attribute).map(([attr, value]) => encodeBase64(`configurable/${attr}/${value}`));
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
/** @namespace ../../utils/Product/Transform/getSelectedOptions */
|
|
140
|
+
export const getSelectedOptions = (buyRequest: string): string[] => [
|
|
141
|
+
...getBundleOptions(buyRequest),
|
|
142
|
+
...getCustomizableOptions(buyRequest),
|
|
143
|
+
...getDownloadableOptions(buyRequest),
|
|
144
|
+
...getConfigurableOptions(buyRequest),
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
/** @namespace ../../utils/Product/Transform/transformParameters */
|
|
148
|
+
export const transformParameters = (
|
|
149
|
+
parameters: Record<string, string>,
|
|
150
|
+
attributes: Record<string, IndexedAttributeWithValue>,
|
|
151
|
+
): string[] => Object.entries(parameters)
|
|
152
|
+
.map(([attrCode, selectedValue]) => {
|
|
153
|
+
const attrId = attributes[attrCode]?.attribute_id;
|
|
154
|
+
|
|
155
|
+
return encodeBase64(`configurable/${attrId}/${selectedValue}`);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Generates label for bundle option
|
|
160
|
+
*
|
|
161
|
+
* @param option
|
|
162
|
+
* @param currencyCode
|
|
163
|
+
* @returns {{baseLabel: string, priceLabel: string}}
|
|
164
|
+
* @namespace ../../utils/Product/Transform/bundleOptionToLabel
|
|
165
|
+
*/
|
|
166
|
+
export const bundleOptionToLabel = (
|
|
167
|
+
option: Partial<IndexedBundleOption>,
|
|
168
|
+
currencyCode = GQLCurrencyEnum.USD,
|
|
169
|
+
): PriceLabels => {
|
|
170
|
+
const {
|
|
171
|
+
price,
|
|
172
|
+
finalOptionPrice = 0,
|
|
173
|
+
price_type: priceType,
|
|
174
|
+
can_change_quantity: canChangeQuantity,
|
|
175
|
+
quantity = 0,
|
|
176
|
+
label,
|
|
177
|
+
product,
|
|
178
|
+
} = option || {};
|
|
179
|
+
|
|
180
|
+
const noPrice = price === 0 && finalOptionPrice === 0;
|
|
181
|
+
const priceLabel = noPrice ? '' : `+ ${ formatPrice(finalOptionPrice, currencyCode) }`;
|
|
182
|
+
const percentLabel = (noPrice || priceType !== PRICE_TYPE_PERCENT) ? '' : `(${ price }%)`;
|
|
183
|
+
// Accessing name here, because product may be passed as null - which prevents from assigning its
|
|
184
|
+
// default value, thus resulting in error
|
|
185
|
+
const fallbackLabel = product ? product.name : __('Option');
|
|
186
|
+
const renderLabel = label ?? fallbackLabel;
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
baseLabel: !canChangeQuantity && quantity > 0 ? `${ quantity } x ${ renderLabel } ` : `${ renderLabel } `,
|
|
190
|
+
priceLabel: `${ priceLabel } ${ percentLabel }`,
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Converts bundle products options into select field options,
|
|
196
|
+
* meaning into [uid:label] pair
|
|
197
|
+
*
|
|
198
|
+
* @param options
|
|
199
|
+
* @namespace ../../utils/Product/Transform/bundleOptionsToSelectTransform
|
|
200
|
+
*/
|
|
201
|
+
export const bundleOptionsToSelectTransform = (
|
|
202
|
+
options: IndexedBundleOption[],
|
|
203
|
+
currencyCode = GQLCurrencyEnum.USD,
|
|
204
|
+
quantity: Record<string, number> = {},
|
|
205
|
+
): TransformedBundleOption[] => (
|
|
206
|
+
options.reduce((result: TransformedBundleOption[] = [], option) => {
|
|
207
|
+
const {
|
|
208
|
+
uid: sourceUid = '',
|
|
209
|
+
quantity: defaultQuantity = 1,
|
|
210
|
+
position,
|
|
211
|
+
product,
|
|
212
|
+
is_default,
|
|
213
|
+
} = option;
|
|
214
|
+
|
|
215
|
+
const isAvailable = getProductInStock(product);
|
|
216
|
+
|
|
217
|
+
const {
|
|
218
|
+
priceLabel,
|
|
219
|
+
baseLabel,
|
|
220
|
+
} = bundleOptionToLabel(option, currencyCode);
|
|
221
|
+
|
|
222
|
+
const { [sourceUid]: currentQty = defaultQuantity } = quantity;
|
|
223
|
+
const uid = getEncodedBundleUid(sourceUid, currentQty);
|
|
224
|
+
|
|
225
|
+
result.push({
|
|
226
|
+
id: sourceUid,
|
|
227
|
+
name: sourceUid,
|
|
228
|
+
value: uid,
|
|
229
|
+
label: baseLabel,
|
|
230
|
+
subLabel: priceLabel,
|
|
231
|
+
sort_order: position,
|
|
232
|
+
isAvailable,
|
|
233
|
+
isDefault: is_default,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
return result;
|
|
237
|
+
}, [])
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Generates label for customizable option
|
|
242
|
+
*
|
|
243
|
+
* @param option
|
|
244
|
+
* @param currencyCode
|
|
245
|
+
* @returns {{baseLabel: string, priceLabel: string}}
|
|
246
|
+
* @namespace ../../utils/Product/Transform/customizableOptionToLabel
|
|
247
|
+
*/
|
|
248
|
+
export const customizableOptionToLabel = (option: Partial<CustomizableSelectionValue>, currencyCode = GQLCurrencyEnum.USD): PriceLabels => {
|
|
249
|
+
const {
|
|
250
|
+
price,
|
|
251
|
+
priceInclTax = 0,
|
|
252
|
+
price_type,
|
|
253
|
+
title,
|
|
254
|
+
} = option || {};
|
|
255
|
+
const noPrice = price === 0 && priceInclTax === 0;
|
|
256
|
+
const priceLabel = noPrice ? '' : `+ ${ formatPrice(priceInclTax, currencyCode) }`;
|
|
257
|
+
const percentLabel = (noPrice || price_type !== PRICE_TYPE_PERCENT) ? '' : ` (${ price }%)`;
|
|
258
|
+
|
|
259
|
+
return {
|
|
260
|
+
baseLabel: title,
|
|
261
|
+
priceLabel: `${ priceLabel } ${ percentLabel }`,
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Converts customizable products options into select field options,
|
|
267
|
+
* meaning into [uid:label] pair
|
|
268
|
+
*
|
|
269
|
+
* @param options
|
|
270
|
+
* @namespace ../../utils/Product/Transform/customizableOptionsToSelectTransform
|
|
271
|
+
*/
|
|
272
|
+
export const customizableOptionsToSelectTransform = (
|
|
273
|
+
options: CustomizableSelectionValue[],
|
|
274
|
+
currencyCode = GQLCurrencyEnum.USD,
|
|
275
|
+
): TransformedCustomizableOptions[] => (
|
|
276
|
+
options.reduce((result: TransformedCustomizableOptions[] = [], option) => {
|
|
277
|
+
const {
|
|
278
|
+
uid,
|
|
279
|
+
title,
|
|
280
|
+
sort_order = 0,
|
|
281
|
+
} = option;
|
|
282
|
+
|
|
283
|
+
const {
|
|
284
|
+
priceLabel,
|
|
285
|
+
baseLabel,
|
|
286
|
+
} = customizableOptionToLabel(option, currencyCode);
|
|
287
|
+
|
|
288
|
+
result.push({
|
|
289
|
+
id: uid,
|
|
290
|
+
name: title,
|
|
291
|
+
value: uid,
|
|
292
|
+
label: baseLabel,
|
|
293
|
+
subLabel: priceLabel,
|
|
294
|
+
sort_order,
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
return result;
|
|
298
|
+
}, [])
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Generates Magento type product interface for performing
|
|
303
|
+
* actions (add to cart, wishlist, exc.)
|
|
304
|
+
* @param product
|
|
305
|
+
* @param quantity
|
|
306
|
+
* @param enteredOptions
|
|
307
|
+
* @param selectedOptions
|
|
308
|
+
* @returns {*[]}
|
|
309
|
+
* @namespace ../../utils/Product/Transform/magentoProductTransform
|
|
310
|
+
*/
|
|
311
|
+
export const magentoProductTransform = (
|
|
312
|
+
action: string = ADD_TO_CART,
|
|
313
|
+
product: IndexedProduct,
|
|
314
|
+
quantity: number | Record<string, number> = 1,
|
|
315
|
+
enteredOptions: ProductOption[] = [],
|
|
316
|
+
selectedOptions: string[] = [],
|
|
317
|
+
): ProductTransformData[] => {
|
|
318
|
+
const { sku = '', type_id: typeId } = product;
|
|
319
|
+
|
|
320
|
+
const productData: ProductTransformData[] = [];
|
|
321
|
+
|
|
322
|
+
if (typeId === ProductType.GROUPED && action === ADD_TO_CART) {
|
|
323
|
+
const { items = [] } = product;
|
|
324
|
+
const groupedProducts: string[] = [];
|
|
325
|
+
|
|
326
|
+
(items as GroupedProductItem[]).forEach(({ product: { id } }) => {
|
|
327
|
+
const { [String(id)]: groupedQuantity = 0 } = quantity as Record<string, number>;
|
|
328
|
+
|
|
329
|
+
groupedProducts.push(encodeBase64(`grouped/${id}/${groupedQuantity}`));
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
productData.push({
|
|
333
|
+
sku,
|
|
334
|
+
quantity: 1,
|
|
335
|
+
selected_options: [...selectedOptions, ...groupedProducts],
|
|
336
|
+
entered_options: enteredOptions,
|
|
337
|
+
});
|
|
338
|
+
} else {
|
|
339
|
+
const baseProductToAdd: ProductTransformData = {
|
|
340
|
+
sku,
|
|
341
|
+
quantity: quantity as number,
|
|
342
|
+
selected_options: selectedOptions,
|
|
343
|
+
entered_options: enteredOptions,
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
productData.push(baseProductToAdd);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return productData;
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
*
|
|
354
|
+
* @param options
|
|
355
|
+
* @param isRequired
|
|
356
|
+
* @param type
|
|
357
|
+
* @returns {[{uid: string, price: number, priceInclTax: number, title: *, is_default: boolean},...*]|*}
|
|
358
|
+
* @namespace ../../utils/Product/Transform/nonRequiredRadioOptions
|
|
359
|
+
*/
|
|
360
|
+
export const nonRequiredRadioOptions = <T>(
|
|
361
|
+
options: T | T[],
|
|
362
|
+
isRequired = false,
|
|
363
|
+
type: string = FieldType.RADIO,
|
|
364
|
+
): T | Array<T | NoneRadioOption> => {
|
|
365
|
+
if (isRequired || type !== FieldType.RADIO) {
|
|
366
|
+
return options;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
const hasDefault = (options as unknown as Array<
|
|
370
|
+
{ is_default?: boolean; product: StockCheckProduct }
|
|
371
|
+
>).find(({ is_default, product }) => is_default && getProductInStock(product));
|
|
372
|
+
|
|
373
|
+
return [
|
|
374
|
+
{
|
|
375
|
+
...(NONE_RADIO_OPTION as any),
|
|
376
|
+
is_default: !hasDefault,
|
|
377
|
+
},
|
|
378
|
+
...(options as T[]),
|
|
379
|
+
];
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
export default bundleOptionsToSelectTransform;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M Framework - Flexible backend agnostic framework.
|
|
3
|
+
*
|
|
4
|
+
* Copyright © Meeovi, LTD. All rights reserved.
|
|
5
|
+
* See LICENSE for license details.
|
|
6
|
+
*
|
|
7
|
+
* @license OSL-3.0 (Open Software License ("OSL") v. 3.0)
|
|
8
|
+
* @package mframework/mframework
|
|
9
|
+
* @link https://github.com/meeovi/mframework
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export * from './Product';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M Framework - Flexible backend agnostic framework.
|
|
3
|
+
*
|
|
4
|
+
* Copyright © Meeovi, LTD. All rights reserved.
|
|
5
|
+
* See LICENSE for license details.
|
|
6
|
+
*
|
|
7
|
+
* @license OSL-3.0 (Open Software License ("OSL") v. 3.0)
|
|
8
|
+
* @package mframework/mframework
|
|
9
|
+
* @link https://github.com/meeovi/mframework
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { CancelablePromise } from './Promise.type';
|
|
13
|
+
|
|
14
|
+
/* eslint-disable prefer-promise-reject-errors */
|
|
15
|
+
// Disabled due promise being reject with custom error (isCanceled)
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Promise wrapper to make it cancelable
|
|
19
|
+
* @static
|
|
20
|
+
* @param {Promise} promise promise which has to be cancelable
|
|
21
|
+
* @return {Promise} Cancelable promise
|
|
22
|
+
* @namespace ../../utils/Promise/MakeCancelable/makeCancelable */
|
|
23
|
+
export const makeCancelable = <T>(promise: Promise<T>): CancelablePromise<T> => {
|
|
24
|
+
// eslint-disable-next-line fp/no-let
|
|
25
|
+
let hasCanceled = false;
|
|
26
|
+
|
|
27
|
+
const wrappedPromise: Promise<T> = new Promise((resolve, reject) => {
|
|
28
|
+
promise.then(
|
|
29
|
+
/** @namespace ../../utils/Promise/MakeCancelable/makeCancelable/wrappedPromise/promise/then */
|
|
30
|
+
(val) => (!hasCanceled && resolve(val)),
|
|
31
|
+
/** @namespace ../../utils/Promise/MakeCancelable/makeCancelable/wrappedPromise/promise/then/catch */
|
|
32
|
+
(error) => (!hasCanceled && reject(error)),
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
promise: wrappedPromise,
|
|
38
|
+
cancel() {
|
|
39
|
+
hasCanceled = true;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default makeCancelable;
|