Merge pull request #78 from akretion/12.0-mig-base_usability
12.0 mig base usability
This commit is contained in:
1
base_usability/__init__.py
Normal file
1
base_usability/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import models
|
||||||
39
base_usability/__manifest__.py
Normal file
39
base_usability/__manifest__.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# © 2014-2016 Akretion (http://www.akretion.com)
|
||||||
|
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
{
|
||||||
|
'name': 'Base Usability',
|
||||||
|
'version': '12.0.0.1.0',
|
||||||
|
'category': 'Partner',
|
||||||
|
'license': 'AGPL-3',
|
||||||
|
'summary': 'Better usability in base module',
|
||||||
|
'description': """
|
||||||
|
Base Usability
|
||||||
|
==============
|
||||||
|
|
||||||
|
This module adds *track_visibility='onchange'* on all the important fields of the Partner object.
|
||||||
|
|
||||||
|
By default, Odoo doesn't display the title field on all the partner form views. This module fixes it (it replaces the module base_title_on_partner).
|
||||||
|
|
||||||
|
It also adds a log message at INFO level when sending an email via SMTP.
|
||||||
|
|
||||||
|
It displays the local modules with installable filter.
|
||||||
|
A group by 'State' is added to module search view.
|
||||||
|
|
||||||
|
It provides a _display_report_header method on the res.company object and
|
||||||
|
_display_full_address on res.partner which are useful for reporting.
|
||||||
|
""",
|
||||||
|
'author': 'Akretion',
|
||||||
|
'website': 'http://www.akretion.com',
|
||||||
|
'depends': ['base'],
|
||||||
|
'data': [
|
||||||
|
'security/group.xml',
|
||||||
|
'views/partner_view.xml',
|
||||||
|
'views/partner_bank_view.xml',
|
||||||
|
'views/users_view.xml',
|
||||||
|
'views/country_view.xml',
|
||||||
|
'views/module_view.xml',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
diff --git a/odoo/addons/base/models/res_users.py b/odoo/addons/base/models/res_users.py
|
||||||
|
index 083607f9..99ae8857 100644
|
||||||
|
--- a/odoo/addons/base/models/res_users.py
|
||||||
|
+++ b/odoo/addons/base/models/res_users.py
|
||||||
|
@@ -426,7 +426,13 @@ class Users(models.Model):
|
||||||
|
for user in users:
|
||||||
|
user.partner_id.active = user.active
|
||||||
|
if user.partner_id.company_id:
|
||||||
|
- user.partner_id.write({'company_id': user.company_id.id})
|
||||||
|
+ # AKRETION HACK: if you have a multi-company setup where
|
||||||
|
+ # partners are NOT shared between companies, having
|
||||||
|
+ # company_id=False on partners related to users
|
||||||
|
+ # avoids a lot of trouble (you should also disable 'read'
|
||||||
|
+ # on the ir.rule 'user rule' (XMLID base.res_users_rule)
|
||||||
|
+ # user.partner_id.write({'company_id': user.company_id.id})
|
||||||
|
+ user.partner_id.write({'company_id': False})
|
||||||
|
return users
|
||||||
|
|
||||||
|
@api.multi
|
||||||
5
base_usability/models/__init__.py
Normal file
5
base_usability/models/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from . import users
|
||||||
|
from . import partner
|
||||||
|
from . import company
|
||||||
|
from . import mail
|
||||||
|
from . import misc
|
||||||
81
base_usability/models/company.py
Normal file
81
base_usability/models/company.py
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
# © 2015-2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import models, api, _
|
||||||
|
|
||||||
|
|
||||||
|
class ResCompany(models.Model):
|
||||||
|
_inherit = 'res.company'
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def generate_line(self, fields, options, icon=True, separator=' - '):
|
||||||
|
assert fields
|
||||||
|
assert options
|
||||||
|
content = []
|
||||||
|
for field in fields:
|
||||||
|
value = False
|
||||||
|
if isinstance(field, tuple) and len(field) == 2:
|
||||||
|
value = field[0]
|
||||||
|
label = field[1]
|
||||||
|
uicon = False
|
||||||
|
elif isinstance(field, str) and field in options:
|
||||||
|
value = options[field]['value']
|
||||||
|
label = options[field].get('label')
|
||||||
|
uicon = options[field].get('icon')
|
||||||
|
if value:
|
||||||
|
prefix = icon and uicon or label
|
||||||
|
if prefix:
|
||||||
|
content.append('%s %s' % (prefix, value))
|
||||||
|
else:
|
||||||
|
content.append(value)
|
||||||
|
line = separator.join(content)
|
||||||
|
return line
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _prepare_header_options(self):
|
||||||
|
self.ensure_one()
|
||||||
|
options = {
|
||||||
|
'phone': {
|
||||||
|
'value': self.phone,
|
||||||
|
# http://www.fileformat.info/info/unicode/char/1f4de/index.htm
|
||||||
|
'icon': '\U0001F4DE',
|
||||||
|
'label': _('Tel:')},
|
||||||
|
'email': {
|
||||||
|
'value': self.email,
|
||||||
|
# http://www.fileformat.info/info/unicode/char/2709/index.htm
|
||||||
|
'icon': '\u2709',
|
||||||
|
'label': _('E-mail:')},
|
||||||
|
'website': {
|
||||||
|
'value': self.website,
|
||||||
|
'icon': '\U0001f310',
|
||||||
|
'label': _('Website:')},
|
||||||
|
'vat': {
|
||||||
|
'value': self.vat,
|
||||||
|
'label': _('TVA :')}, # TODO translate
|
||||||
|
}
|
||||||
|
return options
|
||||||
|
|
||||||
|
def _report_company_legal_name(self):
|
||||||
|
'''Method inherited in the module base_company_extension'''
|
||||||
|
self.ensure_one()
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
# for reports
|
||||||
|
@api.multi
|
||||||
|
def _display_report_header(
|
||||||
|
self, line_details=[['phone', 'website'], ['vat']],
|
||||||
|
icon=True, line_separator=' - '):
|
||||||
|
self.ensure_one()
|
||||||
|
res = ''
|
||||||
|
address = self.partner_id._display_address(without_company=True)
|
||||||
|
address = address.replace('\n', ' - ')
|
||||||
|
|
||||||
|
line1 = '%s - %s' % (self._report_company_legal_name(), address)
|
||||||
|
lines = [line1]
|
||||||
|
options = self._prepare_header_options()
|
||||||
|
for details in line_details:
|
||||||
|
line = self.generate_line(
|
||||||
|
details, options, icon=icon, separator=line_separator)
|
||||||
|
lines.append(line)
|
||||||
|
res = '\n'.join(lines)
|
||||||
|
return res
|
||||||
35
base_usability/models/mail.py
Normal file
35
base_usability/models/mail.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# © 2015-2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import models, api
|
||||||
|
from odoo.addons.base.models.ir_mail_server import extract_rfc2822_addresses
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class IrMailServer(models.Model):
|
||||||
|
_inherit = "ir.mail_server"
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def send_email(
|
||||||
|
self, message, mail_server_id=None, smtp_server=None,
|
||||||
|
smtp_port=None, smtp_user=None, smtp_password=None,
|
||||||
|
smtp_encryption=None, smtp_debug=False, smtp_session=None):
|
||||||
|
# Start copy from native method
|
||||||
|
smtp_from = message['Return-Path'] or\
|
||||||
|
self._get_default_bounce_address() or message['From']
|
||||||
|
from_rfc2822 = extract_rfc2822_addresses(smtp_from)
|
||||||
|
smtp_from = from_rfc2822[-1]
|
||||||
|
# End copy from native method
|
||||||
|
logger.info(
|
||||||
|
"Sending email from '%s' to '%s' Cc '%s' Bcc '%s' "
|
||||||
|
"with subject '%s'",
|
||||||
|
smtp_from, message.get('To'), message.get('Cc'),
|
||||||
|
message.get('Bcc'), message.get('Subject'))
|
||||||
|
return super(IrMailServer, self).send_email(
|
||||||
|
message, mail_server_id=mail_server_id,
|
||||||
|
smtp_server=smtp_server, smtp_port=smtp_port,
|
||||||
|
smtp_user=smtp_user, smtp_password=smtp_password,
|
||||||
|
smtp_encryption=smtp_encryption, smtp_debug=smtp_debug,
|
||||||
|
smtp_session=smtp_session)
|
||||||
48
base_usability/models/misc.py
Normal file
48
base_usability/models/misc.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# © 2015-2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import models, fields, api
|
||||||
|
from odoo.tools import misc
|
||||||
|
from odoo.tools import float_compare
|
||||||
|
|
||||||
|
|
||||||
|
class BaseLanguageExport(models.TransientModel):
|
||||||
|
_inherit = 'base.language.export'
|
||||||
|
|
||||||
|
# Default format for language files = format used by OpenERP modules
|
||||||
|
format = fields.Selection(default='po')
|
||||||
|
|
||||||
|
|
||||||
|
class BaseLanguageInstall(models.TransientModel):
|
||||||
|
_inherit = 'base.language.install'
|
||||||
|
|
||||||
|
overwrite = fields.Boolean(default=True)
|
||||||
|
|
||||||
|
|
||||||
|
class BaseUsabilityInstalled(models.AbstractModel):
|
||||||
|
_name = "base.usability.installed"
|
||||||
|
_description = "technical flag to see if base_usability module is installed"
|
||||||
|
|
||||||
|
|
||||||
|
formatLang_original = misc.formatLang
|
||||||
|
|
||||||
|
def formatLang(self, value, digits=None, grouping=True, monetary=False,
|
||||||
|
dp=False, currency_obj=False, int_no_digits=True):
|
||||||
|
with api.Environment.manage():
|
||||||
|
env = api.Environment(self.cr, self.uid, {})
|
||||||
|
if (
|
||||||
|
'base.usability.installed' in env and
|
||||||
|
int_no_digits and
|
||||||
|
not monetary and
|
||||||
|
isinstance(value, float) and
|
||||||
|
dp):
|
||||||
|
prec = env['decimal.precision'].precision_get(dp)
|
||||||
|
if not float_compare(value, int(value), precision_digits=prec):
|
||||||
|
digits = 0
|
||||||
|
dp = False
|
||||||
|
res = formatLang_original(
|
||||||
|
self, value, digits=digits, grouping=grouping, monetary=monetary,
|
||||||
|
dp=dp, currency_obj=currency_obj)
|
||||||
|
return res
|
||||||
|
|
||||||
|
misc.formatLang = formatLang
|
||||||
139
base_usability/models/partner.py
Normal file
139
base_usability/models/partner.py
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
# © 2015-2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import models, fields, api, _
|
||||||
|
|
||||||
|
|
||||||
|
class ResPartner(models.Model):
|
||||||
|
_inherit = 'res.partner'
|
||||||
|
|
||||||
|
# track_visibility is handled in the 'mail' module, and base_usability
|
||||||
|
# doesn't depend on 'mail', but that doesn't hurt, it will just be
|
||||||
|
# ignored if mail is not installed
|
||||||
|
name = fields.Char(track_visibility='onchange')
|
||||||
|
parent_id = fields.Many2one(track_visibility='onchange')
|
||||||
|
ref = fields.Char(track_visibility='onchange', copy=False)
|
||||||
|
lang = fields.Selection(track_visibility='onchange')
|
||||||
|
user_id = fields.Many2one(track_visibility='onchange')
|
||||||
|
vat = fields.Char(track_visibility='onchange')
|
||||||
|
customer = fields.Boolean(track_visibility='onchange')
|
||||||
|
supplier = fields.Boolean(track_visibility='onchange')
|
||||||
|
type = fields.Selection(track_visibility='onchange')
|
||||||
|
street = fields.Char(track_visibility='onchange')
|
||||||
|
street2 = fields.Char(track_visibility='onchange')
|
||||||
|
zip = fields.Char(track_visibility='onchange')
|
||||||
|
city = fields.Char(track_visibility='onchange')
|
||||||
|
state_id = fields.Many2one(track_visibility='onchange')
|
||||||
|
country_id = fields.Many2one(track_visibility='onchange')
|
||||||
|
email = fields.Char(track_visibility='onchange')
|
||||||
|
is_company = fields.Boolean(track_visibility='onchange')
|
||||||
|
active = fields.Boolean(track_visibility='onchange')
|
||||||
|
company_id = fields.Many2one(track_visibility='onchange')
|
||||||
|
# For reports
|
||||||
|
name_title = fields.Char(
|
||||||
|
compute='_compute_name_title', string='Name with Title')
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
@api.depends('name', 'title')
|
||||||
|
def _compute_name_title(self):
|
||||||
|
for partner in self:
|
||||||
|
name_title = partner.name
|
||||||
|
if partner.title and not partner.is_company:
|
||||||
|
partner_lg = partner
|
||||||
|
# If prefer to read the lang of the partner than the lang
|
||||||
|
# of the context. That way, an English man will be displayed
|
||||||
|
# with his title in English whatever the environment
|
||||||
|
if partner.lang:
|
||||||
|
partner_lg = partner.with_context(lang=partner.lang)
|
||||||
|
title = partner_lg.title.shortcut or partner_lg.title.name
|
||||||
|
name_title = ' '.join([title, name_title])
|
||||||
|
partner.name_title = name_title
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def _display_address(self, without_company=False):
|
||||||
|
'''Remove empty lines'''
|
||||||
|
res = super(ResPartner, self)._display_address(
|
||||||
|
without_company=without_company)
|
||||||
|
while "\n\n" in res:
|
||||||
|
res = res.replace('\n\n', '\n')
|
||||||
|
return res
|
||||||
|
|
||||||
|
# for reports
|
||||||
|
@api.multi
|
||||||
|
def _display_full_address(
|
||||||
|
self, details=[
|
||||||
|
'company', 'name', 'address', 'phone',
|
||||||
|
'mobile', 'email'],
|
||||||
|
icon=True):
|
||||||
|
self.ensure_one()
|
||||||
|
# To make the icons work with py3o with PDF export, on the py3o server:
|
||||||
|
# 1) sudo apt-get install fonts-symbola
|
||||||
|
# 2) start libreoffice in xvfb (don't use --headless) (To confirm)
|
||||||
|
if self.is_company:
|
||||||
|
company = self.name
|
||||||
|
name = False
|
||||||
|
else:
|
||||||
|
name = self.name_title
|
||||||
|
company = self.parent_id and self.parent_id.is_company and\
|
||||||
|
self.parent_id.name or False
|
||||||
|
options = {
|
||||||
|
'name': {
|
||||||
|
'value': name,
|
||||||
|
},
|
||||||
|
'company': {
|
||||||
|
'value': company,
|
||||||
|
},
|
||||||
|
'phone': {
|
||||||
|
'value': self.phone,
|
||||||
|
# http://www.fileformat.info/info/unicode/char/1f4de/index.htm
|
||||||
|
'icon': '\U0001F4DE',
|
||||||
|
'label': _('Tel:'),
|
||||||
|
},
|
||||||
|
'mobile': {
|
||||||
|
'value': self.mobile,
|
||||||
|
# http://www.fileformat.info/info/unicode/char/1f4f1/index.htm
|
||||||
|
'icon': '\U0001F4F1',
|
||||||
|
'label': _('Mobile:'),
|
||||||
|
},
|
||||||
|
'email': {
|
||||||
|
'value': self.email,
|
||||||
|
# http://www.fileformat.info/info/unicode/char/2709/index.htm
|
||||||
|
'icon': '\u2709',
|
||||||
|
'label': _('E-mail:'),
|
||||||
|
},
|
||||||
|
'website': {
|
||||||
|
'value': self.website,
|
||||||
|
# http://www.fileformat.info/info/unicode/char/1f310/index.htm
|
||||||
|
'icon': '\U0001f310',
|
||||||
|
'label': _('Website:'),
|
||||||
|
},
|
||||||
|
'address': {
|
||||||
|
'value': self._display_address(without_company=True),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res = []
|
||||||
|
for detail in details:
|
||||||
|
if options.get(detail) and options[detail]['value']:
|
||||||
|
entry = options[detail]
|
||||||
|
prefix = icon and entry.get('icon') or entry.get('label')
|
||||||
|
if prefix:
|
||||||
|
res.append('%s %s' % (prefix, entry['value']))
|
||||||
|
else:
|
||||||
|
res.append('%s' % entry['value'])
|
||||||
|
res = '\n'.join(res)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
class ResPartnerCategory(models.Model):
|
||||||
|
_inherit = 'res.partner.category'
|
||||||
|
|
||||||
|
name = fields.Char(translate=False)
|
||||||
|
|
||||||
|
|
||||||
|
class ResPartnerBank(models.Model):
|
||||||
|
_inherit = 'res.partner.bank'
|
||||||
|
|
||||||
|
# In the 'base' module, they didn't put any string, so the bank name is
|
||||||
|
# displayed as 'Name', which the string of the related field it
|
||||||
|
# points to
|
||||||
|
bank_name = fields.Char(string='Bank Name')
|
||||||
40
base_usability/models/users.py
Normal file
40
base_usability/models/users.py
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
# Copyright 2018 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
|
from odoo import models, api, SUPERUSER_ID, _
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
import logging
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class ResUsers(models.Model):
|
||||||
|
_inherit = 'res.users'
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def default_get(self, fields_list):
|
||||||
|
res = super(ResUsers, self).default_get(fields_list)
|
||||||
|
# For a new partner auto-created when you create a new user, we prefer
|
||||||
|
# customer=False and supplier=True by default
|
||||||
|
res.update({
|
||||||
|
'customer': False,
|
||||||
|
'supplier': True,
|
||||||
|
})
|
||||||
|
return res
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def _script_partners_linked_to_users_no_company(self):
|
||||||
|
if self.env.user.id != SUPERUSER_ID:
|
||||||
|
raise UserError(_('You must run this script as admin user'))
|
||||||
|
logger.info(
|
||||||
|
'START to set company_id=False on partners related to users')
|
||||||
|
users = self.search(
|
||||||
|
['|', ('active', '=', True), ('active', '=', False)])
|
||||||
|
for user in users:
|
||||||
|
if user.partner_id.company_id:
|
||||||
|
user.partner_id.company_id = False
|
||||||
|
logger.info(
|
||||||
|
'Wrote company_id=False on user %s ID %d',
|
||||||
|
user.login, user.id)
|
||||||
|
logger.info(
|
||||||
|
'END setting company_id=False on partners related to users')
|
||||||
|
return True
|
||||||
22
base_usability/security/group.xml
Normal file
22
base_usability/security/group.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
© 2016 Akretion (Alexis de Lattre <alexis.delattre@akretion.com>)
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<odoo noupdate="1">
|
||||||
|
|
||||||
|
<!-- This group is used to hide menu entries to everybody,
|
||||||
|
so you should not put any user in this group. It is used
|
||||||
|
by the module account_hide_analytic_line, but it will certainly
|
||||||
|
be used by other modules in the future, that's why I declare
|
||||||
|
this group in the base_usability module
|
||||||
|
I don't want to use the base.group_no_one for this, because a lot
|
||||||
|
of interesing menu entries are attached to this group, so it's
|
||||||
|
common to have several users that belong to this group -->
|
||||||
|
<record id="group_nobody" model="res.groups">
|
||||||
|
<field name="name">Nobody (used to hide native menus)</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
BIN
base_usability/static/description/icon.png
Normal file
BIN
base_usability/static/description/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
51
base_usability/views/country_view.xml
Normal file
51
base_usability/views/country_view.xml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
© 2015-2016 Akretion (http://www.akretion.com/)
|
||||||
|
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="res_country_state_search" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.res.country.state.search</field>
|
||||||
|
<field name="model">res.country.state</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Search States">
|
||||||
|
<field name="name" filter_domain="['|', ('name', 'ilike', self), ('code', '=', self)]" string="Name or Code"/>
|
||||||
|
<field name="code"/>
|
||||||
|
<field name="country_id"/>
|
||||||
|
<group string="Group By" name="groupby">
|
||||||
|
<filter name="country_groupby" string="Country" context="{'group_by': 'country_id'}"/>
|
||||||
|
</group>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="res_country_search" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.res.country.search</field>
|
||||||
|
<field name="model">res.country</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Search Countries">
|
||||||
|
<field name="name" filter_domain="['|', ('name', 'ilike', self), ('code', '=', self)]" string="Name or Code"/>
|
||||||
|
<field name="code"/>
|
||||||
|
<field name="currency_id"/>
|
||||||
|
<group string="Group By" name="groupby">
|
||||||
|
<filter name="currency_groupby" string="Currency" context="{'group_by': 'currency_id'}"/>
|
||||||
|
</group>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_country_form" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.res.country.form</field>
|
||||||
|
<field name="model">res.country</field>
|
||||||
|
<field name="inherit_id" ref="base.view_country_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="code" position="after">
|
||||||
|
<field name="country_group_ids" widget="many2many_tags"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
27
base_usability/views/module_view.xml
Normal file
27
base_usability/views/module_view.xml
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
© 2015-2016 Akretion (http://www.akretion.com/)
|
||||||
|
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="view_module_filter" model="ir.ui.view">
|
||||||
|
<field name="model">ir.module.module</field>
|
||||||
|
<field name="inherit_id" ref="base.view_module_filter"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//filter[@name='extra']" position="after">
|
||||||
|
<filter name="installable" string="Installable" domain="[('state', '!=', 'uninstallable')]"/>
|
||||||
|
</xpath>
|
||||||
|
<group expand="0" position="inside">
|
||||||
|
<filter name="state_groupby" string="State" context="{'group_by': 'state'}"/>
|
||||||
|
</group>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="base.open_module_tree" model="ir.actions.act_window">
|
||||||
|
<field name="context">{'search_default_installable': 1}</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
22
base_usability/views/partner_bank_view.xml
Normal file
22
base_usability/views/partner_bank_view.xml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2018 Akretion (http://www.akretion.com/)
|
||||||
|
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="view_partner_bank_tree" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.res.partner.bank.tree</field>
|
||||||
|
<field name="model">res.partner.bank</field>
|
||||||
|
<field name="inherit_id" ref="base.view_partner_bank_tree"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="sequence" position="attributes">
|
||||||
|
<attribute name="invisible">0</attribute>
|
||||||
|
<attribute name="widget">handle</attribute>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
67
base_usability/views/partner_view.xml
Normal file
67
base_usability/views/partner_view.xml
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
© 2014-2016 Akretion (http://www.akretion.com/)
|
||||||
|
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="view_partner_form" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.title.on.partner.form</field>
|
||||||
|
<field name="model">res.partner</field>
|
||||||
|
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<!-- Wider 'name' field -->
|
||||||
|
<xpath expr="//sheet/div[hasclass('oe_title')]" position="attributes">
|
||||||
|
<attribute name="style">width: 650px;</attribute>
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//field[@name='child_ids']/form//field[@name='email']" position="attributes">
|
||||||
|
<attribute name="widget">email</attribute>
|
||||||
|
</xpath>
|
||||||
|
<!-- Show title not only on Contacts -->
|
||||||
|
<xpath expr="//field[@name='child_ids']/form//field[@name='title']" position="attributes">
|
||||||
|
<attribute name="attrs"></attribute>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_partner_simple_form" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.title.on.partner.simplified.form</field>
|
||||||
|
<field name="model">res.partner</field>
|
||||||
|
<field name="inherit_id" ref="base.view_partner_simple_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="function" position="before">
|
||||||
|
<field name="title"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_partner_tree" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.res.partner.tree</field>
|
||||||
|
<field name="model">res.partner</field>
|
||||||
|
<field name="inherit_id" ref="base.view_partner_tree"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="country_id" position="attributes">
|
||||||
|
<attribute name="invisible">0</attribute>
|
||||||
|
</field>
|
||||||
|
<field name="country_id" position="before">
|
||||||
|
<field name="city"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_res_partner_filter" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.partner.search.form</field>
|
||||||
|
<field name="model">res.partner</field>
|
||||||
|
<field name="inherit_id" ref="base.view_res_partner_filter"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="name" position="attributes">
|
||||||
|
<attribute name="string">Name or Email or Reference</attribute>
|
||||||
|
<!-- for 'ref', change '=' to 'start with' -->
|
||||||
|
<attribute name="filter_domain">['|','|',('display_name','ilike',self),('ref','=ilike',self + '%'),('email','ilike',self)]</attribute>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
21
base_usability/views/users_view.xml
Normal file
21
base_usability/views/users_view.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright 2018 Akretion (http://www.akretion.com/)
|
||||||
|
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
-->
|
||||||
|
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="view_users_tree" model="ir.ui.view">
|
||||||
|
<field name="name">base_usability.res.users.tree</field>
|
||||||
|
<field name="model">res.users</field>
|
||||||
|
<field name="inherit_id" ref="base.view_users_tree"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="login_date" position="after">
|
||||||
|
<field name="company_id" groups="base.group_multi_company"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user