Merge branch 'develop'

Versión 1.0.0
This commit is contained in:
Mauricio Baeza 2017-11-30 00:41:03 -06:00
commit e9fa41a439
20 changed files with 560 additions and 97 deletions

View File

@ -1,7 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
DEBUG = True DEBUG = False
MV = True
#~ Establece una ruta accesible para el servidor web #~ Establece una ruta accesible para el servidor web
LOG_PATH = '/srv/empresa/logs/empresalibre.log' LOG_PATH = '/srv/empresa/logs/empresalibre.log'

View File

@ -4,6 +4,22 @@ import falcon
from middleware import get_template 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): class AppLogin(object):
template = 'login.html' template = 'login.html'
@ -98,6 +114,8 @@ class AppValues(object):
req.context['result'] = self._db.add_unidad(values) req.context['result'] = self._db.add_unidad(values)
elif table == 'addimpuesto': elif table == 'addimpuesto':
req.context['result'] = self._db.add_impuesto(values) req.context['result'] = self._db.add_impuesto(values)
elif table == 'bdfl':
req.context['result'] = self._db.importar_bdfl()
else: else:
req.context['result'] = self._db.validate_cert(values, session) req.context['result'] = self._db.validate_cert(values, session)
else: else:

View File

@ -1079,24 +1079,22 @@ def _totales(doc, cfdi, version):
title = 'Retención {} {}'.format(tmp['impuesto'], '') title = 'Retención {} {}'.format(tmp['impuesto'], '')
retenciones.append((title, float(tmp['importe']))) retenciones.append((title, float(tmp['importe'])))
#~ com = xml.find('%sComplemento' % PRE) node = doc.find('{}Complemento/{}ImpuestosLocales'.format(
#~ if com is not None: PRE[version], PRE['LOCALES']))
#~ otros = com.find('%sImpuestosLocales' % IMP_LOCAL) if node is not None:
#~ if otros is not None: for otro in list(node):
#~ for otro in list(otros): if otro.tag == '{}RetencionesLocales'.format(PRE['LOCALES']):
#~ if otro.tag == '%sRetencionesLocales' % IMP_LOCAL: tipo = 'Retención '
#~ name = 'ImpLocRetenido' name = 'ImpLocRetenido'
#~ tasa = 'TasadeRetencion' tasa = 'TasadeRetencion'
#~ else: else:
#~ name = 'ImpLocTrasladado' tipo = 'Traslado '
#~ tasa = 'TasadeTraslado' name = 'ImpLocTrasladado'
#~ title = '%s %s %%' % (otro.attrib[name], otro.attrib[tasa]) tasa = 'TasadeTraslado'
#~ value = otro.attrib['Importe'] title = '{} {} {}%'.format(
#~ self._copy_cell(cell_title) tipo, otro.attrib[name], otro.attrib[tasa])
#~ self._copy_cell(cell_value) importe = float(otro.attrib['Importe'])
#~ cell_title = self._set_cell(v=title, cell=cell_title) taxlocales.append((title, importe))
#~ cell_value = self._set_cell(v=value, cell=cell_value, value=True)
#~ cell_value.CellStyle = currency
data['traslados'] = traslados data['traslados'] = traslados
data['retenciones'] = retenciones data['retenciones'] = retenciones
@ -1271,6 +1269,15 @@ def upload_file(rfc, opt, file_obj):
name = '{}_3.3_donativo.ods'.format(rfc.lower()) name = '{}_3.3_donativo.ods'.format(rfc.lower())
path = _join(PATH_MEDIA, 'templates', name) 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()): if save_file(path, file_obj.file.read()):
return {'status': 'server', 'name': file_obj.filename, 'ok': True} 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) self._error = 'No se encontró al emisor: {}'.format(self._rfc)
return False return False
if obj['rfc'] != self._rfc: if not DEBUG:
self._error = 'Los datos no corresponden al RFC: {}'.format(self._rfc) if obj['rfc'] != self._rfc:
return False self._error = 'Los datos no corresponden al RFC: {}'.format(self._rfc)
return False
return True return True

