From 920ff62e98b242b0309bb7c62e3c6240b59ac466 Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Sun, 13 Jun 2021 23:12:07 -0500 Subject: [PATCH] Add new table PartnerProducts --- source/app/controllers/main.py | 16 +++++ source/app/controllers/utils.py | 6 ++ source/app/main.py | 4 +- source/app/models/db.py | 19 +++--- source/app/models/main.py | 87 ++++++++++++++++++++++++- source/static/js/controller/products.js | 64 +++++++++++++++++- source/static/js/ui/products.js | 23 ++++--- 7 files changed, 195 insertions(+), 24 deletions(-) diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py index daf9b85..52c88db 100644 --- a/source/app/controllers/main.py +++ b/source/app/controllers/main.py @@ -664,3 +664,19 @@ class AppSucursales(object): req.context['result'] = self._db.sucursales_post(values) resp.status = falcon.HTTP_200 + +class AppPartnerProducts(object): + + def __init__(self, db): + self._db = db + + def on_get(self, req, resp): + values = req.params + req.context['result'] = self._db.partner_products_get(values) + resp.status = falcon.HTTP_200 + + def on_post(self, req, resp): + values = req.params + req.context['result'] = self._db.partner_products_post(values) + resp.status = falcon.HTTP_200 + diff --git a/source/app/controllers/utils.py b/source/app/controllers/utils.py index 05e04ae..cf532cf 100644 --- a/source/app/controllers/utils.py +++ b/source/app/controllers/utils.py @@ -792,6 +792,12 @@ def _products_from_xml(rfc, data): return result result['data'] = cfdi.data + + emisor = result['data']['emisor'] + emisor['rfc'] = emisor['Rfc'] + emisor['nombre'] = emisor['Nombre'] + result['data']['emisor'] = emisor + products = result['data']['conceptos'] rows = [] for p in products: diff --git a/source/app/main.py b/source/app/main.py index 38e9a41..dd6bbad 100644 --- a/source/app/main.py +++ b/source/app/main.py @@ -17,7 +17,8 @@ from controllers.main import (AppEmpresas, AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco, AppMovimientosBanco, AppTickets, AppStudents, AppEmployees, AppNomina, AppInvoicePay, AppCfdiPay, AppSATBancos, AppSociosCuentasBanco, - AppSATFormaPago, AppSATLeyendaFiscales, AppCert, AppSucursales + AppSATFormaPago, AppSATLeyendaFiscales, AppCert, AppSucursales, + AppPartnerProducts ) @@ -64,6 +65,7 @@ api.add_route('/socioscb', AppSociosCuentasBanco(db)) api.add_route('/leyendasfiscales', AppSATLeyendaFiscales(db)) api.add_route('/cert', AppCert(db)) api.add_route('/sucursales', AppSucursales(db)) +api.add_route('/partnerproducts', AppPartnerProducts(db)) session_options = { diff --git a/source/app/models/db.py b/source/app/models/db.py index 3580fa0..ad3b107 100644 --- a/source/app/models/db.py +++ b/source/app/models/db.py @@ -466,17 +466,20 @@ class StorageEngine(object): return main.SATLeyendasFiscales.remove(values) # ~ v2 - def cert_get(self, values): - return main.Certificado.get_data(values) + def cert_get(self, filters): + return main.Certificado.get_data(filters) - def cert_post(self, values): - return main.Certificado.post(values) + def cert_post(self, filters): + return main.Certificado.post(filters) - def sucursales_get(self, values): - return main.Sucursales.get_data(values) + def sucursales_get(self, filters): + return main.Sucursales.get_data(filters) - def sucursales_post(self, values): - return main.Sucursales.post(values) + def sucursales_post(self, filters): + return main.Sucursales.post(filters) + + def partner_products_get(self, filters): + return main.PartnerProducts.get_data(filters) # Companies only in MV def _get_empresas(self, values): diff --git a/source/app/models/main.py b/source/app/models/main.py index bb480fb..3a2433d 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -104,6 +104,37 @@ def desconectar(): return +class UploadFile(object): + + def _read_productsadd(self, result): + emisor = result['data']['emisor'] + rfc = emisor['rfc'] + + where = ((Socios.rfc == rfc) & (Socios.es_proveedor == True)) + try: + row = (Socios + .select(Socios.id) + .where(where) + .get() + .dicts() + ) + emisor['id'] = row['id'] + except Socios.DoesNotExist: + emisor['id'] = 0 + + result['data']['emisor'] = emisor + + return result + + @classmethod + def read(cls, rfc, opt, file_obj): + result = utils.upload_file(rfc, opt, file_obj) + method = f'_read_{opt}' + if hasattr(cls, method): + return getattr(cls, method)(cls, result) + return result + + def upload_file(rfc, opt, file_obj): if opt == 'cfdixml': sxml = file_obj.file.read().decode() @@ -120,7 +151,7 @@ def upload_file(rfc, opt, file_obj): # ~ v2 names = ('productsadd',) if opt in names: - result = utils.upload_file(rfc, opt, file_obj) + result = UploadFile.read(rfc, opt, file_obj) return result result = util.upload_file(rfc, opt, file_obj) @@ -9288,6 +9319,57 @@ class CfdiNominaRelacionados(BaseModel): return [str(r.cfdi_origen.uuid) for r in query] +class PartnerProducts(BaseModel): + partner = ForeignKeyField(Socios) + key = TextField(default='') + product = ForeignKeyField(Productos) + + class Meta: + order_by = ('partner', 'key') + indexes = ( + (('partner', 'key', 'product'), True), + ) + + def _get_product(self, filters): + data = {'ok': True} + id = int(filters['partner_id']) + rfc = filters['partner_rfc'] + key = filters['partner_key'] + + where = (Socios.rfc == rfc) + if id: + where = (Socios.id == id) + where = (where & (PartnerProducts.key == key)) + select = ( + Productos.id.alias('id_product'), + Productos.clave_sat.alias('key_sat1'), + Productos.descripcion.alias('description1'), + ) + try: + row = (PartnerProducts + .select(select) + .join(Socios).switch(PartnerProducts) + .join(Productos).switch(PartnerProducts) + .where(where) + .get() + .dicts() + ) + except PartnerProducts.DoesNotExist: + msg = 'No se encontró un producto existente' + data = {'ok': False, 'msg': msg} + return data + + print('ROW', row) + data['row'] = row + + return data + + @classmethod + def get_data(cls, filters): + method = f"_get_{filters['opt']}" + return getattr(cls, method)(cls, filters) + + @util.run_in_thread def _save_log(user, action, table): data = {'usuario': user, 'accion': action, 'tabla': table} @@ -9503,6 +9585,7 @@ def _crear_tablas(rfc): Socios.tags.get_through_model(), Productos.impuestos.get_through_model(), Productos.tags.get_through_model(), + PartnerProducts, ] log.info('Creando tablas...') database_proxy.create_tables(tablas, True) @@ -9555,7 +9638,7 @@ def _migrate_tables(rfc=''): CfdiNominaOtroPago, CfdiNominaOtros, CfdiNominaPercepciones, CfdiNominaRelacionados, CfdiNominaSeparacion, CfdiNominaSubcontratos, CfdiNominaTotales, SATNivelesEducativos, Roles, Permisos, - SociosCuentasBanco, SATLeyendasFiscales + SociosCuentasBanco, SATLeyendasFiscales, PartnerProducts ] log.info('Creando tablas nuevas...') database_proxy.create_tables(tablas, True) diff --git a/source/static/js/controller/products.js b/source/static/js/controller/products.js index 05ebef1..34cb038 100644 --- a/source/static/js/controller/products.js +++ b/source/static/js/controller/products.js @@ -436,6 +436,8 @@ function up_products_upload_complete(response){ //~ Add products function cmd_products_add_click(id, e, node){ $$("multi_products").setValue("product_add") + cfg_products['partner_id'] = 0 + cfg_products['partner_rfc'] = '' } //~ Close add products @@ -514,13 +516,69 @@ function up_products_from_xml_upload_complete(response){ var grid = $$('grid_partner_products') var data = response.data + cfg_products['partner_id'] = data.emisor.id + cfg_products['partner_rfc'] = data.emisor.rfc var html = '' - html += data.emisor.Nombre + ' (' + data.emisor.Rfc + ')' + html += data.emisor.nombre + ' (' + data.emisor.rfc + ')' $$('lbl_partner').setValue(html) - grid.clearAll(); - grid.parse(data.conceptos, 'json'); + grid.clearAll() + grid.parse(data.conceptos, 'json') grid.refresh() } + + +function get_partner_product(grid, row){ + grid.refresh(row.id) + + var filters = { + opt: 'product', + partner_id: cfg_products['partner_id'], + partner_rfc: cfg_products['partner_rfc'], + partner_key: row.key, + } + + if(!filters['partner_id']){ + msg = 'El Proveedor no esta dado de alta' + msg_ok(msg) + return + } + + webix.ajax().get('/partnerproducts', filters, { + error: function(text, data, xhr) { + msg_error('Ocurrio un error, consulta a soporte técnico.') + }, + success: function(text, data, xhr){ + var values = data.json() + if(values.ok){ + row['id_product'] = values.row.id_product + row['key_sat1'] = values.row.key_sat1 + row['description1'] = values.row.description1 + grid.refresh(row.id) + }else{ + msg_error(values.msg) + } + } + }) + +} + + +function grid_partner_products_select(row_id, state){ + var grid = $$('grid_partner_products') + var row = grid.getItem(row_id) + + if(state){ + row['key_sat1'] = row.key_sat + row['description1'] = row.description + row['cant1'] = row.cant + get_partner_product(grid, row) + }else{ + row['key_sat1'] = '' + row['description1'] = '' + row['cant1'] = '' + grid.refresh(row_id) + } +} diff --git a/source/static/js/ui/products.js b/source/static/js/ui/products.js index 4f3a650..cdcfc7a 100644 --- a/source/static/js/ui/products.js +++ b/source/static/js/ui/products.js @@ -238,23 +238,21 @@ var grid_partner_products_cols = [ {id: 'unit', header:{text: 'Unidad', css: 'center'}, width: 100, adjust: 'data'}, {id: 'unit_value', header:{text: 'Valor Unitario', css: 'center'}, - width: 100, format: format_currency, css: 'right', editor: 'text'}, - //~ {id: 'descuento', header:{text: 'Descuento', css: 'center'}, - //~ width: 100, format: format_currency, css: 'right', editor: 'text'}, - //~ {id: 'precio_final', hidden: true, header: 'precio_final', width: 80, - //~ format: webix.i18n.priceFormat, css: 'right'}, - {id: 'import', header:{text: 'Importe', css: 'center'}, width: 100, - format: webix.i18n.priceFormat, css: 'right'}, + width: 100, format: format_currency, css: 'right'}, {id: 'cant', header: {text: 'Cantidad', css: 'center'}, width: 50, - format: webix.i18n.numberFormat, css: 'right', editor: 'text'}, + format: webix.i18n.numberFormat, css: 'right'}, {id: 'separate', header: '', width: 25}, {id: 'id_product', header: '', hidden: true}, {id: 'key1', header:{text: 'Clave', css: 'center'}, width: 100, - adjust: 'data'}, + adjust: true, editor: 'text', hidden: true}, {id: 'key_sat1', header:{text: 'Clave SAT', css: 'center'}, width: 100, - adjust: 'data'}, + adjust: true, editor: 'text'}, {id: 'description1', header:{text: 'Descripción', css: 'center'}, fillspace: true, editor: 'popup'}, + {id: 'unit_value1', header:{text: 'Valor Unitario', css: 'center'}, + width: 100, format: format_currency, css: 'right', editor: 'text'}, + {id: 'cant1', header: {text: 'Cantidad', css: 'center'}, width: 50, + format: webix.i18n.numberFormat, css: 'right', editor: 'text'}, ] @@ -268,6 +266,11 @@ var grid_partner_products = { columns: grid_partner_products_cols, data: [], fixedRowHeight: false, + on:{ + onCheck:function(rowId, colId, state){ + grid_partner_products_select(rowId, state); + } + } }