From a4d873abf637b4d69faefc5260657e8ae28a5b55 Mon Sep 17 00:00:00 2001 From: merelendor Date: Fri, 20 Oct 2023 11:17:17 +0300 Subject: [PATCH] deals update for documents loading --- components/DealsStatus/SingleDeal.js | 1426 +---------------- .../DealContractsSignPaper.js | 2 +- .../DealsStatus/components/DocumentsForm.js | 386 +++++ .../components/FinancialProgram.js | 40 + .../components/LeasingRegistration.js | 439 +++++ components/DealsStatus/components/Offers.js | 186 +++ .../components/SignPlannedContract.js | 152 ++ .../components/StatusDecisionMaking.js | 45 + .../components/StatusDecisionRefuse.js | 41 + .../components/StatusDocumentsCheck.js | 40 + .../components/StatusPositiveDecision.js | 40 + components/DealsStatus/components/Step.js | 53 + components/FileDropzoneDeals/index.js | 121 +- css/main/style.css | 23 +- css/main/style.less | 30 +- pages/api/deals/file/attach.js | 3 +- pages/api/deals/file/remove.js | 1 - pages/api/deals/upload.js | 2 +- pages/components/AnnouncementsList/index.js | 2 +- .../assets/images/icons/toggle-cell_black.svg | 3 + 20 files changed, 1555 insertions(+), 1480 deletions(-) rename components/DealsStatus/{ => components}/DealContractsSignPaper.js (99%) create mode 100644 components/DealsStatus/components/DocumentsForm.js create mode 100644 components/DealsStatus/components/FinancialProgram.js create mode 100644 components/DealsStatus/components/LeasingRegistration.js create mode 100644 components/DealsStatus/components/Offers.js create mode 100644 components/DealsStatus/components/SignPlannedContract.js create mode 100644 components/DealsStatus/components/StatusDecisionMaking.js create mode 100644 components/DealsStatus/components/StatusDecisionRefuse.js create mode 100644 components/DealsStatus/components/StatusDocumentsCheck.js create mode 100644 components/DealsStatus/components/StatusPositiveDecision.js create mode 100644 components/DealsStatus/components/Step.js create mode 100644 public/assets/images/icons/toggle-cell_black.svg diff --git a/components/DealsStatus/SingleDeal.js b/components/DealsStatus/SingleDeal.js index d540a17..e5ba397 100644 --- a/components/DealsStatus/SingleDeal.js +++ b/components/DealsStatus/SingleDeal.js @@ -1,1423 +1,13 @@ import React from "react"; -import numeral from "numeral"; -import moment from "moment"; -import { eachLimit, eachSeries } from "async"; -import { SpinnerCircular } from "spinners-react"; -import FileDropzoneDeals from "../FileDropzoneDeals"; -import EDOSign from "../../components/EDOSign"; - -import { acceptDealOffers, attachDealDocument, docEDOCancel, docEDOStatus, downloadDealOffer, getFile, removeDealDocument, sendDealDocuments, signDownloadFile, signGetFileContractProject } from "../../actions"; -import DealContractsSignPaper from "./DealContractsSignPaper"; - -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 ( -
= this.status ? { position: "relative", } : { position: "relative", cursor: "inherit" }} onClick={ statuscode_id >= this.status ? this._handle_onSwitch : () => {} }> - { this.status === statuscode_id && (
)} - -

{ title }

