[IMP] account: Send & Print - use the bus to notify cron status

- Add a notification when closing the wizard that states that invoices
will be processed asynchronously.
- Add notifications when the cron is done processing some invoices.
This notification can either be a successful message or a warning when some
invoices are in error state. The notification can redirect to concerned moves.

closes odoo/odoo#149717

Task-id: 3568549
Signed-off-by: Laurent Smet (las) <las@odoo.com>
This commit is contained in:
Claire Bretton (clbr)
2024-01-31 13:47:06 +00:00
parent d67968b5a2
commit 54a1f89bda
6 changed files with 175 additions and 11 deletions
+1
View File
@@ -90,6 +90,7 @@ You could use this simplified accounting in case you work with an (external) acc
'account/static/src/scss/account_journal_dashboard.scss',
'account/static/src/scss/account_searchpanel.scss',
'account/static/src/components/**/*',
'account/static/src/services/*.js',
'account/static/src/js/tours/account.js',
'account/static/src/views/**/*.js',
'account/static/src/js/search/search_bar/search_bar.js',
+53
View File
@@ -7842,6 +7842,21 @@ msgstr ""
msgid "Invoices Statistics"
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/wizard/account_move_send.py:0
#, python-format
msgid "Invoices are being sent in the background."
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_move.py:0
#: code:addons/account/models/account_move.py:0
#, python-format
msgid "Invoices in error"
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_journal_dashboard.py:0
@@ -7849,6 +7864,20 @@ msgstr ""
msgid "Invoices owed to you"
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_move.py:0
#, python-format
msgid "Invoices sent"
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_move.py:0
#, python-format
msgid "Invoices sent successfully."
msgstr ""
#. module: account
#: model_terms:ir.ui.view,arch_db:account.account_journal_dashboard_kanban_view
msgid "Invoices to Validate"
@@ -9710,6 +9739,13 @@ msgstr ""
msgid "One or more Bank Accounts set on this partner are also used by other"
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_move.py:0
#, python-format
msgid "One or more invoices couldn't be processed."
msgstr ""
#. module: account
#: model:ir.ui.menu,name:account.root_payment_menu
msgid "Online Payments"
@@ -9779,8 +9815,11 @@ msgid "Oops"
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_move.py:0
#: model:ir.model.fields.selection,name:account.selection__account_invoice_report__state__posted
#: model:ir.model.fields.selection,name:account.selection__account_journal__invoice_reference_type__none
#, python-format
msgid "Open"
msgstr ""
@@ -12146,11 +12185,25 @@ msgid ""
"money."
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/wizard/account_move_send.py:0
#, python-format
msgid "Sending invoices"
msgstr ""
#. module: account
#: model_terms:ir.ui.view,arch_db:account.view_account_payment_search
msgid "Sent"
msgstr ""
#. module: account
#. odoo-python
#: code:addons/account/models/account_move.py:0
#, python-format
msgid "Sent invoices"
msgstr ""
#. module: account
#: model:mail.template,description:account.mail_template_data_payment_receipt
msgid ""
+38
View File
@@ -4227,6 +4227,24 @@ class AccountMove(models.Model):
""" Handle Send & Print async processing.
:param job_count: maximum number of jobs to process if specified.
"""
def get_account_notification(partner, moves, is_success):
return [
partner,
'account_notification',
{
'type': 'success' if is_success else 'warning',
'title': _('Invoices sent') if is_success else _('Invoices in error'),
'message': _('Invoices sent successfully.') if is_success else _(
"One or more invoices couldn't be processed."),
'action_button': {
'name': _('Open'),
'action_name': _('Sent invoices') if is_success else _('Invoices in error'),
'model': 'account.move',
'res_ids': moves.ids,
},
},
]
limit = job_count + 1
to_process = self.env['account.move']._read_group(
[('send_and_print_values', '!=', False)],
@@ -4250,8 +4268,28 @@ class AccountMove(models.Model):
else:
raise
# Retrieve res.partner that executed the Send & Print wizard
sp_partner_ids = set(moves.mapped(lambda move: move.send_and_print_values.get('sp_partner_id')))
sp_partners = self.env['res.partner'].browse(sp_partner_ids)
moves_map = {
partner: moves.filtered(lambda m: m.send_and_print_values['sp_partner_id'] == partner.id)
for partner in sp_partners
}
self.env['account.move.send']._process_send_and_print(moves)
notifications = []
for partner, partner_moves in moves_map.items():
partner_moves_error = partner_moves.filtered(lambda m: m.send_and_print_values and m.send_and_print_values.get('error'))
if partner_moves_error:
notifications.append(get_account_notification(partner, partner_moves_error, False))
partner_moves_success = partner_moves - partner_moves_error
if partner_moves_success:
notifications.append(get_account_notification(partner, partner_moves_success, True))
partner_moves_error.send_and_print_values = False
self.env['bus.bus']._sendmany(notifications)
if need_retrigger:
self.env.ref('account.ir_cron_account_move_send')._trigger()
@@ -0,0 +1,31 @@
/** @odoo-module **/
import { _t } from "@web/core/l10n/translation";
import { registry } from "@web/core/registry";
export const accountNotificationService = {
dependencies: ["bus_service", "notification", "action"],
start(env, { bus_service, notification, action }) {
bus_service.subscribe("account_notification", ({ message, sticky, title, type, action_button}) => {
const buttons = [{
name: action_button.name,
primary: false,
onClick: () => {
action.doAction({
name: _t(action_button.action_name),
type: 'ir.actions.act_window',
res_model: action_button.model,
domain: [["id", "in", action_button.res_ids]],
views: [[false, 'list'], [false, 'form']],
target: 'current',
});
},
}];
notification.add(message, { sticky, title, type, buttons });
});
}
};
registry.category("services").add("accountNotification", accountNotificationService);
+37 -7
View File
@@ -1,16 +1,15 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from datetime import date
from dateutil.relativedelta import relativedelta
from freezegun import freeze_time
from unittest.mock import patch
from odoo import Command, fields
from odoo import Command
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.addons.mail.tests.common import MailCommon
from odoo.exceptions import UserError
from odoo.tests.common import Form, users, warmup
from odoo.tests.common import users, warmup
from odoo.tests import tagged
from odoo.tools import formataddr, mute_logger
@@ -581,7 +580,8 @@ class TestAccountMoveSend(TestAccountMoveSendCommon):
# Process.
results = wizard.action_send_and_print()
self.assertEqual(results['type'], 'ir.actions.act_window_close')
self.assertEqual(results['type'], 'ir.actions.client')
self.assertEqual(results['params']['next']['type'], 'ir.actions.act_window_close')
self.assertRecordValues(wizard, [{'mode': 'invoice_multi'}])
# Awaiting the CRON.
@@ -996,5 +996,35 @@ class TestAccountMoveSend(TestAccountMoveSendCommon):
self.assertFalse(invoices.invoice_pdf_report_id)
self.assertEqual(invoices.mapped(lambda inv: bool(inv.send_and_print_values)), [True] * len(invoices))
self.env.ref('account.ir_cron_account_move_send').method_direct_trigger() # force processing
self.assertEqual(len(invoices.invoice_pdf_report_id), 4)
self.assertEqual(invoices.mapped(lambda inv: inv.send_and_print_values), [False] * len(invoices))
self.assertTrue(all(invoice.invoice_pdf_report_id for invoice in invoices))
self.assertTrue(all(not invoice.send_and_print_values for invoice in invoices))
def test_cron_notifications(self):
invoice_success = self.init_invoice("out_invoice", amounts=[1000], post=True)
invoice_error = self.init_invoice("out_invoice", amounts=[1000], post=True)
wizard = self.create_send_and_print(invoice_success + invoice_error)
wizard.checkbox_download = False
sp_partner = self.env.user.partner_id
wizard.action_send_and_print()
def _hook_invoice_document_before_pdf_report_render(self, invoice, invoice_data):
if invoice == invoice_error:
invoice_data['error'] = 'blblblbl'
self.assertTrue(invoice_success.send_and_print_values)
self.assertEqual(invoice_success.send_and_print_values.get('sp_partner_id'), sp_partner.id)
with patch(
'odoo.addons.account.wizard.account_move_send.AccountMoveSend._hook_invoice_document_before_pdf_report_render',
_hook_invoice_document_before_pdf_report_render,
):
self.env.ref('account.ir_cron_account_move_send').method_direct_trigger() # force processing
bus = self.env['bus.bus'].sudo().search(
[('channel', 'like', f'"res.partner",{sp_partner.id}')],
order='id desc',
limit=1,
)
self.assertEqual(json.loads(bus.message)['payload']['type'], 'success')
self.assertEqual(json.loads(bus.message)['payload']['action_button']['res_ids'], invoice_success.ids)
# FIXME @las I only manage to get the latest message, and not the previous one with the invoices in error T_T any idea ?
+15 -4
View File
@@ -671,8 +671,10 @@ class AccountMoveSend(models.TransientModel):
self._hook_if_success(success, from_cron=from_cron, allow_fallback_pdf=allow_fallback_pdf)
# Update send and print values of moves
for move in moves:
if move.send_and_print_values:
for move, move_data in moves_data.items():
if from_cron and move_data.get('error'):
move.send_and_print_values = {'error': True}
else:
move.send_and_print_values = False
to_download = {move: move_data for move, move_data in moves_data.items() if move_data.get('download')}
@@ -704,9 +706,18 @@ class AccountMoveSend(models.TransientModel):
if process_later:
# Set sending information on moves
for move in self.move_ids:
move.send_and_print_values = self._get_wizard_values()
move.send_and_print_values = {'sp_partner_id': self.env.user.partner_id.id, **self._get_wizard_values()}
self.env.ref('account.ir_cron_account_move_send')._trigger()
return {'type': 'ir.actions.act_window_close'}
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'type': 'info',
'title': _('Sending invoices'),
'message': _('Invoices are being sent in the background.'),
'next': {'type': 'ir.actions.act_window_close'},
},
}
return self._process_send_and_print(
self.move_ids,