mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 21:41:57 +00:00
269 lines
7.3 KiB
TypeScript
269 lines
7.3 KiB
TypeScript
'use client';
|
|
|
|
import Card from '@/components/Card';
|
|
|
|
import Table from '@/components/Table';
|
|
import { formatCurrency, formatDate, formatNumber } from '@/lib/helper';
|
|
import {
|
|
RowSapronakCalculation,
|
|
TotalSapronakCalculation,
|
|
} from '@/types/api/closing';
|
|
import { ColumnDef } from '@tanstack/react-table';
|
|
import { useMemo } from 'react';
|
|
import useSWR from 'swr';
|
|
import { ClosingApi } from '@/services/api/closing';
|
|
import { isResponseSuccess } from '@/lib/api-helper';
|
|
import { ClosingGeneralInformation } from '@/types/api/closing';
|
|
import { useSearchParams } from 'next/navigation';
|
|
|
|
interface ClosingSapronakCalculationTableProps {
|
|
projectFlockId: number;
|
|
closingGeneralInformation?: ClosingGeneralInformation;
|
|
}
|
|
|
|
const ClosingSapronakCalculationTable = ({
|
|
projectFlockId,
|
|
closingGeneralInformation,
|
|
}: ClosingSapronakCalculationTableProps) => {
|
|
const searchParams = useSearchParams();
|
|
const kandangId = searchParams.get('kandangId');
|
|
|
|
const { data: sapronakCalculation, isLoading } = useSWR(
|
|
`/closing/sapronak-calculation/${projectFlockId}${kandangId ? `/${kandangId}` : ''}`,
|
|
() => ClosingApi.getPerhitunganSapronak(projectFlockId, Number(kandangId)),
|
|
{
|
|
keepPreviousData: true,
|
|
}
|
|
);
|
|
|
|
// Helper function to create columns with footer support
|
|
const createColumns = (
|
|
total?: TotalSapronakCalculation
|
|
): ColumnDef<RowSapronakCalculation>[] => [
|
|
{
|
|
header: 'Tanggal',
|
|
accessorKey: 'date',
|
|
cell: (props) =>
|
|
props.row.original.date
|
|
? formatDate(props.row.original.date, 'DD MMM YYYY')
|
|
: '-',
|
|
footer: 'Total',
|
|
},
|
|
{
|
|
header: 'No. Referensi',
|
|
accessorKey: 'reference_number',
|
|
cell: (props) => (props.row.original.reference_number as string) || '-',
|
|
footer: '',
|
|
},
|
|
{
|
|
header: 'QTY Masuk',
|
|
accessorKey: 'qty_in',
|
|
cell: (props) =>
|
|
props.row.original.qty_in
|
|
? formatNumber(props.row.original.qty_in as number)
|
|
: '0',
|
|
footer: total
|
|
? () => (
|
|
<div className='font-semibold text-gray-900'>
|
|
{total?.qty_in ? formatNumber(total?.qty_in) : '0'}
|
|
</div>
|
|
)
|
|
: '',
|
|
},
|
|
{
|
|
header: 'QTY Keluar',
|
|
accessorKey: 'qty_out',
|
|
cell: (props) =>
|
|
props.row.original.qty_out
|
|
? formatNumber(props.row.original.qty_out as number)
|
|
: '0',
|
|
footer: total
|
|
? () => (
|
|
<div className='font-semibold text-gray-900'>
|
|
{total?.qty_out ? formatNumber(total?.qty_out) : '0'}
|
|
</div>
|
|
)
|
|
: '',
|
|
},
|
|
{
|
|
header: 'QTY Pakai',
|
|
accessorKey: 'qty_used',
|
|
cell: (props) =>
|
|
props.row.original.qty_used
|
|
? formatNumber(props.row.original.qty_used as number)
|
|
: '0',
|
|
footer: total
|
|
? () => (
|
|
<div className='font-semibold text-gray-900'>
|
|
{total?.qty_used ? formatNumber(total?.qty_used) : '0'}
|
|
</div>
|
|
)
|
|
: '',
|
|
},
|
|
{
|
|
header: 'Uraian',
|
|
accessorKey: 'description',
|
|
cell: (props) => (props.row.original.description as string) || '-',
|
|
footer: '',
|
|
},
|
|
{
|
|
header: 'Kategori Produk',
|
|
accessorKey: 'product_category',
|
|
cell: (props) => (props.row.original.product_category as string) || '-',
|
|
footer: '',
|
|
},
|
|
{
|
|
header: 'Harga Beli/Qty (Rp)',
|
|
accessorKey: 'unit_price',
|
|
cell: (props) =>
|
|
props.row.original.unit_price
|
|
? formatCurrency(props.row.original.unit_price as number)
|
|
: '-',
|
|
footer: total
|
|
? () => (
|
|
<div className='font-semibold text-gray-900'>
|
|
{total?.avg_unit_price
|
|
? formatCurrency(total?.avg_unit_price)
|
|
: '-'}
|
|
</div>
|
|
)
|
|
: '',
|
|
},
|
|
{
|
|
header: 'Total Harga (Rp)',
|
|
accessorKey: 'total_amount',
|
|
cell: (props) =>
|
|
props.row.original.total_amount
|
|
? formatCurrency(props.row.original.total_amount as number)
|
|
: '-',
|
|
footer: total
|
|
? () => (
|
|
<div className='font-semibold text-gray-900'>
|
|
{total?.total_amount ? formatCurrency(total?.total_amount) : '-'}
|
|
</div>
|
|
)
|
|
: '',
|
|
},
|
|
{
|
|
header: 'Keterangan',
|
|
accessorKey: 'notes',
|
|
cell: (props) => (props.row.original.notes as string) || '-',
|
|
footer: '',
|
|
},
|
|
];
|
|
|
|
// Memoize columns untuk setiap kategori
|
|
const docColumns = useMemo(
|
|
() =>
|
|
isResponseSuccess(sapronakCalculation)
|
|
? createColumns(sapronakCalculation.data?.doc?.total)
|
|
: createColumns(),
|
|
[sapronakCalculation]
|
|
);
|
|
|
|
const ovkColumns = useMemo(
|
|
() =>
|
|
isResponseSuccess(sapronakCalculation)
|
|
? createColumns(sapronakCalculation.data?.ovk?.total)
|
|
: createColumns(),
|
|
[sapronakCalculation]
|
|
);
|
|
|
|
const pakanColumns = useMemo(
|
|
() =>
|
|
isResponseSuccess(sapronakCalculation)
|
|
? createColumns(sapronakCalculation.data?.pakan?.total)
|
|
: createColumns(),
|
|
[sapronakCalculation]
|
|
);
|
|
|
|
return (
|
|
<div className='flex flex-col gap-4'>
|
|
{/* Table DOC jika kategori Project Flock Growing */}
|
|
<Card
|
|
title={
|
|
closingGeneralInformation?.project_type == 'GROWING'
|
|
? 'DOC'
|
|
: 'Pullet'
|
|
}
|
|
collapsible
|
|
defaultCollapsed={false}
|
|
className={{
|
|
wrapper: 'w-full',
|
|
body: 'p-4 shadow',
|
|
}}
|
|
>
|
|
<Table<RowSapronakCalculation>
|
|
data={
|
|
isResponseSuccess(sapronakCalculation)
|
|
? (sapronakCalculation.data?.doc?.rows ?? [])
|
|
: []
|
|
}
|
|
columns={docColumns}
|
|
className={{
|
|
containerClassName: 'my-4',
|
|
}}
|
|
renderFooter={
|
|
isResponseSuccess(sapronakCalculation) &&
|
|
sapronakCalculation.data?.doc?.rows.length > 0
|
|
}
|
|
/>
|
|
</Card>
|
|
|
|
<Card
|
|
title='OVK'
|
|
variant='bordered'
|
|
collapsible
|
|
defaultCollapsed={true}
|
|
className={{
|
|
wrapper: 'w-full',
|
|
}}
|
|
>
|
|
<Table<RowSapronakCalculation>
|
|
data={
|
|
isResponseSuccess(sapronakCalculation)
|
|
? (sapronakCalculation.data?.ovk?.rows ?? [])
|
|
: []
|
|
}
|
|
columns={ovkColumns}
|
|
className={{
|
|
containerClassName: 'my-4',
|
|
}}
|
|
renderFooter={
|
|
isResponseSuccess(sapronakCalculation) &&
|
|
sapronakCalculation.data?.ovk?.rows.length > 0
|
|
}
|
|
/>
|
|
</Card>
|
|
|
|
<Card
|
|
title='Pakan'
|
|
variant='bordered'
|
|
collapsible
|
|
defaultCollapsed={true}
|
|
className={{
|
|
wrapper: 'w-full',
|
|
}}
|
|
>
|
|
<Table<RowSapronakCalculation>
|
|
data={
|
|
isResponseSuccess(sapronakCalculation)
|
|
? (sapronakCalculation.data?.pakan?.rows ?? [])
|
|
: []
|
|
}
|
|
columns={pakanColumns}
|
|
className={{
|
|
containerClassName: 'my-4',
|
|
}}
|
|
renderFooter={
|
|
isResponseSuccess(sapronakCalculation) &&
|
|
sapronakCalculation.data?.pakan?.rows.length > 0
|
|
}
|
|
/>
|
|
</Card>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default ClosingSapronakCalculationTable;
|