View File

@ -12,7 +12,7 @@ from middleware import (
handle_404 handle_404
) )
from models.db import StorageEngine from models.db import StorageEngine
from controllers.main import ( from controllers.main import (AppEmpresas,
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig, AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios, AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco, AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
@ -32,6 +32,7 @@ api = falcon.API(middleware=[
api.req_options.auto_parse_form_urlencoded = True api.req_options.auto_parse_form_urlencoded = True
api.add_sink(handle_404, '') api.add_sink(handle_404, '')
api.add_route('/empresas', AppEmpresas(db))
api.add_route('/', AppLogin(db)) api.add_route('/', AppLogin(db))
api.add_route('/logout', AppLogout(db)) api.add_route('/logout', AppLogout(db))
api.add_route('/admin', AppAdmin(db)) api.add_route('/admin', AppAdmin(db))

View File

@ -3,7 +3,7 @@
import falcon import falcon
from controllers import util from controllers import util
from models import main from models import main
from settings import PATH_STATIC from settings import MV, PATH_STATIC
def handle_404(req, resp): def handle_404(req, resp):
@ -34,7 +34,12 @@ class AuthMiddleware(object):
def process_resource(self, req, resp, resource, params): def process_resource(self, req, resp, resource, params):
id_session = req.cookies.get('beaker.session.id', '') 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('/') raise falcon.HTTPTemporaryRedirect('/')

View File

@ -14,6 +14,9 @@ class StorageEngine(object):
def get_values(self, table, values=None): def get_values(self, table, values=None):
return getattr(self, '_get_{}'.format(table))(values) return getattr(self, '_get_{}'.format(table))(values)
def _get_main(self, values):
return main.config_main()
def _get_configtimbrar(self, values): def _get_configtimbrar(self, values):
return main.config_timbrar() return main.config_timbrar()
@ -29,7 +32,6 @@ class StorageEngine(object):
def upload_file(self, session, table, file_obj): def upload_file(self, session, table, file_obj):
if not 'rfc' in session: if not 'rfc' in session:
return {'status': 'error'} return {'status': 'error'}
return main.upload_file(session['rfc'], table, file_obj) return main.upload_file(session['rfc'], table, file_obj)
def get_config(self, values): def get_config(self, values):
@ -112,6 +114,9 @@ class StorageEngine(object):
def _get_allunidades(self, values): def _get_allunidades(self, values):
return main.SATUnidades.get_() return main.SATUnidades.get_()
def _get_allformasdepago(self, values):
return main.SATFormaPago.get_()
def _get_taxupdate(self, values): def _get_taxupdate(self, values):
return main.SATImpuestos.actualizar(values) return main.SATImpuestos.actualizar(values)
@ -124,6 +129,9 @@ class StorageEngine(object):
def _get_unidadupdate(self, values): def _get_unidadupdate(self, values):
return main.SATUnidades.actualizar(values) return main.SATUnidades.actualizar(values)
def _get_formasdepagoupdate(self, values):
return main.SATFormaPago.actualizar(values)
def _get_emisorcuentasbanco(self, values): def _get_emisorcuentasbanco(self, values):
return main.CuentasBanco.emisor() return main.CuentasBanco.emisor()
@ -264,3 +272,5 @@ class StorageEngine(object):
def get_movimientosbanco(self, values): def get_movimientosbanco(self, values):
return main.MovimientosBanco.get_(values) return main.MovimientosBanco.get_(values)
def importar_bdfl(self):
return main.importar_bdfl()

View File

@ -64,7 +64,8 @@ def desconectar():
def upload_file(rfc, opt, file_obj): def upload_file(rfc, opt, file_obj):
result = util.upload_file(rfc, opt, file_obj) result = util.upload_file(rfc, opt, file_obj)
if result['ok']: if result['ok']:
Configuracion.add({opt: file_obj.filename}) if opt != 'bdfl':
Configuracion.add({opt: file_obj.filename})
return result return result
@ -102,6 +103,22 @@ def validar_timbrar():
return {'ok': True, 'msg': msg} 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 - <b><font color="#610B0B">{}</font></b>'
data['empresa'] = titulo.format(obj.nombre)
return data
def config_timbrar(): def config_timbrar():
try: try:
obj = Emisor.select()[0] obj = Emisor.select()[0]
@ -695,6 +712,11 @@ class SATFormaPago(BaseModel):
def __str__(self): def __str__(self):
return 'Forma de pago: ({}) {}'.format(self.key, self.name) return 'Forma de pago: ({}) {}'.format(self.key, self.name)
@classmethod
def get_(self):
rows = SATFormaPago.select().dicts()
return tuple(rows)
@classmethod @classmethod
def get_by_key(cls, key): def get_by_key(cls, key):
return SATFormaPago.get(SATFormaPago.key==key) return SATFormaPago.get(SATFormaPago.key==key)
@ -711,6 +733,27 @@ class SATFormaPago(BaseModel):
) )
return tuple(rows) 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): class SATAduanas(BaseModel):
key = TextField(unique=True, index=True) key = TextField(unique=True, index=True)
@ -1227,6 +1270,7 @@ class MovimientosBanco(BaseModel):
with database_proxy.transaction(): with database_proxy.transaction():
obj.cancelado = True obj.cancelado = True
obj.save() obj.save()
FacturasPagos.cancelar(obj)
obj = cls._movimiento_anterior(cls, obj.cuenta, obj.fecha) obj = cls._movimiento_anterior(cls, obj.cuenta, obj.fecha)
cls._actualizar_saldos(cls, obj) cls._actualizar_saldos(cls, obj)
@ -1970,6 +2014,9 @@ class Facturas(BaseModel):
if invoice.tipo_comprobante == 'T': if invoice.tipo_comprobante == 'T':
return return
if invoice.donativo and invoice.forma_pago == '12':
return
importe = invoice.total_mn importe = invoice.total_mn
if invoice.tipo_comprobante == 'E': if invoice.tipo_comprobante == 'E':
importe *= -1 importe *= -1
@ -2511,11 +2558,11 @@ class Facturas(BaseModel):
impuestos['traslados'] = traslados impuestos['traslados'] = traslados
impuestos['retenciones'] = retenciones impuestos['retenciones'] = retenciones
impuestos['total_locales_trasladados'] = '' impuestos['total_locales_trasladados'] = '0.00'
if total_locales_trasladados: if total_locales_trasladados:
impuestos['total_locales_trasladados'] = \ impuestos['total_locales_trasladados'] = \
FORMAT.format(total_locales_trasladados) FORMAT.format(total_locales_trasladados)
impuestos['total_locales_retenciones'] = '' impuestos['total_locales_retenciones'] = '0.00'
if total_locales_retenciones: if total_locales_retenciones:
impuestos['total_locales_retenciones'] = \ impuestos['total_locales_retenciones'] = \
FORMAT.format(total_locales_retenciones) FORMAT.format(total_locales_retenciones)
@ -3175,17 +3222,90 @@ class FacturasPagos(BaseModel):
auto_round=True) auto_round=True)
saldo = DecimalField(default=0.0, max_digits=18, decimal_places=6, saldo = DecimalField(default=0.0, max_digits=18, decimal_places=6,
auto_round=True) auto_round=True)
# ~ cancelado = BooleanField(default=False)
class Meta: class Meta:
order_by = ('factura',) order_by = ('factura',)
indexes = ( 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 @classmethod
def add(cls, mov, ids): def add(cls, mov, ids):
print (mov) for i, importe in ids.items():
print (ids) 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 return
@ -3634,7 +3754,6 @@ def _importar_facturas(rows):
} }
FacturasImpuestos.create(**new) FacturasImpuestos.create(**new)
except IntegrityError as e: except IntegrityError as e:
#~ print (e)
msg = '\tFactura: id: {}'.format(row['serie'] + str(row['folio'])) msg = '\tFactura: id: {}'.format(row['serie'] + str(row['folio']))
log.error(msg) log.error(msg)
log.info('\tFacturas importadas...') log.info('\tFacturas importadas...')
@ -3756,6 +3875,35 @@ def _generar_archivo_productos(archivo):
return 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): def _importar_factura_libre(archivo):
rfc = input('Introduce el RFC: ').strip().upper() rfc = input('Introduce el RFC: ').strip().upper()
if not rfc: if not rfc:

