Remove tree structure from company
issue10163 review332181002
This commit is contained in:
1 parent
883a4b4b83
commit
34ff16a200
11 files changed
+90
-138
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Remove tree structure from company
|
||||
* Add test on context of company multivalue target fields
|
||||
* Use report header for CompanyReport
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ def register():
|
||||
company.Company,
|
||||
company.Employee,
|
||||
company.CompanyConfigStart,
|
||||
res.UserCompany,
|
||||
res.UserEmployee,
|
||||
res.User,
|
||||
ir.Sequence,
|
||||
|
||||
+4
-8
@@ -1,6 +1,6 @@
|
||||
# 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 ModelView, ModelSQL, fields, tree
|
||||
from trytond.model import ModelView, ModelSQL, fields
|
||||
from trytond.wizard import Wizard, StateView, Button, StateTransition
|
||||
from trytond.report import Report
|
||||
from trytond.pyson import Eval, If
|
||||
@@ -17,15 +17,11 @@ TIMEZONES += [(None, '')]
|
||||
Transaction.cache_keys.update({'company', 'employee'})
|
||||
|
||||
|
||||
class Company(tree(), ModelSQL, ModelView):
|
||||
class Company(ModelSQL, ModelView):
|
||||
'Company'
|
||||
__name__ = 'company.company'
|
||||
party = fields.Many2One('party.party', 'Party', required=True,
|
||||
ondelete='CASCADE')
|
||||
parent = fields.Many2One('company.company', 'Parent',
|
||||
help="Add the company below the parent.")
|
||||
childs = fields.One2Many('company.company', 'parent', 'Children',
|
||||
help="Add children below the company.")
|
||||
header = fields.Text(
|
||||
'Header', help="The text to display on report headers.")
|
||||
footer = fields.Text(
|
||||
@@ -130,10 +126,10 @@ class CompanyConfig(Wizard):
|
||||
|
||||
self.company.save()
|
||||
users = User.search([
|
||||
('main_company', '=', None),
|
||||
('companies', '=', None),
|
||||
])
|
||||
User.write(users, {
|
||||
'main_company': self.company.id,
|
||||
'companies': [('add', [self.company.id])],
|
||||
'company': self.company.id,
|
||||
})
|
||||
return 'end'
|
||||
|
||||
+1
-30
@@ -44,41 +44,12 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="inherit" eval="None"/>
|
||||
<field name="name">company_form</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="company_view_tree">
|
||||
<field name="model">company.company</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_childs">childs</field>
|
||||
<field name="name">company_tree</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="company_view_list">
|
||||
<field name="model">company.company</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="priority" eval="10"/>
|
||||
<field name="name">company_list</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_company_tree">
|
||||
<field name="name">Companies</field>
|
||||
<field name="res_model">company.company</field>
|
||||
<field name="domain" eval="[('parent', '=', None)]" pyson="1"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_company_tree_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="company_view_tree"/>
|
||||
<field name="act_window" ref="act_company_tree"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view"
|
||||
id="act_company_tree_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="company_view_form"/>
|
||||
<field name="act_window" ref="act_company_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_company"
|
||||
action="act_company_tree"
|
||||
sequence="10"
|
||||
id="menu_company_tree"/>
|
||||
|
||||
<record model="ir.action.act_window" id="act_company_list">
|
||||
<field name="name">Companies</field>
|
||||
@@ -97,7 +68,7 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<field name="act_window" ref="act_company_list"/>
|
||||
</record>
|
||||
<menuitem
|
||||
parent="menu_company_tree"
|
||||
parent="menu_company"
|
||||
action="act_company_list"
|
||||
sequence="10"
|
||||
id="menu_company_list"/>
|
||||
|
||||
+5
-7
@@ -27,10 +27,8 @@ user form.
|
||||
User
|
||||
****
|
||||
|
||||
Are added to the user model: a main company, a company and an employee
|
||||
field. The company field defines the current company of the user, this
|
||||
current company will influence the data this user see in Tryton: most
|
||||
of the records that are linked to a company will only be available for
|
||||
users in this very company. The main company define which current
|
||||
company a user can choose: either the main company itself or one of
|
||||
the children companies.
|
||||
Are added to the user model: companies, a company and an employee field. The
|
||||
company field defines the current company of the user, this current company
|
||||
will influence the data this user see in Tryton: most of the records that are
|
||||
linked to a company will only be available for users in this very company. The
|
||||
companies define which current company a user can choose.
|
||||
@@ -1,11 +1,24 @@
|
||||
# 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 sql import Null
|
||||
|
||||
from trytond.model import ModelSQL, fields
|
||||
from trytond.pool import PoolMeta, Pool
|
||||
from trytond.pyson import Eval
|
||||
from trytond.transaction import Transaction
|
||||
|
||||
|
||||
class UserCompany(ModelSQL):
|
||||
"User - Company"
|
||||
__name__ = 'res.user-company.company'
|
||||
|
||||
user = fields.Many2One(
|
||||
'res.user', "User", ondelete='CASCADE', select=True, required=True)
|
||||
company = fields.Many2One(
|
||||
'company.company', "Company",
|
||||
ondelete='CASCADE', select=True, required=True)
|
||||
|
||||
|
||||
class UserEmployee(ModelSQL):
|
||||
'User - Employee'
|
||||
__name__ = 'res.user-company.employee'
|
||||
@@ -17,16 +30,23 @@ class UserEmployee(ModelSQL):
|
||||
|
||||
class User(metaclass=PoolMeta):
|
||||
__name__ = 'res.user'
|
||||
main_company = fields.Many2One('company.company', 'Main Company',
|
||||
help="Grant access to the company and its children.")
|
||||
company = fields.Many2One('company.company', 'Current Company',
|
||||
domain=[('parent', 'child_of', [Eval('main_company')], 'parent')],
|
||||
depends=['main_company'],
|
||||
|
||||
companies = fields.Many2Many(
|
||||
'res.user-company.company', 'user', 'company', "Companies",
|
||||
help="The companies that the user has access to.")
|
||||
company = fields.Many2One(
|
||||
'company.company', "Current Company",
|
||||
domain=[
|
||||
('id', 'in', Eval('companies', [])),
|
||||
],
|
||||
depends=['companies'],
|
||||
help="Select the company to work for.")
|
||||
companies = fields.Function(fields.One2Many('company.company', None,
|
||||
'Companies'), 'get_companies')
|
||||
employees = fields.Many2Many('res.user-company.employee', 'user',
|
||||
'employee', 'Employees',
|
||||
domain=[
|
||||
('company', 'in', Eval('companies', [])),
|
||||
],
|
||||
depends=['companies'],
|
||||
help="Add employees to grant the user access to them.")
|
||||
employee = fields.Many2One('company.employee', 'Current Employee',
|
||||
domain=[
|
||||
@@ -42,37 +62,42 @@ class User(metaclass=PoolMeta):
|
||||
cls._context_fields.insert(0, 'company')
|
||||
cls._context_fields.insert(0, 'employee')
|
||||
|
||||
@staticmethod
|
||||
def default_main_company():
|
||||
return Transaction().context.get('company')
|
||||
@classmethod
|
||||
def __register__(cls, module):
|
||||
pool = Pool()
|
||||
UserCompany = pool.get('res.user-company.company')
|
||||
transaction = Transaction()
|
||||
table = cls.__table__()
|
||||
user_company = UserCompany.__table__()
|
||||
|
||||
super().__register__(module)
|
||||
|
||||
table_h = cls.__table_handler__(module)
|
||||
cursor = transaction.connection.cursor()
|
||||
|
||||
# Migration from 5.8: remove main_company
|
||||
if table_h.column_exist('main_company'):
|
||||
cursor.execute(*user_company.insert(
|
||||
[user_company.user, user_company.company],
|
||||
table.select(
|
||||
table.id, table.main_company,
|
||||
where=table.main_company != Null)))
|
||||
cursor.execute(*user_company.insert(
|
||||
[user_company.user, user_company.company],
|
||||
table.select(
|
||||
table.id, table.company,
|
||||
where=(table.company != Null)
|
||||
& (table.company != table.main_company))))
|
||||
table_h.drop_column('main_company')
|
||||
|
||||
@classmethod
|
||||
def default_companies(cls):
|
||||
company = Transaction().context.get('company')
|
||||
return [company] if company else None
|
||||
|
||||
@classmethod
|
||||
def default_company(cls):
|
||||
return cls.default_main_company()
|
||||
|
||||
@classmethod
|
||||
def get_companies(cls, users, name):
|
||||
Company = Pool().get('company.company')
|
||||
companies = {}
|
||||
company_childs = {}
|
||||
for user in users:
|
||||
companies[user.id] = []
|
||||
company = None
|
||||
if user.company:
|
||||
company = user.company
|
||||
elif user.main_company:
|
||||
company = user.main_company
|
||||
if company:
|
||||
if company in company_childs:
|
||||
company_ids = company_childs[company]
|
||||
else:
|
||||
company_ids = list(map(int, Company.search([
|
||||
('parent', 'child_of', [company.id]),
|
||||
])))
|
||||
company_childs[company] = company_ids
|
||||
if company_ids:
|
||||
companies[user.id].extend(company_ids)
|
||||
return companies
|
||||
return Transaction().context.get('company')
|
||||
|
||||
def get_status_bar(self, name):
|
||||
def same_company(record):
|
||||
@@ -82,16 +107,11 @@ class User(metaclass=PoolMeta):
|
||||
and len(list(filter(same_company, self.employees))) > 1):
|
||||
status += ' - %s' % self.employee.rec_name
|
||||
if self.company:
|
||||
if self.main_company.childs:
|
||||
if len(self.companies) > 1:
|
||||
status += ' - %s' % self.company.rec_name
|
||||
status += ' [%s]' % self.company.currency.code
|
||||
return status
|
||||
|
||||
@fields.depends('main_company')
|
||||
def on_change_main_company(self):
|
||||
self.company = self.main_company
|
||||
self.employee = None
|
||||
|
||||
@fields.depends('company', 'employees')
|
||||
def on_change_company(self):
|
||||
Employee = Pool().get('company.employee')
|
||||
@@ -109,16 +129,12 @@ class User(metaclass=PoolMeta):
|
||||
res = super(User, cls)._get_preferences(user,
|
||||
context_only=context_only)
|
||||
if not context_only:
|
||||
res['main_company'] = None
|
||||
if user.main_company:
|
||||
res['main_company'] = user.main_company.id
|
||||
res['main_company.rec_name'] = user.main_company.rec_name
|
||||
res['companies'] = [c.id for c in user.companies]
|
||||
res['employees'] = [e.id for e in user.employees]
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def read(cls, ids, fields_names):
|
||||
Company = Pool().get('company.company')
|
||||
user_id = Transaction().user
|
||||
if user_id == 0 and 'user' in Transaction().context:
|
||||
user_id = Transaction().context['user']
|
||||
@@ -138,15 +154,12 @@ class User(metaclass=PoolMeta):
|
||||
if values:
|
||||
if ('company' in fields_names
|
||||
and 'company' in Transaction().context):
|
||||
main_company_id = values.get('main_company')
|
||||
if not main_company_id:
|
||||
main_company_id = cls.read([user_id],
|
||||
['main_company'])[0]['main_company']
|
||||
companies = Company.search([
|
||||
('parent', 'child_of', [main_company_id]),
|
||||
])
|
||||
companies = values.get('companies')
|
||||
if not companies:
|
||||
companies = cls.read([user_id],
|
||||
['companies'])[0]['companies']
|
||||
company_id = Transaction().context['company']
|
||||
if ((company_id and company_id in map(int, companies))
|
||||
if ((company_id and company_id in companies)
|
||||
or not company_id
|
||||
or Transaction().user == 0):
|
||||
values['company'] = company_id
|
||||
|
||||
@@ -57,7 +57,7 @@ else:
|
||||
if local_version:
|
||||
version += '+' + '.'.join(local_version)
|
||||
|
||||
requires = []
|
||||
requires = ['python-sql >= 0.4']
|
||||
for dep in info.get('depends', []):
|
||||
if not re.match(r'(ir|res)(\W|$)', dep):
|
||||
requires.append(get_require_version('trytond_%s' % dep))
|
||||
|
||||
+6
-24
@@ -51,7 +51,7 @@ def set_company(company):
|
||||
pool = Pool()
|
||||
User = pool.get('res.user')
|
||||
User.write([User(Transaction().user)], {
|
||||
'main_company': company.id,
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
})
|
||||
with Transaction().set_context(User.get_preferences(context_only=True)):
|
||||
@@ -110,23 +110,6 @@ class CompanyTestCase(
|
||||
company = create_company()
|
||||
self.assertTrue(company)
|
||||
|
||||
@with_transaction()
|
||||
def test_company_recursion(self):
|
||||
'Test company recursion'
|
||||
pool = Pool()
|
||||
Company = pool.get('company.company')
|
||||
|
||||
company1 = create_company()
|
||||
company2 = create_company('Michael Scott Paper Company')
|
||||
company2.parent = company1
|
||||
company2.save()
|
||||
self.assertTrue(company2)
|
||||
|
||||
self.assertRaises(Exception, Company.write,
|
||||
[company1], {
|
||||
'parent': company2.id,
|
||||
})
|
||||
|
||||
@with_transaction()
|
||||
def test_employe(self):
|
||||
'Create employee'
|
||||
@@ -154,19 +137,18 @@ class CompanyTestCase(
|
||||
company1 = create_company()
|
||||
company2 = create_company('Michael Scott Paper Company',
|
||||
currency=company1.currency)
|
||||
company2.parent = company1
|
||||
company2.save()
|
||||
company3 = create_company()
|
||||
|
||||
user1, user2 = User.create([{
|
||||
'name': 'Jim Halper',
|
||||
'login': 'jim',
|
||||
'main_company': company1.id,
|
||||
'companies': [('add', [company1.id, company2.id])],
|
||||
'company': company1.id,
|
||||
}, {
|
||||
'name': 'Pam Beesly',
|
||||
'login': 'pam',
|
||||
'main_company': company2.id,
|
||||
'companies': [('add', [company2.id])],
|
||||
'company': company2.id,
|
||||
}])
|
||||
self.assertTrue(user1)
|
||||
@@ -200,7 +182,7 @@ class CompanyTestCase(
|
||||
company = create_company()
|
||||
root = User(0)
|
||||
root.company = None
|
||||
root.main_company = None
|
||||
root.companies = None
|
||||
root.save()
|
||||
|
||||
with transaction.set_user(0):
|
||||
@@ -224,14 +206,14 @@ class CompanyTestCase(
|
||||
user1, user2 = User.create([{
|
||||
'name': "Jim Halper",
|
||||
'login': "jim",
|
||||
'main_company': company.id,
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
'employees': [('add', [employee1.id, employee2.id])],
|
||||
'employee': employee1.id,
|
||||
}, {
|
||||
'name': "Pam Beesly",
|
||||
'login': "pam",
|
||||
'main_company': company.id,
|
||||
'companies': [('add', [company.id])],
|
||||
'company': company.id,
|
||||
'employees': [('add', [employee2.id])],
|
||||
'employee': employee2.id,
|
||||
|
||||
@@ -9,10 +9,8 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<label name="timezone"/>
|
||||
<field name="timezone"/>
|
||||
<notebook colspan="6">
|
||||
<page string="Company" col="2" id="company">
|
||||
<label name="parent"/>
|
||||
<field name="parent"/>
|
||||
<field name="employees" colspan="2"/>
|
||||
<page name="employees" col="1">
|
||||
<field name="employees"/>
|
||||
</page>
|
||||
<page string="Reports" col="1" id="reports">
|
||||
<separator name="header"/>
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
|
||||
this repository contains the full copyright notices and license terms. -->
|
||||
<tree>
|
||||
<field name="party" expand="1"/>
|
||||
<field name="currency"/>
|
||||
</tree>
|
||||
+2
-3
@@ -4,12 +4,11 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<data>
|
||||
<xpath expr="/form/notebook/page/separator[@name='signature']"
|
||||
position="before">
|
||||
<label name="main_company"/>
|
||||
<field name="main_company" widget="selection"/>
|
||||
<label name="company"/>
|
||||
<field name="company" widget="selection"/>
|
||||
<label name="employee"/>
|
||||
<field name="employee" widget="selection"/>
|
||||
<field name="employees" colspan="4"/>
|
||||
<field name="companies" colspan="2"/>
|
||||
<field name="employees" colspan="2"/>
|
||||
</xpath>
|
||||
</data>
|
||||
Reference in new issue
Block a user