Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion project_task_sign_oca/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@
"demo/sign_oca_role.xml",
"demo/sign_oca_template.xml",
],
"installable": True,
"maintainers": ["WesleyOliveira98"],
}
10 changes: 7 additions & 3 deletions project_task_sign_oca/models/project_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,13 @@ def create(self, vals_list):
return res

def write(self, vals):
old_partner_id = self.partner_id
new_partner_id = vals.get("partner_id")
# Store old partner IDs for each task before write
old_partner_ids = {task.id: task.partner_id.id for task in self}
res = super().write(vals)
if new_partner_id and new_partner_id != old_partner_id.id:
self._generate_sign_oca_request()
if new_partner_id:
# Generate sign requests only for tasks whose partner actually changed
for task in self:
if new_partner_id != old_partner_ids.get(task.id):
task._generate_sign_oca_request()
return res
20 changes: 11 additions & 9 deletions project_task_sign_oca/models/sign_oca_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,17 @@ class SignOcaRequest(models.Model):

@api.depends("record_ref")
def _compute_task_id(self):
for item in self.filtered(
lambda x: x.record_ref and x.record_ref._name == "project.task"
):
item.task_id = item.record_ref.id
for item in self:
if item.record_ref and item.record_ref._name == "project.task":
item.task_id = item.record_ref.id
else:
item.task_id = False

@api.depends("record_ref")
def _compute_project_id(self):
for item in self.filtered(
lambda x: x.record_ref and x.record_ref._name == "project.task"
):
task = self.env["project.task"].browse(item.record_ref.id)
item.project_id = task.project_id
for item in self:
if item.record_ref and item.record_ref._name == "project.task":
task = self.env["project.task"].browse(item.record_ref.id)
item.project_id = task.project_id
else:
item.project_id = False
24 changes: 16 additions & 8 deletions sign_oca/controllers/main.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from collections import OrderedDict
from urllib import parse

from odoo import _, http
from odoo import http
from odoo.exceptions import AccessError, MissingError
from odoo.http import request
from odoo.osv import expression
Expand Down Expand Up @@ -124,13 +124,13 @@ def get_sign_requests_domain(self, request):

def _get_my_sign_requests_searchbar_filters(self):
searchbar_filters = {
"all": {"label": _("All"), "domain": []},
"all": {"label": request.env._("All"), "domain": []},
"sent": {
"label": _("sent"),
"label": request.env._("sent"),
"domain": [("request_id.state", "=", "0_sent")],
},
"signed": {
"label": _("Signed"),
"label": request.env._("Signed"),
"domain": [("request_id.state", "=", "2_signed")],
},
}
Expand All @@ -139,10 +139,13 @@ def _get_my_sign_requests_searchbar_filters(self):
def _prepare_sign_portal_rendering_values(self, page=1, sign_page=False, **kwargs):
# Sorting feature
searchbar_sortings = {
"state": {"label": _("Sent to Signed"), "order": "request_id"},
"reverse_state": {"label": _("Signed to Sent"), "order": "request_id desc"},
"date": {"label": _("Newest"), "order": "create_date desc"},
"reverse_date": {"label": _("Oldest"), "order": "create_date"},
"state": {"label": request.env._("Sent to Signed"), "order": "request_id"},
"reverse_state": {
"label": request.env._("Signed to Sent"),
"order": "request_id desc",
},
"date": {"label": request.env._("Newest"), "order": "create_date desc"},
"reverse_date": {"label": request.env._("Oldest"), "order": "create_date"},
}
sortby = kwargs.get("sortby", "state")
order = searchbar_sortings[sortby]["order"]
Expand Down Expand Up @@ -208,6 +211,11 @@ def portal_download_signed(self, request_id, **kw):
sign_request = request.env["sign.oca.request"].sudo().browse(request_id)
if not sign_request.exists():
return request.not_found()
# Security check: user must be a signer of this document
user_partner = request.env.user.partner_id
signer_partners = sign_request.signer_ids.mapped("partner_id")
if user_partner not in signer_partners:
return request.not_found()
# find the signed document attachment
attachment = (
request.env["ir.attachment"]
Expand Down
26 changes: 15 additions & 11 deletions sign_oca/models/sign_oca_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,11 @@ def sign(self):
@api.depends("signatory_data")
def _compute_next_item_id(self):
for record in self:
record.next_item_id = (
record.signatory_data
and max([int(key) for key in record.signatory_data.keys()])
or 0
) + 1
if record.signatory_data:
keys = [int(key) for key in record.signatory_data.keys()]
record.next_item_id = (max(keys) if keys else 0) + 1
else:
record.next_item_id = 1

def preview(self):
self.ensure_one()
Expand Down Expand Up @@ -227,7 +227,8 @@ def add_item(self, item_vals):

def cancel(self):
self.write({"state": "3_cancel"})
self._set_action_log("cancel")
for record in self:
record._set_action_log("cancel")

@api.depends("signer_ids")
def _compute_signer_count(self):
Expand Down Expand Up @@ -435,8 +436,10 @@ def action_sign(self, items, access_token=False, latitude=False, longitude=False
self.ensure_one()
if self.signed_on:
raise ValidationError(
self.env._("Users %s has already signed the document")
% self.partner_id.name
self.env._(
"Users %(name)s has already signed the document",
name=self.partner_id.name,
)
)
if self.request_id.state != "0_sent":
raise ValidationError(self.env._("Request cannot be signed"))
Expand Down Expand Up @@ -500,7 +503,9 @@ def _check_signable(self, item):
if not item["required"]:
return
if not item["value"]:
raise ValidationError(self.env._("Field %s is not filled") % item["name"])
raise ValidationError(
self.env._("Field %(name)s is not filled", name=item["name"])
)

def _get_pdf_page_text(self, item, box):
packet = BytesIO()
Expand Down Expand Up @@ -670,9 +675,8 @@ def _get_integrity_hash_fields(self):

class SignRequestLog(models.Model):
_name = "sign.oca.request.log"
_description = "Sign Request Log"
_log_access = False
_description = "Log access and edition on requests"
_log_access = False

uid = fields.Many2one(
"res.users",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class SignOcaPdfCommon extends Component {
this.dialogService = useService("dialog");
}
getPdfUrl() {
return "/web/content/" + this.model + "/" + this.res_id + "/data";
return "/web/content?model=" + this.model + "&id=" + this.res_id + "&field=data";
}
async willStart() {
this.info = await this.orm.call(this.model, "get_info", [[this.res_id]]);
Expand Down
Loading