import React, { useState, useEffect, useRef, useCallback, useMemo } from 'react'; import { __, sprintf } from '@wordpress/i18n'; import { useNavigate, useParams } from 'react-router-dom'; import { is, isEmpty, isNil, sum, pathOr, head, pluck } from 'ramda'; import { klona } from 'klona'; import { wrap } from 'object-path-immutable'; import { evaluate } from 'mathjs'; import equal from 'fast-deep-equal'; import { useForm } from 'react-hook-form'; // store import { storeGet, storeSet, useStore } from '../../store'; // api import ApplicationEvaluationService from '../../service/application-evaluation-service'; import AmendmentsService from '../../service/amendments-service'; import AppointmentService from '../../service/appointment-service'; // tools import set404FromErrorResponse from '../../helpers/set404FromErrorResponse'; import { isCAP, isCodiceFiscale, isEmail, isEmailPEC, isIBAN, isMarcaDaBollo, isPIVA, isUrl, maxChecks, minChecks, nonEmptyTables } from '../../helpers/validators'; import formatDateString from '../../helpers/formatDateString'; import getTokens from '../../helpers/getTokens'; import parseCommaDecimal from '../../helpers/parseCommaDecimal'; import renderWithDataVars from '../../helpers/renderWithDataVars'; import renderHtmlContent from '../../helpers/renderHtmlContent'; // components import { Skeleton } from 'primereact/skeleton'; import { Button } from 'primereact/button'; import { Tag } from 'primereact/tag'; import { Checkbox } from 'primereact/checkbox'; import { Editor } from 'primereact/editor'; import { InputNumber } from 'primereact/inputnumber'; import { Toast } from 'primereact/toast'; import { Dialog } from 'primereact/dialog'; import HelpIcon from '../../icons/HelpIcon'; import { classNames } from 'primereact/utils'; import { InputTextarea } from 'primereact/inputtextarea'; import { InputText } from 'primereact/inputtext'; import ListOfFiles from '../DomandaEditPreInstructor/components/ListOfFiles'; import RepeaterFields from '../DomandaEditPreInstructor/components/RepeaterFields'; import ApplicationInfo from '../DomandaEditPreInstructor/components/ApplicationInfo'; import ApplicationDownloadFiles from '../DomandaEditPreInstructor/components/ApplicationDownloadFiles'; import FormField from '../../components/FormField'; const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID; const APP_HUB_ID = process.env.REACT_APP_HUB_ID; const DomandaEditInstructorManager = () => { const isAsyncRequest = useStore().main.isAsyncRequest(); const { id } = useParams(); const navigate = useNavigate(); const [data, setData] = useState({}); const [isVisibleCriterionData, setIsVisibleCriterionData] = useState(0); const [criterionDataTitle, setCriterionDataTitle] = useState(''); const [criterionDataContent, setCriterionDataContent] = useState(''); const [isAdmissible, setIsAdmissible] = useState(false); const [connectedSoccorsoId, setConnectedSoccorsoId] = useState(0); const toast = useRef(null); const [loading, setLoading] = useState(false); const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false); const [operationType, setOperationType] = useState(''); const [motivation, setMotivation] = useState(''); const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false); const [allFilesRated, setAllFilesRated] = useState(false); const [atLeastOneChecked, setAtLeastOneChecked] = useState(false); const [allChecksChecked, setAllChecksChecked] = useState(false); const [appointmentData, setAppointmentData] = useState({ title: '', text: '', duration: 0, amount: 0 }); const [formData, setFormData] = useState([]); const [formId, setFormId] = useState(0); const [formInitialData, setFormInitialData] = useState(null); const { control, handleSubmit, formState: { errors }, setValue, trigger, register, getValues, watch, reset } = useForm({ defaultValues: useMemo(() => { return formInitialData ? formInitialData : {} }, [formInitialData]), mode: 'onChange' }); const validationFns = { isPIVA, isCodiceFiscale, isCAP, isIBAN, isEmail, isEmailPEC, isUrl, isMarcaDaBollo, minChecks, maxChecks, nonEmptyTables } const values = getValues(); const formValues = watch(); const goToEvaluationsPage = () => { navigate('/mie-domande'); } const updateFlagsForSoccorso = useCallback((data) => { let nonRatedFilesLength = 0; if (data.files) { const nonRatedFiles = data.files .map(el => el.valid) .filter(v => isNil(v)); nonRatedFilesLength = nonRatedFiles.length; } if (data.amendmentDetails) { const nonRatedFiles = data.amendmentDetails .map(el => el.valid) .filter(v => isNil(v)); nonRatedFilesLength = nonRatedFiles.length; } setAllFilesRated(nonRatedFilesLength === 0); if (data.evaluationVersion === 'V1') { if (data.checklist) { const checkedChecklistItems = data.checklist .map(el => el.valid) .filter(v => v); setAtLeastOneChecked(checkedChecklistItems.length > 0); setAllChecksChecked(checkedChecklistItems.length === data.checklist.length) } } else if (data.evaluationVersion === 'V2') { const minChecks = data.numberOfCheck; const formFieldsChecklist = formData .filter(o => head(o.settings.filter(s => s.name === 'isChecklistItem' && s.value))) .map(o => o.id); if (formFieldsChecklist.length >= minChecks) { const valuesTotal = formFieldsChecklist.map(v => formValues[v]); const valuesFirst = valuesTotal.toSpliced(minChecks); setAtLeastOneChecked(valuesTotal.filter(v => v === true).length === valuesTotal.length); setAllChecksChecked(valuesFirst.filter(v => v === true).length === valuesFirst.length) } } }, [formValues]); const doNewSoccorso = () => { if (connectedSoccorsoId !== 0) { navigate(`/mie-domande/${id}/soccorso/${connectedSoccorsoId}`); } else { doSaveDraft(`/mie-domande/${id}/aggiungi-soccorso/`) } } const getVersion = (resp) => { if (resp.status === 'SUCCESS') { if (resp.data.evaluationVersion === 'V1') { storeSet.main.setAsyncRequest(); ApplicationEvaluationService.getEvaluationByApplId(getCallback, errGetCallback, [ ['applicationId', resp.data.applicationId] ]); } else if (resp.data.evaluationVersion === 'V2') { storeSet.main.setAsyncRequest(); ApplicationEvaluationService.getEvaluationV2ByApplId(getCallback, errGetCallback, [ ['applicationId', resp.data.applicationId] ]); } } storeSet.main.unsetAsyncRequest(); } const errGetVersion = (resp) => { if (toast.current && data.message) { toast.current.show({ severity: 'error', summary: '', detail: resp.message }); } set404FromErrorResponse(resp); storeSet.main.unsetAsyncRequest(); } const getCallback = (resp) => { if (resp.status === 'SUCCESS') { setData(getFormattedData(resp.data)); setMotivation(resp.data.motivation); updateFlagsForSoccorso(resp.data); if (resp.data.evaluationVersion === 'V2') { setFormData(resp.data.applicationEvaluationFormResponse.content); setFormId(resp.data.applicationEvaluationFormResponse.id); let formDataInitial = {}; if (resp.data.applicationEvaluationFormResponse.formFields) { const submitData = resp.data.applicationEvaluationFormResponse.formFields.map((o) => ({ fieldId: o.fieldId, fieldValue: o.fieldValue })); formDataInitial = submitData.reduce((acc, cur) => { if (cur.fieldValue) { acc[cur.fieldId] = cur.fieldValue; } return acc; }, formDataInitial); } reset(); setFormInitialData(formDataInitial); } } storeSet.main.unsetAsyncRequest(); } const errGetCallback = (resp) => { if (toast.current && resp.message) { toast.current.show({ severity: 'error', summary: '', detail: resp.message }); } set404FromErrorResponse(resp); storeSet.main.unsetAsyncRequest(); } const getFormattedData = (data) => { data.submissionDate = is(String, data.submissionDate) ? new Date(data.submissionDate) : (data.submissionDate ? data.submissionDate : ''); data.evaluationDate = is(String, data.evaluationDate) ? new Date(data.evaluationDate) : (data.evaluationDate ? data.evaluationDate : ''); return data; }; const renderHeader = () => { return ( ); }; const header = renderHeader(); const updateEvaluationValue = (value, path, maxValue = null) => { let finalValue = value; if (maxValue || maxValue === 0) { finalValue = value > maxValue ? maxValue : value; } const newData = wrap(data).set(path, finalValue).value(); setData(newData); updateFlagsForSoccorso(newData); } const getTransformedSubmitData = () => { const formValues = getValues(); const usedFieldsIds = pluck('id', formData); return Object.keys(formValues) .filter(v => usedFieldsIds.includes(v)) .reduce((acc, cur) => { const formField = head(formData.filter(o => o.id === cur)); let fieldVal = formValues[cur]; if (formValues[cur] && formValues[cur].toISOString) { fieldVal = formatDateString(formValues[cur]); } fieldVal = isEmpty(fieldVal) ? null : fieldVal; if (formField && formField.name === 'fileupload') { fieldVal = is(Array, fieldVal) ? fieldVal.map(o => o.id).join(',') : null; } acc.push({ 'fieldId': cur, 'fieldValue': fieldVal }); return acc; }, []); } const doSaveDraft = useCallback((doRedirect = '') => { if (data.evaluationVersion === 'V1') { const submitData = { criteria: klona(data.criteria), checklist: klona(data.checklist), files: klona(data.files), evaluationDocument: klona(data.evaluationDocument.map(o => ({ ...o, fileValue: o.fileValue[0] ? o.fileValue[0].id : '' }) )), amendmentDetails: klona(data.amendmentDetails), note: data.note }; ApplicationEvaluationService.updateEvaluation( data.assignedApplicationId, submitData, (data) => updateCallback(data, doRedirect), errUpdateCallback ); } else if (data.evaluationVersion === 'V2') { const newFormValues = getTransformedSubmitData(); const submitData = { formFields: newFormValues, files: klona(data.files), evaluationDocument: klona(data.evaluationDocument.map(o => ({ ...o, fileValue: o.fileValue[0] ? o.fileValue[0].id : '' }) )), amendmentDetails: klona(data.amendmentDetails), note: data.note } ApplicationEvaluationService.updateEvaluationV2( data.assignedApplicationId, formId, submitData, (data) => updateCallback(data, doRedirect), errUpdateCallback ); } }, [data]); const updateCallback = (data, doRedirect = '') => { if (data.status === 'SUCCESS') { setData(getFormattedData(data.data)); if (toast.current) { toast.current.show({ severity: 'success', summary: '', detail: data.message }); } if (!isEmpty(doRedirect)) { navigate(doRedirect); } } storeSet.main.unsetAsyncRequest(); } const errUpdateCallback = (data) => { if (toast.current && data.message) { toast.current.show({ severity: 'error', summary: '', detail: data.message }); } set404FromErrorResponse(data); storeSet.main.unsetAsyncRequest(); } const doApprove = () => { if (data.evaluationVersion === 'V1') { const submitData = { applicationStatus: 'APPROVED', criteria: klona(data.criteria), checklist: klona(data.checklist), files: klona(data.files), note: data.note, motivation } setLoading(true); setIsVisibleCompleteDialog(false); ApplicationEvaluationService.updateEvaluation( data.assignedApplicationId, submitData, updateStatusCallback, errUpdateStatusCallback ); } else if (data.evaluationVersion === 'V2') { const newFormValues = getTransformedSubmitData(); const submitData = { formFields: newFormValues, files: klona(data.files), evaluationDocument: klona(data.evaluationDocument.map(o => ({ ...o, fileValue: o.fileValue[0] ? o.fileValue[0].id : '' }) )), amendmentDetails: klona(data.amendmentDetails), note: data.note, motivation } setLoading(true); setIsVisibleCompleteDialog(false); ApplicationEvaluationService.updateEvaluationV2( data.assignedApplicationId, formId, submitData, updateStatusCallback, errUpdateStatusCallback ); } } const doReject = () => { if (data.evaluationVersion === 'V1') { const submitData = { applicationStatus: 'REJECTED', criteria: klona(data.criteria), checklist: klona(data.checklist), files: klona(data.files), note: data.note, motivation } setLoading(true); setIsVisibleCompleteDialog(false); ApplicationEvaluationService.updateEvaluation( data.assignedApplicationId, submitData, updateStatusCallback, errUpdateStatusCallback ); } else if (data.evaluationVersion === 'V2') { const newFormValues = getTransformedSubmitData(); const submitData = { formFields: newFormValues, files: klona(data.files), evaluationDocument: klona(data.evaluationDocument.map(o => ({ ...o, fileValue: o.fileValue[0] ? o.fileValue[0].id : '' }) )), amendmentDetails: klona(data.amendmentDetails), note: data.note, motivation } setLoading(true); setIsVisibleCompleteDialog(false); ApplicationEvaluationService.updateEvaluationV2( data.assignedApplicationId, formId, submitData, updateStatusCallback, errUpdateStatusCallback ); } } const updateStatusCallback = (data) => { if (data.status === 'SUCCESS') { setData(getFormattedData(data.data)); if (toast.current) { toast.current.show({ severity: 'success', summary: '', detail: data.message }); } } setLoading(false); } const errUpdateStatusCallback = (data) => { if (toast.current && data.message) { toast.current.show({ severity: 'error', summary: '', detail: data.message }); } set404FromErrorResponse(data); setLoading(false); } const displayCriterionData = (id) => { const criterion = head(data.criteria.filter(o => o.id === id)); setCriterionDataTitle(criterion.label); const content =
| {v} | )}
|---|
| {v} | )}
{__('Nessun documento allegato', 'gepafin')}
}{__('Nessun documento allegato', 'gepafin')}
}| {__('Parametro', 'gepafin')} | {__('Punteggio', 'gepafin')} | {__('Stato', 'gepafin')} |
|---|---|---|
| {o.label} |
|
{!isEmpty(o.criteriaMappedFields)
?
|
| {__('Punteggio:', 'gepafin')} | {sum(data.criteria.map(o => o.score))} |
{isAdmissible
? |
| {sprintf(__('Punteggio minimo per l\'ammissione: %d'), data.minScore)} | ||