Merge branch 'develop'

Agregar cuentas de banco
This commit is contained in:
Mauricio Baeza 2017-11-17 22:39:13 -06:00
commit 5cb7ba2c95
19 changed files with 1033 additions and 89 deletions

View File

@ -140,6 +140,7 @@ class AppPartners(object):
def on_get(self, req, resp):
values = req.params
#~ print ('VALUES', values)
req.context['result'] = self._db.get_partners(values)
resp.status = falcon.HTTP_200
@ -257,7 +258,31 @@ class AppCuentasBanco(object):
def on_get(self, req, resp):
values = req.params
session = req.env['beaker.session']
#~ req.context['result'] = self._db.get_emisor(session['rfc'])
req.context['result'] = self._db.get_cuentasbanco(values)
resp.status = falcon.HTTP_200
def on_post(self, req, resp):
values = req.params
req.context['result'] = self._db.cuentasbanco(values)
resp.status = falcon.HTTP_200
def on_delete(self, req, resp):
values = req.params
if self._db.delete('cuentasbanco', values['id']):
resp.status = falcon.HTTP_200
else:
resp.status = falcon.HTTP_204
class AppMovimientosBanco(object):
def __init__(self, db):
self._db = db
def on_get(self, req, resp):
values = req.params
session = req.env['beaker.session']
req.context['result'] = self._db.get_movimientosbanco(values)
resp.status = falcon.HTTP_200
def on_post(self, req, resp):

View File

@ -36,7 +36,7 @@ from dateutil import parser
from .helper import CaseInsensitiveDict, NumLet, SendMail, TemplateInvoice
from settings import DEBUG, log, template_lookup, COMPANIES, DB_SAT, \
PATH_XSLT, PATH_XSLTPROC, PATH_OPENSSL, PATH_TEMPLATES, PATH_MEDIA, PRE, \
PATH_XMLSEC, TEMPLATE_CANCEL, IMPUESTOS
PATH_XMLSEC, TEMPLATE_CANCEL, DEFAULT_SAT_PRODUCTO
#~ def _get_hash(password):
@ -767,9 +767,8 @@ class LIBO(object):
#~ Si no se encuentra, copia las celdas hacia abajo de
#~ {subtotal.titulo} y {subtotal}
print (data['descuento'])
#~ print (data['descuento'])
if 'descuento' in data:
self._copy_cell(cell_title)
self._copy_cell(cell_value)
cell_title = self._set_cell(v='Descuento', cell=cell_title)
@ -1277,10 +1276,10 @@ class ImportFacturaLibre(object):
self._rfc = rfc
self._con = None
self._cursor = None
self._error = ''
self._is_connect = self._connect(path)
self._clientes = []
self._clientes_rfc = []
self._error = ''
@property
def error(self):
@ -1299,7 +1298,7 @@ class ImportFacturaLibre(object):
return False
if obj['rfc'] != self._rfc:
self._error = 'Los datos no corresponden al emisor: {}'.format(self._rfc)
self._error = 'Los datos no corresponden al RFC: {}'.format(self._rfc)
return False
return True
@ -1328,6 +1327,7 @@ class ImportFacturaLibre(object):
tables = (
('receptores', 'Socios'),
('cfdfacturas', 'Facturas'),
('categorias', 'Categorias'),
)
for source, target in tables:
data[target] = self._get_table(source)
@ -1339,6 +1339,63 @@ class ImportFacturaLibre(object):
def _get_table(self, table):
return getattr(self, '_{}'.format(table))()
def import_productos(self):
sql = "SELECT * FROM productos"
self._cursor.execute(sql)
rows = self._cursor.fetchall()
fields = (
('id_categoria', 'categoria'),
('noIdentificacion', 'clave'),
('descripcion', 'descripcion'),
('unidad', 'unidad'),
('valorUnitario', 'valor_unitario'),
('existencia', 'existencia'),
('inventario', 'inventario'),
('codigobarras', 'codigo_barras'),
('CuentaPredial', 'cuenta_predial'),
('precio_compra', 'ultimo_precio'),
('minimo', 'minimo'),
)
data = []
sql = """
SELECT nombre, tasa, tipo
FROM impuestos, productos, productosimpuestos
WHERE productos.id=productosimpuestos.id_producto
AND productosimpuestos.id_impuesto=impuestos.id
AND productos.id = ?
"""
for row in rows:
new = {t: row[s] for s, t in fields}
new['descripcion'] = ' '.join(new['descripcion'].split())
new['clave_sat'] = DEFAULT_SAT_PRODUCTO
self._cursor.execute(sql, (row['id'],))
impuestos = self._cursor.fetchall()
new['impuestos'] = tuple(impuestos)
data.append(new)
return data
def _categorias(self):
sql = "SELECT * FROM categorias"
self._cursor.execute(sql)
rows = self._cursor.fetchall()
fields = (
('categoria', 'categoria'),
('id_padre', 'padre'),
)
data = []
for row in rows:
new = {t: row[s] for s, t in fields}
if new['padre'] == 0:
new['padre'] = None
data.append(new)
return data
def _get_cliente(self, invoice):
sql = "SELECT rfc, nombre FROM receptores WHERE id=?"
self._cursor.execute(sql, [invoice['id_cliente']])
@ -1476,6 +1533,10 @@ class ImportFacturaLibre(object):
data = []
for row in rows:
new = {t: row[s] for s, t in fields}
if not new['uuid']:
new['uuid'] = None
if new['xml'] is None:
new['xml'] = ''
if row['estatus'] == 'Pagada':
new['pagada'] = True
elif row['estatus'] == 'Cancelada':

View File

@ -15,7 +15,8 @@ from models.db import StorageEngine
from controllers.main import (
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
AppMovimientosBanco
)
from settings import DEBUG
@ -46,6 +47,7 @@ api.add_route('/products', AppProducts(db))
api.add_route('/invoices', AppInvoices(db))
api.add_route('/preinvoices', AppPreInvoices(db))
api.add_route('/cuentasbanco', AppCuentasBanco(db))
api.add_route('/movbanco', AppMovimientosBanco(db))
if DEBUG:

View File