- { statuscode_id >= this.status && ( -
-
-
- ) } - { this._renderHeaderButtons !== undefined && this._renderHeaderButtons() } -
- ) - } -} - -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; - - if(!loading && open && checked.length > 0) - { - return ( -
- -
- ) - } - - return null; - } - - render() - { - const { index, statuscode_id, dealSelected, offers } = this.props; - const { checked, open, loading } = this.state; - - return ( -
this.status ? "done" : "" }`}> -

№ { dealSelected }

- -
- { this._renderHeader("Выбор КП ") } -
- { offers === undefined || loading ? ( -
- -
- ) : ( - <> - { offers.length > 0 ? ( - - - - - - - - - - - - - - - - { offers.map((offer, offer_index) => - { - console.log({ offer }); - - return ( - - { offer.quote_status ? ( - - ) : ( - - )} - - - - - - - - - - ) - } ) } - -
СтоимостьПервый платеж, ₽Первый платеж, %МаркаМодельОбъектов лизинга
-
- -1 } onChange={ () => { this._handle_onCheckOffer(offer.quote_number) } }/> - -
-
{ offer_index + 1 }{ numeral(offer.price).format(' ., ') } ₽{ numeral(offer.first_payment_rub).format(' ., ') } ₽{ offer.first_payment_perc }%{ offer.brand_name }{ offer.model_name }{ offer.object_count } -
this._handle_onOffer(offer.quote_number) }> -
-
-

- КП - №{ offer.quote_number } -

-
-
-
-
- ) : ( -

Нет предложений

- ) } - - ) } -
-
-
- ) - } -} - -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 ( -
this.status ? "done" : "" }`}> -

№ { dealSelected }

- -
- { this._renderHeader("Программа финансирования") } -
-
- { statuscode_id === this.status ? ( -

Идёт подбор оптимальной программы финансирования

- ) : ( -

Программа финансирования выбрана

- ) } -
-
-
-
- ) - } -} - -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(); -// 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) => - { - console.log("_onSendFileStats", { group, index }); - - return new Promise((resolve) => - { - const uploaded = { ...this.state.uploaded }; - - uploaded[group].files[index].sent = 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 ] = { - sent: false, - 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].sent = false; - files[nf].update = update; - - document_files.push(files[nf]); - } - - existed_files[ document_id ].sent = false; - existed_files[ document_id ].files = document_files; - } - - this.setState({ uploaded: existed_files, uploading: true }, () => - { - const { opp_number } = this.props; - - 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) - { - const group = documents[g].doc_id; - - 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].sent) - { - 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 ( -
- -
- ) - } - } - - return null; - } - - render() - { - const { index, statuscode_id, dealSelected, documents, questionnaire_status, } = this.props; - const { open, uploaded, uploading, loading } = this.state; - - return ( -
this.status ? "done" : "" }`}> -

№ { dealSelected }

- -
- { this._renderHeader("Сборка пакета документов") } -
- { loading ? ( -
- -
- ) : ( - <> -
-
-

Анкета клиента:

-
-
- { questionnaire_status === "need_to_fill" ? ( -
-

Требуется обновить данные в анкете

- -
- ) : ( - <> - { questionnaire_status !== "up_to_date" ? ( -
-

Проводится проверка анкеты Вашей организации

-
- ) : ( -
-

Вам не требуется актуализация данных анкеты Клиента

-
- ) } - - ) } -
-
- { documents === undefined ? ( - <> - ) : ( - <> - { documents.map((document, index) => - { - console.log({ document }); - return ( -
-
-

{ document.name }:

-
-
- { document.add ? ( - { this._handle_onAddFile(document.doc_id, file, update) } } - onDeleteFile={ this._handle_onDeleteFile } - document={ document } - /> - ) : ( - <> - { document.check === "Документ принят" ? ( -
-

{ document.check }

-
- ) : ( -
-

{ document.check }

-
- ) } - - ) } -
-
- ) - } ) } - - ) } - {/*} -
-
-
-

Документы, отправленные Вами принадлежат другой организации бла бла коммент от менеджера

-
- {*/} - - ) } -
-
-
- ) - } -} - -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 ( -
this.status ? "done" : "" }`}> -

№ { dealSelected }

- -
- { this._renderHeader("Проверка документов") } -
-
- { statuscode_id === this.status ? ( -

Идёт проверка предоставленных документов

- ) : ( -

Документы проверены

- ) } -
-
-
-
- ) - } -} - -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 ( -
this.status) ? "done" : "" }`}> -

№ { dealSelected }

- -
- { this._renderHeader("Принятие решения по сделке") } -
-
- { this.status === statuscode_id ? ( -

Принятие решение о финансировании

- ) : ( -

Поздравляем! Принято положительное решение по сделке.

- ) } -
-
-
-
- ) - } -} - -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 ( -
this.status) ? "done" : "" }`}> -

