Skip to content

Commit 8169f94

Browse files
committed
[16.0][IMP] sign_oca: enable signing from portal
1 parent 175bb9e commit 8169f94

File tree

8 files changed

+334
-38
lines changed

8 files changed

+334
-38
lines changed

sign_oca/README.rst

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
.. image:: https://odoo-community.org/readme-banner-image
2-
:target: https://odoo-community.org/get-involved?utm_source=readme
3-
:alt: Odoo Community Association
4-
51
========
62
Sign Oca
73
========
@@ -17,7 +13,7 @@ Sign Oca
1713
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
1814
:target: https://odoo-community.org/page/development-status
1915
:alt: Beta
20-
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
2117
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
2218
:alt: License: AGPL-3
2319
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsign-lightgray.png?logo=github
@@ -115,6 +111,12 @@ Sign from template
115111
- Some extra modules (e.g. maintenance_sign_oca) will automatically set
116112
the signers for each request.
117113

114+
Sign from portal
115+
----------------
116+
117+
- customers who are using portal can sign their documents from portal
118+
directly in addition to being able to sign them from emails.
119+
118120
Known issues / Roadmap
119121
======================
120122

sign_oca/__manifest__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"data": [
1414
"security/security.xml",
1515
"views/menu.xml",
16+
"views/sign_portal_oca_templates.xml",
17+
"views/portal_templates.xml",
1618
"data/data.xml",
1719
"wizards/res_config_settings_views.xml",
1820
"data/ir_sequence_data.xml",
@@ -66,6 +68,9 @@
6668
"sign_oca/static/src/scss/sign.scss",
6769
"web/static/src/libs/fontawesome/css/font-awesome.css",
6870
],
71+
"web.assets_tests": [
72+
"sign_oca/static/src/tests/sign_tour.esm.js",
73+
],
6974
},
7075
"maintainers": ["etobella"],
7176
}

sign_oca/controllers/main.py

Lines changed: 124 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1-
from odoo import http
1+
from collections import OrderedDict
2+
from urllib import parse
3+
4+
from odoo import _, http
25
from odoo.exceptions import AccessError, MissingError
36
from odoo.http import request
7+
from odoo.osv import expression
48

59
from odoo.addons.base.models.assetsbundle import AssetsBundle
6-
from odoo.addons.portal.controllers.portal import CustomerPortal
10+
from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager
711

812

