Commit a1127cde authored by Juorder Antonio's avatar Juorder Antonio

se modifica la vista de ventas, para solo hacer solicitudes de compras de...

se modifica la vista de ventas, para solo hacer solicitudes de compras de casillas al area de ventas
parent f38a5fb5
import React from 'react'; import React from 'react';
import PageInfo from '../page_info.jsx'; import PageInfo from '../page_info.jsx';
import Panel from '../panel.jsx'; import Panel from '../panel.jsx';
import moment from 'moment';
import currencyFormatter from 'currency-formatter';
import EventStore from '../../stores/event_store.jsx';
import UserStore from '../../stores/user_store.jsx'; import UserStore from '../../stores/user_store.jsx';
import * as GlobalActions from '../../action_creators/global_actions.jsx';
import * as Utils from '../../utils/utils.jsx'; import * as Utils from '../../utils/utils.jsx';
import * as Client from '../../utils/client.jsx'; import * as Client from '../../utils/client.jsx';
import sweetAlert from 'sweetalert';
import ZimbraStore from '../../stores/zimbra_store.jsx';
export default class SalesForm extends React.Component { export default class SalesForm extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.handleSetNumbersOfMailboxes = this.handleSetNumbersOfMailboxes.bind(this); this.buildPurchase = this.buildPurchase.bind(this);
this.getPrices = this.getPrices.bind(this);
this.onlyNumber = this.onlyNumber.bind(this);
this.confirmShipping = this.confirmShipping.bind(this); this.confirmShipping = this.confirmShipping.bind(this);
this.getDomainInfo = this.getDomainInfo.bind(this);
this.tryAgain = this.tryAgain.bind(this);
this.cos = Utils.getEnabledPlansByCos(ZimbraStore.getAllCos());
this.plans = window.manager_config.plans;
this.keys = Object.keys(this.cos);
this.sales = {};
this.isNAN = false;
this.currency = window.manager_config.invoiceAPI.currency;
const precision = this.currency === 'CLP' ? 0 : 2;
this.currencyParams = {code: this.currency, symbol: '', precision};
this.state = { const {name, attrs} = UserStore.getCurrentUser();
loading: true, const {displayName, cn, sn} = attrs._attrs;
errorAjax: false,
disabled: false const state = {
}; disabled: true,
} purchase: {},
user: {
confirmShipping(e) { email: name,
e.preventDefault(); fullname: this.buildFullName(displayName, cn, sn)
const plans = []; },
const {domain} = this.state; domainId: props.params.domainId
const domainId = domain.id;
const companyId = domain.attrs.businessCategory;
const adminEmail = UserStore.getCurrentUser().name;
const items = {};
const data = {
domainId,
companyId,
adminEmail,
upgrade: false,
currency: this.currency
}; };
this.keys.forEach((plan) => { this.avoidPlans = ['archiving', 'default'];
if (this.sales[plan] && this.sales[plan].quantity && this.sales[plan].quantity > 0) { this.plans = window.manager_config.plans;
items[plan] = this.sales[plan]; this.messageCode = window.manager_config.messageCode;
items[plan].type = 'Producto';
plans.push(`${Utils.titleCase(plan)} : <strong>${this.sales[plan].quantity}</strong>`);
}
});
if (plans.length < 1) {
return EventStore.emitToast({
type: 'error',
title: 'Compra Casillas',
body: 'Debe indicar cuantas casillas desea comprar.',
options: {
timeOut: 4000,
extendedTimeOut: 2000,
closeButton: true
}
});
}
const content = plans.join(', '); this.mailboxes = Object.keys(this.plans).filter((plan) => {
const total = `${this.refs.total.value} ${this.currency}`; const isValidPlan = !this.avoidPlans.includes(plan);
const options = {
title: 'Confirmación',
text: `Esta seguro de realizar la compra de ${content} por un total de <strong>${total}</strong>`,
html: true,
confirmButtonText: 'Si, compraré',
confirmButtonColor: '#4EA5EC',
showLoaderOnConfirm: true,
closeOnConfirm: false
};
Utils.alertToBuy((isConfirmed) => { if (isValidPlan) {
if (isConfirmed) { state.purchase[plan] = 0;
data.items = items;
const requestObject = JSON.stringify(data);
Client.makeSale(requestObject, () => {
Utils.alertToBuy((isConfirmed) => {
if (isConfirmed) {
Utils.handleLink(null, `/domains/${domainId}/mailboxes/new`);
}
}, {
title: 'Compra de Casillas',
text: 'Su compra se ha realizado con éxito.',
showCancelButton: false,
confirmButtonColor: '#4EA5EC',
confirmButtonText: 'Muy bien',
type: 'success'
});
}, (error) => {
Utils.alertToBuy(() => {
return null;
}, {
title: 'Error',
text: error.message || error.error.message || 'Ha ocurrido un error desconocido.',
showCancelButton: false,
confirmButtonColor: '#4EA5EC',
confirmButtonText: 'Entiendo',
type: 'error',
closeOnConfirm: true
});
});
} }
}, options);
}
getPrices() { return isValidPlan;
const {domainId} = this.props.params || this.state.domain.name || null;
const attrs = this.state.domain.attrs;
const {zimbraCreateTimestamp} = attrs;
const {businessCategory} = attrs;
const createdDate = moment(zimbraCreateTimestamp, ['YYYYDDMM', 'YYYY-DD-MM', 'DD-MM-YYYY', 'YYYY-MM-DD']);
if (!createdDate.isValid()) {
this.setState({
disabled: true,
loading: false,
errorAjax: true
});
return EventStore.emitToast({
type: 'error',
title: 'Compras - Precios',
body: 'Ha ocurrido un error al obtener su fecha de creación de dominio.',
options: {
timeOut: 4000,
extendedTimeOut: 2000,
closeButton: true
}
});
}
const data = {
domainId,
domainCreatedDate: createdDate.format('MM/DD/Y'),
anualRenovation: true,
companyId: businessCategory,
type: 'standar',
currency: this.currency
};
Client.getPrices(data, (success) => {
this.setState({
loading: false,
disabled: false,
prices: success.result.prices,
isAnual: success.result.isAnual,
description: success.result.isAnual ? success.result.description : null
});
}, (error) => {
this.setState({
errorAjax: true,
loading: false
});
return EventStore.emitToast({
type: 'error',
title: 'Compras - Precios',
body: error.message || error.error.message || 'Ha ocurrido un error al intentar obtener los precios, vuelva a intentarlo por favor.',
options: {
timeOut: 4000,
extendedTimeOut: 2000,
closeButton: true
}
});
}); });
this.state = state;
} }
tryAgain(e) { onKeyupInput(event, label) {
e.preventDefault(); const value = event.target.value;
this.setState({ this.checkAmount(label, value);
loading: true,
errorAjax: false
});
this.getPrices();
} }
getDomainInfo() { buildFullName(displayName, cn, sn) {
const {domainId} = this.props.params; const fullname = displayName && displayName.trim() !== '' ? displayName : `${cn} ${sn}`;
Client.getDomain(domainId, (res, err) => { return fullname;
if (err) { }
return Utils.alertToBuy(() => {
return null;
}, {
title: 'Error',
text: err.message || err.error.message || 'Ha ocurrido un error desconocido, cuando se recuperaba la información del dominio.',
showCancelButton: false,
confirmButtonColor: '#4EA5EC',
confirmButtonText: 'Entiendo',
type: 'error',
closeOnConfirm: true
});
}
this.setState({ checkAmount(label, _value) {
domain: res const value = _value || 0;
}); const state = this.state;
const purchase = state.purchase;
const isEnabled = this.mailboxes.some((plan) => {
const planAmount = plan === label ? value : purchase[plan];
return planAmount > 0;
});
return this.getPrices(); this.setState({
disabled: !isEnabled,
purchase: {...purchase, [label]: parseInt(value, 10)}
}); });
} }
componentDidMount() { onKeydownInput(event) {
GlobalActions.emitEndLoading(); const keycode = event.keyCode || event.which;
this.getDomainInfo(); const allows = [8, 9, 37, 39, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105];
}
handleSetNumbersOfMailboxes(e, id) { if (allows.includes(keycode)) {
if (this.isNAN) { return true;
e.preventDefault();
return null;
} }
const amount = e.target.value.trim(); event.preventDefault();
let totalPrice = 0; return null;
let description = 'Nuevas Casillas '; }
this.keys.forEach((plan) => {
if (this.cos[plan] === id) {
const price = this.state.prices[plan];
const size = amount.length > 0 ? parseInt(amount, 10) : 0;
const total = size ? size * price : size;
const totalFormatted = total ? currencyFormatter.format(total, this.currencyParams) : total;
this.refs[`${plan}-total`].value = totalFormatted;
description += Utils.titleCase(plan);
this.sales[plan] = { buildPurchase(purchase) {
quantity: size, const plans = this.plans;
description, const content = [];
price, this.mailboxes.reduce((last, current) => {
id, const quantity = purchase[current];
total if (quantity > 0) {
}; const plan = plans[current];
const label = quantity > 1 ? 'casillas' : 'casilla';
last.push(`${quantity} ${label} ${plan.label}`);
} }
if (this.sales[plan] && this.sales[plan].total && this.sales[plan].total > 0) { return last;
totalPrice += this.sales[plan].total; }, content);
} return content;
});
const currentTotal = totalPrice ? currencyFormatter.format(totalPrice, this.currencyParams) : totalPrice;
this.refs.total.value = currentTotal;
} }
onlyNumber(e) { transformToHTML(content) {
const key = e.keyCode; const list = content.join('</strong>, <strong>');
const forbidden = [48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 8, 9, 37, 39]; return `<p><strong>${list}</strong></p>`;
this.isNAN = false;
if (!(forbidden.indexOf(key) > -1)) {
this.isNAN = true;
e.preventDefault();
return null;
}
} }
render() { confirmShipping(e) {
const plans = this.cos; e.preventDefault();
const configPlans = this.plans; const {purchase, user, domainId} = this.state;
const keysPlans = this.keys; const content = this.transformToHTML(this.buildPurchase(purchase));
let form = null; let data = {
let actions; purchase,
const buttons = []; user: user.email,
const {description, disabled} = this.state; fullname: user.fullname
let descriptionText; };
const options = {
if (description) { title: 'Confirmación',
descriptionText = ( text: `Esta seguro de realizar la compra de ${content}`,
<div html: true,
key='desc-key' confirmButtonText: 'Si, compraré',
className='alert alert-info margin-bottom' confirmButtonColor: '#4EA5EC',
> showLoaderOnConfirm: true,
<span closeOnConfirm: false
className='glyphicon glyphicon glyphicon-question-sign' };
aria-hidden='true'
></span>
<span className='sr-only'>Info:</span>
{description}
</div>
);
}
if (this.state.errorAjax) {
form = (
<div
className='text-center'
key={'errorajax-loading'}
>
<i
className='fa fa-refresh fa-4x fa-fw pointer'
onClick={this.tryAgain}
>
</i>
<p>{'Intentarlo de nuevo'}</p>
</div>
);
}
if (this.state.isAnual) { Utils.alertToBuy((isConfirmed) => {
buttons.push( if (isConfirmed) {
{ Client.getDomain(domainId, (domain, err) => {
label: 'Anual', if (err) {
props: { return sweetAlert('Error', 'El Dominio no existe.', 'error');
className: 'btn btn-success btn-xs'
}
}
);
} else {
buttons.push(
{
label: 'Mensual',
props: {
className: 'btn btn-info btn-xs'
} }
}
);
}
if (this.state.loading) {
form = (
<div
className='text-center'
key={'prices-loading'}
>
<i className='fa fa-spinner fa-spin fa-4x fa-fw'></i>
<p>{'Cargando Precios...'}</p>
</div>
);
}
if (!this.state.loading && this.state.prices) { const {name} = domain;
const prices = this.state.prices; data.domain = name;
const rows = keysPlans.map((plan) => { Client.requestMailboxes(data, (response) => {
const cosId = plans[plan]; const text = this.messageCode[response.messageCode];
const salesArray = configPlans[plan].sales; sweetAlert('Compra éxitosa', text, 'success');
const fields = salesArray.map((field, index) => { }, (error) => {
const label = field.label || `Casillas ${Utils.titleCase(plan)}`; const text = this.messageCode[error.messageCode];
const price = field.hasPrice ? currencyFormatter.format(prices[plan], this.currencyParams) : ''; sweetAlert('Error', text, 'error');
const myref = field.ref ? {ref: `${plan}-${field.ref}`} : {}; });
return (
<div
key={`sale-input-${plan}-${index}`}
className='col-xs-4'
>
<div className='form-group'>
<div className='input-group'>
<div className='input-group-addon'>{label}</div>
<input
type='text'
className='form-control'
disabled={field.disabled}
defaultValue={price}
{...myref}
onKeyUp={(e) => {
this.handleSetNumbersOfMailboxes(e, cosId);
}}
onKeyDown={this.onlyNumber}
/>
</div>
</div>
</div>
);
}); });
}
}, options);
}
return ( renderInputs() {
<div const {purchase} = this.state;
key={`row-fields-${plan}`} return this.mailboxes.map((input, index) => {
className='row' const plan = this.plans[input];
> const value = purchase[input];
{fields} return (
</div>
);
});
form = (
<form key='form-container'>
{rows}
<div className='row'>
<div className='col-xs-4 pull-right'>
<div className='form-group'>
<div className='input-group'>
<div className='input-group-addon'>Total</div>
<input
type='text'
disabled={true}
className='form-control'
ref='total'
/>
<div className='input-group-addon'>{this.currency}</div>
</div>
</div>
</div>
</div>
</form>
);
actions = (
<div <div
className='row' key={`sale-input-${plan.label}-${index}`}
key='actions-container' className='col-xs-4'
> >
<div className='col-xs-12 text-right'> <div className='form-group'>
<button className='btn btn-default'>Cancelar</button> <div className='input-group'>
<button <div className='input-group-addon'>{`Casilla ${plan.label}`}</div>
disabled={disabled} <input
className='btn btn-info' type='text'
onClick={this.confirmShipping} className='form-control'
>Comprar</button> defaultValue={value}
onKeyUp={(event) => this.onKeyupInput(event, input)}
onKeyDown={this.onKeydownInput}
/>
</div>
</div> </div>
</div> </div>
); );
} });
}
render() {
const {disabled} = this.state;
return ( return (
<div> <div>
...@@ -441,9 +182,26 @@ export default class SalesForm extends React.Component { ...@@ -441,9 +182,26 @@ export default class SalesForm extends React.Component {
<div className='row'> <div className='row'>
<div className='col-md-12 central-content'> <div className='col-md-12 central-content'>
<Panel <Panel
btnsHeader={buttons} hasHeader={true}
children={[descriptionText, form, actions]} title={'Selecciona la cantidad de casillas que deseas comprar.'}
/> >
<form key='form-container'>
<div className='row'>
{this.renderInputs()}
</div>
<div
className='row'
>
<div className='col-xs-12 text-right'>
<button
disabled={disabled}
className='btn btn-info'
onClick={this.confirmShipping}
>Comprar</button>
</div>
</div>
</form>
</Panel>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -75,7 +75,7 @@ function initZimbra() { ...@@ -75,7 +75,7 @@ function initZimbra() {
export function getClientConfig(success, error) { export function getClientConfig(success, error) {
return $.ajax({ return $.ajax({
url: 'https://manager-api.zboxapp.com/parse/functions/getConfigManager', url: 'https://manager.zboxapp.com/ventas_api/parse/functions/getConfigManager',
//url: './config/config.json', //url: './config/config.json',
dataType: 'json', dataType: 'json',
method: 'POST', method: 'POST',
...@@ -845,6 +845,30 @@ export function getPrices(data, success, error) { ...@@ -845,6 +845,30 @@ export function getPrices(data, success, error) {
}); });
} }
export function requestMailboxes(data, success, error) {
const appId = window.manager_config.salesAPI.appId;
const endpoints = window.manager_config.salesAPI;
const url = endpoints.base + endpoints.requestSale;
$.ajax({
url: url,
method: 'POST',
data: data,
contentType: 'application/json',
headers: {
'X-Parse-Application-Id': appId,
'X-Parse-REST-API-Key': 'master'
},
dataType: 'json',
success: function onSuccess(response) {
success(response);
},
error: function onError(err) {
error(err.responseJSON || err);
}
});
}
export function makeSale(data, success, error) { export function makeSale(data, success, error) {
const appId = window.manager_config.salesAPI.appId; const appId = window.manager_config.salesAPI.appId;
const endpoints = window.manager_config.salesAPI; const endpoints = window.manager_config.salesAPI;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment