mirror of https://github.com/OCA/social.git
commit
201781c262
|
@ -126,6 +126,10 @@ Contributors
|
||||||
|
|
||||||
* Nguyễn Minh Chiến <chien@trobz.com>
|
* Nguyễn Minh Chiến <chien@trobz.com>
|
||||||
|
|
||||||
|
* `Moduon <https://www.moduon.team>`_:
|
||||||
|
|
||||||
|
* Jairo Llopis
|
||||||
|
|
||||||
Other credits
|
Other credits
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -17,3 +17,7 @@
|
||||||
* `Trobz <https://trobz.com>`_:
|
* `Trobz <https://trobz.com>`_:
|
||||||
|
|
||||||
* Nguyễn Minh Chiến <chien@trobz.com>
|
* Nguyễn Minh Chiến <chien@trobz.com>
|
||||||
|
|
||||||
|
* `Moduon <https://www.moduon.team>`_:
|
||||||
|
|
||||||
|
* Jairo Llopis
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
@ -9,10 +8,11 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
:Author: David Goodger (goodger@python.org)
|
:Author: David Goodger (goodger@python.org)
|
||||||
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
|
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
|
||||||
:Copyright: This stylesheet has been placed in the public domain.
|
:Copyright: This stylesheet has been placed in the public domain.
|
||||||
|
|
||||||
Default cascading style sheet for the HTML output of Docutils.
|
Default cascading style sheet for the HTML output of Docutils.
|
||||||
|
Despite the name, some widely supported CSS2 features are used.
|
||||||
|
|
||||||
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
||||||
customize this style sheet.
|
customize this style sheet.
|
||||||
|
@ -275,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
|
||||||
margin-left: 2em ;
|
margin-left: 2em ;
|
||||||
margin-right: 2em }
|
margin-right: 2em }
|
||||||
|
|
||||||
pre.code .ln { color: grey; } /* line numbers */
|
pre.code .ln { color: gray; } /* line numbers */
|
||||||
pre.code, code { background-color: #eeeeee }
|
pre.code, code { background-color: #eeeeee }
|
||||||
pre.code .comment, code .comment { color: #5C6576 }
|
pre.code .comment, code .comment { color: #5C6576 }
|
||||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||||
|
@ -301,7 +301,7 @@ span.option {
|
||||||
span.pre {
|
span.pre {
|
||||||
white-space: pre }
|
white-space: pre }
|
||||||
|
|
||||||
span.problematic {
|
span.problematic, pre.problematic {
|
||||||
color: red }
|
color: red }
|
||||||
|
|
||||||
span.section-subtitle {
|
span.section-subtitle {
|
||||||
|
@ -479,6 +479,13 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</li>
|
</li>
|
||||||
|
<li><p class="first"><a class="reference external" href="https://www.moduon.team">Moduon</a>:</p>
|
||||||
|
<blockquote>
|
||||||
|
<ul class="simple">
|
||||||
|
<li>Jairo Llopis</li>
|
||||||
|
</ul>
|
||||||
|
</blockquote>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="other-credits">
|
<div class="section" id="other-credits">
|
||||||
|
@ -488,7 +495,9 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||||
<div class="section" id="maintainers">
|
<div class="section" id="maintainers">
|
||||||
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
|
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
|
||||||
<p>This module is maintained by the OCA.</p>
|
<p>This module is maintained by the OCA.</p>
|
||||||
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
|
<a class="reference external image-reference" href="https://odoo-community.org">
|
||||||
|
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
||||||
|
</a>
|
||||||
<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>
|
||||||
|
|
|
@ -14,15 +14,16 @@ class DynamicListCase(common.TransactionCase):
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
super().setUpClass()
|
super().setUpClass()
|
||||||
cls.tag = cls.env["res.partner.category"].create({"name": "testing tag"})
|
cls.tag = cls.env["res.partner.category"].create({"name": "testing tag"})
|
||||||
cls.partners = cls.env["res.partner"]
|
cls.partners = cls.env["res.partner"].create(
|
||||||
for number in range(5):
|
[
|
||||||
cls.partners |= cls.partners.create(
|
|
||||||
{
|
{
|
||||||
"name": "partner %d" % number,
|
"name": "partner %d" % number,
|
||||||
"category_id": [(4, cls.tag.id, False)],
|
"category_id": [(4, cls.tag.id, False)],
|
||||||
"email": "%d@example.com" % number,
|
"email": "%d@example.com" % number,
|
||||||
}
|
}
|
||||||
)
|
for number in range(5)
|
||||||
|
]
|
||||||
|
)
|
||||||
cls.list = cls.env["mailing.list"].create(
|
cls.list = cls.env["mailing.list"].create(
|
||||||
{
|
{
|
||||||
"name": "test list",
|
"name": "test list",
|
||||||
|
@ -180,3 +181,17 @@ class DynamicListCase(common.TransactionCase):
|
||||||
wizard.action_merge()
|
wizard.action_merge()
|
||||||
self.assertTrue(partner_1.id in self.list.contact_ids.mapped("partner_id").ids)
|
self.assertTrue(partner_1.id in self.list.contact_ids.mapped("partner_id").ids)
|
||||||
self.assertTrue(partner_1.id in list2.contact_ids.mapped("partner_id").ids)
|
self.assertTrue(partner_1.id in list2.contact_ids.mapped("partner_id").ids)
|
||||||
|
|
||||||
|
def test_synced_contacts_can_be_bounced(self):
|
||||||
|
self.list.sync_method = "full"
|
||||||
|
self.list.action_sync()
|
||||||
|
contact = self.env["mailing.contact"].search(
|
||||||
|
[
|
||||||
|
("list_ids", "in", self.list.ids),
|
||||||
|
("partner_id", "=", self.partners[0].id),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
# A bounce arrives through fetchmail
|
||||||
|
contact._message_receive_bounce(contact.email, contact.partner_id)
|
||||||
|
# The contact is marked as bounced
|
||||||
|
self.assertEqual(contact.message_bounce, 1)
|
||||||
|
|
|
@ -98,6 +98,10 @@ Contributors
|
||||||
|
|
||||||
* Nguyễn Minh Chiến <chien@trobz.com>
|
* Nguyễn Minh Chiến <chien@trobz.com>
|
||||||
|
|
||||||
|
* `Moduon <https://www.moduon.team>`_:
|
||||||
|
|
||||||
|
* Jairo Llopis
|
||||||
|
|
||||||
Other credits
|
Other credits
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -53,37 +53,30 @@ class MailingContact(models.Model):
|
||||||
)
|
)
|
||||||
self.country_id = self.partner_id.country_id
|
self.country_id = self.partner_id.country_id
|
||||||
|
|
||||||
@api.model
|
def _overwrite_partner(self, vals, creating=False):
|
||||||
def _get_contact_vals(self, origin_vals):
|
"""Overwrite partner and update contact data if needed."""
|
||||||
record = self.new(origin_vals)
|
self.ensure_one()
|
||||||
if not record.partner_id:
|
if self.env.context.get("mass_mailing_partner_writing"):
|
||||||
record._set_partner()
|
return
|
||||||
record._onchange_partner_mass_mailing_partner()
|
_self = self.with_context(mass_mailing_partner_writing=True)
|
||||||
new_vals = record._convert_to_write(record._cache)
|
prev_partner = _self.partner_id
|
||||||
new_vals.update(
|
if "partner_id" not in vals:
|
||||||
subscription_list_ids=origin_vals.get("subscription_list_ids", []),
|
_self._set_partner()
|
||||||
list_ids=origin_vals.get("list_ids", []),
|
if creating or prev_partner != _self.partner_id:
|
||||||
)
|
_self._onchange_partner_mass_mailing_partner()
|
||||||
if new_vals.get("partner_id") and "tag_ids" in new_vals:
|
|
||||||
# When there is a partner, tag_ids must get value from the compute function
|
|
||||||
# otherwise, its values will be different from partner
|
|
||||||
del new_vals["tag_ids"]
|
|
||||||
return new_vals
|
|
||||||
|
|
||||||
@api.model_create_multi
|
@api.model_create_multi
|
||||||
def create(self, vals_list):
|
def create(self, vals_list):
|
||||||
new_vals_list = []
|
result = super().create(vals_list)
|
||||||
for vals in vals_list:
|
for contact, vals in zip(result, vals_list):
|
||||||
new_vals = self._get_contact_vals(vals)
|
contact._overwrite_partner(vals, True)
|
||||||
new_vals_list.append(new_vals)
|
return result
|
||||||
return super().create(new_vals_list)
|
|
||||||
|
|
||||||
def write(self, vals):
|
def write(self, vals):
|
||||||
|
result = super().write(vals)
|
||||||
for contact in self:
|
for contact in self:
|
||||||
origin_vals = contact.copy_data(vals)[0]
|
contact._overwrite_partner(vals)
|
||||||
new_vals = self._get_contact_vals(origin_vals)
|
return result
|
||||||
super(MailingContact, contact).write(new_vals)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _get_categories(self):
|
def _get_categories(self):
|
||||||
ca_ids = (
|
ca_ids = (
|
||||||
|
@ -113,6 +106,8 @@ class MailingContact(models.Model):
|
||||||
email = self.email.strip()
|
email = self.email.strip()
|
||||||
partner = m_partner.search([("email", "=ilike", email)], limit=1)
|
partner = m_partner.search([("email", "=ilike", email)], limit=1)
|
||||||
if partner:
|
if partner:
|
||||||
|
if partner == self.partner_id:
|
||||||
|
return
|
||||||
# Partner found
|
# Partner found
|
||||||
self.partner_id = partner
|
self.partner_id = partner
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -16,3 +16,7 @@
|
||||||
* `Trobz <https://trobz.com>`_:
|
* `Trobz <https://trobz.com>`_:
|
||||||
|
|
||||||
* Nguyễn Minh Chiến <chien@trobz.com>
|
* Nguyễn Minh Chiến <chien@trobz.com>
|
||||||
|
|
||||||
|
* `Moduon <https://www.moduon.team>`_:
|
||||||
|
|
||||||
|
* Jairo Llopis
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
@ -9,10 +8,11 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
:Author: David Goodger (goodger@python.org)
|
:Author: David Goodger (goodger@python.org)
|
||||||
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
|
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
|
||||||
:Copyright: This stylesheet has been placed in the public domain.
|
:Copyright: This stylesheet has been placed in the public domain.
|
||||||
|
|
||||||
Default cascading style sheet for the HTML output of Docutils.
|
Default cascading style sheet for the HTML output of Docutils.
|
||||||
|
Despite the name, some widely supported CSS2 features are used.
|
||||||
|
|
||||||
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
|
||||||
customize this style sheet.
|
customize this style sheet.
|
||||||
|
@ -275,7 +275,7 @@ pre.literal-block, pre.doctest-block, pre.math, pre.code {
|
||||||
margin-left: 2em ;
|
margin-left: 2em ;
|
||||||
margin-right: 2em }
|
margin-right: 2em }
|
||||||
|
|
||||||
pre.code .ln { color: grey; } /* line numbers */
|
pre.code .ln { color: gray; } /* line numbers */
|
||||||
pre.code, code { background-color: #eeeeee }
|
pre.code, code { background-color: #eeeeee }
|
||||||
pre.code .comment, code .comment { color: #5C6576 }
|
pre.code .comment, code .comment { color: #5C6576 }
|
||||||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
|
||||||
|
@ -301,7 +301,7 @@ span.option {
|
||||||
span.pre {
|
span.pre {
|
||||||
white-space: pre }
|
white-space: pre }
|
||||||
|
|
||||||
span.problematic {
|
span.problematic, pre.problematic {
|
||||||
color: red }
|
color: red }
|
||||||
|
|
||||||
span.section-subtitle {
|
span.section-subtitle {
|
||||||
|
@ -447,6 +447,13 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||||
</ul>
|
</ul>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</li>
|
</li>
|
||||||
|
<li><p class="first"><a class="reference external" href="https://www.moduon.team">Moduon</a>:</p>
|
||||||
|
<blockquote>
|
||||||
|
<ul class="simple">
|
||||||
|
<li>Jairo Llopis</li>
|
||||||
|
</ul>
|
||||||
|
</blockquote>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="section" id="other-credits">
|
<div class="section" id="other-credits">
|
||||||
|
@ -456,7 +463,9 @@ If you spotted it first, help us to smash it by providing a detailed and welcome
|
||||||
<div class="section" id="maintainers">
|
<div class="section" id="maintainers">
|
||||||
<h1>Maintainers</h1>
|
<h1>Maintainers</h1>
|
||||||
<p>This module is maintained by the OCA.</p>
|
<p>This module is maintained by the OCA.</p>
|
||||||
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
|
<a class="reference external image-reference" href="https://odoo-community.org">
|
||||||
|
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
|
||||||
|
</a>
|
||||||
<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>
|
||||||
|
|
|
@ -14,7 +14,7 @@ class PartnerMailListWizardCase(base.BaseCase):
|
||||||
wizard = self.env["partner.mail.list.wizard"].create(
|
wizard = self.env["partner.mail.list.wizard"].create(
|
||||||
{"mail_list_id": self.mailing_list.id}
|
{"mail_list_id": self.mailing_list.id}
|
||||||
)
|
)
|
||||||
wizard.partner_ids = [self.partner.id]
|
wizard.partner_ids = self.partner
|
||||||
wizard.add_to_mail_list()
|
wizard.add_to_mail_list()
|
||||||
contacts = self.env["mailing.contact"].search(
|
contacts = self.env["mailing.contact"].search(
|
||||||
[("partner_id", "=", self.partner.id)]
|
[("partner_id", "=", self.partner.id)]
|
||||||
|
|
|
@ -36,8 +36,8 @@ class PartnerMailListWizard(models.TransientModel):
|
||||||
contact_vals = {
|
contact_vals = {
|
||||||
"partner_id": partner.id,
|
"partner_id": partner.id,
|
||||||
"list_ids": [(4, self.mail_list_id.id)],
|
"list_ids": [(4, self.mail_list_id.id)],
|
||||||
"title_id": partner.title or False,
|
"title_id": partner.title.id or False,
|
||||||
"company_name": partner.company_id.name or False,
|
"company_name": partner.company_id.name or False,
|
||||||
"country_id": partner.country_id or False,
|
"country_id": partner.country_id.id or False,
|
||||||
}
|
}
|
||||||
contact_obj.create(contact_vals)
|
contact_obj.create(contact_vals)
|
||||||
|
|
Loading…
Reference in New Issue