Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0] Add printing_auto_base #310

Open
wants to merge 8 commits into
base: 14.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions printing_auto_base/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
==================
printing_auto_base
==================

.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Freport--print--send-lightgray.png?logo=github
:target: https://github.com/OCA/report-print-send/tree/14.0/printing_auto_base
:alt: OCA/report-print-send
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/report-print-send-14-0/report-print-send-14-0-printing_auto_base
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/webui/builds.html?repo=OCA/report-print-send&target_branch=14.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

Base module to support automatic printing of a report or attachments.

Check other repo like stock-logistics-reporting module printing_auto_stock_picking
for printing documents related to a stock transfer.

**Table of contents**

.. contents::
:local:

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/report-print-send/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed
`feedback <https://github.com/OCA/report-print-send/issues/new?body=module:%20printing_auto_base%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* BCIM
* MT Software

Contributors
~~~~~~~~~~~~

* Jacques-Etienne Baudoux (BCIM) <[email protected]>
* Michael Tietz (MT Software) <[email protected]>
* Camptocamp
* Christopher Hansen <[email protected]>

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/report-print-send <https://github.com/OCA/report-print-send/tree/14.0/printing_auto_base>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions printing_auto_base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
18 changes: 18 additions & 0 deletions printing_auto_base/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2022 Jacques-Etienne Baudoux (BCIM) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Printing Auto Base",
"author": "BCIM, MT Software, Odoo Community Association (OCA)",
jbaudoux marked this conversation as resolved.
Show resolved Hide resolved
"maintainers": ["jbaudoux"],
"category": "Warehouse Management",
"data": [
"views/printing_auto.xml",
],
"depends": [
"base_report_to_printer",
],
"license": "AGPL-3",
"version": "14.0.1.0.0",
"website": "https://github.com/OCA/report-print-send",
}
2 changes: 2 additions & 0 deletions printing_auto_base/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import printing_auto
from . import printing_auto_mixin
153 changes: 153 additions & 0 deletions printing_auto_base/models/printing_auto.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# Copyright 2022 Jacques-Etienne Baudoux (BCIM) <[email protected]>
# Copyright 2022 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import base64

from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
from odoo.osv import expression
from odoo.tools.safe_eval import safe_eval


class PrintingAuto(models.Model):
jbaudoux marked this conversation as resolved.
Show resolved Hide resolved
"""Configure which document to print automatically. This model must be
linked with a many2many relation from the another model from which you want
to print a document"""

_name = "printing.auto"
_description = "Printing Auto"

name = fields.Char(string="Name", required=True)
model = fields.Char(string="Related Document Model", required=True)

data_source = fields.Selection(
[
("report", "Report"),
("attachment", "Attachment"),
],
string="Data source",
default="report",
required=True,
help=(
"Choose to print the result of an odoo report or a pre-existing "
"attachment (useful for labels received from carriers that are "
"recorded on the picking as an attachment)"
),
)
report_id = fields.Many2one("ir.actions.report")
attachment_domain = fields.Char("Attachment domain", default="[]")

condition = fields.Char(
"Condition",
default="[]",
help="Give a domain that must be valid for printing this",
)
record_change = fields.Char(
"Record change",
help="Select on which document the report must be executed. Use a path "
"using a dotted notation starting from any record field. For "
"example, if your record is a stock.picking, you can access the "
"next picking with 'move_lines.move_dest_ids.picking_id'",
)

printer_id = fields.Many2one("printing.printer", "Printer")
printer_tray_id = fields.Many2one("printing.tray", "Tray")
nbr_of_copies = fields.Integer("Number of Copies", default=1)
action_on_error = fields.Selection(
[("log", "Record an error"), ("raise", "Raise an Exception")],
"Action on error",
default="log",
required=True,
)

@api.constrains("data_source", "report_id", "attachment_domain")
def _check_data_source(self):
for rec in self:
if rec.data_source == "report" and not rec.report_id:
raise ValidationError(_("Report is not set"))

Check warning on line 68 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L68

Added line #L68 was not covered by tests
if rec.data_source == "attachment" and (
not rec.attachment_domain or rec.attachment_domain == "[]"
):
raise ValidationError(_("Attachment domain is not set"))

Check warning on line 72 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L72

Added line #L72 was not covered by tests

def _get_behaviour(self):
if self.printer_id:
result = {"printer": self.printer_id}

Check warning on line 76 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L76

Added line #L76 was not covered by tests
if self.printer_tray_id:
result["tray"] = self.printer_tray_id.system_name
return result

Check warning on line 79 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L78-L79

Added lines #L78 - L79 were not covered by tests
if self.data_source == "report":
return self.report_id.behaviour()
return self.env["ir.actions.report"]._get_user_default_print_behaviour()

Check warning on line 82 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L81-L82

Added lines #L81 - L82 were not covered by tests

def _get_record(self, record):
if self.record_change:
try:
return safe_eval(f"obj.{self.record_change}", {"obj": record})
except Exception as e:
raise UserError(

Check warning on line 89 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L86-L89

Added lines #L86 - L89 were not covered by tests
_("The Record change could not be applied because: %s") % str(e)
) from e
return record

Check warning on line 92 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L92

Added line #L92 was not covered by tests

def _check_condition(self, record):
domain = safe_eval(self.condition, {"env": self.env})
return record.filtered_domain(domain)

Check warning on line 96 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L95-L96

Added lines #L95 - L96 were not covered by tests

def _get_content(self, records):
generate_data_func = getattr(

Check warning on line 99 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L99

Added line #L99 was not covered by tests
self, f"_generate_data_from_{self.data_source}", None
)
content = []

Check warning on line 102 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L102

Added line #L102 was not covered by tests
if generate_data_func:
records = self._get_record(records)

Check warning on line 104 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L104

Added line #L104 was not covered by tests
for record in records:
content += generate_data_func(record)
return content

Check warning on line 107 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L106-L107

Added lines #L106 - L107 were not covered by tests

def _prepare_attachment_domain(self, record):
domain = safe_eval(self.attachment_domain)
record_domain = [

Check warning on line 111 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L110-L111

Added lines #L110 - L111 were not covered by tests
("res_id", "=", record.id),
("res_model", "=", record._name),
]
return expression.AND([domain, record_domain])

Check warning on line 115 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L115

Added line #L115 was not covered by tests

def _generate_data_from_attachment(self, record):
domain = self._prepare_attachment_domain(record)
attachments = self.env["ir.attachment"].search(domain)

Check warning on line 119 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L118-L119

Added lines #L118 - L119 were not covered by tests
if not attachments:
raise UserError(_("No attachment was found."))

Check warning on line 121 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L121

Added line #L121 was not covered by tests
return [base64.b64decode(a.datas) for a in attachments]

def _generate_data_from_report(self, record):
self.ensure_one()
data, _ = self.report_id.with_context(must_skip_send_to_printer=True)._render(

Check warning on line 126 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L125-L126

Added lines #L125 - L126 were not covered by tests
record.id
)
return [data]

Check warning on line 129 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L129

Added line #L129 was not covered by tests

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

Check warning on line 132 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L132

Added line #L132 was not covered by tests

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

Check warning on line 135 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L134-L135

Added lines #L134 - L135 were not covered by tests

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

Check warning on line 139 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L138-L139

Added lines #L138 - L139 were not covered by tests
if not records:
return (printer, 0)

Check warning on line 141 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L141

Added line #L141 was not covered by tests

if not printer:
raise UserError(

Check warning on line 144 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L144

Added line #L144 was not covered by tests
_("No printer configured to print this {}.").format(self.name)
)

count = 0

Check warning on line 148 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L148

Added line #L148 was not covered by tests
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
return (printer, count)

Check warning on line 153 in printing_auto_base/models/printing_auto.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto.py#L151-L153

Added lines #L151 - L153 were not covered by tests
73 changes: 73 additions & 0 deletions printing_auto_base/models/printing_auto_mixin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Copyright 2022 Jacques-Etienne Baudoux (BCIM) <[email protected]>
# Copyright 2022 Michael Tietz (MT Software) <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging

from odoo import _, fields, models

_logger = logging.getLogger(__name__)


class PrintingAutoMixin(models.AbstractModel):
_name = "printing.auto.mixin"
_description = "Printing Auto Mixin"

auto_printing_ids = fields.Many2many(
"printing.auto", string="Auto Printing Configuration"
)
printing_auto_error = fields.Text("Printing error")

def _on_printing_auto_start(self):
self.write({"printing_auto_error": False})

Check warning on line 21 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L21

Added line #L21 was not covered by tests

def _printing_auto_done_post(self, auto, printer, count):
self.ensure_one()
self.message_post(

Check warning on line 25 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L24-L25

Added lines #L24 - L25 were not covered by tests
body=_("{name}: {count} document(s) sent to printer {printer}").format(
name=auto.name, count=count, printer=printer.name
)
)

def _on_printing_auto_done(self, auto, printer, count):
self._printing_auto_done_post(auto, printer, count)

Check warning on line 32 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L32

Added line #L32 was not covered by tests

def _on_printing_auto_error(self, e):
self.write({"printing_auto_error": str(e)})

Check warning on line 35 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L35

Added line #L35 was not covered by tests

def _get_printing_auto(self):
return self.auto_printing_ids

Check warning on line 38 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L38

Added line #L38 was not covered by tests

def _do_print_auto(self, printing_auto):
printing_auto.ensure_one()
printer, count = printing_auto.do_print(self)

Check warning on line 42 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L41-L42

Added lines #L41 - L42 were not covered by tests
if count:
self._on_printing_auto_done(printing_auto, printer, count)

Check warning on line 44 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L44

Added line #L44 was not covered by tests

def _handle_print_auto(self, printing_auto):
printing_auto.ensure_one()

Check warning on line 47 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L47

Added line #L47 was not covered by tests
if printing_auto.action_on_error == "raise":
self._do_print_auto(printing_auto)
return
try:
with self.env.cr.savepoint():
self._do_print_auto(printing_auto)
except Exception as e:
_logger.exception(

Check warning on line 55 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L49-L55

Added lines #L49 - L55 were not covered by tests
"An error occurred while printing '%s' for record %s.",
printing_auto,
self,
)
self._on_printing_auto_error(e)

Check warning on line 60 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L60

Added line #L60 was not covered by tests

def handle_print_auto(self):
"""Print some report or attachment directly to the corresponding printer."""
self._on_printing_auto_start()
to_print = {}

Check warning on line 65 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L64-L65

Added lines #L64 - L65 were not covered by tests
for record in self:
for printing_auto in record._get_printing_auto():
if printing_auto not in to_print.keys():
to_print[printing_auto] = record

Check warning on line 69 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L69

Added line #L69 was not covered by tests
else:
to_print[printing_auto] |= record

Check warning on line 71 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L71

Added line #L71 was not covered by tests
for printing_auto, records in to_print.items():
records._handle_print_auto(printing_auto)

Check warning on line 73 in printing_auto_base/models/printing_auto_mixin.py

View check run for this annotation

Codecov / codecov/patch

printing_auto_base/models/printing_auto_mixin.py#L73

Added line #L73 was not covered by tests
4 changes: 4 additions & 0 deletions printing_auto_base/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* Jacques-Etienne Baudoux (BCIM) <[email protected]>
* Michael Tietz (MT Software) <[email protected]>
* Camptocamp
* Christopher Hansen <[email protected]>
4 changes: 4 additions & 0 deletions printing_auto_base/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Base module to support automatic printing of a report or attachments.

Check other repo like stock-logistics-reporting module printing_auto_stock_picking
for printing documents related to a stock transfer.
Loading
Loading