From 61ff2ce29aa10b55a01746f9ef442bb693803cc7 Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Wed, 22 Nov 2017 00:46:23 -0600 Subject: [PATCH] UI para depositos --- source/app/controllers/main.py | 10 +- source/app/controllers/util.py | 2 +- source/app/models/main.py | 131 +++++++++++++++++---- source/static/js/controller/bancos.js | 61 +++++++++- source/static/js/controller/invoices.js | 4 +- source/static/js/controller/main.js | 15 +++ source/static/js/controller/util.js | 5 + source/static/js/ui/bancos.js | 146 ++++++++++++++++++++++-- source/static/js/ui/invoices.js | 2 +- source/static/js/ui/main.js | 5 +- 10 files changed, 336 insertions(+), 45 deletions(-) diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py index 0b2cceb..183a479 100644 --- a/source/app/controllers/main.py +++ b/source/app/controllers/main.py @@ -18,9 +18,10 @@ class AppLogin(object): session = req.env['beaker.session'] values = req.params values['rfc'] = values['rfc'].upper() - result = self._db.authenticate(values) + result, user = self._db.authenticate(values) if result['login']: session.save() + session['userobj'] = user session['user'] = result['user'] session['rfc'] = values['rfc'] req.context['result'] = result @@ -68,7 +69,11 @@ class AppValues(object): def on_get(self, req, resp, table): values = req.params - req.context['result'] = self._db.get_values(table, values) + if table == 'admin': + session = req.env['beaker.session'] + req.context['result'] = session['userobj'].es_admin + else: + req.context['result'] = self._db.get_values(table, values) resp.status = falcon.HTTP_200 def on_delete(self, req, resp, table): @@ -140,7 +145,6 @@ class AppPartners(object): def on_get(self, req, resp): values = req.params - #~ print ('VALUES', values) req.context['result'] = self._db.get_partners(values) resp.status = falcon.HTTP_200 diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py index db46559..bc4d446 100644 --- a/source/app/controllers/util.py +++ b/source/app/controllers/util.py @@ -816,7 +816,7 @@ class LIBO(object): image.GraphicURL = data['path_cbb'] pd.add(image) s = Size() - s.Width = 4250 + s.Width = 4150 s.Height = 4500 image.setSize(s) image.Anchor = self._set_cell('{timbre.cbb}') diff --git a/source/app/models/main.py b/source/app/models/main.py index 6199bd5..939223f 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -176,7 +176,7 @@ class Configuracion(BaseModel): def add(cls, values): try: for k, v in values.items(): - print (k, v) + #~ print (k, v) obj, created = Configuracion.get_or_create(clave=k) obj.valor = v obj.save() @@ -1110,17 +1110,42 @@ class MovimientosBanco(BaseModel): class Meta: order_by = ('fecha',) - def _ultimo_saldo(self, cuenta): + def _ultimo_saldo(self, cuenta, fecha): query = (MovimientosBanco .select() - .where(MovimientosBanco.cuenta==cuenta)[-1] + .where( + (MovimientosBanco.cuenta==cuenta) & + (MovimientosBanco.fecharow.fecha)) + ) + + saldo = row.saldo + if row.retiro: + importe = row.retiro * -1 + else: + importe = row.deposito + + for mov in query: + mov.saldo = saldo + importe + mov.save() + saldo = mov.saldo + CuentasBanco.actualizar_saldo(None, saldo) + return saldo + @classmethod def add(cls, values): #~ print(values) + actualizar = False if not 'saldo' in values: + actualizar = True hora = values.pop('hora') values['fecha'] = '{}T{}'.format(values['fecha'][:10], hora) values['cuenta'] = int(values['cuenta']) @@ -1128,9 +1153,11 @@ class MovimientosBanco(BaseModel): values['deposito'] = util.get_float(values['deposito']) values['forma_pago'] = int(values['forma_pago']) - ultimo_saldo = cls._ultimo_saldo(cls, values['cuenta']) + ultimo_saldo = cls._ultimo_saldo( + cls, values['cuenta'], values['fecha']) values['saldo'] = \ ultimo_saldo - values['retiro'] + values['deposito'] + with database_proxy.transaction(): try: obj = MovimientosBanco.create(**values) @@ -1138,9 +1165,10 @@ class MovimientosBanco(BaseModel): msg = 'Este movimiento ya existe' return {'ok': False, 'msg': msg} - CuentasBanco.actualizar_saldo(values['cuenta'], obj.saldo) + if actualizar: + saldo = cls._actualizar_saldos(cls, obj) - return {'ok': True, 'saldo': obj.saldo} + return {'ok': True, 'saldo': saldo} @classmethod def con(cls, id): @@ -1328,7 +1356,7 @@ class Socios(BaseModel): @classmethod def get_(cls, values): - print ('values', values) + #~ print ('values', values) id = values.get('id', 0) if id: id = int(values['id']) @@ -1447,7 +1475,16 @@ class Socios(BaseModel): return bool(q.execute()) +class Almacenes(BaseModel): + nombre = TextField(default='') + ubicacion = TextField(default='') + + class Meta: + order_by = ('nombre',) + + class Productos(BaseModel): + almacen = ForeignKeyField(Almacenes, null=True) categoria = ForeignKeyField(Categorias, null=True) clave = TextField(unique=True, index=True) clave_sat = TextField(default='') @@ -1678,6 +1715,8 @@ class Facturas(BaseModel): estatus_sat = TextField(default='Vigente') regimen_fiscal = TextField(default='') notas = TextField(default='') + saldo = DecimalField(default=0.0, max_digits=20, decimal_places=6, + auto_round=True) pagada = BooleanField(default=False) cancelada = BooleanField(default=False) fecha_cancelacion = DateTimeField(null=True) @@ -1928,7 +1967,39 @@ class Facturas(BaseModel): return (Facturas.folio.between(folio1, folio2)) + def _get_por_pagar(self): + filtros = ( + (Facturas.cancelada==False) & + (Facturas.uuid.is_null(False)) & + (Facturas.tipo_comprobante=='I') & + (Facturas.saldo>0) + ) + rows = tuple(Facturas + .select( + Facturas.id, + Facturas.serie, + Facturas.folio, + Facturas.uuid, + Facturas.fecha, + Facturas.tipo_comprobante, + Facturas.estatus, + Socios.nombre.alias('cliente'), + Facturas.total, + Facturas.saldo, + ) + .where(filtros) + .join(Socios) + .switch(Facturas) + .dicts() + ) + return {'ok': True, 'rows': rows} + + return + def _get_opt(self, values): + if values['opt'] == 'porpagar': + return self._get_por_pagar(self) + cfdis = util.loads(values['cfdis']) if values['year'] == '-1': @@ -2175,6 +2246,7 @@ class Facturas(BaseModel): obj.total_trasladados = totals['total_trasladados'] obj.total_retenciones = totals['total_retenciones'] obj.total = totals['total'] + obj.saldo = totals['total'] obj.total_mn = totals['total_mn'] obj.save() @@ -2855,11 +2927,18 @@ class FacturasComplementos(BaseModel): class CfdiPagosFacturas(BaseModel): pago = ForeignKeyField(CfdiPagos) factura = ForeignKeyField(Facturas) + numero = IntegerField(default=1) + saldo_anterior = DecimalField(default=0.0, max_digits=20, decimal_places=6, + auto_round=True) + importe = DecimalField(default=0.0, max_digits=18, decimal_places=6, + auto_round=True) + saldo = DecimalField(default=0.0, max_digits=18, decimal_places=6, + auto_round=True) class Meta: order_by = ('pago',) indexes = ( - (('pago', 'factura'), True), + (('pago', 'factura', 'numero'), True), ) @@ -3005,21 +3084,21 @@ class FacturasImpuestos(BaseModel): ) -class FacturasPagos(BaseModel): - factura = ForeignKeyField(Facturas) - numero = IntegerField(default=1) - saldo_anterior = DecimalField(default=0.0, max_digits=20, decimal_places=6, - auto_round=True) - importe = DecimalField(default=0.0, max_digits=18, decimal_places=6, - auto_round=True) - saldo = DecimalField(default=0.0, max_digits=18, decimal_places=6, - auto_round=True) +#~ class FacturasPagos(BaseModel): + #~ factura = ForeignKeyField(Facturas) + #~ numero = IntegerField(default=1) + #~ saldo_anterior = DecimalField(default=0.0, max_digits=20, decimal_places=6, + #~ auto_round=True) + #~ importe = DecimalField(default=0.0, max_digits=18, decimal_places=6, + #~ auto_round=True) + #~ saldo = DecimalField(default=0.0, max_digits=18, decimal_places=6, + #~ auto_round=True) - class Meta: - order_by = ('factura',) - indexes = ( - (('factura', 'numero'), True), - ) + #~ class Meta: + #~ order_by = ('factura',) + #~ indexes = ( + #~ (('factura', 'numero'), True), + #~ ) class PreFacturasImpuestos(BaseModel): @@ -3080,9 +3159,11 @@ def authenticate(args): respuesta['msg'] = '' respuesta['login'] = True respuesta['user'] = str(obj) + #~ respuesta['user'] = obj respuesta['super'] = obj.es_superusuario + #~ respuesta['admin'] = obj.es_superusuario or obj.es_admin #~ desconectar() - return respuesta + return respuesta, obj def get_cp(cp): @@ -3173,8 +3254,8 @@ def _init_values(rfc): def _crear_tablas(rfc): tablas = [Addendas, Categorias, Certificado, CondicionesPago, Configuracion, Folios, - Emisor, Facturas, FacturasDetalle, FacturasImpuestos, FacturasPagos, - FacturasRelacionadas, FacturasComplementos, Productos, + Emisor, Facturas, FacturasDetalle, FacturasImpuestos, + FacturasRelacionadas, FacturasComplementos, Almacenes, Productos, PreFacturas, PreFacturasDetalle, PreFacturasImpuestos, PreFacturasRelacionadas, SATAduanas, SATFormaPago, SATImpuestos, SATMonedas, SATRegimenes, diff --git a/source/static/js/controller/bancos.js b/source/static/js/controller/bancos.js index fd6558a..d476871 100644 --- a/source/static/js/controller/bancos.js +++ b/source/static/js/controller/bancos.js @@ -7,6 +7,8 @@ var bancos_controllers = { $$('cmd_agregar_deposito').attachEvent('onItemClick', cmd_agregar_deposito_click) $$('cmd_guardar_retiro').attachEvent('onItemClick', cmd_guardar_retiro_click) $$('txt_retiro_importe').attachEvent('onChange', txt_retiro_importe_change) + $$('grid_cfdi_este_deposito').attachEvent('onAfterDrop', grid_cfdi_este_deposito_after_drop) + $$('grid_cfdi_por_pagar').attachEvent('onAfterDrop', grid_cfdi_por_pagar_after_drop) set_year_month() } } @@ -97,22 +99,47 @@ function lst_cuentas_banco_change(nv, ov){ } -function get_retiro_forma_pago(){ +function get_bancos_forma_pago(retiro){ webix.ajax().get('/values/formapago', {}, function(text, data){ var values = data.json() - $$('lst_retiro_forma_pago').getList().parse(values) + if(retiro){ + $$('lst_retiro_forma_pago').getList().parse(values) + }else{ + $$('lst_deposito_forma_pago').getList().parse(values) + } + }) +} + + +function get_facturas_por_pagar(){ + var grid = $$('grid_cfdi_por_pagar') + + webix.ajax().get('/invoices', {'opt': 'porpagar'}, { + error:function(text, data, XmlHttpRequest){ + msg = 'Ocurrio un error, consulta a soporte técnico' + msg_error(msg) + }, + success:function(text, data, XmlHttpRequest){ + var values = data.json() + grid.clearAll() + if (values.ok){ + grid.parse(values.rows, 'json') + } + } }) } function cmd_agregar_retiro_click(){ - get_retiro_forma_pago() + get_bancos_forma_pago(true) $$('multi_bancos').setValue('banco_retiro') } function cmd_agregar_deposito_click(){ - showvar('Depósito') + get_bancos_forma_pago(false) + get_facturas_por_pagar() + $$('multi_bancos').setValue('banco_deposito') } @@ -234,3 +261,29 @@ function txt_retiro_importe_change(new_value, old_value){ this.refresh() } } + + +function actualizar_deposito(grid){ + var suma = 0 + var descripcion = '' + grid.data.each(function(obj){ + suma += obj.saldo.to_float() + descripcion += 'Pago de la factura: ' + obj.serie + obj.folio + ' del ' + descripcion += 'cliente: ' + obj.cliente + '\n' + }) + $$('txt_deposito_importe').setValue(suma) + $$('deposito_descripcion').setValue(descripcion) +} + + +function grid_cfdi_por_pagar_after_drop(context, native_event){ + var grid = $$('grid_cfdi_este_deposito') + actualizar_deposito(grid) +} + + +function grid_cfdi_este_deposito_after_drop(context, native_event){ + var grid = $$('grid_cfdi_este_deposito') + grid.sort("#fecha#", "asc", "string") + actualizar_deposito(grid) +} diff --git a/source/static/js/controller/invoices.js b/source/static/js/controller/invoices.js index d6e9c3b..7520e67 100644 --- a/source/static/js/controller/invoices.js +++ b/source/static/js/controller/invoices.js @@ -112,7 +112,7 @@ function default_config(){ var values = data.json() show('chk_cfdi_anticipo', values.cfdi_anticipo) show('chk_cfdi_donativo', values.cfdi_donativo) - if(values.cfdi_ine == '0'){ + if(!values.cfdi_ine || values.cfdi_ine == '0'){ $$('tv_invoice').getTabbar().hideOption('INE') }else{ $$('tv_invoice').getTabbar().showOption('INE') @@ -409,7 +409,7 @@ function save_invoice(data){ if(values.ok){ msg_sucess('Factura guardada correctamente. Enviando a timbrar') update_grid_invoices(values) - gi.showItem(values.row['id']) + gi.select(values.row['id'], false) send_timbrar(values.row['id']) result = true }else{ diff --git a/source/static/js/controller/main.js b/source/static/js/controller/main.js index 2453a0e..68e0815 100644 --- a/source/static/js/controller/main.js +++ b/source/static/js/controller/main.js @@ -1,10 +1,25 @@ var gi = null +function configuracion_inicial(){ + webix.ajax().get('/values/admin', function(text, data){ + var values = data.json() + $$('cmd_ir_al_admin').show(values) + }) +} + + +function cmd_ir_al_admin_click(){ + window.location = '/admin' +} + + var controllers = { init: function(){ //~ Main $$('menu_user').attachEvent('onMenuItemClick', menu_user_click); + configuracion_inicial() + //~ Partner $$('cmd_new_partner').attachEvent('onItemClick', cmd_new_partner_click); $$('cmd_new_contact').attachEvent('onItemClick', cmd_new_contact_click); diff --git a/source/static/js/controller/util.js b/source/static/js/controller/util.js index 142b4dd..7d53233 100644 --- a/source/static/js/controller/util.js +++ b/source/static/js/controller/util.js @@ -75,6 +75,11 @@ String.prototype.is_number = function(){ } +String.prototype.to_float = function(){ + return get_float(this) +} + + function get_float(value){ return parseFloat(value.replace('$', '').replace(',', '').trim()).round(2) } diff --git a/source/static/js/ui/bancos.js b/source/static/js/ui/bancos.js index 60eea37..b77ad3d 100644 --- a/source/static/js/ui/bancos.js +++ b/source/static/js/ui/bancos.js @@ -51,18 +51,103 @@ var grid_cuentabanco = { } +var grid_cfdi_por_pagar_cols = [ + {id: 'index', header: '#', adjust: 'data', css: 'right'}, + {id: 'id', header: 'ID', hidden: true}, + {id: 'serie', header: 'Serie', adjust: 'data'}, + {id: 'folio', header: 'Folio', adjust: 'data', css: 'right'}, + {id: 'uuid', header: 'UUID', width: 250, hidden: true}, + {id: 'fecha', header: 'Fecha y Hora', width: 150, sort: 'date'}, + {id: 'tipo_comprobante', header: 'Tipo', adjust: 'data'}, + {id: 'estatus', header: 'Estatus', adjust: 'header'}, + {id: 'cliente', header: ['Razón Social', {content: 'selectFilter'}], + fillspace:true, sort: 'string'}, + {id: 'total', header: ['Total'], width: 125, sort: 'int', + format: webix.i18n.priceFormat, css: 'right'}, + {id: 'saldo', header: ['Saldo'], width: 125, sort: 'int', + format: webix.i18n.priceFormat, css: 'right'}, +] + + +var grid_cfdi_este_deposito_cols = [ + {id: 'index', header: '#', adjust: 'data', css: 'right'}, + {id: 'id', header: 'ID', hidden: true}, + {id: 'serie', header: 'Serie', adjust: 'data'}, + {id: 'folio', header: 'Folio', adjust: 'data', css: 'right'}, + {id: 'uuid', header: 'UUID', width: 250, hidden: true}, + {id: 'fecha', header: 'Fecha y Hora', width: 150, sort: 'date'}, + {id: 'tipo_comprobante', header: 'Tipo', adjust: 'data'}, + {id: 'estatus', header: 'Estatus', adjust: 'header'}, + {id: 'cliente', header: ['Razón Social'], fillspace: true}, + {id: 'total', header: ['Total'], width: 125, sort: 'int', + format: webix.i18n.priceFormat, css: 'right'}, + {id: 'saldo', header: ['Saldo'], width: 125, sort: 'int', + format: webix.i18n.priceFormat, css: 'right'}, +] + + +var grid_cfdi_por_pagar = { + view: 'datatable', + id: 'grid_cfdi_por_pagar', + select: 'row', + autoConfig: false, + adjust: true, + height: 250, + resizeColumn: true, + headermenu: true, + drag: true, + columns: grid_cfdi_por_pagar_cols, + on:{ + 'data->onStoreUpdated':function(){ + this.data.each(function(obj, i){ + obj.index = i + 1 + }) + } + }, +} + + +var grid_cfdi_este_deposito = { + view: 'datatable', + id: 'grid_cfdi_este_deposito', + select: 'row', + autoConfig: false, + adjust: true, + height: 200, + resizeColumn: true, + headermenu: true, + drag: true, + columns: grid_cfdi_este_deposito_cols, + on:{ + 'data->onStoreUpdated':function(){ + this.data.each(function(obj, i){ + obj.index = i + 1 + }) + } + }, +} + + var toolbar_banco_retiro = [ {view: 'label', label: 'Agregar retiro de banco'}, {}, + {view: 'button', id: 'cmd_guardar_retiro', label: 'Guardar Retiro', + type: 'iconButton', autowidth: true, icon: 'minus'}, {view: 'icon', click: '$$("multi_bancos").setValue("banco_home")', icon: 'times-circle'} ] -var body_banco_retiro = [ - +var toolbar_banco_deposito = [ + {view: 'label', label: 'Agregar depósito de banco'}, + {}, + {view: 'button', id: 'cmd_guardar_deposito', label: 'Guardar Depósito', + type: 'iconButton', autowidth: true, icon: 'plus'}, + {view: 'icon', click: '$$("multi_bancos").setValue("banco_home")', + icon: 'times-circle'} ] + var controls_banco_retiro = [ {view: 'toolbar', elements: toolbar_banco_retiro}, {cols: [ @@ -91,10 +176,41 @@ var controls_banco_retiro = [ label: 'Descripción', labelAlign: 'right', required: true, labelWidth: 125}, ]}, - {cols: [{}, - {view: 'button', id: 'cmd_guardar_retiro', label: 'Guardar Retiro', - type: 'iconButton', autowidth: true, icon: 'minus'}, - {}]}, +] + + +var controls_banco_deposito = [ + {view: 'toolbar', elements: toolbar_banco_deposito}, + {cols: [ + {view: 'datepicker', id: 'date_deposito', name: 'deposito_fecha', + label: 'Fecha', format: '%d-%M-%Y', labelAlign: 'right', + required: true, invalidMessage: 'Selecciona una fecha', + labelWidth: 125}, + {view: 'search', id: 'time_deposito', name: 'deposito_hora', + label: 'Hora', icon: 'clock-o', labelAlign: 'right', + pattern:{mask: '##:##:##', allow:/[0-9]/g}, required: true, + invalidMessage: 'Captura una hora'}, + {view: 'text', id: 'deposito_referencia', name: 'deposito_referencia', + label: 'Referencia', labelAlign: 'right'}, + ]}, + {cols: [ + {view: 'richselect', id: 'lst_deposito_forma_pago', + name: 'deposito_forma_pago', label: 'Forma de Pago', required: true, + options: [], labelWidth: 125, labelAlign: 'right'}, + {view: 'currency', type: 'text', id: 'txt_deposito_importe', + name: 'deposito_importe', label: 'Importe', labelAlign: 'right', + required: true, invalidMessage: 'Captura un valor númerico', + inputAlign: 'right', value: ''} + ]}, + {cols: [ + {view: 'textarea', id: 'deposito_descripcion', label: 'Descripción', + name: 'deposito_descripcion', labelAlign: 'right', required: true, + labelWidth: 125, height: 70}, + ]}, + {view: 'label', label: 'Facturas por pagar: '}, + grid_cfdi_por_pagar, + {view: 'label', label: 'Facturas a pagar en este depósito: '}, + grid_cfdi_este_deposito, ] @@ -107,7 +223,20 @@ var form_banco_retiro = { complexData: true, scroll: true, elements: controls_banco_retiro, - }] + }], +} + + +var form_banco_deposito = { + type: 'space', + responsive: true, + cols: [{ + view: 'form', + id: 'form_banco_deposito', + complexData: true, + scroll: true, + elements: controls_banco_deposito, + }], } @@ -120,7 +249,8 @@ var multi_bancos = { {view: 'toolbar', elements: toolbar_filtro_cuenta}, grid_cuentabanco, ]}, - {id: 'banco_retiro', rows: [form_banco_retiro]} + {id: 'banco_retiro', rows: [form_banco_retiro]}, + {id: 'banco_deposito', rows: [form_banco_deposito]} ], } diff --git a/source/static/js/ui/invoices.js b/source/static/js/ui/invoices.js index dd70624..6df8320 100644 --- a/source/static/js/ui/invoices.js +++ b/source/static/js/ui/invoices.js @@ -228,7 +228,7 @@ var grid_invoices = { obj.index = i + 1 }) } - } + }, } diff --git a/source/static/js/ui/main.js b/source/static/js/ui/main.js index 2e61ebb..5034328 100644 --- a/source/static/js/ui/main.js +++ b/source/static/js/ui/main.js @@ -67,7 +67,10 @@ var ui_main = { {}, menu_user, {view: 'button', type: 'icon', width: 45, css: 'app_button', - icon: 'bell-o', badge: 0} + icon: 'bell-o', badge: 0}, + {view: 'button', type: 'icon', width: 45, css: 'app_button', + icon: 'cogs', id: 'cmd_ir_al_admin', hidden: true, + click: 'cmd_ir_al_admin_click'} ] }, {