diff --git a/hr_payroll_period/README.rst b/hr_payroll_period/README.rst index 66a1f742c..8ede3ecc9 100644 --- a/hr_payroll_period/README.rst +++ b/hr_payroll_period/README.rst @@ -54,6 +54,10 @@ Configuration Create a fiscal year ~~~~~~~~~~~~~~~~~~~~ + +Go to: Payroll -> Configuration -> Settings -> Payroll + - Put the number of months in advance for creating the new HR periods + Go to: Payroll -> Configuration -> Payroll Fiscal Year - Select a type of schedule, e.g. monthly diff --git a/hr_payroll_period/__manifest__.py b/hr_payroll_period/__manifest__.py index 283e671f1..65ff4e89e 100644 --- a/hr_payroll_period/__manifest__.py +++ b/hr_payroll_period/__manifest__.py @@ -27,6 +27,7 @@ "views/hr_payslip_view.xml", "views/hr_payslip_run_view.xml", "views/hr_payslip_employee_view.xml", + "views/res_config_settings_view.xml", ], "installable": True, "maintainers": ["nimarosa"], diff --git a/hr_payroll_period/data/ir_cron.xml b/hr_payroll_period/data/ir_cron.xml index 6eaf732ab..143f40323 100644 --- a/hr_payroll_period/data/ir_cron.xml +++ b/hr_payroll_period/data/ir_cron.xml @@ -1,7 +1,7 @@ - Create Next Fiscal Year + Create Next Payroll Fiscal Year 1 months -1 diff --git a/hr_payroll_period/models/__init__.py b/hr_payroll_period/models/__init__.py index 1d19beedd..4efe34ad5 100644 --- a/hr_payroll_period/models/__init__.py +++ b/hr_payroll_period/models/__init__.py @@ -8,3 +8,5 @@ from . import hr_payslip_run from . import hr_period from . import hr_employee +from . import res_company +from . import res_config_settings diff --git a/hr_payroll_period/models/hr_fiscal_year.py b/hr_payroll_period/models/hr_fiscal_year.py index d74bdb96f..d179f74b4 100644 --- a/hr_payroll_period/models/hr_fiscal_year.py +++ b/hr_payroll_period/models/hr_fiscal_year.py @@ -305,44 +305,45 @@ def search_period(self, number): @api.model def cron_create_next_fiscal_year(self): - current_year = datetime.now().year + company = self.env.company + today = fields.Date.context_today(self) + current_year = today.year next_year = current_year + 1 - # Get the latest fiscal year that has not ended yet - latest_fiscal_year = self.search( - [("date_end", "<", datetime(next_year, 1, 1).strftime(DF))], - order="date_end desc", + current_fy = self.search( + [("date_start", "<=", today), ("date_end", ">=", today)], limit=1, ) - if not latest_fiscal_year: + if not current_fy: return self - latest_period_end = max(latest_fiscal_year.period_ids.mapped("date_end")) - fiscal_year_start = latest_period_end + relativedelta(days=1) + + threshold_date = fields.Date.from_string(current_fy.date_end) - relativedelta( + months=company.payroll_fiscalyear_creation_months_before + ) + if today < threshold_date: + return self + fiscal_year_start = fields.Date.from_string( + current_fy.date_end + ) + relativedelta(days=1) fiscal_year_end = datetime(next_year, 12, 31).strftime(DF) - # Check if a fiscal year with the same start and end dates already exists - existing_fiscal_year = self.search( + existing_fy = self.search( [ ("date_start", "=", fiscal_year_start), ("date_end", "=", fiscal_year_end), ], limit=1, ) - if existing_fiscal_year: - return existing_fiscal_year - - schedule_pay = latest_fiscal_year.schedule_pay - payment_weekday = latest_fiscal_year.payment_weekday - payment_week = latest_fiscal_year.payment_week + if existing_fy: + return existing_fy + schedule_pay = current_fy.schedule_pay + payment_weekday = current_fy.payment_weekday + payment_week = current_fy.payment_week schedule_name = next( (s[1] for s in get_schedules(self) if s[0] == schedule_pay), False ) - fiscal_year = self.create( { "name": "%(year)s - %(schedule)s" - % { - "year": next_year, - "schedule": schedule_name, - }, + % {"year": next_year, "schedule": schedule_name}, "date_start": fiscal_year_start, "date_end": fiscal_year_end, "schedule_pay": schedule_pay, diff --git a/hr_payroll_period/models/res_company.py b/hr_payroll_period/models/res_company.py new file mode 100644 index 000000000..54986ef69 --- /dev/null +++ b/hr_payroll_period/models/res_company.py @@ -0,0 +1,26 @@ +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class ResCompany(models.Model): + _inherit = "res.company" + + payroll_fiscalyear_creation_months_before = fields.Integer( + string="Months Before HR Fiscal Year Creation", + default=1, + help="How many months before the end of the HR fiscal year " + "a new one should be created.", + ) + + @api.constrains("payroll_fiscalyear_creation_months_before") + def _check_fiscalyear_creation_months_before(self): + for company in self: + if ( + company.payroll_fiscalyear_creation_months_before < 0 + or company.payroll_fiscalyear_creation_months_before > 12 + ): + raise ValidationError( + _( + "Payroll fiscal year creation months before must be between 0 and 12." + ) + ) diff --git a/hr_payroll_period/models/res_config_settings.py b/hr_payroll_period/models/res_config_settings.py new file mode 100644 index 000000000..536a540e3 --- /dev/null +++ b/hr_payroll_period/models/res_config_settings.py @@ -0,0 +1,10 @@ +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + payroll_fiscalyear_creation_months_before = fields.Integer( + related="company_id.payroll_fiscalyear_creation_months_before", + readonly=False, + ) diff --git a/hr_payroll_period/readme/CONFIGURE.rst b/hr_payroll_period/readme/CONFIGURE.rst index 081975b38..e2dc073f5 100644 --- a/hr_payroll_period/readme/CONFIGURE.rst +++ b/hr_payroll_period/readme/CONFIGURE.rst @@ -1,5 +1,9 @@ Create a fiscal year ~~~~~~~~~~~~~~~~~~~~ + +Go to: Payroll -> Configuration -> Settings -> Payroll + - Put the number of months in advance for creating the new HR periods + Go to: Payroll -> Configuration -> Payroll Fiscal Year - Select a type of schedule, e.g. monthly diff --git a/hr_payroll_period/static/description/index.html b/hr_payroll_period/static/description/index.html index 0e07e5556..c4a28da0c 100644 --- a/hr_payroll_period/static/description/index.html +++ b/hr_payroll_period/static/description/index.html @@ -408,6 +408,13 @@

