Skip to content

Commit

Permalink
[IMP] hr_payroll_period: Add a cron to create next fiscal year automa…
Browse files Browse the repository at this point in the history
…tically
  • Loading branch information
AaronHForgeFlow committed Jul 12, 2024
1 parent 23ae5bf commit d5e610e
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 2 deletions.
1 change: 1 addition & 0 deletions hr_payroll_period/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"security/hr_period_security.xml",
"data/ir_sequence_data.xml",
"data/date_range_type.xml",
"data/ir_cron.xml",
"views/menus.xml",
"views/date_range_type_view.xml",
"views/hr_period_view.xml",
Expand Down
15 changes: 15 additions & 0 deletions hr_payroll_period/data/ir_cron.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo noupdate="1">
<record id="ir_cron_hr_payroll_period" model="ir.cron">
<field name='name'>Create Next Fiscal Year</field>
<field name='interval_number'>1</field>
<field name='interval_type'>months</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False" />
<field name="active" eval="False" />
<field name="code">model.cron_create_next_fiscal_year()</field>
<field name="state">code</field>
<field name="user_id" ref="base.user_root" />
<field name="model_id" ref="model_hr_fiscalyear" />
</record>
</odoo>
50 changes: 50 additions & 0 deletions hr_payroll_period/models/hr_fiscal_year.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,3 +302,53 @@ def search_period(self, number):
return next(
(p for p in self.period_ids if p.number == number), self.env["hr.period"]
)

@api.model
def cron_create_next_fiscal_year(self):
current_year = datetime.now().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",
limit=1,
)
if not latest_fiscal_year:
return self

Check warning on line 317 in hr_payroll_period/models/hr_fiscal_year.py

View check run for this annotation

Codecov / codecov/patch

hr_payroll_period/models/hr_fiscal_year.py#L317

Added line #L317 was not covered by tests
latest_period_end = max(latest_fiscal_year.period_ids.mapped("date_end"))
fiscal_year_start = latest_period_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(
[
("date_start", "=", fiscal_year_start),
("date_end", "=", fiscal_year_end),
],
limit=1,
)
if existing_fiscal_year:
return existing_fiscal_year

Check warning on line 330 in hr_payroll_period/models/hr_fiscal_year.py

View check run for this annotation

Codecov / codecov/patch

hr_payroll_period/models/hr_fiscal_year.py#L330

Added line #L330 was not covered by tests

schedule_pay = latest_fiscal_year.schedule_pay
payment_weekday = latest_fiscal_year.payment_weekday
payment_week = latest_fiscal_year.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,
},
"date_start": fiscal_year_start,
"date_end": fiscal_year_end,
"schedule_pay": schedule_pay,
"payment_weekday": payment_weekday,
"payment_week": payment_week,
}
)
fiscal_year.create_periods()
return fiscal_year
1 change: 0 additions & 1 deletion hr_payroll_period/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
Expand Down
49 changes: 48 additions & 1 deletion hr_payroll_period/tests/test_hr_fiscalyear.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Copyright 2015 Savoir-faire Linux. All Rights Reserved.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import date
from datetime import date, datetime

from dateutil.relativedelta import relativedelta

from odoo import fields
from odoo.exceptions import UserError, ValidationError
Expand Down Expand Up @@ -344,3 +346,48 @@ def test_create_periods_semi_monthly_payment_last_day(self):
self.assertEqual(periods[2].date_payment, date(2015, 5, 4))
self.assertEqual(periods[22].date_payment, date(2016, 3, 5))
self.assertEqual(periods[23].date_payment, date(2016, 3, 19))

def test_cron_create_next_fiscal_year(self):
# if we are in 2024, it should create the periods for 2025
current_year = datetime.now().year
current_fiscal_year = self.fy_model.search(
[
("date_start", "=", f"{current_year}-01-01"),
("date_end", "=", f"{current_year}-12-31"),
],
limit=1,
)

# If 2024 doesn't exist, create it
if not current_fiscal_year:
current_fiscal_year = self.create_fiscal_year(
{
"date_start": f"{current_year}-01-01",
"date_end": f"{current_year}-12-31",
}
)
current_fiscal_year.create_periods()
next_fiscal_year = self.env["hr.fiscalyear"].cron_create_next_fiscal_year()
periods = self.get_periods(next_fiscal_year)
# Ensure the periods are continuous and within the fiscal year dates
for i, period in enumerate(periods):
if i == 0:
self.assertEqual(period.date_start, next_fiscal_year.date_start)
else:
self.assertEqual(
period.date_start, periods[i - 1].date_end + relativedelta(days=1)
)
if i == len(periods) - 1:
self.assertEqual(period.date_end, next_fiscal_year.date_end)
# Check that the first period of next fiscal year starts 1 day after
current_year_periods = self.get_periods(current_fiscal_year)
last_period_current_year = current_year_periods[-1]
first_period_next_year = periods[0]
self.assertEqual(
first_period_next_year.date_start,
last_period_current_year.date_end + relativedelta(days=1),
)
# Check that the first period end is on last of January
self.assertEqual(
first_period_next_year.date_end, datetime(current_year + 1, 1, 31).date()
)

0 comments on commit d5e610e

Please sign in to comment.