№ { dealSelected }

- -
- { this._renderHeader("Требуется изменение параметров") } -
-
-

Продолжение оформления заблокировано

-
-
-
-
- ) - } -} - -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 ( -
this.status ? "done" : "" }`}> -

№ { dealSelected }

- -
- { this._renderHeader("Принято положительное решение") } -
-
- { statuscode_id === this.status ? ( -

Идёт подготовка необходимых документов для заключения сделки

- ) : ( -

Документы подготовлены

- ) } -
-
-
-
- ) - } -} - -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 ( -
-
- PDF -
-
-

{ contract.name }

-
- { moment(contract.date).format("DD.MM.YYYY") } - { contract.brand_name } - { contract.model_name } -
-
- { loading ? ( - - ) : ( - <> - { contract.sign_type === "PAPER" && ( -
- -
- ) } - { contract.sign_type === "EDO" && ( -
- { status === 1 && ( - - ) } - { status === 1 && ( - - )} - { status === 1 && ( - - ) } - { status >= 2 && ( - - ) } -
- ) } - - ) } -
- ) - } -} - -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 ( - - ) - } - - if(paper) - { - return ( - - ) - } - - return ( -
-
- { contracts.length > 0 ? - contracts.map((contract, index) => ( -
-
- -1 ? true : false } onChange={ () => { this._handle_onPreparedContract(contract.name) } }/> - -
- { moment(contract.date).format('MM.DD.YYYY') } - { contract.brand_name } - { contract.model_name } -
-
-
- )) : ( -

Нет договоров

- ) } -
- { contracts.length > 0 && - ( -
- - -
- ) } -
- ) - } - - _render_signingPlanContracts = () => - { - const contracts = this.props.contracts['signing_plan_contracts']; - const { onDealContractsUpdate } = this.props; - console.log("_render_signingPlanContracts", { contracts }); - - return ( -
- { contracts.length > 0 ? - contracts.map((contract, index) => ( - - ) - ) : ( -

Нет договоров

- ) } -
- ) - } - - _render_signingFactContracts = () => - { - const contracts = this.props.contracts['signing_fact_contracts']; - console.log("_render_signingFactContracts", { contracts }); - - return ( -
- { contracts.length > 0 ? - contracts.map((contract, index) => ( -
-
- PDF -
-
-

{ contract.name }

-
- { moment(contract.date).format("DD.MM.YYYY") } - { contract.brand_name } - { contract.model_name } -
-
-
-
-
- { contract.statuscode_name } -
- -
-
- )) : ( -

Нет договоров

- ) } -
- ) - } - - _render_issuedContracts = () => - { - const contracts = this.props.contracts['issued_contracts']; - console.log("_render_issuedContracts", { contracts }); - - return ( -
- { contracts.length > 0 ? - contracts.map((contract, index) => ( -
-
- PDF -
-
-

{ contract.name }

-
- { moment(contract.date).format("DD.MM.YYYY") } - { contract.brand_name } - { contract.model_name } -
-
-
- )) : ( -

Нет договоров

- ) } -
- ) - } - - _render_annuledContracts = () => - { - const contracts = this.props.contracts['annulled_contracts']; - console.log("_render_annuledContracts", { contracts }); - - return ( -
- { contracts.length > 0 ? - contracts.map((contract, index) => ( -
-
- PDF -
-
-

{ contract.name }

-
- { moment(contract.date).format("DD.MM.YYYY") } - { contract.brand_name } - { contract.model_name } -
-
-
- )) : ( -

Нет договоров

- ) } -
- ) - } - - _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 ( -
this.status ? "done" : "" }`} ref={ this.container_ref }> -

№ { dealSelected }

