Skip to content

Commit

Permalink
[IMP] hr_period_create_timesheet: configure months in advance to crea…
Browse files Browse the repository at this point in the history
…te periods
  • Loading branch information
AaronHForgeFlow committed Jan 23, 2025
1 parent ed6e5bd commit 088b322
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 19 deletions.
2 changes: 1 addition & 1 deletion hr_period_create_timesheet/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions hr_period_create_timesheet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from . import wizards
from . import models
1 change: 1 addition & 0 deletions hr_period_create_timesheet/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
2 changes: 2 additions & 0 deletions hr_period_create_timesheet/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import res_company
from . import res_config_settings
11 changes: 11 additions & 0 deletions hr_period_create_timesheet/models/res_company.py
Original file line number Diff line number Diff line change
@@ -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.",
)
12 changes: 12 additions & 0 deletions hr_period_create_timesheet/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -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.",
)
13 changes: 8 additions & 5 deletions hr_period_create_timesheet/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

/*
:Author: David Goodger ([email protected])
: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.
Expand Down Expand Up @@ -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 }
Expand All @@ -301,7 +302,7 @@
span.pre {
white-space: pre }

span.problematic {
span.problematic, pre.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -367,7 +368,7 @@ <h1 class="title">HR period create timesheet</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:81e2a29a70c3c038721b45c78c57dfdfcf651eebd84c26efe2d52c5ecf5527c7
!! source digest: sha256:d626a2ca5abdd5fed3b28c537473d94e09d268e03366d33fc2ee161f68e0bddc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/timesheet/tree/15.0/hr_period_create_timesheet"><img alt="OCA/timesheet" src="https://img.shields.io/badge/github-OCA%2Ftimesheet-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/timesheet-15-0/timesheet-15-0-hr_period_create_timesheet"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/timesheet&amp;target_branch=15.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module prepare the timesheets for all the periods created for all
Expand Down Expand Up @@ -423,7 +424,9 @@ <h2><a class="toc-backref" href="#toc-entry-5">Contributors</a></h2>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-6">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
</a>
<p>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.</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def setUp(self):
self.dept_1 = self.env.ref("hr.dep_rd")
self.dept.write({"parent_id": self.root.id})
self.company_id = self.env.user.company_id
self.company_id.hr_period_create_months_in_advance = 12
self.type = self.create_data_range_type("test_hr_period")

self.vals = {
Expand Down
42 changes: 42 additions & 0 deletions hr_period_create_timesheet/views/res_config_settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<odoo>
<record id="res_config_settings_view_form_hr_period" model="ir.ui.view">
<field name="name">res.config.settings.view.form.hr.period</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="55" />
<field
name="inherit_id"
ref="hr_timesheet_sheet.res_config_settings_view_form"
/>
<field name="arch" type="xml">
<xpath expr="//div[@name='hr_timesheet_sheet']" position="after">
<h2>HR Period Settings</h2>
<div class="row mt16 o_settings_container" name="hr_period_settings">
<div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_right_pane">
<label for="hr_period_create_months_in_advance" />
<span
class="fa fa-lg fa-building"
title="Values set here are company-specific."
aria-label="Values set here are company-specific."
groups="base.group_multi_company"
role="img"
/>
<div class="text-muted">
Define how many months in advance HR periods should be created for timesheets.
</div>
<div class="content-group">
<div class="mt16">
<field
name="hr_period_create_months_in_advance"
class="o_light_label"
widget="integer"
/>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>
49 changes: 36 additions & 13 deletions hr_period_create_timesheet/wizards/hr_period_create_timesheet.py
Original file line number Diff line number Diff line change
@@ -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

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 088b322

Please sign in to comment.