From 4a846541175c2cf69ffb8887bf33c4dc020da583 Mon Sep 17 00:00:00 2001 From: El Mau Date: Mon, 29 Nov 2021 21:57:32 -0600 Subject: [PATCH] Validar existencia por almacen --- source/app/controllers/main.py | 9 +- source/app/controllers/utils.py | 2 +- source/app/models/db.py | 7 +- source/app/models/main.py | 107 +++++++++++++++++++++++- source/static/js/controller/invoices.js | 25 +++++- source/static/js/controller/tickets.js | 22 ++++- 6 files changed, 161 insertions(+), 11 deletions(-) diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py index 8146a19..4f2c8c9 100644 --- a/source/app/controllers/main.py +++ b/source/app/controllers/main.py @@ -279,7 +279,11 @@ class AppProducts(object): def on_get(self, req, resp): values = req.params - req.context['result'] = self._db.get_products(values) + user = req.env['beaker.session']['userobj'] + if 'opt' in values: + req.context['result'] = self._db.products_get(values, user) + else: + req.context['result'] = self._db.get_products(values) resp.status = falcon.HTTP_200 def on_post(self, req, resp): @@ -722,7 +726,8 @@ class AppWareHouseProduct(object): def on_get(self, req, resp): values = req.params - req.context['result'] = self._db.warehouseproduct_get(values) + user = req.env['beaker.session']['userobj'] + req.context['result'] = self._db.warehouseproduct_get(values, user) resp.status = falcon.HTTP_200 def on_post(self, req, resp): diff --git a/source/app/controllers/utils.py b/source/app/controllers/utils.py index c8ff49c..0a8f147 100644 --- a/source/app/controllers/utils.py +++ b/source/app/controllers/utils.py @@ -682,7 +682,7 @@ def _cancel_with_cert(invoice, auth, certificado): def cancel_xml_sign(invoice, auth, certificado): - # ~ return _cancel_with_cert(invoice, auth, certificado) + return _cancel_with_cert(invoice, auth, certificado) cert = SATCertificate(certificado.cer, certificado.key_enc.encode()) pac = PACS[auth['pac']]() diff --git a/source/app/models/db.py b/source/app/models/db.py index 371d006..4e74252 100644 --- a/source/app/models/db.py +++ b/source/app/models/db.py @@ -493,8 +493,8 @@ class StorageEngine(object): def warehouse_post(self, values, user): return main.Almacenes.post(values, user) - def warehouseproduct_get(self, filters): - return main.WareHouseProduct.get_data(filters) + def warehouseproduct_get(self, filters, user): + return main.WareHouseProduct.get_data(filters, user) def warehouseproduct_post(self, filters, user): return main.WareHouseProduct.post(filters, user) @@ -508,6 +508,9 @@ class StorageEngine(object): def ticketsdetails_get(self, filters, user): return main.TicketsDetalle.get_data(filters, user) + def products_get(self, filters, user): + return main.Productos.get_data(filters, user) + # Companies only in MV def _get_empresas(self, values): return main.companies_get() diff --git a/source/app/models/main.py b/source/app/models/main.py index bc25f1b..427af8e 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -3712,6 +3712,68 @@ class Productos(BaseModel): class Meta: order_by = ('descripcion',) + @classmethod + def _get_by_key(cls, args, user): + try: + warehouse = user.sucursal.warehouse + except: + warehouse = None + + key = args['key'] + + select = ( + Productos.id.alias('id_product'), + Productos.clave, + Productos.clave_sat, + Productos.descripcion, + SATUnidades.id.alias('unidad'), + Productos.valor_unitario, + Productos.descuento, + Productos.inventario, + Productos.existencia, + ) + where = ( + (Productos.es_activo==True) & + ( + (Productos.clave==key) | + (Productos.codigo_barras==key) + ) + ) + row = (Productos + .select(*select) + .join(SATUnidades).switch(Productos) + .where(where) + .limit(1) + .dicts() + ) + + if not len(row): + return {'ok': False} + + obj = row[0] + + model_pt = Productos.impuestos.get_through_model() + taxes = tuple( + model_pt + .select( + model_pt.productos_id.alias('product'), + model_pt.satimpuestos_id.alias('tax')) + .where(model_pt.productos_id==obj['id_product']).dicts() + ) + + if obj['inventario'] and not warehouse is None: + obj['existencia'] = WareHouseProduct.get_exists_by_warehouse( + obj['id_product'], warehouse) + + result = {'ok': True, 'row': obj, 'taxes': taxes} + + return result + + @classmethod + def get_data(cls, values, user): + opt = values.pop('opt') + return getattr(cls, f'_get_{opt}')(values, user) + @classmethod def next_key(cls): try: @@ -4049,7 +4111,7 @@ class WareHouseProduct(BaseModel): ) @classmethod - def _get_by_product(cls, args): + def _get_by_product(cls, args, user): id = int(args['id']) select = ( Almacenes.id, @@ -4067,9 +4129,45 @@ class WareHouseProduct(BaseModel): return tuple(rows) @classmethod - def get_data(cls, values): + def get_exists_by_warehouse(cls, product, warehouse): + where = ( + (WareHouseProduct.product==product) & + (WareHouseProduct.warehouse==warehouse) + ) + exists = (WareHouseProduct + .select(WareHouseProduct.exists) + .where(where) + .limit(1) + .scalar() + ) or 0 + return exists + + @classmethod + def _get_exists(cls, args, user): + id_product = int(args['id']) + warehouse = None + try: + warehouse = user.sucursal.warehouse + except: + obj = Productos.get(id==id_product) + return obj.existencia + + where = ( + (WareHouseProduct.product==id) & + (WareHouseProduct.warehouse==warehouse) + ) + exists = (WareHouseProduct + .select(WareHouseProduct.exists) + .where(where) + .limit(1) + .scalar() + ) + return exists + + @classmethod + def get_data(cls, values, user): opt = values.pop('opt') - return getattr(cls, f'_get_{opt}')(values) + return getattr(cls, f'_get_{opt}')(values, user) @classmethod def update_exists(cls, args): @@ -4111,6 +4209,9 @@ class WareHouseProduct(BaseModel): ) query.execute() + msg = 'ajustar stock' + _save_log(user.usuario, msg, 'WHP') + result = {'ok': True, 'row': {'existencia': total}} return result diff --git a/source/static/js/controller/invoices.js b/source/static/js/controller/invoices.js index 2dce686..8f7be01 100644 --- a/source/static/js/controller/invoices.js +++ b/source/static/js/controller/invoices.js @@ -987,7 +987,13 @@ function grid_students_found_click(obj){ function search_product_by_key(key){ - webix.ajax().get('/values/productokey', {'key': key}, { + + var filters = { + opt: 'by_key', + key: key, + } + + webix.ajax().get('/products', filters, { error: function(text, data, xhr) { msg_error('Error al consultar') }, @@ -996,12 +1002,27 @@ function search_product_by_key(key){ if (values.ok){ set_product(values) } else { - msg = 'No se encontrĂ³ un producto con la clave: ' + key + msg = 'No se encontrĂ³ un producto con la clave