@ -58,6 +58,9 @@ class StorageEngine(object):
years2 = main.PreFacturas.filter_years()
return [years1, years2]
def _get_cuentayears(self, values):
return main.CuentasBanco.get_years()
def _get_cert(self, values):
return main.Certificado.get_data()
@ -145,6 +148,9 @@ class StorageEngine(object):
def _get_usocfdi(self, values):
return main.SATUsoCfdi.get_activos()
def _get_ebancomov(self, values):
return main.MovimientosBanco.con(values['id'])
def delete(self, table, id):
if table == 'partner':
return main.Socios.remove(id)
@ -158,6 +164,8 @@ class StorageEngine(object):
return main.PreFacturas.remove(id)
if table == 'satimpuesto':
return main.SATImpuestos.remove(id)
if table == 'cuentasbanco':
return main.CuentasBanco.remove(id)
return False
def _get_client(self, values):
@ -217,6 +225,9 @@ class StorageEngine(object):
def cuentasbanco(self, values):
return main.CuentasBanco.add(values)
def get_cuentasbanco(self, values):
return main.CuentasBanco.get_(values)
def get_folios(self):
return main.Folios.get_()
@ -239,3 +250,6 @@ class StorageEngine(object):
return data, file_name, content_type
def get_movimientosbanco(self, values):
return main.MovimientosBanco.get_(values)

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python
from decimal import Decimal
import sqlite3
import click
from peewee import *
@ -15,7 +16,7 @@ if __name__ == '__main__':
from controllers import util
from settings import log, VERSION, PATH_CP, COMPANIES, PRE, CURRENT_CFDI, \
INIT_VALUES, DEFAULT_PASSWORD, DECIMALES, IMPUESTOS
INIT_VALUES, DEFAULT_PASSWORD, DECIMALES, IMPUESTOS, DEFAULT_SAT_PRODUCTO
FORMAT = '{0:.2f}'
@ -529,6 +530,10 @@ class Categorias(BaseModel):
(('categoria', 'padre'), True),
)
@classmethod
def exists(cls, filters):
return Categorias.select().where(filters).exists()
@classmethod
def get_all(cls):
rows = (Categorias.select(
@ -536,6 +541,9 @@ class Categorias(BaseModel):
Categorias.categoria.alias('value'),
Categorias.padre.alias('parent_id'))
).dicts()
for row in rows:
if row['parent_id'] is None:
row['parent_id'] = 0
return tuple(rows)
@ -574,6 +582,9 @@ class SATUnidades(BaseModel):
(('key', 'name'), True),
)
def __str__(self):
return '{} ({})'.format(self.name, self.key)
@classmethod
def get_(self):
rows = SATUnidades.select().dicts()
@ -635,6 +646,10 @@ class SATFormaPago(BaseModel):
def __str__(self):
return 'Forma de pago: ({}) {}'.format(self.key, self.name)
@classmethod
def get_by_key(cls, key):
return SATFormaPago.get(SATFormaPago.key==key)
@classmethod
def get_activos(cls, values):
field = SATFormaPago.id
@ -740,12 +755,17 @@ class SATImpuestos(BaseModel):
(('key', 'factor', 'tipo', 'tasa'), True),
)
@classmethod
def get_o_crea(self, values):
obj, _ = SATImpuestos.get_or_create(**values)
return obj
@classmethod
def add(self, values):
tasa = float(values['tasa'])
tipo = 'T'
if tasa < 0:
tipo: 'R'
tipo = 'R'
row = {
'key': IMPUESTOS.get(values['impuesto']),
@ -753,6 +773,7 @@ class SATImpuestos(BaseModel):
'tipo': tipo,
'tasa': abs(tasa),
}
try:
obj = SATImpuestos.create(**row)
row['id'] = obj.id
@ -764,8 +785,11 @@ class SATImpuestos(BaseModel):
@classmethod
def remove(cls, id):
with database_proxy.transaction():
q = SATImpuestos.delete().where(SATImpuestos.id==id)
return bool(q.execute())
try:
q = SATImpuestos.delete().where(SATImpuestos.id==id)
return bool(q.execute())
except IntegrityError:
return False
@classmethod
def get_(self):
@ -774,7 +798,9 @@ class SATImpuestos(BaseModel):
SQL(" '-' AS delete"),
SATImpuestos.name,
SATImpuestos.tipo,
SATImpuestos.tasa)
SATImpuestos.tasa,
SATImpuestos.activo,
SATImpuestos.default)
.dicts()
)
return tuple(rows)
@ -902,6 +928,58 @@ class CuentasBanco(BaseModel):
def __str__(self):
return '{} ({})'.format(self.banco.name, self.cuenta[-4:])
@classmethod
def remove(cls, id):
try:
with database_proxy.atomic() as txn:
q = MovimientosBanco.delete().where(MovimientosBanco.cuenta==id)
q.execute()
q = CuentasBanco.delete().where(CuentasBanco.id==id)
q.execute()
return True
except:
return False
@classmethod
def get_years(cls):
data = [{'id': -1, 'value': 'Todos'}]
year1 = (CuentasBanco
.select(fn.Min(CuentasBanco.fecha_apertura.year))
.where(CuentasBanco.de_emisor==True, CuentasBanco.activa==True)
.group_by(CuentasBanco.fecha_apertura.year)
.order_by(CuentasBanco.fecha_apertura.year)
.scalar()
)
if year1:
year2 = util.now().year + 1
data += [{'id': y, 'value': y} for y in range(int(year1), year2)]
return data
@classmethod
def get_(cls, values):
if values['tipo'] == '1':
rows = (CuentasBanco
.select()
.where(CuentasBanco.de_emisor==True, CuentasBanco.activa==True)
)
if not (len(rows)):
return {'ok': False}
first = rows[0]
rows = [{'id': r.id, 'value': '{} ({})'.format(
r.banco.name, r.cuenta[-4:])} for r in rows]
data = {
'ok': True,
'rows': tuple(rows),
'moneda': first.moneda.name,
'saldo': first.saldo,
}
return data
return
@classmethod
def emisor(cls):
rows = (CuentasBanco
@ -926,15 +1004,32 @@ class CuentasBanco(BaseModel):
def add(cls, values):
w = '37137137137137137'
dv = str(
10 -
(10 -
sum([(int(v) * int(values['clabe'][i])) % 10 for i, v in enumerate(w)])
% 10)
% 10) % 10)
if dv != values['clabe'][-1]:
msg = 'Digito de control de la CLABE es incorrecto'
return {'ok': False, 'msg': msg}
fecha_deposito = values.pop('fecha_deposito', None)
with database_proxy.transaction():
obj = CuentasBanco.create(**values)
try:
obj = CuentasBanco.create(**values)
except IntegrityError:
msg = 'Esta cuenta ya existe'
return {'ok': False, 'msg': msg}
nuevo_mov= {
'cuenta': obj.id,
'fecha': fecha_deposito,
'movimiento': 1,
'descripcion': 'Saldo inicial',
'forma_pago': SATFormaPago.get_by_key('99'),
'deposito': values['saldo'],
'saldo': values['saldo'],
}
MovimientosBanco.add(nuevo_mov)
rows = (CuentasBanco
.select(
@ -956,6 +1051,113 @@ class CuentasBanco(BaseModel):
return data
class MovimientosBanco(BaseModel):
cuenta = ForeignKeyField(CuentasBanco)
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
movimiento = IntegerField(default=0)
descripcion = TextField(default='')
forma_pago = ForeignKeyField(SATFormaPago)
retiro = DecimalField(default=0.0, max_digits=20, decimal_places=6,
auto_round=True)
deposito = DecimalField(default=0.0, max_digits=20, decimal_places=6,
auto_round=True)
saldo = DecimalField(default=0.0, max_digits=20, decimal_places=6,
auto_round=True)
moneda = TextField(default='MXN') # Complemento de pagos
tipo_cambio = DecimalField(default=1.0, max_digits=15, decimal_places=6,
auto_round=True)
numero_operacion = TextField(default='')
origen_rfc = TextField(default='')
origen_nombre = TextField(default='')
origen_cuenta = TextField(default='')
destino_rfc = TextField(default='')
destino_cuenta = TextField(default='')
tipo_cadena_pago = TextField(default='')
certificado_pago = TextField(default='')
cadena_pago = TextField(default='')
sello_pago = TextField(default='')
class Meta:
order_by = ('fecha',)
indexes = (
(('cuenta', 'movimiento'), True),
)
@classmethod
def add(cls, values):
with database_proxy.transaction():
try:
obj = MovimientosBanco.create(**values)
except IntegrityError:
msg = 'Este movimiento ya existe'
return {'ok': False, 'msg': msg}
return {'ok': True}
@classmethod
def con(cls, id):
cant = (MovimientosBanco
.select(MovimientosBanco.id)
.where(MovimientosBanco.cuenta==id)
.count()
)
if cant > 2:
return {'ok': True}
return {'ok': False}
@classmethod
def get_(cls, values):
cuenta = int(values['cuenta'])
if 'fechas' in values:
rango = values['fechas']
fd = (MovimientosBanco.fecha.between(
util.get_date(rango['start']),
util.get_date(rango['end'], True)))
filtros = (fd & (MovimientosBanco.cuenta==cuenta))
else:
year = int(values['year'])
mes = int(values['mes'])
if year == -1:
fy = (MovimientosBanco.fecha.year > 0)
else:
fy = (MovimientosBanco.fecha.year == year)
if mes == -1:
fm = (MovimientosBanco.fecha.month > 0)
else:
fm = (MovimientosBanco.fecha.month == mes)
filtros = (fy & fm & (MovimientosBanco.cuenta==cuenta))
rows = tuple(MovimientosBanco
.select(
MovimientosBanco.id,
MovimientosBanco.fecha,
MovimientosBanco.numero_operacion,
MovimientosBanco.descripcion,
MovimientosBanco.retiro,
MovimientosBanco.deposito,
MovimientosBanco.saldo)
.where(filtros)
.dicts()
)
return {'ok': True, 'rows': rows}
class CfdiPagos(BaseModel):
movimiento = ForeignKeyField(MovimientosBanco)
xml = TextField(default='')
uuid = UUIDField(null=True)
estatus = TextField(default='Guardado')
estatus_sat = TextField(default='')
notas = TextField(default='')
cancelado = BooleanField(default=False)
class Meta:
order_by = ('movimiento',)
class SATUsoCfdi(BaseModel):
key = TextField(index=True, unique=True)
name = TextField(default='', index=True)
@ -1076,7 +1278,9 @@ class Socios(BaseModel):
@classmethod
def get_(cls, values):
if values:
print ('values', values)
id = values.get('id', 0)
if id:
id = int(values['id'])
row = Socios.select().where(Socios.id==id).dicts()[0]
row['uso_cfdi_socio'] = row.pop('uso_cfdi')
@ -1085,6 +1289,18 @@ class Socios(BaseModel):
str(CondicionesPago.get(id=row['condicion_pago']))
return row
#~ return {'data': data['rows'][:100], 'pos':0, 'total_count': 1300}
#~ start = 0
#~ count = 0
#~ end = 100
#~ if values:
#~ {'start': '100', 'count': '100', 'continue': 'true'}
#~ start = int(values['start'])
#~ cont = int(values['count'])
#~ end = start + count
total = Socios.select().count()
rows = (Socios
.select(
Socios.id,
@ -1093,7 +1309,7 @@ class Socios(BaseModel):
Socios.saldo_cliente)
.dicts()
)
return {'ok': True, 'rows': tuple(rows)}
return {'pos': 0, 'total_count': total, 'data': tuple(rows)}
@classmethod
def get_by_client(cls, values):
@ -1834,8 +2050,8 @@ class Facturas(BaseModel):
invoice_tax = {
'factura': invoice.id,
'impuesto': tax['id'],
'base': tax['importe'],
'impuesto': tax.id,
'base': tax.importe,
'importe': import_tax,
}
FacturasImpuestos.create(**invoice_tax)
@ -2497,6 +2713,17 @@ class FacturasRelacionadas(BaseModel):
return [str(r.factura_origen.uuid) for r in query]
class CfdiPagosFacturas(BaseModel):
pago = ForeignKeyField(CfdiPagos)
factura = ForeignKeyField(Facturas)
class Meta:
order_by = ('pago',)
indexes = (
(('pago', 'factura'), True),
)
class PreFacturasRelacionadas(BaseModel):
factura = ForeignKeyField(PreFacturas, related_name='original')
factura_origen = ForeignKeyField(PreFacturas, related_name='relacion')
@ -2639,6 +2866,23 @@ class FacturasImpuestos(BaseModel):
)
class FacturasPagos(BaseModel):
factura = ForeignKeyField(Facturas)
numero = IntegerField(default=1)
saldo_anterior = DecimalField(default=0.0, max_digits=20, decimal_places=6,
auto_round=True)
importe = DecimalField(default=0.0, max_digits=18, decimal_places=6,
auto_round=True)
saldo = DecimalField(default=0.0, max_digits=18, decimal_places=6,
auto_round=True)
class Meta:
order_by = ('factura',)
indexes = (
(('factura', 'numero'), True),
)
class PreFacturasImpuestos(BaseModel):
factura = ForeignKeyField(PreFacturas)
impuesto = ForeignKeyField(SATImpuestos)
@ -2789,13 +3033,15 @@ def _init_values(rfc):
def _crear_tablas(rfc):
tablas = [Addendas, Categorias, Certificado, CondicionesPago, Configuracion,
Emisor, Facturas, FacturasDetalle, FacturasImpuestos, Folios,
Folios,
Emisor, Facturas, FacturasDetalle, FacturasImpuestos, FacturasPagos,
FacturasRelacionadas, Productos,
PreFacturas, PreFacturasDetalle, PreFacturasImpuestos,
PreFacturasRelacionadas,
SATAduanas, SATFormaPago, SATImpuestos, SATMonedas, SATRegimenes,
SATTipoRelacion, SATUnidades, SATUsoCfdi, SATBancos,
Socios, Tags, Usuarios, CuentasBanco, TipoCambio,
Socios, Tags, Usuarios, CuentasBanco, TipoCambio, MovimientosBanco,
CfdiPagos, CfdiPagosFacturas,
Emisor.regimenes.get_through_model(),
Socios.tags.get_through_model(),
Productos.impuestos.get_through_model(),
@ -3039,12 +3285,22 @@ def _importar_socios(rows):
with database_proxy.atomic() as txn:
Socios.create(**row)
except IntegrityError:
msg = '\tSocio: id: {}'.format(row['nombre'])
log.error(msg)
msg = '\tSocio existente: {}'.format(row['nombre'])
log.info(msg)
log.info('\tClientes importados...')
return
def _existe_factura(row):
filtro = (Facturas.uuid==row['uuid'])
if row['uuid'] is None:
filtro = (
(Facturas.serie==row['serie']) &
(Facturas.folio==row['folio'])
)
return Facturas.select().where(filtro).exists()
def _importar_facturas(rows):
log.info('\tImportando Facturas...')
for row in rows:
@ -3054,6 +3310,11 @@ def _importar_facturas(rows):
cliente = row.pop('cliente')
row['cliente'] = Socios.get(**cliente)
with database_proxy.atomic() as txn:
if _existe_factura(row):
msg = '\tFactura existente: {}{}'.format(
row['serie'], row['folio'])
log.info(msg)
continue
obj = Facturas.create(**row)
for detalle in detalles:
detalle['factura'] = obj
@ -3066,13 +3327,129 @@ def _importar_facturas(rows):
'importe': impuesto['importe'],
}
FacturasImpuestos.create(**new)
except IntegrityError:
msg = '\tFactura: id: {}'.format(row['serie'] + row['folio'])
except IntegrityError as e:
#~ print (e)
msg = '\tFactura: id: {}'.format(row['serie'] + str(row['folio']))
log.error(msg)
log.info('\tFacturas importadas...')
return
def _importar_categorias(rows):
log.info('\tImportando Categorías...')
for row in rows:
if row['padre'] is None:
filters = (
(Categorias.categoria==row['categoria']) &
(Categorias.padre.is_null(True))
)
else:
filters = (
(Categorias.categoria==row['categoria']) &
(Categorias.padre==row['padre'])
)
if Categorias.exists(filters):
continue
try:
Categorias.create(**row)
except IntegrityError:
msg = '\tCategoria: ({}) {}'.format(row['padre'], row['categoria'])
log.error(msg)
log.info('\tCategorías importadas...')
return
def _get_id_unidad(unidad):
try:
if 'pieza' in unidad.lower():
unidad = 'pieza'
obj = SATUnidades.get(SATUnidades.name.contains(unidad))
except SATUnidades.DoesNotExist:
msg = '\tNo se encontró la unidad: {}'.format(unidad)
log.error(msg)
return unidad
return str(obj.id)
def _get_impuestos(impuestos):
lines = '|'
for impuesto in impuestos:
if impuesto['tasa'] == '-2/3':
tasa = str(round(2/3, 6))
else:
tasa = str(round(float(impuesto['tasa']) / 100.0, 6))
info = (
IMPUESTOS.get(impuesto['nombre']),
impuesto['nombre'],
impuesto['tipo'][0],
tasa,
)
lines += '|'.join(info)
return lines
def _generar_archivo_productos(archivo):
rfc = input('Introduce el RFC: ').strip().upper()
if not rfc:
msg = 'El RFC es requerido'
log.error(msg)
return
args = util.get_con(rfc)
if not args:
return
conectar(args)
log.info('Importando datos...')
app = util.ImportFacturaLibre(archivo, rfc)
if not app.is_connect:
log.error('\t{}'.format(app._error))
return
rows = app.import_productos()
p, _, _, _ = util.get_path_info(archivo)
path_txt = util._join(p, 'productos.txt')
log.info('\tGenerando archivo: {}'.format(path_txt))
fields = (
'clave',
'clave_sat',
'unidad',
'categoria',
'descripcion',
'valor_unitario',
'existencia',
'inventario',
'codigo_barras',
'cuenta_predial',
'ultimo_precio',
'minimo',
)
data = ['|'.join(fields)]
for row in rows:
impuestos = row.pop('impuestos', ())
line = [str(row[r]) for r in fields]
if line[10] == 'None':
line[10] = '0.0'
line[2] = _get_id_unidad(line[2])
line = '|'.join(line) + _get_impuestos(impuestos)
data.append(line)
with open(path_txt, 'w') as fh:
fh.write('\n'.join(data))
log.info('\tArchivo generado: {}'.format(path_txt))
return
def _importar_factura_libre(archivo):
rfc = input('Introduce el RFC: ').strip().upper()
if not rfc:
@ -3089,18 +3466,115 @@ def _importar_factura_libre(archivo):
log.info('Importando datos...')
app = util.ImportFacturaLibre(archivo, rfc)
if not app.is_connect:
log.error('\t{}'.format(app.error))
log.error('\t{}'.format(app._error))
return
data = app.import_data()
_importar_socios(data['Socios'])
_importar_facturas(data['Facturas'])
_importar_categorias(data['Categorias'])
log.info('Importación terminada...')
return
def _importar_productos(archivo):
rfc = input('Introduce el RFC: ').strip().upper()
if not rfc:
msg = 'El RFC es requerido'
log.error(msg)
return
args = util.get_con(rfc)
if not args:
return
conectar(args)
log.info('Importando productos...')
fields = (
'clave',
'clave_sat',
'unidad',
'categoria',
'descripcion',
'valor_unitario',
'existencia',
'inventario',
'codigo_barras',
'cuenta_predial',
'ultimo_precio',
'minimo',
)
rows = util.read_file(archivo, 'r').split('\n')
for i, row in enumerate(rows):
if i == 0:
continue
data = row.split('|')
new = {}
for i, f in enumerate(fields):
if not len(data[0]):
continue
if i in (2, 3):
try:
new[f] = int(data[i])
except ValueError:
continue
elif i in (5, 6, 10, 11):
new[f] = float(data[i])
elif i == 7:
new[f] = bool(data[i])
else:
new[f] = data[i]
impuestos = data[i + 1:]
if not impuestos:
taxes = [SATImpuestos.select().where(SATImpuestos.id==6)]
else:
taxes = []
for i in range(0, len(impuestos), 4):
w = {
'key': impuestos[i],
'name': impuestos[i+1],
'tipo': impuestos[i+2],
'tasa': float(impuestos[i+3]),
}
taxes.append(SATImpuestos.get_o_crea(w))
with database_proxy.transaction():
try:
obj = Productos.create(**new)
obj.impuestos = taxes
except IntegrityError:
pass
log.info('Importación terminada...')
return
def _test():
rfc = input('Introduce el RFC: ').strip().upper()
if not rfc:
msg = 'El RFC es requerido'
log.error(msg)
return
args = util.get_con(rfc)
if not args:
return
conectar(args)
rows = Categorias.select().where(
Categorias.categoria=='Productos', Categorias.padre.is_null(True)).exists()
print (rows)
return
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
help_create_tables = 'Crea las tablas en la base de datos'
help_migrate_db = 'Migra las tablas en la base de datos'
@ -3125,10 +3599,19 @@ help_lr = 'Listar RFCs'
@click.option('-i', '--importar-valores', is_flag=True, default=False)
@click.option('-a', '--archivo')
@click.option('-fl', '--factura-libre', is_flag=True, default=False)
@click.option('-t', '--test', is_flag=True, default=False)
@click.option('-gap', '--generar-archivo-productos', is_flag=True, default=False)
@click.option('-ip', '--importar-productos', is_flag=True, default=False)
def main(iniciar_bd, migrar_bd, nuevo_superusuario, cambiar_contraseña, rfc,
borrar_rfc, listar_rfc, importar_valores, archivo, factura_libre):
borrar_rfc, listar_rfc, importar_valores, archivo, factura_libre, test,
generar_archivo_productos, importar_productos):
opt = locals()
if opt['test']:
_test()
sys.exit(0)
if opt['iniciar_bd']:
_iniciar_bd()
sys.exit(0)
@ -3183,6 +3666,36 @@ def main(iniciar_bd, migrar_bd, nuevo_superusuario, cambiar_contraseña, rfc,
_importar_factura_libre(opt['archivo'])
sys.exit(0)
if opt['generar_archivo_productos']:
if not opt['archivo']:
msg = 'Falta la ruta de la base de datos'
raise click.ClickException(msg)
if not util.is_file(opt['archivo']):
msg = 'No es un archivo'
raise click.ClickException(msg)
_, _, _, ext = util.get_path_info(opt['archivo'])
if ext != '.sqlite':
msg = 'No es una base de datos'
raise click.ClickException(msg)
_generar_archivo_productos(opt['archivo'])
sys.exit(0)
if opt['importar_productos']:
if not opt['archivo']:
msg = 'Falta la ruta del archivo'
raise click.ClickException(msg)
if not util.is_file(opt['archivo']):
msg = 'No es un archivo'
raise click.ClickException(msg)
_, _, _, ext = util.get_path_info(opt['archivo'])
if ext != '.txt':
msg = 'No es un archivo de texto'
raise click.ClickException(msg)
_importar_productos(opt['archivo'])
sys.exit(0)
return

View File

@ -102,3 +102,4 @@ IMPUESTOS = {
'ICIC': '000',
'CEDULAR': '000',
}
DEFAULT_SAT_PRODUCTO = '01010101'

View File

@ -22,6 +22,7 @@ var controllers = {
$$('cmd_guardar_correo').attachEvent('onItemClick', cmd_guardar_correo_click)
$$('emisor_logo').attachEvent('onItemClick', emisor_logo_click)
$$('cmd_emisor_agregar_cuenta').attachEvent('onItemClick', cmd_emisor_agregar_cuenta_click)
$$('cmd_emisor_eliminar_cuenta').attachEvent('onItemClick', cmd_emisor_eliminar_cuenta_click)
$$('emisor_cuenta_saldo_inicial').attachEvent('onChange', emisor_cuenta_saldo_inicial_change)
//~ SAT
tb_sat = $$('tab_sat').getTabbar()
@ -184,7 +185,7 @@ function get_certificado(){
}
function get_cuentas_banco(){
function get_admin_cuentas_banco(){
webix.ajax().get('/values/monedasid', function(text, data){
var values = data.json()
@ -310,7 +311,7 @@ function multi_admin_change(prevID, nextID){
$$('tab_emisor').setValue('Datos Fiscales')
get_emisor()
get_certificado()
get_cuentas_banco()
get_admin_cuentas_banco()
return
}
@ -906,17 +907,18 @@ function cmd_emisor_agregar_cuenta_click(){
var values = form.getValues()
var si = parseFloat(values.emisor_cuenta_saldo_inicial.replace('$', '').replace(',', ''))
var saldo_inicial = parseFloat(values.emisor_cuenta_saldo_inicial.replace('$', '').replace(',', ''))
var cuenta = {
de_emisor: true,
activa: true,
nombre: values.emisor_cuenta_nombre.trim(),
banco: values.emisor_banco,
fecha_apertura: values.emisor_cuenta_fecha,
fecha_deposito: values.emisor_fecha_saldo,
cuenta: values.emisor_cuenta.trim(),
clabe: values.emisor_clabe.trim(),
moneda: values.emisor_cuenta_moneda,
saldo_inicial: si
saldo_inicial: saldo_inicial
}
if(!cuenta.nombre){
@ -979,6 +981,7 @@ function cmd_emisor_agregar_cuenta_click(){
var values = data.json()
if(values.ok){
$$('grid_emisor_cuentas_banco').add(values.row)
form.setValues({})
}else{
msg_error(values.msg)
}
@ -1096,10 +1099,13 @@ function borrar_impuesto(row){
var grid = $$('grid_admin_taxes')
webix.ajax().del('/values/satimpuesto', {id: row}, function(text, xml, xhr){
var msg = 'Impuesto eliminado correctamente'
msg = 'Impuesto eliminado correctamente'
if(xhr.status == 200){
grid.remove(row)
msg_sucess(msg)
}else{
msg = 'Impuesto en uso, no se pudo eliminar.'
msg_sucess(msg)
}
})
}
@ -1125,3 +1131,57 @@ function grid_admin_taxes_click(id, e, node){
})
}
function eliminar_cuenta_banco(id){
var grid = $$('grid_emisor_cuentas_banco')
webix.ajax().del('/cuentasbanco', {id: id}, function(text, xml, xhr){
msg = 'Cuenta eliminada correctamente'
if(xhr.status == 200){
grid.remove(id)
msg_sucess(msg)
}else{
msg = 'No se pudo eliminar'
msg_error(msg)
}
})
}
function cmd_emisor_eliminar_cuenta_click(){
var respuesta = undefined
var row = $$('grid_emisor_cuentas_banco').getSelectedItem()
if (row == undefined){
msg = 'Selecciona una cuenta de banco'
msg_error(msg)
return
}
webix.ajax().sync().get('/values/ebancomov', {id: row['id']}, function(text, data){
respuesta = data.json()
})
if(respuesta.ok){
msg = 'La cuenta tiene movimientos, no se puede eliminar'
msg_error(msg)
return
}
var msg = '¿Estás seguro de eliminar la cuenta de banco?<BR><BR>'
msg += row['banco'] + ' (' + row['cuenta'] + ')'
msg += '<BR><BR>ESTA ACCIÓN NO SE PUEDE DESHACER'
webix.confirm({
title: 'Eliminar Cuenta de Banco',
ok: 'Si',
cancel: 'No',
type: 'confirm-error',
text: msg,
callback:function(result){
if (result){
eliminar_cuenta_banco(row['id'])
}
}
})
}

View File

@ -0,0 +1,106 @@
var msg = ''
var bancos_controllers = {
init: function(){
$$('lst_cuentas_banco').attachEvent('onChange', lst_cuentas_banco_change)
$$('cmd_agregar_retiro').attachEvent('onItemClick', cmd_agregar_retiro_click)
$$('cmd_agregar_deposito').attachEvent('onItemClick', cmd_agregar_deposito_click)
set_year_month()
}
}
function set_year_month(){
var d = new Date()
var y = $$('filtro_cuenta_year')
var m = $$('filtro_cuenta_mes')
webix.ajax().get('/values/cuentayears', {
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()
y.getList().parse(values)
y.blockEvent()
m.blockEvent()
y.setValue(d.getFullYear())
m.setValue(d.getMonth() + 1)
y.unblockEvent()
m.unblockEvent()
}
})
}
function get_cuentas_banco(){
var list = $$('lst_cuentas_banco')
webix.ajax().get('/cuentasbanco', {'tipo': 1}, {
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){
list.getList().parse(values.rows)
list.blockEvent()
list.setValue(values.rows[0].id)
list.unblockEvent()
$$('txt_cuenta_moneda').setValue(values.moneda)
$$('txt_cuenta_saldo').setValue(values.saldo)
get_estado_cuenta()
}
}
})
}
function get_estado_cuenta(rango){
if(rango == undefined){
var filtro = {
cuenta: $$('lst_cuentas_banco').getValue(),
year: $$('filtro_cuenta_year').getValue(),
mes: $$('filtro_cuenta_mes').getValue(),
}
}else{
var filtro = {
cuenta: $$('lst_cuentas_banco').getValue(),
fechas: rango,
}
}
var grid = $$('grid_cuentabanco')
webix.ajax().get('/movbanco', filtro, {
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()
grid.clearAll()
if (values.ok){
grid.parse(values.rows, 'json')
}
}
})
}
function lst_cuentas_banco_change(nv, ov){
show('Cuenta change')
}
function cmd_agregar_retiro_click(){
show('Retiro')
}
function cmd_agregar_deposito_click(){
show('Depósito')
}

View File

@ -953,6 +953,8 @@ function get_invoices(rango){
}
var grid = $$('grid_invoices')
grid.showProgress({type: 'icon'})
webix.ajax().get('/invoices', rango, {
error: function(text, data, xhr) {
webix.message({type: 'error', text: 'Error al consultar'})

View File

@ -63,6 +63,10 @@ var controllers = {
$$('cmd_delete_preinvoice').attachEvent('onItemClick', cmd_delete_preinvoice_click)
$$('cmd_facturar_preinvoice').attachEvent('onItemClick', cmd_facturar_preinvoice_click)
$$('grid_preinvoices').attachEvent('onItemClick', grid_preinvoices_click)
webix.extend($$('grid_invoices'), webix.ProgressBar)
bancos_controllers.init()
}
}
@ -77,18 +81,18 @@ function get_uso_cfdi_to_table(){
function get_partners(){
webix.ajax().get("/partners", {}, {
webix.ajax().get('/partners', {}, {
error: function(text, data, xhr) {
webix.message({ type:"error", text: "Error al consultar"});
webix.message({type: 'error', text: 'Error al consultar'});
},
success: function(text, data, xhr) {
var values = data.json();
$$("grid_partners").clearAll();
if (values.ok){
$$("grid_partners").parse(values.rows, 'json');
$$('grid_partners').clearAll();
if (values.data){
$$('grid_partners').parse(values.data, 'json');
};
}
});
})
}
@ -164,6 +168,14 @@ function multi_change(prevID, nextID){
return
}
if(nextID == 'app_bancos'){
active = $$('multi_bancos').getActiveId()
if(active == 'bancos_home'){
get_cuentas_banco()
}
return
}
if(nextID == 'app_invoices'){
active = $$('multi_invoices').getActiveId()
if(active == 'invoices_home'){

View File

@ -1,13 +1,21 @@
function get_categorias(){
webix.ajax().sync().get('/values/categorias', function(text, data){
var values = data.json()
$$('categoria').getList().parse(values, 'plainjs')
})
}
function cmd_new_product_click(id, e, node){
$$('form_product').setValues({
id: 0, es_activo_producto: true})
id: 0, es_activo_producto: true})
add_config({'key': 'id_product', 'value': ''})
get_new_key()
get_taxes()
get_categorias()
$$('grid_products').clearSelection()
$$('categoria').getList().load('/values/categorias')
$$('unidad').getList().load('/values/unidades')
$$("multi_products").setValue("product_new")
}

View File

@ -15,6 +15,23 @@ var table_usocfdi = db.addCollection('usocfdi')
var table_relaciones = db.addCollection('relaciones')
var months = [
{id: -1, value: 'Todos'},
{id: 1, value: 'Enero'},
{id: 2, value: 'Febrero'},
{id: 3, value: 'Marzo'},
{id: 4, value: 'Abril'},
{id: 5, value: 'Mayo'},
{id: 6, value: 'Junio'},
{id: 7, value: 'Julio'},
{id: 8, value: 'Agosto'},
{id: 9, value: 'Septiembre'},
{id: 10, value: 'Octubre'},
{id: 11, value: 'Noviembre'},
{id: 12, value: 'Diciembre'},
]
function show(values){
webix.message(JSON.stringify(values, null, 2))
}
@ -153,3 +170,29 @@ function get_config(value){
return key.value
}
}
webix.DataDriver.plainjs = webix.extend({
arr2hash:function(data){
var hash = {};
for (var i=0; i<data.length; i++){
var pid = data[i].parent_id;
if (!hash[pid]) hash[pid]=[];
hash[pid].push(data[i]);
}
return hash;
},
hash2tree:function(hash, level){
var top = hash[level];
for (var i=0; i<top.length; i++){
var branch = top[i].id;
if (hash[branch])
top[i].data = this.hash2tree(hash, branch);
}
return top;
},
getRecords:function(data, id){
var hash = this.arr2hash(data);
return this.hash2tree(hash, 0);
}
}, webix.DataDriver.json)

View File

@ -5,7 +5,8 @@ var menu_data = [
{id: 'app_folios', icon: 'sort-numeric-asc', value: 'Folios'},
{id: 'app_correo', icon: 'envelope-o', value: 'Correo'},
{id: 'app_sat', icon: 'table', value: 'Catalogos SAT'},
{id: 'app_options', icon: 'cog', value: 'Opciones'},
{id: 'app_options', icon: 'check-circle-o', value: 'Opciones'},
{id: 'app_utilidades', icon: 'cog', value: 'Utilidades'},
]
@ -163,13 +164,9 @@ var emisor_cuentas_banco = [
{view: 'form', id: 'form_emisor_cuenta_banco', rows: [
{cols: [
{view: 'text', id: 'emisor_cuenta_nombre', name: 'emisor_cuenta_nombre',
label: 'Nombre: ', required: true}, {}]},
{cols: [
label: 'Nombre: ', required: true},
{view: 'richselect', id: 'lst_emisor_banco', name: 'emisor_banco',
label: 'Banco: ', required: true, options: []},
{view: 'datepicker', id: 'emisor_cuenta_fecha', format: '%d-%M-%Y',
name: 'emisor_cuenta_fecha', label: 'Fecha de apertura: ',
required: true},
]},
{cols: [
{view: 'text', id: 'emisor_cuenta', name: 'emisor_cuenta',
@ -182,14 +179,25 @@ var emisor_cuentas_banco = [
name: 'emisor_cuenta_moneda', label: 'Moneda: ', required: true,
options: []},
{view: 'currency', type: 'text', id: 'emisor_cuenta_saldo_inicial',
name: 'emisor_cuenta_saldo_inicial', label: 'Saldo inicial',
name: 'emisor_cuenta_saldo_inicial', label: 'Saldo inicial: ',
required: true, invalidMessage: 'Captura un valor númerico',
inputAlign: 'right', value: ''},
]},
{cols: [
{view: 'datepicker', id: 'emisor_cuenta_fecha', format: '%d-%M-%Y',
name: 'emisor_cuenta_fecha', label: 'Fecha de apertura: ',
required: true},
{view: 'datepicker', id: 'emisor_fecha_saldo', format: '%d-%M-%Y',
name: 'emisor_fecha_saldo', label: 'Fecha saldo inicial: ',
required: true},
]},
{minHeight: 10},
{cols: [{}, {view: 'button', id: 'cmd_emisor_agregar_cuenta',
label: 'Agregar cuenta'}, {}]},
{cols: [{},
{view: 'button', id: 'cmd_emisor_agregar_cuenta',
label: 'Agregar cuenta'}, {},
{view: 'button', id: 'cmd_emisor_eliminar_cuenta',
label: 'Eliminar cuenta'},
{}]},
],
rules: {

View File

@ -0,0 +1,78 @@
var toolbar_banco = [
{view: 'richselect', id: 'lst_cuentas_banco', label: 'Cuenta',
labelWidth: 100, options: []},
{view: 'text', id: 'txt_cuenta_moneda', label: 'Moneda', readonly: true},
{view: 'currency', id: 'txt_cuenta_saldo', label: 'Saldo', readonly: true,
inputAlign: 'right', value: 0}
]
var toolbar_filtro_cuenta = [
{view: 'richselect', id: 'filtro_cuenta_year', label: 'Año',
labelAlign: 'right', labelWidth: 50, width: 150, options: []},
{view: 'richselect', id: 'filtro_cuenta_mes', label: 'Mes',
labelAlign: 'right', labelWidth: 50, width: 200, options: months},
{view: 'daterangepicker', id: 'filtro_cuenta_fechas', label: 'Fechas',
labelAlign: 'right', width: 300},
{},
{view: 'button', id: 'cmd_agregar_retiro', label: 'Retiro',
type: 'iconButton', autowidth: true, icon: 'minus'},
{view: 'button', id: 'cmd_agregar_deposito', label: 'Depósito',
type: 'iconButton', autowidth: true, icon: 'plus'},
]
var grid_cuentabanco_cols = [
{id: 'id', header:'ID', hidden: true},
{id: 'fecha', header: 'Fecha', width: 150},
{id: 'numero_operacion', header: 'Referencia'},
{id: 'descripcion', header: ['Descripción', {content: 'textFilter'}],
fillspace:true},
{id: 'retiro', header: ['Retiro', {content: 'numberFilter'}],
width: 125, format: webix.i18n.priceFormat, css: 'right'},
{id: 'deposito', header: ['Depósito', {content: 'numberFilter'}],
width: 125, format: webix.i18n.priceFormat, css: 'right'},
{id: 'saldo', header: ['Saldo'],
width: 125, format: webix.i18n.priceFormat, css: 'right'},
]
var grid_cuentabanco = {
view: 'datatable',
id: 'grid_cuentabanco',
select: 'row',
adjust: true,
footer: true,
resizeColumn: true,
headermenu: true,
columns: grid_cuentabanco_cols,
}
var multi_bancos = {
id: 'multi_bancos',
animate: true,
cells:[
{id: 'bancos_home', rows:[
{view: 'toolbar', elements: toolbar_banco},
{view: 'toolbar', elements: toolbar_filtro_cuenta},
grid_cuentabanco,
]}
//~ {id: 'partners_new', rows:[form_partner]}
],
}
var title_partners = 'Administración de Bancos'
var app_bancos = {
id: 'app_bancos',
rows:[
{view: 'template', id: 'th_bancos', type: 'header',
template: title_partners},
multi_bancos
]
}

View File

@ -1,20 +1,4 @@
var months = [
{id: -1, value: 'Todos'},
{id: 1, value: 'Enero'},
{id: 2, value: 'Febrero'},
{id: 3, value: 'Marzo'},
{id: 4, value: 'Abril'},
{id: 5, value: 'Mayo'},
{id: 6, value: 'Junio'},
{id: 7, value: 'Julio'},
{id: 8, value: 'Agosto'},
{id: 9, value: 'Septiembre'},
{id: 10, value: 'Octubre'},
{id: 11, value: 'Noviembre'},
{id: 12, value: 'Diciembre'},
]
var grid_cfdi_cliente_cols = [
{id: 'index', header: '#', adjust: 'data', css: 'right',
@ -253,15 +237,15 @@ var grid_details_cols = [
fillspace: true, editor: 'text'},
{id: "unidad", header:{text: 'Unidad', css: 'center'}, width: 100},
{id: 'cantidad', header: {text: 'Cantidad', css: 'center'}, width: 100,
format: webix.i18n.numberFormat, css:'right', editor: 'text'},
format: webix.i18n.numberFormat, css: 'right', editor: 'text'},
{id: "valor_unitario", header:{text: 'Valor Unitario', css: 'center'},
width: 100, format: webix.i18n.priceFormat, css:'right', editor: 'text'},
width: 100, format: webix.i18n.priceFormat, css: 'right', editor: 'text'},
{id: 'descuento', header:{text: 'Descuento', css: 'center'},
width: 80, format: webix.i18n.priceFormat, css:'right', editor: 'text'},
width: 80, format: webix.i18n.priceFormat, css: 'right', editor: 'text'},
{id: 'precio_final', hidden: true, header: 'precio_final', width: 80,
format: webix.i18n.priceFormat, css:'right'},
format: webix.i18n.priceFormat, css: 'right'},
{id: "importe", header:{text: 'Importe', css: 'center'}, width: 150,
format: webix.i18n.priceFormat, css:'right'},
format: webix.i18n.priceFormat, css: 'right'},
]
@ -556,6 +540,7 @@ var form_invoice = {
view: 'form',
id: 'form_invoice',
complexData: true,
scroll: true,
elements: controls_invoices,
}]
}
@ -572,7 +557,7 @@ var multi_invoices = {
{view: 'toolbar', elements: toolbar_invoices_filter},
grid_invoices,
]},
{id: 'invoices_new', rows:[form_invoice, {}]}
{id: 'invoices_new', rows:[form_invoice]}
]
}

