You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

158 lines
6.1 KiB

# -*- coding: utf-8 -*-
# Copyright 2014-2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from lxml import etree
from odoo.osv.orm import transfer_modifiers_to_node
from odoo.osv import expression
from odoo import _, api, fields, models
_logger = logging.getLogger(__name__)
NAME_PREFIX = 'relation_ids_tab'
class ResPartner(models.Model):
_inherit = 'res.partner'
def _get_tab_fieldname(self, tab):
"""Create fieldname for tab."""
return '%s_%s' % (NAME_PREFIX, tab.id)
@api.model
def _add_tab_field(self, tab):
fieldname = self._get_tab_fieldname(tab)
_logger.info(_(
"Adding field %s to res.partner model." % fieldname))
field = fields.One2many(
comodel_name='res.partner.relation.all',
inverse_name='this_partner_id',
domain=[('tab_id', '=', tab.id)],
string=tab.name)
self._add_field(fieldname, field)
@api.model
def _update_tab_field(self, tab):
fieldname = self._get_tab_fieldname(tab)
if fieldname not in self._fields:
return self._add_tab_field(tab)
_logger.info(_(
"Updating field %s in res.partner model." % fieldname))
self._fields[fieldname].string = tab.name
@api.model
def _delete_tab_field(self, fieldname):
_logger.info(_(
"deleting field %s from res.partner model." % fieldname))
self._pop_field(fieldname)
@api.model
def _update_tab_fields(self):
"""Create a field for each tab that might be shown for a partner."""
deprecated_tab_fields = [
name for name in self._fields
if name.startswith(NAME_PREFIX)]
tab_model = self.env['res.partner.tab']
for tab in tab_model.search([]): # get all tabs
fieldname = self._get_tab_fieldname(tab)
self._add_tab_field(tab)
if fieldname in deprecated_tab_fields:
deprecated_tab_fields.remove(fieldname) # not deprecated
for fieldname in deprecated_tab_fields:
self._delete_tab_field(fieldname)
def _register_hook(self):
self._update_tab_fields()
def _create_tab_page(self, fieldname, tab):
"""Create an xml node containing the tab page to be added view."""
# pylint: disable=no-member
tab_page = etree.Element('page')
invisible = [('id', '=', False)] # Partner not created yet
if tab.partner_ids:
invisible = expression.OR([
invisible,
[('id', 'not in', tab.partner_ids.ids)]])
else:
if tab.contact_type:
invisible = expression.OR([
invisible,
[('is_company', '=', tab.contact_type != 'c')]])
if tab.partner_category_id:
invisible = expression.OR([
invisible,
[('category_id', '!=', tab.partner_category_id.id)]])
attrs = {'invisible': invisible}
tab_page.set('string', tab.name)
tab_page.set('attrs', repr(attrs))
transfer_modifiers_to_node(attrs, tab_page)
field = etree.Element(
'field',
name=fieldname,
context='{'
'"default_this_partner_id": id,'
'"default_tab_id": %d,'
'"active_test": False}' % tab.id)
tree = etree.Element('tree', editable='bottom')
# Now add fields for the editable tree view in the tab:
type_field = etree.Element(
'field',
name='type_selection_id',
widget='many2one_clickable')
type_field.set('domain', repr([('tab_id', '=', tab.id)]))
type_field.set('options', repr({'no_create': True}))
tree.append(type_field)
other_partner_field = etree.Element(
'field',
name='other_partner_id',
widget='many2one_clickable')
other_partner_field.set('options', repr({'no_create': True}))
tree.append(other_partner_field)
tree.append(etree.Element('field', name='date_start'))
tree.append(etree.Element('field', name='date_end'))
field.append(tree)
tab_page.append(field)
return tab_page
def _add_tab_pages(self, view):
"""Adds the relevant tabs to the partner's formview."""
# pylint: disable=no-member
last_page_nodes = view.xpath('//page[last()]')
if not last_page_nodes:
# Nothing to do if form contains no pages/tabs.
return []
extra_fields = []
if not view.xpath('//field[@name="id"]'):
view.append(
etree.Element('field', name='id', invisible='True'))
extra_fields.append('id')
last_page = last_page_nodes[0]
tab_model = self.env['res.partner.tab']
for tab in tab_model.search([]): # get all tabs
fieldname = self._get_tab_fieldname(tab)
self._update_tab_field(tab)
extra_fields.append(fieldname)
tab_page = self._create_tab_page(fieldname, tab)
last_page.addnext(tab_page)
last_page = tab_page # Keep ordering of tabs
return extra_fields
@api.model
def fields_view_get(
self, view_id=None, view_type='form', toolbar=False,
submenu=False):
"""Override to add relation tabs to form."""
result = super(ResPartner, self).fields_view_get(
view_id=view_id, view_type=view_type, toolbar=toolbar,
submenu=submenu)
if view_type != 'form' or self.env.context.get('check_view_ids'):
return result
view = etree.fromstring(result['arch']) # pylint: disable=no-member
extra_fields = self._add_tab_pages(view)
view_model = self.env['ir.ui.view']
result['arch'], original_fields = view_model.postprocess_and_fields(
self._name, view, result['view_id'])
for fieldname in extra_fields:
result['fields'][fieldname] = original_fields[fieldname]
return result