questionnaire print upload sending

This commit is contained in:
merelendor 2023-04-07 14:04:40 +03:00
parent 26a3562e99
commit 65c95fce8d
22 changed files with 1541 additions and 348 deletions

View File

@ -248,6 +248,33 @@ export const uploadAttachmentFile = (file) =>
});
}
export const uploadSignedFile = (file, id) =>
{
return new Promise((resolve, reject) =>
{
let data = new FormData();
data.append('file', file);
data.append('id', id);
axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/questionnaire/send`, data,
{
headers: {
"Content-Type": "multipart/form-data; charset=utf-8",
},
withCredentials: true,
})
.then(async (response) =>
{
resolve(response.data);
})
.catch((error) =>
{
console.error(error);
reject();
});
});
}
export const removeAttachmentFiles = (files) =>
{
for(let i in files)
@ -282,7 +309,7 @@ export const removeAttachmentFile = (id) =>
});
}
export const downloadQuestionnaire = (download = true) =>
export const downloadQuestionnaire = ({ filename, download = true }) =>
{
console.log("ACTION", "questionnaireActions", "downloadQuestionnaire()", );
@ -306,7 +333,7 @@ export const downloadQuestionnaire = (download = true) =>
})
*/
axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/questionnaire/download`, { questionnaire: playload }, {
axios.post(`${ process.env.NEXT_PUBLIC_SELF_API_HOST }/api/questionnaire/download`, { questionnaire: playload, filename }, {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/pdf'
@ -318,13 +345,13 @@ export const downloadQuestionnaire = (download = true) =>
if(download)
{
console.log("downloadQuestionnaire", "response.data");
fileDownload(response.data, response.headers.filename);
fileDownload(response.data, filename);
resolve();
}
else
{
resolve({ file: response.data, filename: response.headers.filename });
resolve({ file: response.data, filename });
}
//dispatch({ type: actionTypes.SUPPORT_APPEALS, data: { appeals: { list: response.data.appeals, new: response.data.new, } } });

View File

@ -90,9 +90,11 @@ export default class CalendarDatePicker extends React.Component
render()
{
const { id, placeholder, value, min, max, disabled, plain, style } = this.props;
const { id, placeholder, value, min, max, disabled, plain, style, required, className } = this.props;
const { readonly, input_value } = this.state;
console.log("DATE", className);
if(disabled)
{
return (
@ -114,6 +116,7 @@ export default class CalendarDatePicker extends React.Component
min={ min }
max={ max }
onChange={ this._handle_onChange }
inputProps={{ required }}
/>
<div style={{ position: "absolute", left: 0, top: 0, width: "100%", height: "100%", opacity: 0.0 }} onClick={ (event) => { event.stopPropagation(); event.preventDefault(); } }/>
</>
@ -124,7 +127,7 @@ export default class CalendarDatePicker extends React.Component
else
{
return (
<div className="date_input_wrapper" style={ this.props.style }>
<div className={ `date_input_wrapper ${ className }` } style={ this.props.style }>
<DatePicker
//valueEditFormat={{ dateStyle: "short" }}
messages={ messages }
@ -138,6 +141,7 @@ export default class CalendarDatePicker extends React.Component
min={ min }
max={ max }
onChange={ this._handle_onChange }
inputProps={{ required }}
/>
</div>
)

View File

@ -155,14 +155,14 @@ export default class SuggestsInput extends React.Component
render()
{
const { focused, options } = this.state;
const { value, disabled, required, placeholder, name } = this.props;
const { value, disabled, required, placeholder, name, className } = this.props;
return (
<div className="autocomlete" style={{ position: "relative" }}>
<input type="text"
autoComplete="off"
style={{ width: "100%" }}
className={ `react-select__control react-select__control--is-focused ${ focused ? "react-select__control--menu-is-open" : "" }` }
className={ `react-select__control react-select__control--is-focused ${ focused ? "react-select__control--menu-is-open" : "" } ${ className }` }
id={ name }
name={ name }
value={ value }

View File

@ -75,7 +75,7 @@ export default class DigitalSignaturesList extends React.Component
_sign = () =>
{
downloadQuestionnaire(false)
downloadQuestionnaire({ download: false })
.then(({ file, filename }) =>
{
//let created_at = moment().format('DD-MM-yyyy');

View File

@ -38,7 +38,6 @@ class Form_2_Contacts extends QuestionnaireForm
fias_id: null,
},
},
step: 1,
};
}

View File

@ -17,6 +17,8 @@ import FilesList from "../FilesList";
import Modal from "../../../../pages/components/Modal/modal";
import countries from "../../../../lib/countries.json";
import citizenships from "../../../../lib/citizenships.json";
import doctypes_personal from "../../../../lib/doctypes_personal.json";
import doctypes_corporate from "../../../../lib/doctypes_corporate.json";
import { reduxWrapper } from '../../../../store';
import moment from "moment";
import AddressSuggests from "../../AddressSuggests";
@ -117,13 +119,15 @@ class Form_3_Signer extends QuestionnaireForm
delegation_files: [],
head_person_files: [],
signatory_person_files: [],
personal_data_consent: false,
signatory_corporate_files: [],
loading: false,
modal_show_personal_data: false,
step: 1,
status: "empty",
errors: [],
};
this.ref_form = React.createRef();
this.ref_submit = React.createRef();
}
static getDerivedStateFromProps(nextProps, prevState)
@ -135,12 +139,18 @@ class Form_3_Signer extends QuestionnaireForm
delegation_files: nextProps.questionnaire.delegation_files,
signatory_person: nextProps.questionnaire.signatory_person,
signatory_person_files: nextProps.questionnaire.signatory_person_files,
signatory_corporate_files: nextProps.questionnaire.signatory_corporate_files,
status: nextProps.questionnaire.status,
};
}
componentDidMount()
{
const { main } = this.state;
if( main.inn !== null && main.inn.length === 12)
{
this._handle_onCheckboxFieldChange("head_person.evo_indefinite", true);
}
}
_handle_onCitizenshipChange = (name, value) =>
@ -193,21 +203,12 @@ class Form_3_Signer extends QuestionnaireForm
}
}
_handle_onFormSubmit = (event) =>
_handle_onNextPage = (event) =>
{
console.log("Form_3_Signer", "_handle_onNextPage");
event.preventDefault();
console.log("Form_3_Signer", "_handle_onFormSubmit");
this._handle_onCheckboxFieldChange("step", 4);
setTimeout(() =>
{
saveQuestionnaire();
this.props.onNextStep("shareholders");
}, 10);
}
_checkDisabled = () =>
{
const errors = [];
const { main, head_person, signatory_person, } = this.state;
const head_person_check = [
@ -229,17 +230,21 @@ class Form_3_Signer extends QuestionnaireForm
for(let i in head_person_check)
{
if(_get(head_person, head_person_check[i]) === "")
let v = _get(head_person, head_person_check[i]);
if(v === "" || v === null)
{
return true;
errors.push(`head_person.${ head_person_check[i] }`);
}
}
console.log({ errors });
if(!head_person.evo_indefinite)
{
if(head_person.evo_credentials_dateend === "")
{
return true;
errors.push(`head_person.evo_credentials_dateend`);
}
}
@ -256,9 +261,11 @@ class Form_3_Signer extends QuestionnaireForm
for(let i in main_check)
{
if(_get(main, main_check[i]) === "")
let v = _get(main, main_check[i]);
if(v === "" || v === null)
{
return true;
errors.push(`main.${ main_check[i] }`);
}
}
}
@ -271,9 +278,6 @@ class Form_3_Signer extends QuestionnaireForm
"firstname",
"jobtitle",
"signer_rule_basis",
"signer_rule_basis_add",
"docdate",
"docnumber",
"telephone",
"email",
"identity_document.seria",
@ -286,40 +290,58 @@ class Form_3_Signer extends QuestionnaireForm
"identity_document.registration_address.title",
];
if(signatory_person.signer_rule_basis === 100000003)
{
signatory_person_check.push("signer_rule_basis_add");
}
if(signatory_person.signer_rule_basis === 100000001 || signatory_person.signer_rule_basis === 100000003)
{
signatory_person_check.push("docdate");
signatory_person_check.push("docnumber");
}
for(let i in signatory_person_check)
{
if(_get(signatory_person, signatory_person_check[i]) === "")
let v = _get(signatory_person, signatory_person_check[i]);
if(v === "" || v === null)
{
return true;
errors.push(`signatory_person.${ signatory_person_check[i] }`);
}
}
}
return false;
this.setState({ errors }, () =>
{
this.ref_submit.current.click();
});
//this.ref_form.current.submit();
//this.ref_form.current.dispatchEvent(new Event('submit', { cancelable: true }));
}
/*
_checkDisabled = () =>
_removeError = (name) =>
{
const { main } = this.state;
const check = ["high_level", "board_of_directors", "collective_executive", "individual_executive"];
for(let i in check)
const errors = [ ...this.state.errors ];
if(errors.indexOf(name) > -1)
{
if(main[check[i]] === "")
{
return true;
}
errors.splice(errors.indexOf(name), 1);
}
if(!main.accept)
{
return true;
}
return false;
this.setState({ errors });
}
_handle_onFormSubmit = (event) =>
{
event.preventDefault();
console.log("Form_3_Signer", "_handle_onFormSubmit");
this._handle_onCheckboxFieldChange("step", 4);
setTimeout(() =>
{
saveQuestionnaire();
this.props.onNextStep("shareholders");
}, 10);
}
*/
render()
{
@ -328,31 +350,37 @@ class Form_3_Signer extends QuestionnaireForm
personal_data_consent,
head_person_files,
signatory_person_files,
signatory_corporate_files,
delegation_files,
modal_show_personal_data,
errors,
} = this.state;
console.log("delegation_files", delegation_files);
const { loading, } = this.state;
const { main, head_person, signatory_person, status } = this.state;
console.log("head_person.evo_assignment_date", head_person.evo_assignment_date);
let head_person_citizenship = { label: getCitizenshipTitleByCode(head_person.identity_document.citizenship.code), code: head_person.identity_document.citizenship.code };
let signatory_person_citizenship = { label: getCitizenshipTitleByCode(signatory_person.identity_document.citizenship.code), code: signatory_person.identity_document.citizenship.code };
return (
<React.Fragment>
<form onSubmit={ this._handle_onFormSubmit } className={`questionnaire questionnaire_3 ${ checking && "disabled" }`}>
<form ref={ this.ref_form } onSubmit={ this._handle_onFormSubmit } className={`questionnaire questionnaire_3 ${ checking && "disabled" }`} onKeyDown={(e) => {if (e.key === 'Enter') e.preventDefault() }}>
<p className="title">3. Информация о единоличном исполнительном органе, подписанте договора лизинга</p>
<div className="form_field">
<label>Фамилия <sup className="required_label">*</sup></label>
<SuggestsInput
className={ errors.indexOf("head_person.lastname") > -1 ? "error" : "" }
type="lastname"
id="head_person.lastname"
name="head_person.lastname"
value={ this._checkStrValue(head_person.lastname) }
placeholder="Введите фамилию"
onChange={ (value) => this._handle_onTextFieldChange("head_person.lastname", value) }
onChange={ (value) => { this._removeError("head_person.lastname"); this._handle_onTextFieldChange("head_person.lastname", value); } }
required={ true }
disabled={ checking }
/>
@ -371,12 +399,13 @@ class Form_3_Signer extends QuestionnaireForm
<div className="form_field">
<label>Имя <sup className="required_label">*</sup></label>
<SuggestsInput
className={ errors.indexOf("head_person.firstname") > -1 ? "error" : "" }
type="firstname"
id="head_person.firstname"
name="head_person.firstname"
value={ this._checkStrValue(head_person.firstname) }
placeholder="Введите имя"
onChange={ (value) => this._handle_onTextFieldChange("head_person.firstname", value) }
onChange={ (value) => { this._removeError("head_person.firstname"); this._handle_onTextFieldChange("head_person.firstname", value) } }
required={ true }
disabled={ checking }
/>
@ -395,12 +424,13 @@ class Form_3_Signer extends QuestionnaireForm
<div className="form_field">
<label>Отчество <small>если имеется</small></label>
<SuggestsInput
className={ errors.indexOf("head_person.middlename") > -1 ? "error" : "" }
type="middlename"
id="head_person.middlename"
name="head_person.middlename"
value={ this._checkStrValue(head_person.middlename) }
placeholder="Введите отчество"
onChange={ (value) => this._handle_onTextFieldChange("head_person.middlename", value) }
onChange={ (value) => { this._removeError("head_person.middlename"); this._handle_onTextFieldChange("head_person.middlename", value) } }
required={ false }
disabled={ checking }
/>
@ -415,17 +445,35 @@ class Form_3_Signer extends QuestionnaireForm
/>
{*/}
</div>
<div className="form_field">
<label>Тип документа <sup className="required_label">*</sup></label>
<Select
id="head_person.identity_document.doctype"
name="head_person.identity_document.doctype"
options={ doctypes_personal }
placeholder="Выберите тип документа"
noOptionsMessage={ ({ inputValue }) => !inputValue ? noOptionsText :"Ничего не найдено" }
isSearchable={ true }
className="autocomlete"
classNamePrefix="react-select"
value={ doctypes_personal.filter((type) => head_person.identity_document.doctype === type.value) }
onChange={ (element) => this._handle_onTextFieldChange(`head_person.identity_document.doctype`, element.value) }
required={ true }
isDisabled={ checking }
/>
</div>
<div className="formgroup">
<div className="form_field">
<label>Серия паспорта <sup className="required_label">*</sup></label>
<InputMask
className={ errors.indexOf("head_person.identity_document.seria") > -1 ? "error" : "" }
mask='9999'
id="head_person.identity_document.seria"
name="head_person.identity_document.seria"
value={ this._checkStrValue(head_person.identity_document.seria) }
placeholder="Введите серию"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
onChange={ (event) => { this._removeError("head_person.identity_document.seria"); this._handle_onTextFieldChange(event.target.name, event.target.value) } }
required={ true }
disabled={ checking }
/>
@ -433,12 +481,13 @@ class Form_3_Signer extends QuestionnaireForm
<div className="form_field">
<label>Номер паспорта <sup className="required_label">*</sup></label>
<InputMask
className={ errors.indexOf("head_person.identity_document.docnumber") > -1 ? "error" : "" }
mask='999999'
id="head_person.identity_document.docnumber"
name="head_person.identity_document.docnumber"
value={ this._checkStrValue(head_person.identity_document.docnumber) }
placeholder="Введите номер"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
onChange={ (event) => { this._removeError("head_person.identity_document.docnumber"); this._handle_onTextFieldChange(event.target.name, event.target.value) } }
required={ true }
disabled={ checking }>
</InputMask>
@ -452,7 +501,7 @@ class Form_3_Signer extends QuestionnaireForm
placeholder="ДД.ММ.ГГГГ"
id={ "head_person.identity_document.issuedate" }
value={ this._checkStrValue(head_person.identity_document.issuedate) !== "" ? this._checkStrValue(head_person.identity_document.issuedate) : null }
onChange={ (date) => this._handle_onTextFieldChange("head_person.identity_document.issuedate", date) }
onChange={ (date) => { this._removeError("head_person.identity_document.issuedate"); this._handle_onTextFieldChange("head_person.identity_document.issuedate", date) } }
required={ true }
disabled={ checking }
/>
@ -465,21 +514,10 @@ class Form_3_Signer extends QuestionnaireForm
name="head_person.identity_document.code"
value={ this._checkStrValue(head_person.identity_document.code) }
placeholder="Введите код"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
onChange={ (event) => { this._removeError("head_person.identity_document.code"); this._handle_onTextFieldChange(event.target.name, event.target.value) } }
required={ true }
disabled={ checking }
/>
{/*}
<input type="text"
id="head_person.identity_document.code"
name="head_person.identity_document.code"
value={ this._checkStrValue(head_person.identity_document.code) }
placeholder="Введите номер"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
required={ true }
disabled={ checking }
/>
{*/}
</div>
</div>
<div className="form_field">
@ -489,7 +527,7 @@ class Form_3_Signer extends QuestionnaireForm
name="head_person.identity_document.issueby"
value={ this._checkStrValue(head_person.identity_document.issueby) }
placeholder="Введите наименование подразделения выдавшего документ"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
onChange={ (event) => { this._removeError("head_person.identity_document.issueby"); this._handle_onTextFieldChange(event.target.name, event.target.value) } }
required={ true }
disabled={ checking }
/>
@ -500,7 +538,7 @@ class Form_3_Signer extends QuestionnaireForm
id={ "head_person.identity_document.placebirth" }
value={ this._checkStrValue(head_person.identity_document.placebirth) }
placeholder="Укажите место рождения"
onChange={ (data) => this._handle_onTextFieldChange("head_person.identity_document.placebirth", data.title) }
onChange={ (data) => { this._removeError("head_person.identity_document.issueby"); this._handle_onTextFieldChange("head_person.identity_document.placebirth", data.title) } }
required={ true }
disabled={ checking }
/>
@ -517,7 +555,7 @@ class Form_3_Signer extends QuestionnaireForm
className="autocomlete"
classNamePrefix="react-select"
value={ head_person_citizenship.code !== null ? head_person_citizenship : undefined }
onChange={ (element) => this._handle_onCitizenshipChange(`head_person.identity_document.citizenship`, element.value) }
onChange={ (element) => { this._removeError("head_person.identity_document.citizenship"); this._handle_onCitizenshipChange(`head_person.identity_document.citizenship`, element.value) } }
required={ true }
isDisabled={ checking }
/>
@ -528,7 +566,7 @@ class Form_3_Signer extends QuestionnaireForm
value={ this._checkStrValue(head_person.identity_document.registration_address.name) }
fias={ this._checkStrValue(head_person.identity_document.registration_address.fias_id) }
placeholder="Укажите адрес регистрации"
onChange={ (data) => this._handle_onTextFieldChange("head_person.identity_document.registration_address", data) }
onChange={ (data) => { this._removeError("head_person.identity_document.registration_address.name"); this._handle_onTextFieldChange("head_person.identity_document.registration_address", data) } }
required={ true }
disabled={ checking }
/>
@ -536,6 +574,7 @@ class Form_3_Signer extends QuestionnaireForm
<div className="form_field">
<label>Должность <sup className="required_label">*</sup></label>
<input type="text"
className={ errors.indexOf("head_person.jobtitle") > -1 ? "error" : "" }
id="head_person.jobtitle"
name="head_person.jobtitle"
value={ this._checkStrValue(head_person.jobtitle) }
@ -577,10 +616,11 @@ class Form_3_Signer extends QuestionnaireForm
<label>Дата назначения <sup className="required_label">*</sup></label>
<div style={{ display: "flex", flexWrap: "wrap", width: "calc(100% - 198px)"}}>
<CalendarDatePicker
className={ errors.indexOf("head_person.evo_assignment_date") > -1 ? "error" : "" }
placeholder="ДД.ММ.ГГГГ"
id={ "head_person.evo_assignment_date" }
value={ this._checkStrValue(head_person.evo_assignment_date) !== "" ? this._checkStrValue(head_person.evo_assignment_date) : null }
onChange={ (date) => this._handle_onTextFieldChange("head_person.evo_assignment_date", date) }
onChange={ (date) => { this._removeError("head_person.evo_assignment_date"); this._handle_onTextFieldChange("head_person.evo_assignment_date", date) } }
required={ true }
disabled={ checking }
style={{maxWidth: "320px"}}
@ -648,7 +688,7 @@ class Form_3_Signer extends QuestionnaireForm
<div className="formgroup" style={{ width: "100%" }}>
<div className="form_field" style={{ flexDirection: "row", flexWrap: "nowrap" }}>
<label>ИНН ? <sup className="required_label">*</sup></label>
<label>ИНН <sup className="required_label">*</sup></label>
<InputMask
style={{ width: "100%" }}
mask='999999999999'
@ -809,6 +849,24 @@ class Form_3_Signer extends QuestionnaireForm
/>
</div>
<div className="form_field">
<label>Тип документа <sup className="required_label">*</sup></label>
<Select
id="signatory_person.identity_document.doctype"
name="signatory_person.identity_document.doctype"
options={ doctypes_personal }
placeholder="Выберите тип документа"
noOptionsMessage={ ({ inputValue }) => !inputValue ? noOptionsText :"Ничего не найдено" }
isSearchable={ true }
className="autocomlete"
classNamePrefix="react-select"
value={ doctypes_personal.filter((type) => signatory_person.identity_document.doctype === type.value) }
onChange={ (element) => this._handle_onTextFieldChange(`signatory_person.identity_document.doctype`, element.value) }
required={ true }
isDisabled={ checking }
/>
</div>
<div className="formgroup">
<div className="form_field">
<label>Серия паспорта <sup className="required_label">*</sup></label>
@ -975,64 +1033,9 @@ class Form_3_Signer extends QuestionnaireForm
</div>
</div>
<p><b>Реквизиты документа подтверждающие полномочия на подписание договора лизинга</b></p>
<div className="form_field">
<label>Вид документа <sup className="required_label">*</sup></label>
<input type="text"
id="signatory_person.signer_rule_basis"
name="signatory_person.signer_rule_basis"
value={ this._checkStrValue(signatory_person.signer_rule_basis) }
placeholder="Вид документа"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
required={ true }
disabled={ checking }
/>
</div>
<div className="form_field">
<label>Наименование документа <sup className="required_label">*</sup></label>
<input type="text"
id="signatory_person.signer_rule_basis_add"
name="signatory_person.signer_rule_basis_add"
value={ this._checkStrValue(signatory_person.signer_rule_basis_add) }
placeholder="Наименование документа"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
required={ true }
disabled={ checking }
/>
</div>
<div className="formgroup">
<div className="form_field">
<label>Номер документа <sup className="required_label">*</sup></label>
<input type="text"
id="signatory_person.docnumber"
name="signatory_person.docnumber"
value={ this._checkStrValue(signatory_person.docnumber) }
placeholder="Номер документа"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
required={ true }
disabled={ checking }
/>
</div>
<div className="form_field">
<label>Дата <sup className="required_label">*</sup></label>
<CalendarDatePicker
style={{ width: "calc(100% - 198px)" }}
placeholder="ДД.ММ.ГГГГ"
id={ "signatory_person.docdate" }
value={ this._checkStrValue(signatory_person.docdate) !== "" ? this._checkStrValue(signatory_person.docdate) : null }
onChange={ (date) => this._handle_onTextFieldChange("signatory_person.docdate", date) }
required={ true }
disabled={ checking }
/>
</div>
</div>
<FilesList
//group="signatory_person"
title="Прикрепить скан паспорта подписанта"
name="signatory_person_files"
files={ signatory_person_files }
onAddFile={ this._handle_onAddFile }
@ -1040,6 +1043,83 @@ class Form_3_Signer extends QuestionnaireForm
checking={ checking }
/>
<p><b>Реквизиты документа подтверждающие полномочия на подписание договора лизинга</b></p>
<div className="form_field">
<label>Право подписи на основании <sup className="required_label">*</sup></label>
<Select
id="signatory_person.signer_rule_basis"
name="signatory_person.signer_rule_basis"
options={ doctypes_corporate }
placeholder="Вид документа"
noOptionsMessage={ ({ inputValue }) => !inputValue ? noOptionsText :"Ничего не найдено" }
isSearchable={ true }
className="autocomlete"
classNamePrefix="react-select"
value={ doctypes_corporate.filter((type) => signatory_person.signer_rule_basis === type.value) }
onChange={ (element) => this._handle_onTextFieldChange(`signatory_person.signer_rule_basis`, element.value) }
required={ true }
isDisabled={ checking }
/>
</div>
{ signatory_person.signer_rule_basis === 100000003 && (
<div className="form_field">
<label>Наименование документа <sup className="required_label">*</sup></label>
<input type="text"
id="signatory_person.signer_rule_basis_add"
name="signatory_person.signer_rule_basis_add"
value={ this._checkStrValue(signatory_person.signer_rule_basis_add) }
placeholder="Наименование документа"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
required={ true }
disabled={ checking }
/>
</div>
) }
{ (signatory_person.signer_rule_basis === 100000000 || signatory_person.signer_rule_basis === 100000003) && (
<>
<div className="formgroup">
<div className="form_field">
<label>Номер документа <sup className="required_label">*</sup></label>
<input type="text"
id="signatory_person.docnumber"
name="signatory_person.docnumber"
value={ this._checkStrValue(signatory_person.docnumber) }
placeholder="Номер документа"
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
required={ true }
disabled={ checking }
/>
</div>
<div className="form_field">
<label>Дата документа <sup className="required_label">*</sup></label>
<CalendarDatePicker
style={{ width: "calc(100% - 198px)" }}
placeholder="ДД.ММ.ГГГГ"
id={ "signatory_person.docdate" }
value={ this._checkStrValue(signatory_person.docdate) !== "" ? this._checkStrValue(signatory_person.docdate) : null }
onChange={ (date) => this._handle_onTextFieldChange("signatory_person.docdate", date) }
required={ true }
disabled={ checking }
/>
</div>
</div>
<FilesList
//group="signatory_person"
title="Прикрепить скан документа на право подписи"
name="signatory_corporate_files"
files={ signatory_corporate_files }
onAddFile={ this._handle_onAddFile }
onRemoveFile={ this._handle_onRemoveFile }
checking={ checking }
/>
</>
) }
{/*}
<div className="dosc_list medium-icon">
<div className="row">
@ -1067,11 +1147,12 @@ class Form_3_Signer extends QuestionnaireForm
{*/}
{ !checking && (
<div className="action">
<button type="submit" className="button button-blue" disabled={ this._checkDisabled() }>
<button type="button" className="button button-blue" onClick={ this._handle_onNextPage }>
{ loading ? (
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" style={{ marginTop: "4px" }}/>
) : "Продолжить" }
</button>
<button ref={ this.ref_submit } type="submit" style={{ display: "none" }}/>
{ status !== "empty" && (
<>
<br/><br/>

View File

@ -14,6 +14,7 @@ import { get as _get } from 'lodash';
import QuestionnaireForm from "../QuestionnaireForm";
import CalendarDatePicker from '../../../CalendarDatePicker';
import citizenships from "../../../../lib/citizenships.json";
import doctypes_personal from "../../../../lib/doctypes_personal.json";
import { reduxWrapper } from '../../../../store';
import AddressSuggests from "../../AddressSuggests";
import InputMask from 'react-input-mask';
@ -78,7 +79,7 @@ class ShareholderForm extends React.Component
</div>
<div className="form_field">
<label>Отчество <sup className="required_label">*</sup><small>если имеется</small></label>
<label>Отчество <small>если имеется</small></label>
<SuggestsInput
type="middlename"
id={ `founder_persons[${ index }].middlename` }
@ -131,6 +132,24 @@ class ShareholderForm extends React.Component
/>
</div>
<div className="form_field">
<label>Тип документа <sup className="required_label">*</sup></label>
<Select
id={ `founder_persons[${ index }].identity_document.doctype` }
name={ `founder_persons[${ index }].identity_document.doctype` }
options={ doctypes_personal }
placeholder="Выберите тип документа"
noOptionsMessage={ ({ inputValue }) => !inputValue ? noOptionsText :"Ничего не найдено" }
isSearchable={ true }
className="autocomlete"
classNamePrefix="react-select"
value={ doctypes_personal.filter((type) => shareholder.identity_document.doctype === type.value) }
onChange={ (element) => this._handle_onTextFieldChange(`founder_persons[${ index }].identity_document.doctype`, element.value) }
required={ true }
isDisabled={ checking }
/>
</div>
<div className="form_field ">
<div className="form_field">
<label>Серия и номер паспорта <sup className="required_label">*</sup></label>
@ -447,7 +466,7 @@ class Form_4_Shareholders extends QuestionnaireForm
is_beneficial: false,
identity_document:
{
doctype: null,
doctype: 100000000,
seria: null,
docnumber: null,
issuedate: null,

View File

@ -29,7 +29,6 @@ class Form_7_Check extends QuestionnaireForm
loading: false,
phone_number_format_error: false,
step: 7,
main: {},
legal_address: {},
fact_address: {},
@ -41,7 +40,6 @@ class Form_7_Check extends QuestionnaireForm
founder_persons: [],
client_contacts: {},
non_profit: {},
personal_data_consent: false,
loading: false,
modal_show_personal_data: false,
company: {},

View File

@ -11,6 +11,7 @@ import { withRouter } from 'next/router';
import moment from "moment";
import QuestionnaireForm from "../QuestionnaireForm";
import { MatchMedia } from '../../../../utils/mediaqueries';
import { reduxWrapper } from '../../../../store';
import DigitalSignaturesList from "../DigitalSignaturesList";
import { downloadQuestionnaire } from "../../../../actions";
@ -21,25 +22,29 @@ class Form_8_Signing extends QuestionnaireForm
{
super(props);
this.state = {
main: {},
sign_digital: true,
address: "",
phone_check_loading: false,
phone_number_format_error: false,
certificates: [],
filename: null,
mobile: MatchMedia() === "mobile" ? true : false,
};
}
static getDerivedStateFromProps(nextProps, prevState)
{
return {
observer: nextProps.observer,
user: nextProps.user,
main: nextProps.main,
};
}
componentDidMount()
{
const { main } = this.state;
this.setState({ filename: `${ main.inn }_questionnaire_${ moment().format("DDMMYYYY_HHmmss") }.pdf` })
}
_handle_onFormSubmit = (event) =>
@ -63,10 +68,16 @@ class Form_8_Signing extends QuestionnaireForm
_download = () =>
{
downloadQuestionnaire()
const { filename } = this.state;
downloadQuestionnaire({ filename, download: true })
.then(() =>
{
alert("Скачивание сформированного PDF");
this._handle_onCheckboxFieldChange("step", 9);
setTimeout(() =>
{
this.props.onNextStep("status");
}, 10);
});
}
@ -81,7 +92,7 @@ class Form_8_Signing extends QuestionnaireForm
render()
{
const { phone_check_loading, sign_digital, certificates } = this.state;
const { filename, sign_digital, mobile } = this.state;
return (
<React.Fragment>
@ -105,7 +116,20 @@ class Form_8_Signing extends QuestionnaireForm
</div>
{ sign_digital && (
<DigitalSignaturesList form={ null }/>
<>
{ mobile ? (
<div className="questionnaire message moderate">
<svg width="44" height="45" viewBox="0 0 44 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M40.5425 31.1863L25.7969 8.08116C24.9653 6.77804 23.5459 6 22 6C20.4539 6 19.0345 6.77804 18.2032 8.08116L3.45741 31.1862C2.57234 32.5732 2.51363 34.3313 3.30467 35.7746C4.09572 37.2173 5.60918 38.1137 7.25444 38.1137H36.7456C38.3909 38.1137 39.9044 37.2175 40.6956 35.7742C41.4863 34.3313 41.4276 32.5733 40.5425 31.1863ZM22 34.2245C20.644 34.2245 19.5448 33.1252 19.5448 31.7694C19.5448 30.4133 20.6441 29.3141 22 29.3141C23.356 29.3141 24.4551 30.4133 24.4551 31.7694C24.4551 33.1252 23.3559 34.2245 22 34.2245ZM25.403 17.1635L24.1937 25.3052C24.0157 26.5037 22.8999 27.3309 21.7016 27.1529C20.7334 27.0091 20.0075 26.25 19.8582 25.333L18.5451 17.2074C18.2394 15.3155 19.5251 13.534 21.417 13.2283C23.3089 12.9226 25.0904 14.2083 25.3962 16.1002C25.4536 16.4565 25.4517 16.8243 25.403 17.1635Z" fill="white"/>
</svg>
<p><b>Внимание</b>
Для подписания анкеты посредством ЭЦП пожалуйста воспользуйтесь стационарным компьютером или ноутбуком с установленной программой КриптоПро CSP.
</p>
</div>
) : (
<DigitalSignaturesList form={ null }/>
) }
</>
) }
<div className="form_field">
@ -128,7 +152,7 @@ class Form_8_Signing extends QuestionnaireForm
<div className="dosc_list medium-icon">
<div className="row">
<p className="doc_name i-pdf extension">
{ moment().format("DD.MM.YYYY HH:mm:ss") } (.PDF)
{ filename }
<span style={{ width: "100%" }}>Анкета клиента</span>
</p>
<a className="button button-blue " onClick={ this._download }>Скачать</a>
@ -145,16 +169,6 @@ function mapStateToProps(state, ownProps)
{
return {
main: state.questionnaire.main,
legal_address: state.questionnaire.legal_address,
fact_address: state.questionnaire.fact_address,
postal_address: state.questionnaire.postal_address,
head_person: state.questionnaire.head_person,
head_person_files: state.questionnaire.head_person_files,
signatory_person: state.questionnaire.signatory_person,
signatory_person_files: state.questionnaire.signatory_person_files,
founder_persons: state.questionnaire.founder_persons,
client_contacts: state.questionnaire.client_contacts,
non_profit: state.questionnaire.non_profit,
}
}

View File

@ -13,7 +13,7 @@ import moment from "moment";
import QuestionnaireForm from "../QuestionnaireForm";
import { reduxWrapper } from '../../../../store';
import DigitalSignaturesList from "../DigitalSignaturesList";
import { downloadQuestionnaire } from "../../../../actions";
import { downloadQuestionnaire, uploadSignedFile } from "../../../../actions";
class Form_9_Status extends QuestionnaireForm
{
@ -21,20 +21,22 @@ class Form_9_Status extends QuestionnaireForm
{
super(props);
this.state = {
sign_digital: true,
address: "",
phone_check_loading: false,
phone_number_format_error: false,
certificates: [],
sign: {},
uploading: false,
file: null,
sent: null,
company: {},
};
this.ref_file_input = React.createRef();
}
static getDerivedStateFromProps(nextProps, prevState)
{
return {
observer: nextProps.observer,
user: nextProps.user,
sign: nextProps.questionnaire.sign,
step: nextProps.questionnaire.step,
company: nextProps.company,
};
}
@ -42,52 +44,135 @@ class Form_9_Status extends QuestionnaireForm
{
}
_handle_onFileUpload = () =>
{
console.log("_handle_onFileUpload");
console.log(this.ref_file_input);
this.ref_file_input.current.click();
}
_handle_onFileChange = (event) =>
{
console.log("_handle_onFileChange");
console.log(event);
console.log("file", file);
const file = event.target.files[0];
this.setState({ file: file });
}
_handle_onSend = () =>
{
const { file, company } = this.state;
console.log("company", company);
this.setState({ uploading: true }, () =>
{
uploadSignedFile(file, company.questionnaire_id)
.then(() =>
{
this.setState({ sent: true });
})
.catch(() =>
{
});
});
}
render()
{
const { phone_check_loading, sign_digital, certificates } = this.state;
const { sign, file, uploading, sent } = this.state;
console.log( {sign} );
return (
<React.Fragment>
<div className="questionnaire message moderate">
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z" fill="white"/>
<path d="M23.0322 14.699L28.301 19.9678L29.0537 22.9785L25.2903 26.7419M14.0478 23.779L19.221 28.9522M18.957 29H14.7527C14.5531 29 14.3616 28.9207 14.2205 28.7795C14.0793 28.6384 14 28.4469 14 28.2473V24.043C14 23.9441 14.0195 23.8463 14.0573 23.7549C14.0951 23.6636 14.1506 23.5806 14.2205 23.5107L25.5107 12.2205C25.6519 12.0793 25.8433 12 26.043 12C26.2426 12 26.434 12.0793 26.5752 12.2205L30.7795 16.4248C30.9207 16.566 31 16.7574 31 16.957C31 17.1567 30.9207 17.3481 30.7795 17.4893L19.4893 28.7795C19.4194 28.8494 19.3364 28.9049 19.2451 28.9427C19.1537 28.9805 19.0559 29 18.957 29Z" stroke="#8E94A7" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<p>
<b>Анкета заполнена и ожидает вашего подписания</b>
Вы заполнили и подписали анкету лизингополучателя посредством
ЭЦП. Анкета передана в обрабатывающий центр. Если у
сотрудников возникнут вопросы мы свяжемся с Вами. Спасибо!
</p>
</div>
<div className="questionnaire status_action">
<button className="button button-blue">
Загрузить подписанный документ
</button>
</div>
<div className="questionnaire status_action" style={{ width: "100%" }}>
<div className="dosc_list medium-icon">
<div className="row">
<p className="doc_name i-pdf extension">
1234567 от 21.01.2021
</p>
<button className="button button-blue">Отправить</button>
</div>
{ sign.digital && (
<div className="questionnaire message success">
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z" fill="white"/>
<path d="M29.5625 17.875L19.4791 27.5L14.4375 22.6875" stroke="#5FB158" strokeWidth="4" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<p>
<b>Анкета заполнена и подписана</b>
Вы заполнили и подписали анкету лизингополучателя посредством
ЭЦП. Анкета передана в обрабатывающий центр. Если у
сотрудников возникнут вопросы мы свяжемся с Вами. Спасибо!
</p>
</div>
</div>
<div className="questionnaire message success">
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z" fill="white"/>
<path d="M29.5625 17.875L19.4791 27.5L14.4375 22.6875" stroke="#5FB158" strokeWidth="4" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<p>
<b>Анкета заполнена и подписана</b>
Вы заполнили и подписали анкету лизингополучателя посредством
загрузки скана анкеты. Анкета передана в обрабатывающий центр.
Если у сотрудников возникнут вопросы мы свяжемся с Вами.
Спасибо!
</p>
</div>
) }
{ sign.print && (
<React.Fragment>
{ file === null ? (
<React.Fragment>
<div className="questionnaire message moderate">
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z" fill="white"/>
<path d="M23.0322 14.699L28.301 19.9678L29.0537 22.9785L25.2903 26.7419M14.0478 23.779L19.221 28.9522M18.957 29H14.7527C14.5531 29 14.3616 28.9207 14.2205 28.7795C14.0793 28.6384 14 28.4469 14 28.2473V24.043C14 23.9441 14.0195 23.8463 14.0573 23.7549C14.0951 23.6636 14.1506 23.5806 14.2205 23.5107L25.5107 12.2205C25.6519 12.0793 25.8433 12 26.043 12C26.2426 12 26.434 12.0793 26.5752 12.2205L30.7795 16.4248C30.9207 16.566 31 16.7574 31 16.957C31 17.1567 30.9207 17.3481 30.7795 17.4893L19.4893 28.7795C19.4194 28.8494 19.3364 28.9049 19.2451 28.9427C19.1537 28.9805 19.0559 29 18.957 29Z" stroke="#8E94A7" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<p>
<b>Анкета заполнена и ожидает вашего подписания</b>
Вы заполнили анкету лизингополучателя для подписания в режиме загрузки скана анкеты. Пожалуйста, загрузите скан подписанной анкеты.
</p>
</div>
<div className="questionnaire status_action">
<>
<button className="button button-blue" style={{ width: "100%", minWidth: "255px" }} onClick={ this._handle_onFileUpload }>Загрузить подписанный документ</button>
<input type="file" id="file" multiple={ false } ref={ this.ref_file_input } style={{ display: "none" }} onChange={ this._handle_onFileChange }/>
</>
</div>
</React.Fragment>
) : (
<React.Fragment>
{ !sent ? (
<React.Fragment>
<div className="questionnaire message moderate">
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z" fill="white"/>
<path d="M23.0322 14.699L28.301 19.9678L29.0537 22.9785L25.2903 26.7419M14.0478 23.779L19.221 28.9522M18.957 29H14.7527C14.5531 29 14.3616 28.9207 14.2205 28.7795C14.0793 28.6384 14 28.4469 14 28.2473V24.043C14 23.9441 14.0195 23.8463 14.0573 23.7549C14.0951 23.6636 14.1506 23.5806 14.2205 23.5107L25.5107 12.2205C25.6519 12.0793 25.8433 12 26.043 12C26.2426 12 26.434 12.0793 26.5752 12.2205L30.7795 16.4248C30.9207 16.566 31 16.7574 31 16.957C31 17.1567 30.9207 17.3481 30.7795 17.4893L19.4893 28.7795C19.4194 28.8494 19.3364 28.9049 19.2451 28.9427C19.1537 28.9805 19.0559 29 18.957 29Z" stroke="#8E94A7" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<p>
<b>Анкета заполнена, подписана и ожидает отправки</b>
Вы заполнили и подписали анкету лизингополучателя в режиме загрузки скана анкеты. Пожалуйста, отправьте подписанный документ.
</p>
</div>
<div className="questionnaire status_action" style={{ width: "100%" }}>
<div className="dosc_list medium-icon">
<div className="row">
<p className="doc_name i-pdf extension">
{ file.name }
<span style={{width: "100%"}}>Подписанный скан анкеты</span>
</p>
<button className="button button-blue" style={{ width: "130px" }} onClick={ this._handle_onSend }>
{ uploading ? (
<SpinnerCircular size={ 24 } thickness={ 50 } speed={ 100 } color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
) : "Отправить" }
</button>
</div>
</div>
</div>
</React.Fragment>
) : (
<React.Fragment>
<div className="questionnaire message success">
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z" fill="white"/>
<path d="M29.5625 17.875L19.4791 27.5L14.4375 22.6875" stroke="#5FB158" strokeWidth="4" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<p>
<b>Анкета заполнена и подписана</b>
Вы заполнили и подписали анкету лизингополучателя посредством
загрузки скана анкеты. Анкета передана в обрабатывающий центр.
Если у сотрудников возникнут вопросы мы свяжемся с Вами.
Спасибо!
</p>
</div>
</React.Fragment>
) }
</React.Fragment>
)}
</React.Fragment>
) }
</React.Fragment>
);
}
@ -96,17 +181,8 @@ class Form_9_Status extends QuestionnaireForm
function mapStateToProps(state, ownProps)
{
return {
main: state.questionnaire.main,
legal_address: state.questionnaire.legal_address,
fact_address: state.questionnaire.fact_address,
postal_address: state.questionnaire.postal_address,
head_person: state.questionnaire.head_person,
head_person_files: state.questionnaire.head_person_files,
signatory_person: state.questionnaire.signatory_person,
signatory_person_files: state.questionnaire.signatory_person_files,
founder_persons: state.questionnaire.founder_persons,
client_contacts: state.questionnaire.client_contacts,
non_profit: state.questionnaire.non_profit,
questionnaire: state.questionnaire,
company: state.company,
}
}

File diff suppressed because one or more lines are too long

View File

@ -359,7 +359,7 @@ input[type="radio"] {
}
&.error {
border-color: var(--red);
border-color: var(--red) !important;
}
&.filled {
@ -645,3 +645,7 @@ ul.custom-dots {
}
}
}
.error {
border: solid 1px var(--red) !important;
}

View File

@ -0,0 +1,6 @@
[
{ "label": "Доверенности", "value": 100000000 },
{ "label": "Устава", "value": 100000001 },
{ "label": "Является главой ИП \\ ИН КФХ", "value": 100000002 },
{ "label": "Прочего", "value": 100000003 }
]

View File

@ -0,0 +1,5 @@
[
{ "label": "Паспорт гражданина РФ", "value": 100000000 },
{ "label": "Иностранный паспорт", "value": 100000001 },
{ "label": "Вид на жительство", "value": 100000002 }
]

View File

@ -18,6 +18,7 @@
"cors": "^2.8.5",
"dadata": "^0.0.3",
"debounce-promise": "^3.1.2",
"file-type": "^18.2.1",
"form-data": "^4.0.0",
"ioredis": "^4.28.2",
"js-file-download": "^0.4.12",

View File

@ -114,7 +114,7 @@ export default async function handler(req, res)
console.log("API", "questionnaire", "get");
console.log(req.body);
console.log("-".repeat(50));
const { questionnaire } = req.body;
const { questionnaire, filename } = req.body;
await cors(req, res);
@ -303,11 +303,11 @@ export default async function handler(req, res)
const pdfBytes = await pdfDoc.save();
//responseType: 'blob',
//fs.writeFileSync(`${ __dirname }/../../../../../uploads/${ client_jwt_decoded.acc_number }_anketa.pdf`, pdfBytes);
fs.writeFileSync(`${ __dirname }/../../../../../uploads/${ client_jwt_decoded.acc_number }_questionnaire.pdf`, pdfBytes);
//res.setHeader('Content-Type', 'application/pdf');
//res.send(pdfBytes);
console.log("pdfBytes.size", pdfBytes, pdfBytes.byteLength);
res.setHeader("filename", `${ client_jwt_decoded.acc_number }_anketa.pdf`);
res.setHeader("filename", filename);
res.setHeader('Content-Type', 'application/pdf');
res.send(Buffer.from(pdfBytes));

View File

@ -0,0 +1,82 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import fs from 'fs';
import axios from 'axios';
import { Cookies } from 'react-cookie';
import cookie from 'cookie';
import moment from 'moment';
import jwt from 'jsonwebtoken';
import Redis from 'ioredis';
import md5 from 'md5';
import { inspect } from 'util';
import multer from 'multer';
import { fileTypeFromBuffer } from "file-type";
//import { MIMEType } from 'util';
import { cors } from '../../../../lib/cors';
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
export default async function handler(req, res)
{
console.log("API", "questionnaire", "get");
await cors(req, res);
return new Promise((resolve) =>
{
if(req.headers.cookie !== undefined)
{
const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : "");
if(cookies.jwt !== undefined && cookies.jwt !== null)
{
var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT);
var crm_jwt = jwt.sign({ acc_number: client_jwt_decoded.acc_number }, process.env.JWT_SECRET_CRM, { noTimestamp: true });
upload.single("file")(req, {}, async (err) =>
{
const { file, body } = req;
const id = md5(`${ file.buffer }`);
const local_filename = `${ client_jwt_decoded.acc_number }_signed_questionnaire_${ moment().format("YYYY_MM_DD_HH:mm:ss") }`;
console.log("fileTypeFromBuffer", await fileTypeFromBuffer(file.buffer));
const file_payload = {
id: id,
name: Buffer.from(file.originalname, 'latin1').toString('utf8'),
filename: local_filename,
};
try
{
fs.writeFileSync(`${ __dirname }/../../../../../../uploads/${ local_filename }`, file.buffer);
console.log("multer.upload.single file");
console.log({ file_payload });
res.status(200).json(file_payload);
resolve();
}
catch(upload_single_error)
{
console.error("upload_single_error");
console.error(upload_single_error);
res.status(500).send();
resolve();
}
});
}
else
{
res.status(403).send();
resolve();
}
}
});
}
export const config = {
api: {
bodyParser: false
}
}

View File

@ -0,0 +1,279 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import fs from 'fs';
import axios from 'axios';
import { Cookies } from 'react-cookie';
import cookie from 'cookie';
import moment from 'moment';
import jwt from 'jsonwebtoken';
import FormData from 'form-data';
import Redis from 'ioredis';
import md5 from 'md5';
import { inspect } from 'util';
import multer from 'multer';
import { get as _get, pick as _pick } from 'lodash';
import { eachSeries } from 'async';
import { fileTypeFromBuffer } from "file-type";
//import { MIMEType } from 'util';
import { cors } from '../../../lib/cors';
import RedisClient from '../../../lib/RedisClient';
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });
export default async function handler(req, res)
{
console.log("API", "questionnaire", "send");
await cors(req, res);
return new Promise((resolve) =>
{
if(req.headers.cookie !== undefined)
{
const cookies = cookie.parse(req.headers?.cookie ? req.headers?.cookie : "");
if(cookies.jwt !== undefined && cookies.jwt !== null)
{
var client_jwt_decoded = jwt.verify(cookies.jwt, process.env.JWT_SECRET_CLIENT);
var crm_jwt = jwt.sign({ acc_number: client_jwt_decoded.acc_number }, process.env.JWT_SECRET_CRM, { noTimestamp: true });
console.log("JWT", cookies.jwt);
console.log("CRM_JWT", crm_jwt);
upload.single("file")(req, {}, async (err) =>
{
const { file } = req;
const { id } = req.body;
const path = `${ process.env.CRM_API_HOST }/lk/Questionnaire/PreQuestionnaire/`;
const filetype = await fileTypeFromBuffer(file.buffer);
console.log("fileTypeFromBuffer", filetype);
const local_filename = `${ client_jwt_decoded.acc_number }_signed_questionnaire_${ moment().format("YYYY_MM_DD_HH:mm:ss") }.${ filetype.ext }`;
const key = md5(`questionnaire_${ client_jwt_decoded.acc_number }`);
const questionnaire = await RedisClient.get(key);
try
{
fs.writeFileSync(`${ __dirname }/../../../../../uploads/${ local_filename }`, file.buffer);
console.log("multer.upload.single file");
console.log({ questionnaire });
const parsed = JSON.parse(questionnaire);
console.log("parsed");
console.log(".".repeat(50));
console.log(inspect(parsed, true, null, true));
//const main = _pick(parsed.main, ["title", "inn", "kpp", "email", "telephone", "websiteurl", "financial_loan"]);
let payload = { ...parsed.main, ...{ head_person: parsed.head_person }, ...{ signatory_person: parsed.signatory_person }, };
payload.telephone = payload.telephone.replace(/[^0-9]/g, '');
payload.individual_executive_inn = payload.individual_executive_inn.replace(/[^0-9]/g, '');
payload.individual_executive_kpp = payload.individual_executive_kpp.replace(/[^0-9]/g, '');
payload.individual_executive_docdate = payload.individual_executive_docdate !== null ? moment(payload.individual_executive_docdate).format("YYYY-MM-DD") : null;
if(payload.head_person.middlename !== "" && payload.head_person.middlename !== null)
{
payload.head_person.no_middle_name = false;
}
else
{
payload.head_person.no_middle_name = true;
}
payload.head_person.identity_document.citizenship_code = payload.head_person.identity_document.citizenship.code;
payload.head_person.telephone = payload.head_person.telephone.replace(/[^0-9]/g, '');
payload.head_person.identity_document.issuedate = payload.head_person.identity_document.issuedate !== null ? moment(payload.head_person.identity_document.issuedate).format("YYYY-MM-DD") : null;
payload.head_person.evo_assignment_date = payload.head_person.evo_assignment_date !== null ? moment(payload.head_person.evo_assignment_date).format("YYYY-MM-DD") : null;
if(payload.signatory_person.not_head_person)
{
if(payload.signatory_person.middlename !== "" && payload.signatory_person.middlename !== null)
{
payload.signatory_person.no_middle_name = false;
}
else
{
payload.signatory_person.no_middle_name = true;
}
}
else
{
payload.signatory_person = { ...payload.signatory_person, ..._pick(payload.head_person, [
"lastname", "firstname", "middlename", "no_middle_name", "jobtitle", "telephone", "email", "identity_document", "evo_assignment_date", "evo_credentials_dateend", "evo_indefinite",
]) };
}
payload.signatory_person.identity_document.citizenship_code = payload.signatory_person.identity_document.citizenship.code;
payload.signatory_person.telephone = payload.signatory_person.telephone.replace(/[^0-9]/g, '');
payload.signatory_person.identity_document.issuedate = payload.signatory_person.identity_document.issuedate !== null ? moment(payload.signatory_person.identity_document.issuedate).format("YYYY-MM-DD") : null;
payload.signatory_person.docdate = payload.signatory_person.docdate !== null ? moment(payload.signatory_person.docdate).format("YYYY-MM-DD") : null;
payload.signatory_person.assignment_date = payload.signatory_person.assignment_date !== null ? moment(payload.signatory_person.assignment_date).format("YYYY-MM-DD") : null;
const founder_persons = parsed.founder_persons;
for(let i in founder_persons)
{
founder_persons[i].founder_number = parseInt(i, 10) + 1;
founder_persons[i].telephone = founder_persons[i].telephone.replace(/[^0-9]/g, '');
founder_persons[i].identity_document.issuedate = founder_persons[i].identity_document.issuedate !== null ? moment(founder_persons[i].identity_document.issuedate).format("YYYY-MM-DD") : null;
if(founder_persons[i].middlename !== "" && founder_persons[i].middlename !== null)
{
founder_persons[i].no_middle_name = false;
}
else
{
founder_persons[i].no_middle_name = true;
}
}
payload = { ...payload, ...{ founder_persons }, ...{
revenue_source_main: parsed.non_profit.fin_source_business,
revenue_source_donat: parsed.non_profit.fin_source_donate,
revenue_source_entrance_fee: parsed.non_profit.fin_source_fees,
revenue_source_other: parsed.non_profit.fin_source_another_description,
foreign_countries_financing: parsed.non_profit.foreign_payers,
purpose_use_la: parsed.non_profit.fin_goals_cars,
purpose_use_lkt: parsed.non_profit.fin_goals_trucks,
purpose_use_gt_sc: parsed.non_profit.fin_goals_special,
} };
payload.financial_loan = parseFloat(payload.financial_loan.replace(/[^0-9.]/g, ''));
console.log("=".repeat(50));
console.log(inspect(payload, true, null, true));
/*
for(let i in parsed.main)
{
payload[i] = parsed.main[i] === null ? "" : parsed.main[i];
}
*/
console.log(id);
console.log("path", path);
console.log("*".repeat(50));
console.log(payload);
const files_to_send = [];
for(let i in parsed.head_person_files)
{
//console.log(parsed.head_person_files[i]);
files_to_send.push({ ...parsed.head_person_files[i], ...{ number: 1, } })
}
/*
for(let i in parsed.delegation_files)
{
console.log(parsed.delegation_files[i]);
files_to_send.push({ ...parsed.delegation_files[i], ...{ number: 1, } })
}
*/
for(let i in parsed.signatory_person_files)
{
//console.log(parsed.signatory_person_files[i]);
files_to_send.push({ ...parsed.signatory_person_files[i], ...{ number: 23, } })
}
for(let i in parsed.signatory_corporate_files)
{
//console.log(parsed.signatory_corporate_files[i]);
files_to_send.push({ ...parsed.signatory_corporate_files[i], ...{ number: 22, } })
}
files_to_send.push({ ...{
name: `${ client_jwt_decoded.acc_number }_questionnaire.pdf`,
filename: `${ client_jwt_decoded.acc_number }_questionnaire.pdf`,
}, ...{ number: 18, } });
files_to_send.push({ ...{
name: local_filename,
filename: local_filename,
}, ...{ number: 161, } });
console.log("@".repeat(200));
console.log(payload);
axios.put(path, payload,
{
params: { name: id },
headers: {
"Authorization": `Bearer ${ crm_jwt }`,
"Content-Type": "application/json"
}
}
)
.then((crm_response) =>
{
console.log("crm_response for", path);
console.log(inspect(crm_response.data, true, null, true));
eachSeries(files_to_send, (file_entry, callback) =>
{
console.log({ file_entry });
const file_to_send_data = fs.readFileSync(`${ __dirname }/../../../../../uploads/${ file_entry.filename }`);
const data = new FormData();
data.append("file", file_to_send_data, file_entry.name);
data.append("entity", "evo_client_questionnaire");
data.append("documentTypeNumber", file_entry.number);
data.append("name", id);
axios.post(`${ process.env.CRM_API_HOST }/lk/document/upload/`, data,
{
headers: {
"Content-Type": `multipart/form-data; boundary=${ data._boundary }`,
"Authorization": `Bearer ${ crm_jwt }`,
},
withCredentials: true,
})
.then(() =>
{
console.log("FILE", file_entry.filename, "SENT");
callback();
})
.catch((crm_file_upload_error) =>
{
console.error("crm_file_upload_error", crm_file_upload_error);
callback();
});
}, () =>
{
res.status(200).send();
resolve();
});
})
.catch((error) =>
{
console.error(error);
console.error("-".repeat(30), "error.response.data:");
console.error(error.response.data);
res.status(500).send();
resolve();
});
//res.status(200).send();
}
catch(upload_single_error)
{
console.error("upload_single_error");
console.error(upload_single_error.response.data);
res.status(500).send();
resolve();
}
});
}
else
{
res.status(403).send();
resolve();
}
}
});
}
export const config = {
api: {
bodyParser: false
}
}

View File

@ -7,6 +7,7 @@ import { connect } from "react-redux";
import numeral from "numeral";
import pluralize from 'pluralize-ru';
import { SpinnerCircular } from 'spinners-react';
import NoSSR from "@mpth/react-no-ssr";
import { withRouter } from 'next/router';
import { reduxWrapper } from '../../store';
@ -104,7 +105,7 @@ class QuestionnairePage extends React.Component
if (route.indexOf("#regulatory") > -1) return (<Form_5_Regulatory company={ company } onNextStep={ this._handle_onNextStep } checking={ false }/>);
if (route.indexOf("#non-profit") > -1) return (<Form_6_NonProfit company={ company } onNextStep={ this._handle_onNextStep } checking={ false }/>);
if (route.indexOf("#check") > -1) return (<Form_7_Check company={ company } signatories={ signatories } onNextStep={ this._handle_onNextStep } checking={ true }/>);
if (route.indexOf("#signing") > -1) return (<Form_8_Signing/>);
if (route.indexOf("#signing") > -1) return (<Form_8_Signing onNextStep={ this._handle_onNextStep }/>);
if (route.indexOf("#status") > -1) return (<Form_9_Status/>);
return (<Form_1_Main company={ company } onNextStep={ this._handle_onNextStep } checking={ false }/>);
@ -128,14 +129,16 @@ class QuestionnairePage extends React.Component
<h1 className="section_title">Анкета лизингополучателя</h1>
</div>
</div>
<div className={ `aside_container ${ route.indexOf("#status") < 0 ? "about" : "" }` }>
{ route.indexOf("#status") < 0 && (
<InnerMenu company={ company } nko={ nko } { ...this.props }/>
) }
<article>
{ this._renderForm() }
</article>
</div>
<NoSSR>
<div className={ `aside_container ${ route.indexOf("#status") < 0 ? "about" : "" }` }>
{ route.indexOf("#status") < 0 && (
<InnerMenu company={ company } nko={ nko } { ...this.props }/>
) }
<article>
{ this._renderForm() }
</article>
</div>
</NoSSR>
</AccountLayout>
<Footer/>
</React.Fragment>

View File

@ -137,110 +137,75 @@ class QuestionnairePage extends React.Component {
return false;
};
render() {
const { phone, phone_check_loading, phone_number_format_error } =
this.state;
render()
{
const { phone, phone_check_loading, phone_number_format_error } = this.state;
return (
<React.Fragment>
<Head>
<title>ЛК Эволюция автолизинга - Анкета лизингополучателя</title>
<meta
name="description"
content="ЛК Эволюция автолизинга - Анкета лизингополучателя"
/>
</Head>
<Header {...this.props} />
<AccountLayout>
<div className="title_wrapper">
<div className="left">
<h1 className="section_title">Анкета лизингополучателя</h1>
</div>
</div>
<div className="aside_container about">
<article>
<div className="questionnaire message moderate">
<svg
width="44"
height="44"
viewBox="0 0 44 44"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z"
fill="white"
/>
<path
d="M23.0322 14.699L28.301 19.9678L29.0537 22.9785L25.2903 26.7419M14.0478 23.779L19.221 28.9522M18.957 29H14.7527C14.5531 29 14.3616 28.9207 14.2205 28.7795C14.0793 28.6384 14 28.4469 14 28.2473V24.043C14 23.9441 14.0195 23.8463 14.0573 23.7549C14.0951 23.6636 14.1506 23.5806 14.2205 23.5107L25.5107 12.2205C25.6519 12.0793 25.8433 12 26.043 12C26.2426 12 26.434 12.0793 26.5752 12.2205L30.7795 16.4248C30.9207 16.566 31 16.7574 31 16.957C31 17.1567 30.9207 17.3481 30.7795 17.4893L19.4893 28.7795C19.4194 28.8494 19.3364 28.9049 19.2451 28.9427C19.1537 28.9805 19.0559 29 18.957 29Z"
stroke="#8E94A7"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<p>
<b>Анкета заполнена и ожидает вашего подписания</b>
Вы заполнили и подписали анкету лизингополучателя посредством
ЭЦП. Анкета передана в обрабатывающий центр. Если у
сотрудников возникнут вопросы мы свяжемся с Вами. Спасибо!
</p>
</div>
<div className="questionnaire status_action">
<button className="button button-blue">
Загрузить подписанный документ
</button>
</div>
<div className="questionnaire status_action" style={{width: "100%"}}>
<div className="dosc_list medium-icon">
<div className="row">
<p className="doc_name i-pdf extension">
1234567 от 21.01.2021
</p>
<button className="button button-blue">Отправить</button>
</div>
</div>
</div>
<div className="questionnaire message success">
<svg
width="44"
height="44"
viewBox="0 0 44 44"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z"
fill="white"
/>
<path
d="M29.5625 17.875L19.4791 27.5L14.4375 22.6875"
stroke="#5FB158"
strokeWidth="4"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
<p>
<b>Анкета заполнена и подписана</b>
Вы заполнили и подписали анкету лизингополучателя посредством
загрузки скана анкеты. Анкета передана в обрабатывающий центр.
Если у сотрудников возникнут вопросы мы свяжемся с Вами.
Спасибо!
</p>
</div>
</article>
</div>
</AccountLayout>
<Footer />
</React.Fragment>
);
}
return (
<React.Fragment>
<Head>
<title>ЛК Эволюция автолизинга - Анкета лизингополучателя</title>
<meta
name="description"
content="ЛК Эволюция автолизинга - Анкета лизингополучателя"
/>
</Head>
<Header {...this.props} />
<AccountLayout>
<div className="title_wrapper">
<div className="left">
<h1 className="section_title">Анкета лизингополучателя</h1>
</div>
</div>
<div className="aside_container about">
<article>
<div className="questionnaire message moderate">
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z" fill="white"/>
<path d="M23.0322 14.699L28.301 19.9678L29.0537 22.9785L25.2903 26.7419M14.0478 23.779L19.221 28.9522M18.957 29H14.7527C14.5531 29 14.3616 28.9207 14.2205 28.7795C14.0793 28.6384 14 28.4469 14 28.2473V24.043C14 23.9441 14.0195 23.8463 14.0573 23.7549C14.0951 23.6636 14.1506 23.5806 14.2205 23.5107L25.5107 12.2205C25.6519 12.0793 25.8433 12 26.043 12C26.2426 12 26.434 12.0793 26.5752 12.2205L30.7795 16.4248C30.9207 16.566 31 16.7574 31 16.957C31 17.1567 30.9207 17.3481 30.7795 17.4893L19.4893 28.7795C19.4194 28.8494 19.3364 28.9049 19.2451 28.9427C19.1537 28.9805 19.0559 29 18.957 29Z" stroke="#8E94A7" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<p>
<b>Анкета заполнена и ожидает вашего подписания</b>
Вы заполнили и подписали анкету лизингополучателя посредством
ЭЦП. Анкета передана в обрабатывающий центр. Если у
сотрудников возникнут вопросы мы свяжемся с Вами. Спасибо!
</p>
</div>
<div className="questionnaire status_action">
<button className="button button-blue">
Загрузить подписанный документ
</button>
</div>
<div className="questionnaire status_action" style={{ width: "100%" }}>
<div className="dosc_list medium-icon">
<div className="row">
<p className="doc_name i-pdf extension">
1234567 от 21.01.2021
</p>
<button className="button button-blue">Отправить</button>
</div>
</div>
</div>
<div className="questionnaire message success">
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22 38.5C31.1127 38.5 38.5 31.1127 38.5 22C38.5 12.8873 31.1127 5.5 22 5.5C12.8873 5.5 5.5 12.8873 5.5 22C5.5 31.1127 12.8873 38.5 22 38.5Z" fill="white"/>
<path d="M29.5625 17.875L19.4791 27.5L14.4375 22.6875" stroke="#5FB158" strokeWidth="4" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
<p>
<b>Анкета заполнена и подписана</b>
Вы заполнили и подписали анкету лизингополучателя посредством
загрузки скана анкеты. Анкета передана в обрабатывающий центр.
Если у сотрудников возникнут вопросы мы свяжемся с Вами.
Спасибо!
</p>
</div>
</article>
</div>
</AccountLayout>
<Footer />
</React.Fragment>
);
}
}
function mapStateToProps(state, ownProps) {

View File

@ -48,7 +48,7 @@ export const questionnaire_template = {
telephone: null,
email: null,
identity_document: {
doctype: null,
doctype: 100000000,
seria: null,
docnumber: null,
issuedate: null,
@ -77,7 +77,7 @@ export const questionnaire_template = {
middlename: null,
no_middle_name: false,
jobtitle: null,
signer_rule_basis: null,
signer_rule_basis: 100000000,
signer_rule_basis_add: null,
docdate: null,
docnumber: null,
@ -85,7 +85,7 @@ export const questionnaire_template = {
telephone: null,
email: null,
identity_document: {
docype: null,
doctype: 100000000,
seria: null,
docnumber: null,
issuedate: null,
@ -104,6 +104,7 @@ export const questionnaire_template = {
}
},
signatory_person_files: [],
signatory_corporate_files: [],
founder_persons: [],
client_contacts: {
lastname: null,
@ -123,7 +124,7 @@ export const questionnaire_template = {
delegation_agreement: false,
functiontype: null,
identity_document: {
doctype: null,
doctype: 100000000,
seria: null,
docnumber: null,
issuedate: null,
@ -152,7 +153,16 @@ export const questionnaire_template = {
fin_goals_trucks: null,
fin_goals_special: null,
},
personal_data_consent: false,
personal_data_consent: true,
sign: {
digital: false,
print: true,
uploading: false,
uploaded: false,
sent: false,
filename: null,
filedate: null,
}
};
export const defaultState = {

View File

@ -393,6 +393,11 @@
resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz#0c8b74c50f29ee44f423f7416829c0bf8bb5eb27"
integrity sha512-LwzQKA4vzIct1zNZzBmRKI9QuNpLgTQMEjsQLf3BXuGYb3QPTP4Yjf6mkdX+X1mYttZ808QpOwAzZjv28kq7DA==
"@tokenizer/token@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276"
integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==
"@types/classnames@^2.3.1":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.3.1.tgz#3c2467aa0f1a93f1f021e3b9bcf938bd5dfdc0dd"
@ -2953,6 +2958,15 @@ file-selector@^0.6.0:
dependencies:
tslib "^2.4.0"
file-type@^18.2.1:
version "18.2.1"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-18.2.1.tgz#6d8f1fa3b079606f6ecf89483346f55fcd2c671b"
integrity sha512-Yw5MtnMv7vgD2/6Bjmmuegc8bQEVA9GmAyaR18bMYWKqsWDG9wgYZ1j4I6gNMF5Y5JBDcUcjRQqNQx7Y8uotcg==
dependencies:
readable-web-to-node-stream "^3.0.2"
strtok3 "^7.0.0"
token-types "^5.0.1"
file-uri-to-path@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
@ -3489,7 +3503,7 @@ iconv-lite@^0.6.2:
dependencies:
safer-buffer ">= 2.1.2 < 3.0.0"
ieee754@^1.1.4:
ieee754@^1.1.4, ieee754@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
@ -5099,6 +5113,11 @@ pdf-lib@^1.17.1:
pako "^1.0.11"
tslib "^1.11.1"
peek-readable@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.0.0.tgz#7ead2aff25dc40458c60347ea76cfdfd63efdfec"
integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
@ -5529,6 +5548,13 @@ readable-stream@~2.3.6:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-web-to-node-stream@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb"
integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==
dependencies:
readable-stream "^3.6.0"
readdirp@^2.0.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525"
@ -6261,6 +6287,14 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
strtok3@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-7.0.0.tgz#868c428b4ade64a8fd8fee7364256001c1a4cbe5"
integrity sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==
dependencies:
"@tokenizer/token" "^0.3.0"
peek-readable "^5.0.0"
styled-jsx@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.1.tgz#ae3f716eacc0792f7050389de88add6d5245b9e9"
@ -6429,6 +6463,14 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
token-types@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/token-types/-/token-types-5.0.1.tgz#aa9d9e6b23c420a675e55413b180635b86a093b4"
integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==
dependencies:
"@tokenizer/token" "^0.3.0"
ieee754 "^1.2.1"
tough-cookie@^2.3.2, tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"