View File

@ -1,10 +1,12 @@
var menu_data = [
{id: 'app_home', icon: 'dashboard', value: 'Inicio'},
{id: 'app_partners', icon: 'users', value: 'Clientes y Proveedores'},
{id: 'app_products', icon: 'server', value: 'Productos y Servicios'},
{id: 'app_bancos', icon: 'university', value: 'Bancos'},
{id: 'app_invoices', icon: 'cart-plus', value: 'Facturas'},
];
]
var sidebar = {
@ -18,8 +20,8 @@ var sidebar = {
onAfterSelect: function(id){
$$('multi').setValue(id)
}
}
};
},
}
var multi_main = {
@ -33,9 +35,10 @@ var multi_main = {
},
app_partners,
app_products,
app_bancos,
app_invoices,
]
};
],
}
var menu_user = {
@ -49,7 +52,8 @@ var menu_user = {
type: {
subsign: true,
},
};
}
var ui_main = {
rows: [

View File

@ -11,10 +11,10 @@ var toolbar_partners = [
var grid_partners_cols = [
{id: 'index', header:'#', adjust:'data', css: 'right',
{id: 'index', header:'#', css: 'right',
footer: {content: 'rowCount', colspan: 2, css: 'right'}},
{id: 'id', header: 'Clave', adjust:'data', sort: 'int', css: 'right'},
{id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust:'data',
{id: 'id', header: 'Clave', sort: 'int', css: 'right'},
{id: 'rfc', header: ['RFC', {content: 'textFilter'}],
sort: 'string', footer: {text: 'Clientes y Proveedores', colspan: 2}},
{id: 'nombre', header: ['Razón Social', {content: 'textFilter'}],
fillspace:true, sort: 'string'},
@ -32,6 +32,15 @@ var grid_partners = {
resizeColumn: true,
headermenu: true,
columns: grid_partners_cols,
pager: 'pager_clientes',
//~ datafetch: 100,
//~ loadahead: 100,
//~ url: '/partners',
ready:function(){
this.adjustColumn('index');
this.adjustColumn('id');
this.adjustColumn('rfc');
},
on:{
'data->onStoreUpdated':function(){
this.data.each(function(obj, i){
@ -286,12 +295,12 @@ var form_partner = {
view: 'form',
id: 'form_partner',
complexData: true,
scroll: true,
elements: controls_partner,
elementsConfig: {
labelWidth: 150,
labelAlign: 'right'
},
autoheight: true,
rules: {
nombre: function(value){ return value.trim() != '';},
rfc: validate_rfc,
@ -300,6 +309,15 @@ var form_partner = {
}
var pager_clientes = {
view: "pager",
id: "pager_clientes",
template: "{common.prev()} {common.pages()} {common.next()}",
size: 100,
group: 10,
}
var multi_partners = {
id: 'multi_partners',
animate: true,
@ -307,8 +325,9 @@ var multi_partners = {
{id: 'partners_home', rows:[
{view: 'toolbar', elements: toolbar_partners},
grid_partners,
pager_clientes,
]},
{id: 'partners_new', rows:[form_partner, {}]}
{id: 'partners_new', rows:[form_partner]}
]
}

View File

@ -13,9 +13,9 @@ var toolbar_products = [
var grid_products_cols = [
{ id: "id", header: "ID", width: 75},
{ id: "clave", header: ["Clave", {content: "textFilter"}], width: 100,
sort:"string" },
sort: 'string', footer: {content: 'rowCount', css: 'right'}},
{ id: "descripcion", header: ["Descripción", {content: "textFilter"}],
fillspace:true, sort:"string" },
fillspace:true, sort: 'string', footer: 'Productos y Servicios'},
{ id: "unidad", header: ["Unidad", {content: "selectFilter"}], width: 150,
sort:"string" },
{ id: "valor_unitario", header: ["Precio", {content: "numberFilter"}], width: 150,
@ -34,6 +34,7 @@ var grid_products = {
columns: grid_products_cols,
}
var suggest_categories = {
view: 'datasuggest',
type: 'tree',
@ -85,7 +86,7 @@ var suggest_sat_producto = {
this.hide()
}
}
}
},
}
@ -95,7 +96,7 @@ var controls_generals = [
bottomLabel: 'Se recomienda solo desactivar y no eliminar'},
{cols: [
{view: 'combo', id: 'categoria', name: 'categoria', label: 'Categoría',
labelPosition: 'top', options: suggest_categories},
labelPosition: 'top', suggest: suggest_categories},
{view: 'text', id: 'clave', name: 'clave', label: 'Clave',
labelPosition: 'top', readonly: true, required: true},
{view: 'checkbox', id: 'chk_automatica', label: 'Automática',
@ -163,7 +164,7 @@ var form_product = {
cols: [{
view: "form",
id: "form_product",
//~ width: 600,
scroll: true,
complexData: true,
elements: controls_products,
rules: {
@ -182,7 +183,7 @@ var multi_products = {
{view:"toolbar", elements: toolbar_products},
grid_products,
]},
{id: "product_new", rows:[form_product, {}]}
{id: "product_new", rows:[form_product]}
],
}

View File

@ -7,11 +7,13 @@
<script src="/static/js/controller/util.js" type="text/javascript" ></script>
<script src="/static/js/ui/partners.js" type="text/javascript" ></script>
<script src="/static/js/ui/products.js" type="text/javascript" ></script>
<script src="/static/js/ui/bancos.js" type="text/javascript" ></script>
<script src="/static/js/ui/invoices.js" type="text/javascript" ></script>
<script src="/static/js/ui/main.js" type="text/javascript" ></script>
<script src="/static/js/controller/partners.js" type="text/javascript" ></script>
<script src="/static/js/controller/products.js" type="text/javascript" ></script>
<script src="/static/js/controller/bancos.js" type="text/javascript" ></script>
<script src="/static/js/controller/invoices.js" type="text/javascript" ></script>
<script src="/static/js/controller/main.js" type="text/javascript" ></script>