Installation

Configuration

Create a fiscal year

+
+
Go to: Payroll -> Configuration -> Settings -> Payroll
+
    +
  • Put the number of months in advance for creating the new HR periods
  • +
+
+

Go to: Payroll -> Configuration -> Payroll Fiscal Year

    diff --git a/hr_payroll_period/tests/test_hr_fiscalyear.py b/hr_payroll_period/tests/test_hr_fiscalyear.py index 5c0f62bd2..af7cec54b 100644 --- a/hr_payroll_period/tests/test_hr_fiscalyear.py +++ b/hr_payroll_period/tests/test_hr_fiscalyear.py @@ -349,6 +349,7 @@ def test_create_periods_semi_monthly_payment_last_day(self): def test_cron_create_next_fiscal_year(self): # if we are in 2024, it should create the periods for 2025 + self.env.company.payroll_fiscalyear_creation_months_before = 12 current_year = datetime.now().year current_fiscal_year = self.fy_model.search( [ diff --git a/hr_payroll_period/views/res_config_settings_view.xml b/hr_payroll_period/views/res_config_settings_view.xml new file mode 100644 index 000000000..f4d6e1b8a --- /dev/null +++ b/hr_payroll_period/views/res_config_settings_view.xml @@ -0,0 +1,42 @@ + + + + res.config.settings.view.form.inherit.fiscalyear + res.config.settings + + + + +

    Payroll Fiscal Year Periods Automation

    +
    +
    +
    +
    +
    +
    +
    +
    +
    + +