- updated page for instructor manager;

This commit is contained in:
Vitalii Kiiko
2025-09-30 08:36:00 +02:00
parent 8bf4ea1264
commit 0ffe86789f
3 changed files with 299 additions and 84 deletions

1
.env
View File

@@ -4,6 +4,7 @@ REACT_APP_API_ADDRESS=https://api-dev-gepafin.memento.credit
REACT_APP_API_ADDRESS_WS=https://api-dev-gepafin.memento.credit/wss REACT_APP_API_ADDRESS_WS=https://api-dev-gepafin.memento.credit/wss
REACT_APP_LOGO_FILENAME=gepafin-logo.svg REACT_APP_LOGO_FILENAME=gepafin-logo.svg
REACT_APP_FAVICON_FILENAME=gepafin-favicon.ico REACT_APP_FAVICON_FILENAME=gepafin-favicon.ico
# t7jh5wfg9QXylNaTZkPoE - sviluppumbria | p4lk3bcx1RStqTaIVVbXs - gepafin
REACT_APP_HUB_ID=p4lk3bcx1RStqTaIVVbXs REACT_APP_HUB_ID=p4lk3bcx1RStqTaIVVbXs
REACT_APP_EVALUATION_FLOW_ID=1 REACT_APP_EVALUATION_FLOW_ID=1
REACT_APP_LOCAL_DEVELOPMENT=1 REACT_APP_LOCAL_DEVELOPMENT=1

View File

