Merge branch 'master' of https://github.com/merelendor/evoleasing-account
This commit is contained in:
commit
2c02bca53d
File diff suppressed because it is too large
Load Diff
@ -6,7 +6,7 @@ import { concatSeries } from "async";
|
||||
import { eachSeries } from 'async';
|
||||
import Select from 'react-select';
|
||||
|
||||
import { createEDOProject, docEDOCancel, signCheckCreatePrintForm, signDownloadFile, signGetGUIDEntity, signGetWMDoc, docEDOSign, docEDOStatus, docEDOConnect } from "../../actions";
|
||||
import { createEDOProject, docEDOCancel, signCheckCreatePrintForm, signDownloadFile, signGetGUIDEntity, signGetWMDoc, docEDOSign, docEDOStatus, docEDOConnect } from "../../../actions";
|
||||
|
||||
export default class DealContractsSignPaper extends React.Component
|
||||
{
|
||||
386
components/DealsStatus/components/DocumentsForm.js
Normal file
386
components/DealsStatus/components/DocumentsForm.js
Normal file
@ -0,0 +1,386 @@
|
||||
import React from "react";
|
||||
import { eachSeries } from "async";
|
||||
import { SpinnerCircular } from "spinners-react";
|
||||
|
||||
import FileDropzoneDeals from "../../FileDropzoneDeals";
|
||||
|
||||
import { attachDealDocument, removeDealDocument, sendDealDocuments, } from "../../../actions";
|
||||
|
||||
import Step from "./Step";
|
||||
|
||||
export default class DocumentsForm extends Step
|
||||
{
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
this.state = {
|
||||
open: false,
|
||||
uploaded: {},
|
||||
uploading: false,
|
||||
completed: false,
|
||||
loading: true,
|
||||
};
|
||||
this.status = 102;
|
||||
}
|
||||
|
||||
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 });
|
||||
}
|
||||
}
|
||||
|
||||
if(prevProps.uploaded !== this.props.uploaded)
|
||||
{
|
||||
this.setState({ uploaded: this.props.uploaded, loading: false }, () =>
|
||||
{
|
||||
const completed = this._checkFilesCompleted();
|
||||
this.setState({ completed });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_handle_onSendFiles = (event) =>
|
||||
{
|
||||
event.stopPropagation();
|
||||
const { dealSelected, onDealsUpdate } = this.props;
|
||||
|
||||
this.setState({ loading: true }, () =>
|
||||
{
|
||||
sendDealDocuments({ deal_id: dealSelected })
|
||||
.then(() =>
|
||||
{
|
||||
onDealsUpdate();
|
||||
})
|
||||
.catch(() =>
|
||||
{
|
||||
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
_onSendFileStats = (group, index) =>
|
||||
{
|
||||
console.log("_onSendFileStats", { group, index });
|
||||
|
||||
return new Promise((resolve) =>
|
||||
{
|
||||
const uploaded = { ...this.state.uploaded };
|
||||
|
||||
uploaded[group].files[index].uploaded = true;
|
||||
|
||||
this.setState({ uploaded }, () =>
|
||||
{
|
||||
console.log("_onSendFileStats", { uploaded });
|
||||
|
||||
resolve();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
_handle_onAddFile = (document_id, files, update) =>
|
||||
{
|
||||
const existed_files = { ...this.state.uploaded };
|
||||
console.log("_handle_onAddFile", { existed_files });
|
||||
const document_files = existed_files[ document_id ] === undefined ? [] : existed_files[ document_id ].files;
|
||||
|
||||
if(existed_files[ document_id ] === undefined)
|
||||
{
|
||||
existed_files[ document_id ] = {
|
||||
files: [],
|
||||
};
|
||||
}
|
||||
|
||||
let index = parseInt(existed_files[ document_id ].files.length, 10);
|
||||
|
||||
for(let nf in files)
|
||||
{
|
||||
console.log("_handle_onAddFile", { files });
|
||||
//let e = false;
|
||||
//for(let ef in document_files)
|
||||
//{
|
||||
// if(document_files[ef].name === files[nf].name) { e = true; }
|
||||
//}
|
||||
|
||||
//if(!e)
|
||||
//{
|
||||
// const ei = parseInt(existed_files[ document_id ].files.length, 10) > 0 ? parseInt(existed_files[ document_id ].files.length, 10) : 0;
|
||||
// const new_index = ei + parseInt(nf, 10);
|
||||
// console.log({ new_index });
|
||||
|
||||
// files[nf].index = new_index;
|
||||
files[nf].group = document_id;
|
||||
files[nf].uploaded = false;
|
||||
files[nf].update = update;
|
||||
|
||||
document_files.push(files[nf]);
|
||||
//}
|
||||
|
||||
existed_files[ document_id ].files = document_files;
|
||||
}
|
||||
|
||||
this.setState({ uploaded: existed_files, uploading: true }, () =>
|
||||
{
|
||||
const { opp_number } = this.props;
|
||||
|
||||
console.log("DOUBLE", { files });
|
||||
|
||||
eachSeries(files, (file, callback) =>
|
||||
{
|
||||
const payload = {
|
||||
deal_id: opp_number,
|
||||
document_id: file.group,
|
||||
filename: file.name,
|
||||
lastModified: file.lastModified,
|
||||
type: file.type,
|
||||
file,
|
||||
update,
|
||||
index,
|
||||
};
|
||||
|
||||
attachDealDocument(payload)
|
||||
.then(async () =>
|
||||
{
|
||||
await this._onSendFileStats(document_id, index);
|
||||
index++;
|
||||
callback();
|
||||
}, 1000)
|
||||
}, () =>
|
||||
{
|
||||
const completed = this._checkFilesCompleted();
|
||||
this.setState({ uploading: false, completed });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_handle_onDeleteFile = (document_id, index) =>
|
||||
{
|
||||
const uploaded = { ...this.state.uploaded };
|
||||
const { opp_number } = this.props;
|
||||
|
||||
const list = [ ...uploaded[document_id].files ];
|
||||
list.splice(index, 1);
|
||||
|
||||
uploaded[document_id].files = list;
|
||||
|
||||
/*
|
||||
for(let i in uploaded[document_id].files)
|
||||
{
|
||||
if(uploaded[document_id].files[i].name !== file.name)
|
||||
{
|
||||
list.push(uploaded[document_id].files[i]);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
if(list.length > 0)
|
||||
{
|
||||
uploaded[document_id].files = list;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete uploaded[document_id];
|
||||
}
|
||||
*/
|
||||
|
||||
this.setState({ uploaded }, () =>
|
||||
{
|
||||
const completed = this._checkFilesCompleted();
|
||||
this.setState({ completed }, () =>
|
||||
{
|
||||
removeDealDocument({ deal_id: opp_number, document_id, index });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
_handle_onQuestionnaire = (event) =>
|
||||
{
|
||||
const { onQuestionnaire } = this.props;
|
||||
|
||||
event.preventDefault();
|
||||
onQuestionnaire();
|
||||
}
|
||||
|
||||
_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 { uploaded } = this.state;
|
||||
const { documents } = this.props;
|
||||
|
||||
let c = true;
|
||||
if(documents !== undefined)
|
||||
{
|
||||
for(let g in documents)
|
||||
{
|
||||
if(!documents[g].add)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const group = documents[g].doc_id;
|
||||
console.log({ g: documents[g] });
|
||||
|
||||
if(uploaded[group] === undefined || uploaded[group].files.length === 0)
|
||||
{
|
||||
c = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(let f in uploaded[group].files)
|
||||
{
|
||||
if(!uploaded[group].files[f].uploaded)
|
||||
{
|
||||
c = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c = false;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
_renderHeaderButtons = () =>
|
||||
{
|
||||
const { open, uploading, completed, loading, } = this.state;
|
||||
const { statuscode_id } = this.props;
|
||||
|
||||
if(open && !uploading && !loading)
|
||||
{
|
||||
if(this.status === statuscode_id)
|
||||
{
|
||||
return (
|
||||
<div className="buttons">
|
||||
<button className="button button button-blue" onClick={ this._handle_onSendFiles } disabled={ completed ? false : true }>Отправить документы</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
const { index, statuscode_id, dealSelected, documents, questionnaire_status, } = this.props;
|
||||
const { open, uploaded, 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" onClick={ this._handle_onQuestionnaire }>Актуализировать данные</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
|
||||
statuscode_id={ statuscode_id }
|
||||
uploading={ uploading }
|
||||
uploaded={ uploaded[ document.doc_id ] !== undefined ? uploaded[ document.doc_id ] : { files: [] } }
|
||||
onAddFile={ (file, update) => { this._handle_onAddFile(document.doc_id, file, update) } }
|
||||
onDeleteFile={ this._handle_onDeleteFile }
|
||||
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>
|
||||
)
|
||||
}
|
||||
}
|
||||
40
components/DealsStatus/components/FinancialProgram.js
Normal file
40
components/DealsStatus/components/FinancialProgram.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React from "react";
|
||||
|
||||
import Step from "./Step";
|
||||
|
||||
export default 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
439
components/DealsStatus/components/LeasingRegistration.js
Normal file
439
components/DealsStatus/components/LeasingRegistration.js
Normal file
@ -0,0 +1,439 @@
|
||||
import React from "react";
|
||||
import moment from "moment";
|
||||
import { SpinnerCircular } from "spinners-react";
|
||||
|
||||
import EDOSign from "../../../components/EDOSign";
|
||||
|
||||
import Step from "./Step";
|
||||
import DealContractsSignPaper from "./DealContractsSignPaper";
|
||||
import SignPlannedContract from "./SignPlannedContract";
|
||||
|
||||
export default 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,
|
||||
paper: 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, paper: false }, () =>
|
||||
{
|
||||
this._handle_onScrollToContainer();
|
||||
});
|
||||
}
|
||||
|
||||
_handle_onSignPaper = (contract) =>
|
||||
{
|
||||
this.setState({ edo: false, paper: true }, () =>
|
||||
{
|
||||
this._handle_onScrollToContainer();
|
||||
});
|
||||
}
|
||||
|
||||
_onEDOCancel = (clean = false) =>
|
||||
{
|
||||
if(clean)
|
||||
{
|
||||
this.setState({ edo: false, checked: [] });
|
||||
}
|
||||
else
|
||||
{
|
||||
this.setState({ edo: false });
|
||||
}
|
||||
}
|
||||
|
||||
_handle_onCancelEDO = () =>
|
||||
{
|
||||
const { onDealContractsUpdate } = this.props;
|
||||
|
||||
this.setState({ edo: false, checked: [] }, () =>
|
||||
{
|
||||
onDealContractsUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
_handle_onFinishEDO = () =>
|
||||
{
|
||||
const { onDealContractsUpdate } = this.props;
|
||||
|
||||
this.setState({ edo: false, checked: [] }, () =>
|
||||
{
|
||||
onDealContractsUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
_handle_onCancelPaper = () =>
|
||||
{
|
||||
const { onDealContractsUpdate } = this.props;
|
||||
|
||||
this.setState({ paper: false, checked: [] }, () =>
|
||||
{
|
||||
onDealContractsUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
_handle_onFinishPaper = () =>
|
||||
{
|
||||
const { onDealContractsUpdate } = this.props;
|
||||
|
||||
this.setState({ paper: false, checked: [] }, () =>
|
||||
{
|
||||
onDealContractsUpdate();
|
||||
});
|
||||
}
|
||||
|
||||
_handle_onGoToEDOInvites = () =>
|
||||
{
|
||||
console.log("_handle_onGoToEDOInvites", { props: this.props });
|
||||
|
||||
this.props.router.push("/settings/digital");
|
||||
}
|
||||
|
||||
_getDocuments = () =>
|
||||
{
|
||||
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, paper, 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._getDocuments() }
|
||||
onCancel={ this._handle_onCancelEDO }
|
||||
onFinish={ this._handle_onFinishEDO }
|
||||
onGoToEDOInvites={ this._handle_onGoToEDOInvites }
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if(paper)
|
||||
{
|
||||
return (
|
||||
<DealContractsSignPaper
|
||||
documents={ this._getDocuments() }
|
||||
onCancel={ this._handle_onCancelPaper }
|
||||
onFinish={ this._handle_onFinishPaper }
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
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" onClick={ this._handle_onSignPaper } 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
186
components/DealsStatus/components/Offers.js
Normal file
186
components/DealsStatus/components/Offers.js
Normal file
@ -0,0 +1,186 @@
|
||||
import React from "react";
|
||||
import numeral from "numeral";
|
||||
import { SpinnerCircular } from "spinners-react";
|
||||
|
||||
import { acceptDealOffers, downloadDealOffer, } from "../../../actions";
|
||||
import Step from "./Step";
|
||||
|
||||
export default 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_onOffer = (quote_number) =>
|
||||
{
|
||||
downloadDealOffer({ quote_number, filename: `ЛК Эволюция КП №${ quote_number }.pdf` })
|
||||
.then(() => {})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
_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;
|
||||
const { statuscode_id } = this.props;
|
||||
|
||||
if(statuscode_id === this.status)
|
||||
{
|
||||
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 }>
|
||||
{ statuscode_id === this.status && 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" style={{ cursor: "pointer" }} onClick={ () => this._handle_onOffer(offer.quote_number) }>
|
||||
<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>
|
||||
)
|
||||
}
|
||||
}
|
||||
152
components/DealsStatus/components/SignPlannedContract.js
Normal file
152
components/DealsStatus/components/SignPlannedContract.js
Normal file
@ -0,0 +1,152 @@
|
||||
import React from "react";
|
||||
import moment from "moment";
|
||||
import { SpinnerCircular } from "spinners-react";
|
||||
|
||||
import { docEDOCancel, docEDOStatus, getFile, signGetFileContractProject } from "../../../actions";
|
||||
|
||||
export default 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,
|
||||
url: 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, url: status_result.url_edo });
|
||||
}
|
||||
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_onGoToEDO = () =>
|
||||
{
|
||||
const { url } = this.state;
|
||||
console.log("_handle_onGoToEDO", { url });
|
||||
|
||||
if(url !== undefined && url !== null)
|
||||
{
|
||||
window.open(url, "_blank");
|
||||
}
|
||||
}
|
||||
|
||||
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 === 1 && (
|
||||
<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 === 1 && (
|
||||
<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 === 1 && (
|
||||
<button className="button blue" disabled={ disabled } style={{ minWidth: "145px" }} onClick={ () => this._handle_sendToEDO() }>Отправить в ЭДО</button>
|
||||
) }
|
||||
{ status >= 2 && (
|
||||
<button className="button blue" style={{ minWidth: "145px" }} onClick={ () => this._handle_onGoToEDO() }>Перейти в ЭДО</button>
|
||||
) }
|
||||
</div>
|
||||
) }
|
||||
</>
|
||||
) }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
45
components/DealsStatus/components/StatusDecisionMaking.js
Normal file
45
components/DealsStatus/components/StatusDecisionMaking.js
Normal file
@ -0,0 +1,45 @@
|
||||
import React from "react";
|
||||
|
||||
import Step from "./Step";
|
||||
|
||||
export default 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
41
components/DealsStatus/components/StatusDecisionRefuse.js
Normal file
41
components/DealsStatus/components/StatusDecisionRefuse.js
Normal file
@ -0,0 +1,41 @@
|
||||
import React from "react";
|
||||
|
||||
import Step from "./Step";
|
||||
|
||||
export default 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
40
components/DealsStatus/components/StatusDocumentsCheck.js
Normal file
40
components/DealsStatus/components/StatusDocumentsCheck.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React from "react";
|
||||
|
||||
import Step from "./Step";
|
||||
|
||||
export default 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
40
components/DealsStatus/components/StatusPositiveDecision.js
Normal file
40
components/DealsStatus/components/StatusPositiveDecision.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React from "react";
|
||||
|
||||
import Step from "./Step";
|
||||
|
||||
export default 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
53
components/DealsStatus/components/Step.js
Normal file
53
components/DealsStatus/components/Step.js
Normal file
@ -0,0 +1,53 @@
|
||||
import React from "react";
|
||||
|
||||
export default 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>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -8,80 +8,99 @@ const LIMIT_FILES = 10;
|
||||
|
||||
export default class FileDropzoneDeals extends FileDropzone
|
||||
{
|
||||
constructor(props)
|
||||
{
|
||||
super(props);
|
||||
this.state = {
|
||||
message: true,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount()
|
||||
{
|
||||
console.log("FileDropzoneDeals", "CDM");
|
||||
}
|
||||
|
||||
_handle_onToggleShowMessage = () =>
|
||||
{
|
||||
this.setState({ message: this.state.message ? false : true });
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
const { uploaded, onAddFile, onDeleteFile, uploading, document, } = this.props;
|
||||
console.log("FileDropzoneDeals", { uploaded, document });
|
||||
const { uploaded, onAddFile, onDeleteFile, uploading, document, statuscode_id, } = this.props;
|
||||
const { message } = this.state;
|
||||
|
||||
let show_comment = false;
|
||||
if(document.comment !== null && document.comment !== "")
|
||||
{
|
||||
show_comment = true;
|
||||
if(!uploaded.sent)
|
||||
{
|
||||
show_comment = false;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ show_comment && (
|
||||
<div className="horizontal_dropzone_files_item horizontal_dropzone_files_error">
|
||||
<p className="horizontal_dropzone_files_comment">
|
||||
<span>{ document.check }</span>
|
||||
<span>{ document.comment }</span>
|
||||
</p>
|
||||
{ message ? (
|
||||
<p className="horizontal_dropzone_files_comment">
|
||||
<span className="title">{ document.check }</span>
|
||||
<span>{ document.comment }</span>
|
||||
</p>
|
||||
) : (
|
||||
<p className={`horizontal_dropzone_files_comment ${ !message ? "closed" : "" }`}>
|
||||
<span>Комментарий к ранее загруженным файлам</span>
|
||||
</p>
|
||||
) }
|
||||
<div className={`switch ${ !message ? "up" : "" }`} onClick={ this._handle_onToggleShowMessage }></div>
|
||||
</div>
|
||||
) }
|
||||
{ uploaded.files.length > 0 && (
|
||||
<div className="horizontal_dropzone_files_wrapper">
|
||||
<div className="horizontal_dropzone_files horizontal_dropzone_files_item">
|
||||
{ uploaded.files.map((file, index) =>
|
||||
{
|
||||
return (
|
||||
<div className="file" key={ index }>
|
||||
{ uploaded.sent ? (
|
||||
<div className="delete" onClick={ () => onDeleteFile(file.group, index) }>
|
||||
<div className="icon"></div>
|
||||
{ statuscode_id === 102 && (
|
||||
<>
|
||||
{ uploaded.files.length > 0 && (
|
||||
<div className="horizontal_dropzone_files_wrapper">
|
||||
<div className="horizontal_dropzone_files horizontal_dropzone_files_item">
|
||||
{ uploaded.files.map((file, index) =>
|
||||
{
|
||||
return (
|
||||
<div className="file" key={ index }>
|
||||
{ file.uploaded ? (
|
||||
<div className="delete" onClick={ () => onDeleteFile(file.group, index) }>
|
||||
<div className="icon"></div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="loading">
|
||||
<SpinnerCircular size={ 22 } thickness={ 100 } speed={ 100 } color="rgba(255, 255, 255, 1)" secondaryColor="rgba(168, 2, 107, 0.5)" style={{ marginTop: "8px" }}/>
|
||||
</div>
|
||||
) }
|
||||
<div className="doc_icon">
|
||||
<span className="extension">PDF</span>
|
||||
</div>
|
||||
<div className="title">
|
||||
<span>{ file.name }</span>
|
||||
<span>{ moment().format("DD.MM.YYYY") }</span>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="loading">
|
||||
<SpinnerCircular size={ 22 } thickness={ 100 } speed={ 100 } color="rgba(255, 255, 255, 1)" secondaryColor="rgba(168, 2, 107, 0.5)" style={{ marginTop: "8px" }}/>
|
||||
</div>
|
||||
) }
|
||||
<div className="doc_icon">
|
||||
<span className="extension">PDF</span>
|
||||
</div>
|
||||
<div className="title">
|
||||
<span>{ file.name }</span>
|
||||
<span>{ moment().format("DD.MM.YYYY") }</span>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
} ) }
|
||||
</div>
|
||||
</div>
|
||||
) }
|
||||
{ uploaded.files.length < LIMIT_FILES && (
|
||||
<Dropzone onDrop={ (acceptedFiles) => onAddFile(acceptedFiles, document.comment !== null && document.comment !== "" ? true : false) } maxFiles={ LIMIT_FILES } multiple={ true } disabled={ uploading }>
|
||||
{ ({getRootProps, getInputProps}) => (
|
||||
<div className={`file_upload dropzone horizontal_dropzone_wrapper ${ uploading ? "disabled" : "" }`} { ...getRootProps() }>
|
||||
<div className={`files`}></div>
|
||||
<div className={`horizontal_dropzone_inner`}>
|
||||
<p data-sm-text="Выберите файлы">
|
||||
<span>Перенесите файлы на экран для быстрой загрузки или выберите файл с компьютера</span>
|
||||
</p>
|
||||
<label htmlFor="" className="button button-blue">Загрузить файл</label>
|
||||
)
|
||||
} ) }
|
||||
</div>
|
||||
<input { ...getInputProps() } />
|
||||
</div>
|
||||
) }
|
||||
</Dropzone>
|
||||
{ uploaded.files.length < LIMIT_FILES && (
|
||||
<Dropzone onDrop={ (acceptedFiles) => onAddFile(acceptedFiles, document.comment !== null && document.comment !== "" ? true : false) } maxFiles={ LIMIT_FILES } multiple={ true } disabled={ uploading }>
|
||||
{ ({getRootProps, getInputProps}) => (
|
||||
<div className={`file_upload dropzone horizontal_dropzone_wrapper ${ uploading ? "disabled" : "" }`} { ...getRootProps() }>
|
||||
<div className={`files`}></div>
|
||||
<div className={`horizontal_dropzone_inner`}>
|
||||
<p data-sm-text="Выберите файлы">
|
||||
<span>Перенесите файлы на экран для быстрой загрузки или выберите файл с компьютера</span>
|
||||
</p>
|
||||
<label htmlFor="" className="button button-blue">Загрузить файл</label>
|
||||
</div>
|
||||
<input { ...getInputProps() } />
|
||||
</div>
|
||||
) }
|
||||
</Dropzone>
|
||||
) }
|
||||
</>
|
||||
) }
|
||||
</>
|
||||
)
|
||||
|
||||
@ -5773,6 +5773,7 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block .block_body .fines_
|
||||
display: flex;
|
||||
color: #8E94A7;
|
||||
margin-right: 20%;
|
||||
padding-top: 10px;
|
||||
}
|
||||
.contractStatus_modal .single_status > div .status_body .wrap .single_text p:before {
|
||||
content: "";
|
||||
@ -5782,6 +5783,7 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block .block_body .fines_
|
||||
height: 40px;
|
||||
min-width: 40px;
|
||||
margin-right: 20px;
|
||||
margin-top: -10px;
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='40' height='40' rx='8' fill='%232F80ED' fill-opacity='0.1'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M20 29C24.9706 29 29 24.9706 29 20C29 15.0294 24.9706 11 20 11C15.0294 11 11 15.0294 11 20C11 24.9706 15.0294 29 20 29ZM21 14.5C21 13.9477 20.5523 13.5 20 13.5C19.4477 13.5 19 13.9477 19 14.5V19.75C19 20.4404 19.5596 21 20.25 21H23.5C24.0523 21 24.5 20.5523 24.5 20C24.5 19.4477 24.0523 19 23.5 19H21V14.5Z' fill='%232F80ED'/%3E%3C/svg%3E");
|
||||
}
|
||||
.contractStatus_modal .single_status > div .status_body .wrap table {
|
||||
@ -6000,6 +6002,7 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block .block_body .fines_
|
||||
.contractStatus_modal .single_status > div .status_body .documents .document .actions .status span {
|
||||
font-weight: 300;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.contractStatus_modal .single_status > div .status_body .documents .document .wide {
|
||||
justify-content: space-between;
|
||||
@ -6176,6 +6179,21 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block .block_body .fines_
|
||||
}
|
||||
.horizontal_dropzone_files_error {
|
||||
padding-bottom: 15px;
|
||||
position: relative;
|
||||
}
|
||||
.horizontal_dropzone_files_error .switch {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14.625 6.75L9 12.375L3.375 6.75' stroke='%238E94A7' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center;
|
||||
z-index: 2;
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
.horizontal_dropzone_files_error .switch.up {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
.horizontal_dropzone_files_comment {
|
||||
background: rgba(131, 3, 84, 0.1);
|
||||
@ -6183,9 +6201,12 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block .block_body .fines_
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.horizontal_dropzone_files_comment span:first-child {
|
||||
.horizontal_dropzone_files_comment .title {
|
||||
font-weight: 600;
|
||||
}
|
||||
.horizontal_dropzone_files_comment.closed {
|
||||
background: #edeff5;
|
||||
}
|
||||
.deals_contracts {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -6591,6 +6591,7 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block {
|
||||
display: flex;
|
||||
color: #8E94A7;
|
||||
margin-right: 20%;
|
||||
padding-top: 10px;
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
@ -6600,6 +6601,7 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block {
|
||||
height: 40px;
|
||||
min-width: 40px;
|
||||
margin-right: 20px;
|
||||
margin-top: -10px;
|
||||
|
||||
background-image: url("data:image/svg+xml,%3Csvg width='40' height='40' viewBox='0 0 40 40' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Crect width='40' height='40' rx='8' fill='%232F80ED' fill-opacity='0.1'/%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M20 29C24.9706 29 29 24.9706 29 20C29 15.0294 24.9706 11 20 11C15.0294 11 11 15.0294 11 20C11 24.9706 15.0294 29 20 29ZM21 14.5C21 13.9477 20.5523 13.5 20 13.5C19.4477 13.5 19 13.9477 19 14.5V19.75C19 20.4404 19.5596 21 20.25 21H23.5C24.0523 21 24.5 20.5523 24.5 20C24.5 19.4477 24.0523 19 23.5 19H21V14.5Z' fill='%232F80ED'/%3E%3C/svg%3E");
|
||||
}
|
||||
@ -6880,6 +6882,7 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block {
|
||||
span {
|
||||
font-weight: 300;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7108,6 +7111,23 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block {
|
||||
|
||||
.horizontal_dropzone_files_error {
|
||||
padding-bottom: 15px;
|
||||
position: relative;
|
||||
|
||||
.switch {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M14.625 6.75L9 12.375L3.375 6.75' stroke='%238E94A7' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center;
|
||||
z-index: 2;
|
||||
transform: rotate(180deg);
|
||||
|
||||
&.up {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.horizontal_dropzone_files_comment {
|
||||
@ -7116,10 +7136,12 @@ main .dropdown_blocks_list.zero-margin.gibdd .dropdown_block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
span {
|
||||
&:first-child {
|
||||
font-weight: 600;
|
||||
}
|
||||
.title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&.closed {
|
||||
background: rgb(237 239 245);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ export default async function handler(req, res)
|
||||
group: document_id,
|
||||
index,
|
||||
type,
|
||||
uploaded: true,
|
||||
lastModified,
|
||||
};
|
||||
|
||||
@ -77,13 +78,11 @@ export default async function handler(req, res)
|
||||
{
|
||||
if(uploaded[ document_id ] !== undefined)
|
||||
{
|
||||
uploaded[ document_id ].sent = false;
|
||||
uploaded[ document_id ].files.push(file_payload);
|
||||
}
|
||||
else
|
||||
{
|
||||
uploaded[ document_id ] = {
|
||||
sent: false,
|
||||
files: [ file_payload ],
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +72,6 @@ export default async function handler(req, res)
|
||||
{
|
||||
console.log({ files: uploaded[ document_id ].files });
|
||||
|
||||
uploaded[ document_id ].sent = false;
|
||||
uploaded[ document_id ].files.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,7 +160,6 @@ export default async function handler(req, res)
|
||||
eachSeries(Object.keys(deals[ deal_id ].uploaded), (group, callback) =>
|
||||
{
|
||||
const document = deals[ deal_id ].uploaded[ group ];
|
||||
deals[ deal_id ].uploaded[ group ].sent = true;
|
||||
console.log({ group, document });
|
||||
|
||||
if(document.files.length === 1)
|
||||
@ -205,6 +204,7 @@ export default async function handler(req, res)
|
||||
}, async () =>
|
||||
{
|
||||
console.log("ALL FILES SENT");
|
||||
delete deals[ deal_id ];
|
||||
await RedisClient.set(key, JSON.stringify(deals));
|
||||
|
||||
res.status(200).json({});
|
||||
|
||||
@ -102,7 +102,7 @@ class AnnouncementsList extends React.Component
|
||||
</p>
|
||||
<p className="item_desc info">Наш оператор Диадок. Идентификатор участника ЭДО (GUID): <br/>2BM-9724016636-772401001-202007300714591533849</p>
|
||||
<div className="buttons">
|
||||
<a href={ "/" } className="item_link">Что такое ЭДО?</a>
|
||||
<a href={ "https://www.evoleasing.ru/services/edo/" } className="item_link" target="_blank">Что такое ЭДО?</a>
|
||||
<a href={ "/settings/digital" } className="item_link">Получить приглашение в ЭДО</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
3
public/assets/images/icons/toggle-cell_black.svg
Normal file
3
public/assets/images/icons/toggle-cell_black.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M13 6L8 11L3 6" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 208 B |
Loading…
x
Reference in New Issue
Block a user