import Card from '@/components/Card'; import Table, { TABLE_DEFAULT_STYLING } from '@/components/Table'; import { isResponseSuccess } from '@/lib/api-helper'; import { formatCurrency, formatTitleCase } from '@/lib/helper'; import { ClosingApi } from '@/services/api/closing'; import { DataSummarySubTotal, HppPurchaseData, ProfitLossDataAmount, } from '@/types/api/closing'; import useSWR from 'swr'; type HppTableRow = | (HppPurchaseData & { group_name: string; group_index: number; isGroupHeader?: boolean; }) | { group_name: string; group_index: number; isGroupHeader: true; type?: never; budgeting?: never; realization?: never; }; type ProfitLossTableRow = | (DataSummarySubTotal & { type: string; group_name: string; group_index: number; isGroupHeader?: boolean; }) | { group_name: string; group_index: number; isGroupHeader: true; type?: never; rp_per_bird?: never; rp_per_kg?: never; amount?: never; }; const ClosingFinanceTable = ({ projectFlockId, }: { projectFlockId: number; }) => { const { data: finance, isLoading } = useSWR( `/closing/finance/${projectFlockId}`, () => ClosingApi.getFinance(projectFlockId) ); const hppTableData: HppTableRow[] = isResponseSuccess(finance) ? finance.data.hpp_purchases.hpp.flatMap((hpp, groupIndex) => [ // Group header row { group_name: hpp.group_name, group_index: groupIndex, isGroupHeader: true as const, }, // Data rows ...hpp.data.map((item) => ({ group_name: hpp.group_name, group_index: groupIndex, type: item.type, budgeting: item.budgeting, realization: item.realization, isGroupHeader: false as const, })), ]) : []; const profitLossTableData: ProfitLossTableRow[] = isResponseSuccess(finance) ? [ // Pembelian group ...finance.data.profit_loss.data.pembelian.map((item) => ({ label: 'Pembelian', group_name: 'Pembelian', group_index: 1, type: item.type, rp_per_bird: item.rp_per_bird, rp_per_kg: item.rp_per_kg, amount: item.amount, isGroupHeader: false as const, })), { label: finance.data.profit_loss.data.summary.gross_profit.label, group_name: 'Penjualan', group_index: 0, isGroupHeader: true as const, type: finance.data.profit_loss.data.summary.gross_profit.label, rp_per_bird: finance.data.profit_loss.data.summary.gross_profit.rp_per_bird, rp_per_kg: finance.data.profit_loss.data.summary.gross_profit.rp_per_kg, amount: finance.data.profit_loss.data.summary.gross_profit.amount, }, // Penjualan group ...finance.data.profit_loss.data.penjualan.map((item) => ({ label: 'Penjualan', group_name: 'Penjualan', group_index: 0, type: item.type, rp_per_bird: item.rp_per_bird, rp_per_kg: item.rp_per_kg, amount: item.amount, isGroupHeader: false as const, })), { label: finance.data.profit_loss.data.summary.sub_total.label, group_name: 'Pembelian', group_index: 1, isGroupHeader: true as const, type: finance.data.profit_loss.data.summary.sub_total.label, rp_per_bird: finance.data.profit_loss.data.summary.sub_total.rp_per_bird, rp_per_kg: finance.data.profit_loss.data.summary.sub_total.rp_per_kg, amount: finance.data.profit_loss.data.summary.sub_total.amount, }, ] : []; return (
<>
{isResponseSuccess(finance) ? formatTitleCase( finance.data.profit_loss.data.summary.gross_profit .label || '-' ) : 'Laba Rugi Brutto'}
{isResponseSuccess(finance) ? formatCurrency( finance.data.profit_loss.data.summary.gross_profit.amount ) : '-'}
{isResponseSuccess(finance) ? formatTitleCase( finance.data.profit_loss.data.summary.net_profit.label || '-' ) : 'Laba Rugi Netto'}
{isResponseSuccess(finance) ? formatCurrency( finance.data.profit_loss.data.summary.net_profit.amount ) : '-'}
data={hppTableData} columns={[ { header: 'No.', enableSorting: false, accessorFn: (item, index) => { if (item.isGroupHeader) return '-'; const dataRowsBefore = hppTableData .slice(0, index) .filter((row) => !row.isGroupHeader).length; return dataRowsBefore + 1; }, footer: (props) => { return 'HPP'; }, }, { header: 'Type', enableSorting: false, accessorFn: (item) => formatTitleCase(item.type || '-'), }, { header: 'Budgeting', enableSorting: false, columns: [ { header: 'Rp/Ekor', id: 'budgeting_rp_per_bird', enableSorting: false, accessorFn: (item) => formatCurrency(item.budgeting?.rp_per_bird || 0), footer: (props) => { return props.column.id === 'budgeting_rp_per_bird' && isResponseSuccess(finance) ? formatCurrency( finance.data.hpp_purchases.summary_hpp.budgeting .rp_per_bird || 0 ) : '-'; }, }, { header: 'Rp/Kg', id: 'budgeting_rp_per_kg', enableSorting: false, accessorFn: (item) => formatCurrency(item.budgeting?.rp_per_kg || 0), footer: (props) => { return props.column.id === 'budgeting_rp_per_kg' && isResponseSuccess(finance) ? formatCurrency( finance.data.hpp_purchases.summary_hpp.budgeting .rp_per_kg || 0 ) : '-'; }, }, { header: 'Jumlah (Rp)', id: 'budgeting_amount', enableSorting: false, accessorFn: (item) => formatCurrency(item.budgeting?.amount || 0), footer: (props) => { return props.column.id === 'budgeting_amount' && isResponseSuccess(finance) ? formatCurrency( finance.data.hpp_purchases.summary_hpp.budgeting .amount || 0 ) : '-'; }, }, ], }, { header: 'Realization', enableSorting: false, columns: [ { header: 'Rp/Ekor', id: 'realization_rp_per_bird', enableSorting: false, accessorFn: (item) => formatCurrency(item.realization?.rp_per_bird || 0), footer: (props) => { return props.column.id === 'realization_rp_per_bird' && isResponseSuccess(finance) ? formatCurrency( finance.data.hpp_purchases.summary_hpp.realization .rp_per_bird || 0 ) : '-'; }, }, { header: 'Rp/Kg', id: 'realization_rp_per_kg', enableSorting: false, accessorFn: (item) => formatCurrency(item.realization?.rp_per_kg || 0), footer: (props) => { return props.column.id === 'realization_rp_per_kg' && isResponseSuccess(finance) ? formatCurrency( finance.data.hpp_purchases.summary_hpp.realization .rp_per_kg || 0 ) : '-'; }, }, { header: 'Jumlah (Rp)', id: 'realization_amount', enableSorting: false, accessorFn: (item) => formatCurrency(item.realization?.amount || 0), footer: (props) => { return props.column.id === 'realization_amount' && isResponseSuccess(finance) ? formatCurrency( finance.data.hpp_purchases.summary_hpp.realization .amount || 0 ) : '-'; }, }, ], }, ]} renderCustomRow={(row) => { const rowData = row.original; if (rowData.isGroupHeader) { return (
{formatTitleCase(rowData.group_name ?? '-')}
); } return null; }} renderFooter={isResponseSuccess(finance)} />
data={profitLossTableData} columns={[ { header: 'Jenis', enableSorting: false, accessorFn: (item) => item.type, cell: (item) => (
{formatTitleCase(item.row.original.type || '-')}
), footer: (item) => (
{isResponseSuccess(finance) ? formatTitleCase( finance.data.profit_loss.data.summary.net_profit .label || '-' ) : '-'}
), }, { header: 'Rp/Ekor', enableSorting: false, accessorFn: (item) => formatCurrency(item.rp_per_bird || 0), footer: (item) => (
{isResponseSuccess(finance) ? formatCurrency( finance.data.profit_loss.data.summary.net_profit .rp_per_bird || 0 ) : formatCurrency(0)}
), }, { header: 'Rp/Kg', enableSorting: false, accessorFn: (item) => formatCurrency(item.rp_per_kg || 0), footer: (item) => (
{isResponseSuccess(finance) ? formatCurrency( finance.data.profit_loss.data.summary.net_profit .rp_per_kg || 0 ) : formatCurrency(0)}
), }, { header: 'Jumlah (Rp)', enableSorting: false, accessorFn: (item) => formatCurrency(item.amount || 0), footer: (item) => (
{isResponseSuccess(finance) ? formatCurrency( finance.data.profit_loss.data.summary.net_profit .amount || 0 ) : formatCurrency(0)}
), }, ]} renderCustomRow={(row) => { const rowData = row.original; if (rowData.isGroupHeader) { if (rowData.amount) { return (
{formatTitleCase(rowData.label ?? '-')}
{formatCurrency(rowData.rp_per_bird ?? 0)}
{formatCurrency(rowData.rp_per_kg ?? 0)}
{formatCurrency(rowData.amount ?? 0)}
); } return (
{formatTitleCase(rowData.group_name ?? '-')}
); } return null; }} className={{ paginationClassName: 'hidden', }} renderFooter={isResponseSuccess(finance)} />
); }; export default ClosingFinanceTable;