Remove employee and employees from evaluation context of rule domain

Closes #12581
This commit is contained in:
Cédric Krier
2023-09-24 13:56:20 +02:00
parent 0c8303994e
commit cea1fcad74
9 changed files with 185 additions and 40 deletions
+2 -1
View File
@@ -3,13 +3,14 @@
from trytond.pool import Pool
from . import attendance
from . import attendance, ir
__all__ = ['register']
def register():
Pool.register(
ir.Rule,
attendance.Line,
attendance.Period,
attendance.SheetLine,
+26
View File
@@ -0,0 +1,26 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import Pool, PoolMeta
class Rule(metaclass=PoolMeta):
__name__ = 'ir.rule'
@classmethod
def _get_context(cls, model_name):
pool = Pool()
User = pool.get('res.user')
context = super()._get_context(model_name)
if model_name == 'attendance.line':
context['employees'] = User.get_employees()
return context
@classmethod
def _get_cache_key(cls, model_name):
pool = Pool()
User = pool.get('res.user')
key = super()._get_cache_key(model_name)
if model_name == 'attendance.line':
key = (*key, User.get_employees())
return key
+1
View File
@@ -1,3 +1,4 @@
* Remove employee and employees from evaluation context of rule domain
* Define when set or reset employee field
Version 6.8.0 - 2023-05-01
+6 -32
View File
@@ -1,10 +1,9 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.model import (
EvalEnvironment, ModelSQL, ModelView, dualmethod, fields)
from trytond.model import ModelSQL, ModelView, dualmethod, fields
from trytond.pool import Pool, PoolMeta
from trytond.tools import timezone as tz
from trytond.transaction import Transaction, without_check_access
from trytond.transaction import Transaction
class Sequence(metaclass=PoolMeta):
@@ -49,46 +48,21 @@ class Rule(metaclass=PoolMeta):
def __setup__(cls):
super().__setup__()
cls.domain.help += (
'\n- "employee" from the current user'
'\n- "employees" as list of ids from the current user'
'\n- "companies" as list of ids from the current user')
@classmethod
def _get_cache_key(cls, model_name):
pool = Pool()
User = pool.get('res.user')
key = super()._get_cache_key(model_name)
# XXX Use company from context instead of browse to prevent infinite
# loop, but the cache is cleared when User is written.
context = Transaction().context
return key + (
context.get('company'),
context.get('employee'),
context.get('company_filter'),
)
return (*key, User.get_companies())
@classmethod
def _get_context(cls, model_name):
pool = Pool()
User = pool.get('res.user')
Employee = pool.get('company.employee')
context = super()._get_context(model_name)
# Use root to avoid infinite loop when accessing user attributes
user_id = Transaction().user
with Transaction().set_user(0):
user = User(user_id)
if user.employee:
with without_check_access(), \
Transaction().set_context(_datetime=None):
context['employee'] = EvalEnvironment(
Employee(user.employee.id), Employee)
if user.company_filter == 'one':
context['companies'] = [user.company.id] if user.company else []
context['employees'] = [user.employee.id] if user.employee else []
elif user.company_filter == 'all':
context['companies'] = [c.id for c in user.companies]
context['employees'] = [e.id for e in user.employees]
else:
context['companies'] = []
context['employees'] = []
context['companies'] = User.get_companies()
return context
+94 -5
View File
@@ -2,6 +2,7 @@
# this repository contains the full copyright notices and license terms.
from sql import Null
from trytond.cache import Cache
from trytond.model import ModelSQL, fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
@@ -18,6 +19,28 @@ class UserCompany(ModelSQL):
'company.company', "Company",
ondelete='CASCADE', required=True)
@classmethod
def create(cls, vlist):
pool = Pool()
User = pool.get('res.user')
records = super().create(vlist)
User._get_companies_cache.clear()
return records
@classmethod
def write(cls, *args):
pool = Pool()
User = pool.get('res.user')
super().write(*args)
User._get_companies_cache.clear()
@classmethod
def delete(cls, records):
pool = Pool()
User = pool.get('res.user')
super().delete(records)
User._get_companies_cache.clear()
class UserEmployee(ModelSQL):
'User - Employee'
@@ -27,6 +50,28 @@ class UserEmployee(ModelSQL):
employee = fields.Many2One(
'company.employee', "Employee", ondelete='CASCADE', required=True)
@classmethod
def create(cls, vlist):
pool = Pool()
User = pool.get('res.user')
records = super().create(vlist)
User._get_employees_cache.clear()
return records
@classmethod
def write(cls, *args):
pool = Pool()
User = pool.get('res.user')
super().write(*args)
User._get_employees_cache.clear()
@classmethod
def delete(cls, records):
pool = Pool()
User = pool.get('res.user')
super().delete(records)
User._get_employees_cache.clear()
class User(metaclass=PoolMeta):
__name__ = 'res.user'
@@ -57,6 +102,8 @@ class User(metaclass=PoolMeta):
('all', "All"),
], "Company Filter",
help="Define records of which companies are shown.")
_get_companies_cache = Cache(__name__ + '.get_companies', context=False)
_get_employees_cache = Cache(__name__ + '.get_employees', context=False)
@classmethod
def __setup__(cls):
@@ -140,6 +187,50 @@ class User(metaclass=PoolMeta):
res['employees'] = [e.id for e in user.employees]
return res
@classmethod
def get_companies(cls):
'''
Return an ordered tuple of company ids for the user
'''
transaction = Transaction()
user_id = transaction.user
companies = cls._get_companies_cache.get(user_id)
if companies is not None:
return companies
with transaction.set_user(0):
user = cls(user_id)
if user.company_filter == 'one':
companies = [user.company.id] if user.company else []
elif user.company_filter == 'all':
companies = [c.id for c in user.companies]
else:
companies = []
companies = tuple(companies)
cls._get_companies_cache.set(user_id, companies)
return companies
@classmethod
def get_employees(cls):
'''
Return an ordered tuple of employee ids for the user
'''
transaction = Transaction()
user_id = transaction.user
employees = cls._get_employees_cache.get(user_id)
if employees is not None:
return employees
with transaction.set_user(0):
user = cls(user_id)
if user.company_filter == 'one':
employees = [user.employee.id] if user.employee else []
elif user.company_filter == 'all':
employees = [e.id for e in user.employees]
else:
employees = []
employees = tuple(employees)
cls._get_employees_cache.set(user_id, employees)
return employees
@classmethod
def read(cls, ids, fields_names):
user_id = Transaction().user
@@ -189,8 +280,6 @@ class User(metaclass=PoolMeta):
@classmethod
def write(cls, *args):
pool = Pool()
Rule = pool.get('ir.rule')
super(User, cls).write(*args)
# Restart the cache on the domain_get method
Rule._domain_get_cache.clear()
super().write(*args)
cls._get_companies_cache.clear()
cls._get_employees_cache.clear()
+2 -1
View File
@@ -3,11 +3,12 @@
from trytond.pool import Pool
from . import purchase
from . import ir, purchase
def register():
Pool.register(
ir.Rule,
purchase.PurchaseRequest,
purchase.PurchaseRequisition,
purchase.PurchaseRequisitionLine,
+26
View File
@@ -0,0 +1,26 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import Pool, PoolMeta
class Rule(metaclass=PoolMeta):
__name__ = 'ir.rule'
@classmethod
def _get_context(cls, model_name):
pool = Pool()
User = pool.get('res.user')
context = super()._get_context(model_name)
if model_name == 'purchase.requisition':
context['employees'] = User.get_employees()
return context
@classmethod
def _get_cache_key(cls, model_name):
pool = Pool()
User = pool.get('res.user')
key = super()._get_cache_key(model_name)
if model_name == 'purchase.requisition':
key = (*key, User.get_employees())
return key
+2 -1
View File
@@ -2,13 +2,14 @@
# this repository contains the full copyright notices and license terms.
from trytond.pool import Pool
from . import line, routes, user, work
from . import ir, line, routes, user, work
__all__ = ['register', 'routes']
def register():
Pool.register(
ir.Rule,
work.Work,
work.WorkContext,
line.Line,
+26
View File
@@ -0,0 +1,26 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import Pool, PoolMeta
class Rule(metaclass=PoolMeta):
__name__ = 'ir.rule'
@classmethod
def _get_context(cls, model_name):
pool = Pool()
User = pool.get('res.user')
context = super()._get_context(model_name)
if model_name == 'timesheet.line':
context['employees'] = User.get_employees()
return context
@classmethod
def _get_cache_key(cls, model_name):
pool = Pool()
User = pool.get('res.user')
key = super()._get_cache_key(model_name)
if model_name == 'timesheet.line':
key = (*key, User.get_employees())
return key