# Copyright 2013-2017 Therp BV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). """ For the model defined here _auto is set to False to prevent creating a database file. The model is based on a SQL view based on res_partner_relation_type where each type is included in the result set twice, so it appears that the connection type and the inverse type are separate records.. The original function _auto_init is still called because this function normally (if _auto == True) not only creates the db tables, but it also takes care of registering all fields in ir_model_fields. This is needed to make the field labels translatable. """ from psycopg2.extensions import AsIs from odoo import api, fields, models from odoo.tools import drop_view_if_exists class ResPartnerRelationTypeSelection(models.Model): """Virtual relation types""" _name = 'res.partner.relation.type.selection' _description = 'All relation types' _auto = False # Do not try to create table in _auto_init(..) _foreign_keys = [] _log_access = False _order = 'name asc' @api.model def get_partner_types(self): """Partner types are defined by model res.partner.relation.type.""" # pylint: disable=no-self-use rprt_model = self.env['res.partner.relation.type'] return rprt_model.get_partner_types() type_id = fields.Many2one( comodel_name='res.partner.relation.type', string='Type', ) name = fields.Char('Name') contact_type_this = fields.Selection( selection='get_partner_types', string='Current record\'s partner type', ) is_inverse = fields.Boolean( string="Is reverse type?", help="Inverse relations are from right to left partner.", ) contact_type_other = fields.Selection( selection='get_partner_types', string='Other record\'s partner type', ) partner_category_this = fields.Many2one( comodel_name='res.partner.category', string='Current record\'s category', ) partner_category_other = fields.Many2one( comodel_name='res.partner.category', string='Other record\'s category', ) allow_self = fields.Boolean( string='Reflexive', ) is_symmetric = fields.Boolean( string='Symmetric', ) def _get_additional_view_fields(self): """Allow inherit models to add fields to view. If fields are added, the resulting string must have each field prepended by a comma, like so: return ', typ.allow_self, typ.left_partner_category' """ return '' def _get_additional_tables(self): """Allow inherit models to add tables (JOIN's) to view. Example: return 'JOIN type_extention ext ON (bas.type_id = ext.id)' """ return '' @api.model_cr_context def _auto_init(self): cr = self._cr drop_view_if_exists(cr, self._table) cr.execute( """\ CREATE OR REPLACE VIEW %(table)s AS WITH selection_type AS ( SELECT id * 2 AS id, id AS type_id, name AS name, False AS is_inverse, contact_type_left AS contact_type_this, contact_type_right AS contact_type_other, partner_category_left AS partner_category_this, partner_category_right AS partner_category_other FROM %(underlying_table)s UNION SELECT (id * 2) + 1, id, name_inverse, True, contact_type_right, contact_type_left, partner_category_right, partner_category_left FROM %(underlying_table)s WHERE not is_symmetric ) SELECT bas.*, typ.allow_self, typ.is_symmetric %(additional_view_fields)s FROM selection_type bas JOIN res_partner_relation_type typ ON (bas.type_id = typ.id) %(additional_tables)s """, {'table': AsIs(self._table), 'underlying_table': AsIs('res_partner_relation_type'), 'additional_view_fields': AsIs(self._get_additional_view_fields()), 'additional_tables': AsIs(self._get_additional_tables())}) return super(ResPartnerRelationTypeSelection, self)._auto_init() @api.multi def name_get(self): """Get name or name_inverse from underlying model.""" return [ (this.id, this.is_inverse and this.type_id.name_inverse or this.type_id.display_name) for this in self] @api.model def name_search(self, name='', args=None, operator='ilike', limit=100): """Search for name or inverse name in underlying model.""" # pylint: disable=no-value-for-parameter return self.search( ['|', ('type_id.name', operator, name), ('type_id.name_inverse', operator, name)] + (args or []), limit=limit).name_get()