nomina en odoo

Hola a tod@s, en este pequeño tutorial quiero mostrar, una nomina en odoo que desarrolle para llevar un registro a los empleados, y de esa manera tengan una copia de su liquidación de sueldo, este desarrollo no es, tan complejo o tan completo como lo puedes encontrar dentro de odoo (https://apps.odoo.com/apps) (https://odoo-community.org/shop), pero sirve para el propósito de mi cliente y si alguien lo quiere utilizar aqui les dejo el código, obviamente siéntanse libre de mejorarlo.

bueno supongo que si estas viendo esto, es porque ya sabes algo de odoo y te manejas en algo con el código y su estructura, dejo una imagen de como se ve el from, aclaro que esta hecho para Chile.

Nomina en Odoo

nomina en odoo

Ahora ingresare el código del .py que concierne a la nomina, como comente ustedes son libres de modificar los nombres y si lo pueden mejorar lo puedan compartir.

Nomina.py

# -*- coding: utf-8 -*-

from datetime import date
from dateutil.relativedelta import relativedelta

from odoo import api, fields, models, _
from odoo.exceptions import ValidationError

from odoo.osv import expression

class NominaCert(models.Model):
    _name = 'cert.nomina'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _description = 'Nomina Empleados'

    name = fields.Many2one('res.users', string='Empleados', required=True,)
    rut = fields.Char(string='Rut', related="name.identification_id")
    poste = fields.Char(related='name.job_title', string='Puesto de Trabajo')
    date = fields.Date('Fecha', default=fields.Date.today())
    sale = fields.Integer(string='Sueldo dias Trabajados', compute='_sale', help='Son los Dias que Trabajo el Empleado')
    bonus = fields.Integer(string='Bonificación Imponible')
    extra = fields.Integer(string='Horas Extras')
    gratuity = fields.Integer(string='Gratificación Legal', compute='_gratuity')
    afp = fields.Integer(string='AFP', compute='_afp', store=True)
    afp_id = fields.Float(string='Fondo AFP %', related='contract_id.afp_id')
    fonasa = fields.Integer(string='Fonasa / Isapre', compute='_fonasa', store=True)
    fonasa_id = fields.Float(string='Fonasa %', related='contract_id.fonasa_id')
    sure = fields.Integer(string='Seguro de Cesantia', compute='_sure')
    sure_id = fields.Float(string='Seguro %', related='contract_id.sure_id')
    tax = fields.Integer(string='Impuesto Unico')
    family = fields.Integer(string='Cargas Familiares')
    car = fields.Integer(string='Asignación Locomoción')
    lunch = fields.Integer(string='Asignación de Colación')

    taxi = fields.Integer(string='Haberes Imponibles', compute='_taxi')
    tax_id = fields.Integer(string='Haberes No Imponibles', compute='_tax_id')
    discount = fields.Integer(string='Descuentos', compute='_discount')
    pay = fields.Integer(string='Liquido a Pagar', compute='_pay', store=True)
    month = fields.Selection([('E', 'Enero'), ('F', 'Febrero'), ('M', 'Marzo'), ('A', 'Abril'), ('Z', 'Mayo'),
                              ('J', 'Junio'), ('X', 'Julio'), ('B', 'Agosto'), ('S', 'Septiembre'), ('O', 'Octubre'),
                              ('N', 'Noviembre'), ('D', 'Diciembre')], default=' ')

    contract_id = fields.Many2one('hr.contract', string='Contracto', required=True)
    days = fields.Integer(string='Dias Trabajados', required=True)
    sale_id = fields.Integer(string='Sueldo Base', related='contract_id.sale', store=True)


    @api.depends('days','sale_id')
    def _sale(self):
        for r in self:
            her = r.days
            jer = r.sale_id /30
            ger = jer * her
            if her <= 30:
                r.sale = ger
            else:
                r.sale = 0

    @api.depends('sale','bonus','extra')
    def _gratuity(self):
        for r in self:
            gratuity = 0.25*(r.sale+r.bonus+r.extra)
            if gratuity <= 158333:
                r.gratuity = gratuity
            else:
                r.gratuity = 158333

    @api.depends('sale','bonus','extra','gratuity')
    def _taxi(self):
        for r in self:
            r.taxi = r.sale+r.bonus+r.extra+r.gratuity

    @api.depends('family','car','lunch')
    def _tax_id(self):
        for r in self:
            r.tax_id = r.family+r.car+r.lunch

    @api.depends('taxi','sure_id')
    def _sure(self):
        for r in self:
            r.sure =  r.sure_id*r.taxi/100

    @api.depends('taxi','fonasa_id')
    def _fonasa(self):
        for r in self:
            r.fonasa = r.fonasa_id*r.taxi/100

    @api.depends('taxi','afp_id')
    def _afp(self):
       for r in self:
          r.afp = r.afp_id*r.taxi/100

    @api.depends('afp','fonasa','sure','tax')
    def _discount(self):
        for r in self:
            r.discount = r.afp+r.fonasa+r.sure+r.tax

    @api.depends('taxi','tax_id','discount')
    def _pay(self):
        for r in self:
            r.pay = r.taxi+r.tax_id-r.discount

Ahora les comparto el código del archivo XML, donde creo el form, el tree y el pivot el cual se usa para sacar valores para el pago de los impuestos.

Views_nomina.xml

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>

        //from para el modulo de nomina de los empleados//

        <record id="view_cert_nomina_form" model="ir.ui.view">
            <field name="name">nomina.form</field>
            <field name="model">cert.nomina</field>
            <field name="arch" type="xml">
                <form string="Nomina">
                    <sheet>
                        <separator string="CREAR LIQUIDACIÓN"/>
                        <div class="oe_title">
                             <h1>
                                <field name="name" placeholder="Empleado..."  />
                             </h1>
                        </div>
                        <group col="4">
                            <field name="rut"/>
                            <field name="poste"/>
                            <field name="date"/>
                            <field name="contract_id"/>
                            <field name="month" required="1"/>
                            <field name="sale_id"/>
                        </group>

                        <group col="4">
                            <field name="days"/>
                            <field name="afp_id" invisible="True"/>
                            <field name="sale"/>
                            <field name="afp"/>
                            <field name="bonus"/>
                            <field name="fonasa"/>
                            <field name="extra"/>
                            <field name="sure"/>
                            <field name="gratuity"/>
                            <field name="fonasa_id" invisible="True"/>
                            <field name="sure_id" invisible="True"/>
                        </group>
                        <group col="4">
                            <field name="family"/>
                            <field name="tax"/>
                            <field name="car"/>
                            <field name="lunch"/>
                        </group>
                        <group col="4">
                            <field name="taxi"/>
                            <field name="discount"/>
                            <field name="tax_id"/>
                            <field name="pay" sum="Total"/>
                        </group>
                    </sheet>
                    <div class="oe_chatter">
                        <field name="message_follower_ids"/>
                        <field name="activity_ids"/>
                        <field name="message_ids"/>
                    </div>
                </form>
            </field>
        </record>


        <record id="view_cert_nomina_tree" model="ir.ui.view">
            <field name="name">nomina.tree</field>
            <field name="model">cert.nomina</field>
            <field name="arch" type="xml">
                <tree string="Nomina">
                    <field name="name"/>
                    <field name="rut"/>
                    <field name="poste" optional="hide"/>
                    <field name="month"/>
                    <field name="days"/>
                    <field name="sale"/>
                    <field name="afp"/>
                    <field name="fonasa" optional="hide"/>
                    <field name="sure" optional="hide"/>
                    <field name="gratuity" optional="hide"/>
                    <field name="taxi" optional="hide"/>
                    <field name="discount"/>
                    <field name="pay"/>
                </tree>
            </field>
        </record>


        <record id="view_cert_nomina_pivot" model="ir.ui.view">
            <field name="model">cert.nomina</field>
            <field name="arch" type="xml">
                <pivot>
                    <field name="name" type="row"/>
                    <field name="month" interval="year" type="col"/>
                    <field name="afp" type="measure"/>
                    <field name="fonasa" type="measure"/>
                    <field name="pay" type="measure"/>
                </pivot>
            </field>
        </record>

    </data>
</odoo>

Por ultimo les dejare el codigo del template, para imprimir la liquidacion de sueldo al empleado.

Templates_nomina.xml

<?xml version="1.0" encoding="utf-8"?>
<odoo>
    <data>
        <report id="reporte_nomina_cert"
            string="Imp Liquidación"
            model="cert.nomina"
            report_type="qweb-pdf"
            name="shool_startel.nomina_reporte_nomina_cert"
            print_report_name="'Liquidación - %s' % (object.name)"

        />

        <template id="nomina_reporte_nomina_cert">
            <t t-call="web.html_container">
                <t t-foreach="docs" t-as="o">
                    <t t-call="web.external_layout">
                        <div class="page">
                            <head>
                                <style>
                                    .demo {
                                    border: 1px sólido #354259;
                                    border-collapse:colapso;
                                    padding:0px;
                                    border-radius: 10px;
                                    font-size: 12px;
                                    }
                                    .demo th {
                                    border: 1px sólido #354259;
                                    padding:5px;
                                    text-align:centrar;
                                    background:#839AA8;
                                    }
                                    .demo td {
                                    border: 1px sólido #354259;
                                    padding:5px;
                                    }
                                </style>
                            </head>
                            <div>
                                <h4>
                                    <center>Escuela de Conductores </center>
                                    <center>76.000.000-0</center>
                                    <center>Andres Bello 100 - Valdivia</center>
                                </h4>
                                <h4>
                                    <center>Liquidaciones de Remuneraciones Mes
                                        <span t-field="o.month"/>
                                    </center>
                                </h4>
                                <br/>
                                <h5>
                                    Nombre :
                                    <span t-field="o.name"/>
                                    <br/>
                                    Rut :
                                    <span t-field="o.rut"/>
                                    <br/>
                                    Cargo :
                                    <span t-field="o.poste"/>
                                    <br/>
                                    Dias Trabajados :
                                    <span t-field="o.days"/>
                                </h5>
                            </div>
                            <br/>

                            <div class="row" align="center">
                                <table width="100%" style="border: 2px solid black" class="demo">
                                    <thead>
                                        <tr>
                                            <th>Haberes</th>
                                            <th></th>
                                            <th>Descuentos</th>
                                            <th></th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        <tr>
                                            <td>Sueldo Base</td>
                                            <td style="text-align: right">
                                                <span t-field="o.sale"/>
                                            </td>
                                            <td>AFP</td>
                                            <td style="text-align: right">
                                                <span t-field="o.afp"/>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>Bonificación Imponible</td>
                                            <td style="text-align: right">
                                                <span t-field="o.bonus"/>
                                            </td>
                                            <td>Fonasa</td>
                                            <td style="text-align: right">
                                                <span t-field="o.fonasa"/>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>Horas Extras</td>
                                            <td style="text-align: right">
                                                <span t-field="o.extra"/>
                                            </td>
                                            <td>Seguro de Cesantia</td>
                                            <td style="text-align: right">
                                                <span t-field="o.sure"/>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>Gratificación Legal</td>
                                            <td style="text-align: right">
                                                <span t-field="o.gratuity"/>
                                            </td>
                                            <td>Impuesto Unico</td>
                                            <td style="text-align: right">
                                                <span t-field="o.tax"/>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>Cargas Familiares</td>
                                            <td style="text-align: right">
                                                <span t-field="o.family"/>
                                            </td>
                                            <td></td>
                                            <td style="text-align: right">0</td>
                                        </tr>
                                        <tr>
                                            <td>Asignación de Locomoción</td>
                                            <td style="text-align: right">
                                                <span t-field="o.car"/>
                                            </td>
                                            <td></td>
                                            <td style="text-align: right">0</td>
                                        </tr>
                                        <tr>
                                            <td>Asignación de Colación</td>
                                            <td style="text-align: right">
                                                <span t-field="o.lunch"/>
                                            </td>
                                            <td></td>
                                            <td style="text-align: right">0</td>
                                        </tr>
                                        <tr>
                                            <td></td>
                                            <td></td>
                                            <td></td>
                                            <td></td>
                                        </tr>
                                        <tr>
                                            <td>Haberes Imponibles</td>
                                            <td style="text-align: right">
                                                <span t-field="o.taxi"/>
                                            </td>
                                            <td>Descuentos</td>
                                            <td style="text-align: right">
                                                <span t-field="o.discount"/>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>Haberes No Imponibles</td>
                                            <td style="text-align: right">
                                                <span t-field="o.tax_id"/>
                                            </td>
                                            <td style="background: #839AA8">Liquido a Pagar</td>
                                            <td style="background: #839AA8; text-align: right">
                                                <span t-field="o.pay"/>
                                            </td>
                                        </tr>
                                    </tbody>
                                </table>

                            </div>
                            <div>
                                <p>
                                    Certifico Haber recibido de C la remuneracion integra a pagar indicada
                                    en esta liquidacion no teneniendo cobro alguno que hacer por dichos conceptos.
                                </p>
                            </div>
                            <br/>
                            <br/>
                            <br/>
                            <div>
                                <h5>
                                    <center>FIRMA DEL TRABAJADOR</center>
                                </h5>
                            </div>
                        </div>
                        <div class="footer">
                            <p>
                                <center>www.serco.com - Telefono:(45)11111868 - Mail: [email protected]</center>
                            </p>
                        </div>
                    </t>
                </t>
            </t>
        </template>
    </data>
</odoo>

Dejo una imagen del template como se veria al imprimir.

nomina en odoo

Obviamente todo lo que comparto es porque yo lo he realizado y esta funcionando, mas adelante seguire compartiendo mas cosas en las cuales estoy trabajando, no soy un esperto en odoo, ni en programacion, me dedico a la conectividad y seguridad de la información.

Scroll al inicio