diff --git a/hr_period_create_timesheet/README.rst b/hr_period_create_timesheet/README.rst
index c63a67650..5a7ef3147 100644
--- a/hr_period_create_timesheet/README.rst
+++ b/hr_period_create_timesheet/README.rst
@@ -7,7 +7,7 @@ HR period create timesheet
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- !! source digest: sha256:81e2a29a70c3c038721b45c78c57dfdfcf651eebd84c26efe2d52c5ecf5527c7
+ !! source digest: sha256:d626a2ca5abdd5fed3b28c537473d94e09d268e03366d33fc2ee161f68e0bddc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
diff --git a/hr_period_create_timesheet/__init__.py b/hr_period_create_timesheet/__init__.py
index aebfda808..e3a185218 100644
--- a/hr_period_create_timesheet/__init__.py
+++ b/hr_period_create_timesheet/__init__.py
@@ -2,3 +2,4 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import wizards
+from . import models
diff --git a/hr_period_create_timesheet/__manifest__.py b/hr_period_create_timesheet/__manifest__.py
index 36c989770..035f714fe 100644
--- a/hr_period_create_timesheet/__manifest__.py
+++ b/hr_period_create_timesheet/__manifest__.py
@@ -15,6 +15,7 @@
"security/ir.model.access.csv",
"data/ir_cron.xml",
"wizards/hr_period_create_timesheet_view.xml",
+ "views/res_config_settings.xml",
],
"installable": True,
}
diff --git a/hr_period_create_timesheet/models/__init__.py b/hr_period_create_timesheet/models/__init__.py
new file mode 100644
index 000000000..0b150f71c
--- /dev/null
+++ b/hr_period_create_timesheet/models/__init__.py
@@ -0,0 +1,2 @@
+from . import res_company
+from . import res_config_settings
diff --git a/hr_period_create_timesheet/models/res_company.py b/hr_period_create_timesheet/models/res_company.py
new file mode 100644
index 000000000..e4ca53e19
--- /dev/null
+++ b/hr_period_create_timesheet/models/res_company.py
@@ -0,0 +1,11 @@
+from odoo import fields, models
+
+
+class ResCompany(models.Model):
+ _inherit = "res.company"
+
+ hr_period_create_months_in_advance = fields.Integer(
+ string="Months to Create Periods in Advance",
+ default=1,
+ help="Defines how many months in advance timesheets should be created for HR periods.",
+ )
diff --git a/hr_period_create_timesheet/models/res_config_settings.py b/hr_period_create_timesheet/models/res_config_settings.py
new file mode 100644
index 000000000..a64f7522c
--- /dev/null
+++ b/hr_period_create_timesheet/models/res_config_settings.py
@@ -0,0 +1,12 @@
+from odoo import fields, models
+
+
+class ResConfigSettings(models.TransientModel):
+ _inherit = "res.config.settings"
+
+ hr_period_create_months_in_advance = fields.Integer(
+ string="Months to Create Periods in Advance",
+ related="company_id.hr_period_create_months_in_advance",
+ readonly=False,
+ help="Defines how many months in advance timesheets should be created for HR periods.",
+ )
diff --git a/hr_period_create_timesheet/static/description/index.html b/hr_period_create_timesheet/static/description/index.html
index 07589a136..6dbe70564 100644
--- a/hr_period_create_timesheet/static/description/index.html
+++ b/hr_period_create_timesheet/static/description/index.html
@@ -9,10 +9,11 @@
/*
:Author: David Goodger (goodger@python.org)
-:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
+:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
+Despite the name, some widely supported CSS2 features are used.
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
@@ -275,7 +276,7 @@
margin-left: 2em ;
margin-right: 2em }
-pre.code .ln { color: grey; } /* line numbers */
+pre.code .ln { color: gray; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
@@ -301,7 +302,7 @@
span.pre {
white-space: pre }
-span.problematic {
+span.problematic, pre.problematic {
color: red }
span.section-subtitle {
@@ -367,7 +368,7 @@
HR period create timesheet
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-!! source digest: sha256:81e2a29a70c3c038721b45c78c57dfdfcf651eebd84c26efe2d52c5ecf5527c7
+!! source digest: sha256:d626a2ca5abdd5fed3b28c537473d94e09d268e03366d33fc2ee161f68e0bddc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
This module prepare the timesheets for all the periods created for all
@@ -423,7 +424,9 @@
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.
+ Define how many months in advance HR periods should be created for timesheets.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hr_period_create_timesheet/wizards/hr_period_create_timesheet.py b/hr_period_create_timesheet/wizards/hr_period_create_timesheet.py
index 5e524dc03..04a957d06 100644
--- a/hr_period_create_timesheet/wizards/hr_period_create_timesheet.py
+++ b/hr_period_create_timesheet/wizards/hr_period_create_timesheet.py
@@ -1,6 +1,8 @@
# Copyright 2023 ForgeFlow S.L.
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
+from dateutil.relativedelta import relativedelta
+
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
@@ -93,25 +95,46 @@ def compute(self):
def create_timesheets_on_future_periods(self):
timesheet_obj = self.env["hr_timesheet.sheet"]
today = fields.Date.today()
- periods = self.env["hr.period"].search([("date_end", ">=", today)])
+
+ # Search for employees who have a user and a valid contract
employees = self.env["hr.employee"].search(
[("user_id", "!=", False), ("contract_id.date_start", "<=", today)]
)
- if not periods or not employees:
+ if not employees:
return
+
# Create a dictionary to store existing timesheets per employee
existing_timesheets = {}
- timesheet_domain = [
- ("employee_id", "in", employees.ids),
- ("date_start", "<=", max(periods.mapped("date_end"))),
- ("date_end", ">=", min(periods.mapped("date_start"))),
- ]
- for timesheet in timesheet_obj.search(timesheet_domain):
- key = (timesheet.employee_id.id, timesheet.date_start, timesheet.date_end)
- existing_timesheets[key] = timesheet
-
- for hr_period in periods:
- for employee in employees:
+ for employee in employees:
+ # Get the company configuration for months in advance
+ months_in_advance = (
+ employee.company_id.hr_period_create_months_in_advance or 1
+ )
+ advance_date_limit = today + relativedelta(months=months_in_advance)
+
+ # Search for periods within the allowed range for this employee's company
+ periods = self.env["hr.period"].search(
+ [("date_end", ">=", today), ("date_end", "<=", advance_date_limit)]
+ )
+ if not periods:
+ continue
+
+ # Find existing timesheets for this employee
+ timesheet_domain = [
+ ("employee_id", "=", employee.id),
+ ("date_start", "<=", max(periods.mapped("date_end"))),
+ ("date_end", ">=", min(periods.mapped("date_start"))),
+ ]
+ for timesheet in timesheet_obj.search(timesheet_domain):
+ key = (
+ timesheet.employee_id.id,
+ timesheet.date_start,
+ timesheet.date_end,
+ )
+ existing_timesheets[key] = timesheet
+
+ # Create timesheets for missing periods
+ for hr_period in periods:
key = (employee.id, hr_period.date_start, hr_period.date_end)
if key not in existing_timesheets:
ts_data = self._prepare_timesheet(employee, hr_period)