632 lines
23 KiB
JavaScript
632 lines
23 KiB
JavaScript
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||
import { __ } from '@wordpress/i18n';
|
||
import { isEmpty, pathOr, head } from 'ramda';
|
||
import { klona } from 'klona';
|
||
import { wrap } from 'object-path-immutable';
|
||
import { useForm } from 'react-hook-form';
|
||
//import emailjs from '@emailjs/browser';
|
||
//import { useNavigate } from 'react-router-dom';
|
||
|
||
// store
|
||
import { storeSet, useStoreValue, storeGet } from '../../store';
|
||
|
||
// api
|
||
import CompanyService from '../../service/company-service';
|
||
|
||
// tools
|
||
import { isPIVA, isEmail, isEmailPEC } from '../../helpers/validators';
|
||
import set404FromErrorResponse from '../../helpers/set404FromErrorResponse';
|
||
|
||
// components
|
||
import { Messages } from 'primereact/messages';
|
||
import FormField from '../../components/FormField';
|
||
import { Button } from 'primereact/button';
|
||
import BlockingOverlay from '../../components/BlockingOverlay';
|
||
import { InputText } from 'primereact/inputtext';
|
||
import FileuploadDelega from '../../components/FileuploadDelega';
|
||
import { Toast } from 'primereact/toast';
|
||
import getFormatedFileSizeText from '../../helpers/getFormatedFileSizeText';
|
||
import { defaultMaxFileSize } from '../../configData';
|
||
//import { Dialog } from 'primereact/dialog';
|
||
import { confirmPopup, ConfirmPopup } from 'primereact/confirmpopup';
|
||
import { useNavigate } from 'react-router-dom';
|
||
|
||
const APP_HUB_ID = process.env.REACT_APP_HUB_ID;
|
||
|
||
const ProfileCompany = () => {
|
||
const isAsyncRequest = useStoreValue('isAsyncRequest');
|
||
const chosenCompanyId = useStoreValue('chosenCompanyId');
|
||
const companies = useStoreValue('companies');
|
||
const infoMsgs = useRef(null);
|
||
const [formInitialData, setFormInitialData] = useState({});
|
||
const [delegaData, setDelegaData] = useState({});
|
||
const navigate = useNavigate();
|
||
const [delega, setDelega] = useState([]);
|
||
//const [isVisibleRemoveDialog, setIsVisibleRemoveDialog] = useState(false);
|
||
const { delegaFirstName = '', delegaLastName = '', delegaCodiceFiscale = '' } = delegaData;
|
||
const toast = useRef(null);
|
||
//const navigate = useNavigate();
|
||
|
||
const {
|
||
control,
|
||
handleSubmit,
|
||
formState: { errors },
|
||
setValue,
|
||
watch,
|
||
reset
|
||
} = useForm({
|
||
defaultValues: useMemo(() => {
|
||
return formInitialData;
|
||
}, [formInitialData]),
|
||
mode: 'onChange'
|
||
});
|
||
const isLegalRepresentant = watch('isLegalRepresentant')
|
||
|
||
const setEmptyValues = () => {
|
||
const formData = {
|
||
cap: '',
|
||
pec: '',
|
||
email: '',
|
||
city: '',
|
||
codiceFiscale: '',
|
||
address: '',
|
||
companyName: ''
|
||
}
|
||
Object.keys(formData).map(k => setValue(k, formData[k]));
|
||
}
|
||
|
||
const onSubmit = (formData) => {
|
||
infoMsgs.current.clear();
|
||
storeSet('setAsyncRequest');
|
||
|
||
CompanyService.updateCompany(formData.id, formData, updateCallback, updateError);
|
||
};
|
||
|
||
const updateCallback = (data) => {
|
||
if (data.status === 'SUCCESS') {
|
||
const company = klona(data.data);
|
||
const companies = storeGet('companies');
|
||
const existingCompany = head(companies.filter(o => o.id === company.id));
|
||
let newCompanies = [];
|
||
|
||
if (existingCompany) {
|
||
newCompanies = companies.map(o => o.id === company.id ? company : o)
|
||
} else {
|
||
newCompanies = [...companies, company];
|
||
storeSet('chosenCompanyId', company.id);
|
||
}
|
||
|
||
storeSet('companies', newCompanies);
|
||
|
||
if (toast.current) {
|
||
toast.current.show({
|
||
severity: 'success',
|
||
summary: '',
|
||
detail: __('L\'azienda è stata aggiornata!', 'gepafin')
|
||
});
|
||
}
|
||
}
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const updateError = (data) => {
|
||
set404FromErrorResponse(data);
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const checkVatNumber = (e) => {
|
||
infoMsgs.current.clear();
|
||
const isValid = isPIVA(e.target.value);
|
||
|
||
if (isValid) {
|
||
storeSet('setAsyncRequest');
|
||
CompanyService.checkVat(checkVatCallback, errCheckVatCallback, [['vatNumber', e.target.value]])
|
||
} else {
|
||
setEmptyValues();
|
||
}
|
||
}
|
||
|
||
const checkVatCallback = (data) => {
|
||
if (data.status === 'SUCCESS') {
|
||
const resp = data.data.data;
|
||
if (!isEmpty(resp)) {
|
||
const {
|
||
cap, cf, denominazione, piva, indirizzo, comune, dettaglio: { pec }
|
||
} = resp;
|
||
|
||
const formData = {
|
||
cap,
|
||
pec,
|
||
email: pec,
|
||
city: comune,
|
||
codiceFiscale: cf,
|
||
address: indirizzo,
|
||
vatNumber: piva,
|
||
companyName: denominazione
|
||
}
|
||
Object.keys(formData).map(k => setValue(k, formData[k]));
|
||
}
|
||
//setData(getFormattedBandiData(data.data));
|
||
} else {
|
||
setEmptyValues();
|
||
}
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const errCheckVatCallback = (data) => {
|
||
setEmptyValues();
|
||
set404FromErrorResponse(data);
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const setDelegaFieldValue = (value, name) => {
|
||
const newDelegaData = wrap(delegaData).set([name], value).value();
|
||
setDelegaData(newDelegaData)
|
||
}
|
||
|
||
const setDelegaFile = (name, value) => {
|
||
setDelega(value);
|
||
}
|
||
|
||
const getDellegaCallback = (data) => {
|
||
if (data.data) {
|
||
setDelega([data.data]);
|
||
}
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const errDellegaCallback = () => {
|
||
setDelega([]);
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const downloadDelega = () => {
|
||
storeSet('setAsyncRequest');
|
||
const data = {
|
||
codiceFiscale: delegaCodiceFiscale,
|
||
firstName: delegaFirstName,
|
||
lastName: delegaLastName
|
||
}
|
||
CompanyService.downloadCompanyDelega(formInitialData.id, data, getDellegaDownloadCallback, errDellegaDownloadCallback)
|
||
}
|
||
|
||
const getDellegaDownloadCallback = (data) => {
|
||
const pdfFile = new Blob([data], { type: 'application/octet-stream' })
|
||
const url = window.URL.createObjectURL(pdfFile);
|
||
const link = document.createElement('a');
|
||
link.href = url;
|
||
link.setAttribute('download', 'delega.docx');
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
link.remove();
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const errDellegaDownloadCallback = () => {
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const confirmDelete = (event) => {
|
||
confirmPopup({
|
||
target: event.currentTarget,
|
||
message: __('Sei sicuro di voler rimuovere l\'azienda?', 'gepafin'),
|
||
acceptLabel: __('Si', 'gepafin'),
|
||
icon: 'pi pi-info-circle',
|
||
defaultFocus: 'reject',
|
||
acceptClassName: 'p-button-danger',
|
||
accept: () => {
|
||
doRemoveCompanyAPI();
|
||
},
|
||
reject: () => {
|
||
}
|
||
});
|
||
};
|
||
|
||
/*const headerRemoveDialog = () => {
|
||
return <span>{__('Rimuovi azienda', 'gepafin')}</span>
|
||
}
|
||
|
||
const hideRemoveDialog = () => {
|
||
setIsVisibleRemoveDialog(false);
|
||
}*/
|
||
|
||
/*const doRemoveCompany = () => {
|
||
const userData = storeGet('userData');
|
||
let chosenCompany = {};
|
||
|
||
if (chosenCompanyId) {
|
||
chosenCompany = head(companies.filter(o => o.id === chosenCompanyId));
|
||
}
|
||
|
||
const templateParams = {
|
||
firstName: userData.firstName,
|
||
lastName: userData.lastName,
|
||
userId: userData.id,
|
||
companyName: chosenCompany.companyName,
|
||
companyId: chosenCompany.id
|
||
};
|
||
|
||
emailjs.send(
|
||
'service_qu9yy6o',
|
||
'template_oie3kcp',
|
||
templateParams,
|
||
{
|
||
publicKey: 'TPWwaPLM2dDuEIa10'
|
||
}
|
||
).then(() => {
|
||
/!*if (toast.current) {
|
||
toast.current.show({
|
||
severity: 'success',
|
||
summary: '',
|
||
detail: __('La richiesta è stata inviata!', 'gepafin')
|
||
});
|
||
}*!/
|
||
setIsVisibleRemoveDialog(true);
|
||
})
|
||
.catch((err) => {
|
||
console.log(err)
|
||
if (toast.current) {
|
||
toast.current.show({
|
||
severity: 'error',
|
||
summary: '',
|
||
detail: __('Error', 'gepafin')
|
||
});
|
||
}
|
||
});
|
||
}*/
|
||
|
||
const doRemoveCompanyAPI = () => {
|
||
storeSet('setAsyncRequest');
|
||
CompanyService.deleteCompany(formInitialData.id, deleteCompanyCallback, errDeleteCompanyCallback)
|
||
}
|
||
|
||
const deleteCompanyCallback = (data) => {
|
||
if (data.status === 'SUCCESS') {
|
||
const userData = storeGet('userData');
|
||
const newCompanies = companies.filter(o => o.id !== chosenCompanyId);
|
||
storeSet('companies', newCompanies);
|
||
const newUserData = wrap(userData).set('companies', newCompanies).value();
|
||
storeSet('userData', newUserData);
|
||
|
||
if (!isEmpty(newCompanies)) {
|
||
const newChosenCompanyId = newCompanies[0].id;
|
||
storeSet('chosenCompanyId', newChosenCompanyId);
|
||
} else {
|
||
storeSet('chosenCompanyId', 0);
|
||
navigate(`/`);
|
||
}
|
||
}
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
const errDeleteCompanyCallback = (data) => {
|
||
set404FromErrorResponse(data);
|
||
storeSet('unsetAsyncRequest');
|
||
}
|
||
|
||
useEffect(() => {
|
||
const newFormData = klona(formInitialData);
|
||
Object.keys(newFormData).map(v => setValue(v, newFormData[v]));
|
||
}, [formInitialData]);
|
||
|
||
useEffect(() => {
|
||
reset();
|
||
let chosenCompany = {};
|
||
|
||
if (chosenCompanyId) {
|
||
chosenCompany = head(companies.filter(o => o.id === chosenCompanyId));
|
||
}
|
||
|
||
if (!chosenCompany) {
|
||
chosenCompany = pathOr({}, [0], companies);
|
||
}
|
||
|
||
const {
|
||
cap, codiceFiscale, companyName, vatNumber, address, city, pec, email,
|
||
contactName, contactEmail, isLegalRepresentant, id
|
||
} = chosenCompany;
|
||
const companyData = {
|
||
id,
|
||
cap,
|
||
pec,
|
||
email,
|
||
city,
|
||
codiceFiscale,
|
||
address,
|
||
vatNumber,
|
||
companyName,
|
||
contactName,
|
||
contactEmail,
|
||
isLegalRepresentant
|
||
}
|
||
|
||
setFormInitialData(companyData);
|
||
}, [chosenCompanyId, companies]);
|
||
|
||
useEffect(() => {
|
||
if (formInitialData.id) {
|
||
storeSet('setAsyncRequest');
|
||
CompanyService.getCompanyDelega(getDellegaCallback, errDellegaCallback, [
|
||
['companyId', formInitialData.id]
|
||
]);
|
||
}
|
||
}, [formInitialData])
|
||
|
||
return (
|
||
<div className="appPage">
|
||
<div className="appPage__pageHeader">
|
||
<h1>{__('Profilo aziendale', 'gepafin')}</h1>
|
||
</div>
|
||
|
||
<div className="appPage__spacer"></div>
|
||
<Messages ref={infoMsgs}/>
|
||
<Toast ref={toast}/>
|
||
|
||
<form id="companyForm" className="appForm" onSubmit={handleSubmit(onSubmit)}>
|
||
<BlockingOverlay shouldDisplay={isAsyncRequest}/>
|
||
<div className="appPageSection">
|
||
<h2>{__('Informazioni aziendali', 'gepafin')}</h2>
|
||
<div className="appForm__cols">
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="companyName"
|
||
label={__('Ragione Sociale', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
placeholder="Nome di azienda"
|
||
/>
|
||
</div>
|
||
|
||
<div className="appForm__cols">
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="vatNumber"
|
||
disabled={true}
|
||
label={__('P.IVA', 'gepafin')}
|
||
onBlurFn={checkVatNumber}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
/>
|
||
|
||
<FormField
|
||
type="textinput"
|
||
disabled={true}
|
||
fieldName="codiceFiscale"
|
||
label={__('Codice fiscale', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
/>
|
||
</div>
|
||
|
||
<div className="appForm__cols">
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="pec"
|
||
label={__('Email PEC', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{
|
||
required: __('È obbligatorio', 'gepafin'),
|
||
validate: {
|
||
isEmailPEC
|
||
}
|
||
}}
|
||
/>
|
||
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="email"
|
||
label={__('Email', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{
|
||
required: __('È obbligatorio', 'gepafin'),
|
||
validate: {
|
||
isEmail
|
||
}
|
||
}}
|
||
/>
|
||
|
||
{/*<FormField
|
||
type="textinput"
|
||
fieldName="phoneNumber"
|
||
label={__('Telefono', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
/>*/}
|
||
</div>
|
||
|
||
<div className="appForm__cols">
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="address"
|
||
label={__('Indirizzo', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
/>
|
||
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="city"
|
||
label={__('Città', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
/>
|
||
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="cap"
|
||
label={__('CAP', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
/>
|
||
</div>
|
||
|
||
<div className="appForm__cols">
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="contactName"
|
||
label={__('Nome di referente aziendale', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
/>
|
||
|
||
<FormField
|
||
type="textinput"
|
||
fieldName="contactEmail"
|
||
label={__('Email di referente aziendale', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{
|
||
required: __('È obbligatorio', 'gepafin'),
|
||
validate: {
|
||
isEmail
|
||
}
|
||
}}
|
||
/>
|
||
|
||
{/*<FormField
|
||
type="textinput"
|
||
fieldName="phoneNumber"
|
||
label={__('Telefono', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
config={{ required: __('È obbligatorio', 'gepafin') }}
|
||
/>*/}
|
||
</div>
|
||
</div>
|
||
|
||
<div className="appPageSection">
|
||
<FormField
|
||
type="switch"
|
||
fieldName="isLegalRepresentant"
|
||
label={__('Sei il Rappresentante Legale dell’azienda?', 'gepafin')}
|
||
control={control}
|
||
errors={errors}
|
||
onLabel={__('Si', 'gepafin')}
|
||
offLabel={__('No', 'gepafin')}
|
||
/>
|
||
</div>
|
||
</form>
|
||
|
||
{!isLegalRepresentant
|
||
? <div className="appForm__delegaForm">
|
||
<div className="appForm__delegaFormHeader">
|
||
<legend>{__('Compilazione Delega', 'gepafin')}</legend>
|
||
<p className="appForm__delegaFormText">{__('Per procedere come delegato, compila il form seguente, scarica il documento della delega, fallo firmare dal rappresentante legale e ricaricalo nel form di domanda.', 'gepafin')}</p>
|
||
</div>
|
||
|
||
<div className="appForm__cols">
|
||
<div className="appForm__field">
|
||
<label htmlFor="delegaFirstName">
|
||
{__('Nome del rappresentante legale', 'gepafin')}
|
||
<span className="appForm__field--required">*</span>
|
||
</label>
|
||
<InputText
|
||
id="delegaFirstName"
|
||
value={delegaFirstName}
|
||
onChange={(e) => setDelegaFieldValue(e.target.value, 'delegaFirstName')}/>
|
||
</div>
|
||
|
||
<div className="appForm__field">
|
||
<label htmlFor="delegaLastName">
|
||
{__('Cognome del rappresentante legale', 'gepafin')}
|
||
<span className="appForm__field--required">*</span>
|
||
</label>
|
||
<InputText
|
||
id="delegaLastName"
|
||
value={delegaLastName}
|
||
onChange={(e) => setDelegaFieldValue(e.target.value, 'delegaLastName')}/>
|
||
</div>
|
||
|
||
<div className="appForm__field">
|
||
<label htmlFor="delegaCodiceFiscale">
|
||
{__('Codice fiscale del rappresentante legale', 'gepafin')}
|
||
<span className="appForm__field--required">*</span>
|
||
</label>
|
||
<InputText
|
||
id="delegaCodiceFiscale"
|
||
value={delegaCodiceFiscale}
|
||
onChange={(e) => setDelegaFieldValue(e.target.value, 'delegaCodiceFiscale')}/>
|
||
</div>
|
||
</div>
|
||
|
||
{APP_HUB_ID
|
||
//=== 'nonexisting' // hide it from all hub
|
||
? <div>
|
||
<Button
|
||
disabled={isEmpty(delegaCodiceFiscale) || isEmpty(delegaFirstName) || isEmpty(delegaLastName)}
|
||
onClick={downloadDelega}
|
||
type="button"
|
||
label={__('Genera documento Delega', 'gepafin')}
|
||
icon="pi pi-check" iconPos="right"/>
|
||
</div> : null}
|
||
|
||
{APP_HUB_ID
|
||
//=== 'nonexisting' // hide it from all hub
|
||
? <div className="appForm__field">
|
||
<label htmlFor="delega">
|
||
{__('Carica documento Delega Firmato', 'gepafin')}
|
||
<span className="appForm__field--required">*</span>
|
||
{' (.p7m) '}
|
||
{`(max ${getFormatedFileSizeText(defaultMaxFileSize)})`}
|
||
</label>
|
||
<FileuploadDelega
|
||
setDataFn={setDelegaFile}
|
||
fieldName="delega"
|
||
defaultValue={delega}
|
||
accept={['.p7m,application/pkcs7-mime,application/x-pkcs7-mime']}
|
||
chooseLabel={__('Aggiungi documento', 'gepafin')}
|
||
multiple={false}
|
||
doctype="document"
|
||
companyId={formInitialData.id}
|
||
/>
|
||
</div> : null}
|
||
|
||
</div> : <div className="appPage__spacer"></div>}
|
||
|
||
<div className="appPageSection__hr">
|
||
<span>{__('Azioni', 'gepafin')}</span>
|
||
</div>
|
||
|
||
<div className="appPageSection">
|
||
<div className="appPageSection__actions">
|
||
<Button
|
||
form="companyForm"
|
||
label={__('Salva modifiche', 'gepafin')}
|
||
icon="pi pi-check" iconPos="right"/>
|
||
|
||
<ConfirmPopup/>
|
||
<Button
|
||
type="button"
|
||
onClick={confirmDelete}
|
||
severity="danger"
|
||
label={__('Rimuovi azienda', 'gepafin')}
|
||
icon="pi pi-trash" iconPos="right"/>
|
||
</div>
|
||
</div>
|
||
|
||
{/*<Dialog
|
||
visible={isVisibleRemoveDialog}
|
||
modal
|
||
header={headerRemoveDialog}
|
||
footer={footerRemoveDialog}
|
||
style={{ maxWidth: '600px', width: '100%' }}
|
||
onHide={hideRemoveDialog}>
|
||
<p>Abbiamo preso in carica la tua richiesta a breve l'azienda sarà rimossa dal tuo profilo</p>
|
||
</Dialog>*/}
|
||
|
||
</div>
|
||
)
|
||
|
||
}
|
||
|
||
export default ProfileCompany; |