Report to printer CUPS

base_report_to_printer_cups
REPOSITORY
REPOSITORYOCA/report-print-send
GIT
GIThttps://github.com/OCA/report-print-send.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/report-print-send/tree/19.0/base_report_to_printer_cups
VERSION
VERSION 0.2.0
CATEGORY
CATEGORYGeneric Modules/Base
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Camptocamp, LasLabs, Agile Business Group & Domsense, Pegueroles SCP, NaN, Open for Small Business Ltd
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Camptocamp, LasLabs, Agile Business Group & Domsense, Pegueroles SCP, NaN, Open for Small Business Ltd
COMMITTERS
COMMITTERSEmanuel Cino, Weblate, OCA-git-bot, oca-ci, Miquel Alzanillas
WEBSITE
WEBSITEhttps://github.com/OCA/report-print-send
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:40:50
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/report-print-send:
    - base_report_to_printer
odoo/odoo:
    - web
    - base
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES pycups
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module extends *base_report_to_printer* to add support for printing
reports through a CUPS server.

It allows users to configure one or more CUPS servers, automatically
fetch available printers and trays, and send reports directly to them
instead of downloading a PDF.

Main features:
- Manage CUPS servers from the Odoo backend.
- Synchronize available printers and trays with CUPS.
- Define default printing behavior globally, per user, per report, or
  per user and report.
- Test printer connectivity with a **Print Test Page** action.

Typical usage:
- Send reports directly to CUPS printers.
- Configure dedicated trays for pre-printed forms such as payment slips.
- Allow each user to define their own default printer preferences.

Code Analysis

Views touched (8)
XML IDNameModelTypeStatus
printer_update_wizard printing.printer.update.wizard printing.printer.update.wizard form New
printing_job_view_tree_inherit_cups printing.job.tree.inherit.cups printing.job xpath Inherits base_report_to_printer.printing_job_view_tree
printing_printer_view_form_inherit_cups printing.printer.form (in base_report_to_printer) printing.printer xpath Inherits base_report_to_printer.printing_printer_view_form
printing_printer_view_tree_inherit_cups printing.printer.tree printing.printer xpath Inherits base_report_to_printer.printing_printer_view_tree
printing_server_cups_view_form printing.server.form printing.server form New
printing_server_view_search printing.server.search (in base_report_to_printer) printing.server search New
printing_server_view_tree printing.server.tree (in base_report_to_printer) printing.server list New
view_printing_job_form_inherit_cups printing.job.form.inherit.cups printing.job xpath Inherits base_report_to_printer.printing_job_view_form
Models touched (5)

New fields (0)

No new fields.

Public methods (1)
  • behaviour(self)

New fields (6)
  • active Boolean
    default=True help='Unchecked if the job is purged from CUPS.'
  • job_id_cups Integer
    help='CUPS id for this job.' required=True string='Job ID'
  • job_media_progress Integer
    help='Percentage of progress for this job.' required=True string='Media Progress'
  • job_state Selection
    selection_add=[('pending held', 'Pending Held'), ('processing', 'Processing'), ('processing stopped', 'Processing Stopped'), ('canceled', 'Canceled'), ('aborted', 'Aborted')]
  • job_state_reason Selection
    help='Reason for the current job state.' selection=[('none', 'No reason'), ('aborted-by-system', 'Aborted by the system'), ('compression-error', 'Error in the compressed data'), ('cups-filter-crashed', 'CUPS filter crashed'), ('document-access-error', 'The URI cannot be accessed'), ('document-format-error', 'Error in the document'), ('job-canceled-at-device', 'Cancelled at the device'), ('job-canceled-by-operator', 'Cancelled by the printer operator'), ('job-canceled-by-user', 'Cancelled by the user'), ('job-completed-successfully', 'Completed successfully'), ('job-completed-with-errors', 'Completed with some errors'), ('job-completed-with-warnings', 'Completed with some warnings'), ('job-data-insufficient', 'No data has been received'), ('job-hold-until-specified', 'Currently held'), ('job-incoming', 'Files are currently being received'), ('job-interpreting', 'Currently being interpreted'), ('job-outgoing', 'Currently being sent to the printer'), ('job-printing', 'Currently printing'), ('job-queued', 'Queued for printing'), ('job-queued-for-marker', 'Printer needs ink/marker/toner'), ('job-restartable', 'Can be restarted'), ('job-transforming', 'Being transformed into a different format'), ('printer-stopped', 'Printer is stopped'), ('printer-stopped-partly', "Printer state reason set to 'stopped-partly'"), ('processing-to-stop-point', 'Cancelled, but printing already processed pages'), ('queued-in-device', 'Queued at the output device'), ('resources-are-not-ready', 'Resources not available to print the job'), ('service-off-line', 'Held because the printer is offline'), ('submission-interrupted', 'Files were not received in full'), ('unsupported-compression', 'Compressed using an unknown algorithm'), ('unsupported-document-format', 'Unsupported format')] string='State Reason'
  • server_id Many2one → printing.server
    comodel_name='printing.server' help='Server which hosts this job.' related='printer_id.server_id' store=True string='Server'
Public methods (1)
  • cancel(self, purge_job=False)

New fields (6)
  • backend Selection
    ondelete={'cups': 'cascade'} selection_add=[('cups', 'CUPS')]
  • input_tray_ids One2many → printing.tray.input
    comodel_name='printing.tray.input' inverse_name='printer_id' string='Paper Sources'
  • job_ids One2many → printing.job
    comodel_name='printing.job' inverse_name='printer_id' string='Jobs'
  • multi_thread Boolean
    compute='_compute_multi_thread' readonly=False store=True
  • output_tray_ids One2many → printing.tray.output
    comodel_name='printing.tray.output' inverse_name='printer_id' string='Output trays'
  • server_id Many2one → printing.server
    comodel_name='printing.server' string='Server'
Public methods (5)
  • cancel_all_jobs(self, purge_jobs=False)
  • disable(self)
  • enable(self)
  • print_file(self, file_name, report=None, **print_opts)
  • print_test_page(self)

New fields (0)

No new fields.

Public methods (1)
  • action_ok(self)

New fields (9)
  • active Boolean
    default=True help='If checked, this server is useable.'
  • address Char
    default='localhost' help='IP address or hostname of the server' required=True
  • encryption_policy Selection
    help='Encryption Policy to connect to the server. Empty by default.' args: [('0', 'HTTP_ENCRYPT_IF_REQUESTED'), ('1', 'HTTP_ENCRYPT_NEVER'), ('2', 'HTTP_ENCRYPT_REQUIRED'), ('3', 'HTTP_ENCRYPT_ALWAYS')]
  • multi_thread Boolean
  • name Char
    default='Localhost' help='Name of the server.' required=True
  • password Char
    help='Password to connect to the server. Empty by default.'
  • port Integer
    default=631 help='Port of the server.' required=True
  • printer_ids One2many → printing.printer
    comodel_name='printing.printer' help='List of printers available on this server.' inverse_name='server_id' string='Printers List'
  • user Char
    help='User name to connect to the server. Empty by default.'
Public methods (4)
  • action_update_jobs(self)
  • action_update_printers(self)
  • update_jobs(self, which='all', first_job_id=-1)
  • update_printers(self, domain=None, raise_on_error=False)