From 33994b69707d245058f9bfe9ddcbe95ceb236cdc Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Fri, 19 Jan 2018 01:00:22 -0600 Subject: [PATCH] Importar empleados --- source/app/controllers/main.py | 23 +++++++++ source/app/controllers/util.py | 61 +++++++++++++++++++++-- source/app/main.py | 3 +- source/app/models/db.py | 3 ++ source/app/models/main.py | 17 ++++++- source/static/js/controller/nomina.js | 69 ++++++++++++++++++++++++++- source/static/js/ui/nomina.js | 34 ++++++++++++- 7 files changed, 201 insertions(+), 9 deletions(-) diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py index a342572..b1b0b1c 100644 --- a/source/app/controllers/main.py +++ b/source/app/controllers/main.py @@ -401,6 +401,29 @@ class AppFolios(object): resp.status = falcon.HTTP_204 +class AppEmployees(object): + + def __init__(self, db): + self._db = db + + def on_get(self, req, resp): + values = req.params + req.context['result'] = self._db.get_employees(values) + resp.status = falcon.HTTP_200 + + def on_post(self, req, resp): + values = req.params + req.context['result'] = self._db.employees(values) + resp.status = falcon.HTTP_200 + + def on_delete(self, req, resp): + values = req.params + if self._db.delete('employee', values['id']): + resp.status = falcon.HTTP_200 + else: + resp.status = falcon.HTTP_204 + + class AppDocumentos(object): def __init__(self, db): diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py index 8ac98bb..144689f 100644 --- a/source/app/controllers/util.py +++ b/source/app/controllers/util.py @@ -969,21 +969,49 @@ class LIBO(object): rows = [dict(zip(fields, r)) for r in data[1:]] return rows, '' - def invoice(self, path): + def employees(self, path): options = {'AsTemplate': True, 'Hidden': True} doc = self._doc_open(path, options) if doc is None: - return (), 'No se pudo abrir la plantilla' + return () - data, msg = self._get_data(doc) + data, msg = self._get_data(doc, 'Empleados') doc.close(True) if len(data) == 1: msg = 'Sin datos para importar' return (), msg - rows = tuple(data[1:]) - return rows, '' + fields = ( + 'num_empleado', + 'rfc', + 'curp', + 'nombre', + 'paterno', + 'materno', + 'fecha_ingreso', + 'imss', + 'tipo_contrato', + 'es_sindicalizado', + 'tipo_jornada', + 'tipo_regimen', + 'departamento', + 'puesto', + 'riesgo_puesto', + 'periodicidad_pago', + 'banco', + 'cuenta_bancaria', + 'clabe', + 'salario_base', + 'salario_diario', + 'estado', + 'codigo_postal', + 'notas', + 'correo', + ) + rows = [dict(zip(fields, r)) for r in data[1:]] + msg = 'Empleados importados correctamente' + return rows, msg def to_pdf(data, emisor_rfc, ods=False): @@ -1014,6 +1042,20 @@ def to_pdf(data, emisor_rfc, ods=False): return read_file(path) +def import_employees(rfc): + name = '{}_employees.ods'.format(rfc.lower()) + path = _join(PATH_MEDIA, 'tmp', name) + if not is_file(path): + return () + + if APP_LIBO: + app = LIBO() + if app.is_running: + return app.employees(path) + + return () + + def parse_xml(xml): return ET.fromstring(xml) @@ -1437,6 +1479,15 @@ def upload_file(rfc, opt, file_obj): name = '{}_invoice.ods'.format(rfc.lower()) path = _join(PATH_MEDIA, 'tmp', name) + elif opt == 'employees': + tmp = file_obj.filename.split('.') + ext = tmp[-1].lower() + if ext != 'ods': + msg = 'Extensión de archivo incorrecta, selecciona un archivo ODS' + return {'status': 'server', 'name': msg, 'ok': False} + + name = '{}_employees.ods'.format(rfc.lower()) + path = _join(PATH_MEDIA, 'tmp', name) if save_file(path, file_obj.file.read()): return {'status': 'server', 'name': file_obj.filename, 'ok': True} diff --git a/source/app/main.py b/source/app/main.py index 2aa6e39..a394349 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, AppEmployees ) @@ -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('/employees', AppEmployees(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 ad8f47c..77e21c3 100644 --- a/source/app/models/db.py +++ b/source/app/models/db.py @@ -11,6 +11,9 @@ class StorageEngine(object): def authenticate(self, args): return main.authenticate(args) + def get_employees(self, values): + return main.Empleados.get_by(values) + def empresa_agregar(self, values): return main.empresa_agregar(values['alta_rfc'], False) diff --git a/source/app/models/main.py b/source/app/models/main.py index 5a9ef2d..0a350f5 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -5195,9 +5195,9 @@ class Departamentos(BaseModel): class Puestos(BaseModel): + departamento = ForeignKeyField(Departamentos) nombre = TextField(default='') descripcion = TextField(default='') - departamento = ForeignKeyField(Departamentos) class Meta: order_by = ('nombre',) @@ -5244,6 +5244,21 @@ class Empleados(BaseModel): (('num_empleado', 'rfc'), True), ) + def _import(self): + emisor = Emisor.select()[0] + data, msg = util.import_employees(emisor.rfc) + if not data: + return {'ok': False, 'msg': msg} + + print ('DATA', data) + return {'ok': True, 'msg': msg} + + @classmethod + def get_by(cls, values): + # ~ print (values) + if values['opt'] == 'import': + return cls._import(cls) + class CfdiNomina(BaseModel): empleado = ForeignKeyField(Empleados) diff --git a/source/static/js/controller/nomina.js b/source/static/js/controller/nomina.js index eee5bb0..36ed648 100644 --- a/source/static/js/controller/nomina.js +++ b/source/static/js/controller/nomina.js @@ -48,5 +48,72 @@ function cmd_close_empleados_click(){ function cmd_import_empleados_click(){ - showvar('Importar') + win_import_employees.init() + $$('win_import_employees').show() +} + +function cmd_immport_employees_click(){ + var form = $$('form_upload_employees') + + var values = form.getValues() + + if(!$$('lst_upload_employees').count()){ + $$('win_import_employees').close() + return + } + + if($$('lst_upload_employees').count() > 1){ + msg = 'Selecciona solo un archivo' + msg_error(msg) + return + } + + var template = $$('up_employees').files.getItem($$('up_employees').files.getFirstId()) + + if(template.type.toLowerCase() != 'ods'){ + msg = 'Archivo inválido.\n\nSe requiere un archivo ODS' + msg_error(msg) + return + } + + msg = '¿Estás seguro de importar este archivo?' + webix.confirm({ + title: 'Importar Empleados', + ok: 'Si', + cancel: 'No', + type: 'confirm-error', + text: msg, + callback:function(result){ + if(result){ + $$('up_employees').send() + } + } + }) +} + + +function up_employees_upload_complete(response){ + if(response.status != 'server'){ + msg = 'Ocurrio un error al subir el archivo' + msg_error(msg) + return + } + msg = 'Archivo subido correctamente.\n\nComenzando importación.' + msg_ok(msg) + $$('win_import_employees').close() + + webix.ajax().get('/employees', {opt: 'import'}, { + error: function(text, data, xhr) { + msg = 'Error al importar' + msg_error(msg) + }, + success: function(text, data, xhr) { + var values = data.json(); + if (values.ok){ + msg_ok(values.msg) + }else{ + msg_error(values.msg) + } + } + }) } \ No newline at end of file diff --git a/source/static/js/ui/nomina.js b/source/static/js/ui/nomina.js index d665305..e42f37e 100644 --- a/source/static/js/ui/nomina.js +++ b/source/static/js/ui/nomina.js @@ -163,4 +163,36 @@ var app_nomina = { {view: 'template', type: 'header', template: 'Timbrado de Nómina'}, multi_nomina ], -} \ No newline at end of file +} + + +var body_import_employees = {rows: [ + {view: 'form', id: 'form_upload_employees', rows: [ + {cols: [{}, + {view: 'uploader', id: 'up_employees', autosend: false, + link: 'lst_upload_employees', value: 'Seleccionar Plantilla', + upload: '/files/employees'}, {}]}, + {cols: [ + {view: 'list', id: 'lst_upload_employees', name: 'lst_employees', + type: 'uploader', autoheight: true, borderless: true}]}, + {cols: [{}, {view: 'button', id: 'cmd_immport_employees', + label: 'Importar Empleados'}, {}]}, + ]}, +]} + + +var win_import_employees = { + init: function(){ + webix.ui({ + view: 'window', + id: 'win_import_employees', + width: 400, + modal: true, + position: 'center', + head: 'Importar Empleados', + body: body_import_employees, + }) + $$('cmd_immport_employees').attachEvent('onItemClick', cmd_immport_employees_click) + $$('up_employees').attachEvent('onUploadComplete', up_employees_upload_complete) + } +}