367 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

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

import React from "react";
import Head from 'next/head';
import Image from 'next/image';
import { connect } from "react-redux";
import { withRouter } from 'next/router';
import numeral from "numeral";
import moment from "moment";
import { SpinnerCircular } from 'spinners-react';
import { reduxWrapper } from '../../store';
import Header from '../components/Header';
import Footer from '../components/Footer';
import Company from "../components/Company";
import InnerMenu from "./components/InnerMenu";
import { getContract, getContractDebtInvoiceFile, getContractInfo, getContractPenaltyInvoiceFile } from './../../actions';
class ContractSchedulePage extends React.Component
{
constructor(props)
{
super(props);
this.state = {
loading: false,
payments: null,
avans: null,
debt: null,
penalty: null,
date: null,
car: null,
full: false,
opened: [],
debt_invoice_file_loading: false,
penalty_invoice_file_loading: false,
}
}
static getDerivedStateFromProps(nextProps, prevState)
{
return {
date: nextProps.date,
car: nextProps.car,
payments: nextProps.payments,
avans: nextProps.avans,
debt: nextProps.debt,
penalty: nextProps.penalty,
};
}
componentDidMount()
{
if(!this.state.loading && this.props.number !== undefined)
{
this.setState({ loading: true }, () =>
{
getContractInfo({ dispatch: this.props.dispatch, number: this.props.number });
getContract({ dispatch: this.props.dispatch, number: this.props.number }).then(() => {
this.setState({ loading: false });
}).catch(() => {});
});
}
}
_getLastPayDate = () =>
{
let last = null;
const { payments } = this.state;
for(let i in payments)
{
if(payments[i].status === "Paid")
{
last = moment(payments[i].date, "DD-MM-YYYY");
}
}
return last;
}
_handle_onSetFull = () =>
{
this.setState({ full: true });
}
_handle_onSetOpen = (number) =>
{
const opened = [ ...this.state.opened ];
if(opened.indexOf(number) < 0)
{ opened.push(number); }
else
{ opened.splice(opened.indexOf(number), 1); }
this.setState({ opened: opened });
}
_handle_onDownloadDebtFile = () =>
{
const { number } = this.props;
if(!this.state.debt_invoice_file_loading)
{
this.setState({ debt_invoice_file_loading: true }, () =>
{
getContractDebtInvoiceFile({ contract: number })
.then(() =>
{
this.setState({ debt_invoice_file_loading: false });
})
.catch(() =>
{
this.setState({ debt_invoice_file_loading: false });
});
});
}
}
_handle_onDownloadPenaltyFile = () =>
{
const { number } = this.props;
if(!this.state.penalty_invoice_file_loading)
{
this.setState({ penalty_invoice_file_loading: true }, () =>
{
/*
getContractPenaltyInvoiceFile({ contract: number })
.then(() =>
{
this.setState({ penalty_invoice_file_loading: false });
})
.catch(() =>
{
this.setState({ penalty_invoice_file_loading: false });
});
*/
});
}
}
_handle_onCalculatePenalty = () =>
{
const { number } = this.props;
this.props.router.push(`/contract/${ number }/documents`);
}
render()
{
const { payments, avans, debt, penalty, date, car, full, opened, loading, debt_invoice_file_loading, penalty_invoice_file_loading } = this.state;
const { number } = this.props;
console.log(".".repeat(50));
console.log("this.state", this.state);
console.log("this.props", this.props);
console.log(".".repeat(50));
console.log("RENDER", "payments");
console.log(payments);
console.log("avans", avans);
const statuses = {
"NotPaid": "",
"HalfPaid": "overpayment-1",
"OverPaid": "overpayment-2",
"Paid": "paid",
};
let today = moment();
let last_pay_date = this._getLastPayDate();
return (
<React.Fragment>
<Head>
<title>ЛК Эволюция автолизинга</title>
<meta
name="description"
content="ЛК Эволюция автолизинга"
/>
</Head>
<Header { ...this.props }/>
<main>
<section>
<div className="clear"></div>
<div className="container">
<div className="title_wrapper">
<div className="left" style={{ flexDirection: 'column', }}>
<h1 className="section_title">Договор { number }</h1>
<p className="section_subtitle">{ date !== undefined && date !== null && date !== null && (<> от { moment(date).format("DD.MM.YYYY") }</>)}{ car !== undefined && car !== null ? ` - ${ car.brand.name } ${ car.model.name } | ${ car.reg_number !== null ? car.reg_number : 'без рег. номера' } | ${ car.vin_number !== null ? car.vin_number : 'без VIN номера' }` : '' }</p>
</div>
<Company { ...this.props }/>
</div>
<div className="aside_container about">
<InnerMenu number={ number } { ...this.props }/>
<article>
{ parseInt(avans, 10) > 0 && (
<div className="payments_actions">
<div className="avans">
<p>Сумма авансовых поступлений по договору: <span style={{ whiteSpace: "nowrap" }}>{ numeral(avans).format(' ., ') }&nbsp;</span></p>
</div>
</div>
) }
{/* Вариант 1 */}
<div className="payments_actions">
{ parseInt(debt, 10) > 0 && (
<div>
<p>Счёт на основной долг: { numeral(debt).format(' ., ') }&nbsp;</p>
<button className="button button-blue" onClick={ this._handle_onDownloadDebtFile } style={{ minWidth: 113 }}>
{ debt_invoice_file_loading ? (
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" style={{ marginTop: "0px" }}/>
) :
("Скачать счет")
}
</button>
</div>
) }
{ parseInt(penalty, 10) > 0 && (
<div>
<p><span>Пени:</span> { numeral(penalty).format(' ., ') }&nbsp;</p>
<button className="button button-blue" onClick={ this._handle_onDownloadPenaltyFile } style={{ minWidth: 113 }}>
{ penalty_invoice_file_loading ? (
<SpinnerCircular size={24} thickness={100} speed={100} color="rgba(255, 255, 255, 1)" secondaryColor="rgba(255, 255, 255, 0.5)" style={{ marginTop: "0px" }}/>
) :
("Скачать счет")
}
</button>
<button className="button button-blue" onClick={ this._handle_onCalculatePenalty }>Рассчитать пени</button>
</div>
) }
</div>
<div className="contract_table schedule">
<div className="table_row table_header">
<div className="table_cell"> платежа</div>
<div className="table_cell">Дата лизингового платежа</div>
<div className="table_cell">Лизинговый платеж с НДС </div>
<div className="table_cell">НДС, 20% </div>
<div className="table_cell">Статус платежа</div>
<div className="table_cell">Платежное поручение</div>
</div>
{ loading ? (
<div className="table_row table_header" style={{ minHeight: 300, 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>
) : (
<>
{ !full && (
<button className="show_more primary" onClick={ this._handle_onSetFull }>Показать прошедшие платежи</button>
) }
{ payments !== undefined && payments !== null && Object.values(payments).map((payment, index) =>
{
let pd = moment(payment.date, "DD-MM-YYYY");
if(!full && pd < last_pay_date) { return null; }
return (
<div className={ `table_row ${ opened.indexOf(payment.number) > -1 ? "opened" : "" }` } data-status={ payment.status === "NotPaid" && pd < today ? "notpaid" : statuses[payment.status] } key={ index } onClick={ () => this._handle_onSetOpen(payment.number) }>
<div className="table_cell" data-title="Платеж №">{ payment.number }</div>
<div className="table_cell" data-title="от">{ moment(payment.date, "DD-MM-YYYY").format("DD.MM.YYYY") }</div>
<div className="table_cell" data-title="На сумму" style={{ whiteSpace: "nowrap" }}>{ numeral(payment.total_amount).format(' ., ') }&nbsp;</div>
<div className="table_cell" data-title="НДС, 20%" style={{ whiteSpace: "nowrap" }}>{ numeral(payment.vat_amount).format(' ., ') }&nbsp;</div>
<div className="table_cell">
{ payment.status === "Paid" && "Оплачено" }
{ payment.status === "NotPaid" && "Не оплачено" }
{ payment.status === "HalfPaid" && (
<><span>Недоплата</span><br/><span style={{ whiteSpace: "nowrap" }}>{ numeral(payment.total_amount - payment.paid_amount).format(' ., ') }&nbsp;</span></>
) }
{ payment.status === "OverPaid" && (
<><span>Переплата</span> <span style={{ whiteSpace: "nowrap" }}>{ numeral(payment.total_amount).format(' ., ') }&nbsp;</span></>
) }
</div>
<div className="table_cell">
{ payment.invoices !== undefined && payment.invoices.map((invoice, invoice_index) =>
(
<React.Fragment key={invoice_index}>
<p style={{ paddingBottom: "15px", lineHeight: "18px" }}>{ invoice.number } от { moment(invoice.date, "DD-MM-YYYY").format("DD.MM.YYYY") } на сумму <span style={{ whiteSpace: "nowrap" }}>{ numeral(invoice.total_amount).format(' ., ') }&nbsp;</span></p>
</React.Fragment>
)) }
</div>
<button className="toggle_cell" ></button>
</div>
)
}) }
{/*}
<div className="table_row" data-status="overpayment-2">
<div className="table_cell" data-title="Платеж №">11</div>
<div className="table_cell" data-title="от">21.02.2021</div>
<div className="table_cell" data-title="На сумму">239 724,05</div>
<div className="table_cell" data-title="НДС, 20% ₽">43 079,18</div>
<div className="table_cell"><span>Переплата</span> <span>15 000,00 ₽</span></div>
<div className="table_cell">№18432 от 20/01/2021 на сумму 255 000,00 ₽</div>
<button className="toggle_cell"></button>
</div>
<div className="table_row opened" data-status="overpayment-1">
<div className="table_cell" data-title="Платеж №">12</div>
<div className="table_cell" data-title="от">21.02.2021</div>
<div className="table_cell" data-title="На сумму">239 724,05</div>
<div className="table_cell" data-title="НДС, 20% ₽">43 079,18</div>
<div className="table_cell">Переплата 10 000,00 ₽</div>
<div className="table_cell">№34223 от 21/02/2021 на сумму 229 724,05 ₽</div>
<button className="toggle_cell"></button>
</div>
<div className="table_row" data-status="paid">
<div className="table_cell" data-title="Платеж №">13</div>
<div className="table_cell" data-title="от">21.02.2021</div>
<div className="table_cell" data-title="На сумму">239 724,05</div>
<div className="table_cell" data-title="НДС, 20% ₽">43 079,18</div>
<div className="table_cell">Оплачено </div>
<div className="table_cell">№44911 от 10/03/2021 на сумму 100 000,00 ₽
№49877 от 21/03/2021 на сумму 139 724,05 ₽</div>
<button className="toggle_cell"></button>
</div>
<div className="table_row">
<div className="table_cell" data-title="Платеж №">14</div>
<div className="table_cell" data-title="от">21.02.2021</div>
<div className="table_cell" data-title="На сумму">239 724,05</div>
<div className="table_cell" data-title="НДС, 20% ₽">43 079,18</div>
<div className="table_cell">Не оплачено </div>
<div className="table_cell">-</div>
<button className="toggle_cell"></button>
</div>
{*/}
</>
) }
</div>
</article>
</div>
</div>
</section>
</main>
<Footer authenticated={ true }/>
</React.Fragment>
);
}
}
function mapStateToProps(state, ownProps)
{
return {
company: state.company,
payments: state.contract.payments,
avans: state.contract.avans,
debt: state.contract.debt,
penalty: state.contract.penalty,
date: state.contract.date,
car: state.contract.car,
//schedule: state.payments,
}
}
export const getServerSideProps = reduxWrapper.getServerSideProps(
(store) =>
async ({ req, res, query }) =>
{
return {
props: {
number: query.number,
}
}
}
);
export default withRouter(connect(mapStateToProps)(ContractSchedulePage));