From 29de76f3246fea7faaab82862189bcdd39a9dfe7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 30 Jan 2024 10:34:34 +0100 Subject: [PATCH] Activate employee based on dates Closes #12077 --- modules/attendance/attendance.py | 3 + modules/company/CHANGELOG | 1 + modules/company/company.py | 41 ++++++++++++++ modules/company/tests/test_module.py | 82 ++++++++++++++++++++++++++++ modules/timesheet/line.py | 6 +- 5 files changed, 132 insertions(+), 1 deletion(-) diff --git a/modules/attendance/attendance.py b/modules/attendance/attendance.py index 1ca7cb66d8..9580f94aa5 100644 --- a/modules/attendance/attendance.py +++ b/modules/attendance/attendance.py @@ -34,6 +34,9 @@ class Line(ModelSQL, ModelView): company = fields.Many2One('company.company', "Company", required=True, help="The company which the employee attended.") employee = fields.Many2One('company.employee', "Employee", required=True, + search_context={ + 'active_test': False, + }, domain=[ ('company', '=', Eval('company')), ['OR', diff --git a/modules/company/CHANGELOG b/modules/company/CHANGELOG index 3b57a92340..59830c8b83 100644 --- a/modules/company/CHANGELOG +++ b/modules/company/CHANGELOG @@ -1,3 +1,4 @@ +* Activate employee based on dates * Use template substitution for company header/footer Version 7.0.0 - 2023-10-30 diff --git a/modules/company/company.py b/modules/company/company.py index 2a0bc7e752..f8bd3c505f 100644 --- a/modules/company/company.py +++ b/modules/company/company.py @@ -1,6 +1,7 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. +import datetime as dt from string import Template from trytond.model import ModelSQL, ModelView, fields @@ -98,6 +99,9 @@ class Employee(ModelSQL, ModelView): help="The party which represents the employee.") company = fields.Many2One('company.company', 'Company', required=True, help="The company to which the employee belongs.") + active = fields.Function( + fields.Boolean("Active"), + 'on_change_with_active', searcher='search_active') start_date = fields.Date('Start Date', domain=[If((Eval('start_date')) & (Eval('end_date')), ('start_date', '<=', Eval('end_date')), @@ -129,6 +133,43 @@ class Employee(ModelSQL, ModelView): def default_company(): return Transaction().context.get('company') + @fields.depends('start_date', 'end_date') + def on_change_with_active(self, name=None): + pool = Pool() + Date = pool.get('ir.date') + context = Transaction().context + date = context.get('date') or Date.today() + start_date = self.start_date or dt.date.min + end_date = self.end_date or dt.date.max + return start_date <= date <= end_date + + @classmethod + def search_active(cls, name, domain): + pool = Pool() + Date = pool.get('ir.date') + context = Transaction().context + date = context.get('date') or Date.today() + _, operator, value = domain + if (operator == '=' and value) or (operator == '!=' and not value): + domain = [ + ['OR', + ('start_date', '=', None), + ('start_date', '<=', date), + ], + ['OR', + ('end_date', '=', None), + ('end_date', '>=', date), + ], + ] + elif (operator == '=' and not value) or (operator == '!=' and value): + domain = ['OR', + ('start_date', '>', date), + ('end_date', '<', date), + ] + else: + domain = [] + return domain + def get_rec_name(self, name): return self.party.rec_name diff --git a/modules/company/tests/test_module.py b/modules/company/tests/test_module.py index abcc5cd767..7b2a5909d0 100644 --- a/modules/company/tests/test_module.py +++ b/modules/company/tests/test_module.py @@ -1,6 +1,7 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. +import datetime as dt from collections import defaultdict from contextlib import contextmanager @@ -329,5 +330,86 @@ class CompanyTestCase( self.assertEqual( company.footer_used, "Dunder Mifflin - company@example.com") + @with_transaction() + def test_employee_active_no_dates(self): + "Test employee active with dates" + pool = Pool() + Employee = pool.get('company.employee') + + company = create_company() + employee = create_employee(company, "Jim Halper") + + self.assertEqual(employee.active, True) + self.assertEqual(Employee.search([ + ('active', '=', True), + ]), [employee]) + self.assertEqual(Employee.search([ + ('active', '!=', False), + ]), [employee]) + self.assertEqual(Employee.search([ + ('active', '=', False), + ]), []) + self.assertEqual(Employee.search([ + ('active', '!=', True), + ]), []) + + @with_transaction() + def test_employee_active_start_date(self): + "Test employee active with start date" + pool = Pool() + Employee = pool.get('company.employee') + + company = create_company() + employee = create_employee(company, "Jim Halper") + employee.start_date = dt.date.today() + employee.save() + + with Transaction().set_context(date=employee.start_date): + self.assertEqual(Employee(employee).active, True) + self.assertEqual(Employee.search([ + ('active', '=', True), + ]), [employee]) + with Transaction().set_context( + date=employee.start_date - dt.timedelta(days=1)): + self.assertEqual(Employee(employee).active, False) + self.assertEqual(Employee.search([ + ('active', '=', True), + ]), []) + with Transaction().set_context( + date=employee.start_date + dt.timedelta(days=1)): + self.assertEqual(Employee(employee).active, True) + self.assertEqual(Employee.search([ + ('active', '=', True), + ]), [employee]) + + @with_transaction() + def test_employee_active_end_date(self): + "Test employee active with end date" + pool = Pool() + Employee = pool.get('company.employee') + + company = create_company() + employee = create_employee(company, "Jim Halper") + employee.end_date = dt.date.today() + employee.save() + + with Transaction().set_context(date=employee.end_date): + self.assertEqual(Employee(employee).active, True) + self.assertEqual(Employee.search([ + ('active', '=', True), + ]), [employee]) + with Transaction().set_context( + date=employee.end_date - dt.timedelta(days=1)): + self.assertEqual(Employee(employee).active, True) + self.assertEqual(Employee.search([ + ('active', '=', True), + ]), [employee]) + with Transaction().set_context( + date=employee.end_date + dt.timedelta(days=1)): + self.assertEqual(Employee(employee).active, False) + self.assertEqual(Employee.search([ + ('active', '=', True), + ]), []) + del ModuleTestCase diff --git a/modules/timesheet/line.py b/modules/timesheet/line.py index 6c302a536e..5e63752970 100644 --- a/modules/timesheet/line.py +++ b/modules/timesheet/line.py @@ -23,7 +23,11 @@ class Line(ModelSQL, ModelView): company = fields.Many2One('company.company', 'Company', required=True, help="The company on which the time is spent.") employee = fields.Many2One( - 'company.employee', "Employee", required=True, domain=[ + 'company.employee', "Employee", required=True, + search_context={ + 'active_test': False, + }, + domain=[ ('company', '=', Eval('company', -1)), ['OR', ('start_date', '=', None),