Skip to content

Commit

Permalink
fix: avoiding references to rest api cart functions (#909)
Browse files Browse the repository at this point in the history
* fix: avoiding references to rest api cart functions

* fix: adapt code to graphql response

* fix: update line items to be similar to graphql structure (#915)

---------

Co-authored-by: Marco Loyo <marco.loyo@bigcommerce.com>
Co-authored-by: bc-marco <109162781+bc-marco@users.noreply.github.com>
  • Loading branch information
3 people authored and libruce committed Jan 9, 2024
1 parent fd9f3ce commit 83ca3aa
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 37 deletions.
21 changes: 14 additions & 7 deletions apps/storefront/src/components/HeadlessController.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Dispatch, SetStateAction, useContext, useEffect, useRef } from 'react'
import { useDispatch } from 'react-redux'
import { useDispatch, useSelector } from 'react-redux'
import type { OpenPageState } from '@b3/hooks'
import { useB3Lang } from '@b3/lang'

Expand Down Expand Up @@ -65,13 +65,16 @@ interface HeadlessControllerProps {

const transformOptionSelectionsToAttributes = (items: LineItems[]) =>
items.map((product) => {
const { optionSelections } = product
const { selectedOptions } = product

return {
...product,
optionSelections: optionSelections?.reduce(
(accumulator: Record<string, number>, { optionId, optionValue }) => {
accumulator[`attribute[${optionId}]`] = optionValue
selectedOptions: selectedOptions?.reduce(
(
accumulator: Record<string, number>,
{ optionEntityId, optionValueEntityId }
) => {
accumulator[`attribute[${optionEntityId}]`] = optionValueEntityId

return accumulator
},
Expand Down Expand Up @@ -136,11 +139,14 @@ export default function HeadlessController({
registerEnabled,
},
} = useContext(GlobaledContext)
const platform = useSelector(({ global }) => global.storeInfo.platform)
const {
state: { addQuoteBtn, shoppingListBtn },
} = useContext(CustomStyleContext)
const { addToQuote: addProductsFromCart } =
addProductsFromCartToQuote(setOpenPage)
const { addToQuote: addProductsFromCart } = addProductsFromCartToQuote(
setOpenPage,
platform
)

const saveFn = () => {
setOpenPage({
Expand Down Expand Up @@ -203,6 +209,7 @@ export default function HeadlessController({
} = await superAdminCompanies(B3UserIdRef.current, {
first: 50,
offset: 0,
orderBy: 'companyId',
})

return {
Expand Down
7 changes: 6 additions & 1 deletion apps/storefront/src/hooks/dom/useCartToQuote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
useContext,
useEffect,
} from 'react'
import { useSelector } from 'react-redux'
import globalB3 from '@b3/global-b3'
import type { OpenPageState } from '@b3/hooks'

Expand Down Expand Up @@ -35,7 +36,11 @@ const useCartToQuote = ({
setOpenPage,
cartQuoteEnabled,
}: MutationObserverProps) => {
const { addToQuote, addLoadding } = addProductsFromCartToQuote(setOpenPage)
const platform = useSelector(({ global }) => global.storeInfo.platform)
const { addToQuote, addLoadding } = addProductsFromCartToQuote(
setOpenPage,
platform
)

const {
state: { addToAllQuoteBtn },
Expand Down
26 changes: 18 additions & 8 deletions apps/storefront/src/hooks/dom/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import type { OpenPageState } from '@b3/hooks'

import B3AddToQuoteTip from '@/components/B3AddToQuoteTip'
import { searchB2BProducts, searchBcProducts } from '@/shared/service/b2b'
import { getCartInfoWithOptions } from '@/shared/service/bc'
import { getCart } from '@/shared/service/bc/graphql/cart'
import {
addQuoteDraftProduce,
addQuoteDraftProducts,
B3LStorage,
B3SStorage,
calculateProductsPrice,
getCalculatedProductPrice,
getCookie,
globalSnackbar,
isAllRequiredOptionFilled,
LineItems,
Expand Down Expand Up @@ -175,7 +176,7 @@ const addProductsToDraftQuote = async (
) => {
// filter products with SKU
const productsWithSKUOrVariantId = products.filter(
({ sku, variantId }) => sku || variantId
({ sku, variantEntityId }) => sku || variantEntityId
)

const companyId =
Expand All @@ -185,7 +186,11 @@ const addProductsToDraftQuote = async (
// fetch data with products IDs
const { productsSearch } = await searchB2BProducts({
productIds: Array.from(
new Set(productsWithSKUOrVariantId.map(({ productId }) => +productId))
new Set(
productsWithSKUOrVariantId.map(
({ productEntityId }) => +productEntityId
)
)
),
companyId,
customerGroupId,
Expand Down Expand Up @@ -228,20 +233,25 @@ const addProductsToDraftQuote = async (
})
}

const addProductsFromCartToQuote = (setOpenPage: DispatchProps) => {
const addProductsFromCartToQuote = (
setOpenPage: DispatchProps,
platform?: string
) => {
const addToQuote = async () => {
const entityCartId = platform === 'bigcommerce' ? null : getCookie('cartId')
try {
const cartInfoWithOptions: CartInfoProps | any =
await getCartInfoWithOptions()
// we should get the platform parameter from wherever this function is used
await getCart(entityCartId, platform ?? '')

if (!cartInfoWithOptions[0]) {
if (!cartInfoWithOptions.data.site.cart) {
globalSnackbar.error('No products in Cart.', {
isClose: true,
})
return
}

const { lineItems, id: cartId } = cartInfoWithOptions[0]
const { lineItems, entityId } = cartInfoWithOptions.data.site.cart

const { cartProductsList, noSkuProducts } = getCartProducts(lineItems)

Expand All @@ -258,7 +268,7 @@ const addProductsFromCartToQuote = (setOpenPage: DispatchProps) => {
}
if (noSkuProducts.length === cartProductsList.length) return

await addProductsToDraftQuote(cartProductsList, setOpenPage, cartId)
await addProductsToDraftQuote(cartProductsList, setOpenPage, entityId)
} catch (e) {
console.log(e)
} finally {
Expand Down
6 changes: 4 additions & 2 deletions apps/storefront/src/pages/quote/QuoteDraft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import {
getB2BCustomerAddresses,
getBCCustomerAddresses,
} from '@/shared/service/b2b'
import { deleteCart } from '@/shared/service/bc'
import { deleteCart } from '@/shared/service/bc/graphql/cart'
import { store } from '@/store'
import { AddressItemType, BCAddressItemType } from '@/types/address'
import {
Expand All @@ -42,6 +42,7 @@ import {
storeHash,
} from '@/utils'
import { CallbackKey } from '@/utils/b3Callbacks'
import { deleteCartData } from '@/utils/cartUtils'

import { getProductOptionsFields } from '../../utils/b3Product/shared/config'
import { convertBCToB2BAddress } from '../address/shared/config'
Expand Down Expand Up @@ -576,8 +577,9 @@ function QuoteDraft({ setOpenPage }: QuoteDraftProps) {

if (id) {
const cartId = B3LStorage.get('cartToQuoteId')
const deleteCartObject = deleteCartData(cartId)

await deleteCart(cartId)
await deleteCart(deleteCartObject)
}

navigate(`/quoteDetail/${id}?date=${createdAt}`, {
Expand Down
3 changes: 1 addition & 2 deletions apps/storefront/src/shared/service/bc/graphql/cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ const lineItemsFragment = `lineItems {
value
}
}
totalQuantity
}`

const getCartInfoForHeadless = `query getCart($entityId: String!) {
Expand Down Expand Up @@ -320,7 +319,7 @@ const deleteCartQuery = `mutation deleteCart($deleteCartInput: DeleteCartInput!)
}
}`

export const getCart = (entityId: string, platform: string): any =>
export const getCart = (entityId: string | null, platform: string): any =>
platform === 'bigcommerce'
? B3Request.graphqlBC({
// for stencil not using proxy
Expand Down
38 changes: 21 additions & 17 deletions apps/storefront/src/utils/b3Product/b3Product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ interface NewOptionProps {
}

interface ProductOption {
optionId: number
optionValue: number
optionEntityId: number
optionValueEntityId: number
}

interface ProductOptionString {
Expand All @@ -83,10 +83,10 @@ interface OptionsProps {

export interface LineItems {
quantity: number
productId: number
optionSelections?: ProductOption[]
productEntityId: number
selectedOptions?: ProductOption[]
sku?: string
variantId?: number
variantEntityId?: number
}

const getModifiersPrice = (
Expand Down Expand Up @@ -745,10 +745,10 @@ const formatOptionsSelections = (
) =>
options.reduce((accumulator: CalculatedOptions[], option) => {
const matchedOption = allOptions.find(({ id, type, option_values }) => {
if (option.optionId === id) {
if (option.optionEntityId === id) {
if (
(type !== 'text' && option_values?.length) ||
(type === 'date' && option.optionValue)
(type === 'date' && option.optionValueEntityId)
) {
return true
}
Expand All @@ -759,11 +759,11 @@ const formatOptionsSelections = (
if (matchedOption) {
if (matchedOption.type === 'date') {
const id = matchedOption.id ? +matchedOption.id : 0
accumulator.push(...getDateValuesArray(id, option.optionValue))
accumulator.push(...getDateValuesArray(id, option.optionValueEntityId))
} else {
accumulator.push({
option_id: matchedOption.id ? +matchedOption.id : 0,
value_id: +option.optionValue,
value_id: +option.optionValueEntityId,
})
}
}
Expand All @@ -780,20 +780,22 @@ const formatLineItemsToGetPrices = (
items: Calculateditems[]
variants: ProductInfo[]
},
{ optionSelections = [], productId, sku, variantId, quantity }
{ selectedOptions = [], productEntityId, sku, variantEntityId, quantity }
) => {
const selectedProduct = productsSearch.find(({ id }) => id === productId)
const selectedProduct = productsSearch.find(
({ id }) => id === productEntityId
)
const variantItem = selectedProduct?.variants?.find(
({ sku: skuResult, variant_id: variantIdResult }) =>
sku === skuResult || variantIdResult === variantId
sku === skuResult || variantIdResult === variantEntityId
)

if (!variantItem || !selectedProduct) {
return formatedLineItems
}
const { allOptions = [] } = selectedProduct

const options = formatOptionsSelections(optionSelections, allOptions)
const options = formatOptionsSelections(selectedOptions, allOptions)

formatedLineItems.items.push({
product_id: variantItem.product_id,
Expand All @@ -804,10 +806,12 @@ const formatLineItemsToGetPrices = (
...variantItem,
quantity,
productsSearch: selectedProduct,
optionSelections: optionSelections.map(({ optionId, optionValue }) => ({
optionId: `attribute[${optionId}]`,
optionValue: `${optionValue}`,
})),
optionSelections: selectedOptions.map(
({ optionEntityId, optionValueEntityId }) => ({
optionId: `attribute[${optionEntityId}]`,
optionValue: `${optionValueEntityId}`,
})
),
})
return formatedLineItems
},
Expand Down

0 comments on commit 83ca3aa

Please sign in to comment.