import { useState, useMemo } from 'react'; import Card from '@/components/Card'; import SelectInput, { useSelect } from '@/components/input/SelectInput'; import DateInput from '@/components/input/DateInput'; import { AreaApi } from '@/services/api/master-data'; import { SupplierApi } from '@/services/api/master-data'; import { ProductApi } from '@/services/api/master-data'; import Table from '@/components/Table'; import { ColumnDef } from '@tanstack/react-table'; import { formatCurrency, formatDate } from '@/lib/helper'; const PurchasesPerSupplierTab = () => { const [selectedArea, setSelectedArea] = useState(null); const [selectedSupplier, setSelectedSupplier] = useState(null); const [selectedProduct, setSelectedProduct] = useState(null); const [dataType, setDataType] = useState<'received_date' | 'po_date'>( 'received_date' ); const [startDate, setStartDate] = useState(null); const [endDate, setEndDate] = useState(null); const { options: areaOptions, isLoadingOptions: isLoadingAreas } = useSelect( AreaApi.basePath, 'id', 'name', 'search' ); const { options: supplierOptions, isLoadingOptions: isLoadingSuppliers } = useSelect(SupplierApi.basePath, 'id', 'name', 'search'); const { options: productOptions, isLoadingOptions: isLoadingProducts } = useSelect(ProductApi.basePath, 'id', 'name', 'search'); const dataTypeOptions = useMemo( () => [ { value: 'received_date', label: 'Tanggal Terima' }, { value: 'po_date', label: 'Tanggal PO' }, ], [] ); const data = useMemo( () => [ { id: 1, supplier: 'PT. RAJAWALI MITRA PAKANINDO', items: [ { id: 1, received_date: '2025-09-26', po_date: '2025-09-30', po_number: 'PO-MBU-00670', product_name: 'KAPORIT BESAR (TCCA) 200 GR @1 KG', destination_warehouse: 'GUDANG CIMARAGAS 1', qty: 5, price: 45000, purchase_amount: 225000, transport: 0, value_transport: 0, total: 225000, expedition_vendor_name: 'PT. RAJAWALI MITRA PAKANINDO', travel_number: '-', }, { id: 2, received_date: '2025-09-30', po_date: '2025-09-30', po_number: 'PO-MBU-00670', product_name: 'KAPORIT BESAR (TCCA) 200 GR @1 KG', destination_warehouse: 'GUDANG CIMARAGAS 2', qty: 5, price: 45000, purchase_amount: 225000, transport: 0, value_transport: 0, total: 225000, expedition_vendor_name: 'PT. RAJAWALI MITRA PAKANINDO', travel_number: '-', }, { id: 3, received_date: '2025-09-30', po_date: '2025-09-30', po_number: 'PO-MBU-00670', product_name: 'KAPORIT BESAR (TCCA) 200 GR @1 KG', destination_warehouse: 'GUDANG CIMARAGAS 3', qty: 5, price: 45000, purchase_amount: 225000, transport: 0, value_transport: 0, total: 225000, expedition_vendor_name: 'PT. RAJAWALI MITRA PAKANINDO', travel_number: '-', }, { id: 4, received_date: '2025-09-30', po_date: '2025-09-30', po_number: 'PO-MBU-00670', product_name: 'KAPORIT BESAR (TCCA) 200 GR @1 KG', destination_warehouse: 'GUDANG CIMARAGAS 4', qty: 5, price: 45000, purchase_amount: 225000, transport: 0, value_transport: 0, total: 225000, expedition_vendor_name: 'PT. RAJAWALI MITRA PAKANINDO', travel_number: '-', }, { id: 5, received_date: '2025-09-04', po_date: '2025-09-30', po_number: 'PO-MBU-00606', product_name: 'DESINFEKTAN C 100 @20L', destination_warehouse: 'GUDANG MANDALAWANGI 1', qty: 1, price: 800000, purchase_amount: 800000, transport: 0, value_transport: 0, total: 800000, expedition_vendor_name: 'PT. RAJAWALI MITRA PAKANINDO', travel_number: '-', }, ], }, { id: 2, supplier: 'Supplier B', items: [ { id: 6, received_date: '2024-01-18', po_date: '2024-01-13', po_number: 'PO-2024-004', product_name: 'Produk D', destination_warehouse: 'Gudang Pusat', qty: 200, price: 25000, purchase_amount: 5000000, transport: 200000, value_transport: 200000, total: 5200000, expedition_vendor_name: 'Ekspedisi GHI', travel_number: 'SJ-004', }, ], }, { id: 3, supplier: 'Supplier C', items: [ { id: 7, received_date: '2024-01-20', po_date: '2024-01-15', po_number: 'PO-2024-006', product_name: 'Produk F', destination_warehouse: 'Gudang Cabang', qty: 80, price: 55000, purchase_amount: 4400000, transport: 80000, value_transport: 80000, total: 4480000, expedition_vendor_name: 'Ekspedisi MNO', travel_number: 'SJ-006', }, ], }, ], [] ); // TODO START // eslint-disable-next-line @typescript-eslint/no-explicit-any const getTableColumns = (totals: any) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any const tableColumns: ColumnDef[] = [ { id: 'no', header: 'No', cell: (props) => props.row.index + 1, footer: () =>
Total
, }, { id: 'received_date', header: 'Tanggal Terima', accessorKey: 'received_date', cell: (props) => formatDate(props.getValue() as string, 'DD MMM YYYY'), }, { id: 'po_date', header: 'Tanggal PO', accessorKey: 'po_date', cell: (props) => formatDate(props.getValue() as string, 'DD MMM YYYY'), }, { id: 'po_number', header: 'No. Referensi', accessorKey: 'po_number', cell: (props) => props.getValue() || '-', }, { id: 'product_name', header: 'Nama Produk', accessorKey: 'product_name', cell: (props) => props.getValue() || '-', }, { id: 'destination_warehouse', header: 'Tujuan', accessorKey: 'destination_warehouse', cell: (props) => props.getValue() || '-', }, { id: 'qty', header: 'QTY', accessorKey: 'qty', cell: (props) => { const value = props.getValue() as number; return
{value.toLocaleString()}
; }, footer: () => (
{totals.totalQty.toLocaleString()}
), }, { id: 'price', header: 'Harga Beli (Rp)', accessorKey: 'price', cell: (props) => { const value = props.getValue() as number; return
{formatCurrency(value)}
; }, footer: () => (
{formatCurrency(totals.totalPrice)}
), }, { id: 'purchase_amount', header: 'Value Harga Beli (Rp)', accessorKey: 'purchase_amount', cell: (props) => { const value = props.getValue() as number; return
{formatCurrency(value)}
; }, footer: () => (
{formatCurrency(totals.totalPurchaseAmount)}
), }, { id: 'transport', header: 'Transport (Rp)', accessorKey: 'transport', cell: (props) => { const value = props.getValue() as number; return
{formatCurrency(value)}
; }, footer: () => (
{formatCurrency(totals.totalTransport)}
), }, { id: 'value_transport', header: 'Value Transport (Rp)', accessorKey: 'value_transport', cell: (props) => { const value = props.getValue() as number; return
{formatCurrency(value)}
; }, footer: () => (
{formatCurrency(totals.totalValueTransport)}
), }, { id: 'total', header: 'Jumlah (Rp)', accessorKey: 'total', cell: (props) => { const value = props.getValue() as number; return
{formatCurrency(value)}
; }, footer: () => (
{formatCurrency(totals.totalJumlah)}
), }, { id: 'expedition_vendor_name', header: 'Ekspedisi', accessorKey: 'expedition_vendor_name', cell: (props) => props.getValue() || '-', }, { id: 'travel_number', header: 'Surat Jalan', accessorKey: 'travel_number', cell: (props) => props.getValue() || '-', }, ]; return tableColumns; }; return ( <>
{/* TODO START */} option.value === selectedArea) || null } // @ts-expect-error TS2345 onChange={(val) => setSelectedArea(val?.value || null)} isLoading={isLoadingAreas} isClearable /> option.value === selectedSupplier ) || null } // @ts-expect-error TS2345 onChange={(val) => setSelectedSupplier(val?.value || null)} isLoading={isLoadingSuppliers} isClearable /> option.value === selectedProduct ) || null } // @ts-expect-error TS2345 onChange={(val) => setSelectedProduct(val?.value || null)} isLoading={isLoadingProducts} isClearable /> option.value === dataType) || null } // @ts-expect-error TS2345 onChange={(val) => setDataType(val?.value || 'received_date')} isLoading={false} isClearable={false} /> {/* TODO END */}
{data.length === 0 ? (
Tidak ada data untuk ditampilkan.
) : ( data.map((supplier) => { const totalQty = supplier.items.reduce( (sum, item) => sum + (item.qty || 0), 0 ); const totalPrice = supplier.items.reduce( (sum, item) => sum + (item.price || 0), 0 ); const totalPurchaseAmount = supplier.items.reduce( (sum, item) => sum + (item.purchase_amount || 0), 0 ); const totalTransport = supplier.items.reduce( (sum, item) => sum + (item.transport || 0), 0 ); const totalValueTransport = supplier.items.reduce( (sum, item) => sum + (item.value_transport || 0), 0 ); const totalJumlah = supplier.items.reduce( (sum, item) => sum + (item.total || 0), 0 ); const totals = { totalQty, totalPrice, totalPurchaseAmount, totalTransport, totalValueTransport, totalJumlah, }; const totalPurchase = totals.totalJumlah; const tableColumns = getTableColumns(totals); return ( 0} className={{ containerClassName: 'mb-0!', tableWrapperClassName: 'overflow-x-auto mt-4', tableClassName: 'w-full table-auto text-sm', headerRowClassName: 'border-b border-b-gray-200 bg-gray-50', headerColumnClassName: 'px-4 py-3 text-xs font-semibold text-gray-700 text-left border border-gray-200', bodyRowClassName: 'hover:bg-gray-50 transition-colors border-b border-l border-r border-b-gray-200 border-l-gray-200 border-r-gray-200', bodyColumnClassName: 'px-4 py-3 text-xs text-gray-900 whitespace-nowrap', tableFooterClassName: 'bg-gray-100 font-semibold border border-gray-200', footerRowClassName: 'border-t-2 border-gray-300', footerColumnClassName: 'px-4 py-3 text-xs text-gray-900 whitespace-nowrap', paginationClassName: 'hidden', }} /> ); }) )} ); }; export default PurchasesPerSupplierTab;