summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/checkout/api/ExpedisiList.js8
-rw-r--r--src/lib/checkout/api/serviceExpedisi.js8
-rw-r--r--src/lib/checkout/components/Checkout.jsx308
-rw-r--r--src/lib/variant/components/VariantCard.jsx3
4 files changed, 318 insertions, 9 deletions
diff --git a/src/lib/checkout/api/ExpedisiList.js b/src/lib/checkout/api/ExpedisiList.js
new file mode 100644
index 00000000..ca22bec1
--- /dev/null
+++ b/src/lib/checkout/api/ExpedisiList.js
@@ -0,0 +1,8 @@
+import odooApi from '@/core/api/odooApi'
+
+const ExpedisiList = async () => {
+ const dataExpedisi = await odooApi('GET', '/api/v1/courier')
+ return dataExpedisi
+}
+
+export default ExpedisiList
diff --git a/src/lib/checkout/api/serviceExpedisi.js b/src/lib/checkout/api/serviceExpedisi.js
new file mode 100644
index 00000000..0ff0aa03
--- /dev/null
+++ b/src/lib/checkout/api/serviceExpedisi.js
@@ -0,0 +1,8 @@
+import rajaOngkir from '@/core/api/rajaOngkirApi'
+
+const serviceExpedisi = async (body) => {
+ const dataExpedisi = await rajaOngkir('POST', '/starter/cost', body)
+ return dataExpedisi
+}
+
+export default serviceExpedisi
diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx
index dc3908db..b2f9a866 100644
--- a/src/lib/checkout/components/Checkout.jsx
+++ b/src/lib/checkout/components/Checkout.jsx
@@ -6,7 +6,7 @@ import { getItemAddress } from '@/core/utils/address'
import addressesApi from '@/lib/address/api/addressesApi'
import CartApi from '@/lib/cart/api/CartApi'
import { ExclamationCircleIcon } from '@heroicons/react/24/outline'
-import { useEffect, useRef, useState } from 'react'
+import React, { useEffect, useRef, useState } from 'react'
import _ from 'lodash'
import { deleteItemCart, getCart, getItemCart } from '@/core/utils/cart'
import currencyFormat from '@/core/utils/currencyFormat'
@@ -19,8 +19,11 @@ import axios from 'axios'
import Image from '@/core/components/elements/Image/Image'
import MobileView from '@/core/components/views/MobileView'
import DesktopView from '@/core/components/views/DesktopView'
+import ExpedisiList from '../api/ExpedisiList'
import whatsappUrl from '@/core/utils/whatsappUrl'
import { createSlug } from '@/core/utils/slug'
+import { Button, Modal } from 'flowbite-react'
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
const Checkout = () => {
const router = useRouter()
@@ -63,7 +66,32 @@ const Checkout = () => {
const [products, setProducts] = useState(null)
const [totalAmount, setTotalAmount] = useState(0)
const [totalDiscountAmount, setTotalDiscountAmount] = useState(0)
+ const [totalWeight, setTotalWeight] = useState(0)
const [priceCheck, setPriceCheck] = useState(false)
+ const [listExpedisi, setExpedisi] = useState([])
+ const [listserviceExpedisi, setListServiceExpedisi] = useState([])
+ const [selectedExpedisi, setSelectedExpedisi] = useState(0)
+ const [selectedCarrierId, setselectedCarrierId] = useState(0)
+ const [selectedCarrier, setselectedCarrier] = useState(0)
+ const [biayaKirim, setBiayaKirim] = useState(0)
+ const [checkWeigth, setCheckWeight] = useState(false)
+ const [selectedServiceType, setSelectedServiceType] = useState(null)
+ const [selectedExpedisiService, setselectedExpedisiService] = useState(null)
+ const [etd, setEtd] = useState(null)
+ const [etdFix, setEtdFix] = useState(null)
+
+ useEffect(() => {
+ const loadExpedisi = async () => {
+ let dataExpedisi = await ExpedisiList()
+ dataExpedisi = dataExpedisi.map((expedisi) => ({
+ value: expedisi.id,
+ label: expedisi.name,
+ carrierId: expedisi.deliveryCarrierId
+ }))
+ setExpedisi(dataExpedisi)
+ }
+ loadExpedisi()
+ }, [])
useEffect(() => {
const loadProducts = async () => {
@@ -97,16 +125,101 @@ const Checkout = () => {
if (products) {
let calculateTotalAmount = 0
let calculateTotalDiscountAmount = 0
+ let calcuateTotalWeight = 0
products.forEach((product) => {
calculateTotalAmount += product.price.price * product.quantity
calculateTotalDiscountAmount +=
(product.price.price - product.price.priceDiscount) * product.quantity
+ calcuateTotalWeight += product.weight * product.quantity
+ if (product.weight == 0) {
+ setCheckWeight(true)
+ }
})
setTotalAmount(calculateTotalAmount)
setTotalDiscountAmount(calculateTotalDiscountAmount)
+ setTotalWeight(calcuateTotalWeight * 1000)
}
}, [products])
+ useEffect(() => {
+ const loadServiceRajaOngkir = async () => {
+ const body = {
+ origin: 155,
+ destination: selectedAddress.shipping.rajaongkirCityId,
+ weight: totalWeight,
+ courier: selectedCarrier,
+ originType: 'city',
+ destinationType: 'city'
+ }
+ setBiayaKirim(0)
+ const dataService = await axios('/api/rajaongkir-service?body=' + JSON.stringify(body))
+ 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('Silahkan Pilih Service Tipe')
+ } else {
+ toast.error('Tidak Ada Service, Silahkan Pilih Expedisi lain !')
+ }
+ }
+ if (selectedCarrier != 0 && selectedCarrier != 1 && totalWeight > 0) {
+ loadServiceRajaOngkir()
+ } else {
+ setListServiceExpedisi()
+ setBiayaKirim(0)
+ setselectedExpedisiService()
+ setEtd()
+ }
+ }, [selectedCarrier, selectedAddress, totalWeight])
+
+ useEffect(() => {
+ if (selectedServiceType) {
+ let serviceType = selectedServiceType.split(',')
+ setBiayaKirim(serviceType[0])
+ setselectedExpedisiService(serviceType[1])
+ setEtd(serviceType[2])
+ }
+ }, [selectedServiceType])
+
+ useEffect(() => {
+ if (etd) {
+ let estimationDate = etd.split('-')
+ if (Array.isArray(estimationDate)) {
+ let from = new Date()
+ let to = new Date()
+ from.setDate(from.getDate() + parseInt(estimationDate[0]))
+ to.setDate(to.getDate() + parseInt(estimationDate[1]))
+ setEtdFix(
+ '(' +
+ from.getDate() +
+ ' ' +
+ from.toLocaleString('default', { month: 'short' }) +
+ ' - ' +
+ to.getDate() +
+ ' ' +
+ to.toLocaleString('default', { month: 'short' }) +
+ ')'
+ )
+ } else {
+ let to = new Date()
+ to.setDate(to.getDate() + parseInt(10))
+ setEtdFrom('>')
+ setEtdTo(to.getDate() + ' ' + to.toLocaleString('default', { month: 'short' }))
+ }
+ }
+ }, [etd])
+
+ useEffect(() => {
+ if (selectedExpedisi) {
+ let serviceType = selectedExpedisi.split(',')
+ setselectedCarrier(serviceType[0])
+ setselectedCarrierId(serviceType[1])
+ }
+ }, [selectedExpedisi])
+
const poNumber = useRef(null)
const poFile = useRef(null)
@@ -127,6 +240,9 @@ const Checkout = () => {
partner_shipping_id: auth.partnerId,
partner_invoice_id: auth.partnerId,
order_line: JSON.stringify(productOrder),
+ delivery_amount: biayaKirim,
+ carrier_id: selectedCarrierId,
+ delivery_service_type: selectedExpedisiService,
type: 'sale_order'
}
if (poNumber.current.value) data.po_number = poNumber.current.value
@@ -164,8 +280,37 @@ const Checkout = () => {
<Divider />
- <PickupAddress label='Alamat Pickup' />
-
+ {/* <PickupAddress label='Alamat Pickup' /> */}
+ <SectionAddress
+ address={selectedAddress.shipping}
+ label='Alamat Kirim'
+ url='/my/address?select=shipping'
+ ></SectionAddress>
+ <Divider />
+ <SectionAddress
+ address={selectedAddress.invoicing}
+ label='Alamat Penagihan'
+ url='/my/address?select=invoice'
+ ></SectionAddress>
+ <Divider />
+ <SectionValidation
+ address={selectedAddress.invoicing}
+ checkWeigth={checkWeigth}
+ ></SectionValidation>
+ <Divider />
+ <SectionExpedisi
+ address={selectedAddress.shipping}
+ listExpedisi={listExpedisi}
+ setSelectedExpedisi={setSelectedExpedisi}
+ checkWeigth={checkWeigth}
+ ></SectionExpedisi>
+ <Divider />
+ <SectionListService
+ listserviceExpedisi={listserviceExpedisi}
+ setSelectedServiceType={setSelectedServiceType}
+ ></SectionListService>
+ <Divider />
+ <Divider />
<Divider />
<div className='p-4 flex flex-col gap-y-4'>
@@ -197,12 +342,23 @@ const Checkout = () => {
<div className='text-gray_r-11'>PPN 11%</div>
<div>{currencyFormat(taxTotal)}</div>
</div>
+ <div className='flex gap-x-2 justify-between'>
+ <div className='text-gray_r-11'>
+ Biaya Kirim <p className='text-xs'>*Estimasi tiba {etdFix} </p>
+ </div>
+ <div>{currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)}</div>
+ </div>
</div>
<hr className='my-4 border-gray_r-6' />
<div className='flex gap-x-2 justify-between mb-4'>
<div>Grand Total</div>
<div className='font-semibold text-gray_r-12'>
- {currencyFormat(totalAmount - totalDiscountAmount + taxTotal)}
+ {currencyFormat(
+ totalAmount -
+ totalDiscountAmount +
+ taxTotal +
+ Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000
+ )}
</div>
</div>
{/* <p className='text-caption-2 text-gray_r-10 mb-2'>*) Belum termasuk biaya pengiriman</p> */}
@@ -244,7 +400,9 @@ const Checkout = () => {
<button
className='flex-1 btn-yellow'
onClick={checkout}
- disabled={isLoading || !products || products?.length == 0 || priceCheck}
+ disabled={
+ isLoading || !products || products?.length == 0 || priceCheck || selectedExpedisi == 0
+ }
>
{isLoading ? 'Loading...' : 'Lanjut Pembayaran'}
</button>
@@ -264,8 +422,35 @@ const Checkout = () => {
<DesktopView>
<div className='container mx-auto py-10 flex'>
<div className='w-3/4 border border-gray_r-6 rounded bg-white'>
- <PickupAddress label='Alamat Pickup' />
-
+ {/* <PickupAddress label='Alamat Pickup' /> */}
+ <SectionAddress
+ address={selectedAddress.shipping}
+ label='Alamat Kirim'
+ url='/my/address?select=shipping'
+ ></SectionAddress>
+ <Divider />
+ <SectionAddress
+ address={selectedAddress.invoicing}
+ label='Alamat Penagihan'
+ url='/my/address?select=invoice'
+ ></SectionAddress>
+ <Divider />
+ <SectionValidation
+ address={selectedAddress.invoicing}
+ checkWeigth={checkWeigth}
+ ></SectionValidation>
+ <Divider />
+ <SectionExpedisi
+ address={selectedAddress.shipping}
+ listExpedisi={listExpedisi}
+ setSelectedExpedisi={setSelectedExpedisi}
+ checkWeigth={checkWeigth}
+ ></SectionExpedisi>
+ <Divider />
+ <SectionListService
+ listserviceExpedisi={listserviceExpedisi}
+ setSelectedServiceType={setSelectedServiceType}
+ ></SectionListService>
<Divider />
<div className='p-4'>
@@ -300,6 +485,9 @@ const Checkout = () => {
? `| ${product?.attributes.join(', ')}`
: ''}
</div>
+ <div className='text-gray_r-11 mt-2'>
+ Berat item : {product?.weight} Kg
+ </div>
</div>
</td>
<td>
@@ -377,6 +565,13 @@ const Checkout = () => {
<div className='text-gray_r-11'>PPN 11%</div>
<div>{currencyFormat(taxTotal)}</div>
</div>
+ <div className='flex gap-x-2 justify-between'>
+ <div className='text-gray_r-11'>
+ Biaya Kirim
+ <p className='text-xs'>*Estimasi tiba {etdFix} </p>
+ </div>
+ <div>{currencyFormat(Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000)}</div>
+ </div>
</div>
<hr className='my-4 border-gray_r-6' />
@@ -384,7 +579,12 @@ const Checkout = () => {
<div className='flex gap-x-2 justify-between mb-4'>
<div>Grand Total</div>
<div className='font-semibold text-gray_r-12'>
- {currencyFormat(totalAmount - totalDiscountAmount + taxTotal)}
+ {currencyFormat(
+ totalAmount -
+ totalDiscountAmount +
+ taxTotal +
+ Math.round(parseInt(biayaKirim * 1.1) / 1000) * 1000
+ )}
</div>
</div>
<p className='text-caption-2 text-gray_r-11 leading-5'>
@@ -423,7 +623,14 @@ const Checkout = () => {
<button
className='w-full btn-yellow mt-4'
onClick={checkout}
- disabled={isLoading || !products || products?.length == 0 || priceCheck}
+ disabled={
+ isLoading ||
+ !products ||
+ products?.length == 0 ||
+ priceCheck ||
+ selectedCarrier == 0 ||
+ (selectedCarrier != 1 && biayaKirim == 0)
+ }
>
{isLoading ? 'Loading...' : 'Lanjut Pembayaran'}
</button>
@@ -468,6 +675,89 @@ const SectionAddress = ({ address, label, url }) => (
)}
</div>
)
+
+const SectionValidation = ({ address, checkWeigth }) =>
+ address?.rajaongkirCityId == 0 && (
+ <BottomPopup active={true} title='Update Alamat'>
+ <div className='leading-7 text-gray_r-12/80'>
+ Silahkan Update Alamat Anda Melalui Tombol di bawah ini{' '}
+ </div>
+ <div className='flex justify-center mt-6 gap-x-4'>
+ <Link className='btn-solid-red w-full md:w-fit text-white' href={`/my/address/${address?.id}/edit`}>
+ Update Alamat
+ </Link>
+ </div>
+ </BottomPopup>
+ )
+
+const SectionExpedisi = ({ address, listExpedisi, setSelectedExpedisi, checkWeigth }) =>
+ address?.rajaongkirCityId > 0 && (
+ <div className='p-4'>
+ <div className='flex justify-between items-center'>
+ <div className='font-medium'>Pilih Expedisi : </div>
+ <div>
+ <select className='form-input' onChange={(e) => setSelectedExpedisi(e.target.value)}>
+ <option value='0,0'>Pengiriman</option>
+ <option value='1,32'>SELF PICKUP</option>
+ {checkWeigth != true &&
+ listExpedisi.map((expedisi) => (
+ <option
+ disabled={checkWeigth}
+ value={expedisi.label + ',' + expedisi.carrierId}
+ key={expedisi.value}
+ >
+ {' '}
+ {expedisi.label.toUpperCase()}{' '}
+ </option>
+ ))}
+ </select>
+ </div>
+ </div>
+ {checkWeigth == true && (
+ <p className='mt-2 text-gray_r-11'>
+ Opsi pengiriman hanya ada self pickup, ada berat item yang belum di setting, silahkan hub
+ admin di{' '}
+ <span>
+ <a className='text-danger-500' href='https://api.whatsapp.com/send?phone=628128080622'>
+ Link InI !
+ </a>
+ </span>
+ </p>
+ )}
+ </div>
+ )
+
+const SectionListService = ({ listserviceExpedisi, setSelectedServiceType }) =>
+ listserviceExpedisi?.length > 0 && (
+ <div className='p-4'>
+ <div className='flex justify-between items-center'>
+ <div className='font-medium'>Service Type Expedisi : </div>
+ <div>
+ <select className='form-input' onChange={(e) => setSelectedServiceType(e.target.value)}>
+ {listserviceExpedisi.map((service) => (
+ <option
+ value={
+ service.cost[0].value +
+ ',' +
+ service.description +
+ '-' +
+ service.service +
+ ',' +
+ service.cost[0].etd
+ }
+ key={service.service}
+ >
+ {' '}
+ {service.description} - {service.service.toUpperCase()} (Estimasi Tiba{' '}
+ {service.cost[0].etd} Hari)
+ </option>
+ ))}
+ </select>
+ </div>
+ </div>
+ </div>
+ )
+
const PickupAddress = ({ label }) => (
<div className='p-4'>
<div className='flex justify-between items-center'>
diff --git a/src/lib/variant/components/VariantCard.jsx b/src/lib/variant/components/VariantCard.jsx
index 93234c53..0f9f02f6 100644
--- a/src/lib/variant/components/VariantCard.jsx
+++ b/src/lib/variant/components/VariantCard.jsx
@@ -39,6 +39,9 @@ const VariantCard = ({ product, openOnClick = true, buyMore = false }) => {
{product.code || '-'}
{product.attributes.length > 0 ? ` ・ ${product.attributes.join(', ')}` : ''}
</p>
+ <p className='text-caption-2 text-gray_r-11 mt-1'>
+ Berat Item : {product?.weight} Kg
+ </p>
<div className='flex flex-wrap gap-x-1 items-center mt-auto'>
{product.price.discountPercentage > 0 && (
<>