diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py index 945c3c4..56218e0 100644 --- a/source/app/controllers/util.py +++ b/source/app/controllers/util.py @@ -1009,7 +1009,7 @@ class LIBO(object): 'notas', 'correo', ) - rows = [dict(zip(fields, r)) for r in data[1:]] + rows = tuple([dict(zip(fields, r)) for r in data[1:]]) msg = 'Empleados importados correctamente' return rows, msg @@ -2758,3 +2758,6 @@ def import_invoice(rfc): return (), 'No se encontro LibreOffice' + +def calc_to_date(value): + return datetime.date.fromordinal(int(value) + 693594) diff --git a/source/app/models/main.py b/source/app/models/main.py index 0a350f5..8ef4128 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -1400,6 +1400,18 @@ class SATBancos(BaseModel): result = bool(q.execute()) return {'ok': result} + @classmethod + def get_by_key(cls, key): + if not key: + return + try: + obj = SATBancos.get(SATBancos.key==key) + return obj + except SATBancos.DoesNotExist: + msg = 'SATBancos no existe: {}'.format(key) + log.error(msg) + return + class SATNivelesEducativos(BaseModel): name = TextField(index=True) @@ -1867,6 +1879,16 @@ class SATEstados(BaseModel): def __str__(self): return 'Estado: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATEstados.get(SATEstados.key==key) + return obj + except SATEstados.DoesNotExist: + msg = 'SATEstados no existe: {}'.format(key) + log.error(msg) + return + class SATOrigenRecurso(BaseModel): key = TextField(index=True, unique=True) @@ -1882,6 +1904,16 @@ class SATOrigenRecurso(BaseModel): def __str__(self): return 'Origen Recurso: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATOrigenRecurso.get(SATOrigenRecurso.key==key) + return obj + except SATOrigenRecurso.DoesNotExist: + msg = 'SATOrigenRecurso no existe: {}'.format(key) + log.error(msg) + return + class SATPeriodicidadPago(BaseModel): key = TextField(index=True, unique=True) @@ -1897,6 +1929,16 @@ class SATPeriodicidadPago(BaseModel): def __str__(self): return 'Periodicidad de Pago: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATPeriodicidadPago.get(SATPeriodicidadPago.key==key) + return obj + except SATPeriodicidadPago.DoesNotExist: + msg = 'SATPeriodicidadPago no existe: {}'.format(key) + log.error(msg) + return + class SATTipoContrato(BaseModel): key = TextField(index=True, unique=True) @@ -1912,6 +1954,16 @@ class SATTipoContrato(BaseModel): def __str__(self): return 'Tipo de Contrato: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoContrato.get(SATTipoContrato.key==key) + return obj + except SATTipoContrato.DoesNotExist: + msg = 'SATTipoContrato no existe: {}'.format(key) + log.error(msg) + return + class SATTipoDeduccion(BaseModel): key = TextField(index=True, unique=True) @@ -1929,6 +1981,16 @@ class SATTipoDeduccion(BaseModel): def __str__(self): return 'Tipo de Deducción: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoDeduccion.get(SATTipoDeduccion.key==key) + return obj + except SATTipoDeduccion.DoesNotExist: + msg = 'SATTipoDeduccion no existe: {}'.format(key) + log.error(msg) + return + class SATTipoHoras(BaseModel): key = TextField(index=True, unique=True) @@ -1944,6 +2006,16 @@ class SATTipoHoras(BaseModel): def __str__(self): return 'Tipo de Horas: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoHoras.get(SATTipoHoras.key==key) + return obj + except SATTipoHoras.DoesNotExist: + msg = 'SATTipoHoras no existe: {}'.format(key) + log.error(msg) + return + class SATTipoIncapacidad(BaseModel): key = TextField(index=True, unique=True) @@ -1959,6 +2031,16 @@ class SATTipoIncapacidad(BaseModel): def __str__(self): return 'Tipo de Incapacidad: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoIncapacidad.get(SATTipoIncapacidad.key==key) + return obj + except SATTipoIncapacidad.DoesNotExist: + msg = 'SATTipoIncapacidad no existe: {}'.format(key) + log.error(msg) + return + class SATTipoJornada(BaseModel): key = TextField(index=True, unique=True) @@ -1974,6 +2056,16 @@ class SATTipoJornada(BaseModel): def __str__(self): return 'Tipo de Jornada: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoJornada.get(SATTipoJornada.key==key) + return obj + except SATTipoJornada.DoesNotExist: + msg = 'SATTipoJornada no existe: {}'.format(key) + log.error(msg) + return + class SATTipoNomina(BaseModel): key = TextField(index=True, unique=True) @@ -1989,6 +2081,16 @@ class SATTipoNomina(BaseModel): def __str__(self): return 'Tipo de Nómina: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoNomina.get(SATTipoNomina.key==key) + return obj + except SATTipoNomina.DoesNotExist: + msg = 'SATTipoNomina no existe: {}'.format(key) + log.error(msg) + return + class SATTipoOtroPago(BaseModel): key = TextField(index=True, unique=True) @@ -2006,6 +2108,16 @@ class SATTipoOtroPago(BaseModel): def __str__(self): return 'Tipo de Otro Pago: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoOtroPago.get(SATTipoOtroPago.key==key) + return obj + except SATTipoOtroPago.DoesNotExist: + msg = 'SATTipoOtroPago no existe: {}'.format(key) + log.error(msg) + return + class SATTipoPercepcion(BaseModel): key = TextField(index=True, unique=True) @@ -2023,6 +2135,16 @@ class SATTipoPercepcion(BaseModel): def __str__(self): return 'Tipo de Percepción: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoPercepcion.get(SATTipoPercepcion.key==key) + return obj + except SATTipoPercepcion.DoesNotExist: + msg = 'SATTipoPercepcion no existe: {}'.format(key) + log.error(msg) + return + class SATTipoRegimen(BaseModel): key = TextField(index=True, unique=True) @@ -2038,6 +2160,16 @@ class SATTipoRegimen(BaseModel): def __str__(self): return 'Regimen de contratación: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATTipoRegimen.get(SATTipoRegimen.key==key) + return obj + except SATTipoRegimen.DoesNotExist: + msg = 'SATTipoRegimen no existe: {}'.format(key) + log.error(msg) + return + class SATRiesgoPuesto(BaseModel): key = TextField(index=True, unique=True) @@ -2053,6 +2185,16 @@ class SATRiesgoPuesto(BaseModel): def __str__(self): return 'Riesgo Puesto: {} ({})'.format(self.name, self.key) + @classmethod + def get_by_key(cls, key): + try: + obj = SATRiesgoPuesto.get(SATRiesgoPuesto.key==key) + return obj + except SATRiesgoPuesto.DoesNotExist: + msg = 'SATRiesgoPuesto no existe: {}'.format(key) + log.error(msg) + return + class TipoCambio(BaseModel): dia = DateField(default=util.now) @@ -5187,7 +5329,7 @@ class SeriesProductos(BaseModel): class Departamentos(BaseModel): - nombre = TextField(default='') + nombre = TextField(default='', unique=True) descripcion = TextField(default='') class Meta: @@ -5195,15 +5337,22 @@ class Departamentos(BaseModel): class Puestos(BaseModel): - departamento = ForeignKeyField(Departamentos) - nombre = TextField(default='') + departamento = ForeignKeyField(Departamentos, null=True) + nombre = TextField(default='', unique=True) descripcion = TextField(default='') class Meta: order_by = ('nombre',) - indexes = ( - (('nombre', 'departamento'), True), - ) + + @classmethod + def get_by_depto(cls, puesto, depto): + departamento = None + if depto: + with database_proxy.transaction(): + departamento, _ = Departamentos.get_or_create(nombre=depto) + data = {'departamento': departamento, 'nombre': puesto} + obj, _ = Puestos.get_or_create(**data) + return obj class Empleados(BaseModel): @@ -5244,18 +5393,68 @@ class Empleados(BaseModel): (('num_empleado', 'rfc'), True), ) + def _validate_import(self, row): + sn = {'si': True, 'no': False} + data = row.copy() + data['nombre_completo'] = '{} {} {}'.format( + row['nombre'], row['paterno'], row['materno']).strip() + data['fecha_ingreso'] = util.calc_to_date(row['fecha_ingreso']) + data['tipo_contrato'] = SATTipoContrato.get_by_key(row['tipo_contrato']) + data['es_sindicalizado'] = sn.get(row['es_sindicalizado'].lower(), False) + data['tipo_jornada'] = SATTipoJornada.get_by_key(row['tipo_jornada']) + data['tipo_regimen'] = SATTipoRegimen.get_by_key(row['tipo_regimen']) + data['puesto'] = Puestos.get_by_depto(row['puesto'], row['departamento']) + data['riesgo_puesto'] = SATRiesgoPuesto.get_by_key(row['riesgo_puesto']) + data['periodicidad_pago'] = SATPeriodicidadPago.get_by_key(row['periodicidad_pago']) + data['banco'] = SATBancos.get_by_key(row['banco']) + data['estado'] = SATEstados.get_by_key(row['estado']) + del data['departamento'] + return data + def _import(self): emisor = Emisor.select()[0] - data, msg = util.import_employees(emisor.rfc) - if not data: + rows, msg = util.import_employees(emisor.rfc) + if not rows: return {'ok': False, 'msg': msg} - print ('DATA', data) + en = 0 + ea = 0 + for row in rows: + data = self._validate_import(self, row) + w = (Empleados.rfc==row['rfc']) + with database_proxy.transaction(): + if Empleados.select().where(w).exists(): + q = Empleados.update(**data).where(w) + q.execute() + ea += 1 + else: + obj = Empleados.create(**data) + en += 1 + + msg = 'Empleados encontrados: {}
'.format(len(rows)) + msg += 'Empleados nuevos: {}
'.format(en) + msg += 'Empleados actualizados: {}
'.format(ea) + msg += 'Empleados no importados: {}'.format(len(rows) - en - ea) return {'ok': True, 'msg': msg} + def _get(self): + rows = (Empleados + .select( + Empleados.id, + Empleados.num_empleado, + Empleados.rfc, + Empleados.curp, + Empleados.nombre_completo, + Empleados.fecha_ingreso) + .dicts() + ) + return {'ok': True, 'rows': tuple(rows)} + @classmethod def get_by(cls, values): - # ~ print (values) + if not 'opt' in values: + return cls._get(cls) + if values['opt'] == 'import': return cls._import(cls) diff --git a/source/static/js/controller/nomina.js b/source/static/js/controller/nomina.js index 36ed648..033bd8e 100644 --- a/source/static/js/controller/nomina.js +++ b/source/static/js/controller/nomina.js @@ -36,8 +36,27 @@ function current_dates_nomina(){ fm.unblockEvent() } +function get_employees(){ + webix.ajax().get('/employees', { + error: function(text, data, xhr) { + msg = 'Error al consultar' + msg_error(msg) + }, + success: function(text, data, xhr) { + var values = data.json(); + if (values.ok){ + $$('grid_employees').clearAll(); + $$('grid_employees').parse(values.rows, 'json'); + }else{ + msg_error(values.msg) + } + } + }) +} + function cmd_empleados_click(){ + get_employees() $$('multi_nomina').setValue('nomina_empleados') } @@ -52,7 +71,7 @@ function cmd_import_empleados_click(){ $$('win_import_employees').show() } -function cmd_immport_employees_click(){ +function cmd_import_employees_click(){ var form = $$('form_upload_employees') var values = form.getValues() diff --git a/source/static/js/ui/nomina.js b/source/static/js/ui/nomina.js index e42f37e..c5b3d39 100644 --- a/source/static/js/ui/nomina.js +++ b/source/static/js/ui/nomina.js @@ -111,18 +111,18 @@ var grid_cols_empleados = [ footer: {content: 'countRows', colspan: 3, css: 'right'}}, {id: "id", header:"ID", hidden:true}, {id: "num_empleado", header: ["No Empleado"], adjust: "header"}, - {id: "rfc", header: ["RFC", {content: 'textFilter'}], adjust: "data"}, - {id: "curp", header: ["CURP"], adjust: "data", hidden:true}, + {id: "rfc", header: ["RFC", {content: 'textFilter'}], adjust: "data", sort: "string"}, + {id: "curp", header: ["CURP"], adjust: "data", hidden:true, sort: "string"}, {id: "nombre_completo", header: ["Empleado", {content: 'textFilter'}], - adjust: "data", fillspace: true}, - {id: "fecha_ingreso", header: ["Fecha de Ingreso"], adjust: "data", + adjust: "data", fillspace: true, sort: "string"}, + {id: "fecha_ingreso", header: ["Fecha de Ingreso"], adjust: "header", sort: "string"}, ] var grid_empleados = { view: 'datatable', - id: 'grid_empleados', + id: 'grid_employees', select: 'row', scrollY: true, adjust: true, @@ -175,10 +175,10 @@ var body_import_employees = {rows: [ {cols: [ {view: 'list', id: 'lst_upload_employees', name: 'lst_employees', type: 'uploader', autoheight: true, borderless: true}]}, - {cols: [{}, {view: 'button', id: 'cmd_immport_employees', + {cols: [{}, {view: 'button', id: 'cmd_import_employees', label: 'Importar Empleados'}, {}]}, ]}, -]} +],} var win_import_employees = { @@ -192,7 +192,7 @@ var win_import_employees = { head: 'Importar Empleados', body: body_import_employees, }) - $$('cmd_immport_employees').attachEvent('onItemClick', cmd_immport_employees_click) + $$('cmd_import_employees').attachEvent('onItemClick', cmd_import_employees_click) $$('up_employees').attachEvent('onUploadComplete', up_employees_upload_complete) } }