- added better amount field validation;

- removed field PEC;
This commit is contained in:
Vitalii Kiiko
2025-10-02 09:51:10 +02:00
parent facc022f3a
commit 5cbfc11a50
2 changed files with 66 additions and 138 deletions

View File

@@ -5,7 +5,7 @@ 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 { useForm } from 'react-hook-form';
import { evaluate } from 'mathjs'; import { evaluate, isNaN } from 'mathjs';
import equal from 'fast-deep-equal'; import equal from 'fast-deep-equal';
// store // store
@@ -81,7 +81,6 @@ const DomandaEditInstructorManager = () => {
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false); const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
const [preTecEvalData, setPreTecEvalData] = useState({ const [preTecEvalData, setPreTecEvalData] = useState({
amendmentDocumentType: '', amendmentDocumentType: '',
pec: '',
amount: 0 amount: 0
}); });
const [allFilesRated, setAllFilesRated] = useState(false); const [allFilesRated, setAllFilesRated] = useState(false);
@@ -780,18 +779,22 @@ const DomandaEditInstructorManager = () => {
const hidePreTecEvalDialog = () => { const hidePreTecEvalDialog = () => {
setIsVisiblePreTecEvalDialog(false); setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({}); setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
});
} }
const footerPreTecEvalDialog = () => { const footerPreTecEvalDialog = useCallback(() => {
const amount = pathOr(null, ['amount'], preTecEvalData);
return <div> return <div>
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hidePreTecEvalDialog} outlined/> <Button type="button" label={__('Annulla', 'gepafin')} onClick={hidePreTecEvalDialog} outlined/>
<Button <Button
type="button" type="button"
disabled={loading} disabled={loading || isNil(amount) || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0}
label={__('Invia', 'gepafin')} onClick={doCreateSpecialAmendment}/> label={__('Invia', 'gepafin')} onClick={startCreatingSpecialAmendment}/>
</div> </div>
} }, [preTecEvalData]);
const doCreateAppointmentRequest = () => { const doCreateAppointmentRequest = () => {
if ( if (
@@ -845,9 +848,14 @@ const DomandaEditInstructorManager = () => {
storeSet('unsetAsyncRequest'); storeSet('unsetAsyncRequest');
} }
const startCreatingSpecialAmendment = () => {
doSaveDraft(doCreateSpecialAmendment);
}
const doCreateSpecialAmendment = useCallback(() => { const doCreateSpecialAmendment = useCallback(() => {
if ( if (
!isEmpty(preTecEvalData.amount) && !isEmpty(preTecEvalData.pec) && !isEmpty(preTecEvalData.amendmentDocumentType) !isEmpty(preTecEvalData.amount) && !isNil(preTecEvalData.amount)
&& !isNaN(parseInt(preTecEvalData.amount)) && parseFloat(preTecEvalData.amount) >= 0 && !isEmpty(preTecEvalData.amendmentDocumentType)
) { ) {
storeSet('setAsyncRequest'); storeSet('setAsyncRequest');
@@ -869,7 +877,10 @@ const DomandaEditInstructorManager = () => {
} }
} }
setIsVisiblePreTecEvalDialog(false); setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({}); setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
});
storeSet('unsetAsyncRequest'); storeSet('unsetAsyncRequest');
} }
@@ -882,7 +893,10 @@ const DomandaEditInstructorManager = () => {
}); });
} }
setIsVisiblePreTecEvalDialog(false); setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({}); setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
});
set404FromErrorResponse(data); set404FromErrorResponse(data);
storeSet('unsetAsyncRequest'); storeSet('unsetAsyncRequest');
} }
@@ -1015,11 +1029,16 @@ const DomandaEditInstructorManager = () => {
: APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' : APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
? <SplitButton ? <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 || !isAdmissible}
label={__('Valutazione tecnico-finanziaria', 'gepafin')} label={__('Valutazione tecnico-finanziaria', 'gepafin')}
onClick={(e) => { onClick={(e) => {
tecFinBtnRef.current.show(e); tecFinBtnRef.current.show(e);
}} }}
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'}
model={technicalEvalItems}/> : null} model={technicalEvalItems}/> : null}
<Button <Button
type="button" type="button"
@@ -1571,72 +1590,17 @@ const DomandaEditInstructorManager = () => {
onHide={hidePreTecEvalDialog}> onHide={hidePreTecEvalDialog}>
<div className="appForm__field"> <div className="appForm__field">
<label <label
className={classNames({ 'p-error': isEmpty(preTecEvalData.amount) || preTecEvalData.amount === 0 })}> className={classNames({ 'p-error': isEmpty(preTecEvalData.amount)
|| isNaN(parseFloat(preTecEvalData.amount)) || parseFloat(preTecEvalData.amount) <= 0 })}>
{__('Importo', 'gepafin')} {__('Importo', 'gepafin')}
</label> </label>
<InputNumber <InputNumber
value={preTecEvalData.amount} value={preTecEvalData.amount}
locale="it-IT" locale="it-IT"
minFractionDigits={2} minFractionDigits={2}
invalid={isEmpty(preTecEvalData.amount) || preTecEvalData.amount === 0} invalid={isEmpty(preTecEvalData.amount) || isNaN(parseFloat(preTecEvalData.amount)) || parseFloat(preTecEvalData.amount) <= 0}
onChange={(e) => setPreTecEvalFieldValue('amount', e.value)}/> onChange={(e) => setPreTecEvalFieldValue('amount', e.value)}/>
</div> </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> </Dialog>
</div> </div>

View File

@@ -5,7 +5,7 @@ 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 { useForm } from 'react-hook-form';
import { evaluate } from 'mathjs'; import { evaluate, isNaN } from 'mathjs';
import equal from 'fast-deep-equal'; import equal from 'fast-deep-equal';
// store // store
@@ -81,7 +81,6 @@ const DomandaEditPreInstructor = () => {
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false); const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
const [preTecEvalData, setPreTecEvalData] = useState({ const [preTecEvalData, setPreTecEvalData] = useState({
amendmentDocumentType: '', amendmentDocumentType: '',
pec: '',
amount: 0 amount: 0
}); });
const [allFilesRated, setAllFilesRated] = useState(false); const [allFilesRated, setAllFilesRated] = useState(false);
@@ -780,18 +779,22 @@ const DomandaEditPreInstructor = () => {
const hidePreTecEvalDialog = () => { const hidePreTecEvalDialog = () => {
setIsVisiblePreTecEvalDialog(false); setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({}); setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
});
} }
const footerPreTecEvalDialog = () => { const footerPreTecEvalDialog = useCallback(() => {
const amount = pathOr(null, ['amount'], preTecEvalData);
return <div> return <div>
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hidePreTecEvalDialog} outlined/> <Button type="button" label={__('Annulla', 'gepafin')} onClick={hidePreTecEvalDialog} outlined/>
<Button <Button
type="button" type="button"
disabled={loading} disabled={loading || isNil(amount) || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0}
label={__('Invia', 'gepafin')} onClick={doCreateSpecialAmendment}/> label={__('Invia', 'gepafin')} onClick={startCreatingSpecialAmendment}/>
</div> </div>
} }, [preTecEvalData]);
const doCreateAppointmentRequest = () => { const doCreateAppointmentRequest = () => {
if ( if (
@@ -845,9 +848,14 @@ const DomandaEditPreInstructor = () => {
storeSet('unsetAsyncRequest'); storeSet('unsetAsyncRequest');
} }
const startCreatingSpecialAmendment = () => {
doSaveDraft(doCreateSpecialAmendment);
}
const doCreateSpecialAmendment = useCallback(() => { const doCreateSpecialAmendment = useCallback(() => {
if ( if (
!isEmpty(preTecEvalData.amount) && !isEmpty(preTecEvalData.pec) && !isEmpty(preTecEvalData.amendmentDocumentType) !isEmpty(preTecEvalData.amount) && !isNil(preTecEvalData.amount)
&& !isNaN(parseInt(preTecEvalData.amount)) && parseFloat(preTecEvalData.amount) >= 0 && !isEmpty(preTecEvalData.amendmentDocumentType)
) { ) {
storeSet('setAsyncRequest'); storeSet('setAsyncRequest');
@@ -869,7 +877,10 @@ const DomandaEditPreInstructor = () => {
} }
} }
setIsVisiblePreTecEvalDialog(false); setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({}); setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
});
storeSet('unsetAsyncRequest'); storeSet('unsetAsyncRequest');
} }
@@ -882,7 +893,10 @@ const DomandaEditPreInstructor = () => {
}); });
} }
setIsVisiblePreTecEvalDialog(false); setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({}); setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
});
set404FromErrorResponse(data); set404FromErrorResponse(data);
storeSet('unsetAsyncRequest'); storeSet('unsetAsyncRequest');
} }
@@ -1015,11 +1029,16 @@ const DomandaEditPreInstructor = () => {
: APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE' : APP_HUB_ID !== 't7jh5wfg9QXylNaTZkPoE'
? <SplitButton ? <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 || !isAdmissible}
label={__('Valutazione tecnico-finanziaria', 'gepafin')} label={__('Valutazione tecnico-finanziaria', 'gepafin')}
onClick={(e) => { onClick={(e) => {
tecFinBtnRef.current.show(e); tecFinBtnRef.current.show(e);
}} }}
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'}
model={technicalEvalItems}/> : null} model={technicalEvalItems}/> : null}
<Button <Button
type="button" type="button"
@@ -1571,72 +1590,17 @@ const DomandaEditPreInstructor = () => {
onHide={hidePreTecEvalDialog}> onHide={hidePreTecEvalDialog}>
<div className="appForm__field"> <div className="appForm__field">
<label <label
className={classNames({ 'p-error': isEmpty(preTecEvalData.amount) || preTecEvalData.amount === 0 })}> className={classNames({ 'p-error': isEmpty(preTecEvalData.amount)
|| isNaN(parseFloat(preTecEvalData.amount)) || parseFloat(preTecEvalData.amount) <= 0 })}>
{__('Importo', 'gepafin')} {__('Importo', 'gepafin')}
</label> </label>
<InputNumber <InputNumber
value={preTecEvalData.amount} value={preTecEvalData.amount}
locale="it-IT" locale="it-IT"
minFractionDigits={2} minFractionDigits={2}
invalid={isEmpty(preTecEvalData.amount) || preTecEvalData.amount === 0} invalid={isEmpty(preTecEvalData.amount) || isNaN(parseFloat(preTecEvalData.amount)) || parseFloat(preTecEvalData.amount) <= 0}
onChange={(e) => setPreTecEvalFieldValue('amount', e.value)}/> onChange={(e) => setPreTecEvalFieldValue('amount', e.value)}/>
</div> </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> </Dialog>
</div> </div>