diff --git a/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx b/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx index 0b476b6b..fd83058c 100644 --- a/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx +++ b/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx @@ -28,6 +28,7 @@ import { deleteBcShoppingListItem, updateB2BShoppingList, updateBcShoppingList, + getB2BJuniorPlaceOrder, } from '@/shared/service/b2b' import { @@ -119,6 +120,8 @@ const ShoppingListDetails = () => { const [validateSuccessProducts, setValidateSuccessProducts] = useState([]) const [validateFailureProducts, setValidateFailureProducts] = useState([]) + const [allowJuniorPlaceOrder, setAllowJuniorPlaceOrder] = useState(false) + const isJuniorApprove = shoppingListInfo?.status === 0 && role === 2 const isReadForApprove = shoppingListInfo?.status === 40 || shoppingListInfo?.status === 20 @@ -317,6 +320,20 @@ const ShoppingListDetails = () => { await handleCancelClick() } + const getJuniorPlaceOrder = async () => { + const { + storeConfigSwitchStatus: { + isEnabled, + }, + } = await getB2BJuniorPlaceOrder() + + setAllowJuniorPlaceOrder(isEnabled === '1') + } + + useEffect(() => { + if (isJuniorApprove) getJuniorPlaceOrder() + }, [isJuniorApprove]) + return ( <> { ref={tableRef} isReadForApprove={isReadForApprove} isJuniorApprove={isJuniorApprove} + allowJuniorPlaceOrder={allowJuniorPlaceOrder} setCheckedArr={setCheckedArr} shoppingListInfo={shoppingListInfo} currencyToken={currencyToken} @@ -408,10 +426,11 @@ const ShoppingListDetails = () => { { - (!isReadForApprove && !isJuniorApprove) && ( + (!isReadForApprove && (allowJuniorPlaceOrder || !isJuniorApprove)) && ( { () => ( ) interface ShoppingProductsProps { + shoppingListInfo: any, + role: string | number, products: ProductsProps[], currencyToken: string, successProducts: number, + allowJuniorPlaceOrder: boolean, getProductQuantity?: (item: ProductsProps) => number onProductChange?: (products: ProductsProps[]) => void setValidateFailureProducts: (arr: ProductsProps[]) => void, @@ -174,9 +177,12 @@ const defaultProductImage = 'https://cdn11.bigcommerce.com/s-1i6zpxpe3g/stencil/ export const ReAddToCart = (props: ShoppingProductsProps) => { const { + shoppingListInfo, + role, products, currencyToken, successProducts, + allowJuniorPlaceOrder, setValidateFailureProducts, setValidateSuccessProducts, } = props @@ -242,15 +248,19 @@ export const ReAddToCart = (props: ShoppingProductsProps) => { snackbar.error(res.detail) } else { handleCancelClicked() - snackbar.success('', { - jsx: successTip({ - message: 'Products were added to cart', - link: '/cart.php', - linkText: 'VIEW CART', - isOutLink: true, - }), - isClose: true, - }) + if (allowJuniorPlaceOrder && +role === 2 && shoppingListInfo?.status === 0) { + window.location.href = '/checkout' + } else { + snackbar.success('', { + jsx: successTip({ + message: 'Products were added to cart', + link: '/cart.php', + linkText: 'VIEW CART', + isOutLink: true, + }), + isClose: true, + }) + } } } finally { setLoading(false) @@ -289,8 +299,8 @@ export const ReAddToCart = (props: ShoppingProductsProps) => { isOpen={isOpen} handleLeftClick={handleCancelClicked} handRightClick={handRightClick} - title="Add to cart" - rightSizeBtn="Add to cart" + title={allowJuniorPlaceOrder ? 'Proceed to checkout' : 'Add to cart'} + rightSizeBtn={allowJuniorPlaceOrder ? 'Proceed to checkout' : 'Add to cart'} maxWidth="xl" > @@ -303,7 +313,7 @@ export const ReAddToCart = (props: ShoppingProductsProps) => { variant="filled" severity="success" > - {`${successProducts} product(s) were added to cart`} + {allowJuniorPlaceOrder ? `${successProducts} product(s) can checkout` : `${successProducts} product(s) were added to cart`} @@ -316,7 +326,7 @@ export const ReAddToCart = (props: ShoppingProductsProps) => { variant="filled" severity="error" > - {`${products.length} product(s) were not added to cart, please change the quantity`} + {allowJuniorPlaceOrder ? `${successProducts} product(s) can\n't checkout, please change the quantity` : `${products.length} product(s) were not added to cart, please change the quantity`} () => ( interface ShoppingDetailFooterProps { shoppingListInfo: any, role: string | number, + allowJuniorPlaceOrder: boolean, checkedArr: any, currencyToken: string, selectedSubTotal: number, @@ -91,6 +93,7 @@ const ShoppingDetailFooter = (props: ShoppingDetailFooterProps) => { const { shoppingListInfo, role, + allowJuniorPlaceOrder, checkedArr, currencyToken, selectedSubTotal, @@ -158,7 +161,7 @@ const ShoppingDetailFooter = (props: ShoppingDetailFooterProps) => { }) if (skus.length === 0) { - snackbar.error('Please select at least one item to add to cart') + snackbar.error(allowJuniorPlaceOrder ? 'Please select at least one item to checkout' : 'Please select at least one item to add to cart') return } @@ -176,23 +179,35 @@ const ShoppingDetailFooter = (props: ShoppingDetailFooterProps) => { if (validateSuccessArr.length !== 0) { const lineItems = addlineItems(validateSuccessArr) const cartInfo = await getCartInfo() - const res = cartInfo.length ? await addProductToCart({ - lineItems, - }, cartInfo[0].id) : await createCart({ - lineItems, - }) + let res = null + if (allowJuniorPlaceOrder && cartInfo.length) { + await deleteCart(cartInfo[0].id) + res = await createCart({ + lineItems, + }) + } else { + res = cartInfo.length ? await addProductToCart({ + lineItems, + }, cartInfo[0].id) : await createCart({ + lineItems, + }) + } if (res.status === 422) { snackbar.error(res.detail) } else if (validateFailureArr.length === 0) { - snackbar.success('', { - jsx: successTip({ - message: 'Products were added to cart', - link: '/cart.php', - linkText: 'VIEW CART', - isOutLink: true, - }), - isClose: true, - }) + if (allowJuniorPlaceOrder && +role === 2 && shoppingListInfo?.status === 0) { + window.location.href = '/checkout' + } else { + snackbar.success('', { + jsx: successTip({ + message: 'Products were added to cart', + link: '/cart.php', + linkText: 'VIEW CART', + isOutLink: true, + }), + isClose: true, + }) + } } } setValidateFailureProducts(validateFailureArr) @@ -274,24 +289,28 @@ const ShoppingDetailFooter = (props: ShoppingDetailFooterProps) => { width: isMobile ? '100%' : 'auto', }} > - { - (role !== 2 || shoppingListInfo?.status === 0) && ( + (!allowJuniorPlaceOrder) && ( + + ) + } + { + (allowJuniorPlaceOrder || (role !== 2 && shoppingListInfo?.status === 0) || !isB2BUser) && ( ) } diff --git a/apps/storefront/src/pages/shoppingListDetails/components/ShoppingDetailTable.tsx b/apps/storefront/src/pages/shoppingListDetails/components/ShoppingDetailTable.tsx index 5dfed402..c9d40f22 100644 --- a/apps/storefront/src/pages/shoppingListDetails/components/ShoppingDetailTable.tsx +++ b/apps/storefront/src/pages/shoppingListDetails/components/ShoppingDetailTable.tsx @@ -99,6 +99,7 @@ interface ShoppingDetailTableProps { setCheckedArr: (values: CustomFieldItems) => void, isReadForApprove: boolean, isJuniorApprove: boolean, + allowJuniorPlaceOrder: boolean, setDeleteItemId: (itemId: number | string) => void, setDeleteOpen: (open: boolean) => void, isB2BUser: boolean, @@ -170,6 +171,7 @@ const ShoppingDetailTable = (props: ShoppingDetailTableProps, ref: Ref) setDeleteOpen, isJuniorApprove, isB2BUser, + allowJuniorPlaceOrder, } = props const paginationTableRef = useRef(null) @@ -599,7 +601,7 @@ const ShoppingDetailTable = (props: ShoppingDetailTableProps, ref: Ref) searchParams={search} isCustomRender={false} showCheckbox - disableCheckbox={isReadForApprove || isJuniorApprove} + disableCheckbox={allowJuniorPlaceOrder ? !allowJuniorPlaceOrder : isReadForApprove || isJuniorApprove} hover labelRowsPerPage="Items per page:" showBorder={false} diff --git a/apps/storefront/src/shared/service/b2b/graphql/shoppingList.ts b/apps/storefront/src/shared/service/b2b/graphql/shoppingList.ts index c516d241..d079e41f 100644 --- a/apps/storefront/src/shared/service/b2b/graphql/shoppingList.ts +++ b/apps/storefront/src/shared/service/b2b/graphql/shoppingList.ts @@ -384,6 +384,15 @@ const deleteCustomerShoppingListItem = (data: CustomFieldItems) => `mutation { message, } }` +const getJuniorPlaceOrder = () => `{ + storeConfigSwitchStatus( + key: "junior_place_order", + ) { + id, + key, + isEnabled, + } +}` export const getB2BShoppingList = (data: CustomFieldItems = {}): CustomFieldItems => B3Request.graphqlB2B({ query: getShoppingList(data), @@ -456,3 +465,6 @@ export const updateBcShoppingListsItem = (data: CustomFieldItems = {}): CustomFi export const deleteBcShoppingListItem = (data: CustomFieldItems = {}): CustomFieldItems => B3Request.graphqlProxyBC({ query: deleteCustomerShoppingListItem(data), }) +export const getB2BJuniorPlaceOrder = () => B3Request.graphqlB2B({ + query: getJuniorPlaceOrder(), +}) diff --git a/apps/storefront/src/shared/service/b2b/index.ts b/apps/storefront/src/shared/service/b2b/index.ts index a2b4284c..de510f4c 100644 --- a/apps/storefront/src/shared/service/b2b/index.ts +++ b/apps/storefront/src/shared/service/b2b/index.ts @@ -92,6 +92,7 @@ import { addProductToBcShoppingList, updateBcShoppingListsItem, deleteBcShoppingListItem, + getB2BJuniorPlaceOrder, } from './graphql/shoppingList' import { @@ -190,6 +191,7 @@ export { addProductToShoppingList, updateB2BShoppingListsItem, deleteB2BShoppingListItem, + getB2BJuniorPlaceOrder, checkUserEmail, checkUserBCEmail, setChannelStoreType, diff --git a/apps/storefront/src/shared/service/bc/api/cart.ts b/apps/storefront/src/shared/service/bc/api/cart.ts index 8f54fee1..be390b94 100644 --- a/apps/storefront/src/shared/service/bc/api/cart.ts +++ b/apps/storefront/src/shared/service/bc/api/cart.ts @@ -15,3 +15,5 @@ export const createCart = (data: CustomFieldItems): CustomFieldItems => B3Reques export const addProductToCart = (data: CustomFieldItems, cartId: string): CustomFieldItems => B3Request.post(`${bcBaseUrl}/api/storefront/carts/${cartId}/items`, RequestType.BCRest, data) export const getCartInfoWithOptions = (): CustomFieldItems => B3Request.get(`${bcBaseUrl}/api/storefront/carts?include=lineItems.digitalItems.options,lineItems.physicalItems.options`, RequestType.BCRest) + +export const deleteCart = (cartId: string) => B3Request.delete(`${bcBaseUrl}/api/storefront/carts/${cartId}`, RequestType.BCRest) diff --git a/apps/storefront/src/shared/service/bc/index.ts b/apps/storefront/src/shared/service/bc/index.ts index 5c0eb2b8..49791936 100644 --- a/apps/storefront/src/shared/service/bc/index.ts +++ b/apps/storefront/src/shared/service/bc/index.ts @@ -12,6 +12,7 @@ import { getCartInfo, addProductToCart, getCartInfoWithOptions, + deleteCart, } from './api/cart' import { @@ -39,4 +40,5 @@ export { getCartInfo, addProductToCart, getCartInfoWithOptions, + deleteCart, } diff --git a/apps/storefront/src/shared/service/request/b3Fetch.ts b/apps/storefront/src/shared/service/request/b3Fetch.ts index bb4aca29..dc602c0e 100644 --- a/apps/storefront/src/shared/service/request/b3Fetch.ts +++ b/apps/storefront/src/shared/service/request/b3Fetch.ts @@ -142,6 +142,11 @@ export const B3Request = { }, }, type) }, + delete: function deleteFn(url: string, type: string): Promise { + return request(url, { + method: 'DELETE', + }, type) + }, fileUpload: function fileUpload(url: string, formData: T, config?: Y): Promise { return request(`${B2B_BASIC_URL}${url}`, { method: 'POST',