diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py
index bc3ac45..ab7323a 100644
--- a/source/app/controllers/main.py
+++ b/source/app/controllers/main.py
@@ -98,6 +98,8 @@ class AppValues(object):
req.context['result'] = self._db.add_unidad(values)
elif table == 'addimpuesto':
req.context['result'] = self._db.add_impuesto(values)
+ elif table == 'bdfl':
+ req.context['result'] = self._db.importar_bdfl()
else:
req.context['result'] = self._db.validate_cert(values, session)
else:
diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py
index a8997a0..3512985 100644
--- a/source/app/controllers/util.py
+++ b/source/app/controllers/util.py
@@ -1079,24 +1079,22 @@ def _totales(doc, cfdi, version):
title = 'Retención {} {}'.format(tmp['impuesto'], '')
retenciones.append((title, float(tmp['importe'])))
- #~ com = xml.find('%sComplemento' % PRE)
- #~ if com is not None:
- #~ otros = com.find('%sImpuestosLocales' % IMP_LOCAL)
- #~ if otros is not None:
- #~ for otro in list(otros):
- #~ if otro.tag == '%sRetencionesLocales' % IMP_LOCAL:
- #~ name = 'ImpLocRetenido'
- #~ tasa = 'TasadeRetencion'
- #~ else:
- #~ name = 'ImpLocTrasladado'
- #~ tasa = 'TasadeTraslado'
- #~ title = '%s %s %%' % (otro.attrib[name], otro.attrib[tasa])
- #~ value = otro.attrib['Importe']
- #~ self._copy_cell(cell_title)
- #~ self._copy_cell(cell_value)
- #~ cell_title = self._set_cell(v=title, cell=cell_title)
- #~ cell_value = self._set_cell(v=value, cell=cell_value, value=True)
- #~ cell_value.CellStyle = currency
+ node = doc.find('{}Complemento/{}ImpuestosLocales'.format(
+ PRE[version], PRE['LOCALES']))
+ if node is not None:
+ for otro in list(node):
+ if otro.tag == '{}RetencionesLocales'.format(PRE['LOCALES']):
+ tipo = 'Retención '
+ name = 'ImpLocRetenido'
+ tasa = 'TasadeRetencion'
+ else:
+ tipo = 'Traslado '
+ name = 'ImpLocTrasladado'
+ tasa = 'TasadeTraslado'
+ title = '{} {} {}%'.format(
+ tipo, otro.attrib[name], otro.attrib[tasa])
+ importe = float(otro.attrib['Importe'])
+ taxlocales.append((title, importe))
data['traslados'] = traslados
data['retenciones'] = retenciones
@@ -1271,6 +1269,15 @@ def upload_file(rfc, opt, file_obj):
name = '{}_3.3_donativo.ods'.format(rfc.lower())
path = _join(PATH_MEDIA, 'templates', name)
+ elif opt == 'bdfl':
+ tmp = file_obj.filename.split('.')
+ ext = tmp[-1].lower()
+ if ext != 'sqlite':
+ msg = 'Extensión de archivo incorrecta, selecciona un archivo SQLite'
+ return {'status': 'server', 'name': msg, 'ok': False}
+
+ name = '{}.sqlite'.format(rfc.lower())
+ path = _join('/tmp', name)
if save_file(path, file_obj.file.read()):
return {'status': 'server', 'name': file_obj.filename, 'ok': True}
@@ -1371,9 +1378,10 @@ class ImportFacturaLibre(object):
self._error = 'No se encontró al emisor: {}'.format(self._rfc)
return False
- if obj['rfc'] != self._rfc:
- self._error = 'Los datos no corresponden al RFC: {}'.format(self._rfc)
- return False
+ if not DEBUG:
+ if obj['rfc'] != self._rfc:
+ self._error = 'Los datos no corresponden al RFC: {}'.format(self._rfc)
+ return False
return True
diff --git a/source/app/models/db.py b/source/app/models/db.py
index 90d1f4d..f7fa23a 100644
--- a/source/app/models/db.py
+++ b/source/app/models/db.py
@@ -32,7 +32,6 @@ class StorageEngine(object):
def upload_file(self, session, table, file_obj):
if not 'rfc' in session:
return {'status': 'error'}
-
return main.upload_file(session['rfc'], table, file_obj)
def get_config(self, values):
@@ -273,3 +272,5 @@ class StorageEngine(object):
def get_movimientosbanco(self, values):
return main.MovimientosBanco.get_(values)
+ def importar_bdfl(self):
+ return main.importar_bdfl()
diff --git a/source/app/models/main.py b/source/app/models/main.py
index e804340..80503f2 100644
--- a/source/app/models/main.py
+++ b/source/app/models/main.py
@@ -64,7 +64,8 @@ def desconectar():
def upload_file(rfc, opt, file_obj):
result = util.upload_file(rfc, opt, file_obj)
if result['ok']:
- Configuracion.add({opt: file_obj.filename})
+ if opt != 'bdfl':
+ Configuracion.add({opt: file_obj.filename})
return result
@@ -2557,11 +2558,11 @@ class Facturas(BaseModel):
impuestos['traslados'] = traslados
impuestos['retenciones'] = retenciones
- impuestos['total_locales_trasladados'] = ''
+ impuestos['total_locales_trasladados'] = '0.00'
if total_locales_trasladados:
impuestos['total_locales_trasladados'] = \
FORMAT.format(total_locales_trasladados)
- impuestos['total_locales_retenciones'] = ''
+ impuestos['total_locales_retenciones'] = '0.00'
if total_locales_retenciones:
impuestos['total_locales_retenciones'] = \
FORMAT.format(total_locales_retenciones)
@@ -3753,7 +3754,6 @@ def _importar_facturas(rows):
}
FacturasImpuestos.create(**new)
except IntegrityError as e:
- #~ print (e)
msg = '\tFactura: id: {}'.format(row['serie'] + str(row['folio']))
log.error(msg)
log.info('\tFacturas importadas...')
@@ -3875,6 +3875,35 @@ def _generar_archivo_productos(archivo):
return
+def importar_bdfl():
+ try:
+ emisor = Emisor.select()[0]
+ except IndexError:
+ msg = 'Configura primero al emisor'
+ return {'ok': False, 'msg': msg}
+
+ name = '{}.sqlite'.format(emisor.rfc.lower())
+ path = util._join('/tmp', name)
+
+ log.info('Importando datos...')
+ app = util.ImportFacturaLibre(path, emisor.rfc)
+ if not app.is_connect:
+ msg = app._error
+ log.error('\t{}'.format(msg))
+ return {'ok': False, 'msg': msg}
+
+ data = app.import_data()
+
+ _importar_socios(data['Socios'])
+ _importar_facturas(data['Facturas'])
+ _importar_categorias(data['Categorias'])
+
+ msg = 'Importación terminada...'
+ log.info(msg)
+
+ return {'ok': True, 'msg': msg}
+
+
def _importar_factura_libre(archivo):
rfc = input('Introduce el RFC: ').strip().upper()
if not rfc:
diff --git a/source/app/settings.py b/source/app/settings.py
index 58007ca..89029af 100644
--- a/source/app/settings.py
+++ b/source/app/settings.py
@@ -86,6 +86,7 @@ PRE = {
'TIMBRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}',
'DONATARIA': '{http://www.sat.gob.mx/donat}',
'INE': '{http://www.sat.gob.mx/ine}',
+ 'LOCALES': '{http://www.sat.gob.mx/implocal}',
'NOMINA': {
'1.1': '{http://www.sat.gob.mx/nomina}',
'1.2': '{http://www.sat.gob.mx/nomina12}',
diff --git a/source/static/js/controller/admin.js b/source/static/js/controller/admin.js
index e1d850c..fb08555 100644
--- a/source/static/js/controller/admin.js
+++ b/source/static/js/controller/admin.js
@@ -44,6 +44,9 @@ var controllers = {
$$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click)
$$('chk_config_anticipo').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_ine').attachEvent('onItemClick', chk_config_item_click)
+
+ $$('cmd_subir_bdfl').attachEvent('onItemClick', cmd_subir_bdfl_click)
+ $$('up_bdfl').attachEvent('onUploadComplete', up_bdfl_upload_complete)
}
}
@@ -1320,3 +1323,81 @@ function chk_config_item_click(id, e){
})
}
+
+
+function cmd_subir_bdfl_click(){
+ var form = $$('form_upload_bdfl')
+
+ if (!form.validate()){
+ msg = 'Valores inválidos'
+ msg_error(msg)
+ return
+ }
+
+ var values = form.getValues()
+
+ if($$('lst_bdfl').count() < 1){
+ msg = 'Selecciona la base de datos SQLite de Factura Libre'
+ msg_error(msg)
+ return
+ }
+
+ if($$('lst_bdfl').count() > 1){
+ msg = 'Selecciona solo un archivo'
+ msg_error(msg)
+ return
+ }
+
+ var bdfl = $$('up_bdfl').files.getItem($$('up_bdfl').files.getFirstId())
+
+ var ext = []
+ if(bdfl.type.toLowerCase() != 'sqlite'){
+ msg = 'Archivo inválido, se requiere un archivo SQLITE'
+ msg_error(msg)
+ return
+ }
+
+ msg = '¿Estás seguro de subir este archivo?'
+ webix.confirm({
+ title: 'Base de datos de Factura Libre',
+ ok: 'Si',
+ cancel: 'No',
+ type: 'confirm-error',
+ text: msg,
+ callback:function(result){
+ if(result){
+ $$('up_bdfl').send()
+ }
+ }
+ })
+}
+
+
+function up_bdfl_upload_complete(response){
+ if(response.status != 'server'){
+ msg = 'Ocurrio un error al subir los archivos'
+ msg_error(msg)
+ return
+ }
+
+ msg = 'Archivo subido correctamente'
+ msg_ok(msg)
+
+ $$('form_upload_bdfl').setValues({})
+ $$('up_bdfl').files.data.clearAll()
+
+ //~ webix.ajax().post('/values/bdfl', {}, {
+ //~ 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){
+ //~ msg_ok(values.msg)
+ //~ }else{
+ //~ msg_error(values.msg)
+ //~ }
+ //~ }
+ //~ })
+}
\ No newline at end of file
diff --git a/source/static/js/ui/admin.js b/source/static/js/ui/admin.js
index 0ba0be3..be017fb 100644
--- a/source/static/js/ui/admin.js
+++ b/source/static/js/ui/admin.js
@@ -467,6 +467,33 @@ var tab_options = {
}
+var utilidades_archivos = [
+ {maxHeight: 15},
+ {template: 'Cargar Base de Datos de Factura Libre', type: 'section'},
+ {view: 'form', id: 'form_upload_bdfl', rows: [
+ {cols: [{},
+ {view: 'uploader', id: 'up_bdfl', autosend: false, link: 'lst_bdfl',
+ value: 'Seleccionar base de datos', upload: '/files/bdfl'}, {}]},
+ {cols: [{},
+ {view: 'list', id: 'lst_bdfl', name: 'bdfl',
+ type: 'uploader', autoheight: true, borderless: true}, {}]},
+ {cols: [{}, {view: 'button', id: 'cmd_subir_bdfl',
+ label: 'Subir base de datos de Factura Libre'}, {}]},
+ ]},
+{}]
+
+
+var tab_utilidades = {
+ view: 'tabview',
+ id: 'tab_utilidades',
+ multiview: true,
+ animate: true,
+ cells: [
+ {id: 'Utilidades', rows: utilidades_archivos},
+ ],
+}
+
+
var grid_admin_taxes_cols = [
{id: 'id', header: 'ID', hidden: true},
{id: 'delete', header: '', width: 30, css: 'delete'},
@@ -768,6 +795,16 @@ var app_options = {
}
+var app_utilidades = {
+ id: 'app_utilidades',
+ rows:[
+ {view: 'template', id: 'th_utilidades', type: 'header',
+ template: 'Herramientas'},
+ tab_utilidades,
+ ],
+}
+
+
var multi_admin = {
id: 'multi_admin',
animate: true,
@@ -782,6 +819,7 @@ var multi_admin = {
app_correo,
app_sat,
app_options,
+ app_utilidades,
],
}
diff --git a/source/templates/base.html b/source/templates/base.html
index 253cdcc..dd5df6e 100644
--- a/source/templates/base.html
+++ b/source/templates/base.html
@@ -7,7 +7,7 @@
-
+
<%block name="media"/>
diff --git a/source/xslt/donat11.xslt b/source/xslt/donat11.xslt
index 1f0d7a4..24d4363 100644
--- a/source/xslt/donat11.xslt
+++ b/source/xslt/donat11.xslt
@@ -1,13 +1,13 @@
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/source/xslt/implocal.xslt b/source/xslt/implocal.xslt
index dd95023..80b8d23 100644
--- a/source/xslt/implocal.xslt
+++ b/source/xslt/implocal.xslt
@@ -1,39 +1,39 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/xslt/ine11.xslt b/source/xslt/ine11.xslt
index 06def84..05c1e56 100644
--- a/source/xslt/ine11.xslt
+++ b/source/xslt/ine11.xslt
@@ -1,5 +1,5 @@
-
+