1001 lines
37 KiB
JavaScript
1001 lines
37 KiB
JavaScript
import React from "react";
|
||
import Head from 'next/head';
|
||
import Image from 'next/image';
|
||
import Link from "next/link";
|
||
import cookie from 'cookie';
|
||
import numeral from "numeral";
|
||
import pluralize from 'pluralize-ru';
|
||
import { SpinnerCircular } from 'spinners-react';
|
||
import Select from 'react-select';
|
||
import { connect } from "react-redux";
|
||
import { withRouter } from 'next/router';
|
||
import { get as _get, slice } from 'lodash';
|
||
import InputMask from 'react-input-mask';
|
||
import CurrencyInput from 'react-currency-input-field';
|
||
import moment from "moment";
|
||
|
||
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 { getCitizenshipTitleByCode } from "../../../../utils/citizenship";
|
||
import { checkDocumentData, saveQuestionnaire } from "../../../../actions";
|
||
import SuggestsInput from "../../SuggestsInput";
|
||
import DocumentIssuerSuggestsInput from "../../DocumentIssuerSuggestsInput";
|
||
import FormMessage from "../FormMessage";
|
||
|
||
class ShareholderForm extends React.Component
|
||
{
|
||
_handle_onTextFieldChange = this.props._handle_onTextFieldChange;
|
||
_handle_onCheckboxFieldChange = this.props._handle_onCheckboxFieldChange;
|
||
_handle_onFieldChange = this.props._handle_onFieldChange;
|
||
_checkStrValue = this.props._checkStrValue;
|
||
_checkDateValue = this.props._checkDateValue;
|
||
_removeError = this.props._removeError;
|
||
_handle_onIssuerCodeChange = this.props._handle_onIssuerCodeChange;
|
||
_handle_onIssuerChange = this.props._handle_onIssuerChange;
|
||
_handle_onDocumentTypeChange = this.props._handle_onDocumentTypeChange;
|
||
_handle_onDateFieldChange = this.props._handle_onDateFieldChange;
|
||
|
||
_handle_onCitizenshipChange = (name, value) =>
|
||
{
|
||
let citizenship = getCitizenshipTitleByCode(value);
|
||
this._handle_onFieldChange(name, {
|
||
title: citizenship,
|
||
code: value,
|
||
});
|
||
}
|
||
|
||
_handle_onFloatFieldChange = (name, value) =>
|
||
{
|
||
let float = parseFloat(value);
|
||
let val = value;
|
||
|
||
if(isNaN(float))
|
||
{
|
||
val = "";
|
||
}
|
||
else if(float > 100)
|
||
{
|
||
val = 100;
|
||
}
|
||
else
|
||
{
|
||
//float = float.toFixed(2);
|
||
}
|
||
this._handle_onTextFieldChange(name, val);
|
||
}
|
||
|
||
_renderFloat = (value) =>
|
||
{
|
||
if(this._checkStrValue(value) !== "")
|
||
{
|
||
const float = parseFloat(value);
|
||
if(!isNaN(float))
|
||
{
|
||
return float.toFixed(2);
|
||
}
|
||
else
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, shareholder, checking, errors } = this.props;
|
||
|
||
let citizenship = { label: getCitizenshipTitleByCode(shareholder.identity_document.citizenship.code), code: shareholder.identity_document.citizenship.code };
|
||
|
||
return (
|
||
<React.Fragment>
|
||
<div className="form_field">
|
||
<label>Фамилия <sup className="required_label">*</sup></label>
|
||
<SuggestsInput
|
||
className={ errors.indexOf("lastname") > -1 ? "error" : "" }
|
||
type="lastname"
|
||
id={ `founder_persons[${ index }].lastname` }
|
||
name={ `founder_persons[${ index }].lastname` }
|
||
value={ this._checkStrValue(shareholder.lastname) }
|
||
placeholder="Введите фамилию"
|
||
onChange={ (value) => { this._removeError("lastname"); this._handle_onTextFieldChange(`founder_persons[${ index }].lastname`, value) } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
<div className="form_field">
|
||
<label>Имя <sup className="required_label">*</sup></label>
|
||
<SuggestsInput
|
||
className={ errors.indexOf("firstname") > -1 ? "error" : "" }
|
||
type="firstname"
|
||
id={ `founder_persons[${ index }].firstname` }
|
||
name={ `founder_persons[${ index }].firstname` }
|
||
value={ this._checkStrValue(shareholder.firstname) }
|
||
placeholder="Введите имя"
|
||
onChange={ (value) => { this._removeError("firstname"); this._handle_onTextFieldChange(`founder_persons[${ index }].firstname`, value) } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
<div className="form_field">
|
||
<label>Отчество <small>если имеется</small></label>
|
||
<SuggestsInput
|
||
className={ errors.indexOf("middlename") > -1 ? "error" : "" }
|
||
type="middlename"
|
||
id={ `founder_persons[${ index }].middlename` }
|
||
name={ `founder_persons[${ index }].middlename` }
|
||
value={ this._checkStrValue(shareholder.middlename) }
|
||
placeholder="Введите отчество"
|
||
onChange={ (value) => this._handle_onTextFieldChange(`founder_persons[${ index }].middlename`, value) }
|
||
required={ false }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
<div className="form_field">
|
||
<label>Должность <small>если имеется</small></label>
|
||
<input type="text"
|
||
id={ `founder_persons[${ index }].jobtitle` }
|
||
name={ `founder_persons[${ index }].jobtitle` }
|
||
value={ this._checkStrValue(shareholder.jobtitle) }
|
||
placeholder="Введите должность"
|
||
onChange={ (event) => this._handle_onTextFieldChange(event.target.name, event.target.value) }
|
||
required={ false }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
|
||
{/*
|
||
Запрос 2024-02-13 на удаление телефона и адреса E-mail
|
||
|
||
<div className="form_field">
|
||
<label>Телефон <sup className="required_label">*</sup></label>
|
||
<InputMask
|
||
className={ errors.indexOf("telephone") > -1 ? "error" : "" }
|
||
mask='+7 (999) 999 99 99'
|
||
id={ `founder_persons[${ index }].telephone` }
|
||
name={ `founder_persons[${ index }].telephone` }
|
||
value={ this._checkStrValue(shareholder.telephone) }
|
||
placeholder="Введите номер телефона"
|
||
onChange={ (event) => { if(event.target.value !== "" && !isNaN(parseInt(event.target.value.replace(/[^\d]+/g, ''), 10)) && parseInt(event.target.value.replace(/[^\d]+/g, ''), 10) > 7) { this._removeError("telephone"); } this._handle_onTextFieldChange(event.target.name, event.target.value) } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
<div className="form_field">
|
||
<label>Адрес E-mail <sup className="required_label">*</sup></label>
|
||
<input type="email"
|
||
className={ errors.indexOf("email") > -1 ? "error" : "" }
|
||
id={ `founder_persons[${ index }].email` }
|
||
name={ `founder_persons[${ index }].email` }
|
||
value={ this._checkStrValue(shareholder.email) }
|
||
placeholder="Введите E-mail"
|
||
onChange={ (event) => { this._removeError("email"); this._handle_onTextFieldChange(event.target.name, event.target.value) } }
|
||
pattern="[^@\s]+@[^@\s]+\.[^@\s]+"
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</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={ false }
|
||
className="autocomlete"
|
||
classNamePrefix="react-select"
|
||
value={ doctypes_personal.filter((type) => shareholder.identity_document.doctype === type.value) }
|
||
onChange={ (element) => { this._removeError("identity_document.doctype"); this._handle_onDocumentTypeChange(`founder_persons[${ index }]`, element); } }
|
||
//onChange={ (element) => this._handle_onTextFieldChange(`founder_persons[${ index }].identity_document.doctype`, element.value) }
|
||
required={ true }
|
||
isDisabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
{ errors.indexOf("identity_document.invalid") > -1 &&
|
||
(
|
||
<FormMessage type="error" title="Ошибка" message="Указаны недействительные паспортные данные."/>
|
||
) }
|
||
|
||
<div className="form_field ">
|
||
<div className="form_field">
|
||
<label>Серия и номер { parseInt(shareholder.identity_document.doctype, 10) === 100000002 ? "ВНЖ" : "паспорта" } <sup className="required_label">*</sup></label>
|
||
<div className="formgroup">
|
||
<div className="form_field">
|
||
<InputMask
|
||
className={ errors.indexOf("identity_document.seria") > -1 ? "error" : "" }
|
||
mask={ parseInt(shareholder.identity_document.doctype, 10) === 100000000 ? "9999" : parseInt(shareholder.identity_document.doctype, 10) === 100000002 ? "99" : undefined }
|
||
id={ `founder_persons[${ index }].identity_document.seria` }
|
||
name={ `founder_persons[${ index }].identity_document.seria` }
|
||
value={ this._checkStrValue(shareholder.identity_document.seria) }
|
||
placeholder="Введите серию"
|
||
onChange={ (event) => { this._removeError(["identity_document.seria", "identity_document.invalid"]); this._handle_onTextFieldChange(event.target.name, event.target.value) } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
<div className="form_field">
|
||
<InputMask
|
||
className={ errors.indexOf("identity_document.docnumber") > -1 ? "error" : "" }
|
||
mask={ parseInt(shareholder.identity_document.doctype, 10) === 100000000 ? "999999" : parseInt(shareholder.identity_document.doctype, 10) === 100000002 ? "9999999" : undefined }
|
||
id={ `founder_persons[${ index }].identity_document.docnumber` }
|
||
name={ `founder_persons[${ index }].identity_document.docnumber` }
|
||
value={ this._checkStrValue(shareholder.identity_document.docnumber) }
|
||
placeholder="Введите номер"
|
||
onChange={ (event) => { this._removeError(["identity_document.docnumber", "identity_document.invalid"]); this._handle_onTextFieldChange(event.target.name, event.target.value); } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="form_field ">
|
||
<div className="form_field">
|
||
<label>{ parseInt(shareholder.identity_document.doctype, 10) === 100000000 ? "Дата выдачи и код подразделения" : "Дата выдачи" } <sup className="required_label">*</sup></label>
|
||
<div className="formgroup">
|
||
<div className="form_field">
|
||
<CalendarDatePicker
|
||
className={ errors.indexOf("identity_document.issuedate") > -1 ? "error" : "" }
|
||
//style={{ width: "calc(100% - 198px)" }}
|
||
placeholder="ДД.ММ.ГГГГ"
|
||
max={ moment().toDate() }
|
||
id={ `founder_persons[${ index }].identity_document.issuedate` }
|
||
value={ this._checkStrValue(shareholder.identity_document.issuedate) !== "" ? this._checkStrValue(shareholder.identity_document.issuedate) : null }
|
||
onChange={ (date, raw) => { this._removeError("identity_document.issuedate"); this._handle_onDateFieldChange(`founder_persons[${ index }].identity_document.issuedate`, date, raw) } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
{ parseInt(shareholder.identity_document.doctype, 10) === 100000000 && (
|
||
<div className="form_field">
|
||
<DocumentIssuerSuggestsInput
|
||
className={ errors.indexOf("identity_document.code") > -1 ? "error" : "" }
|
||
style={{ width: "calc(100% - 198px)" }}
|
||
innerStyle={{ width: "100%", }}
|
||
type="issuer"
|
||
id={ `founder_persons[${ index }].identity_document.code` }
|
||
name={ `founder_persons[${ index }].identity_document.code` }
|
||
value={ this._checkStrValue(shareholder.identity_document.code) }
|
||
placeholder="Введите код"
|
||
onChange={ (value) => { this._handle_onIssuerCodeChange(`founder_persons[${ index }]`, index, value); } }
|
||
maxResults={ 5 }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="form_field">
|
||
<label>Кем выдан <sup className="required_label">*</sup></label>
|
||
<DocumentIssuerSuggestsInput
|
||
className={ errors.indexOf(`identity_document.issueby`) > -1 ? "error" : "" }
|
||
type="issuer"
|
||
id={ `founder_persons[${ index }].identity_document.issueby` }
|
||
name={ `founder_persons[${ index }].identity_document.issueby` }
|
||
value={ this._checkStrValue(shareholder.identity_document.issueby) }
|
||
placeholder="Введите наименование подразделения выдавшего документ"
|
||
onChange={ (value) => { this._handle_onIssuerChange(`founder_persons[${ index }]`, index, value); } }
|
||
maxResults={ 10 }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
<div className="form_field">
|
||
<label>Дата рождения <sup className="required_label">*</sup></label>
|
||
<CalendarDatePicker
|
||
className={ errors.indexOf("birthdate") > -1 ? "error" : "" }
|
||
//style={{ width: "calc(100% - 198px)" }}
|
||
placeholder="ДД.ММ.ГГГГ"
|
||
min={ moment().clone().subtract(90, 'years').toDate() }
|
||
max={ moment().clone().subtract(18, 'years').toDate() }
|
||
id={ `founder_persons[${ index }].birthdate` }
|
||
value={ this._checkStrValue(shareholder.birthdate) !== "" ? this._checkDateValue(shareholder.birthdate) : null }
|
||
onChange={ (date, raw) => { this._removeError("birthdate"); this._handle_onDateFieldChange(`founder_persons[${ index }].birthdate`, date, raw) } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
<div className="form_field" style={{ flex: 1 }}>
|
||
<label>Место рождения <sup className="required_label">*</sup></label>
|
||
<AddressSuggests
|
||
className={ errors.indexOf("identity_document.placebirth") > -1 ? "error" : "" }
|
||
id={ `founder_persons[${ index }].identity_document.placebirth` }
|
||
value={ this._checkStrValue(shareholder.identity_document.placebirth) }
|
||
onChange={ (data) => { this._removeError("identity_document.placebirth"); this._handle_onTextFieldChange(`founder_persons[${ index }].identity_document.placebirth`, data.name) } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
{ parseInt(shareholder.identity_document.doctype, 10) !== 100000000 && (
|
||
<div className="form_field">
|
||
<label>Гражданство <sup className="required_label">*</sup></label>
|
||
<Select
|
||
className={ errors.indexOf("identity_document.placebirth") > -1 ? "autocomlete error" : "autocomlete" }
|
||
id={ `founder_persons[${ index }].identity_document.citizenship` }
|
||
name={ `founder_persons[${ index }].identity_document.citizenship` }
|
||
options={ [ ...citizenships ] }
|
||
placeholder="Выберите страну"
|
||
noOptionsMessage={ ({ inputValue }) => !inputValue ? noOptionsText :"Ничего не найдено" }
|
||
isSearchable={ true }
|
||
classNamePrefix="react-select"
|
||
value={ citizenship.code !== null ? citizenship : undefined }
|
||
onChange={ (element) => this._handle_onCitizenshipChange(`founder_persons[${ index }].identity_document.citizenship`, element.value) }
|
||
required={ true }
|
||
isDisabled={ checking }
|
||
/>
|
||
</div>
|
||
) }
|
||
|
||
<div className="form_field">
|
||
<label>Адрес регистрации <sup className="required_label">*</sup></label>
|
||
<AddressSuggests
|
||
className={ errors.indexOf("identity_document.registration_address.name") > -1 ? "error" : "" }
|
||
id={ `founder_persons[${ index }].identity_document.registration_address` }
|
||
value={ this._checkStrValue(shareholder.identity_document.registration_address.name) }
|
||
fias={ this._checkStrValue(shareholder.identity_document.registration_address.fias_id) }
|
||
onChange={ (data) => { this._removeError("identity_document.registration_address.name"); this._handle_onTextFieldChange(`founder_persons[${ index }].identity_document.registration_address`, data) } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
{ index === 0 && errors.indexOf("founder_part_total") > -1 && (
|
||
<FormMessage type="error" title="Ошибка" message="Сумма долей не может быть больше 100%"/>
|
||
) }
|
||
|
||
<div className="form_field">
|
||
<label>Доля в уставном капитале (%) <sup className="required_label">*</sup>{ index > 0 && (<small>не менее 25%</small>) }</label>
|
||
{/*}
|
||
<InputMask
|
||
className={ errors.indexOf("founder_part") > -1 ? "error" : "" }
|
||
mask={ [ /[0-9]/, /[0-9]/, /./, /[0-9]/, /[0-9]/ ] }
|
||
maskPlaceholder="-"
|
||
// formatChars={{ '9': '[0-9]', }}
|
||
id={ `founder_persons[${ index }].founder_part` }
|
||
name={ `founder_persons[${ index }].founder_part` }
|
||
value={ this._checkStrValue(shareholder.founder_part) }
|
||
placeholder="Укажите размер доли"
|
||
onChange={ (event) => { this._removeError("founder_part"); this._handle_onFloatFieldChange(event.target.name, event.target.value); } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
{*/}
|
||
<CurrencyInput
|
||
className={ errors.indexOf("founder_part") > -1 ? "error" : "" }
|
||
id={ `founder_persons[${ index }].founder_part` }
|
||
name={ `founder_persons[${ index }].founder_part` }
|
||
// value={ this._renderFloat(shareholder.founder_part) }
|
||
value={ this._checkStrValue(shareholder.founder_part) !== "" && parseFloat(shareholder.founder_part) > 0 ? this._checkStrValue(shareholder.founder_part) : null }
|
||
// decimalsLimit={ 2 }
|
||
//selectAllOnFocus={ true }
|
||
placeholder="Укажите сумму"
|
||
decimalSeparator="."
|
||
groupSeparator=" "
|
||
//suffix=" ₽"
|
||
maxLength={ 5 }
|
||
// fixedDecimalLength={ 1 }
|
||
onValueChange={ (value, name) => { this._removeError(name); this._handle_onFloatFieldChange(name, value); } }
|
||
required={ true }
|
||
disabled={ checking }
|
||
/>
|
||
</div>
|
||
|
||
<div className="form_field">
|
||
<label>Является ли бенефициарным владельцем</label>
|
||
<div className="formgroup">
|
||
<div className="form_field checkbox">
|
||
<input type="radio" hidden=""
|
||
value="1"
|
||
id={ `founder_persons[${ index }].is_beneficial_1` }
|
||
name={ `founder_persons[${ index }].is_beneficial` }
|
||
checked={ shareholder.is_beneficial ? true : false }
|
||
onChange={ (event) => this._handle_onCheckboxFieldChange(event.target.name, true) }
|
||
disabled={ checking }
|
||
/>
|
||
<label className="unselectable" htmlFor={ `founder_persons[${ index }].is_beneficial_1` }>Да</label>
|
||
</div>
|
||
<div className="form_field checkbox">
|
||
<input type="radio" hidden=""
|
||
value="0"
|
||
id={ `founder_persons[${ index }].is_beneficial_0` }
|
||
name={ `founder_persons[${ index }].is_beneficial` }
|
||
checked={ shareholder.is_beneficial ? false : true }
|
||
onChange={ (event) => this._handle_onCheckboxFieldChange(event.target.name, false) }
|
||
disabled={ checking }
|
||
/>
|
||
<label className="unselectable" htmlFor={ `founder_persons[${ index }].is_beneficial_0` }>Нет</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</React.Fragment>
|
||
)
|
||
}
|
||
}
|
||
|
||
class Shareholder extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {};
|
||
}
|
||
|
||
_handle_onTextFieldChange = this.props._handle_onTextFieldChange;
|
||
_handle_onCheckboxFieldChange = this.props._handle_onCheckboxFieldChange;
|
||
_checkStrValue = this.props._checkStrValue;
|
||
_checkDateValue = this.props._checkDateValue;
|
||
_removeError = this.props._removeError;
|
||
|
||
_checkContactListDisabled = (check) =>
|
||
{
|
||
const { shareholders } = this.props;
|
||
for(let i in shareholders)
|
||
{
|
||
const shareholder = shareholders[i];
|
||
const hash = `${ shareholder.lastname }_${ shareholder.firstname }_${ shareholder.middlename }`;
|
||
|
||
if(hash === check)
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, shareholders, removeShareholder, signatories, contacts, changeFounderSelectionFromList, clearFounderFromListSelection, checking, errors, } = this.props;
|
||
const shareholder = shareholders[index];
|
||
|
||
return (
|
||
<React.Fragment>
|
||
<div className="added_person">
|
||
|
||
<div className="form_field">
|
||
<label>Физическое лицо { index + 1 }</label>
|
||
<div className="formgroup control">
|
||
|
||
{ !checking && (
|
||
<div className="form_field checkbox">
|
||
<input type="checkbox" hidden=""
|
||
checked={ shareholder.founder_from_list }
|
||
id={ `founder_persons[${ index }].founder_from_list` }
|
||
name={ `founder_persons[${ index }].founder_from_list` }
|
||
onChange={ (event) => clearFounderFromListSelection(`founder_persons[${ index }]`, { founder_from_list: !shareholder.founder_from_list ? true : false, lastname: "", firstname: "", middlename: "", no_middle_name: false, }) }
|
||
/>
|
||
<label className="unselectable" htmlFor={ `founder_persons[${ index }].founder_from_list` }>Выбрать из списка</label>
|
||
</div>
|
||
) }
|
||
|
||
{ !checking && (
|
||
<button className="delete" onClick={ (event) => { event.preventDefault(); removeShareholder(index) } }>
|
||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||
<path d="M20.25 5.25L3.75 5.25001" stroke="#ED0A34" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||
<path d="M9.75 9.75V15.75" stroke="#ED0A34" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||
<path d="M14.25 9.75V15.75" stroke="#ED0A34" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||
<path d="M18.75 5.25V19.5C18.75 19.6989 18.671 19.8897 18.5303 20.0303C18.3897 20.171 18.1989 20.25 18 20.25H6C5.80109 20.25 5.61032 20.171 5.46967 20.0303C5.32902 19.8897 5.25 19.6989 5.25 19.5V5.25" stroke="#ED0A34" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||
<path d="M15.75 5.25V3.75C15.75 3.35218 15.592 2.97064 15.3107 2.68934C15.0294 2.40804 14.6478 2.25 14.25 2.25H9.75C9.35218 2.25 8.97064 2.40804 8.68934 2.68934C8.40804 2.97064 8.25 3.35218 8.25 3.75V5.25" stroke="#ED0A34" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||
</svg>
|
||
</button>
|
||
) }
|
||
|
||
</div>
|
||
</div>
|
||
|
||
{ shareholder.founder_from_list ? (
|
||
<div className="feed">
|
||
<div className="feed_list">
|
||
|
||
{ contacts !== undefined && contacts !== null && contacts.map((contact, s_index) =>
|
||
{
|
||
const hash = `${ contact.lastname }_${ contact.firstname }_${ contact.middlename }`;
|
||
const disabled = hash !== shareholder.hash ? this._checkContactListDisabled(hash) : false;
|
||
|
||
if(checking)
|
||
{
|
||
if(shareholder.hash !== hash)
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
return (
|
||
<div className="form_field checkbox" key={ s_index }>
|
||
<input type="radio" hidden=""
|
||
id={ `founder_persons[${ index }].contact_${ hash }` }
|
||
name={ `founder_persons[${ index }].contact_${ hash }` }
|
||
checked={ hash === shareholder.hash }
|
||
onChange={ () => changeFounderSelectionFromList(index, `founder_persons[${ index }]`, { ...shareholder, ...contact, ...{
|
||
founder_from_list: false,
|
||
founder_number: shareholders.length,
|
||
} }) }
|
||
disabled={ disabled }
|
||
/>
|
||
<label className="unselectable" style={ disabled ? { opacity: "0.5" } : {} } htmlFor={ `founder_persons[${ index }].contact_${ hash }` }>
|
||
<div className="feed_item user">
|
||
<img src="/assets/images/icons/avatar.svg" alt="" />
|
||
<div>
|
||
<p className="item_title">{ contact.lastname } { contact.firstname } { contact.middlename }</p>
|
||
<p className="item_desc">
|
||
<span>{ contact.jobtitle }</span>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</label>
|
||
</div>
|
||
);
|
||
}) }
|
||
</div>
|
||
</div>
|
||
) : (
|
||
<ShareholderForm index={ index } shareholder={ shareholder } { ...this.props } />
|
||
) }
|
||
</div>
|
||
|
||
</React.Fragment>
|
||
)
|
||
}
|
||
}
|
||
|
||
class Form_4_Shareholders extends QuestionnaireForm
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
founder_persons: [],
|
||
founder_persons_template: {
|
||
signatory_id: null,
|
||
lastname: null,
|
||
firstname: null,
|
||
middlename: null,
|
||
no_middle_name: false,
|
||
jobtitle: null,
|
||
telephone: null,
|
||
email: null,
|
||
founder_from_list: true,
|
||
founder_number: 0,
|
||
founder_part: null,
|
||
is_beneficial: false,
|
||
birthdate: null,
|
||
identity_document:
|
||
{
|
||
doctype: 100000000,
|
||
seria: null,
|
||
docnumber: null,
|
||
issuedate: null,
|
||
code: null,
|
||
issueby: null,
|
||
issueby_search_dadata: null,
|
||
placebirth: null,
|
||
citizenship: {
|
||
title: "РОССИЯ",
|
||
code: 643,
|
||
},
|
||
registration_address: {
|
||
name: null,
|
||
fias_id: null,
|
||
}
|
||
}
|
||
},
|
||
loading: false,
|
||
status: "empty",
|
||
errors: [
|
||
[], [], [], []
|
||
],
|
||
client_contacts: [],
|
||
};
|
||
|
||
this.ref_form = React.createRef();
|
||
this.ref_submit = React.createRef();
|
||
}
|
||
|
||
static getDerivedStateFromProps(nextProps, prevState)
|
||
{
|
||
return {
|
||
founder_persons: nextProps.questionnaire.founder_persons,
|
||
client_contacts: nextProps.questionnaire.client_contacts,
|
||
status: nextProps.questionnaire.status,
|
||
};
|
||
}
|
||
|
||
componentDidMount()
|
||
{
|
||
const founder_persons_template = JSON.parse(JSON.stringify(this.state.founder_persons_template));
|
||
|
||
if(this.state.founder_persons.length === 0)
|
||
{
|
||
this._updateQuestionnaire({
|
||
founder_persons: [{ ...founder_persons_template, ...{ founder_from_list: false, founder_number: this.state.founder_persons.length + 1 } }],
|
||
});
|
||
}
|
||
}
|
||
|
||
_handle_onAddShareholder = () =>
|
||
{
|
||
const founder_persons = [ ...this.state.founder_persons ];
|
||
const founder_persons_template = JSON.parse(JSON.stringify(this.state.founder_persons_template));
|
||
|
||
if(founder_persons.length < 4)
|
||
{
|
||
founder_persons.push(founder_persons_template);
|
||
|
||
this._updateQuestionnaire({
|
||
founder_persons,
|
||
});
|
||
}
|
||
}
|
||
|
||
_handle_onRemoveShareholder = (index) =>
|
||
{
|
||
const founder_persons = [ ...this.state.founder_persons ];
|
||
|
||
founder_persons.splice(index, 1);
|
||
|
||
this._updateQuestionnaire({
|
||
founder_persons,
|
||
});
|
||
}
|
||
|
||
_handle_onClearFounderFromListSelection = (name, values) =>
|
||
{
|
||
const founder_persons_template = JSON.parse(JSON.stringify(this.state.founder_persons_template));
|
||
const update = { ...founder_persons_template , ...values };
|
||
|
||
this._handle_onFieldChange(name, update );
|
||
}
|
||
|
||
_handle_onChangeFounderSelectionFromList = (index, name, values) =>
|
||
{
|
||
this._handle_onFieldChange(name, { ...values } );
|
||
const { errors } = this.state;
|
||
errors.splice(index, 1, []);
|
||
this.setState({ errors });
|
||
}
|
||
|
||
_handle_onIssuerCodeChange = (branch, index, option) =>
|
||
{
|
||
this._onRemoveError(index, `identity_document.code`);
|
||
|
||
if(typeof option === "string")
|
||
{
|
||
this._handle_onTextFieldChange(`${ branch }.identity_document.code`, option);
|
||
}
|
||
else
|
||
{
|
||
this._handle_onBranchChange([
|
||
{ name: `${ branch }.identity_document.code`, value: option.data.code },
|
||
{ name: `${ branch }.identity_document.issueby`, value: option.value },
|
||
]);
|
||
this._onRemoveError(index, `identity_document.issueby`);
|
||
}
|
||
}
|
||
|
||
_handle_onIssuerChange = (branch, index, option) =>
|
||
{
|
||
this._onRemoveError(index, `identity_document.issueby`);
|
||
|
||
if(typeof option === "string")
|
||
{
|
||
this._handle_onTextFieldChange(`${ branch }.identity_document.issueby`, option);
|
||
}
|
||
else
|
||
{
|
||
this._handle_onBranchChange([
|
||
{ name: `${ branch }.identity_document.code`, value: option.data.code },
|
||
{ name: `${ branch }.identity_document.issueby`, value: option.value },
|
||
]);
|
||
this._onRemoveError(index, `identity_document.code`);
|
||
}
|
||
}
|
||
|
||
_handle_onDocumentTypeChange = (branch, element) =>
|
||
{
|
||
this._handle_onBranchChange([
|
||
{ name: `${ branch }.identity_document.doctype`, value: element.value },
|
||
{ name: `${ branch }.identity_document.citizenship_code`, value: parseInt(element.value, 10) === 100000000 ? 643 : null },
|
||
]);
|
||
}
|
||
|
||
_handle_onFormSubmit = (event) =>
|
||
{
|
||
event.preventDefault();
|
||
|
||
this._handle_onCheckboxFieldChange("step", 5);
|
||
setTimeout(() =>
|
||
{
|
||
saveQuestionnaire();
|
||
this.props.onNextStep("regulatory");
|
||
}, 10);
|
||
}
|
||
|
||
_handle_onNextPage = (event) =>
|
||
{
|
||
event.preventDefault();
|
||
const errors = [
|
||
[], [], [], []
|
||
];
|
||
|
||
const { founder_persons } = this.state;
|
||
|
||
const check = [
|
||
"founder_part",
|
||
"lastname",
|
||
"firstname",
|
||
/*
|
||
Запрос 2024-02-13 на удаление телефона и адреса E-mail
|
||
"telephone",
|
||
"email",
|
||
*/
|
||
"birthdate",
|
||
"identity_document.seria",
|
||
"identity_document.docnumber",
|
||
"identity_document.issuedate",
|
||
"identity_document.code",
|
||
"identity_document.issueby",
|
||
"identity_document.placebirth",
|
||
"identity_document.citizenship.code",
|
||
"identity_document.registration_address.name",
|
||
];
|
||
|
||
this.setState({ loading: true }, async () =>
|
||
{
|
||
if(parseInt(_get("signatory_person.identity_document.doctype"), 10) === 100000000)
|
||
{
|
||
}
|
||
|
||
let total_parts = 0;
|
||
|
||
for(let f in founder_persons)
|
||
{
|
||
for(let i in check)
|
||
{
|
||
if(check[i] === "identity_document.code")
|
||
{
|
||
if(parseInt(_get(founder_persons[f], "identity_document.doctype"), 10) !== 100000000)
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
|
||
const v = _get(founder_persons[f], check[i]);
|
||
/*
|
||
Запрос 2024-02-13 на удаление телефона и адреса E-mail
|
||
|
||
if(check[i] === "telephone")
|
||
{
|
||
if(v === "" || v === null || isNaN(parseInt(v.replace(/[^\d]+/g, ''), 10)) || parseInt(v.replace(/[^\d]+/g, ''), 10).toString().length < 11)
|
||
{
|
||
errors[f].push(`telephone`);
|
||
}
|
||
}
|
||
else if(check[i] === "email")
|
||
{
|
||
const r = new RegExp(/[^@\s]+@[^@\s]+\.[^@\s]+/);
|
||
if(!r.test(v))
|
||
{
|
||
errors[f].push(`email`);
|
||
}
|
||
}
|
||
*/
|
||
if(check[i] === "founder_part")
|
||
{
|
||
if(v !== "" && v !== null && !isNaN(parseFloat(v)))
|
||
{
|
||
total_parts = total_parts + parseFloat(v)
|
||
|
||
if(f > 0)
|
||
{
|
||
if(parseFloat(v) < 25)
|
||
{
|
||
errors[f].push(`founder_part`);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
errors[f].push(`founder_part`);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(v === "" || v === null)
|
||
{
|
||
errors[f].push(check[i]);
|
||
}
|
||
}
|
||
}
|
||
|
||
if(parseInt(total_parts, 10) > 100)
|
||
{
|
||
errors[0].push(`founder_part_total`);
|
||
}
|
||
|
||
if(parseInt(_get(founder_persons[f], "identity_document.doctype"), 10) === 100000000 && errors.indexOf("identity_document.seria") < 0 && errors.indexOf("identity_document.docnumber") < 0)
|
||
{
|
||
const founder_document_check_response = await checkDocumentData({
|
||
seria: _get(founder_persons[f], "identity_document.seria"),
|
||
number: _get(founder_persons[f], "identity_document.docnumber"),
|
||
});
|
||
|
||
if(founder_document_check_response[0] !== undefined && founder_document_check_response[0].qc !== 0)
|
||
{
|
||
errors[f].push(`identity_document.invalid`);
|
||
errors[f].push(`identity_document.seria`);
|
||
errors[f].push(`identity_document.docnumber`);
|
||
}
|
||
}
|
||
}
|
||
|
||
this.setState({ errors, loading: false }, () =>
|
||
{
|
||
window.scroll(0, 0);
|
||
let errnum = 0;
|
||
for(let i in errors)
|
||
{
|
||
for(let e in errors[i])
|
||
{
|
||
errnum++;
|
||
}
|
||
}
|
||
|
||
if(errnum === 0)
|
||
{
|
||
this.ref_submit.current.click();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
_onRemoveError = (index, name) =>
|
||
{
|
||
const errors = [ ...this.state.errors ];
|
||
|
||
if(typeof name === "string")
|
||
{
|
||
if(errors[index].indexOf(name) > -1)
|
||
{
|
||
errors[index].splice(errors[index].indexOf(name), 1);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for(let i in name)
|
||
{
|
||
if(errors[index].indexOf(name[i]) > -1)
|
||
{
|
||
errors[index].splice(errors[index].indexOf(name[i]), 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
this.setState({ errors });
|
||
}
|
||
|
||
_checkErrorsList = () =>
|
||
{
|
||
const { errors } = this.state;
|
||
|
||
for(let i in errors)
|
||
{
|
||
if(errors[i].length > 0)
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { checking } = this.props;
|
||
const { founder_persons, client_contacts, loading, address, status, errors, } = this.state;
|
||
console.log("Form_4_Shareholders", { errors });
|
||
|
||
return (
|
||
<form ref={ this.ref_form } onSubmit={ this._handle_onFormSubmit } onKeyDown={(e) => {if (e.key === 'Enter') e.preventDefault() }} className={`questionnaire questionnaire_4 ${ checking && "disabled" }`}>
|
||
<p className="title">4. Сведения об участниках (акционерах) и бенефициарных владельцах</p>
|
||
<p>– физических лицах, владеющих долей в уставном капитале более 25%
|
||
<small>*бенефициарный владелец (в соответствии с Федеральным законом от 07.08.2001 No115-ФЗ «О противодействии легализации (отмыванию) доходов, полученных преступным путем, и финансированию терроризма») —
|
||
физическое лицо, которое в конечном счете прямо или косвенно (через третьих лиц) владеет (имеет преобладающее участие более 25 процентов в капитале) вышеуказанным лизингополучателем-юридическим лицом, либо
|
||
имеет возможность контролировать действия вышеуказанного лизингополучателя. Бенефициарным владельцем лизингополучателя-физического лица считается это лицо, за исключением случаев, если имеются основания
|
||
полагать, что бенефициарным владельцем является иное физическое лицо. В случае, если бенефициарным владельцем являются несколько человек, сведения предоставляются в отношении каждого.</small>
|
||
</p>
|
||
{ this._checkErrorsList() &&
|
||
(
|
||
<FormMessage type="error" title="Ошибка" message="Пожалуйста, проверьте корректность заполнения данных в форме."/>
|
||
) }
|
||
{ founder_persons.map((shareholder, index) => {
|
||
return (
|
||
<Shareholder
|
||
key={ index }
|
||
index={ index }
|
||
shareholders={ founder_persons }
|
||
address={ address }
|
||
errors={ errors[index] }
|
||
_handle_onTextFieldChange={ this._handle_onTextFieldChange }
|
||
_handle_onDateFieldChange={ this._handle_onDateFieldChange }
|
||
_handle_onCheckboxFieldChange={ this._handle_onCheckboxFieldChange }
|
||
_handle_onFieldChange={ this._handle_onFieldChange }
|
||
_handle_onIssuerCodeChange={ this._handle_onIssuerCodeChange }
|
||
_handle_onIssuerChange={ this._handle_onIssuerChange }
|
||
_handle_onDocumentTypeChange={ this._handle_onDocumentTypeChange }
|
||
_checkStrValue={ this._checkStrValue }
|
||
_checkDateValue={ this._checkDateValue }
|
||
_removeError={ (name) => this._onRemoveError(index, name) }
|
||
removeShareholder={ this._handle_onRemoveShareholder }
|
||
clearFounderFromListSelection={ this._handle_onClearFounderFromListSelection }
|
||
changeFounderSelectionFromList={ this._handle_onChangeFounderSelectionFromList }
|
||
contacts={ client_contacts }
|
||
checking={ checking }
|
||
/>
|
||
) }
|
||
) }
|
||
|
||
{ !checking && (
|
||
<div className="action">
|
||
{ founder_persons.length < 4 ? (
|
||
<button className="button button-blue" disabled={ false } onClick={ (event) => { event.preventDefault(); this._handle_onAddShareholder(); }}>{ founder_persons.length === 0 ? "Добавить владельца" : "Добавить еще одного владельца" }</button>
|
||
) : (
|
||
<div></div>
|
||
) }
|
||
<div className="questionnaire_button_continue">
|
||
<button type="submit" className="button button-blue" onClick={ this._handle_onNextPage } disabled={ founder_persons.length === 0 ? true : founder_persons[0].founder_from_list ? true : false }>
|
||
{ 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/>
|
||
<a style={{ cursor: "pointer" }} onClick={ this._handle_onReset }>Отменить изменения в анкете</a>
|
||
</>
|
||
) }
|
||
</div>
|
||
</div>
|
||
) }
|
||
</form>
|
||
)
|
||
}
|
||
}
|
||
|
||
function mapStateToProps(state, ownProps)
|
||
{
|
||
return {
|
||
questionnaire: state.questionnaire,
|
||
}
|
||
}
|
||
|
||
export const getServerSideProps = reduxWrapper.getServerSideProps(store =>
|
||
async ({ req, res, query }) =>
|
||
{
|
||
}
|
||
);
|
||
|
||
export default connect(mapStateToProps)(Form_4_Shareholders); |