Skip to content

Commit

Permalink
Merge PR #43 into 12.0
Browse files Browse the repository at this point in the history
Signed-off-by huguesdk
  • Loading branch information
github-grap-bot committed Oct 11, 2024
2 parents 59316fd + 58aa163 commit d83dc4e
Show file tree
Hide file tree
Showing 20 changed files with 324 additions and 20 deletions.
3 changes: 2 additions & 1 deletion .copier-answers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ odoo_test_flavor: OCB
odoo_version: 12.0
org_name: Coop IT Easy SC
org_slug: coopiteasy
rebel_module_groups: []
rebel_module_groups:
- hr_timesheet_sheet_prefill_multi
repo_description: hr_timesheet modules
repo_name: cie-timesheet
repo_slug: cie-timesheet
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ jobs:
matrix:
include:
- container: ghcr.io/oca/oca-ci/py3.6-ocb12.0:latest
include: "hr_timesheet_sheet_prefill_multi"
name: test with OCB
makepot: "true"
- container: ghcr.io/oca/oca-ci/py3.6-ocb12.0:latest
exclude: "hr_timesheet_sheet_prefill_multi"
name: test with OCB
makepot: "true"
services:
Expand All @@ -30,6 +35,9 @@ jobs:
POSTGRES_DB: odoo
ports:
- 5432:5432
env:
INCLUDE: "${{ matrix.include }}"
EXCLUDE: "${{ matrix.exclude }}"
steps:
- uses: actions/checkout@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion hr_timesheet_sheet_prefill/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

