1329 lines
34 KiB
JavaScript
1329 lines
34 KiB
JavaScript
import React from "react";
|
||
import numeral from "numeral";
|
||
import moment from "moment";
|
||
import { eachLimit } from "async";
|
||
import { SpinnerCircular } from "spinners-react";
|
||
|
||
import FileDropzoneDeals from "../FileDropzoneDeals";
|
||
import EDOSign from "../../components/EDOSign";
|
||
|
||
import { acceptDealOffers, attachDealDocument, docEDOCancel, docEDOStatus, getFile, removeDealDocument, sendDealDocuments, signDownloadFile, signGetFileContractProject } from "../../actions";
|
||
|
||
class Step extends React.Component
|
||
{
|
||
componentDidMount()
|
||
{
|
||
if(this.status === this.props.statuscode_id)
|
||
{
|
||
this.setState({ open: true });
|
||
}
|
||
}
|
||
|
||
componentDidUpdate(prevProps, prevState)
|
||
{
|
||
if(this.props.statuscode_id !== prevProps.statuscode_id)
|
||
{
|
||
if(this.status === this.props.statuscode_id)
|
||
{
|
||
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 ? { position: "relative", } : { position: "relative", cursor: "inherit" }} onClick={ statuscode_id >= this.status ? this._handle_onSwitch : () => {} }>
|
||
{ this.status === statuscode_id && ( <div className="background"></div> )}
|
||
<i className={`status_${ this.status } ${ statuscode_id < this.status ? "inactive" : "" }`}></i>
|
||
<p>{ title }</p>
|
||
{ statuscode_id >= this.status && (
|
||
<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;
|
||
const offers = [];
|
||
|
||
for(let i in checked)
|
||
{
|
||
offers.push({
|
||
quote_number: checked[i],
|
||
agreed: true,
|
||
});
|
||
}
|
||
|
||
acceptDealOffers({ deal_id: dealSelected, offers })
|
||
.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, dealSelected, offers } = this.props;
|
||
const { checked, open, loading } = this.state;
|
||
|
||
return (
|
||
<div className={`${ this.status === statuscode_id ? "current" : statuscode_id > this.status ? "done" : "" }`}>
|
||
<p>№ { dealSelected }</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 className="deal_offers_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) =>
|
||
{
|
||
console.log({ offer });
|
||
|
||
return (
|
||
<tr key={ offer_index }>
|
||
{ offer.quote_status ? (
|
||
<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></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="docs_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, dealSelected } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ this.status === statuscode_id ? "current" : statuscode_id > this.status ? "done" : "" }`}>
|
||
<p>№ { dealSelected }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Программа финансирования") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
<div className="single_text">
|
||
{ statuscode_id === this.status ? (
|
||
<p>Идёт подбор оптимальной программы финансирования</p>
|
||
) : (
|
||
<p>Программа финансирования выбрана</p>
|
||
) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class DocumentsForm extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
files: {},
|
||
uploading: false,
|
||
completed: false,
|
||
loading: true,
|
||
};
|
||
this.status = 102;
|
||
}
|
||
|
||
componentDidUpdate(prevProps, prevState)
|
||
{
|
||
if(this.props.statuscode_id !== prevProps.statuscode_id)
|
||
{
|
||
if(this.status === this.props.statuscode_id)
|
||
{
|
||
this.setState({ open: true });
|
||
}
|
||
else
|
||
{
|
||
this.setState({ open: false });
|
||
}
|
||
}
|
||
|
||
if(prevProps.files !== this.props.files)
|
||
{
|
||
this.setState({ files: this.props.files, loading: false }, () =>
|
||
{
|
||
this._checkFilesCompleted();
|
||
});
|
||
}
|
||
}
|
||
|
||
_handle_onSendFiles = (event) =>
|
||
{
|
||
event.stopPropagation();
|
||
// event.preventDefault();
|
||
const { dealSelected, onDealsUpdate } = this.props;
|
||
|
||
this.setState({ loading: true }, () =>
|
||
{
|
||
sendDealDocuments({ deal_id: dealSelected })
|
||
.then(() =>
|
||
{
|
||
onDealsUpdate();
|
||
})
|
||
.catch(() =>
|
||
{
|
||
|
||
});
|
||
})
|
||
/*
|
||
const { files } = this.state;
|
||
const files_array = [];
|
||
|
||
for(let g in files)
|
||
{
|
||
for(let f in files[g])
|
||
{
|
||
files_array.push(files[g][f])
|
||
}
|
||
}
|
||
|
||
this.setState({ uploading: true }, () =>
|
||
{
|
||
eachLimit(files_array, 1, (file, callback) =>
|
||
{
|
||
const { opp_number } = this.props;
|
||
|
||
const payload = {
|
||
deal_id: opp_number,
|
||
document_id: file.group,
|
||
filename: file.name,
|
||
file,
|
||
};
|
||
|
||
attachDealDocument(payload)
|
||
.then(() =>
|
||
{
|
||
this._onSendFileStats(file.group, file.index);
|
||
|
||
callback();
|
||
}, 1000)
|
||
}, () =>
|
||
{
|
||
this.setState({ uploading: false }, () =>
|
||
{
|
||
this._checkFilesCompleted();
|
||
onDealsUpdate();
|
||
});
|
||
});
|
||
});
|
||
*/
|
||
}
|
||
|
||
_onSendFileStats = (group, index) =>
|
||
{
|
||
const files = { ...this.state.files };
|
||
|
||
files[group][index].sent = true;
|
||
|
||
this.setState({ files });
|
||
}
|
||
|
||
_handle_onAddFile = (document_id, files) =>
|
||
{
|
||
const existed_files = this.state.files;
|
||
const document_files = existed_files[ document_id ] === undefined ? [] : existed_files[ document_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)
|
||
{
|
||
files[nf].index = nf;
|
||
files[nf].group = document_id;
|
||
files[nf].sent = false;
|
||
document_files.push(files[nf]);
|
||
}
|
||
|
||
existed_files[ document_id ] = document_files;
|
||
|
||
this.setState({ files: existed_files }, () =>
|
||
{
|
||
const { opp_number } = this.props;
|
||
|
||
const payload = {
|
||
deal_id: opp_number,
|
||
document_id: files[0].group,
|
||
filename: files[0].name,
|
||
index: files[0].index,
|
||
lastModified: files[0].lastModified,
|
||
file: files[0],
|
||
type: files[0].type,
|
||
};
|
||
|
||
attachDealDocument(payload)
|
||
.then(() =>
|
||
{
|
||
this._onSendFileStats(document_id, 0);
|
||
this._checkFilesCompleted();
|
||
}, 1000)
|
||
//this._checkFilesCompleted();
|
||
});
|
||
}
|
||
}
|
||
|
||
_handle_onDeleteFile = (document_id, file) =>
|
||
{
|
||
const files = { ...this.state.files };
|
||
const { opp_number } = this.props;
|
||
|
||
const list = [];
|
||
|
||
for(let i in files[document_id])
|
||
{
|
||
if(files[document_id][i].name !== file.name)
|
||
{
|
||
list.push(files[document_id][i]);
|
||
}
|
||
}
|
||
|
||
if(list.length > 0)
|
||
{
|
||
files[document_id] = list;
|
||
}
|
||
else
|
||
{
|
||
delete files[document_id];
|
||
}
|
||
|
||
this.setState({ files }, () =>
|
||
{
|
||
this._checkFilesCompleted();
|
||
|
||
removeDealDocument({ deal_id: opp_number, document_id });
|
||
});
|
||
}
|
||
|
||
_checkFilesCompleted = () =>
|
||
{
|
||
const documents_length = this.props.documents.length;
|
||
const files_length = Object.keys(this.state.files).length;
|
||
|
||
const c = files_length >= documents_length ? true : false;
|
||
/*
|
||
const { files } = this.state;
|
||
const { documents } = this.props;
|
||
|
||
let c = true;
|
||
for(let g in documents)
|
||
{
|
||
const group = documents[g].doc_id;
|
||
|
||
if(files[group] === undefined || files[group].length === 0)
|
||
{
|
||
c = false;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
for(let f in files[group])
|
||
{
|
||
if(!files[group][f].sent)
|
||
{
|
||
c = false;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
|
||
this.setState({ completed: c });
|
||
}
|
||
|
||
_renderHeaderButtons = () =>
|
||
{
|
||
const { open, uploading, completed, loading, } = this.state;
|
||
const { statuscode_id } = this.props;
|
||
|
||
if(open && !uploading && !loading && completed)
|
||
{
|
||
if(this.status === statuscode_id)
|
||
{
|
||
return (
|
||
<div className="buttons">
|
||
<button className="button button button-blue" onClick={ this._handle_onSendFiles }>Отправить документы</button>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, statuscode_id, dealSelected, documents, questionnaire_status } = this.props;
|
||
const { open, files, uploading, loading } = this.state;
|
||
|
||
return (
|
||
<div className={`${ this.status === statuscode_id ? "current" : statuscode_id > this.status ? "done" : "" }`}>
|
||
<p>№ { dealSelected }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Сборка пакета документов") }
|
||
<div className="wrap form" style={{ display: open ? "block" : "none" }}>
|
||
{ 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>
|
||
) : (
|
||
<>
|
||
<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) =>
|
||
{
|
||
console.log({ document });
|
||
return (
|
||
<div className="block deal_documents_form_group" key={ index }>
|
||
<div className="left">
|
||
<p><b><span>{ document.name }</span>:</b></p>
|
||
</div>
|
||
<div className="right">
|
||
{ document.add ? (
|
||
<FileDropzoneDeals
|
||
uploading={ uploading }
|
||
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) }
|
||
document={ document }
|
||
/>
|
||
) : (
|
||
<>
|
||
{ document.check === "Документ принят" ? (
|
||
<div className="message ok">
|
||
<p>{ document.check }</p>
|
||
</div>
|
||
) : (
|
||
<div className="message wait">
|
||
<p>{ document.check }</p>
|
||
</div>
|
||
) }
|
||
</>
|
||
) }
|
||
</div>
|
||
</div>
|
||
)
|
||
} ) }
|
||
</>
|
||
) }
|
||
{/*}
|
||
<div className="message documents">
|
||
<div className="doc_list">
|
||
</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, dealSelected } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ statuscode_id === this.status ? "current" : statuscode_id > this.status ? "done" : "" }`}>
|
||
<p>№ { dealSelected }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Проверка документов") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
<div className="single_text">
|
||
{ statuscode_id === this.status ? (
|
||
<p>Идёт проверка предоставленных документов</p>
|
||
) : (
|
||
<p>Документы проверены</p>
|
||
) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class StatusDecisionMaking extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 104;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, statuscode_id, dealSelected } = this.props;
|
||
const { open } = this.state;
|
||
|
||
if(statuscode_id === 105)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
return (
|
||
<div className={`${ this.status === statuscode_id ? "current" : (statuscode_id > this.status) ? "done" : "" }`}>
|
||
<p>№ { dealSelected }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Принятие решения по сделке") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
<div className="single_text">
|
||
{ this.status === statuscode_id ? (
|
||
<p>Принятие решение о финансировании</p>
|
||
) : (
|
||
<p>Поздравляем! Принято положительное решение по сделке.</p>
|
||
) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class StatusDecisionRefuse extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 105;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, statuscode_id, dealSelected } = this.props;
|
||
const { open } = this.state;
|
||
|
||
if(statuscode_id !== this.status)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
return (
|
||
<div className={`${ this.status === statuscode_id ? "current" : (statuscode_id > this.status) ? "done" : "" }`}>
|
||
<p>№ { dealSelected }</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 StatusPositiveDecision extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
};
|
||
this.status = 106;
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, statuscode_id, dealSelected } = this.props;
|
||
const { open } = this.state;
|
||
|
||
return (
|
||
<div className={`${ this.status === statuscode_id ? "current" : statuscode_id > this.status ? "done" : "" }`}>
|
||
<p>№ { dealSelected }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Принято положительное решение") }
|
||
<div className="wrap" style={{ display: open ? "block" : "none" }}>
|
||
<div className="single_text">
|
||
{ statuscode_id === this.status ? (
|
||
<p>Идёт подготовка необходимых документов для заключения сделки</p>
|
||
) : (
|
||
<p>Документы подготовлены</p>
|
||
) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class SignPlannedContract extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
loading: true,
|
||
loading_download_file: false,
|
||
loading_cancel_sign: false,
|
||
disabled: false,
|
||
status: undefined,
|
||
contract_entity_id: undefined,
|
||
};
|
||
}
|
||
|
||
async componentDidMount()
|
||
{
|
||
const { contract } = this.props;
|
||
console.log("SignPlannedContract", "CDM", { props: this.props });
|
||
|
||
if(contract.sign_type === "EDO")
|
||
{
|
||
const status_result = await docEDOStatus({ contract_number: contract.name });
|
||
console.log("SignPlannedContract", "CDM", { status_result });
|
||
this.setState({ contract_entity_id: status_result.edoid, status: status_result.status, loading: false });
|
||
}
|
||
else
|
||
{
|
||
this.setState({ loading: false });
|
||
}
|
||
}
|
||
|
||
_handle_downloadFile = (edo) =>
|
||
{
|
||
console.log("_handle_downloadFile");
|
||
|
||
const { contract } = this.props;
|
||
//const { contract_entity_id } = this.state;
|
||
|
||
this.setState({ disabled: true, loading_download_file: true }, async () =>
|
||
{
|
||
const link_result = await signGetFileContractProject({
|
||
contract_number: contract.name
|
||
});
|
||
|
||
console.log("_downloadFile", { link_result });
|
||
await getFile({ id: link_result.url, filename: `ЛК ЭВОЛЮЦИЯ ${ contract.name }.${ link_result.extension }` });
|
||
this.setState({ disabled: false, loading_download_file: false });
|
||
|
||
/*
|
||
const wmdoc_result = await signDownloadFile({
|
||
payload: { entity_name: "evo_contract", entity_id: contract_entity_id, sign_type: edo ? "EDO" : "Paper", evo_id: "144", },
|
||
filename: `ЛК ЭВОЛЮЦИЯ ${ contract.name }.pdf`,
|
||
});
|
||
console.log({ wmdoc_result });
|
||
*/
|
||
});
|
||
}
|
||
|
||
_handle_cancelEDOSign = () =>
|
||
{
|
||
console.log("_handle_cancelEDOSign");
|
||
const { contract, onDealContractsUpdate } = this.props;
|
||
|
||
this.setState({ disabled: true, loading_cancel_sign: true }, async () =>
|
||
{
|
||
await docEDOCancel({ contract_number: contract.name, doc_type_id: contract.sign_type === "EDO" ? "144" : "60" });
|
||
setTimeout(() => {
|
||
onDealContractsUpdate();
|
||
//this.setState({ disabled: false, loading_cancel_sign: false });
|
||
}, 1000);
|
||
});
|
||
}
|
||
|
||
_handle_sendToEDO = () =>
|
||
{
|
||
console.log("_handle_sendToEDO");
|
||
}
|
||
|
||
_handle_goToEDO = () =>
|
||
{
|
||
console.log("_handle_goToEDO");
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, contract, } = this.props;
|
||
const { status, loading, disabled, loading_download_file, loading_cancel_sign } = this.state;
|
||
|
||
return (
|
||
<div className="document deal_contract_sign_item">
|
||
<div className="icon">
|
||
<span className="extension">PDF</span>
|
||
</div>
|
||
<div className="title">
|
||
<p>{ contract.name }</p>
|
||
<div className="description">
|
||
<span>{ moment(contract.date).format("DD.MM.YYYY") }</span>
|
||
<span>{ contract.brand_name }</span>
|
||
<span>{ contract.model_name }</span>
|
||
</div>
|
||
</div>
|
||
{ loading ? (
|
||
<SpinnerCircular size={ 22 } thickness={ 100 } speed={ 100 } color="rgba(236, 239, 244, 1)" secondaryColor="rgba(28, 1, 169, 1)" />
|
||
) : (
|
||
<>
|
||
{ contract.sign_type === "PAPER" && (
|
||
<div className="actions" style={{ justifyContent: "flex-end" }}>
|
||
<button className="button blue" disabled={ disabled } style={{ minWidth: "230px" }} onClick={ () => this._handle_downloadFile(false) }>{ loading_download_file ? (
|
||
<SpinnerCircular size={ 22 } thickness={ 100 } speed={ 100 } color="rgba(236, 239, 244, 1)" secondaryColor="rgba(28, 1, 169, 1)" />
|
||
) : ("Скачать файл для подписания") }</button>
|
||
</div>
|
||
) }
|
||
{ contract.sign_type === "EDO" && (
|
||
<div className="actions">
|
||
{ status < 3 && (
|
||
<button className="button blue" disabled={ disabled } style={{ minWidth: "130px" }} onClick={ () => this._handle_downloadFile(true) }>{ loading_download_file ? (
|
||
<SpinnerCircular size={ 22 } thickness={ 100 } speed={ 100 } color="rgba(236, 239, 244, 1)" secondaryColor="rgba(28, 1, 169, 1)" />
|
||
) : ("Скачать проект") }</button>
|
||
) }
|
||
{ status < 3 && (
|
||
<button className="button blue" disabled={ disabled } style={{ minWidth: "175px" }} onClick={ () => this._handle_cancelEDOSign() }>{ loading_cancel_sign ? (
|
||
<SpinnerCircular size={ 22 } thickness={ 100 } speed={ 100 } color="rgba(236, 239, 244, 1)" secondaryColor="rgba(28, 1, 169, 1)" />
|
||
) : ("Отменить подписание") }</button>
|
||
)}
|
||
{ status < 3 && (
|
||
<button className="button blue" disabled={ disabled } style={{ minWidth: "145px" }} onClick={ () => this._handle_sendToEDO() }>Отправить в ЭДО</button>
|
||
) }
|
||
{ status === 3 && (
|
||
<button className="button blue" style={{ minWidth: "145px" }} onClick={ () => this._handle_goToEDO() }>Перейти в ЭДО</button>
|
||
) }
|
||
</div>
|
||
) }
|
||
</>
|
||
) }
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
class LeasingRegistration extends Step
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.state = {
|
||
open: false,
|
||
/*
|
||
checked: {
|
||
prepared_contracts: [],
|
||
signing_plan_contracts: [],
|
||
signing_fact_contracts: [],
|
||
issued_contracts: [],
|
||
annulled_contracts: [],
|
||
},
|
||
*/
|
||
checked: [],
|
||
edo: false,
|
||
};
|
||
this.status = 107;
|
||
this.types = [
|
||
{
|
||
title: "Подготовлено",
|
||
key: "prepared_contracts",
|
||
},
|
||
{
|
||
title: "К подписанию",
|
||
key: "signing_plan_contracts",
|
||
},
|
||
{
|
||
title: "Подписано",
|
||
key: "signing_fact_contracts",
|
||
},
|
||
{
|
||
title: "Выдано",
|
||
key: "issued_contracts",
|
||
},
|
||
{
|
||
title: "Анулировано",
|
||
key: "annulled_contracts",
|
||
},
|
||
];
|
||
this.container_ref = React.createRef();
|
||
}
|
||
|
||
_handle_onScrollToContainer = () =>
|
||
{
|
||
const element = this.container_ref.current;
|
||
const y = (element.getBoundingClientRect().top + window.scrollY - 160);
|
||
window.scrollTo({top: y, behavior: 'smooth'});
|
||
}
|
||
|
||
_handle_onPreparedContract = (contract) =>
|
||
{
|
||
const checked = [ ...this.state.checked ];
|
||
|
||
if(checked.indexOf(contract) > -1)
|
||
{
|
||
checked.splice(checked.indexOf(contract), 1);
|
||
}
|
||
else
|
||
{
|
||
checked.push(contract);
|
||
}
|
||
|
||
this.setState({ checked });
|
||
}
|
||
|
||
_handle_onSignEDO = () =>
|
||
{
|
||
this.setState({ edo: true }, () =>
|
||
{
|
||
this._handle_onScrollToContainer();
|
||
});
|
||
}
|
||
|
||
_onEDOCancel = (clean = false) =>
|
||
{
|
||
if(clean)
|
||
{
|
||
this.setState({ edo: false, checked: [] });
|
||
}
|
||
else
|
||
{
|
||
this.setState({ edo: false });
|
||
}
|
||
}
|
||
|
||
_onEDOCancel = () =>
|
||
{
|
||
const { onDealContractsUpdate } = this.props;
|
||
|
||
this.setState({ edo: false }, () =>
|
||
{
|
||
onDealContractsUpdate();
|
||
});
|
||
}
|
||
|
||
_getEDODocuments = () =>
|
||
{
|
||
const contracts = this.props.contracts['prepared_contracts'];
|
||
const { checked } = this.state;
|
||
const documents = [];
|
||
|
||
for(let i in contracts)
|
||
{
|
||
if(checked.indexOf(contracts[i].name) > -1)
|
||
{
|
||
documents.push({
|
||
id: contracts[i].name,
|
||
name: `Договор № ${ contracts[i].name }`,
|
||
date: contracts[i].date,
|
||
type: `${ contracts[i].brand_name } ${ contracts[i].model_name }`,
|
||
extension: 'pdf',
|
||
})
|
||
}
|
||
}
|
||
|
||
return documents;
|
||
}
|
||
|
||
_render_preparedContracts = () =>
|
||
{
|
||
const { edo, checked } = this.state;
|
||
//const checked = this.state.checked.prepared_contracts;
|
||
|
||
const contracts = this.props.contracts['prepared_contracts'];
|
||
console.log("_render_preparedContracts", { contracts });
|
||
|
||
if(edo)
|
||
{
|
||
return (
|
||
<EDOSign
|
||
documents={ this._getEDODocuments() }
|
||
onCancel={ this._onEDOCancel }
|
||
onFinish={ this._onEDOFinish }
|
||
/>
|
||
)
|
||
}
|
||
|
||
return (
|
||
<div className="block-column">
|
||
<div className="docs_list acts_list-checkbox medium-icon">
|
||
{ contracts.length > 0 ?
|
||
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={ `contract_${ index }` } checked={ checked.indexOf(contract.name) > -1 ? true : false } onChange={ () => { this._handle_onPreparedContract(contract.name) } }/>
|
||
<label htmlFor={ `contract_${ index }` }>№{ 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>
|
||
)) : (
|
||
<p className="empty">Нет договоров</p>
|
||
) }
|
||
</div>
|
||
{ contracts.length > 0 &&
|
||
(
|
||
<div className="block_footer_btn">
|
||
<button className="button button-blue" onClick={ this._handle_onSignEDO } disabled={ checked.length > 0 ? false : true }>Подписать в ЭДО</button>
|
||
<button className="button button-blue" disabled={ checked.length > 0 ? false : true }>Подписать в бумажном виде</button>
|
||
</div>
|
||
) }
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_signingPlanContracts = () =>
|
||
{
|
||
const contracts = this.props.contracts['signing_plan_contracts'];
|
||
const { onDealContractsUpdate } = this.props;
|
||
console.log("_render_signingPlanContracts", { contracts });
|
||
|
||
return (
|
||
<div className="documents deal_contract_sign_list">
|
||
{ contracts.length > 0 ?
|
||
contracts.map((contract, index) => (
|
||
<SignPlannedContract
|
||
key={ `SignPlannedContract_${ contract.name }` }
|
||
index={ index }
|
||
contract={ contract }
|
||
onDealContractsUpdate={ onDealContractsUpdate }
|
||
/>
|
||
)
|
||
) : (
|
||
<p className="empty">Нет договоров</p>
|
||
) }
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_signingFactContracts = () =>
|
||
{
|
||
const contracts = this.props.contracts['signing_fact_contracts'];
|
||
console.log("_render_signingFactContracts", { contracts });
|
||
|
||
return (
|
||
<div className="documents">
|
||
{ contracts.length > 0 ?
|
||
contracts.map((contract, index) => (
|
||
<div className="document" key={ index }>
|
||
<div className="icon">
|
||
<span className="extension">PDF</span>
|
||
</div>
|
||
<div className="title">
|
||
<p>{ contract.name }</p>
|
||
<div className="description">
|
||
<span>{ moment(contract.date).format("DD.MM.YYYY") }</span>
|
||
<span>{ contract.brand_name }</span>
|
||
<span>{ contract.model_name }</span>
|
||
</div>
|
||
</div>
|
||
<div className="actions wide">
|
||
<div className="status">
|
||
<div className="status_icon"></div>
|
||
<span>{ contract.statuscode_name }</span>
|
||
</div>
|
||
<button className="button blue">Скачать</button>
|
||
</div>
|
||
</div>
|
||
)) : (
|
||
<p className="empty">Нет договоров</p>
|
||
) }
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_issuedContracts = () =>
|
||
{
|
||
const contracts = this.props.contracts['issued_contracts'];
|
||
console.log("_render_issuedContracts", { contracts });
|
||
|
||
return (
|
||
<div className="documents">
|
||
{ contracts.length > 0 ?
|
||
contracts.map((contract, index) => (
|
||
<div className="document" key={ index }>
|
||
<div className="icon">
|
||
<span className="extension">PDF</span>
|
||
</div>
|
||
<div className="title">
|
||
<p>{ contract.name }</p>
|
||
<div className="description">
|
||
<span>{ moment(contract.date).format("DD.MM.YYYY") }</span>
|
||
<span>{ contract.brand_name }</span>
|
||
<span>{ contract.model_name }</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)) : (
|
||
<p className="empty">Нет договоров</p>
|
||
) }
|
||
</div>
|
||
)
|
||
}
|
||
|
||
_render_annuledContracts = () =>
|
||
{
|
||
const contracts = this.props.contracts['annulled_contracts'];
|
||
console.log("_render_annuledContracts", { contracts });
|
||
|
||
return (
|
||
<div className="documents">
|
||
{ contracts.length > 0 ?
|
||
contracts.map((contract, index) => (
|
||
<div className="document" key={ index }>
|
||
<div className="icon">
|
||
<span className="extension">PDF</span>
|
||
</div>
|
||
<div className="title">
|
||
<p>{ contract.name }</p>
|
||
<div className="description">
|
||
<span>{ moment(contract.date).format("DD.MM.YYYY") }</span>
|
||
<span>{ contract.brand_name }</span>
|
||
<span>{ contract.model_name }</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)) : (
|
||
<p className="empty">Нет договоров</p>
|
||
) }
|
||
</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 "signing_fact_contracts":
|
||
{
|
||
return this._render_signingFactContracts();
|
||
}
|
||
|
||
case "issued_contracts":
|
||
{
|
||
return this._render_issuedContracts();
|
||
}
|
||
|
||
case "annulled_contracts":
|
||
{
|
||
return this._render_annuledContracts();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, statuscode_id, dealSelected } = this.props;
|
||
const { open, edo } = this.state;
|
||
|
||
return (
|
||
<div className={`${ this.status === statuscode_id ? "current" : statuscode_id > this.status ? "done" : "" }`} ref={ this.container_ref }>
|
||
<p>№ { dealSelected }</p>
|
||
<span></span>
|
||
<div className="status_body">
|
||
{ this._renderHeader("Оформление лизинга") }
|
||
<div className="wrap form contracts" style={{ display: open ? "block" : "none" }}>
|
||
{ this.props.contracts === undefined ? (
|
||
<div style={{ minHeight: 200, display: "flex", justifyContent: "center", alignItems: "center", }}>
|
||
<SpinnerCircular size={ 90 } thickness={ 51 } speed={ 100 } color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" />
|
||
</div>
|
||
) : (
|
||
<>
|
||
{ this.types.map((type, index) => (
|
||
<div className="block deal_contracts_group_item" key={ index }>
|
||
{ edo ? (
|
||
<>
|
||
{ type.key !== "prepared_contracts" && (
|
||
<div className="left"><p><b>{ type.title }</b></p></div>
|
||
) }
|
||
</>
|
||
) : (
|
||
<div className="left"><p><b>{ type.title }</b></p></div>
|
||
) }
|
||
<div className="right" style={ edo && type.key === "prepared_contracts" ? { width: "100%" } : {} }>
|
||
{ this._render_contracts(type.key) }
|
||
</div>
|
||
</div>
|
||
)) }
|
||
</>
|
||
) }
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
}
|
||
|
||
export default class SingleDeal extends React.Component
|
||
{
|
||
constructor(props)
|
||
{
|
||
super(props);
|
||
this.leasing_registration_ref = React.createRef();
|
||
}
|
||
|
||
_onDealContractsUpdate = () =>
|
||
{
|
||
const { onDealContractsUpdate, dealSelected } = this.props;
|
||
onDealContractsUpdate(dealSelected);
|
||
}
|
||
|
||
render()
|
||
{
|
||
const { index, status, deals, dealSelected, onCloseDeal, } = this.props;
|
||
|
||
const offers = deals.details[ dealSelected ] !== undefined ? deals.details[ dealSelected ].offers : undefined;
|
||
const documents = deals.details[ dealSelected ] !== undefined ? deals.details[ dealSelected ].documents : undefined;
|
||
const files = deals.details[ dealSelected ] !== undefined ? deals.details[ dealSelected ].files : 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 } files={ files }/>
|
||
<StatusDocumentsCheck { ...this.props }/>
|
||
<StatusDecisionMaking { ...this.props }/>
|
||
<StatusDecisionRefuse { ...this.props }/>
|
||
<StatusPositiveDecision { ...this.props }/>
|
||
<LeasingRegistration { ...this.props } contracts={ contracts } onDealContractsUpdate={ this._onDealContractsUpdate }/>
|
||
</div>
|
||
<div className="bottom_button_close" onClick={ onCloseDeal } >
|
||
<span>Свернуть</span>
|
||
<div className="icon"></div>
|
||
</div>
|
||
</div>
|
||
)
|
||
}
|
||
} |