Merge branch 'fix/FE/US-163-164/api-integration-adjustment-in-expense-request-and-realization' into 'development'

[FIX/FE][US#163-164] API Integration Adjustment in Expense Request and Realization

See merge request mbugroup/lti-web-client!78
This commit is contained in:
Adnan Zahir
2025-12-10 11:32:21 +07:00
12 changed files with 110 additions and 120 deletions
@@ -207,7 +207,7 @@ const ExpenseRealizationContent = ({
let expenseGrandTotal = 0; let expenseGrandTotal = 0;
kandangExpense.pengajuans?.forEach( kandangExpense.pengajuans?.forEach(
(item) => (expenseGrandTotal += item.total_price) (item) => (expenseGrandTotal += item.price)
); );
return ( return (
@@ -238,7 +238,7 @@ const ExpenseRealizationContent = ({
<tr key={pengajuanIdx}> <tr key={pengajuanIdx}>
<td>{pengajuanItem.nonstock.name}</td> <td>{pengajuanItem.nonstock.name}</td>
<td>{pengajuanItem.qty}</td> <td>{pengajuanItem.qty}</td>
<td>{formatCurrency(pengajuanItem.total_price)}</td> <td>{formatCurrency(pengajuanItem.price)}</td>
<td className='w-xs'>{pengajuanItem.note ?? '-'}</td> <td className='w-xs'>{pengajuanItem.note ?? '-'}</td>
</tr> </tr>
) )
@@ -269,7 +269,7 @@ const ExpenseRealizationContent = ({
let expenseGrandTotal = 0; let expenseGrandTotal = 0;
kandangExpense.realisasi?.forEach( kandangExpense.realisasi?.forEach(
(item) => (expenseGrandTotal += item.total_price) (item) => (expenseGrandTotal += item.price)
); );
return ( return (
@@ -300,7 +300,7 @@ const ExpenseRealizationContent = ({
<tr key={realisasiIdx}> <tr key={realisasiIdx}>
<td>{realisasiItem.nonstock.name}</td> <td>{realisasiItem.nonstock.name}</td>
<td>{realisasiItem.qty}</td> <td>{realisasiItem.qty}</td>
<td>{formatCurrency(realisasiItem.total_price)}</td> <td>{formatCurrency(realisasiItem.price)}</td>
<td className='w-xs'>{realisasiItem.note ?? '-'}</td> <td className='w-xs'>{realisasiItem.note ?? '-'}</td>
</tr> </tr>
) )
@@ -402,7 +402,10 @@ const ExpenseRequestContent = ({
<th>Tanggal Transaksi</th> <th>Tanggal Transaksi</th>
<th>:</th> <th>:</th>
<td> <td>
{formatDate(initialValues?.expense_date, 'DD MMMM YYYY')} {formatDate(
initialValues?.transaction_date,
'DD MMMM YYYY'
)}
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -529,7 +532,7 @@ const ExpenseRequestContent = ({
let expenseGrandTotal = 0; let expenseGrandTotal = 0;
kandangExpense.pengajuans?.forEach( kandangExpense.pengajuans?.forEach(
(item) => (expenseGrandTotal += item.total_price) (item) => (expenseGrandTotal += item.price)
); );
return ( return (
@@ -550,7 +553,7 @@ const ExpenseRequestContent = ({
<tr> <tr>
<th>Nonstock</th> <th>Nonstock</th>
<th>Total Kuantitas</th> <th>Total Kuantitas</th>
<th>Total Biaya</th> <th>Harga Satuan</th>
<th>Catatan</th> <th>Catatan</th>
</tr> </tr>
</thead> </thead>
@@ -560,9 +563,7 @@ const ExpenseRequestContent = ({
<tr key={pengajuanIdx}> <tr key={pengajuanIdx}>
<td>{pengajuanItem.nonstock.name}</td> <td>{pengajuanItem.nonstock.name}</td>
<td>{pengajuanItem.qty}</td> <td>{pengajuanItem.qty}</td>
<td> <td>{formatCurrency(pengajuanItem.price)}</td>
{formatCurrency(pengajuanItem.total_price)}
</td>
<td className='w-xs'> <td className='w-xs'>
{pengajuanItem.note ?? '-'} {pengajuanItem.note ?? '-'}
</td> </td>
@@ -263,11 +263,11 @@ const ExpensesTable = () => {
}, },
}, },
{ {
accessorKey: 'expense_date', accessorKey: 'transaction_date',
header: 'Tanggal Pengajuan', header: 'Tanggal Pengajuan',
cell: (props) => cell: (props) =>
props.row.original.expense_date props.row.original.transaction_date
? formatDate(props.row.original.expense_date, 'DD MMM YYYY') ? formatDate(props.row.original.transaction_date, 'DD MMM YYYY')
: '-', : '-',
}, },
{ {
@@ -27,7 +27,7 @@ type ExpenseRealizationFormSchemaType = {
label: string; label: string;
}; };
quantity?: number; quantity?: number;
total_cost?: number; price?: number;
notes?: string; notes?: string;
}[]; }[];
}[]; }[];
@@ -82,7 +82,7 @@ export const ExpenseRealizationFormSchema: Yup.ObjectSchema<ExpenseRealizationFo
label: Yup.string().required(), label: Yup.string().required(),
}).required('Nonstock wajib diisi!'), }).required('Nonstock wajib diisi!'),
quantity: Yup.number().required('Total kuantitas wajib diisi!'), quantity: Yup.number().required('Total kuantitas wajib diisi!'),
total_cost: Yup.number().required('Total biaya wajib diisi!'), price: Yup.number().required('Harga satuan wajib diisi!'),
notes: Yup.string(), notes: Yup.string(),
}) })
) )
@@ -155,7 +155,7 @@ export const getExpenseRealizationFormInitialValues = (
label: realisasiItem.nonstock.name, label: realisasiItem.nonstock.name,
}, },
quantity: realisasiItem.qty, quantity: realisasiItem.qty,
total_cost: realisasiItem.total_price, price: realisasiItem.price,
notes: realisasiItem.note, notes: realisasiItem.note,
}; };
}) })
@@ -166,7 +166,7 @@ export const getExpenseRealizationFormInitialValues = (
label: expenseItem.nonstock.name, label: expenseItem.nonstock.name,
}, },
quantity: expenseItem.qty, quantity: expenseItem.qty,
total_cost: expenseItem.total_price, price: expenseItem.price,
notes: expenseItem.note, notes: expenseItem.note,
})) }))
: []; : [];
@@ -98,15 +98,10 @@ const ExpenseRealizationForm = ({
values.realizations.forEach((realization) => { values.realizations.forEach((realization) => {
realization.cost_items.forEach((costItem) => { realization.cost_items.forEach((costItem) => {
const unitPrice =
parseFloat(String(costItem.total_cost)) /
parseFloat(String(costItem.quantity));
const realizationItem = { const realizationItem = {
expense_nonstock_id: costItem.nonstock?.value as number, expense_nonstock_id: costItem.nonstock?.value as number,
qty: parseFloat(String(costItem.quantity)) as number, qty: parseFloat(String(costItem.quantity)) as number,
unit_price: unitPrice, price: parseFloat(String(costItem.price)) as number,
total_price: parseFloat(String(costItem.total_cost)) as number,
notes: costItem.notes ?? '', notes: costItem.notes ?? '',
}; };
@@ -177,7 +172,7 @@ const ExpenseRealizationForm = ({
{ {
nonstock: undefined, nonstock: undefined,
quantity: undefined, quantity: undefined,
total_cost: undefined, price: undefined,
notes: '', notes: '',
}, },
], ],
@@ -48,7 +48,7 @@ const ExpenseRealizationKandangDetailExpense: React.FC<
}; };
const isExpenseRepeaterInputError = ( const isExpenseRepeaterInputError = (
column: 'nonstock' | 'quantity' | 'total_cost' | 'notes', column: 'nonstock' | 'quantity' | 'price' | 'notes',
kandangExpenseIdx: number, kandangExpenseIdx: number,
expenseIdx: number expenseIdx: number
) => { ) => {
@@ -112,7 +112,7 @@ const ExpenseRealizationKandangDetailExpense: React.FC<
<tr> <tr>
<th>Nonstock</th> <th>Nonstock</th>
<th>Total Kuantitas</th> <th>Total Kuantitas</th>
<th>Total Biaya</th> <th>Harga Satuan</th>
<th>Catatan</th> <th>Catatan</th>
</tr> </tr>
</thead> </thead>
@@ -163,17 +163,17 @@ const ExpenseRealizationKandangDetailExpense: React.FC<
<td className='p-2'> <td className='p-2'>
<NumberInput <NumberInput
name={`realizations[${kandangExpenseIdx}].cost_items[${expenseIdx}].total_cost`} name={`realizations[${kandangExpenseIdx}].cost_items[${expenseIdx}].price`}
placeholder='Masukkan Total Biaya' placeholder='Masukkan Harga Satuan'
value={ value={
formik.values.realizations[ formik.values.realizations[
kandangExpenseIdx kandangExpenseIdx
].cost_items[expenseIdx].total_cost ?? '' ].cost_items[expenseIdx].price ?? ''
} }
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isExpenseRepeaterInputError( isError={isExpenseRepeaterInputError(
'total_cost', 'price',
kandangExpenseIdx, kandangExpenseIdx,
expenseIdx expenseIdx
)} )}
@@ -20,7 +20,7 @@ type ExpenseFormSchemaType = {
existing_documents?: { id: number; name: string; url: string }[]; existing_documents?: { id: number; name: string; url: string }[];
deleted_documents?: number[]; deleted_documents?: number[];
documents?: File[]; documents?: File[];
cost_per_kandangs: { expense_nonstocks: {
kandang_id: number; kandang_id: number;
cost_items: { cost_items: {
nonstock?: { nonstock?: {
@@ -28,7 +28,7 @@ type ExpenseFormSchemaType = {
label: string; label: string;
}; };
quantity?: number; quantity?: number;
total_cost?: number; price?: number;
notes?: string; notes?: string;
}[]; }[];
}[]; }[];
@@ -74,7 +74,7 @@ export const ExpenseRequestFormSchema: Yup.ObjectSchema<ExpenseFormSchemaType> =
documents: Yup.array().of(Yup.mixed<File>().required()).optional(), documents: Yup.array().of(Yup.mixed<File>().required()).optional(),
cost_per_kandangs: Yup.array() expense_nonstocks: Yup.array()
.of( .of(
Yup.object({ Yup.object({
kandang_id: Yup.number().min(1, 'Wajib memilih kandang!').required(), kandang_id: Yup.number().min(1, 'Wajib memilih kandang!').required(),
@@ -86,7 +86,7 @@ export const ExpenseRequestFormSchema: Yup.ObjectSchema<ExpenseFormSchemaType> =
label: Yup.string().required(), label: Yup.string().required(),
}).required('Nonstock wajib diisi!'), }).required('Nonstock wajib diisi!'),
quantity: Yup.number().required('Total kuantitas wajib diisi!'), quantity: Yup.number().required('Total kuantitas wajib diisi!'),
total_cost: Yup.number().required('Total biaya wajib diisi!'), price: Yup.number().required('Harga satuan wajib diisi!'),
notes: Yup.string(), notes: Yup.string(),
}) })
) )
@@ -128,8 +128,8 @@ export const getExpenseFormInitialValues = (
label: initialValues.location.name, label: initialValues.location.name,
} }
: undefined, : undefined,
transaction_date: initialValues?.expense_date transaction_date: initialValues?.transaction_date
? formatDate(initialValues.expense_date, 'YYYY-MM-DD') ? formatDate(initialValues.transaction_date, 'YYYY-MM-DD')
: undefined, : undefined,
kandangs: initialValues?.kandangs.map((kandang) => ({ kandangs: initialValues?.kandangs.map((kandang) => ({
id: kandang.kandang_id, id: kandang.kandang_id,
@@ -148,7 +148,7 @@ export const getExpenseFormInitialValues = (
})), })),
deleted_documents: [], deleted_documents: [],
documents: [], documents: [],
cost_per_kandangs: initialValues?.kandangs expense_nonstocks: initialValues?.kandangs
? initialValues.kandangs.map((kandangExpense) => ({ ? initialValues.kandangs.map((kandangExpense) => ({
kandang_id: kandangExpense.kandang_id, kandang_id: kandangExpense.kandang_id,
cost_items: kandangExpense.pengajuans cost_items: kandangExpense.pengajuans
@@ -158,7 +158,7 @@ export const getExpenseFormInitialValues = (
label: expenseItem.nonstock.name, label: expenseItem.nonstock.name,
}, },
quantity: expenseItem.qty, quantity: expenseItem.qty,
total_cost: expenseItem.total_price, price: expenseItem.price,
notes: expenseItem.note, notes: expenseItem.note,
})) }))
: [], : [],
@@ -110,12 +110,12 @@ const ExpenseRequestForm = ({
transaction_date: values?.transaction_date as string, transaction_date: values?.transaction_date as string,
supplier_id: values.supplier?.value as number, supplier_id: values.supplier?.value as number,
documents: values.documents as File[], documents: values.documents as File[],
cost_per_kandangs: values.cost_per_kandangs.map((costPerKandang) => ({ expense_nonstocks: values.expense_nonstocks.map((expenseNonstock) => ({
kandang_id: costPerKandang.kandang_id, kandang_id: expenseNonstock.kandang_id,
cost_items: costPerKandang.cost_items.map((costItem) => ({ cost_items: expenseNonstock.cost_items.map((costItem) => ({
nonstock_id: costItem.nonstock?.value as number, nonstock_id: costItem.nonstock?.value as number,
quantity: parseFloat(String(costItem.quantity)) as number, quantity: parseFloat(String(costItem.quantity)) as number,
total_cost: parseFloat(String(costItem.total_cost)) as number, price: parseFloat(String(costItem.price)) as number,
notes: costItem.notes ?? '', notes: costItem.notes ?? '',
})), })),
})), })),
@@ -132,13 +132,13 @@ const ExpenseRequestForm = ({
transaction_date: values?.transaction_date as string, transaction_date: values?.transaction_date as string,
supplier_id: values.supplier?.value as number, supplier_id: values.supplier?.value as number,
documents: values.documents as File[], documents: values.documents as File[],
cost_per_kandang: values.cost_per_kandangs.map( expense_nonstocks: values.expense_nonstocks.map(
(costPerKandang) => ({ (expenseNonstock) => ({
kandang_id: costPerKandang.kandang_id, kandang_id: expenseNonstock.kandang_id,
cost_items: costPerKandang.cost_items.map((costItem) => ({ cost_items: expenseNonstock.cost_items.map((costItem) => ({
nonstock_id: costItem.nonstock?.value as number, nonstock_id: costItem.nonstock?.value as number,
quantity: parseFloat(String(costItem.quantity)) as number, quantity: parseFloat(String(costItem.quantity)) as number,
total_cost: parseFloat(String(costItem.total_cost)) as number, price: parseFloat(String(costItem.price)) as number,
notes: costItem.notes ?? '', notes: costItem.notes ?? '',
})), })),
}) })
@@ -179,53 +179,54 @@ const ExpenseRequestForm = ({
formik.setFieldValue('location', val); formik.setFieldValue('location', val);
formik.setFieldValue('kandangs', []); formik.setFieldValue('kandangs', []);
formik.setFieldValue('cost_per_kandangs', []); formik.setFieldValue('expense_nonstocks', []);
}; };
const kandangsChangeHandler = (kandangs: { id: number; name: string }[]) => { const kandangsChangeHandler = (kandangs: { id: number; name: string }[]) => {
formik.setFieldTouched('kandangs', true); formik.setFieldTouched('kandangs', true);
formik.setFieldValue('kandangs', kandangs); formik.setFieldValue('kandangs', kandangs);
const newCostPerKandangs = [...(formik.values.cost_per_kandangs ?? [])]; const newExpenseNonstocks = [...(formik.values.expense_nonstocks ?? [])];
// add new cost_per_kandangs // add new expense_nonstocks
kandangs.forEach((kandangItem) => { kandangs.forEach((kandangItem) => {
const isKandangExistInCostPerKandangs = newCostPerKandangs.find( const isKandangExistInExpenseNonstocks = newExpenseNonstocks.find(
(costPerKandangItem) => costPerKandangItem.kandang_id === kandangItem.id (expenseNonstockItem) =>
expenseNonstockItem.kandang_id === kandangItem.id
); );
if (isKandangExistInCostPerKandangs) return; if (isKandangExistInExpenseNonstocks) return;
newCostPerKandangs.push({ newExpenseNonstocks.push({
kandang_id: kandangItem.id, kandang_id: kandangItem.id,
cost_items: [ cost_items: [
{ {
nonstock: undefined, nonstock: undefined,
quantity: undefined, quantity: undefined,
total_cost: undefined, price: undefined,
notes: '', notes: '',
}, },
], ],
}); });
}); });
// prune cost_per_kandangs // prune expense_nonstocks
const kandangIds = new Set(kandangs.map((kandang) => kandang.id)); const kandangIds = new Set(kandangs.map((kandang) => kandang.id));
const deletedCostPerKandangsIdx: number[] = []; const deletedExpenseNonstocksIdx: number[] = [];
newCostPerKandangs.forEach((costPerKandang, idx) => { newExpenseNonstocks.forEach((expenseNonstock, idx) => {
const isCostPerKandangValid = kandangIds.has(costPerKandang.kandang_id); const isExpenseNonstockValid = kandangIds.has(expenseNonstock.kandang_id);
if (!isCostPerKandangValid) { if (!isExpenseNonstockValid) {
deletedCostPerKandangsIdx.push(idx); deletedExpenseNonstocksIdx.push(idx);
} }
}); });
deletedCostPerKandangsIdx.forEach((deletedCostPerKandangIdx) => { deletedExpenseNonstocksIdx.forEach((deletedExpenseNonstockIdx) => {
newCostPerKandangs.splice(deletedCostPerKandangIdx, 1); newExpenseNonstocks.splice(deletedExpenseNonstockIdx, 1);
}); });
formik.setFieldValue('cost_per_kandangs', newCostPerKandangs); formik.setFieldValue('expense_nonstocks', newExpenseNonstocks);
}; };
const supplierChangeHandler = (val: OptionType | OptionType[] | null) => { const supplierChangeHandler = (val: OptionType | OptionType[] | null) => {
@@ -41,28 +41,28 @@ const ExpenseRequestKandangDetailExpense: React.FC<
val: OptionType | OptionType[] | null val: OptionType | OptionType[] | null
) => { ) => {
formik.setFieldTouched( formik.setFieldTouched(
`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`, `expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`,
true true
); );
formik.setFieldValue( formik.setFieldValue(
`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`, `expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`,
val val
); );
}; };
const addExpenseItemHandler = (kandangExpenseIdx: number) => { const addExpenseItemHandler = (kandangExpenseIdx: number) => {
const newExpensesValue = [ const newExpensesValue = [
...formik.values.cost_per_kandangs[kandangExpenseIdx].cost_items, ...formik.values.expense_nonstocks[kandangExpenseIdx].cost_items,
{ {
nonstock: undefined, nonstock: undefined,
total_cost: undefined, price: undefined,
quantity: undefined, quantity: undefined,
notes: '', notes: '',
}, },
]; ];
formik.setFieldValue( formik.setFieldValue(
`cost_per_kandangs[${kandangExpenseIdx}].cost_items`, `expense_nonstocks[${kandangExpenseIdx}].cost_items`,
newExpensesValue newExpensesValue
); );
}; };
@@ -71,28 +71,28 @@ const ExpenseRequestKandangDetailExpense: React.FC<
kandangExpenseIdx: number, kandangExpenseIdx: number,
expenseIdx: number expenseIdx: number
) => { ) => {
const path = `cost_per_kandangs[${kandangExpenseIdx}].cost_items`; const path = `expense_nonstocks[${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' | 'quantity' | 'total_cost' | 'notes', column: 'nonstock' | 'quantity' | 'price' | 'notes',
kandangExpenseIdx: number, kandangExpenseIdx: number,
expenseIdx: number expenseIdx: number
) => { ) => {
return ( return (
formik.touched.cost_per_kandangs?.[kandangExpenseIdx]?.cost_items?.[ formik.touched.expense_nonstocks?.[kandangExpenseIdx]?.cost_items?.[
expenseIdx expenseIdx
]?.[column] && ]?.[column] &&
Boolean( Boolean(
formik.errors.cost_per_kandangs?.[kandangExpenseIdx] instanceof formik.errors.expense_nonstocks?.[kandangExpenseIdx] instanceof
Object && Object &&
formik.errors.cost_per_kandangs?.[kandangExpenseIdx].cost_items?.[ formik.errors.expense_nonstocks?.[kandangExpenseIdx].cost_items?.[
expenseIdx expenseIdx
] instanceof Object && ] instanceof Object &&
formik.errors.cost_per_kandangs?.[kandangExpenseIdx].cost_items?.[ formik.errors.expense_nonstocks?.[kandangExpenseIdx].cost_items?.[
expenseIdx expenseIdx
]?.[column] ]?.[column]
) )
@@ -113,7 +113,7 @@ 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.cost_per_kandangs.length === 0 || {(formik.values.expense_nonstocks.length === 0 ||
!formik.values.supplier?.value) && ( !formik.values.supplier?.value) && (
<div> <div>
<p className='text-sm text-gray-400 text-center'> <p className='text-sm text-gray-400 text-center'>
@@ -122,9 +122,9 @@ const ExpenseRequestKandangDetailExpense: React.FC<
</div> </div>
)} )}
{formik.values.cost_per_kandangs.length > 0 && {formik.values.expense_nonstocks.length > 0 &&
formik.values.supplier?.value && formik.values.supplier?.value &&
formik.values.cost_per_kandangs.map( formik.values.expense_nonstocks.map(
(kandangExpense, kandangExpenseIdx) => { (kandangExpense, kandangExpenseIdx) => {
const kandangName = formik.values.kandangs?.find( const kandangName = formik.values.kandangs?.find(
(kandang) => kandang.id === kandangExpense.kandang_id (kandang) => kandang.id === kandangExpense.kandang_id
@@ -147,7 +147,7 @@ const ExpenseRequestKandangDetailExpense: React.FC<
<tr> <tr>
<th>Nonstock</th> <th>Nonstock</th>
<th>Total Kuantitas</th> <th>Total Kuantitas</th>
<th>Total Biaya</th> <th>Harga Satuan</th>
<th>Catatan</th> <th>Catatan</th>
{type !== 'detail' && <th>Aksi</th>} {type !== 'detail' && <th>Aksi</th>}
</tr> </tr>
@@ -178,10 +178,10 @@ const ExpenseRequestKandangDetailExpense: React.FC<
<td className='p-2'> <td className='p-2'>
<NumberInput <NumberInput
required required
name={`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].quantity`} name={`expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].quantity`}
placeholder='Masukkan Total Kuantitas' placeholder='Masukkan Total Kuantitas'
value={ value={
formik.values.cost_per_kandangs[ formik.values.expense_nonstocks[
kandangExpenseIdx kandangExpenseIdx
].cost_items[expenseIdx].quantity ?? '' ].cost_items[expenseIdx].quantity ?? ''
} }
@@ -198,18 +198,17 @@ const ExpenseRequestKandangDetailExpense: React.FC<
<td className='p-2'> <td className='p-2'>
<NumberInput <NumberInput
name={`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].total_cost`} name={`expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].price`}
placeholder='Masukkan Total Biaya' placeholder='Masukkan Harga Satuan'
value={ value={
formik.values.cost_per_kandangs[ formik.values.expense_nonstocks[
kandangExpenseIdx kandangExpenseIdx
].cost_items[expenseIdx].total_cost ?? ].cost_items[expenseIdx].price ?? ''
''
} }
onChange={formik.handleChange} onChange={formik.handleChange}
onBlur={formik.handleBlur} onBlur={formik.handleBlur}
isError={isExpenseRepeaterInputError( isError={isExpenseRepeaterInputError(
'total_cost', 'price',
kandangExpenseIdx, kandangExpenseIdx,
expenseIdx expenseIdx
)} )}
@@ -224,10 +223,10 @@ const ExpenseRequestKandangDetailExpense: React.FC<
<td className='p-2'> <td className='p-2'>
<TextInput <TextInput
name={`cost_per_kandangs[${kandangExpenseIdx}].cost_items[${expenseIdx}].notes`} name={`expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].notes`}
placeholder='Tuliskan catatan' placeholder='Tuliskan catatan'
value={ value={
formik.values.cost_per_kandangs[ formik.values.expense_nonstocks[
kandangExpenseIdx kandangExpenseIdx
].cost_items[expenseIdx].notes ?? '' ].cost_items[expenseIdx].notes ?? ''
} }
@@ -224,7 +224,7 @@ const ExpensePDF = ({ expense }: ExpensePDFProps) => {
{ label: 'Vendor', value: expense?.supplier.name }, { label: 'Vendor', value: expense?.supplier.name },
{ {
label: 'Tanggal Transaksi', label: 'Tanggal Transaksi',
value: formatDate(expense?.expense_date, 'DD MMMM YYYY'), value: formatDate(expense?.transaction_date, 'DD MMMM YYYY'),
}, },
{ {
label: 'Tanggal Realisasi', label: 'Tanggal Realisasi',
@@ -326,7 +326,7 @@ const ExpensePDF = ({ expense }: ExpensePDFProps) => {
let expenseRequestTotal = 0; let expenseRequestTotal = 0;
kandangExpense.pengajuans?.forEach( kandangExpense.pengajuans?.forEach(
(item) => (expenseRequestTotal += item.total_price) (item) => (expenseRequestTotal += item.price)
); );
return ( return (
@@ -374,7 +374,7 @@ const ExpensePDF = ({ expense }: ExpensePDFProps) => {
<Text <Text
style={ExpensePDFStyle.kandangExpenseHeaderLabelText} style={ExpensePDFStyle.kandangExpenseHeaderLabelText}
> >
Total Biaya Harga Satuan
</Text> </Text>
</View> </View>
<View <View
@@ -424,7 +424,7 @@ const ExpensePDF = ({ expense }: ExpensePDFProps) => {
]} ]}
> >
<Text style={ExpensePDFStyle.kandangExpenseLabelText}> <Text style={ExpensePDFStyle.kandangExpenseLabelText}>
{formatCurrency(pengajuan.total_price)} {formatCurrency(pengajuan.price)}
</Text> </Text>
</View> </View>
<View <View
@@ -484,7 +484,7 @@ const ExpensePDF = ({ expense }: ExpensePDFProps) => {
let expenseRealizationTotal = 0; let expenseRealizationTotal = 0;
kandangExpense.realisasi?.forEach( kandangExpense.realisasi?.forEach(
(item) => (expenseRealizationTotal += item.total_price) (item) => (expenseRealizationTotal += item.price)
); );
return ( return (
@@ -532,7 +532,7 @@ const ExpensePDF = ({ expense }: ExpensePDFProps) => {
<Text <Text
style={ExpensePDFStyle.kandangExpenseHeaderLabelText} style={ExpensePDFStyle.kandangExpenseHeaderLabelText}
> >
Total Biaya Harga Satuan
</Text> </Text>
</View> </View>
<View <View
@@ -582,7 +582,7 @@ const ExpensePDF = ({ expense }: ExpensePDFProps) => {
]} ]}
> >
<Text style={ExpensePDFStyle.kandangExpenseLabelText}> <Text style={ExpensePDFStyle.kandangExpenseLabelText}>
{formatCurrency(realisasi.total_price)} {formatCurrency(realisasi.price)}
</Text> </Text>
</View> </View>
<View <View
+4 -4
View File
@@ -492,8 +492,8 @@ export class ExpenseApiService extends BaseApiService<
}); });
formData.append( formData.append(
'cost_per_kandangs', 'expense_nonstocks',
JSON.stringify(payload.cost_per_kandangs) JSON.stringify(payload.expense_nonstocks)
); );
return formData; return formData;
@@ -514,8 +514,8 @@ export class ExpenseApiService extends BaseApiService<
}); });
formData.append( formData.append(
'cost_per_kandang', 'expense_nonstocks',
JSON.stringify(payload.cost_per_kandang) JSON.stringify(payload.expense_nonstocks)
); );
return formData; return formData;
+14 -20
View File
@@ -18,7 +18,7 @@ export type BaseExpense = {
id: number; id: number;
path: string; path: string;
}[]; }[];
expense_date: string; transaction_date: string;
realization_date?: string; realization_date?: string;
grand_total: number; grand_total: number;
location: BaseLocation; location: BaseLocation;
@@ -29,28 +29,23 @@ export type BaseExpense = {
name: string; name: string;
pengajuans?: { pengajuans?: {
id: number; id: number;
expense_id: number;
kandang_id: number;
nonstock_id: number;
qty: number; qty: number;
unit_price: number; price: number;
total_price: number;
note?: string; note?: string;
nonstock: Pick<BaseNonstock, 'id' | 'name' | 'flags'>; nonstock: Pick<BaseNonstock, 'id' | 'name' | 'flags'>;
project_flock_kandang: { created_at: string;
id: number;
kandang_id: number;
};
}[]; }[];
realisasi?: { realisasi?: {
id: number; id: number;
expense_nonstock_id: number;
qty: number; qty: number;
unit_price: number; price: number;
total_price: number;
date: string;
note?: string; note?: string;
nonstock: Pick<BaseNonstock, 'id' | 'name' | 'flags'>; nonstock: Pick<BaseNonstock, 'id' | 'name' | 'flags'>;
project_flock_kandang: { created_at: string;
id: number;
kandang_id: number;
};
}[]; }[];
}[]; }[];
total_pengajuan: number; total_pengajuan: number;
@@ -65,12 +60,12 @@ export type CreateExpensePayload = {
transaction_date: string; transaction_date: string;
supplier_id: number; supplier_id: number;
documents: File[]; documents: File[];
cost_per_kandangs: { expense_nonstocks: {
kandang_id: number; kandang_id: number;
cost_items: { cost_items: {
nonstock_id: number; nonstock_id: number;
quantity: number; quantity: number;
total_cost: number; price: number;
notes: string; notes: string;
}[]; }[];
}[]; }[];
@@ -81,12 +76,12 @@ export type UpdateExpensePayload = {
transaction_date: string; transaction_date: string;
supplier_id: number; supplier_id: number;
documents: File[]; documents: File[];
cost_per_kandang: { expense_nonstocks: {
kandang_id: number; kandang_id: number;
cost_items: { cost_items: {
nonstock_id: number; nonstock_id: number;
quantity: number; quantity: number;
total_cost: number; price: number;
notes: string; notes: string;
}[]; }[];
}[]; }[];
@@ -98,8 +93,7 @@ export type CreateExpenseRealizationPayload = {
realizations: { realizations: {
expense_nonstock_id: number; expense_nonstock_id: number;
qty: number; qty: number;
unit_price: number; price: number;
total_price: number;
notes: string; notes: string;
}[]; }[];
}; };