mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 15:55:48 +00:00
chore(FE-188,193): adjust ExpenseRequestKandangDetailExpense component
This commit is contained in:
@@ -41,28 +41,28 @@ const ExpenseRequestKandangDetailExpense: React.FC<
|
|||||||
val: OptionType | OptionType[] | null
|
val: OptionType | OptionType[] | null
|
||||||
) => {
|
) => {
|
||||||
formik.setFieldTouched(
|
formik.setFieldTouched(
|
||||||
`kandangExpenses[${kandangExpenseIdx}].expenses[${expenseIdx}].nonstock`,
|
`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
`kandangExpenses[${kandangExpenseIdx}].expenses[${expenseIdx}].nonstock`,
|
`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`,
|
||||||
val
|
val
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addExpenseItemHandler = (kandangExpenseIdx: number) => {
|
const addExpenseItemHandler = (kandangExpenseIdx: number) => {
|
||||||
const newExpensesValue = [
|
const newExpensesValue = [
|
||||||
...formik.values.kandangExpenses[kandangExpenseIdx].expenses,
|
...formik.values.cost_per_kandangs[kandangExpenseIdx].cost_items,
|
||||||
{
|
{
|
||||||
nonstock: undefined,
|
nonstock: undefined,
|
||||||
totalExpense: undefined,
|
total_cost: undefined,
|
||||||
totalQuantity: undefined,
|
quantity: undefined,
|
||||||
notes: '',
|
notes: '',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
formik.setFieldValue(
|
formik.setFieldValue(
|
||||||
`kandangExpenses[${kandangExpenseIdx}].expenses`,
|
`cost_per_kandangs[${kandangExpenseIdx}].cost_items`,
|
||||||
newExpensesValue
|
newExpensesValue
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -71,27 +71,28 @@ const ExpenseRequestKandangDetailExpense: React.FC<
|
|||||||
kandangExpenseIdx: number,
|
kandangExpenseIdx: number,
|
||||||
expenseIdx: number
|
expenseIdx: number
|
||||||
) => {
|
) => {
|
||||||
const path = `kandangExpenses[${kandangExpenseIdx}].expenses`;
|
const path = `cost_per_kandangs[${kandangExpenseIdx}].cost_items`;
|
||||||
|
|
||||||
// trims values, errors, and touched at expenseIdx
|
// trims values, errors, and touched at expenseIdx
|
||||||
removeArrayItemAndSync(formik, path, expenseIdx);
|
removeArrayItemAndSync(formik, path, expenseIdx);
|
||||||
};
|
};
|
||||||
|
|
||||||
const isExpenseRepeaterInputError = (
|
const isExpenseRepeaterInputError = (
|
||||||
column: 'nonstock' | 'totalQuantity' | 'totalExpense' | 'notes',
|
column: 'nonstock' | 'quantity' | 'total_cost' | 'notes',
|
||||||
kandangExpenseIdx: number,
|
kandangExpenseIdx: number,
|
||||||
expenseIdx: number
|
expenseIdx: number
|
||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
formik.touched.kandangExpenses?.[kandangExpenseIdx]?.expenses?.[
|
formik.touched.cost_per_kandangs?.[kandangExpenseIdx]?.cost_items?.[
|
||||||
expenseIdx
|
expenseIdx
|
||||||
]?.[column] &&
|
]?.[column] &&
|
||||||
Boolean(
|
Boolean(
|
||||||
formik.errors.kandangExpenses?.[kandangExpenseIdx] instanceof Object &&
|
formik.errors.cost_per_kandangs?.[kandangExpenseIdx] instanceof
|
||||||
formik.errors.kandangExpenses?.[kandangExpenseIdx].expenses?.[
|
Object &&
|
||||||
|
formik.errors.cost_per_kandangs?.[kandangExpenseIdx].cost_items?.[
|
||||||
expenseIdx
|
expenseIdx
|
||||||
] instanceof Object &&
|
] instanceof Object &&
|
||||||
formik.errors.kandangExpenses?.[kandangExpenseIdx].expenses?.[
|
formik.errors.cost_per_kandangs?.[kandangExpenseIdx].cost_items?.[
|
||||||
expenseIdx
|
expenseIdx
|
||||||
]?.[column]
|
]?.[column]
|
||||||
)
|
)
|
||||||
@@ -112,7 +113,8 @@ const ExpenseRequestKandangDetailExpense: React.FC<
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='w-full flex flex-col gap-6'>
|
<div className='w-full flex flex-col gap-6'>
|
||||||
{formik.values.kandangExpenses.length === 0 && (
|
{(formik.values.cost_per_kandangs.length === 0 ||
|
||||||
|
!formik.values.supplier?.value) && (
|
||||||
<div>
|
<div>
|
||||||
<p className='text-sm text-gray-400 text-center'>
|
<p className='text-sm text-gray-400 text-center'>
|
||||||
Pilih kandang terlebih dahulu!
|
Pilih kandang terlebih dahulu!
|
||||||
@@ -120,168 +122,171 @@ const ExpenseRequestKandangDetailExpense: React.FC<
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{formik.values.kandangExpenses.map(
|
{formik.values.cost_per_kandangs.length > 0 &&
|
||||||
(kandangExpense, kandangExpenseIdx) => {
|
formik.values.supplier?.value &&
|
||||||
const kandangName = formik.values.kandangs?.find(
|
formik.values.cost_per_kandangs.map(
|
||||||
(kandang) => kandang.id === kandangExpense.kandangId
|
(kandangExpense, kandangExpenseIdx) => {
|
||||||
);
|
const kandangName = formik.values.kandangs?.find(
|
||||||
|
(kandang) => kandang.id === kandangExpense.kandang_id
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
kandangName?.name && (
|
kandangName?.name && (
|
||||||
<div
|
<div
|
||||||
key={`kandangExpense-${kandangExpenseIdx}`}
|
key={`kandangExpense-${kandangExpenseIdx}`}
|
||||||
className='w-full flex flex-col gap-4'
|
className='w-full flex flex-col gap-4'
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<h5 className='mb-2 text-lg font-bold text-center'>
|
<h5 className='mb-2 text-lg font-bold text-center'>
|
||||||
Biaya {kandangName?.name}
|
Biaya {kandangName?.name}
|
||||||
</h5>
|
</h5>
|
||||||
|
|
||||||
<div className='overflow-x-auto'>
|
<div className='overflow-x-auto'>
|
||||||
<table className='table'>
|
<table className='table'>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Nonstock</th>
|
<th>Nonstock</th>
|
||||||
<th>Total Kuantitas</th>
|
<th>Total Kuantitas</th>
|
||||||
<th>Total Biaya</th>
|
<th>Total Biaya</th>
|
||||||
<th>Catatan</th>
|
<th>Catatan</th>
|
||||||
{type !== 'detail' && <th>Aksi</th>}
|
{type !== 'detail' && <th>Aksi</th>}
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{kandangExpense.expenses.map(
|
{kandangExpense.cost_items.map(
|
||||||
(expenseItem, expenseIdx) => (
|
(expenseItem, expenseIdx) => (
|
||||||
<tr key={`expense-${expenseIdx}`}>
|
<tr key={`expense-${expenseIdx}`}>
|
||||||
<td className='p-2'>
|
<td className='p-2'>
|
||||||
<SelectInput
|
<SelectInput
|
||||||
placeholder='Pilih Nonstock'
|
placeholder='Pilih Nonstock'
|
||||||
value={expenseItem.nonstock}
|
value={expenseItem.nonstock}
|
||||||
onChange={(val) => {
|
onChange={(val) => {
|
||||||
nonstockChangeHandler(
|
nonstockChangeHandler(
|
||||||
kandangExpenseIdx,
|
|
||||||
expenseIdx,
|
|
||||||
val
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
options={nonstockOptions}
|
|
||||||
isLoading={isLoadingNonstockOptions}
|
|
||||||
onInputChange={setNonstockInputValue}
|
|
||||||
className={{ wrapper: 'min-w-48' }}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td className='p-2'>
|
|
||||||
<NumberInput
|
|
||||||
required
|
|
||||||
name={`kandangExpenses[${kandangExpenseIdx}].expenses[${expenseIdx}].totalQuantity`}
|
|
||||||
placeholder='Masukkan Total Kuantitas'
|
|
||||||
value={
|
|
||||||
formik.values.kandangExpenses[
|
|
||||||
kandangExpenseIdx
|
|
||||||
].expenses[expenseIdx].totalQuantity ?? ''
|
|
||||||
}
|
|
||||||
onChange={formik.handleChange}
|
|
||||||
onBlur={formik.handleBlur}
|
|
||||||
isError={isExpenseRepeaterInputError(
|
|
||||||
'totalQuantity',
|
|
||||||
kandangExpenseIdx,
|
|
||||||
expenseIdx
|
|
||||||
)}
|
|
||||||
className={{ wrapper: 'min-w-24' }}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td className='p-2'>
|
|
||||||
<NumberInput
|
|
||||||
name={`kandangExpenses[${kandangExpenseIdx}].expenses[${expenseIdx}].totalExpense`}
|
|
||||||
placeholder='Masukkan Total Biaya'
|
|
||||||
value={
|
|
||||||
formik.values.kandangExpenses[
|
|
||||||
kandangExpenseIdx
|
|
||||||
].expenses[expenseIdx].totalExpense ?? ''
|
|
||||||
}
|
|
||||||
onChange={formik.handleChange}
|
|
||||||
onBlur={formik.handleBlur}
|
|
||||||
isError={isExpenseRepeaterInputError(
|
|
||||||
'totalExpense',
|
|
||||||
kandangExpenseIdx,
|
|
||||||
expenseIdx
|
|
||||||
)}
|
|
||||||
inputPrefix={
|
|
||||||
<span className='text-gray-600 font-medium'>
|
|
||||||
Rp
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
className={{ wrapper: 'min-w-24' }}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
<td className='p-2'>
|
|
||||||
<TextInput
|
|
||||||
name={`kandangExpenses[${kandangExpenseIdx}].expenses[${expenseIdx}].notes`}
|
|
||||||
placeholder='Tuliskan catatan'
|
|
||||||
value={
|
|
||||||
formik.values.kandangExpenses[
|
|
||||||
kandangExpenseIdx
|
|
||||||
].expenses[expenseIdx].notes ?? ''
|
|
||||||
}
|
|
||||||
onChange={formik.handleChange}
|
|
||||||
onBlur={formik.handleBlur}
|
|
||||||
isError={isExpenseRepeaterInputError(
|
|
||||||
'notes',
|
|
||||||
kandangExpenseIdx,
|
|
||||||
expenseIdx
|
|
||||||
)}
|
|
||||||
className={{ wrapper: 'min-w-24' }}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
|
|
||||||
{type !== 'detail' && (
|
|
||||||
<td>
|
|
||||||
<Button
|
|
||||||
type='button'
|
|
||||||
color='error'
|
|
||||||
onClick={() =>
|
|
||||||
deleteExpenseItemHandler(
|
|
||||||
kandangExpenseIdx,
|
kandangExpenseIdx,
|
||||||
expenseIdx
|
expenseIdx,
|
||||||
)
|
val
|
||||||
}
|
);
|
||||||
>
|
}}
|
||||||
<Icon
|
options={nonstockOptions}
|
||||||
icon='material-symbols:delete-outline-rounded'
|
isLoading={isLoadingNonstockOptions}
|
||||||
width={24}
|
onInputChange={setNonstockInputValue}
|
||||||
height={24}
|
className={{ wrapper: 'min-w-48' }}
|
||||||
/>
|
/>
|
||||||
</Button>
|
|
||||||
</td>
|
</td>
|
||||||
)}
|
|
||||||
</tr>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{type !== 'detail' && (
|
<td className='p-2'>
|
||||||
<Button
|
<NumberInput
|
||||||
type='button'
|
required
|
||||||
variant='outline'
|
name={`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].quantity`}
|
||||||
color='success'
|
placeholder='Masukkan Total Kuantitas'
|
||||||
onClick={() => addExpenseItemHandler(kandangExpenseIdx)}
|
value={
|
||||||
className='w-fit mx-auto'
|
formik.values.cost_per_kandangs[
|
||||||
>
|
kandangExpenseIdx
|
||||||
<Icon icon='ic:round-plus' width={24} height={24} />{' '}
|
].cost_items[expenseIdx].quantity ?? ''
|
||||||
Tambah
|
}
|
||||||
</Button>
|
onChange={formik.handleChange}
|
||||||
)}
|
onBlur={formik.handleBlur}
|
||||||
</div>
|
isError={isExpenseRepeaterInputError(
|
||||||
)
|
'quantity',
|
||||||
);
|
kandangExpenseIdx,
|
||||||
}
|
expenseIdx
|
||||||
)}
|
)}
|
||||||
|
className={{ wrapper: 'min-w-24' }}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td className='p-2'>
|
||||||
|
<NumberInput
|
||||||
|
name={`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].total_cost`}
|
||||||
|
placeholder='Masukkan Total Biaya'
|
||||||
|
value={
|
||||||
|
formik.values.cost_per_kandangs[
|
||||||
|
kandangExpenseIdx
|
||||||
|
].cost_items[expenseIdx].total_cost ??
|
||||||
|
''
|
||||||
|
}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
isError={isExpenseRepeaterInputError(
|
||||||
|
'total_cost',
|
||||||
|
kandangExpenseIdx,
|
||||||
|
expenseIdx
|
||||||
|
)}
|
||||||
|
inputPrefix={
|
||||||
|
<span className='text-gray-600 font-medium'>
|
||||||
|
Rp
|
||||||
|
</span>
|
||||||
|
}
|
||||||
|
className={{ wrapper: 'min-w-24' }}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td className='p-2'>
|
||||||
|
<TextInput
|
||||||
|
name={`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].notes`}
|
||||||
|
placeholder='Tuliskan catatan'
|
||||||
|
value={
|
||||||
|
formik.values.cost_per_kandangs[
|
||||||
|
kandangExpenseIdx
|
||||||
|
].cost_items[expenseIdx].notes ?? ''
|
||||||
|
}
|
||||||
|
onChange={formik.handleChange}
|
||||||
|
onBlur={formik.handleBlur}
|
||||||
|
isError={isExpenseRepeaterInputError(
|
||||||
|
'notes',
|
||||||
|
kandangExpenseIdx,
|
||||||
|
expenseIdx
|
||||||
|
)}
|
||||||
|
className={{ wrapper: 'min-w-24' }}
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
{type !== 'detail' && (
|
||||||
|
<td>
|
||||||
|
<Button
|
||||||
|
type='button'
|
||||||
|
color='error'
|
||||||
|
onClick={() =>
|
||||||
|
deleteExpenseItemHandler(
|
||||||
|
kandangExpenseIdx,
|
||||||
|
expenseIdx
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
icon='material-symbols:delete-outline-rounded'
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{type !== 'detail' && (
|
||||||
|
<Button
|
||||||
|
type='button'
|
||||||
|
variant='outline'
|
||||||
|
color='success'
|
||||||
|
onClick={() => addExpenseItemHandler(kandangExpenseIdx)}
|
||||||
|
className='w-fit mx-auto'
|
||||||
|
>
|
||||||
|
<Icon icon='ic:round-plus' width={24} height={24} />{' '}
|
||||||
|
Tambah
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user