diff --git a/source/app/controllers/utils.py b/source/app/controllers/utils.py index cf532cf..f72a858 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 + # ~ result['data']['xml'] = cfdi.source + del result['data']['cfdi']['Certificado'] + del result['data']['cfdi']['NoCertificado'] + del result['data']['cfdi']['Sello'] + del result['data']['timbre']['SelloCFD'] + del result['data']['timbre']['SelloSAT'] emisor = result['data']['emisor'] emisor['rfc'] = emisor['Rfc'] diff --git a/source/app/models/main.py b/source/app/models/main.py index 3a2433d..869d7de 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -9370,6 +9370,63 @@ class PartnerProducts(BaseModel): return getattr(cls, method)(cls, filters) +class PartnerInvoices(BaseModel): + partner = ForeignKeyField(Socios) + serie = TextField(default='') + folio = TextField(default='') + cfdi_date = DateTimeField() + cfdi_stamp = DateTimeField() + pay_way = TextField(default='') + pay_conditions = TextField(default='') + pay_method = TextField(default='') + subtotal = DecimalField(default=0.0, max_digits=20, decimal_places=6, + auto_round=True) + discount = DecimalField(default=0.0, max_digits=20, decimal_places=6, + auto_round=True) + currency = TextField(default='MXN') + type_change = DecimalField(default=1.0, max_digits=15, decimal_places=6, + auto_round=True) + total = DecimalField(default=0.0, max_digits=20, decimal_places=6, + auto_round=True) + total_mn = DecimalField(default=0.0, max_digits=20, decimal_places=6, + auto_round=True) + type_cfdi = TextField(default='') + cfdi_use = TextField(default='') + total_retenciones = DecimalField( + max_digits=20, decimal_places=6, auto_round=True, null=True) + total_trasladados = DecimalField( + max_digits=20, decimal_places=6, auto_round=True, null=True) + xml = TextField(default='') + uuid = UUIDField() + status = TextField(default='Guardada') + status_sat = TextField(default='Vigente') + notes = TextField(default='') + balance = DecimalField(default=0.0, max_digits=20, decimal_places=6, + auto_round=True) + pagada = BooleanField(default=False) + cancelada = BooleanField(default=False) + date_cancel = DateTimeField(null=True) + error = TextField(default='') + + class Meta: + order_by = ('-cfdi_date',) + + +class InventoryEntries(BaseModel): + storage = ForeignKeyField(Almacenes, null=True) + invoice = ForeignKeyField(PartnerInvoices, null=True) + product = ForeignKeyField(Productos) + date_add = DateTimeField(default=utils.now) + cant = DecimalField(default=0.0, max_digits=18, decimal_places=2, + auto_round=True) + + class Meta: + order_by = ('-date_add',) + indexes = ( + (('storage', 'product', 'date_add', 'cant'), True), + ) + + @util.run_in_thread def _save_log(user, action, table): data = {'usuario': user, 'accion': action, 'tabla': table} @@ -9586,6 +9643,8 @@ def _crear_tablas(rfc): Productos.impuestos.get_through_model(), Productos.tags.get_through_model(), PartnerProducts, + InventoryEntries, + PartnerInvoices, ] log.info('Creando tablas...') database_proxy.create_tables(tablas, True) @@ -9638,7 +9697,10 @@ def _migrate_tables(rfc=''): CfdiNominaOtroPago, CfdiNominaOtros, CfdiNominaPercepciones, CfdiNominaRelacionados, CfdiNominaSeparacion, CfdiNominaSubcontratos, CfdiNominaTotales, SATNivelesEducativos, Roles, Permisos, - SociosCuentasBanco, SATLeyendasFiscales, PartnerProducts + SociosCuentasBanco, SATLeyendasFiscales, + PartnerProducts, + InventoryEntries, + PartnerInvoices, ] 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 8d14095..8a59fb4 100644 --- a/source/static/js/controller/products.js +++ b/source/static/js/controller/products.js @@ -449,11 +449,36 @@ function cmd_close_products_add_click(id, e, node){ grid.clearAll() } + +function _add_entries_inventory(data){ + var grid = $$('grid_partner_products') + + webix.ajax().sync().post('inventoryentries', data, { + 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(); + if (values.ok) { + $$('multi_invoices').setValue('products_home') + $$('lbl_partner').setValue('') + grid.clearAll() + }else{ + msg_error(values.msg) + } + } + }) + +} + //~ Save add products function cmd_save_products_add_click(id, e, node){ var grid = $$('grid_partner_products') var count = 0 var products = [] + var validate_import = false + var validate_cant = false grid.eachRow(function(row){ var r = grid.getItem(row) @@ -466,6 +491,14 @@ function cmd_save_products_add_click(id, e, node){ p.unit_value = r.unit_value1 p.cant = r.cant1 products.push(p) + + if(p.unit_value < parseFloat(r.unit_value)){ + validate_import = true + } + if(p.cant > r.cant){ + validate_cant = true + } + } }) @@ -475,9 +508,37 @@ function cmd_save_products_add_click(id, e, node){ return } - $$('multi_invoices').setValue('products_home') - $$('lbl_partner').setValue('') - grid.clearAll() + if(validate_import){ + msg = 'El Valor Unitario no puede ser menor al Valor Unitario del proveedor' + msg_error(msg) + return + } + + if(validate_cant){ + msg = 'La Cantidad no puede ser mayor a la Cantidad del proveedor' + msg_error(msg) + return + } + + var data = { + partner: cfg_products['partner'], + products: products, + } + + msg = '¿Estás seguro de ingresar estos productos?

\ + Esta acción no se puede deshacer.' + webix.confirm({ + title: 'Agregar entrada', + ok: 'Si', + cancel: 'No', + type: 'confirm-error', + text: msg, + callback:function(result){ + if(result){ + _add_entries_inventory(data) + } + } + }) } //~ Import from xml @@ -545,8 +606,8 @@ 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 + cfg_products['partner'] = data.emisor + //~ cfg_products['xml'] = data.xml var html = '' html += data.emisor.nombre + ' (' + data.emisor.rfc + ')' @@ -562,14 +623,14 @@ function up_products_from_xml_upload_complete(response){ function get_partner_product(grid, row){ grid.refresh(row.id) + var partner_id = cfg_products['partner'].id var filters = { opt: 'product', - partner_id: cfg_products['partner_id'], - partner_rfc: cfg_products['partner_rfc'], + partner: cfg_products['partner'], partner_key: row.key, } - if(!filters['partner_id']){ + if(!partner_id){ msg = 'El Proveedor no esta dado de alta' msg_ok(msg) return @@ -603,6 +664,7 @@ function grid_partner_products_select(row_id, state){ row['key_sat1'] = row.key_sat row['description1'] = row.description row['cant1'] = row.cant + row['unit_value1'] = 0.0 get_partner_product(grid, row) }else{ row['key_sat1'] = ''