Skip to content

Commit

Permalink
feat: add actions for quote (#437)
Browse files Browse the repository at this point in the history
* feat: add actions for quote

* fix: clear naming functions
  • Loading branch information
bc-marco authored and CarlLiu2023 committed Jun 6, 2023
1 parent 27fe346 commit 69cf780
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 118 deletions.
26 changes: 25 additions & 1 deletion apps/storefront/src/components/HeadlessController.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { Dispatch, SetStateAction, useEffect } from 'react'
import { Dispatch, SetStateAction, useContext, useEffect, useRef } from 'react'
import type { OpenPageState } from '@b3/hooks'

import { HeadlessRoutes } from '@/constants'
import {
addProductFromProductPageToQuote,
addProductsFromCartToQuote,
addProductsToDraftQuote,
} from '@/hooks/dom/utils'
import { GlobaledContext } from '@/shared/global'

interface HeadlessControllerProps {
setOpenPage: Dispatch<SetStateAction<OpenPageState>>
Expand All @@ -10,6 +16,18 @@ interface HeadlessControllerProps {
export default function HeadlessController({
setOpenPage,
}: HeadlessControllerProps) {
const {
state: { role },
} = useContext(GlobaledContext)
const { addToQuote: addProductFromPage } =
addProductFromProductPageToQuote(setOpenPage)
const { addToQuote: addProductsFromCart } =
addProductsFromCartToQuote(setOpenPage)

// Keep updated role value
const addProductFromPageRef = useRef(() => addProductFromPage(role))
addProductFromPageRef.current = () => addProductFromPage(role)

useEffect(() => {
window.b2b = {
utils: {
Expand All @@ -20,8 +38,14 @@ export default function HeadlessController({
0
)
},
quote: {
addProductFromPage: addProductFromPageRef.current,
addProductsFromCart: () => addProductsFromCart(),
addProducts: (items) => addProductsToDraftQuote(items),
},
},
}
}, [])

return null
}
4 changes: 2 additions & 2 deletions apps/storefront/src/hooks/dom/useCartToQuote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { CustomStyleContext } from '@/shared/customStyleButtton'
import { GlobaledContext } from '@/shared/global'
import { B3SStorage, globalSnackbar } from '@/utils'

import { addQuoteToCart } from './utils'
import { addProductsFromCartToQuote } from './utils'

type DispatchProps = Dispatch<SetStateAction<OpenPageState>>
interface MutationObserverProps {
Expand All @@ -33,7 +33,7 @@ const useCartToQuote = ({
setOpenPage,
cartQuoteEnabled,
}: MutationObserverProps) => {
const { addToQuote, addLoadding } = addQuoteToCart(setOpenPage)
const { addToQuote, addLoadding } = addProductsFromCartToQuote(setOpenPage)

const {
state: { addToAllQuoteBtn },
Expand Down
5 changes: 3 additions & 2 deletions apps/storefront/src/hooks/dom/useMyQuote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { B3LStorage, removeCartPermissions } from '@/utils'

// import { removeCartPermissions } from '@/utils/b3RolePermissions'
import useDomVariation from './useDomVariation'
import { addQuoteToProduct, removeElement } from './utils'
import { addProductFromProductPageToQuote, removeElement } from './utils'

type DispatchProps = Dispatch<SetStateAction<OpenPageState>>

Expand Down Expand Up @@ -53,7 +53,8 @@ const useMyQuote = ({
} = useContext(CustomStyleContext)

// quote method and goto draft
const { addToQuote, addLoadding } = addQuoteToProduct(setOpenPage)
const { addToQuote, addLoadding } =
addProductFromProductPageToQuote(setOpenPage)

const quoteCallBbck = useCallback(() => {
const b3MyQuote = document.querySelector('.b2b-add-to-quote')
Expand Down
234 changes: 121 additions & 113 deletions apps/storefront/src/hooks/dom/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,64 +133,124 @@ const gotoQuoteDraft = (setOpenPage: DispatchProps) => {
})
}

const addQuoteToCart = (setOpenPage: DispatchProps) => {
const getCartProducts = (lineItems: LineItemsProps) => {
const cartProductsList: CustomFieldItems[] = []

productTypes.forEach((type: Cart) => {
if (lineItems[type].length > 0) {
lineItems[type].forEach(
(product: ProductItemProps | CustomFieldItems) => {
if (!product.parentId) {
cartProductsList.push(product)
}
const getCartProducts = (lineItems: LineItemsProps) => {
const cartProductsList: CustomFieldItems[] = []

productTypes.forEach((type: Cart) => {
if (lineItems[type].length > 0) {
lineItems[type].forEach(
(product: ProductItemProps | CustomFieldItems) => {
if (!product.parentId) {
cartProductsList.push(product)
}
)
}
})
}
)
}
})

return cartProductsList
}
return cartProductsList
}

const getOptionsList = (options: ProductOptionsProps[] | []) => {
if (options?.length === 0) return []
const option: CustomFieldItems = []
options.forEach(({ nameId, valueId, value }) => {
let optionValue: number | string = valueId
? `${valueId}`.toString()
: value
if (
typeof valueId === 'number' &&
`${valueId}`.toString().length === 10
) {
optionValue = valueId
const date = new Date(+valueId * 1000)
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
option.push({
optionId: `attribute[${nameId}][year]`,
optionValue: year,
})
option.push({
optionId: `attribute[${nameId}][month]`,
optionValue: month,
})
option.push({
optionId: `attribute[${nameId}][day]`,
optionValue: day,
})
} else {
option.push({
optionId: `attribute[${nameId}]`,
optionValue,
})
}
})
const getOptionsList = (options: ProductOptionsProps[] | []) => {
if (!options?.length) return []
const option: CustomFieldItems = []
options.forEach(({ nameId, valueId, value }) => {
let optionValue: number | string = valueId ? `${valueId}`.toString() : value
if (typeof valueId === 'number' && `${valueId}`.toString().length === 10) {
optionValue = valueId
const date = new Date(+valueId * 1000)
const year = date.getFullYear()
const month = date.getMonth() + 1
const day = date.getDate()
option.push({
optionId: `attribute[${nameId}][year]`,
optionValue: year,
})
option.push({
optionId: `attribute[${nameId}][month]`,
optionValue: month,
})
option.push({
optionId: `attribute[${nameId}][day]`,
optionValue: day,
})
} else {
option.push({
optionId: `attribute[${nameId}]`,
optionValue,
})
}
})

return option
}

const addProductsToDraftQuote = async (products: CustomFieldItems[]) => {
// filter products with SKU
const productsWithSKU = products.filter(({ sku }) => !!sku)

// fetch data with products IDs
const { productsSearch } = await searchB2BProducts({
productIds: Array.from(
new Set(products.map(({ productId }) => +productId))
),
})

// convert to product search response format
const productsListSearch: CustomFieldItems[] =
conversionProductsList(productsSearch)

// create products list structure compatible with quote structure
const productsList = productsWithSKU.map((product) => {
const {
options,
sku,
productId,
name,
quantity,
variantId,
salePrice,
imageUrl,
listPrice,
} = product

const optionsList = getOptionsList(options)

const currentProductSearch = productsListSearch.find(
(product: any) => +product.id === +productId
)

const quoteListitem = {
node: {
id: uuid(),
variantSku: sku,
variantId,
productsSearch: currentProductSearch,
primaryImage: imageUrl || PRODUCT_DEFAULT_IMAGE,
productName: name,
quantity: +quantity || 1,
optionList: JSON.stringify(optionsList),
productId,
basePrice: listPrice,
taxPrice: salePrice - listPrice,
},
}

return quoteListitem
})

// update prices for products list
await calculateProductListPrice(productsList, '2')

return option
const isSuccess = validProductQty(productsList)
if (isSuccess) {
addQuoteDraftProducts(productsList)
}

return isSuccess
}

const addProductsFromCartToQuote = (setOpenPage: DispatchProps) => {
const addToQuote = async () => {
try {
const cartInfoWithOptions: CartInfoProps | any =
Expand All @@ -213,66 +273,8 @@ const addQuoteToCart = (setOpenPage: DispatchProps) => {
})
}

const productsWithSKU = cartProductsList.filter(({ sku }) => !!sku)

const productIds: number[] = []
productsWithSKU.forEach((product: CustomFieldItems) => {
if (!productIds.includes(+product.productId)) {
productIds.push(+product.productId)
}
})

const { productsSearch } = await searchB2BProducts({
productIds,
})

const newProduct: CustomFieldItems[] = []

const newProductInfo: CustomFieldItems =
conversionProductsList(productsSearch)
productsWithSKU.forEach((product) => {
const {
options,
sku,
productId,
name,
quantity,
variantId,
salePrice,
imageUrl,
listPrice,
} = product

const optionsList = getOptionsList(options)

const currentProductSearch = newProductInfo.find(
(product: any) => +product.id === +productId
)

const quoteListitem = {
node: {
id: uuid(),
variantSku: sku,
variantId,
productsSearch: currentProductSearch,
primaryImage: imageUrl || PRODUCT_DEFAULT_IMAGE,
productName: name,
quantity: +quantity || 1,
optionList: JSON.stringify(optionsList),
productId,
basePrice: listPrice,
taxPrice: salePrice - listPrice,
},
}

newProduct.push(quoteListitem)
})

const isSuccess = validProductQty(newProduct)
const isSuccess = await addProductsToDraftQuote(cartProductsList)
if (isSuccess) {
await calculateProductListPrice(newProduct, '2')
addQuoteDraftProducts(newProduct)

globalSnackbar.success('', {
jsx: () =>
B3AddToQuoteTip({
Expand Down Expand Up @@ -304,7 +306,7 @@ const addQuoteToCart = (setOpenPage: DispatchProps) => {
}
}

const addQuoteToProduct = (setOpenPage: DispatchProps) => {
const addProductFromProductPageToQuote = (setOpenPage: DispatchProps) => {
const addToQuote = async (role: string | number) => {
try {
const productId = (
Expand Down Expand Up @@ -390,4 +392,10 @@ const addQuoteToProduct = (setOpenPage: DispatchProps) => {
}
}

export { addLoadding, addQuoteToCart, addQuoteToProduct, removeElement }
export {
addLoadding,
addProductFromProductPageToQuote,
addProductsFromCartToQuote,
addProductsToDraftQuote,
removeElement,
}
5 changes: 5 additions & 0 deletions apps/storefront/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ declare interface Window {
b2b: {
utils: {
openPage: (page: import('./constants').HeadlessRoute) => void
quote: {
addProductFromPage: () => Promise<void>
addProductsFromCart: () => Promise<void>
addProducts: (items: CustomFieldItems[]) => Promise<boolean>
}
}
}
}

0 comments on commit 69cf780

Please sign in to comment.