[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:
@@ -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',
|
||||
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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);
|
||||
@@ -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 ?
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user