' + key msg_error(msg) } } }) + //~ webix.ajax().get('/values/productokey', {'key': key}, { + //~ error: function(text, data, xhr) { + //~ msg_error('Error al consultar') + //~ }, + //~ success: function(text, data, xhr){ + //~ var values = data.json() + //~ if (values.ok){ + //~ set_product(values) + //~ } else { + //~ msg = 'No se encontrĂ³ un producto con la clave: ' + key + //~ msg_error(msg) + //~ } + //~ } + //~ }) + } diff --git a/source/static/js/controller/tickets.js b/source/static/js/controller/tickets.js index 8adbec0..b1532da 100644 --- a/source/static/js/controller/tickets.js +++ b/source/static/js/controller/tickets.js @@ -392,7 +392,13 @@ function agregar_producto(values){ function buscar_producto_key(key){ - webix.ajax().get('/values/productokey', {'key': key}, { + + var filters = { + opt: 'by_key', + key: key, + } + + webix.ajax().get('/products', filters, { error: function(text, data, xhr) { msg_error('Error al consultar') }, @@ -406,6 +412,20 @@ function buscar_producto_key(key){ } } }) + //~ webix.ajax().get('/values/productokey', {'key': key}, { + //~ error: function(text, data, xhr) { + //~ msg_error('Error al consultar') + //~ }, + //~ success: function(text, data, xhr){ + //~ var values = data.json() + //~ if (values.ok){ + //~ agregar_producto(values) + //~ } else { + //~ msg = 'No se encontrĂ³ la clave

' + key + //~ msg_error(msg) + //~ } + //~ } + //~ }) }