diff --git a/project_task_sign_oca/__manifest__.py b/project_task_sign_oca/__manifest__.py index 72a72282..dee5689e 100644 --- a/project_task_sign_oca/__manifest__.py +++ b/project_task_sign_oca/__manifest__.py @@ -19,6 +19,5 @@ "demo/sign_oca_role.xml", "demo/sign_oca_template.xml", ], - "installable": True, "maintainers": ["WesleyOliveira98"], } diff --git a/project_task_sign_oca/models/project_task.py b/project_task_sign_oca/models/project_task.py index 5f808cb1..4e0a1786 100644 --- a/project_task_sign_oca/models/project_task.py +++ b/project_task_sign_oca/models/project_task.py @@ -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 diff --git a/project_task_sign_oca/models/sign_oca_request.py b/project_task_sign_oca/models/sign_oca_request.py index 29165de7..3615d75d 100644 --- a/project_task_sign_oca/models/sign_oca_request.py +++ b/project_task_sign_oca/models/sign_oca_request.py @@ -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 diff --git a/sign_oca/controllers/main.py b/sign_oca/controllers/main.py index cd011641..f7e6c086 100644 --- a/sign_oca/controllers/main.py +++ b/sign_oca/controllers/main.py @@ -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 @@ -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")], }, } @@ -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"] @@ -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"] diff --git a/sign_oca/models/sign_oca_request.py b/sign_oca/models/sign_oca_request.py index 339307cd..e03548c3 100644 --- a/sign_oca/models/sign_oca_request.py +++ b/sign_oca/models/sign_oca_request.py @@ -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() @@ -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): @@ -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")) @@ -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() @@ -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", diff --git a/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common.esm.js b/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common.esm.js index ad9e12b0..87e9de74 100644 --- a/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common.esm.js +++ b/sign_oca/static/src/components/sign_oca_pdf_common/sign_oca_pdf_common.esm.js @@ -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]]);