- -
- { this._renderHeader("Оформление лизинга") } -
- { this.props.contracts === undefined ? ( -
- -
- ) : ( - <> - { this.types.map((type, index) => ( -
- { edo ? ( - <> - { type.key !== "prepared_contracts" && ( -

{ type.title }

- ) } - - ) : ( -

{ type.title }

- ) } -
- { this._render_contracts(type.key) } -
-
- )) } - - ) } -
-
-
- ) - } -} +import Offers from "./components/Offers"; +import FinancialProgram from "./components/FinancialProgram"; +import DocumentsForm from "./components/DocumentsForm"; +import StatusDocumentsCheck from "./components/StatusDocumentsCheck"; +import StatusDecisionMaking from "./components/StatusDecisionMaking"; +import StatusDecisionRefuse from "./components/StatusDecisionRefuse"; +import StatusPositiveDecision from "./components/StatusPositiveDecision"; +import LeasingRegistration from "./components/LeasingRegistration"; export default class SingleDeal extends React.Component { diff --git a/components/DealsStatus/DealContractsSignPaper.js b/components/DealsStatus/components/DealContractsSignPaper.js similarity index 99% rename from components/DealsStatus/DealContractsSignPaper.js rename to components/DealsStatus/components/DealContractsSignPaper.js index 4bce3db..f2ae34e 100644 --- a/components/DealsStatus/DealContractsSignPaper.js +++ b/components/DealsStatus/components/DealContractsSignPaper.js @@ -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 { diff --git a/components/DealsStatus/components/DocumentsForm.js b/components/DealsStatus/components/DocumentsForm.js new file mode 100644 index 0000000..2e46f68 --- /dev/null +++ b/components/DealsStatus/components/DocumentsForm.js @@ -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 ( +
+ +
+ ) + } + } + + return null; + } + + render() + { + const { index, statuscode_id, dealSelected, documents, questionnaire_status, } = this.props; + const { open, uploaded, uploading, loading } = this.state; + + return ( +
this.status ? "done" : "" }`}> +

№ { dealSelected }

+ +
+ { this._renderHeader("Сборка пакета документов") } +
+ { loading ? ( +
+ +
+ ) : ( + <> +
+
+

Анкета клиента:

+
+
+ { questionnaire_status === "need_to_fill" ? ( +
+

Требуется обновить данные в анкете

+ +
+ ) : ( + <> + { questionnaire_status !== "up_to_date" ? ( +
+

Проводится проверка анкеты Вашей организации

+
+ ) : ( +
+

Вам не требуется актуализация данных анкеты Клиента

+
+ ) } + + ) } +
+
+ { documents === undefined ? ( + <> + ) : ( + <> + { documents.map((document, index) => + { + console.log({ document }); + return ( +
+
+

{ document.name }:

+
+
+ { document.add ? ( + { this._handle_onAddFile(document.doc_id, file, update) } } + onDeleteFile={ this._handle_onDeleteFile } + document={ document } + /> + ) : ( + <> + { document.check === "Документ принят" ? ( +
+

{ document.check }

+
+ ) : ( +
+

{ document.check }

+
+ ) } + + ) } +
+
+ ) + } ) } + + ) } + {/*} +
+
+
+

Документы, отправленные Вами принадлежат другой организации бла бла коммент от менеджера

+
+ {*/} + + ) } +
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/FinancialProgram.js b/components/DealsStatus/components/FinancialProgram.js new file mode 100644 index 0000000..091e6cd --- /dev/null +++ b/components/DealsStatus/components/FinancialProgram.js @@ -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 ( +
this.status ? "done" : "" }`}> +

№ { dealSelected }

