mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-25 15:55:48 +00:00
refactor: update CreateExpensePayload, UpdateExpensePayload, and CreateExpenseRealizationPayload types
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Vendored
+14
-20
@@ -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;
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user