- implemented special amendment creation BLUE_TONGUE;

This commit is contained in:
Vitalii Kiiko
2026-02-23 12:21:19 +01:00
parent 80b0ee5ab1
commit 5505602b1f
2 changed files with 198 additions and 235 deletions

View File

@@ -88,7 +88,9 @@ const DomandaEditInstructorManager = () => {
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
const [preTecEvalData, setPreTecEvalData] = useState({
amendmentDocumentType: '',
amount: 0
amount: 0,
blueTongueField1: 0,
blueTongueField2: 0
});
const [allFilesRated, setAllFilesRated] = useState(false);
const [atLeastOneChecked, setAtLeastOneChecked] = useState(false);
@@ -851,6 +853,14 @@ const DomandaEditInstructorManager = () => {
setPreTecEvalData(newData);
}
const setBlueTongueFieldValue = (name, value) => {
const numVal = value ?? 0;
const updated = wrap(preTecEvalData).set(name, numVal).value();
const field1 = name === 'blueTongueField1' ? numVal : (updated.blueTongueField1 ?? 0);
const field2 = name === 'blueTongueField2' ? numVal : (updated.blueTongueField2 ?? 0);
setPreTecEvalData(wrap(updated).set('amount', field1 + field2).value());
};
const headerPreTecEvalDialog = () => {
return <span>{__('Valutazione Tecnico-Finanziaria', 'gepafin')}</span>;
}
@@ -859,17 +869,28 @@ const DomandaEditInstructorManager = () => {
setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
amount: 0,
blueTongueField1: 0,
blueTongueField2: 0
});
}
const footerPreTecEvalDialog = useCallback(() => {
const amount = pathOr(null, ['amount'], preTecEvalData);
const isBlueTongue = preTecEvalData.amendmentDocumentType === 'BLUE_TONGUE';
const field1 = pathOr(null, ['blueTongueField1'], preTecEvalData);
const field2 = pathOr(null, ['blueTongueField2'], preTecEvalData);
const isBlueTongueInvalid = isBlueTongue && (
isNil(field1) || isNaN(parseFloat(field1)) ||
isNil(field2) || isNaN(parseFloat(field2)) ||
parseFloat(field1) + parseFloat(field2) <= 0
);
const isAmountInvalid = isNil(amount) || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0;
return <div>
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hidePreTecEvalDialog} outlined/>
<Button
type="button"
disabled={loading || isNil(amount) || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0}
disabled={loading || (isBlueTongue ? isBlueTongueInvalid : isAmountInvalid)}
label={__('Invia', 'gepafin')} onClick={startCreatingSpecialAmendment}/>
</div>
}, [preTecEvalData]);
@@ -946,7 +967,12 @@ const DomandaEditInstructorManager = () => {
const getAmendmentSpecialCallback = (data) => {
if (data.status === 'SUCCESS') {
setData(getFormattedData(data.data));
setConnectedSoccorsoId(data.data.id);
setData(prev => ({
...prev,
applicationStatus: 'AWAITING_TECHNICAL_EVALUATION',
status: 'SOCCORSO'
}));
if (toast.current && data.message) {
toast.current.show({
severity: 'success',
@@ -958,7 +984,9 @@ const DomandaEditInstructorManager = () => {
setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
amount: 0,
blueTongueField1: 0,
blueTongueField2: 0
});
storeSet('unsetAsyncRequest');
}
@@ -974,7 +1002,9 @@ const DomandaEditInstructorManager = () => {
setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
amount: 0,
blueTongueField1: 0,
blueTongueField2: 0
});
set404FromErrorResponse(data);
storeSet('unsetAsyncRequest');
@@ -2035,7 +2065,50 @@ const DomandaEditInstructorManager = () => {
footer={footerPreTecEvalDialog}
style={{ maxWidth: '600px', width: '100%' }}
onHide={hidePreTecEvalDialog}>
{preTecEvalData.amendmentDocumentType === 'BLUE_TONGUE'
? <>
<div className="appForm__field">
<label
className={classNames({
'p-error': isNil(preTecEvalData.blueTongueField1)
|| isNaN(parseFloat(preTecEvalData.blueTongueField1))
})}>
{__('Indenizzo per morti capi', 'gepafin')}
</label>
<InputNumber
value={preTecEvalData.blueTongueField1}
locale="it-IT"
minFractionDigits={2}
invalid={isNil(preTecEvalData.blueTongueField1)
|| isNaN(parseFloat(preTecEvalData.blueTongueField1))}
onChange={(e) => setBlueTongueFieldValue('blueTongueField1', e.value)}/>
</div>
<div className="appForm__field">
<label
className={classNames({
'p-error': isNil(preTecEvalData.blueTongueField2)
|| isNaN(parseFloat(preTecEvalData.blueTongueField2))
})}>
{__('Indenizzo per smaltimento', 'gepafin')}
</label>
<InputNumber
value={preTecEvalData.blueTongueField2}
locale="it-IT"
minFractionDigits={2}
invalid={isNil(preTecEvalData.blueTongueField2)
|| isNaN(parseFloat(preTecEvalData.blueTongueField2))}
onChange={(e) => setBlueTongueFieldValue('blueTongueField2', e.value)}/>
</div>
<div className="appForm__field">
<label>{__('Indenizzo totale', 'gepafin')}</label>
<InputNumber
value={preTecEvalData.amount}
locale="it-IT"
minFractionDigits={2}
disabled/>
</div>
</>
: <div className="appForm__field">
<label
className={classNames({
'p-error': isEmpty(preTecEvalData.amount)
@@ -2050,6 +2123,7 @@ const DomandaEditInstructorManager = () => {
invalid={isEmpty(preTecEvalData.amount) || isNaN(parseFloat(preTecEvalData.amount)) || parseFloat(preTecEvalData.amount) <= 0}
onChange={(e) => setPreTecEvalFieldValue('amount', e.value)}/>
</div>
}
</Dialog>
{/*

View File

@@ -88,7 +88,9 @@ const DomandaEditPreInstructor = () => {
const [isVisiblePreTecEvalDialog, setIsVisiblePreTecEvalDialog] = useState(false);
const [preTecEvalData, setPreTecEvalData] = useState({
amendmentDocumentType: '',
amount: 0
amount: 0,
blueTongueField1: 0,
blueTongueField2: 0
});
const [allFilesRated, setAllFilesRated] = useState(false);
const [atLeastOneChecked, setAtLeastOneChecked] = useState(false);
@@ -332,6 +334,14 @@ const DomandaEditPreInstructor = () => {
setPreTecEvalData(prev => ({ ...prev, amendmentDocumentType: 'ALTRE_GARANZIE' }));
setIsVisiblePreTecEvalDialog(true);
}
},
{
label: __('Blue Tongue', 'gepafin'),
icon: 'pi pi-pen-to-square',
command: () => {
setPreTecEvalData(prev => ({ ...prev, amendmentDocumentType: 'BLUE_TONGUE' }));
setIsVisiblePreTecEvalDialog(true);
}
}
]
@@ -851,6 +861,14 @@ const DomandaEditPreInstructor = () => {
setPreTecEvalData(newData);
}
const setBlueTongueFieldValue = (name, value) => {
const numVal = value ?? 0;
const updated = wrap(preTecEvalData).set(name, numVal).value();
const field1 = name === 'blueTongueField1' ? numVal : (updated.blueTongueField1 ?? 0);
const field2 = name === 'blueTongueField2' ? numVal : (updated.blueTongueField2 ?? 0);
setPreTecEvalData(wrap(updated).set('amount', field1 + field2).value());
};
const headerPreTecEvalDialog = () => {
return <span>{__('Valutazione Tecnico-Finanziaria', 'gepafin')}</span>;
}
@@ -859,17 +877,28 @@ const DomandaEditPreInstructor = () => {
setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
amount: 0,
blueTongueField1: 0,
blueTongueField2: 0
});
}
const footerPreTecEvalDialog = useCallback(() => {
const amount = pathOr(null, ['amount'], preTecEvalData);
const isBlueTongue = preTecEvalData.amendmentDocumentType === 'BLUE_TONGUE';
const field1 = pathOr(null, ['blueTongueField1'], preTecEvalData);
const field2 = pathOr(null, ['blueTongueField2'], preTecEvalData);
const isBlueTongueInvalid = isBlueTongue && (
isNil(field1) || isNaN(parseFloat(field1)) ||
isNil(field2) || isNaN(parseFloat(field2)) ||
parseFloat(field1) + parseFloat(field2) <= 0
);
const isAmountInvalid = isNil(amount) || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0;
return <div>
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hidePreTecEvalDialog} outlined/>
<Button
type="button"
disabled={loading || isNil(amount) || isNaN(parseFloat(amount)) || parseFloat(amount) <= 0}
disabled={loading || (isBlueTongue ? isBlueTongueInvalid : isAmountInvalid)}
label={__('Invia', 'gepafin')} onClick={startCreatingSpecialAmendment}/>
</div>
}, [preTecEvalData]);
@@ -946,7 +975,12 @@ const DomandaEditPreInstructor = () => {
const getAmendmentSpecialCallback = (data) => {
if (data.status === 'SUCCESS') {
setData(getFormattedData(data.data));
setConnectedSoccorsoId(data.data.id);
setData(prev => ({
...prev,
applicationStatus: 'AWAITING_TECHNICAL_EVALUATION',
status: 'SOCCORSO'
}));
if (toast.current && data.message) {
toast.current.show({
severity: 'success',
@@ -958,7 +992,9 @@ const DomandaEditPreInstructor = () => {
setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
amount: 0,
blueTongueField1: 0,
blueTongueField2: 0
});
storeSet('unsetAsyncRequest');
}
@@ -974,7 +1010,9 @@ const DomandaEditPreInstructor = () => {
setIsVisiblePreTecEvalDialog(false);
setPreTecEvalData({
amendmentDocumentType: '',
amount: 0
amount: 0,
blueTongueField1: 0,
blueTongueField2: 0
});
set404FromErrorResponse(data);
storeSet('unsetAsyncRequest');
@@ -1015,99 +1053,6 @@ const DomandaEditPreInstructor = () => {
setData(newData);
}, [data]);
/*const openSendContractForm = () => {
setIsVisibleContractForm(true);
}
const headerContractDialog = () => {
return <span>{__('Invia il contratto', 'gepafin')}</span>;
}
const hideContractDialog = () => {
setIsVisibleContractForm(false);
setContractFormData({
subject: '',
text: ''
});
}
const footerContractDialog = useCallback(() => {
let isDisabled = !contractFormData.subject || isEmpty(contractFormData.subject)
|| !contractFormData.text || isEmpty(contractFormData.text)
|| !contractFormData.files || isEmpty(contractFormData.files) || isAsyncRequest;
return <div>
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hideContractDialog} outlined/>
<Button
type="button"
disabled={isDisabled}
label={__('Invia', 'gepafin')} onClick={doSendContract}/>
</div>
}, [contractFormData]);
const updateContractFormData = (value, path) => {
const newData = wrap(contractFormData).set(path.split('.'), value).value();
setContractFormData(newData);
};
const doSendContract = useCallback(() => {
if (
contractFormData.subject && !isEmpty(contractFormData.subject)
&& contractFormData.text && !isEmpty(contractFormData.text)
&& contractFormData.files && !isEmpty(contractFormData.files)
) {
const formDataToSend = new FormData();
const contractFormDataTemp = {
...contractFormData
};
delete contractFormDataTemp.files;
const jsonBlob = new Blob([JSON.stringify(contractFormDataTemp)], {
type: 'application/json'
});
formDataToSend.append('applicationContractRequest', jsonBlob);
if (contractFormData.files && contractFormData.files.length > 0) {
contractFormData.files.forEach((file) => {
formDataToSend.append('contractDocuments', file);
});
}
storeSet('setAsyncRequest');
ApplicationContractService.uploadApplicationContract(
data.applicationId,
formDataToSend,
getUploadApplicationContractCallback,
errGetUploadApplicationContractCallback
);
}
}, [contractFormData]);
const getUploadApplicationContractCallback = (data) => {
if (data.status === 'SUCCESS') {
setData((prev) => ({
...prev,
applicationStatus: 'AWAITING_CONTRACT',
contract: data.data
}));
if (toast.current && data.message) {
toast.current.show({
severity: 'success',
summary: '',
detail: data.message
});
}
}
hideContractDialog();
storeSet('unsetAsyncRequest');
}
const errGetUploadApplicationContractCallback = (data) => {
if (toast.current && data.message) {
toast.current.show({
severity: data.status === 'SUCCESS' ? 'info' : 'error',
summary: '',
detail: data.message
});
}
hideContractDialog();
set404FromErrorResponse(data);
storeSet('unsetAsyncRequest');
}*/
const actionBtns = () => {
return <div className="appPageSection__actions">
{(['SOCCORSO', 'CLOSE', 'EVALUATION', 'NDG', 'APPOINTMENT', 'ADMISSIBLE',
@@ -2034,7 +1979,50 @@ const DomandaEditPreInstructor = () => {
footer={footerPreTecEvalDialog}
style={{ maxWidth: '600px', width: '100%' }}
onHide={hidePreTecEvalDialog}>
{preTecEvalData.amendmentDocumentType === 'BLUE_TONGUE'
? <>
<div className="appForm__field">
<label
className={classNames({
'p-error': isNil(preTecEvalData.blueTongueField1)
|| isNaN(parseFloat(preTecEvalData.blueTongueField1))
})}>
{__('Indenizzo per morti capi', 'gepafin')}
</label>
<InputNumber
value={preTecEvalData.blueTongueField1}
locale="it-IT"
minFractionDigits={2}
invalid={isNil(preTecEvalData.blueTongueField1)
|| isNaN(parseFloat(preTecEvalData.blueTongueField1))}
onChange={(e) => setBlueTongueFieldValue('blueTongueField1', e.value)}/>
</div>
<div className="appForm__field">
<label
className={classNames({
'p-error': isNil(preTecEvalData.blueTongueField2)
|| isNaN(parseFloat(preTecEvalData.blueTongueField2))
})}>
{__('Indenizzo per smaltimento', 'gepafin')}
</label>
<InputNumber
value={preTecEvalData.blueTongueField2}
locale="it-IT"
minFractionDigits={2}
invalid={isNil(preTecEvalData.blueTongueField2)
|| isNaN(parseFloat(preTecEvalData.blueTongueField2))}
onChange={(e) => setBlueTongueFieldValue('blueTongueField2', e.value)}/>
</div>
<div className="appForm__field">
<label>{__('Indenizzo totale', 'gepafin')}</label>
<InputNumber
value={preTecEvalData.amount}
locale="it-IT"
minFractionDigits={2}
disabled/>
</div>
</>
: <div className="appForm__field">
<label
className={classNames({
'p-error': isEmpty(preTecEvalData.amount)
@@ -2049,107 +2037,8 @@ const DomandaEditPreInstructor = () => {
invalid={isEmpty(preTecEvalData.amount) || isNaN(parseFloat(preTecEvalData.amount)) || parseFloat(preTecEvalData.amount) <= 0}
onChange={(e) => setPreTecEvalFieldValue('amount', e.value)}/>
</div>
}
</Dialog>
{/*
This functionality has been moved
*/}
{/*<Dialog
visible={isVisibleContractForm}
modal
header={headerContractDialog}
footer={footerContractDialog}
style={{ maxWidth: '600px', width: '100%' }}
onHide={hideContractDialog}>
<div className="appForm__field">
<label
className={classNames({ 'p-error': !contractFormData.subject || isEmpty(contractFormData.subject) })}>
{__('Oggetto', 'gepafin')}*
</label>
<InputText
value={contractFormData.subject}
invalid={isEmpty(contractFormData.subject)}
onChange={(e) => updateContractFormData(e.target.value, 'subject')}/>
</div>
<div className="appForm__field">
<label
className={classNames({ 'p-error': !contractFormData.text || isEmpty(contractFormData.text) })}>
{__('Testo', 'gepafin')}*
</label>
<div translate="no">
<Editor
value={contractFormData.text}
readOnly={loading}
placeholder={__('Digita qui il messagio', 'gepafin')}
headerTemplate={header}
onTextChange={(e) => updateContractFormData(e.htmlValue, 'text')}
style={{ height: 80 * 3, width: '100%' }}
/>
</div>
</div>
<div className="appForm__field">
<label
className={classNames({ 'p-error': !contractFormData.files || isEmpty(contractFormData.files) })}>
{__('Files', 'gepafin')}*
</label>
<FileUpload
ref={contractFormFilesRef}
name="files[]"
multiple
accept={mimeTypes.map(o => o.code).join(',')}
maxFileSize={defaultMaxFileSize}
auto={false}
customUpload={true}
className={classNames({ 'p-invalid': !contractFormData.files || isEmpty(contractFormData.files) })}
onSelect={(e) => {
updateContractFormData(e.files, 'files');
}}
onRemove={(e) => {
const updatedFiles = contractFormFilesRef.current.getFiles();
updateContractFormData(updatedFiles, 'files');
}}
headerTemplate={(options) => {
const { chooseButton } = options;
return (
<div className="p-fileupload-buttonbar" data-pc-section="buttonbar">
{chooseButton}
</div>
);
}}
chooseOptions={{
label: __('Aggiungi i file', 'gepafin'),
icon: 'pi pi-plus'
}}
itemTemplate={(file, props) => {
return (
<div className="p-fileupload-row" data-pc-section="file">
<div data-pc-section="details" style={{
display: 'flex',
flexDirection: 'column',
gap: '10px',
textAlign: 'left'
}}>
<div className="p-fileupload-filename" data-pc-section="filename">
{file.name}
</div>
<span
data-pc-section="filesize">{getFormatedFileSizeText(file.size)}</span>
</div>
<div data-pc-section="actions">
<Button
type="button"
icon="pi pi-times"
className="p-button-rounded p-button-danger p-button-text"
onClick={() => props.onRemove()}
/>
</div>
</div>
)
}}
emptyTemplate={<p className="m-0">{__('Trascina i file qua')}</p>}
/>
</div>
</Dialog>*/}
</div>
: <>
<Skeleton width="20%" height="1rem" className="mb-2"></Skeleton>