diff --git a/base_report_to_print_node/README.rst b/base_report_to_print_node/README.rst deleted file mode 100644 index fe2a6c2a..00000000 --- a/base_report_to_print_node/README.rst +++ /dev/null @@ -1,49 +0,0 @@ -.. |company| replace:: ADHOC SA - -.. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png - :alt: ADHOC SA - :target: https://www.adhoc.com.ar - -.. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png - -.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png - :target: https://www.gnu.org/licenses/agpl - :alt: License: AGPL-3 - -=================== -Print Node Printing -=================== - -This module extends the functionality of direct printing. It allows to add your print node printers to odoo - -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: http://runbot.adhoc.com.ar/ - -Bug Tracker -=========== - -Bugs are tracked on `GitHub 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. - -Credits -======= - -Images ------- - -* |company| |icon| - -Contributors ------------- - -Maintainer ----------- - -|company_logo| - -This module is maintained by the |company|. - -To contribute to this module, please visit https://www.adhoc.com.ar. diff --git a/base_report_to_print_node/models/__init__.py b/base_report_to_print_node/models/__init__.py deleted file mode 100644 index be045498..00000000 --- a/base_report_to_print_node/models/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -############################################################################## -# For copyright and license notices, see __manifest__.py file in module root -# directory -############################################################################## -from . import printing_printer -from . import ir_actions_report diff --git a/base_report_to_print_node/models/ir_actions_report.py b/base_report_to_print_node/models/ir_actions_report.py deleted file mode 100644 index fc24676a..00000000 --- a/base_report_to_print_node/models/ir_actions_report.py +++ /dev/null @@ -1,10 +0,0 @@ -from odoo import models - - -class IrActionsReport(models.Model): - _inherit = "ir.actions.report" - - def behaviour(self): - # Parche ADHOC por PR: https://github.com/OCA/report-print-send/pull/367 - self = self.with_context(skip_printer_exception=True) - return super().behaviour() diff --git a/base_report_to_print_node/models/printing_printer.py b/base_report_to_print_node/models/printing_printer.py deleted file mode 100644 index 6963e2cb..00000000 --- a/base_report_to_print_node/models/printing_printer.py +++ /dev/null @@ -1,198 +0,0 @@ -############################################################################## -# For copyright and license notices, see __manifest__.py file in module root -# directory -############################################################################## -import base64 -import json -import logging -import os -import time -import urllib.request -from tempfile import mkstemp -from urllib.error import HTTPError - -from odoo import _, api, fields, models -from odoo.exceptions import RedirectWarning, UserError - -PRINTNODE_URL = "https://api.printnode.com" -TIMEOUT = 20 -_logger = logging.getLogger(__name__) - - -class PrintingPrinter(models.Model): - _inherit = "printing.printer" - - print_node_printer = fields.Boolean(string="Print Node Printer?") - server_id = fields.Many2one(required=False) - - @api.model - def _get_print_node_printer(self, print_nodeId): - return self.env["printing.printer"].search( - [("print_node_printer", "=", True), ("uri", "=", print_nodeId)], limit=1 - ) - - @api.model - def _print_node_status_map(self, state): - return {"online": "available"}.get(state, "unknown") - - @api.model - def update_print_node_printers(self): - _logger.info("Updating Print Node Printers") - pn_printers = self._get_response("printers") - for pn_printer in pn_printers: - printer = self._get_print_node_printer(pn_printer.get("id")) - if not printer: - printer.create( - { - "name": pn_printer["description"], - "system_name": pn_printer["name"], - "model": pn_printer["name"], - "location": pn_printer.get("computer", {}).get("name"), - "uri": pn_printer["id"], - "print_node_printer": True, - "status": self._print_node_status_map(pn_printer["state"]), - "status_message": pn_printer.get("state", False), - } - ) - return True - - @api.model - def update_print_node_printers_status(self): - _logger.info("Updating Print Node Printers Status") - pn_printers = self._get_response("printers") - for pn_printer in pn_printers: - printer = self._get_print_node_printer(pn_printer.get("id")) - if printer: - vals = { - "status": self._print_node_status_map(pn_printer["state"]), - "status_message": pn_printer.get("state", False), - } - printer.write(vals) - - def print_document(self, report, content, **print_opts): - """Print a file - Format could be pdf, qweb-pdf, raw, ... - """ - if len(self) != 1: - _logger.error( - "Print Node print called with %s but singleton is expeted." "Check printers configuration." % self - ) - return super().print_document(report, content, **print_opts) - - if not self.print_node_printer: - return super().print_document(report, content, **print_opts) - - fd, file_name = mkstemp() - try: - os.write(fd, content) - finally: - os.close(fd) - - options = self.print_options(report, **print_opts) - - _logger.debug("Sending job to PrintNode printer %s" % (self.system_name)) - - try: - res = self._submit_job( - self.uri, - options.get("format", report.report_type), - file_name, - options, - ) - _logger.info(f"Printing job '{res}' for document {file_name}") - except Exception as e: - _logger.error("Could not submit job to print node. This is what we get:\n%s" % e) - return True - - def enable(self): - print_node_printers = self.filtered("print_node_printer") - print_node_printers.update_print_node_printers_status() - return super(PrintingPrinter, self - print_node_printers).enable() - - def disable(self): - print_node_printers = self.filtered("print_node_printer") - print_node_printers.write({"status": "unavailable", "status_message": "disabled by user"}) - return super(PrintingPrinter, self - print_node_printers).disable() - - # API interaction - - @api.model - def ReadFile(self, pathname): - """Read contents of a file and return content. - Args: - pathname: string, (path)name of file. - Returns: - string: contents of file. - """ - try: - f = open(pathname, "rb") - try: - s = f.read() - except OSError as error: - _logger.info("Error reading %s\n%s", pathname, error) - finally: - f.close() - return s - except OSError as error: - _logger.error("Error opening %s\n%s", pathname, error) - return None - - @api.model - def _submit_job(self, printerid, jobtype, jobsrc, options): - """Submit a job to printerid with content of dataUrl. - - Args: - printerid: string, the printer id to submit the job to. - jobtype: string, must match the dictionary keys in content and - content_type. - jobsrc: string, points to source for job. Could be a pathname or - id string. - Returns: - boolean: True = submitted, False = errors. - """ - if jobtype in ["qweb-pdf", "pdf", "aeroo"]: - jobtype = "pdf" - elif jobtype in ["qweb-text"]: - jobtype = "txt" - else: - raise UserError(_("Jobtype %s not implemented for Print Node") % (jobtype)) - - content = self.ReadFile(jobsrc) - content = base64.b64encode(content).decode("utf-8") - - # Make the title unique for each job, since the printer by default will - # name the print job file the same as the title. - datehour = time.strftime("%b%d%H%M", time.localtime()) - title = f"{datehour}{jobsrc}" - - data = { - "printerId": printerid, - "title": title, - "contentType": "pdf_base64" if jobtype == "pdf" else "raw_base64", - "content": content, - "source": "created by odoo db: %s" % self.env.cr.dbname, - } - return self._get_response("printjobs", data) - - @api.model - def _get_response(self, service, data=None): - api_key = self.env["ir.config_parameter"].sudo().get_param("base_report_to_print_node.api_key") - if not api_key: - dummy, action_id = self.env["ir.model.data"].get_object_reference( - "base_setup", "action_general_configuration" - ) - msg = _("You haven't configured your 'Print Node Api Key'.") - raise RedirectWarning(msg, action_id, _("Go to the configuration panel")) - request_url = f"{PRINTNODE_URL}/{service}" - headers = { - "authorization": "Basic " + base64.b64encode(api_key.encode("UTF-8")).decode("UTF-8"), - } - if data: - headers["Content-Type"] = "application/json" - data_json = data and json.dumps(data).encode("utf-8") or None - try: - req = urllib.request.Request(request_url, data_json, headers) - response = urllib.request.urlopen(req, timeout=TIMEOUT).read() - except HTTPError: - raise UserError(_("Could not connect to print node. Check your configuration")) - return json.loads(response.decode("utf-8")) diff --git a/base_report_to_print_node/readme/CONFIGURE.rst b/base_report_to_print_node/readme/CONFIGURE.rst deleted file mode 100644 index cd861f47..00000000 --- a/base_report_to_print_node/readme/CONFIGURE.rst +++ /dev/null @@ -1,96 +0,0 @@ -Requirements: - -#. Computer serving as print server: - - * Where the PrintNode client can be installed - * Where the printer to be shared is connected and accessible. - * Have internet access - -#. Printer to share -#. Account registered at https://www.printnode.com/ - -Brefore configure this module, you need to: - -#. Get an API Key from PrintNode: - - #. After creating an account on Printnode go to https://app.printnode.com/app/apikeys (enter the account password if is requested) - #. Enter some description in the "API Key Description" text box like "Odoo" and hit the "CREATE" button. - #. Copy the generated API key. We will need this below. - -#. Installing the PrintNode Client on the print server: - - * Guide for windows users https://www.printnode.com/en/docs/installation - * Guide for windows macOS / OS X - * Guide for Linux (Ubuntu): - - #. Download Cliet binary - - * Go to https://app.printnode.com/app/downloads - * Login - * Download the correct version acording your SO and architecture. For example for Ubuntu 20.04 TLS x64, download PrintNode-4.24.1-ubuntu-20.04-x86_64.tar.gz - #. Install (With UI) - - * uncompress the downloaded file on the directory /usr/local/PrintNode - * go to /usr/local/PrintNode directory and execute the instalator ./PrintNode - #. Install (Console) - - Assuming the file was downloaded in ~/Downloads - - .. code-block:: bash - - tar xf PrintNode-4.24.1-ubuntu-20.04-x86_64.tar.gz - - sudo mv PrintNode-4.24.1-ubuntu-20.04-x86_64 /usr/local/PrintNode - - cd /usr/local/PrintNode - - ./PrintNode --headless --web-interface --web-interface-shutdown --shutdown-on-sigint - - Now you can go to http://localhost:8888/ to configure the client. You can also access here (using the computer's IP instead of localhost) from the lan network (you may need to open port 8888 in the firewall) - -#. Configuring the client. - - * On the web client (or UI) login with your acccount - * Go to "Printers" tab - * The printers installed in the system should appear under this section. With this, your printers will be synchronized with PrintNode - -#. Install Client as service - - .. code-block:: bash - - cd /usr/local/PrintNode - - sudo cp init.sh /etc/init.d/PrintNode - - sudo update-rc.d PrintNode defaults - - sudo systemctl daemon-reload - - sudo /etc/init.d/PrintNode start - - (Optional or for advanced users) You can edit "init.sh" file to modify the user with which this client runs, by default it is done as root. - -#. Testing installation - - * go to https://app.printnode.com/app/print (and login) - * go in the menu to the option "Print Something" - * select: - - * Source: “PrintNode Test Page” - * Printer: name of configurated printer - * Test File: “test.pdf” - * and now hit on "PRINT" button - -#. Odoo configuration - - #. First you need link Print Node with odoo - - * go to settings / general options - * on "integrations" secction enter the API Key under the label "Print Node Api Key" - - #. Printer Configuring - - * go to settings / printing - * hit on "sync printers from cups" and next on "OK" - * after that you can see the printers on list - * open the new printer and mark it as the default printer. diff --git a/base_report_to_print_node/readme/CONTRIBUTORS.rst b/base_report_to_print_node/readme/CONTRIBUTORS.rst deleted file mode 100644 index b0351423..00000000 --- a/base_report_to_print_node/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,2 +0,0 @@ -* Juan José Scarafia -* Andrés Zacchino diff --git a/base_report_to_print_node/readme/DESCRIPTION.rst b/base_report_to_print_node/readme/DESCRIPTION.rst deleted file mode 100644 index 61222469..00000000 --- a/base_report_to_print_node/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -This module extends the functionality of direct printing. It allows to add your print node printers to odoo diff --git a/base_report_to_print_node/readme/HISTORY.rst b/base_report_to_print_node/readme/HISTORY.rst deleted file mode 100644 index 8f9fbe80..00000000 --- a/base_report_to_print_node/readme/HISTORY.rst +++ /dev/null @@ -1,4 +0,0 @@ -13.0.1.0.0 (2021-01-26) -~~~~~~~~~~~~~~~~~~~~~~~ - -* [RELEASE] Port from V11. diff --git a/base_report_to_print_node/readme/INSTALL.rst b/base_report_to_print_node/readme/INSTALL.rst deleted file mode 100644 index 4986e005..00000000 --- a/base_report_to_print_node/readme/INSTALL.rst +++ /dev/null @@ -1 +0,0 @@ -To install this module, you don't need anything extra installs: diff --git a/base_report_to_print_node/readme/USAGE.rst b/base_report_to_print_node/readme/USAGE.rst deleted file mode 100644 index 5e323851..00000000 --- a/base_report_to_print_node/readme/USAGE.rst +++ /dev/null @@ -1,13 +0,0 @@ -Guidelines for use: - - * To update the CUPS printers in *Settings > Printing > Update Printers - from CUPS* - * To print a report on a specific printer you can change - these in *Settings > Printing > Reports* to define default behaviour. - * To print a report on a specific printer for a user, you can - change these in *Settings > Printing > Reports* in - *Specific actions per user* - * Users may also select a default printer in their preferences. - -When no tray is configured for a report and a user, the -default tray setup on the CUPS server is used. diff --git a/base_report_to_print_node/wizards/__init__.py b/base_report_to_print_node/wizards/__init__.py deleted file mode 100644 index c5a86a2d..00000000 --- a/base_report_to_print_node/wizards/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -############################################################################## -# For copyright and license notices, see __manifest__.py file in module root -# directory -############################################################################## -from . import printing_printer_update_wizard -from . import res_config_settings diff --git a/base_report_to_print_node/wizards/printing_printer_update_wizard.py b/base_report_to_print_node/wizards/printing_printer_update_wizard.py deleted file mode 100644 index 09e873ee..00000000 --- a/base_report_to_print_node/wizards/printing_printer_update_wizard.py +++ /dev/null @@ -1,14 +0,0 @@ -############################################################################## -# For copyright and license notices, see __manifest__.py file in module root -# directory -############################################################################## -from odoo import models - - -class PrintingPrinterUpdateWizard(models.TransientModel): - _inherit = "printing.printer.update.wizard" - - def action_ok(self): - self.ensure_one() - self.env["printing.printer"].update_print_node_printers() - return super(PrintingPrinterUpdateWizard, self).action_ok() diff --git a/base_report_to_print_node/wizards/res_config_settings.py b/base_report_to_print_node/wizards/res_config_settings.py deleted file mode 100644 index 5ecf50d6..00000000 --- a/base_report_to_print_node/wizards/res_config_settings.py +++ /dev/null @@ -1,13 +0,0 @@ -############################################################################## -# For copyright and license notices, see __manifest__.py file in module root -# directory -############################################################################## -from odoo import fields, models - - -class ResConfigSettings(models.TransientModel): - _inherit = "res.config.settings" - - print_node_api_key = fields.Char( - config_parameter="base_report_to_print_node.api_key", - ) diff --git a/base_report_to_print_node/wizards/res_config_settings_view.xml b/base_report_to_print_node/wizards/res_config_settings_view.xml deleted file mode 100644 index 1e3d2e26..00000000 --- a/base_report_to_print_node/wizards/res_config_settings_view.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - General Settings - res.config.settings - - - -

