2023-09-15 13:56:13 +03:00

752 lines
19 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from "react"
import numeral from "numeral";
import moment from "moment";
import { SpinnerCircular } from "spinners-react";
import FileDropzoneDeals from "../FileDropzoneDeals";
import { acceptDealOffers } from "../../actions";
class Step extends React.Component
{
componentDidMount()
{
if(this.status.indexOf(this.props.statuscode_id) > -1)
{
this.setState({ open: true });
}
}
componentDidUpdate(prevProps, prevState)
{
if(this.props.statuscode_id !== prevProps.statuscode_id)
{
if(this.status.indexOf(this.props.statuscode_id) > -1)
{
this.setState({ open: true });
}
else
{
this.setState({ open: false });
}
}
}
_handle_onSwitch = () =>
{
const { statuscode_id } = this.props;
this.setState({ open: !this.state.open ? true : false });
}
_renderHeader = (title) =>
{
const { statuscode_id } = this.props;
const { open } = this.state;
return (
<div className="status_header" style={statuscode_id >= this.status[ 0 ] ? { position: "relative", } : { position: "relative", cursor: "inherit" }} onClick={ statuscode_id >= this.status[ 0 ] ? this._handle_onSwitch : () => {} }>
{ this.status.indexOf(statuscode_id) > -1 && ( <div className="background"></div> )}
<i className={`status_${ this.status[ 0 ] } ${ statuscode_id < this.status[ 0 ] ? "inactive" : "" }`}></i>
<p>{ title }</p>
{ statuscode_id >= this.status[ 0 ] && (
<div className="button_arrow">
<div className={`icon ${ open ? "up" : "down" }`}></div>
</div>
) }
{ this._renderHeaderButtons !== undefined && this._renderHeaderButtons() }
</div>
)
}
}
class Offers extends Step
{
constructor(props)
{
super(props);
this.state = {
open: false,
loading: false,
checked: [],
};
this.status = [ 100 ];
}
_handle_onCheckOffer = (quote_number) =>
{
const checked = [ ...this.state.checked ];
let is_new = true;
if(checked.indexOf(quote_number) > -1)
{
checked.splice(checked.indexOf(quote_number), 1);
is_new = false;
}
if(is_new)
{
checked.push(quote_number);
}
this.setState({ checked });
}
_handle_onSend = (event) =>
{
event.preventDefault();
event.stopPropagation();
this.setState({ loading: true }, () =>
{
const { checked } = this.state;
const { dealSelected, onDealsUpdate } = this.props;
acceptDealOffers({ deal_id: dealSelected, offers: checked })
.then(() =>
{
onDealsUpdate()
.then(() =>
{
this.setState({ loading: false });
})
.catch(() =>
{
this.setState({ loading: false });
});
})
});
}
_renderHeaderButtons = () =>
{
const { open, checked, loading } = this.state;
if(!loading && open && checked.length > 0)
{
return (
<div className="buttons">
<button className="button button button-blue" onClick={ this._handle_onSend }>Согласовать</button>
</div>
)
}
return null;
}
render()
{
const { index, statuscode_id, offers } = this.props;
const { checked, open, loading } = this.state;
return (
<div className={`${ this.status.indexOf( statuscode_id ) > -1 ? "current" : statuscode_id > this.status[ 0 ] ? "done" : "" }`}>
<p>Сделка { index + 1 }</p>
<span></span>
<div className="status_body">
{ this._renderHeader("Выбор КП ") }
<div className="wrap" style={{ display: open ? "block" : "none" }}>
{ offers === undefined || loading ? (
<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={`offer_${ offer.quote_number }`} checked={ checked.indexOf(offer.quote_number) > -1 } onChange={ () => { this._handle_onCheckOffer(offer.quote_number) } }/>
<label htmlFor={`offer_${ offer.quote_number }`}></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 = [ 101 ];
}
render()
{
const { index, statuscode_id } = this.props;
const { open } = this.state;
return (
<div className={`${ this.status.indexOf( statuscode_id ) > -1 ? "current" : statuscode_id > this.status[ 0 ] ? "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 = [ 102 ];
}
_renderHeaderButtons = () =>
{
const { open, files } = this.state;
if(open && Object.keys(files).length > 0)
{
return (
<div className="buttons">
<button className="button button button-blue">Отправить документы</button>
</div>
)
}
return null;
}
_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) =>
{
const files = { ...this.state.files };
const list = [];
for(let i in files[file_id])
{
if(files[file_id][i].name !== file.name)
{
list.push(files[file_id][i]);
}
}
if(list.length > 0)
{
files[file_id] = list;
}
else
{
delete files[file_id];
}
this.setState({ files });
}
render()
{
const { index, statuscode_id, documents, questionnaire_status } = this.props;
const { open, files } = this.state;
console.log("DocumentsForm", { documents });
return (
<div className={`${ this.status.indexOf( statuscode_id ) > -1 ? "current" : statuscode_id > this.status[ 0 ] ? "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 = [ 103 ];
}
render()
{
const { index, statuscode_id } = this.props;
const { open } = this.state;
return (
<div className={`${ this.status.indexOf( statuscode_id ) > -1 ? "current" : statuscode_id > this.status[ 0 ] ? "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 = [ 104, 105, ];
}
render()
{
const { index, statuscode_id } = this.props;
const { open } = this.state;
return (
<div className={`${ this.status.indexOf(statuscode_id) > -1 ? "current" : (statuscode_id > this.status[0] && statuscode_id > this.status[1]) ? "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 = [ 106 ];
}
render()
{
const { index, statuscode_id } = this.props;
const { open } = this.state;
return (
<div className={`${ this.status.indexOf( statuscode_id ) > -1 ? "current" : statuscode_id > this.status[ 0 ] ? "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 = [ 107 ];
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("_render_preparedContracts", { 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.contracts['prepared_contracts'];
console.log("_render_signingPlanContracts", { contracts });
return (
<div className="horizontal_dropzone_files">
{ contracts.map((contract, index) => (
<div className="contract" key={ index }>
<div className="doc_icon">
</div>
<div className="title">
<span>{ contract.name }</span>
<span>{ moment().format("DD.MM.YYYY") }</span>
</div>
</div>
)) }
</div>
)
}
_render_issuedContracts = () =>
{
const contracts = this.props.contracts['issued_contracts'];
console.log("_render_issuedContracts", { contracts });
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.contracts['signing_fact_contracts'];
console.log("_render_signingFactContracts", { contracts });
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.contracts['annulled_contracts'];
console.log("_render_annuledContracts", { contracts });
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, statuscode_id } = this.props;
const { open } = this.state;
return (
<div className={`${ this.status.indexOf( statuscode_id ) > -1 ? "current" : statuscode_id > this.status[ 0 ] ? "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>
)
}
}