diff --git a/src/components/pages/expense/ExpenseRealizationContent.tsx b/src/components/pages/expense/ExpenseRealizationContent.tsx new file mode 100644 index 00000000..b9199102 --- /dev/null +++ b/src/components/pages/expense/ExpenseRealizationContent.tsx @@ -0,0 +1,323 @@ +import { useFormik } from 'formik'; +import toast from 'react-hot-toast'; + +import Link from 'next/link'; +import { Icon } from '@iconify/react'; +import Button from '@/components/Button'; +import Card from '@/components/Card'; +import DropFileInput from '@/components/input/DropFileInput'; + +import { Expense } from '@/types/api/expense'; +import { formatCurrency, formatDate } from '@/lib/helper'; +import { + UploadRequestDocumentsFormSchema, + UploadRequestDocumentsFormValues, +} from '@/components/pages/expense/form/ExpenseRequestForm.schema'; +import { ExpenseApi } from '@/services/api/expense'; +import { isResponseSuccess } from '@/lib/api-helper'; +import { ACCEPTED_FILE_TYPE } from '@/config/constant'; + +interface ExpenseRealizationContentProps { + initialValues?: Expense; +} + +const ExpenseRealizationContent = ({ + initialValues, +}: ExpenseRealizationContentProps) => { + const formik = useFormik({ + initialValues: { + documents: [], + }, + validationSchema: UploadRequestDocumentsFormSchema, + onSubmit: async (values) => { + const addRealizationDocumentsRes = + await ExpenseApi.uploadRealizationDocuments( + initialValues?.id as number, + values.documents + ); + + if (isResponseSuccess(addRealizationDocumentsRes)) { + toast.success(addRealizationDocumentsRes.message); + window.location.reload(); + } else { + toast.error(String(addRealizationDocumentsRes?.message)); + } + }, + }); + + const realizationDocumentsChangeHandler = (val: File[]) => { + formik.setFieldTouched('documents', true); + formik.setFieldValue('documents', val); + }; + + const realizationDocumentsDeleteHandler = (deletedFileIdx: number) => { + const newRealizationDocuments = formik.values.documents; + + newRealizationDocuments?.splice(deletedFileIdx, 1); + + formik.setFieldValue('documents', newRealizationDocuments); + }; + + return ( +
+
+
+ {/* TODO: apply RBAC */} + +
+
+ +
+ + + + + + + + + + + + + +
Tanggal Realisasi: + {initialValues?.realization_date + ? formatDate(initialValues?.realization_date, 'DD MMMM YYYY') + : '-'} +
Dokumen Realisasi: +
+ {!initialValues?.realization_docs || + (initialValues?.realization_docs && + initialValues?.realization_docs.length === 0 && + '-')} + + {initialValues?.realization_docs && + initialValues?.realization_docs.length > 0 && ( +
    + {initialValues?.realization_docs.map( + (realizationDocument, realizationDocumentIdx) => ( +
  • + + {realizationDocument.path}{' '} + + +
  • + ) + )} +
+ )} +
+ +
+ + + {formik.values.documents && + formik.values.documents.length > 0 && ( + + )} +
+
+
+ +
+
+ +

Nominal Pengajuan

+ + + {formatCurrency(initialValues?.total_pengajuan as number)} + + + + Terbayar{' '} + {formatCurrency(initialValues?.total_realisasi as number)} + +
+ + +

Nominal Realisasi

+ + + {formatCurrency(initialValues?.total_realisasi as number)} + + + + Selisih{' '} + {formatCurrency( + (initialValues?.total_realisasi as number) - + (initialValues?.total_pengajuan as number) + )} + +
+
+
+ +
+

+ Rincian Pengajuan Biaya Operasional +

+ +
+ {initialValues?.kandangs.map((kandangExpense, kandangExpenseIdx) => { + let expenseGrandTotal = 0; + + kandangExpense.pengajuans?.forEach( + (item) => (expenseGrandTotal += item.total_price) + ); + + return ( +
+ + + + + + + + + + + + + + {kandangExpense.pengajuans?.map( + (pengajuanItem, pengajuanIdx) => ( + + + + + + + ) + )} + + + + + + + +
+ Biaya {kandangExpense.name} +
NonstockTotal KuantitasTotal BiayaCatatan
{pengajuanItem.nonstock.name}{pengajuanItem.qty}{formatCurrency(pengajuanItem.total_price)}{pengajuanItem.note ?? '-'}
+ Total Biaya Keseluruhan: + {formatCurrency(expenseGrandTotal)}
+
+ ); + })} +
+
+ +
+

+ Rincian Realisasi Biaya Operasional +

+ +
+ {initialValues?.kandangs.map((kandangExpense, kandangExpenseIdx) => { + let expenseGrandTotal = 0; + + kandangExpense.realisasi?.forEach( + (item) => (expenseGrandTotal += item.total_price) + ); + + return ( +
+ + + + + + + + + + + + + + {kandangExpense.realisasi?.map( + (realisasiItem, realisasiIdx) => ( + + + + + + + ) + )} + + + + + + + +
+ Biaya {kandangExpense.name} +
NonstockTotal KuantitasTotal BiayaCatatan
{realisasiItem.nonstock.name}{realisasiItem.qty}{formatCurrency(realisasiItem.total_price)}{realisasiItem.note ?? '-'}
+ Total Biaya Keseluruhan: + {formatCurrency(expenseGrandTotal)}
+
+ ); + })} +
+
+
+ ); +}; + +export default ExpenseRealizationContent;