Print Node

- -
-
-
-
diff --git a/iot_print_node/README.rst b/iot_print_node/README.rst new file mode 100644 index 00000000..a2795150 --- /dev/null +++ b/iot_print_node/README.rst @@ -0,0 +1,83 @@ +.. |company| replace:: ADHOC SA + +.. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png + :alt: ADHOC SA + :target: https://www.adhoc.com.ar + +.. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png + +.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: https://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + +========================= +IoT Print Node Printing +========================= + +This module integrates PrintNode cloud printing service with Odoo's IoT functionality, allowing you to print documents directly to PrintNode printers without requiring a physical IoT Box. + +Installation +============ + +Before installing this module, you need to: + +1. Have a PrintNode account (https://www.printnode.com/) +2. Get your PrintNode API Key from your PrintNode account settings + +Configuration +============= + +To configure this module: + +1. Go to **IoT > Add PrintNode** +2. Enter a name for your PrintNode IoT Box +3. Enter your PrintNode API Key +4. Click **Add** to create the IoT Box and automatically import your printers +5. Your PrintNode printers will be automatically synced with Odoo + +Usage +===== + +Once configured: + +* Your PrintNode printers will appear in the IoT devices list +* You can print reports directly to PrintNode printers from any Odoo document +* The system will automatically send print jobs to PrintNode cloud service +* You'll receive a notification when a print job is successfully sent + +Features +======== + +* **Cloud-based printing**: Print without a physical IoT Box +* **Automatic printer sync**: Printers are automatically imported from your PrintNode account +* **Easy setup**: Simple wizard to add PrintNode credentials +* **Real-time notifications**: Get notified when print jobs are sent +* **Multiple printer support**: Manage multiple PrintNode printers from a single Odoo instance + +Bug Tracker +=========== + +Bugs are tracked on `GitHub 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. + +Credits +======= + +Images +------ + +* |company| |icon| + +Contributors +------------ + +Maintainer +---------- + +|company_logo| + +This module is maintained by the |company|. + +To contribute to this module, please visit https://www.adhoc.com.ar. diff --git a/base_report_to_print_node/__init__.py b/iot_print_node/__init__.py similarity index 92% rename from base_report_to_print_node/__init__.py rename to iot_print_node/__init__.py index 6c1e1357..173091eb 100644 --- a/base_report_to_print_node/__init__.py +++ b/iot_print_node/__init__.py @@ -3,4 +3,4 @@ # directory ############################################################################## from . import models -from . import wizards +from . import wizard diff --git a/base_report_to_print_node/__manifest__.py b/iot_print_node/__manifest__.py similarity index 78% rename from base_report_to_print_node/__manifest__.py rename to iot_print_node/__manifest__.py index cdca7bb9..eb30f521 100644 --- a/base_report_to_print_node/__manifest__.py +++ b/iot_print_node/__manifest__.py @@ -18,12 +18,16 @@ # ############################################################################## { - "name": "Print Node Printing", - "version": "18.0.1.1.0", + "name": "IOT Print Node Printing", + "version": "19.0.0.1.0", "category": "Generic Modules/Base", - "author": "ADHOC SA, Odoo Community Association (OCA)", + "author": "ADHOC SA", "license": "AGPL-3", - "depends": ["base_report_to_printer"], - "data": ["wizards/res_config_settings_view.xml"], - "installable": False, + "depends": ["iot"], + "data": [ + "security/ir.model.access.csv", + "views/iot_views.xml", + "wizard/add_iot_printnode_views.xml", + ], + "installable": True, } diff --git a/base_report_to_print_node/i18n/es.po b/iot_print_node/i18n/es.po similarity index 100% rename from base_report_to_print_node/i18n/es.po rename to iot_print_node/i18n/es.po diff --git a/base_report_to_print_node/i18n/pt_BR.po b/iot_print_node/i18n/pt_BR.po similarity index 100% rename from base_report_to_print_node/i18n/pt_BR.po rename to iot_print_node/i18n/pt_BR.po diff --git a/iot_print_node/models/__init__.py b/iot_print_node/models/__init__.py new file mode 100644 index 00000000..cc0c7a1e --- /dev/null +++ b/iot_print_node/models/__init__.py @@ -0,0 +1,3 @@ +from . import iot_box +from . import iot_device +from . import ir_actions_report diff --git a/iot_print_node/models/iot_box.py b/iot_print_node/models/iot_box.py new file mode 100644 index 00000000..ac7ee355 --- /dev/null +++ b/iot_print_node/models/iot_box.py @@ -0,0 +1,106 @@ +import base64 +import logging +import time +import uuid + +import requests +from odoo import Command, _, api, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + +PRINTNODE_URL = "https://api.printnode.com" +TIMEOUT = 20 + + +class IotBox(models.Model): + _inherit = "iot.box" + + print_node_api_key = fields.Char("Print Node API Key", readonly=True) + + def open_homepage(self): + self.ensure_one() + if self.print_node_api_key: + return { + "type": "ir.actions.act_url", + "url": "https://api.printnode.com/app/print", + "target": "new", + } + return super().open_homepage() + + @api.model + def _get_response(self, service, data=None): + request_url = f"{PRINTNODE_URL}/{service}" + headers = { + "authorization": "Basic " + base64.b64encode(self.print_node_api_key.encode("UTF-8")).decode("UTF-8"), + } + try: + if data: + headers["Content-Type"] = "application/json" + response = requests.post(request_url, json=data, headers=headers, timeout=TIMEOUT) + response.raise_for_status() + else: + response = requests.get(request_url, headers=headers, timeout=TIMEOUT) + response.raise_for_status() + except requests.RequestException: + raise UserError(_("Could not connect to print node. Check your configuration")) + return response.json() + + def action_print_update_devices(self): + _logger.info("Updating Print Node Printers") + devices = self._get_response("printers") + device_commands = [] + existing_devices = self.device_ids.mapped("identifier") + + for pn_printer in devices: + vals = { + "name": pn_printer["description"], + "identifier": str(pn_printer["id"]), + "type": "printer", + "connection": "printnode_printer", + "connected_status": "connected" if pn_printer["state"] == "online" else "disconnected", + } + if str(pn_printer["id"]) in existing_devices: + del existing_devices[existing_devices.index(str(pn_printer["id"]))] + + if device_id := self.device_ids.filtered(lambda d: d.identifier == str(pn_printer["id"])): + device_commands.append(Command.update(device_id.id, vals)) + else: + device_commands.append(Command.create(vals)) + + for to_deleted_devices in existing_devices: + device_commands.append( + Command.delete(self.device_ids.filtered(lambda d: d.identifier == to_deleted_devices).id) + ) + self.sudo().device_ids = device_commands + + def _print_node_submit_job(self, printerid, jobtype, content): + """Submit a job to printerid with content of dataUrl. + + Args: + printerid: string, the printer id to submit the job to. + jobtype: string, must match the dictionary keys in content and + content_type. + jobsrc: string, points to source for job. Could be a pathname or + id string. + Returns: + boolean: True = submitted, False = errors. + """ + if jobtype in ["qweb-pdf", "pdf", "aeroo"]: + jobtype = "pdf" + elif jobtype in ["qweb-text"]: + jobtype = "txt" + else: + raise UserError(_("Jobtype %s not implemented for Print Node") % (jobtype)) + + # Generate a unique title using timestamp and microseconds + title = f"odoo_print_{int(time.time() * 1000)}_{uuid.uuid4().hex[:8]}" + + data = { + "printerId": printerid, + "title": title, + "contentType": "pdf_base64" if jobtype == "pdf" else "raw_base64", + "content": content.decode("utf-8"), + "source": "created by odoo db: %s" % self.env.cr.dbname, + } + return self._get_response("printjobs", data) diff --git a/iot_print_node/models/iot_device.py b/iot_print_node/models/iot_device.py new file mode 100644 index 00000000..7aa83c89 --- /dev/null +++ b/iot_print_node/models/iot_device.py @@ -0,0 +1,11 @@ +from odoo import fields, models + + +class IotDevice(models.Model): + _inherit = "iot.device" + + # print_node_api_key = fields.Char('Print Node API Key', readonly=True) + connection = fields.Selection( + selection_add=[("printnode_printer", "Print Node Printer")], + ondelete={"printnode_printer": "set null"}, + ) diff --git a/iot_print_node/models/ir_actions_report.py b/iot_print_node/models/ir_actions_report.py new file mode 100644 index 00000000..e9911525 --- /dev/null +++ b/iot_print_node/models/ir_actions_report.py @@ -0,0 +1,30 @@ +from odoo import _, models + + +class IrActionsReport(models.Model): + _inherit = "ir.actions.report" + + def render_document(self, device_id_list, res_ids, data=None): + result = super().render_document(device_id_list, res_ids, data) + filtered_result = [] + for item in result: + iot_box = self.env["iot.box"].browse(item["iotBoxId"]) + if iot_box.print_node_api_key: + job = iot_box._print_node_submit_job( + printerid=item["deviceIdentifier"], + jobtype=self.report_type, + content=item["document"], + ) + if job: + device = iot_box.device_ids.filtered(lambda d: d.identifier == item["deviceIdentifier"]) + printer_name = device.name if device else _("Printer") + self.env.user._bus_send( + "simple_notification", + { + "type": "success", + "message": _("Print job successfully sent to %s via PrintNode", printer_name), + }, + ) + else: + filtered_result.append(item) + return filtered_result diff --git a/iot_print_node/security/ir.model.access.csv b/iot_print_node/security/ir.model.access.csv new file mode 100644 index 00000000..3919d708 --- /dev/null +++ b/iot_print_node/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_add_iot_printnode_admin,add.iot.printnode.admin,model_add_iot_printnode,iot.group_iot_admin,1,1,1,1 +access_add_iot_printnode_user,add.iot.printnode.user,model_add_iot_printnode,base.group_user,1,1,1,0 diff --git a/iot_print_node/views/iot_views.xml b/iot_print_node/views/iot_views.xml new file mode 100644 index 00000000..b1ff7f54 --- /dev/null +++ b/iot_print_node/views/iot_views.xml @@ -0,0 +1,12 @@ + + + iot.box.view.form + iot.box + + + + + + diff --git a/iot_print_node/wizard/__init__.py b/iot_print_node/wizard/__init__.py new file mode 100644 index 00000000..7a275a7d --- /dev/null +++ b/iot_print_node/wizard/__init__.py @@ -0,0 +1 @@ +from . import add_iot_printnode diff --git a/iot_print_node/wizard/add_iot_printnode.py b/iot_print_node/wizard/add_iot_printnode.py new file mode 100644 index 00000000..b7a49b6d --- /dev/null +++ b/iot_print_node/wizard/add_iot_printnode.py @@ -0,0 +1,40 @@ +############################################################################## +# For copyright and license notices, see __manifest__.py file in module root +# directory +############################################################################## +from odoo import fields, models + + +class AddIotPrintnode(models.TransientModel): + _name = "add.iot.printnode" + _description = "Add IoT PrintNode" + + name = fields.Char( + required=True, + ) + print_node_api_key = fields.Char( + required=True, + ) + + def action_add_iot_printnode_box(self): + self.ensure_one() + iot_box = ( + self.env["iot.box"] + .sudo() + .create( + { + "name": self.name, + "print_node_api_key": self.print_node_api_key, + "token": self.print_node_api_key, + } + ) + ) + iot_box.action_print_update_devices() + + return { + "type": "ir.actions.act_window", + "res_model": "iot.box", + "res_id": iot_box.id, + "view_mode": "form", + "target": "current", + } diff --git a/iot_print_node/wizard/add_iot_printnode_views.xml b/iot_print_node/wizard/add_iot_printnode_views.xml new file mode 100644 index 00000000..3db9bf40 --- /dev/null +++ b/iot_print_node/wizard/add_iot_printnode_views.xml @@ -0,0 +1,38 @@ + + + + + + add.iot.printnode.form + add.iot.printnode + +
+ + + + +
+
+
+
+
+ + + + Add IoT PrintNode + add.iot.printnode + form + new + + + + + +