From ac72444f1a7017b97e041cf1efcbebb620b1e7d6 Mon Sep 17 00:00:00 2001 From: kris-liu-smile Date: Fri, 21 Apr 2023 18:46:39 +0800 Subject: [PATCH] fix: add Calculate the price and tax of the product --- apps/storefront/src/App.tsx | 4 +- .../ShoppingListDetails.tsx | 2 - .../components/ChooseOptionsDialog.tsx | 4 +- .../src/shared/service/b2b/graphql/global.ts | 22 ++ .../src/shared/service/b2b/graphql/product.ts | 1 + .../src/shared/service/b2b/index.ts | 2 + apps/storefront/src/store/index.ts | 1 + apps/storefront/src/store/reducer.ts | 2 + apps/storefront/src/store/selectors.ts | 1 + apps/storefront/src/store/slices/glabol.ts | 55 +++++ apps/storefront/src/types/products.ts | 109 ++++----- apps/storefront/src/types/shoppingList.ts | 22 +- .../src/utils/b3Product/b3Product.ts | 226 ++++++++++++------ .../src/utils/b3Product/b3TaxRate.ts | 34 +++ .../src/utils/b3Product/shared/config.ts | 35 ++- apps/storefront/src/utils/index.ts | 1 + apps/storefront/src/utils/storefrontConfig.ts | 33 +++ packages/store/reducer.ts | 2 +- 18 files changed, 381 insertions(+), 175 deletions(-) create mode 100644 apps/storefront/src/store/slices/glabol.ts create mode 100644 apps/storefront/src/utils/b3Product/b3TaxRate.ts diff --git a/apps/storefront/src/App.tsx b/apps/storefront/src/App.tsx index 07eff5ea..ae5287f1 100644 --- a/apps/storefront/src/App.tsx +++ b/apps/storefront/src/App.tsx @@ -28,6 +28,7 @@ import { getQuoteEnabled, getTemPlateConfig, setStorefrontConfig, + getStoreTaxZoneRates, } from '@/utils' import { @@ -167,7 +168,8 @@ export default function App() { await loginInfo() } setChannelStoreType(currentChannelId) - await Promise.all([setStorefrontConfig(dispatch), getTemPlateConfig(currentChannelId, styleDispatch, dispatch)]) + // await getTaxZoneRates() + await Promise.all([getStoreTaxZoneRates(), setStorefrontConfig(dispatch), getTemPlateConfig(currentChannelId, styleDispatch, dispatch)]) const userInfo = { role: +role, isAgenting, diff --git a/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx b/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx index 54845dad..c8985791 100644 --- a/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx +++ b/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx @@ -23,8 +23,6 @@ import { } from '@/shared/global' import { - searchB2BProducts, - searchBcProducts, getB2BShoppingListDetails, getBcShoppingListDetails, deleteB2BShoppingListItem, diff --git a/apps/storefront/src/pages/shoppingListDetails/components/ChooseOptionsDialog.tsx b/apps/storefront/src/pages/shoppingListDetails/components/ChooseOptionsDialog.tsx index 80c7f831..74cfc8f7 100644 --- a/apps/storefront/src/pages/shoppingListDetails/components/ChooseOptionsDialog.tsx +++ b/apps/storefront/src/pages/shoppingListDetails/components/ChooseOptionsDialog.tsx @@ -32,7 +32,7 @@ import { import { ShoppingListProductItem, - ShoppingListProductItemVariants, + Variant, SimpleObject, } from '../../../types' @@ -127,7 +127,7 @@ export const ChooseOptionsDialog = (props: ChooseOptionsDialogProps) => { const [quantity, setQuantity] = useState(1) const [formFields, setFormFields] = useState([]) - const [variantInfo, setVariantInfo] = useState(null) + const [variantInfo, setVariantInfo] = useState | null>(null) const [variantSku, setVariantSku] = useState('') const [additionalProducts, setAdditionalProducts] = useState({}) diff --git a/apps/storefront/src/shared/service/b2b/graphql/global.ts b/apps/storefront/src/shared/service/b2b/graphql/global.ts index c967b692..d7025c71 100644 --- a/apps/storefront/src/shared/service/b2b/graphql/global.ts +++ b/apps/storefront/src/shared/service/b2b/graphql/global.ts @@ -150,6 +150,24 @@ const storefrontConfigs = (channelId: number, keys: string[]) => `{ } }` +const taxZoneRates = () => `{ + taxZoneRates(storeHash: "${storeHash}") { + rates { + id, + name, + enabled, + priority, + classRates { + rate, + taxClassId, + } + }, + enabled, + id, + name, + } +}` + export const getB2BToken = (bcJwtToken: string, channelId: number = 1): CustomFieldItems => B3Request.graphqlB2B({ query: getB2BTokenQl(bcJwtToken, channelId), }) @@ -188,3 +206,7 @@ export const getBcCurrencies = (channelId: string): CustomFieldItems => B3Reques export const getStorefrontConfigs = (channelId: number, keys: string[]): CustomFieldItems => B3Request.graphqlB2B({ query: storefrontConfigs(channelId, keys), }) + +export const getTaxZoneRates = (): CustomFieldItems => B3Request.graphqlB2B({ + query: taxZoneRates(), +}) diff --git a/apps/storefront/src/shared/service/b2b/graphql/product.ts b/apps/storefront/src/shared/service/b2b/graphql/product.ts index a2332b41..0364e2df 100644 --- a/apps/storefront/src/shared/service/b2b/graphql/product.ts +++ b/apps/storefront/src/shared/service/b2b/graphql/product.ts @@ -72,6 +72,7 @@ const searchProducts = (data: CustomFieldItems) => `{ optionsV3, channelId, productUrl, + taxClassId, } }` diff --git a/apps/storefront/src/shared/service/b2b/index.ts b/apps/storefront/src/shared/service/b2b/index.ts index a113876c..d579708e 100644 --- a/apps/storefront/src/shared/service/b2b/index.ts +++ b/apps/storefront/src/shared/service/b2b/index.ts @@ -70,6 +70,7 @@ import { getCurrencies, getBcCurrencies, getStorefrontConfigs, + getTaxZoneRates, } from './graphql/global' import { @@ -234,4 +235,5 @@ export { B2BProductsBulkUploadCSV, BcProductsBulkUploadCSV, getStorefrontConfigs, + getTaxZoneRates, } diff --git a/apps/storefront/src/store/index.ts b/apps/storefront/src/store/index.ts index 0a26ccae..c92ecd00 100644 --- a/apps/storefront/src/store/index.ts +++ b/apps/storefront/src/store/index.ts @@ -1,3 +1,4 @@ export * from './reducer' export * from './selectors' export * from './slices/theme' +export * from './slices/glabol' diff --git a/apps/storefront/src/store/reducer.ts b/apps/storefront/src/store/reducer.ts index e21a1e13..f9f84589 100644 --- a/apps/storefront/src/store/reducer.ts +++ b/apps/storefront/src/store/reducer.ts @@ -2,6 +2,7 @@ import { setupStore, } from '@b3/store' import theme from './slices/theme' +import glabol from './slices/glabol' export const middlewareOptions = { serializableCheck: { @@ -12,6 +13,7 @@ export const middlewareOptions = { export const store = setupStore({ reducers: { + glabol, theme, }, middlewareOptions, diff --git a/apps/storefront/src/store/selectors.ts b/apps/storefront/src/store/selectors.ts index 3642523e..15e0107d 100644 --- a/apps/storefront/src/store/selectors.ts +++ b/apps/storefront/src/store/selectors.ts @@ -6,4 +6,5 @@ import { } from './reducer' const themeSelector = (state: RootState) => state.theme + export const themeFrameSelector = createSelector(themeSelector, (theme) => theme.themeFrame) diff --git a/apps/storefront/src/store/slices/glabol.ts b/apps/storefront/src/store/slices/glabol.ts new file mode 100644 index 00000000..09a67a04 --- /dev/null +++ b/apps/storefront/src/store/slices/glabol.ts @@ -0,0 +1,55 @@ +import { + Draft, + createSlice, +} from '@reduxjs/toolkit' +import type { + PayloadAction, +} from '@reduxjs/toolkit' + +export interface TaxZoneRates { + rate?: number, + taxClassId?: number +} + +interface Rates { + enabled: boolean, + id: number, + name: string, + priority: number, + classRates: TaxZoneRates[], +} + +export interface TaxZoneRatesProps { + enabled: boolean, + id: number, + name: string, + rates: Rates[] +} + +export interface glabolState { + taxZoneRates?: TaxZoneRatesProps[] +} + +const initialState: glabolState = { + taxZoneRates: [], +} + +export const glabolSlice = createSlice({ + name: 'glabol', + initialState, + reducers: { + clearglabol: () => initialState, + setTaxZoneRates: (state, { + payload, + }: PayloadAction) => { + state.taxZoneRates = payload as Draft + }, + }, +}) + +export const { + clearglabol, + setTaxZoneRates, +} = glabolSlice.actions + +export default glabolSlice.reducer diff --git a/apps/storefront/src/types/products.ts b/apps/storefront/src/types/products.ts index 1b148b46..2616df0f 100644 --- a/apps/storefront/src/types/products.ts +++ b/apps/storefront/src/types/products.ts @@ -1,3 +1,8 @@ +import { + ShoppingListProductItemModifiers, + ShoppingListProductItemOption, +} from '@/types/shoppingList' + export interface ProductOptionsItem { option_id: number, display_name: string, @@ -51,60 +56,35 @@ export interface ProductVariantSkuInfo{ variantSku: string, } -interface OptionValue { - id: number; - label: string; - option_id: number; - option_display_name: string; +export interface OptionValue { + id: number, + label: string, + option_display_name: string, + option_id: number, } -interface Variant { +export interface Variant { variant_id: number; product_id: number; sku: string; + price: number, option_values: OptionValue[]; calculated_price: number; image_url: string; has_price_list: boolean; - bulk_prices: any[]; // not sure about the type + bulk_prices?: any[]; // not sure about the type purchasing_disabled: boolean; - cost_price: number; + cost_price?: number; inventory_level: number; - bc_calculated_price: { - as_entered: number; - tax_inclusive: number; - tax_exclusive: number; - entered_inclusive: boolean; - }; -} - -interface Modifier { - id: number; - display_name: string; - type: string; - required: boolean; - config: any; // not sure about the type - option_values: any[]; // not sure about the type + bc_calculated_price: BcCalculatedPrice; } -interface Option { - option_id: number; - display_name: string; - sort_order: number; - is_required: boolean; +export interface AdjustersPrice { + adjuster: string; + adjuster_value: number; } -interface OptionV3 { - id: number; - product_id: number; - name: string; - display_name: string; - type: string; - sort_order: number; - option_values: OptionValue[]; -} - -interface ALlOptionValue { +export interface ALlOptionValue { id: number; label: string; sort_order: number; @@ -129,27 +109,40 @@ interface ALlOptionValue { message: string; }; } | null; + product_id?: number, } export interface AllOptionProps { - id: number; + id: number | string; product_id?: number; name: string; display_name: string; type: string; sort_order: number; - option_values: ALlOptionValue[]; - config: { - product_list_adjusts_inventory?: boolean; - product_list_adjusts_pricing?: boolean; - product_list_shipping_calc?: string; - default_value?: string; - text_characters_limited?: boolean; - text_min_length?: number; - text_max_length?: number; - checkbox_label?: string; - checked_by_default?: boolean; - } | null; + option_values: Partial[]; + config?: { + default_value?: string, + text_characters_limited?: boolean, + text_max_length?: number, + text_min_length?: number, + text_lines_limited?: boolean, + text_max_lines?: number, + date_earliest_value?: string, + date_latest_value?: string, + date_limit_mode?: string, + date_limited?: boolean, + number_highest_value?: number, + number_integers_only?: boolean, + number_limit_mode?: string, + number_limited?: boolean, + number_lowest_value?: number, + checkbox_label?: string, + checked_by_default?: boolean, + file_max_size?: number, + file_types_mode?: string, + file_types_other?: string[], + file_types_supported?: string[], + }; required: boolean; isVariantOption?: boolean; } @@ -158,20 +151,22 @@ export interface Product { id: number; name: string; sku: string; + base_price: string, costPrice: string; channelId: number[], + selectOptions: string, inventoryLevel: number; inventoryTracking: string; availability: string; orderQuantityMinimum: number; orderQuantityMaximum: number; - variants: Variant[]; + variants?: Partial[]; currencyCode: string; imageUrl: string; - modifiers: Modifier[]; - options: Option[]; - optionsV3: OptionV3[]; - allOptions: AllOptionProps + modifiers: ShoppingListProductItemModifiers[]; + options?: ShoppingListProductItemOption[]; + optionsV3?: ShoppingListProductItemModifiers[]; + allOptions?: Partial[] productUrl: string; quantity: number; [key:string]: any; diff --git a/apps/storefront/src/types/shoppingList.ts b/apps/storefront/src/types/shoppingList.ts index 5da702be..6e89ea46 100644 --- a/apps/storefront/src/types/shoppingList.ts +++ b/apps/storefront/src/types/shoppingList.ts @@ -1,6 +1,7 @@ import { ProductItem, - BcCalculatedPrice, + Variant, + AllOptionProps, } from './products' export interface ShoppingListItem { @@ -64,7 +65,7 @@ export interface ShoppingListProductItemModifiers { file_types_supported?: string[], }, display_name: string, - id: number | string, + id?: number | string, option_values: ShoppingListProductItemModifiersOption[], required: boolean, type: string, @@ -78,26 +79,13 @@ export interface ShoppingListProductItemVariantsOption { option_id: number, } -export interface ShoppingListProductItemVariants { - product_id: number, - sku: string, - variant_id: number, - purchasing_disabled: boolean, - option_values: ShoppingListProductItemVariantsOption[], - cost_price: number, - image_url: string, - calculated_price: number, - price: number, - bc_calculated_price: BcCalculatedPrice, -} - export interface ShoppingListProductItem extends ProductItem{ options?: ShoppingListProductItemOption[], optionsV3?: ShoppingListProductItemModifiers[], modifiers?: ShoppingListProductItemModifiers[], costPrice?: string, - variants?: ShoppingListProductItemVariants[], - allOptions?: ShoppingListProductItemModifiers[], + variants?: Variant[], + allOptions?: Partial[], selectOptions?: string, orderQuantityMaximum?: number, orderQuantityMinimum?: number, diff --git a/apps/storefront/src/utils/b3Product/b3Product.ts b/apps/storefront/src/utils/b3Product/b3Product.ts index b093259a..c6e58cac 100644 --- a/apps/storefront/src/utils/b3Product/b3Product.ts +++ b/apps/storefront/src/utils/b3Product/b3Product.ts @@ -1,5 +1,11 @@ import { Product, + AllOptionProps, + OptionValue, + AdjustersPrice, + ALlOptionValue, + Variant, + BcCalculatedPrice, } from '@/types/products' import { B3LStorage, @@ -14,8 +20,17 @@ import { import { ListItemProps, conversionProductsList, + ProductInfoProps, } from './shared/config' +import { + getTaxRate, +} from './b3TaxRate' + +// import { +// ShoppingListProductItemModifiers, +// } from '@/types/shoppingList' + interface QuoteListitemProps { node: { id: number, @@ -162,15 +177,14 @@ const getQuickAddProductExtraPrice = (allOptions: CustomFieldItems[], newSelectO return additionalCalculatedPrices } -const getListModifierPrice = (allOptions, node) => { +const getListModifierPrice = (allOptions: Partial[], node: ProductInfoProps) => { const optionList = JSON.parse(node?.optionList || '[]') - console.log(optionList, 'optionList') - const modifierPrices: any = [] + const modifierPrices: AdjustersPrice[] = [] if (optionList.length) { - optionList.forEach((option: any) => { - const itemOption = allOptions.find((item: any) => option.option_id.includes(item.id)) + optionList.forEach((option: CustomFieldItems) => { + const itemOption = allOptions.find((item: Partial) => option.option_id.includes(item.id)) if (itemOption && itemOption?.option_values && itemOption.option_values.length) { - const optionValues = itemOption.option_values.find((optionValue: any) => +optionValue.id === +option.option_value) + const optionValues = itemOption.option_values.find((optionValue: Partial) => (optionValue?.id ? +optionValue.id : 0) === +option.option_value) if (optionValues && optionValues?.adjusters && optionValues?.adjusters?.price) { const { price, @@ -186,6 +200,128 @@ const getListModifierPrice = (allOptions, node) => { return modifierPrices } +const setItemProductPrice = (newListProducts: ListItemProps[]) => { + newListProducts.forEach((item: ListItemProps) => { + const { + node: { + modifierPrices = [], + currentProductPrices, + extraProductPrices = [], + taxClassId, + }, + } = item + + const rate = getTaxRate(taxClassId) + + let singleCurrentPrice = currentProductPrices?.tax_exclusive || 0 + let singleAllTax = 0 + let singleextraProductPrice = 0 + + if (modifierPrices.length) { + modifierPrices.forEach((modifierPrice) => { + switch (modifierPrice?.adjuster) { + case 'relative': singleCurrentPrice += modifierPrice.adjuster_value + break + default: singleCurrentPrice += (modifierPrice.adjuster_value * singleCurrentPrice) / 100 + break + } + }) + } + + if (extraProductPrices.length) { + extraProductPrices.forEach((extraProductPrice) => { + singleextraProductPrice += extraProductPrice.tax_exclusive * ((100 + rate) / 100) + singleAllTax += extraProductPrice.tax_exclusive * (rate / 100) + }) + } + const productPrice = singleCurrentPrice * ((100 + rate) / 100) + singleextraProductPrice + const productTax = singleCurrentPrice * ((rate) / 100) + singleAllTax + + item.node.basePrice = productPrice.toFixed(2) + item.node.basePricetax = productTax.toFixed(2) + }) +} + +const getExtraProductPricesProducts = async (isB2BUser: boolean, listProducts: ListItemProps[], picklistIds: number[]) => { + const getProducts = isB2BUser ? searchB2BProducts : searchBcProducts + const { + currency_code: currencyCode, + } = getDefaultCurrencyInfo() + const { + productsSearch: picklistProductsSearch, + } = await getProducts({ + productIds: picklistIds, + currencyCode, + }) + const newpicklistProducts: Partial[] = conversionProductsList(picklistProductsSearch) + + listProducts.forEach((item) => { + const { + node, + } = item + + const extraProductPrices: BcCalculatedPrice[] = [] + if (node?.picklistIds?.length) { + node?.picklistIds.forEach((picklistId: number) => { + const picklistItem = newpicklistProducts.find((product: Partial) => product?.id && +product.id === +picklistId) + if (picklistItem && picklistItem?.variants?.length && picklistItem.variants[0]?.bc_calculated_price) { + extraProductPrices.push(picklistItem.variants[0]?.bc_calculated_price) + } + }) + } + node.extraProductPrices = extraProductPrices + }) + + return listProducts +} + +const addTaxProductPrices = (listProducts: ListItemProps[], newProductsSearch:Partial[], picklistIds: number[]) => { + listProducts.forEach((item) => { + const { + node, + } = item + + const productInfo: Partial = newProductsSearch.find((search: Partial) => { + const { + id: productId, + } = search + + return node.productId === productId + }) || {} + + // gets the associated product id + const currentPicklistIds: number[] = [] + if (productInfo?.allOptions && productInfo?.allOptions.length) { + const picklist = productInfo.allOptions.find((item: Partial) => item.type === 'product_list_with_images') + if (picklist && picklist?.option_values?.length) { + picklist.option_values.forEach(((list: Partial) => { + const picklistProductId: number = list?.value_data?.product_id || 0 + if (picklistProductId) currentPicklistIds.push(picklistProductId) + if (!picklistIds.includes(picklistProductId)) { + picklistIds.push(picklistProductId) + } + })) + } + } + // get modifier price + if (productInfo?.variants?.length && productInfo?.allOptions?.length) { + const modifierPrices = getListModifierPrice(productInfo.allOptions, node) + node.modifierPrices = modifierPrices + } + + // get current price and tax price + const variantItem = productInfo?.variants?.find((item: Partial) => item.sku === node.variantSku) + if (variantItem) { + node.currentProductPrices = variantItem.bc_calculated_price + } + node.taxClassId = productInfo.taxClassId + + node.picklistIds = currentPicklistIds + + node.productsSearch = productInfo || {} + }) +} + const getNewProductsList = async (listProducts: ListItemProps[], isB2BUser: boolean, companyId: number | string) => { const { currency_code: currencyCode, @@ -212,83 +348,21 @@ const getNewProductsList = async (listProducts: ListItemProps[], isB2BUser: bool const newProductsSearch: Partial[] = conversionProductsList(productsSearch) - console.log(newProductsSearch, 'newProductsSearch') - const picklistIds: number[] = [] - listProducts.forEach((item) => { - const { - node, - } = item + // add modifier price, current price and tax price, get the associated product id + addTaxProductPrices(listProducts, newProductsSearch, picklistIds) - const productInfo = newProductsSearch.find((search: Product) => { - const { - id: productId, - } = search + let newListProducts: ListItemProps[] = listProducts - return node.productId === productId - }) - - // 获取相关的产品的id - const currentPicklistIds: number[] = [] - if (productInfo?.allOptions && productInfo?.allOptions.length) { - const picklist = productInfo.allOptions.find((item: any) => item.type === 'product_list_with_images') - if (picklist && picklist?.option_values?.length) { - picklist.option_values.forEach(((list: any) => { - const picklistProductId = list?.value_data?.product_id - if (picklistProductId) currentPicklistIds.push(picklistProductId) - if (!picklistIds.includes(list.productId) && picklistProductId) { - picklistIds.push(picklistProductId) - } - })) - } - } - // get modifier price - if (productInfo?.variants.length) { - const modifierPrices = getListModifierPrice(productInfo.allOptions, node) - node.modifierPrices = modifierPrices - } - - // get current price and tax price - const variantItem = productInfo?.variants.find((item: any) => item.sku === node.variantSku) - if (variantItem) { - node.currentProductPrices = variantItem.bc_calculated_price - } - - node.picklistIds = currentPicklistIds - - node.productsSearch = productInfo || {} - }) - - // 获取相关产品的集合 + // Get a collection of related products if (picklistIds.length) { - const { - productsSearch: picklistProductsSearch, - } = await getProducts({ - productIds: picklistIds - currencyCode, - }) - const newpicklistProducts = conversionProductsList(picklistProductsSearch) - - listProducts.forEach((item) => { - const { - node, - } = item -· - const extraProductPrices: any = [] - if (node?.picklistIds?.length) { - node?.picklistIds.forEach((picklistId: number) => { - const picklistItem = newpicklistProducts.find((product: any) => +product.id === +picklistId) - if (picklistItem && picklistItem?.variants?.length) { - extraProductPrices.push(picklistItem.variants[0].bc_calculated_price) - } - }) - } - node.extraProductPrices = extraProductPrices - }) + newListProducts = await getExtraProductPricesProducts(isB2BUser, listProducts, picklistIds) } - return listProducts + setItemProductPrice(newListProducts) + + return newListProducts } } diff --git a/apps/storefront/src/utils/b3Product/b3TaxRate.ts b/apps/storefront/src/utils/b3Product/b3TaxRate.ts new file mode 100644 index 00000000..c84f0048 --- /dev/null +++ b/apps/storefront/src/utils/b3Product/b3TaxRate.ts @@ -0,0 +1,34 @@ +import { + store, +} from '@/store/reducer' + +import { + TaxZoneRates, + TaxZoneRatesProps, +} from '@/store/slices/glabol' + +const getTaxRate = (taxClassId: number) => { + const { + glabol: { + taxZoneRates, + }, + } = store.getState() + + let taxRates: TaxZoneRates[] = [] + + if (taxZoneRates.length) { + taxZoneRates.forEach((taxZoneRate: TaxZoneRatesProps) => { + if (taxZoneRate.rates[0].priority === 1) { + taxRates = taxZoneRate?.rates[0]?.classRates || [] + } + }) + } + + const rate = taxRates.find((item) => item.taxClassId === taxClassId)?.rate || 0 + + return rate +} + +export { + getTaxRate, +} diff --git a/apps/storefront/src/utils/b3Product/shared/config.ts b/apps/storefront/src/utils/b3Product/shared/config.ts index 8002c83a..d4e1938a 100644 --- a/apps/storefront/src/utils/b3Product/shared/config.ts +++ b/apps/storefront/src/utils/b3Product/shared/config.ts @@ -2,12 +2,16 @@ import { format, } from 'date-fns' +import { + AllOptionProps, + ALlOptionValue, +} from '@/types/products' + import { ShoppingListProductItem, - ShoppingListProductItemModifiers, - ShoppingListProductItemModifiersOption, SimpleObject, ShoppingListSelectProductOption, + BcCalculatedPrice, } from '../../../types' export interface ShoppingListInfoProps { @@ -28,13 +32,6 @@ export interface CustomerInfoProps { userId: number | string; } -interface ProductPrices { - as_entered: number, - entered_inclusive: number, - tax_exclusive: number, - tax_inclusive: number, -} - interface ModifierPrices { adjuster: string, adjuster_value: number @@ -61,8 +58,8 @@ export interface ProductInfoProps { productsSearch: CustomFieldItems, picklistIds?: number[] modifierPrices?: ModifierPrices[], - currentProductPrices?: ProductPrices, - extraProductPrices?: ProductPrices[], + currentProductPrices?: BcCalculatedPrice, + extraProductPrices?: BcCalculatedPrice[], [key: string]: any, } @@ -135,7 +132,7 @@ export const Base64 = { }, } -const getFieldOptions = (fieldType: string, option: ShoppingListProductItemModifiers, productImages: SimpleObject) => { +const getFieldOptions = (fieldType: string, option: Partial, productImages: SimpleObject) => { const { option_values: optionValues = [], config, @@ -191,7 +188,7 @@ const getFieldOptions = (fieldType: string, option: ShoppingListProductItemModif checked_by_default: checked, } = config || {} - const checkedId: number | string = optionValues.find((values) => values.label === 'Yes')?.id || (optionValues.length > 0 ? optionValues[0].id : '') + const checkedId: number | string = optionValues.find((values) => values.label === 'Yes')?.id || (optionValues.length > 0 ? optionValues[0].id : '') || '' return { options: [{ @@ -203,7 +200,7 @@ const getFieldOptions = (fieldType: string, option: ShoppingListProductItemModif } if (['radio', 'productRadio', 'rectangle', 'swatch'].includes(fieldType)) { - const options = (optionValues || []).map((item: ShoppingListProductItemModifiersOption) => ({ + const options = (optionValues || []).map((item: Partial) => ({ value: item.id, label: item.label, image: { @@ -212,7 +209,7 @@ const getFieldOptions = (fieldType: string, option: ShoppingListProductItemModif }, colors: item.value_data?.colors || [], })) - const value = (optionValues || []).find((item: ShoppingListProductItemModifiersOption) => item.is_default)?.id || '' + const value = (optionValues || []).find((item: Partial) => item.is_default)?.id || '' return { options, @@ -244,7 +241,7 @@ const getFieldOptions = (fieldType: string, option: ShoppingListProductItemModif } } -const getValueText = (fieldType: string, value: string | number | (string | number)[], option: ShoppingListProductItemModifiers) => { +const getValueText = (fieldType: string, value: string | number | (string | number)[], option: Partial) => { const { option_values: optionValues = [], } = option @@ -268,7 +265,7 @@ export const getProductOptionsFields = (product: ShoppingListProductItem, produc } = product || {} const list: CustomFieldItems[] = [] - allOptions.forEach((option: ShoppingListProductItemModifiers) => { + allOptions.forEach((option: Partial) => { const { type, id, @@ -281,7 +278,7 @@ export const getProductOptionsFields = (product: ShoppingListProductItem, produc option_values: optionValues = [], } = option - const fieldType = fieldTypes[type] || '' + const fieldType = type ? fieldTypes[type] : '' if (!fieldType) return @@ -309,7 +306,7 @@ export const getProductOptionsFields = (product: ShoppingListProductItem, produc if (fieldType === 'checkbox') { const optionValue = (selectOptionsJSON[`attribute[${id}]`] || {})[optionValueKey] || '' - const checkedId: number | string = optionValues.find((values) => values.label === 'Yes')?.id || (optionValues.length > 0 ? optionValues[0].id : '') + const checkedId: number | string = optionValues.find((values) => values.label === 'Yes')?.id || (optionValues.length > 0 ? optionValues[0].id : '') || '' value = (optionValue === '1' || optionValue.includes(`${checkedId}`)) ? [checkedId] : [] } else if (fieldType !== 'date') { value = (selectOptionsJSON[`attribute[${id}]`] || {})[optionValueKey] || '' diff --git a/apps/storefront/src/utils/index.ts b/apps/storefront/src/utils/index.ts index 61ad60ad..56e4b365 100644 --- a/apps/storefront/src/utils/index.ts +++ b/apps/storefront/src/utils/index.ts @@ -85,6 +85,7 @@ export { getTemPlateConfig, getQuoteConfig, setStorefrontConfig, + getStoreTaxZoneRates, } from './storefrontConfig' export { diff --git a/apps/storefront/src/utils/storefrontConfig.ts b/apps/storefront/src/utils/storefrontConfig.ts index ed62caa1..adf3cdbc 100644 --- a/apps/storefront/src/utils/storefrontConfig.ts +++ b/apps/storefront/src/utils/storefrontConfig.ts @@ -5,6 +5,7 @@ import { getStorefrontConfigs, getB2BRegisterLogo, getStorefrontConfig, + getTaxZoneRates, } from '@/shared/service/b2b' import { @@ -15,10 +16,33 @@ import { CustomStyleButtonState, } from '@/shared/customStyleButtton/context/config' +import { + setTaxZoneRates, +} from '@/store' + +import { + store, +} from '@/store/reducer' + // import { // storeHash, // } from '@/utils' +// interface Rates { +// enabled: boolean, +// id: number, +// name: string, +// priority: number, +// classRates: TaxZoneRates[], +// } + +// interface TaxZoneRatesProps { +// enabled: boolean, +// id: number, +// name: string, +// rates: Rates[] +// } + interface StoreforntKeysProps { key: string, name: string, @@ -158,8 +182,17 @@ const setStorefrontConfig = async (dispatch: DispatchProps) => { }) } +const getStoreTaxZoneRates = async () => { + const { + taxZoneRates = [], + } = await getTaxZoneRates() + + store.dispatch(setTaxZoneRates(taxZoneRates)) +} + export { getTemPlateConfig, getQuoteConfig, setStorefrontConfig, + getStoreTaxZoneRates, } diff --git a/packages/store/reducer.ts b/packages/store/reducer.ts index afa096f8..fa3aeb78 100644 --- a/packages/store/reducer.ts +++ b/packages/store/reducer.ts @@ -11,7 +11,7 @@ import lang from './slices/lang' type Reducers = Record> interface SetupStoreParams { - reducers: Reducers + reducers: any, preloadedState?: { [x: string]: (Type extends object ? PreloadedState : Type) | undefined; } | undefined middlewareOptions?: Record }