Skip to content

Commit

Permalink
[FIX] printing_auto_base: don't print twice
Browse files Browse the repository at this point in the history
Fix same record printed multiple times
  • Loading branch information
TDu authored and jbaudoux committed Sep 19, 2023
1 parent dd85c24 commit 0e100aa
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 8 deletions.
12 changes: 6 additions & 6 deletions printing_auto_base/models/printing_auto.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,13 @@ def _check_condition(self, record):
domain = safe_eval(self.condition, {"env": self.env})
return record.filtered_domain(domain)

def _get_content(self, record):
def _get_content(self, records):
generate_data_func = getattr(
self, f"_generate_data_from_{self.data_source}", None
)
content = []
if generate_data_func:
records = self._get_record(record)
records = self._get_record(records)
for record in records:
content.append(generate_data_func(record)[0])
return content
Expand All @@ -127,16 +127,16 @@ def _generate_data_from_report(self, record):
)
return [data]

def do_print(self, record):
def do_print(self, records):
self.ensure_one()
record.ensure_one()

behaviour = self._get_behaviour()
printer = behaviour["printer"]

if self.nbr_of_copies <= 0:
return (printer, 0)
if not self._check_condition(record):
records = self._check_condition(records)
if not records:
return (printer, 0)

if not printer:
Expand All @@ -145,7 +145,7 @@ def do_print(self, record):
)

count = 0
for content in self._get_content(record):
for content in self._get_content(records):
for _n in range(self.nbr_of_copies):
printer.print_document(report=None, content=content, **behaviour)
count += 1
Expand Down
9 changes: 7 additions & 2 deletions printing_auto_base/models/printing_auto_mixin.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def _get_printing_auto(self):
return self.auto_printing_ids

def _do_print_auto(self, printing_auto):
self.ensure_one()
printing_auto.ensure_one()
printer, count = printing_auto.do_print(self)
if count:
Expand All @@ -63,6 +62,12 @@ def _handle_print_auto(self, printing_auto):
def handle_print_auto(self):
"""Print some report or attachment directly to the corresponding printer."""
self._on_printing_auto_start()
to_print = {}
for record in self:
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 changes: 37 additions & 0 deletions printing_auto_base/tests/model_test.py
Original file line number Diff line number Diff line change
@@ -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")
61 changes: 61 additions & 0 deletions printing_auto_base/tests/test_printing_auto_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@
from odoo.exceptions import UserError, ValidationError

from .common import PrintingPrinter, TestPrintingAutoCommon, print_document
from .model_test import PrintingAutoTester, PrintingAutoTesterChild, setup_test_model


@mock.patch.object(PrintingPrinter, "print_document", print_document)
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):
with self.assertRaises(UserError):
self._create_printing_auto_report({"report_id": False})
Expand Down Expand Up @@ -90,3 +97,57 @@ def test_do_print(self):
printing_auto.condition = "[('name', '=', 'test_printing_auto')]"
expected = (self.printer_1, 0)
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
)

0 comments on commit 0e100aa

Please sign in to comment.