+ +
+ { this._renderHeader("Программа финансирования") } +
+
+ { statuscode_id === this.status ? ( +

Идёт подбор оптимальной программы финансирования

+ ) : ( +

Программа финансирования выбрана

+ ) } +
+
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/LeasingRegistration.js b/components/DealsStatus/components/LeasingRegistration.js new file mode 100644 index 0000000..71950dd --- /dev/null +++ b/components/DealsStatus/components/LeasingRegistration.js @@ -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 ( + + ) + } + + if(paper) + { + return ( + + ) + } + + return ( +
+
+ { contracts.length > 0 ? + contracts.map((contract, index) => ( +
+
+ -1 ? true : false } onChange={ () => { this._handle_onPreparedContract(contract.name) } }/> + +
+ { moment(contract.date).format('MM.DD.YYYY') } + { contract.brand_name } + { contract.model_name } +
+
+
+ )) : ( +

Нет договоров

+ ) } +
+ { contracts.length > 0 && + ( +
+ + +
+ ) } +
+ ) + } + + _render_signingPlanContracts = () => + { + const contracts = this.props.contracts['signing_plan_contracts']; + const { onDealContractsUpdate } = this.props; + console.log("_render_signingPlanContracts", { contracts }); + + return ( +
+ { contracts.length > 0 ? + contracts.map((contract, index) => ( + + ) + ) : ( +

Нет договоров

+ ) } +
+ ) + } + + _render_signingFactContracts = () => + { + const contracts = this.props.contracts['signing_fact_contracts']; + console.log("_render_signingFactContracts", { contracts }); + + return ( +
+ { contracts.length > 0 ? + contracts.map((contract, index) => ( +
+
+ PDF +
+
+

{ contract.name }

+
+ { moment(contract.date).format("DD.MM.YYYY") } + { contract.brand_name } + { contract.model_name } +
+
+
+
+
+ { contract.statuscode_name } +
+ +
+
+ )) : ( +

Нет договоров

+ ) } +
+ ) + } + + _render_issuedContracts = () => + { + const contracts = this.props.contracts['issued_contracts']; + console.log("_render_issuedContracts", { contracts }); + + return ( +
+ { contracts.length > 0 ? + contracts.map((contract, index) => ( +
+
+ PDF +
+
+

{ contract.name }

+
+ { moment(contract.date).format("DD.MM.YYYY") } + { contract.brand_name } + { contract.model_name } +
+
+
+ )) : ( +

Нет договоров

+ ) } +
+ ) + } + + _render_annuledContracts = () => + { + const contracts = this.props.contracts['annulled_contracts']; + console.log("_render_annuledContracts", { contracts }); + + return ( +
+ { contracts.length > 0 ? + contracts.map((contract, index) => ( +
+
+ PDF +
+
+

{ contract.name }

+
+ { moment(contract.date).format("DD.MM.YYYY") } + { contract.brand_name } + { contract.model_name } +
+
+
+ )) : ( +

Нет договоров

+ ) } +
+ ) + } + + _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 ( +
this.status ? "done" : "" }`} ref={ this.container_ref }> +

№ { dealSelected }

+ +
+ { this._renderHeader("Оформление лизинга") } +
+ { this.props.contracts === undefined ? ( +
+ +
+ ) : ( + <> + { this.types.map((type, index) => ( +
+ { edo ? ( + <> + { type.key !== "prepared_contracts" && ( +

{ type.title }

+ ) } + + ) : ( +

{ type.title }

+ ) } +
+ { this._render_contracts(type.key) } +
+
+ )) } + + ) } +
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/Offers.js b/components/DealsStatus/components/Offers.js new file mode 100644 index 0000000..a5ecc18 --- /dev/null +++ b/components/DealsStatus/components/Offers.js @@ -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 ( +
+ +
+ ) + } + } + + return null; + } + + render() + { + const { index, statuscode_id, dealSelected, offers } = this.props; + const { checked, open, loading } = this.state; + + return ( +
this.status ? "done" : "" }`}> +

№ { dealSelected }

