870 lines
43 KiB
Python
870 lines
43 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
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
|
|
|
|
class tabla_nomina(models.Model):
|
|
_name = 'tabla_nomina.tabla_nomina'
|
|
_description = 'tabla_nomina.tabla_nomina'
|
|
# _inherit = 'mail.message'
|
|
|
|
name = fields.Char('Nombre')
|
|
fecha_pago = fields.Date("Fecha de Pago")
|
|
xml = fields.Text("XML")
|
|
transaccionID = fields.Char("transaccionID")
|
|
impreso = fields.Boolean("Impreso")
|
|
prefijo = fields.Char("Prefijo")
|
|
consecutivo = fields.Char("consecutivo")
|
|
paisgeneracion = fields.Char("Pais de generacion")
|
|
departamentoestado = fields.Char("Departamento")
|
|
municipiociudad = fields.Char("Ciudad")
|
|
Idioma = fields.Char("Idioma",default="es")
|
|
|
|
version = fields.Char("Version",default="")
|
|
ambiente = fields.Selection([
|
|
('1', 'Produccion'),
|
|
('2', 'Pruebas'),
|
|
], string='Ambiente',default="1")
|
|
tipoXML = fields.Char("Tipo XML",default="102")
|
|
Algoritmo = fields.Char("Algoritmo",default="CUNE-384")
|
|
PeriodoNomina = fields.Selection([
|
|
('1', 'Semanal'),
|
|
('2', 'Decenal'),
|
|
('3', 'Catorcenal'),
|
|
('4', 'Quincenal'),
|
|
('5', 'Mensual'),
|
|
], string='Periodo Nomina')
|
|
TipoMoneda = fields.Char('TipoMoneda', default="COP")
|
|
##EMPLEADOR
|
|
RazonSocial = fields.Char('RazonSocial')
|
|
PrimerApellido = fields.Char('PrimerApellido')
|
|
SegundoApellido = fields.Char('SegundoApellido')
|
|
PrimerNombre = fields.Char('PrimerNombre')
|
|
OtrosNombres = fields.Char('OtrosNombres')
|
|
NIT = fields.Char('NIT')
|
|
DV = fields.Char('DV')
|
|
PaisEmpleador = fields.Char('Pais')
|
|
MunicipioCiudadEmpleador = fields.Char('MunicipioCiudad')
|
|
DepartamentoEstadoEmpleador = fields.Char('DepartamentoEstado')
|
|
DireccionEmpleador = fields.Char('Direccion')
|
|
|
|
tipocontrato = fields.Selection([
|
|
('1', 'Termino Fijo'),
|
|
('2', 'Termino Indefinido'),
|
|
('3', 'Obra o Labor'),
|
|
('4', 'Aprendizaje'),
|
|
('5', 'Practicas'),
|
|
], string='Tipo de contrato')
|
|
|
|
id_plataforma = fields.Char('id_plataforma')
|
|
password = fields.Char('password')
|
|
|
|
mp_id = fields.One2many('tabla_nomina.line','mp_id', ondelete='cascade')
|
|
|
|
|
|
class line_nomina(models.Model):
|
|
_name = 'tabla_nomina.line'
|
|
_description = 'tabla_nomina.line'
|
|
|
|
name = fields.Char('Nombre')
|
|
categoria = fields.Char('Categoria')
|
|
codigo = fields.Char('Codigo')
|
|
dias = fields.Boolean('Son dias?')
|
|
horas = fields.Boolean('Son horas?')
|
|
porcentaje = fields.Boolean('Es porcentaje?')
|
|
subcategoria = fields.Char('Sub Categoria')
|
|
obligatorio = fields.Boolean('Obligatorio')
|
|
detalle = fields.Char('Detalle')
|
|
mensaje = fields.Char('Mensaje')
|
|
campo_tecnico = fields.Char('Campo tecnico')
|
|
titulo = fields.Char('Titulo')
|
|
link = fields.Char('Link')
|
|
|
|
mp_id = fields.Many2one('tabla_nomina.tabla_nomina', string='Campos',ondelete='restrict', index=True)
|
|
|
|
|
|
class nomina_input_lines(models.Model):
|
|
_name = 'hr.salary.rule'
|
|
_inherit = 'hr.salary.rule'
|
|
|
|
porcentaje = fields.Integer("Porcentaje")
|
|
|
|
|
|
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'),
|
|
('Generada_correctamente', 'Generada_correctamente'),
|
|
('Generada_con_errores', 'Generada_con_errores'),
|
|
], string='Estado',default="no_generada")
|
|
prefijo = fields.Char("Prefijo")
|
|
consecutivo = fields.Char("consecutivo")
|
|
paisgeneracion = fields.Char("Pais de generacion")
|
|
departamentoestado = fields.Char("Departamento")
|
|
municipiociudad = fields.Char("Ciudad")
|
|
Idioma = fields.Char("Idioma",default="es")
|
|
|
|
version = fields.Char("Version",default="")
|
|
ambiente = fields.Selection([
|
|
('1', 'Produccion'),
|
|
('2', 'Pruebas'),
|
|
], string='Ambiente',default="1")
|
|
tipoXML = fields.Char("Tipo XML",default="102")
|
|
Algoritmo = fields.Char("Algoritmo",default="CUNE-384")
|
|
PeriodoNomina = fields.Selection([
|
|
('1', 'Semanal'),
|
|
('2', 'Decenal'),
|
|
('3', 'Catorcenal'),
|
|
('4', 'Quincenal'),
|
|
('5', 'Mensual'),
|
|
], string='Periodo Nomina')
|
|
TipoMoneda = fields.Char('TipoMoneda', default="COP")
|
|
Notas = fields.Char('Notas')
|
|
##EMPLEADOR
|
|
RazonSocial = fields.Char('RazonSocial')
|
|
PrimerApellido = fields.Char('PrimerApellido')
|
|
SegundoApellido = fields.Char('SegundoApellido')
|
|
PrimerNombre = fields.Char('PrimerNombre')
|
|
OtrosNombres = fields.Char('OtrosNombres')
|
|
NIT = fields.Char('NIT')
|
|
DV = fields.Char('DV')
|
|
PaisEmpleador = fields.Char('Pais')
|
|
MunicipioCiudadEmpleador = fields.Char('MunicipioCiudad')
|
|
DepartamentoEstadoEmpleador = fields.Char('DepartamentoEstado')
|
|
DireccionEmpleador = fields.Char('Direccion')
|
|
|
|
tipocontrato = fields.Selection([
|
|
('1', 'Termino Fijo'),
|
|
('2', 'Termino Indefinido'),
|
|
('3', 'Obra o Labor'),
|
|
('4', 'Aprendizaje'),
|
|
('5', 'Practicas'),
|
|
], string='Tipo de contrato')
|
|
|
|
FechaGen = fields.Char('Fecha Generacion')
|
|
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
|
|
self.paisgeneracion = valores.paisgeneracion
|
|
self.departamentoestado = valores.departamentoestado
|
|
self.municipiociudad = valores.municipiociudad
|
|
self.Idioma = valores.Idioma
|
|
self.ambiente = valores.ambiente
|
|
self.tipoXML = valores.tipoXML
|
|
self.PeriodoNomina = valores.PeriodoNomina
|
|
##Empleador
|
|
self.RazonSocial = valores.RazonSocial
|
|
self.PrimerApellido = valores.PrimerApellido
|
|
self.SegundoApellido = valores.SegundoApellido
|
|
self.PrimerNombre = valores.PrimerNombre
|
|
self.OtrosNombres = valores.OtrosNombres
|
|
self.NIT = valores.NIT
|
|
self.DV = valores.DV
|
|
self.PaisEmpleador = valores.PaisEmpleador
|
|
self.MunicipioCiudadEmpleador = valores.MunicipioCiudadEmpleador
|
|
self.DepartamentoEstadoEmpleador = valores.DepartamentoEstadoEmpleador
|
|
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'}
|
|
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)
|
|
if result.status_code == 200:
|
|
resultado = json.loads(result.text)
|
|
if "documentBase64" in resultado:
|
|
final = resultado["documentBase64"]
|
|
return self.env['wk.wizard.message'].genrated_message('Documento impreso', '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)
|
|
#archivo = final_data['code']
|
|
module_path = modules.get_module_path('tabla_nomina')
|
|
model = "facturas"
|
|
if '\\' in module_path:
|
|
src_path = '\\static\\'
|
|
src_model_path = "{0}{1}\\".format('\\static', model)
|
|
else:
|
|
src_path = '/static/'
|
|
src_model_path = "{0}{1}/".format('/static/', model)
|
|
|
|
# if "model" folder does not exists create it
|
|
os.chdir("{0}{1}".format(module_path, src_path))
|
|
if not os.path.exists(model):
|
|
os.makedirs(model)
|
|
extension = ".pdf"
|
|
#file_path = "{0}{1}".format(module_path + src_model_path + str(name), extension)
|
|
file_path = "{0}{1}".format(module_path + src_model_path + str(self.number), extension)
|
|
if not (os.path.exists(file_path)):
|
|
size =1
|
|
if size == 0:
|
|
os.remove(file_path)
|
|
raise UserError(_('imprimible se esta preparando intenta de nuevo, Factura preparandose.'))
|
|
else:
|
|
import base64
|
|
print(final_data)
|
|
if final_data['code'] == '400':
|
|
return self.env['wk.wizard.message'].genrated_message('Estamos recibiendo un codigo 400 Es necesario esperar para volver imprimir el documento', 'Es necesario esperar para volver a imprimir el documento')
|
|
elif final_data['code'] == '200':
|
|
print("el codigo")
|
|
print(final_data['code'])
|
|
image_64_encode = base64.b64decode(final_data['documentBase64']) #eval(
|
|
i64 = base64.b64encode(image_64_encode)
|
|
att_id = self.env['ir.attachment'].create({
|
|
'name': self.number+extension,
|
|
'type': 'binary',
|
|
'datas': i64,
|
|
'datas_fname': self.number+extension,
|
|
'res_model': 'hr.payslip',
|
|
'res_id': self.id,
|
|
})
|
|
if att_id:
|
|
self.write({"impreso":True})
|
|
return self.env['wk.wizard.message'].genrated_message("Ve a attachment","Factura impresa" ,"https://navegasoft.com")
|
|
else:
|
|
return self.env['wk.wizard.message'].genrated_message('Estamos recibiendo un codigo de error Es necesario esperar para volver imprimir el documento', 'Es necesario esperar para volver a imprimir el documento')
|
|
|
|
else:
|
|
raise UserError(_('Ve a attachment, Factura ya impresa.'))
|
|
|
|
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 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")
|
|
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 = {}
|
|
for linea in valores_lineas:
|
|
if linea.codigo:
|
|
if linea.dias == True:
|
|
for lineacomprobante in self.worked_days_line_ids:
|
|
if linea.codigo == lineacomprobante.code:
|
|
if lineacomprobante.number_of_days > 0.0:
|
|
send[linea.name] = lineacomprobante.number_of_days
|
|
elif linea.horas == True:
|
|
for lineacomprobante in self.worked_days_line_ids:
|
|
if linea.codigo == lineacomprobante.code:
|
|
if lineacomprobante.number_of_hours > 0.0:
|
|
send[linea.name] = lineacomprobante.number_of_hours
|
|
elif linea.porcentaje == True:
|
|
reglas = self.env['hr.salary.rule'].search([('code','=',linea.codigo)])
|
|
for regla in reglas:
|
|
if regla.porcentaje:
|
|
send[linea.name] = regla.porcentaje
|
|
else:
|
|
for lineacomprobante in self.line_ids:
|
|
if linea.codigo == lineacomprobante.code:
|
|
if lineacomprobante.amount != 0.00:
|
|
send[linea.name] = lineacomprobante.amount
|
|
elif linea.campo_tecnico:
|
|
#buscar en el comprobante el codigo
|
|
try:
|
|
if eval(linea.campo_tecnico):
|
|
send[linea.name] = eval(linea.campo_tecnico)
|
|
except SyntaxError:
|
|
return self.env['wk.wizard.message'].genrated_message("El campo tecnico no existe"+linea.campo_tecnico,"Error en el campo"+linea.name,"https://navegasoft.com")
|
|
#pass
|
|
# if linea.name == "DepartamentoEstado":
|
|
# print(linea.name)
|
|
# print(linea.campo_tecnico)
|
|
# print(eval(linea.campo_tecnico))
|
|
# 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:
|
|
resultado = json.loads(result.text)
|
|
if "result" in resultado:
|
|
final = resultado["result"]
|
|
if "error_d" in final:
|
|
if "transactionID" in final:
|
|
self.write({"impreso":False,"transaccionID":final['transactionID'],"estado":"Generada_correctamente"})
|
|
return self.env['wk.wizard.message'].genrated_message(final['mensaje'],final['titulo'] ,final['link'])
|
|
else:
|
|
final_error = json.loads(final) #.decode("utf-8")
|
|
final_text = final_error['error']
|
|
return self.env['wk.wizard.message'].genrated_message("2 "+final_text['mensaje'], final_text['titulo'],final_text['link'])
|
|
# else:
|
|
# return self.env['wk.wizard.message'].genrated_message('3 No hemos recibido una respuesta satisfactoria vuelve a enviarlo', 'Reenviar')
|
|
else:
|
|
if "error" in resultado:
|
|
final = resultado["error"]
|
|
final_error = json.loads(json.dumps(final))
|
|
data = final_error["data"]
|
|
data_final = data['message']
|
|
return self.env['wk.wizard.message'].genrated_message("1 "+data_final,"Los datos no estan correctos" ,"https://navegasoft.com")
|
|
else:
|
|
raise Warning(result)
|
|
return self.env['wk.wizard.message'].genrated_message('Existen problemas de coneccion debes reportarlo con navegasoft', 'Servidor')
|
|
|
|
|
|
|
|
|
|
class nomina_hr_contract(models.Model):
|
|
_name = 'hr.contract'
|
|
_inherit = 'hr.contract'
|
|
|
|
tipo_contrato = fields.Selection([
|
|
('1', 'Término Fijo'),
|
|
('2', 'Término Indefinido'),
|
|
('3', 'Obra o Labor'),
|
|
('4', 'Aprendizaje'),
|
|
('5', 'Practicas'),
|
|
], string='Tipo Contrato')
|
|
|
|
tipo_trabajador = fields.Selection([
|
|
('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'),
|
|
('19', 'Aprendices del SENA en etapa productiva'),
|
|
('20', 'Estudiantes (régimen especial ley 789 de 2002)'),
|
|
('21', 'Estudiantes de postgrado en salud'),
|
|
('22', 'Profesor de establecimiento particular'),
|
|
('23', 'Estudiantes aportes solo riesgos laborales'),
|
|
('30', 'Dependiente entidades o universidades públicas con régimen especial en salud'),
|
|
('31', 'Cooperados o pre cooperativas de trabajo asociado'),
|
|
('32', 'Cotizante miembro de la carrera diplomática o consular de un país extranjero o funcionario de organismo multilateral'),
|
|
('33', 'Beneficiario del fondo de solidaridad pensional'),
|
|
('34', 'Concejal municipal o distrital o edil de junta administrativa local que percibe honorarios amparado por póliza de salud'),
|
|
('35', 'Concejal municipal o distrital que percibe honorarios no amparado con póliza de salud'),
|
|
('36', 'Concejal municipal o distrital que percibe honorarios no amparado con póliza de salud beneficiario del fondo de solidaridad pensional'),
|
|
('40', 'Beneficiario upc adicional'),
|
|
('41', 'Beneficiario sin ingresos con pago por tercero'),
|
|
('42', 'Cotizante pago solo salud articulo 2 ley 1250 de 2008 (independientes de bajos ingresos)'),
|
|
('43', 'Cotizante voluntario a pensiones con pago por tercero'),
|
|
('44', 'Cotizante dependiente de empleo de emergencia con duración mayor o igual a un mes'),
|
|
('45', 'Cotizante dependiente de empleo de emergencia con duración menor a un mes'),
|
|
('47', 'Trabajador dependiente de entidad beneficiaria del sistema general de participaciones - aportes patronales'),
|
|
('51', 'Trabajador de tiempo parcial'),
|
|
('52', 'Beneficiario del mecanismo de protección al cesante'),
|
|
('53', 'Afiliado participe'),
|
|
('54', 'Pre pensionado de entidad en liquidación.'),
|
|
('55', 'Afiliado participe - dependiente'),
|
|
('56', 'Pre pensionado con aporte voluntario a salud'),
|
|
('57', 'Independiente voluntario al sistema de riesgos laborales'),
|
|
('58', 'Estudiantes de prácticas laborales en el sector público'),
|
|
('59', 'Independiente con contrato de prestación de servicios superior a 1 mes'),
|
|
('61', 'Beneficiario programa de reincorporación'),
|
|
], string='Tipo Trabajador')
|
|
sub_tipo_trabajador = fields.Selection([
|
|
('00', 'No Aplica'),
|
|
('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'),
|
|
('19', 'Residente en el exterior afiliado voluntario al sistema general de pensiones y/o afiliado'),
|
|
('20', 'Conductores del servicio público de transporte terrestre automotor individual de pasajeros en vehículos taxi decreto 1047 de 2014'),
|
|
('21', 'Conductores servicio taxi no aporte pensión dec. 1047'),
|
|
], string='Subtipo de Trabajador')
|
|
AltoRiegoPension = fields.Selection([
|
|
('false', 'NO'),
|
|
('true', 'SI'),
|
|
], string='Alto Riego Pension',default='false')
|
|
SalarioIntegral = fields.Selection([
|
|
('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")
|
|
metodo_pago = fields.Selection([
|
|
('1', 'Instrumento no definido'),
|
|
('2', 'Crédito ACH'),
|
|
('3', 'Débito ACH'),
|
|
('4', 'Reversión débito de demanda ACH'),
|
|
('5', 'Reversión crédito de demanda ACH'),
|
|
('6', 'Crédito de demanda ACH'),
|
|
('7', 'Débito de demanda ACH'),
|
|
('8', 'Mantener'),
|
|
('9', 'Clearing Nacional o Regional'),
|
|
('10', 'Efectivo'),
|
|
('11', 'Reversión Crédito Ahorro'),
|
|
('12', 'Reversión Débito Ahorro'),
|
|
('13', 'Crédito Ahorro'),
|
|
('14', 'Débito Ahorro'),
|
|
('15', 'Bookentry Crédito'),
|
|
('16', 'Bookentry Débito'),
|
|
('17', 'Concentración de la demanda en efectivo Desembolso Crédito (CCD)'),
|
|
('18', 'Concentración de la demanda en efectivo Desembolso (CCD) débito'),
|
|
('19', 'Crédito Pago negocio corporativo (CTP)'),
|
|
('20', 'Cheque'),
|
|
('21', 'Proyecto bancario'),
|
|
('22', 'Proyecto bancario certificado'),
|
|
('23', 'Cheque bancario'),
|
|
('24', 'Nota cambiaria esperando aceptación'),
|
|
('25', 'Cheque certificado'),
|
|
('26', 'Cheque Local'),
|
|
('27', 'Débito Pago Negocio Corporativo (CTP)'),
|
|
('28', 'Crédito Negocio Intercambio Corporativo (CTX)'),
|
|
('29', 'Débito Negocio Intercambio Corporativo (CTX)'),
|
|
('30', 'Transferencia Crédito'),
|
|
('31', 'Transferencia Débito'),
|
|
('32', 'Concentración Efectivo / Desembolso Crédito plus (CCD+)'),
|
|
('33', 'Concentración Efectivo / Desembolso Débito plus (CCD+)'),
|
|
('34', 'Pago y depósito pre acordado (PPD)'),
|
|
('35', 'Concentración efectivo ahorros / Desembolso Crédito (CCD)'),
|
|
('36', 'Concentración efectivo ahorros / Desembolso Crédito (CCD)'),
|
|
('37', 'Pago Negocio Corporativo Ahorros Crédito (CTP)'),
|
|
('38', 'Pago Negocio Corporativo Ahorros Débito (CTP)'),
|
|
('39', 'Crédito Negocio Intercambio Corporativo (CTX)'),
|
|
('40', 'Débito Negocio Intercambio Corporativo (CTX)'),
|
|
('41', 'Concentración efectivo/Desembolso Crédito plus (CCD+)'),
|
|
('42', 'Consignación bancaria'),
|
|
('43', 'Concentración efectivo / Desembolso Débito plus (CCD+)'),
|
|
('44', 'Nota cambiaria'),
|
|
('45', 'Transferencia Crédito Bancario'),
|
|
('46', 'Transferencia Débito Interbancario'),
|
|
('47', 'Transferencia Débito Bancaria'),
|
|
('48', 'Tarjeta Crédito'),
|
|
('49', 'Tarjeta Débito'),
|
|
('50', 'Postgiro'),
|
|
('51', 'Telex estándar bancario francés'),
|
|
('52', 'Pago comercial urgente'),
|
|
('53', 'Pago Tesorería Urgente'),
|
|
('60', 'Nota promisoria'),
|
|
('61', 'Nota promisoria firmada por el acreedor'),
|
|
('62', 'Nota promisoria firmada por el acreedor, avalada por el banco'),
|
|
('63', 'Nota promisoria firmada por el acreedor, avalada por un tercero'),
|
|
('64', 'Nota promisoria firmada por el banco'),
|
|
('65', 'Nota promisoria firmada por un banco avalada por otro banco'),
|
|
('66', 'Nota promisoria firmada'),
|
|
('67', 'Nota promisoria firmada por un tercero avalada por un banco'),
|
|
('70', 'Retiro de nota por el por el acreedor'),
|
|
('71', 'Bonos'),
|
|
('72', 'Vales'),
|
|
('74', 'Retiro de nota por el por el acreedor sobre un banco'),
|
|
('75', 'Retiro de nota por el acreedor, avalada por otro banco'),
|
|
('76', 'Retiro de nota por el acreedor, sobre un banco avalada por un tercero'),
|
|
('77', 'Retiro de una nota por el acreedor sobre un tercero'),
|
|
('78', 'Retiro de una nota por el acreedor sobre un tercero avalada por un banco'),
|
|
('91', 'Nota bancaria transferible'),
|
|
('92', 'Cheque local trasferible'),
|
|
('93', 'Giro referenciado'),
|
|
('94', 'Giro urgente'),
|
|
('95', 'Giro formato abierto'),
|
|
('96', 'Método de pago solicitado no usado'),
|
|
('97', 'Clearing entre partners'),
|
|
('ZZZ', 'Acuerdo mutuo'),
|
|
], string='Metodo de pago',default='10')
|
|
|
|
#raise Warning(final["error"])
|
|
#print()
|
|
|
|
|
|
|
|
# for nombre in numeracion:
|
|
# print(nombre)
|
|
|
|
# print(result.message)
|
|
# print(result.messageError)
|
|
|
|
# clause_final = [('name', '=', 'primer')]
|
|
# valores = self.env['tabla_nomina.tabla_nomina'].search(clause_final)
|
|
# fields = self.env['tabla_nomina.tabla_nomina'].fields_get()
|
|
# #
|
|
# totalDays =100
|
|
# numero =1
|
|
# send = {}
|
|
# for k, v in fields.items():
|
|
# numero = numero + 1
|
|
# if numero < 6:
|
|
# print("nuevo valor")
|
|
# print(k)
|
|
# print(valores[k])
|
|
# if valores[k]:
|
|
# if not k == "name":
|
|
# send[k] = exec(valores[k])
|
|
# print(exec(valores[k]))
|
|
|
|
|
|
|