diff --git a/tabla_nomina/__init__.py b/tabla_nomina/__init__.py index 511a0ca..a24914b 100644 --- a/tabla_nomina/__init__.py +++ b/tabla_nomina/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- from . import controllers -from . import models \ No newline at end of file +from . import models +from . import wizard \ No newline at end of file diff --git a/tabla_nomina/__manifest__.py b/tabla_nomina/__manifest__.py old mode 100755 new mode 100644 index 8a5057e..b08b5b1 --- a/tabla_nomina/__manifest__.py +++ b/tabla_nomina/__manifest__.py @@ -25,6 +25,7 @@ # always loaded 'data': [ 'security/ir.model.access.csv', + 'wizard/wizard_message.xml', 'data/data.xml', 'views/views.xml', 'views/templates.xml', diff --git a/tabla_nomina/data/data.xml b/tabla_nomina/data/data.xml old mode 100755 new mode 100644 index 4b7683a..e28883a --- a/tabla_nomina/data/data.xml +++ b/tabla_nomina/data/data.xml @@ -1,9 +1,25 @@ + + + + FechaIngreso + Periodo + true + self.contract_id.date_start + Fecha de Ingreso del trabajador a la empresa (AAAA-MM-DD)* + + + + Refund Salary Slip + salary.refund + NOA + 3 + + 1 Nómina electrónica - 1 @@ -1293,6 +1309,33 @@ Reintegro + + + + ConceptoS + ConceptoS + false + false + false + Devengado + false + + Otros conceptos Salarial + + + + ConceptoNS + ConceptoNS + false + false + false + Devengado + false + + Otros conceptos No salarial + + + PorcentajeSalud @@ -1704,6 +1747,86 @@ Valor deduccion fondo de pension + + + + credit_note + + false + false + false + informaciongeneral + + false + self.credit_note + Indica si es ajuste de nomina o nota credito + + + + nota_credito + + false + false + false + informaciongeneral + + false + self.nota_credito + Indica el tipo de ajuste eliminacion o ajuste + + + + causa + + false + false + false + informaciongeneral + + false + self.causa + causa por el ajuste nomina + + + + CUNEPred + + false + false + false + informaciongeneral + + false + self.CUNEPred + El numero cune predecesor si existe + + + + NumeroPred + + false + false + false + informaciongeneral + + false + self.NumeroPred + Numero predecesor de la nomina a ajustar + + + + FechaGenPred + + false + false + false + informaciongeneral + + false + self.FechaGenPred + Fecha de generacion predecesor nomina + + diff --git a/tabla_nomina/models/models.py b/tabla_nomina/models/models.py old mode 100755 new mode 100644 index db11146..8f24a11 --- a/tabla_nomina/models/models.py +++ b/tabla_nomina/models/models.py @@ -1,10 +1,14 @@ # -*- coding: utf-8 -*- -from odoo import models, fields, modules, api,_ +from odoo import models, fields, modules,tools , api,_ import os import requests import json from odoo.exceptions import AccessError, UserError, RedirectWarning, ValidationError, Warning +import babel + +import time +from dateutil import relativedelta from datetime import datetime, timedelta from datetime import time as datetime_time @@ -99,15 +103,19 @@ class nomina_electronica(models.Model): _name = 'hr.payslip' _inherit = 'hr.payslip' - + nota_credito = fields.Selection([('Eliminar', 'Eliminar'), ('Modificar', 'Modificar')], string='Tipo de nota' ,required=False,default='Eliminar') + CUNEPred = fields.Char("CUNE") + NumeroPred = fields.Char("Numero Anterior") + FechaGenPred = fields.Date("Fecha de Predecesor") + causa = fields.Char("Causa") fecha_pago = fields.Date("Fecha de Pago") xml = fields.Text("XML") transaccionID = fields.Char("transaccionID") estado = fields.Selection([ - ('No_generada', 'No_generada'), + ('no_generada', 'No_generada'), ('Generada_correctamente', 'Generada_correctamente'), ('Generada_con_errores', 'Generada_con_errores'), - ], string='Estado',default="No_generada") + ], string='Estado',default="no_generada") prefijo = fields.Char("Prefijo") consecutivo = fields.Char("consecutivo") paisgeneracion = fields.Char("Pais de generacion") @@ -156,15 +164,271 @@ class nomina_electronica(models.Model): HoraGen = fields.Char('Hora Generacion') id_plataforma = fields.Char('id_plataforma') password = fields.Char('password') + cune = fields.Char('CUNE') # PeriodoNomina = fields.Char('Periodo Nomina') # TipoMoneda = fields.Char('TipoMoneda', default="COP") # Notas = fields.Char('Notas') + # @api.multi + def compute_refund(self,causa,tipo_nota): + for payslip in self: + numero_pred = payslip.prefijo+payslip.consecutivo + fecha_gen_pred = payslip.FechaGen + CUNEPred = payslip.cune + number = payslip.number or self.env['ir.sequence'].next_by_code('salary.refund') + numbersequence = self.env['ir.sequence'].search([('code', '=', 'salary.refund')]) + prefijo = numbersequence.prefix + longitudprefijo = len(prefijo) + longitudsecuencia = len(number) + consecutivo = number[longitudprefijo:longitudsecuencia] + # delete old payslip lines + payslip.line_ids.unlink() + # set the list of contract for which the rules have to be applied + # if we don't give the contract, then the rules to apply should be for all current contracts of the employee + contract_ids = payslip.contract_id.ids or \ + self.get_contract(payslip.employee_id, payslip.date_from, payslip.date_to) + lines = [(0, 0, line) for line in self._get_payslip_lines(contract_ids, payslip.id)] + payslip.write({'line_ids': lines, 'number': number,'transaccionID':'', + 'estado':'no_generada','nota_credito':tipo_nota,'causa':causa, + 'CUNEPred':CUNEPred,'NumeroPred':numero_pred,'FechaGenPred':fecha_gen_pred, + 'prefijo':prefijo,'consecutivo':consecutivo}) + + return True + + # @api.multi + def refund_sheet(self): + view_id = self.env.ref('tabla_nomina.form_wizard_message2').id + return { + 'name' : "Ajuste de nomina", + 'type' : 'ir.actions.act_window', + 'res_model': 'wk.wizard.message2', + 'view_mode': 'form', + 'view_id':view_id, + 'target' : 'new', + 'res_id' : False, + } + + @api.model + def get_worked_day_lines2(self, contracts, date_from, date_to): + """ + @param contract: Browse record of contracts + @return: returns a list of dict containing the input that should be applied for the given contract between date_from and date_to + """ + res = [] + # fill only if the contract as a working schedule linked + for contract in contracts.filtered(lambda contract: contract.resource_calendar_id): + day_from = datetime.combine(fields.Date.from_string(date_from), datetime_time.min) + day_to = datetime.combine(fields.Date.from_string(date_to), datetime_time.max) + + # compute leave days + leaves = {} + day_leave_intervals = contract.employee_id.iter_leaves(day_from, day_to, calendar=contract.resource_calendar_id) + for day_intervals in day_leave_intervals: + for interval in day_intervals: + holiday = interval[2]['leaves'].holiday_id + current_leave_struct = leaves.setdefault(holiday.holiday_status_id, { + 'name': holiday.holiday_status_id.name or _('Global Leaves'), + 'sequence': 5, + 'code': holiday.holiday_status_id.name or 'GLOBAL', + 'number_of_days': 0.0, + 'number_of_hours': 0.0, + 'contract_id': contract.id, + }) + leave_time = (interval[1] - interval[0]).seconds / 3600 + current_leave_struct['number_of_hours'] += leave_time + work_hours = contract.employee_id.get_day_work_hours_count(interval[0].date(), calendar=contract.resource_calendar_id) + if work_hours: + current_leave_struct['number_of_days'] += leave_time / work_hours + + # compute worked days + work_data = contract.employee_id.with_context(no_tz_convert=True).get_work_days_data(day_from, day_to, calendar=contract.resource_calendar_id) + attendances = { + 'name': _("Normal Working Days paid at 100%"), + 'sequence': 1, + 'code': 'WORK100', + 'number_of_days': work_data['days'], + 'number_of_hours': work_data['hours'], + 'contract_id': contract.id, + } + res.append(attendances) + tipos = ["HED","HEN","HRN","HEDDF","HRDDF","HENDF","HRNDF", + "VacacionesComunes","VacacionesCompensadas","Primas","Cesantias","Incapacidad","LicenciaMP","LicenciaR","LicenciaNR", + "HuelgaLegal","CompensacionO","CompensacionE"] + otros = ['ConceptoS','ConceptoNS',"AuxilioTransporte","ViaticoManuAlojS","ViaticoManuAlojNS","PagoS","PagoNS","PagoAlimentacionS","PagoAlimentacionNS", + "Comision","PagoTercero","Anticipo","Dotacion","ApoyoSost","Teletrabajo","BonifRetiro","Indemnizacion","Reintegro" + ,"BonificacionS","BonificacionNS","AuxilioS","AuxilioNS"] + for tipo in tipos: + attendances = { + 'name': _(self.descripcion(tipo)), + 'sequence': 1, + 'code': tipo, + 'number_of_days': 0, + 'number_of_hours': 0, + 'contract_id': contract.id, + } + res.append(attendances) + res.extend(leaves.values()) + return res + def descripcion(self,tipo): + if tipo == "HED": + return "Hora extra diurna" + if tipo == "HEN": + return "Hora Extra Nocturna" + if tipo == "HRN": + return "Hora Recargo Nocturno" + if tipo == "HEDDF": + return "Horas Extras Diurnas Dominical y Festivos" + if tipo == "HENDF": + return "Horas Extras Nocturna Dominical y Festivos" + if tipo == "HRNDF": + return "Horas Recargo Diurno Dominical y Festivos" + if tipo == "HRDDF": + return "Recargo Diurno Dominical y Festivos" + if tipo == "VacacionesComunes": + return "Vacaciones Comunes" + if tipo == "VacacionesCompensadas": + return "Vacaciones Compensadas" + if tipo == "Primas": + return "Primas" + if tipo == "Cesantias": + return "Cesantias" + if tipo == "Incapacidad": + return "Incapacidad" + if tipo == "LicenciaMP": + return "Licencia de Maternidad o Paternidad" + if tipo == "LicenciaR": + return "Licencia Remunerada" + if tipo == "LicenciaNR": + return "Licencia NO Remunerada" + if tipo == "HuelgaLegal": + return "Huelga Legal" + # if tipo == "OtroConcepto": + # return "Otros conceptos" + if tipo == "CompensacionO": + return "Compensacion Ordinaria" + if tipo == "CompensacionE": + return "Compensacion Extraordinaria" + + @api.model + def get_inputs2(self, contracts, date_from, date_to): + res = [] + + structure_ids = contracts.get_all_structures() + rule_ids = self.env['hr.payroll.structure'].browse(structure_ids).get_all_rules() + sorted_rule_ids = [id for id, sequence in sorted(rule_ids, key=lambda x:x[1])] + inputs = self.env['hr.salary.rule'].browse(sorted_rule_ids).mapped('input_ids') + + otros = ['ConceptoS','ConceptoNS',"ViaticoManuAlojS","ViaticoManuAlojNS","PagoS","PagoNS","PagoAlimentacionS","PagoAlimentacionNS", + "Comision","PagoTercero","Anticipo","Dotacion","ApoyoSost","Teletrabajo","BonifRetiro","Indemnizacion","Reintegro" + ,"BonificacionS","BonificacionNS","AuxilioS","AuxilioNS"] + + for contract in contracts: + for otro in otros: + input_data = { + 'name': self.descripcion2(otro), + 'code': otro, + 'contract_id': contract.id, + } + res += [input_data] + for input in inputs: + input_data = { + 'name': input.name, + 'code': input.code, + 'contract_id': contract.id, + } + res += [input_data] + + + return res + + def descripcion2(self,tipo): + if tipo == "ConceptoS": + return "Valor de los demás pagos fijos o variables realizados al trabajador (SALARIAL)" + if tipo == "ConceptoNS": + return "Valor de los demás pagos fijos o variables realizados al trabajador (NO SALARIAL)" + if tipo == "ViaticoManuAlojS": + return "Parte de los viáticos pagado al trabajador correspondientes a manutención y/o alojamiento.(SALARIAL)" + if tipo == "ViaticoManuAlojNS": + return "Parte de los viáticos pagado al trabajador correspondientes a manutención y/o alojamiento.(NO SALARIAL)" + if tipo == "PagoS": + return "Valor que el trabajador recibe como contraprestación por el trabajo realizado, por medio de bonos electrónicos, recargas, cheques, vales. es decir, todo pago realizado en un medio diferente a dinero en efectivo o consignación de cuenta bancaria (Salarial)." + if tipo == "PagoNS": + return "Valor que el trabajador recibe como contraprestación por el trabajo realizado, por medio de bonos electrónicos, recargas, cheques, vales. es decir, todo pago realizado en un medio diferente a dinero en efectivo o consignación de cuenta bancaria (NO Salarial)." + if tipo == "PagoAlimentacionS": + return "Valor que el trabajador recibe como concepto no salarial, por medio de bonos electrónicos, recargas, cheques, vales. es decir, todo pago realizado en un medio diferente a dinero en efectivo o consignación de cuenta bancaria (Para Alimentación Salarial)." + if tipo == "PagoAlimentacionNS": + return "Valor que el trabajador recibe como concepto no salarial, por medio de bonos electrónicos, recargas, cheques, vales. es decir, todo pago realizado en un medio diferente a dinero en efectivo o consignación de cuenta bancaria (Para Alimentación NO Salarial)." + if tipo == "Comision": + return "Valor pagado al trabajador usualmente del área comercial, y de forma regular se liquida con un porcentaje sobre el importe de una operación, también se presenta como incentivo por el logro de objetivos." + if tipo == "PagoTercero": + return "Beneficios en cabeza del Trabjador que se pagan a un proveedor o tercero." + if tipo == "Anticipo": + return "Anticipos de Nómina." + if tipo == "Dotacion": + return "De conformidad con lo previsto en el artículo 230 del Código Sustantivo del Trabajo, o la norma que lo modifique, adicione o sustituya, corresponde al valor que el empleador dispone para suministrar la dotación de sus trabajadores." + if tipo == "ApoyoSost": + return "Corresponde al valor no salarial que el patrocinador paga de forma mensual como ayuda o apoyo economía al aprendiz o practicante universitario durante su etapa lectiva y fase practica." + if tipo == "Teletrabajo": + return "Valor que debe ser pagado al trabajador cuyo contrato indica expresamente que puede laborar mediante teletrabajo" + if tipo == "BonifRetiro": + return "Valor establecido por mutuo acuerdo por retiro del Trabajador" + if tipo == "Indemnizacion": + return "Valor de Indemnizacion establecido por ley" + if tipo == "Reintegro": + return "Valor que le regresa la empresa al trabajador por una deducción mal realizada en otro pago de nomina" + if tipo == "BonificacionS": + return "Son valores pagados al trabajador en forma de incentivo o recompensa por la contraprestación directa del servicio." + if tipo == "BonificacionNS": + return "Son valores de incentivos pagados al trabajador de forma ocasional y por mera liberalidad o los pactados entre las partes de forma expresa como pago no salarial." + if tipo == "AuxilioS": + return "Son beneficios, ayudas o apoyos económicos, pagados al trabajador de forma habitual o pactados entre las partes como factor salarial." + if tipo == "AuxilioNS": + return "Son beneficios, ayudas o apoyos económicos, pagados al trabajador de forma ocasional y por mera liberalidad o los pactados entre las partes de forma expresa como pago no salarial." + @api.onchange('employee_id') def on_change_employee(self): + # if (not self.employee_id) or (not self.date_from) or (not self.date_to): + # return + + # employee = self.employee_id + # date_from = self.date_from + # date_to = self.date_to + # contract_ids = [] + + # ttyme = datetime.fromtimestamp(time.mktime(time.strptime(date_from, "%Y-%m-%d"))) + # locale = self.env.context.get('lang') or 'en_US' + # self.name = _('Salary Slip of %s for %s') % (employee.name, tools.ustr(babel.dates.format_date(date=ttyme, format='MMMM-y', locale=locale))) + # self.company_id = employee.company_id + + # if not self.env.context.get('contract') or not self.contract_id: + # contract_ids = self.get_contract(employee, date_from, date_to) + # if not contract_ids: + # return + # self.contract_id = self.env['hr.contract'].browse(contract_ids[0]) + + # if not self.contract_id.struct_id: + # return + # self.struct_id = self.contract_id.struct_id + + # #computation of the salary input + # contracts = self.env['hr.contract'].browse(contract_ids) + # worked_days_line_ids = self.get_worked_day_lines(contracts, date_from, date_to) + # worked_days_lines = self.worked_days_line_ids.browse([]) + # for r in worked_days_line_ids: + # worked_days_lines += worked_days_lines.new(r) + # self.worked_days_line_ids = worked_days_lines + + # input_line_ids = self.get_inputs(contracts, date_from, date_to) + # input_lines = self.input_line_ids.browse([]) + # for r in input_line_ids: + # input_lines += input_lines.new(r) + # self.input_line_ids = input_lines + # return for record in self: valores = self.env['tabla_nomina.tabla_nomina'].search([('name', '=', 'Nómina electrónica')]) + # print("IMPRIMIENDO valores") + # print(valores) if valores: self.prefijo = valores.prefijo self.consecutivo = valores.consecutivo @@ -189,8 +453,17 @@ class nomina_electronica(models.Model): self.DireccionEmpleador = valores.DireccionEmpleador self.id_plataforma = valores.id_plataforma self.password = valores.password - + # return + # @api.model + # def create(self, values): + + + # result = super(nomina_electronica, self).create(values) + # print("IMPRIMIENDO valores despues") + # print(valores) + # return result + # @api.multi def action_cfdi_generate(self): urlini = "https://odoo15.navegasoft.com/admonclientes/status/" headers = {'content-type': 'application/json'} @@ -273,25 +546,75 @@ class nomina_electronica(models.Model): raise Warning(result) + # @api.multi + def genera_cufe(self): + urlini = "https://odoo15.navegasoft.com/admonclientes/cune/" + headers = {'content-type': 'application/json'} + send = {"id_plataforma":self.id_plataforma,"transaccionID":self.transaccionID,"prefix":self.prefijo,"number":self.consecutivo,"ambiente":self.ambiente} + result = requests.post(urlini,headers=headers,data = json.dumps(send)) + #resultado = json.loads(result.text) + #print(result.text) + print(result) + if result.status_code == 200: + resultado = json.loads(result.text) + print("el primer resultado es !!!") + print(resultado) + if "cune" in resultado: + final = resultado["cune"] + return self.env['wk.wizard.message'].genrated_message('CUNE: '+final, 'listos') + else: + if "error" in resultado: + final = resultado["error"] + final_error = json.loads(json.dumps(final)) + data = final_error["data"] + data_final = data['message'] + final_data = json.loads(json.dumps(data_final)) + # archivo = final_data['code'] + return self.env['wk.wizard.message'].genrated_message(data_final,"Los datos no estan correctos" ,"https://navegasoft.com") + else: + final = json.loads(json.dumps(resultado)) + final2 = final['result'] + final_data = json.loads(json.dumps(final2)) #eval(final2) + print('y el resultado es ...') + print(final_data) + if 'CUNE' in final_data: + self.write({"cune":final_data['CUNE']}) + return self.env['wk.wizard.message'].genrated_message("Este es el CUNE "+final_data['CUNE'],"Se guardo dentro de los datos de la nomina" ,"https://navegasoft.com") + else: + return self.env['wk.wizard.message'].genrated_message('Estamos recibiendo un codigo de error Es necesario esperar para volver generar el cune', 'Es necesario esperar para volver a imprimir el documento') + final = resultado["error"] + final_error = json.loads(json.dumps(final)) + data = final_error["data"] + data_final = data['message'] + else: + raise Warning(result) + + # @api.multi def envio_directo(self): import time now2 = datetime.now() current_time = now2.strftime("%H:%M:%S") - numeracion = self.env['ir.sequence'].sudo().search([('code', '=', 'salary.slip')]) - lon_prefix = len(numeracion.prefix) - long_total = len(self.number) - number = self.number[lon_prefix:long_total] - - self.prefijo = numeracion.prefix - self.consecutivo = number - + if self.credit_note == True: + numeracion = self.env['ir.sequence'].search([('code', '=', 'salary.refund')]) + lon_prefix = len(numeracion.prefix) + long_total = len(self.number) + number = self.number[lon_prefix:long_total] + self.prefijo = numeracion.prefix + self.consecutivo = number + else: + numeracion = self.env['ir.sequence'].sudo().search([('code', '=', 'salary.slip')]) + lon_prefix = len(numeracion.prefix) + long_total = len(self.number) + number = self.number[lon_prefix:long_total] + self.prefijo = numeracion.prefix + self.consecutivo = number self.FechaGen = str(now2.date()) self.HoraGen = str(current_time) urlini = "https://odoo15.navegasoft.com/admonclientes/objects/" valores = self.env['tabla_nomina.tabla_nomina'].search([('name', '=', 'Nómina electrónica')]) response2={} valores_lineas = valores.mp_id - send = {} + send = {} for linea in valores_lineas: if linea.codigo: if linea.dias == True: @@ -329,6 +652,7 @@ class nomina_electronica(models.Model): # else: # send[linea.name] = None # print(send) + #send['credit_note']= self.credit_note headers = {'content-type': 'application/json'} result = requests.post(urlini,headers=headers,data = json.dumps(send)) if result.status_code == 200: @@ -372,10 +696,10 @@ class nomina_hr_contract(models.Model): ], string='Tipo Contrato') tipo_trabajador = fields.Selection([ - ('1', 'Dependiente'), - ('2', 'Servicio domestico'), - ('3', 'Independiente'), - ('4', 'Madre comunitaria'), + ('01', 'Dependiente'), + ('02', 'Servicio domestico'), + ('03', 'Independiente'), + ('04', 'Madre comunitaria'), ('12', 'Aprendices del Sena en etapa lectiva'), ('16', 'Independiente agremiado o asociado'), ('18', 'Funcionarios públicos sin tope máximo de ibc'), @@ -411,10 +735,10 @@ class nomina_hr_contract(models.Model): ], string='Tipo Trabajador') sub_tipo_trabajador = fields.Selection([ ('00', 'No Aplica'), - ('1', 'Dependiente pensionado por vejez activo'), - ('2', 'Independiente pensionado por vejez activo'), - ('3', 'Cotizante no obligado a cotizar a pensión por edad'), - ('4', 'Cotizante con requisitos cumplidos para pensión'), + ('01', 'Dependiente pensionado por vejez activo'), + ('02', 'Independiente pensionado por vejez activo'), + ('03', 'Cotizante no obligado a cotizar a pensión por edad'), + ('04', 'Cotizante con requisitos cumplidos para pensión'), ('12', 'Cotizante a quien se le ha reconocido indemnización sustitutiva o devolución de saldos'), ('16', 'Cotizante perteneciente a un régimen de exceptuado de pensiones a entidades autorizadas para recibir aportes exclusivamente de un grupo de sus propios'), ('18', 'Cotizante pensionado con mesada superior a 25 smlmv'), @@ -423,13 +747,13 @@ class nomina_hr_contract(models.Model): ('21', 'Conductores servicio taxi no aporte pensión dec. 1047'), ], string='Subtipo de Trabajador') AltoRiegoPension = fields.Selection([ - ('NO', 'NO'), - ('SI', 'SI'), - ], string='Alto Riego Pension',default='NO') + ('false', 'NO'), + ('true', 'SI'), + ], string='Alto Riego Pension',default='false') SalarioIntegral = fields.Selection([ - ('NO', 'NO'), - ('SI', 'SI'), - ], string='Salario Integral',default='NO') + ('false', 'NO'), + ('true', 'SI'), + ], string='Salario Integral',default='false') banco = fields.Char("Banco") tipo_cuenta = fields.Char("Tipo cuenta") numero_cuenta = fields.Char("Numero de cuenta") @@ -540,4 +864,7 @@ class nomina_hr_contract(models.Model): # if valores[k]: # if not k == "name": # send[k] = exec(valores[k]) - # print(exec(valores[k])) \ No newline at end of file + # print(exec(valores[k])) + + + \ No newline at end of file diff --git a/tabla_nomina/security/ir.model.access.csv b/tabla_nomina/security/ir.model.access.csv old mode 100755 new mode 100644 index 306fc3d..4b9b519 --- a/tabla_nomina/security/ir.model.access.csv +++ b/tabla_nomina/security/ir.model.access.csv @@ -1,3 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_tabla_nomina_tabla_nomina,tabla_nomina.tabla_nomina,model_tabla_nomina_tabla_nomina,base.group_user,1,1,1,1 -access_tabla_nomina_tabla_nomina_line,tabla_nomina.line,model_tabla_nomina_line,base.group_user,1,1,1,1 \ No newline at end of file +access_wizard_message2,Access Message Wizard2,model_wk_wizard_message2,,1,1,1,1 \ No newline at end of file diff --git a/tabla_nomina/views/views.xml b/tabla_nomina/views/views.xml old mode 100755 new mode 100644 index 06f4e23..ebb4968 --- a/tabla_nomina/views/views.xml +++ b/tabla_nomina/views/views.xml @@ -157,10 +157,18 @@