View File

@ -7,7 +7,7 @@ from mako.lookup import TemplateLookup
from logbook import Logger, StreamHandler, RotatingFileHandler from logbook import Logger, StreamHandler, RotatingFileHandler
logbook.set_datetime_format('local') logbook.set_datetime_format('local')
from conf import DEBUG, LOG_PATH from conf import DEBUG, MV, LOG_PATH
DEBUG = DEBUG DEBUG = DEBUG
@ -86,6 +86,7 @@ PRE = {
'TIMBRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}', 'TIMBRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}',
'DONATARIA': '{http://www.sat.gob.mx/donat}', 'DONATARIA': '{http://www.sat.gob.mx/donat}',
'INE': '{http://www.sat.gob.mx/ine}', 'INE': '{http://www.sat.gob.mx/ine}',
'LOCALES': '{http://www.sat.gob.mx/implocal}',
'NOMINA': { 'NOMINA': {
'1.1': '{http://www.sat.gob.mx/nomina}', '1.1': '{http://www.sat.gob.mx/nomina}',
'1.2': '{http://www.sat.gob.mx/nomina12}', '1.2': '{http://www.sat.gob.mx/nomina12}',

View File

@ -32,6 +32,7 @@ var controllers = {
$$('grid_admin_monedas').attachEvent('onCheck', grid_admin_monedas_on_check) $$('grid_admin_monedas').attachEvent('onCheck', grid_admin_monedas_on_check)
$$('grid_admin_bancos').attachEvent('onCheck', grid_admin_bancos_on_check) $$('grid_admin_bancos').attachEvent('onCheck', grid_admin_bancos_on_check)
$$('grid_admin_unidades').attachEvent('onCheck', grid_admin_unidades_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) $$('grid_unidad_found').attachEvent('onValueSuggest', grid_unidad_found_click)
$$('cmd_agregar_impuesto').attachEvent('onItemClick', cmd_agregar_impuesto_click) $$('cmd_agregar_impuesto').attachEvent('onItemClick', cmd_agregar_impuesto_click)
//~ Opciones //~ Opciones
@ -43,6 +44,9 @@ var controllers = {
$$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click) $$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click)
$$('chk_config_anticipo').attachEvent('onItemClick', chk_config_item_click) $$('chk_config_anticipo').attachEvent('onItemClick', chk_config_item_click)
$$('chk_config_ine').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').clearAll()
$$('grid_admin_taxes').parse(values, 'json') $$('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){ function get_config_values(opt){
if(opt == undefined){ if(opt == undefined){
return return
@ -906,6 +920,8 @@ function tab_sat_change(nv, ov){
get_admin_bancos() get_admin_bancos()
}else if(nv == 'Unidades'){ }else if(nv == 'Unidades'){
get_admin_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){ function emisor_cuenta_saldo_inicial_change(new_value, old_value){
if(!isFinite(new_value)){ if(!isFinite(new_value)){
this.config.value = old_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)
//~ }
//~ }
//~ })
}

View File

@ -4,6 +4,7 @@ var msg = ''
var result = false var result = false
var tipo_relacion = '' var tipo_relacion = ''
var anticipo = false var anticipo = false
var donativo = false
function get_condicion_pago(){ function get_condicion_pago(){
@ -498,7 +499,7 @@ function guardar_y_timbrar(values){
data['relacionados'] = ids data['relacionados'] = ids
data['tipo_relacion'] = tipo_relacion data['tipo_relacion'] = tipo_relacion
data['anticipo'] = anticipo data['anticipo'] = anticipo
data['donativo'] = $$('chk_cfdi_donativo').getValue() data['donativo'] = donativo
var usar_ine = $$('chk_cfdi_usar_ine').getValue() var usar_ine = $$('chk_cfdi_usar_ine').getValue()
if(usar_ine){ if(usar_ine){
@ -518,6 +519,7 @@ function guardar_y_timbrar(values){
tipo_relacion = '' tipo_relacion = ''
anticipo = false anticipo = false
$$('chk_cfdi_anticipo').setValue(0) $$('chk_cfdi_anticipo').setValue(0)
$$('chk_cfdi_donativo').setValue(0)
$$('chk_cfdi_usar_ine').setValue(0) $$('chk_cfdi_usar_ine').setValue(0)
$$('form_invoice').setValues({id_partner: 0, lbl_partner: 'Ninguno'}) $$('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<BR><BR>' msg += 'La factura tiene CFDI relacionados<BR><BR>'
} }
if(anticipo){ if(anticipo){
msg += 'La factura es Anticipo<BR><BR>' msg += 'La factura es un Anticipo<BR><BR>'
}
if(donativo){
msg += 'La factura es un Donativo'
if($$('lst_forma_pago').getValue()=='12'){
msg += ' en Especie'
}
msg += '<BR><BR>'
} }
usar_ine = $$('chk_cfdi_usar_ine').getValue() usar_ine = $$('chk_cfdi_usar_ine').getValue()
if(usar_ine){ if(usar_ine){

View File

@ -6,6 +6,10 @@ function configuracion_inicial(){
var values = data.json() var values = data.json()
$$('cmd_ir_al_admin').show(values) $$('cmd_ir_al_admin').show(values)
}) })
webix.ajax().get('/values/main', function(text, data){
var values = data.json()
$$('lbl_title_main').setValue(values.empresa)
})
} }

View File

@ -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 = [ var grid_admin_taxes_cols = [
{id: 'id', header: 'ID', hidden: true}, {id: 'id', header: 'ID', hidden: true},
{id: 'delete', header: '', width: 30, css: 'delete'}, {id: 'delete', header: '', width: 30, css: 'delete'},
@ -515,7 +542,7 @@ var grid_admin_taxes = {
view: 'datatable', view: 'datatable',
id: 'grid_admin_taxes', id: 'grid_admin_taxes',
select: 'cell', select: 'cell',
multiselect: true, //~ multiselect: true,
adjust: true, adjust: true,
autoheight: true, autoheight: true,
autowidth: true, autowidth: true,
@ -528,7 +555,7 @@ var grid_admin_monedas = {
view: 'datatable', view: 'datatable',
id: 'grid_admin_monedas', id: 'grid_admin_monedas',
select: 'cell', select: 'cell',
multiselect: true, //~ multiselect: true,
adjust: true, adjust: true,
autoheight: true, autoheight: true,
autowidth: true, autowidth: true,
@ -541,7 +568,7 @@ var grid_admin_bancos = {
view: 'datatable', view: 'datatable',
id: 'grid_admin_bancos', id: 'grid_admin_bancos',
select: 'cell', select: 'cell',
multiselect: true, //~ multiselect: true,
adjust: true, adjust: true,
autowidth: true, autowidth: true,
headermenu: true, headermenu: true,
@ -554,7 +581,7 @@ var grid_admin_unidades = {
view: 'datatable', view: 'datatable',
id: 'grid_admin_unidades', id: 'grid_admin_unidades',
select: 'cell', select: 'cell',
multiselect: true, //~ multiselect: true,
adjust: true, adjust: true,
autowidth: true, autowidth: true,
autoheight: 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}, var admin_sat_impuestos = {cols: [{maxWidth: 15},
{view: 'richselect', id: 'lst_admin_impuestos', label: 'Impuesto', options: {view: 'richselect', id: 'lst_admin_impuestos', label: 'Impuesto', options:
['ISR', 'IVA', 'IEPS', 'ISH', 'INSPECCION DE OBRA', 'ICIC', 'CEDULAR'], ['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 = { var tab_sat = {
view: 'tabview', view: 'tabview',
id: 'tab_sat', id: 'tab_sat',
multiview: true, multiview: true,
tabbar: {options: [ //~ tabbar: {options: [
'Impuestos', //~ 'Impuestos',
'Monedas', //~ 'Monedas',
'Bancos', //~ 'Bancos',
'Unidades' //~ 'Unidades'
]}, //~ ]},
animate: true, animate: true,
cells: [ cells: [
{id: 'Impuestos', rows: sat_impuestos}, {id: 'Impuestos', rows: sat_impuestos},
{id: 'Monedas', rows: sat_monedas}, {id: 'Monedas', rows: sat_monedas},
{id: 'Bancos', rows: sat_bancos}, {id: 'Bancos', rows: sat_bancos},
{id: 'Unidades', rows: sat_unidades}, {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 = { var multi_admin = {
id: 'multi_admin', id: 'multi_admin',
animate: true, animate: true,
@ -746,6 +819,7 @@ var multi_admin = {
app_correo, app_correo,
app_sat, app_sat,
app_options, app_options,
app_utilidades,
], ],
} }

View File

@ -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() != '';},
}
},
]}, {}, ]
},
]
}

View File

@ -63,7 +63,7 @@ var ui_main = {
$$('$sidebar1').toggle() $$('$sidebar1').toggle()
} }
}, },
{view: 'label', label: 'Empresa Libre'}, {view: 'label', id: 'lbl_title_main', label: '<b>Empresa Libre</b>'},
{}, {},
menu_user, menu_user,
{view: 'button', type: 'icon', width: 45, css: 'app_button', {view: 'button', type: 'icon', width: 45, css: 'app_button',

View File

@ -14,7 +14,7 @@ var grid_partners_cols = [
{id: 'index', header:'#', css: 'right', {id: 'index', header:'#', css: 'right',
footer: {content: 'rowCount', colspan: 2, css: 'right'}}, footer: {content: 'rowCount', colspan: 2, css: 'right'}},
{id: 'id', header: 'Clave', sort: 'int', 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}}, sort: 'string', footer: {text: 'Clientes y Proveedores', colspan: 2}},
{id: 'nombre', header: ['Razón Social', {content: 'textFilter'}], {id: 'nombre', header: ['Razón Social', {content: 'textFilter'}],
fillspace:true, sort: 'string'}, fillspace:true, sort: 'string'},

View File

@ -7,7 +7,7 @@
<link rel="shortcut icon" href="/static/img/favicon.png"> <link rel="shortcut icon" href="/static/img/favicon.png">
<link rel="stylesheet" href="/static/css/air.css" type="text/css"> <link rel="stylesheet" href="/static/css/air.css" type="text/css">
<link rel="stylesheet" href="/static/css/app.css" type="text/css"> <link rel="stylesheet" href="/static/css/app.css" type="text/css">
<script src="/static/js/webix_debug.js" type="text/javascript" ></script> <script src="/static/js/webix.js" type="text/javascript" ></script>
<script src="/static/js/es-MX.js" type="text/javascript" ></script> <script src="/static/js/es-MX.js" type="text/javascript" ></script>
<script src="/static/js/lokijs.min.js" type="text/javascript" ></script> <script src="/static/js/lokijs.min.js" type="text/javascript" ></script>
<%block name="media"/> <%block name="media"/>

View File

@ -0,0 +1,39 @@
<%inherit file="base.html"/>
<%block name="media">
<script src="/static/js/ui/empresas.js" type="text/javascript" ></script>
</%block>
<%block name="content">
<div id="form_empresas"></div>
<script type="text/javascript" charset="utf-8">
function validate_nuevo_rfc(){
var form = this.getFormView();
if (!form.validate()) {
webix.message({ type:"error", text:"Valores inválidos" });
return
}
var values = form.getValues()
webix.ajax().post("/empresas", values, function(text, data, xhr) {
var values = data.json();
if (values.ok) {
} else {
webix.message({ type:"error", text: values.msg })
}
});
};
webix.ready(function(){
webix.ui(ui_empresas);
});
</script>
</%block>

View File

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:donat="http://www.sat.gob.mx/donat"> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:donat="http://www.sat.gob.mx/donat">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/> <xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<!-- Manejador de nodos tipo donat:Donatarias --> <!-- Manejador de nodos tipo donat:Donatarias -->
<xsl:template match="donat:Donatarias"> <xsl:template match="donat:Donatarias">
<!-- Iniciamos el tratamiento de los atributos de donat:Donatarias --> <!-- Iniciamos el tratamiento de los atributos de donat:Donatarias -->
<xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@version"/></xsl:call-template> <xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@version"/></xsl:call-template>
<xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@noAutorizacion"/></xsl:call-template> <xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@noAutorizacion"/></xsl:call-template>
<xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@fechaAutorizacion"/></xsl:call-template> <xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@fechaAutorizacion"/></xsl:call-template>
<xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@leyenda"/></xsl:call-template> <xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@leyenda"/></xsl:call-template>
</xsl:template> </xsl:template>
</xsl:stylesheet> </xsl:stylesheet>

View File

@ -1,39 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:implocal="http://www.sat.gob.mx/implocal"> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:implocal="http://www.sat.gob.mx/implocal">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/> <xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<!-- Manejador de nodos tipo implocal --> <!-- Manejador de nodos tipo implocal -->
<xsl:template match="implocal:ImpuestosLocales"> <xsl:template match="implocal:ImpuestosLocales">
<!--Iniciamos el tratamiento de los atributos de ImpuestosLocales --> <!--Iniciamos el tratamiento de los atributos de ImpuestosLocales -->
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@version"/> <xsl:with-param name="valor" select="./@version"/>
</xsl:call-template> </xsl:call-template>
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TotaldeRetenciones"/> <xsl:with-param name="valor" select="./@TotaldeRetenciones"/>
</xsl:call-template> </xsl:call-template>
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TotaldeTraslados"/> <xsl:with-param name="valor" select="./@TotaldeTraslados"/>
</xsl:call-template> </xsl:call-template>
<xsl:for-each select="implocal:RetencionesLocales"> <xsl:for-each select="implocal:RetencionesLocales">
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ImpLocRetenido"/> <xsl:with-param name="valor" select="./@ImpLocRetenido"/>
</xsl:call-template> </xsl:call-template>
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TasadeRetencion"/> <xsl:with-param name="valor" select="./@TasadeRetencion"/>
</xsl:call-template> </xsl:call-template>
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe"/> <xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template> </xsl:call-template>
</xsl:for-each> </xsl:for-each>
<xsl:for-each select="implocal:TrasladosLocales"> <xsl:for-each select="implocal:TrasladosLocales">
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ImpLocTrasladado"/> <xsl:with-param name="valor" select="./@ImpLocTrasladado"/>
</xsl:call-template> </xsl:call-template>
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TasadeTraslado"/> <xsl:with-param name="valor" select="./@TasadeTraslado"/>
</xsl:call-template> </xsl:call-template>
<xsl:call-template name="Requerido"> <xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe"/> <xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template> </xsl:call-template>
</xsl:for-each> </xsl:for-each>
</xsl:template> </xsl:template>
</xsl:stylesheet> </xsl:stylesheet>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ine="http://www.sat.gob.mx/ine"> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ine="http://www.sat.gob.mx/ine">
<xsl:template match="ine:INE"> <xsl:template match="ine:INE">
<!--Manejador de nodos tipo INE--> <!--Manejador de nodos tipo INE-->