# -*- coding: utf-8 -*- ############################################################################## # # OpenERP, Open Source Management Solution # This module copyright (C) 2014 Therp BV (). # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # ############################################################################## from openerp import models, fields, api from openerp.tools import drop_view_if_exists from .res_partner_relation_type_selection import \ ResPartnerRelationTypeSelection from . import get_partner_type, PADDING class ResPartnerRelationAll(models.AbstractModel): _auto = False _log_access = False _name = 'res.partner.relation.all' _overlays = 'res.partner.relation' _description = 'All (non-inverse + inverse) relations between partners' _additional_view_fields = [] '''append to this list if you added fields to res_partner_relation that you need in this model and related fields are not adequate (ie for sorting) You must use the same name as in res_partner_relation. Don't overwrite this list in your declaration but append in _auto_init: def _auto_init(self, cr, context=None): self._additional_view_fields.append('my_field') return super(ResPartnerRelationAll, self)._auto_init( cr, context=context) my_field = fields... ''' this_partner_id = fields.Many2one( 'res.partner', string='Current Partner', required=True, ) other_partner_id = fields.Many2one( 'res.partner', string='Other Partner', required=True, ) type_id = fields.Many2one( 'res.partner.relation.type', string='Relation Type', required=True, ) type_selection_id = fields.Many2one( 'res.partner.relation.type.selection', string='Relation Type', required=True, ) relation_id = fields.Many2one( 'res.partner.relation', 'Relation', readonly=True, ) record_type = fields.Selection( ResPartnerRelationTypeSelection._RECORD_TYPES, 'Record Type', readonly=True, ) contact_type = fields.Selection( lambda s: s.env['res.partner.relation.type']._get_partner_types(), 'Partner Type', default=lambda self: self._get_default_contact_type() ) date_start = fields.Date('Starting date') date_end = fields.Date('Ending date') active = fields.Boolean('Active', default=True) def _auto_init(self, cr, context=None): drop_view_if_exists(cr, self._table) additional_view_fields = ','.join(self._additional_view_fields) additional_view_fields = (',' + additional_view_fields)\ if additional_view_fields else '' cr.execute( '''create or replace view %(table)s as select id * %(padding)d as id, id as relation_id, type_id, cast('a' as char(1)) as record_type, left_contact_type as contact_type, left_partner_id as this_partner_id, right_partner_id as other_partner_id, date_start, date_end, active, type_id * %(padding)d as type_selection_id %(additional_view_fields)s from %(underlying_table)s union select id * %(padding)d + 1, id, type_id, cast('b' as char(1)), right_contact_type, right_partner_id, left_partner_id, date_start, date_end, active, type_id * %(padding)d + 1 %(additional_view_fields)s from %(underlying_table)s''' % { 'table': self._table, 'padding': PADDING, 'additional_view_fields': additional_view_fields, 'underlying_table': 'res_partner_relation', } ) return super(ResPartnerRelationAll, self)._auto_init( cr, context=context) @api.one def get_underlying_object(self): """Get the record on which this record is overlaid""" return self.env[self._overlays].browse(self.id / PADDING) def _get_default_contact_type(self): partner_id = self._context.get('default_this_partner_id') if partner_id: partner = self.env['res.partner'].browse(partner_id) return get_partner_type(partner) return False @api.multi def name_get(self): return { this.id: '%s %s %s' % ( this.this_partner_id.name, this.type_selection_id.name_get()[0][1], this.other_partner_id.name, ) for this in self } @api.onchange('type_selection_id') def onchange_type_selection_id(self): """Add domain on other_partner_id according to category_other""" if not self.type_selection_id.partner_category_other: return {'domain': []} is_company = self.type_selection_id.partner_category_other == 'c' return { 'domain': { 'other_partner_id': [('is_company', '=', is_company)], } } @api.one def write(self, vals): """divert non-problematic writes to underlying table""" underlying_objs = self.get_underlying_object() vals = { key: val for key, val in vals.iteritems() if not self._columns[key].readonly } vals['type_selection_id'] = vals.get( 'type_selection_id', underlying_objs.type_selection_id.id ) return underlying_objs.write(vals) @api.model def create(self, vals): """divert non-problematic creates to underlying table Create a res.partner.relation but return the converted id """ vals = { key: val for key, val in vals.iteritems() if not self._columns[key].readonly } vals['type_selection_id'] = vals.get( 'type_selection_id', False, ) res = self.env[self._overlays].create(vals) return self.browse(res.id * PADDING) @api.one def unlink(self): """divert non-problematic creates to underlying table""" return self.get_underlying_object().unlink()