diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2025-08-12 09:00:01 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2025-08-12 09:00:01 +0000 |
| commit | f62358c34e8449088093267ccf694b18b4d09cd6 (patch) | |
| tree | 3de77144beefa54e6d75354a1a57600213864d42 /src | |
| parent | c33f96ba48e112d3beb3c4b63522a9c1e1840051 (diff) | |
| parent | cb1bf0046249492094e59107ee5c904a36338eeb (diff) | |
Merged in cr/repeat-order (pull request #436)
Cr/repeat order
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/transaction/components/Transaction.jsx | 452 | ||||
| -rw-r--r-- | src/lib/treckingAwb/component/InformationSection.jsx | 4 | ||||
| -rw-r--r-- | src/lib/treckingAwb/component/Manifest.jsx | 25 | ||||
| -rw-r--r-- | src/lib/variant/components/VariantGroupCard.jsx | 7 |
4 files changed, 231 insertions, 257 deletions
diff --git a/src/lib/transaction/components/Transaction.jsx b/src/lib/transaction/components/Transaction.jsx index 842567f8..77e60dc1 100644 --- a/src/lib/transaction/components/Transaction.jsx +++ b/src/lib/transaction/components/Transaction.jsx @@ -45,9 +45,11 @@ import { downloadInvoice, downloadTaxInvoice, } from '@/lib/invoice/utils/invoices'; +import { Download } from 'lucide-react'; import axios from 'axios'; import InformationSection from '../../treckingAwb/component/InformationSection'; import { Button } from '@chakra-ui/react'; +import { div } from 'lodash-contrib'; const Transaction = ({ id }) => { const PPN = process.env.NEXT_PUBLIC_PPN; const router = useRouter(); @@ -56,7 +58,6 @@ const Transaction = ({ id }) => { const [reason, setReason] = useState(''); const auth = useAuth(); const { transaction } = useTransaction({ id }); - console.log('transaction', transaction); const statusApprovalWeb = transaction.data?.approvalStep; const [isLoading, setIsLoading] = useState(false); const { queryAirwayBill } = useAirwayBill({ orderId: id }); @@ -87,8 +88,6 @@ const Transaction = ({ id }) => { setTotalDiscountAmount(calculateTotalDiscountAmount); } }, [transaction.data, transaction.isLoading]); - console.log('totalAmount', totalAmount); - console.log('totalDiscountAmount', totalDiscountAmount); const submitUploadPo = async () => { const file = poFile.current.files[0]; const name = poNumber.current.value; @@ -195,6 +194,7 @@ const Transaction = ({ id }) => { } toast.success('Berhasil melanjutkan pesanan'); transaction.refetch(); + // console.log(transaction); /* const midtrans = async () => { for (const product of products) deleteItemCart({ productId: product.id }); @@ -336,7 +336,7 @@ const Transaction = ({ id }) => { const [day, month, year] = dateString.split('/'); return `${day} ${months[parseInt(month, 10) - 1]} ${year}`; }; - + // console.log(transaction); return ( transaction.data?.name && ( <> @@ -526,7 +526,7 @@ const Transaction = ({ id }) => { <div className='flex flex-row justify-between items-center gap-2 px-4'> <div className='flex flex-col justify-start items-start gap-2'> - <div className='font-medium'>Status Transaksi</div> + <div className='font-semibold'>{transaction.data?.name}</div> <TransactionStatusBadge status={transaction.data?.status} /> </div> <div> @@ -559,16 +559,7 @@ const Transaction = ({ id }) => { <Divider /> <div className='flex flex-col gap-y-4 p-4'> - <DescriptionRow label='Status Transaksi'> - <div className='flex justify-end'> - <TransactionStatusBadge status={transaction.data?.status} /> - </div> - </DescriptionRow> - <DescriptionRow label='Status Transaksi'> - <div className='flex justify-end font-semibold text-red-500'> - {transaction.data?.expectedReadyToShip} - </div> - </DescriptionRow> + <h4 className="font-semibold">Detail Order</h4> <DescriptionRow label='No Transaksi'> <p className='font-semibold'>{transaction.data?.name}</p> </DescriptionRow> @@ -580,9 +571,6 @@ const Transaction = ({ id }) => { <DescriptionRow label='Purchase Order'> {transaction.data?.purchaseOrderName || '-'} </DescriptionRow> - <DescriptionRow label='Ketentuan Pembayaran'> - {transaction.data?.paymentTerm || '-'} - </DescriptionRow> <DescriptionRow label='Nama Sales'> {transaction.data?.sales} </DescriptionRow> @@ -590,103 +578,80 @@ const Transaction = ({ id }) => { <Divider /> + <div className='flex flex-col gap-y-4 p-4'> + <h4 className="font-semibold">Alamat Pengiriman</h4> + <DescriptionRow label='Nama Penerima'> + <p className='font-semibold'>{transaction?.data?.address?.customer?.name}</p> + </DescriptionRow> + <DescriptionRow label='No. Telp'> + {transaction?.data?.address?.customer?.phone + ? transaction?.data?.address?.customer?.phone + : '-'} + </DescriptionRow> + <DescriptionRow label='Email'> + {transaction?.data?.address?.customer?.email + ? transaction?.data?.address?.customer?.email + : '-'} + </DescriptionRow> + <DescriptionRow label='Alamat Pengiriman'> + {transaction?.data?.address?.customer?.alamatBisnis} + </DescriptionRow> + </div> + + <Divider /> <div className='p-4'> - <div className='flex flex-row justify-between items-center'> - <div className='font-medium'>Info Pengiriman</div> - <span - className='text-red-500' - onClick={() => setIdAWB(transaction?.data?.pickings[0]?.id)} + <div className='font-medium mb-4'>Info Pengiriman</div> + {transaction?.data?.pickings.length == 0 && ( + <div className='badge-red text-sm'> + Belum ada pengiriman + </div> + )} + {transaction?.data?.pickings?.map((airway) => ( + <div + key={airway?.id} + className='border border-gray_r-6 rounded mb-3' > - Lihat Detail - </span> - </div> - <hr className='mt-4 mb-4 border border-gray-100' /> - <div className='flex flex-col gap-y-4'> - <DescriptionRow label='Dokumen Pengiriman'> - <p className='text-red-500 font-semibold text-start'> - {transaction.data?.pickings?.length == 0 - ? 'Belum ada pengiriman' - : transaction?.data?.pickings[0].name} - </p> - </DescriptionRow> - <DescriptionRow label='Kurir'> - <p className='text-start'> - {transaction?.data?.pickings[0]?.carrierName ? ( - <p className=' text-nowrap'> - {transaction?.data?.pickings[0]?.carrierName} - </p> - ) : ( - '-' - )} - </p> - </DescriptionRow> - <DescriptionRow label='Jenis Service'> - <p className='text-start'> - {transaction?.data?.pickings[0]?.serviceType && - transaction?.data?.pickings[0]?.carrierName - ? transaction?.data?.pickings[0]?.serviceType - : '-'} - </p> - </DescriptionRow> - <DescriptionRow label='Nomor Resi'> - <div className='flex flex-row gap-1 text-start'> - {transaction?.data?.pickings[0]?.trackingNumber || '-'} - {transaction?.data?.pickings[0]?.trackingNumber && ( - <button - className={`${ - copied ? 'text-gray-400' : 'text-red-600 ' - }`} - onClick={() => - handleCopyClick( - transaction?.data?.pickings[0]?.trackingNumber - ) + <InformationSection manifests={airway} /> + <div className='p-4'> + <button + className='bg-transparent text-red-600 hover:underline p-0 font-semibold' + onClick={() => { + if (airway?.waybillNumber == '-') { + toast.error('Nomor Resi belum tersedia'); + return; } - > - <svg - aria-hidden='true' - fill='none' - stroke='currentColor' - stroke-width='1.5' - viewBox='0 0 24 24' - className='w-5 h-6' - > - <path - d='M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75' - stroke-linecap='round' - stroke-linejoin='round' - ></path> - </svg> - </button> - )} - </div> - </DescriptionRow> - <DescriptionRow label='Estimasi Tiba'> - <p className='text-start'> - {transaction?.data?.pickings[0]?.eta - ? transaction?.data?.pickings[0]?.eta - : '-'} - </p> - </DescriptionRow> - <DescriptionRow label='Alamat Pengiriman'> - <div className='flex flex-col justify-start items-start'> - <div className='text-start text-nowrap truncate w-full'> - {transaction?.data?.address?.customer?.name} - </div> - <div className='text-start'> - {transaction?.data?.address?.customer?.phone - ? transaction?.data?.address?.customer?.phone - : '-'} - </div> - <div className='text-start'> - {transaction?.data?.address?.customer?.alamatBisnis} - </div> + setIdAWB(airway.id); + }} + > + Lacak Pengiriman + </button> </div> - </DescriptionRow> - </div> + </div> + // <button + // className='shadow rounded-md p-3 text-gray_r-12 font-normal flex justify-between items-center text-left h-20' + // key={airway?.id} + // onClick={() => setIdAWB(airway?.id)} + // > + // <div> + // <span className='text-sm text-gray_r-11'> + // No Resi : {airway?.trackingNumber || '-'}{' '} + // </span> + // <p className='mt-1 font-medium'>{airway?.name}</p> + // </div> + // <div className='flex gap-x-2'> + // <div className='text-sm text-gray-600 badge-green leading-[1.5] mt-1'> + // {airway?.delivered + // ? 'Pesanan Tiba' + // : 'Sedang Dikirim'} + // </div> + // <ChevronRightIcon className='w-5 stroke-2' /> + // </div> + // </button> + ))} </div> - {/* <Divider /> + <Divider /> <div className='p-4'> <p className='font-medium'>Invoice</p> @@ -715,17 +680,17 @@ const Transaction = ({ id }) => { <div className='badge-red text-sm px-2'>Belum ada invoice</div> )} </div> - </div> */} + </div> <Divider /> - {/* {!auth?.feature.soApproval && ( + {!auth?.feature.soApproval && ( <div className='p-4 flex flex-col gap-y-4'> <DescriptionRow label='Purchase Order'> {transaction.data?.purchaseOrderName || '-'} </DescriptionRow> - <div className='flex items-center'> - <p className='text-gray_r-11 leading-none'>Dokumen PO</p> + <div className='flex items-center justify-between'> + <p className='text-gray_r-11 leading-none'>Dokumen PO : </p> <button type='button' className='inline-block text-danger-500' @@ -747,26 +712,22 @@ const Transaction = ({ id }) => { </div> )} - <Divider /> */} + <Divider /> <div className='font-medium p-4'>Detail Produk</div> {transaction?.data?.products.length > 0 ? ( <div className='p-4 pt-0 flex flex-col gap-y-3'> - <VariantGroupCard variants={transaction.data?.products} buyMore /> + <VariantGroupCard variants={transaction.data?.products}/> <div className='font-medium'>Rincian Pembayaran</div> <div className='flex justify-between mt-1'> <p className='text-gray_r-12/70'>Metode Pembayaran</p> <p> - {transaction.data?.paymentType - ? transaction.data?.paymentType - ?.replace(/_/g, ' ') - .replace(/\b\w/g, (char) => char.toUpperCase()) - : '-'} + {transaction.data?.paymentTerm || '-'} </p> </div> <div className='flex justify-between mt-1'> <p className='text-gray_r-12/70'>Berat Barang</p> - <p>{transaction.data?.pickings[0]?.weightTotal + ' Kg'}</p> + <p>{(transaction.data?.products?.reduce((total, item) => total + (item.weight || 0), 0)) + ' Kg'}</p> </div> <hr className='mt-1 border border-gray-100' /> <div className='flex justify-between mt-1'> @@ -822,7 +783,7 @@ const Transaction = ({ id }) => { {transaction.data?.status === 'draft' && ( <div className='p-4 pt-0'> <button - className='btn-yellow w-full mt-4' + className='btn-light w-full mt-4' disabled={transaction.data?.status != 'draft'} onClick={() => downloadQuotation(transaction.data)} > @@ -834,6 +795,15 @@ const Transaction = ({ id }) => { > Batalkan Transaksi </button> + {transaction.data?.status == 'draft' && + transaction?.data?.purchaseOrderFile && ( + <button + className='btn-yellow w-full mt-4' + onClick={openContinueTransaction} + > + Lanjutkan Transaksi + </button> + )} </div> )} </MobileView> @@ -876,15 +846,44 @@ const Transaction = ({ id }) => { {transaction?.data?.name} </span> <TransactionStatusBadge status={transaction?.data?.status} /> + {transaction.data?.status === 'draft' && ( + <div className='flex items-center justify-between w-full'> + <button + type='button' + className='btn-light px-3 py-2' + onClick={() => downloadQuotation(transaction.data)} + > + <Download size={12} /> + </button> + + <div className="flex gap-x-4"> + <button + className='btn-solid-red' + onClick={openCancelTransaction} + > + Batalkan Transaksi + </button> + {transaction.data?.status == 'draft' && + transaction?.data?.purchaseOrderFile && ( + <button + className='btn-yellow' + onClick={openContinueTransaction} + > + Lanjutkan Transaksi + </button> + )} + </div> + </div> + )} </div> - {transaction.data?.status === 'draft' && ( + {/* {transaction.data?.status === 'draft' && ( <div className='flex gap-x-4'> <button type='button' - className='btn-yellow px-3 py-2 mr-auto' + className='btn-light px-3 py-2 mr-auto' onClick={() => downloadQuotation(transaction.data)} > - Download + <Download size={12} /> </button> <button className='btn-solid-red' @@ -892,8 +891,18 @@ const Transaction = ({ id }) => { > Batalkan Transaksi </button> + + {transaction.data?.status == 'draft' && + transaction?.data?.purchaseOrderFile && ( + <button + className='btn-yellow' + onClick={openContinueTransaction} + > + Lanjutkan Transaksi + </button> + )} </div> - )} + )} */} <div className='grid grid-cols-2 gap-x-6 mt-4'> <div className='grid grid-cols-[35%_65%] gap-y-4'> @@ -1016,88 +1025,54 @@ const Transaction = ({ id }) => { </div> <div className='flex flex-col w-1/2 justify-start items-start'> <span className='text-h-sm font-medium mb-2'> - Info Pengiriman + Info Ekspedisi </span> <div className='grid grid-cols-[34%_2%_64%] gap-y-4 w-full'> - <div>Nomor Resi</div> - <div>: </div> - <div className='flex flex-row gap-1 '> - {transaction?.data?.pickings[0]?.trackingNumber || '-'} - {transaction?.data?.pickings[0]?.trackingNumber && ( - <button - className={`${ - copied ? 'text-gray-400' : 'text-red-600 ' - }`} - onClick={() => - handleCopyClick( - transaction?.data?.pickings[0]?.trackingNumber - ) - } - > - <svg - aria-hidden='true' - fill='none' - stroke='currentColor' - stroke-width='1.5' - viewBox='0 0 24 24' - className='w-5 h-6' - > - <path - d='M15.75 17.25v3.375c0 .621-.504 1.125-1.125 1.125h-9.75a1.125 1.125 0 01-1.125-1.125V7.875c0-.621.504-1.125 1.125-1.125H6.75a9.06 9.06 0 011.5.124m7.5 10.376h3.375c.621 0 1.125-.504 1.125-1.125V11.25c0-4.46-3.243-8.161-7.5-8.876a9.06 9.06 0 00-1.5-.124H9.375c-.621 0-1.125.504-1.125 1.125v3.5m7.5 10.375H9.375a1.125 1.125 0 01-1.125-1.125v-9.25m12 6.625v-1.875a3.375 3.375 0 00-3.375-3.375h-1.5a1.125 1.125 0 01-1.125-1.125v-1.5a3.375 3.375 0 00-3.375-3.375H9.75' - stroke-linecap='round' - stroke-linejoin='round' - ></path> - </svg> - </button> - )} - </div> - <div>Kurir</div> <div>: </div> - {transaction?.data?.pickings[0]?.carrierName ? ( + {transaction?.data?.carrierName ? ( <div className='flex flex-row w-full gap-1 items-center justify-start '> <p className=' text-nowrap'> - {transaction?.data?.pickings[0]?.carrierName} + {transaction?.data?.carrierName} </p> - <span - className='text-red-500 text-sm font-semibold hover:cursor-pointer' - onClick={() => - setIdAWB(transaction?.data?.pickings[0]?.id) - } - > - Lacak Pengiriman - </span> </div> ) : ( '-' )} + {transaction?.data?.carrierId !== 32 &&( + <> + <div>Jenis Service</div> + <div>: </div> + <div> + {' '} + {transaction?.data?.serviceType + ? transaction?.data?.serviceType + : '-'} + </div> + </> + )} - <div>Jenis Service</div> - <div>: </div> - <div> - {' '} - {transaction?.data?.pickings[0]?.serviceType && - transaction?.data?.pickings[0]?.carrierName - ? transaction?.data?.pickings[0]?.serviceType - : '-'} - </div> - - <div>Tanggal Kirim</div> + <div>Estimasi Tanggal Kirim</div> <div>: </div> <div> - {transaction?.data?.pickings[0]?.date - ? formatDate(transaction?.data?.pickings[0]?.date) - : '-'} - </div> - - <div>Estimasi Tiba</div> - <div>: </div> - <div className='text-red-500'> - {transaction?.data?.pickings[0]?.eta - ? transaction?.data?.pickings[0]?.eta + {transaction?.data?.expectedReadyToShip + ? transaction?.data?.expectedReadyToShip : '-'} </div> - {transaction?.data?.pickings[0] && ( + {transaction?.data?.carrierId !== 32 &&( + <> + <div>Estimasi Tiba</div> + <div>: </div> + <div className=''> + {transaction?.data?.etaDateStart && transaction?.data?.etaDateEnd ? ( + `${transaction.data.etaDateStart} - ${transaction.data.etaDateEnd}` + ) : ( + '-' + )} + </div> + </> + )} + {transaction?.data?.pickings[0] && transaction?.data?.carrierId !== 32 && ( <div className='w-full bagian-informasi col-span-3'> <div class='flex items-center w-fit py-2 px-3 mb-4 text-sm border border-yellow-500 text-yellow-800 rounded-lg bg-yellow-50' @@ -1123,72 +1098,39 @@ const Transaction = ({ id }) => { </div> </div> - <div className='flex gap-x-3'> - <div className='w-1/2'> - <div className='text-h-sm font-semibold mt-10 mb-4'> - Informasi Pelanggan - </div> - <div className='border border-gray_r-6 rounded p-3'> - <div className='font-medium mb-4'>Detail Pelanggan</div> - <SectionContent - address={transaction?.data?.address?.customer} - /> - </div> - </div> - <div className='w-1/2'> - <div className='text-h-sm font-semibold mt-10 mb-4'> - Informasi Pengiriman + <div className='text-h-sm font-semibold mt-4 mb-4'> + Informasi Pengiriman + </div> + <div className='grid grid-cols-1 md:grid-cols-2 gap-3'> + {transaction?.data?.pickings.length == 0 && ( + <div className='badge-red text-sm'> + Belum ada pengiriman </div> - {transaction?.data?.pickings.length == 0 && ( - <div className='badge-red text-sm'> - Belum ada pengiriman - </div> - )} - {/* <div className='grid grid-cols-1 gap-1 w-1/2'> */} - {transaction?.data?.pickings?.map((airway) => ( - <div - key={airway?.id} - className='border border-gray_r-6 rounded p-3' - > - <InformationSection manifests={airway} /> - <div className='p-4'> - <button - className='bg-transparent text-red-600 hover:underline p-0 font-semibold' - onClick={() => { - if (airway?.waybillNumber == '-') { - toast.error('Nomor Resi belum tersedia'); - return; - } - setIdAWB(airway.id); - }} - > - Lacak Pengiriman - </button> - </div> + )} + {transaction?.data?.pickings?.map((airway) => ( + <div + key={airway?.id} + className='border border-gray_r-6 rounded p-3' + > + <InformationSection manifests={airway} /> + <div className='p-4'> + <button + className='bg-transparent text-red-600 hover:underline p-0 font-semibold' + onClick={() => { + if (airway?.waybillNumber == '-') { + toast.error('Nomor Resi belum tersedia'); + return; + } + setIdAWB(airway.id); + }} + > + Lacak Pengiriman + </button> </div> - // <button - // className='shadow rounded-md p-3 text-gray_r-12 font-normal flex justify-between items-center text-left h-20' - // key={airway?.id} - // onClick={() => setIdAWB(airway?.id)} - // > - // <div> - // <span className='text-sm text-gray_r-11'> - // No Resi : {airway?.trackingNumber || '-'}{' '} - // </span> - // <p className='mt-1 font-medium'>{airway?.name}</p> - // </div> - // <div className='flex gap-x-2'> - // <div className='text-sm text-gray-600 badge-green leading-[1.5] mt-1'> - // {airway?.delivered - // ? 'Pesanan Tiba' - // : 'Sedang Dikirim'} - // </div> - // <ChevronRightIcon className='w-5 stroke-2' /> - // </div> - // </button> - ))} - {/* </div> */} - </div> + </div> + ))} + {/* </div> */} + </div> <div className='flex '> diff --git a/src/lib/treckingAwb/component/InformationSection.jsx b/src/lib/treckingAwb/component/InformationSection.jsx index a2297af3..4b3bd5fb 100644 --- a/src/lib/treckingAwb/component/InformationSection.jsx +++ b/src/lib/treckingAwb/component/InformationSection.jsx @@ -69,6 +69,10 @@ const InformationSection = ({ manifests }) => { <span className='text-red-600 font-semibold'>{manifests?.eta}</span> </span> </div> + <div className='grid grid-cols-[150px_auto]'> + <span>Total Product</span> + <span className='font-semibold'> : {Array.isArray(manifests?.products) ? manifests.products.length : 0} Product</span> + </div> </div> </div> ); diff --git a/src/lib/treckingAwb/component/Manifest.jsx b/src/lib/treckingAwb/component/Manifest.jsx index acb86f57..6eb0b0ac 100644 --- a/src/lib/treckingAwb/component/Manifest.jsx +++ b/src/lib/treckingAwb/component/Manifest.jsx @@ -223,6 +223,31 @@ const Manifest = ({ idAWB, closePopup }) => { ) } </div> + + {/* Barang */} + <div className='mt-1'> + {Array.isArray(manifests?.products) && manifests.products.length > 0 ? ( + <div className='flex flex-col gap-4'> + {manifests.products.map((product, idx) => ( + <div key={idx} className='flex gap-4 border-b pb-4'> + {/* Gambar Produk */} + <img + src={product.image} + alt={product.name} + className='w-16 h-16 object-contain border' + /> + {/* Info Produk */} + <div className='flex flex-col flex-1'> + <span className='font-semibold'>{product.name}</span> + <span className='text-sm text-gray-500'>{product.code}</span> + </div> + </div> + ))} + </div> + ) : ( + <span></span> + )} + </div> </BottomPopup> )} </> diff --git a/src/lib/variant/components/VariantGroupCard.jsx b/src/lib/variant/components/VariantGroupCard.jsx index 1e921546..7db9703b 100644 --- a/src/lib/variant/components/VariantGroupCard.jsx +++ b/src/lib/variant/components/VariantGroupCard.jsx @@ -10,7 +10,10 @@ const VariantGroupCard = ({ variants, ...props }) => { return ( <> {variantsToShow?.map((variant, index) => ( - <> + <div + key={index} + className='shadow border border-gray rounded-md p-4 mb-1 shadow-sm bg-white' + > <VariantCard key={index} product={variant} {...props} /> {variant.program && variant.program.items && @@ -48,7 +51,7 @@ const VariantGroupCard = ({ variants, ...props }) => { </div> </div> ))} - </> + </div> ))} {variants.length > 2 && ( <button |
