636 lines
17 KiB
JavaScript
636 lines
17 KiB
JavaScript
import React from "react"
|
||
import numeral from "numeral";
|
||
import moment from "moment";
|
||
|
||
import { SpinnerCircular } from "spinners-react";
|
||
import FileDropzoneDeals from "../FileDropzoneDeals";
|
||
|
||
class Step extends React.Component
|
||
{
|
||
componentDidMount()
|
||
{
|
||
if(this.props.status === this.status)
|
||
{
|
||
this.setState({ open: true });
|
||
}
|
||
}
|
||
|
||
_handle_onSwitch = () =>
|
||
{
|
||
this.setState({ open: !this.state.open ? true : false });
|
||
}
|
||
|
||
_renderHeader = (title) =>
|
||
{
|
||
const { status } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className="status_header" style={{ position: "relative" }} onClick={ this._handle_onSwitch }>
|
||
{ status >= this.status && ( <div className="background"></div> )}
|
||
<i className={`status_${ this.status } ${ status < this.status ? "inactive" : "" }`}></i>
|
||
<p>{ title }</p>
|
||
<div className="button_arrow">
|
||
<div className={`icon ${ open ? "up" : "down" }`}></div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class Offers extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 1;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status, offers } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ status === this.status ? "current" : status > this.status ? "done" : "" }`}>
|
||
<p>Сделка { index + 1 }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Выбор КП") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
{ offers === undefined ? (
|
||
<div style={{ minHeight: 100, display: "flex", justifyContent: "center", alignItems: "center", }}>
|
||
<SpinnerCircular size={ 50 } thickness={ 51 } speed={ 100 } color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
|
||
</div>
|
||
) : (
|
||
<>
|
||
{ offers.length > 0 ? (
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th></th>
|
||
<th>№</th>
|
||
<th>Стоимость</th>
|
||
<th>Первый платеж, р.</th>
|
||
<th>Первый платеж, %</th>
|
||
<th>Марка</th>
|
||
<th>Модель</th>
|
||
<th>Объектов лизинга</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{ offers.map((offer, offer_index) => (
|
||
<tr key={ offer_index }>
|
||
<td>
|
||
<div className="form_field checkbox">
|
||
<input type="checkbox" name="row" id="row" checked="" onChange={ () => {} }/>
|
||
<label htmlFor="row"></label>
|
||
</div>
|
||
</td>
|
||
<td>{ offer_index + 1 }</td>
|
||
<td>{ numeral(offer.price).format(' ., ') } р.</td>
|
||
<td>{ numeral(offer.first_payment_rub).format(' ., ') } р.</td>
|
||
<td>{ offer.first_payment_perc }%</td>
|
||
<td>{ offer.brand_name }</td>
|
||
<td>{ offer.model_name }</td>
|
||
<td>{ offer.object_count }</td>
|
||
<td>
|
||
<div className="dosc_list">
|
||
<div className="row">
|
||
<div className="small-icon">
|
||
<p className="doc_name i-pdf">
|
||
КП
|
||
<span>№{ offer.quote_number }</span>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
)) }
|
||
</tbody>
|
||
</table>
|
||
) : (
|
||
<p>Нет предложений</p>
|
||
) }
|
||
</>
|
||
) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class FinancialProgram extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 2;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ status === this.status ? "current" : status > this.status ? "done" : "" }`}>
|
||
<p>Сделка { index + 1 }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Программа финансирования") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
<div className="single_text">
|
||
<p>Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class DocumentsForm extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
files: {},
|
||
};
|
||
this.status = 3;
|
||
}
|
||
|
||
_handle_onAddFile = (file_id, files) =>
|
||
{
|
||
console.log("_handle_onAddFile", { file_id, files });
|
||
const existed_files = this.state.files;
|
||
const document_files = existed_files[ file_id ] === undefined ? [] : existed_files[ file_id ];
|
||
|
||
for(let nf in files)
|
||
{
|
||
let e = false;
|
||
for(let ef in document_files)
|
||
{
|
||
if(document_files[ef].name === files[nf].name) { e = true; }
|
||
}
|
||
|
||
if(!e)
|
||
{
|
||
document_files.push(files[nf]);
|
||
}
|
||
|
||
existed_files[ file_id ] = document_files;
|
||
|
||
this.setState({ files: existed_files });
|
||
}
|
||
}
|
||
|
||
_handle_onDeleteFile = (file_id, file) =>
|
||
{
|
||
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status, documents, questionnaire_status } = this.props;
|
||
const { open, files } = this.state;
|
||
|
||
console.log({ documents });
|
||
|
||
return (
|
||
<div className={`${ status === this.status ? "current" : status > this.status ? "done" : "" }`}>
|
||
<p>Сделка { index + 1 }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Сборка пакета документов") }
|
||
<div className="wrap form" style={{ display: open ? "block" : "none" }}>
|
||
<div className="block">
|
||
<div className="left">
|
||
<p><b>Устав организации:</b></p>
|
||
</div>
|
||
<div className="right">
|
||
{ questionnaire_status === "need_to_fill" ? (
|
||
<div className="message alert">
|
||
<p>Требуется обновить данные в анкете</p>
|
||
<button className="button button-blue">Актуализировать данные</button>
|
||
</div>
|
||
) : (
|
||
<>
|
||
{ questionnaire_status !== "up_to_date" ? (
|
||
<div className="message wait">
|
||
<p>Проводится проверка анкеты Вашей организации</p>
|
||
</div>
|
||
) : (
|
||
<div className="message ok">
|
||
<p>Вам не требуется актуализация данных анкеты Клиента</p>
|
||
</div>
|
||
) }
|
||
</>
|
||
) }
|
||
</div>
|
||
</div>
|
||
{ documents === undefined ? (
|
||
<></>
|
||
) : (
|
||
<>
|
||
{ documents.map((document, index) => (
|
||
<div className="block" key={ index }>
|
||
<div className="left">
|
||
<p><b><span>{ document.name }</span>:</b></p>
|
||
</div>
|
||
<div className="right">
|
||
<FileDropzoneDeals
|
||
files={ files[ document.doc_id ] !== undefined ? files[ document.doc_id ] : [] }
|
||
onAddFile={ (file) => { this._handle_onAddFile(document.doc_id, file) } }
|
||
onDeleteFile={ (file) => this._handle_onDeleteFile(document.doc_id, file) }
|
||
/>
|
||
</div>
|
||
</div>
|
||
)) }
|
||
</>
|
||
)}
|
||
{/*}
|
||
<div className="message documents">
|
||
<div className="doc_list">
|
||
<div className="dosc_list medium-icon">
|
||
<div className="row">
|
||
<p className="doc_name i-pdf i-medium">№123/2023 от 01.01.2023</p>
|
||
</div>
|
||
</div>
|
||
<div className="dosc_list medium-icon">
|
||
<div className="row">
|
||
<p className="doc_name i-pdf i-medium">№123/2023 от 01.01.2023</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<p>Документы, отправленные Вами принадлежат другой организации бла бла коммент от менеджера</p>
|
||
</div>
|
||
{*/}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class StatusDocumentsCheck extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 4;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ status === this.status ? "current" : status > this.status ? "done" : "" }`}>
|
||
<p>Сделка { index + 1 }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Проверка документов") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
<div className="single_text">
|
||
<p>Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class StatusDecisionMaking extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 5;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ status === this.status ? "current" : status > this.status ? "done" : "" }`}>
|
||
<p>Сделка { index + 1 }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Принятие решения по заявке") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
<div className="single_text">
|
||
<p>Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class StatusLeasingRegistration extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 6;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ status === this.status ? "current" : status > this.status ? "done" : "" }`}>
|
||
<p>Сделка { index + 1 }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Оформление лизинга") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
<div className="single_text">
|
||
<p>Статусный текст о том что выбирается программа финансированияи может быть по центру иконочка часиков или слева от статусного текста иконочка часиков</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class SigningTypeSelection extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 7;
|
||
this.types = [
|
||
{
|
||
title: "Подготовлено",
|
||
key: "prepared_contracts",
|
||
},
|
||
/*
|
||
{
|
||
title: "К подписанию",
|
||
key: "signing_plan_contracts",
|
||
},
|
||
{
|
||
title: "Выдано",
|
||
key: "issued_contracts",
|
||
},
|
||
{
|
||
title: "Подписано",
|
||
key: "signing_fact_contracts",
|
||
},
|
||
{
|
||
title: "Анулировано",
|
||
key: "annulled_contracts",
|
||
},
|
||
*/
|
||
];
|
||
}
|
||
|
||
_render_preparedContracts = () =>
|
||
{
|
||
const contracts = this.props.contracts['prepared_contracts'];
|
||
console.log({ contracts });
|
||
|
||
return (
|
||
<div className="block-column">
|
||
<div className="dosc_list acts_list-checkbox medium-icon">
|
||
{ contracts.map((contract, index) => (
|
||
<div className="row" key={ index }>
|
||
<div className="doc_name i-doc i-medium blue deals_contracts" style={{ alignItems: "flex-start" }}>
|
||
<input type="checkbox" name="" id="" checked="" onChange={ () => {} }/>
|
||
<label htmlFor="">№{ contract.name }</label>
|
||
<div className="info">
|
||
<span>{ moment(contract.date).format('MM.DD.YYYY') }</span>
|
||
<span>{ contract.brand_name }</span>
|
||
<span>{ contract.model_name }</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)) }
|
||
</div>
|
||
<div className="block_footer_btn">
|
||
<button className="button button-blue">Подписать в ЭДО</button>
|
||
<button className="button button-blue">Подписать в бумажном виде</button>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_signingPlanContracts = () =>
|
||
{
|
||
const { contracts } = this.props;
|
||
|
||
return (
|
||
<div className="block-column">
|
||
<div className="dosc_list medium-icon">
|
||
<div className="row flex-start">
|
||
<p className="doc_name i-doc i-medium" >
|
||
№123/2023 от 01.01.2023
|
||
</p>
|
||
<button className="button">Перейти в ЭДО</button>
|
||
</div>
|
||
<div className="row flex-start">
|
||
<p className="doc_name i-doc i-medium" >
|
||
№123/2023 от 01.01.2023
|
||
</p>
|
||
<button className="button">Скачать документ</button>
|
||
<button className="button">Загрузить подписанный экземпляр</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_issuedContracts = () =>
|
||
{
|
||
const { contracts } = this.props;
|
||
|
||
return (
|
||
<div className="block-column">
|
||
<div className="dosc_list medium-icon">
|
||
<div className="row">
|
||
<p className="doc_name i-doc i-medium" >
|
||
<a href="#">Скачать №129/2023 от 01.01.2023 - Ожидание оплаты</a>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_signingFactContracts = () =>
|
||
{
|
||
const { contracts } = this.props;
|
||
|
||
return (
|
||
<div className="block-column">
|
||
<div className="dosc_list medium-icon">
|
||
<div className="row">
|
||
<p className="doc_name i-doc i-medium">
|
||
№123/2023 от 01.01.2023
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_annuledContracts = () =>
|
||
{
|
||
const { contracts } = this.props;
|
||
|
||
return (
|
||
<div className="block-column">
|
||
<div className="dosc_list medium-icon">
|
||
<div className="row">
|
||
<p className="doc_name i-doc i-medium">
|
||
№123/2023 от 01.01.2023
|
||
</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_contracts = (type) =>
|
||
{
|
||
const { contracts } = this.props;
|
||
|
||
if(contracts !== undefined)
|
||
{
|
||
switch (type)
|
||
{
|
||
case "prepared_contracts":
|
||
{
|
||
return this._render_preparedContracts();
|
||
}
|
||
|
||
case "signing_plan_contracts":
|
||
{
|
||
return this._render_signingPlanContracts();
|
||
}
|
||
|
||
case "issued_contracts":
|
||
{
|
||
return this._render_issuedContracts();
|
||
}
|
||
|
||
case "signing_fact_contracts":
|
||
{
|
||
return this._render_signingFactContracts();
|
||
}
|
||
|
||
case "annulled_contracts":
|
||
{
|
||
return this._render_annuledContracts();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ status === this.status ? "current" : status > this.status ? "done" : "" }`}>
|
||
<p>Сделка { index + 1 }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Выбор типа подписания") }
|
||
<div className="wrap form" style={{ display: open ? "block" : "none" }}>
|
||
{ this.types.map((type, index) => (
|
||
<div className="block" key={ index }>
|
||
<div className="left">
|
||
<p><b>{ type.title }</b></p>
|
||
</div>
|
||
<div className="right">
|
||
{ this._render_contracts(type.key) }
|
||
</div>
|
||
</div>
|
||
)) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
export default class SingleDeal extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status, deals, dealSelected, onCloseDeal } = this.props;
|
||
console.log({ "deals": deals });
|
||
|
||
const offers = deals.details[ dealSelected ] !== undefined ? deals.details[ dealSelected ].offers : undefined;
|
||
const documents = deals.details[ dealSelected ] !== undefined ? deals.details[ dealSelected ].documents : undefined;
|
||
const contracts = deals.details[ dealSelected ] !== undefined ? deals.details[ dealSelected ].contracts : undefined;
|
||
|
||
return (
|
||
<div className="contractStatus_modal">
|
||
{/*}
|
||
<div className="modal_header">
|
||
<p className="modal_title">Статус сделки</p>
|
||
<button className="modal_close" onClick={close}></button>
|
||
</div>
|
||
{*/}
|
||
<div className="modal_body single_status">
|
||
<Offers { ...this.props } offers={ offers }/>
|
||
<FinancialProgram { ...this.props }/>
|
||
<DocumentsForm { ...this.props } documents={ documents }/>
|
||
<StatusDocumentsCheck { ...this.props }/>
|
||
<StatusDecisionMaking { ...this.props }/>
|
||
<StatusLeasingRegistration { ...this.props }/>
|
||
<SigningTypeSelection { ...this.props } contracts={ contracts }/>
|
||
</div>
|
||
<div className="bottom_button_close" onClick={ onCloseDeal } >
|
||
<span>Свернуть</span>
|
||
<div className="icon"></div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
} |