[MIG] base_partner_one2many_phone v14 -> v16
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
from . import partner_phone
|
||||
from . import models
|
||||
from .post_install import migrate_to_partner_phone
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# Copyright 2014-2020 Abbaye du Barroux (http://www.barroux.org)
|
||||
# Copyright 2014-2020 Akretion (http://www.akretion.com>)
|
||||
# Copyright 2014-2023 Abbaye du Barroux (http://www.barroux.org)
|
||||
# Copyright 2014-2023 Akretion (http://www.akretion.com>)
|
||||
# @author: Frère Bernard <informatique@barroux.org>
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
{
|
||||
'name': 'Base Partner One2many Phone',
|
||||
'version': '14.0.1.0.0',
|
||||
'version': '16.0.1.0.0',
|
||||
'category': 'Phone',
|
||||
'license': 'AGPL-3',
|
||||
'summary': 'One2many link between partners and phone numbers/emails',
|
||||
@@ -19,13 +19,14 @@ With this module, one partner can have several phone numbers and several emails.
|
||||
It has been developped by brother Bernard from Barroux Abbey and Alexis de Lattre from Akretion.
|
||||
""",
|
||||
'author': 'Akretion',
|
||||
'website': 'https://akretion.com/',
|
||||
'website': 'https://github.com/akretion/odoo-usability',
|
||||
'depends': ['contacts', 'base_usability', 'phone_validation'],
|
||||
'excludes': ['sms'], # because sms introduces big changes in partner form view
|
||||
'data': [
|
||||
'partner_phone_view.xml',
|
||||
'views/res_partner_phone.xml',
|
||||
'views/res_partner.xml',
|
||||
'security/ir.model.access.csv',
|
||||
],
|
||||
'installable': False,
|
||||
'installable': True,
|
||||
'post_init_hook': 'migrate_to_partner_phone',
|
||||
}
|
||||
|
||||
2
base_partner_one2many_phone/models/__init__.py
Normal file
2
base_partner_one2many_phone/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import res_partner_phone
|
||||
from . import res_partner
|
||||
94
base_partner_one2many_phone/models/res_partner.py
Normal file
94
base_partner_one2many_phone/models/res_partner.py
Normal file
@@ -0,0 +1,94 @@
|
||||
# Copyright 2014-2023 Abbaye du Barroux (http://www.barroux.org)
|
||||
# Copyright 2016-2023 Akretion (http://www.akretion.com>)
|
||||
# @author: Frère Bernard <informatique@barroux.org>
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models, Command
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
# in v10, we are supposed to have in DB E.164 format
|
||||
# with the current implementation, we have:
|
||||
# in res.partner : PhoneNumberFormat.INTERNATIONAL
|
||||
# in res.partner.phone : E.164
|
||||
# It is not good, but it is not a big bug and it's complex to fix
|
||||
# so let's let it like that. In v12, we store in
|
||||
# PhoneNumberFormat.INTERNATIONAL, so this bug is kind of an anticipation
|
||||
# for the future :)
|
||||
|
||||
phone_ids = fields.One2many(
|
||||
'res.partner.phone', 'partner_id', string='Phones/Emails')
|
||||
phone = fields.Char(compute='_compute_partner_phone', store=True)
|
||||
mobile = fields.Char(compute='_compute_partner_phone', store=True)
|
||||
email = fields.Char(compute='_compute_partner_phone', store=True)
|
||||
|
||||
@api.depends('phone_ids.phone', 'phone_ids.type', 'phone_ids.email')
|
||||
def _compute_partner_phone(self):
|
||||
for partner in self:
|
||||
phone = mobile = email = False
|
||||
for pphone in partner.phone_ids:
|
||||
if pphone.type == '1_email_primary' and pphone.email:
|
||||
email = pphone.email
|
||||
elif pphone.phone:
|
||||
if pphone.type == '5_mobile_primary':
|
||||
mobile = pphone.phone
|
||||
elif pphone.type == '3_phone_primary':
|
||||
phone = pphone.phone
|
||||
partner.phone = phone
|
||||
partner.mobile = mobile
|
||||
partner.email = email
|
||||
|
||||
def _update_create_vals(
|
||||
self, vals, type, partner_field, partner_phone_field):
|
||||
if vals.get(partner_field):
|
||||
vals['phone_ids'].append(
|
||||
Command.create({'type': type, partner_phone_field: vals[partner_field]}))
|
||||
if partner_field in vals:
|
||||
vals.pop(partner_field)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
for vals in vals_list:
|
||||
if 'phone_ids' not in vals:
|
||||
vals['phone_ids'] = []
|
||||
self._update_create_vals(vals, '1_email_primary', 'email', 'email')
|
||||
self._update_create_vals(vals, '3_phone_primary', 'phone', 'phone')
|
||||
self._update_create_vals(vals, '5_mobile_primary', 'mobile', 'phone')
|
||||
return super().create(vals_list)
|
||||
|
||||
def _update_write_vals(
|
||||
self, vals, type, partner_field, partner_phone_field):
|
||||
self.ensure_one()
|
||||
rppo = self.env['res.partner.phone']
|
||||
if partner_field in vals:
|
||||
pphone = rppo.search([
|
||||
('partner_id', '=', self.id),
|
||||
('type', '=', type)], limit=1)
|
||||
if vals[partner_field]:
|
||||
if pphone:
|
||||
vals['phone_ids'].append(Command.update(pphone.id, {
|
||||
partner_phone_field: vals[partner_field]}))
|
||||
else:
|
||||
vals['phone_ids'].append(Command.create({
|
||||
'type': type,
|
||||
partner_phone_field: vals[partner_field],
|
||||
}))
|
||||
else:
|
||||
if pphone:
|
||||
vals['phone_ids'].append(Command.delete(pphone.id))
|
||||
vals.pop(partner_field)
|
||||
|
||||
def write(self, vals):
|
||||
if 'phone_ids' not in vals:
|
||||
for rec in self:
|
||||
cvals = dict(vals, phone_ids=[])
|
||||
rec._update_write_vals(cvals, '1_email_primary', 'email', 'email')
|
||||
rec._update_write_vals(cvals, '3_phone_primary', 'phone', 'phone')
|
||||
rec._update_write_vals(cvals, '5_mobile_primary', 'mobile', 'phone')
|
||||
super(ResPartner, rec).write(cvals)
|
||||
return True
|
||||
else:
|
||||
return super().write(vals)
|
||||
108
base_partner_one2many_phone/models/res_partner_phone.py
Normal file
108
base_partner_one2many_phone/models/res_partner_phone.py
Normal file
@@ -0,0 +1,108 @@
|
||||
# Copyright 2014-2023 Abbaye du Barroux (http://www.barroux.org)
|
||||
# Copyright 2016-2023 Akretion (http://www.akretion.com>)
|
||||
# @author: Frère Bernard <informatique@barroux.org>
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.phone_validation.tools import phone_validation
|
||||
|
||||
EMAIL_TYPES = ('1_email_primary', '2_email_secondary')
|
||||
PHONE_TYPES = ('3_phone_primary', '4_phone_secondary', '5_mobile_primary', '6_mobile_secondary', '7_fax_primary', '8_fax_secondary')
|
||||
|
||||
|
||||
class ResPartnerPhone(models.Model):
|
||||
_name = 'res.partner.phone'
|
||||
_order = 'partner_id, type'
|
||||
_phone_name_sequence = 8
|
||||
_description = 'Multiple emails and phones for partners'
|
||||
|
||||
partner_id = fields.Many2one(
|
||||
'res.partner', string='Related Partner', index=True, ondelete='cascade')
|
||||
type = fields.Selection([
|
||||
('1_email_primary', 'Primary E-mail'),
|
||||
('2_email_secondary', 'Secondary E-mail'),
|
||||
('3_phone_primary', 'Primary Phone'),
|
||||
('4_phone_secondary', 'Secondary Phone'),
|
||||
('5_mobile_primary', 'Primary Mobile'),
|
||||
('6_mobile_secondary', 'Secondary Mobile'),
|
||||
('7_fax_primary', 'Primary Fax'),
|
||||
('8_fax_secondary', 'Secondary Fax'),
|
||||
],
|
||||
string='Type', required=True, index=True)
|
||||
phone = fields.Char(string='Phone')
|
||||
email = fields.Char(string='E-Mail')
|
||||
note = fields.Char('Note')
|
||||
|
||||
@api.onchange('type')
|
||||
def type_change(self):
|
||||
if self.type:
|
||||
if self.type in EMAIL_TYPES:
|
||||
self.phone = False
|
||||
elif self.type in PHONE_TYPES:
|
||||
self.email = False
|
||||
|
||||
@api.onchange('phone', 'partner_id')
|
||||
def _onchange_phone_validation(self):
|
||||
if self.phone:
|
||||
country = self.partner_id.country_id
|
||||
self.phone = phone_validation.phone_format(
|
||||
self.phone,
|
||||
country.code or None,
|
||||
country.phone_code or None,
|
||||
force_format='INTERNATIONAL',
|
||||
raise_exception=False)
|
||||
|
||||
@api.constrains('type', 'phone', 'email')
|
||||
def _check_partner_phone(self):
|
||||
for rec in self:
|
||||
if rec.type in EMAIL_TYPES:
|
||||
if not rec.email:
|
||||
raise ValidationError(_(
|
||||
"E-mail field must have a value when type is Primary E-mail or Secondary E-mail."))
|
||||
if rec.phone:
|
||||
raise ValidationError(_(
|
||||
"Phone field must be empty when type is Primary E-mail or Secondary E-mail."))
|
||||
elif rec.type in PHONE_TYPES:
|
||||
if not rec.phone:
|
||||
raise ValidationError(_(
|
||||
"Phone field must have a value when type is Primary/Secondary Phone, Primary/Secondary Mobile or Primary/Secondary Fax."))
|
||||
if rec.email:
|
||||
raise ValidationError(_(
|
||||
"E-mail field must be empty when type is Primary/Secondary Phone, Primary/Secondary Mobile or Primary/Secondary Fax."))
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
for pphone in self:
|
||||
if pphone.partner_id:
|
||||
if self._context.get('callerid'):
|
||||
name = pphone.partner_id.display_name
|
||||
else:
|
||||
name = u'%s (%s)' % (pphone.phone, pphone.partner_id.name)
|
||||
else:
|
||||
name = pphone.phone
|
||||
res.append((pphone.id, name))
|
||||
return res
|
||||
|
||||
def init(self):
|
||||
self._cr.execute('''
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS single_email_primary
|
||||
ON res_partner_phone (partner_id, type)
|
||||
WHERE (type='1_email_primary')
|
||||
''')
|
||||
self._cr.execute('''
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS single_phone_primary
|
||||
ON res_partner_phone (partner_id, type)
|
||||
WHERE (type='3_phone_primary')
|
||||
''')
|
||||
self._cr.execute('''
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS single_mobile_primary
|
||||
ON res_partner_phone (partner_id, type)
|
||||
WHERE (type='5_mobile_primary')
|
||||
''')
|
||||
self._cr.execute('''
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS single_fax_primary
|
||||
ON res_partner_phone (partner_id, type)
|
||||
WHERE (type='7_fax_primary')
|
||||
''')
|
||||
@@ -1,193 +0,0 @@
|
||||
# Copyright 2014-2020 Abbaye du Barroux (http://www.barroux.org)
|
||||
# Copyright 2016-2020 Akretion (http://www.akretion.com>)
|
||||
# @author: Frère Bernard <informatique@barroux.org>
|
||||
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
EMAIL_TYPES = ('1_email_primary', '2_email_secondary')
|
||||
PHONE_TYPES = ('3_phone_primary', '4_phone_secondary', '5_mobile_primary', '6_mobile_secondary', '7_fax_primary', '8_fax_secondary')
|
||||
|
||||
|
||||
class ResPartnerPhone(models.Model):
|
||||
_name = 'res.partner.phone'
|
||||
_order = 'partner_id, type'
|
||||
_phone_name_sequence = 8
|
||||
_inherit = ['phone.validation.mixin']
|
||||
_description = 'Multiple emails and phones for partners'
|
||||
|
||||
partner_id = fields.Many2one(
|
||||
'res.partner', string='Related Partner', index=True, ondelete='cascade')
|
||||
type = fields.Selection([
|
||||
('1_email_primary', 'Primary E-mail'),
|
||||
('2_email_secondary', 'Secondary E-mail'),
|
||||
('3_phone_primary', 'Primary Phone'),
|
||||
('4_phone_secondary', 'Secondary Phone'),
|
||||
('5_mobile_primary', 'Primary Mobile'),
|
||||
('6_mobile_secondary', 'Secondary Mobile'),
|
||||
('7_fax_primary', 'Primary Fax'),
|
||||
('8_fax_secondary', 'Secondary Fax'),
|
||||
],
|
||||
string='Type', required=True, index=True)
|
||||
phone = fields.Char(string='Phone')
|
||||
email = fields.Char(string='E-Mail')
|
||||
note = fields.Char('Note')
|
||||
|
||||
@api.onchange('type')
|
||||
def type_change(self):
|
||||
if self.type:
|
||||
if self.type in EMAIL_TYPES:
|
||||
self.phone = False
|
||||
elif self.type in PHONE_TYPES:
|
||||
self.email = False
|
||||
|
||||
@api.onchange('phone', 'partner_id')
|
||||
def _onchange_phone_validation(self):
|
||||
if self.phone:
|
||||
self.phone = self.phone_format(self.phone, country=self.partner_id.country_id)
|
||||
|
||||
@api.constrains('type', 'phone', 'email')
|
||||
def _check_partner_phone(self):
|
||||
for rec in self:
|
||||
if rec.type in EMAIL_TYPES:
|
||||
if not rec.email:
|
||||
raise ValidationError(_(
|
||||
"E-mail field must have a value when type is Primary E-mail or Secondary E-mail."))
|
||||
if rec.phone:
|
||||
raise ValidationError(_(
|
||||
"Phone field must be empty when type is Primary E-mail or Secondary E-mail."))
|
||||
elif rec.type in PHONE_TYPES:
|
||||
if not rec.phone:
|
||||
raise ValidationError(_(
|
||||
"Phone field must have a value when type is Primary/Secondary Phone, Primary/Secondary Mobile or Primary/Secondary Fax."))
|
||||
if rec.email:
|
||||
raise ValidationError(_(
|
||||
"E-mail field must be empty when type is Primary/Secondary Phone, Primary/Secondary Mobile or Primary/Secondary Fax."))
|
||||
|
||||
def name_get(self):
|
||||
res = []
|
||||
for pphone in self:
|
||||
if pphone.partner_id:
|
||||
if self._context.get('callerid'):
|
||||
name = pphone.partner_id.display_name
|
||||
else:
|
||||
name = u'%s (%s)' % (pphone.phone, pphone.partner_id.name)
|
||||
else:
|
||||
name = pphone.phone
|
||||
res.append((pphone.id, name))
|
||||
return res
|
||||
|
||||
def init(self):
|
||||
self._cr.execute('''
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS single_email_primary
|
||||
ON res_partner_phone (partner_id, type)
|
||||
WHERE (type='1_email_primary')
|
||||
''')
|
||||
self._cr.execute('''
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS single_phone_primary
|
||||
ON res_partner_phone (partner_id, type)
|
||||
WHERE (type='3_phone_primary')
|
||||
''')
|
||||
self._cr.execute('''
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS single_mobile_primary
|
||||
ON res_partner_phone (partner_id, type)
|
||||
WHERE (type='5_mobile_primary')
|
||||
''')
|
||||
self._cr.execute('''
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS single_fax_primary
|
||||
ON res_partner_phone (partner_id, type)
|
||||
WHERE (type='7_fax_primary')
|
||||
''')
|
||||
|
||||
|
||||
class ResPartner(models.Model):
|
||||
_inherit = 'res.partner'
|
||||
|
||||
# in v10, we are supposed to have in DB E.164 format
|
||||
# with the current implementation, we have:
|
||||
# in res.partner : PhoneNumberFormat.INTERNATIONAL
|
||||
# in res.partner.phone : E.164
|
||||
# It is not good, but it is not a big bug and it's complex to fix
|
||||
# so let's let it like that. In v12, we store in
|
||||
# PhoneNumberFormat.INTERNATIONAL, so this bug is kind of an anticipation
|
||||
# for the future :)
|
||||
|
||||
phone_ids = fields.One2many(
|
||||
'res.partner.phone', 'partner_id', string='Phones/Emails')
|
||||
phone = fields.Char(
|
||||
compute='_compute_partner_phone',
|
||||
store=True, readonly=True, compute_sudo=True)
|
||||
mobile = fields.Char(
|
||||
compute='_compute_partner_phone',
|
||||
store=True, readonly=True, compute_sudo=True)
|
||||
email = fields.Char(
|
||||
compute='_compute_partner_phone',
|
||||
store=True, readonly=True, compute_sudo=True)
|
||||
|
||||
@api.depends('phone_ids.phone', 'phone_ids.type', 'phone_ids.email')
|
||||
def _compute_partner_phone(self):
|
||||
for partner in self:
|
||||
phone = mobile = email = False
|
||||
for pphone in partner.phone_ids:
|
||||
if pphone.type == '1_email_primary' and pphone.email:
|
||||
email = pphone.email
|
||||
elif pphone.phone:
|
||||
if pphone.type == '5_mobile_primary':
|
||||
mobile = pphone.phone
|
||||
elif pphone.type == '3_phone_primary':
|
||||
phone = pphone.phone
|
||||
partner.phone = phone
|
||||
partner.mobile = mobile
|
||||
partner.email = email
|
||||
|
||||
def _update_create_vals(
|
||||
self, vals, type, partner_field, partner_phone_field):
|
||||
if vals.get(partner_field):
|
||||
vals['phone_ids'].append(
|
||||
(0, 0, {'type': type, partner_phone_field: vals[partner_field]}))
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if 'phone_ids' not in vals:
|
||||
vals['phone_ids'] = []
|
||||
self._update_create_vals(vals, '1_email_primary', 'email', 'email')
|
||||
self._update_create_vals(vals, '3_phone_primary', 'phone', 'phone')
|
||||
self._update_create_vals(vals, '5_mobile_primary', 'mobile', 'phone')
|
||||
# self._update_create_vals(vals, '7_fax_primary', 'fax', 'phone')
|
||||
return super().create(vals)
|
||||
|
||||
def _update_write_vals(
|
||||
self, vals, type, partner_field, partner_phone_field):
|
||||
self.ensure_one()
|
||||
rppo = self.env['res.partner.phone']
|
||||
if partner_field in vals:
|
||||
pphone = rppo.search([
|
||||
('partner_id', '=', self.id),
|
||||
('type', '=', type)], limit=1)
|
||||
if vals[partner_field]:
|
||||
if pphone:
|
||||
vals['phone_ids'].append((1, pphone.id, {
|
||||
partner_phone_field: vals[partner_field]}))
|
||||
else:
|
||||
vals['phone_ids'].append((0, 0, {
|
||||
'type': type,
|
||||
partner_phone_field: vals[partner_field],
|
||||
}))
|
||||
else:
|
||||
if pphone:
|
||||
vals['phone_ids'].append((2, pphone.id))
|
||||
|
||||
def write(self, vals):
|
||||
if 'phone_ids' not in vals:
|
||||
for rec in self:
|
||||
vals['phone_ids'] = []
|
||||
rec._update_write_vals(vals, '1_email_primary', 'email', 'email')
|
||||
rec._update_write_vals(vals, '3_phone_primary', 'phone', 'phone')
|
||||
rec._update_write_vals(vals, '5_mobile_primary', 'mobile', 'phone')
|
||||
rec._update_write_vals(vals, '7_fax_primary', 'fax', 'phone')
|
||||
super(ResPartner, rec).write(vals)
|
||||
return True
|
||||
else:
|
||||
return super().write(vals)
|
||||
@@ -1,4 +1,4 @@
|
||||
# Copyright 2017-2020 Akretion France (http://www.akretion.com/)
|
||||
# Copyright 2017-2023 Akretion France (http://www.akretion.com/)
|
||||
# @author Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
@@ -36,7 +36,6 @@ def create_partner_email(cr):
|
||||
|
||||
def migrate_to_partner_phone(cr, registry):
|
||||
logger.info('start data migration for one2many_phone')
|
||||
with api.Environment.manage():
|
||||
env = api.Environment(cr, SUPERUSER_ID, {})
|
||||
rppo = env['res.partner.phone']
|
||||
to_create = []
|
||||
@@ -46,4 +45,3 @@ def migrate_to_partner_phone(cr, registry):
|
||||
# I need to create all at the end for invalidation purposes
|
||||
rppo.create(to_create)
|
||||
logger.info('end data migration for one2many_phone')
|
||||
return
|
||||
|
||||
@@ -8,8 +8,9 @@ from odoo.tests.common import TransactionCase
|
||||
|
||||
class TestPartnerPhone(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPartnerPhone, self).setUp()
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
def _check_result(self, partner, result):
|
||||
rppo = self.env['res.partner.phone']
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2014-2020 Abbaye du Barroux (http://www.barroux.org)
|
||||
Copyright 2016-2020 Akretion (http://www.akretion.com>)
|
||||
Copyright 2014-2023 Abbaye du Barroux (http://www.barroux.org)
|
||||
Copyright 2016-2023 Akretion (http://www.akretion.com>)
|
||||
@author: Frère Bernard <informatique@barroux.org>
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
@@ -9,65 +9,6 @@
|
||||
|
||||
<odoo>
|
||||
|
||||
<!-- Partner phones -->
|
||||
<record id="res_partner_phone_tree" model="ir.ui.view">
|
||||
<field name="name">res.partner.phone.tree</field>
|
||||
<field name="model">res.partner.phone</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom">
|
||||
<field name="partner_id" invisible="not context.get('partner_phone_main_view')"/>
|
||||
<field name="type"/>
|
||||
<field name="phone" widget="phone" options="{'enable_sms': false}" attrs="{'required': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'readonly': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
|
||||
<field name="email" widget="email" attrs="{'readonly': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'required': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
|
||||
<field name="note"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_phone_form" model="ir.ui.view">
|
||||
<field name="name">res.partner.phone.form</field>
|
||||
<field name="model">res.partner.phone</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group name="main">
|
||||
<field name="partner_id" invisible="not context.get('partner_phone_main_view')"/>
|
||||
<field name="type"/>
|
||||
<field name="phone" widget="phone" options="{'enable_sms': false}" attrs="{'required': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'invisible': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
|
||||
<field name="email" widget="email" attrs="{'invisible': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'required': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
|
||||
<field name="note"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_phone_search" model="ir.ui.view">
|
||||
<field name="name">res.partner.phone.search</field>
|
||||
<field name="model">res.partner.phone</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="phone" />
|
||||
<field name="email" />
|
||||
<group name="groupby">
|
||||
<filter name="type_groupby" string="Type" context="{'group_by': 'type'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_phone_action" model="ir.actions.act_window">
|
||||
<field name="name">Phones/E-mails</field>
|
||||
<field name="res_model">res.partner.phone</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="context">{'partner_phone_main_view': True}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="res_partner_phone_menu" action="res_partner_phone_action"
|
||||
parent="contacts.menu_contacts" sequence="10"/>
|
||||
|
||||
<record id="contacts.res_partner_menu_config" model="ir.ui.menu">
|
||||
<field name="sequence">20</field>
|
||||
</record>
|
||||
|
||||
<!-- PARTNER views -->
|
||||
<record id="view_partner_form" model="ir.ui.view">
|
||||
<field name="name">add.phone_ids.on.partner.form</field>
|
||||
@@ -159,7 +100,7 @@
|
||||
<field name="inherit_id" ref="base_usability.view_res_partner_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="name" position="attributes">
|
||||
<attribute name="filter_domain">['|', '|', ('display_name', 'ilike', self), ('ref', '=ilike', self + '%'), ('phone_ids.email', 'ilike', self)]</attribute>
|
||||
<attribute name="filter_domain">['|', '|', '|', '|', ('display_name', 'ilike', self), ('ref', '=ilike', self + '%'), ('phone_ids.email', 'ilike', self), ('vat', 'ilike', self), ('company_registry', 'ilike', self)]</attribute>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
71
base_partner_one2many_phone/views/res_partner_phone.xml
Normal file
71
base_partner_one2many_phone/views/res_partner_phone.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2014-2020 Abbaye du Barroux (http://www.barroux.org)
|
||||
Copyright 2016-2020 Akretion (http://www.akretion.com>)
|
||||
@author: Frère Bernard <informatique@barroux.org>
|
||||
@author: Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
-->
|
||||
|
||||
<odoo>
|
||||
|
||||
<!-- Partner phones -->
|
||||
<record id="res_partner_phone_tree" model="ir.ui.view">
|
||||
<field name="name">res.partner.phone.tree</field>
|
||||
<field name="model">res.partner.phone</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom">
|
||||
<field name="partner_id" invisible="not context.get('partner_phone_main_view')"/>
|
||||
<field name="type"/>
|
||||
<field name="phone" widget="phone" options="{'enable_sms': false}" attrs="{'required': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'readonly': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
|
||||
<field name="email" widget="email" attrs="{'readonly': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'required': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
|
||||
<field name="note"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_phone_form" model="ir.ui.view">
|
||||
<field name="name">res.partner.phone.form</field>
|
||||
<field name="model">res.partner.phone</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group name="main">
|
||||
<field name="partner_id" invisible="not context.get('partner_phone_main_view')"/>
|
||||
<field name="type"/>
|
||||
<field name="phone" widget="phone" options="{'enable_sms': false}" attrs="{'required': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'invisible': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
|
||||
<field name="email" widget="email" attrs="{'invisible': [('type', 'not in', ('1_email_primary', '2_email_secondary'))], 'required': [('type', 'in', ('1_email_primary', '2_email_secondary'))]}"/>
|
||||
<field name="note"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_phone_search" model="ir.ui.view">
|
||||
<field name="name">res.partner.phone.search</field>
|
||||
<field name="model">res.partner.phone</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="phone" />
|
||||
<field name="email" />
|
||||
<group name="groupby">
|
||||
<filter name="type_groupby" string="Type" context="{'group_by': 'type'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_phone_action" model="ir.actions.act_window">
|
||||
<field name="name">Phones/E-mails</field>
|
||||
<field name="res_model">res.partner.phone</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="context">{'partner_phone_main_view': True}</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="res_partner_phone_menu" action="res_partner_phone_action"
|
||||
parent="contacts.menu_contacts" sequence="10"/>
|
||||
|
||||
<record id="contacts.res_partner_menu_config" model="ir.ui.menu">
|
||||
<field name="sequence">20</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user