import Alert from '@/core/components/elements/Alert/Alert'; import Divider from '@/core/components/elements/Divider/Divider'; import Link from '@/core/components/elements/Link/Link'; import useAuth from '@/core/hooks/useAuth'; import CartApi from '@/lib/cart/api/CartApi'; import { ExclamationCircleIcon } from '@heroicons/react/24/outline'; import { useEffect, useRef, useState } from 'react'; import _ from 'lodash'; 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'; import DesktopView from '@/core/components/views/DesktopView'; import Image from '@/core/components/elements/Image/Image'; import { useQuery } from 'react-query'; import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList'; import { Skeleton } from '@chakra-ui/react'; import { PickupAddress, SectionAddress, SectionExpedisi, SectionListService, SectionValidation, calculateEstimatedArrival, splitDuration, } from '../../checkout/components/CheckoutSection'; import addressesApi from '@/lib/address/api/addressesApi'; import { getItemAddress } from '@/core/utils/address'; import ExpedisiList from '../../checkout/api/ExpedisiList'; import axios from 'axios'; const { checkoutApi } = require('@/lib/checkout/api/checkoutApi'); const { getProductsCheckout } = require('@/lib/checkout/api/checkoutApi'); const Quotation = () => { const PPN = process.env.NEXT_PUBLIC_PPN ? parseFloat(process.env.NEXT_PUBLIC_PPN) : 0; const router = useRouter(); const auth = useAuth(); const query = router.query.source ?? null; const { data: cartCheckout } = useQuery('cartCheckout', () => getProductsCheckout({ source: query, }) ); const { setRefreshCart } = useProductCartContext(); const SELF_PICKUP_ID = 32; const [products, setProducts] = useState(null); 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(''); useEffect(() => { if (!auth) return; const getAddresses = async () => { const dataAddresses = await addressesApi(); setAddresses(dataAddresses); }; getAddresses(); setIsApproval(auth?.feature?.soApproval); }, [auth]); useEffect(() => { if (!addresses) return; const matchAddress = (key) => { if (key === 'invoicing') { key = 'invoice'; } const addressToMatch = getItemAddress(key); const foundAddress = addresses.filter( (address) => address.id == addressToMatch ); if (foundAddress.length > 0) { return foundAddress[0]; } return addresses[0]; }; setSelectedAddress({ shipping: matchAddress('shipping'), invoicing: matchAddress('invoicing'), }); }, [addresses]); const loadExpedisi = async () => { let dataExpedisi = await ExpedisiList(); dataExpedisi = dataExpedisi.map((expedisi) => ({ value: expedisi.id, label: expedisi.name, carrierId: expedisi.deliveryCarrierId, })); setExpedisi(dataExpedisi); }; 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'); } }, [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); }, [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); } }, [products]); const [isLoading, setIsLoading] = useState(false); const checkout = async () => { // validation checkout if (selectedExpedisi === 0 && !isApproval) { setCheckoutValidation(true); if (expedisiValidation.current) { const position = expedisiValidation.current.getBoundingClientRect(); window.scrollTo({ top: position.top - 300 + window.pageYOffset, behavior: 'smooth', }); } return; } if (selectedCarrier != 1 && biayaKirim == 0 && !isApproval) { toast.error('Maaf, layanan tidak tersedia. Mohon pilih expedisi lain.'); return; } if (!products || products.length == 0) return; 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, }; 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; } toast.error('Gagal melakukan transaksi, terjadi kesalahan internal'); }; const taxTotal = (totalAmount - totalDiscountAmount) * (PPN - 1); return ( <>
Jika mengalami kesulitan dalam melakukan pembelian di website Indoteknik. Hubungi kami disini
{selectedCarrierId == SELF_PICKUP_ID && (
)} {selectedCarrierId == SELF_PICKUP_ID && ( )} {selectedCarrierId != SELF_PICKUP_ID && ( )} {!isApproval && ( <> )}
{products && ( )}
Ringkasan Penawaran
{products?.length} Barang

Total Belanja
{currencyFormat(cartCheckout?.totalPurchase)}
Diskon Produk
- {currencyFormat(cartCheckout?.totalDiscount)}
Subtotal
{currencyFormat(cartCheckout?.subtotal)}
PPN {((PPN - 1) * 100).toFixed(0)}%
{currencyFormat(cartCheckout?.tax)}
Biaya Kirim

{etdFix}

{currencyFormat( Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 )}

Grand Total
{currencyFormat( cartCheckout?.grandTotal + Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000 )}

*) Belum termasuk biaya pengiriman

Dengan melakukan pembelian melalui website Indoteknik, saya menyetujui{' '} Syarat & Ketentuan {' '} yang berlaku


Note
{isApproval && (
*harus diisi
)}