diff options
| author | it-fixcomart <it@fixcomart.co.id> | 2025-08-11 09:29:11 +0700 |
|---|---|---|
| committer | it-fixcomart <it@fixcomart.co.id> | 2025-08-11 09:29:11 +0700 |
| commit | 43f08a6b39cf6555b9c87d94ade2af5a5f7747bf (patch) | |
| tree | a7a6b64e7bd44d0265908e6e953564b3f0fa4f4d /src/lib/quotation/components/Quotation.jsx | |
| parent | bb656eb35742fbb18fe9c700a3569c4765c65a1c (diff) | |
<hafid> fix biteship quotation
Diffstat (limited to 'src/lib/quotation/components/Quotation.jsx')
| -rw-r--r-- | src/lib/quotation/components/Quotation.jsx | 318 |
1 files changed, 98 insertions, 220 deletions
diff --git a/src/lib/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx index 189c48ee..f0791512 100644 --- a/src/lib/quotation/components/Quotation.jsx +++ b/src/lib/quotation/components/Quotation.jsx @@ -10,7 +10,6 @@ import { deleteItemCart, getCart, getItemCart } from '@/core/utils/cart'; import currencyFormat from '@/core/utils/currencyFormat'; import { toast } from 'react-hot-toast'; import { useProductCartContext } from '@/contexts/ProductCartContext'; -// import checkoutApi from '@/lib/checkout/api/checkoutApi' import { useRouter } from 'next/router'; import VariantGroupCard from '@/lib/variant/components/VariantGroupCard'; import MobileView from '@/core/components/views/MobileView'; @@ -20,12 +19,10 @@ import { useQuery } from 'react-query'; import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList'; import { Skeleton } from '@chakra-ui/react'; import { useAddress } from '@/lib/checkout/stores/useAdress'; -import { useQuotation } from '@/lib/checkout/stores/stateQuotation'; +import { useCheckout } from '@/lib/checkout/stores/stateCheckout'; import { PickupAddress, SectionAddress, - SectionExpedisi, - SectionListService, SectionValidation, calculateEstimatedArrival, splitDuration, @@ -33,13 +30,12 @@ import { import addressesApi from '@/lib/address/api/addressesApi'; import { getItemAddress } from '@/core/utils/address'; import ExpedisiList from '../../checkout/api/ExpedisiList'; +import SectionQuotationExpedition from '@/lib/checkout/components/SectionQuotationExpedition'; +import { useQuotation } from '@/lib/checkout/stores/stateQuotation'; const { checkoutApi } = require('@/lib/checkout/api/checkoutApi'); const { getProductsCheckout } = require('@/lib/checkout/api/checkoutApi'); -import SectionExpedition from '@/lib/checkout/components/SectionExpedition'; - - const Quotation = () => { const PPN = process.env.NEXT_PUBLIC_PPN ? parseFloat(process.env.NEXT_PUBLIC_PPN) : 0; const router = useRouter(); @@ -55,41 +51,12 @@ const Quotation = () => { const { setRefreshCart } = useProductCartContext(); const SELF_PICKUP_ID = 32; - // const [products, setProducts] = useState(null); - const [totalAmount, setTotalAmount] = useState(0); + const [totalAmount, setTotalAmount] = useState(0); const [totalDiscountAmount, setTotalDiscountAmount] = useState(0); - - //start set up address and carrier - const [selectedCarrierId, setselectedCarrierId] = useState(0); - // const [listExpedisi, setExpedisi] = useState([]); - const [selectedExpedisi, setSelectedExpedisi] = useState(0); - // const [checkWeigth, setCheckWeight] = useState(false); - // const [checkoutValidation, setCheckoutValidation] = useState(false); - const [loadingRajaOngkir, setLoadingRajaOngkir] = useState(false); - - const [listserviceExpedisi, setListServiceExpedisi] = useState([]); - const [selectedServiceType, setSelectedServiceType] = useState(null); - - const [selectedCarrier, setselectedCarrier] = useState(0); - const [totalWeight, setTotalWeight] = useState(0); - - // const [biayaKirim, setBiayaKirim] = useState(0); - const [selectedExpedisiService, setselectedExpedisiService] = useState(null); - // const [etd, setEtd] = useState(null); - const [etdFix, setEtdFix] = useState(null); - const [isApproval, setIsApproval] = useState(false); - - const expedisiValidation = useRef(null); - - // const [selectedAddress, setSelectedAddress] = useState({ - // shipping: null, - // invoicing: null, - // }); - - // const [addresses, setAddresses] = useState(null); - const [note_websiteText, setselectedNote_websiteText] = useState(''); + const [isLoading, setIsLoading] = useState(false); + const [etdFix, setEtdFix] = useState(null); const { selectedAddress, @@ -102,15 +69,13 @@ const Quotation = () => { } = useAddress(); const { + products, + setProducts, checkWeigth, setCheckWeight, - hasFlashSale, - setHasFlashSale, checkoutValidation, setCheckoutValidation, biayaKirim, - products, - setProducts, etd, unit, selectedCourier, @@ -118,8 +83,16 @@ const Quotation = () => { selectedService, listExpedisi, setExpedisi, - productSla + productSla, + setProductSla, + setBiayaKirim, + setUnit, + setEtd, + setSelectedCourier, + setSelectedService, + setSelectedCourierId } = useQuotation(); + useEffect(() => { if (!auth) return; @@ -167,7 +140,6 @@ const Quotation = () => { }, [addresses]); useEffect(() => { - // voucher(); const loadExpedisi = async () => { let dataExpedisi = await ExpedisiList(); dataExpedisi = dataExpedisi.map((expedisi) => ({ @@ -192,182 +164,104 @@ const Quotation = () => { }; }, []); - // const loadServiceRajaOngkir = async () => { - // setLoadingRajaOngkir(true); - // const body = { - // origin: 2127, - // destination: selectedAddress.shipping.rajaongkirCityId, - // weight: totalWeight, - // courier: selectedCarrier, - // originType: 'subdistrict', - // destinationType: 'subdistrict', - // }; - // setBiayaKirim(0); - // const dataService = await axios( - // '/api/rajaongkir-service?body=' + JSON.stringify(body) - // ); - // setLoadingRajaOngkir(false); - // setListServiceExpedisi(dataService.data[0].costs); - // if (dataService.data[0].costs[0]) { - // setBiayaKirim(dataService.data[0].costs[0]?.cost[0].value); - // setselectedExpedisiService( - // dataService.data[0].costs[0]?.description + - // '-' + - // dataService.data[0].costs[0]?.service - // ); - // setEtd(dataService.data[0].costs[0]?.cost[0].etd); - // toast.success('Harap pilih tipe layanan pengiriman'); - // } else { - // toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.'); - // } - // }; - - useEffect(() => { - setCheckoutValidation(false); - - if (selectedCarrier != 0 && selectedCarrier != 1 && totalWeight > 0) { - // loadServiceRajaOngkir(); - } else { - setListServiceExpedisi(); - // setBiayaKirim(0); - setselectedExpedisiService(); - // setEtd(); - } - }, [selectedCarrier, selectedAddress, totalWeight]); - - useEffect(() => { - if (selectedExpedisi) { - let serviceType = selectedExpedisi.split(','); - if (serviceType[0] === 0) return; - - setselectedCarrier(serviceType[0]); - setselectedCarrierId(serviceType[1]); - setListServiceExpedisi([]); - } - }, [selectedExpedisi]); - - useEffect(() => { - if (selectedServiceType) { - let serviceType = selectedServiceType.split(','); - setBiayaKirim(serviceType[0]); - setselectedExpedisiService(serviceType[1]); - setEtd(serviceType[2]); - } - }, [selectedServiceType]); - - useEffect(() => { - if (etd) setEtdFix(calculateEstimatedArrival(etd)); - }, [etd]); - useEffect(() => { if (isApproval) { - setselectedCarrierId(1); - setselectedExpedisiService('indoteknik'); + setSelectedCourierId(1); + setSelectedCourier('indoteknik'); } }, [isApproval]); - // end set up address and carrier - useEffect(() => { - const loadProducts = async () => { - const cart = getCart(); - const variantIds = _.filter(cart, (o) => o.selected == true) - .map((o) => o.productId) - .join(','); - const dataProducts = await CartApi({ variantIds }); - const productsWithQuantity = dataProducts?.map((product) => { - return { - ...product, - quantity: getItemCart({ productId: product.id }).quantity, - }; - }); - if (productsWithQuantity) { - Promise.all(productsWithQuantity).then((resolvedProducts) => { - setProducts(resolvedProducts); - }); - } - }; - // loadExpedisi(); - // loadProducts() - }, []); - - useEffect(() => { - setProducts(cartCheckout?.products); - setCheckWeight(cartCheckout?.hasProductWithoutWeight); - setTotalWeight(cartCheckout?.totalWeight.g); + if (cartCheckout) { + setProducts(cartCheckout?.products); + setCheckWeight(cartCheckout?.hasProductWithoutWeight); + } }, [cartCheckout]); useEffect(() => { if (products) { - let calculateTotalAmount = 0; - let calculateTotalDiscountAmount = 0; - products.forEach((product) => { - calculateTotalAmount += product.price.price * product.quantity; - calculateTotalDiscountAmount += - (product.price.price - product.price.priceDiscount) * - product.quantity; - }); - setTotalAmount(calculateTotalAmount); - setTotalDiscountAmount(calculateTotalDiscountAmount); + const calculateTotals = () => { + let calculateTotalAmount = 0; + let calculateTotalDiscountAmount = 0; + + products.forEach((product) => { + calculateTotalAmount += product.price.price * product.quantity; + calculateTotalDiscountAmount += + (product.price.price - product.price.priceDiscount) * product.quantity; + }); + + setTotalAmount(calculateTotalAmount); + setTotalDiscountAmount(calculateTotalDiscountAmount); + }; + + calculateTotals(); } }, [products]); - const [isLoading, setIsLoading] = useState(false); + useEffect(() => { + if (etd) { + setEtdFix(calculateEstimatedArrival(etd)); + } + }, [etd]); const checkout = async () => { - // validation checkout - if (selectedExpedisi === 0 && !isApproval) { + // Validation + if (!selectedCourierId && !isApproval) { setCheckoutValidation(true); - if (expedisiValidation.current) { - const position = expedisiValidation.current.getBoundingClientRect(); - window.scrollTo({ - top: position.top - 300 + window.pageYOffset, - behavior: 'smooth', - }); - } + toast.error('Silahkan pilih ekspedisi'); return; } - if (selectedCarrier != 1 && biayaKirim == 0 && !isApproval) { + + if (selectedCourierId !== SELF_PICKUP_ID && biayaKirim === 0 && !isApproval) { toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.'); return; } - if (!products || products.length == 0) return; + if (!products || products.length === 0) return; - if (isApproval && note_websiteText == '') { + if (isApproval && note_websiteText === '') { toast.error('Maaf, Note wajib dimasukkan.'); return; } setIsLoading(true); - const productOrder = products.map((product) => ({ - product_id: product.id, - quantity: product.quantity, - })); - let data = { - partner_shipping_id: selectedAddress.shipping.id, - partner_invoice_id: selectedAddress.invoicing.id, - user_id: auth.id, - order_line: JSON.stringify(productOrder), - delivery_amount: biayaKirim, - carrier_id: selectedCarrierId, - estimated_arrival_days: splitDuration(etd), - delivery_service_type: selectedExpedisiService, - note_website: note_websiteText, - }; + try { + const productOrder = products.map((product) => ({ + product_id: product.id, + quantity: product.quantity, + })); - const isSuccess = await checkoutApi({ data }); - setIsLoading(false); - if (isSuccess?.id) { - for (const product of products) deleteItemCart({ productId: product.id }); - router.push(`/shop/quotation/finish?id=${isSuccess.id}`); - setRefreshCart(true); - return; + const data = { + partner_shipping_id: selectedAddress.shipping.id, + partner_invoice_id: selectedAddress.invoicing.id, + user_id: auth.id, + order_line: JSON.stringify(productOrder), + delivery_amount: biayaKirim, + carrier_id: selectedCourierId, + estimated_arrival_days: splitDuration(etd), + delivery_service_type: selectedService?.service_type || selectedCourier, + note_website: note_websiteText, + }; + + const isSuccess = await checkoutApi({ data }); + + if (isSuccess?.id) { + for (const product of products) { + deleteItemCart({ productId: product.id }); + } + router.push(`/shop/quotation/finish?id=${isSuccess.id}`); + setRefreshCart(true); + } else { + toast.error('Gagal melakukan transaksi, terjadi kesalahan internal'); + } + } catch (error) { + toast.error('Terjadi kesalahan saat memproses quotation'); + } finally { + setIsLoading(false); } - - toast.error('Gagal melakukan transaksi, terjadi kesalahan internal'); }; + const taxTotal = (totalAmount - totalDiscountAmount) * (PPN - 1); return ( @@ -387,21 +281,21 @@ const Quotation = () => { <Divider /> - {selectedCarrierId == SELF_PICKUP_ID && ( + {selectedCourierId == SELF_PICKUP_ID && ( <div className='p-4'> <div - class='flex items-center p-4 mb-4 text-sm border border-yellow-500 text-yellow-800 rounded-lg bg-yellow-50' + className='flex items-center p-4 mb-4 text-sm border border-yellow-500 text-yellow-800 rounded-lg bg-yellow-50' role='alert' > <svg - class='flex-shrink-0 inline w-4 h-4 mr-3' + className='flex-shrink-0 inline w-4 h-4 mr-3' aria-hidden='true' fill='currentColor' viewBox='0 0 20 20' > <path d='M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5ZM9.5 4a1.5 1.5 0 1 1 0 3 1.5 1.5 0 0 1 0-3ZM12 15H8a1 1 0 0 1 0-2h1v-3H8a1 1 0 0 1 0-2h2a1 1 0 0 1 1 1v4h1a1 1 0 0 1 0 2Z' /> </svg> - <span class='sr-only'>Info</span> + <span className='sr-only'>Info</span> <div className='text-justify'> Fitur Self Pickup, hanya berlaku untuk customer di area jakarta. Apa bila memilih fitur ini, anda akan dihubungi setelah barang @@ -411,10 +305,10 @@ const Quotation = () => { </div> )} - {selectedCarrierId == SELF_PICKUP_ID && ( + {selectedCourierId == SELF_PICKUP_ID && ( <PickupAddress label='Alamat Pickup' /> )} - {selectedCarrierId != SELF_PICKUP_ID && ( + {selectedCourierId != SELF_PICKUP_ID && ( <Skeleton isLoaded={!!selectedAddress.invoicing && !!selectedAddress.shipping} minHeight={320} @@ -434,23 +328,16 @@ const Quotation = () => { )} <Divider /> <SectionValidation address={selectedAddress.invoicing} /> - {!isApproval && ( - <> - {/* <SectionExpedition products={products} /> */} - <Divider /> - </> - )} - + <div className='p-4 flex flex-col gap-y-4'> {products && ( <VariantGroupCard openOnClick={false} variants={products} /> )} </div> + <SectionQuotationExpedition products={products} /> <Divider /> - {products && products.length > 0 && ( - <SectionExpedition products={products} listExpedisi={listExpedisi} /> - )} + <div className='p-4'> <div className='flex justify-between items-center'> <div className='font-medium'>Ringkasan Penawaran</div> @@ -546,10 +433,10 @@ const Quotation = () => { <DesktopView> <div className='container mx-auto py-10 flex'> <div className='w-3/4 border border-gray_r-6 rounded bg-white p-4'> - {selectedCarrierId == SELF_PICKUP_ID && ( + {selectedCourierId == SELF_PICKUP_ID && ( <PickupAddress label='Alamat Pickup' /> )} - {selectedCarrierId != SELF_PICKUP_ID && ( + {selectedCourierId != SELF_PICKUP_ID && ( <Skeleton isLoaded={ !!selectedAddress.invoicing && !!selectedAddress.shipping @@ -571,22 +458,16 @@ const Quotation = () => { )} <Divider /> <SectionValidation address={selectedAddress.invoicing} /> - {/* {!isApproval && ( - <SectionExpedition products={products} /> - )} */} - + + <SectionQuotationExpedition products={products} /> <Divider /> - {products && products.length > 0 && ( - <SectionExpedition products={products} listExpedisi={listExpedisi} /> - )} - {/* <div className='p-4'> */} + <div className='font-medium mb-6'>Detail Barang</div> <CardProdcuctsList isLoading={isLoading} products={products} source='checkout' /> - {/* </div> */} </div> <div className='w-1/4 pl-4'> @@ -641,9 +522,6 @@ const Quotation = () => { )} </div> </div> - {/* <p className='text-caption-2 text-gray_r-11 mb-2'> - *) Belum termasuk biaya pengiriman - </p> */} <p className='text-caption-2 text-gray_r-11 leading-5'> Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '} @@ -695,4 +573,4 @@ const Quotation = () => { ); }; -export default Quotation; +export default Quotation;
\ No newline at end of file |
