This commit is contained in:
Mauricio Baeza 2018-10-12 01:14:01 -05:00
parent 4eb4cc8fa5
commit af5d526bad
11 changed files with 212 additions and 74 deletions

View File

@ -1,4 +1,4 @@
v 1.21.0 [11-oct-2018]
v 1.21.0 [12-oct-2018]
----------------------
- Error #287
- Mejora: Complemento de pago con datos de cuentas
@ -11,7 +11,7 @@ v 1.20.0 [08-oct-2018]
- Error #295
- Mejora: Cuentas de banco para clientes
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar.
v 1.19.1 [03-oct-2018]

View File

@ -6,7 +6,7 @@ siempre actualizado.** Solo se da soporte sobre la ultima versión de **Empresa
Libre**.
### 1.21.0 [11-oct-2018]
### 1.21.0 [12-oct-2018]
- Error [#287](https://gitlab.com/mauriciobaeza/empresa-libre/issues/287)
- Mejora: Complemento de pago con datos de cuentas

View File

@ -77,6 +77,16 @@ Toma en cuenta que este sitio esta en constante actualización y desarrollo, los
datos generados se limpian de forma regular.
<BR>
### ¿Dondé descargar los archivos necesarios?
Todos los archivos necesarios para probar localmente **Empresa Libre** en tu
equipo, los puedes descargar desde nuestra carpeta compartida, donde también
puedes descargar todas las plantillas necesarias para el sistema
[Carpeta pública de Empresa Libre][7]
<BR>
### Después de actualizar, no veo los cambios esperados en pantalla
@ -92,3 +102,4 @@ tu pantalla, en la mayoría de los navegadores con la combinación de teclas
[4]: https://gitlab.com/mauriciobaeza/empresa-libre/issues
[5]:
[6]: https://universolibre.org/hacemos/
[7]: https://doc.elmau.net/d/dbb11c9186684457beb6/

View File

@ -45,6 +45,7 @@ FORMAT6 = '{0:.6f}'
FORMAT_TAX = FORMAT4
FORMAT_PRECIO = FORMAT4
RFC_PUBLICO = 'XAXX010101000'
RFC_EXTRANJERO = 'XEXX010101000'
database_proxy = Proxy()
@ -241,7 +242,8 @@ def config_main():
'nomina': nomina,
'timbres': 0,
'decimales_precios': DECIMALES,
'pagos': Configuracion.get_bool('chk_config_pagos')
'pagos': Configuracion.get_bool('chk_config_pagos'),
'pays_data_bank': Configuracion.get_bool('chk_cfg_pays_data_bank')
}
dp = Configuracion.get_bool('chk_config_decimales_precios')
if dp:
@ -320,6 +322,28 @@ class Configuracion(BaseModel):
values = {r.clave: util.get_bool(r.valor) for r in data}
return values
def _get_complements(self):
fields = (
'chk_config_ine',
'chk_config_edu',
'chk_config_pagos',
'chk_cfg_pays_data_bank',
)
data = (Configuracion
.select()
.where(Configuracion.clave.in_(fields))
)
values = {r.clave: util.get_bool(r.valor) for r in data}
fields = (
'txt_config_cfdipay_serie',
'txt_config_cfdipay_folio',
)
for f in fields:
values[f] = Configuracion.get_(f)
return values
@classmethod
def get_(cls, keys):
if isinstance(keys, str):
@ -331,7 +355,7 @@ class Configuracion(BaseModel):
return data[0].valor
return ''
options = ('partners',)
options = ('partners', 'complements')
opt = keys['fields']
if opt in options:
return getattr(cls, '_get_{}'.format(opt))(cls)
@ -388,9 +412,6 @@ class Configuracion(BaseModel):
'chk_config_codigo_barras',
'chk_config_precio_con_impuestos',
'chk_llevar_inventario',
'chk_config_ine',
'chk_config_edu',
'chk_config_pagos',
'chk_usar_punto_de_venta',
'chk_ticket_pdf_show',
'chk_ticket_direct_print',
@ -2547,6 +2568,7 @@ class Socios(BaseModel):
class SociosCuentasBanco(BaseModel):
socio = ForeignKeyField(Socios)
activa = BooleanField(default=True)
banco = ForeignKeyField(SATBancos)
cuenta = TextField(default='')
clabe = TextField(default='')
@ -2561,10 +2583,15 @@ class SociosCuentasBanco(BaseModel):
def __str__(self):
return '{} ({})'.format(self.banco.name, self.cuenta[-4:])
@classmethod
def get_values(cls, values):
opt = values.pop('opt')
return getattr(cls, '_get_{}'.format(opt))(cls, values)
def _get_by_name(self, values):
name = values['name']
query = (SociosCuentasBanco
.select()
.where(SociosCuentasBanco.activa==True, Socios.nombre==name)
.join(Socios).switch(SociosCuentasBanco)
)
rows = tuple([{'id': q.id, 'value': str(q)} for q in query])
return {'ok': True, 'values': rows}
def _get_by_partner(self, values):
id = int(values['id_partner'])
@ -2579,6 +2606,11 @@ class SociosCuentasBanco(BaseModel):
.dicts())
return tuple(rows)
@classmethod
def get_values(cls, values):
opt = values.pop('opt')
return getattr(cls, '_get_{}'.format(opt))(cls, values)
@classmethod
def post(cls, values):
opt = values.pop('opt')
@ -2612,6 +2644,13 @@ class SociosCuentasBanco(BaseModel):
msg = 'Cuenta borrada correctamente'
return {'ok': result, 'msg': msg}
@classmethod
def validate_partner_account(cls, id, invoices):
id_invoice = int(tuple(invoices.keys())[0])
account = SociosCuentasBanco.get(SociosCuentasBanco.id==id)
invoice = Facturas.get(Facturas.id==id_invoice)
return account.socio == invoice.cliente
class Contactos(BaseModel):
socio = ForeignKeyField(Socios)
@ -2737,6 +2776,16 @@ class MovimientosBanco(BaseModel):
def _add(self, values):
ids = values.pop('ids', '')
cuenta_socio = values.get('cuenta_socio', None)
if not ids:
cuenta_socio = None
if ids and cuenta_socio and \
not SociosCuentasBanco.validate_partner_account(cuenta_socio, util.loads(ids)):
msg = 'La cuenta seleccionada no corresponde al cliente'
data = {'ok': False, 'msg': msg}
return data
if ids and not Facturas.validate_count_partners(util.loads(ids)):
msg = 'Facturas relacionadas a diferentes clientes'
data = {'ok': False, 'msg': msg}
@ -2751,6 +2800,7 @@ class MovimientosBanco(BaseModel):
account = CuentasBanco.get(CuentasBanco.id==int(values['cuenta']))
values['fecha'] = '{}T{}'.format(values['fecha'][:10], hora)
values['cuenta'] = account
values['cuenta_socio'] = cuenta_socio
values['moneda'] = account.moneda.key
values['retiro'] = util.get_float(values['retiro'])
values['deposito'] = util.get_float(values['deposito'])
@ -3456,13 +3506,6 @@ class Facturas(BaseModel):
@classmethod
def validate_count_partners(cls, ids):
filters = (Facturas.id.in_(tuple(ids.keys())))
# ~ partners = (Facturas.select(fn.COUNT(Facturas.cliente))
# ~ .where(filters)
# ~ .group_by(Facturas.cliente)
# ~ .order_by(Facturas.cliente).tuples())
# ~ if len(partners) > 1:
# ~ return False
# ~ return True
partners = (Facturas.select(fn.COUNT(Socios.rfc))
.where(filters)
.join(Socios).switch(Facturas)
@ -5795,6 +5838,7 @@ class CfdiPagos(BaseModel):
def _generate_xml(self, invoice, auth):
emisor = Emisor.select()[0]
cert = Certificado.get_cert()
used_data_bank = Configuracion.get_bool('chk_cfg_pays_data_bank')
cfdi = {}
related = {}
@ -5844,7 +5888,6 @@ class CfdiPagos(BaseModel):
impuestos = {}
mov = invoice.movimiento
# ~ currency = mov.cuenta.moneda.key
currency = mov.moneda
related_docs = self._get_related_xml(self, invoice.movimiento, currency)
pagos = {
@ -5854,6 +5897,20 @@ class CfdiPagos(BaseModel):
'Monto': FORMAT.format(mov.deposito),
'relacionados': related_docs,
}
if mov.numero_operacion:
pagos['NumOperacion'] = mov.numero_operacion
if used_data_bank and mov.cuenta_socio:
if mov.cuenta_socio.banco.rfc:
pagos['RfcEmisorCtaOrd'] = mov.cuenta_socio.banco.rfc
if mov.cuenta_socio.banco.rfc == RFC_EXTRANJERO:
pagos['NomBancoOrdExt'] = mov.cuenta_socio.banco.name
pagos['CtaOrdenante'] = mov.cuenta_socio.cuenta
if mov.cuenta.banco.rfc:
pagos['RfcEmisorCtaBen'] = mov.cuenta.banco.rfc
pagos['CtaBeneficiario'] = mov.cuenta.cuenta
if currency != CURRENCY_MN:
pagos['TipoCambioP'] = FORMAT_TAX.format(mov.tipo_cambio)
@ -8416,15 +8473,21 @@ def _migrate_tables(rfc=''):
table = 'movimientosbanco'
columns = [c.name for c in database_proxy.get_columns(table)]
if not 'cuenta_socio' in columns:
if not 'cuenta_socio_id' in columns:
cuenta_socio = ForeignKeyField(SociosCuentasBanco, null=True, to_field=SociosCuentasBanco.id)
migrations.append(migrator.add_column(table, 'socioscuentasbanco_id', cuenta_socio))
migrations.append(migrator.add_column(table, 'cuenta_socio_id', cuenta_socio))
migrations.append(migrator.drop_column(table, 'origen_rfc'))
migrations.append(migrator.drop_column(table, 'origen_nombre'))
migrations.append(migrator.drop_column(table, 'origen_cuenta'))
migrations.append(migrator.drop_column(table, 'destino_rfc'))
migrations.append(migrator.drop_column(table, 'destino_cuenta'))
table = 'socioscuentasbanco'
columns = [c.name for c in database_proxy.get_columns(table)]
if not 'activa' in columns:
activa = BooleanField(default=True)
migrations.append(migrator.add_column(table, 'activa', activa))
if migrations:
with database_proxy.atomic() as txn:
migrate(*migrations)

View File

@ -92,6 +92,7 @@ var controllers = {
$$('chk_config_ine').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_edu').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_pagos').attachEvent('onItemClick', chk_config_item_click)
$$('chk_cfg_pays_data_bank').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_cuenta_predial').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_codigo_barras').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_precio_con_impuestos').attachEvent('onItemClick', chk_config_item_click)
@ -1133,6 +1134,7 @@ function tab_options_change(nv, ov){
var cv = {
tab_admin_templates: 'templates',
tab_admin_partners: 'partners',
tab_admin_complements: 'complements',
tab_admin_otros: 'configotros',
}
get_config_values(cv[nv])

View File

@ -37,8 +37,12 @@ function init_config_bank(){
g3.showColumn('total')
g3.showColumn('currency')
}
show('cmd_complemento_pago', get_config('used_cfdi_pays'))
show('cmd_show_invoice_pay', get_config('used_cfdi_pays'))
var used_cfdi_pays = get_config('used_cfdi_pays')
show('cmd_complemento_pago', used_cfdi_pays)
show('cmd_show_invoice_pay', used_cfdi_pays)
if(used_cfdi_pays){
show_column('grid_cuentabanco', 'invoice')
}
set_year_month()
}
@ -69,6 +73,7 @@ var bancos_controllers = {
$$('cmd_pay_delete').attachEvent('onItemClick', cmd_pay_delete_click)
$$('grid_cfdi_pay').attachEvent('onItemClick', grid_cfdi_pay_click)
$$('grid_cfdi_por_pagar').attachEvent('onItemDblClick', grid_cfdi_por_pagar_double_click)
$$('grid_cfdi_por_pagar').attachEvent('onAfterFilter', grid_cfdi_por_pagar_on_after_filter)
$$('grid_cfdi_este_deposito').attachEvent('onItemDblClick', grid_cfdi_este_deposito_double_click)
$$('cmd_show_invoice_pay').attachEvent('onItemClick', cmd_show_invoice_pay_click)
$$('filter_invoice_pay_year').attachEvent('onChange', filter_invoice_pay_change)
@ -246,7 +251,6 @@ function get_facturas_por_pagar(){
function cmd_agregar_retiro_click(){
//~ get_bancos_forma_pago(true)
set_way_payment('lst_retiro_forma_pago', true, current_way_payment)
var title = 'Agregar retiro de banco a la cuenta ' + $$('lst_cuentas_banco').getText() + ' en ' + $$('txt_cuenta_moneda').getValue()
$$('title_bank_retiro').setValue(title)
@ -256,14 +260,17 @@ function cmd_agregar_retiro_click(){
function cmd_agregar_deposito_click(){
msg_importe = ''
//~ get_bancos_forma_pago(false)
get_facturas_por_pagar()
set_way_payment('lst_deposito_forma_pago', true, current_way_payment)
var g = $$('grid_cfdi_este_deposito')
g.config.columns[g.getColumnIndex('importe')].header = 'Este Pago ' + current_currency
g.refreshColumns()
show('deposit_type_change', current_currency!=CURRENCY_MN)
var pays = get_config('used_cfdi_pays') && get_config('pays_data_bank')
show('lst_partner_account_bank', pays)
var title = 'Agregar depósito de banco a la cuenta ' + $$('lst_cuentas_banco').getText() + ' en ' + $$('txt_cuenta_moneda').getValue()
$$('title_bank_deposit').setValue(title)
@ -668,6 +675,7 @@ function guardar_deposito(values){
data['tipo_cambio'] = values.deposit_type_change.to_float4()
data['retiro'] = 0.0
data['descripcion'] = values.deposito_descripcion
data['cuenta_socio'] = values.partner_account_bank
current_way_payment = data['forma_pago']
@ -718,41 +726,40 @@ function cmd_guardar_deposito_click(){
return
}
msg = 'Todos los datos son correctos.<br><br>'
if(!grid.count()){
msg = 'Todos los datos son correctos<br>br>'
msg = 'El depósito no tiene facturas relacionadas<br><br>¿Estás '
msg += ' seguro de guardar el depósito sin facturas relacionadas?'
webix.confirm({
title: 'Guardar depósito',
ok: 'Si',
cancel: 'No',
type: 'confirm-error',
text: msg,
callback:function(result){
if(result){
guardar_deposito(values)
}
}
})
msg += 'El depósito no tiene facturas relacionadas<br>¿Estás '
msg += ' seguro de guardar el depósito sin facturas relacionadas?<br><br>'
}else{
if(!msg_importe){
msg_importe = 'Se van a relacionar ' + grid.count() + ' facturas.'
}
msg = 'Todos los datos son correctos.<br><br>' + msg_importe + '<br><br>'
msg += '¿Deseas agregar este depósito?'
webix.confirm({
title: 'Guardar depósito',
ok: 'Si',
cancel: 'No',
type: 'confirm-error',
text: msg,
callback:function(result){
if(result){
guardar_deposito(values)
}
if(grid.count()==1){
msg += 'Se va a relacionar 1 factura.<br><br>'
}else{
msg += 'Se van a relacionar ' + grid.count() + ' facturas.<br><br>'
}
})
}
}
if(get_config('pays_data_bank') && grid.count() && !values.partner_account_bank){
msg += 'NO seleccionaste cuenta origen.<br><br>'
}
msg += '¿Deseas agregar este depósito?'
webix.confirm({
title: 'Guardar depósito',
ok: 'Si',
cancel: 'No',
type: 'confirm-error',
text: msg,
callback:function(result){
if(result){
guardar_deposito(values)
}
}
})
}
@ -1261,3 +1268,28 @@ function get_invoices_pay(rango){
}
})
}
function grid_cfdi_por_pagar_on_after_filter(){
var partner = $$('grid_cfdi_por_pagar').getFilter('cliente').value
var lst = $$('lst_partner_account_bank')
lst_clear(lst)
if(partner){
var args = {opt: 'by_name', name: partner}
webix.ajax().get('/socioscb', args, {
error:function(text, data, XmlHttpRequest){
msg = 'Ocurrio un error, consulta a soporte técnico'
msg_error(msg)
},
success:function(text, data, XmlHttpRequest){
var result = data.json()
if (result.ok){
lst_parse(lst, result.values)
}else{
msg_error(result.msg)
}
}
})
}
}

View File

@ -39,6 +39,7 @@ function configuracion_inicial(){
add_config({'key': 'decimales_precios', 'value': values.decimales_precios})
add_config({'key': 'used_cfdi_pays', 'value': values.pagos})
add_config({'key': 'multi_currency', 'value': values.multi_currency})
add_config({'key': 'pays_data_bank', 'value': values.pays_data_bank})
})

View File

@ -488,7 +488,7 @@ function cmd_partner_add_account_bank_click(){
return
}
if(account.cuenta.length < 9){
if(account.cuenta.length < 10){
msg = 'Longitud incorrecta de la cuenta'
msg_error(msg)
return

View File

@ -112,6 +112,11 @@ function show(nombre, value){
}
function show_column(table, column){
$$(table).showColumn(column)
}
function enable(nombre, value){
if(value == '0'){
value = false
@ -560,5 +565,16 @@ function pause(milliseconds) {
}
//~ Revisado
function lst_clear(lst){
lst.setValue('')
lst.define('options', [])
lst.refresh()
}
function lst_parse(lst, values){
lst.getList().parse(values)
}

View File

@ -667,22 +667,6 @@ var options_admin_otros = [
labelRight: 'Mostrar inventario'},
]},
{maxHeight: 20},
{template: 'Complementos', type: 'section'},
{cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_ine', labelWidth: 0,
labelRight: 'Usar el complemento INE'},
{view: 'checkbox', id: 'chk_config_edu', labelWidth: 0,
labelRight: 'Usar el complemento EDU'},
{}]},
{cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_pagos', labelWidth: 0,
labelRight: 'Usar complemento de pagos'},
{view: 'text', id: 'txt_config_cfdipay_serie', name: 'txt_config_cfdipay_serie',
label: 'Serie', labelWidth: 50, labelAlign: 'right'},
{view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie',
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
{}]},
{maxHeight: 20},
{template: 'Punto de venta', type: 'section'},
{cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_usar_punto_de_venta', labelWidth: 0,
@ -723,6 +707,29 @@ var options_admin_partners = [
]
var options_admin_complements = [
{maxHeight: 20},
{cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_ine', labelWidth: 0,
labelRight: 'Usar el complemento INE'},
{view: 'checkbox', id: 'chk_config_edu', labelWidth: 0,
labelRight: 'Usar el complemento EDU'},
{}]},
{maxHeight: 20},
{template: 'Complemento de Pagos', type: 'section'},
{cols: [{maxWidth: 15},
{view: 'checkbox', id: 'chk_config_pagos', labelWidth: 0,
labelRight: 'Usar complemento de pagos'},
{view: 'checkbox', id: 'chk_cfg_pays_data_bank', labelWidth: 0,
labelRight: 'Usar datos bancarios'},
{view: 'text', id: 'txt_config_cfdipay_serie', name: 'txt_config_cfdipay_serie',
label: 'Serie', labelWidth: 50, labelAlign: 'right'},
{view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie',
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
{maxWidth: 15}]},
]
var tab_options = {
view: 'tabview',
id: 'tab_options',
@ -732,6 +739,8 @@ var tab_options = {
rows: options_templates}},
{header: 'Clientes y Proveedores', body: {id: 'tab_admin_partners',
view: 'scrollview', body: {rows: options_admin_partners}}},
{header: 'Complementos', body: {id: 'tab_admin_complements',
view: 'scrollview', body: {rows: options_admin_complements}}},
{header: 'Otros', body: {id: 'tab_admin_otros', view: 'scrollview',
body: {rows: options_admin_otros}}},
],

View File

@ -64,7 +64,7 @@ var grid_cuentabanco_cols = [
width: 125, format: webix.i18n.priceFormat, css: 'right'},
{id: 'saldo', header: ['Saldo'],
width: 125, format: webix.i18n.priceFormat, css: 'right'},
{id: 'invoice', header: ['FP'], width: 40, css: 'center'},
{id: 'invoice', header: ['FP'], width: 40, css: 'center', hidden: true},
]
@ -438,6 +438,10 @@ var controls_banco_deposito = [
]},
{cols: [
{view: 'label', label: '<b>Facturas por pagar: </b>'},
{view: 'richselect', id: 'lst_partner_account_bank', hidden: true,
name: 'partner_account_bank', label: 'Cuenta Origen', required: false,
options: [], labelWidth: 125, labelAlign: 'right'},
{},
{view: 'button', id: 'cmd_invoice_payed', label: 'Solo marcar pagada',
type: 'iconButton', autowidth: true, icon: 'check-circle',
tooltip: 'No afecta a saldos'},