Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions hr_master_data/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
============================
Employee Master Data History
============================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:29a588be2e853bcfaa92f2f2c0c3d43b2e9f769097eec5f550fc44f437d19bcd
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html
:alt: License: LGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpayroll-lightgray.png?logo=github
:target: https://github.com/OCA/payroll/tree/18.0/hr_master_data
:alt: OCA/payroll
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/payroll-18-0/payroll-18-0-hr_master_data
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/payroll&target_branch=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

Historical employee master data management.

Configure the relevant master data attributes, and track their change
along time. For example, professional details (Profession, Category, Pay
Grade), tax information (Social Security Status, Income Tax Status) or
even pay related (Is Time Schedule Exempt, Base Salary, etc.).

**Table of contents**

.. contents::
:local:

Configuration
=============

On Employees / Configuration you can:

- "Master Data Types": configure the attributes to track, that can be
organized in groups. An attribute value can be a selection from a
list, a number, or a boolean flag.
- "Master Data Change Reasons": configure the differernt reasons that
can be used to track why a history value has changed.

Usage
=====

On Employee Contracts, click on the "Master Data" snart button to open
the list of employee master data records.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/payroll/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/payroll/issues/new?body=module:%20hr_master_data%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Daniel Reis

Contributors
------------

- Daniel Reis <<[email protected]>>

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-dreispt| image:: https://github.com/dreispt.png?size=40px
:target: https://github.com/dreispt
:alt: dreispt

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-dreispt|

