mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
fix(FE): fixing closing overhead per kandang
This commit is contained in:
@@ -66,7 +66,13 @@ const ClosingDetail: React.FC<ClosingDetailProps> = ({
|
||||
{
|
||||
id: 'overhead',
|
||||
label: 'Overhead',
|
||||
content: <ClosingOverheadTabContent projectFlockId={id} />,
|
||||
content: (
|
||||
<ClosingOverheadTabContent
|
||||
projectFlockId={id}
|
||||
generalInformation={initialValue}
|
||||
kandangData={kandangData}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'hppEkspedisi',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { formatNumber } from '@/lib/helper';
|
||||
import { ClosingGeneralInformation } from '@/types/api/closing';
|
||||
import { ProjectFlock } from '@/types/api/production/project-flock';
|
||||
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
|
||||
@@ -56,8 +57,8 @@ const ClosingGeneralInformationTable = ({
|
||||
<td>:</td>
|
||||
<td>
|
||||
{!kandangData
|
||||
? (initialValue?.population ?? 0)
|
||||
: (chickinPopulation ?? 0)}{' '}
|
||||
? formatNumber(initialValue?.population || 0)
|
||||
: formatNumber(chickinPopulation || 0)}{' '}
|
||||
Ekor
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
import ClosingOverheadTable from '@/components/pages/closing/ClosingOverheadTable';
|
||||
import { ClosingGeneralInformation } from '@/types/api/closing';
|
||||
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
|
||||
|
||||
interface ClosingOverheadTabContentProps {
|
||||
projectFlockId: number;
|
||||
generalInformation?: ClosingGeneralInformation;
|
||||
kandangData?: ProjectFlockKandang;
|
||||
}
|
||||
|
||||
const ClosingOverheadTabContent = ({
|
||||
projectFlockId,
|
||||
generalInformation,
|
||||
kandangData,
|
||||
}: ClosingOverheadTabContentProps) => {
|
||||
return (
|
||||
<div className='flex flex-col gap-4'>
|
||||
{projectFlockId && (
|
||||
<ClosingOverheadTable projectFlockId={projectFlockId} />
|
||||
<ClosingOverheadTable
|
||||
projectFlockId={projectFlockId}
|
||||
generalInformation={generalInformation}
|
||||
kandangData={kandangData}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,13 @@ import Table, { TABLE_DEFAULT_STYLING } from '@/components/Table';
|
||||
import { isResponseSuccess } from '@/lib/api-helper';
|
||||
import { cn, formatCurrency, formatDate, formatNumber } from '@/lib/helper';
|
||||
import { ClosingApi } from '@/services/api/closing';
|
||||
import { Overhead, OverheadTotal } from '@/types/api/closing';
|
||||
import {
|
||||
ClosingGeneralInformation,
|
||||
Overhead,
|
||||
OverheadTotal,
|
||||
} from '@/types/api/closing';
|
||||
import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang';
|
||||
import { Icon } from '@iconify/react';
|
||||
import { ColumnDef } from '@tanstack/react-table';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import { useMemo } from 'react';
|
||||
@@ -11,16 +17,30 @@ import useSWR from 'swr';
|
||||
|
||||
interface ClosingOverheadTableProps {
|
||||
projectFlockId: number;
|
||||
generalInformation?: ClosingGeneralInformation;
|
||||
kandangData?: ProjectFlockKandang;
|
||||
}
|
||||
|
||||
const ClosingOverheadTable = ({
|
||||
projectFlockId,
|
||||
generalInformation,
|
||||
kandangData,
|
||||
}: ClosingOverheadTableProps) => {
|
||||
const searchParams = useSearchParams();
|
||||
const kandangId = searchParams.get('kandangId');
|
||||
|
||||
const { data: overhead, isLoading: isLoadingOverhead } = useSWR(
|
||||
`${ClosingApi.basePath}/${projectFlockId}${kandangId ? `/${kandangId}` : ''}/overhead`,
|
||||
`${ClosingApi.basePath}/${projectFlockId}/overhead`,
|
||||
() => ClosingApi.getOverhead(projectFlockId),
|
||||
{
|
||||
keepPreviousData: true,
|
||||
}
|
||||
);
|
||||
|
||||
const { data: overheadKandang, isLoading: isLoadingOverheadKandang } = useSWR(
|
||||
kandangId
|
||||
? `${ClosingApi.basePath}/${projectFlockId}/${kandangId}/overhead`
|
||||
: undefined,
|
||||
() =>
|
||||
ClosingApi.getOverhead(
|
||||
projectFlockId,
|
||||
@@ -31,6 +51,26 @@ const ClosingOverheadTable = ({
|
||||
}
|
||||
);
|
||||
|
||||
const chickinPopulation = useMemo(() => {
|
||||
if (kandangData) {
|
||||
return kandangData?.chickins?.reduce(
|
||||
(acc, chickin) => acc + chickin.usage_qty,
|
||||
0
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
}, [kandangData]);
|
||||
|
||||
const kandangTotal = useMemo(() => {
|
||||
if (!isResponseSuccess(overhead)) {
|
||||
return 0;
|
||||
}
|
||||
const total =
|
||||
((chickinPopulation ?? 0) * overhead.data.total.actual_total_amount) /
|
||||
(generalInformation?.population ?? 0);
|
||||
return total;
|
||||
}, [overhead, chickinPopulation, generalInformation]);
|
||||
|
||||
// Helper function to create columns with footer support
|
||||
const createColumns = (
|
||||
total?: OverheadTotal,
|
||||
@@ -44,17 +84,13 @@ const ClosingOverheadTable = ({
|
||||
{
|
||||
id: 'budget_quantity',
|
||||
header: 'Jumlah',
|
||||
accessorFn: (props) =>
|
||||
props.budget_quantity ? formatNumber(props.budget_quantity) : '-',
|
||||
accessorFn: (props) => formatNumber(props.budget_quantity),
|
||||
footer: total ? () => formatNumber(total.budget_quantity) : '',
|
||||
},
|
||||
{
|
||||
id: 'budget_unit_price',
|
||||
header: 'Harga Satuan',
|
||||
accessorFn: (props) =>
|
||||
props.budget_unit_price
|
||||
? formatCurrency(props.budget_unit_price)
|
||||
: '-',
|
||||
accessorFn: (props) => formatCurrency(props.budget_unit_price),
|
||||
footer: '',
|
||||
},
|
||||
{
|
||||
@@ -78,34 +114,25 @@ const ClosingOverheadTable = ({
|
||||
id: 'actual_date',
|
||||
header: 'Tanggal',
|
||||
accessorFn: (props) =>
|
||||
props.actual_date
|
||||
? formatDate(props.actual_date, 'DD MMM, YYYY')
|
||||
: '-',
|
||||
formatDate(props.actual_date, 'DD MMM, YYYY'),
|
||||
footer: '',
|
||||
},
|
||||
{
|
||||
id: 'actual_quantity',
|
||||
header: 'Jumlah',
|
||||
accessorFn: (props) =>
|
||||
props.actual_quantity ? formatNumber(props.actual_quantity) : '-',
|
||||
accessorFn: (props) => formatNumber(props.actual_quantity),
|
||||
footer: total ? () => formatNumber(total.actual_quantity) : '',
|
||||
},
|
||||
{
|
||||
id: 'actual_unit_price',
|
||||
header: 'Harga Satuan',
|
||||
accessorFn: (props) =>
|
||||
props.actual_unit_price
|
||||
? formatCurrency(props.actual_unit_price)
|
||||
: '-',
|
||||
accessorFn: (props) => formatCurrency(props.actual_unit_price),
|
||||
footer: '',
|
||||
},
|
||||
{
|
||||
id: 'actual_total_amount',
|
||||
header: 'Total',
|
||||
accessorFn: (props) =>
|
||||
props.actual_total_amount
|
||||
? formatCurrency(props.actual_total_amount)
|
||||
: '-',
|
||||
accessorFn: (props) => formatCurrency(props.actual_total_amount),
|
||||
footer: total
|
||||
? () => formatCurrency(total.actual_total_amount)
|
||||
: '',
|
||||
@@ -118,35 +145,25 @@ const ClosingOverheadTable = ({
|
||||
{
|
||||
id: 'actual_date',
|
||||
header: 'Tanggal',
|
||||
accessorFn: (props) =>
|
||||
props.actual_date
|
||||
? formatDate(props.actual_date, 'DD MMM, YYYY')
|
||||
: '-',
|
||||
accessorFn: (props) => formatDate(props.actual_date, 'DD MMM, YYYY'),
|
||||
footer: '',
|
||||
},
|
||||
{
|
||||
id: 'actual_quantity',
|
||||
header: 'Jumlah',
|
||||
accessorFn: (props) =>
|
||||
props.actual_quantity ? formatNumber(props.actual_quantity) : '-',
|
||||
accessorFn: (props) => formatNumber(props.actual_quantity),
|
||||
footer: total ? () => formatNumber(total.actual_quantity) : '',
|
||||
},
|
||||
{
|
||||
id: 'actual_unit_price',
|
||||
header: 'Harga Satuan',
|
||||
accessorFn: (props) =>
|
||||
props.actual_unit_price
|
||||
? formatCurrency(props.actual_unit_price)
|
||||
: '-',
|
||||
accessorFn: (props) => formatCurrency(props.actual_unit_price),
|
||||
footer: '',
|
||||
},
|
||||
{
|
||||
id: 'actual_total_amount',
|
||||
header: 'Total',
|
||||
accessorFn: (props) =>
|
||||
props.actual_total_amount
|
||||
? formatCurrency(props.actual_total_amount)
|
||||
: '-',
|
||||
accessorFn: (props) => formatCurrency(props.actual_total_amount),
|
||||
footer: total ? () => formatCurrency(total.actual_total_amount) : '',
|
||||
},
|
||||
];
|
||||
@@ -171,8 +188,7 @@ const ClosingOverheadTable = ({
|
||||
{
|
||||
id: 'cost_per_bird',
|
||||
header: 'Rp/Ekor',
|
||||
accessorFn: (props) =>
|
||||
props.cost_per_bird ? formatCurrency(props.cost_per_bird) : '-',
|
||||
accessorFn: (props) => formatCurrency(props.cost_per_bird),
|
||||
footer: total ? () => formatCurrency(total.cost_per_bird) : '',
|
||||
},
|
||||
];
|
||||
@@ -183,11 +199,15 @@ const ClosingOverheadTable = ({
|
||||
() =>
|
||||
isResponseSuccess(overhead)
|
||||
? createColumns(
|
||||
overhead.data?.total,
|
||||
kandangId
|
||||
? isResponseSuccess(overheadKandang)
|
||||
? overheadKandang.data?.total
|
||||
: undefined
|
||||
: overhead.data?.total,
|
||||
kandangId ? Number(kandangId) : undefined
|
||||
)
|
||||
: createColumns(),
|
||||
[overhead]
|
||||
[overhead, kandangId, overheadKandang]
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -203,7 +223,13 @@ const ClosingOverheadTable = ({
|
||||
>
|
||||
<Table<Overhead>
|
||||
data={
|
||||
isResponseSuccess(overhead) ? (overhead.data?.overheads ?? []) : []
|
||||
kandangId
|
||||
? isResponseSuccess(overheadKandang)
|
||||
? (overheadKandang.data?.overheads ?? [])
|
||||
: []
|
||||
: isResponseSuccess(overhead)
|
||||
? (overhead.data?.overheads ?? [])
|
||||
: []
|
||||
}
|
||||
columns={columns}
|
||||
className={{
|
||||
@@ -220,6 +246,60 @@ const ClosingOverheadTable = ({
|
||||
: false
|
||||
}
|
||||
/>
|
||||
{kandangId && (
|
||||
<Card
|
||||
className={{
|
||||
wrapper: 'w-full',
|
||||
body: 'p-4 shadow-button-soft border border-base-content/10 rounded-lg',
|
||||
}}
|
||||
>
|
||||
<div className='flex flex-row gap-4 w-full justify-center items-stretch'>
|
||||
<div className='flex flex-row items-center justify-between'>
|
||||
<h2 className='text-base font-bold'>Pembelian Kandang </h2>
|
||||
</div>
|
||||
<div className='flex flex-col items-center justify-center'>
|
||||
<Icon icon='heroicons:equals' className='inline' />
|
||||
</div>
|
||||
<div className='flex flex-col flex-1'>
|
||||
<div className='flex flex-row items-center justify-center font-medium'>
|
||||
Populasi Akhir KANDANG{' '}
|
||||
<Icon icon='heroicons:x-mark' className='inline' /> Pemakaian
|
||||
Di FARM
|
||||
</div>
|
||||
<hr className='w-full h-1' />
|
||||
<div className='flex flex-row items-center justify-center font-medium'>
|
||||
Populasi Akhir Proyek
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col items-center justify-center'>
|
||||
<Icon icon='heroicons:equals' className='inline' />
|
||||
</div>
|
||||
<div className='flex flex-col flex-1'>
|
||||
<div className='flex flex-row items-center justify-center font-medium'>
|
||||
{formatNumber(chickinPopulation ?? 0)}
|
||||
<Icon icon='heroicons:x-mark' className='inline' />
|
||||
{formatCurrency(
|
||||
isResponseSuccess(overhead)
|
||||
? overhead.data?.total.actual_total_amount
|
||||
: 0
|
||||
)}
|
||||
</div>
|
||||
<hr className='w-full h-1' />
|
||||
<div className='flex flex-row items-center justify-center font-medium'>
|
||||
{formatNumber(generalInformation?.population ?? 0)}
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-col items-center justify-center'>
|
||||
<Icon icon='heroicons:equals' className='inline' />
|
||||
</div>
|
||||
<div className='flex flex-row items-center justify-between'>
|
||||
<h2 className='text-base font-bold'>
|
||||
{formatNumber(kandangTotal || 0)}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
</Card>
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user