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)
);
const { data: salesData, isLoading: isLoadingSales } = useSWR(
closingId ? `sales-${closingId}` : null,
() => ClosingApi.getPenjualan(Number(closingId))
);
// const { data: salesData, isLoading: isLoadingSales } = useSWR(
// closingId ? `sales-${closingId}` : null,
// () => ClosingApi.getPenjualan(Number(closingId))
// );
const { data: hppEkspedisiData, isLoading: isLoadingHppEkspedisi } = useSWR(
closingId ? `hpp-ekspedisi-${closingId}` : null,
@@ -44,7 +44,8 @@ const ClosingDetailPage = () => {
return;
}
const isLoading = isLoadingClosing || isLoadingSales || isLoadingHppEkspedisi;
const isLoading = isLoadingClosing || isLoadingHppEkspedisi;
// const isLoading = isLoadingClosing || isLoadingSales || isLoadingHppEkspedisi;
return (
<div className='w-full p-4 flex flex-row justify-center'>
@@ -54,7 +55,7 @@ const ClosingDetailPage = () => {
<ClosingDetail
id={Number(closingId)}
initialValue={closing.data}
salesData={isResponseSuccess(salesData) ? salesData.data : undefined}
// salesData={isResponseSuccess(salesData) ? salesData.data : undefined}
hppExpeditionData={
isResponseSuccess(hppEkspedisiData)
? hppEkspedisiData.data
@@ -52,11 +52,11 @@ const ClosingDetail: React.FC<ClosingDetailProps> = ({
/>
),
},
{
id: 'penjualan',
label: 'Penjualan',
content: <SalesReportTable initialValues={salesData} />,
},
// {
// id: 'penjualan',
// label: 'Penjualan',
// content: <SalesReportTable initialValues={salesData} />,
// },
{
id: 'overhead',
label: 'Overhead',
@@ -23,6 +23,14 @@ type HppTableRow =
type?: never;
budgeting?: 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 =
@@ -52,25 +60,117 @@ const ClosingFinanceTable = ({
() => 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,
const staticHppRows: Array<{
group_name: string;
type: string;
group_index: number;
}> = [
{
group_name: 'HPP dan Pengeluaran',
type: 'Pembelian PAKAN',
group_index: 0,
},
{
group_name: 'HPP dan Pengeluaran',
type: 'Pembelian STARTER',
group_index: 0,
},
{
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,
})),
])
: [];
};
}),
{
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)
? [
@@ -217,8 +317,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'budgeting_rp_per_bird' &&
isResponseSuccess(finance)
? formatCurrency(
finance.data.hpp_purchases.summary_hpp.budgeting
.rp_per_bird || 0
finance.data.hpp_purchases.summary_hpp?.budgeting
?.rp_per_bird || 0
)
: '-';
},
@@ -233,8 +333,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'budgeting_rp_per_kg' &&
isResponseSuccess(finance)
? formatCurrency(
finance.data.hpp_purchases.summary_hpp.budgeting
.rp_per_kg || 0
finance.data.hpp_purchases.summary_hpp?.budgeting
?.rp_per_kg || 0
)
: '-';
},
@@ -249,8 +349,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'budgeting_amount' &&
isResponseSuccess(finance)
? formatCurrency(
finance.data.hpp_purchases.summary_hpp.budgeting
.amount || 0
finance.data.hpp_purchases.summary_hpp?.budgeting
?.amount || 0
)
: '-';
},
@@ -271,8 +371,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'realization_rp_per_bird' &&
isResponseSuccess(finance)
? formatCurrency(
finance.data.hpp_purchases.summary_hpp.realization
.rp_per_bird || 0
finance.data.hpp_purchases.summary_hpp
?.realization?.rp_per_bird || 0
)
: '-';
},
@@ -287,8 +387,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'realization_rp_per_kg' &&
isResponseSuccess(finance)
? formatCurrency(
finance.data.hpp_purchases.summary_hpp.realization
.rp_per_kg || 0
finance.data.hpp_purchases.summary_hpp
?.realization?.rp_per_kg || 0
)
: '-';
},
@@ -303,8 +403,8 @@ const ClosingFinanceTable = ({
return props.column.id === 'realization_amount' &&
isResponseSuccess(finance)
? formatCurrency(
finance.data.hpp_purchases.summary_hpp.realization
.amount || 0
finance.data.hpp_purchases.summary_hpp
?.realization?.amount || 0
)
: '-';
},
@@ -236,7 +236,9 @@ const UniformityTable = () => {
setInputValue: setFilterLocationInputValue,
options: filterLocationOptions,
isLoadingOptions: isLoadingFilterLocations,
} = useSelect(LocationApi.basePath, 'id', 'name', 'search');
} = useSelect(LocationApi.basePath, 'id', 'name', 'search', {
limit: '100',
});
// ===== FETCH PROJECT FLOCKS DATA FOR FILTER =====
const filterProjectFlocksUrl = useMemo(() => {
@@ -308,6 +310,7 @@ const UniformityTable = () => {
project_flock_id: filterProjectFlock.value.toString(),
kandang_id: filterKandang.value.toString(),
withpopulation: Boolean(true).toString(),
limit: '100',
});
return `${ProjectFlockApi.basePath}/kandangs/lookup?${params.toString()}`;
}, [filterProjectFlock, filterKandang]);