[12.0][MIG] mass_mailing_partner: Migration to v12.0

This commit is contained in:
Sergio Teruel 2018-11-09 13:24:39 +01:00 committed by emagdalenaC2i
parent a5b869b487
commit 8e47af7cbc
15 changed files with 171 additions and 29 deletions

View File

@ -14,13 +14,13 @@ Link partners with mass-mailing
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3 :alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github
:target: https://github.com/OCA/social/tree/11.0/mass_mailing_partner :target: https://github.com/OCA/social/tree/12.0/mass_mailing_partner
:alt: OCA/social :alt: OCA/social
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/social-11-0/social-11-0-mass_mailing_partner :target: https://translation.odoo-community.org/projects/social-12-0/social-12-0-mass_mailing_partner
:alt: Translate me on Weblate :alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/205/11.0 :target: https://runbot.odoo-community.org/runbot/205/12.0
:alt: Try me on Runbot :alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5| |badge1| |badge2| |badge3| |badge4| |badge5|
@ -61,7 +61,7 @@ Bug Tracker
Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/issues>`_. Bugs are tracked on `GitHub Issues <https://github.com/OCA/social/issues>`_.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/social/issues/new?body=module:%20mass_mailing_partner%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. `feedback <https://github.com/OCA/social/issues/new?body=module:%20mass_mailing_partner%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues. Do not contact contributors directly about support or help with technical issues.
@ -99,6 +99,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
This module is part of the `OCA/social <https://github.com/OCA/social/tree/11.0/mass_mailing_partner>`_ project on GitHub. This module is part of the `OCA/social <https://github.com/OCA/social/tree/12.0/mass_mailing_partner>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@ -5,7 +5,7 @@
{ {
"name": "Link partners with mass-mailing", "name": "Link partners with mass-mailing",
"version": "11.0.1.0.0", "version": "12.0.1.0.0",
"author": "Tecnativa, " "author": "Tecnativa, "
"Odoo Community Association (OCA)", "Odoo Community Association (OCA)",
"website": "https://github.com/OCA/social", "website": "https://github.com/OCA/social",

View File

@ -7,3 +7,4 @@ from . import mail_mass_mailing_contact
from . import res_partner from . import res_partner
from . import mail_mass_mailing from . import mail_mass_mailing
from . import mail_mail_statistics from . import mail_mail_statistics
from . import mail_mass_mailing_list_contact_rel

View File

@ -3,7 +3,8 @@
# Copyright 2015 Javier Iniesta <javieria@antiun.com> # Copyright 2015 Javier Iniesta <javieria@antiun.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
class MailMassMailingList(models.Model): class MailMassMailingList(models.Model):
@ -13,3 +14,18 @@ class MailMassMailingList(models.Model):
default=False) default=False)
partner_category = fields.Many2one(comodel_name='res.partner.category', partner_category = fields.Many2one(comodel_name='res.partner.category',
string="Partner Tag") string="Partner Tag")
@api.constrains('contact_ids')
def _check_contact_ids_partner_id(self):
contact_obj = self.env['mail.mass_mailing.contact']
for mailing_list in self:
data = contact_obj.read_group(
[
('id', 'in', mailing_list.contact_ids.ids),
('partner_id', '!=', False),
],
['partner_id'], ['partner_id']
)
if len(list(filter(lambda r: r['partner_id_count'] > 1, data))):
raise ValidationError(_("A partner cannot be multiple times "
"in the same list"))

View File

@ -45,6 +45,10 @@ class MailMassMailingContact(models.Model):
record._set_partner() record._set_partner()
record._onchange_partner_mass_mailing_partner() record._onchange_partner_mass_mailing_partner()
new_vals = record._convert_to_write(record._cache) new_vals = record._convert_to_write(record._cache)
new_vals.update(
subscription_list_ids=vals.get('subscription_list_ids', False),
list_ids=vals.get('list_ids', False)
)
return super(MailMassMailingContact, self).create(new_vals) return super(MailMassMailingContact, self).create(new_vals)
def write(self, vals): def write(self, vals):
@ -55,6 +59,10 @@ class MailMassMailingContact(models.Model):
record._set_partner() record._set_partner()
record._onchange_partner_mass_mailing_partner() record._onchange_partner_mass_mailing_partner()
new_vals = record._convert_to_write(record._cache) new_vals = record._convert_to_write(record._cache)
new_vals.update(
subscription_list_ids=vals.get('subscription_list_ids', False),
list_ids=vals.get('list_ids', False)
)
super(MailMassMailingContact, contact).write(new_vals) super(MailMassMailingContact, contact).write(new_vals)
return True return True
@ -92,6 +100,9 @@ class MailMassMailingContact(models.Model):
if partner: if partner:
# Partner found # Partner found
self.partner_id = partner self.partner_id = partner
elif self.list_ids.filtered('partner_mandatory'): else:
lts = self.subscription_list_ids.mapped('list_id') | self.list_ids
if lts.filtered('partner_mandatory'):
# Create partner # Create partner
self.partner_id = m_partner.sudo().create(self._prepare_partner()) partner_vals = self._prepare_partner()
self.partner_id = m_partner.sudo().create(partner_vals)

View File

@ -0,0 +1,18 @@
# Copyright 2018 Tecnativa - Ernesto Tejeda
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, models, _
from odoo.exceptions import ValidationError
class MassMailingContactListRel(models.Model):
_inherit = 'mail.mass_mailing.list_contact_rel'
@api.constrains('contact_id', 'list_id')
def _check_contact_id_partner_id_list_id(self):
for rel in self:
if rel.contact_id.partner_id:
contacts = rel.list_id.contact_ids - rel.contact_id
if rel.contact_id.partner_id in contacts.mapped('partner_id'):
raise ValidationError(_("A partner cannot be multiple "
"times in the same list"))

View File

@ -14,7 +14,6 @@ class ResPartner(models.Model):
mass_mailing_contact_ids = fields.One2many( mass_mailing_contact_ids = fields.One2many(
string="Mailing contacts", string="Mailing contacts",
oldname="mass_mailing_contacts", oldname="mass_mailing_contacts",
domain=[('opt_out', '=', False)],
comodel_name='mail.mass_mailing.contact', inverse_name='partner_id') comodel_name='mail.mass_mailing.contact', inverse_name='partner_id')
mass_mailing_contacts_count = fields.Integer( mass_mailing_contacts_count = fields.Integer(
string='Mailing contacts number', string='Mailing contacts number',
@ -36,8 +35,7 @@ class ResPartner(models.Model):
"mailing contact. Email must be assigned." "mailing contact. Email must be assigned."
) % partner.name) ) % partner.name)
@api.depends('mass_mailing_contact_ids', @api.depends('mass_mailing_contact_ids')
'mass_mailing_contact_ids.opt_out')
def _compute_mass_mailing_contacts_count(self): def _compute_mass_mailing_contacts_count(self):
contact_data = self.env['mail.mass_mailing.contact'].read_group( contact_data = self.env['mail.mass_mailing.contact'].read_group(
[('partner_id', 'in', self.ids)], ['partner_id'], ['partner_id']) [('partner_id', 'in', self.ids)], ['partner_id'], ['partner_id'])

View File

@ -367,7 +367,7 @@ ul.auto-toc {
!! This file is generated by oca-gen-addon-readme !! !! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !! !! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/social/tree/11.0/mass_mailing_partner"><img alt="OCA/social" src="https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/social-11-0/social-11-0-mass_mailing_partner"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/205/11.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> <p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/social/tree/12.0/mass_mailing_partner"><img alt="OCA/social" src="https://img.shields.io/badge/github-OCA%2Fsocial-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/social-12-0/social-12-0-mass_mailing_partner"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/205/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module links mass-mailing contacts with partners.</p> <p>This module links mass-mailing contacts with partners.</p>
<div class="section" id="features"> <div class="section" id="features">
<h1>Features</h1> <h1>Features</h1>
@ -404,7 +404,7 @@ as mailing list contacts.</p>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/social/issues">GitHub Issues</a>. <p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/social/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed If you spotted it first, help us smashing it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/social/issues/new?body=module:%20mass_mailing_partner%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> <a class="reference external" href="https://github.com/OCA/social/issues/new?body=module:%20mass_mailing_partner%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p> <p>Do not contact contributors directly about support or help with technical issues.</p>
</div> </div>
<div class="section" id="credits"> <div class="section" id="credits">
@ -442,7 +442,7 @@ If you spotted it first, help us smashing it by providing a detailed and welcome
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose <p>OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use.</p> promote its widespread use.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/social/tree/11.0/mass_mailing_partner">OCA/social</a> project on GitHub.</p> <p>This module is part of the <a class="reference external" href="https://github.com/OCA/social/tree/12.0/mass_mailing_partner">OCA/social</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> <p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div> </div>
</div> </div>

View File

@ -6,3 +6,5 @@
from . import test_mail_mass_mailing_contact, test_res_partner from . import test_mail_mass_mailing_contact, test_res_partner
from . import test_mail_mail_statistics from . import test_mail_mail_statistics
from . import test_partner_mail_list_wizard from . import test_partner_mail_list_wizard
from . import test_mail_mass_mailing_list
from . import test_mail_mass_mailing_list_contact_rel

View File

@ -13,13 +13,13 @@ class BaseCase(TransactionCase):
self.main_company = self.env.ref('base.main_company') self.main_company = self.env.ref('base.main_company')
self.country_es = self.env.ref('base.es') self.country_es = self.env.ref('base.es')
self.category_0 = self.env.ref('base.res_partner_category_0') self.category_0 = self.env.ref('base.res_partner_category_0')
self.category_1 = self.env.ref('base.res_partner_category_1') self.category_2 = self.env.ref('base.res_partner_category_2')
self.title_mister = self.env.ref('base.res_partner_title_mister') self.title_mister = self.env.ref('base.res_partner_title_mister')
self.partner = self.create_partner( self.partner = self.create_partner(
{'name': 'Partner test', 'email': 'partner@test.com', {'name': 'Partner test', 'email': 'partner@test.com',
'title': self.title_mister.id, 'company_id': self.main_company.id, 'title': self.title_mister.id, 'company_id': self.main_company.id,
'country_id': self.country_es.id, 'country_id': self.country_es.id,
'category_id': [(6, 0, (self.category_0 | self.category_1).ids)]}) 'category_id': [(6, 0, (self.category_0 | self.category_2).ids)]})
self.category_3 = self.env.ref('base.res_partner_category_3') self.category_3 = self.env.ref('base.res_partner_category_3')
self.mailing_list = self.create_mailing_list({'name': 'List test'}) self.mailing_list = self.create_mailing_list({'name': 'List test'})

View File

@ -21,13 +21,13 @@ class MailMassMailingContactCase(base.BaseCase):
def test_create_mass_mailing_contact(self): def test_create_mass_mailing_contact(self):
title_doctor = self.env.ref('base.res_partner_title_doctor') title_doctor = self.env.ref('base.res_partner_title_doctor')
country_cu = self.env.ref('base.cu') country_cu = self.env.ref('base.cu')
category_4 = self.env.ref('base.res_partner_category_4') category_8 = self.env.ref('base.res_partner_category_8')
category_5 = self.env.ref('base.res_partner_category_5') category_11 = self.env.ref('base.res_partner_category_11')
contact_vals = { contact_vals = {
'name': 'Partner test 2', 'email': 'partner2@test.com', 'name': 'Partner test 2', 'email': 'partner2@test.com',
'title_id': title_doctor.id, 'company_name': "TestCompany", 'title_id': title_doctor.id, 'company_name': "TestCompany",
'country_id': country_cu.id, 'country_id': country_cu.id,
'tag_ids': [(6, 0, (category_4 | category_5).ids)], 'tag_ids': [(6, 0, (category_8 | category_11).ids)],
'list_ids': [(6, 0, (self.mailing_list | self.mailing_list2).ids)], 'list_ids': [(6, 0, (self.mailing_list | self.mailing_list2).ids)],
} }
contact = self.create_mailing_contact(contact_vals) contact = self.create_mailing_contact(contact_vals)
@ -37,6 +37,31 @@ class MailMassMailingContactCase(base.BaseCase):
{'email': 'partner2@test.com', {'email': 'partner2@test.com',
'list_ids': [[6, 0, [self.mailing_list2.id]]]}) 'list_ids': [[6, 0, [self.mailing_list2.id]]]})
def test_create_mass_mailing_contact_with_subscription(self):
title_doctor = self.env.ref('base.res_partner_title_doctor')
country_cu = self.env.ref('base.cu')
category_8 = self.env.ref('base.res_partner_category_8')
category_11 = self.env.ref('base.res_partner_category_11')
contact_vals = {
'name': 'Partner test 2', 'email': 'partner2@test.com',
'title_id': title_doctor.id, 'company_name': "TestCompany",
'country_id': country_cu.id,
'tag_ids': [(6, 0, (category_8 | category_11).ids)],
'subscription_list_ids': [
(0, 0, {'list_id': self.mailing_list.id}),
(0, 0, {'list_id': self.mailing_list2.id}),
],
}
contact = self.create_mailing_contact(contact_vals)
self.check_mailing_contact_partner(contact)
with self.assertRaises(ValidationError):
self.create_mailing_contact({
'email': 'partner2@test.com',
'subscription_list_ids': [
(0, 0, {'list_id': self.mailing_list2.id}),
],
})
def test_write_mass_mailing_contact(self): def test_write_mass_mailing_contact(self):
contact = self.create_mailing_contact( contact = self.create_mailing_contact(
{'email': 'partner@test.com', {'email': 'partner@test.com',
@ -55,13 +80,13 @@ class MailMassMailingContactCase(base.BaseCase):
'list_ids': [[6, 0, [self.mailing_list.id]]]}) 'list_ids': [[6, 0, [self.mailing_list.id]]]})
title_doctor = self.env.ref('base.res_partner_title_doctor') title_doctor = self.env.ref('base.res_partner_title_doctor')
country_cu = self.env.ref('base.cu') country_cu = self.env.ref('base.cu')
category_4 = self.env.ref('base.res_partner_category_4') category_8 = self.env.ref('base.res_partner_category_8')
category_5 = self.env.ref('base.res_partner_category_5') category_11 = self.env.ref('base.res_partner_category_11')
partner_vals = { partner_vals = {
'name': 'Partner test 2', 'email': 'partner2@test.com', 'name': 'Partner test 2', 'email': 'partner2@test.com',
'title': title_doctor.id, 'company_id': self.main_company.id, 'title': title_doctor.id, 'company_id': self.main_company.id,
'country_id': country_cu.id, 'country_id': country_cu.id,
'category_id': [(6, 0, (category_4 | category_5).ids)], 'category_id': [(6, 0, (category_8 | category_11).ids)],
} }
partner = self.create_partner(partner_vals) partner = self.create_partner(partner_vals)
with self.env.do_in_onchange(): with self.env.do_in_onchange():

View File

@ -0,0 +1,41 @@
# Copyright 2018 Tecnativa - Ernesto tejeda
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import base
from odoo.exceptions import ValidationError
class MailMassMailingListCase(base.BaseCase):
def test_create_mass_mailing_list(self):
contact_test_1 = self.create_mailing_contact({
'name': 'Contact test 1',
'partner_id': self.partner.id,
})
contact_test_2 = self.create_mailing_contact({
'name': 'Contact test 2',
'partner_id': self.partner.id,
})
with self.assertRaises(ValidationError):
self.create_mailing_list({
'name': 'List test 3',
'contact_ids': [(6, 0, (contact_test_1 | contact_test_2).ids)]
})
def test_create_mass_mailing_list_with_subscription(self):
contact_test_1 = self.create_mailing_contact({
'name': 'Contact test 1',
'partner_id': self.partner.id,
})
contact_test_2 = self.create_mailing_contact({
'name': 'Contact test 2',
'partner_id': self.partner.id,
})
with self.assertRaises(ValidationError):
self.create_mailing_list({
'name': 'List test 3',
'subscription_contact_ids': [
(0, 0, {'contact_id': contact_test_1.id}),
(0, 0, {'contact_id': contact_test_2.id}),
]
})

View File

@ -0,0 +1,30 @@
# Copyright 2018 Tecnativa - Ernesto tejeda
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import base
from odoo.exceptions import ValidationError
class MailMassMailingListContactRelCase(base.BaseCase):
def test_create_mass_mailing_list(self):
contact_test_1 = self.create_mailing_contact({
'name': 'Contact test 1',
'partner_id': self.partner.id,
})
contact_test_2 = self.create_mailing_contact({
'name': 'Contact test 2',
'partner_id': self.partner.id,
})
list_3 = self.create_mailing_list({'name': 'List test 3'})
self.env['mail.mass_mailing.list_contact_rel'].create({
'list_id': list_3.id,
'contact_id': contact_test_1.id,
})
with self.assertRaises(ValidationError):
self.env['mail.mass_mailing.list_contact_rel'].create({
'list_id': list_3.id,
'contact_id': contact_test_2.id,
})

View File

@ -26,13 +26,13 @@ class ResPartnerCase(base.BaseCase):
title_doctor = self.env.ref('base.res_partner_title_doctor') title_doctor = self.env.ref('base.res_partner_title_doctor')
country_cu = self.env.ref('base.cu') country_cu = self.env.ref('base.cu')
category_4 = self.env.ref('base.res_partner_category_4') category_8 = self.env.ref('base.res_partner_category_8')
category_5 = self.env.ref('base.res_partner_category_5') category_11 = self.env.ref('base.res_partner_category_11')
self.partner.write({ self.partner.write({
'name': 'Changed', 'email': 'partner@changed.com', 'name': 'Changed', 'email': 'partner@changed.com',
'title': title_doctor.id, 'company_id': self.main_company.id, 'title': title_doctor.id, 'company_id': self.main_company.id,
'country_id': country_cu.id, 'country_id': country_cu.id,
'category_id': [(6, 0, (category_4 | category_5).ids)], 'category_id': [(6, 0, (category_8 | category_11).ids)],
}) })
self.check_mailing_contact_partner(contact) self.check_mailing_contact_partner(contact)
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):

View File

@ -22,9 +22,9 @@
<field name="model">mail.mass_mailing.contact</field> <field name="model">mail.mass_mailing.contact</field>
<field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_form"/> <field name="inherit_id" ref="mass_mailing.view_mail_mass_mailing_contact_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="email" position="after"> <xpath expr="//field[@name='email']/.." position="after">
<field name="partner_id"/> <field name="partner_id"/>
</field> </xpath>
<field name="title_id" position="attributes"> <field name="title_id" position="attributes">
<attribute name="attrs">{'readonly': [('partner_id', '!=', False)]}</attribute> <attribute name="attrs">{'readonly': [('partner_id', '!=', False)]}</attribute>
</field> </field>