Remove employee and employees from evaluation context of rule domain
Closes #12581
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,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
@@ -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
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,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,
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user