From c21d14fe35d5cc95c06b76993349695c426c003b Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Mon, 29 Jan 2018 01:55:42 -0600 Subject: [PATCH] Agregar alumnos --- source/app/controllers/main.py | 23 +++++ source/app/main.py | 3 +- source/app/models/db.py | 8 ++ source/app/models/main.py | 42 +++++++- source/static/js/controller/main.js | 21 +++- source/static/js/controller/school.js | 70 +++++++++++++ source/static/js/controller/util.js | 6 ++ source/static/js/ui/main.js | 1 + source/static/js/ui/school.js | 143 ++++++++++++++++++++++++++ source/templates/main.html | 2 + 10 files changed, 315 insertions(+), 4 deletions(-) create mode 100644 source/static/js/controller/school.js create mode 100644 source/static/js/ui/school.js diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py index 4192e3b..59cb9e1 100644 --- a/source/app/controllers/main.py +++ b/source/app/controllers/main.py @@ -221,6 +221,29 @@ class AppPartners(object): resp.status = falcon.HTTP_204 +class AppStudents(object): + + def __init__(self, db): + self._db = db + + def on_get(self, req, resp): + values = req.params + req.context['result'] = self._db.get_students(values) + resp.status = falcon.HTTP_200 + + def on_post(self, req, resp): + values = req.params + req.context['result'] = self._db.students(values) + resp.status = falcon.HTTP_200 + + def on_delete(self, req, resp): + values = req.params + if self._db.delete('students', values['id']): + resp.status = falcon.HTTP_200 + else: + resp.status = falcon.HTTP_204 + + class AppProducts(object): def __init__(self, db): diff --git a/source/app/main.py b/source/app/main.py index 2aa6e39..21c96ee 100644 --- a/source/app/main.py +++ b/source/app/main.py @@ -16,7 +16,7 @@ from controllers.main import (AppEmpresas, AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig, AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios, AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco, - AppMovimientosBanco, AppTickets + AppMovimientosBanco, AppTickets, AppStudents ) @@ -52,6 +52,7 @@ api.add_route('/preinvoices', AppPreInvoices(db)) api.add_route('/tickets', AppTickets(db)) api.add_route('/cuentasbanco', AppCuentasBanco(db)) api.add_route('/movbanco', AppMovimientosBanco(db)) +api.add_route('/students', AppStudents(db)) # ~ Activa si usas waitress y NO estas usando servidor web diff --git a/source/app/models/db.py b/source/app/models/db.py index 98fce0d..0e6b1f0 100644 --- a/source/app/models/db.py +++ b/source/app/models/db.py @@ -299,6 +299,14 @@ class StorageEngine(object): #~ return main.PreFacturas.actualizar(values, id) return main.PreFacturas.add(values) + def get_students(self, values): + return main.Alumnos.get_by(values) + + def students(self, values): + opt = values.pop('opt') + if opt == 'add': + return main.Alumnos.add(values['values']) + def tickets(self, values, user): opt = values.pop('opt') if opt == 'add': diff --git a/source/app/models/main.py b/source/app/models/main.py index 136ffb3..f5b4cb5 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -195,12 +195,13 @@ def config_main(): punto_de_venta = util.get_bool(Configuracion.get_('chk_usar_punto_de_venta')) data = { 'empresa': get_title_app(3), - 'punto_de_venta': punto_de_venta - + 'punto_de_venta': punto_de_venta, + 'escuela': False, } if not obj is None: titulo = '{} - {}' data['empresa'] = titulo.format(data['empresa'], obj.nombre) + data['escuela'] = obj.es_escuela return data @@ -2154,6 +2155,43 @@ class Alumnos(BaseModel): class Meta: order_by = ('nombre', 'paterno') + def _clean(self, values): + fields = util.clean(util.loads(values)) + fields['rfc'] = fields['rfc'].upper() + fields['curp'] = fields['curp'].upper() + fields['nombre'] = util.spaces(fields['nombre']) + fields['paterno'] = util.spaces(fields['paterno']) + fields['materno'] = util.spaces(fields['materno']) + return fields + + def _get(self, where): + rows = (Alumnos + .select() + .where(where) + .dicts() + ) + return tuple(rows) + + @classmethod + def get_by(cls, values): + if not values: + w = None + + return cls._get(cls, w) + + @classmethod + def add(cls, values): + fields = cls._clean(cls, values) + try: + obj = Alumnos.create(**fields) + except IntegrityError as e: + msg = 'Ya existe un alumno con este CURP' + data = {'ok': False, 'msg': msg} + return data + + data = {'ok': True} + return data + class AlumnosParientes(BaseModel): alumno = ForeignKeyField(Alumnos) diff --git a/source/static/js/controller/main.js b/source/static/js/controller/main.js index d2bbf9e..5e4575d 100644 --- a/source/static/js/controller/main.js +++ b/source/static/js/controller/main.js @@ -10,12 +10,21 @@ function configuracion_inicial(){ var values = data.json() $$('lbl_title_main').setValue(values.empresa) //~ showvar() + var pos = 4 + if(values.escuela){ + var node = { + id: 'app_school', + icon: 'graduation-cap', + value: 'Escuela'} + $$('main_sidebar').add(node, pos) + pos += 1 + } if(values.punto_de_venta){ var node = { id: 'app_tickets', icon: 'money', value: 'Punto de venta'} - $$('main_sidebar').add(node, 4) + $$('main_sidebar').add(node, pos) } }) @@ -45,6 +54,7 @@ var controllers = { products_controllers.init() bancos_controllers.init() invoices_controllers.init() + controllers_school.init() tickets_controllers.init() } } @@ -113,6 +123,7 @@ function current_dates(){ function multi_change(prevID, nextID){ + if(nextID == 'app_partners'){ active = $$('multi_partners').getActiveId() if(active == 'partners_home'){ @@ -137,6 +148,14 @@ function multi_change(prevID, nextID){ return } + if(nextID == 'app_school'){ + active = $$('multi_school').getActiveId() + if(active == 'school_home'){ + init_config_school() + } + return + } + if(nextID == 'app_tickets'){ active = $$('multi_tickets').getActiveId() if(active == 'tickets_home'){ diff --git a/source/static/js/controller/school.js b/source/static/js/controller/school.js new file mode 100644 index 0000000..5f5a080 --- /dev/null +++ b/source/static/js/controller/school.js @@ -0,0 +1,70 @@ + + +var controllers_school = { + init: function(){ + $$('cmd_new_student').attachEvent('onItemClick', cmd_new_student_click) + $$('cmd_save_student').attachEvent('onItemClick', cmd_save_student_click) + $$('cmd_cancel_student').attachEvent('onItemClick', cmd_cancel_student_click) + } +} + + +function init_config_school(){ + get_students() +} + + +function cmd_new_student_click(){ + $$('grid_students').clearSelection() + $$('multi_school').setValue('new_student') +} + + +function cmd_cancel_student_click(){ + $$('multi_school').setValue('school_home') +} + + +function cmd_save_student_click(){ + var msg = 'Valores inválidos' + var form = this.getFormView(); + + if (!form.validate()) { + msg_error(msg) + return + } + + var values = form.getValues(); + + webix.ajax().post('/students', {opt: 'add', values: 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({}) + $$('multi_school').setValue('school_home') + get_students() + } else { + msg_error(values.msg) + } + } + }) + +} + + +function get_students(){ + webix.ajax().get('/students', {}, { + error: function(text, data, xhr) { + msg_error('Error al consultar') + }, + success: function(text, data, xhr) { + var values = data.json() + $$('grid_students').clearAll() + $$('grid_students').parse(values) + } + }) +} \ No newline at end of file diff --git a/source/static/js/controller/util.js b/source/static/js/controller/util.js index 0081054..de495ba 100644 --- a/source/static/js/controller/util.js +++ b/source/static/js/controller/util.js @@ -377,6 +377,12 @@ function validate_pedimento(value){ } +function validate_curp(value){ + var pattern = '[A-Z][A,E,I,O,U,X][A-Z]{2}[0-9]{2}[0-1][0-9][0-3][0-9][M,H][A-Z]{2}[B,C,D,F,G,H,J,K,L,M,N,Ñ,P,Q,R,S,T,V,W,X,Y,Z]{3}[0-9,A-Z][0-9]' + return validate_regexp(value, pattern) +} + + //config may as well include only text, color and date hash webix.editors.$popup = { text:{ diff --git a/source/static/js/ui/main.js b/source/static/js/ui/main.js index cd6bdaf..7462eae 100644 --- a/source/static/js/ui/main.js +++ b/source/static/js/ui/main.js @@ -37,6 +37,7 @@ var multi_main = { app_partners, app_products, app_bancos, + app_school, app_tickets, app_invoices, ], diff --git a/source/static/js/ui/school.js b/source/static/js/ui/school.js new file mode 100644 index 0000000..2af1a23 --- /dev/null +++ b/source/static/js/ui/school.js @@ -0,0 +1,143 @@ + + + + +var toolbar_students = [ + {view: 'button', id: 'cmd_new_student', label: 'Nuevo', type: 'iconButton', + autowidth: true, icon: 'user-plus'}, + {view: 'button', id: 'cmd_edit_student', label: 'Editar', type: 'iconButton', + autowidth: true, icon: 'user'}, + {view: 'button', id: 'cmd_delete_student', label: 'Eliminar', type: 'iconButton', + autowidth: true, icon: 'user-times'}, +] + + +var grid_cols_students = [ + {id: 'index', header:'#', css: 'right', + footer: {content: 'countRows', colspan: 2, css: 'right'}}, + {id: 'id', header: 'Clave', sort: 'int', css: 'right'}, + {id: 'nombre', header: ['Nombre', {content: 'textFilter'}], + sort: 'string'}, + {id: 'paterno', header: ['A. Paterno', {content: 'textFilter'}], + sort: 'string'}, + {id: 'materno', header: ['A. Materno', {content: 'textFilter'}], + sort: 'string'}, + {id: 'rfc', header: ['RFC', {content: 'textFilter'}], adjust: 'data', + sort: 'string'}, + {id: 'curp', header: ['CURP'], sort: 'string'}, +] + + +var grid_students = { + view: 'datatable', + id: 'grid_students', + select: 'row', + adjust: true, + footer: true, + resizeColumn: true, + headermenu: true, + columns: grid_cols_students, + ready:function(){ + this.adjustColumn('index'); + this.adjustColumn('id'); + this.adjustColumn('nombre'); + this.adjustColumn('rfc'); + this.adjustColumn('curp'); + }, + on:{ + 'data->onStoreUpdated':function(){ + this.data.each(function(obj, i){ + obj.index = i+1; + }) + } + }, +} + + +var rows_school_home = [ + {view: 'toolbar', elements: toolbar_students}, + grid_students, +] + + +var student_controls_generales = [ + {view: 'text', id: 'student_name', name: 'nombre', label: 'Nombre: ', + required: true, invalidMessage: 'El nombre es requerido'}, + {view: 'text', id: 'student_paterno', name: 'paterno', label: 'Apellido Paterno: ', + required: true, invalidMessage: 'El apellido paterno es requerido'}, + {view: 'text', id: 'student_materno', name: 'materno', + label: 'Apellido Materno: '}, + {cols: [ + {view: 'text', id: 'student_rfc', name: 'rfc', label: 'RFC: ', + required: true, invalidMessage: 'RFC inválido', adjust: 'data', + attributes: {maxlength: 13}}, + {view: 'text', id: 'student_curp', name: 'curp', label: 'CURP: ', + required: true, invalidMessage: 'CURP inválido', adjust: 'data', + attributes: {maxlength: 20}}, + {}]}, +] + + +var form_controls_student = [ + { + view: 'tabview', + id: 'tab_student', + tabbar: {options: ['Datos Generales']}, animate: true, + cells: [ + {id: 'Datos Generales', rows: student_controls_generales}, + ] + }, + {rows: [ + { template:"", type: "section" }, + { margin: 10, cols: [{}, + {view: "button", id: "cmd_save_student", label: "Guardar" , + type: "form", autowidth: true, align: "center"}, + {view: "button", id: "cmd_cancel_student", label: "Cancelar" , + type: "danger", autowidth: true, align: "center"}, + {}] + }, + ]} +] + + +var form_student = { + type: 'space', + cols: [{ + view: 'form', + id: 'form_student', + complexData: true, + scroll: true, + elements: form_controls_student, + elementsConfig: { + labelWidth: 150, + labelAlign: 'right' + }, + rules: { + nombre: function(value){ return value.trim() != '';}, + rfc: validate_rfc, + curp: validate_curp, + } + }] +} + + +var multi_school = { + id: 'multi_school', + view: 'multiview', + animate: true, + cells:[ + {id: 'school_home', rows: rows_school_home}, + {id: 'school_groups', rows: []}, + {id: 'new_student', rows: [form_student]}, + ], +} + + +var app_school = { + id: 'app_school', + rows:[ + {view: 'template', id: 'th_school', type: 'header', + template: 'Administración de Escuela'}, + multi_school + ], +} diff --git a/source/templates/main.html b/source/templates/main.html index d5395ca..eb2a7aa 100644 --- a/source/templates/main.html +++ b/source/templates/main.html @@ -8,6 +8,7 @@ + @@ -15,6 +16,7 @@ +