This module is part of the `OCA/payroll <https://github.com/OCA/payroll/tree/18.0/hr_master_data>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions hr_master_data/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
23 changes: 23 additions & 0 deletions hr_master_data/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2025 Open Source Integrators (www.opensourceintegrators.com)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
{
"name": "Employee Master Data History",
"summary": "Configure master data attributes and track their changes history.",
"version": "18.0.1.0.0",
"category": "Payroll",
"website": "https://github.com/OCA/payroll",
"license": "LGPL-3",
"author": "Daniel Reis, Odoo Community Association (OCA)",
"depends": ["hr_contract"],
"data": [
"security/hr_payroll_security.xml",
"security/ir.model.access.csv",
"data/hr_master_data.xml",
"views/hr_data_value_views.xml",
"views/hr_contract_value_views.xml",
"views/hr_contract_views.xml",
],
"demo": ["data/demo_data.xml"],
"installable": True,
"maintainers": ["dreispt"],
}
90 changes: 90 additions & 0 deletions hr_master_data/data/demo_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<odoo>
<!-- Master Data Values -->
<record model="hr.data.type.value" id="value_colcontr1">
<field name="type_id" ref="data_colcontr" />
<field name="name">General Labor Law</field>
</record>
<record model="hr.data.type.value" id="value_colcontr2">
<field name="type_id" ref="data_colcontr" />
<field name="name">Collective Contract</field>
</record>
<record model="hr.data.type.value" id="value_profcateg1">
<field name="type_id" ref="data_profcateg" />
<field name="name">Category A</field>
</record>
<record model="hr.data.type.value" id="value_profcateg2">
<field name="type_id" ref="data_profcateg" />
<field name="name">Category B</field>
</record>

<record model="hr.data.type.value" id="value_paygrade1">
<field name="type_id" ref="data_paygrade" />
<field name="name">Grade 1</field>
</record>
<record model="hr.data.type.value" id="value_paygrade2">
<field name="type_id" ref="data_paygrade" />
<field name="name">Grade 2</field>
</record>

<record model="hr.data.type.value" id="value_ss1">
<field name="type_id" ref="data_sspos" />
<field name="name">SS Position 1</field>
</record>
<record model="hr.data.type.value" id="value_ss2">
<field name="type_id" ref="data_sspos" />
<field name="name">SS Position 2</field>
</record>

<record model="hr.data.type.value" id="value_tax1">
<field name="type_id" ref="data_taxpos" />
<field name="name">Tax Position 1</field>
</record>
<record model="hr.data.type.value" id="value_tax2">
<field name="type_id" ref="data_taxpos" />
<field name="name">Tax Position 2</field>
</record>

<!-- Employee Data Values -->
<record model="hr.employee.data.value" id="contract_value_contrcol">
<field name="contract_id" ref="hr_contract.hr_contract_mit" />
<field name="type_id" ref="data_colcontr" />
<field name="value_id" ref="value_colcontr1" />
<field name="date_start">2019-01-01</field>
</record>
<record model="hr.employee.data.value" id="contract_value1">
<field name="contract_id" ref="hr_contract.hr_contract_mit" />
<field name="type_id" ref="data_profcateg" />
<field name="value_id" ref="value_profcateg1" />
<field name="date_start">2019-01-01</field>
</record>
<record model="hr.employee.data.value" id="contract_value2">
<field name="contract_id" ref="hr_contract.hr_contract_mit" />
<field name="type_id" ref="data_paygrade" />
<field name="value_id" ref="value_paygrade1" />
<field name="date_start">2019-01-01</field>
</record>
<record model="hr.employee.data.value" id="contract_value3">
<field name="contract_id" ref="hr_contract.hr_contract_mit" />
<field name="type_id" ref="data_sspos" />
<field name="value_id" ref="value_ss1" />
<field name="date_start">2019-01-01</field>
</record>
<record model="hr.employee.data.value" id="contract_value4">
<field name="contract_id" ref="hr_contract.hr_contract_mit" />
<field name="type_id" ref="data_taxpos" />
<field name="value_id" ref="value_tax1" />
<field name="date_start">2019-01-01</field>
</record>
<record model="hr.employee.data.value" id="contract_value_sal1">
<field name="contract_id" ref="hr_contract.hr_contract_mit" />
<field name="type_id" ref="data_base_salary" />
<field name="value_float">3000.00</field>
<field name="date_start">2019-01-01</field>
</record>
<record model="hr.employee.data.value" id="contract_value_sal2">
<field name="contract_id" ref="hr_contract.hr_contract_mit" />
<field name="type_id" ref="data_exempt" />
<field name="value_bool">True</field>
<field name="date_start">2019-01-01</field>
</record>
</odoo>
49 changes: 49 additions & 0 deletions hr_master_data/data/hr_master_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<odoo>
<!-- Master Data Groups -->
<record model="hr.data.group" id="data_group_professional">
<field name="name">Professional Data</field>
</record>
<record model="hr.data.group" id="data_group_taxes">
<field name="name">Tax Positions</field>
</record>
<record model="hr.data.group" id="data_salary">
<field name="name">Salary Data</field>
</record>

<!-- Master Data Types -->
<record model="hr.data.type" id="data_colcontr">
<field name="name">Collective Contract</field>
<field name="value_type">id</field>
<field name="group_id" ref="data_group_professional" />
</record>
<record model="hr.data.type" id="data_profcateg">
<field name="name">Professional Category</field>
<field name="value_type">id</field>
<field name="group_id" ref="data_group_professional" />
</record>
<record model="hr.data.type" id="data_paygrade">
<field name="name">Pay Grade</field>
<field name="value_type">id</field>
<field name="group_id" ref="data_group_professional" />
</record>
<record model="hr.data.type" id="data_sspos">
<field name="name">Social Security Position</field>
<field name="value_type">id</field>
<field name="group_id" ref="data_group_taxes" />
</record>
<record model="hr.data.type" id="data_taxpos">
<field name="name">Income Tax Position</field>
<field name="value_type">id</field>
<field name="group_id" ref="data_group_taxes" />
</record>
<record model="hr.data.type" id="data_base_salary">
<field name="name">Base Salary</field>
<field name="value_type">float</field>
<field name="group_id" ref="data_salary" />
</record>
<record model="hr.data.type" id="data_exempt">
<field name="name">Time Schedule Exempt</field>
<field name="value_type">bool</field>
<field name="group_id" ref="data_salary" />
</record>
</odoo>
6 changes: 6 additions & 0 deletions hr_master_data/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from . import hr_contract
from . import hr_data_group
from . import hr_data_type
from . import hr_data_type_value
from . import hr_data_value_reason
from . import hr_employee_data_value
42 changes: 42 additions & 0 deletions hr_master_data/models/hr_contract.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2025 Open Source Integrators (www.opensourceintegrators.com)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo import api, fields, models


class HrContract(models.Model):
_inherit = "hr.contract"

@api.depends_context("active_date")
@api.depends("contract_values_ids")
def _compute_active_values_ids(self):
"Returns the active values for the contract at a context given date"
active_date = self.env.context.get("active_date")

Check warning on line 13 in hr_master_data/models/hr_contract.py

View check run for this annotation

Codecov / codecov/patch

hr_master_data/models/hr_contract.py#L13

Added line #L13 was not covered by tests
for contract in self:
contract.active_values_ids = contract.contract_values_ids.filtered(

Check warning on line 15 in hr_master_data/models/hr_contract.py

View check run for this annotation

Codecov / codecov/patch

hr_master_data/models/hr_contract.py#L15

Added line #L15 was not covered by tests
lambda x: not active_date
or (
(not x.date_start or x.date_start <= active_date)
and (not x.date_end or x.date_end >= active_date)
)
)

contract_values_ids = fields.One2many(
comodel_name="hr.employee.data.value",
inverse_name="contract_id",
)
active_values_ids = fields.One2many(
comodel_name="hr.employee.data.value",
compute="_compute_active_values_ids",
)

def action_open_master_data(self):
self.ensure_one()
xmlid = "hr_master_data.action_hr_employee_data_value"
action = self.env["ir.actions.actions"]._for_xml_id(xmlid)
action.update(

Check warning on line 36 in hr_master_data/models/hr_contract.py

View check run for this annotation

Codecov / codecov/patch

hr_master_data/models/hr_contract.py#L33-L36

Added lines #L33 - L36 were not covered by tests
{
"domain": [("contract_id", "=", self.id)],
"context": {"default_contract_id": self.id},
}
)
return action

Check warning on line 42 in hr_master_data/models/hr_contract.py

View check run for this annotation

Codecov / codecov/patch

hr_master_data/models/hr_contract.py#L42

Added line #L42 was not covered by tests
13 changes: 13 additions & 0 deletions hr_master_data/models/hr_data_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025 Open Source Integrators (www.opensourceintegrators.com)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo import fields, models


class HrDataGroup(models.Model):
_name = "hr.data.group"
_description = "Master Data Group"
_order = "code,name"

name = fields.Char()
code = fields.Char()
active = fields.Boolean()
21 changes: 21 additions & 0 deletions hr_master_data/models/hr_data_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2025 Open Source Integrators (www.opensourceintegrators.com)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo import fields, models


class HrDataType(models.Model):
_name = "hr.data.type"
_description = "Master Data Type"
_order = "code,name"

name = fields.Char(required=True)
code = fields.Char()
value_type = fields.Selection(
selection=[("bool", "Yes/No"), ("float", "Numeric"), ("id", "Selection Value")],
required=True,
)
group_id = fields.Many2one(comodel_name="hr.data.group")
active = fields.Boolean(default=True)
values_ids = fields.One2many(
comodel_name="hr.data.type.value", inverse_name="type_id"
)
15 changes: 15 additions & 0 deletions hr_master_data/models/hr_data_type_value.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2025 Open Source Integrators (www.opensourceintegrators.com)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo import fields, models


class HrDataTypeValue(models.Model):
_name = "hr.data.type.value"
_description = "Master Data Value"
_order = "sequence,name"

name = fields.Char()
code = fields.Char()
sequence = fields.Integer()
type_id = fields.Many2one(comodel_name="hr.data.type")
active = fields.Boolean(default=True)
13 changes: 13 additions & 0 deletions hr_master_data/models/hr_data_value_reason.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025 Open Source Integrators (www.opensourceintegrators.com)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo import fields, models


class HrDataValueReason(models.Model):
_name = "hr.data.value.reason"
_description = "Master Data Change Reason"
_order = "code,name"

name = fields.Char()
code = fields.Char()
active = fields.Boolean(default=True)
Loading