mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
Merge branch 'dev/restu' into 'development'
[HOTFIX/FE][US#281-391] Adjustment Uniformity, Purchase and Expense See merge request mbugroup/lti-web-client!138
This commit is contained in:
@@ -33,6 +33,7 @@ const FileInput = ({
|
||||
isError,
|
||||
errorMessage,
|
||||
disabled = false,
|
||||
required = false,
|
||||
onChange,
|
||||
onBlur,
|
||||
readOnly = false,
|
||||
@@ -56,6 +57,13 @@ const FileInput = ({
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
{required && (
|
||||
<>
|
||||
<span className='tooltip tooltip-error' data-tip='required'>
|
||||
<span className='text-error'> *</span>
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</label>
|
||||
)}
|
||||
|
||||
|
||||
@@ -140,17 +140,17 @@ const ExpenseRequestContent = ({
|
||||
const confirmationModalDeleteClickHandler = async () => {
|
||||
setIsDeleteLoading(true);
|
||||
|
||||
try {
|
||||
await ExpenseApi.delete(initialValues?.id as number);
|
||||
const deleteResponse = await ExpenseApi.delete(initialValues?.id as number);
|
||||
|
||||
if (isResponseSuccess(deleteResponse)) {
|
||||
toast.success('Berhasil menghapus data biaya operasional!');
|
||||
router.push('/expense');
|
||||
} catch (error) {
|
||||
} else {
|
||||
toast.error('Gagal menghapus data biaya operasional!');
|
||||
} finally {
|
||||
deleteModal.closeModal();
|
||||
setIsDeleteLoading(false);
|
||||
}
|
||||
|
||||
deleteModal.closeModal();
|
||||
setIsDeleteLoading(false);
|
||||
};
|
||||
|
||||
const confirmationModalCompleteClickHandler = async () => {
|
||||
|
||||
@@ -21,7 +21,7 @@ const ExpenseStatusBadge = ({ approval }: ExpenseStatusBadgeProps) => {
|
||||
|
||||
switch (latestApprovalStepNumber) {
|
||||
case 1:
|
||||
expenseStatusPillBadgeColor = 'yellow';
|
||||
expenseStatusPillBadgeColor = 'gray';
|
||||
break;
|
||||
|
||||
case 2:
|
||||
@@ -33,7 +33,7 @@ const ExpenseStatusBadge = ({ approval }: ExpenseStatusBadgeProps) => {
|
||||
break;
|
||||
|
||||
case 4:
|
||||
expenseStatusPillBadgeColor = 'red';
|
||||
expenseStatusPillBadgeColor = 'yellow';
|
||||
break;
|
||||
|
||||
case 5:
|
||||
|
||||
@@ -420,11 +420,19 @@ const ExpensesTable = () => {
|
||||
const confirmationModalDeleteClickHandler = async () => {
|
||||
setIsDeleteLoading(true);
|
||||
|
||||
await ExpenseApi.delete(selectedExpense?.id as number);
|
||||
refreshExpenses();
|
||||
const deleteResponse = await ExpenseApi.delete(
|
||||
selectedExpense?.id as number
|
||||
);
|
||||
|
||||
if (isResponseSuccess(deleteResponse)) {
|
||||
refreshExpenses();
|
||||
deleteModal.closeModal();
|
||||
toast.success('Berhasil menghapus biaya operasional!');
|
||||
} else {
|
||||
deleteModal.closeModal();
|
||||
toast.error('Gagal menghapus biaya operasional!');
|
||||
}
|
||||
|
||||
deleteModal.closeModal();
|
||||
toast.success('Berhasil menghapus biaya operasional!');
|
||||
setIsDeleteLoading(false);
|
||||
};
|
||||
|
||||
|
||||
@@ -1562,7 +1562,9 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
{delivery.document.name}
|
||||
<span className='truncate max-w-[200px]'>
|
||||
{delivery.document.name}
|
||||
</span>
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
@@ -1582,6 +1584,7 @@ const MovementForm = ({ type = 'add', initialValues }: MovementFormProps) => {
|
||||
</>
|
||||
) : (
|
||||
<FileInput
|
||||
accept='.pdf,.jpg,.jpeg,.png'
|
||||
name={`deliveries.${idx}.document`}
|
||||
onChange={(e) => {
|
||||
const file = e.target.files?.[0];
|
||||
|
||||
@@ -51,8 +51,10 @@ import MenuItem from '@/components/menu/MenuItem';
|
||||
|
||||
const UniformityConfirmationPreview = ({
|
||||
uniformity,
|
||||
uniformityDetail,
|
||||
}: {
|
||||
uniformity?: Uniformity;
|
||||
uniformityDetail?: UniformityDetail;
|
||||
}) => {
|
||||
const data: DetailOptionType[] = [
|
||||
{
|
||||
@@ -60,32 +62,42 @@ const UniformityConfirmationPreview = ({
|
||||
label: 'Tanggal',
|
||||
value: uniformity
|
||||
? formatDate(uniformity.applied_at, 'DD MMM YYYY')
|
||||
: '-',
|
||||
: uniformityDetail
|
||||
? formatDate(uniformityDetail.info_umum.tanggal, 'DD MMM YYYY')
|
||||
: '-',
|
||||
},
|
||||
{
|
||||
id: 'lokasi-farm',
|
||||
label: 'Lokasi Farm',
|
||||
value: uniformity?.location_name || '-',
|
||||
value:
|
||||
uniformity?.location_name ||
|
||||
uniformityDetail?.info_umum?.lokasi_farm ||
|
||||
'-',
|
||||
},
|
||||
{
|
||||
id: 'project-flock',
|
||||
label: 'Project Flock',
|
||||
value: uniformity?.flock_name || '-',
|
||||
value:
|
||||
uniformity?.flock_name ||
|
||||
uniformityDetail?.info_umum?.project_flock ||
|
||||
'-',
|
||||
},
|
||||
{
|
||||
id: 'kandang',
|
||||
label: 'Kandang',
|
||||
value: uniformity?.kandang_name || '-',
|
||||
value:
|
||||
uniformity?.kandang_name || uniformityDetail?.info_umum?.kandang || '-',
|
||||
},
|
||||
{
|
||||
id: 'file-uniformity',
|
||||
label: 'File Uniformity',
|
||||
value: '-',
|
||||
value:
|
||||
uniformity?.file_name || uniformityDetail?.info_umum?.file_name || '-',
|
||||
},
|
||||
{
|
||||
id: 'status',
|
||||
label: 'Status',
|
||||
value: uniformity?.status || '-',
|
||||
value: uniformity?.status || (uniformityDetail ? 'CREATED' : '-'),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -448,9 +460,15 @@ const UniformityTable = () => {
|
||||
const canApproveReject = useMemo(() => {
|
||||
return (
|
||||
selectedUniformities.length > 0 &&
|
||||
selectedUniformities.every(
|
||||
(u) => u.status === 'CREATED' || u.status === 'Pengajuan'
|
||||
)
|
||||
selectedUniformities.every((u) => {
|
||||
const approvalAction = u.latest_approval?.action;
|
||||
return (
|
||||
approvalAction === 'CREATED' ||
|
||||
approvalAction === 'Pengajuan' ||
|
||||
(!approvalAction &&
|
||||
(u.status === 'CREATED' || u.status === 'Pengajuan'))
|
||||
);
|
||||
})
|
||||
);
|
||||
}, [selectedUniformities]);
|
||||
|
||||
@@ -805,7 +823,9 @@ const UniformityTable = () => {
|
||||
accessorKey: 'status',
|
||||
header: 'Status',
|
||||
cell: (props) => {
|
||||
const status = props.row.original.status;
|
||||
const uniformity = props.row.original;
|
||||
const status =
|
||||
uniformity.latest_approval?.action ?? uniformity.status;
|
||||
return (
|
||||
<div className='w-full'>
|
||||
<Badge
|
||||
@@ -938,34 +958,7 @@ const UniformityTable = () => {
|
||||
<div className='flex flex-col gap-4 mt-4'>
|
||||
{createdUniformity ? (
|
||||
<UniformityConfirmationPreview
|
||||
uniformity={{
|
||||
id: createdUniformity.id,
|
||||
location_name: createdUniformity.info_umum.lokasi_farm,
|
||||
flock_name: createdUniformity.info_umum.project_flock,
|
||||
kandang_name: createdUniformity.info_umum.kandang,
|
||||
applied_at: createdUniformity.info_umum.tanggal,
|
||||
week: 0,
|
||||
status: 'Pengajuan',
|
||||
uniformity: createdUniformity.result.uniformity,
|
||||
cv: createdUniformity.result.cv,
|
||||
chick_qty_of_weight:
|
||||
createdUniformity.sampling.chick_qty_of_weight,
|
||||
uniform_qty: createdUniformity.result.uniform_qty,
|
||||
mean_up: createdUniformity.sampling.mean_up,
|
||||
mean_down: createdUniformity.sampling.mean_down,
|
||||
standard_mean_weight: null,
|
||||
standard_uniformity: null,
|
||||
created_at: '',
|
||||
created_by: 0,
|
||||
project_flock_kandang_id: 0,
|
||||
created_user: {
|
||||
id: 0,
|
||||
id_user: 0,
|
||||
email: '',
|
||||
name: '',
|
||||
},
|
||||
updated_at: '',
|
||||
}}
|
||||
uniformityDetail={createdUniformity}
|
||||
/>
|
||||
) : selectedRowIds.length === 1 ? (
|
||||
<UniformityConfirmationPreview
|
||||
|
||||
@@ -689,6 +689,16 @@ const PurchaseOrderAcceptApprovalForm = ({
|
||||
accept='.pdf,.jpg,.jpeg,.png'
|
||||
onChange={(e) => {
|
||||
const files = Array.from(e.target.files || []);
|
||||
const invalidFiles = files.filter(
|
||||
(file) => file.size > 2 * 1024 * 1024
|
||||
);
|
||||
|
||||
if (invalidFiles.length > 0) {
|
||||
toast.error('Ukuran dokumen maksimal 2 MB!');
|
||||
e.target.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
formik.setFieldValue('travel_documents', files);
|
||||
}}
|
||||
onBlur={formik.handleBlur}
|
||||
|
||||
@@ -312,7 +312,8 @@ export const PurchaseRequestStaffApprovalFormInitialValues: PurchaseRequestStaff
|
||||
};
|
||||
|
||||
export const PurchaseRequestStaffApprovalFormDefaultValues = (
|
||||
purchase?: Purchase
|
||||
purchase?: Purchase,
|
||||
type?: 'add' | 'edit'
|
||||
): PurchaseRequestStaffApprovalFormSchemaType => {
|
||||
return {
|
||||
action: 'APPROVED',
|
||||
@@ -331,8 +332,18 @@ export const PurchaseRequestStaffApprovalFormDefaultValues = (
|
||||
label: item.warehouse?.name || '',
|
||||
},
|
||||
qty: item.sub_qty || item.qty || 0,
|
||||
price: item.price,
|
||||
total_price: item.total_price,
|
||||
price:
|
||||
type === 'add'
|
||||
? 'ProductPrice' in item.product
|
||||
? item.product.ProductPrice || item.price || ''
|
||||
: item.price
|
||||
: item.price,
|
||||
total_price:
|
||||
type === 'add'
|
||||
? ('ProductPrice' in item.product
|
||||
? item.product.ProductPrice || item.price || 0
|
||||
: item.price) * (item.sub_qty || item.qty || 0)
|
||||
: item.total_price,
|
||||
}))
|
||||
: [
|
||||
{
|
||||
@@ -381,7 +392,15 @@ export const PurchaseRequestAcceptApprovalFormSchema: Yup.ObjectSchema<PurchaseR
|
||||
.required('Item pembelian wajib diisi!')
|
||||
.typeError('Item pembelian wajib diisi!'),
|
||||
travel_documents: Yup.array()
|
||||
.of(Yup.mixed<File>().required())
|
||||
.of(
|
||||
Yup.mixed<File>()
|
||||
.required('Dokumen surat jalan wajib diupload!')
|
||||
.test('fileSize', 'Ukuran dokumen maksimal 2 MB', (value) => {
|
||||
if (!value) return true;
|
||||
if (value instanceof File) return value.size <= 2 * 1024 * 1024;
|
||||
return true;
|
||||
})
|
||||
)
|
||||
.required('Dokumen surat jalan wajib diupload!')
|
||||
.min(1, 'Minimal upload 1 dokumen surat jalan!')
|
||||
.typeError('Dokumen surat jalan wajib diupload!'),
|
||||
|
||||
@@ -294,9 +294,9 @@ const PurchaseOrderStaffApprovalForm = ({
|
||||
// ===== FORM CONFIGURATION =====
|
||||
const formikInitialValues = useMemo(() => {
|
||||
return initialValues
|
||||
? PurchaseRequestStaffApprovalFormDefaultValues(initialValues)
|
||||
? PurchaseRequestStaffApprovalFormDefaultValues(initialValues, type)
|
||||
: PurchaseRequestStaffApprovalFormInitialValues;
|
||||
}, [initialValues]);
|
||||
}, [initialValues, type]);
|
||||
|
||||
const formik = useFormik({
|
||||
initialValues: formikInitialValues,
|
||||
@@ -485,9 +485,18 @@ const PurchaseOrderStaffApprovalForm = ({
|
||||
},
|
||||
warehouse_id: purchaseItem.warehouse_id || 0,
|
||||
qty: originalItem?.qty || purchaseItem.quantity || 0,
|
||||
price: type === 'edit' && originalItem ? originalItem.price : '',
|
||||
price:
|
||||
type === 'edit' && originalItem
|
||||
? originalItem.price
|
||||
: originalItem?.product && 'ProductPrice' in originalItem.product
|
||||
? originalItem.product.ProductPrice || ''
|
||||
: '',
|
||||
total_price:
|
||||
type === 'edit' && originalItem ? originalItem.total_price : '',
|
||||
type === 'edit' && originalItem
|
||||
? originalItem.total_price
|
||||
: (originalItem?.product && 'ProductPrice' in originalItem.product
|
||||
? originalItem.product.ProductPrice || 0
|
||||
: 0) * (originalItem?.qty || purchaseItem.quantity || 0),
|
||||
};
|
||||
return itemData;
|
||||
});
|
||||
@@ -1140,6 +1149,7 @@ const PurchaseOrderStaffApprovalForm = ({
|
||||
color='warning'
|
||||
className='px-4'
|
||||
onClick={() => {
|
||||
formik.setValues(formikInitialValues);
|
||||
formik.resetForm();
|
||||
setPurchaseOrderFormErrorMessage('');
|
||||
onCancel?.();
|
||||
|
||||
Vendored
+2
@@ -10,6 +10,8 @@ export type BaseInventoryProduct = {
|
||||
name: string;
|
||||
brand: string;
|
||||
sku: string;
|
||||
ProductPrice: number;
|
||||
SellingPrice?: number;
|
||||
product_price: number;
|
||||
selling_price?: number;
|
||||
tax?: number;
|
||||
|
||||
+1
-3
@@ -1,7 +1,4 @@
|
||||
import { BaseMetadata } from '@/types/api/api-general';
|
||||
import { Location } from '@/types/api/location/location';
|
||||
import { ProjectFlock } from '@/types/api/project-flock/project-flock';
|
||||
import { Kandang } from '@/types/api/kandang/kandang';
|
||||
import { BaseApproval } from '@/types/api/approval/approval';
|
||||
|
||||
// ==================== GET ALL RESPONSE ====================
|
||||
@@ -11,6 +8,7 @@ export type Uniformity = BaseMetadata & {
|
||||
location_name: string;
|
||||
flock_name: string;
|
||||
kandang_name: string;
|
||||
file_name: string;
|
||||
applied_at: string;
|
||||
week: number;
|
||||
status: string;
|
||||
|
||||
Vendored
+2
@@ -10,6 +10,8 @@ export type PurchaseItemProduct = {
|
||||
id: number;
|
||||
name: string;
|
||||
flags?: string[];
|
||||
ProductPrice?: number;
|
||||
SellingPrice?: number;
|
||||
uom?: {
|
||||
name: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user