+ +
+ { this._renderHeader("Выбор КП ") } +
+ { offers === undefined || loading ? ( +
+ +
+ ) : ( + <> + { offers.length > 0 ? ( + + + + + + + + + + + + + + + + { offers.map((offer, offer_index) => + { + console.log({ offer }); + + return ( + + { statuscode_id === this.status && offer.quote_status ? ( + + ) : ( + + )} + + + + + + + + + + ) + } ) } + +
СтоимостьПервый платеж, ₽Первый платеж, %МаркаМодельОбъектов лизинга
+
+ -1 } onChange={ () => { this._handle_onCheckOffer(offer.quote_number) } }/> + +
+
{ offer_index + 1 }{ numeral(offer.price).format(' ., ') } ₽{ numeral(offer.first_payment_rub).format(' ., ') } ₽{ offer.first_payment_perc }%{ offer.brand_name }{ offer.model_name }{ offer.object_count } +
this._handle_onOffer(offer.quote_number) }> +
+
+

+ КП + №{ offer.quote_number } +

+
+
+
+
+ ) : ( +

Нет предложений

+ ) } + + ) } +
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/SignPlannedContract.js b/components/DealsStatus/components/SignPlannedContract.js new file mode 100644 index 0000000..41e78ba --- /dev/null +++ b/components/DealsStatus/components/SignPlannedContract.js @@ -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 ( +
+
+ PDF +
+
+

{ contract.name }

+
+ { moment(contract.date).format("DD.MM.YYYY") } + { contract.brand_name } + { contract.model_name } +
+
+ { loading ? ( + + ) : ( + <> + { contract.sign_type === "PAPER" && ( +
+ +
+ ) } + { contract.sign_type === "EDO" && ( +
+ { status === 1 && ( + + ) } + { status === 1 && ( + + )} + { status === 1 && ( + + ) } + { status >= 2 && ( + + ) } +
+ ) } + + ) } +
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/StatusDecisionMaking.js b/components/DealsStatus/components/StatusDecisionMaking.js new file mode 100644 index 0000000..650c9e6 --- /dev/null +++ b/components/DealsStatus/components/StatusDecisionMaking.js @@ -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 ( +
this.status) ? "done" : "" }`}> +

№ { dealSelected }

+ +
+ { this._renderHeader("Принятие решения по сделке") } +
+
+ { this.status === statuscode_id ? ( +

Принятие решение о финансировании

+ ) : ( +

Поздравляем! Принято положительное решение по сделке.

+ ) } +
+
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/StatusDecisionRefuse.js b/components/DealsStatus/components/StatusDecisionRefuse.js new file mode 100644 index 0000000..0ea4242 --- /dev/null +++ b/components/DealsStatus/components/StatusDecisionRefuse.js @@ -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 ( +
this.status) ? "done" : "" }`}> +

№ { dealSelected }

+ +
+ { this._renderHeader("Требуется изменение параметров") } +
+
+

Продолжение оформления заблокировано

+
+
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/StatusDocumentsCheck.js b/components/DealsStatus/components/StatusDocumentsCheck.js new file mode 100644 index 0000000..c4a6598 --- /dev/null +++ b/components/DealsStatus/components/StatusDocumentsCheck.js @@ -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 ( +
this.status ? "done" : "" }`}> +

№ { dealSelected }

+ +
+ { this._renderHeader("Проверка документов") } +
+
+ { statuscode_id === this.status ? ( +

Идёт проверка предоставленных документов

+ ) : ( +

Документы проверены

+ ) } +
+
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/StatusPositiveDecision.js b/components/DealsStatus/components/StatusPositiveDecision.js new file mode 100644 index 0000000..b8b9dc5 --- /dev/null +++ b/components/DealsStatus/components/StatusPositiveDecision.js @@ -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 ( +
this.status ? "done" : "" }`}> +

№ { dealSelected }

+ +
+ { this._renderHeader("Принято положительное решение") } +
+
+ { statuscode_id === this.status ? ( +

Идёт подготовка необходимых документов для заключения сделки

+ ) : ( +

Документы подготовлены

+ ) } +
+
+
+
+ ) + } +} \ No newline at end of file diff --git a/components/DealsStatus/components/Step.js b/components/DealsStatus/components/Step.js new file mode 100644 index 0000000..74489c0 --- /dev/null +++ b/components/DealsStatus/components/Step.js @@ -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 ( +
= this.status ? { position: "relative", } : { position: "relative", cursor: "inherit" }} onClick={ statuscode_id >= this.status ? this._handle_onSwitch : () => {} }> + { this.status === statuscode_id && (
)} + +

{ title }