{
"name": "Timesheet Sheet prefill",
"version": "12.0.1.0.0",
"version": "12.0.1.1.0",
"category": "Human Resources",
"summary": "Prefill a timesheet sheet with daily timesheets",
"author": "Coop IT Easy SC, Odoo Community Association (OCA)",
Expand Down
11 changes: 10 additions & 1 deletion hr_timesheet_sheet_prefill/models/hr_employee.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,13 @@
class Employee(models.Model):
_inherit = "hr.employee"

project_ids = fields.Many2many(comodel_name="project.project", string="Projects")
project_ids = fields.Many2many(
comodel_name="project.project",
relation="hr_employee_project_project_rel",
string="Projects",
)

# This exists solely for extension in hr_timesheet_sheet_prefill_multi.
def all_prefill_projects(self):
self.ensure_one()
return self.project_ids
34 changes: 18 additions & 16 deletions hr_timesheet_sheet_prefill/models/hr_timesheet_sheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,6 @@
class Sheet(models.Model):
_inherit = "hr_timesheet.sheet"

def get_number_days_between_dates(self, date_start, date_end):
"""
Return the number of days between two dates, including both of them.
Arguments:
date_start (date): start date
date_end (date): end date
Returns:
int: the number of days between the provided dates
"""
difference = date_end - date_start
# return result and add a day
return difference.days + 1

@api.model
def create(self, vals):
ts = super().create(vals)
Expand All @@ -37,13 +22,30 @@ def create(self, vals):
days = self.get_number_days_between_dates(date_start, date_end)
for day in range(days):
date_current = date_start + timedelta(days=day)
for project in employee_id.project_ids:
for project in employee_id.all_prefill_projects():
aal_dict = self._prepare_analytic_line(
date_current, project, sheet_id, employee_id.user_id
)
ts.write({"timesheet_ids": [(0, 0, aal_dict)]})
return ts

@api.model
def get_number_days_between_dates(self, date_start, date_end):
"""
Return the number of days between two dates, including both of them.
Arguments:
date_start (date): start date
date_end (date): end date
Returns:
int: the number of days between the provided dates
"""
difference = date_end - date_start
# return result and add a day
return difference.days + 1

@api.model
def _prepare_analytic_line(self, date, project, sheet_id, user_id):
return {
"project_id": project.id,
Expand Down
6 changes: 5 additions & 1 deletion hr_timesheet_sheet_prefill/models/project_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,8 @@
class Project(models.Model):
_inherit = "project.project"

employee_ids = fields.Many2many(comodel_name="hr.employee", string="Employees")
employee_ids = fields.Many2many(
comodel_name="hr.employee",
relation="hr_employee_project_project_rel",
string="Employees",
)
5 changes: 5 additions & 0 deletions hr_timesheet_sheet_prefill_multi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from . import models
21 changes: 21 additions & 0 deletions hr_timesheet_sheet_prefill_multi/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

{
"name": "Timesheet Sheet prefill with duplicates",
"summary": "Allow duplicates in prefill templates.",
"version": "12.0.1.0.0",
"category": "Human Resources",
"website": "https://coopiteasy.be",
"author": "Coop IT Easy SC, Odoo Community Association (OCA)",
"maintainers": ["carmenbianca"],
"license": "AGPL-3",
"depends": [
"hr_timesheet_sheet_prefill",
],
"data": [
"security/ir.model.access.csv",
"views/hr_employee_views.xml",
],
}
6 changes: 6 additions & 0 deletions hr_timesheet_sheet_prefill_multi/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from . import hr_employee
from . import hr_timesheet_sheet_prefill
28 changes: 28 additions & 0 deletions hr_timesheet_sheet_prefill_multi/models/hr_employee.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from odoo import fields, models


class HrEmployee(models.Model):
_inherit = "hr.employee"

timesheet_prefill_ids = fields.One2many(
comodel_name="hr_timesheet.sheet.prefill",
inverse_name="hr_employee_id",
string="Prefill Projects",
copy=False,
)

def all_prefill_projects(self):
self.ensure_one()
# The only purpose of the below code is to sort the projects according
# to the sequence of the prefill records. Instead of doing
# `self.timesheet_prefill_ids.mapped("project_project_id")`, we
# manually create the recordset. This is because the recordset MAY
# contain duplicates, and `mapped()` removes duplicates.
projects = self.env["project.project"].browse()
for prefill in self.timesheet_prefill_ids:
projects += prefill.project_project_id
return projects
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from odoo import api, fields, models


class HrTimesheetSheetPrefill(models.Model):
_name = "hr_timesheet.sheet.prefill"
_description = "Timesheet prefill line"
_order = "sequence, id"
# This is a weird hack, inspired by what is done in the `mail` module for
# the `mail.notification` model. That model, like this one, is a model
# doubling as a Many2many table. In `hr_timesheet_sheet_prefill`, the below
# Many2many relation table is created. Here, we claim that table for
# ourselves to add the functionality we want, while still preserving the
# original Many2many functionality without any changes upstream.
_table = "hr_employee_project_project_rel"
_rec_name = "project_project_id"

hr_employee_id = fields.Many2one(
string="Employee",
comodel_name="hr.employee",
ondelete="cascade",
required=True,
)
project_project_id = fields.Many2one(
string="Project",
comodel_name="project.project",
ondelete="cascade",
required=True,
)
sequence = fields.Integer(string="Sequence", default=10)
active = fields.Boolean(related="project_project_id.active")

@api.model_cr
def init(self):
# Add id column if it doesn't exist yet.
self.env.cr.execute(
"""
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns
WHERE table_name='hr_employee_project_project_rel'
AND column_name='id') THEN
ALTER TABLE hr_employee_project_project_rel
ADD COLUMN id SERIAL NOT NULL PRIMARY KEY;
END IF;
END $$;
"""
)
# Get rid of the unique constraint from the Many2many relationship.
self.env.cr.execute(
"""
ALTER TABLE hr_employee_project_project_rel
DROP CONSTRAINT IF EXISTS
hr_employee_project_project_r_hr_employee_id_project_projec_key;
"""
)
3 changes: 3 additions & 0 deletions hr_timesheet_sheet_prefill_multi/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `Coop IT Easy SC <https://coopiteasy.be>`_:

* Carmen Bianca BAKKER
1 change: 1 addition & 0 deletions hr_timesheet_sheet_prefill_multi/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow duplicates in prefill templates.
5 changes: 5 additions & 0 deletions hr_timesheet_sheet_prefill_multi/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
As part of installing this module, some adjustments are made to an existing
Many2many table. These adjustments are (presumably?) NOT undone upon
uninstallation.

A safe way to uninstall this module should be provided.
2 changes: 2 additions & 0 deletions hr_timesheet_sheet_prefill_multi/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_hr_timesheet_sheet_prefill_user,hr_timesheet.sheet.prefill.user,model_hr_timesheet_sheet_prefill,base.group_user,1,1,1,1
5 changes: 5 additions & 0 deletions hr_timesheet_sheet_prefill_multi/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from . import test_prefill_multi
106 changes: 106 additions & 0 deletions hr_timesheet_sheet_prefill_multi/tests/test_prefill_multi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# SPDX-FileCopyrightText: 2024 Coop IT Easy SC
#
# SPDX-License-Identifier: AGPL-3.0-or-later

from odoo.tests.common import TransactionCase


class TestPrefillMulti(TransactionCase):
def setUp(self):
super().setUp()

self.project_01 = self.env["project.project"].create({"name": "Project 01"})
self.project_02 = self.env["project.project"].create({"name": "Project 02"})

self.user = self.env["res.users"].create(
{
"name": "Test",
"login": "test",
"password": "test",
}
)
self.employee = self.env["hr.employee"].create(
{
"name": "Test",
"user_id": self.user.id,
"address_id": self.user.partner_id.id,
}
)

def test_all_prefill_projects_filtered_sorted(self):
"""Prefill projects are sorted and filtered."""
project_03 = self.env["project.project"].create({"name": "Project 03"})
self.project_02.active = False

self.employee.timesheet_prefill_ids = [
(0, False, {"project_project_id": self.project_01.id, "sequence": 1}),
(0, False, {"project_project_id": self.project_02.id, "sequence": 2}),
(0, False, {"project_project_id": project_03.id, "sequence": 3}),
]
sheet = self.env["hr_timesheet.sheet"].create(
{
"employee_id": self.employee.id,
"date_start": "2024-01-01",
"date_end": "2024-01-01",
}
)
self.assertEqual(len(sheet.timesheet_ids), 2)
used_projects = sheet.timesheet_ids.mapped("project_id")
self.assertIn(self.project_01, used_projects)
self.assertNotIn(self.project_02, used_projects)
self.assertIn(project_03, used_projects)

def test_project_ids_still_works(self):
"""You can still use project_ids on hr.employee as normally. It will
create prefill records.
"""
projects = self.project_01 | self.project_02
self.employee.project_ids = projects

self.assertEqual(len(self.employee.timesheet_prefill_ids), 2)
prefill_01 = self.employee.timesheet_prefill_ids[0]
prefill_02 = self.employee.timesheet_prefill_ids[1]
# We can't know for sure which project was sorted first, so we do the
# below to make sure they are both given a timesheet.
self.assertNotEqual(
prefill_01.project_project_id, prefill_02.project_project_id
)
self.assertIn(prefill_01.project_project_id, projects)
self.assertIn(prefill_02.project_project_id, projects)

sheet = self.env["hr_timesheet.sheet"].create(
{
"employee_id": self.employee.id,
"date_start": "2024-01-01",
"date_end": "2024-01-01",
}
)
self.assertEqual(len(sheet.timesheet_ids), 2)
self.assertNotEqual(
sheet.timesheet_ids[0].project_id, sheet.timesheet_ids[1].project_id
)
self.assertIn(sheet.timesheet_ids[0].project_id, projects)
self.assertIn(sheet.timesheet_ids[1].project_id, projects)

def test_sequenced_repeated_prefills(self):
"""You can repeat and sequence prefills."""
self.employee.timesheet_prefill_ids = [
(0, False, {"project_project_id": self.project_01.id, "sequence": 1}),
(0, False, {"project_project_id": self.project_02.id, "sequence": 2}),
(0, False, {"project_project_id": self.project_01.id, "sequence": 3}),
]

# Sanity check.
self.assertEqual(len(self.employee.project_ids), 3)

sheet = self.env["hr_timesheet.sheet"].create(
{
"employee_id": self.employee.id,
"date_start": "2024-01-01",
"date_end": "2024-01-01",
}
)
self.assertEqual(len(sheet.timesheet_ids), 3)
self.assertEqual(sheet.timesheet_ids[0].project_id, self.project_01)
self.assertEqual(sheet.timesheet_ids[1].project_id, self.project_02)
self.assertEqual(sheet.timesheet_ids[2].project_id, self.project_01)
Loading

0 comments on commit d83dc4e

Please sign in to comment.