Merge branch 'develop'

Se puede modidicar el saldo del cliente
Se muestra la cantidad de facturas de pago en los movimientos
This commit is contained in:
Mauricio Baeza 2018-09-16 22:10:15 -05:00
commit 127ceceada
10 changed files with 214 additions and 94 deletions

View File

@ -1,3 +1,9 @@
v 1.16.0 [16-sep-2018]
----------------------
- Se puede editar el saldo de un cliente
- Se muestra la cantidad de facturas de pago en los movimientos
v 1.15.0 [12-sep-2018] v 1.15.0 [12-sep-2018]
---------------------- ----------------------
- Se pueden mover las facturas con doble clic en los movimientos de banco. - Se pueden mover las facturas con doble clic en los movimientos de banco.

View File

@ -1 +1 @@
1.15.0 1.16.0

View File

@ -306,6 +306,17 @@ class Configuracion(BaseModel):
return util.get_bool(data[0].valor) return util.get_bool(data[0].valor)
return False return False
def _get_partners(self):
fields = (
'chk_config_change_balance_partner',
)
data = (Configuracion
.select()
.where(Configuracion.clave.in_(fields))
)
values = {r.clave: util.get_bool(r.valor) for r in data}
return values
@classmethod @classmethod
def get_(cls, keys): def get_(cls, keys):
if isinstance(keys, str): if isinstance(keys, str):
@ -317,6 +328,11 @@ class Configuracion(BaseModel):
return data[0].valor return data[0].valor
return '' return ''
options = ('partners',)
opt = keys['fields']
if opt in options:
return getattr(cls, '_get_{}'.format(opt))(cls)
if keys['fields'] == 'productos': if keys['fields'] == 'productos':
fields = ( fields = (
'chk_config_cuenta_predial', 'chk_config_cuenta_predial',
@ -1946,26 +1962,6 @@ class MovimientosBanco(BaseModel):
msg = 'Movimiento cancelado correctamente' msg = 'Movimiento cancelado correctamente'
return {'ok': True, 'msg': msg, 'balance': balance} return {'ok': True, 'msg': msg, 'balance': balance}
# ~ @classmethod
# ~ def remove(cls, id):
# ~ try:
# ~ obj = MovimientosBanco.get(MovimientosBanco.id==id)
# ~ except MovimientosBanco.DoesNotExist:
# ~ return False
# ~ if obj.conciliado or obj.cancelado:
# ~ return False
# ~ with database_proxy.transaction():
# ~ obj.cancelado = True
# ~ obj.save()
# ~ FacturasPagos.cancelar(obj)
# ~ obj = cls._movimiento_anterior(cls, obj.cuenta, obj.fecha)
# ~ cls._actualizar_saldos(cls, obj)
# ~ return True
@classmethod @classmethod
def con(cls, id): def con(cls, id):
cant = (MovimientosBanco cant = (MovimientosBanco
@ -2007,19 +2003,22 @@ class MovimientosBanco(BaseModel):
(MovimientosBanco.cancelado==False) (MovimientosBanco.cancelado==False)
) )
rows = tuple(MovimientosBanco rows = tuple(MovimientosBanco.select(
.select( MovimientosBanco.id,
MovimientosBanco.id, MovimientosBanco.fecha,
MovimientosBanco.fecha, MovimientosBanco.numero_operacion,
SATFormaPago.name.alias('way_payment'), SATFormaPago.name.alias('way_payment'),
MovimientosBanco.numero_operacion, MovimientosBanco.descripcion,
MovimientosBanco.descripcion, MovimientosBanco.retiro,
MovimientosBanco.retiro, MovimientosBanco.deposito,
MovimientosBanco.deposito, MovimientosBanco.saldo,
MovimientosBanco.saldo) fn.COUNT(CfdiPagos.id).alias('invoice')
.join(SATFormaPago).switch(MovimientosBanco) )
.where(filtros) .join(SATFormaPago).switch(MovimientosBanco)
.dicts() .join(CfdiPagos, JOIN.LEFT_OUTER).switch(MovimientosBanco)
.where(filtros)
.group_by(MovimientosBanco.id, SATFormaPago.name)
.dicts()
) )
return {'ok': True, 'rows': rows} return {'ok': True, 'rows': rows}
@ -2485,6 +2484,12 @@ class Socios(BaseModel):
def _clean(self, values): def _clean(self, values):
fields = util.clean(values) fields = util.clean(values)
change_balance = Configuracion.get_bool('chk_config_change_balance_partner')
balance = fields.pop('partner_balance', '').replace('$', '').replace(',', '')
if change_balance:
fields['saldo_cliente'] = round(float(balance), 2)
fields['rfc'] = fields['rfc'].upper() fields['rfc'] = fields['rfc'].upper()
fields['nombre'] = util.spaces(fields['nombre']) fields['nombre'] = util.spaces(fields['nombre'])
fields['slug'] = util.to_slug(fields['nombre']) fields['slug'] = util.to_slug(fields['nombre'])
@ -2521,6 +2526,7 @@ class Socios(BaseModel):
if not row['condicion_pago'] is None: if not row['condicion_pago'] is None:
row['condicion_pago'] = \ row['condicion_pago'] = \
str(CondicionesPago.get(id=row['condicion_pago'])) str(CondicionesPago.get(id=row['condicion_pago']))
row['partner_balance'] = row.pop('saldo_cliente')
return row return row
#~ return {'data': data['rows'][:100], 'pos':0, 'total_count': 1300} #~ return {'data': data['rows'][:100], 'pos':0, 'total_count': 1300}
@ -2610,10 +2616,12 @@ class Socios(BaseModel):
data = {'ok': False, 'row': {}, 'new': True, 'msg': msg} data = {'ok': False, 'row': {}, 'new': True, 'msg': msg}
return data return data
obj = Socios.get(Socios.id==id)
row = { row = {
'id': id, 'id': id,
'rfc': fields['rfc'], 'rfc': obj.rfc,
'nombre': fields['nombre'], 'nombre': obj.nombre,
'saldo_cliente': obj.saldo_cliente,
} }
data = {'ok': True, 'row': row, 'new': False} data = {'ok': True, 'row': row, 'new': False}
return data return data
@ -2630,11 +2638,11 @@ class Socios(BaseModel):
q = Socios.delete().where(Socios.id==id) q = Socios.delete().where(Socios.id==id)
return bool(q.execute()) return bool(q.execute())
def _reset_saldo(self, id): # ~ def _reset_saldo(self, id):
obj = Socios.get(Socios.id==id) # ~ obj = Socios.get(Socios.id==id)
obj.saldo_cliente = 0.0 # ~ obj.saldo_cliente = 0.0
obj.save() # ~ obj.save()
return {'ok': True} # ~ return {'ok': True}
@classmethod @classmethod
def opt(cls, args): def opt(cls, args):
@ -5357,6 +5365,12 @@ class CfdiPagos(BaseModel):
class Meta: class Meta:
order_by = ('movimiento',) order_by = ('movimiento',)
@classmethod
def with_invoice(cls, id):
if CfdiPagos.select().where(CfdiPagos.movimiento==id).count():
return 'Si'
return ''
@classmethod @classmethod
def post(cls, values): def post(cls, values):
opt = values.pop('opt') opt = values.pop('opt')

View File

@ -47,7 +47,7 @@ except ImportError:
DEBUG = DEBUG DEBUG = DEBUG
VERSION = '1.15.0' VERSION = '1.16.0'
EMAIL_SUPPORT = ('soporte@empresalibre.net',) EMAIL_SUPPORT = ('soporte@empresalibre.net',)
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION) TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)

