Skip to content

Commit

Permalink
Merge pull request #20 from coopiteasy/12.0-store-fields-overtime
Browse files Browse the repository at this point in the history
[12.0] Store computed values working_time and timesheet_overtime
  • Loading branch information
carmenbianca authored Jul 20, 2022
2 parents defc784 + fa25f61 commit 86f1f07
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 24 deletions.
1 change: 1 addition & 0 deletions hr_timesheet_overtime/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"website": "https://coopiteasy.be",
"license": "AGPL-3",
"depends": [
"company_today",
"hr_timesheet_sheet",
"resource_work_time_from_contracts",
],
Expand Down
7 changes: 6 additions & 1 deletion hr_timesheet_overtime/models/hr_employee.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class HrEmployee(models.Model):
string="Total Overtime",
compute="_compute_total_overtime",
help="Total Overtime since Overtime Start Date",
store=True,
)
timesheet_sheet_ids = fields.One2many(
comodel_name="hr_timesheet.sheet",
Expand Down Expand Up @@ -76,7 +77,11 @@ def _compute_current_day_working_time(self):
employee.current_day_working_time = employee.get_working_time(current_day)

@api.multi
@api.depends("timesheet_sheet_ids.active")
@api.depends(
"initial_overtime",
"overtime_start_date",
"timesheet_sheet_ids.timesheet_overtime_trimmed",
)
def _compute_total_overtime(self):
"""
Computes total overtime since employee's overtime start date
Expand Down
45 changes: 45 additions & 0 deletions hr_timesheet_overtime/models/hr_timesheet_sheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class HrTimesheetSheet(models.Model):
"Working Hours",
compute="_compute_working_time",
help="Hours to work for the timesheet period",
store=True,
)
daily_overtime = fields.Float(
"Daily Overtime",
Expand All @@ -33,12 +34,14 @@ class HrTimesheetSheet(models.Model):
"Timesheet Overtime",
compute="_compute_timesheet_overtime",
help="Overtime for this timesheet period",
store=True,
)
timesheet_overtime_trimmed = fields.Float(
"Trimmed Timesheet Overtime",
compute="_compute_timesheet_overtime_trimmed",
help="Overtime for this timesheet period, from the employee's start date until"
" today",
store=True,
)
total_overtime = fields.Float(
"Overtime Total",
Expand Down Expand Up @@ -67,6 +70,25 @@ def get_worked_time(self, start_date, end_date=None):
return sum(line.unit_amount for line in aal)

@api.multi
@api.depends(
"active",
"date_start",
"date_end",
"employee_id",
"employee_id.contract_ids",
"employee_id.contract_ids.date_start",
"employee_id.contract_ids.date_end",
"employee_id.contract_ids.resource_calendar_id",
"employee_id.contract_ids.resource_calendar_id.attendance_ids",
"employee_id.contract_ids.resource_calendar_id.attendance_ids.dayofweek",
"employee_id.contract_ids.resource_calendar_id.attendance_ids.hour_from",
"employee_id.contract_ids.resource_calendar_id.attendance_ids.hour_to",
"employee_id.resource_calendar_id",
"employee_id.resource_calendar_id.attendance_ids",
"employee_id.resource_calendar_id.attendance_ids.dayofweek",
"employee_id.resource_calendar_id.attendance_ids.hour_from",
"employee_id.resource_calendar_id.attendance_ids.hour_to",
)
def _compute_working_time(self):
for sheet in self:
sheet.working_time = sheet.employee_id.get_working_time(
Expand All @@ -85,11 +107,34 @@ def _compute_daily_overtime(self):
sheet.daily_overtime = worked_time - working_time

@api.multi
@api.depends("total_time", "working_time")
def _compute_timesheet_overtime(self):
for sheet in self:
sheet.timesheet_overtime = sheet.total_time - sheet.working_time

@api.multi
@api.depends(
"active",
"date_start",
"date_end",
"company_id.today",
"employee_id",
"employee_id.contract_ids",
"employee_id.contract_ids.date_end",
"employee_id.contract_ids.date_start",
"employee_id.contract_ids.resource_calendar_id",
"employee_id.contract_ids.resource_calendar_id.attendance_ids",
"employee_id.contract_ids.resource_calendar_id.attendance_ids.dayofweek",
"employee_id.contract_ids.resource_calendar_id.attendance_ids.hour_from",
"employee_id.contract_ids.resource_calendar_id.attendance_ids.hour_to",
"employee_id.overtime_start_date",
"employee_id.resource_calendar_id",
"employee_id.resource_calendar_id.attendance_ids",
"employee_id.resource_calendar_id.attendance_ids.dayofweek",
"employee_id.resource_calendar_id.attendance_ids.hour_from",
"employee_id.resource_calendar_id.attendance_ids.hour_to",
"timesheet_ids.unit_amount",
)
def _compute_timesheet_overtime_trimmed(self):
"""
Computes overtime for the timesheet period
Expand Down
129 changes: 106 additions & 23 deletions hr_timesheet_overtime/tests/test_overtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,35 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import date

from odoo.tests.common import TransactionCase
from freezegun import freeze_time

from odoo.tests.common import SavepointCase

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

class TestOvertime(SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# users
user1_dict = {"name": "User 1", "login": "user1", "password": "user1"}
self.user1 = self.env["res.users"].create(user1_dict)
cls.user1 = cls.env["res.users"].create(user1_dict)

# employees
employee1_dict = {
"name": "Employee 1",
"user_id": self.user1.id,
"address_id": self.user1.partner_id.id,
"user_id": cls.user1.id,
"address_id": cls.user1.partner_id.id,
"overtime_start_date": "2019-01-01",
}
self.employee1 = self.env["hr.employee"].create(employee1_dict)
cls.employee1 = cls.env["hr.employee"].create(employee1_dict)

# working hours
# calendar have default attendance_ids, force it to have none.
calendar = self.env["resource.calendar"].create(
calendar = cls.env["resource.calendar"].create(
{"name": "Calendar", "attendance_ids": False}
)
for day in range(5):
self.env["resource.calendar.attendance"].create(
cls.env["resource.calendar.attendance"].create(
{
"name": "Attendance",
"dayofweek": str(day),
Expand All @@ -41,49 +44,49 @@ def setUp(self):
# contracts
contract_dict = {
"name": "Contract 1",
"employee_id": self.employee1.id,
"employee_id": cls.employee1.id,
"wage": 0.0,
"resource_calendar_id": calendar.id,
"date_start": "2019-01-01",
}

self.contract1 = self.env["hr.contract"].create(contract_dict)
cls.contract1 = cls.env["hr.contract"].create(contract_dict)

# projects
self.project_01 = self.env["project.project"].create({"name": "Project 01"})
cls.project_01 = cls.env["project.project"].create({"name": "Project 01"})

# create ts
ts1_dict = {
"employee_id": self.employee1.id,
"employee_id": cls.employee1.id,
"date_start": "2019-12-02",
"date_end": "2019-12-08",
}
self.ts1 = self.env["hr_timesheet.sheet"].create(ts1_dict)
cls.ts1 = cls.env["hr_timesheet.sheet"].create(ts1_dict)

# create and link aal
# monday 02/12/2019
self.env["account.analytic.line"].create(
cls.env["account.analytic.line"].create(
{
"project_id": self.project_01.id,
"project_id": cls.project_01.id,
"amount": 0.0,
"date": "2019-12-02",
"name": "-",
"sheet_id": self.ts1.id,
"sheet_id": cls.ts1.id,
"unit_amount": 10.0, # 1 hour overtime
"user_id": self.employee1.user_id.id,
"user_id": cls.employee1.user_id.id,
}
)
# tuesday 03/12/2019 -> friday 06/12/2019
for day in range(3, 7):
self.env["account.analytic.line"].create(
cls.env["account.analytic.line"].create(
{
"project_id": self.project_01.id,
"project_id": cls.project_01.id,
"amount": 0.0,
"date": date(2019, 12, day),
"name": "-",
"sheet_id": self.ts1.id,
"sheet_id": cls.ts1.id,
"unit_amount": 9.0, # expected time
"user_id": self.employee1.user_id.id,
"user_id": cls.employee1.user_id.id,
}
)

Expand Down Expand Up @@ -338,3 +341,83 @@ def test_overtime_archived_timesheet(self):
self.assertEqual(ts2.timesheet_overtime, 5)
self.assertEqual(ts2.total_overtime, 1)
self.assertEqual(self.employee1.total_overtime, 1)

# The subsequent tests verify whether the stored fields respond correctly to
# changing variables.

def test_stored_change_contract_date_start(self):
"""When contract_id.date_start is changed, adjust correctly."""
# These initial assertions are not repeated in subsequent tests.
self.assertEqual(self.ts1.timesheet_overtime_trimmed, 1)
self.assertEqual(self.ts1.timesheet_overtime, 1)
self.assertEqual(self.ts1.total_overtime, 1)
self.assertEqual(self.ts1.working_time, 9 * 5)
self.contract1.date_start = date(2019, 12, 3)
self.assertEqual(self.ts1.timesheet_overtime_trimmed, 10)
self.assertEqual(self.ts1.timesheet_overtime, 10)
self.assertEqual(self.ts1.total_overtime, 10)
self.assertEqual(self.ts1.working_time, 9 * 4)

def test_stored_change_contract_date_end(self):
"""When contract_id.date_end is changed, adjust correctly."""
self.contract1.date_end = date(2019, 12, 5)
self.assertEqual(self.ts1.timesheet_overtime_trimmed, 10)
self.assertEqual(self.ts1.timesheet_overtime, 10)
self.assertEqual(self.ts1.total_overtime, 10)
self.assertEqual(self.ts1.working_time, 9 * 4)

def test_stored_change_attendance_hour_to(self):
"""When contract_id.resource_calendar_id.attendance_ids.hour_to is changed,
adjust correctly.
"""
self.contract1.resource_calendar_id.attendance_ids[0].hour_to = 17
self.assertEqual(self.ts1.timesheet_overtime_trimmed, 2)
self.assertEqual(self.ts1.timesheet_overtime, 2)
self.assertEqual(self.ts1.total_overtime, 2)
self.assertEqual(self.ts1.working_time, 9 * 5 - 1)

def test_stored_change_attendance_hour_from(self):
"""When contract_id.resource_calendar_id.attendance_ids.hour_from is changed,
adjust correctly.
"""
self.contract1.resource_calendar_id.attendance_ids[0].hour_from = 10
self.assertEqual(self.ts1.timesheet_overtime_trimmed, 2)
self.assertEqual(self.ts1.timesheet_overtime, 2)
self.assertEqual(self.ts1.total_overtime, 2)
self.assertEqual(self.ts1.working_time, 9 * 5 - 1)

def test_stored_change_initial_overtime(self):
"""When employee_id.initial_overtime is changed, adjust accordingly."""
self.employee1.initial_overtime = 1
self.assertEqual(self.ts1.total_overtime, 2)

def test_stored_change_overtime_start_date(self):
"""When employee_id.overtime_start_date is changed, adjust accordingly."""
self.employee1.overtime_start_date = date(2020, 1, 1)
# No matching records.
self.assertEqual(self.ts1.total_overtime, 0)

def test_stored_change_today(self):
"""When today is changed, adjust accordingly."""
# More hours of work in the week
line = self.env["account.analytic.line"].search(
[
("date", "=", "2019-12-4"),
("sheet_id", "=", self.ts1.id),
]
)
line.unit_amount = 10
self.assertEqual(self.ts1.timesheet_overtime_trimmed, 2)
self.assertEqual(self.ts1.timesheet_overtime, 2)
self.assertEqual(self.ts1.total_overtime, 2)
self.assertEqual(self.ts1.working_time, 9 * 5)

# Time travel into the past before the overtime.
with freeze_time("2019-12-3"):
self.ts1.company_id.cron_update_today()
# Not affected by the extra overtime
self.assertEqual(self.ts1.timesheet_overtime_trimmed, 1)
self.assertEqual(self.ts1.total_overtime, 1)
self.assertEqual(self.ts1.working_time, 9 * 5)
# Affected by the extra overtime
self.assertEqual(self.ts1.timesheet_overtime, 2)
1 change: 1 addition & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
git+https://github.com/coopiteasy/addons@12.0#subdirectory=setup/resource_work_time_from_contracts
git+https://github.com/coopiteasy/addons@12.0#subdirectory=setup/company_today

0 comments on commit 86f1f07

Please sign in to comment.