913
class SignController(http.Controller):
@@ -104,3 +108,121 @@ def get_sign_oca_sign_access(
104108
return signer_sudo.action_sign(
105109
items, access_token=access_token, latitude=latitude, longitude=longitude
106110
)
111+
112+
def get_sign_requests_domain(self, request):
113+
domain = [
114+
("request_id.state", "in", ("0_sent", "2_signed")),
115+
("partner_id", "child_of", [request.env.user.partner_id.id]),
116+
]
117+
return domain
118+
119+
def _get_my_sign_requests_searchbar_filters(self):
120+
searchbar_filters = {
121+
"all": {"label": _("All"), "domain": []},
122+
"sent": {
123+
"label": _("sent"),
124+
"domain": [("request_id.state", "=", "0_sent")],
125+
},
126+
"signed": {
127+
"label": _("Signed"),
128+
"domain": [("request_id.state", "=", "2_signed")],
129+
},
130+
}
131+
return searchbar_filters
132+
133+
def _prepare_sign_portal_rendering_values(self, page=1, sign_page=False, **kwargs):
134+
# Sorting feature
135+
searchbar_sortings = {
136+
"state": {"label": _("Sent to Signed"), "order": "request_id"},
137+
"reverse_state": {"label": _("Signed to Sent"), "order": "request_id desc"},
138+
"date": {"label": _("Newest"), "order": "create_date desc"},
139+
"reverse_date": {"label": _("Oldest"), "order": "create_date"},
140+
}
141+
sortby = kwargs.get("sortby", "state")
142+
order = searchbar_sortings[sortby]["order"]
143+
# Filtering feature
144+
searchbar_filters = self._get_my_sign_requests_searchbar_filters()
145+
filterby = kwargs.get("filterby") or "all"
146+
domain = searchbar_filters.get(filterby, searchbar_filters["all"])["domain"]
147+
domain = expression.AND([domain, self.get_sign_requests_domain(request)])
148+
SignRequests = request.env["sign.oca.request.signer"].sudo()
149+
pager_values = portal_pager(
150+
url="/my/sign_requests",
151+
total=SignRequests.search_count(domain),
152+
page=page,
153+
step=self._items_per_page,
154+
url_args={},
155+
)
156+
sign_requests = SignRequests.search(
157+
domain,
158+
order=order,
159+
limit=self._items_per_page,
160+
offset=pager_values["offset"],
161+
)
162+
values = self._prepare_portal_layout_values()
163+
values.update(
164+
{
165+
"sign_requests": sign_requests.sudo() if sign_page else SignRequests,
166+
"page_name": "My Sign Requests",
167+
"pager": pager_values,
168+
"default_url": "/my/sign_requests",
169+
"searchbar_sortings": searchbar_sortings,
170+
"searchbar_filters": OrderedDict(sorted(searchbar_filters.items())),
171+
"sortby": sortby,
172+
"filterby": filterby,
173+
}
174+
)
175+
return values
176+
177+
def _prepare_home_portal_values(self, counters):
178+
values = super()._prepare_home_portal_values(counters)
179+
if "sign_oca_count" in counters:
180+
domain = self.get_sign_requests_domain(request)
181+
SignRequests = request.env["sign.oca.request.signer"].sudo()
182+
values["sign_oca_count"] = SignRequests.search_count(domain)
183+
return values
184+
185+
@http.route(
186+
["/my/sign_requests", "/my/sign_requests/page/<int:page>"],
187+
type="http",
188+
auth="public",
189+
website=True,
190+
)
191+
def sign_requests(self, **kwargs):
192+
values = self._prepare_sign_portal_rendering_values(sign_page=True, **kwargs)
193+
return request.render(
194+
"sign_oca.sign_requests",
195+
values,
196+
)
197+
198+
@http.route(
199+
["/my/sign/<int:request_id>/download"], type="http", auth="user", website=True
200+
)
201+
def portal_download_signed(self, request_id, **kw):
202+
sign_request = request.env["sign.oca.request"].sudo().browse(request_id)
203+
if not sign_request.exists():
204+
return request.not_found()
205+
# find the signed document attachment
206+
attachment = (
207+
request.env["ir.attachment"]
208+
.sudo()
209+
.search(
210+
[
211+
("res_model", "=", "sign.oca.request"),
212+
("res_id", "=", sign_request.id),
213+
("res_field", "=", "data"),
214+
],
215+
limit=1,
216+
)
217+
)
218+
if not attachment:
219+
return request.not_found()
220+
ascii_filename = "document.pdf"
221+
filename = sign_request.name or ascii_filename
222+
# Ensure .pdf extension
223+
if not filename.lower().endswith(".pdf"):
224+
filename = f"{filename}.pdf"
225+
utf8_filename = parse.quote(filename)
226+
return request.redirect(
227+
f"/web/content/{attachment.id}?download=true&filename={utf8_filename}"
228+
)

sign_oca/readme/USAGE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,7 @@
5555
no signer will be set.
5656
- Some extra modules (e.g. maintenance_sign_oca) will automatically set
5757
the signers for each request.
58+
59+
## Sign from portal
60+
- customers who are using portal can sign their documents from portal
61+
directly in addition to being able to sign them from emails.

sign_oca/static/description/index.html

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
55
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
6-
<title>README.rst</title>
6+
<title>Sign Oca</title>
77
<style type="text/css">
88

99
/*
@@ -360,21 +360,16 @@
360360
</style>
361361
</head>
362362
<body>
363-
<div class="document">
363+
<div class="document" id="sign-oca">
364+
<h1 class="title">Sign Oca</h1>
364365

365-
366-
<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
367-
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
368-
</a>
369-
<div class="section" id="sign-oca">
370-
<h1>Sign Oca</h1>
371366
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
372367
!! This file is generated by oca-gen-addon-readme !!
373368
!! changes will be overwritten. !!
374369
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
375370
!! source digest: sha256:b17d01dcbe348901b5e778fda1c276bbd58e85a4a1c3f1cdffbb855ad51afe05
376371
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
377-
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/sign/tree/16.0/sign_oca"><img alt="OCA/sign" src="https://img.shields.io/badge/github-OCA%2Fsign-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sign-16-0/sign-16-0-sign_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/sign&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
372+
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/sign/tree/16.0/sign_oca"><img alt="OCA/sign" src="https://img.shields.io/badge/github-OCA%2Fsign-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/sign-16-0/sign-16-0-sign_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/sign&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
378373
<p>This module allows to create documents for signature inside Odoo using
379374
OWL.</p>
380375
<p><strong>Table of contents</strong></p>
@@ -387,33 +382,34 @@ <h1>Sign Oca</h1>
387382
<li><a class="reference internal" href="#sign-a-document-from-template" id="toc-entry-5">Sign a document from template</a></li>
388383
<li><a class="reference internal" href="#sign-a-pending-document" id="toc-entry-6">Sign a pending document</a></li>
389384
<li><a class="reference internal" href="#sign-from-template" id="toc-entry-7">Sign from template</a></li>
385+
<li><a class="reference internal" href="#sign-from-portal" id="toc-entry-8">Sign from portal</a></li>
390386
</ul>
391387
</li>
392-
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-8">Known issues / Roadmap</a><ul>
393-
<li><a class="reference internal" href="#tasks" id="toc-entry-9">Tasks</a></li>
388+
<li><a class="reference internal" href="#known-issues-roadmap" id="toc-entry-9">Known issues / Roadmap</a><ul>
389+
<li><a class="reference internal" href="#tasks" id="toc-entry-10">Tasks</a></li>
394390
</ul>
395391
</li>
396-
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-10">Bug Tracker</a></li>
397-
<li><a class="reference internal" href="#credits" id="toc-entry-11">Credits</a><ul>
398-
<li><a class="reference internal" href="#authors" id="toc-entry-12">Authors</a></li>
399-
<li><a class="reference internal" href="#contributors" id="toc-entry-13">Contributors</a></li>
400-
<li><a class="reference internal" href="#maintainers" id="toc-entry-14">Maintainers</a></li>
392+
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-11">Bug Tracker</a></li>
393+
<li><a class="reference internal" href="#credits" id="toc-entry-12">Credits</a><ul>
394+
<li><a class="reference internal" href="#authors" id="toc-entry-13">Authors</a></li>
395+
<li><a class="reference internal" href="#contributors" id="toc-entry-14">Contributors</a></li>
396+
<li><a class="reference internal" href="#maintainers" id="toc-entry-15">Maintainers</a></li>
401397
</ul>
402398
</li>
403399
</ul>
404400
</div>
405401
<div class="section" id="configuration">
406-
<h2><a class="toc-backref" href="#toc-entry-1">Configuration</a></h2>
402+
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
407403
<p>There is a wizard (sign.oca.template.generate.multi) that can be used
408404
for any model needed. If there is a template without a linked model or
409405
linked to a model (res.partner for example) an action will be
410406
automatically displayed in the tree and form view (only for users with
411407
Sign permissions).</p>
412408
</div>
413409
<div class="section" id="usage">
414-
<h2><a class="toc-backref" href="#toc-entry-2">Usage</a></h2>
410+
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
415411
<div class="section" id="creation-of-templates">
416-
<h3><a class="toc-backref" href="#toc-entry-3">Creation of templates</a></h3>
412+
<h2><a class="toc-backref" href="#toc-entry-3">Creation of templates</a></h2>
417413
<ul class="simple">
418414
<li>Access Sign / Templates</li>
419415
<li>Create a new template</li>
@@ -425,7 +421,7 @@ <h3><a class="toc-backref" href="#toc-entry-3">Creation of templates</a></h3>
425421
</ul>
426422
</div>
427423
<div class="section" id="sign-role">
428-
<h3><a class="toc-backref" href="#toc-entry-4">Sign role</a></h3>
424+
<h2><a class="toc-backref" href="#toc-entry-4">Sign role</a></h2>
429425
<ul class="simple">
430426
<li>Access Sign / Settings / Roles</li>
431427
<li>Create a new role (Equipment employee for example)</li>
@@ -436,7 +432,7 @@ <h3><a class="toc-backref" href="#toc-entry-4">Sign role</a></h3>
436432
</ul>
437433
</div>
438434
<div class="section" id="sign-a-document-from-template">
439-
<h3><a class="toc-backref" href="#toc-entry-5">Sign a document from template</a></h3>
435+
<h2><a class="toc-backref" href="#toc-entry-5">Sign a document from template</a></h2>
440436
<ul class="simple">
441437
<li>Access Sign / Templates</li>
442438
<li>Press the Sign button from a template</li>
@@ -451,7 +447,7 @@ <h3><a class="toc-backref" href="#toc-entry-5">Sign a document from template</a>
451447
</ul>
452448
</div>
453449
<div class="section" id="sign-a-pending-document">
454-
<h3><a class="toc-backref" href="#toc-entry-6">Sign a pending document</a></h3>
450+
<h2><a class="toc-backref" href="#toc-entry-6">Sign a pending document</a></h2>
455451
<ul class="simple">
456452
<li>Go to the pencil icon in the upper right corner (systray) of the sign
457453
request to access the pending signatures.</li>
@@ -464,7 +460,7 @@ <h3><a class="toc-backref" href="#toc-entry-6">Sign a pending document</a></h3>
464460
</ul>
465461
</div>
466462
<div class="section" id="sign-from-template">
467-
<h3><a class="toc-backref" href="#toc-entry-7">Sign from template</a></h3>
463+
<h2><a class="toc-backref" href="#toc-entry-7">Sign from template</a></h2>
468464
<ul class="simple">
469465
<li>Go to any list view or form view (except sign.oca models), e.g.:
470466
Contacts</li>
@@ -480,11 +476,18 @@ <h3><a class="toc-backref" href="#toc-entry-7">Sign from template</a></h3>
480476
the signers for each request.</li>
481477
</ul>
482478
</div>
479+
<div class="section" id="sign-from-portal">
480+
<h2><a class="toc-backref" href="#toc-entry-8">Sign from portal</a></h2>
481+
<ul class="simple">
482+
<li>customers who are using portal can sign their documents from portal
483+
directly in addition to being able to sign them from emails.</li>
484+
</ul>
485+
</div>
483486
</div>
484487
<div class="section" id="known-issues-roadmap">
485-
<h2><a class="toc-backref" href="#toc-entry-8">Known issues / Roadmap</a></h2>
488+
<h1><a class="toc-backref" href="#toc-entry-9">Known issues / Roadmap</a></h1>
486489
<div class="section" id="tasks">
487-
<h3><a class="toc-backref" href="#toc-entry-9">Tasks</a></h3>
490+
<h2><a class="toc-backref" href="#toc-entry-10">Tasks</a></h2>
488491
<ul class="simple">
489492
<li>Ensure that the signature is inalterable. Maybe we might need to use
490493
some tools like endevise or pyHanko with a certificate. Signer can be
@@ -493,23 +496,23 @@ <h3><a class="toc-backref" href="#toc-entry-9">Tasks</a></h3>
493496
</div>
494497
</div>
495498
<div class="section" id="bug-tracker">
496-
<h2><a class="toc-backref" href="#toc-entry-10">Bug Tracker</a></h2>
499+
<h1><a class="toc-backref" href="#toc-entry-11">Bug Tracker</a></h1>
497500
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/sign/issues">GitHub Issues</a>.
498501
In case of trouble, please check there if your issue has already been reported.
499502
If you spotted it first, help us to smash it by providing a detailed and welcomed
500503
<a class="reference external" href="https://github.com/OCA/sign/issues/new?body=module:%20sign_oca%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
501504
<p>Do not contact contributors directly about support or help with technical issues.</p>
502505
</div>
503506
<div class="section" id="credits">
504-
<h2><a class="toc-backref" href="#toc-entry-11">Credits</a></h2>
507+
<h1><a class="toc-backref" href="#toc-entry-12">Credits</a></h1>
505508
<div class="section" id="authors">
506-
<h3><a class="toc-backref" href="#toc-entry-12">Authors</a></h3>
509+
<h2><a class="toc-backref" href="#toc-entry-13">Authors</a></h2>
507510
<ul class="simple">
508511
<li>Dixmit</li>
509512
</ul>
510513
</div>
511514
<div class="section" id="contributors">
512-
<h3><a class="toc-backref" href="#toc-entry-13">Contributors</a></h3>
515+
<h2><a class="toc-backref" href="#toc-entry-14">Contributors</a></h2>
513516
<ul class="simple">
514517
<li>Enric Tobella (<a class="reference external" href="http://www.dixmit.com">www.dixmit.com</a>)</li>
515518
<li><a class="reference external" href="https://www.tecnativa.com">Tecnativa</a>:<ul>
@@ -523,7 +526,7 @@ <h3><a class="toc-backref" href="#toc-entry-13">Contributors</a></h3>
523526
</ul>
524527
</div>
525528
<div class="section" id="maintainers">
526-
<h3><a class="toc-backref" href="#toc-entry-14">Maintainers</a></h3>
529+
<h2><a class="toc-backref" href="#toc-entry-15">Maintainers</a></h2>
527530
<p>This module is maintained by the OCA.</p>
528531
<a class="reference external image-reference" href="https://odoo-community.org">
529532
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
@@ -538,6 +541,5 @@ <h3><a class="toc-backref" href="#toc-entry-14">Maintainers</a></h3>
538541
</div>
539542
</div>
540543
</div>
541-
</div>
542544
</body>
543545
</html>

0 commit comments

Comments
 (0)