2022-08-18 17:56:41 +03:00

670 lines
17 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 { SpinnerCircular } from "spinners-react";
import moment from "moment";
import pluralize from 'pluralize-ru';
import numeral from "numeral";
import DateInput from "../../../../components/DatePicker";
import { getContractGraphicChangeOptions, getContractGraphicChangeCalculate } from "../../../../../actions";
class PaymentDate extends React.Component
{
constructor(props)
{
super(props);
this.state = {
value: null,
min: null,
max: null,
}
}
componentDidMount()
{
const { option, onOption } = this.props;
this.setState({
value: moment(option.value).toDate(),
min: moment(option.from).toDate(),
max: moment(option.to).toDate(),
}, () =>
{
onOption(this.state.value);
});
}
_handle_onChange = (value) =>
{
const { onOption } = this.props;
this.setState({ value }, () =>
{
onOption(value);
});
}
render()
{
const { value, min, max } = this.state;
return (
<div className="form_field">
<label>Дата платежа</label>
<DateInput
placeholder=""
value={ value }
min={ min }
max={ max }
id={"date_to"}
onChange={ this._handle_onChange }
/>
</div>
)
}
}
class FixLastPayment extends React.Component
{
constructor(props)
{
super(props);
this.state = {
value: false,
};
}
componentDidMount()
{
const { option, onOption } = this.props;
this.setState({
value: option.value,
}, () =>
{
onOption(this.state.value);
});
}
_handle_onChange = () =>
{
const { onOption } = this.props;
this.setState({ value: this.state.value ? false : true }, () =>
{
onOption(this.state.value);
});
}
render()
{
const { value } = this.state;
return (
<div className="form_field">
<input type="checkbox" hidden id="fix_pay" name="fix_pay" checked={ value } onChange={ this._handle_onChange }/>
<label htmlFor="fix_pay">
Фиксировать последний платеж
</label>
<div className="help_tooltip">
<div className="help_icon">
<svg width={ 24 } height={ 24 } fill="none" xmlns="http://www.w3.org/2000/svg" >
<path d="M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z" stroke="#8E94A7" strokeWidth={ 2 } strokeLinecap="round" strokeLinejoin="round" />
<path d="M11.25 11.25H12v5.25h.75" stroke="#8E94A7" strokeWidth={ 2 } strokeLinecap="round" strokeLinejoin="round" />
<path d="M12 9a1.125 1.125 0 1 0 0-2.25A1.125 1.125 0 0 0 12 9Z" fill="#8E94A7" />
</svg>
</div>
<div className="help_content ">
{" "}
{/* opened */}
<div>
<p>Какой-то описательный текст</p>
<p className="button">Закрыть</p>
</div>
</div>
</div>
</div>
)
}
}
class DateOffestType extends React.Component
{
constructor(props)
{
super(props);
this.state = {
value: null,
}
}
componentDidMount()
{
const { option, onOption } = this.props;
this.setState({
value: parseInt(option.value, 10),
}, () =>
{
onOption(this.state.value);
});
}
_handle_onChange = (value) =>
{
const { onOption } = this.props;
this.setState({ value: parseInt(value, 10) }, () =>
{
onOption(this.state.value);
});
}
render()
{
const { value } = this.state;
return (
<div className="form_field">
<label>Тип каникул</label>
<div className="form_field">
<input type="radio" hidden id="weeekend_type_1" name="weeekend_type" checked={ value === 100000001 ? true : false } onChange={ () => this._handle_onChange(100000001) }/>
<label htmlFor="weeekend_type_1">С увеличением срока</label>
</div>
<div className="form_field">
<input type="radio" hidden id="weeekend_type_2" name="weeekend_type" checked={ value === 100000000 ? true : false } onChange={ () => this._handle_onChange(100000000) }/>
<label htmlFor="weeekend_type_2">Без изменения срока</label>
</div>
</div>
)
}
}
class PeriodSelector extends React.Component
{
constructor(props)
{
super(props);
this.state = {
value: null,
periods: [],
}
}
componentDidMount()
{
const { option, onOption } = this.props;
const periods = [];
if(option.min !== undefined && option.min !== null)
{
for(let i = parseInt(option.min, 10); i <= parseInt(option.max, 10); i++)
{
periods.push(i);
}
this.setState({
value: periods[0], periods
}, () =>
{
onOption(this.state.value);
});
}
}
_handle_onChange = (event) =>
{
const { onOption } = this.props;
this.setState({ value: parseInt(event.target.value, 10) }, () =>
{
onOption(this.state.value);
});
}
render()
{
const { value, periods } = this.state;
if(value !== null)
{
return (
<div className="form_field">
<label>Увеличить график на</label>
<select value={ value } onChange={ this._handle_onChange }>
{ periods.map((period, index) => (
<option key={ index } value={ period }>{ index + 1 } { pluralize( index + 1, 'месяца', 'месяц', 'месяца', 'месяцев') } ({ period } { pluralize( period, 'платежа', 'платеж', 'платежа', 'платежей') })</option>
)) }
</select>
</div>
)
}
return null;
}
}
class SumSelector extends React.Component
{
constructor(props)
{
super(props);
this.state = {
value: "",
min: null,
max: null,
}
}
componentDidMount()
{
const { option, onOption } = this.props;
this.setState({
value: option.min,
min: option.min,
max: option.max,
}, () =>
{
onOption(this.state.value, false);
});
}
_handle_onChange = (event) =>
{
const { onOption } = this.props;
const { min, max } = this.state;
const value = parseFloat(event.target.value.replace('/[^\d]/m', ''));
if(value >= min && value <= max && !isNaN(value))
{
this.setState({ value: value }, () =>
{
onOption(this.state.value, false);
});
}
else
{
onOption(this.state.value, true);
}
}
render()
{
const { value, min, max } = this.state;
return (
<div className="form_field">
<label>Увеличить платеж на (ЧДП)</label>
<div className="input_with_notes">
<input type="number" placeholder="Укажите сумму" defaultValue={ value } onChange={ this._handle_onChange }/>
<span>от { numeral(min).format(' ., ') }&nbsp;</span>
<span>до { numeral(max).format(' ., ') }&nbsp;</span>
</div>
<div className="help_tooltip">
<div className="help_icon">
<svg width={ 24 } height={ 24 } fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z" stroke="#8E94A7" strokeWidth={ 2 } strokeLinecap="round" strokeLinejoin="round" />
<path d="M11.25 11.25H12v5.25h.75" stroke="#8E94A7" strokeWidth={ 2 } strokeLinecap="round" strokeLinejoin="round" />
<path d="M12 9a1.125 1.125 0 1 0 0-2.25A1.125 1.125 0 0 0 12 9Z" fill="#8E94A7" />
</svg>
</div>
<div className="help_content ">
{" "}
{/* opened */}
<div>
<p>Какой-то описательный текст</p>
<p className="button">Закрыть</p>
</div>
</div>
</div>
</div>
)
}
}
class InsurancePriceSelector extends React.Component
{
constructor(props)
{
super(props);
this.state = {
value: "",
min: null,
max: null,
}
}
componentDidMount()
{
const { option, onOption } = this.props;
this.setState({
value: option.min,
min: option.min,
max: option.max,
}, () =>
{
onOption(this.state.value, false);
});
}
_handle_onChange = (event) =>
{
const { onOption } = this.props;
const { min, max } = this.state;
const value = parseFloat(event.target.value.replace('/[^\d]/m', ''));
if(value >= min && value <= max && !isNaN(value))
{
this.setState({ value: value }, () =>
{
onOption(this.state.value, false);
});
}
else
{
onOption(this.state.value, true);
}
}
render()
{
const { value, min, max } = this.state;
return (
<div className="form_field">
<label>Сумма пролонгации</label>
<div className="input_with_notes">
<input type="number" placeholder="Укажите сумму" defaultValue={ value } onChange={ this._handle_onChange }/>
<span>от { numeral(min).format(' ., ') }&nbsp;</span>
<span>до { numeral(max).format(' ., ') }&nbsp;</span>
</div>
<div className="help_tooltip">
<div className="help_icon">
<svg width={ 24 } height={ 24 } fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18Z" stroke="#8E94A7" strokeWidth={ 2 } strokeLinecap="round" strokeLinejoin="round" />
<path d="M11.25 11.25H12v5.25h.75" stroke="#8E94A7" strokeWidth={ 2 } strokeLinecap="round" strokeLinejoin="round" />
<path d="M12 9a1.125 1.125 0 1 0 0-2.25A1.125 1.125 0 0 0 12 9Z" fill="#8E94A7" />
</svg>
</div>
<div className="help_content ">
{" "}
{/* opened */}
<div>
<p>Какой-то описательный текст</p>
<p className="button">Закрыть</p>
</div>
</div>
</div>
</div>
)
}
}
class InsuranceDateFromSelector extends React.Component
{
constructor(props)
{
super(props);
this.state = {
value: null,
min: null,
max: null,
}
}
componentDidMount()
{
const { option, onOption } = this.props;
this.setState({
value: moment(option.value !== null ? option.value : option.from).toDate(),
min: moment(option.from).toDate(),
max: moment(option.to).toDate(),
}, () =>
{
onOption(this.state.value);
});
}
_handle_onChange = (value) =>
{
const { onOption } = this.props;
this.setState({ value }, () =>
{
onOption(value);
});
}
render()
{
const { value, min, max } = this.state;
return (
<div className="form_field">
<label>Дата начала пролонгации</label>
<DateInput
placeholder=""
value={ value }
min={ min }
max={ max }
id={"date_to"}
onChange={ this._handle_onChange }
/>
</div>
)
}
}
export default class Options extends React.Component
{
constructor(props)
{
super(props);
this.state = {
loading: true,
sending: false,
date: null,
car: null,
contract_date: null,
agreement: null,
rules: null,
number_paydate: null,
period_new: null,
fix_last_payment_available: false,
date_offset_type: null,
sum: null,
insurance_price_result: null,
datefrom: null,
errors: {},
};
}
componentDidMount()
{
const { dispatch, number, variants } = this.props;
const varianst_for_options = {};
for(let i in variants.types)
{
if(variants.types[i].value)
{
varianst_for_options[variants.types[i].name] = true;
}
}
getContractGraphicChangeOptions({ dispatch, number, variants: varianst_for_options })
.then(() =>
{
this.setState({ loading: false });
})
.catch(() =>
{
});
}
_handle_onBack = (event) =>
{
event.preventDefault();
this.props.onVariants();
}
_handle_onCalculate = (event) =>
{
const { sending, number_paydate, period_new, fix_last_payment_available, date_offset_type, sum, insurance_price_result, datefrom, } = this.state;
const { number, options, variants, onCalculate } = this.props;
event.preventDefault();
console.log(this.props);
const selected = {
number_planpayment: options.number_planpayment.value,
};
if(number_paydate !== null) { selected.number_paydate = moment(number_paydate).format(); }
if(period_new !== null) { selected.period_new = period_new; }
if(fix_last_payment_available !== null) { selected.fix_last_payment_available = fix_last_payment_available; }
if(date_offset_type !== null) { selected.date_offset_type = date_offset_type; }
if(sum !== null) { selected.sum = sum; }
if(insurance_price_result !== null) { selected.insurance_price_result = insurance_price_result; }
//if(early_redemption_change !== null) { selected.early_redemption_change = early_redemption_change; }
if(datefrom !== null) { selected.datefrom = moment(datefrom).format(); }
if(!sending)
{
const v = {};
for(let i in variants.types) { v[ variants.types[i].name ] = variants.types[i].value; }
const payload = {
...{ contract_number: number },
...v,
...selected
};
console.log(payload);
this.setState({ sending: true, }, () =>
{
getContractGraphicChangeCalculate(payload)
.then((calculation) =>
{
onCalculate(calculation.addcontract_number);
})
.catch(() =>
{
this.setState({ sending: false, }, () =>
{
alert("К сожаление при расчете возникла ошибка.");
});
});
});
}
}
_handle_onPaymentDateChange = (date) =>
{
this.setState({ number_paydate: date });
}
_handle_onFixLastPaymentChange = (value) =>
{
this.setState({ fix_last_payment_available: value });
}
_handle_onDateOffsetTypeChange = (value) =>
{
this.setState({ date_offset_type: value });
}
_handle_onPeriodChange = (value) =>
{
this.setState({ period_new: value });
}
_handle_onSumChange = (value, error) =>
{
const { errors } = this.state;
if(error) { errors['sum'] = true; } else { delete errors['sum']; }
this.setState({ sum: value, errors });
}
_handle_onInsurancePriceChange = (value, error) =>
{
const { errors } = this.state;
if(error) { errors['insurance_price_result'] = true; } else { delete errors['insurance_price_result']; }
this.setState({ insurance_price_result: value, errors });
}
_handle_onInsuranceDateFromChange = (date) =>
{
this.setState({ datefrom: date });
}
_checkAllowCalculate = () =>
{
const { errors } = this.state;
for(let i in errors)
{
if(errors[i])
{
return false;
}
}
return true;
}
render()
{
const { loading, sending, } = this.state;
const { variants, options } = this.props;
return (
<div className="block">
<p className="title">Параметры опций изменений графика платежей</p>
{ loading ? (
<div style={{ position: "absolute", left: "50%", top: "50%" }}>
<SpinnerCircular size={ 90 } thickness={ 51 } speed={ 100 } color="rgba(28, 1, 169, 1)" secondaryColor="rgba(236, 239, 244, 1)" style={{ marginTop: "-45px", marginLeft: "-45px", }}/>
</div>
) : (
<form className="calc">
{ options !== undefined && options !== null && options.number_paydate !== undefined && options.number_paydate !== null && options.number_paydate.visible && (
<PaymentDate option={ options.number_paydate } onOption={ this._handle_onPaymentDateChange } />
) }
{ options !== undefined && options !== null && options.fix_last_payment_available !== undefined && options.fix_last_payment_available !== null && options.fix_last_payment_available.visible && (
<FixLastPayment option={ options.fix_last_payment_available } onOption={ this._handle_onFixLastPaymentChange } />
) }
{ options !== undefined && options !== null && options.date_offset_type !== undefined && options.date_offset_type !== null && options.date_offset_type.visible && (
<DateOffestType option={ options.date_offset_type } onOption={ this._handle_onDateOffsetTypeChange } />
) }
{ options !== undefined && options !== null && options.period_new !== undefined && options.period_new !== null && options.period_new.visible && (
<PeriodSelector option={ options.period_new } onOption={ this._handle_onPeriodChange } />
) }
{ options !== undefined && options !== null && options.sum !== undefined && options.sum !== null && options.sum.visible && (
<SumSelector option={ options.sum } onOption={ this._handle_onSumChange } />
) }
{ options !== undefined && options !== null && options.insurance_price_result !== undefined && options.insurance_price_result !== null && options.insurance_price_result.visible && (
<InsurancePriceSelector option={ options.insurance_price_result } onOption={ this._handle_onInsurancePriceChange } />
) }
{ options !== undefined && options !== null && options.datefrom !== undefined && options.datefrom !== null && options.datefrom.visible && (
<InsuranceDateFromSelector option={ options.datefrom } onOption={ this._handle_onInsuranceDateFromChange } />
) }
<div className="btn_group">
<button className="button button-gray" onClick={ this._handle_onBack }>Назад</button>
<button className="button button-blue" onClick={ this._handle_onCalculate } disabled={ this._checkAllowCalculate() ? false : true } style={{ minWidth: 350 }}>
{ sending ? (
<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>
</form>
) }
</div>
);
}
}