+ { statuscode_id >= this.status && ( +
+
+
+ ) } + { this._renderHeaderButtons !== undefined && this._renderHeaderButtons() } +
+ ) + } +} \ No newline at end of file diff --git a/components/FileDropzoneDeals/index.js b/components/FileDropzoneDeals/index.js index 9663ac9..6f38ecb 100644 --- a/components/FileDropzoneDeals/index.js +++ b/components/FileDropzoneDeals/index.js @@ -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 && (
-

- { document.check } - { document.comment } -

+ { message ? ( +

+ { document.check } + { document.comment } +

+ ) : ( +

+ Комментарий к ранее загруженным файлам +

+ ) } +
) } - { uploaded.files.length > 0 && ( -
-
- { uploaded.files.map((file, index) => - { - return ( -
- { uploaded.sent ? ( -
onDeleteFile(file.group, index) }> -
+ { statuscode_id === 102 && ( + <> + { uploaded.files.length > 0 && ( +
+
+ { uploaded.files.map((file, index) => + { + return ( +
+ { file.uploaded ? ( +
onDeleteFile(file.group, index) }> +
+
+ ) : ( +
+ +
+ ) } +
+ PDF +
+
+ { file.name } + { moment().format("DD.MM.YYYY") } +
- ) : ( -
- -
- ) } -
- PDF -
-
- { file.name } - { moment().format("DD.MM.YYYY") } -
-
- ) - } ) } -
-
- ) } - { uploaded.files.length < LIMIT_FILES && ( - onAddFile(acceptedFiles, document.comment !== null && document.comment !== "" ? true : false) } maxFiles={ LIMIT_FILES } multiple={ true } disabled={ uploading }> - { ({getRootProps, getInputProps}) => ( -
-
-
-

- Перенесите файлы на экран для быстрой загрузки или выберите файл с компьютера -

- + ) + } ) }
-
) } -
+ { uploaded.files.length < LIMIT_FILES && ( + onAddFile(acceptedFiles, document.comment !== null && document.comment !== "" ? true : false) } maxFiles={ LIMIT_FILES } multiple={ true } disabled={ uploading }> + { ({getRootProps, getInputProps}) => ( +
+
+
+

+ Перенесите файлы на экран для быстрой загрузки или выберите файл с компьютера +

+ +
+ +
+ ) } +
+ ) } + ) } ) diff --git a/css/main/style.css b/css/main/style.css index 942ec00..c9aae5e 100644 --- a/css/main/style.css +++ b/css/main/style.css @@ -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; diff --git a/css/main/style.less b/css/main/style.less index ca38416..e6de450 100644 --- a/css/main/style.less +++ b/css/main/style.less @@ -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); } } diff --git a/pages/api/deals/file/attach.js b/pages/api/deals/file/attach.js index d6a98f6..85c6723 100644 --- a/pages/api/deals/file/attach.js +++ b/pages/api/deals/file/attach.js @@ -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 ], } } diff --git a/pages/api/deals/file/remove.js b/pages/api/deals/file/remove.js index c366023..84aaa59 100644 --- a/pages/api/deals/file/remove.js +++ b/pages/api/deals/file/remove.js @@ -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); } } diff --git a/pages/api/deals/upload.js b/pages/api/deals/upload.js index bdb220b..73c6329 100644 --- a/pages/api/deals/upload.js +++ b/pages/api/deals/upload.js @@ -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({}); diff --git a/pages/components/AnnouncementsList/index.js b/pages/components/AnnouncementsList/index.js index 78a6049..f992892 100644 --- a/pages/components/AnnouncementsList/index.js +++ b/pages/components/AnnouncementsList/index.js @@ -102,7 +102,7 @@ class AnnouncementsList extends React.Component

Наш оператор Диадок. Идентификатор участника ЭДО (GUID):
2BM-9724016636-772401001-202007300714591533849

diff --git a/public/assets/images/icons/toggle-cell_black.svg b/public/assets/images/icons/toggle-cell_black.svg new file mode 100644 index 0000000..86f933f --- /dev/null +++ b/public/assets/images/icons/toggle-cell_black.svg @@ -0,0 +1,3 @@ + + +