- added company docs;

This commit is contained in:
Vitalii Kiiko
2026-03-26 16:55:10 +01:00
parent 8f8f565117
commit f7c58b6d1b
2 changed files with 184 additions and 87 deletions

View File

@@ -24,8 +24,9 @@ import { Tag } from 'primereact/tag';
import ProperBandoLabel from '../../../../components/ProperBandoLabel'; import ProperBandoLabel from '../../../../components/ProperBandoLabel';
import { confirmPopup, ConfirmPopup } from 'primereact/confirmpopup'; import { confirmPopup, ConfirmPopup } from 'primereact/confirmpopup';
const DocumentsTable = ({ type, reload = 0 }) => { const DocumentsTable = ({ type, reload = 0, companyId: companyIdProp }) => {
const chosenCompanyId = useStoreValue('chosenCompanyId'); const storedCompanyId = useStoreValue('chosenCompanyId');
const effectiveCompanyId = companyIdProp || storedCompanyId;
const companies = useStoreValue('companies'); const companies = useStoreValue('companies');
const [docs, setDocs] = useState([]); const [docs, setDocs] = useState([]);
const [filters, setFilters] = useState(null); const [filters, setFilters] = useState(null);
@@ -33,22 +34,26 @@ const DocumentsTable = ({ type, reload = 0 }) => {
const [statuses, setStatuses] = useState([]); const [statuses, setStatuses] = useState([]);
useEffect(() => { useEffect(() => {
const existingCompany = head(companies.filter(o => o.id === chosenCompanyId)); const shouldFetch = companyIdProp
? !!effectiveCompanyId
: !!head(companies.filter(o => o.id === effectiveCompanyId));
if (!loading && existingCompany && reload !== 0) { if (!loading && shouldFetch && reload !== 0) {
setLoading(true); setLoading(true);
CompanyDocumentsService.getCompanyDocuments(chosenCompanyId, getCallback, errGetCallbacks, [ CompanyDocumentsService.getCompanyDocuments(effectiveCompanyId, getCallback, errGetCallbacks, [
['documentType', type] ['documentType', type]
]); ]);
} }
}, [chosenCompanyId, reload, companies]); }, [effectiveCompanyId, reload, companies]);
useEffect(() => { useEffect(() => {
const existingCompany = head(companies.filter(o => o.id === chosenCompanyId)); const shouldFetch = companyIdProp
? !!effectiveCompanyId
: !!head(companies.filter(o => o.id === effectiveCompanyId));
if (existingCompany) { if (shouldFetch) {
setLoading(true); setLoading(true);
CompanyDocumentsService.getCompanyDocuments(chosenCompanyId, getCallback, errGetCallbacks, [ CompanyDocumentsService.getCompanyDocuments(effectiveCompanyId, getCallback, errGetCallbacks, [
['documentType', type] ['documentType', type]
]); ]);
} }

View File

@@ -1,22 +1,30 @@
import React, { useMemo, useState, useCallback, useEffect, useRef } from 'react'; import React, { useMemo, useState, useCallback, useEffect, useRef } from 'react';
import { useForm, useFieldArray } from 'react-hook-form'; import { useForm, useFieldArray } from 'react-hook-form';
import { isEmpty, head, pluck } from 'ramda'; import { isEmpty, head, isNil } from 'ramda';
import { __ } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { klona } from 'klona'; import { klona } from 'klona';
import { wrap } from 'object-path-immutable';
import { classNames } from 'primereact/utils';
// tools // tools
import uniqid from '../../../../helpers/uniqid'; import uniqid from '../../../../helpers/uniqid';
import formatDateString from '../../../../helpers/formatDateString';
// components // components
import FormField from '../../../../components/FormField'; import FormField from '../../../../components/FormField';
import { Button } from 'primereact/button'; import { Button } from 'primereact/button';
import { Dialog } from 'primereact/dialog'; import { Dialog } from 'primereact/dialog';
import { Toast } from 'primereact/toast'; import { Toast } from 'primereact/toast';
import CompanyService from '../../../../service/company-service'; import { Dropdown } from 'primereact/dropdown';
import FileSelect from '../../../../components/FormField/components/FileSelect'; import { InputText } from 'primereact/inputtext';
import ApplicationService from '../../../../service/application-service'; import { Calendar } from 'primereact/calendar';
import { FileUpload } from 'primereact/fileupload';
import DocumentsTable from '../../../DocumentsBeneficiary/components/DocumentsTable';
// services
import CompanyDocumentsService from '../../../../service/company-documents-service';
import DocumentCategoryService from '../../../../service/document-category-service';
import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse'; import set404FromErrorResponse from '../../../../helpers/set404FromErrorResponse';
import { storeSet } from '../../../../store';
const EvaluationExtraFiles = ({ const EvaluationExtraFiles = ({
sourceId, sourceId,
@@ -32,9 +40,16 @@ const EvaluationExtraFiles = ({
}) => { }) => {
const [chosen, setChosen] = useState(''); const [chosen, setChosen] = useState('');
const [isVisibleCompanyDocsDialog, setIsVisibleCompanyDocsDialog] = useState(false); const [isVisibleCompanyDocsDialog, setIsVisibleCompanyDocsDialog] = useState(false);
const [companyDocs, setCompanyDocs] = useState([]); const [isVisibleAddDocDialog, setIsVisibleAddDocDialog] = useState(false);
const [companyDocsSelected, setCompanyDocsSelected] = useState([]); const [newDocData, setNewDocData] = useState({});
const [docFileAttached, setDocFileAttached] = useState([]);
const [documentCategories, setDocumentCategories] = useState([]);
const [addDocLoading, setAddDocLoading] = useState(false);
const [reloadHash, setReloadHash] = useState(0);
const toast = useRef(null); const toast = useRef(null);
const today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(today.getDate() + 1);
const { const {
control, control,
handleSubmit, handleSubmit,
@@ -107,74 +122,113 @@ const EvaluationExtraFiles = ({
const hideCompanyDocsDialog = () => { const hideCompanyDocsDialog = () => {
setIsVisibleCompanyDocsDialog(false); setIsVisibleCompanyDocsDialog(false);
setCompanyDocsSelected([]);
} }
const footerPreTecEvalDialog = useCallback(() => { const footerCompanyDocsDialog = () => {
return <div> return <div>
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hideCompanyDocsDialog} outlined/> <Button type="button" label={__('Chiudi', 'gepafin')} onClick={hideCompanyDocsDialog} outlined/>
</div>
}
const openAddDocDialog = () => {
setNewDocData({
name: '',
documentCategoryId: 0,
expirationDate: ''
});
setDocFileAttached([]);
setIsVisibleAddDocDialog(true);
}
const hideAddDocDialog = () => {
setIsVisibleAddDocDialog(false);
setNewDocData({});
setDocFileAttached([]);
}
const headerAddDocDialog = () => {
return <span>{__('Aggiungi documento aziendale', 'gepafin')}</span>;
}
const isDocFormValid = useCallback(() => {
return !isEmpty(docFileAttached)
&& !isEmpty(newDocData.name) && !isNil(newDocData.name)
&& newDocData.documentCategoryId !== 0 && !isNil(newDocData.documentCategoryId)
&& !isEmpty(newDocData.expirationDate) && !isNil(newDocData.expirationDate);
}, [docFileAttached, newDocData]);
const footerAddDocDialog = () => {
return <div>
<Button type="button" label={__('Annulla', 'gepafin')} onClick={hideAddDocDialog} outlined/>
<Button <Button
type="button" type="button"
disabled={isEmpty(companyDocsSelected)} disabled={addDocLoading || !isDocFormValid()}
label={__('Aggiungi', 'gepafin')} onClick={doImportCompanyDocs}/> label={__('Salva', 'gepafin')}
onClick={doAddNewDoc}/>
</div> </div>
}, [companyDocsSelected]); }
const doImportCompanyDocs = useCallback(() => { const onUpdateDocFieldValue = useCallback((value, name) => {
if (!isEmpty(companyDocsSelected)) { setNewDocData(prev => wrap(prev).set([name], value).value());
const ids = pluck('id', companyDocsSelected); }, []);
ApplicationService.setApplicationDocuments(applicationId, setDocsCallback, errSetDocsCallback, [
['companyDocumentIds', ids] const onDocFileSelect = (file) => {
]) setDocFileAttached(file.files);
}
const doAddNewDoc = useCallback(() => {
const submitData = {
...newDocData,
expirationDate: formatDateString(newDocData.expirationDate),
documentType: 'COMPANY_DOCUMENT'
};
const queryParams = Object.keys(submitData).map(k => [k, submitData[k]]);
if (!isEmpty(docFileAttached)) {
const formData = new FormData();
for (const file of docFileAttached) {
formData.append('file', file);
}
setAddDocLoading(true);
CompanyDocumentsService.uploadCompanyDocument(companyId, formData, uploadDocCallback, errUploadDocCallback, queryParams);
} }
}, [companyDocsSelected]); }, [docFileAttached, newDocData, companyId]);
const setDocsCallback = (resp) => { const uploadDocCallback = (resp) => {
if (resp.status === 'SUCCESS') { if (resp.status === 'SUCCESS') {
hideAddDocDialog();
setReloadHash(new Date().getTime());
} else {
if (toast.current && resp.message) { if (toast.current && resp.message) {
toast.current.show({ toast.current.show({
severity: 'success', severity: 'error',
summary: '', summary: '',
detail: resp.message detail: resp.message
}); });
} }
} }
setIsVisibleCompanyDocsDialog(false); setAddDocLoading(false);
setCompanyDocsSelected([]);
storeSet('unsetAsyncRequest');
setTimeout(() => {
window.location.reload();
}, 2500);
} }
const errSetDocsCallback = (resp) => { const errUploadDocCallback = (resp) => {
if (toast.current && resp.message) { if (toast.current && resp.message) {
toast.current.show({ toast.current.show({
severity: resp.status === 'SUCCESS' ? 'info' : 'error', severity: 'error',
summary: '', summary: '',
detail: resp.message detail: resp.message
}); });
} }
setIsVisibleCompanyDocsDialog(false);
setCompanyDocsSelected([]);
set404FromErrorResponse(resp); set404FromErrorResponse(resp);
storeSet('unsetAsyncRequest'); setAddDocLoading(false);
} }
const getDocsCallback = (resp) => {
if (resp.status === 'SUCCESS') {
setCompanyDocs(resp.data);
}
}
const errGetDocsCallback = () => {}
useEffect(() => { useEffect(() => {
CompanyService.getCompanyDocuments(companyId, getDocsCallback, errGetDocsCallback, [ DocumentCategoryService.getCategories((resp) => {
['documentType', 'COMPANY_DOCUMENT'] if (resp.status === 'SUCCESS') {
]) setDocumentCategories(resp.data.map(o => ({ value: o.id, label: o.description })));
}, [companyId]); }
}, () => {});
}, []);
return ( return (
<> <>
@@ -240,7 +294,7 @@ const EvaluationExtraFiles = ({
className="fieldsRepeater__addNew" className="fieldsRepeater__addNew"
outlined outlined
type="button" type="button"
disabled={(watchFields && watchFields.filter(o => isEmpty(o.nameValue) || isEmpty(o.fileValue)).length > 0) || shouldDisable} disabled={shouldDisable}
onClick={openCompanyArchive} onClick={openCompanyArchive}
label={__('Documenti aziendale', 'gepafin')} label={__('Documenti aziendale', 'gepafin')}
/> />
@@ -251,41 +305,79 @@ const EvaluationExtraFiles = ({
visible={isVisibleCompanyDocsDialog} visible={isVisibleCompanyDocsDialog}
modal modal
header={headerCompanyDocsDialog} header={headerCompanyDocsDialog}
footer={footerPreTecEvalDialog} footer={footerCompanyDocsDialog}
style={{ maxWidth: '600px', width: '100%' }} style={{ maxWidth: '900px', width: '100%' }}
onHide={hideCompanyDocsDialog}> onHide={hideCompanyDocsDialog}>
<div className="appForm__field"> <div style={{ marginBottom: '1rem' }}>
{/*<label <Button
className={classNames({ type="button"
'p-error': isEmpty(companyDocsSelected) label={__('Aggiungi nuovo documento', 'gepafin')}
})}> icon="pi pi-plus"
{__('Documenti', 'gepafin')} iconPos="right"
</label>*/} onClick={openAddDocDialog}/>
<FileSelect </div>
fieldName="companyDocsSelected" <DocumentsTable type="COMPANY_DOCUMENT" companyId={companyId} reload={reloadHash}/>
label={null} </Dialog>
errors={{}} <Dialog
register={() => {}} visible={isVisibleAddDocDialog}
key={companyDocsSelected} modal
defaultValue={companyDocsSelected} header={headerAddDocDialog}
options={companyDocs} footer={footerAddDocDialog}
sourceId="0" style={{ maxWidth: '600px', width: '100%' }}
source="DOCUMENT" onHide={hideAddDocDialog}>
documentCategories={[]} <div className="appForm__cols">
attachFilesCallback={(o) => { <div className="appForm__field">
setCompanyDocsSelected(prev => { <label
const newSelected = [...prev]; className={classNames({ 'p-error': isEmpty(newDocData.name) || isNil(newDocData.name) })}>
if (!newSelected.find(s => s.id === o.id)) { {__('Nome', 'gepafin')}*
newSelected.push(o); </label>
} <InputText
return newSelected; value={newDocData.name || ''}
}) invalid={isEmpty(newDocData.name || '') || isNil(newDocData.name)}
}} onChange={(e) => onUpdateDocFieldValue(e.target.value, 'name')}/>
/> </div>
<div className="appForm__field">
<label
className={classNames({ 'p-error': !newDocData.documentCategoryId || newDocData.documentCategoryId === 0 })}>
{__('Categoria', 'gepafin')}*
</label>
<Dropdown
value={newDocData.documentCategoryId}
invalid={!newDocData.documentCategoryId || newDocData.documentCategoryId === 0}
onChange={(e) => onUpdateDocFieldValue(e.value, 'documentCategoryId')}
options={documentCategories}
optionLabel="label"
optionValue="value"/>
</div>
</div>
<div className="appForm__cols">
<div className="appForm__field">
<label
className={classNames({ 'p-error': isEmpty(newDocData.expirationDate || '') || isNil(newDocData.expirationDate) })}>
{__('Scadenza', 'gepafin')}*
</label>
<Calendar
value={newDocData.expirationDate}
minDate={tomorrow}
invalid={isEmpty(newDocData.expirationDate || '') || isNil(newDocData.expirationDate)}
onChange={(e) => onUpdateDocFieldValue(e.value, 'expirationDate')}/>
</div>
</div>
<div className="appForm__cols">
<div className="appForm__field">
<label
className={classNames({ 'p-error': isEmpty(docFileAttached) })}>
{__('File', 'gepafin')}*
</label>
<FileUpload
mode="basic"
name="file"
onSelect={onDocFileSelect}/>
</div>
</div> </div>
</Dialog> </Dialog>
</> </>
) )
} }
export default EvaluationExtraFiles; export default EvaluationExtraFiles;