View File

@ -74,6 +74,9 @@ var controllers = {
$$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click) $$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click)
$$('txt_plantilla_nomina1233').attachEvent('onItemClick', txt_plantilla_nomina1233_click) $$('txt_plantilla_nomina1233').attachEvent('onItemClick', txt_plantilla_nomina1233_click)
$$('txt_plantilla_pagos10').attachEvent('onItemClick', txt_plantilla_pagos10_click) $$('txt_plantilla_pagos10').attachEvent('onItemClick', txt_plantilla_pagos10_click)
//~ Partners
$$('chk_config_change_balance_partner').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_ocultar_metodo_pago').attachEvent('onItemClick', chk_config_item_click) $$('chk_config_ocultar_metodo_pago').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_ocultar_condiciones_pago').attachEvent('onItemClick', chk_config_item_click) $$('chk_config_ocultar_condiciones_pago').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_send_zip').attachEvent('onItemClick', chk_config_item_click) $$('chk_config_send_zip').attachEvent('onItemClick', chk_config_item_click)
@ -1124,6 +1127,7 @@ function txt_plantilla_pagos10_click(e){
function tab_options_change(nv, ov){ function tab_options_change(nv, ov){
var cv = { var cv = {
tab_admin_templates: 'templates', tab_admin_templates: 'templates',
tab_admin_partners: 'partners',
tab_admin_otros: 'configotros', tab_admin_otros: 'configotros',
} }
get_config_values(cv[nv]) get_config_values(cv[nv])

View File

@ -1,3 +1,21 @@
//~ Empresa Libre
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
//~
//~ This program is free software: you can redistribute it and/or modify
//~ it under the terms of the GNU General Public License as published by
//~ the Free Software Foundation, either version 3 of the License, or
//~ (at your option) any later version.
//~
//~ This program is distributed in the hope that it will be useful,
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//~ GNU General Public License for more details.
//~
//~ You should have received a copy of the GNU General Public License
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
var cfg_partners = new Object()
var partners_controllers = { var partners_controllers = {
@ -9,7 +27,7 @@ var partners_controllers = {
$$('cmd_save_partner').attachEvent('onItemClick', cmd_save_partner_click); $$('cmd_save_partner').attachEvent('onItemClick', cmd_save_partner_click);
$$('cmd_cancel_partner').attachEvent('onItemClick', cmd_cancel_partner_click); $$('cmd_cancel_partner').attachEvent('onItemClick', cmd_cancel_partner_click);
$$('cmd_cancel_contact').attachEvent('onItemClick', cmd_cancel_contact_click); $$('cmd_cancel_contact').attachEvent('onItemClick', cmd_cancel_contact_click);
$$('cmd_partner_zero').attachEvent('onItemClick', cmd_partner_zero_click); //~ $$('cmd_partner_zero').attachEvent('onItemClick', cmd_partner_zero_click);
$$('codigo_postal').attachEvent('onKeyPress', postal_code_key_press); $$('codigo_postal').attachEvent('onKeyPress', postal_code_key_press);
$$('codigo_postal').attachEvent('onTimedKeyPress', postal_code_key_up); $$('codigo_postal').attachEvent('onTimedKeyPress', postal_code_key_up);
$$('colonia').attachEvent('onFocus', colonia_on_focus) $$('colonia').attachEvent('onFocus', colonia_on_focus)
@ -18,12 +36,31 @@ var partners_controllers = {
$$("es_proveedor").attachEvent( "onChange", is_supplier_change) $$("es_proveedor").attachEvent( "onChange", is_supplier_change)
$$("rfc").attachEvent( "onBlur", rfc_lost_focus) $$("rfc").attachEvent( "onBlur", rfc_lost_focus)
$$('multi').attachEvent('onViewChange', multi_change) $$('multi').attachEvent('onViewChange', multi_change)
$$('grid_partners').attachEvent('onItemDblClick', cmd_edit_partner_click) $$('grid_partners').attachEvent('onItemDblClick', grid_partners_double_click)
$$('grid_partners').attachEvent('onSelectChange', grid_partners_on_select_change) //~ $$('grid_partners').attachEvent('onSelectChange', grid_partners_on_select_change)
$$('partner_balance').attachEvent('onChange', partner_balance_on_change)
default_config_partners()
} }
} }
function default_config_partners(){
webix.ajax().get('/config', {'fields': 'partners'}, {
error: function(text, data, xhr) {
msg = 'Error al consultar'
msg_error(msg)
},
success: function(text, data, xhr) {
var values = data.json()
cfg_partners = values
//~ show('cmd_partner_zero', cfg_partners['chk_config_change_balance_partner'])
}
})
}
function get_condicion_pago(){ function get_condicion_pago(){
webix.ajax().get('/values/condicionespago', { webix.ajax().get('/values/condicionespago', {
error: function(text, data, xhr) { error: function(text, data, xhr) {
@ -38,8 +75,10 @@ function get_condicion_pago(){
function cmd_new_partner_click(id, e, node){ function cmd_new_partner_click(id, e, node){
$$('form_partner').clearValidation()
$$('form_partner').setValues({ $$('form_partner').setValues({
id: 0, pais: 'México', tipo_persona: 1, es_activo: true}) id: 0, pais: 'México', tipo_persona: 1, es_activo: true,
partner_balance: 0.00})
$$('forma_pago').getList().load('/values/formapago') $$('forma_pago').getList().load('/values/formapago')
get_condicion_pago() get_condicion_pago()
$$('grid_partners').clearSelection() $$('grid_partners').clearSelection()
@ -49,6 +88,7 @@ function cmd_new_partner_click(id, e, node){
get_uso_cfdi_to_table() get_uso_cfdi_to_table()
query = table_usocfdi.chain().find({fisica: true}).data() query = table_usocfdi.chain().find({fisica: true}).data()
$$('lst_uso_cfdi_socio').getList().parse(query) $$('lst_uso_cfdi_socio').getList().parse(query)
$$('partner_balance').define('readonly', !cfg_partners['chk_config_change_balance_partner'])
} }
@ -75,10 +115,13 @@ function cmd_edit_partner_click(){
}, },
success: function(text, data, xhr){ success: function(text, data, xhr){
var values = data.json() var values = data.json()
$$('form_partner').clearValidation()
$$('form_partner').setValues(values) $$('form_partner').setValues(values)
$$('forma_pago').getList().load('/values/formapago') $$('forma_pago').getList().load('/values/formapago')
$$('partner_balance').define('readonly', !cfg_partners['chk_config_change_balance_partner'])
get_uso_cfdi_to_table() get_uso_cfdi_to_table()
if(values.tipo_persona == 1){ if(values.tipo_persona == 1){
query = table_usocfdi.chain().find({fisica: true}).data() query = table_usocfdi.chain().find({fisica: true}).data()
}else if(values.tipo_persona == 2){ }else if(values.tipo_persona == 2){
@ -156,6 +199,13 @@ function cmd_save_partner_click(id, e, node){
var values = form.getValues(); var values = form.getValues();
if(!values.rfc){
msg = 'Captura el RFC'
msg_error(msg)
$$('tab_partner').setValue('Datos Fiscales')
return
}
if(values.tipo_persona != 4){ if(values.tipo_persona != 4){
if(values.codigo_postal && values.codigo_postal.length != 5){ if(values.codigo_postal && values.codigo_postal.length != 5){
msg = 'Longitud inválida del C.P.' msg = 'Longitud inválida del C.P.'
@ -337,54 +387,54 @@ function is_supplier_change(new_value, old_value){
} }
function partner_reset_saldo(id){ //~ function partner_reset_saldo(id){
webix.ajax().post('/partners', {opt: 'reset', id: id}, { //~ webix.ajax().post('/partners', {opt: 'reset', id: id}, {
error:function(text, data, XmlHttpRequest){ //~ error:function(text, data, XmlHttpRequest){
msg = 'Ocurrio un error, consulta a soporte técnico'; //~ msg = 'Ocurrio un error, consulta a soporte técnico';
msg_error(msg) //~ msg_error(msg)
}, //~ },
success:function(text, data, XmlHttpRequest){ //~ success:function(text, data, XmlHttpRequest){
var values = data.json(); //~ var values = data.json();
if(values.ok){ //~ if(values.ok){
msg = 'Saldo actualizado correctamente' //~ msg = 'Saldo actualizado correctamente'
$$('grid_partners').updateItem(id, {saldo_cliente: 0.0}) //~ $$('grid_partners').updateItem(id, {saldo_cliente: 0.0})
$$('cmd_partner_zero').disable() //~ $$('cmd_partner_zero').disable()
msg_ok(msg) //~ msg_ok(msg)
} //~ }
} //~ }
}) //~ })
} //~ }
function cmd_partner_zero_click(){ //~ function cmd_partner_zero_click(){
var g = $$('grid_partners') //~ var g = $$('grid_partners')
var row = g.getSelectedItem() //~ var row = g.getSelectedItem()
var saldo = row.saldo_cliente.to_float() //~ var saldo = row.saldo_cliente.to_float()
if(saldo){ //~ if(saldo){
msg = '¿Estas seguro de poner en cero el saldo del cliente?<BR><BR>' //~ msg = '¿Estas seguro de poner en cero el saldo del cliente?<BR><BR>'
msg += 'ESTA ACCIÓN NO SE PUEDE DESHACER' //~ msg += 'ESTA ACCIÓN NO SE PUEDE DESHACER'
webix.confirm({ //~ webix.confirm({
title: 'Saldo Cliente', //~ title: 'Saldo Cliente',
ok: 'Si', //~ ok: 'Si',
cancel: 'No', //~ cancel: 'No',
type: 'confirm-error', //~ type: 'confirm-error',
text: msg, //~ text: msg,
callback:function(result){ //~ callback:function(result){
if (result){ //~ if (result){
partner_reset_saldo(row.id) //~ partner_reset_saldo(row.id)
} //~ }
} //~ }
}) //~ })
}else{ //~ }else{
$$('cmd_partner_zero').disable() //~ $$('cmd_partner_zero').disable()
} //~ }
} //~ }
function grid_partners_on_select_change(){ //~ function grid_partners_on_select_change(){
$$('cmd_partner_zero').enable() //~ $$('cmd_partner_zero').enable()
} //~ }
@ -430,3 +480,16 @@ function multi_partners_change(prevID, nextID){
} }
function grid_partners_double_click(id, e, node){
//~ if(id.column!='saldo_cliente'){
cmd_edit_partner_click()
//~ }
}
function partner_balance_on_change(new_value, old_value){
if(!isFinite(new_value)){
this.config.value = old_value
this.refresh()
}
}

View File

@ -188,6 +188,7 @@ webix.protoUI({
$init:function(){ $init:function(){
this.attachEvent("onItemClick", function(){ this.attachEvent("onItemClick", function(){
this.$setValue(this.config.raw, true) this.$setValue(this.config.raw, true)
this.getInputNode().select()
}) })
this.attachEvent("onBlur", function(){ this.attachEvent("onBlur", function(){
this.$setValue(this.config.value) this.$setValue(this.config.value)

View File

@ -714,6 +714,15 @@ var options_admin_otros = [
{}] {}]
var options_admin_partners = [
{maxHeight: 20},
{cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_change_balance_partner',
labelWidth: 0, labelRight: 'Permitir cambiar saldo'},
]},
]
var tab_options = { var tab_options = {
view: 'tabview', view: 'tabview',
id: 'tab_options', id: 'tab_options',
@ -721,9 +730,11 @@ var tab_options = {
cells: [ cells: [
{header: 'Plantillas', body: {id: 'tab_admin_templates', {header: 'Plantillas', body: {id: 'tab_admin_templates',
rows: options_templates}}, rows: options_templates}},
{header: 'Clientes y Proveedores', body: {id: 'tab_admin_partners',
view: 'scrollview', body: {rows: options_admin_partners}}},
{header: 'Otros', body: {id: 'tab_admin_otros', view: 'scrollview', {header: 'Otros', body: {id: 'tab_admin_otros', view: 'scrollview',
body: {rows: options_admin_otros}}}, body: {rows: options_admin_otros}}},
] ],
} }

View File

@ -62,6 +62,7 @@ var grid_cuentabanco_cols = [
width: 125, format: webix.i18n.priceFormat, css: 'right'}, width: 125, format: webix.i18n.priceFormat, css: 'right'},
{id: 'saldo', header: ['Saldo'], {id: 'saldo', header: ['Saldo'],
width: 125, format: webix.i18n.priceFormat, css: 'right'}, width: 125, format: webix.i18n.priceFormat, css: 'right'},
{id: 'invoice', header: ['FP'], width: 40, css: 'center'},
] ]

View File

@ -1,3 +1,18 @@
//~ Empresa Libre
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
//~
//~ This program is free software: you can redistribute it and/or modify
//~ it under the terms of the GNU General Public License as published by
//~ the Free Software Foundation, either version 3 of the License, or
//~ (at your option) any later version.
//~
//~ This program is distributed in the hope that it will be useful,
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//~ GNU General Public License for more details.
//~
//~ You should have received a copy of the GNU General Public License
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
var toolbar_partners = [ var toolbar_partners = [
@ -8,8 +23,8 @@ var toolbar_partners = [
{view: 'button', id: 'cmd_delete_partner', label: 'Eliminar', type: 'iconButton', {view: 'button', id: 'cmd_delete_partner', label: 'Eliminar', type: 'iconButton',
autowidth: true, icon: 'user-times'}, autowidth: true, icon: 'user-times'},
{}, {},
{view: 'button', id: 'cmd_partner_zero', label: 'Saldo 0', type: 'iconButton', //~ {view: 'button', id: 'cmd_partner_zero', label: 'Saldo 0', type: 'iconButton',
autowidth: true, icon: 'power-off', disabled: true}, //~ autowidth: true, icon: 'power-off', disabled: true},
] ]
@ -113,7 +128,7 @@ var controls_fiscales = [
var controls_others = [ var controls_others = [
{view: 'checkbox', id: 'es_activo', name: 'es_activo', label: 'Activo: ', {view: 'checkbox', id: 'es_activo', name: 'es_activo', label: 'Activo: ',
value: true, bottomLabel: '&nbsp;&nbsp;&nbsp;Se recomienda solo desactivar y no eliminar'}, value: true, bottomLabel: '&nbsp;&nbsp;Se recomienda solo desactivar y no eliminar'},
{view: 'text', id: 'commercial_name', name: 'nombre_comercial', {view: 'text', id: 'commercial_name', name: 'nombre_comercial',
label: 'Nombre Comercial: '}, label: 'Nombre Comercial: '},
{view: 'text', id: 'telefonos', name: 'telefonos', label: 'Teléfonos: '}, {view: 'text', id: 'telefonos', name: 'telefonos', label: 'Teléfonos: '},
@ -125,7 +140,12 @@ var controls_others = [
{view: 'checkbox', id: 'es_cliente', name: 'es_cliente', {view: 'checkbox', id: 'es_cliente', name: 'es_cliente',
label: 'Es Cliente: ', value: true, width: 180}, label: 'Es Cliente: ', value: true, width: 180},
{view: 'text', id: 'cuenta_cliente', name: 'cuenta_cliente', {view: 'text', id: 'cuenta_cliente', name: 'cuenta_cliente',
label: 'Cuenta Cliente: ', disabled: true}, {}] label: 'Cuenta Cliente: ', disabled: true},
{view: "currency", type: "text", id: 'partner_balance', width: 300,
name: 'partner_balance', label: 'Saldo', labelWidth: 100,
labelAlign: "right", required: true, inputAlign: "right",
invalidMessage: "Captura un valor númerico", readonly: true},
]
}, },
{cols: [ {cols: [
{view: 'checkbox', id: 'es_proveedor', name: 'es_proveedor', {view: 'checkbox', id: 'es_proveedor', name: 'es_proveedor',