Merge branch 'dev/restu' into 'development'

[FEAT/FE] Refactor Closing (Keuangan) & Takeout Closing (Penjualan)

See merge request mbugroup/lti-web-client!148
This commit is contained in:
Rivaldi A N S
2026-01-09 06:24:06 +00:00
4 changed files with 146 additions and 42 deletions
+7 -6
View File
@@ -19,10 +19,10 @@ const ClosingDetailPage = () => {
(id: number) => ClosingApi.getGeneralInfo(id) (id: number) => ClosingApi.getGeneralInfo(id)
); );
const { data: salesData, isLoading: isLoadingSales } = useSWR( // const { data: salesData, isLoading: isLoadingSales } = useSWR(
closingId ? `sales-${closingId}` : null, // closingId ? `sales-${closingId}` : null,
() => ClosingApi.getPenjualan(Number(closingId)) // () => ClosingApi.getPenjualan(Number(closingId))
); // );
const { data: hppEkspedisiData, isLoading: isLoadingHppEkspedisi } = useSWR( const { data: hppEkspedisiData, isLoading: isLoadingHppEkspedisi } = useSWR(
closingId ? `hpp-ekspedisi-${closingId}` : null, closingId ? `hpp-ekspedisi-${closingId}` : null,
@@ -44,7 +44,8 @@ const ClosingDetailPage = () => {
return; return;
} }
const isLoading = isLoadingClosing || isLoadingSales || isLoadingHppEkspedisi; const isLoading = isLoadingClosing || isLoadingHppEkspedisi;
// const isLoading = isLoadingClosing || isLoadingSales || isLoadingHppEkspedisi;
return ( return (
<div className='w-full p-4 flex flex-row justify-center'> <div className='w-full p-4 flex flex-row justify-center'>
@@ -54,7 +55,7 @@ const ClosingDetailPage = () => {
<ClosingDetail <ClosingDetail
id={Number(closingId)} id={Number(closingId)}
initialValue={closing.data} initialValue={closing.data}
salesData={isResponseSuccess(salesData) ? salesData.data : undefined} // salesData={isResponseSuccess(salesData) ? salesData.data : undefined}
hppExpeditionData={ hppExpeditionData={
isResponseSuccess(hppEkspedisiData) isResponseSuccess(hppEkspedisiData)
? hppEkspedisiData.data ? hppEkspedisiData.data
@@ -52,11 +52,11 @@ const ClosingDetail: React.FC<ClosingDetailProps> = ({
/> />
), ),
}, },
{ // {
id: 'penjualan', // id: 'penjualan',
label: 'Penjualan', // label: 'Penjualan',
content: <SalesReportTable initialValues={salesData} />, // content: <SalesReportTable initialValues={salesData} />,
}, // },
{ {
id: 'overhead', id: 'overhead',
label: 'Overhead', label: 'Overhead',
@@ -23,6 +23,14 @@ type HppTableRow =
type?: never; type?: never;
budgeting?: never; budgeting?: never;
realization?: never; realization?: never;
}
| {
type: string;
group_name: string;
group_index: number;
isGroupHeader: false;
budgeting?: { rp_per_bird: number; rp_per_kg: number; amount: number };
realization?: { rp_per_bird: number; rp_per_kg: number; amount: number };
}; };
type ProfitLossTableRow = type ProfitLossTableRow =
@@ -52,25 +60,117 @@ const ClosingFinanceTable = ({
() => ClosingApi.getFinance(projectFlockId) () => ClosingApi.getFinance(projectFlockId)
); );
const hppTableData: HppTableRow[] = isResponseSuccess(finance) const staticHppRows: Array<{
? finance.data.hpp_purchases.hpp.flatMap((hpp, groupIndex) => [ group_name: string;
// Group header row type: string;
{ group_index: number;
group_name: hpp.group_name, }> = [
group_index: groupIndex, {
isGroupHeader: true as const, group_name: 'HPP dan Pengeluaran',
}, type: 'Pembelian PAKAN',
// Data rows group_index: 0,
...hpp.data.map((item) => ({ },
group_name: hpp.group_name, {
group_index: groupIndex, group_name: 'HPP dan Pengeluaran',
type: item.type, type: 'Pembelian STARTER',
budgeting: item.budgeting, group_index: 0,
realization: item.realization, },
{
group_name: 'HPP dan Pengeluaran',
type: 'Pembelian DOC',
group_index: 0,
},
{
group_name: 'HPP dan Pengeluaran',
type: 'Pembelian PULLET',
group_index: 0,
},
{
group_name: 'HPP dan Pengeluaran',
type: 'Pembelian LAYER',
group_index: 0,
},
{
group_name: 'HPP dan Bahan Baku',
type: 'Pengeluaran Overhead',
group_index: 1,
},
{
group_name: 'HPP dan Bahan Baku',
type: 'Beban Ekspedisi',
group_index: 1,
},
];
const hppTableData: HppTableRow[] = [
{
group_name: 'HPP dan Pengeluaran',
group_index: 0,
isGroupHeader: true as const,
},
...staticHppRows
.filter((row) => row.group_index === 0)
.map((staticRow) => {
const apiData = isResponseSuccess(finance)
? finance.data.hpp_purchases.hpp
.find((g) => g.group_name === staticRow.group_name)
?.data.find((d) => d.type === staticRow.type)
: null;
return {
group_name: staticRow.group_name,
group_index: staticRow.group_index,
type: staticRow.type,
budgeting: apiData?.budgeting || {
rp_per_bird: 0,
rp_per_kg: 0,
amount: 0,
},
realization: apiData?.realization || {
rp_per_bird: 0,
rp_per_kg: 0,
amount: 0,
},
isGroupHeader: false as const, isGroupHeader: false as const,
})), };
]) }),
: []; {
group_name: 'HPP dan Bahan Baku',
group_index: 1,
isGroupHeader: true as const,
},
...staticHppRows
.filter((row) => row.group_index === 1)
.map((staticRow) => {
const apiData = isResponseSuccess(finance)
? finance.data.hpp_purchases.hpp
.find((g) => g.group_name === staticRow.group_name)
?.data.find((d) => d.type === staticRow.type)
: null;
return {
group_name: staticRow.group_name,
group_index: staticRow.group_index,
type: staticRow.type,
budgeting: apiData?.budgeting || {
rp_per_bird: 0,
rp_per_kg: 0,
amount: 0,
},
realization: apiData?.realization || {
rp_per_bird: 0,
rp_per_kg: 0,
amount: 0,
},
isGroupHeader: false as const,
};
}),
{
group_name: 'HPP',
group_index: 2,
isGroupHeader: true as const,
},
];
const profitLossTableData: ProfitLossTableRow[] = isResponseSuccess(finance) const profitLossTableData: ProfitLossTableRow[] = isResponseSuccess(finance)
? [ ? [
@@ -217,8 +317,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'budgeting_rp_per_bird' && return props.column.id === 'budgeting_rp_per_bird' &&
isResponseSuccess(finance) isResponseSuccess(finance)
? formatCurrency( ? formatCurrency(
finance.data.hpp_purchases.summary_hpp.budgeting finance.data.hpp_purchases.summary_hpp?.budgeting
.rp_per_bird || 0 ?.rp_per_bird || 0
) )
: '-'; : '-';
}, },
@@ -233,8 +333,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'budgeting_rp_per_kg' && return props.column.id === 'budgeting_rp_per_kg' &&
isResponseSuccess(finance) isResponseSuccess(finance)
? formatCurrency( ? formatCurrency(
finance.data.hpp_purchases.summary_hpp.budgeting finance.data.hpp_purchases.summary_hpp?.budgeting
.rp_per_kg || 0 ?.rp_per_kg || 0
) )
: '-'; : '-';
}, },
@@ -249,8 +349,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'budgeting_amount' && return props.column.id === 'budgeting_amount' &&
isResponseSuccess(finance) isResponseSuccess(finance)
? formatCurrency( ? formatCurrency(
finance.data.hpp_purchases.summary_hpp.budgeting finance.data.hpp_purchases.summary_hpp?.budgeting
.amount || 0 ?.amount || 0
) )
: '-'; : '-';
}, },
@@ -271,8 +371,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'realization_rp_per_bird' && return props.column.id === 'realization_rp_per_bird' &&
isResponseSuccess(finance) isResponseSuccess(finance)
? formatCurrency( ? formatCurrency(
finance.data.hpp_purchases.summary_hpp.realization finance.data.hpp_purchases.summary_hpp
.rp_per_bird || 0 ?.realization?.rp_per_bird || 0
) )
: '-'; : '-';
}, },
@@ -287,8 +387,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'realization_rp_per_kg' && return props.column.id === 'realization_rp_per_kg' &&
isResponseSuccess(finance) isResponseSuccess(finance)
? formatCurrency( ? formatCurrency(
finance.data.hpp_purchases.summary_hpp.realization finance.data.hpp_purchases.summary_hpp
.rp_per_kg || 0 ?.realization?.rp_per_kg || 0
) )
: '-'; : '-';
}, },
@@ -303,8 +403,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'realization_amount' && return props.column.id === 'realization_amount' &&
isResponseSuccess(finance) isResponseSuccess(finance)
? formatCurrency( ? formatCurrency(
finance.data.hpp_purchases.summary_hpp.realization finance.data.hpp_purchases.summary_hpp
.amount || 0 ?.realization?.amount || 0
) )
: '-'; : '-';
}, },
@@ -236,7 +236,9 @@ const UniformityTable = () => {
setInputValue: setFilterLocationInputValue, setInputValue: setFilterLocationInputValue,
options: filterLocationOptions, options: filterLocationOptions,
isLoadingOptions: isLoadingFilterLocations, isLoadingOptions: isLoadingFilterLocations,
} = useSelect(LocationApi.basePath, 'id', 'name', 'search'); } = useSelect(LocationApi.basePath, 'id', 'name', 'search', {
limit: '100',
});
// ===== FETCH PROJECT FLOCKS DATA FOR FILTER ===== // ===== FETCH PROJECT FLOCKS DATA FOR FILTER =====
const filterProjectFlocksUrl = useMemo(() => { const filterProjectFlocksUrl = useMemo(() => {
@@ -308,6 +310,7 @@ const UniformityTable = () => {
project_flock_id: filterProjectFlock.value.toString(), project_flock_id: filterProjectFlock.value.toString(),
kandang_id: filterKandang.value.toString(), kandang_id: filterKandang.value.toString(),
withpopulation: Boolean(true).toString(), withpopulation: Boolean(true).toString(),
limit: '100',
}); });
return `${ProjectFlockApi.basePath}/kandangs/lookup?${params.toString()}`; return `${ProjectFlockApi.basePath}/kandangs/lookup?${params.toString()}`;
}, [filterProjectFlock, filterKandang]); }, [filterProjectFlock, filterKandang]);