Move all OCA HR modules from oca-technical to dedicated oca-hr submodule

Reorganized 67 HR-related modules for better structure:
- Moved all odoo-bringout-oca-hr-* packages from packages/oca-technical/
- Now organized in dedicated packages/oca-hr/ submodule
- Includes attendance, expense, holiday, employee, and contract modules
- Maintains all module functionality while improving project organization

This creates a cleaner separation between general technical modules
and HR-specific functionality.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ernad Husremovic 2025-08-30 17:11:28 +02:00
parent f672249949
commit dfcda4100c
2456 changed files with 120722 additions and 0 deletions

View file

@ -0,0 +1,5 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import hr_employee
from . import res_company
from . import res_config_settings

View file

@ -0,0 +1,69 @@
# Copyright 2011, 2013 Michael Telahun Makonnen <mmakonnen@gmail.com>
# Copyright 2016 OpenSynergy Indonesia
# Copyright 2018 Brainbean Apps (https://brainbeanapps.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
import random
import string
from odoo import _, api, fields, models
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class HrEmployee(models.Model):
"""Implement company wide unique identification number."""
_inherit = "hr.employee"
identification_id = fields.Char(string="Identification No", copy=False)
_sql_constraints = [
(
"identification_id_uniq",
"unique(identification_id)",
"The Employee Number must be unique across the company(s).",
),
]
@api.model
def _generate_identification_id(self):
"""Generate a random employee identification number"""
company = self.env.user.company_id
steps = 0
for _retry in range(50):
employee_id = False
if company.employee_id_gen_method == "sequence":
if not company.employee_id_sequence:
_logger.warning("No sequence configured for employee ID generation")
return employee_id
employee_id = company.employee_id_sequence.next_by_id()
elif company.employee_id_gen_method == "random":
employee_id_random_digits = company.employee_id_random_digits
rnd = random.SystemRandom()
employee_id = "".join(
rnd.choice(string.digits) for x in range(employee_id_random_digits)
)
if self.search_count([("identification_id", "=", employee_id)]):
steps += 1
continue
return employee_id
raise UserError(
_("Unable to generate unique Employee ID in %d steps.") % (steps,)
)
@api.model_create_multi
def create(self, vals_list):
records = super().create(vals_list)
for record in records:
if not record.identification_id:
record.identification_id = record._generate_identification_id()
return records

View file

@ -0,0 +1,27 @@
# Copyright 2015 Salton Massally <smassally@idtlabs.sl>
# Copyright 2016 OpenSynergy Indonesia
# Copyright 2018 Brainbean Apps (https://brainbeanapps.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class ResCompany(models.Model):
_inherit = "res.company"
employee_id_gen_method = fields.Selection(
selection=[
("random", "Random"),
("sequence", "Sequence"),
],
string="Generation Method",
default="random",
)
employee_id_random_digits = fields.Integer(
string="# of Digits", default=5, help="Number of digits in employee identifier"
)
employee_id_sequence = fields.Many2one(
comodel_name="ir.sequence",
string="Identifier Sequence",
help="Pattern to be used for employee identifier generation",
)

View file

@ -0,0 +1,49 @@
# Copyright 2015 Salton Massally <smassally@idtlabs.sl>
# Copyright 2016 OpenSynergy Indonesia
# Copyright 2018 Brainbean Apps (https://brainbeanapps.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
employee_id_gen_method = fields.Selection(
related="company_id.employee_id_gen_method",
readonly=False,
default=lambda self: self._default_id_gen_method(),
)
employee_id_random_digits = fields.Integer(
related="company_id.employee_id_random_digits",
readonly=False,
default=lambda self: self._default_id_random_digits(),
)
employee_id_sequence = fields.Many2one(
"ir.sequence",
related="company_id.employee_id_sequence",
readonly=False,
default=lambda self: self._default_id_sequence(),
)
def _default_id_gen_method(self):
gen_method = self.env.user.company_id.employee_id_gen_method
if not gen_method:
gen_method = self.env["res.company"].default_get(
["employee_id_gen_method"]
)["employee_id_gen_method"]
return gen_method
def _default_id_random_digits(self):
digits = self.env.user.company_id.employee_id_random_digits
if not digits:
digits = self.env["res.company"].default_get(["employee_id_random_digits"])[
"employee_id_random_digits"
]
return digits
def _default_id_sequence(self):
sequence = self.env.user.company_id.employee_id_sequence
if not sequence:
sequence = self.env.ref("hr_employee_id.seq_hr_employee_id")
return sequence and sequence.id or False