Merge branch 'development' of https://gitlab.com/mbugroup/lti-web-client into dev/randy

This commit is contained in:
randy-ar
2026-01-12 17:19:53 +07:00
6 changed files with 125 additions and 73 deletions
+6 -6
View File
@@ -34,10 +34,10 @@ const ClosingDetailPage = () => {
() => ProjectFlockKandangApi.getSingle(Number(kandangId))
);
// const { data: salesData, isLoading: isLoadingSales } = useSWR(
// closingId ? `sales-${closingId}` : null,
// () => ClosingApi.getPenjualan(Number(closingId))
// );
const { data: salesData, isLoading: isLoadingSales } = useSWR(
closingId ? `sales-${closingId}` : null,
() => ClosingApi.getPenjualan(Number(closingId))
);
const { data: hppEkspedisiData, isLoading: isLoadingHppEkspedisi } = useSWR(
closingId ? `hpp-ekspedisi-${closingId}` : null,
@@ -61,10 +61,10 @@ const ClosingDetailPage = () => {
const isLoading =
isLoadingClosing ||
isLoadingSales ||
isLoadingHppEkspedisi ||
isLoadingProject ||
isLoadingKandang;
// const isLoading = isLoadingClosing || isLoadingSales || isLoadingHppEkspedisi;
return (
<div className='w-full p-4 flex flex-row justify-center'>
@@ -74,7 +74,7 @@ const ClosingDetailPage = () => {
<ClosingDetail
id={Number(closingId)}
initialValue={closing.data}
// salesData={isResponseSuccess(salesData) ? salesData.data : undefined}
salesData={isResponseSuccess(salesData) ? salesData.data : undefined}
hppExpeditionData={
isResponseSuccess(hppEkspedisiData)
? hppEkspedisiData.data
@@ -58,11 +58,11 @@ const ClosingDetail: React.FC<ClosingDetailProps> = ({
/>
),
},
// {
// id: 'penjualan',
// label: 'Penjualan',
// content: <SalesReportTable initialValues={salesData} />,
// },
{
id: 'penjualan',
label: 'Penjualan',
content: <SalesReportTable initialValues={salesData} />,
},
{
id: 'overhead',
label: 'Overhead',
@@ -215,31 +215,31 @@ const SalesReportTable = ({
return kandang?.name || '-';
},
},
{
id: 'payment_status',
accessorKey: 'payment_status',
header: 'Status Pembayaran',
cell: (props) => {
const status = props.getValue() as string;
const getStatusColor = (status: string) => {
if (!status) return 'neutral';
switch (status.toLowerCase()) {
case 'paid':
return 'success';
case 'tempo':
return 'warning';
default:
return 'neutral';
}
};
// {
// id: 'payment_status',
// accessorKey: 'payment_status',
// header: 'Status Pembayaran',
// cell: (props) => {
// const status = props.getValue() as string;
// const getStatusColor = (status: string) => {
// if (!status) return 'neutral';
// switch (status.toLowerCase()) {
// case 'paid':
// return 'success';
// case 'tempo':
// return 'warning';
// default:
// return 'neutral';
// }
// };
return (
<Badge variant='soft' size='sm' color={getStatusColor(status)}>
{status || '-'}
</Badge>
);
},
},
// return (
// <Badge variant='soft' size='sm' color={getStatusColor(status)}>
// {status || '-'}
// </Badge>
// );
// },
// },
],
[]
);
@@ -7,18 +7,19 @@ type ExpenseFormSchemaType = {
category?: {
value: 'BOP' | 'NON-BOP';
label: 'BOP' | 'NON-BOP';
};
} | null;
location?: {
value: number;
label: string;
};
} | null;
location_id: number;
transaction_date?: string;
kandangs?: { id?: number; name?: string }[];
supplier?: {
value: number;
label: string;
};
} | null;
supplier_id: number;
existing_documents?: { id: number; name: string; url: string }[];
deleted_documents?: number[];
documents?: File[];
@@ -28,7 +29,8 @@ type ExpenseFormSchemaType = {
nonstock?: {
value: number;
label: string;
};
} | null;
nonstock_id?: number;
quantity?: number;
price?: number;
notes?: string;
@@ -41,16 +43,24 @@ export const ExpenseRequestFormSchema: Yup.ObjectSchema<ExpenseFormSchemaType> =
category: Yup.object({
value: Yup.string().oneOf(['BOP', 'NON-BOP']).required(),
label: Yup.string().oneOf(['BOP', 'NON-BOP']).required(),
}).required('Kategori wajib diisi!'),
})
.nullable()
.optional(),
location: Yup.object({
value: Yup.number().min(1).required(),
label: Yup.string().required(),
}).required('Lokasi wajib diisi!'),
})
.nullable()
.optional(),
location_id: Yup.number().min(1).required('Lokasi wajib diisi!'),
location_id: Yup.number()
.required('Lokasi wajib diisi!')
.min(1, 'Lokasi wajib diisi!')
.typeError('Lokasi wajib diisi!'),
transaction_date: Yup.string().required('Tanggal transaksi wajib diisi!'),
kandangs: Yup.array()
.of(
Yup.object({
@@ -63,28 +73,28 @@ export const ExpenseRequestFormSchema: Yup.ObjectSchema<ExpenseFormSchemaType> =
supplier: Yup.object({
value: Yup.number().min(1).required(),
label: Yup.string().required(),
}).required('Vendor wajib diisi!'),
})
.nullable()
.optional(),
existing_documents: Yup.array().of(
Yup.object({
id: Yup.number().required(),
name: Yup.string().required(),
url: Yup.string().required(),
})
),
supplier_id: Yup.number()
.required('Vendor wajib diisi!')
.min(1, 'Vendor wajib diisi!')
.typeError('Vendor wajib diisi!'),
existing_documents: Yup.array()
.of(
Yup.object({
id: Yup.number().required(),
name: Yup.string().required(),
url: Yup.string().required(),
})
)
.optional(),
deleted_documents: Yup.array().of(Yup.number().required()).optional(),
documents: Yup.array()
.of(
Yup.mixed<File>()
.required()
.test('fileSize', 'Ukuran dokumen maksimal 5 MB', (value) => {
if (!value || !(value instanceof File)) return true;
return value.size <= 5 * 1024 * 1024;
})
)
.optional(),
documents: Yup.array().of(Yup.mixed<File>().required()).optional(),
expense_nonstocks: Yup.array()
.of(
@@ -96,9 +106,17 @@ export const ExpenseRequestFormSchema: Yup.ObjectSchema<ExpenseFormSchemaType> =
nonstock: Yup.object({
value: Yup.number().min(1).required(),
label: Yup.string().required(),
}).required('Nonstock wajib diisi!'),
quantity: Yup.number().required('Total kuantitas wajib diisi!'),
price: Yup.number().required('Harga satuan wajib diisi!'),
}).nullable(),
nonstock_id: Yup.number()
.required('Nonstock wajib diisi!')
.min(1, 'Nonstock wajib diisi!')
.typeError('Nonstock wajib diisi!'),
quantity: Yup.number()
.required('Total kuantitas wajib diisi!')
.typeError('Total kuantitas wajib diisi!'),
price: Yup.number()
.required('Harga satuan wajib diisi!')
.typeError('Harga satuan wajib diisi!'),
notes: Yup.string(),
})
)
@@ -142,13 +160,13 @@ export const getExpenseFormInitialValues = (
value: initialValues.category,
label: initialValues.category,
}
: undefined,
: null,
location: initialValues?.location
? {
value: initialValues.location.id,
label: initialValues.location.name,
}
: undefined,
: null,
location_id: Number(initialValues?.location.id || 0),
transaction_date: initialValues?.transaction_date
? formatDate(initialValues.transaction_date, 'YYYY-MM-DD')
@@ -162,7 +180,8 @@ export const getExpenseFormInitialValues = (
value: initialValues.supplier.id,
label: initialValues.supplier.name,
}
: undefined,
: null,
supplier_id: initialValues?.supplier?.id ?? 0,
existing_documents: initialValues?.documents?.map((doc) => {
const path = doc.path.startsWith('/') ? doc.path.slice(1) : doc.path;
return {
@@ -182,12 +201,25 @@ export const getExpenseFormInitialValues = (
value: expenseItem.nonstock.id,
label: expenseItem.nonstock.name,
},
nonstock_id: expenseItem.nonstock.id,
quantity: expenseItem.qty,
price: expenseItem.price,
notes: expenseItem.note,
}))
: [],
}))
: [],
: [
{
cost_items: [
{
nonstock: null,
nonstock_id: 0,
quantity: undefined,
price: undefined,
notes: '',
},
],
},
],
};
};
@@ -204,7 +204,8 @@ const ExpenseRequestForm = ({
{
cost_items: [
{
nonstock: undefined,
nonstock: null,
nonstock_id: 0,
quantity: undefined,
price: undefined,
notes: '',
@@ -226,7 +227,8 @@ const ExpenseRequestForm = ({
{
cost_items: [
{
nonstock: undefined,
nonstock: null,
nonstock_id: 0,
quantity: undefined,
price: undefined,
notes: '',
@@ -251,7 +253,8 @@ const ExpenseRequestForm = ({
kandang_id: kandangItem.id,
cost_items: existingExpenseNonstock?.cost_items || [
{
nonstock: undefined,
nonstock: null,
nonstock_id: 0,
quantity: undefined,
price: undefined,
notes: '',
@@ -266,10 +269,20 @@ const ExpenseRequestForm = ({
const supplierChangeHandler = (val: OptionType | OptionType[] | null) => {
formik.setFieldTouched('supplier', true);
formik.setFieldValue('supplier', val);
const supplierId = Array.isArray(val) ? val[0]?.value : val?.value;
formik.setFieldValue('supplier_id', supplierId ?? 0);
};
const requestDocumentsChangeHandler = (val: File[]) => {
formik.setFieldTouched('documents', true);
const invalidFiles = val.filter((file) => file.size > 5 * 1024 * 1024);
if (invalidFiles.length > 0) {
toast.error('Ukuran dokumen maksimal 5 MB!');
return;
}
formik.setFieldValue('documents', val);
};
@@ -585,7 +598,7 @@ const ExpenseRequestForm = ({
type='submit'
color='primary'
isLoading={formik.isSubmitting}
disabled={!formik.isValid || formik.isSubmitting}
disabled={formik.isSubmitting}
className='px-4'
>
Submit
@@ -25,7 +25,7 @@ interface ExpenseRequestKandangDetailExpenseProps {
location?: {
value: number;
label: string;
};
} | null;
className?: {
wrapper?: string;
};
@@ -59,13 +59,20 @@ const ExpenseRequestKandangDetailExpense: React.FC<
`expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock`,
val
);
const nonstockId = Array.isArray(val) ? val[0]?.value : val?.value;
formik.setFieldValue(
`expense_nonstocks[${kandangExpenseIdx}].cost_items[${expenseIdx}].nonstock_id`,
nonstockId ?? 0
);
};
const addExpenseItemHandler = (kandangExpenseIdx: number) => {
const newExpensesValue = [
...formik.values.expense_nonstocks[kandangExpenseIdx].cost_items,
{
nonstock: undefined,
nonstock: null,
nonstock_id: 0,
price: undefined,
quantity: undefined,
notes: '',