diff --git a/source/app/conf.py.example b/source/app/conf.py.example
index 2cdf172..8610043 100644
--- a/source/app/conf.py.example
+++ b/source/app/conf.py.example
@@ -1,7 +1,8 @@
#!/usr/bin/env python
-DEBUG = True
+DEBUG = False
+MV = True
#~ Establece una ruta accesible para el servidor web
LOG_PATH = '/srv/empresa/logs/empresalibre.log'
diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py
index bc3ac45..eab4209 100644
--- a/source/app/controllers/main.py
+++ b/source/app/controllers/main.py
@@ -4,6 +4,22 @@ import falcon
from middleware import get_template
+class AppEmpresas(object):
+ template = 'empresas.html'
+
+ def __init__(self, db):
+ self._db = db
+
+ @falcon.after(get_template)
+ def on_get(self, req, resp):
+ resp.status = falcon.HTTP_200
+
+ def on_post(self, req, resp):
+ values = req.params
+ req.context['result'] = self._db.empresas(values)
+ resp.status = falcon.HTTP_200
+
+
class AppLogin(object):
template = 'login.html'
@@ -98,6 +114,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/main.py b/source/app/main.py
index 2db8add..e30da00 100644
--- a/source/app/main.py
+++ b/source/app/main.py
@@ -12,7 +12,7 @@ from middleware import (
handle_404
)
from models.db import StorageEngine
-from controllers.main import (
+from controllers.main import (AppEmpresas,
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
@@ -32,6 +32,7 @@ api = falcon.API(middleware=[
api.req_options.auto_parse_form_urlencoded = True
api.add_sink(handle_404, '')
+api.add_route('/empresas', AppEmpresas(db))
api.add_route('/', AppLogin(db))
api.add_route('/logout', AppLogout(db))
api.add_route('/admin', AppAdmin(db))
diff --git a/source/app/middleware.py b/source/app/middleware.py
index fc2d00f..ac2e2d7 100644
--- a/source/app/middleware.py
+++ b/source/app/middleware.py
@@ -3,7 +3,7 @@
import falcon
from controllers import util
from models import main
-from settings import PATH_STATIC
+from settings import MV, PATH_STATIC
def handle_404(req, resp):
@@ -34,7 +34,12 @@ class AuthMiddleware(object):
def process_resource(self, req, resp, resource, params):
id_session = req.cookies.get('beaker.session.id', '')
- if not id_session and req.path != '/':
+ if req.path == '/empresas':
+ if MV:
+ pass
+ else:
+ raise falcon.HTTPTemporaryRedirect('/')
+ elif not id_session and req.path != '/':
raise falcon.HTTPTemporaryRedirect('/')
diff --git a/source/app/models/db.py b/source/app/models/db.py
index 4b8c81d..f7fa23a 100644
--- a/source/app/models/db.py
+++ b/source/app/models/db.py
@@ -14,6 +14,9 @@ class StorageEngine(object):
def get_values(self, table, values=None):
return getattr(self, '_get_{}'.format(table))(values)
+ def _get_main(self, values):
+ return main.config_main()
+
def _get_configtimbrar(self, values):
return main.config_timbrar()
@@ -29,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):
@@ -112,6 +114,9 @@ class StorageEngine(object):
def _get_allunidades(self, values):
return main.SATUnidades.get_()
+ def _get_allformasdepago(self, values):
+ return main.SATFormaPago.get_()
+
def _get_taxupdate(self, values):
return main.SATImpuestos.actualizar(values)
@@ -124,6 +129,9 @@ class StorageEngine(object):
def _get_unidadupdate(self, values):
return main.SATUnidades.actualizar(values)
+ def _get_formasdepagoupdate(self, values):
+ return main.SATFormaPago.actualizar(values)
+
def _get_emisorcuentasbanco(self, values):
return main.CuentasBanco.emisor()
@@ -264,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 427db72..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
@@ -102,6 +103,22 @@ def validar_timbrar():
return {'ok': True, 'msg': msg}
+def config_main():
+ try:
+ obj = Emisor.select()[0]
+ except IndexError:
+ obj = None
+
+ data = {
+ 'empresa': 'Empresa Libre',
+ }
+ if not obj is None:
+ titulo = 'Empresa Libre - {}'
+ data['empresa'] = titulo.format(obj.nombre)
+
+ return data
+
+
def config_timbrar():
try:
obj = Emisor.select()[0]
@@ -695,6 +712,11 @@ class SATFormaPago(BaseModel):
def __str__(self):
return 'Forma de pago: ({}) {}'.format(self.key, self.name)
+ @classmethod
+ def get_(self):
+ rows = SATFormaPago.select().dicts()
+ return tuple(rows)
+
@classmethod
def get_by_key(cls, key):
return SATFormaPago.get(SATFormaPago.key==key)
@@ -711,6 +733,27 @@ class SATFormaPago(BaseModel):
)
return tuple(rows)
+ @classmethod
+ def actualizar(self, values):
+ id = int(values['id'])
+ if values['field'] == 'activo':
+ v = {'0': False, '1': True}
+ q = (SATFormaPago
+ .update(**{'activo': v[values['value']]})
+ .where(SATFormaPago.id==id))
+ result = bool(q.execute())
+ elif values['field'] == 'default':
+ q = SATFormaPago.update(**{'default': False})
+ q.execute()
+
+ v = {'false': False, 'true': True}
+ q = (SATFormaPago
+ .update(**{'default': v[values['value']]})
+ .where(SATFormaPago.id==id))
+ result = bool(q.execute())
+
+ return {'ok': result}
+
class SATAduanas(BaseModel):
key = TextField(unique=True, index=True)
@@ -1227,6 +1270,7 @@ class MovimientosBanco(BaseModel):
with database_proxy.transaction():
obj.cancelado = True
obj.save()
+ FacturasPagos.cancelar(obj)
obj = cls._movimiento_anterior(cls, obj.cuenta, obj.fecha)
cls._actualizar_saldos(cls, obj)
@@ -1970,6 +2014,9 @@ class Facturas(BaseModel):
if invoice.tipo_comprobante == 'T':
return
+ if invoice.donativo and invoice.forma_pago == '12':
+ return
+
importe = invoice.total_mn
if invoice.tipo_comprobante == 'E':
importe *= -1
@@ -2511,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)
@@ -3175,17 +3222,90 @@ class FacturasPagos(BaseModel):
auto_round=True)
saldo = DecimalField(default=0.0, max_digits=18, decimal_places=6,
auto_round=True)
+ # ~ cancelado = BooleanField(default=False)
class Meta:
order_by = ('factura',)
indexes = (
- (('factura', 'numero'), True),
+ (('movimiento', 'factura', 'numero'), True),
)
+ def _movimiento_anterior(self, mov, id):
+ query = (FacturasPagos
+ .select()
+ .where(FacturasPagos.factura==id)
+ )
+ if len(query):
+ return query[-1], len(query) + 1
+ else:
+ return None, 1
+
+ def _actualizar_saldo_cliente(self, cliente, importe):
+ q = (Socios
+ .update(saldo_cliente=Socios.saldo_cliente + importe)
+ .where(Socios.id==cliente.id)
+ )
+ return bool(q.execute())
+
+ def _actualizar_saldos(self, factura, saldo_anterior):
+ query = (FacturasPagos
+ .select()
+ .where(FacturasPagos.factura==factura)
+ )
+ saldo = saldo_anterior
+ for i, row in enumerate(query):
+ if not saldo_anterior:
+ saldo_anterior = row.saldo_anterior
+ row.numero = i + 1
+ row.saldo_anterior = saldo_anterior
+ row.saldo = saldo_anterior - row.importe
+ row.save()
+ saldo_anterior = row.saldo
+ saldo = row.saldo
+
+ factura.saldo = saldo
+ factura.pagada = False
+ factura.save()
+ return
+
+ @classmethod
+ def cancelar(cls, mov):
+ query = (FacturasPagos
+ .select()
+ .where(FacturasPagos.movimiento==mov)
+ )
+ for row in query:
+ cls._actualizar_saldo_cliente(cls, row.factura.cliente, row.importe)
+ factura = row.factura
+ saldo_anterior = 0
+ if row.numero == 1:
+ saldo_anterior = row.saldo_anterior
+ row.delete_instance()
+ cls._actualizar_saldos(cls, factura, saldo_anterior)
+ return
+
@classmethod
def add(cls, mov, ids):
- print (mov)
- print (ids)
+ for i, importe in ids.items():
+ fac = Facturas.get(Facturas.id==int(i))
+ mov_ant, numero = cls._movimiento_anterior(cls, mov, fac)
+ nuevo = {
+ 'movimiento': mov,
+ 'factura': fac,
+ 'numero': numero,
+ 'importe': importe,
+ }
+ if mov_ant is None:
+ nuevo['saldo_anterior'] = float(fac.saldo)
+ else:
+ nuevo['saldo_anterior'] = float(mov_ant.saldo)
+ nuevo['saldo'] = nuevo['saldo_anterior'] - importe
+ FacturasPagos.create(**nuevo)
+ fac.saldo = nuevo['saldo']
+ if nuevo['saldo'] == 0:
+ fac.pagada = True
+ fac.save()
+ cls._actualizar_saldo_cliente(cls, fac.cliente, importe * -1)
return
@@ -3634,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...')
@@ -3756,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..f11028c 100644
--- a/source/app/settings.py
+++ b/source/app/settings.py
@@ -7,7 +7,7 @@ from mako.lookup import TemplateLookup
from logbook import Logger, StreamHandler, RotatingFileHandler
logbook.set_datetime_format('local')
-from conf import DEBUG, LOG_PATH
+from conf import DEBUG, MV, LOG_PATH
DEBUG = DEBUG
@@ -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 4330737..fb08555 100644
--- a/source/static/js/controller/admin.js
+++ b/source/static/js/controller/admin.js
@@ -32,6 +32,7 @@ var controllers = {
$$('grid_admin_monedas').attachEvent('onCheck', grid_admin_monedas_on_check)
$$('grid_admin_bancos').attachEvent('onCheck', grid_admin_bancos_on_check)
$$('grid_admin_unidades').attachEvent('onCheck', grid_admin_unidades_on_check)
+ $$('grid_admin_formasdepago').attachEvent('onCheck', grid_admin_formasdepago_on_check)
$$('grid_unidad_found').attachEvent('onValueSuggest', grid_unidad_found_click)
$$('cmd_agregar_impuesto').attachEvent('onItemClick', cmd_agregar_impuesto_click)
//~ Opciones
@@ -43,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)
}
}
@@ -259,6 +263,7 @@ function get_admin_impuestos(){
$$('grid_admin_taxes').clearAll()
$$('grid_admin_taxes').parse(values, 'json')
})
+ $$('tab_sat').setValue('Impuestos')
}
@@ -289,6 +294,15 @@ function get_admin_unidades(){
}
+function get_admin_formasdepago(){
+ webix.ajax().sync().get('/values/allformasdepago', function(text, data){
+ var values = data.json()
+ $$('grid_admin_formasdepago').clearAll()
+ $$('grid_admin_formasdepago').parse(values, 'json')
+ })
+}
+
+
function get_config_values(opt){
if(opt == undefined){
return
@@ -906,6 +920,8 @@ function tab_sat_change(nv, ov){
get_admin_bancos()
}else if(nv == 'Unidades'){
get_admin_unidades()
+ }else if(nv == 'Formas de Pago'){
+ get_admin_formasdepago()
}
}
@@ -974,6 +990,22 @@ function grid_admin_unidades_on_check(row, column, state){
}
+function grid_admin_formasdepago_on_check(row, column, state){
+
+ var values = {
+ id: row,
+ field: column,
+ value: state,
+ }
+ webix.ajax().get('/values/formasdepagoupdate', values, {
+ error: function(text, data, xhr) {
+ },
+ success: function(text, data, xhr) {
+ }
+ })
+}
+
+
function emisor_cuenta_saldo_inicial_change(new_value, old_value){
if(!isFinite(new_value)){
this.config.value = old_value
@@ -1291,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/controller/invoices.js b/source/static/js/controller/invoices.js
index cd96780..4c19d51 100644
--- a/source/static/js/controller/invoices.js
+++ b/source/static/js/controller/invoices.js
@@ -4,6 +4,7 @@ var msg = ''
var result = false
var tipo_relacion = ''
var anticipo = false
+var donativo = false
function get_condicion_pago(){
@@ -498,7 +499,7 @@ function guardar_y_timbrar(values){
data['relacionados'] = ids
data['tipo_relacion'] = tipo_relacion
data['anticipo'] = anticipo
- data['donativo'] = $$('chk_cfdi_donativo').getValue()
+ data['donativo'] = donativo
var usar_ine = $$('chk_cfdi_usar_ine').getValue()
if(usar_ine){
@@ -518,6 +519,7 @@ function guardar_y_timbrar(values){
tipo_relacion = ''
anticipo = false
$$('chk_cfdi_anticipo').setValue(0)
+ $$('chk_cfdi_donativo').setValue(0)
$$('chk_cfdi_usar_ine').setValue(0)
$$('form_invoice').setValues({id_partner: 0, lbl_partner: 'Ninguno'})
@@ -545,7 +547,14 @@ function cmd_timbrar_click(id, e, node){
msg += 'La factura tiene CFDI relacionados
'
}
if(anticipo){
- msg += 'La factura es Anticipo
'
+ msg += 'La factura es un Anticipo
'
+ }
+ if(donativo){
+ msg += 'La factura es un Donativo'
+ if($$('lst_forma_pago').getValue()=='12'){
+ msg += ' en Especie'
+ }
+ msg += '
'
}
usar_ine = $$('chk_cfdi_usar_ine').getValue()
if(usar_ine){
diff --git a/source/static/js/controller/main.js b/source/static/js/controller/main.js
index d74004a..6fbef20 100644
--- a/source/static/js/controller/main.js
+++ b/source/static/js/controller/main.js
@@ -6,6 +6,10 @@ function configuracion_inicial(){
var values = data.json()
$$('cmd_ir_al_admin').show(values)
})
+ webix.ajax().get('/values/main', function(text, data){
+ var values = data.json()
+ $$('lbl_title_main').setValue(values.empresa)
+ })
}
diff --git a/source/static/js/ui/admin.js b/source/static/js/ui/admin.js
index 1178aaf..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'},
@@ -515,7 +542,7 @@ var grid_admin_taxes = {
view: 'datatable',
id: 'grid_admin_taxes',
select: 'cell',
- multiselect: true,
+ //~ multiselect: true,
adjust: true,
autoheight: true,
autowidth: true,
@@ -528,7 +555,7 @@ var grid_admin_monedas = {
view: 'datatable',
id: 'grid_admin_monedas',
select: 'cell',
- multiselect: true,
+ //~ multiselect: true,
adjust: true,
autoheight: true,
autowidth: true,
@@ -541,7 +568,7 @@ var grid_admin_bancos = {
view: 'datatable',
id: 'grid_admin_bancos',
select: 'cell',
- multiselect: true,
+ //~ multiselect: true,
adjust: true,
autowidth: true,
headermenu: true,
@@ -554,7 +581,7 @@ var grid_admin_unidades = {
view: 'datatable',
id: 'grid_admin_unidades',
select: 'cell',
- multiselect: true,
+ //~ multiselect: true,
adjust: true,
autowidth: true,
autoheight: true,
@@ -564,6 +591,31 @@ var grid_admin_unidades = {
}
+var grid_admin_formasdepago_cols = [
+ {id: 'id', header: 'ID', hidden: true},
+ {id: 'key', header: 'Clave'},
+ {id: 'name', header: 'Nombre', adjust: 'data'},
+ {id: 'activo', header: 'Activa', template: '{common.checkbox()}',
+ editor: 'checkbox'},
+ {id: 'default', header: 'Predeterminada', template: '{common.radio()}',
+ adjust: 'header'},
+]
+
+
+var grid_admin_formasdepago = {
+ view: 'datatable',
+ id: 'grid_admin_formasdepago',
+ select: 'cell',
+ //~ multiselect: true,
+ adjust: true,
+ autowidth: true,
+ //~ autoheight: true,
+ headermenu: true,
+ footer: true,
+ columns: grid_admin_formasdepago_cols,
+}
+
+
var admin_sat_impuestos = {cols: [{maxWidth: 15},
{view: 'richselect', id: 'lst_admin_impuestos', label: 'Impuesto', options:
['ISR', 'IVA', 'IEPS', 'ISH', 'INSPECCION DE OBRA', 'ICIC', 'CEDULAR'],
@@ -653,22 +705,33 @@ var sat_unidades = [
]
+var msg_formasdepago = 'Activar las formas de pago.'
+var sat_formasdepago = [
+ {maxHeight: 20},
+ {cols: [{maxWidth: 15}, {view: 'label', label: msg_formasdepago}, {}]},
+ {maxHeight: 20},
+ {cols: [{maxWidth: 15}, grid_admin_formasdepago, {}]},
+ {maxHeight: 20},
+]
+
+
var tab_sat = {
view: 'tabview',
id: 'tab_sat',
multiview: true,
- tabbar: {options: [
- 'Impuestos',
- 'Monedas',
- 'Bancos',
- 'Unidades'
- ]},
+ //~ tabbar: {options: [
+ //~ 'Impuestos',
+ //~ 'Monedas',
+ //~ 'Bancos',
+ //~ 'Unidades'
+ //~ ]},
animate: true,
cells: [
{id: 'Impuestos', rows: sat_impuestos},
{id: 'Monedas', rows: sat_monedas},
{id: 'Bancos', rows: sat_bancos},
{id: 'Unidades', rows: sat_unidades},
+ {id: 'Formas de Pago', rows: sat_formasdepago},
],
}
@@ -732,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,
@@ -746,6 +819,7 @@ var multi_admin = {
app_correo,
app_sat,
app_options,
+ app_utilidades,
],
}
diff --git a/source/static/js/ui/empresas.js b/source/static/js/ui/empresas.js
new file mode 100644
index 0000000..750febc
--- /dev/null
+++ b/source/static/js/ui/empresas.js
@@ -0,0 +1,35 @@
+
+var msg_rfc = 'El RFC es requerido'
+
+var form_controls_empresa = [
+ {view: 'text', label: 'RFC', id: 'txt_alta_rfc', name: 'alta_rfc',
+ labelPosition: 'top', required: true, invalidMessage: msg_rfc},
+ {margin: 10, cols:[{}, {view: 'button', value: 'Agregar RFC',
+ click: 'validate_nuevo_rfc', hotkey: 'enter'}, {}]}
+]
+
+
+var msg_header = 'Bienvenido a Empresa Libre'
+
+var ui_empresas = {
+ rows: [
+ {maxHeight: 50},
+ {view: 'template', template: msg_header, maxHeight: 50, css: 'login_header'},
+ {maxHeight: 50},
+ {cols: [{}, {type: 'space', padding: 5,
+ rows: [
+ {view: 'template', template: 'Alta de nuevo emisor', type: 'header'},
+ {
+ container: 'form_empresas',
+ view: 'form',
+ id: 'form_empresas',
+ width: 400,
+ elements: form_controls_empresa,
+ rules:{
+ alta_rfc:function(value){ return value.trim() != '';},
+ }
+ },
+ ]}, {}, ]
+ },
+ ]
+}
diff --git a/source/static/js/ui/main.js b/source/static/js/ui/main.js
index 5034328..d004c18 100644
--- a/source/static/js/ui/main.js
+++ b/source/static/js/ui/main.js
@@ -63,7 +63,7 @@ var ui_main = {
$$('$sidebar1').toggle()
}
},
- {view: 'label', label: 'Empresa Libre'},
+ {view: 'label', id: 'lbl_title_main', label: 'Empresa Libre'},
{},
menu_user,
{view: 'button', type: 'icon', width: 45, css: 'app_button',
diff --git a/source/static/js/ui/partners.js b/source/static/js/ui/partners.js
index 3c399c3..4b763fe 100644
--- a/source/static/js/ui/partners.js
+++ b/source/static/js/ui/partners.js
@@ -14,7 +14,7 @@ var grid_partners_cols = [
{id: 'index', header:'#', css: 'right',
footer: {content: 'rowCount', colspan: 2, css: 'right'}},
{id: 'id', header: 'Clave', sort: 'int', css: 'right'},
- {id: 'rfc', header: ['RFC', {content: 'textFilter'}],
+ {id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust: 'data',
sort: 'string', footer: {text: 'Clientes y Proveedores', colspan: 2}},
{id: 'nombre', header: ['Razón Social', {content: 'textFilter'}],
fillspace:true, sort: 'string'},
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/templates/empresas.html b/source/templates/empresas.html
new file mode 100644
index 0000000..a557531
--- /dev/null
+++ b/source/templates/empresas.html
@@ -0,0 +1,39 @@
+<%inherit file="base.html"/>
+
+<%block name="media">
+
+%block>
+
+<%block name="content">
+
+