odoo-addon-base-report-to-printer 18.0.1.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- odoo/addons/base_report_to_printer/README.rst +205 -0
- odoo/addons/base_report_to_printer/__init__.py +9 -0
- odoo/addons/base_report_to_printer/__manifest__.py +39 -0
- odoo/addons/base_report_to_printer/data/neutralize.sql +2 -0
- odoo/addons/base_report_to_printer/data/printing_data.xml +27 -0
- odoo/addons/base_report_to_printer/i18n/am.po +936 -0
- odoo/addons/base_report_to_printer/i18n/base_report_to_printer.pot +932 -0
- odoo/addons/base_report_to_printer/i18n/bg.po +939 -0
- odoo/addons/base_report_to_printer/i18n/ca.po +936 -0
- odoo/addons/base_report_to_printer/i18n/de.po +994 -0
- odoo/addons/base_report_to_printer/i18n/el_GR.po +937 -0
- odoo/addons/base_report_to_printer/i18n/es.po +1004 -0
- odoo/addons/base_report_to_printer/i18n/es_AR.po +987 -0
- odoo/addons/base_report_to_printer/i18n/es_ES.po +937 -0
- odoo/addons/base_report_to_printer/i18n/fi.po +939 -0
- odoo/addons/base_report_to_printer/i18n/fr.po +999 -0
- odoo/addons/base_report_to_printer/i18n/gl.po +936 -0
- odoo/addons/base_report_to_printer/i18n/hr.po +966 -0
- odoo/addons/base_report_to_printer/i18n/hr_HR.po +941 -0
- odoo/addons/base_report_to_printer/i18n/it.po +985 -0
- odoo/addons/base_report_to_printer/i18n/nl.po +939 -0
- odoo/addons/base_report_to_printer/i18n/nl_NL.po +950 -0
- odoo/addons/base_report_to_printer/i18n/pt.po +936 -0
- odoo/addons/base_report_to_printer/i18n/pt_BR.po +940 -0
- odoo/addons/base_report_to_printer/i18n/pt_PT.po +937 -0
- odoo/addons/base_report_to_printer/i18n/sl.po +943 -0
- odoo/addons/base_report_to_printer/i18n/sv.po +983 -0
- odoo/addons/base_report_to_printer/i18n/tr.po +936 -0
- odoo/addons/base_report_to_printer/i18n/zh_CN.po +958 -0
- odoo/addons/base_report_to_printer/models/__init__.py +8 -0
- odoo/addons/base_report_to_printer/models/ir_actions_report.py +253 -0
- odoo/addons/base_report_to_printer/models/printing_action.py +26 -0
- odoo/addons/base_report_to_printer/models/printing_job.py +131 -0
- odoo/addons/base_report_to_printer/models/printing_printer.py +268 -0
- odoo/addons/base_report_to_printer/models/printing_report_xml_action.py +48 -0
- odoo/addons/base_report_to_printer/models/printing_server.py +275 -0
- odoo/addons/base_report_to_printer/models/printing_tray.py +21 -0
- odoo/addons/base_report_to_printer/models/res_users.py +55 -0
- odoo/addons/base_report_to_printer/readme/CONFIGURE.md +13 -0
- odoo/addons/base_report_to_printer/readme/CONTRIBUTORS.md +18 -0
- odoo/addons/base_report_to_printer/readme/CREDITS.md +1 -0
- odoo/addons/base_report_to_printer/readme/DESCRIPTION.md +27 -0
- odoo/addons/base_report_to_printer/readme/HISTORY.md +7 -0
- odoo/addons/base_report_to_printer/readme/INSTALL.md +10 -0
- odoo/addons/base_report_to_printer/readme/ROADMAP.md +3 -0
- odoo/addons/base_report_to_printer/readme/USAGE.md +15 -0
- odoo/addons/base_report_to_printer/security/ir.model.access.csv +2 -0
- odoo/addons/base_report_to_printer/security/security.xml +151 -0
- odoo/addons/base_report_to_printer/static/description/icon.png +0 -0
- odoo/addons/base_report_to_printer/static/description/index.html +561 -0
- odoo/addons/base_report_to_printer/static/src/js/qweb_action_manager.esm.js +92 -0
- odoo/addons/base_report_to_printer/tests/__init__.py +13 -0
- odoo/addons/base_report_to_printer/tests/test_ir_actions_report.py +350 -0
- odoo/addons/base_report_to_printer/tests/test_printing_job.py +70 -0
- odoo/addons/base_report_to_printer/tests/test_printing_printer.py +198 -0
- odoo/addons/base_report_to_printer/tests/test_printing_printer_tray.py +256 -0
- odoo/addons/base_report_to_printer/tests/test_printing_printer_wizard.py +94 -0
- odoo/addons/base_report_to_printer/tests/test_printing_report_xml_action.py +98 -0
- odoo/addons/base_report_to_printer/tests/test_printing_server.py +219 -0
- odoo/addons/base_report_to_printer/tests/test_printing_tray.py +49 -0
- odoo/addons/base_report_to_printer/tests/test_report.py +226 -0
- odoo/addons/base_report_to_printer/tests/test_res_users.py +53 -0
- odoo/addons/base_report_to_printer/views/ir_actions_report.xml +21 -0
- odoo/addons/base_report_to_printer/views/printing_job.xml +46 -0
- odoo/addons/base_report_to_printer/views/printing_printer.xml +147 -0
- odoo/addons/base_report_to_printer/views/printing_report.xml +39 -0
- odoo/addons/base_report_to_printer/views/printing_server.xml +79 -0
- odoo/addons/base_report_to_printer/views/res_users.xml +33 -0
- odoo/addons/base_report_to_printer/wizards/__init__.py +2 -0
- odoo/addons/base_report_to_printer/wizards/print_attachment_report.py +80 -0
- odoo/addons/base_report_to_printer/wizards/print_attachment_report.xml +56 -0
- odoo/addons/base_report_to_printer/wizards/printing_printer_update_wizard.py +27 -0
- odoo/addons/base_report_to_printer/wizards/printing_printer_update_wizard_view.xml +37 -0
- odoo_addon_base_report_to_printer-18.0.1.1.6.dist-info/METADATA +222 -0
- odoo_addon_base_report_to_printer-18.0.1.1.6.dist-info/RECORD +77 -0
- odoo_addon_base_report_to_printer-18.0.1.1.6.dist-info/WHEEL +5 -0
- odoo_addon_base_report_to_printer-18.0.1.1.6.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
|
|
2
|
+
# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
|
|
3
|
+
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
|
|
4
|
+
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
|
|
5
|
+
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
|
6
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
7
|
+
|
|
8
|
+
from odoo import api, fields, models
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class PrintingReportXmlAction(models.Model):
|
|
12
|
+
_name = "printing.report.xml.action"
|
|
13
|
+
_description = "Printing Report Printing Actions"
|
|
14
|
+
|
|
15
|
+
report_id = fields.Many2one(
|
|
16
|
+
comodel_name="ir.actions.report",
|
|
17
|
+
string="Report",
|
|
18
|
+
required=True,
|
|
19
|
+
ondelete="cascade",
|
|
20
|
+
)
|
|
21
|
+
user_id = fields.Many2one(
|
|
22
|
+
comodel_name="res.users", string="User", required=True, ondelete="cascade"
|
|
23
|
+
)
|
|
24
|
+
action = fields.Selection(
|
|
25
|
+
selection=lambda s: s.env["printing.action"]._available_action_types,
|
|
26
|
+
required=True,
|
|
27
|
+
)
|
|
28
|
+
printer_id = fields.Many2one(comodel_name="printing.printer", string="Printer")
|
|
29
|
+
|
|
30
|
+
printer_tray_id = fields.Many2one(
|
|
31
|
+
comodel_name="printing.tray",
|
|
32
|
+
string="Paper Source",
|
|
33
|
+
domain="[('printer_id', '=', printer_id)]",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
@api.onchange("printer_id")
|
|
37
|
+
def onchange_printer_id(self):
|
|
38
|
+
"""Reset the tray when the printer is changed"""
|
|
39
|
+
self.printer_tray_id = False
|
|
40
|
+
|
|
41
|
+
def behaviour(self):
|
|
42
|
+
if not self:
|
|
43
|
+
return {}
|
|
44
|
+
return {
|
|
45
|
+
"action": self.action,
|
|
46
|
+
"printer": self.printer_id,
|
|
47
|
+
"tray": self.printer_tray_id.system_name,
|
|
48
|
+
}
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# Copyright (C) 2016 SYLEAM (<http://www.syleam.fr>)
|
|
2
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
3
|
+
|
|
4
|
+
import logging
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
from odoo import _, exceptions, fields, models
|
|
8
|
+
|
|
9
|
+
_logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
import cups
|
|
13
|
+
except ImportError:
|
|
14
|
+
_logger.debug("Cannot `import cups`.")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class PrintingServer(models.Model):
|
|
18
|
+
_name = "printing.server"
|
|
19
|
+
_description = "Printing server"
|
|
20
|
+
|
|
21
|
+
name = fields.Char(default="Localhost", required=True, help="Name of the server.")
|
|
22
|
+
address = fields.Char(
|
|
23
|
+
default="localhost", required=True, help="IP address or hostname of the server"
|
|
24
|
+
)
|
|
25
|
+
port = fields.Integer(default=631, required=True, help="Port of the server.")
|
|
26
|
+
user = fields.Char(help="User name to connect to the server. Empty by default.")
|
|
27
|
+
password = fields.Char(help="Password to connect to the server. Empty by default.")
|
|
28
|
+
encryption_policy = fields.Selection(
|
|
29
|
+
[
|
|
30
|
+
("0", "HTTP_ENCRYPT_IF_REQUESTED"),
|
|
31
|
+
("1", "HTTP_ENCRYPT_NEVER"),
|
|
32
|
+
("2", "HTTP_ENCRYPT_REQUIRED"),
|
|
33
|
+
("3", "HTTP_ENCRYPT_ALWAYS"),
|
|
34
|
+
],
|
|
35
|
+
help="Encryption Policy to connect to the server. Empty by default.",
|
|
36
|
+
)
|
|
37
|
+
active = fields.Boolean(default=True, help="If checked, this server is useable.")
|
|
38
|
+
printer_ids = fields.One2many(
|
|
39
|
+
comodel_name="printing.printer",
|
|
40
|
+
inverse_name="server_id",
|
|
41
|
+
string="Printers List",
|
|
42
|
+
help="List of printers available on this server.",
|
|
43
|
+
)
|
|
44
|
+
multi_thread = fields.Boolean()
|
|
45
|
+
|
|
46
|
+
def _open_connection(self, raise_on_error=False):
|
|
47
|
+
self.ensure_one()
|
|
48
|
+
connection = False
|
|
49
|
+
|
|
50
|
+
# Password callback
|
|
51
|
+
password = self.password
|
|
52
|
+
|
|
53
|
+
def pw_callback(prompt):
|
|
54
|
+
return password
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
# Sometimes connecting to printer servers outside of the local network
|
|
58
|
+
# can result in a weird error "cups.IPPError: (1030, 'The printer
|
|
59
|
+
# or class does not exist.')".
|
|
60
|
+
# An explicit call to `setServer` and `setPort` fixed the issue.
|
|
61
|
+
# (see https://github.com/OpenPrinting/pycups/issues/30)
|
|
62
|
+
cups.setServer(self.address)
|
|
63
|
+
cups.setPort(self.port)
|
|
64
|
+
if self.user:
|
|
65
|
+
cups.setUser(self.user)
|
|
66
|
+
if self.encryption_policy:
|
|
67
|
+
cups.setEncryption(int(self.encryption_policy))
|
|
68
|
+
if self.password:
|
|
69
|
+
cups.setPasswordCB(pw_callback)
|
|
70
|
+
|
|
71
|
+
connection = cups.Connection(host=self.address, port=self.port)
|
|
72
|
+
except Exception:
|
|
73
|
+
message = _(
|
|
74
|
+
"Failed to connect to the CUPS server on %(address)s:%(port)s. "
|
|
75
|
+
"Check that the CUPS server is running and that "
|
|
76
|
+
"you can reach it from the Odoo server."
|
|
77
|
+
) % {
|
|
78
|
+
"address": self.address,
|
|
79
|
+
"port": self.port,
|
|
80
|
+
}
|
|
81
|
+
_logger.warning(message)
|
|
82
|
+
if raise_on_error:
|
|
83
|
+
raise exceptions.UserError(message) from Exception
|
|
84
|
+
|
|
85
|
+
return connection
|
|
86
|
+
|
|
87
|
+
def action_update_printers(self):
|
|
88
|
+
return self.update_printers(raise_on_error=True)
|
|
89
|
+
|
|
90
|
+
# ruff: noqa: B023
|
|
91
|
+
def update_printers(self, domain=None, raise_on_error=False):
|
|
92
|
+
if domain is None:
|
|
93
|
+
domain = []
|
|
94
|
+
|
|
95
|
+
servers = self
|
|
96
|
+
if not self:
|
|
97
|
+
servers = self.search(domain)
|
|
98
|
+
|
|
99
|
+
res = True
|
|
100
|
+
for server in servers.with_context(active_test=False):
|
|
101
|
+
connection = server._open_connection(raise_on_error=raise_on_error)
|
|
102
|
+
if not connection:
|
|
103
|
+
server.printer_ids.write({"status": "server-error"})
|
|
104
|
+
res = False
|
|
105
|
+
continue
|
|
106
|
+
|
|
107
|
+
# Update Printers
|
|
108
|
+
printers = connection.getPrinters()
|
|
109
|
+
existing_printers = {
|
|
110
|
+
printer.system_name: printer for printer in server.printer_ids
|
|
111
|
+
}
|
|
112
|
+
updated_printers = []
|
|
113
|
+
for name, printer_info in printers.items():
|
|
114
|
+
printer = self.env["printing.printer"]
|
|
115
|
+
if name in existing_printers:
|
|
116
|
+
printer = existing_printers[name]
|
|
117
|
+
|
|
118
|
+
printer_values = printer._prepare_update_from_cups(
|
|
119
|
+
connection, printer_info
|
|
120
|
+
)
|
|
121
|
+
if server != printer.server_id:
|
|
122
|
+
printer_values["server_id"] = server.id
|
|
123
|
+
|
|
124
|
+
updated_printers.append(name)
|
|
125
|
+
# We want to keep any existing customized name over existing printer
|
|
126
|
+
# We want also to rely in the system name as a fallback to avoid
|
|
127
|
+
# empty names.
|
|
128
|
+
if not printer_values.get("name") and not printer.name:
|
|
129
|
+
printer_values["name"] = name
|
|
130
|
+
if not printer:
|
|
131
|
+
printer_values["system_name"] = name
|
|
132
|
+
printer.create(printer_values)
|
|
133
|
+
elif printer_values:
|
|
134
|
+
printer.write(printer_values)
|
|
135
|
+
|
|
136
|
+
# Set printers not found as unavailable
|
|
137
|
+
server.printer_ids.filtered(
|
|
138
|
+
lambda record: record.system_name not in updated_printers
|
|
139
|
+
).write({"status": "unavailable"})
|
|
140
|
+
|
|
141
|
+
return res
|
|
142
|
+
|
|
143
|
+
def action_update_jobs(self):
|
|
144
|
+
if not self:
|
|
145
|
+
self = self.search([])
|
|
146
|
+
return self.update_jobs()
|
|
147
|
+
|
|
148
|
+
def update_jobs(self, which="all", first_job_id=-1):
|
|
149
|
+
job_obj = self.env["printing.job"]
|
|
150
|
+
printer_obj = self.env["printing.printer"]
|
|
151
|
+
|
|
152
|
+
mapping = {
|
|
153
|
+
3: "pending",
|
|
154
|
+
4: "pending held",
|
|
155
|
+
5: "processing",
|
|
156
|
+
6: "processing stopped",
|
|
157
|
+
7: "canceled",
|
|
158
|
+
8: "aborted",
|
|
159
|
+
9: "completed",
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
# Update printers list, to ensure that jobs printers will be in Odoo
|
|
163
|
+
self.update_printers()
|
|
164
|
+
|
|
165
|
+
for server in self:
|
|
166
|
+
connection = server._open_connection()
|
|
167
|
+
if not connection:
|
|
168
|
+
continue
|
|
169
|
+
|
|
170
|
+
# Retrieve asked job data
|
|
171
|
+
jobs_data = connection.getJobs(
|
|
172
|
+
which_jobs=which,
|
|
173
|
+
first_job_id=first_job_id,
|
|
174
|
+
requested_attributes=[
|
|
175
|
+
"job-name",
|
|
176
|
+
"job-id",
|
|
177
|
+
"printer-uri",
|
|
178
|
+
"job-media-progress",
|
|
179
|
+
"time-at-creation",
|
|
180
|
+
"job-state",
|
|
181
|
+
"job-state-reasons",
|
|
182
|
+
"time-at-processing",
|
|
183
|
+
"time-at-completed",
|
|
184
|
+
],
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
# Retrieve known uncompleted jobs data to update them
|
|
188
|
+
if which == "not-completed":
|
|
189
|
+
oldest_uncompleted_job = job_obj.search(
|
|
190
|
+
[("job_state", "not in", ("canceled", "aborted", "completed"))],
|
|
191
|
+
limit=1,
|
|
192
|
+
order="job_id_cups",
|
|
193
|
+
)
|
|
194
|
+
if oldest_uncompleted_job:
|
|
195
|
+
jobs_data.update(
|
|
196
|
+
connection.getJobs(
|
|
197
|
+
which_jobs="completed",
|
|
198
|
+
first_job_id=oldest_uncompleted_job.job_id_cups,
|
|
199
|
+
requested_attributes=[
|
|
200
|
+
"job-name",
|
|
201
|
+
"job-id",
|
|
202
|
+
"printer-uri",
|
|
203
|
+
"job-media-progress",
|
|
204
|
+
"time-at-creation",
|
|
205
|
+
"job-state",
|
|
206
|
+
"job-state-reasons",
|
|
207
|
+
"time-at-processing",
|
|
208
|
+
"time-at-completed",
|
|
209
|
+
],
|
|
210
|
+
)
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
all_cups_job_ids = set()
|
|
214
|
+
for cups_job_id, job_data in jobs_data.items():
|
|
215
|
+
all_cups_job_ids.add(cups_job_id)
|
|
216
|
+
jobs = job_obj.with_context(active_test=False).search(
|
|
217
|
+
[("job_id_cups", "=", cups_job_id), ("server_id", "=", server.id)]
|
|
218
|
+
)
|
|
219
|
+
cups_job_values = {
|
|
220
|
+
"name": job_data.get("job-name", ""),
|
|
221
|
+
"active": True,
|
|
222
|
+
"job_media_progress": job_data.get("job-media-progress", 0),
|
|
223
|
+
"job_state": mapping.get(job_data.get("job-state"), "unknown"),
|
|
224
|
+
"job_state_reason": job_data.get("job-state-reasons", ""),
|
|
225
|
+
"time_at_creation": datetime.fromtimestamp(
|
|
226
|
+
job_data.get("time-at-creation", 0)
|
|
227
|
+
),
|
|
228
|
+
}
|
|
229
|
+
if job_data.get("time-at-processing"):
|
|
230
|
+
cups_job_values["time_at_processing"] = datetime.fromtimestamp(
|
|
231
|
+
job_data["time-at-processing"]
|
|
232
|
+
)
|
|
233
|
+
if job_data.get("time-at-completed"):
|
|
234
|
+
cups_job_values["time_at_completed"] = datetime.fromtimestamp(
|
|
235
|
+
job_data["time-at-completed"]
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
job_values = {
|
|
239
|
+
fieldname: value
|
|
240
|
+
for fieldname, value in cups_job_values.items()
|
|
241
|
+
if not jobs or value != jobs[fieldname]
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
# Search for the printer in Odoo
|
|
245
|
+
printer_uri = job_data["printer-uri"]
|
|
246
|
+
printer_system_name = printer_uri[printer_uri.rfind("/") + 1 :]
|
|
247
|
+
printer = printer_obj.search(
|
|
248
|
+
[
|
|
249
|
+
("server_id", "=", server.id),
|
|
250
|
+
("system_name", "=", printer_system_name),
|
|
251
|
+
],
|
|
252
|
+
limit=1,
|
|
253
|
+
)
|
|
254
|
+
# CUPS retains jobs for disconnected printers and also may
|
|
255
|
+
# leak jobs data for unshared printers, therefore we just
|
|
256
|
+
# discard here if not printer found
|
|
257
|
+
if not printer:
|
|
258
|
+
continue
|
|
259
|
+
if jobs.printer_id != printer:
|
|
260
|
+
job_values["printer_id"] = printer.id
|
|
261
|
+
|
|
262
|
+
if not jobs:
|
|
263
|
+
job_values["job_id_cups"] = cups_job_id
|
|
264
|
+
job_obj.create(job_values)
|
|
265
|
+
elif job_values:
|
|
266
|
+
jobs.write(job_values)
|
|
267
|
+
|
|
268
|
+
# Deactive purged jobs
|
|
269
|
+
if which == "all" and first_job_id == -1:
|
|
270
|
+
purged_jobs = job_obj.search(
|
|
271
|
+
[("job_id_cups", "not in", list(all_cups_job_ids))]
|
|
272
|
+
)
|
|
273
|
+
purged_jobs.write({"active": False})
|
|
274
|
+
|
|
275
|
+
return True
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
|
2
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
3
|
+
|
|
4
|
+
from odoo import fields, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class PrinterTray(models.Model):
|
|
8
|
+
_name = "printing.tray"
|
|
9
|
+
_description = "Printer Tray"
|
|
10
|
+
|
|
11
|
+
_order = "name asc"
|
|
12
|
+
|
|
13
|
+
name = fields.Char(required=True)
|
|
14
|
+
system_name = fields.Char(required=True, readonly=True)
|
|
15
|
+
printer_id = fields.Many2one(
|
|
16
|
+
comodel_name="printing.printer",
|
|
17
|
+
string="Printer",
|
|
18
|
+
required=True,
|
|
19
|
+
readonly=True,
|
|
20
|
+
ondelete="cascade",
|
|
21
|
+
)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Copyright (c) 2007 Ferran Pegueroles <ferran@pegueroles.com>
|
|
2
|
+
# Copyright (c) 2009 Albert Cervera i Areny <albert@nan-tic.com>
|
|
3
|
+
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
|
|
4
|
+
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
|
|
5
|
+
# Copyright (C) 2013-2014 Camptocamp (<http://www.camptocamp.com>)
|
|
6
|
+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
7
|
+
|
|
8
|
+
from odoo import api, fields, models
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ResUsers(models.Model):
|
|
12
|
+
_inherit = "res.users"
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def _user_available_action_types(self):
|
|
16
|
+
return [
|
|
17
|
+
(code, string)
|
|
18
|
+
for code, string in self.env["printing.action"]._available_action_types
|
|
19
|
+
if code != "user_default"
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
printing_action = fields.Selection(
|
|
23
|
+
selection=lambda self: self._user_available_action_types
|
|
24
|
+
)
|
|
25
|
+
printing_printer_id = fields.Many2one(
|
|
26
|
+
comodel_name="printing.printer", string="Default Printer"
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
@api.constrains("printing_action")
|
|
30
|
+
def _check_printing_action(self):
|
|
31
|
+
for rec in self:
|
|
32
|
+
if rec.printing_action == "user_default":
|
|
33
|
+
raise ValueError("user_default should not be available")
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def SELF_READABLE_FIELDS(self):
|
|
37
|
+
return super().SELF_READABLE_FIELDS + ["printing_action", "printing_printer_id"]
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def SELF_WRITEABLE_FIELDS(self):
|
|
41
|
+
return super().SELF_WRITEABLE_FIELDS + [
|
|
42
|
+
"printing_action",
|
|
43
|
+
"printing_printer_id",
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
printer_tray_id = fields.Many2one(
|
|
47
|
+
comodel_name="printing.tray",
|
|
48
|
+
string="Default Printer Paper Source",
|
|
49
|
+
domain="[('printer_id', '=', printing_printer_id)]",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
@api.onchange("printing_printer_id")
|
|
53
|
+
def onchange_printing_printer_id(self):
|
|
54
|
+
"""Reset the tray when the printer is changed"""
|
|
55
|
+
self.printer_tray_id = False
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
To configure this module, you need to:
|
|
2
|
+
|
|
3
|
+
1. Enable the "Printing / Print User" option under access rights to
|
|
4
|
+
give users the ability to view the print menu.
|
|
5
|
+
|
|
6
|
+
The jobs will be sent to the printer with a name matching the
|
|
7
|
+
print_report_name of the report (truncated at 80 characters). By default
|
|
8
|
+
this will not be displayed by CUPS web interface or in Odoo. To see this
|
|
9
|
+
information, you need to change the configuration of your CUPS server
|
|
10
|
+
and set the JobPrivateValue directive to "none" (or some other list of
|
|
11
|
+
values which does not include "job-name") , and reload the server. See
|
|
12
|
+
cupsd.conf(5) \<https://www.cups.org/doc/man-cupsd.conf.html\> for
|
|
13
|
+
details.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
- Ferran Pegueroles \<<ferran@pegueroles.com>\>
|
|
2
|
+
- Albert Cervera i Areny \<<albert@nan-tic.com>\>
|
|
3
|
+
- Davide Corio \<<davide.corio@agilebg.com>\>
|
|
4
|
+
- Lorenzo Battistini \<<lorenzo.battistini@agilebg.com>\>
|
|
5
|
+
- Yannick Vaucher \<<yannick.vaucher@camptocamp.com>\>
|
|
6
|
+
- Lionel Sausin \<<ls@numerigraphe.com>\>
|
|
7
|
+
- Guewen Baconnier \<<guewen.baconnier@camptocamp.com>\>
|
|
8
|
+
- Dave Lasley \<<dave@laslabs.com>\>
|
|
9
|
+
- Sylvain Garancher \<<sylvain.garancher@syleam.fr>\>
|
|
10
|
+
- Jairo Llopis \<<jairo.llopis@tecnativa.com>\>
|
|
11
|
+
- Graeme Gellatly \<<graeme@o4sb.com>\>
|
|
12
|
+
- Rod Schouteden \<<rod@schout-it.be>\>
|
|
13
|
+
- Alexandre Fayolle \<<alexandre.fayolle@camptocamp.com>\>
|
|
14
|
+
- Matias Peralta \<<mnp@adhoc.com.ar>\>
|
|
15
|
+
- Hughes Damry \<<hughes.damry@acsone.eu>\>
|
|
16
|
+
- Akim Juillerat \<<akim.juillerat@camptocamp.com>\>
|
|
17
|
+
- Jacques-Etienne Baudoux (BCIM) \<<je@bcim.be>\>
|
|
18
|
+
- Tris Doan \<<tridm@trobz.com>\>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
The migration of this module from 17.0 to 18.0 was financially supported by Camptocamp.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
This module allows users to send reports to a printer attached to the
|
|
2
|
+
server.
|
|
3
|
+
|
|
4
|
+
It adds an optional behaviour on reports to send it directly to a
|
|
5
|
+
printer.
|
|
6
|
+
|
|
7
|
+
- Send to Client is the default behaviour providing you a downloadable
|
|
8
|
+
PDF
|
|
9
|
+
- Send to Printer prints the report on selected printer
|
|
10
|
+
|
|
11
|
+
It detects trays on printers installation plus permits to select the
|
|
12
|
+
paper source on which you want to print directly.
|
|
13
|
+
|
|
14
|
+
Report behaviour is defined by settings.
|
|
15
|
+
|
|
16
|
+
You will find this option on default user config, on default report
|
|
17
|
+
config and on specific config per user per report.
|
|
18
|
+
|
|
19
|
+
This allows you to dedicate a specific paper source for example for
|
|
20
|
+
preprinted paper such as payment slip.
|
|
21
|
+
|
|
22
|
+
Settings can be configured:
|
|
23
|
+
|
|
24
|
+
- globally
|
|
25
|
+
- per user
|
|
26
|
+
- per report
|
|
27
|
+
- per user and report
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Guidelines for use:
|
|
2
|
+
|
|
3
|
+
> - To update the CUPS printers in *Settings \> Printing \> Update
|
|
4
|
+
> Printers from CUPS*
|
|
5
|
+
> - To print a report on a specific printer or tray, you can change
|
|
6
|
+
> these in *Settings \> Printing \> Reports* to define default
|
|
7
|
+
> behaviour.
|
|
8
|
+
> - To print a report on a specific printer and/or tray for a user, you
|
|
9
|
+
> can change these in *Settings \> Printing \> Reports* in *Specific
|
|
10
|
+
> actions per user*
|
|
11
|
+
> - Users may also select a default action, printer or tray in their
|
|
12
|
+
> preferences.
|
|
13
|
+
|
|
14
|
+
When no tray is configured for a report and a user, the default tray
|
|
15
|
+
setup on the CUPS server is used.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
<?xml version="1.0" ?>
|
|
2
|
+
<odoo>
|
|
3
|
+
<record id="printing_group_user" model="res.groups">
|
|
4
|
+
<field name="name">Printing / Print User</field>
|
|
5
|
+
</record>
|
|
6
|
+
<record id="printing_group_manager" model="res.groups">
|
|
7
|
+
<field name="name">Printing / Print Manager</field>
|
|
8
|
+
<field name="implied_ids" eval="[(4, ref('printing_group_user'))]" />
|
|
9
|
+
</record>
|
|
10
|
+
<record id="base.group_user" model="res.groups">
|
|
11
|
+
<field name="implied_ids" eval="[(4, ref('printing_group_user'))]" />
|
|
12
|
+
</record>
|
|
13
|
+
<record id="base.group_erp_manager" model="res.groups">
|
|
14
|
+
<field name="implied_ids" eval="[(4, ref('printing_group_manager'))]" />
|
|
15
|
+
</record>
|
|
16
|
+
<record id="printing_server_group_manager" model="ir.model.access">
|
|
17
|
+
<field name="name">Printing Server Manager</field>
|
|
18
|
+
<field name="model_id" ref="model_printing_server" />
|
|
19
|
+
<field name="group_id" ref="printing_group_manager" />
|
|
20
|
+
<field eval="1" name="perm_read" />
|
|
21
|
+
<field eval="1" name="perm_unlink" />
|
|
22
|
+
<field eval="1" name="perm_write" />
|
|
23
|
+
<field eval="1" name="perm_create" />
|
|
24
|
+
</record>
|
|
25
|
+
<record id="printing_printer_group_manager" model="ir.model.access">
|
|
26
|
+
<field name="name">Printing Printer Manager</field>
|
|
27
|
+
<field name="model_id" ref="model_printing_printer" />
|
|
28
|
+
<field name="group_id" ref="printing_group_manager" />
|
|
29
|
+
<field eval="1" name="perm_read" />
|
|
30
|
+
<field eval="1" name="perm_unlink" />
|
|
31
|
+
<field eval="1" name="perm_write" />
|
|
32
|
+
<field eval="1" name="perm_create" />
|
|
33
|
+
</record>
|
|
34
|
+
<record id="printing_action_group_manager" model="ir.model.access">
|
|
35
|
+
<field name="name">Printing Action Manager</field>
|
|
36
|
+
<field name="model_id" ref="model_printing_action" />
|
|
37
|
+
<field name="group_id" ref="printing_group_manager" />
|
|
38
|
+
<field eval="1" name="perm_read" />
|
|
39
|
+
<field eval="1" name="perm_unlink" />
|
|
40
|
+
<field eval="1" name="perm_write" />
|
|
41
|
+
<field eval="1" name="perm_create" />
|
|
42
|
+
</record>
|
|
43
|
+
<record id="printing_report_xml_action_group_manager" model="ir.model.access">
|
|
44
|
+
<field name="name">Printing Report Xml Action Manager</field>
|
|
45
|
+
<field name="model_id" ref="model_printing_report_xml_action" />
|
|
46
|
+
<field name="group_id" ref="printing_group_manager" />
|
|
47
|
+
<field eval="1" name="perm_read" />
|
|
48
|
+
<field eval="1" name="perm_unlink" />
|
|
49
|
+
<field eval="1" name="perm_write" />
|
|
50
|
+
<field eval="1" name="perm_create" />
|
|
51
|
+
</record>
|
|
52
|
+
<record id="printing_server_group_user" model="ir.model.access">
|
|
53
|
+
<field name="name">Printing Server User</field>
|
|
54
|
+
<field name="model_id" ref="model_printing_server" />
|
|
55
|
+
<field name="group_id" ref="printing_group_user" />
|
|
56
|
+
<field eval="1" name="perm_read" />
|
|
57
|
+
<field eval="0" name="perm_unlink" />
|
|
58
|
+
<field eval="0" name="perm_write" />
|
|
59
|
+
<field eval="0" name="perm_create" />
|
|
60
|
+
</record>
|
|
61
|
+
<record id="printing_printer_group_user" model="ir.model.access">
|
|
62
|
+
<field name="name">Printing Printer User</field>
|
|
63
|
+
<field name="model_id" ref="model_printing_printer" />
|
|
64
|
+
<field name="group_id" ref="printing_group_user" />
|
|
65
|
+
<field eval="1" name="perm_read" />
|
|
66
|
+
<field eval="0" name="perm_unlink" />
|
|
67
|
+
<field eval="0" name="perm_write" />
|
|
68
|
+
<field eval="0" name="perm_create" />
|
|
69
|
+
</record>
|
|
70
|
+
<record id="printing_job_group_user" model="ir.model.access">
|
|
71
|
+
<field name="name">Printing Job User</field>
|
|
72
|
+
<field name="model_id" ref="model_printing_job" />
|
|
73
|
+
<field name="group_id" ref="printing_group_user" />
|
|
74
|
+
<field eval="1" name="perm_read" />
|
|
75
|
+
<field eval="0" name="perm_unlink" />
|
|
76
|
+
<field eval="0" name="perm_write" />
|
|
77
|
+
<field eval="0" name="perm_create" />
|
|
78
|
+
</record>
|
|
79
|
+
<record id="printing_job_group_manager" model="ir.model.access">
|
|
80
|
+
<field name="name">Printing Job User</field>
|
|
81
|
+
<field name="model_id" ref="model_printing_job" />
|
|
82
|
+
<field name="group_id" ref="printing_group_manager" />
|
|
83
|
+
<field eval="1" name="perm_read" />
|
|
84
|
+
<field eval="1" name="perm_unlink" />
|
|
85
|
+
<field eval="1" name="perm_write" />
|
|
86
|
+
<field eval="1" name="perm_create" />
|
|
87
|
+
</record>
|
|
88
|
+
<record id="printing_action_group_user" model="ir.model.access">
|
|
89
|
+
<field name="name">Printing Action User</field>
|
|
90
|
+
<field name="model_id" ref="model_printing_action" />
|
|
91
|
+
<field name="group_id" ref="printing_group_user" />
|
|
92
|
+
<field eval="1" name="perm_read" />
|
|
93
|
+
<field eval="0" name="perm_unlink" />
|
|
94
|
+
<field eval="0" name="perm_write" />
|
|
95
|
+
<field eval="0" name="perm_create" />
|
|
96
|
+
</record>
|
|
97
|
+
<record id="printing_report_xml_action_group_user" model="ir.model.access">
|
|
98
|
+
<field name="name">Printing Report Xml Action User</field>
|
|
99
|
+
<field name="model_id" ref="model_printing_report_xml_action" />
|
|
100
|
+
<field name="group_id" ref="printing_group_user" />
|
|
101
|
+
<field eval="1" name="perm_read" />
|
|
102
|
+
<field eval="0" name="perm_unlink" />
|
|
103
|
+
<field eval="0" name="perm_write" />
|
|
104
|
+
<field eval="0" name="perm_create" />
|
|
105
|
+
</record>
|
|
106
|
+
<record id="access_printing_tray_all" model="ir.model.access">
|
|
107
|
+
<field name="name">Printing Tray User</field>
|
|
108
|
+
<field name="model_id" ref="model_printing_tray" />
|
|
109
|
+
<field name="group_id" ref="printing_group_user" />
|
|
110
|
+
<field eval="1" name="perm_read" />
|
|
111
|
+
<field eval="0" name="perm_unlink" />
|
|
112
|
+
<field eval="0" name="perm_write" />
|
|
113
|
+
<field eval="0" name="perm_create" />
|
|
114
|
+
</record>
|
|
115
|
+
<record id="access_printing_tray_operator" model="ir.model.access">
|
|
116
|
+
<field name="name">Printing Tray User</field>
|
|
117
|
+
<field name="model_id" ref="model_printing_tray" />
|
|
118
|
+
<field name="group_id" ref="printing_group_manager" />
|
|
119
|
+
<field eval="1" name="perm_read" />
|
|
120
|
+
<field eval="1" name="perm_unlink" />
|
|
121
|
+
<field eval="1" name="perm_write" />
|
|
122
|
+
<field eval="1" name="perm_create" />
|
|
123
|
+
</record>
|
|
124
|
+
<record id="access_printing_printer_update_wizard" model="ir.model.access">
|
|
125
|
+
<field name="name">Update printer wizard</field>
|
|
126
|
+
<field name="model_id" ref="model_printing_printer_update_wizard" />
|
|
127
|
+
<field name="group_id" ref="printing_group_manager" />
|
|
128
|
+
<field eval="1" name="perm_read" />
|
|
129
|
+
<field eval="1" name="perm_unlink" />
|
|
130
|
+
<field eval="1" name="perm_write" />
|
|
131
|
+
<field eval="1" name="perm_create" />
|
|
132
|
+
</record>
|
|
133
|
+
<record id="access_wizard_print_attachment_user" model="ir.model.access">
|
|
134
|
+
<field name="name">Print Attachment User</field>
|
|
135
|
+
<field name="model_id" ref="model_wizard_print_attachment" />
|
|
136
|
+
<field name="group_id" ref="printing_group_user" />
|
|
137
|
+
<field eval="1" name="perm_read" />
|
|
138
|
+
<field eval="1" name="perm_unlink" />
|
|
139
|
+
<field eval="1" name="perm_write" />
|
|
140
|
+
<field eval="1" name="perm_create" />
|
|
141
|
+
</record>
|
|
142
|
+
<record id="access_wizard_print_attachment_line_user" model="ir.model.access">
|
|
143
|
+
<field name="name">Print Attachment Line User</field>
|
|
144
|
+
<field name="model_id" ref="model_wizard_print_attachment_line" />
|
|
145
|
+
<field name="group_id" ref="printing_group_user" />
|
|
146
|
+
<field eval="1" name="perm_read" />
|
|
147
|
+
<field eval="1" name="perm_unlink" />
|
|
148
|
+
<field eval="1" name="perm_write" />
|
|
149
|
+
<field eval="1" name="perm_create" />
|
|
150
|
+
</record>
|
|
151
|
+
</odoo>
|
|
Binary file
|