mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[FIX] printing_auto_base: don't print twice
Fix same record printed multiple times
This commit is contained in:
committed by
Jacques-Etienne Baudoux
parent
fb24e652fe
commit
28ad399edf
@@ -94,13 +94,13 @@ class PrintingAuto(models.Model):
|
|||||||
domain = safe_eval(self.condition, {"env": self.env})
|
domain = safe_eval(self.condition, {"env": self.env})
|
||||||
return record.filtered_domain(domain)
|
return record.filtered_domain(domain)
|
||||||
|
|
||||||
def _get_content(self, record):
|
def _get_content(self, records):
|
||||||
generate_data_func = getattr(
|
generate_data_func = getattr(
|
||||||
self, f"_generate_data_from_{self.data_source}", None
|
self, f"_generate_data_from_{self.data_source}", None
|
||||||
)
|
)
|
||||||
content = []
|
content = []
|
||||||
if generate_data_func:
|
if generate_data_func:
|
||||||
records = self._get_record(record)
|
records = self._get_record(records)
|
||||||
for record in records:
|
for record in records:
|
||||||
content.append(generate_data_func(record)[0])
|
content.append(generate_data_func(record)[0])
|
||||||
return content
|
return content
|
||||||
@@ -127,16 +127,16 @@ class PrintingAuto(models.Model):
|
|||||||
)
|
)
|
||||||
return [data]
|
return [data]
|
||||||
|
|
||||||
def do_print(self, record):
|
def do_print(self, records):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
record.ensure_one()
|
|
||||||
|
|
||||||
behaviour = self._get_behaviour()
|
behaviour = self._get_behaviour()
|
||||||
printer = behaviour["printer"]
|
printer = behaviour["printer"]
|
||||||
|
|
||||||
if self.nbr_of_copies <= 0:
|
if self.nbr_of_copies <= 0:
|
||||||
return (printer, 0)
|
return (printer, 0)
|
||||||
if not self._check_condition(record):
|
records = self._check_condition(records)
|
||||||
|
if not records:
|
||||||
return (printer, 0)
|
return (printer, 0)
|
||||||
|
|
||||||
if not printer:
|
if not printer:
|
||||||
@@ -145,7 +145,7 @@ class PrintingAuto(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
for content in self._get_content(record):
|
for content in self._get_content(records):
|
||||||
for _n in range(self.nbr_of_copies):
|
for _n in range(self.nbr_of_copies):
|
||||||
printer.print_document(report=None, content=content, **behaviour)
|
printer.print_document(report=None, content=content, **behaviour)
|
||||||
count += 1
|
count += 1
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ class PrintingAutoMixin(models.AbstractModel):
|
|||||||
return self.auto_printing_ids
|
return self.auto_printing_ids
|
||||||
|
|
||||||
def _do_print_auto(self, printing_auto):
|
def _do_print_auto(self, printing_auto):
|
||||||
self.ensure_one()
|
|
||||||
printing_auto.ensure_one()
|
printing_auto.ensure_one()
|
||||||
printer, count = printing_auto.do_print(self)
|
printer, count = printing_auto.do_print(self)
|
||||||
if count:
|
if count:
|
||||||
@@ -63,6 +62,12 @@ class PrintingAutoMixin(models.AbstractModel):
|
|||||||
def handle_print_auto(self):
|
def handle_print_auto(self):
|
||||||
"""Print some report or attachment directly to the corresponding printer."""
|
"""Print some report or attachment directly to the corresponding printer."""
|
||||||
self._on_printing_auto_start()
|
self._on_printing_auto_start()
|
||||||
|
to_print = {}
|
||||||
for record in self:
|
for record in self:
|
||||||
for printing_auto in record._get_printing_auto():
|
for printing_auto in record._get_printing_auto():
|
||||||
record._handle_print_auto(printing_auto)
|
if printing_auto not in to_print.keys():
|
||||||
|
to_print[printing_auto] = record
|
||||||
|
else:
|
||||||
|
to_print[printing_auto] |= record
|
||||||
|
for printing_auto, records in to_print.items():
|
||||||
|
records._handle_print_auto(printing_auto)
|
||||||
|
|||||||
37
printing_auto_base/tests/model_test.py
Normal file
37
printing_auto_base/tests/model_test.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
def setup_test_model(env, model_cls):
|
||||||
|
"""Pass a test model class and initialize it.
|
||||||
|
|
||||||
|
Courtesy of SBidoul from https://github.com/OCA/mis-builder :)
|
||||||
|
"""
|
||||||
|
model_cls._build_model(env.registry, env.cr)
|
||||||
|
env.registry.setup_models(env.cr)
|
||||||
|
env.registry.init_models(
|
||||||
|
env.cr, [model_cls._name], dict(env.context, update_custom_fields=True)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def teardown_test_model(env, model_cls):
|
||||||
|
"""Pass a test model class and deinitialize it.
|
||||||
|
|
||||||
|
Courtesy of SBidoul from https://github.com/OCA/mis-builder :)
|
||||||
|
"""
|
||||||
|
if not getattr(model_cls, "_teardown_no_delete", False):
|
||||||
|
del env.registry.models[model_cls._name]
|
||||||
|
env.registry.setup_models(env.cr)
|
||||||
|
|
||||||
|
|
||||||
|
class PrintingAutoTesterChild(models.Model):
|
||||||
|
_name = "printingauto.tester.child"
|
||||||
|
|
||||||
|
name = fields.Char()
|
||||||
|
|
||||||
|
|
||||||
|
class PrintingAutoTester(models.Model):
|
||||||
|
_name = "printingauto.tester"
|
||||||
|
_inherit = "printing.auto.mixin"
|
||||||
|
|
||||||
|
name = fields.Char()
|
||||||
|
child_ids = fields.Many2many("printingauto.tester.child")
|
||||||
@@ -7,10 +7,17 @@ from unittest import mock
|
|||||||
from odoo.exceptions import UserError, ValidationError
|
from odoo.exceptions import UserError, ValidationError
|
||||||
|
|
||||||
from .common import PrintingPrinter, TestPrintingAutoCommon, print_document
|
from .common import PrintingPrinter, TestPrintingAutoCommon, print_document
|
||||||
|
from .model_test import PrintingAutoTester, PrintingAutoTesterChild, setup_test_model
|
||||||
|
|
||||||
|
|
||||||
@mock.patch.object(PrintingPrinter, "print_document", print_document)
|
@mock.patch.object(PrintingPrinter, "print_document", print_document)
|
||||||
class TestPrintingAutoBase(TestPrintingAutoCommon):
|
class TestPrintingAutoBase(TestPrintingAutoCommon):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
super().setUpClass()
|
||||||
|
setup_test_model(cls.env, PrintingAutoTesterChild)
|
||||||
|
setup_test_model(cls.env, PrintingAutoTester)
|
||||||
|
|
||||||
def test_check_data_source(self):
|
def test_check_data_source(self):
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
self._create_printing_auto_report({"report_id": False})
|
self._create_printing_auto_report({"report_id": False})
|
||||||
@@ -90,3 +97,57 @@ class TestPrintingAutoBase(TestPrintingAutoCommon):
|
|||||||
printing_auto.condition = "[('name', '=', 'test_printing_auto')]"
|
printing_auto.condition = "[('name', '=', 'test_printing_auto')]"
|
||||||
expected = (self.printer_1, 0)
|
expected = (self.printer_1, 0)
|
||||||
self.assertEqual(expected, printing_auto.do_print(self.record))
|
self.assertEqual(expected, printing_auto.do_print(self.record))
|
||||||
|
|
||||||
|
def test_do_not_print_multiple_time_the_same_record(self):
|
||||||
|
"""Check the same record is not printed multiple times.
|
||||||
|
|
||||||
|
When the 'record_change' field is being used on the printing auto configuration
|
||||||
|
and 'handle_print_auto' is called from a recrodset.
|
||||||
|
The same record could be send for printing multiple times.
|
||||||
|
|
||||||
|
"""
|
||||||
|
printing_auto = self._create_printing_auto_report(
|
||||||
|
vals={"record_change": "child_ids", "printer_id": self.printer_1.id}
|
||||||
|
)
|
||||||
|
child1 = self.env["printingauto.tester.child"].create({"name": "Child One"})
|
||||||
|
child2 = self.env["printingauto.tester.child"].create({"name": "Child Two"})
|
||||||
|
parent1 = self.env["printingauto.tester"].create(
|
||||||
|
{
|
||||||
|
"name": "Customer One",
|
||||||
|
"child_ids": [(4, child1.id, 0)],
|
||||||
|
"auto_printing_ids": [(4, printing_auto.id, 0)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
parent2 = self.env["printingauto.tester"].create(
|
||||||
|
{
|
||||||
|
"name": "Customer Two",
|
||||||
|
"child_ids": [(4, child1.id, 0)],
|
||||||
|
"auto_printing_ids": [(4, printing_auto.id, 0)],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
parents = parent1 | parent2
|
||||||
|
generate_data_from = (
|
||||||
|
"odoo.addons.printing_auto_base.models.printing_auto."
|
||||||
|
"PrintingAuto._generate_data_from_report"
|
||||||
|
)
|
||||||
|
with mock.patch(generate_data_from) as generate_data_from:
|
||||||
|
# Both parents have the same child only print the child report once
|
||||||
|
parents.handle_print_auto()
|
||||||
|
self.assertEqual(generate_data_from.call_count, 1)
|
||||||
|
generate_data_from.assert_called_with(child1)
|
||||||
|
generate_data_from.reset_mock()
|
||||||
|
# Both parents have different childs, print both child reports
|
||||||
|
parent2.child_ids = [(6, 0, child2.ids)]
|
||||||
|
parents.handle_print_auto()
|
||||||
|
self.assertEqual(generate_data_from.call_count, 2)
|
||||||
|
generate_data_from.assert_has_calls(
|
||||||
|
[mock.call(child1), mock.call(child2)], any_order=True
|
||||||
|
)
|
||||||
|
generate_data_from.reset_mock()
|
||||||
|
# THe parents have one child in common and one parent has a 2nd child
|
||||||
|
parent2.child_ids = [(4, child1.id, 0)]
|
||||||
|
parents.handle_print_auto()
|
||||||
|
self.assertEqual(generate_data_from.call_count, 2)
|
||||||
|
generate_data_from.assert_has_calls(
|
||||||
|
[mock.call(child1), mock.call(child2)], any_order=True
|
||||||
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user