fixing recording filter form

This commit is contained in:
ragilap
2026-03-11 15:35:37 +07:00
parent 811850857d
commit 85f6677c2a
3 changed files with 168 additions and 23 deletions
@@ -79,6 +79,7 @@ import {
GROWING_RECORDING_APPROVAL_LINE, GROWING_RECORDING_APPROVAL_LINE,
LAYING_RECORDING_APPROVAL_LINE, LAYING_RECORDING_APPROVAL_LINE,
} from '@/config/approval-line'; } from '@/config/approval-line';
import { PROJECT_FLOCK_STATUS } from '@/config/constant';
import { useFormikErrorList } from '@/services/hooks/useFormikErrorList'; import { useFormikErrorList } from '@/services/hooks/useFormikErrorList';
import { getRecordingRestriction } from '../recording-utils'; import { getRecordingRestriction } from '../recording-utils';
@@ -360,6 +361,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
loadMore: loadMoreProjectFlocks, loadMore: loadMoreProjectFlocks,
} = useSelect(ProjectFlockApi.basePath, 'id', 'flock_name', 'search', { } = useSelect(ProjectFlockApi.basePath, 'id', 'flock_name', 'search', {
location_id: selectedProjectFlockLocationId, location_id: selectedProjectFlockLocationId,
status: PROJECT_FLOCK_STATUS.AKTIF,
}); });
const projectFlockKandangLookupUrl = useMemo(() => { const projectFlockKandangLookupUrl = useMemo(() => {
@@ -446,6 +448,23 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
? projectFlockKandangDetailData.data ? projectFlockKandangDetailData.data
: undefined; : undefined;
const selectedProjectFlockKandangId = useMemo(() => {
if (type === 'add') {
return projectFlockKandangLookup?.project_flock_kandang_id ?? null;
}
return (
projectFlockKandangDetail?.id ??
initialValues?.project_flock?.project_flock_kandang_id ??
null
);
}, [
type,
projectFlockKandangLookup,
projectFlockKandangDetail,
initialValues,
]);
// ===== TRANSITION RESTRICTION LOGIC ===== // ===== TRANSITION RESTRICTION LOGIC =====
const isTransitionPeriod = useMemo(() => { const isTransitionPeriod = useMemo(() => {
return ( return (
@@ -756,8 +775,36 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
return options; return options;
}, [locationOptions, projectFlockKandangDetail, type]); }, [locationOptions, projectFlockKandangDetail, type]);
const isProjectFlockActive = useCallback((projectFlock: ProjectFlock) => {
const approvalStepName = projectFlock.approval?.step_name
?.trim()
.toLowerCase();
if (approvalStepName) {
return approvalStepName === PROJECT_FLOCK_STATUS.AKTIF.toLowerCase();
}
return (
projectFlock.status?.trim().toLowerCase() ===
PROJECT_FLOCK_STATUS.AKTIF.toLowerCase()
);
}, []);
const activeProjectFlockIDs = useMemo(() => {
if (!isResponseSuccess(projectFlocksRawData)) return new Set<number>();
const data = projectFlocksRawData.data as ProjectFlock[];
return new Set(
data
.filter((projectFlock) => isProjectFlockActive(projectFlock))
.map((projectFlock) => projectFlock.id)
);
}, [projectFlocksRawData, isProjectFlockActive]);
const enhancedProjectFlockOptions = useMemo(() => { const enhancedProjectFlockOptions = useMemo(() => {
const options = [...projectFlockOptions]; const options = projectFlockOptions.filter((option) => {
if (type !== 'add') return true;
return activeProjectFlockIDs.has(Number(option.value));
});
if (projectFlockKandangDetail && (type === 'edit' || type === 'detail')) { if (projectFlockKandangDetail && (type === 'edit' || type === 'detail')) {
const currentProjectFlock = projectFlockKandangDetail.project_flock; const currentProjectFlock = projectFlockKandangDetail.project_flock;
@@ -773,7 +820,12 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
} }
return options; return options;
}, [projectFlockOptions, projectFlockKandangDetail, type]); }, [
projectFlockOptions,
projectFlockKandangDetail,
type,
activeProjectFlockIDs,
]);
const kandangOptions = useMemo(() => { const kandangOptions = useMemo(() => {
let options: OptionType[] = []; let options: OptionType[] = [];
@@ -881,8 +933,41 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
projectFlockKandangDetail, projectFlockKandangDetail,
]); ]);
const isProductWarehouseBelongsToSelectedProjectFlockKandang = useCallback(
(productWarehouse: ProductWarehouse) => {
if (!selectedProjectFlockKandangId) return false;
return (
productWarehouse.project_flock_kandang?.id ===
selectedProjectFlockKandangId
);
},
[selectedProjectFlockKandangId]
);
const scopedStockProductIds = useMemo(() => {
if (!isResponseSuccess(stockProducts) || !selectedProjectFlockKandangId) {
return new Set<number>();
}
const data = stockProducts.data as unknown as ProductWarehouse[];
return new Set(
data
.filter(isProductWarehouseBelongsToSelectedProjectFlockKandang)
.map((product) => product.id)
);
}, [
stockProducts,
selectedProjectFlockKandangId,
isProductWarehouseBelongsToSelectedProjectFlockKandang,
]);
const unifiedStockProducts = useMemo(() => { const unifiedStockProducts = useMemo(() => {
const options = [...stockProductOptions]; const options = selectedProjectFlockKandangId
? stockProductOptions.filter((option) =>
scopedStockProductIds.has(Number(option.value))
)
: [];
if ( if (
initialValues && initialValues &&
@@ -906,19 +991,30 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
} }
return options; return options;
}, [stockProductOptions, initialValues, type]); }, [
stockProductOptions,
initialValues,
type,
selectedProjectFlockKandangId,
scopedStockProductIds,
]);
const depletionProducts = useMemo(() => { const depletionProducts = useMemo(() => {
const options: OptionType[] = []; const options: OptionType[] = [];
if (isResponseSuccess(depletionProductsData) && selectedKandang) { if (
isResponseSuccess(depletionProductsData) &&
selectedProjectFlockKandangId
) {
const data = depletionProductsData.data as unknown as ProductWarehouse[]; const data = depletionProductsData.data as unknown as ProductWarehouse[];
data.forEach((product) => { data
options.push({ .filter(isProductWarehouseBelongsToSelectedProjectFlockKandang)
value: product.id, .forEach((product) => {
label: product.product.name, options.push({
value: product.id,
label: product.product.name,
});
}); });
});
} }
if (initialValues && initialValues.depletions && type !== 'add') { if (initialValues && initialValues.depletions && type !== 'add') {
@@ -941,19 +1037,27 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
} }
return options; return options;
}, [depletionProductsData, initialValues, type, selectedKandang]); }, [
depletionProductsData,
initialValues,
type,
selectedProjectFlockKandangId,
isProductWarehouseBelongsToSelectedProjectFlockKandang,
]);
const eggProducts = useMemo(() => { const eggProducts = useMemo(() => {
const options: OptionType[] = []; const options: OptionType[] = [];
if (isResponseSuccess(eggProductsData) && selectedKandang) { if (isResponseSuccess(eggProductsData) && selectedProjectFlockKandangId) {
const data = eggProductsData.data as unknown as ProductWarehouse[]; const data = eggProductsData.data as unknown as ProductWarehouse[];
data.forEach((product) => { data
options.push({ .filter(isProductWarehouseBelongsToSelectedProjectFlockKandang)
value: product.id, .forEach((product) => {
label: product.product.name, options.push({
value: product.id,
label: product.product.name,
});
}); });
});
} }
if (initialValues && initialValues.eggs && type !== 'add') { if (initialValues && initialValues.eggs && type !== 'add') {
@@ -973,7 +1077,13 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
} }
return options; return options;
}, [eggProductsData, initialValues, type, selectedKandang]); }, [
eggProductsData,
initialValues,
type,
selectedProjectFlockKandangId,
isProductWarehouseBelongsToSelectedProjectFlockKandang,
]);
// ===== FORMIK SETUP ===== // ===== FORMIK SETUP =====
const formikInitialValues = useMemo(() => { const formikInitialValues = useMemo(() => {
@@ -2699,7 +2809,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
color='success' color='success'
onClick={addStock} onClick={addStock}
className='w-fit' className='w-fit'
disabled={!recordingRestriction.canEditStock} disabled={
!formik.values.project_flock_kandang_id ||
!recordingRestriction.canEditStock
}
> >
<Icon icon='ic:round-plus' width={24} height={24} /> <Icon icon='ic:round-plus' width={24} height={24} />
Tambah Stok Tambah Stok
@@ -2841,7 +2954,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
); );
}} }}
options={getAvailableDepletionProductOptions(idx)} options={getAvailableDepletionProductOptions(idx)}
placeholder='Pilih Kondisi' placeholder={
!formik.values.project_flock_kandang_id
? 'Pilih kandang terlebih dahulu'
: 'Pilih Kondisi'
}
isLoading={isLoadingDepletionProducts} isLoading={isLoadingDepletionProducts}
onMenuScrollToBottom={loadMoreDepletionProducts} onMenuScrollToBottom={loadMoreDepletionProducts}
isError={ isError={
@@ -2860,6 +2977,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
} }
isDisabled={ isDisabled={
type === 'detail' || type === 'detail' ||
!formik.values.project_flock_kandang_id ||
!recordingRestriction.canEditDepletion !recordingRestriction.canEditDepletion
} }
className={{ className={{
@@ -2959,7 +3077,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
color='success' color='success'
onClick={addDepletion} onClick={addDepletion}
className='w-fit' className='w-fit'
disabled={!recordingRestriction.canEditDepletion} disabled={
!formik.values.project_flock_kandang_id ||
!recordingRestriction.canEditDepletion
}
> >
<Icon icon='ic:round-plus' width={24} height={24} /> <Icon icon='ic:round-plus' width={24} height={24} />
Tambah Depletion Tambah Depletion
@@ -3085,7 +3206,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
); );
}} }}
options={getAvailableEggProductOptions(idx)} options={getAvailableEggProductOptions(idx)}
placeholder='Pilih Kondisi Telur' placeholder={
!formik.values.project_flock_kandang_id
? 'Pilih kandang terlebih dahulu'
: 'Pilih Kondisi Telur'
}
isLoading={isLoadingEggProducts} isLoading={isLoadingEggProducts}
onMenuScrollToBottom={loadMoreEggProducts} onMenuScrollToBottom={loadMoreEggProducts}
isError={ isError={
@@ -3102,7 +3227,10 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
idx idx
).errorMessage ).errorMessage
} }
isDisabled={type === 'detail'} isDisabled={
type === 'detail' ||
!formik.values.project_flock_kandang_id
}
className={{ className={{
wrapper: 'w-full min-w-48', wrapper: 'w-full min-w-48',
}} }}
@@ -3207,6 +3335,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
color='success' color='success'
onClick={addEgg} onClick={addEgg}
className='w-fit' className='w-fit'
disabled={!formik.values.project_flock_kandang_id}
> >
<Icon icon='ic:round-plus' width={24} height={24} /> <Icon icon='ic:round-plus' width={24} height={24} />
Tambah Telur Tambah Telur
+6
View File
@@ -555,6 +555,12 @@ export const APPROVAL_WORKFLOWS = {
], ],
}; };
export const PROJECT_FLOCK_STATUS = {
PENGAJUAN: APPROVAL_WORKFLOWS.PROJECT_FLOCKS[0].step_name,
AKTIF: APPROVAL_WORKFLOWS.PROJECT_FLOCKS[1].step_name,
SELESAI: APPROVAL_WORKFLOWS.PROJECT_FLOCKS[2].step_name,
} as const;
export const ACCEPTED_FILE_TYPE = { export const ACCEPTED_FILE_TYPE = {
PDF: { PDF: {
'application/pdf': ['.pdf'], 'application/pdf': ['.pdf'],
+10
View File
@@ -11,6 +11,16 @@ export type BaseProductWarehouse = {
quantity: number; quantity: number;
product: Product; product: Product;
warehouse: Warehouse; warehouse: Warehouse;
project_flock_kandang?: {
id: number;
project_flock_id: number;
kandang_id: number;
period: number;
project_flock?: {
id: number;
flock_name: string;
};
};
week?: number | null; week?: number | null;
}; };