diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py
index ce8bedc..5fcbe6a 100644
--- a/source/app/controllers/main.py
+++ b/source/app/controllers/main.py
@@ -173,3 +173,26 @@ class AppEmisor(object):
resp.status = falcon.HTTP_200
else:
resp.status = falcon.HTTP_204
+
+
+class AppFolios(object):
+
+ def __init__(self, db):
+ self._db = db
+
+ def on_get(self, req, resp):
+ values = req.params
+ req.context['result'] = self._db.get_folios()
+ resp.status = falcon.HTTP_200
+
+ def on_post(self, req, resp):
+ values = req.params
+ req.context['result'] = self._db.add_folios(values)
+ resp.status = falcon.HTTP_200
+
+ def on_delete(self, req, resp):
+ values = req.params
+ if self._db.delete('folios', values['id']):
+ resp.status = falcon.HTTP_200
+ else:
+ resp.status = falcon.HTTP_204
diff --git a/source/app/main.py b/source/app/main.py
index 7f00a2d..f701a7f 100644
--- a/source/app/main.py
+++ b/source/app/main.py
@@ -14,7 +14,7 @@ from middleware import (
from models.db import StorageEngine
from controllers.main import (
AppLogin, AppLogout, AppAdmin, AppEmisor,
- AppMain, AppValues, AppPartners, AppProducts, AppInvoices
+ AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios
)
from settings import DEBUG
@@ -34,6 +34,7 @@ api.add_route('/', AppLogin(db))
api.add_route('/logout', AppLogout(db))
api.add_route('/admin', AppAdmin(db))
api.add_route('/emisor', AppEmisor(db))
+api.add_route('/folios', AppFolios(db))
api.add_route('/main', AppMain(db))
api.add_route('/values/{table}', AppValues(db))
api.add_route('/partners', AppPartners(db))
diff --git a/source/app/models/db.py b/source/app/models/db.py
index 3a9f4f1..81d45ec 100644
--- a/source/app/models/db.py
+++ b/source/app/models/db.py
@@ -51,7 +51,7 @@ class StorageEngine(object):
return main.SATMonedas.get_activos()
def _get_regimenes(self, values):
- return main.Emisor.get_regimenes(values)
+ return main.Emisor.get_regimenes()
def _get_usocfdi(self, values):
return main.SATUsoCfdi.get_activos(values)
@@ -63,6 +63,8 @@ class StorageEngine(object):
return main.Productos.remove(id)
if table == 'invoice':
return main.Facturas.remove(id)
+ if table == 'folios':
+ return main.Folios.remove(id)
return False
def _get_client(self, values):
@@ -107,4 +109,9 @@ class StorageEngine(object):
def emisor(self, values):
return main.Emisor.add(values)
+ def get_folios(self):
+ return main.Folios.get_()
+
+ def add_folios(self, values):
+ return main.Folios.add(values)
diff --git a/source/app/models/main.py b/source/app/models/main.py
index 52f7e62..65a8f5e 100644
--- a/source/app/models/main.py
+++ b/source/app/models/main.py
@@ -4,6 +4,7 @@ import sqlite3
import click
from peewee import *
from playhouse.fields import PasswordField, ManyToManyField
+from playhouse.shortcuts import case
if __name__ == '__main__':
@@ -314,7 +315,7 @@ class Folios(BaseModel):
serie = TextField(unique=True)
inicio = IntegerField(default=1)
default = BooleanField(default=False)
- usar_con = TextField(default='')
+ usarcon = TextField(default='')
class Meta:
order_by = ('-default', 'serie', 'inicio')
@@ -328,12 +329,69 @@ class Folios(BaseModel):
.select(
Folios.id,
Folios.serie.alias('value'),
- Folios.usar_con,
+ Folios.usarcon,
)
.dicts()
)
return tuple(rows)
+ @classmethod
+ def get_(cls):
+ rows = (Folios
+ .select(
+ Folios.id,
+ SQL(" '-' AS 'delete' "),
+ Folios.serie,
+ Folios.inicio,
+ case(Folios.usarcon, (
+ ('I', 'Ingreso'),
+ ('E', 'Egreso'),
+ ('T', 'Traslado'),
+ ), 'Todos').alias('usarcon'),
+ case(Folios.default, (
+ (True, 'Si'),
+ (False, 'No'),
+ )).alias('pre')
+ )
+ .dicts()
+ )
+ return tuple(rows)
+
+ @classmethod
+ def add(cls, values):
+ uc = {
+ '': 'Todos',
+ 'I': 'Ingreso',
+ 'E': 'Egreso',
+ 'T': 'Traslado',
+ }
+ pre = {
+ True: 'Si',
+ False: 'No',
+ }
+
+ if 'default' in values:
+ values['default'] = True
+ try:
+ obj = Folios.create(**values)
+ except IntegrityError:
+ msg = 'Serie ya existe'
+ return {'ok': False, 'msg': msg}
+ row = {
+ 'id': obj.id,
+ 'delete' : '-',
+ 'serie' : obj.serie,
+ 'inicio' : obj.inicio,
+ 'usarcon' : uc[obj.usarcon],
+ 'pre' : pre[obj.default],
+ }
+ return {'ok': True, 'row': row}
+
+ @classmethod
+ def remove(cls, id):
+ q = Folios.delete().where(Folios.id==id)
+ return bool(q.execute())
+
class Categorias(BaseModel):
categoria = TextField()
@@ -369,7 +427,7 @@ class SATUnidades(BaseModel):
default = BooleanField(default=False)
class Meta:
- order_by = ('name',)
+ order_by = ('-default', 'name')
indexes = (
(('key', 'name'), True),
)
diff --git a/source/static/js/controller/admin.js b/source/static/js/controller/admin.js
index 89a026a..4743426 100644
--- a/source/static/js/controller/admin.js
+++ b/source/static/js/controller/admin.js
@@ -1,6 +1,5 @@
var msg = ''
-var reg = /^[a-z]+$/i
-//~ reg.test("somethingELSE")
+
var controllers = {
init: function(){
@@ -15,6 +14,8 @@ var controllers = {
$$('chk_ong').attachEvent('onChange', chk_ong_change)
$$('cmd_subir_certificado').attachEvent('onItemClick', cmd_subir_certificado_click)
$$('up_cert').attachEvent('onUploadComplete', up_cert_upload_complete)
+ $$('cmd_agregar_serie').attachEvent('onItemClick', cmd_agregar_serie_click)
+ $$('grid_folios').attachEvent('onItemClick', grid_folios_click)
}
}
@@ -159,6 +160,21 @@ function get_certificado(){
}
+function get_table_folios(){
+ webix.ajax().get("/folios", {}, {
+ error: function(text, data, xhr) {
+ msg = 'Error al consultar'
+ msg_error(msg)
+ },
+ success: function(text, data, xhr) {
+ var values = data.json()
+ $$('grid_folios').parse(values)
+ }
+ })
+
+}
+
+
function multi_admin_change(prevID, nextID){
//~ webix.message(nextID)
if(nextID == 'app_emisor'){
@@ -168,6 +184,10 @@ function multi_admin_change(prevID, nextID){
return
}
+ if(nextID == 'app_folios'){
+ get_table_folios()
+ return
+ }
}
@@ -336,3 +356,93 @@ function up_cert_upload_complete(response){
}
})
}
+
+
+function cmd_agregar_serie_click(){
+ var form = $$('form_folios')
+ var grid = $$('grid_folios')
+
+ if (!form.validate()){
+ msg = 'Valores inválidos'
+ msg_error(msg)
+ return
+ }
+
+ var values = form.getValues()
+
+ var reg = /^[a-z]+$/i
+ if(!reg.test(values.folio_serie)){
+ msg = 'Introduce una serie válida. Solo letras.'
+ msg_error(msg)
+ return
+ }
+
+ var pre = '1'
+ if(grid.count() > 0){
+ pre = ''
+ }
+
+ var usarcon = ''
+ if(values.folio_usarcon != 'S'){
+ usarcon = values.folio_usarcon
+ }
+
+ var values = {
+ serie: values.folio_serie.trim().toUpperCase(),
+ inicio: values.folio_inicio,
+ usarcon: usarcon,
+ default: pre,
+ }
+
+ webix.ajax().post('/folios', values, {
+ 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){
+ form.setValues(
+ {folio_serie: '', folio_inicio: 1, folio_usarcon: 'S'})
+ grid.add(values.row)
+ msg = 'Serie agregada correctamente'
+ msg_sucess(msg)
+ }else{
+ msg_error(values.msg)
+ }
+ }
+ })
+}
+
+
+function grid_folios_click(id, e, node){
+ if(id.column != 'delete'){
+ return
+ }
+
+ msg = '¿Estás seguro de borrar esta serie?
ESTA ACCIÓN NO SE PUEDE DESHACER'
+ webix.confirm({
+ title: 'Borrar Serie',
+ ok: 'Si',
+ cancel: 'No',
+ type: 'confirm-error',
+ text: msg,
+ callback:function(result){
+ if(result){
+ webix.ajax().del('/folios', {id: id.row}, function(text, xml, xhr){
+ msg = 'Serie eliminada correctamente'
+ if(xhr.status == 200){
+ $$('grid_folios').remove(id.row)
+ msg_sucess(msg)
+ }else{
+ msg = 'No se pudo eliminar'
+ msg_error(msg)
+ }
+ })
+
+
+
+ }
+ }
+ })
+}
diff --git a/source/static/js/ui/admin.js b/source/static/js/ui/admin.js
index d064eef..9ca919d 100644
--- a/source/static/js/ui/admin.js
+++ b/source/static/js/ui/admin.js
@@ -170,7 +170,7 @@ var grid_folios_cols = [
{id: 'serie', header: 'Serie', fillspace: 1},
{id: 'inicio', header: 'Inicio', fillspace: 1},
{id: 'usarcon', header: 'Usar Con', fillspace: 1},
- {id: 'default', header: 'Predeterminado', fillspace: 1}
+ {id: 'pre', header: 'Predeterminado', fillspace: 1}
]
@@ -190,7 +190,7 @@ var emisor_folios = [
{view: 'text', id: 'folio_serie', name: 'folio_serie', label: 'Serie: ',
required: true, attributes: {maxlength: 15}},
{view: 'counter', id: 'folio_inicio', name: 'folio_inicio', value: 1,
- required: true, label: 'Inicio: ', step: 5, min: 1},
+ required: true, label: 'Inicio: ', step: 1, min: 1},
{view: 'richselect', id: 'folio_usarcon', name: 'folio_usarcon',
label: 'Usar Con: ', value: 'S', required: true,
options: options_usarcon},
@@ -232,7 +232,8 @@ var form_folios = {
},
autoheight: true,
rules: {
- serie: function(value){return value.trim() != ''},
+ folio_serie: function(value){return value.trim() != ''},
+ folio_inicio: function(value){return value > 0},
}
}]
}
diff --git a/source/templates/admin.html b/source/templates/admin.html
index cd660d3..9b89966 100644
--- a/source/templates/admin.html
+++ b/source/templates/admin.html
@@ -2,6 +2,7 @@
<%block name="media">
+