[IMP] account, snailmail_account: improve invoice send & print usability
Improve Send & Print general usability by making it more streamlined overall. Options are not activated but preemptive problematic partners are shown, and skipped during the sending process. closes odoo/odoo#131448 Task-id: 3336623 X-original-commit: 4105994e778459c869d885d017118492ffcd2064 Signed-off-by: Laurent Smet (las) <las@odoo.com> Signed-off-by: Yosua Nicolaus (yoni) <yoni@odoo.com>
This commit is contained in:
@@ -466,17 +466,6 @@ class TestAccountMoveSendCommon(AccountTestInvoicingCommon):
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestAccountMoveSend(TestAccountMoveSendCommon):
|
||||
|
||||
def test_send_mail_warning_message(self):
|
||||
invoice = self.init_invoice("out_invoice", amounts=[1000], post=True)
|
||||
self.partner_a.email = None
|
||||
wizard = self.create_send_and_print(invoice)
|
||||
self.assertTrue(wizard.send_mail_warning_message)
|
||||
|
||||
# Fix the partner.
|
||||
self.partner_a.email = "turlututu@tsointsoin"
|
||||
wizard.invalidate_recordset(fnames=['send_mail_warning_message'])
|
||||
self.assertFalse(wizard.send_mail_warning_message)
|
||||
|
||||
def test_invoice_single(self):
|
||||
invoice = self.init_invoice("out_invoice", amounts=[1000], post=True)
|
||||
wizard = self.create_send_and_print(invoice)
|
||||
@@ -491,6 +480,7 @@ class TestAccountMoveSend(TestAccountMoveSendCommon):
|
||||
'mail_lang': 'en_US',
|
||||
'mail_partner_ids': wizard.move_ids.partner_id.ids,
|
||||
}])
|
||||
self.assertFalse(wizard.send_mail_warning_message)
|
||||
self.assertTrue(wizard.mail_subject)
|
||||
self.assertTrue(wizard.mail_body)
|
||||
self._assert_mail_attachments_widget(wizard, [{
|
||||
@@ -536,6 +526,23 @@ class TestAccountMoveSend(TestAccountMoveSendCommon):
|
||||
])
|
||||
self.assertFalse(invoice_attachments)
|
||||
|
||||
def test_invoice_single_readonly_and_checkbox(self):
|
||||
invoice = self.init_invoice("out_invoice", amounts=[1000], post=True)
|
||||
|
||||
self.partner_a.email = None
|
||||
wizard = self.create_send_and_print(invoice)
|
||||
self.assertRecordValues(wizard, [{
|
||||
'send_mail_readonly': True,
|
||||
'checkbox_send_mail': False,
|
||||
}])
|
||||
|
||||
self.partner_a.email = "turlututu@tsointsoin"
|
||||
wizard = self.create_send_and_print(invoice)
|
||||
self.assertRecordValues(wizard, [{
|
||||
'send_mail_readonly': False,
|
||||
'checkbox_send_mail': True,
|
||||
}])
|
||||
|
||||
def test_invoice_multi(self):
|
||||
invoice1 = self.init_invoice("out_invoice", partner=self.partner_a, amounts=[1000], post=True)
|
||||
invoice2 = self.init_invoice("out_invoice", partner=self.partner_b, amounts=[1000], post=True)
|
||||
@@ -612,6 +619,35 @@ class TestAccountMoveSend(TestAccountMoveSendCommon):
|
||||
])
|
||||
self.assertEqual(len(invoice_attachments), 1)
|
||||
|
||||
def test_invoice_multi_readonly_checkbox_warning_message(self):
|
||||
invoice1 = self.init_invoice("out_invoice", partner=self.partner_a, amounts=[1000], post=True)
|
||||
invoice2 = self.init_invoice("out_invoice", partner=self.partner_b, amounts=[1000], post=True)
|
||||
|
||||
self.partner_a.email = None
|
||||
self.partner_b.email = None
|
||||
wizard = self.create_send_and_print(invoice1 + invoice2)
|
||||
self.assertFalse(wizard.send_mail_warning_message)
|
||||
self.assertRecordValues(wizard, [{
|
||||
'send_mail_readonly': True,
|
||||
'checkbox_send_mail': False,
|
||||
}])
|
||||
|
||||
self.partner_a.email = "turlututu@tsointsoin"
|
||||
wizard = self.create_send_and_print(invoice1 + invoice2)
|
||||
self.assertTrue(wizard.send_mail_warning_message)
|
||||
self.assertRecordValues(wizard, [{
|
||||
'send_mail_readonly': False,
|
||||
'checkbox_send_mail': True,
|
||||
}])
|
||||
|
||||
self.partner_b.email = "turlututu@tsointsoin"
|
||||
wizard = self.create_send_and_print(invoice1 + invoice2)
|
||||
self.assertFalse(wizard.send_mail_warning_message)
|
||||
self.assertRecordValues(wizard, [{
|
||||
'send_mail_readonly': False,
|
||||
'checkbox_send_mail': True,
|
||||
}])
|
||||
|
||||
def test_invoice_mail_attachments_widget(self):
|
||||
invoice = self.init_invoice("out_invoice", amounts=[1000], post=True)
|
||||
|
||||
|
||||
@@ -185,29 +185,21 @@ class AccountMoveSend(models.Model):
|
||||
for wizard in self:
|
||||
wizard.checkbox_download = wizard.enable_download and wizard.company_id.invoice_is_download
|
||||
|
||||
@api.depends('move_ids')
|
||||
@api.depends('mode', 'checkbox_send_mail')
|
||||
def _compute_send_mail_extra_fields(self):
|
||||
for wizard in self:
|
||||
wizard.enable_send_mail = wizard.mode in ('invoice_single', 'invoice_multi')
|
||||
wizard.display_mail_composer = wizard.mode == 'invoice_single'
|
||||
send_mail_readonly = False
|
||||
wizard.send_mail_warning_message = False
|
||||
|
||||
display_messages = []
|
||||
if wizard.enable_send_mail:
|
||||
invoices_without_mail_data = wizard.move_ids.filtered(lambda x: not x.partner_id.email)
|
||||
if invoices_without_mail_data:
|
||||
if wizard.mode == 'invoice_multi':
|
||||
display_messages.append(_(
|
||||
"The following invoice(s) will not be sent by email, because the customers don't have email "
|
||||
"address: "
|
||||
))
|
||||
display_messages.append(", ".join(invoices_without_mail_data.mapped('name')))
|
||||
send_mail_readonly = True
|
||||
else:
|
||||
display_messages.append(_("Please add an email address for your partner"))
|
||||
invoices_without_mail_data = wizard.move_ids.filtered(lambda x: not x.partner_id.email)
|
||||
wizard.send_mail_readonly = invoices_without_mail_data == wizard.move_ids
|
||||
|
||||
wizard.send_mail_readonly = send_mail_readonly
|
||||
wizard.send_mail_warning_message = "".join(display_messages) if display_messages else None
|
||||
if wizard.mode == 'invoice_multi' and wizard.checkbox_send_mail and invoices_without_mail_data:
|
||||
wizard.send_mail_warning_message = _(
|
||||
"The partners on the following invoices have no email address, "
|
||||
"so those invoices will not be sent: %s"
|
||||
) % ", ".join(invoices_without_mail_data.mapped('name'))
|
||||
|
||||
@api.depends('move_ids')
|
||||
def _compute_checkbox_send_mail(self):
|
||||
@@ -635,7 +627,7 @@ class AccountMoveSend(models.Model):
|
||||
self._generate_invoice_fallback_documents(errors)
|
||||
|
||||
# Send mail.
|
||||
success = {move: move_data for move, move_data in moves_data.items() if not move_data.get('error')}
|
||||
success = {move: move_data for move, move_data in moves_data.items() if not move_data.get('error') and move.partner_id.email}
|
||||
if success:
|
||||
self._hook_if_success(success, from_cron=from_cron, allow_fallback_pdf=allow_fallback_pdf)
|
||||
|
||||
|
||||
@@ -17,6 +17,16 @@
|
||||
<field name="send_mail_readonly" invisible="1"/>
|
||||
<field name="display_mail_composer" invisible="1"/>
|
||||
<field name="mail_lang" invisible="1"/>
|
||||
<field name="mail_partner_ids" widget="many2many_tags_email" class="d-none" context="{'force_email': True}"/>
|
||||
|
||||
<!-- Warnings -->
|
||||
<div name="warnings">
|
||||
<div class="alert alert-warning"
|
||||
role="alert"
|
||||
attrs="{'invisible': [('send_mail_warning_message', '=', False)]}">
|
||||
<field name="send_mail_warning_message"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Options -->
|
||||
<div name="options" class="row">
|
||||
@@ -31,20 +41,16 @@
|
||||
<field name="checkbox_send_mail"
|
||||
attrs="{'readonly': [('send_mail_readonly', '=', True)]}"/>
|
||||
<b><label for="checkbox_send_mail"/></b>
|
||||
<i class="fa fa-question-circle ml4"
|
||||
role="img"
|
||||
aria-label="Warning"
|
||||
title="The email address is unknown on the partner"
|
||||
attrs="{'invisible': [('send_mail_readonly', '=', False)]}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div name="advanced_options" class="col-3"/>
|
||||
</div>
|
||||
|
||||
<!-- Warnings -->
|
||||
<div name="warnings">
|
||||
<div class="alert alert-warning"
|
||||
role="alert"
|
||||
attrs="{'invisible': [('send_mail_warning_message', '=', False)]}">
|
||||
<field name="send_mail_warning_message"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mail -->
|
||||
<div attrs="{'invisible': [('checkbox_send_mail', '=', False)]}">
|
||||
<group attrs="{'invisible': [('display_mail_composer', '=', False)]}">
|
||||
|
||||
@@ -13,7 +13,9 @@ class AccountMoveSend(models.Model):
|
||||
store=True,
|
||||
readonly=False,
|
||||
)
|
||||
send_by_post_warning_message = fields.Text(compute='_compute_send_by_post_warning_message')
|
||||
send_by_post_cost = fields.Integer(string='Stamps', compute='_compute_send_by_post_extra_fields')
|
||||
send_by_post_warning_message = fields.Text(compute='_compute_send_by_post_extra_fields')
|
||||
send_by_post_readonly = fields.Boolean(compute='_compute_send_by_post_extra_fields')
|
||||
|
||||
def _get_available_field_values_in_multi(self, move):
|
||||
# EXTENDS 'account'
|
||||
@@ -31,23 +33,28 @@ class AccountMoveSend(models.Model):
|
||||
wizard.enable_send_by_post = wizard.mode in ('invoice_single', 'invoice_multi') \
|
||||
and all(x.state == 'posted' for x in wizard.move_ids)
|
||||
|
||||
@api.depends('send_by_post_warning_message')
|
||||
@api.depends('company_id')
|
||||
def _compute_checkbox_send_by_post(self):
|
||||
for wizard in self:
|
||||
wizard.checkbox_send_by_post = not wizard.send_by_post_warning_message \
|
||||
and wizard.company_id.invoice_is_snailmail
|
||||
wizard.checkbox_send_by_post = wizard.company_id.invoice_is_snailmail
|
||||
|
||||
@api.depends('mode')
|
||||
def _compute_send_by_post_warning_message(self):
|
||||
@api.depends('mode', 'checkbox_send_by_post')
|
||||
def _compute_send_by_post_extra_fields(self):
|
||||
for wizard in self:
|
||||
display_messages = []
|
||||
if wizard.enable_send_by_post:
|
||||
wrong_address_partners = wizard.move_ids.partner_id\
|
||||
.filtered(lambda x: not self.env['snailmail.letter']._is_valid_address(x))
|
||||
if wrong_address_partners:
|
||||
display_messages.append(_("The following customers don't have a valid address: "))
|
||||
display_messages.append(", ".join(wrong_address_partners.mapped('display_name')))
|
||||
wizard.send_by_post_warning_message = "".join(display_messages) if display_messages else None
|
||||
partner_with_valid_address = wizard.move_ids.partner_id \
|
||||
.filtered(self.env['snailmail.letter']._is_valid_address)
|
||||
wizard.send_by_post_cost = len(partner_with_valid_address)
|
||||
wizard.send_by_post_readonly = not partner_with_valid_address
|
||||
wizard.send_by_post_warning_message = False
|
||||
|
||||
if wizard.enable_send_by_post and wizard.checkbox_send_by_post:
|
||||
invoice_without_valid_address = wizard.move_ids.filtered(
|
||||
lambda move: not self.env['snailmail.letter']._is_valid_address(move.partner_id))
|
||||
if invoice_without_valid_address:
|
||||
wizard.send_by_post_warning_message = _(
|
||||
"The partners on the following invoices have no valid address, "
|
||||
"so those invoices will not be sent: %s"
|
||||
) % ", ".join(invoice_without_valid_address.mapped('name'))
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# BUSINESS ACTIONS
|
||||
|
||||
@@ -8,11 +8,24 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='standard_options']" position="inside">
|
||||
<field name="enable_send_by_post" invisible="1"/>
|
||||
<field name="send_by_post_readonly" invisible="1"/>
|
||||
|
||||
<div name="option_send_by_post"
|
||||
attrs="{'invisible': [('enable_send_by_post', '=', False)]}">
|
||||
<field name="checkbox_send_by_post"
|
||||
attrs="{'readonly': [('send_by_post_warning_message', '!=', False)]}"/>
|
||||
<b><label for="checkbox_send_by_post"/></b>
|
||||
<field name="checkbox_send_by_post" attrs="{'readonly': [('send_by_post_readonly', '=', True)]}"/>
|
||||
<b><label for="checkbox_send_by_post" class="mr4"/></b>
|
||||
<i class="fa fa-question-circle"
|
||||
role="img"
|
||||
aria-label="Warning"
|
||||
title="The address is unknown on the partner"
|
||||
attrs="{'invisible': [('send_by_post_readonly', '=', False)]}"/>
|
||||
|
||||
<span attrs="{'invisible': ['|', ('send_by_post_cost', 'in', (0, 1)), ('checkbox_send_by_post', '=', False)]}">
|
||||
<b>(
|
||||
<field name="send_by_post_cost" options="{'digits':[0,0]}" class="mr4"/>
|
||||
<label for="send_by_post_cost"/>
|
||||
)</b>
|
||||
</span>
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//div[@name='warnings']" position="inside">
|
||||
|
||||
Reference in New Issue
Block a user