mirror of
https://github.com/OCA/report-print-send.git
synced 2025-02-16 07:11:31 +02:00
[FIX] .travis.yml: Update definition
This commit is contained in:
committed by
Carlos Roca
parent
b1103c7b6d
commit
226d4b2c31
@@ -6,30 +6,28 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
{
|
{
|
||||||
'name': "Report to printer",
|
"name": "Report to printer",
|
||||||
'version': '13.0.1.0.0',
|
"version": "13.0.1.0.0",
|
||||||
'category': 'Generic Modules/Base',
|
"category": "Generic Modules/Base",
|
||||||
'author': "Agile Business Group & Domsense, Pegueroles SCP, NaN,"
|
"author": "Agile Business Group & Domsense, Pegueroles SCP, NaN,"
|
||||||
" LasLabs, Camptocamp, Odoo Community Association (OCA),"
|
" LasLabs, Camptocamp, Odoo Community Association (OCA),"
|
||||||
" Open for Small Business Ltd",
|
" Open for Small Business Ltd",
|
||||||
'website': 'http://www.agilebg.com',
|
"website": "http://www.agilebg.com",
|
||||||
'license': 'AGPL-3',
|
"license": "AGPL-3",
|
||||||
"depends": ['web'],
|
"depends": ["web"],
|
||||||
'data': [
|
"data": [
|
||||||
'data/printing_data.xml',
|
"data/printing_data.xml",
|
||||||
'security/security.xml',
|
"security/security.xml",
|
||||||
'views/assets.xml',
|
"views/assets.xml",
|
||||||
'views/printing_printer.xml',
|
"views/printing_printer.xml",
|
||||||
'views/printing_server.xml',
|
"views/printing_server.xml",
|
||||||
'views/printing_job.xml',
|
"views/printing_job.xml",
|
||||||
'views/printing_report.xml',
|
"views/printing_report.xml",
|
||||||
'views/res_users.xml',
|
"views/res_users.xml",
|
||||||
'views/ir_actions_report.xml',
|
"views/ir_actions_report.xml",
|
||||||
'wizards/printing_printer_update_wizard_view.xml',
|
"wizards/printing_printer_update_wizard_view.xml",
|
||||||
],
|
],
|
||||||
'installable': True,
|
"installable": True,
|
||||||
'application': False,
|
"application": False,
|
||||||
'external_dependencies': {
|
"external_dependencies": {"python": ["pycups"]},
|
||||||
'python': ['pycups'],
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
from . import ir_actions_report
|
from . import ir_actions_report
|
||||||
from . import printing_action
|
from . import printing_action
|
||||||
from . import printing_job
|
from . import printing_job
|
||||||
|
|||||||
@@ -5,35 +5,33 @@
|
|||||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import api, exceptions, fields, models, _
|
from odoo import _, api, exceptions, fields, models
|
||||||
|
|
||||||
|
|
||||||
class IrActionsReport(models.Model):
|
class IrActionsReport(models.Model):
|
||||||
_inherit = 'ir.actions.report'
|
_inherit = "ir.actions.report"
|
||||||
|
|
||||||
property_printing_action_id = fields.Many2one(
|
property_printing_action_id = fields.Many2one(
|
||||||
comodel_name='printing.action',
|
comodel_name="printing.action",
|
||||||
string='Default Behaviour',
|
string="Default Behaviour",
|
||||||
company_dependent=True,
|
company_dependent=True,
|
||||||
)
|
)
|
||||||
printing_printer_id = fields.Many2one(
|
printing_printer_id = fields.Many2one(
|
||||||
comodel_name='printing.printer',
|
comodel_name="printing.printer", string="Default Printer"
|
||||||
string='Default Printer'
|
|
||||||
)
|
)
|
||||||
printer_tray_id = fields.Many2one(
|
printer_tray_id = fields.Many2one(
|
||||||
comodel_name='printing.tray',
|
comodel_name="printing.tray",
|
||||||
string='Paper Source',
|
string="Paper Source",
|
||||||
domain="[('printer_id', '=', printing_printer_id)]",
|
domain="[('printer_id', '=', printing_printer_id)]",
|
||||||
)
|
)
|
||||||
printing_action_ids = fields.One2many(
|
printing_action_ids = fields.One2many(
|
||||||
comodel_name='printing.report.xml.action',
|
comodel_name="printing.report.xml.action",
|
||||||
inverse_name='report_id',
|
inverse_name="report_id",
|
||||||
string='Actions',
|
string="Actions",
|
||||||
help='This field allows configuring action and printer on a per '
|
help="This field allows configuring action and printer on a per " "user basis",
|
||||||
'user basis'
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.onchange('printing_printer_id')
|
@api.onchange("printing_printer_id")
|
||||||
def onchange_printing_printer_id(self):
|
def onchange_printing_printer_id(self):
|
||||||
""" Reset the tray when the printer is changed """
|
""" Reset the tray when the printer is changed """
|
||||||
self.printer_tray_id = False
|
self.printer_tray_id = False
|
||||||
@@ -49,68 +47,69 @@ class IrActionsReport(models.Model):
|
|||||||
return {}
|
return {}
|
||||||
result = report.behaviour()
|
result = report.behaviour()
|
||||||
serializable_result = {
|
serializable_result = {
|
||||||
'action': result['action'],
|
"action": result["action"],
|
||||||
'printer_name': result['printer'].name,
|
"printer_name": result["printer"].name,
|
||||||
}
|
}
|
||||||
return serializable_result
|
return serializable_result
|
||||||
|
|
||||||
def _get_user_default_print_behaviour(self):
|
def _get_user_default_print_behaviour(self):
|
||||||
printer_obj = self.env['printing.printer']
|
printer_obj = self.env["printing.printer"]
|
||||||
user = self.env.user
|
user = self.env.user
|
||||||
return dict(
|
return dict(
|
||||||
action=user.printing_action or 'client',
|
action=user.printing_action or "client",
|
||||||
printer=user.printing_printer_id or printer_obj.get_default(),
|
printer=user.printing_printer_id or printer_obj.get_default(),
|
||||||
tray=str(user.printer_tray_id.system_name) if
|
tray=str(user.printer_tray_id.system_name)
|
||||||
user.printer_tray_id else False
|
if user.printer_tray_id
|
||||||
|
else False,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_report_default_print_behaviour(self):
|
def _get_report_default_print_behaviour(self):
|
||||||
result = {}
|
result = {}
|
||||||
report_action = self.property_printing_action_id
|
report_action = self.property_printing_action_id
|
||||||
if report_action and report_action.action_type != 'user_default':
|
if report_action and report_action.action_type != "user_default":
|
||||||
result['action'] = report_action.action_type
|
result["action"] = report_action.action_type
|
||||||
if self.printing_printer_id:
|
if self.printing_printer_id:
|
||||||
result['printer'] = self.printing_printer_id
|
result["printer"] = self.printing_printer_id
|
||||||
if self.printer_tray_id:
|
if self.printer_tray_id:
|
||||||
result['tray'] = self.printer_tray_id.system_name
|
result["tray"] = self.printer_tray_id.system_name
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def behaviour(self):
|
def behaviour(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
printing_act_obj = self.env['printing.report.xml.action']
|
printing_act_obj = self.env["printing.report.xml.action"]
|
||||||
|
|
||||||
result = self._get_user_default_print_behaviour()
|
result = self._get_user_default_print_behaviour()
|
||||||
result.update(self._get_report_default_print_behaviour())
|
result.update(self._get_report_default_print_behaviour())
|
||||||
|
|
||||||
# Retrieve report-user specific values
|
# Retrieve report-user specific values
|
||||||
print_action = printing_act_obj.search([
|
print_action = printing_act_obj.search(
|
||||||
('report_id', '=', self.id),
|
[
|
||||||
('user_id', '=', self.env.uid),
|
("report_id", "=", self.id),
|
||||||
('action', '!=', 'user_default'),
|
("user_id", "=", self.env.uid),
|
||||||
], limit=1)
|
("action", "!=", "user_default"),
|
||||||
|
],
|
||||||
|
limit=1,
|
||||||
|
)
|
||||||
if print_action:
|
if print_action:
|
||||||
# For some reason design takes report defaults over
|
# For some reason design takes report defaults over
|
||||||
# False action entries so we must allow for that here
|
# False action entries so we must allow for that here
|
||||||
result.update({k: v for k, v in
|
result.update({k: v for k, v in print_action.behaviour().items() if v})
|
||||||
print_action.behaviour().items() if v})
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def print_document(self, record_ids, data=None):
|
def print_document(self, record_ids, data=None):
|
||||||
""" Print a document, do not return the document file """
|
""" Print a document, do not return the document file """
|
||||||
document, doc_format = self.with_context(
|
document, doc_format = self.with_context(
|
||||||
must_skip_send_to_printer=True).render_qweb_pdf(
|
must_skip_send_to_printer=True
|
||||||
record_ids, data=data)
|
).render_qweb_pdf(record_ids, data=data)
|
||||||
behaviour = self.behaviour()
|
behaviour = self.behaviour()
|
||||||
printer = behaviour.pop('printer', None)
|
printer = behaviour.pop("printer", None)
|
||||||
|
|
||||||
if not printer:
|
if not printer:
|
||||||
raise exceptions.Warning(
|
raise exceptions.Warning(_("No printer configured to print this report."))
|
||||||
_('No printer configured to print this report.')
|
|
||||||
)
|
|
||||||
# TODO should we use doc_format instead of report_type
|
# TODO should we use doc_format instead of report_type
|
||||||
return printer.print_document(self, document,
|
return printer.print_document(
|
||||||
doc_format=self.report_type,
|
self, document, doc_format=self.report_type, **behaviour
|
||||||
**behaviour)
|
)
|
||||||
|
|
||||||
def _can_print_report(self, behaviour, printer, document):
|
def _can_print_report(self, behaviour, printer, document):
|
||||||
"""Predicate that decide if report can be sent to printer
|
"""Predicate that decide if report can be sent to printer
|
||||||
@@ -118,16 +117,16 @@ class IrActionsReport(models.Model):
|
|||||||
If you want to prevent `render_qweb_pdf` to send report you can set
|
If you want to prevent `render_qweb_pdf` to send report you can set
|
||||||
the `must_skip_send_to_printer` key to True in the context
|
the `must_skip_send_to_printer` key to True in the context
|
||||||
"""
|
"""
|
||||||
if self.env.context.get('must_skip_send_to_printer'):
|
if self.env.context.get("must_skip_send_to_printer"):
|
||||||
return False
|
return False
|
||||||
if behaviour['action'] == 'server' and printer and document:
|
if behaviour["action"] == "server" and printer and document:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def report_action(self, docids, data=None, config=True):
|
def report_action(self, docids, data=None, config=True):
|
||||||
res = super().report_action(docids, data=data, config=config)
|
res = super().report_action(docids, data=data, config=config)
|
||||||
if not res.get('id'):
|
if not res.get("id"):
|
||||||
res['id'] = self.id
|
res["id"] = self.id
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def render_qweb_pdf(self, res_ids=None, data=None):
|
def render_qweb_pdf(self, res_ids=None, data=None):
|
||||||
@@ -137,14 +136,16 @@ class IrActionsReport(models.Model):
|
|||||||
generated document as well.
|
generated document as well.
|
||||||
"""
|
"""
|
||||||
document, doc_format = super(IrActionsReport, self).render_qweb_pdf(
|
document, doc_format = super(IrActionsReport, self).render_qweb_pdf(
|
||||||
res_ids=res_ids, data=data)
|
res_ids=res_ids, data=data
|
||||||
|
)
|
||||||
|
|
||||||
behaviour = self.behaviour()
|
behaviour = self.behaviour()
|
||||||
printer = behaviour.pop('printer', None)
|
printer = behaviour.pop("printer", None)
|
||||||
can_print_report = self._can_print_report(behaviour, printer, document)
|
can_print_report = self._can_print_report(behaviour, printer, document)
|
||||||
|
|
||||||
if can_print_report:
|
if can_print_report:
|
||||||
printer.print_document(self, document, doc_format=self.report_type,
|
printer.print_document(
|
||||||
**behaviour)
|
self, document, doc_format=self.report_type, **behaviour
|
||||||
|
)
|
||||||
|
|
||||||
return document, doc_format
|
return document, doc_format
|
||||||
|
|||||||
@@ -5,24 +5,22 @@
|
|||||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import models, fields, api
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
class PrintingAction(models.Model):
|
class PrintingAction(models.Model):
|
||||||
_name = 'printing.action'
|
_name = "printing.action"
|
||||||
_description = 'Print Job Action'
|
_description = "Print Job Action"
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _available_action_types(self):
|
def _available_action_types(self):
|
||||||
return [
|
return [
|
||||||
('server', 'Send to Printer'),
|
("server", "Send to Printer"),
|
||||||
('client', 'Send to Client'),
|
("client", "Send to Client"),
|
||||||
('user_default', "Use user's defaults"),
|
("user_default", "Use user's defaults"),
|
||||||
]
|
]
|
||||||
|
|
||||||
name = fields.Char(required=True)
|
name = fields.Char(required=True)
|
||||||
action_type = fields.Selection(
|
action_type = fields.Selection(
|
||||||
selection=_available_action_types,
|
selection=_available_action_types, string="Type", required=True
|
||||||
string='Type',
|
|
||||||
required=True,
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,87 +2,110 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from odoo import models, fields
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PrintingJob(models.Model):
|
class PrintingJob(models.Model):
|
||||||
_name = 'printing.job'
|
_name = "printing.job"
|
||||||
_description = 'Printing Job'
|
_description = "Printing Job"
|
||||||
_order = 'job_id_cups DESC'
|
_order = "job_id_cups DESC"
|
||||||
|
|
||||||
name = fields.Char(help='Job name.')
|
name = fields.Char(help="Job name.")
|
||||||
active = fields.Boolean(
|
active = fields.Boolean(
|
||||||
default=True, help='Unchecked if the job is purged from cups.')
|
default=True, help="Unchecked if the job is purged from cups."
|
||||||
|
)
|
||||||
job_id_cups = fields.Integer(
|
job_id_cups = fields.Integer(
|
||||||
string='Job ID', required=True,
|
string="Job ID", required=True, help="CUPS id for this job."
|
||||||
help='CUPS id for this job.')
|
)
|
||||||
server_id = fields.Many2one(
|
server_id = fields.Many2one(
|
||||||
comodel_name='printing.server', string='Server',
|
comodel_name="printing.server",
|
||||||
related='printer_id.server_id', store=True,
|
string="Server",
|
||||||
help='Server which hosts this job.')
|
related="printer_id.server_id",
|
||||||
|
store=True,
|
||||||
|
help="Server which hosts this job.",
|
||||||
|
)
|
||||||
printer_id = fields.Many2one(
|
printer_id = fields.Many2one(
|
||||||
comodel_name='printing.printer', string='Printer', required=True,
|
comodel_name="printing.printer",
|
||||||
ondelete='cascade', help='Printer used for this job.')
|
string="Printer",
|
||||||
|
required=True,
|
||||||
|
ondelete="cascade",
|
||||||
|
help="Printer used for this job.",
|
||||||
|
)
|
||||||
job_media_progress = fields.Integer(
|
job_media_progress = fields.Integer(
|
||||||
string='Media Progress', required=True,
|
string="Media Progress",
|
||||||
help='Percentage of progress for this job.')
|
required=True,
|
||||||
|
help="Percentage of progress for this job.",
|
||||||
|
)
|
||||||
time_at_creation = fields.Datetime(
|
time_at_creation = fields.Datetime(
|
||||||
required=True, help='Date and time of creation for this job.')
|
required=True, help="Date and time of creation for this job."
|
||||||
time_at_processing = fields.Datetime(
|
)
|
||||||
help='Date and time of process for this job.')
|
time_at_processing = fields.Datetime(help="Date and time of process for this job.")
|
||||||
time_at_completed = fields.Datetime(
|
time_at_completed = fields.Datetime(
|
||||||
help='Date and time of completion for this job.')
|
help="Date and time of completion for this job."
|
||||||
job_state = fields.Selection(selection=[
|
)
|
||||||
('pending', 'Pending'),
|
job_state = fields.Selection(
|
||||||
('pending held', 'Pending Held'),
|
selection=[
|
||||||
('processing', 'Processing'),
|
("pending", "Pending"),
|
||||||
('processing stopped', 'Processing Stopped'),
|
("pending held", "Pending Held"),
|
||||||
('canceled', 'Canceled'),
|
("processing", "Processing"),
|
||||||
('aborted', 'Aborted'),
|
("processing stopped", "Processing Stopped"),
|
||||||
('completed', 'Completed'),
|
("canceled", "Canceled"),
|
||||||
('unknown', 'Unknown'),
|
("aborted", "Aborted"),
|
||||||
], string='State', help='Current state of the job.')
|
("completed", "Completed"),
|
||||||
job_state_reason = fields.Selection(selection=[
|
("unknown", "Unknown"),
|
||||||
('none', 'No reason'),
|
],
|
||||||
('aborted-by-system', 'Aborted by the system'),
|
string="State",
|
||||||
('compression-error', 'Error in the compressed data'),
|
help="Current state of the job.",
|
||||||
('document-access-error', 'The URI cannot be accessed'),
|
)
|
||||||
('document-format-error', 'Error in the document'),
|
job_state_reason = fields.Selection(
|
||||||
('job-canceled-at-device', 'Cancelled at the device'),
|
selection=[
|
||||||
('job-canceled-by-operator', 'Cancelled by the printer operator'),
|
("none", "No reason"),
|
||||||
('job-canceled-by-user', 'Cancelled by the user'),
|
("aborted-by-system", "Aborted by the system"),
|
||||||
('job-completed-successfully', 'Completed successfully'),
|
("compression-error", "Error in the compressed data"),
|
||||||
('job-completed-with-errors', 'Completed with some errors'),
|
("document-access-error", "The URI cannot be accessed"),
|
||||||
('job-completed(with-warnings', 'Completed with some warnings'),
|
("document-format-error", "Error in the document"),
|
||||||
('job-data-insufficient', 'No data has been received'),
|
("job-canceled-at-device", "Cancelled at the device"),
|
||||||
('job-hold-until-specified', 'Currently held'),
|
("job-canceled-by-operator", "Cancelled by the printer operator"),
|
||||||
('job-incoming', 'Files are currently being received'),
|
("job-canceled-by-user", "Cancelled by the user"),
|
||||||
('job-interpreting', 'Currently being interpreted'),
|
("job-completed-successfully", "Completed successfully"),
|
||||||
('job-outgoing', 'Currently being sent to the printer'),
|
("job-completed-with-errors", "Completed with some errors"),
|
||||||
('job-printing', 'Currently printing'),
|
("job-completed(with-warnings", "Completed with some warnings"),
|
||||||
('job-queued', 'Queued for printing'),
|
("job-data-insufficient", "No data has been received"),
|
||||||
('job-queued-for-marker', 'Printer needs ink/marker/toner'),
|
("job-hold-until-specified", "Currently held"),
|
||||||
('job-restartable', 'Can be restarted'),
|
("job-incoming", "Files are currently being received"),
|
||||||
('job-transforming', 'Being transformed into a different format'),
|
("job-interpreting", "Currently being interpreted"),
|
||||||
('printer-stopped', 'Printer is stopped'),
|
("job-outgoing", "Currently being sent to the printer"),
|
||||||
('printer-stopped-partly',
|
("job-printing", "Currently printing"),
|
||||||
'Printer state reason set to \'stopped-partly\''),
|
("job-queued", "Queued for printing"),
|
||||||
('processing-to-stop-point',
|
("job-queued-for-marker", "Printer needs ink/marker/toner"),
|
||||||
'Cancelled, but printing already processed pages'),
|
("job-restartable", "Can be restarted"),
|
||||||
('queued-in-device', 'Queued at the output device'),
|
("job-transforming", "Being transformed into a different format"),
|
||||||
('resources-are-not-ready',
|
("printer-stopped", "Printer is stopped"),
|
||||||
'Resources not available to print the job'),
|
("printer-stopped-partly", "Printer state reason set to 'stopped-partly'"),
|
||||||
('service-off-line', 'Held because the printer is offline'),
|
(
|
||||||
('submission-interrupted', 'Files were not received in full'),
|
"processing-to-stop-point",
|
||||||
('unsupported-compression', 'Compressed using an unknown algorithm'),
|
"Cancelled, but printing already processed pages",
|
||||||
('unsupported-document-format', 'Unsupported format'),
|
),
|
||||||
], string='State Reason', help='Reason for the current job state.')
|
("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",
|
||||||
|
help="Reason for the current job state.",
|
||||||
|
)
|
||||||
|
|
||||||
_sql_constraints = [
|
_sql_constraints = [
|
||||||
('job_id_cups_unique', 'UNIQUE(job_id_cups, server_id)',
|
(
|
||||||
'The id of the job must be unique per server !'),
|
"job_id_cups_unique",
|
||||||
|
"UNIQUE(job_id_cups, server_id)",
|
||||||
|
"The id of the job must be unique per server !",
|
||||||
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
def action_cancel(self):
|
def action_cancel(self):
|
||||||
@@ -98,7 +121,6 @@ class PrintingJob(models.Model):
|
|||||||
connection.cancelJob(job.job_id_cups, purge_job=purge_job)
|
connection.cancelJob(job.job_id_cups, purge_job=purge_job)
|
||||||
|
|
||||||
# Update jobs' states info Odoo
|
# Update jobs' states info Odoo
|
||||||
self.mapped('server_id').update_jobs(
|
self.mapped("server_id").update_jobs(which="all", first_job_id=job.job_id_cups)
|
||||||
which='all', first_job_id=job.job_id_cups)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -11,15 +11,14 @@ import logging
|
|||||||
import os
|
import os
|
||||||
from tempfile import mkstemp
|
from tempfile import mkstemp
|
||||||
|
|
||||||
from odoo import models, fields
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import cups
|
import cups
|
||||||
except ImportError:
|
except ImportError:
|
||||||
_logger.debug('Cannot `import cups`.')
|
_logger.debug("Cannot `import cups`.")
|
||||||
|
|
||||||
|
|
||||||
class PrintingPrinter(models.Model):
|
class PrintingPrinter(models.Model):
|
||||||
@@ -27,63 +26,65 @@ class PrintingPrinter(models.Model):
|
|||||||
Printers
|
Printers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_name = 'printing.printer'
|
_name = "printing.printer"
|
||||||
_description = 'Printer'
|
_description = "Printer"
|
||||||
_order = 'name'
|
_order = "name"
|
||||||
|
|
||||||
name = fields.Char(required=True, index=True)
|
name = fields.Char(required=True, index=True)
|
||||||
server_id = fields.Many2one(
|
server_id = fields.Many2one(
|
||||||
comodel_name='printing.server', string='Server', required=True,
|
comodel_name="printing.server",
|
||||||
help='Server used to access this printer.')
|
string="Server",
|
||||||
|
required=True,
|
||||||
|
help="Server used to access this printer.",
|
||||||
|
)
|
||||||
job_ids = fields.One2many(
|
job_ids = fields.One2many(
|
||||||
comodel_name='printing.job', inverse_name='printer_id', string='Jobs',
|
comodel_name="printing.job",
|
||||||
help='Jobs printed on this printer.')
|
inverse_name="printer_id",
|
||||||
|
string="Jobs",
|
||||||
|
help="Jobs printed on this printer.",
|
||||||
|
)
|
||||||
system_name = fields.Char(required=True, index=True)
|
system_name = fields.Char(required=True, index=True)
|
||||||
default = fields.Boolean(readonly=True)
|
default = fields.Boolean(readonly=True)
|
||||||
status = fields.Selection(
|
status = fields.Selection(
|
||||||
selection=[
|
selection=[
|
||||||
('unavailable', 'Unavailable'),
|
("unavailable", "Unavailable"),
|
||||||
('printing', 'Printing'),
|
("printing", "Printing"),
|
||||||
('unknown', 'Unknown'),
|
("unknown", "Unknown"),
|
||||||
('available', 'Available'),
|
("available", "Available"),
|
||||||
('error', 'Error'),
|
("error", "Error"),
|
||||||
('server-error', 'Server Error'),
|
("server-error", "Server Error"),
|
||||||
],
|
],
|
||||||
required=True,
|
required=True,
|
||||||
readonly=True,
|
readonly=True,
|
||||||
default='unknown')
|
default="unknown",
|
||||||
|
)
|
||||||
status_message = fields.Char(readonly=True)
|
status_message = fields.Char(readonly=True)
|
||||||
model = fields.Char(readonly=True)
|
model = fields.Char(readonly=True)
|
||||||
location = fields.Char(readonly=True)
|
location = fields.Char(readonly=True)
|
||||||
uri = fields.Char(string='URI', readonly=True)
|
uri = fields.Char(string="URI", readonly=True)
|
||||||
tray_ids = fields.One2many(comodel_name='printing.tray',
|
tray_ids = fields.One2many(
|
||||||
inverse_name='printer_id',
|
comodel_name="printing.tray", inverse_name="printer_id", string="Paper Sources"
|
||||||
string='Paper Sources')
|
)
|
||||||
|
|
||||||
def _prepare_update_from_cups(self, cups_connection, cups_printer):
|
def _prepare_update_from_cups(self, cups_connection, cups_printer):
|
||||||
mapping = {
|
mapping = {3: "available", 4: "printing", 5: "error"}
|
||||||
3: 'available',
|
|
||||||
4: 'printing',
|
|
||||||
5: 'error'
|
|
||||||
}
|
|
||||||
vals = {
|
vals = {
|
||||||
'name': cups_printer['printer-info'],
|
"name": cups_printer["printer-info"],
|
||||||
'model': cups_printer.get('printer-make-and-model', False),
|
"model": cups_printer.get("printer-make-and-model", False),
|
||||||
'location': cups_printer.get('printer-location', False),
|
"location": cups_printer.get("printer-location", False),
|
||||||
'uri': cups_printer.get('device-uri', False),
|
"uri": cups_printer.get("device-uri", False),
|
||||||
'status': mapping.get(cups_printer.get(
|
"status": mapping.get(cups_printer.get("printer-state"), "unknown"),
|
||||||
'printer-state'), 'unknown'),
|
"status_message": cups_printer.get("printer-state-message", ""),
|
||||||
'status_message': cups_printer.get('printer-state-message', ''),
|
|
||||||
}
|
}
|
||||||
printer_uri = cups_printer['printer-uri-supported']
|
printer_uri = cups_printer["printer-uri-supported"]
|
||||||
printer_system_name = printer_uri[printer_uri.rfind('/') + 1:]
|
printer_system_name = printer_uri[printer_uri.rfind("/") + 1 :]
|
||||||
ppd_info = cups_connection.getPPD3(printer_system_name)
|
ppd_info = cups_connection.getPPD3(printer_system_name)
|
||||||
ppd_path = ppd_info[2]
|
ppd_path = ppd_info[2]
|
||||||
if not ppd_path:
|
if not ppd_path:
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
ppd = cups.PPD(ppd_path)
|
ppd = cups.PPD(ppd_path)
|
||||||
option = ppd.findOption('InputSlot')
|
option = ppd.findOption("InputSlot")
|
||||||
try:
|
try:
|
||||||
os.unlink(ppd_path)
|
os.unlink(ppd_path)
|
||||||
except OSError as err:
|
except OSError as err:
|
||||||
@@ -94,25 +95,29 @@ class PrintingPrinter(models.Model):
|
|||||||
if not option:
|
if not option:
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
vals['tray_ids'] = []
|
vals["tray_ids"] = []
|
||||||
cups_trays = {
|
cups_trays = {
|
||||||
tray_option['choice']: tray_option['text']
|
tray_option["choice"]: tray_option["text"] for tray_option in option.choices
|
||||||
for tray_option in option.choices
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add new trays
|
# Add new trays
|
||||||
vals['tray_ids'].extend([
|
vals["tray_ids"].extend(
|
||||||
(0, 0, {'name': text, 'system_name': choice})
|
[
|
||||||
for choice, text in cups_trays.items()
|
(0, 0, {"name": text, "system_name": choice})
|
||||||
if choice not in self.tray_ids.mapped('system_name')
|
for choice, text in cups_trays.items()
|
||||||
])
|
if choice not in self.tray_ids.mapped("system_name")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
# Remove deleted trays
|
# Remove deleted trays
|
||||||
vals['tray_ids'].extend([
|
vals["tray_ids"].extend(
|
||||||
(2, tray.id)
|
[
|
||||||
for tray in self.tray_ids.filtered(
|
(2, tray.id)
|
||||||
lambda record: record.system_name not in cups_trays.keys())
|
for tray in self.tray_ids.filtered(
|
||||||
])
|
lambda record: record.system_name not in cups_trays.keys()
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
return vals
|
return vals
|
||||||
|
|
||||||
def print_document(self, report, content, **print_opts):
|
def print_document(self, report, content, **print_opts):
|
||||||
@@ -126,12 +131,11 @@ class PrintingPrinter(models.Model):
|
|||||||
finally:
|
finally:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
|
|
||||||
return self.print_file(
|
return self.print_file(file_name, report=report, **print_opts)
|
||||||
file_name, report=report, **print_opts)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _set_option_doc_format(report, value):
|
def _set_option_doc_format(report, value):
|
||||||
return {'raw': 'True'} if value == 'raw' else {}
|
return {"raw": "True"} if value == "raw" else {}
|
||||||
|
|
||||||
# Backwards compatibility of builtin used as kwarg
|
# Backwards compatibility of builtin used as kwarg
|
||||||
_set_option_format = _set_option_doc_format
|
_set_option_format = _set_option_doc_format
|
||||||
@@ -139,7 +143,7 @@ class PrintingPrinter(models.Model):
|
|||||||
def _set_option_tray(self, report, value):
|
def _set_option_tray(self, report, value):
|
||||||
"""Note we use self here as some older PPD use tray
|
"""Note we use self here as some older PPD use tray
|
||||||
rather than InputSlot so we may need to query printer in override"""
|
rather than InputSlot so we may need to query printer in override"""
|
||||||
return {'InputSlot': str(value)} if value else {}
|
return {"InputSlot": str(value)} if value else {}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _set_option_noop(report, value):
|
def _set_option_noop(report, value):
|
||||||
@@ -152,8 +156,7 @@ class PrintingPrinter(models.Model):
|
|||||||
options = {}
|
options = {}
|
||||||
for option, value in print_opts.items():
|
for option, value in print_opts.items():
|
||||||
try:
|
try:
|
||||||
options.update(getattr(
|
options.update(getattr(self, "_set_option_%s" % option)(report, value))
|
||||||
self, '_set_option_%s' % option)(report, value))
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
options[option] = str(value)
|
options[option] = str(value)
|
||||||
return options
|
return options
|
||||||
@@ -165,33 +168,30 @@ class PrintingPrinter(models.Model):
|
|||||||
options = self.print_options(report=report, **print_opts)
|
options = self.print_options(report=report, **print_opts)
|
||||||
|
|
||||||
_logger.debug(
|
_logger.debug(
|
||||||
'Sending job to CUPS printer %s on %s'
|
"Sending job to CUPS printer %s on %s"
|
||||||
% (self.system_name, self.server_id.address))
|
% (self.system_name, self.server_id.address)
|
||||||
connection.printFile(self.system_name,
|
)
|
||||||
file_name,
|
connection.printFile(self.system_name, file_name, file_name, options=options)
|
||||||
file_name,
|
_logger.info(
|
||||||
options=options)
|
"Printing job: '{}' on {}".format(file_name, self.server_id.address)
|
||||||
_logger.info("Printing job: '%s' on %s" % (
|
)
|
||||||
file_name,
|
|
||||||
self.server_id.address,
|
|
||||||
))
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def set_default(self):
|
def set_default(self):
|
||||||
if not self:
|
if not self:
|
||||||
return
|
return
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
default_printers = self.search([('default', '=', True)])
|
default_printers = self.search([("default", "=", True)])
|
||||||
default_printers.unset_default()
|
default_printers.unset_default()
|
||||||
self.write({'default': True})
|
self.write({"default": True})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def unset_default(self):
|
def unset_default(self):
|
||||||
self.write({'default': False})
|
self.write({"default": False})
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_default(self):
|
def get_default(self):
|
||||||
return self.search([('default', '=', True)], limit=1)
|
return self.search([("default", "=", True)], limit=1)
|
||||||
|
|
||||||
def action_cancel_all_jobs(self):
|
def action_cancel_all_jobs(self):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
@@ -200,11 +200,10 @@ class PrintingPrinter(models.Model):
|
|||||||
def cancel_all_jobs(self, purge_jobs=False):
|
def cancel_all_jobs(self, purge_jobs=False):
|
||||||
for printer in self:
|
for printer in self:
|
||||||
connection = printer.server_id._open_connection()
|
connection = printer.server_id._open_connection()
|
||||||
connection.cancelAllJobs(
|
connection.cancelAllJobs(name=printer.system_name, purge_jobs=purge_jobs)
|
||||||
name=printer.system_name, purge_jobs=purge_jobs)
|
|
||||||
|
|
||||||
# Update jobs' states into Odoo
|
# Update jobs' states into Odoo
|
||||||
self.mapped('server_id').update_jobs(which='completed')
|
self.mapped("server_id").update_jobs(which="completed")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -214,7 +213,7 @@ class PrintingPrinter(models.Model):
|
|||||||
connection.enablePrinter(printer.system_name)
|
connection.enablePrinter(printer.system_name)
|
||||||
|
|
||||||
# Update printers' stats into Odoo
|
# Update printers' stats into Odoo
|
||||||
self.mapped('server_id').update_printers()
|
self.mapped("server_id").update_printers()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -224,6 +223,6 @@ class PrintingPrinter(models.Model):
|
|||||||
connection.disablePrinter(printer.system_name)
|
connection.disablePrinter(printer.system_name)
|
||||||
|
|
||||||
# Update printers' stats into Odoo
|
# Update printers' stats into Odoo
|
||||||
self.mapped('server_id').update_printers()
|
self.mapped("server_id").update_printers()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -5,35 +5,35 @@
|
|||||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import models, fields, api
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
class PrintingReportXmlAction(models.Model):
|
class PrintingReportXmlAction(models.Model):
|
||||||
_name = 'printing.report.xml.action'
|
_name = "printing.report.xml.action"
|
||||||
_description = 'Printing Report Printing Actions'
|
_description = "Printing Report Printing Actions"
|
||||||
|
|
||||||
report_id = fields.Many2one(comodel_name='ir.actions.report',
|
report_id = fields.Many2one(
|
||||||
string='Report',
|
comodel_name="ir.actions.report",
|
||||||
required=True,
|
string="Report",
|
||||||
ondelete='cascade')
|
required=True,
|
||||||
user_id = fields.Many2one(comodel_name='res.users',
|
ondelete="cascade",
|
||||||
string='User',
|
)
|
||||||
required=True,
|
user_id = fields.Many2one(
|
||||||
ondelete='cascade')
|
comodel_name="res.users", string="User", required=True, ondelete="cascade"
|
||||||
|
)
|
||||||
action = fields.Selection(
|
action = fields.Selection(
|
||||||
selection=lambda s: s.env['printing.action']._available_action_types(),
|
selection=lambda s: s.env["printing.action"]._available_action_types(),
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
printer_id = fields.Many2one(comodel_name='printing.printer',
|
printer_id = fields.Many2one(comodel_name="printing.printer", string="Printer")
|
||||||
string='Printer')
|
|
||||||
|
|
||||||
printer_tray_id = fields.Many2one(
|
printer_tray_id = fields.Many2one(
|
||||||
comodel_name='printing.tray',
|
comodel_name="printing.tray",
|
||||||
string='Paper Source',
|
string="Paper Source",
|
||||||
domain="[('printer_id', '=', printer_id)]",
|
domain="[('printer_id', '=', printer_id)]",
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.onchange('printer_id')
|
@api.onchange("printer_id")
|
||||||
def onchange_printer_id(self):
|
def onchange_printer_id(self):
|
||||||
""" Reset the tray when the printer is changed """
|
""" Reset the tray when the printer is changed """
|
||||||
self.printer_tray_id = False
|
self.printer_tray_id = False
|
||||||
@@ -42,7 +42,7 @@ class PrintingReportXmlAction(models.Model):
|
|||||||
if not self:
|
if not self:
|
||||||
return {}
|
return {}
|
||||||
return {
|
return {
|
||||||
'action': self.action,
|
"action": self.action,
|
||||||
'printer': self.printer_id,
|
"printer": self.printer_id,
|
||||||
'tray': self.printer_tray_id.system_name
|
"tray": self.printer_tray_id.system_name,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from odoo import models, fields, exceptions, _
|
|
||||||
|
from odoo import _, exceptions, fields, models
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -11,26 +12,25 @@ _logger = logging.getLogger(__name__)
|
|||||||
try:
|
try:
|
||||||
import cups
|
import cups
|
||||||
except ImportError:
|
except ImportError:
|
||||||
_logger.debug('Cannot `import cups`.')
|
_logger.debug("Cannot `import cups`.")
|
||||||
|
|
||||||
|
|
||||||
class PrintingServer(models.Model):
|
class PrintingServer(models.Model):
|
||||||
_name = 'printing.server'
|
_name = "printing.server"
|
||||||
_description = 'Printing server'
|
_description = "Printing server"
|
||||||
|
|
||||||
name = fields.Char(
|
name = fields.Char(default="Localhost", required=True, help="Name of the server.")
|
||||||
default='Localhost', required=True, help='Name of the server.')
|
|
||||||
address = fields.Char(
|
address = fields.Char(
|
||||||
default='localhost', required=True,
|
default="localhost", required=True, help="IP address or hostname of the server"
|
||||||
help='IP address or hostname of the server')
|
)
|
||||||
port = fields.Integer(
|
port = fields.Integer(default=631, required=True, help="Port of the server.")
|
||||||
default=631, required=True, help='Port of the server.')
|
active = fields.Boolean(default=True, help="If checked, this server is useable.")
|
||||||
active = fields.Boolean(
|
|
||||||
default=True, help='If checked, this server is useable.')
|
|
||||||
printer_ids = fields.One2many(
|
printer_ids = fields.One2many(
|
||||||
comodel_name='printing.printer', inverse_name='server_id',
|
comodel_name="printing.printer",
|
||||||
string='Printers List',
|
inverse_name="server_id",
|
||||||
help='List of printers available on this server.')
|
string="Printers List",
|
||||||
|
help="List of printers available on this server.",
|
||||||
|
)
|
||||||
|
|
||||||
def _open_connection(self, raise_on_error=False):
|
def _open_connection(self, raise_on_error=False):
|
||||||
self.ensure_one()
|
self.ensure_one()
|
||||||
@@ -38,10 +38,11 @@ class PrintingServer(models.Model):
|
|||||||
try:
|
try:
|
||||||
connection = cups.Connection(host=self.address, port=self.port)
|
connection = cups.Connection(host=self.address, port=self.port)
|
||||||
except Exception:
|
except Exception:
|
||||||
message = _("Failed to connect to the CUPS server on %s:%s. "
|
message = _(
|
||||||
"Check that the CUPS server is running and that "
|
"Failed to connect to the CUPS server on %s:%s. "
|
||||||
"you can reach it from the Odoo server.") % (
|
"Check that the CUPS server is running and that "
|
||||||
self.address, self.port)
|
"you can reach it from the Odoo server."
|
||||||
|
) % (self.address, self.port)
|
||||||
_logger.warning(message)
|
_logger.warning(message)
|
||||||
if raise_on_error:
|
if raise_on_error:
|
||||||
raise exceptions.UserError(message)
|
raise exceptions.UserError(message)
|
||||||
@@ -63,28 +64,25 @@ class PrintingServer(models.Model):
|
|||||||
for server in servers:
|
for server in servers:
|
||||||
connection = server._open_connection(raise_on_error=raise_on_error)
|
connection = server._open_connection(raise_on_error=raise_on_error)
|
||||||
if not connection:
|
if not connection:
|
||||||
server.printer_ids.write({'status': 'server-error'})
|
server.printer_ids.write({"status": "server-error"})
|
||||||
res = False
|
res = False
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Update Printers
|
# Update Printers
|
||||||
printers = connection.getPrinters()
|
printers = connection.getPrinters()
|
||||||
existing_printers = dict([
|
existing_printers = {
|
||||||
(printer.system_name, printer)
|
printer.system_name: printer for printer in server.printer_ids
|
||||||
for printer in server.printer_ids
|
}
|
||||||
])
|
|
||||||
updated_printers = []
|
updated_printers = []
|
||||||
for name, printer_info in printers.items():
|
for name, printer_info in printers.items():
|
||||||
printer = self.env['printing.printer']
|
printer = self.env["printing.printer"]
|
||||||
if name in existing_printers:
|
if name in existing_printers:
|
||||||
printer = existing_printers[name]
|
printer = existing_printers[name]
|
||||||
|
|
||||||
printer_values = printer._prepare_update_from_cups(
|
printer_values = printer._prepare_update_from_cups(
|
||||||
connection, printer_info)
|
connection, printer_info
|
||||||
printer_values.update(
|
|
||||||
system_name=name,
|
|
||||||
server_id=server.id,
|
|
||||||
)
|
)
|
||||||
|
printer_values.update(system_name=name, server_id=server.id)
|
||||||
updated_printers.append(name)
|
updated_printers.append(name)
|
||||||
if not printer:
|
if not printer:
|
||||||
printer.create(printer_values)
|
printer.create(printer_values)
|
||||||
@@ -93,8 +91,8 @@ class PrintingServer(models.Model):
|
|||||||
|
|
||||||
# Set printers not found as unavailable
|
# Set printers not found as unavailable
|
||||||
server.printer_ids.filtered(
|
server.printer_ids.filtered(
|
||||||
lambda record: record.system_name not in updated_printers)\
|
lambda record: record.system_name not in updated_printers
|
||||||
.write({'status': 'unavailable'})
|
).write({"status": "unavailable"})
|
||||||
|
|
||||||
return res
|
return res
|
||||||
|
|
||||||
@@ -103,18 +101,18 @@ class PrintingServer(models.Model):
|
|||||||
self = self.search([])
|
self = self.search([])
|
||||||
return self.update_jobs()
|
return self.update_jobs()
|
||||||
|
|
||||||
def update_jobs(self, which='all', first_job_id=-1):
|
def update_jobs(self, which="all", first_job_id=-1):
|
||||||
job_obj = self.env['printing.job']
|
job_obj = self.env["printing.job"]
|
||||||
printer_obj = self.env['printing.printer']
|
printer_obj = self.env["printing.printer"]
|
||||||
|
|
||||||
mapping = {
|
mapping = {
|
||||||
3: 'pending',
|
3: "pending",
|
||||||
4: 'pending held',
|
4: "pending held",
|
||||||
5: 'processing',
|
5: "processing",
|
||||||
6: 'processing stopped',
|
6: "processing stopped",
|
||||||
7: 'canceled',
|
7: "canceled",
|
||||||
8: 'aborted',
|
8: "aborted",
|
||||||
9: 'completed',
|
9: "completed",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Update printers list, to ensure that jobs printers will be in Odoo
|
# Update printers list, to ensure that jobs printers will be in Odoo
|
||||||
@@ -127,86 +125,91 @@ class PrintingServer(models.Model):
|
|||||||
|
|
||||||
# Retrieve asked job data
|
# Retrieve asked job data
|
||||||
jobs_data = connection.getJobs(
|
jobs_data = connection.getJobs(
|
||||||
which_jobs=which, first_job_id=first_job_id,
|
which_jobs=which,
|
||||||
|
first_job_id=first_job_id,
|
||||||
requested_attributes=[
|
requested_attributes=[
|
||||||
'job-name',
|
"job-name",
|
||||||
'job-id',
|
"job-id",
|
||||||
'printer-uri',
|
"printer-uri",
|
||||||
'job-media-progress',
|
"job-media-progress",
|
||||||
'time-at-creation',
|
"time-at-creation",
|
||||||
'job-state',
|
"job-state",
|
||||||
'job-state-reasons',
|
"job-state-reasons",
|
||||||
'time-at-processing',
|
"time-at-processing",
|
||||||
'time-at-completed',
|
"time-at-completed",
|
||||||
])
|
],
|
||||||
|
)
|
||||||
|
|
||||||
# Retrieve known uncompleted jobs data to update them
|
# Retrieve known uncompleted jobs data to update them
|
||||||
if which == 'not-completed':
|
if which == "not-completed":
|
||||||
oldest_uncompleted_job = job_obj.search([
|
oldest_uncompleted_job = job_obj.search(
|
||||||
('job_state', 'not in', (
|
[("job_state", "not in", ("canceled", "aborted", "completed"))],
|
||||||
'canceled',
|
limit=1,
|
||||||
'aborted',
|
order="job_id_cups",
|
||||||
'completed',
|
)
|
||||||
)),
|
|
||||||
], limit=1, order='job_id_cups')
|
|
||||||
if oldest_uncompleted_job:
|
if oldest_uncompleted_job:
|
||||||
jobs_data.update(connection.getJobs(
|
jobs_data.update(
|
||||||
which_jobs='completed',
|
connection.getJobs(
|
||||||
first_job_id=oldest_uncompleted_job.job_id_cups,
|
which_jobs="completed",
|
||||||
requested_attributes=[
|
first_job_id=oldest_uncompleted_job.job_id_cups,
|
||||||
'job-name',
|
requested_attributes=[
|
||||||
'job-id',
|
"job-name",
|
||||||
'printer-uri',
|
"job-id",
|
||||||
'job-media-progress',
|
"printer-uri",
|
||||||
'time-at-creation',
|
"job-media-progress",
|
||||||
'job-state',
|
"time-at-creation",
|
||||||
'job-state-reasons',
|
"job-state",
|
||||||
'time-at-processing',
|
"job-state-reasons",
|
||||||
'time-at-completed',
|
"time-at-processing",
|
||||||
]))
|
"time-at-completed",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
all_cups_job_ids = set()
|
all_cups_job_ids = set()
|
||||||
for cups_job_id, job_data in jobs_data.items():
|
for cups_job_id, job_data in jobs_data.items():
|
||||||
all_cups_job_ids.add(cups_job_id)
|
all_cups_job_ids.add(cups_job_id)
|
||||||
jobs = job_obj.with_context(active_test=False).search([
|
jobs = job_obj.with_context(active_test=False).search(
|
||||||
('job_id_cups', '=', cups_job_id),
|
[("job_id_cups", "=", cups_job_id), ("server_id", "=", server.id)]
|
||||||
('server_id', '=', server.id),
|
)
|
||||||
])
|
|
||||||
job_values = {
|
job_values = {
|
||||||
'name': job_data.get('job-name', ''),
|
"name": job_data.get("job-name", ""),
|
||||||
'active': True,
|
"active": True,
|
||||||
'job_id_cups': cups_job_id,
|
"job_id_cups": cups_job_id,
|
||||||
'job_media_progress': job_data.get(
|
"job_media_progress": job_data.get("job-media-progress", False),
|
||||||
'job-media-progress', False),
|
"job_state": mapping.get(job_data.get("job-state"), "unknown"),
|
||||||
'job_state': mapping.get(
|
"job_state_reason": job_data.get("job-state-reasons", ""),
|
||||||
job_data.get('job-state'), 'unknown'),
|
"time_at_creation": fields.Datetime.to_string(
|
||||||
'job_state_reason': job_data.get('job-state-reasons', ''),
|
datetime.fromtimestamp(job_data.get("time-at-creation", False))
|
||||||
'time_at_creation': fields.Datetime.to_string(
|
),
|
||||||
datetime.fromtimestamp(job_data.get(
|
"time_at_processing": job_data.get("time-at-processing", False)
|
||||||
'time-at-creation', False))),
|
and fields.Datetime.to_string(
|
||||||
'time_at_processing': job_data.get(
|
datetime.fromtimestamp(
|
||||||
'time-at-processing', False) and
|
job_data.get("time-at-processing", False)
|
||||||
fields.Datetime.to_string(datetime.fromtimestamp(
|
)
|
||||||
job_data.get('time-at-processing', False))),
|
),
|
||||||
'time_at_completed': job_data.get(
|
"time_at_completed": job_data.get("time-at-completed", False)
|
||||||
'time-at-completed', False) and
|
and fields.Datetime.to_string(
|
||||||
fields.Datetime.to_string(datetime.fromtimestamp(
|
datetime.fromtimestamp(job_data.get("time-at-completed", False))
|
||||||
job_data.get('time-at-completed', False))),
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Search for the printer in Odoo
|
# Search for the printer in Odoo
|
||||||
printer_uri = job_data['printer-uri']
|
printer_uri = job_data["printer-uri"]
|
||||||
printer_system_name = printer_uri[printer_uri.rfind('/') + 1:]
|
printer_system_name = printer_uri[printer_uri.rfind("/") + 1 :]
|
||||||
printer = printer_obj.search([
|
printer = printer_obj.search(
|
||||||
('server_id', '=', server.id),
|
[
|
||||||
('system_name', '=', printer_system_name),
|
("server_id", "=", server.id),
|
||||||
], limit=1)
|
("system_name", "=", printer_system_name),
|
||||||
|
],
|
||||||
|
limit=1,
|
||||||
|
)
|
||||||
# CUPS retains jobs for disconnected printers and also may
|
# CUPS retains jobs for disconnected printers and also may
|
||||||
# leak jobs data for unshared printers, therefore we just
|
# leak jobs data for unshared printers, therefore we just
|
||||||
# discard here if not printer found
|
# discard here if not printer found
|
||||||
if not printer:
|
if not printer:
|
||||||
continue
|
continue
|
||||||
job_values['printer_id'] = printer.id
|
job_values["printer_id"] = printer.id
|
||||||
|
|
||||||
if jobs:
|
if jobs:
|
||||||
jobs.write(job_values)
|
jobs.write(job_values)
|
||||||
@@ -214,10 +217,10 @@ class PrintingServer(models.Model):
|
|||||||
job_obj.create(job_values)
|
job_obj.create(job_values)
|
||||||
|
|
||||||
# Deactive purged jobs
|
# Deactive purged jobs
|
||||||
if which == 'all' and first_job_id == -1:
|
if which == "all" and first_job_id == -1:
|
||||||
purged_jobs = job_obj.search([
|
purged_jobs = job_obj.search(
|
||||||
('job_id_cups', 'not in', list(all_cups_job_ids)),
|
[("job_id_cups", "not in", list(all_cups_job_ids))]
|
||||||
])
|
)
|
||||||
purged_jobs.write({'active': False})
|
purged_jobs.write({"active": False})
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|||||||
@@ -5,17 +5,17 @@ from odoo import fields, models
|
|||||||
|
|
||||||
|
|
||||||
class PrinterTray(models.Model):
|
class PrinterTray(models.Model):
|
||||||
_name = 'printing.tray'
|
_name = "printing.tray"
|
||||||
_description = 'Printer Tray'
|
_description = "Printer Tray"
|
||||||
|
|
||||||
_order = 'name asc'
|
_order = "name asc"
|
||||||
|
|
||||||
name = fields.Char(required=True)
|
name = fields.Char(required=True)
|
||||||
system_name = fields.Char(required=True, readonly=True)
|
system_name = fields.Char(required=True, readonly=True)
|
||||||
printer_id = fields.Many2one(
|
printer_id = fields.Many2one(
|
||||||
comodel_name='printing.printer',
|
comodel_name="printing.printer",
|
||||||
string='Printer',
|
string="Printer",
|
||||||
required=True,
|
required=True,
|
||||||
readonly=True,
|
readonly=True,
|
||||||
ondelete='cascade',
|
ondelete="cascade",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,46 +5,38 @@
|
|||||||
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||||
|
|
||||||
from odoo import models, fields, api
|
from odoo import api, fields, models
|
||||||
|
|
||||||
|
|
||||||
class ResUsers(models.Model):
|
class ResUsers(models.Model):
|
||||||
_inherit = 'res.users'
|
_inherit = "res.users"
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _user_available_action_types(self):
|
def _user_available_action_types(self):
|
||||||
return [
|
return [
|
||||||
(code, string)
|
(code, string)
|
||||||
for code, string
|
for code, string in self.env["printing.action"]._available_action_types()
|
||||||
in self.env['printing.action']._available_action_types()
|
if code != "user_default"
|
||||||
if code != 'user_default'
|
|
||||||
]
|
]
|
||||||
|
|
||||||
printing_action = fields.Selection(
|
printing_action = fields.Selection(selection=_user_available_action_types)
|
||||||
selection=_user_available_action_types,
|
printing_printer_id = fields.Many2one(
|
||||||
|
comodel_name="printing.printer", string="Default Printer"
|
||||||
)
|
)
|
||||||
printing_printer_id = fields.Many2one(comodel_name='printing.printer',
|
|
||||||
string='Default Printer')
|
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _register_hook(self):
|
def _register_hook(self):
|
||||||
super()._register_hook()
|
super()._register_hook()
|
||||||
self.SELF_WRITEABLE_FIELDS.extend([
|
self.SELF_WRITEABLE_FIELDS.extend(["printing_action", "printing_printer_id"])
|
||||||
'printing_action',
|
self.SELF_READABLE_FIELDS.extend(["printing_action", "printing_printer_id"])
|
||||||
'printing_printer_id',
|
|
||||||
])
|
|
||||||
self.SELF_READABLE_FIELDS.extend([
|
|
||||||
'printing_action',
|
|
||||||
'printing_printer_id',
|
|
||||||
])
|
|
||||||
|
|
||||||
printer_tray_id = fields.Many2one(
|
printer_tray_id = fields.Many2one(
|
||||||
comodel_name='printing.tray',
|
comodel_name="printing.tray",
|
||||||
string='Default Printer Paper Source',
|
string="Default Printer Paper Source",
|
||||||
domain="[('printer_id', '=', printing_printer_id)]",
|
domain="[('printer_id', '=', printing_printer_id)]",
|
||||||
)
|
)
|
||||||
|
|
||||||
@api.onchange('printing_printer_id')
|
@api.onchange("printing_printer_id")
|
||||||
def onchange_printing_printer_id(self):
|
def onchange_printing_printer_id(self):
|
||||||
""" Reset the tray when the printer is changed """
|
""" Reset the tray when the printer is changed """
|
||||||
self.printer_tray_id = False
|
self.printer_tray_id = False
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" ?>
|
<?xml version="1.0" ?>
|
||||||
<odoo>
|
<odoo>
|
||||||
|
|
||||||
<record id="printing_group_user" model="res.groups">
|
<record id="printing_group_user" model="res.groups">
|
||||||
<field name="name">Printing / Print User</field>
|
<field name="name">Printing / Print User</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ odoo.define('base_report_to_printer.print', function (require) {
|
|||||||
}, function () {
|
}, function () {
|
||||||
self.do_notify(_t('Report'),
|
self.do_notify(_t('Report'),
|
||||||
_.str.sprintf(
|
_.str.sprintf(
|
||||||
_t('Error when sending the document\
|
_t('Error when sending the document ' +
|
||||||
to the printer '),
|
'to the printer '),
|
||||||
print_action.printer_name
|
print_action.printer_name
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -48,4 +48,3 @@ odoo.define('base_report_to_printer.print', function (require) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,79 +8,74 @@ from odoo.tests.common import TransactionCase
|
|||||||
|
|
||||||
|
|
||||||
class TestIrActionsReportXml(TransactionCase):
|
class TestIrActionsReportXml(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestIrActionsReportXml, self).setUp()
|
super(TestIrActionsReportXml, self).setUp()
|
||||||
self.Model = self.env['ir.actions.report']
|
self.Model = self.env["ir.actions.report"]
|
||||||
self.vals = {}
|
self.vals = {}
|
||||||
|
|
||||||
self.report = self.env['ir.actions.report'].search([], limit=1)
|
self.report = self.env["ir.actions.report"].search([], limit=1)
|
||||||
self.server = self.env['printing.server'].create({})
|
self.server = self.env["printing.server"].create({})
|
||||||
|
|
||||||
def new_action(self):
|
def new_action(self):
|
||||||
return self.env['printing.action'].create({
|
return self.env["printing.action"].create(
|
||||||
'name': 'Printing Action',
|
{"name": "Printing Action", "action_type": "server"}
|
||||||
'action_type': 'server',
|
)
|
||||||
})
|
|
||||||
|
|
||||||
def new_printing_action(self):
|
def new_printing_action(self):
|
||||||
return self.env['printing.report.xml.action'].create({
|
return self.env["printing.report.xml.action"].create(
|
||||||
'report_id': self.report.id,
|
{
|
||||||
'user_id': self.env.ref('base.user_demo').id,
|
"report_id": self.report.id,
|
||||||
'action': 'server',
|
"user_id": self.env.ref("base.user_demo").id,
|
||||||
})
|
"action": "server",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def new_printer(self):
|
def new_printer(self):
|
||||||
return self.env['printing.printer'].create({
|
return self.env["printing.printer"].create(
|
||||||
'name': 'Printer',
|
{
|
||||||
'server_id': self.server.id,
|
"name": "Printer",
|
||||||
'system_name': 'Sys Name',
|
"server_id": self.server.id,
|
||||||
'default': True,
|
"system_name": "Sys Name",
|
||||||
'status': 'unknown',
|
"default": True,
|
||||||
'status_message': 'Msg',
|
"status": "unknown",
|
||||||
'model': 'res.users',
|
"status_message": "Msg",
|
||||||
'location': 'Location',
|
"model": "res.users",
|
||||||
'uri': 'URI',
|
"location": "Location",
|
||||||
})
|
"uri": "URI",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def new_tray(self, vals=None, defaults=None):
|
def new_tray(self, vals=None, defaults=None):
|
||||||
values = dict(defaults)
|
values = dict(defaults)
|
||||||
if vals is not None:
|
if vals is not None:
|
||||||
values.update(vals)
|
values.update(vals)
|
||||||
return self.env['printing.tray'].create(values)
|
return self.env["printing.tray"].create(values)
|
||||||
|
|
||||||
def test_print_action_for_report_name_gets_report(self):
|
def test_print_action_for_report_name_gets_report(self):
|
||||||
""" It should get report by name """
|
""" It should get report by name """
|
||||||
with mock.patch.object(self.Model, '_get_report_from_name') as mk:
|
with mock.patch.object(self.Model, "_get_report_from_name") as mk:
|
||||||
expect = 'test'
|
expect = "test"
|
||||||
self.Model.print_action_for_report_name(expect)
|
self.Model.print_action_for_report_name(expect)
|
||||||
mk.assert_called_once_with(
|
mk.assert_called_once_with(expect)
|
||||||
expect
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_print_action_for_report_name_returns_if_no_report(self):
|
def test_print_action_for_report_name_returns_if_no_report(self):
|
||||||
""" It should return empty dict when no matching report """
|
""" It should return empty dict when no matching report """
|
||||||
with mock.patch.object(self.Model, '_get_report_from_name') as mk:
|
with mock.patch.object(self.Model, "_get_report_from_name") as mk:
|
||||||
expect = 'test'
|
expect = "test"
|
||||||
mk.return_value = False
|
mk.return_value = False
|
||||||
res = self.Model.print_action_for_report_name(expect)
|
res = self.Model.print_action_for_report_name(expect)
|
||||||
self.assertDictEqual(
|
self.assertDictEqual({}, res)
|
||||||
{}, res,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_print_action_for_report_name_returns_if_report(self):
|
def test_print_action_for_report_name_returns_if_report(self):
|
||||||
""" It should return correct serializable result for behaviour """
|
""" It should return correct serializable result for behaviour """
|
||||||
with mock.patch.object(self.Model, '_get_report_from_name') as mk:
|
with mock.patch.object(self.Model, "_get_report_from_name") as mk:
|
||||||
res = self.Model.print_action_for_report_name('test')
|
res = self.Model.print_action_for_report_name("test")
|
||||||
behaviour = mk().behaviour()
|
behaviour = mk().behaviour()
|
||||||
expect = {
|
expect = {
|
||||||
'action': behaviour['action'],
|
"action": behaviour["action"],
|
||||||
'printer_name': behaviour['printer'].name,
|
"printer_name": behaviour["printer"].name,
|
||||||
}
|
}
|
||||||
self.assertDictEqual(
|
self.assertDictEqual(expect, res, "Expect {}, Got {}".format(expect, res))
|
||||||
expect, res,
|
|
||||||
'Expect %s, Got %s' % (expect, res),
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_behaviour_default_values(self):
|
def test_behaviour_default_values(self):
|
||||||
""" It should return the default action and printer """
|
""" It should return the default action and printer """
|
||||||
@@ -89,81 +84,81 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
self.env.user.printing_printer_id = False
|
self.env.user.printing_printer_id = False
|
||||||
report.property_printing_action_id = False
|
report.property_printing_action_id = False
|
||||||
report.printing_printer_id = False
|
report.printing_printer_id = False
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': 'client',
|
report.behaviour(),
|
||||||
'printer': self.env['printing.printer'],
|
{
|
||||||
'tray': False,
|
"action": "client",
|
||||||
},
|
"printer": self.env["printing.printer"],
|
||||||
|
"tray": False,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_behaviour_user_values(self):
|
def test_behaviour_user_values(self):
|
||||||
""" It should return the action and printer from user """
|
""" It should return the action and printer from user """
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = 'client'
|
self.env.user.printing_action = "client"
|
||||||
self.env.user.printing_printer_id = self.new_printer()
|
self.env.user.printing_printer_id = self.new_printer()
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': 'client',
|
report.behaviour(),
|
||||||
'printer': self.env.user.printing_printer_id,
|
{
|
||||||
'tray': False,
|
"action": "client",
|
||||||
},
|
"printer": self.env.user.printing_printer_id,
|
||||||
|
"tray": False,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_behaviour_report_values(self):
|
def test_behaviour_report_values(self):
|
||||||
""" It should return the action and printer from report """
|
""" It should return the action and printer from report """
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = 'client'
|
self.env.user.printing_action = "client"
|
||||||
report.property_printing_action_id = self.new_action()
|
report.property_printing_action_id = self.new_action()
|
||||||
report.printing_printer_id = self.new_printer()
|
report.printing_printer_id = self.new_printer()
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': report.property_printing_action_id.action_type,
|
report.behaviour(),
|
||||||
'printer': report.printing_printer_id,
|
{
|
||||||
'tray': False,
|
"action": report.property_printing_action_id.action_type,
|
||||||
},
|
"printer": report.printing_printer_id,
|
||||||
|
"tray": False,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_behaviour_user_action(self):
|
def test_behaviour_user_action(self):
|
||||||
""" It should return the action and printer from user action"""
|
""" It should return the action and printer from user action"""
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = 'client'
|
self.env.user.printing_action = "client"
|
||||||
report.property_printing_action_id.action_type = 'user_default'
|
report.property_printing_action_id.action_type = "user_default"
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': 'client',
|
report.behaviour(),
|
||||||
'printer': report.printing_printer_id,
|
{"action": "client", "printer": report.printing_printer_id, "tray": False},
|
||||||
'tray': False,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_behaviour_printing_action_on_wrong_user(self):
|
def test_behaviour_printing_action_on_wrong_user(self):
|
||||||
""" It should return the action and printer ignoring printing action
|
""" It should return the action and printer ignoring printing action
|
||||||
"""
|
"""
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = 'client'
|
self.env.user.printing_action = "client"
|
||||||
printing_action = self.new_printing_action()
|
printing_action = self.new_printing_action()
|
||||||
printing_action.user_id = self.env['res.users'].search([
|
printing_action.user_id = self.env["res.users"].search(
|
||||||
('id', '!=', self.env.user.id),
|
[("id", "!=", self.env.user.id)], limit=1
|
||||||
], limit=1)
|
)
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': 'client',
|
report.behaviour(),
|
||||||
'printer': report.printing_printer_id,
|
{"action": "client", "printer": report.printing_printer_id, "tray": False},
|
||||||
'tray': False,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_behaviour_printing_action_on_wrong_report(self):
|
def test_behaviour_printing_action_on_wrong_report(self):
|
||||||
""" It should return the action and printer ignoring printing action
|
""" It should return the action and printer ignoring printing action
|
||||||
"""
|
"""
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = 'client'
|
self.env.user.printing_action = "client"
|
||||||
printing_action = self.new_printing_action()
|
printing_action = self.new_printing_action()
|
||||||
printing_action.user_id = self.env.user
|
printing_action.user_id = self.env.user
|
||||||
printing_action.report_id = self.env['ir.actions.report'].search([
|
printing_action.report_id = self.env["ir.actions.report"].search(
|
||||||
('id', '!=', report.id),
|
[("id", "!=", report.id)], limit=1
|
||||||
], limit=1)
|
)
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': 'client',
|
report.behaviour(),
|
||||||
'printer': report.printing_printer_id,
|
{"action": "client", "printer": report.printing_printer_id, "tray": False},
|
||||||
'tray': False,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_behaviour_printing_action_with_no_printer(self):
|
def test_behaviour_printing_action_with_no_printer(self):
|
||||||
@@ -171,29 +166,33 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
other
|
other
|
||||||
"""
|
"""
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = 'client'
|
self.env.user.printing_action = "client"
|
||||||
printing_action = self.new_printing_action()
|
printing_action = self.new_printing_action()
|
||||||
printing_action.user_id = self.env.user
|
printing_action.user_id = self.env.user
|
||||||
printing_action.report_id = report
|
printing_action.report_id = report
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': printing_action.action,
|
report.behaviour(),
|
||||||
'printer': report.printing_printer_id,
|
{
|
||||||
'tray': False,
|
"action": printing_action.action,
|
||||||
},
|
"printer": report.printing_printer_id,
|
||||||
|
"tray": False,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_behaviour_printing_action_with_printer(self):
|
def test_behaviour_printing_action_with_printer(self):
|
||||||
""" It should return the action and printer from printing action """
|
""" It should return the action and printer from printing action """
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = 'client'
|
self.env.user.printing_action = "client"
|
||||||
printing_action = self.new_printing_action()
|
printing_action = self.new_printing_action()
|
||||||
printing_action.user_id = self.env.user
|
printing_action.user_id = self.env.user
|
||||||
printing_action.printer_id = self.new_printer()
|
printing_action.printer_id = self.new_printer()
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': printing_action.action,
|
report.behaviour(),
|
||||||
'printer': printing_action.printer_id,
|
{
|
||||||
'tray': False,
|
"action": printing_action.action,
|
||||||
},
|
"printer": printing_action.printer_id,
|
||||||
|
"tray": False,
|
||||||
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_behaviour_printing_action_user_defaults(self):
|
def test_behaviour_printing_action_user_defaults(self):
|
||||||
@@ -201,106 +200,96 @@ class TestIrActionsReportXml(TransactionCase):
|
|||||||
action
|
action
|
||||||
"""
|
"""
|
||||||
report = self.Model.search([], limit=1)
|
report = self.Model.search([], limit=1)
|
||||||
self.env.user.printing_action = 'client'
|
self.env.user.printing_action = "client"
|
||||||
printing_action = self.new_printing_action()
|
printing_action = self.new_printing_action()
|
||||||
printing_action.user_id = self.env.user
|
printing_action.user_id = self.env.user
|
||||||
printing_action.action = 'user_default'
|
printing_action.action = "user_default"
|
||||||
self.assertEqual(report.behaviour(), {
|
self.assertEqual(
|
||||||
'action': 'client',
|
report.behaviour(),
|
||||||
'printer': report.printing_printer_id,
|
{"action": "client", "printer": report.printing_printer_id, "tray": False},
|
||||||
'tray': False,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_print_tray_behaviour(self):
|
def test_print_tray_behaviour(self):
|
||||||
"""
|
"""
|
||||||
It should return the correct tray
|
It should return the correct tray
|
||||||
"""
|
"""
|
||||||
report = self.env['ir.actions.report'].search([], limit=1)
|
report = self.env["ir.actions.report"].search([], limit=1)
|
||||||
action = self.env['printing.report.xml.action'].create({
|
action = self.env["printing.report.xml.action"].create(
|
||||||
'user_id': self.env.user.id,
|
{"user_id": self.env.user.id, "report_id": report.id, "action": "server"}
|
||||||
'report_id': report.id,
|
)
|
||||||
'action': 'server',
|
|
||||||
})
|
|
||||||
printer = self.new_printer()
|
printer = self.new_printer()
|
||||||
tray_vals = {
|
tray_vals = {"name": "Tray", "system_name": "Tray", "printer_id": printer.id}
|
||||||
'name': 'Tray',
|
user_tray = self.new_tray({"system_name": "User tray"}, tray_vals)
|
||||||
'system_name': 'Tray',
|
report_tray = self.new_tray({"system_name": "Report tray"}, tray_vals)
|
||||||
'printer_id': printer.id,
|
action_tray = self.new_tray({"system_name": "Action tray"}, tray_vals)
|
||||||
}
|
|
||||||
user_tray = self.new_tray({'system_name': 'User tray'}, tray_vals)
|
|
||||||
report_tray = self.new_tray({'system_name': 'Report tray'}, tray_vals)
|
|
||||||
action_tray = self.new_tray({'system_name': 'Action tray'}, tray_vals)
|
|
||||||
|
|
||||||
# No report passed
|
# No report passed
|
||||||
self.env.user.printer_tray_id = False
|
self.env.user.printer_tray_id = False
|
||||||
options = printer.print_options()
|
options = printer.print_options()
|
||||||
self.assertFalse('InputSlot' in options)
|
self.assertFalse("InputSlot" in options)
|
||||||
|
|
||||||
# No tray defined
|
# No tray defined
|
||||||
self.env.user.printer_tray_id = False
|
self.env.user.printer_tray_id = False
|
||||||
report.printer_tray_id = False
|
report.printer_tray_id = False
|
||||||
action.printer_tray_id = False
|
action.printer_tray_id = False
|
||||||
options = report.behaviour()
|
options = report.behaviour()
|
||||||
self.assertTrue('tray' in options)
|
self.assertTrue("tray" in options)
|
||||||
|
|
||||||
# Only user tray is defined
|
# Only user tray is defined
|
||||||
self.env.user.printer_tray_id = user_tray
|
self.env.user.printer_tray_id = user_tray
|
||||||
report.printer_tray_id = False
|
report.printer_tray_id = False
|
||||||
action.printer_tray_id = False
|
action.printer_tray_id = False
|
||||||
self.assertEqual('User tray', report.behaviour()['tray'])
|
self.assertEqual("User tray", report.behaviour()["tray"])
|
||||||
|
|
||||||
# Only report tray is defined
|
# Only report tray is defined
|
||||||
self.env.user.printer_tray_id = False
|
self.env.user.printer_tray_id = False
|
||||||
report.printer_tray_id = report_tray
|
report.printer_tray_id = report_tray
|
||||||
action.printer_tray_id = False
|
action.printer_tray_id = False
|
||||||
self.assertEqual('Report tray', report.behaviour()['tray'])
|
self.assertEqual("Report tray", report.behaviour()["tray"])
|
||||||
|
|
||||||
# Only action tray is defined
|
# Only action tray is defined
|
||||||
self.env.user.printer_tray_id = False
|
self.env.user.printer_tray_id = False
|
||||||
report.printer_tray_id = False
|
report.printer_tray_id = False
|
||||||
action.printer_tray_id = action_tray
|
action.printer_tray_id = action_tray
|
||||||
self.assertEqual('Action tray', report.behaviour()['tray'])
|
self.assertEqual("Action tray", report.behaviour()["tray"])
|
||||||
|
|
||||||
# User and report tray defined
|
# User and report tray defined
|
||||||
self.env.user.printer_tray_id = user_tray
|
self.env.user.printer_tray_id = user_tray
|
||||||
report.printer_tray_id = report_tray
|
report.printer_tray_id = report_tray
|
||||||
action.printer_tray_id = False
|
action.printer_tray_id = False
|
||||||
self.assertEqual('Report tray', report.behaviour()['tray'])
|
self.assertEqual("Report tray", report.behaviour()["tray"])
|
||||||
|
|
||||||
# All trays are defined
|
# All trays are defined
|
||||||
self.env.user.printer_tray_id = user_tray
|
self.env.user.printer_tray_id = user_tray
|
||||||
report.printer_tray_id = report_tray
|
report.printer_tray_id = report_tray
|
||||||
action.printer_tray_id = action_tray
|
action.printer_tray_id = action_tray
|
||||||
self.assertEqual('Action tray', report.behaviour()['tray'])
|
self.assertEqual("Action tray", report.behaviour()["tray"])
|
||||||
|
|
||||||
def test_onchange_printer_tray_id_empty(self):
|
def test_onchange_printer_tray_id_empty(self):
|
||||||
action = self.env['ir.actions.report'].new(
|
action = self.env["ir.actions.report"].new({"printer_tray_id": False})
|
||||||
{'printer_tray_id': False})
|
|
||||||
action.onchange_printing_printer_id()
|
action.onchange_printing_printer_id()
|
||||||
self.assertFalse(action.printer_tray_id)
|
self.assertFalse(action.printer_tray_id)
|
||||||
|
|
||||||
def test_onchange_printer_tray_id_not_empty(self):
|
def test_onchange_printer_tray_id_not_empty(self):
|
||||||
server = self.env['printing.server'].create({})
|
server = self.env["printing.server"].create({})
|
||||||
printer = self.env['printing.printer'].create({
|
printer = self.env["printing.printer"].create(
|
||||||
'name': 'Printer',
|
{
|
||||||
'server_id': server.id,
|
"name": "Printer",
|
||||||
'system_name': 'Sys Name',
|
"server_id": server.id,
|
||||||
'default': True,
|
"system_name": "Sys Name",
|
||||||
'status': 'unknown',
|
"default": True,
|
||||||
'status_message': 'Msg',
|
"status": "unknown",
|
||||||
'model': 'res.users',
|
"status_message": "Msg",
|
||||||
'location': 'Location',
|
"model": "res.users",
|
||||||
'uri': 'URI',
|
"location": "Location",
|
||||||
})
|
"uri": "URI",
|
||||||
tray = self.env['printing.tray'].create({
|
}
|
||||||
'name': 'Tray',
|
)
|
||||||
'system_name': 'TrayName',
|
tray = self.env["printing.tray"].create(
|
||||||
'printer_id': printer.id,
|
{"name": "Tray", "system_name": "TrayName", "printer_id": printer.id}
|
||||||
})
|
)
|
||||||
|
|
||||||
action = self.env['ir.actions.report'].new(
|
action = self.env["ir.actions.report"].new({"printer_tray_id": tray.id})
|
||||||
{'printer_tray_id': tray.id})
|
|
||||||
self.assertEqual(action.printer_tray_id, tray)
|
self.assertEqual(action.printer_tray_id, tray)
|
||||||
action.onchange_printing_printer_id()
|
action.onchange_printing_printer_id()
|
||||||
self.assertFalse(action.printer_tray_id)
|
self.assertFalse(action.printer_tray_id)
|
||||||
|
|||||||
@@ -6,60 +6,58 @@ import mock
|
|||||||
from odoo import fields
|
from odoo import fields
|
||||||
from odoo.tests.common import TransactionCase
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
model = "odoo.addons.base_report_to_printer.models.printing_server"
|
||||||
model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
|
||||||
|
|
||||||
|
|
||||||
class TestPrintingJob(TransactionCase):
|
class TestPrintingJob(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPrintingJob, self).setUp()
|
super(TestPrintingJob, self).setUp()
|
||||||
self.Model = self.env['printing.server']
|
self.Model = self.env["printing.server"]
|
||||||
self.server = self.Model.create({})
|
self.server = self.Model.create({})
|
||||||
self.printer_vals = {
|
self.printer_vals = {
|
||||||
'name': 'Printer',
|
"name": "Printer",
|
||||||
'server_id': self.server.id,
|
"server_id": self.server.id,
|
||||||
'system_name': 'Sys Name',
|
"system_name": "Sys Name",
|
||||||
'default': True,
|
"default": True,
|
||||||
'status': 'unknown',
|
"status": "unknown",
|
||||||
'status_message': 'Msg',
|
"status_message": "Msg",
|
||||||
'model': 'res.users',
|
"model": "res.users",
|
||||||
'location': 'Location',
|
"location": "Location",
|
||||||
'uri': 'URI',
|
"uri": "URI",
|
||||||
}
|
}
|
||||||
self.job_vals = {
|
self.job_vals = {
|
||||||
'server_id': self.server.id,
|
"server_id": self.server.id,
|
||||||
'job_id_cups': 1,
|
"job_id_cups": 1,
|
||||||
'job_media_progress': 0,
|
"job_media_progress": 0,
|
||||||
'time_at_creation': fields.Datetime.now(),
|
"time_at_creation": fields.Datetime.now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def new_printer(self):
|
def new_printer(self):
|
||||||
return self.env['printing.printer'].create(self.printer_vals)
|
return self.env["printing.printer"].create(self.printer_vals)
|
||||||
|
|
||||||
def new_job(self, printer, vals=None):
|
def new_job(self, printer, vals=None):
|
||||||
values = self.job_vals
|
values = self.job_vals
|
||||||
if vals is not None:
|
if vals is not None:
|
||||||
values.update(vals)
|
values.update(vals)
|
||||||
values['printer_id'] = printer.id
|
values["printer_id"] = printer.id
|
||||||
return self.env['printing.job'].create(values)
|
return self.env["printing.job"].create(values)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_cancel_job_error(self, cups):
|
def test_cancel_job_error(self, cups):
|
||||||
""" It should catch any exception from CUPS and update status """
|
""" It should catch any exception from CUPS and update status """
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
printer = self.new_printer()
|
printer = self.new_printer()
|
||||||
job = self.new_job(printer, {'job_id_cups': 2})
|
job = self.new_job(printer, {"job_id_cups": 2})
|
||||||
job.action_cancel()
|
job.action_cancel()
|
||||||
cups.Connection.side_effect = None
|
cups.Connection.side_effect = None
|
||||||
self.assertEqual(cups.Connection().cancelJob.call_count, 0)
|
self.assertEqual(cups.Connection().cancelJob.call_count, 0)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_cancel_job(self, cups):
|
def test_cancel_job(self, cups):
|
||||||
""" It should catch any exception from CUPS and update status """
|
""" It should catch any exception from CUPS and update status """
|
||||||
printer = self.new_printer()
|
printer = self.new_printer()
|
||||||
job = self.new_job(printer)
|
job = self.new_job(printer)
|
||||||
job.cancel()
|
job.cancel()
|
||||||
cups.Connection().cancelJob.assert_called_once_with(
|
cups.Connection().cancelJob.assert_called_once_with(
|
||||||
job.job_id_cups, purge_job=False,
|
job.job_id_cups, purge_job=False
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -2,35 +2,34 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
from odoo.tests.common import TransactionCase
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
model = "odoo.addons.base_report_to_printer.models.printing_printer"
|
||||||
model = 'odoo.addons.base_report_to_printer.models.printing_printer'
|
server_model = "odoo.addons.base_report_to_printer.models.printing_server"
|
||||||
server_model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
|
||||||
|
|
||||||
|
|
||||||
class TestPrintingPrinter(TransactionCase):
|
class TestPrintingPrinter(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPrintingPrinter, self).setUp()
|
super(TestPrintingPrinter, self).setUp()
|
||||||
self.Model = self.env['printing.printer']
|
self.Model = self.env["printing.printer"]
|
||||||
self.ServerModel = self.env['printing.server']
|
self.ServerModel = self.env["printing.server"]
|
||||||
self.server = self.env['printing.server'].create({})
|
self.server = self.env["printing.server"].create({})
|
||||||
self.printer_vals = {
|
self.printer_vals = {
|
||||||
'name': 'Printer',
|
"name": "Printer",
|
||||||
'server_id': self.server.id,
|
"server_id": self.server.id,
|
||||||
'system_name': 'Sys Name',
|
"system_name": "Sys Name",
|
||||||
'default': True,
|
"default": True,
|
||||||
'status': 'unknown',
|
"status": "unknown",
|
||||||
'status_message': 'Msg',
|
"status_message": "Msg",
|
||||||
'model': 'res.users',
|
"model": "res.users",
|
||||||
'location': 'Location',
|
"location": "Location",
|
||||||
'uri': 'URI',
|
"uri": "URI",
|
||||||
}
|
}
|
||||||
self.report = self.env['ir.actions.report'].search([], limit=1)
|
self.report = self.env["ir.actions.report"].search([], limit=1)
|
||||||
|
|
||||||
def new_record(self):
|
def new_record(self):
|
||||||
return self.Model.create(self.printer_vals)
|
return self.Model.create(self.printer_vals)
|
||||||
@@ -39,94 +38,88 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
"""
|
"""
|
||||||
It should put the value in InputSlot
|
It should put the value in InputSlot
|
||||||
"""
|
"""
|
||||||
self.assertEqual(self.Model._set_option_tray(None, 'Test Tray'),
|
self.assertEqual(
|
||||||
{'InputSlot': 'Test Tray'})
|
self.Model._set_option_tray(None, "Test Tray"), {"InputSlot": "Test Tray"}
|
||||||
self.assertEqual(self.Model._set_option_tray(None, False),
|
)
|
||||||
{})
|
self.assertEqual(self.Model._set_option_tray(None, False), {})
|
||||||
|
|
||||||
def test_option_noops(self):
|
def test_option_noops(self):
|
||||||
"""
|
"""
|
||||||
Noops should return an empty dict
|
Noops should return an empty dict
|
||||||
"""
|
"""
|
||||||
self.assertEqual(self.Model._set_option_action(None, 'printer'), {})
|
self.assertEqual(self.Model._set_option_action(None, "printer"), {})
|
||||||
self.assertEqual(self.Model._set_option_printer(None, self.Model), {})
|
self.assertEqual(self.Model._set_option_printer(None, self.Model), {})
|
||||||
|
|
||||||
def test_option_doc_format(self):
|
def test_option_doc_format(self):
|
||||||
"""
|
"""
|
||||||
Raw documents should set raw boolean.
|
Raw documents should set raw boolean.
|
||||||
"""
|
"""
|
||||||
self.assertEqual(self.Model._set_option_doc_format(None, 'raw'),
|
self.assertEqual(
|
||||||
{'raw': 'True'})
|
self.Model._set_option_doc_format(None, "raw"), {"raw": "True"}
|
||||||
|
)
|
||||||
# Deprecate _set_option_format in v12.
|
# Deprecate _set_option_format in v12.
|
||||||
self.assertEqual(self.Model._set_option_format(None, 'raw'),
|
self.assertEqual(self.Model._set_option_format(None, "raw"), {"raw": "True"})
|
||||||
{'raw': 'True'})
|
|
||||||
|
|
||||||
self.assertEqual(self.Model._set_option_doc_format(None, 'pdf'), {})
|
self.assertEqual(self.Model._set_option_doc_format(None, "pdf"), {})
|
||||||
# Deprecate _set_option_format in v12.
|
# Deprecate _set_option_format in v12.
|
||||||
self.assertEqual(self.Model._set_option_format(None, 'pdf'), {})
|
self.assertEqual(self.Model._set_option_format(None, "pdf"), {})
|
||||||
|
|
||||||
def test_print_options(self):
|
def test_print_options(self):
|
||||||
""" It should generate the right options dictionnary """
|
""" It should generate the right options dictionnary """
|
||||||
# TODO: None here used as report - tests here should be merged
|
# TODO: None here used as report - tests here should be merged
|
||||||
# with tests in test_printing_printer_tray from when modules merged
|
# with tests in test_printing_printer_tray from when modules merged
|
||||||
report = self.env['ir.actions.report'].search([], limit=1)
|
report = self.env["ir.actions.report"].search([], limit=1)
|
||||||
self.assertEqual(self.Model.print_options(
|
self.assertEqual(self.Model.print_options(doc_format="raw"), {"raw": "True"})
|
||||||
doc_format='raw'), {'raw': 'True'}
|
self.assertEqual(
|
||||||
|
self.Model.print_options(report, doc_format="pdf", copies=2),
|
||||||
|
{"copies": "2"},
|
||||||
)
|
)
|
||||||
self.assertEqual(self.Model.print_options(
|
self.assertEqual(
|
||||||
report, doc_format='pdf', copies=2), {'copies': '2'}
|
self.Model.print_options(report, doc_format="raw", copies=2),
|
||||||
|
{"raw": "True", "copies": "2"},
|
||||||
)
|
)
|
||||||
self.assertEqual(self.Model.print_options(
|
self.assertTrue("InputSlot" in self.Model.print_options(report, tray="Test"))
|
||||||
report, doc_format='raw', copies=2),
|
|
||||||
{'raw': 'True', 'copies': '2'}
|
|
||||||
)
|
|
||||||
self.assertTrue('InputSlot' in self.Model.print_options(report,
|
|
||||||
tray='Test'))
|
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_print_report(self, cups):
|
def test_print_report(self, cups):
|
||||||
""" It should print a report through CUPS """
|
""" It should print a report through CUPS """
|
||||||
fd, file_name = tempfile.mkstemp()
|
fd, file_name = tempfile.mkstemp()
|
||||||
with mock.patch('%s.mkstemp' % model) as mkstemp:
|
with mock.patch("%s.mkstemp" % model) as mkstemp:
|
||||||
mkstemp.return_value = fd, file_name
|
mkstemp.return_value = fd, file_name
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.print_document(self.report, b'content to print',
|
printer.print_document(self.report, b"content to print", doc_format="pdf")
|
||||||
doc_format='pdf')
|
|
||||||
cups.Connection().printFile.assert_called_once_with(
|
cups.Connection().printFile.assert_called_once_with(
|
||||||
printer.system_name,
|
printer.system_name, file_name, file_name, options={}
|
||||||
file_name,
|
)
|
||||||
file_name,
|
|
||||||
options={})
|
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_print_report_error(self, cups):
|
def test_print_report_error(self, cups):
|
||||||
""" It should print a report through CUPS """
|
""" It should print a report through CUPS """
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
fd, file_name = tempfile.mkstemp()
|
fd, file_name = tempfile.mkstemp()
|
||||||
with mock.patch('%s.mkstemp' % model) as mkstemp:
|
with mock.patch("%s.mkstemp" % model) as mkstemp:
|
||||||
mkstemp.return_value = fd, file_name
|
mkstemp.return_value = fd, file_name
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
printer.print_document(
|
printer.print_document(
|
||||||
self.report, b'content to print', doc_format='pdf')
|
self.report, b"content to print", doc_format="pdf"
|
||||||
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_print_file(self, cups):
|
def test_print_file(self, cups):
|
||||||
""" It should print a file through CUPS """
|
""" It should print a file through CUPS """
|
||||||
file_name = 'file_name'
|
file_name = "file_name"
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.print_file(file_name, 'pdf')
|
printer.print_file(file_name, "pdf")
|
||||||
cups.Connection().printFile.assert_called_once_with(
|
cups.Connection().printFile.assert_called_once_with(
|
||||||
printer.system_name,
|
printer.system_name, file_name, file_name, options={}
|
||||||
file_name,
|
)
|
||||||
file_name,
|
|
||||||
options={})
|
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_print_file_error(self, cups):
|
def test_print_file_error(self, cups):
|
||||||
""" It should print a file through CUPS """
|
""" It should print a file through CUPS """
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
file_name = 'file_name'
|
file_name = "file_name"
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
printer.print_file(file_name)
|
printer.print_file(file_name)
|
||||||
@@ -150,38 +143,34 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
printer.unset_default()
|
printer.unset_default()
|
||||||
self.assertFalse(printer.default)
|
self.assertFalse(printer.default)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_cancel_all_jobs(self, cups):
|
def test_cancel_all_jobs(self, cups):
|
||||||
""" It should cancel all jobs """
|
""" It should cancel all jobs """
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.action_cancel_all_jobs()
|
printer.action_cancel_all_jobs()
|
||||||
cups.Connection().cancelAllJobs.assert_called_once_with(
|
cups.Connection().cancelAllJobs.assert_called_once_with(
|
||||||
name=printer.system_name,
|
name=printer.system_name, purge_jobs=False
|
||||||
purge_jobs=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_cancel_and_purge_all_jobs(self, cups):
|
def test_cancel_and_purge_all_jobs(self, cups):
|
||||||
""" It should cancel all jobs """
|
""" It should cancel all jobs """
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.cancel_all_jobs(purge_jobs=True)
|
printer.cancel_all_jobs(purge_jobs=True)
|
||||||
cups.Connection().cancelAllJobs.assert_called_once_with(
|
cups.Connection().cancelAllJobs.assert_called_once_with(
|
||||||
name=printer.system_name,
|
name=printer.system_name, purge_jobs=True
|
||||||
purge_jobs=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_enable_printer(self, cups):
|
def test_enable_printer(self, cups):
|
||||||
""" It should enable the printer """
|
""" It should enable the printer """
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.enable()
|
printer.enable()
|
||||||
cups.Connection().enablePrinter.assert_called_once_with(
|
cups.Connection().enablePrinter.assert_called_once_with(printer.system_name)
|
||||||
printer.system_name)
|
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_disable_printer(self, cups):
|
def test_disable_printer(self, cups):
|
||||||
""" It should disable the printer """
|
""" It should disable the printer """
|
||||||
printer = self.new_record()
|
printer = self.new_record()
|
||||||
printer.disable()
|
printer.disable()
|
||||||
cups.Connection().disablePrinter.assert_called_once_with(
|
cups.Connection().disablePrinter.assert_called_once_with(printer.system_name)
|
||||||
printer.system_name)
|
|
||||||
|
|||||||
@@ -2,13 +2,14 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
import mock
|
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
import mock
|
||||||
|
|
||||||
from odoo.tests.common import TransactionCase
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
model = "odoo.addons.base_report_to_printer.models.printing_printer"
|
||||||
model = 'odoo.addons.base_report_to_printer.models.printing_printer'
|
server_model = "odoo.addons.base_report_to_printer.models.printing_server"
|
||||||
server_model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
|
||||||
|
|
||||||
ppd_header = '*PPD-Adobe: "4.3"'
|
ppd_header = '*PPD-Adobe: "4.3"'
|
||||||
ppd_input_slot_header = """
|
ppd_input_slot_header = """
|
||||||
@@ -33,34 +34,35 @@ ppd_input_slot_footer = """
|
|||||||
|
|
||||||
|
|
||||||
class TestPrintingPrinter(TransactionCase):
|
class TestPrintingPrinter(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPrintingPrinter, self).setUp()
|
super(TestPrintingPrinter, self).setUp()
|
||||||
self.Model = self.env['printing.printer']
|
self.Model = self.env["printing.printer"]
|
||||||
self.ServerModel = self.env['printing.server']
|
self.ServerModel = self.env["printing.server"]
|
||||||
self.server = self.env['printing.server'].create({})
|
self.server = self.env["printing.server"].create({})
|
||||||
self.printer = self.env['printing.printer'].create({
|
self.printer = self.env["printing.printer"].create(
|
||||||
'name': 'Printer',
|
{
|
||||||
'server_id': self.server.id,
|
"name": "Printer",
|
||||||
'system_name': 'Sys Name',
|
"server_id": self.server.id,
|
||||||
'default': True,
|
"system_name": "Sys Name",
|
||||||
'status': 'unknown',
|
"default": True,
|
||||||
'status_message': 'Msg',
|
"status": "unknown",
|
||||||
'model': 'res.users',
|
"status_message": "Msg",
|
||||||
'location': 'Location',
|
"model": "res.users",
|
||||||
'uri': 'URI',
|
"location": "Location",
|
||||||
})
|
"uri": "URI",
|
||||||
|
}
|
||||||
|
)
|
||||||
self.tray_vals = {
|
self.tray_vals = {
|
||||||
'name': 'Tray',
|
"name": "Tray",
|
||||||
'system_name': 'TrayName',
|
"system_name": "TrayName",
|
||||||
'printer_id': self.printer.id,
|
"printer_id": self.printer.id,
|
||||||
}
|
}
|
||||||
|
|
||||||
def new_tray(self, vals=None):
|
def new_tray(self, vals=None):
|
||||||
values = self.tray_vals
|
values = self.tray_vals
|
||||||
if vals is not None:
|
if vals is not None:
|
||||||
values.update(vals)
|
values.update(vals)
|
||||||
return self.env['printing.tray'].create(values)
|
return self.env["printing.tray"].create(values)
|
||||||
|
|
||||||
def build_ppd(self, input_slots=None):
|
def build_ppd(self, input_slots=None):
|
||||||
"""
|
"""
|
||||||
@@ -71,8 +73,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
if input_slots is not None:
|
if input_slots is not None:
|
||||||
for input_slot in input_slots:
|
for input_slot in input_slots:
|
||||||
ppd_contents += ppd_input_slot_body.format(
|
ppd_contents += ppd_input_slot_body.format(
|
||||||
name=input_slot['name'],
|
name=input_slot["name"], text=input_slot["text"]
|
||||||
text=input_slot['text'],
|
|
||||||
)
|
)
|
||||||
ppd_contents += ppd_input_slot_footer
|
ppd_contents += ppd_input_slot_footer
|
||||||
|
|
||||||
@@ -88,29 +89,29 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
|
|
||||||
if file_name:
|
if file_name:
|
||||||
ppd_contents = self.build_ppd(input_slots=input_slots)
|
ppd_contents = self.build_ppd(input_slots=input_slots)
|
||||||
with open(file_name, 'w') as fp:
|
with open(file_name, "w") as fp:
|
||||||
fp.write(ppd_contents)
|
fp.write(ppd_contents)
|
||||||
|
|
||||||
cups.Connection().getPPD3.return_value = (200, 0, file_name)
|
cups.Connection().getPPD3.return_value = (200, 0, file_name)
|
||||||
cups.Connection().getPrinters.return_value = {
|
cups.Connection().getPrinters.return_value = {
|
||||||
self.printer.system_name: {
|
self.printer.system_name: {
|
||||||
'printer-info': 'info',
|
"printer-info": "info",
|
||||||
'printer-uri-supported': 'uri',
|
"printer-uri-supported": "uri",
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_update_printers(self, cups):
|
def test_update_printers(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that the update_printers method calls _prepare_update_from_cups
|
Check that the update_printers method calls _prepare_update_from_cups
|
||||||
"""
|
"""
|
||||||
self.mock_cups_ppd(cups, file_name=False)
|
self.mock_cups_ppd(cups, file_name=False)
|
||||||
|
|
||||||
self.assertEqual(self.printer.name, 'Printer')
|
self.assertEqual(self.printer.name, "Printer")
|
||||||
self.ServerModel.update_printers()
|
self.ServerModel.update_printers()
|
||||||
self.assertEqual(self.printer.name, 'info')
|
self.assertEqual(self.printer.name, "info")
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_prepare_update_from_cups_no_ppd(self, cups):
|
def test_prepare_update_from_cups_no_ppd(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that the tray_ids field has no value when no PPD is available
|
Check that the tray_ids field has no value when no PPD is available
|
||||||
@@ -121,9 +122,9 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
cups_printer = connection.getPrinters()[self.printer.system_name]
|
cups_printer = connection.getPrinters()[self.printer.system_name]
|
||||||
|
|
||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertFalse('tray_ids' in vals)
|
self.assertFalse("tray_ids" in vals)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_prepare_update_from_cups_empty_ppd(self, cups):
|
def test_prepare_update_from_cups_empty_ppd(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that the tray_ids field has no value when the PPD file has
|
Check that the tray_ids field has no value when the PPD file has
|
||||||
@@ -132,23 +133,23 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
fd, file_name = tempfile.mkstemp()
|
fd, file_name = tempfile.mkstemp()
|
||||||
self.mock_cups_ppd(cups, file_name=file_name)
|
self.mock_cups_ppd(cups, file_name=file_name)
|
||||||
# Replace the ppd file's contents by an empty file
|
# Replace the ppd file's contents by an empty file
|
||||||
with open(file_name, 'w') as fp:
|
with open(file_name, "w") as fp:
|
||||||
fp.write(ppd_header)
|
fp.write(ppd_header)
|
||||||
|
|
||||||
connection = cups.Connection()
|
connection = cups.Connection()
|
||||||
cups_printer = connection.getPrinters()[self.printer.system_name]
|
cups_printer = connection.getPrinters()[self.printer.system_name]
|
||||||
|
|
||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertFalse('tray_ids' in vals)
|
self.assertFalse("tray_ids" in vals)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
@mock.patch('os.unlink')
|
@mock.patch("os.unlink")
|
||||||
def test_prepare_update_from_cups_unlink_error(self, os_unlink, cups):
|
def test_prepare_update_from_cups_unlink_error(self, os_unlink, cups):
|
||||||
"""
|
"""
|
||||||
When OSError other than ENOENT is encountered, the exception is raised
|
When OSError other than ENOENT is encountered, the exception is raised
|
||||||
"""
|
"""
|
||||||
# Break os.unlink
|
# Break os.unlink
|
||||||
os_unlink.side_effect = OSError(errno.EIO, 'Error')
|
os_unlink.side_effect = OSError(errno.EIO, "Error")
|
||||||
|
|
||||||
self.mock_cups_ppd(cups)
|
self.mock_cups_ppd(cups)
|
||||||
|
|
||||||
@@ -158,17 +159,16 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
with self.assertRaises(OSError):
|
with self.assertRaises(OSError):
|
||||||
self.printer._prepare_update_from_cups(connection, cups_printer)
|
self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
@mock.patch('os.unlink')
|
@mock.patch("os.unlink")
|
||||||
def test_prepare_update_from_cups_unlink_error_enoent(
|
def test_prepare_update_from_cups_unlink_error_enoent(self, os_unlink, cups):
|
||||||
self, os_unlink, cups):
|
|
||||||
"""
|
"""
|
||||||
When a ENOENT error is encountered, the file has already been unlinked
|
When a ENOENT error is encountered, the file has already been unlinked
|
||||||
This is not an issue, as we were trying to delete the file.
|
This is not an issue, as we were trying to delete the file.
|
||||||
The update can continue.
|
The update can continue.
|
||||||
"""
|
"""
|
||||||
# Break os.unlink
|
# Break os.unlink
|
||||||
os_unlink.side_effect = OSError(errno.ENOENT, 'Error')
|
os_unlink.side_effect = OSError(errno.ENOENT, "Error")
|
||||||
|
|
||||||
self.mock_cups_ppd(cups)
|
self.mock_cups_ppd(cups)
|
||||||
|
|
||||||
@@ -176,12 +176,12 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
cups_printer = connection.getPrinters()[self.printer.system_name]
|
cups_printer = connection.getPrinters()[self.printer.system_name]
|
||||||
|
|
||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertEqual(vals['tray_ids'], [(0, 0, {
|
self.assertEqual(
|
||||||
'name': 'Auto (Default)',
|
vals["tray_ids"],
|
||||||
'system_name': 'Auto',
|
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
||||||
})])
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_prepare_update_from_cups(self, cups):
|
def test_prepare_update_from_cups(self, cups):
|
||||||
"""
|
"""
|
||||||
Check the return value when adding a single tray
|
Check the return value when adding a single tray
|
||||||
@@ -192,55 +192,51 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
cups_printer = connection.getPrinters()[self.printer.system_name]
|
cups_printer = connection.getPrinters()[self.printer.system_name]
|
||||||
|
|
||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertEqual(vals['tray_ids'], [(0, 0, {
|
self.assertEqual(
|
||||||
'name': 'Auto (Default)',
|
vals["tray_ids"],
|
||||||
'system_name': 'Auto',
|
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
||||||
})])
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_prepare_update_from_cups_with_multiple_trays(self, cups):
|
def test_prepare_update_from_cups_with_multiple_trays(self, cups):
|
||||||
"""
|
"""
|
||||||
Check the return value when adding multiple trays at once
|
Check the return value when adding multiple trays at once
|
||||||
"""
|
"""
|
||||||
self.mock_cups_ppd(cups, input_slots=[
|
self.mock_cups_ppd(cups, input_slots=[{"name": "Tray1", "text": "Tray 1"}])
|
||||||
{'name': 'Tray1', 'text': 'Tray 1'},
|
|
||||||
])
|
|
||||||
|
|
||||||
connection = cups.Connection()
|
connection = cups.Connection()
|
||||||
cups_printer = connection.getPrinters()[self.printer.system_name]
|
cups_printer = connection.getPrinters()[self.printer.system_name]
|
||||||
|
|
||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertItemsEqual(vals['tray_ids'], [(0, 0, {
|
self.assertItemsEqual(
|
||||||
'name': 'Auto (Default)',
|
vals["tray_ids"],
|
||||||
'system_name': 'Auto',
|
[
|
||||||
}), (0, 0, {
|
(0, 0, {"name": "Auto (Default)", "system_name": "Auto"}),
|
||||||
'name': 'Tray 1',
|
(0, 0, {"name": "Tray 1", "system_name": "Tray1"}),
|
||||||
'system_name': 'Tray1',
|
],
|
||||||
})])
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_prepare_update_from_cups_already_known_trays(self, cups):
|
def test_prepare_update_from_cups_already_known_trays(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that calling the method twice doesn't create the trays multiple
|
Check that calling the method twice doesn't create the trays multiple
|
||||||
times
|
times
|
||||||
"""
|
"""
|
||||||
self.mock_cups_ppd(cups, input_slots=[
|
self.mock_cups_ppd(cups, input_slots=[{"name": "Tray1", "text": "Tray 1"}])
|
||||||
{'name': 'Tray1', 'text': 'Tray 1'},
|
|
||||||
])
|
|
||||||
|
|
||||||
connection = cups.Connection()
|
connection = cups.Connection()
|
||||||
cups_printer = connection.getPrinters()[self.printer.system_name]
|
cups_printer = connection.getPrinters()[self.printer.system_name]
|
||||||
|
|
||||||
# Create a tray which is in the PPD file
|
# Create a tray which is in the PPD file
|
||||||
self.new_tray({'system_name': 'Tray1'})
|
self.new_tray({"system_name": "Tray1"})
|
||||||
|
|
||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertEqual(vals['tray_ids'], [(0, 0, {
|
self.assertEqual(
|
||||||
'name': 'Auto (Default)',
|
vals["tray_ids"],
|
||||||
'system_name': 'Auto',
|
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"})],
|
||||||
})])
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % server_model)
|
@mock.patch("%s.cups" % server_model)
|
||||||
def test_prepare_update_from_cups_unknown_trays(self, cups):
|
def test_prepare_update_from_cups_unknown_trays(self, cups):
|
||||||
"""
|
"""
|
||||||
Check that trays which are not in the PPD file are removed from Odoo
|
Check that trays which are not in the PPD file are removed from Odoo
|
||||||
@@ -254,7 +250,7 @@ class TestPrintingPrinter(TransactionCase):
|
|||||||
tray = self.new_tray()
|
tray = self.new_tray()
|
||||||
|
|
||||||
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
vals = self.printer._prepare_update_from_cups(connection, cups_printer)
|
||||||
self.assertEqual(vals['tray_ids'], [(0, 0, {
|
self.assertEqual(
|
||||||
'name': 'Auto (Default)',
|
vals["tray_ids"],
|
||||||
'system_name': 'Auto',
|
[(0, 0, {"name": "Auto (Default)", "system_name": "Auto"}), (2, tray.id)],
|
||||||
}), (2, tray.id)])
|
)
|
||||||
|
|||||||
@@ -3,11 +3,10 @@
|
|||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from odoo.tests.common import TransactionCase
|
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
model = "odoo.addons.base_report_to_printer.models.printing_server"
|
||||||
model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
|
||||||
|
|
||||||
|
|
||||||
class StopTest(Exception):
|
class StopTest(Exception):
|
||||||
@@ -15,90 +14,75 @@ class StopTest(Exception):
|
|||||||
|
|
||||||
|
|
||||||
class TestPrintingPrinterWizard(TransactionCase):
|
class TestPrintingPrinterWizard(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPrintingPrinterWizard, self).setUp()
|
super(TestPrintingPrinterWizard, self).setUp()
|
||||||
self.Model = self.env['printing.printer.update.wizard']
|
self.Model = self.env["printing.printer.update.wizard"]
|
||||||
self.server = self.env['printing.server'].create({})
|
self.server = self.env["printing.server"].create({})
|
||||||
self.printer_vals = {
|
self.printer_vals = {
|
||||||
'printer-info': 'Info',
|
"printer-info": "Info",
|
||||||
'printer-make-and-model': 'Make and Model',
|
"printer-make-and-model": "Make and Model",
|
||||||
'printer-location': "location",
|
"printer-location": "location",
|
||||||
'device-uri': 'URI',
|
"device-uri": "URI",
|
||||||
'printer-uri-supported': 'uri'
|
"printer-uri-supported": "uri",
|
||||||
}
|
}
|
||||||
|
|
||||||
def _record_vals(self, sys_name='sys_name'):
|
def _record_vals(self, sys_name="sys_name"):
|
||||||
return {
|
return {
|
||||||
'name': self.printer_vals['printer-info'],
|
"name": self.printer_vals["printer-info"],
|
||||||
'server_id': self.server.id,
|
"server_id": self.server.id,
|
||||||
'system_name': sys_name,
|
"system_name": sys_name,
|
||||||
'model': self.printer_vals['printer-make-and-model'],
|
"model": self.printer_vals["printer-make-and-model"],
|
||||||
'location': self.printer_vals['printer-location'],
|
"location": self.printer_vals["printer-location"],
|
||||||
'uri': self.printer_vals['device-uri'],
|
"uri": self.printer_vals["device-uri"],
|
||||||
}
|
}
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_action_ok_inits_connection(self, cups):
|
def test_action_ok_inits_connection(self, cups):
|
||||||
""" It should initialize CUPS connection """
|
""" It should initialize CUPS connection """
|
||||||
self.Model.action_ok()
|
self.Model.action_ok()
|
||||||
cups.Connection.assert_called_once_with(
|
cups.Connection.assert_called_once_with(
|
||||||
host=self.server.address, port=self.server.port,
|
host=self.server.address, port=self.server.port
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_action_ok_gets_printers(self, cups):
|
def test_action_ok_gets_printers(self, cups):
|
||||||
""" It should get printers from CUPS """
|
""" It should get printers from CUPS """
|
||||||
cups.Connection().getPrinters.return_value = {
|
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
||||||
'sys_name': self.printer_vals,
|
cups.Connection().getPPD3.return_value = (200, 0, "")
|
||||||
}
|
|
||||||
cups.Connection().getPPD3.return_value = (200, 0, '')
|
|
||||||
self.Model.action_ok()
|
self.Model.action_ok()
|
||||||
cups.Connection().getPrinters.assert_called_once_with()
|
cups.Connection().getPrinters.assert_called_once_with()
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_action_ok_raises_warning_on_error(self, cups):
|
def test_action_ok_raises_warning_on_error(self, cups):
|
||||||
""" It should raise Warning on any error """
|
""" It should raise Warning on any error """
|
||||||
cups.Connection.side_effect = StopTest
|
cups.Connection.side_effect = StopTest
|
||||||
with self.assertRaises(UserError):
|
with self.assertRaises(UserError):
|
||||||
self.Model.action_ok()
|
self.Model.action_ok()
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_action_ok_creates_new_printer(self, cups):
|
def test_action_ok_creates_new_printer(self, cups):
|
||||||
""" It should create new printer w/ proper vals """
|
""" It should create new printer w/ proper vals """
|
||||||
cups.Connection().getPrinters.return_value = {
|
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
||||||
'sys_name': self.printer_vals,
|
cups.Connection().getPPD3.return_value = (200, 0, "")
|
||||||
}
|
|
||||||
cups.Connection().getPPD3.return_value = (200, 0, '')
|
|
||||||
self.Model.action_ok()
|
self.Model.action_ok()
|
||||||
rec_id = self.env['printing.printer'].search([
|
rec_id = self.env["printing.printer"].search(
|
||||||
('system_name', '=', 'sys_name')
|
[("system_name", "=", "sys_name")], limit=1
|
||||||
],
|
|
||||||
limit=1,
|
|
||||||
)
|
)
|
||||||
self.assertTrue(rec_id)
|
self.assertTrue(rec_id)
|
||||||
for key, val in self._record_vals().items():
|
for key, val in self._record_vals().items():
|
||||||
if rec_id._fields[key].type == 'many2one':
|
if rec_id._fields[key].type == "many2one":
|
||||||
val = self.env[rec_id._fields[key].comodel_name].browse(val)
|
val = self.env[rec_id._fields[key].comodel_name].browse(val)
|
||||||
|
|
||||||
self.assertEqual(
|
self.assertEqual(val, rec_id[key])
|
||||||
val, rec_id[key],
|
|
||||||
)
|
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_action_ok_skips_existing_printer(self, cups):
|
def test_action_ok_skips_existing_printer(self, cups):
|
||||||
""" It should not recreate existing printers """
|
""" It should not recreate existing printers """
|
||||||
cups.Connection().getPrinters.return_value = {
|
cups.Connection().getPrinters.return_value = {"sys_name": self.printer_vals}
|
||||||
'sys_name': self.printer_vals,
|
cups.Connection().getPPD3.return_value = (200, 0, "")
|
||||||
}
|
self.env["printing.printer"].create(self._record_vals())
|
||||||
cups.Connection().getPPD3.return_value = (200, 0, '')
|
|
||||||
self.env['printing.printer'].create(
|
|
||||||
self._record_vals()
|
|
||||||
)
|
|
||||||
self.Model.action_ok()
|
self.Model.action_ok()
|
||||||
res_ids = self.env['printing.printer'].search([
|
res_ids = self.env["printing.printer"].search(
|
||||||
('system_name', '=', 'sys_name')
|
[("system_name", "=", "sys_name")]
|
||||||
])
|
|
||||||
self.assertEqual(
|
|
||||||
1, len(res_ids),
|
|
||||||
)
|
)
|
||||||
|
self.assertEqual(1, len(res_ids))
|
||||||
|
|||||||
@@ -5,18 +5,17 @@ from odoo.tests.common import TransactionCase
|
|||||||
|
|
||||||
|
|
||||||
class TestPrintingReportXmlAction(TransactionCase):
|
class TestPrintingReportXmlAction(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPrintingReportXmlAction, self).setUp()
|
super(TestPrintingReportXmlAction, self).setUp()
|
||||||
self.Model = self.env['printing.report.xml.action']
|
self.Model = self.env["printing.report.xml.action"]
|
||||||
|
|
||||||
self.report = self.env['ir.actions.report'].search([], limit=1)
|
self.report = self.env["ir.actions.report"].search([], limit=1)
|
||||||
self.server = self.env['printing.server'].create({})
|
self.server = self.env["printing.server"].create({})
|
||||||
|
|
||||||
self.report_vals = {
|
self.report_vals = {
|
||||||
'report_id': self.report.id,
|
"report_id": self.report.id,
|
||||||
'user_id': self.env.ref('base.user_demo').id,
|
"user_id": self.env.ref("base.user_demo").id,
|
||||||
'action': 'server',
|
"action": "server",
|
||||||
}
|
}
|
||||||
|
|
||||||
def new_record(self, vals=None):
|
def new_record(self, vals=None):
|
||||||
@@ -27,65 +26,73 @@ class TestPrintingReportXmlAction(TransactionCase):
|
|||||||
return self.Model.create(values)
|
return self.Model.create(values)
|
||||||
|
|
||||||
def new_printer(self):
|
def new_printer(self):
|
||||||
return self.env['printing.printer'].create({
|
return self.env["printing.printer"].create(
|
||||||
'name': 'Printer',
|
{
|
||||||
'server_id': self.server.id,
|
"name": "Printer",
|
||||||
'system_name': 'Sys Name',
|
"server_id": self.server.id,
|
||||||
'default': True,
|
"system_name": "Sys Name",
|
||||||
'status': 'unknown',
|
"default": True,
|
||||||
'status_message': 'Msg',
|
"status": "unknown",
|
||||||
'model': 'res.users',
|
"status_message": "Msg",
|
||||||
'location': 'Location',
|
"model": "res.users",
|
||||||
'uri': 'URI',
|
"location": "Location",
|
||||||
})
|
"uri": "URI",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def test_behaviour(self):
|
def test_behaviour(self):
|
||||||
""" It should return some action's data, unless called on empty
|
""" It should return some action's data, unless called on empty
|
||||||
recordset
|
recordset
|
||||||
"""
|
"""
|
||||||
xml_action = self.new_record()
|
xml_action = self.new_record()
|
||||||
self.assertEqual(xml_action.behaviour(), {
|
self.assertEqual(
|
||||||
'action': xml_action.action,
|
xml_action.behaviour(),
|
||||||
'printer': xml_action.printer_id,
|
{
|
||||||
'tray': False,
|
"action": xml_action.action,
|
||||||
})
|
"printer": xml_action.printer_id,
|
||||||
|
"tray": False,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
xml_action = self.new_record({'printer_id': self.new_printer().id})
|
xml_action = self.new_record({"printer_id": self.new_printer().id})
|
||||||
self.assertEqual(xml_action.behaviour(), {
|
self.assertEqual(
|
||||||
'action': xml_action.action,
|
xml_action.behaviour(),
|
||||||
'printer': xml_action.printer_id,
|
{
|
||||||
'tray': False,
|
"action": xml_action.action,
|
||||||
})
|
"printer": xml_action.printer_id,
|
||||||
|
"tray": False,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
self.assertEqual(self.Model.behaviour(), {})
|
self.assertEqual(self.Model.behaviour(), {})
|
||||||
|
|
||||||
def test_onchange_printer_tray_id_empty(self):
|
def test_onchange_printer_tray_id_empty(self):
|
||||||
action = self.env['printing.report.xml.action'].new(
|
action = self.env["printing.report.xml.action"].new({"printer_tray_id": False})
|
||||||
{'printer_tray_id': False})
|
|
||||||
action.onchange_printer_id()
|
action.onchange_printer_id()
|
||||||
self.assertFalse(action.printer_tray_id)
|
self.assertFalse(action.printer_tray_id)
|
||||||
|
|
||||||
def test_onchange_printer_tray_id_not_empty(self):
|
def test_onchange_printer_tray_id_not_empty(self):
|
||||||
server = self.env['printing.server'].create({})
|
server = self.env["printing.server"].create({})
|
||||||
printer = self.env['printing.printer'].create({
|
printer = self.env["printing.printer"].create(
|
||||||
'name': 'Printer',
|
{
|
||||||
'server_id': server.id,
|
"name": "Printer",
|
||||||
'system_name': 'Sys Name',
|
"server_id": server.id,
|
||||||
'default': True,
|
"system_name": "Sys Name",
|
||||||
'status': 'unknown',
|
"default": True,
|
||||||
'status_message': 'Msg',
|
"status": "unknown",
|
||||||
'model': 'res.users',
|
"status_message": "Msg",
|
||||||
'location': 'Location',
|
"model": "res.users",
|
||||||
'uri': 'URI',
|
"location": "Location",
|
||||||
})
|
"uri": "URI",
|
||||||
tray = self.env['printing.tray'].create({
|
}
|
||||||
'name': 'Tray',
|
)
|
||||||
'system_name': 'TrayName',
|
tray = self.env["printing.tray"].create(
|
||||||
'printer_id': printer.id,
|
{"name": "Tray", "system_name": "TrayName", "printer_id": printer.id}
|
||||||
})
|
)
|
||||||
|
|
||||||
action = self.env['printing.report.xml.action'].new(
|
action = self.env["printing.report.xml.action"].new(
|
||||||
{'printer_tray_id': tray.id})
|
{"printer_tray_id": tray.id}
|
||||||
|
)
|
||||||
self.assertEqual(action.printer_tray_id, tray)
|
self.assertEqual(action.printer_tray_id, tray)
|
||||||
action.onchange_printer_id()
|
action.onchange_printer_id()
|
||||||
self.assertFalse(action.printer_tray_id)
|
self.assertFalse(action.printer_tray_id)
|
||||||
|
|||||||
@@ -6,207 +6,189 @@ import mock
|
|||||||
from odoo import fields
|
from odoo import fields
|
||||||
from odoo.tests.common import TransactionCase
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
model = "odoo.addons.base_report_to_printer.models.printing_server"
|
||||||
model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
|
||||||
|
|
||||||
|
|
||||||
class TestPrintingServer(TransactionCase):
|
class TestPrintingServer(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPrintingServer, self).setUp()
|
super(TestPrintingServer, self).setUp()
|
||||||
self.Model = self.env['printing.server']
|
self.Model = self.env["printing.server"]
|
||||||
self.server = self.Model.create({})
|
self.server = self.Model.create({})
|
||||||
self.printer_vals = {
|
self.printer_vals = {
|
||||||
'name': 'Printer',
|
"name": "Printer",
|
||||||
'server_id': self.server.id,
|
"server_id": self.server.id,
|
||||||
'system_name': 'Sys Name',
|
"system_name": "Sys Name",
|
||||||
'default': True,
|
"default": True,
|
||||||
'status': 'unknown',
|
"status": "unknown",
|
||||||
'status_message': 'Msg',
|
"status_message": "Msg",
|
||||||
'model': 'res.users',
|
"model": "res.users",
|
||||||
'location': 'Location',
|
"location": "Location",
|
||||||
'uri': 'URI',
|
"uri": "URI",
|
||||||
}
|
}
|
||||||
self.job_vals = {
|
self.job_vals = {
|
||||||
'server_id': self.server.id,
|
"server_id": self.server.id,
|
||||||
'job_id_cups': 1,
|
"job_id_cups": 1,
|
||||||
'job_media_progress': 0,
|
"job_media_progress": 0,
|
||||||
'time_at_creation': fields.Datetime.now(),
|
"time_at_creation": fields.Datetime.now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
def new_printer(self):
|
def new_printer(self):
|
||||||
return self.env['printing.printer'].create(self.printer_vals)
|
return self.env["printing.printer"].create(self.printer_vals)
|
||||||
|
|
||||||
def new_job(self, printer, vals=None):
|
def new_job(self, printer, vals=None):
|
||||||
values = self.job_vals
|
values = self.job_vals
|
||||||
if vals is not None:
|
if vals is not None:
|
||||||
values.update(vals)
|
values.update(vals)
|
||||||
values['printer_id'] = printer.id
|
values["printer_id"] = printer.id
|
||||||
return self.env['printing.job'].create(values)
|
return self.env["printing.job"].create(values)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_printers_error(self, cups):
|
def test_update_printers_error(self, cups):
|
||||||
""" It should catch any exception from CUPS and update status """
|
""" It should catch any exception from CUPS and update status """
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
rec_id = self.new_printer()
|
rec_id = self.new_printer()
|
||||||
self.Model.update_printers()
|
self.Model.update_printers()
|
||||||
self.assertEqual(
|
self.assertEqual("server-error", rec_id.status)
|
||||||
'server-error', rec_id.status,
|
|
||||||
)
|
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_printers_inits_cups(self, cups):
|
def test_update_printers_inits_cups(self, cups):
|
||||||
""" It should init CUPS connection """
|
""" It should init CUPS connection """
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
self.Model.update_printers()
|
self.Model.update_printers()
|
||||||
cups.Connection.assert_called_once_with(
|
cups.Connection.assert_called_once_with(
|
||||||
host=self.server.address, port=self.server.port,
|
host=self.server.address, port=self.server.port
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_printers_gets_all_printers(self, cups):
|
def test_update_printers_gets_all_printers(self, cups):
|
||||||
""" It should get all printers from CUPS server """
|
""" It should get all printers from CUPS server """
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
self.Model.update_printers()
|
self.Model.update_printers()
|
||||||
cups.Connection().getPrinters.assert_called_once_with()
|
cups.Connection().getPrinters.assert_called_once_with()
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_printers_search(self, cups):
|
def test_update_printers_search(self, cups):
|
||||||
""" It should search all when no domain """
|
""" It should search all when no domain """
|
||||||
with mock.patch.object(self.Model, 'search') as search:
|
with mock.patch.object(self.Model, "search") as search:
|
||||||
self.Model.update_printers()
|
self.Model.update_printers()
|
||||||
search.assert_called_once_with([])
|
search.assert_called_once_with([])
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_printers_search_domain(self, cups):
|
def test_update_printers_search_domain(self, cups):
|
||||||
""" It should use specific domain for search """
|
""" It should use specific domain for search """
|
||||||
with mock.patch.object(self.Model, 'search') as search:
|
with mock.patch.object(self.Model, "search") as search:
|
||||||
expect = [('id', '>', 0)]
|
expect = [("id", ">", 0)]
|
||||||
self.Model.update_printers(expect)
|
self.Model.update_printers(expect)
|
||||||
search.assert_called_once_with(expect)
|
search.assert_called_once_with(expect)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_printers_update_unavailable(self, cups):
|
def test_update_printers_update_unavailable(self, cups):
|
||||||
""" It should update status when printer is unavailable """
|
""" It should update status when printer is unavailable """
|
||||||
rec_id = self.new_printer()
|
rec_id = self.new_printer()
|
||||||
cups.Connection().getPrinters().get.return_value = False
|
cups.Connection().getPrinters().get.return_value = False
|
||||||
self.Model.action_update_printers()
|
self.Model.action_update_printers()
|
||||||
self.assertEqual(
|
self.assertEqual("unavailable", rec_id.status)
|
||||||
'unavailable', rec_id.status,
|
|
||||||
)
|
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_jobs_cron(self, cups):
|
def test_update_jobs_cron(self, cups):
|
||||||
""" It should get all jobs from CUPS server """
|
""" It should get all jobs from CUPS server """
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
self.Model.action_update_jobs()
|
self.Model.action_update_jobs()
|
||||||
cups.Connection().getPrinters.assert_called_once_with()
|
cups.Connection().getPrinters.assert_called_once_with()
|
||||||
cups.Connection().getJobs.assert_called_once_with(
|
cups.Connection().getJobs.assert_called_once_with(
|
||||||
which_jobs='all',
|
which_jobs="all",
|
||||||
first_job_id=-1,
|
first_job_id=-1,
|
||||||
requested_attributes=[
|
requested_attributes=[
|
||||||
'job-name',
|
"job-name",
|
||||||
'job-id',
|
"job-id",
|
||||||
'printer-uri',
|
"printer-uri",
|
||||||
'job-media-progress',
|
"job-media-progress",
|
||||||
'time-at-creation',
|
"time-at-creation",
|
||||||
'job-state',
|
"job-state",
|
||||||
'job-state-reasons',
|
"job-state-reasons",
|
||||||
'time-at-processing',
|
"time-at-processing",
|
||||||
'time-at-completed',
|
"time-at-completed",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_jobs_button(self, cups):
|
def test_update_jobs_button(self, cups):
|
||||||
""" It should get all jobs from CUPS server """
|
""" It should get all jobs from CUPS server """
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
self.server.action_update_jobs()
|
self.server.action_update_jobs()
|
||||||
cups.Connection().getPrinters.assert_called_once_with()
|
cups.Connection().getPrinters.assert_called_once_with()
|
||||||
cups.Connection().getJobs.assert_called_once_with(
|
cups.Connection().getJobs.assert_called_once_with(
|
||||||
which_jobs='all',
|
which_jobs="all",
|
||||||
first_job_id=-1,
|
first_job_id=-1,
|
||||||
requested_attributes=[
|
requested_attributes=[
|
||||||
'job-name',
|
"job-name",
|
||||||
'job-id',
|
"job-id",
|
||||||
'printer-uri',
|
"printer-uri",
|
||||||
'job-media-progress',
|
"job-media-progress",
|
||||||
'time-at-creation',
|
"time-at-creation",
|
||||||
'job-state',
|
"job-state",
|
||||||
'job-state-reasons',
|
"job-state-reasons",
|
||||||
'time-at-processing',
|
"time-at-processing",
|
||||||
'time-at-completed',
|
"time-at-completed",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_jobs_error(self, cups):
|
def test_update_jobs_error(self, cups):
|
||||||
""" It should catch any exception from CUPS and update status """
|
""" It should catch any exception from CUPS and update status """
|
||||||
cups.Connection.side_effect = Exception
|
cups.Connection.side_effect = Exception
|
||||||
self.new_printer()
|
self.new_printer()
|
||||||
self.server.update_jobs()
|
self.server.update_jobs()
|
||||||
cups.Connection.assert_called_with(
|
cups.Connection.assert_called_with(
|
||||||
host=self.server.address, port=self.server.port,
|
host=self.server.address, port=self.server.port
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_jobs_uncompleted(self, cups):
|
def test_update_jobs_uncompleted(self, cups):
|
||||||
"""
|
"""
|
||||||
It should search which jobs have been completed since last update
|
It should search which jobs have been completed since last update
|
||||||
"""
|
"""
|
||||||
printer = self.new_printer()
|
printer = self.new_printer()
|
||||||
self.new_job(printer, vals={'job_state': 'completed'})
|
self.new_job(printer, vals={"job_state": "completed"})
|
||||||
self.new_job(printer, vals={
|
self.new_job(printer, vals={"job_id_cups": 2, "job_state": "processing"})
|
||||||
'job_id_cups': 2,
|
self.server.update_jobs(which="not-completed")
|
||||||
'job_state': 'processing',
|
|
||||||
})
|
|
||||||
self.server.update_jobs(which='not-completed')
|
|
||||||
cups.Connection().getJobs.assert_any_call(
|
cups.Connection().getJobs.assert_any_call(
|
||||||
which_jobs='completed', first_job_id=2,
|
which_jobs="completed",
|
||||||
|
first_job_id=2,
|
||||||
requested_attributes=[
|
requested_attributes=[
|
||||||
'job-name',
|
"job-name",
|
||||||
'job-id',
|
"job-id",
|
||||||
'printer-uri',
|
"printer-uri",
|
||||||
'job-media-progress',
|
"job-media-progress",
|
||||||
'time-at-creation',
|
"time-at-creation",
|
||||||
'job-state',
|
"job-state",
|
||||||
'job-state-reasons',
|
"job-state-reasons",
|
||||||
'time-at-processing',
|
"time-at-processing",
|
||||||
'time-at-completed',
|
"time-at-completed",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@mock.patch('%s.cups' % model)
|
@mock.patch("%s.cups" % model)
|
||||||
def test_update_jobs(self, cups):
|
def test_update_jobs(self, cups):
|
||||||
"""
|
"""
|
||||||
It should update all jobs, known or not
|
It should update all jobs, known or not
|
||||||
"""
|
"""
|
||||||
printer = self.new_printer()
|
printer = self.new_printer()
|
||||||
printer_uri = 'hostname:port/' + printer.system_name
|
printer_uri = "hostname:port/" + printer.system_name
|
||||||
cups.Connection().getJobs.return_value = {
|
cups.Connection().getJobs.return_value = {
|
||||||
1: {
|
1: {"printer-uri": printer_uri},
|
||||||
'printer-uri': printer_uri,
|
2: {"printer-uri": printer_uri, "job-state": 9},
|
||||||
},
|
4: {"printer-uri": printer_uri, "job-state": 5},
|
||||||
2: {
|
|
||||||
'printer-uri': printer_uri,
|
|
||||||
'job-state': 9,
|
|
||||||
},
|
|
||||||
4: {
|
|
||||||
'printer-uri': printer_uri,
|
|
||||||
'job-state': 5,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
self.new_job(printer, vals={'job_state': 'completed'})
|
self.new_job(printer, vals={"job_state": "completed"})
|
||||||
completed_job = self.new_job(printer, vals={
|
completed_job = self.new_job(
|
||||||
'job_id_cups': 2,
|
printer, vals={"job_id_cups": 2, "job_state": "processing"}
|
||||||
'job_state': 'processing',
|
)
|
||||||
})
|
purged_job = self.new_job(
|
||||||
purged_job = self.new_job(printer, vals={
|
printer, vals={"job_id_cups": 3, "job_state": "processing"}
|
||||||
'job_id_cups': 3,
|
)
|
||||||
'job_state': 'processing',
|
|
||||||
})
|
|
||||||
self.server.update_jobs()
|
self.server.update_jobs()
|
||||||
new_job = self.env['printing.job'].search([('job_id_cups', '=', 4)])
|
new_job = self.env["printing.job"].search([("job_id_cups", "=", 4)])
|
||||||
self.assertEqual(completed_job.job_state, 'completed')
|
self.assertEqual(completed_job.job_state, "completed")
|
||||||
self.assertEqual(purged_job.active, False)
|
self.assertEqual(purged_job.active, False)
|
||||||
self.assertEqual(new_job.job_state, 'processing')
|
self.assertEqual(new_job.job_state, "processing")
|
||||||
|
|||||||
@@ -3,49 +3,47 @@
|
|||||||
|
|
||||||
from odoo.tests.common import TransactionCase
|
from odoo.tests.common import TransactionCase
|
||||||
|
|
||||||
|
model = "odoo.addons.base_report_to_printer.models.printing_server"
|
||||||
model = 'odoo.addons.base_report_to_printer.models.printing_server'
|
|
||||||
|
|
||||||
|
|
||||||
class TestPrintingTray(TransactionCase):
|
class TestPrintingTray(TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestPrintingTray, self).setUp()
|
super(TestPrintingTray, self).setUp()
|
||||||
self.Model = self.env['printing.tray']
|
self.Model = self.env["printing.tray"]
|
||||||
self.server = self.env['printing.server'].create({})
|
self.server = self.env["printing.server"].create({})
|
||||||
self.printer = self.env['printing.printer'].create({
|
self.printer = self.env["printing.printer"].create(
|
||||||
'name': 'Printer',
|
{
|
||||||
'server_id': self.server.id,
|
"name": "Printer",
|
||||||
'system_name': 'Sys Name',
|
"server_id": self.server.id,
|
||||||
'default': True,
|
"system_name": "Sys Name",
|
||||||
'status': 'unknown',
|
"default": True,
|
||||||
'status_message': 'Msg',
|
"status": "unknown",
|
||||||
'model': 'res.users',
|
"status_message": "Msg",
|
||||||
'location': 'Location',
|
"model": "res.users",
|
||||||
'uri': 'URI',
|
"location": "Location",
|
||||||
})
|
"uri": "URI",
|
||||||
|
}
|
||||||
|
)
|
||||||
self.tray_vals = {
|
self.tray_vals = {
|
||||||
'name': 'Tray',
|
"name": "Tray",
|
||||||
'system_name': 'TrayName',
|
"system_name": "TrayName",
|
||||||
'printer_id': self.printer.id,
|
"printer_id": self.printer.id,
|
||||||
}
|
}
|
||||||
|
|
||||||
def new_tray(self):
|
def new_tray(self):
|
||||||
return self.env['printing.tray'].create(self.tray_vals)
|
return self.env["printing.tray"].create(self.tray_vals)
|
||||||
|
|
||||||
def test_report_behaviour(self):
|
def test_report_behaviour(self):
|
||||||
""" It should add the selected tray in the report data """
|
""" It should add the selected tray in the report data """
|
||||||
ir_report = self.env['ir.actions.report'].search([], limit=1)
|
ir_report = self.env["ir.actions.report"].search([], limit=1)
|
||||||
report = self.env['printing.report.xml.action'].create({
|
report = self.env["printing.report.xml.action"].create(
|
||||||
'user_id': self.env.user.id,
|
{"user_id": self.env.user.id, "report_id": ir_report.id, "action": "server"}
|
||||||
'report_id': ir_report.id,
|
)
|
||||||
'action': 'server',
|
|
||||||
})
|
|
||||||
report.printer_tray_id = False
|
report.printer_tray_id = False
|
||||||
behaviour = report.behaviour()
|
behaviour = report.behaviour()
|
||||||
self.assertEqual(behaviour['tray'], False)
|
self.assertEqual(behaviour["tray"], False)
|
||||||
|
|
||||||
# Check that we have te right value
|
# Check that we have te right value
|
||||||
report.printer_tray_id = self.new_tray()
|
report.printer_tray_id = self.new_tray()
|
||||||
behaviour = report.behaviour()
|
behaviour = report.behaviour()
|
||||||
self.assertEqual(behaviour['tray'], report.printer_tray_id.system_name)
|
self.assertEqual(behaviour["tray"], report.printer_tray_id.system_name)
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
from odoo.tests import common
|
|
||||||
from odoo import exceptions
|
from odoo import exceptions
|
||||||
|
from odoo.tests import common
|
||||||
|
|
||||||
|
|
||||||
@common.at_install(False)
|
@common.at_install(False)
|
||||||
@@ -12,118 +13,124 @@ from odoo import exceptions
|
|||||||
class TestReport(common.HttpCase):
|
class TestReport(common.HttpCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestReport, self).setUp()
|
super(TestReport, self).setUp()
|
||||||
self.Model = self.env['ir.actions.report']
|
self.Model = self.env["ir.actions.report"]
|
||||||
self.server = self.env['printing.server'].create({})
|
self.server = self.env["printing.server"].create({})
|
||||||
self.report_vals = {
|
self.report_vals = {
|
||||||
'name': 'Test Report',
|
"name": "Test Report",
|
||||||
'model': 'ir.actions.report',
|
"model": "ir.actions.report",
|
||||||
'report_name': 'Test Report',
|
"report_name": "Test Report",
|
||||||
}
|
}
|
||||||
self.report_imd = self.env["ir.model.data"].create({
|
self.report_imd = self.env["ir.model.data"].create(
|
||||||
"name": "test",
|
{"name": "test", "module": "base_report_to_printer", "model": "ir.ui.view"}
|
||||||
"module": "base_report_to_printer",
|
)
|
||||||
"model": "ir.ui.view",
|
self.report_view = self.env["ir.ui.view"].create(
|
||||||
})
|
{
|
||||||
self.report_view = self.env["ir.ui.view"].create({
|
"name": "Test",
|
||||||
"name": "Test",
|
"type": "qweb",
|
||||||
"type": "qweb",
|
"xml_id": "base_report_to_printer.test",
|
||||||
"xml_id": "base_report_to_printer.test",
|
"model_data_id": self.report_imd.id,
|
||||||
"model_data_id": self.report_imd.id,
|
"arch": """<t t-name="base_report_to_printer.test">
|
||||||
"arch": """<t t-name="base_report_to_printer.test">
|
|
||||||
<div>Test</div>
|
<div>Test</div>
|
||||||
</t>""",
|
</t>""",
|
||||||
})
|
}
|
||||||
|
)
|
||||||
self.report_imd.res_id = self.report_view.id
|
self.report_imd.res_id = self.report_view.id
|
||||||
self.report = self.Model.create({
|
self.report = self.Model.create(
|
||||||
"name": "Test",
|
{
|
||||||
"report_type": "qweb-pdf",
|
"name": "Test",
|
||||||
"model": "res.partner",
|
"report_type": "qweb-pdf",
|
||||||
"report_name": "base_report_to_printer.test",
|
"model": "res.partner",
|
||||||
})
|
"report_name": "base_report_to_printer.test",
|
||||||
|
}
|
||||||
|
)
|
||||||
self.partners = self.env["res.partner"]
|
self.partners = self.env["res.partner"]
|
||||||
for n in range(5):
|
for n in range(5):
|
||||||
self.partners += self.env["res.partner"].create({
|
self.partners += self.env["res.partner"].create({"name": "Test %d" % n})
|
||||||
"name": "Test %d" % n,
|
|
||||||
})
|
|
||||||
|
|
||||||
def new_record(self):
|
def new_record(self):
|
||||||
return self.Model.create(self.report_vals)
|
return self.Model.create(self.report_vals)
|
||||||
|
|
||||||
def new_printer(self):
|
def new_printer(self):
|
||||||
return self.env['printing.printer'].create({
|
return self.env["printing.printer"].create(
|
||||||
'name': 'Printer',
|
{
|
||||||
'server_id': self.server.id,
|
"name": "Printer",
|
||||||
'system_name': 'Sys Name',
|
"server_id": self.server.id,
|
||||||
'default': True,
|
"system_name": "Sys Name",
|
||||||
'status': 'unknown',
|
"default": True,
|
||||||
'status_message': 'Msg',
|
"status": "unknown",
|
||||||
'model': 'res.users',
|
"status_message": "Msg",
|
||||||
'location': 'Location',
|
"model": "res.users",
|
||||||
'uri': 'URI',
|
"location": "Location",
|
||||||
})
|
"uri": "URI",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def test_can_print_report_context_skip(self):
|
def test_can_print_report_context_skip(self):
|
||||||
""" It should return False based on context """
|
""" It should return False based on context """
|
||||||
rec_id = self.new_record().with_context(
|
rec_id = self.new_record().with_context(must_skip_send_to_printer=True)
|
||||||
must_skip_send_to_printer=True
|
res = rec_id._can_print_report({"action": "server"}, True, True)
|
||||||
)
|
|
||||||
res = rec_id._can_print_report(
|
|
||||||
{'action': 'server'}, True, True
|
|
||||||
)
|
|
||||||
self.assertFalse(res)
|
self.assertFalse(res)
|
||||||
|
|
||||||
def test_can_print_report_true(self):
|
def test_can_print_report_true(self):
|
||||||
""" It should return True when server print allowed """
|
""" It should return True when server print allowed """
|
||||||
res = self.new_record()._can_print_report(
|
res = self.new_record()._can_print_report({"action": "server"}, True, True)
|
||||||
{'action': 'server'}, True, True
|
|
||||||
)
|
|
||||||
self.assertTrue(res)
|
self.assertTrue(res)
|
||||||
|
|
||||||
def test_can_print_report_false(self):
|
def test_can_print_report_false(self):
|
||||||
""" It should return False when server print not allowed """
|
""" It should return False when server print not allowed """
|
||||||
res = self.new_record()._can_print_report(
|
res = self.new_record()._can_print_report({"action": "server"}, True, False)
|
||||||
{'action': 'server'}, True, False
|
|
||||||
)
|
|
||||||
self.assertFalse(res)
|
self.assertFalse(res)
|
||||||
|
|
||||||
def test_render_qweb_pdf_not_printable(self):
|
def test_render_qweb_pdf_not_printable(self):
|
||||||
""" It should print the report, only if it is printable
|
""" It should print the report, only if it is printable
|
||||||
"""
|
"""
|
||||||
with mock.patch('odoo.addons.base_report_to_printer.models.'
|
with mock.patch(
|
||||||
'printing_printer.PrintingPrinter.'
|
"odoo.addons.base_report_to_printer.models."
|
||||||
'print_document') as print_document:
|
"printing_printer.PrintingPrinter."
|
||||||
|
"print_document"
|
||||||
|
) as print_document:
|
||||||
self.report.render_qweb_pdf(self.partners.ids)
|
self.report.render_qweb_pdf(self.partners.ids)
|
||||||
print_document.assert_not_called()
|
print_document.assert_not_called()
|
||||||
|
|
||||||
def test_render_qweb_pdf_printable(self):
|
def test_render_qweb_pdf_printable(self):
|
||||||
""" It should print the report, only if it is printable
|
""" It should print the report, only if it is printable
|
||||||
"""
|
"""
|
||||||
with mock.patch('odoo.addons.base_report_to_printer.models.'
|
with mock.patch(
|
||||||
'printing_printer.PrintingPrinter.'
|
"odoo.addons.base_report_to_printer.models."
|
||||||
'print_document') as print_document:
|
"printing_printer.PrintingPrinter."
|
||||||
self.report.property_printing_action_id.action_type = 'server'
|
"print_document"
|
||||||
|
) as print_document:
|
||||||
|
self.report.property_printing_action_id.action_type = "server"
|
||||||
self.report.printing_printer_id = self.new_printer()
|
self.report.printing_printer_id = self.new_printer()
|
||||||
document = self.report.render_qweb_pdf(self.partners.ids)
|
document = self.report.render_qweb_pdf(self.partners.ids)
|
||||||
print_document.assert_called_once_with(
|
print_document.assert_called_once_with(
|
||||||
self.report, document[0],
|
self.report,
|
||||||
action='server', doc_format='qweb-pdf', tray=False)
|
document[0],
|
||||||
|
action="server",
|
||||||
|
doc_format="qweb-pdf",
|
||||||
|
tray=False,
|
||||||
|
)
|
||||||
|
|
||||||
def test_print_document_not_printable(self):
|
def test_print_document_not_printable(self):
|
||||||
""" It should print the report, regardless of the defined behaviour """
|
""" It should print the report, regardless of the defined behaviour """
|
||||||
self.report.printing_printer_id = self.new_printer()
|
self.report.printing_printer_id = self.new_printer()
|
||||||
with mock.patch('odoo.addons.base_report_to_printer.models.'
|
with mock.patch(
|
||||||
'printing_printer.PrintingPrinter.'
|
"odoo.addons.base_report_to_printer.models."
|
||||||
'print_document') as print_document:
|
"printing_printer.PrintingPrinter."
|
||||||
|
"print_document"
|
||||||
|
) as print_document:
|
||||||
self.report.print_document(self.partners.ids)
|
self.report.print_document(self.partners.ids)
|
||||||
print_document.assert_called_once()
|
print_document.assert_called_once()
|
||||||
|
|
||||||
def test_print_document_printable(self):
|
def test_print_document_printable(self):
|
||||||
""" It should print the report, regardless of the defined behaviour """
|
""" It should print the report, regardless of the defined behaviour """
|
||||||
self.report.property_printing_action_id.action_type = 'server'
|
self.report.property_printing_action_id.action_type = "server"
|
||||||
self.report.printing_printer_id = self.new_printer()
|
self.report.printing_printer_id = self.new_printer()
|
||||||
with mock.patch('odoo.addons.base_report_to_printer.models.'
|
with mock.patch(
|
||||||
'printing_printer.PrintingPrinter.'
|
"odoo.addons.base_report_to_printer.models."
|
||||||
'print_document') as print_document:
|
"printing_printer.PrintingPrinter."
|
||||||
|
"print_document"
|
||||||
|
) as print_document:
|
||||||
self.report.print_document(self.partners.ids)
|
self.report.print_document(self.partners.ids)
|
||||||
print_document.assert_called_once()
|
print_document.assert_called_once()
|
||||||
|
|
||||||
|
|||||||
@@ -7,54 +7,49 @@ from odoo.tests import common
|
|||||||
@common.at_install(False)
|
@common.at_install(False)
|
||||||
@common.post_install(True)
|
@common.post_install(True)
|
||||||
class TestResUsers(common.TransactionCase):
|
class TestResUsers(common.TransactionCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestResUsers, self).setUp()
|
super(TestResUsers, self).setUp()
|
||||||
self.user_vals = {'name': 'Test',
|
self.user_vals = {"name": "Test", "login": "login"}
|
||||||
'login': 'login',
|
|
||||||
}
|
|
||||||
|
|
||||||
def new_record(self):
|
def new_record(self):
|
||||||
return self.env['res.users'].create(self.user_vals)
|
return self.env["res.users"].create(self.user_vals)
|
||||||
|
|
||||||
def test_available_action_types_excludes_user_default(self):
|
def test_available_action_types_excludes_user_default(self):
|
||||||
""" It should not contain `user_default` in avail actions """
|
""" It should not contain `user_default` in avail actions """
|
||||||
self.user_vals['printing_action'] = 'user_default'
|
self.user_vals["printing_action"] = "user_default"
|
||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
self.new_record()
|
self.new_record()
|
||||||
|
|
||||||
def test_available_action_types_includes_something_else(self):
|
def test_available_action_types_includes_something_else(self):
|
||||||
""" It should still contain other valid keys """
|
""" It should still contain other valid keys """
|
||||||
self.user_vals['printing_action'] = 'server'
|
self.user_vals["printing_action"] = "server"
|
||||||
self.assertTrue(self.new_record())
|
self.assertTrue(self.new_record())
|
||||||
|
|
||||||
def test_onchange_printer_tray_id_empty(self):
|
def test_onchange_printer_tray_id_empty(self):
|
||||||
user = self.env['res.users'].new(
|
user = self.env["res.users"].new({"printer_tray_id": False})
|
||||||
{'printer_tray_id': False})
|
|
||||||
user.onchange_printing_printer_id()
|
user.onchange_printing_printer_id()
|
||||||
self.assertFalse(user.printer_tray_id)
|
self.assertFalse(user.printer_tray_id)
|
||||||
|
|
||||||
def test_onchange_printer_tray_id_not_empty(self):
|
def test_onchange_printer_tray_id_not_empty(self):
|
||||||
server = self.env['printing.server'].create({})
|
server = self.env["printing.server"].create({})
|
||||||
printer = self.env['printing.printer'].create({
|
printer = self.env["printing.printer"].create(
|
||||||
'name': 'Printer',
|
{
|
||||||
'server_id': server.id,
|
"name": "Printer",
|
||||||
'system_name': 'Sys Name',
|
"server_id": server.id,
|
||||||
'default': True,
|
"system_name": "Sys Name",
|
||||||
'status': 'unknown',
|
"default": True,
|
||||||
'status_message': 'Msg',
|
"status": "unknown",
|
||||||
'model': 'res.users',
|
"status_message": "Msg",
|
||||||
'location': 'Location',
|
"model": "res.users",
|
||||||
'uri': 'URI',
|
"location": "Location",
|
||||||
})
|
"uri": "URI",
|
||||||
tray = self.env['printing.tray'].create({
|
}
|
||||||
'name': 'Tray',
|
)
|
||||||
'system_name': 'TrayName',
|
tray = self.env["printing.tray"].create(
|
||||||
'printer_id': printer.id,
|
{"name": "Tray", "system_name": "TrayName", "printer_id": printer.id}
|
||||||
})
|
)
|
||||||
|
|
||||||
user = self.env['res.users'].new(
|
user = self.env["res.users"].new({"printer_tray_id": tray.id})
|
||||||
{'printer_tray_id': tray.id})
|
|
||||||
self.assertEqual(user.printer_tray_id, tray)
|
self.assertEqual(user.printer_tray_id, tray)
|
||||||
user.onchange_printing_printer_id()
|
user.onchange_printing_printer_id()
|
||||||
self.assertFalse(user.printer_tray_id)
|
self.assertFalse(user.printer_tray_id)
|
||||||
|
|||||||
@@ -6,4 +6,3 @@
|
|||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
</odoo>
|
</odoo>
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
|
|
||||||
from . import printing_printer_update_wizard
|
from . import printing_printer_update_wizard
|
||||||
|
|||||||
@@ -8,22 +8,20 @@ import logging
|
|||||||
|
|
||||||
from odoo import models
|
from odoo import models
|
||||||
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class PrintingPrinterUpdateWizard(models.TransientModel):
|
class PrintingPrinterUpdateWizard(models.TransientModel):
|
||||||
_name = 'printing.printer.update.wizard'
|
_name = "printing.printer.update.wizard"
|
||||||
_description = 'Printing Printer Update Wizard'
|
_description = "Printing Printer Update Wizard"
|
||||||
|
|
||||||
def action_ok(self):
|
def action_ok(self):
|
||||||
self.env['printing.server'].search([]) \
|
self.env["printing.server"].search([]).update_printers(raise_on_error=True)
|
||||||
.update_printers(raise_on_error=True)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'name': 'Printers',
|
"name": "Printers",
|
||||||
'view_mode': 'tree,form',
|
"view_mode": "tree,form",
|
||||||
'res_model': 'printing.printer',
|
"res_model": "printing.printer",
|
||||||
'type': 'ir.actions.act_window',
|
"type": "ir.actions.act_window",
|
||||||
'target': 'current',
|
"target": "current",
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user