@@ -4,9 +4,9 @@ import { useNavigate, useParams } from 'react-router-dom';
import { is, isEmpty, isNil, sum, pathOr, head, pluck } from 'ramda'; import { is, isEmpty, isNil, sum, pathOr, head, pluck } from 'ramda';
import { klona } from 'klona'; import { klona } from 'klona';
import { wrap } from 'object-path-immutable'; import { wrap } from 'object-path-immutable';
import { useForm } from 'react-hook-form';
import { evaluate } from 'mathjs'; import { evaluate } from 'mathjs';
import equal from 'fast-deep-equal'; import equal from 'fast-deep-equal';
import { useForm } from 'react-hook-form';
// store // store
import { storeGet, storeSet, useStoreValue } from '../../store'; import { storeGet, storeSet, useStoreValue } from '../../store';
@@ -44,6 +44,7 @@ import { InputNumber } from 'primereact/inputnumber';
import { Toast } from 'primereact/toast'; import { Toast } from 'primereact/toast';
import { Dialog } from 'primereact/dialog'; import { Dialog } from 'primereact/dialog';
import HelpIcon from '../../icons/HelpIcon'; import HelpIcon from '../../icons/HelpIcon';
import BlockingOverlay from '../../components/BlockingOverlay';
import { classNames } from 'primereact/utils'; import { classNames } from 'primereact/utils';
import { InputTextarea } from 'primereact/inputtextarea'; import { InputTextarea } from 'primereact/inputtextarea';
import { InputText } from 'primereact/inputtext'; import { InputText } from 'primereact/inputtext';
@@ -54,6 +55,7 @@ import ApplicationDownloadFiles from '../DomandaEditPreInstructor/components/App
import FormField from '../../components/FormField'; import FormField from '../../components/FormField';
import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails'; import SoccorsoResendEmails from '../SoccorsoEditPreInstructor/components/SoccorsoResendEmails';
import EvaluationReAdmit from '../DomandaEditPreInstructor/components/EvaluationReAdmit'; import EvaluationReAdmit from '../DomandaEditPreInstructor/components/EvaluationReAdmit';
import { SplitButton } from 'primereact/splitbutton';
const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID; const APP_EVALUATION_FLOW_ID = process.env.REACT_APP_EVALUATION_FLOW_ID;
const APP_HUB_ID = process.env.REACT_APP_HUB_ID; const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
@@ -69,12 +71,19 @@ const DomandaEditInstructorManager = () => {
const [isAdmissible, setIsAdmissible] = useState(false); const [isAdmissible, setIsAdmissible] = useState(false);
const [connectedSoccorsoId, setConnectedSoccorsoId] = useState(0); const [connectedSoccorsoId, setConnectedSoccorsoId] = useState(0);
const toast = useRef(null); const toast = useRef(null);
const tecFinBtnRef = useRef(null);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false); const [isVisibleCompleteDialog, setIsVisibleCompleteDialog] = useState(false);
const [operationType, setOperationType] = useState(''); const [operationType, setOperationType] = useState('');
const [motivation, setMotivation] = useState(''); const [motivation, setMotivation] = useState('');
const [amountAccepted, setAmountAccepted] = useState(0); const [amountAccepted, setAmountAccepted] = useState(0);
const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false); const [isVisibleAppointmentDialog, setIsVisibleAppointmentDialog] = useState(false);
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
const [preTecEvalData, setPreTecEvalData] = useState({
type: 0,
pec: '',
amount: 0
});
const [allFilesRated, setAllFilesRated] = useState(false); const [allFilesRated, setAllFilesRated] = useState(false);
const [atLeastOneChecked, setAtLeastOneChecked] = useState(false); const [atLeastOneChecked, setAtLeastOneChecked] = useState(false);
const [allChecksChecked, setAllChecksChecked] = useState(false); const [allChecksChecked, setAllChecksChecked] = useState(false);
@@ -276,6 +285,40 @@ const DomandaEditInstructorManager = () => {
}; };
const header = renderHeader(); const header = renderHeader();
const technicalEvalItems = [
{
label: __('Nessuna garanzia', 'gepafin'),
icon: 'pi pi-pen-to-square',
command: () => {
setPreTecEvalData(prev => ({ ...prev, type: 1 }));
setIsVisiblePreTecEvalDialog(true);
}
},
{
label: __('Garanzia MCC', 'gepafin'),
icon: 'pi pi-pen-to-square',
command: () => {
setPreTecEvalData(prev => ({ ...prev, type: 2 }));
setIsVisiblePreTecEvalDialog(true);
}
},
{
label: __('Garanzia MCC Start-Up', 'gepafin'),
icon: 'pi pi-pen-to-square',
command: () => {
setPreTecEvalData(prev => ({ ...prev, type: 3 }));
setIsVisiblePreTecEvalDialog(true);
}
},
{
label: __('Altre garanzie (fideiussioni)', 'gepafin'),
icon: 'pi pi-pen-to-square',
command: () => {
setPreTecEvalData(prev => ({ ...prev, type: 4 }));
setIsVisiblePreTecEvalDialog(true);
}
}
]
const updateEvaluationValue = (value, path, maxValue = null) => { const updateEvaluationValue = (value, path, maxValue = null) => {
let finalValue = value; let finalValue = value;
@@ -579,6 +622,8 @@ const DomandaEditInstructorManager = () => {
if (data.status === 'SUCCESS') { if (data.status === 'SUCCESS') {
if (data.data.length) { if (data.data.length) {
setConnectedSoccorsoId(data.data[0].id); setConnectedSoccorsoId(data.data[0].id);
} else {
setConnectedSoccorsoId(0);
} }
} }
} }
@@ -700,7 +745,7 @@ const DomandaEditInstructorManager = () => {
setIsVisibleAppointmentDialog(true); setIsVisibleAppointmentDialog(true);
} }
const setFieldValue = (name, value) => { const setAppointmentFieldValue = (name, value) => {
const newData = wrap(appointmentData).set(name, value).value(); const newData = wrap(appointmentData).set(name, value).value();
setAppointmentData(newData); setAppointmentData(newData);
} }
@@ -724,6 +769,30 @@ const DomandaEditInstructorManager = () => {
</div> </div>
} }
const setPreTecEvalFieldValue = (name, value) => {
const newData = wrap(preTecEvalData).set(name, value).value();
setPreTecEvalData(newData);
}
const headerPreTecEvalDialog = () => {
return <span>{__('Valutazione Tecnico-Finanziaria', 'gepafin')}</span>;
}
const hidePreTecEvalDialog = () => {
setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({});
}
const footerPreTecEvalDialog = () => {
return <div>
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hidePreTecEvalDialog} outlined/>
<Button
type="button"
disabled={loading}
label={__('Invia', 'gepafin')} onClick={hidePreTecEvalDialog}/>
</div>
}
const doCreateAppointmentRequest = () => { const doCreateAppointmentRequest = () => {
if ( if (
!isEmpty(appointmentData.title) && !isEmpty(appointmentData.text) && !isEmpty(appointmentData.amount) !isEmpty(appointmentData.title) && !isEmpty(appointmentData.text) && !isEmpty(appointmentData.amount)
@@ -796,9 +865,9 @@ const DomandaEditInstructorManager = () => {
} }
const shouldDisableNewSoccorso = () => { const shouldDisableNewSoccorso = () => {
if (data.evaluationVersion === 'V1') { if (APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE') {
return !allFilesRated || !atLeastOneChecked; return !data.ndg || !data.appointmentId || !allFilesRated || !atLeastOneChecked;
} else if (data.evaluationVersion === 'V2') { } else if (APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE') {
return !allFilesRated || !atLeastOneChecked; return !allFilesRated || !atLeastOneChecked;
} else { } else {
return true; return true;
@@ -812,7 +881,11 @@ const DomandaEditInstructorManager = () => {
const actionBtns = () => { const actionBtns = () => {
return <div className="appPageSection__actions"> return <div className="appPageSection__actions">
{['EVALUATION', 'SOCCORSO', 'CLOSE'].includes(data.applicationStatus) {(['SOCCORSO', 'CLOSE', 'EVALUATION', 'NDG', 'APPOINTMENT', 'ADMISSIBLE',
'AWAITING_TECHNICAL_EVALUATION', 'TECHNICAL_EVALUATION'].includes(data.applicationStatus)
&& APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE')
|| (['SOCCORSO', 'CLOSE', 'EVALUATION', 'ADMISSIBLE', 'TECHNICAL_EVALUATION'].includes(data.applicationStatus)
&& APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE')
? <Button ? <Button
type="button" type="button"
disabled={!data.id || data.status === 'CLOSE' disabled={!data.id || data.status === 'CLOSE'
@@ -821,7 +894,7 @@ const DomandaEditInstructorManager = () => {
onClick={doNewSoccorso} onClick={doNewSoccorso}
outlined outlined
label={<> label={<>
{data.applicationStatus === 'EVALUATION' {connectedSoccorsoId === 0
? __('Richiedi soccorso istruttorio', 'gepafin') ? __('Richiedi soccorso istruttorio', 'gepafin')
: __('Apri soccorso istruttorio', 'gepafin')} : __('Apri soccorso istruttorio', 'gepafin')}
<i style={{ marginLeft: 7 }}> <i style={{ marginLeft: 7 }}>
@@ -846,7 +919,7 @@ const DomandaEditInstructorManager = () => {
&& APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' && APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
? <Button ? <Button
type="button" type="button"
disabled={!data.id || !allFilesRated || !allChecksChecked disabled={!data.id
|| !['EVALUATION'].includes(data.applicationStatus) || evaluationBlockedForUser(data)} || !['EVALUATION'].includes(data.applicationStatus) || evaluationBlockedForUser(data)}
onClick={doCheckNDG} onClick={doCheckNDG}
label={__('Controlla NDG', 'gepafin')} label={__('Controlla NDG', 'gepafin')}
@@ -858,15 +931,37 @@ const DomandaEditInstructorManager = () => {
onClick={doCreateAppointment} onClick={doCreateAppointment}
label={__('Crea l\'appuntamento', 'gepafin')} label={__('Crea l\'appuntamento', 'gepafin')}
/> : null} /> : null}
<Button {APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
? <Button
type="button" type="button"
disabled={!data.id || !['APPOINTMENT'].includes(data.applicationStatus) || evaluationBlockedForUser(data)} disabled={!data.id || !allFilesRated || !allChecksChecked
|| !['APPOINTMENT'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
onClick={doMakeAdmisible} onClick={doMakeAdmisible}
label={__('Ammissibile formalmente', 'gepafin')} label={__('Ammissibile formalmente', 'gepafin')}
/> />
<Button : <Button
type="button" type="button"
disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data)} disabled={!data.id || !allFilesRated || !allChecksChecked
|| evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
onClick={doMakeAdmisible}
label={__('Ammissibile formalmente', 'gepafin')}
/>}
{APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE'
? <Button
type="button"
disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
onClick={doPassTechnicalEvaluation}
icon="pi pi-info-circle" iconPos="right"
tooltip={isAdmissible
? __('Punteggio sufficiente per passaggio alla valutazione tecnica ed economico finanziaria', 'gepafin')
: __('Punteggio non sufficiente per passaggio alla valutazione tecnica ed economico finanziaria', 'gepafin')}
severity={isAdmissible ? 'success' : 'warning'}
label={__('Valutazione tecnico-finanziaria positiva', 'gepafin')}
/> : null}
{APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' && data.applicationStatus === 'AWAITING_TECHNICAL_EVALUATION'
? <Button
type="button"
disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
onClick={doPassTechnicalEvaluation} onClick={doPassTechnicalEvaluation}
icon="pi pi-info-circle" iconPos="right" icon="pi pi-info-circle" iconPos="right"
tooltip={isAdmissible tooltip={isAdmissible
@@ -875,6 +970,15 @@ const DomandaEditInstructorManager = () => {
severity={isAdmissible ? 'success' : 'warning'} severity={isAdmissible ? 'success' : 'warning'}
label={__('Valutazione tecnico-finanziaria positiva', 'gepafin')} label={__('Valutazione tecnico-finanziaria positiva', 'gepafin')}
/> />
: APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
? <SplitButton
ref={tecFinBtnRef}
disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
label={__('Valutazione tecnico-finanziaria', 'gepafin')}
onClick={(e) => {
tecFinBtnRef.current.show(e);
}}
model={technicalEvalItems}/> : null}
<Button <Button
type="button" type="button"
disabled={!data.id || !['TECHNICAL_EVALUATION'].includes(data.applicationStatus) || evaluationBlockedForUser(data)} disabled={!data.id || !['TECHNICAL_EVALUATION'].includes(data.applicationStatus) || evaluationBlockedForUser(data)}
@@ -887,19 +991,22 @@ const DomandaEditInstructorManager = () => {
? <Button ? <Button
type="button" type="button"
disabled={!isAdmissible disabled={!isAdmissible
|| ['APPROVED'].includes(data.applicationStatus) || ['APPROVED', 'REJECTED'].includes(data.applicationStatus)
|| evaluationBlockedForUser(data) || evaluationBlockedForUser(data)
|| (APP_EVALUATION_FLOW_ID === '1' && !['ADMISSIBLE', 'TECHNICAL_EVALUATION'].includes(data.applicationStatus)) || (APP_EVALUATION_FLOW_ID === '1' && !['TECHNICAL_EVALUATION'].includes(data.applicationStatus))
|| connectedSoccorsoId !== 0
} }
onClick={initiateApproving} onClick={initiateApproving}
label={__('Domanda deliberata', 'gepafin')} label={__('Domanda in Graduatoria Definitiva', 'gepafin')}
icon="pi pi-check" iconPos="right"/> : null} icon="pi pi-check" iconPos="right"/> : null}
{data.id {data.id
? <Button ? <Button
type="button" type="button"
disabled={APP_EVALUATION_FLOW_ID === '1' disabled={['APPROVED', 'REJECTED'].includes(data.applicationStatus)
&& (!['EVALUATION', 'ADMISSIBLE', 'NDG', 'APPOINTMENT'].includes(data.applicationStatus) || (APP_EVALUATION_FLOW_ID === '1'
|| evaluationBlockedForUser(data))} && (!['EVALUATION', 'ADMISSIBLE', 'APPOINTMENT'].includes(data.applicationStatus)
|| evaluationBlockedForUser(data)))
}
onClick={initiateRejecting} onClick={initiateRejecting}
label={__('Respingi domanda', 'gepafin')} label={__('Respingi domanda', 'gepafin')}
icon="pi pi-times" iconPos="right"/> : null} icon="pi pi-times" iconPos="right"/> : null}
@@ -951,6 +1058,7 @@ const DomandaEditInstructorManager = () => {
console.error('Error in formula', formula) console.error('Error in formula', formula)
context = {} context = {}
} }
const mathFormula = renderWithDataVars(formula.value, context); const mathFormula = renderWithDataVars(formula.value, context);
try { try {
updatedFormValues[o.id] = evaluate(mathFormula); updatedFormValues[o.id] = evaluate(mathFormula);
@@ -1009,6 +1117,7 @@ const DomandaEditInstructorManager = () => {
<div className="appPage__spacer"></div> <div className="appPage__spacer"></div>
<Toast ref={toast}/> <Toast ref={toast}/>
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
<div className="appPageSection__row"> <div className="appPageSection__row">
<Button <Button
@@ -1290,10 +1399,10 @@ const DomandaEditInstructorManager = () => {
<td> <td>
{isAdmissible {isAdmissible
? <Tag icon="pi pi-check" severity="success" ? <Tag icon="pi pi-check" severity="success"
value={__('Punteggio sufficiente per passaggio alla valutazione tecnica ed economico finanziaria')}></Tag> : null} value={__('Punteggio sufficiente per passaggio alla valutazione tecnica ed economico finanziaria', 'gepafin')}></Tag> : null}
{!isAdmissible {!isAdmissible
? <Tag icon="pi pi-times" severity="warning" ? <Tag icon="pi pi-times" severity="warning"
value={__('Punteggio non sufficiente per passaggio alla valutazione tecnica ed economico finanziaria')}></Tag> : null} value={__('Punteggio non sufficiente per passaggio alla valutazione tecnica ed economico finanziaria', 'gepafin')}></Tag> : null}
</td> </td>
</tr> </tr>
</tbody> </tbody>
@@ -1373,9 +1482,10 @@ const DomandaEditInstructorManager = () => {
</label> </label>
<InputNumber <InputNumber
value={appointmentData.amount} value={appointmentData.amount}
keyfilter="int" locale="it-IT"
minFractionDigits={2}
invalid={isEmpty(appointmentData.amount) || appointmentData.amount === 0} invalid={isEmpty(appointmentData.amount) || appointmentData.amount === 0}
onChange={(e) => setFieldValue('amount', e.value)}/> onChange={(e) => setAppointmentFieldValue('amount', e.value)}/>
</div> </div>
<div className="appForm__field"> <div className="appForm__field">
<label <label
@@ -1386,7 +1496,7 @@ const DomandaEditInstructorManager = () => {
value={appointmentData.duration} value={appointmentData.duration}
keyfilter="int" keyfilter="int"
invalid={isEmpty(appointmentData.duration) || appointmentData.duration === 0} invalid={isEmpty(appointmentData.duration) || appointmentData.duration === 0}
onChange={(e) => setFieldValue('duration', e.value)}/> onChange={(e) => setAppointmentFieldValue('duration', e.value)}/>
</div> </div>
<div className="appForm__field"> <div className="appForm__field">
<label className={classNames({ 'p-error': isEmpty(appointmentData.title) })}> <label className={classNames({ 'p-error': isEmpty(appointmentData.title) })}>
@@ -1395,7 +1505,7 @@ const DomandaEditInstructorManager = () => {
<InputText <InputText
value={appointmentData.title} value={appointmentData.title}
invalid={isEmpty(appointmentData.title)} invalid={isEmpty(appointmentData.title)}
onChange={(e) => setFieldValue('title', e.target.value)}/> onChange={(e) => setAppointmentFieldValue('title', e.target.value)}/>
</div> </div>
<div className="appForm__field"> <div className="appForm__field">
<label className={classNames({ 'p-error': isEmpty(appointmentData.text) })}> <label className={classNames({ 'p-error': isEmpty(appointmentData.text) })}>
@@ -1404,12 +1514,89 @@ const DomandaEditInstructorManager = () => {
<InputTextarea <InputTextarea
value={appointmentData.text} value={appointmentData.text}
invalid={isEmpty(appointmentData.text)} invalid={isEmpty(appointmentData.text)}
onChange={(e) => setFieldValue('text', e.target.value)} onChange={(e) => setAppointmentFieldValue('text', e.target.value)}
rows={3} rows={3}
cols={30}/> cols={30}/>
</div> </div>
</Dialog> </Dialog>
<Dialog
visible={isVisiblePreTecEvalDialog}
modal
header={headerPreTecEvalDialog}
footer={footerPreTecEvalDialog}
style={{ maxWidth: '600px', width: '100%' }}
onHide={hidePreTecEvalDialog}>
<div className="appForm__field">
<label
className={classNames({ 'p-error': isEmpty(preTecEvalData.amount) || preTecEvalData.amount === 0 })}>
{__('Importo', 'gepafin')}
</label>
<InputNumber
value={preTecEvalData.amount}
locale="it-IT"
minFractionDigits={2}
invalid={isEmpty(preTecEvalData.amount) || preTecEvalData.amount === 0}
onChange={(e) => setPreTecEvalFieldValue('amount', e.value)}/>
</div>
<div className="appForm__field">
<label className={classNames({ 'p-error': isEmpty(preTecEvalData.pec) })}>
{__('PEC', 'gepafin')}
</label>
<InputText
value={preTecEvalData.title}
invalid={isEmpty(preTecEvalData.title)}
onChange={(e) => setPreTecEvalFieldValue('pec', e.target.value)}/>
</div>
{/*<div className="appForm__field">
<label>
{__('Files', 'gepafin')}
</label>
<div className="file-upload-container">
{(preTecEvalData.files || []).map((file, index) => (
<div key={index} className="file-upload-item">
<span className="file-name">
<i className="pi pi-file"></i>
{file.name}
</span>
<button
type="button"
className="p-button p-button-sm p-button-danger p-button-text"
onClick={() => {
const newFiles = [...(preTecEvalData.files || [])];
newFiles.splice(index, 1);
setPreTecEvalFieldValue('files', newFiles);
}}
>
<i className="pi pi-times"></i>
</button>
</div>
))}
<div>
<input
type="file"
id="file-upload"
style={{ display: 'none' }}
multiple
onChange={(e) => {
const newFiles = Array.from(e.target.files);
const existingFiles = preTecEvalData.files || [];
setPreTecEvalFieldValue('files', [...existingFiles, ...newFiles]);
e.target.value = '';
}}
/>
<label
htmlFor="file-upload"
className="file-upload-button"
>
<i className="pi pi-upload"></i>
{__('Add Files', 'gepafin')}
</label>
</div>
</div>
</div>*/}
</Dialog>
</div> </div>
: <> : <>
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton> <Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>

View File

@@ -28,11 +28,11 @@ import {
isPIVA, isPIVA,
isUrl, maxChecks, minChecks, nonEmptyTables isUrl, maxChecks, minChecks, nonEmptyTables
} from '../../helpers/validators'; } from '../../helpers/validators';
import formatDateString from '../../helpers/formatDateString';
import getTokens from '../../helpers/getTokens'; import getTokens from '../../helpers/getTokens';
import parseCommaDecimal from '../../helpers/parseCommaDecimal'; import parseCommaDecimal from '../../helpers/parseCommaDecimal';
import renderWithDataVars from '../../helpers/renderWithDataVars'; import renderWithDataVars from '../../helpers/renderWithDataVars';
import renderHtmlContent from '../../helpers/renderHtmlContent'; import renderHtmlContent from '../../helpers/renderHtmlContent';
import formatDateString from '../../helpers/formatDateString';
// components // components
import { Skeleton } from 'primereact/skeleton'; import { Skeleton } from 'primereact/skeleton';
@@ -135,6 +135,7 @@ const DomandaEditPreInstructor = () => {
const updateFlagsForSoccorso = useCallback((data) => { const updateFlagsForSoccorso = useCallback((data) => {
let nonRatedFilesLength = 0; let nonRatedFilesLength = 0;
let nonRatedAmmendFilesLength = 0;
if (data.files) { if (data.files) {
const nonRatedFiles = data.files const nonRatedFiles = data.files
@@ -147,10 +148,10 @@ const DomandaEditPreInstructor = () => {
const nonRatedFiles = data.amendmentDetails const nonRatedFiles = data.amendmentDetails
.map(el => el.valid) .map(el => el.valid)
.filter(v => isNil(v)); .filter(v => isNil(v));
nonRatedFilesLength = nonRatedFiles.length; nonRatedAmmendFilesLength = nonRatedFiles.length;
} }
setAllFilesRated(nonRatedFilesLength === 0); setAllFilesRated(nonRatedFilesLength === 0 && nonRatedAmmendFilesLength === 0);
if (data.evaluationVersion === 'V1') { if (data.evaluationVersion === 'V1') {
if (data.checklist) { if (data.checklist) {
@@ -289,7 +290,7 @@ const DomandaEditPreInstructor = () => {
label: __('Nessuna garanzia', 'gepafin'), label: __('Nessuna garanzia', 'gepafin'),
icon: 'pi pi-pen-to-square', icon: 'pi pi-pen-to-square',
command: () => { command: () => {
setPreTecEvalData(prev => ({...prev, type: 1})); setPreTecEvalData(prev => ({ ...prev, type: 1 }));
setIsVisiblePreTecEvalDialog(true); setIsVisiblePreTecEvalDialog(true);
} }
}, },
@@ -297,7 +298,7 @@ const DomandaEditPreInstructor = () => {
label: __('Garanzia MCC', 'gepafin'), label: __('Garanzia MCC', 'gepafin'),
icon: 'pi pi-pen-to-square', icon: 'pi pi-pen-to-square',
command: () => { command: () => {
setPreTecEvalData(prev => ({...prev, type: 2})); setPreTecEvalData(prev => ({ ...prev, type: 2 }));
setIsVisiblePreTecEvalDialog(true); setIsVisiblePreTecEvalDialog(true);
} }
}, },
@@ -305,7 +306,7 @@ const DomandaEditPreInstructor = () => {
label: __('Garanzia MCC Start-Up', 'gepafin'), label: __('Garanzia MCC Start-Up', 'gepafin'),
icon: 'pi pi-pen-to-square', icon: 'pi pi-pen-to-square',
command: () => { command: () => {
setPreTecEvalData(prev => ({...prev, type: 3})); setPreTecEvalData(prev => ({ ...prev, type: 3 }));
setIsVisiblePreTecEvalDialog(true); setIsVisiblePreTecEvalDialog(true);
} }
}, },
@@ -313,7 +314,7 @@ const DomandaEditPreInstructor = () => {
label: __('Altre garanzie (fideiussioni)', 'gepafin'), label: __('Altre garanzie (fideiussioni)', 'gepafin'),
icon: 'pi pi-pen-to-square', icon: 'pi pi-pen-to-square',
command: () => { command: () => {
setPreTecEvalData(prev => ({...prev, type: 4})); setPreTecEvalData(prev => ({ ...prev, type: 4 }));
setIsVisiblePreTecEvalDialog(true); setIsVisiblePreTecEvalDialog(true);
} }
} }
@@ -460,6 +461,7 @@ const DomandaEditPreInstructor = () => {
} else if (data.evaluationVersion === 'V2') { } else if (data.evaluationVersion === 'V2') {
const newFormValues = getTransformedSubmitData(); const newFormValues = getTransformedSubmitData();
const submitData = { const submitData = {
applicationStatus: 'APPROVED',
formFields: newFormValues, formFields: newFormValues,
files: klona(data.files), files: klona(data.files),
evaluationDocument: klona(data.evaluationDocument.map(o => ({ evaluationDocument: klona(data.evaluationDocument.map(o => ({
@@ -858,17 +860,17 @@ const DomandaEditPreInstructor = () => {
}, [isAdmissible]); }, [isAdmissible]);
const evaluationBlockedForUser = (data = {}) => { const evaluationBlockedForUser = (data = {}) => {
const userData = storeGet('userData') const userData = storeGet('userData');
return isAsyncRequest || userData.id !== data.assignedUserId; return isAsyncRequest || userData.id !== data.assignedUserId;
} }
const shouldDisableNewSoccorso = () => { const shouldDisableNewSoccorso = () => {
if (data.evaluationVersion === 'V1') { if (APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE') {
return !data.ndg || !data.appointmentId || !allFilesRated || !atLeastOneChecked;
} else if (data.evaluationVersion === 'V2') {
return !data.ndg || !data.appointmentId || !allFilesRated || !atLeastOneChecked; return !data.ndg || !data.appointmentId || !allFilesRated || !atLeastOneChecked;
} else if (APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE') {
return !allFilesRated || !atLeastOneChecked;
} else { } else {
return false; return true;
} }
} }
@@ -879,7 +881,11 @@ const DomandaEditPreInstructor = () => {
const actionBtns = () => { const actionBtns = () => {
return <div className="appPageSection__actions"> return <div className="appPageSection__actions">
{['SOCCORSO', 'CLOSE', 'EVALUATION', 'NDG', 'APPOINTMENT', 'ADMISSIBLE', 'AWAITING_TECHNICAL_EVALUATION', 'TECHNICAL_EVALUATION'].includes(data.applicationStatus) {(['SOCCORSO', 'CLOSE', 'EVALUATION', 'NDG', 'APPOINTMENT', 'ADMISSIBLE',
'AWAITING_TECHNICAL_EVALUATION', 'TECHNICAL_EVALUATION'].includes(data.applicationStatus)
&& APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE')
|| (['SOCCORSO', 'CLOSE', 'EVALUATION', 'ADMISSIBLE', 'TECHNICAL_EVALUATION'].includes(data.applicationStatus)
&& APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE')
? <Button ? <Button
type="button" type="button"
disabled={!data.id || data.status === 'CLOSE' disabled={!data.id || data.status === 'CLOSE'
@@ -925,14 +931,34 @@ const DomandaEditPreInstructor = () => {
onClick={doCreateAppointment} onClick={doCreateAppointment}
label={__('Crea l\'appuntamento', 'gepafin')} label={__('Crea l\'appuntamento', 'gepafin')}
/> : null} /> : null}
<Button {APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
? <Button
type="button" type="button"
disabled={!data.id || !allFilesRated || !allChecksChecked disabled={!data.id || !allFilesRated || !allChecksChecked
|| !['APPOINTMENT'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0} || !['APPOINTMENT'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
onClick={doMakeAdmisible} onClick={doMakeAdmisible}
label={__('Ammissibile formalmente', 'gepafin')} label={__('Ammissibile formalmente', 'gepafin')}
/> />
{data.applicationStatus === 'AWAITING_TECHNICAL_EVALUATION' : <Button
type="button"
disabled={!data.id || !allFilesRated || !allChecksChecked
|| evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
onClick={doMakeAdmisible}
label={__('Ammissibile formalmente', 'gepafin')}
/>}
{APP_HUB_ID === 't7jh5wfg9QXylNaTZkPoE'
? <Button
type="button"
disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
onClick={doPassTechnicalEvaluation}
icon="pi pi-info-circle" iconPos="right"
tooltip={isAdmissible
? __('Punteggio sufficiente per passaggio alla valutazione tecnica ed economico finanziaria', 'gepafin')
: __('Punteggio non sufficiente per passaggio alla valutazione tecnica ed economico finanziaria', 'gepafin')}
severity={isAdmissible ? 'success' : 'warning'}
label={__('Valutazione tecnico-finanziaria positiva', 'gepafin')}
/> : null}
{APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' && data.applicationStatus === 'AWAITING_TECHNICAL_EVALUATION'
? <Button ? <Button
type="button" type="button"
disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0} disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
@@ -944,14 +970,15 @@ const DomandaEditPreInstructor = () => {
severity={isAdmissible ? 'success' : 'warning'} severity={isAdmissible ? 'success' : 'warning'}
label={__('Valutazione tecnico-finanziaria positiva', 'gepafin')} label={__('Valutazione tecnico-finanziaria positiva', 'gepafin')}
/> />
: <SplitButton : APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
? <SplitButton
ref={tecFinBtnRef} ref={tecFinBtnRef}
disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0} disabled={!data.id || !['ADMISSIBLE'].includes(data.applicationStatus) || evaluationBlockedForUser(data) || connectedSoccorsoId !== 0}
label={__('Valutazione tecnico-finanziaria', 'gepafin')} label={__('Valutazione tecnico-finanziaria', 'gepafin')}
onClick={(e) => { onClick={(e) => {
tecFinBtnRef.current.show(e); tecFinBtnRef.current.show(e);
}} }}
model={technicalEvalItems}/>} model={technicalEvalItems}/> : null}
<Button <Button
type="button" type="button"
disabled={!data.id || !['TECHNICAL_EVALUATION'].includes(data.applicationStatus) || evaluationBlockedForUser(data)} disabled={!data.id || !['TECHNICAL_EVALUATION'].includes(data.applicationStatus) || evaluationBlockedForUser(data)}