diff --git a/src/components/pages/purchase/PurchaseTable.tsx b/src/components/pages/purchase/PurchaseTable.tsx
index fdd2f9be..1e2da838 100644
--- a/src/components/pages/purchase/PurchaseTable.tsx
+++ b/src/components/pages/purchase/PurchaseTable.tsx
@@ -28,7 +28,7 @@ import PurchaseFilterModal from '@/components/pages/purchase/PurchaseFilterModal
import Dropdown from '@/components/dropdown/Dropdown';
import { OptionType } from '@/components/input/SelectInput';
-import { cn, formatDate } from '@/lib/helper';
+import { cn, formatCurrency, formatDate, formatNumber } from '@/lib/helper';
import { getErrorMessage, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
@@ -41,6 +41,9 @@ type PurchaseTableFilters = {
search: string;
sort_by: string;
order_by: string;
+ start_date: string;
+ end_date: string;
+ filter_by: string;
po_date: string;
approval_status: string;
product_category_id: string;
@@ -177,6 +180,9 @@ const PurchaseTable = () => {
search: '',
sort_by: '',
order_by: '',
+ start_date: '',
+ end_date: '',
+ filter_by: '',
po_date: '',
approval_status: '',
product_category_id: '',
@@ -197,6 +203,9 @@ const PurchaseTable = () => {
pageSize: 'limit',
sort_by: 'sort_by',
order_by: 'sort_order',
+ start_date: 'start_date',
+ end_date: 'end_date',
+ filter_by: 'filter_by',
po_date: 'po_date',
approval_status: 'approval_status',
product_category_id: 'product_category_id',
@@ -297,36 +306,11 @@ const PurchaseTable = () => {
);
},
},
- {
- accessorKey: 'supplier',
- header: 'Vendor',
- cell: (props) => props.row.original.supplier.name,
- },
{
accessorKey: 'requester_name',
header: 'Nama Pengaju',
cell: (props) => props.row.original.requester_name || '-',
},
- {
- accessorKey: 'products',
- header: 'Produk',
- cell: (props) => {
- const products = props.row.original.products;
- if (!products || products.length === 0) return '-';
- return (
-
- {products.map((product, index) => (
- - {product.name}
- ))}
-
- );
- },
- },
- {
- accessorKey: 'location',
- header: 'Lokasi',
- cell: (props) => props.row.original.location?.name || '-',
- },
{
accessorKey: 'po_date',
header: 'Tgl. PO',
@@ -364,6 +348,202 @@ const PurchaseTable = () => {
return `${diffDays} hari`;
},
},
+ {
+ accessorKey: 'supplier',
+ header: 'Vendor',
+ cell: (props) => props.row.original.supplier.name,
+ },
+ {
+ accessorKey: 'location',
+ header: 'Lokasi',
+ cell: (props) => props.row.original.location?.name || '-',
+ },
+ {
+ accessorKey: 'warehouse',
+ header: 'Gudang',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ - {item.warehouse?.name ?? '-'}
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'products',
+ header: 'Produk',
+ cell: (props) => {
+ const products = props.row.original.products;
+ if (!products || products.length === 0) return '-';
+ return (
+
+ {products.map((product, index) => (
+ - {product.name}
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'total_qty',
+ header: 'Kuantitas',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ - {formatNumber(item.total_qty ?? 0)}
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'uom',
+ header: 'Satuan',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ - {item.product?.uom?.name ?? '-'}
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'price',
+ header: 'Harga',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ - {formatCurrency(item.price ?? 0)}
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'total_price',
+ header: 'Total Harga',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ - {formatCurrency(item.total_price ?? 0)}
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'products_total',
+ header: 'Total Harga Produk',
+ cell: (props) => formatCurrency(props.row.original.products_total ?? 0),
+ },
+ {
+ accessorKey: 'expedition_vendor',
+ header: 'Vendor Ekspedisi',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ - {item.expedition_vendor?.name ?? '-'}
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'expedition_qty',
+ header: 'Qty Ekspedisi',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ -
+ {item.expedition_qty != null
+ ? formatNumber(item.expedition_qty)
+ : '-'}
+
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'transport_per_item',
+ header: 'Harga Ekspedisi',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ -
+ {item.transport_per_item != null
+ ? formatCurrency(item.transport_per_item)
+ : '-'}
+
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'item_expedition_total',
+ header: 'Total Ekspedisi',
+ enableSorting: false,
+ cell: (props) => {
+ const items = props.row.original.items;
+ if (!items || items.length === 0) return '-';
+ return (
+
+ {items.map((item, index) => (
+ -
+ {item.expedition_total != null
+ ? formatCurrency(item.expedition_total)
+ : '-'}
+
+ ))}
+
+ );
+ },
+ },
+ {
+ accessorKey: 'expedition_total',
+ header: 'Total Ekspedisi Semua Produk',
+ cell: (props) => formatCurrency(props.row.original.expedition_total ?? 0),
+ },
+ {
+ accessorKey: 'grand_total_all',
+ header: 'Grand Total All',
+ cell: (props) => formatCurrency(props.row.original.grand_total_all ?? 0),
+ },
{
accessorKey: 'status',
header: 'Status Approval',
@@ -410,6 +590,11 @@ const PurchaseTable = () => {
);
},
},
+ {
+ accessorKey: 'notes',
+ header: 'Notes',
+ cell: (props) => props.row.original.notes || '-',
+ },
{
accessorKey: 'created_at',
header: 'Tanggal Dibuat',
@@ -476,6 +661,9 @@ const PurchaseTable = () => {
const filterSubmitHandler = (values: PurchaseFilter) => {
setFilters({
+ start_date: values.start_date || '',
+ end_date: values.end_date || '',
+ filter_by: values.filterBy?.value || '',
po_date: values.poDate,
product_category_id: values.category.join(','),
product_category_name:
@@ -500,6 +688,9 @@ const PurchaseTable = () => {
const filterResetHandler = () => {
setFilters({
+ start_date: '',
+ end_date: '',
+ filter_by: '',
po_date: '',
product_category_id: '',
product_category_name: '',
@@ -518,6 +709,13 @@ const PurchaseTable = () => {
};
const purchaseFilterInitialValues = useMemo(() => {
+ const filterByLabelMap: Record = {
+ po_date: 'Tanggal PO',
+ received_date: 'Tanggal Terima',
+ due_date: 'Tanggal Jatuh Tempo',
+ created_at: 'Tanggal Dibuat',
+ };
+
const categoryIds = tableFilterState.product_category_id
? tableFilterState.product_category_id
.split(',')
@@ -539,6 +737,16 @@ const PurchaseTable = () => {
return {
poDate: tableFilterState.po_date,
+ start_date: tableFilterState.start_date,
+ end_date: tableFilterState.end_date,
+ filterBy: tableFilterState.filter_by
+ ? {
+ value: tableFilterState.filter_by,
+ label:
+ filterByLabelMap[tableFilterState.filter_by] ||
+ tableFilterState.filter_by,
+ }
+ : undefined,
category: categoryIds.map((value, index) => ({
value: Number(value),
label: categoryLabels[index] || value,
@@ -706,7 +914,7 @@ const PurchaseTable = () => {
'project_flock_name',
'project_flock_kandang_name',
]}
- fieldGroups={[['startDate', 'endDate']]}
+ fieldGroups={[['start_date', 'end_date']]}
onClick={filterModal.openModal}
className='px-3 py-2.5'
/>