Compare commits

...

4 Commits

Author SHA1 Message Date
rstubryan 3b9bd3c5bd Revert "refactor(FE): Prevent adding recordings for kandangs in transition"
This reverts commit 9dc30c1f58.
2026-03-09 03:50:33 +07:00
rstubryan 9dc30c1f58 refactor(FE): Prevent adding recordings for kandangs in transition 2026-03-09 03:35:03 +07:00
rstubryan 671fd72141 refactor(FE): Make stock fields optional during transition to laying 2026-03-09 03:32:44 +07:00
rstubryan d236138aa7 refactor(FE): Update recording editability logic and extend
BaseRecording type
2026-03-09 03:18:41 +07:00
4 changed files with 72 additions and 38 deletions
@@ -105,12 +105,12 @@ const RowOptionsMenu = ({
};
const isRecordingEditable = (recording: Recording) => {
if (
recording.executed_at &&
recording.project_flock?.project_flock_category === 'GROWING'
) {
if (recording.project_flock?.project_flock_category === 'GROWING') {
if (recording.transfer_executed) {
return false;
}
return recording.population_can_change === true;
}
return true;
};
@@ -29,8 +29,8 @@ type RecordingGrowingFormSchemaType = {
} | null;
project_flock_kandang_id: number;
stocks: {
product_warehouse_id: number;
qty: number | string;
product_warehouse_id?: number;
qty?: number | string;
}[];
depletions: {
product_warehouse_id?: number;
@@ -73,6 +73,18 @@ const StockObjectSchema: Yup.ObjectSchema<StockSchema> = Yup.object({
.typeError('Jumlah penggunaan harus berupa angka!'),
});
const OptionalStockObjectSchema: Yup.ObjectSchema<{
product_warehouse_id?: number;
qty?: number | string;
}> = Yup.object({
product_warehouse_id: Yup.number()
.optional()
.typeError('Produk harus berupa angka!'),
qty: Yup.number()
.optional()
.typeError('Jumlah penggunaan harus berupa angka!'),
});
const DepletionObjectSchema: Yup.ObjectSchema<DepletionSchema> = Yup.object({
product_warehouse_id: Yup.number()
.optional()
@@ -90,7 +102,9 @@ const EggObjectSchema: Yup.ObjectSchema<EggSchema> = Yup.object({
weight: Yup.number().optional().typeError('Berat telur harus berupa angka!'),
});
export const RecordingGrowingFormSchema: Yup.ObjectSchema<RecordingGrowingFormSchemaType> =
export const RecordingGrowingFormSchema = (
isTransitioningToLaying = false
): Yup.ObjectSchema<RecordingGrowingFormSchemaType> =>
Yup.object({
record_date: Yup.string()
.required('Tanggal recording wajib diisi!')
@@ -150,7 +164,9 @@ export const RecordingGrowingFormSchema: Yup.ObjectSchema<RecordingGrowingFormSc
return true;
}
),
stocks: Yup.array()
stocks: isTransitioningToLaying
? Yup.array().of(OptionalStockObjectSchema).default([])
: Yup.array()
.of(StockObjectSchema)
.min(1, 'Minimal harus ada 1 data stok!')
.required('Data stok wajib diisi!'),
@@ -158,12 +174,14 @@ export const RecordingGrowingFormSchema: Yup.ObjectSchema<RecordingGrowingFormSc
});
export const RecordingLayingFormSchema: Yup.ObjectSchema<RecordingLayingFormSchemaType> =
RecordingGrowingFormSchema.shape({
RecordingGrowingFormSchema().shape({
eggs: Yup.array().of(EggObjectSchema).default([]),
});
export const UpdateRecordingGrowingFormSchema =
RecordingGrowingFormSchema.shape({
export const UpdateRecordingGrowingFormSchema = (
isTransitioningToLaying = false
) =>
RecordingGrowingFormSchema(isTransitioningToLaying).shape({
location_id: Yup.number().nullable().optional(),
project_flock_id: Yup.number().nullable().optional(),
kandang_id: Yup.number().nullable().optional(),
@@ -193,10 +211,13 @@ export const UpdateRecordingLayingFormSchema = RecordingLayingFormSchema.shape({
.required('Project Flock Kandang wajib diisi!'),
});
export type RecordingGrowingFormValues = Yup.InferType<
type RecordingGrowingFormSchemaFn = ReturnType<
typeof RecordingGrowingFormSchema
>;
export type RecordingGrowingFormValues =
Yup.InferType<RecordingGrowingFormSchemaFn>;
export type RecordingLayingFormValues = Yup.InferType<
typeof RecordingLayingFormSchema
>;
@@ -273,12 +273,12 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
}, []);
const isRecordingEditable = useCallback((recording?: Recording) => {
if (
recording?.executed_at &&
recording?.project_flock?.project_flock_category === 'GROWING'
) {
if (recording?.project_flock?.project_flock_category === 'GROWING') {
if (recording?.transfer_executed) {
return false;
}
return recording?.population_can_change === true;
}
return true;
}, []);
@@ -591,6 +591,14 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
projectFlockKandangLookup?.project_flock?.category === 'GROWING' ||
projectFlockKandangDetail?.project_flock?.category === 'GROWING';
const isTransitioningToLaying = useMemo(() => {
if (!isGrowingCategory) return false;
return (
initialValues?.population_can_change === true ||
initialValues?.transfer_executed === true
);
}, [initialValues, isGrowingCategory]);
const recordingApprovalLines = useMemo(() => {
if (isLayingCategory) {
return LAYING_RECORDING_APPROVAL_LINE;
@@ -951,8 +959,8 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
} else {
schema =
type === 'edit'
? UpdateRecordingGrowingFormSchema
: RecordingGrowingFormSchema;
? UpdateRecordingGrowingFormSchema(isTransitioningToLaying)
: RecordingGrowingFormSchema(isTransitioningToLaying);
}
return schema.clone().concat(
Yup.object().shape({
@@ -2333,21 +2341,25 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
)}
<th>
Persediaan
{!isTransitioningToLaying && (
<span
className='tooltip tooltip-error tooltip-bottom '
data-tip='required'
>
<span className='text-error'>*</span>
</span>
)}
</th>
<th>
Jumlah Pakai
{!isTransitioningToLaying && (
<span
className='tooltip tooltip-error tooltip-bottom '
data-tip='required'
>
<span className='text-error'>*</span>
</span>
)}
</th>
{(type as 'add' | 'edit' | 'detail') !== 'detail' && (
<th>Action</th>
@@ -2382,7 +2394,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
)}
<td>
<SelectInput
required
required={!isTransitioningToLaying}
key={`stock-product-${idx}-${stock.product_warehouse_id}`}
value={
unifiedStockProducts.find(
@@ -2440,7 +2452,7 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => {
<td>
<div className='flex flex-col gap-1'>
<NumberInput
required
required={!isTransitioningToLaying}
name={`stocks.${idx}.qty`}
value={stock.qty ?? ''}
onChange={handleStockUsageQtyChangeWrapper(idx)}
+2 -1
View File
@@ -49,7 +49,8 @@ export type BaseRecording = {
project_flock: ProjectFlock;
record_datetime: string;
day: number;
executed_at: string;
population_can_change: boolean;
transfer_executed: boolean;
} & ProductionMetrics;
export type RecordingDepletion = {