From f3f6597ed6dca2bc69bc356bf9c6a5ec694723e0 Mon Sep 17 00:00:00 2001 From: kobros-tech Date: Fri, 4 Apr 2025 02:11:07 +0300 Subject: [PATCH 1/9] [ADD] survey_sign_oca: survey and sign_oca connector --- .eslintrc.yml | 2 +- .../odoo/addons/survey_sign_oca | 1 + setup/survey_sign_oca/setup.py | 6 + survey_sign_oca/README.rst | 148 ++++++ survey_sign_oca/__init__.py | 1 + survey_sign_oca/__manifest__.py | 27 + survey_sign_oca/data/sign_oca_role.xml | 21 + survey_sign_oca/models/__init__.py | 4 + survey_sign_oca/models/res_company.py | 14 + survey_sign_oca/models/res_config_settings.py | 15 + survey_sign_oca/models/sign_oca_request.py | 46 ++ survey_sign_oca/models/survey_invite.py | 73 +++ survey_sign_oca/readme/CONFIGURE.md | 28 + survey_sign_oca/readme/CONTRIBUTORS.md | 2 + survey_sign_oca/readme/DESCRIPTION.md | 2 + survey_sign_oca/readme/USAGE.md | 20 + survey_sign_oca/static/description/icon.png | Bin 0 -> 90087 bytes survey_sign_oca/static/description/index.html | 486 ++++++++++++++++++ survey_sign_oca/static/src/text.esm.js | 105 ++++ survey_sign_oca/tests/__init__.py | 2 + .../views/res_config_settings_view.xml | 49 ++ .../views/sign_oca_request_views.xml | 24 + survey_sign_oca/views/survey_user_views.xml | 22 + test-requirements.txt | 1 + 24 files changed, 1098 insertions(+), 1 deletion(-) create mode 120000 setup/survey_sign_oca/odoo/addons/survey_sign_oca create mode 100644 setup/survey_sign_oca/setup.py create mode 100644 survey_sign_oca/README.rst create mode 100644 survey_sign_oca/__init__.py create mode 100644 survey_sign_oca/__manifest__.py create mode 100644 survey_sign_oca/data/sign_oca_role.xml create mode 100644 survey_sign_oca/models/__init__.py create mode 100644 survey_sign_oca/models/res_company.py create mode 100644 survey_sign_oca/models/res_config_settings.py create mode 100644 survey_sign_oca/models/sign_oca_request.py create mode 100644 survey_sign_oca/models/survey_invite.py create mode 100644 survey_sign_oca/readme/CONFIGURE.md create mode 100644 survey_sign_oca/readme/CONTRIBUTORS.md create mode 100644 survey_sign_oca/readme/DESCRIPTION.md create mode 100644 survey_sign_oca/readme/USAGE.md create mode 100644 survey_sign_oca/static/description/icon.png create mode 100644 survey_sign_oca/static/description/index.html create mode 100644 survey_sign_oca/static/src/text.esm.js create mode 100644 survey_sign_oca/tests/__init__.py create mode 100644 survey_sign_oca/views/res_config_settings_view.xml create mode 100644 survey_sign_oca/views/sign_oca_request_views.xml create mode 100644 survey_sign_oca/views/survey_user_views.xml create mode 100644 test-requirements.txt diff --git a/.eslintrc.yml b/.eslintrc.yml index fed88d70..1e64063c 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -4,7 +4,7 @@ env: # See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449 parserOptions: - ecmaVersion: 2019 + ecmaVersion: 2021 overrides: - files: diff --git a/setup/survey_sign_oca/odoo/addons/survey_sign_oca b/setup/survey_sign_oca/odoo/addons/survey_sign_oca new file mode 120000 index 00000000..9418f635 --- /dev/null +++ b/setup/survey_sign_oca/odoo/addons/survey_sign_oca @@ -0,0 +1 @@ +../../../../survey_sign_oca \ No newline at end of file diff --git a/setup/survey_sign_oca/setup.py b/setup/survey_sign_oca/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/survey_sign_oca/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/survey_sign_oca/README.rst b/survey_sign_oca/README.rst new file mode 100644 index 00000000..bb4960d9 --- /dev/null +++ b/survey_sign_oca/README.rst @@ -0,0 +1,148 @@ +=============== +Survey Sign Oca +=============== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c6ec61a6c8661f9097946736d2cd67efc929e1531803516fa6d82728aab2c98a + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsign-lightgray.png?logo=github + :target: https://github.com/OCA/sign/tree/16.0/survey_sign_oca + :alt: OCA/sign +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/sign-16-0/sign-16-0-survey_sign_oca + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/sign&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allows you to make survey signature requests manually or +automatically. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +1. Go to Sign > Settings > Roles and create a new one with the following + data if not there: + + - For the survey participant + + - Partner type: Expression + - Expression: {{object.partner_id.id}} + + - For the survey responsible if you want + + - Partner type: Expression + - Expression: {{object.survey_id.user_id.partner_id.id}} + +2. Go to Sign > Settings > Fields and create a new one with the + following data if not there: + + - Field Type: text + - Default Value: survey + +3. Go to Sign > Templates and create a template with the following data: + + - Model: Survey User Input + - In some of the elements you will have to set the previously created + role[s]. + +4. Go to Settings > Survey Sign OCA: + +5. Defines the template previously created (optional, only for automatic + creation of signature requests). + +Usage +===== + +A smart-button will be displayed on the participations form view of the +linked sign requests. + +Manual Sign Request creation process: + +:: + + - Go to Surveys \> Participations and change to list view. + - Select the records that you want. + - Click on the "Sign from template" action. + - Select a template. + - Click on Generate. + - Sign Requests will have been generated (and sent) for the selected items. + +Automatic Sign Request creation process: + +:: + + - When an partner takes a survey, a sign request will be created automatically. + +For generated sign requests scoping survey, input values are populated +automatically with the survey answered values. + +Signers can still update the input values if they want. + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Kencove + +Contributors +------------ + +- `Kencove `__ + + - Mohamed Alkobrosli + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-Kencove| image:: https://github.com/Kencove.png?size=40px + :target: https://github.com/Kencove + :alt: Kencove + +Current `maintainer `__: + +|maintainer-Kencove| + +This module is part of the `OCA/sign `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/survey_sign_oca/__init__.py b/survey_sign_oca/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/survey_sign_oca/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/survey_sign_oca/__manifest__.py b/survey_sign_oca/__manifest__.py new file mode 100644 index 00000000..2414d9a9 --- /dev/null +++ b/survey_sign_oca/__manifest__.py @@ -0,0 +1,27 @@ +# Copyright 2025 Kencove - Mohamed Alkobrosli +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "Survey Sign Oca", + "version": "16.0.1.0.0", + "category": "Surveys", + "website": "https://github.com/OCA/sign", + "author": "Kencove, Odoo Community Association (OCA)", + "license": "AGPL-3", + "depends": ["sign_oca", "survey"], + "data": [ + "views/survey_user_views.xml", + "views/res_config_settings_view.xml", + "views/sign_oca_request_views.xml", + "data/sign_oca_role.xml", + ], + "assets": { + "web.assets_backend": [ + "survey_sign_oca/static/src/text.esm.js", + ], + "web.assets_frontend": [ + "survey_sign_oca/static/src/text.esm.js", + ], + }, + "installable": True, + "maintainers": ["Kencove"], +} diff --git a/survey_sign_oca/data/sign_oca_role.xml b/survey_sign_oca/data/sign_oca_role.xml new file mode 100644 index 00000000..37474033 --- /dev/null +++ b/survey_sign_oca/data/sign_oca_role.xml @@ -0,0 +1,21 @@ + + + Survey + text + survey + + + + Survey Participant + expression + {{object.partner_id.id}} + + + + Survey Responsible + expression + {{object.survey_id.user_id.partner_id.id}} + + diff --git a/survey_sign_oca/models/__init__.py b/survey_sign_oca/models/__init__.py new file mode 100644 index 00000000..1d665615 --- /dev/null +++ b/survey_sign_oca/models/__init__.py @@ -0,0 +1,4 @@ +from . import survey_invite +from . import res_company +from . import res_config_settings +from . import sign_oca_request diff --git a/survey_sign_oca/models/res_company.py b/survey_sign_oca/models/res_company.py new file mode 100644 index 00000000..534fc9dd --- /dev/null +++ b/survey_sign_oca/models/res_company.py @@ -0,0 +1,14 @@ +# Copyright 2025 Kencove - Mohamed Alkobrosli +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ResCompany(models.Model): + _inherit = "res.company" + + survey_user_input_sign_oca_template_id = fields.Many2one( + comodel_name="sign.oca.template", + domain="[('model_id.model', '=', 'survey.user_input')]", + string="Sign Oca Template", + ) diff --git a/survey_sign_oca/models/res_config_settings.py b/survey_sign_oca/models/res_config_settings.py new file mode 100644 index 00000000..e50fa838 --- /dev/null +++ b/survey_sign_oca/models/res_config_settings.py @@ -0,0 +1,15 @@ +# Copyright 2025 Kencove - Mohamed Alkobrosli +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + survey_user_input_sign_oca_template_id = fields.Many2one( + comodel_name="sign.oca.template", + related="company_id.survey_user_input_sign_oca_template_id", + string="Sign Oca Template", + readonly=False, + ) diff --git a/survey_sign_oca/models/sign_oca_request.py b/survey_sign_oca/models/sign_oca_request.py new file mode 100644 index 00000000..f93a6bb1 --- /dev/null +++ b/survey_sign_oca/models/sign_oca_request.py @@ -0,0 +1,46 @@ +# Copyright 2025 Kencove - Mohamed Alkobrosli +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import api, fields, models + + +class SignOcaRequest(models.Model): + _inherit = "sign.oca.request" + + # This field is required for the inverse of maintenance.equipment. + survey_user_input_id = fields.Many2one( + comodel_name="survey.user_input", + compute="_compute_survey_user_input_id", + string="Survey Participation", + readonly=True, + store=True, + ondelete="cascade", + ) + + @api.depends("record_ref") + def _compute_survey_user_input_id(self): + for item in self.filtered( + lambda x: x.record_ref and x.record_ref._name == "survey.user_input" + ): + item.survey_user_input_id = item.record_ref.id + + +class SignOcaRequestSigner(models.Model): + + _inherit = "sign.oca.request.signer" + + def get_info(self, access_token=False): + vals = super().get_info(access_token) + # send defaults for survey related sign requests + model_id = self.request_id.template_id.model_id + survey_participation = self.request_id.record_ref + if survey_participation and model_id and model_id.model == "survey.user_input": + survey = {} + for line in survey_participation.user_input_line_ids: + if line.question_id.question_type == "matrix": + survey.update( + {line.matrix_row_id.value: line.suggested_answer_id.value} + ) + else: + survey.update({line.question_id.display_name: line.display_name}) + vals["partner"].update({"survey": survey}) + return vals diff --git a/survey_sign_oca/models/survey_invite.py b/survey_sign_oca/models/survey_invite.py new file mode 100644 index 00000000..2972534e --- /dev/null +++ b/survey_sign_oca/models/survey_invite.py @@ -0,0 +1,73 @@ +# Copyright 2025 Kencove - Mohamed Alkobrosli +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import api, fields, models + + +class SurveyUserInput(models.Model): + _inherit = "survey.user_input" + + # This field is stored as a help to filter by. + sign_request_ids = fields.One2many( + comodel_name="sign.oca.request", + inverse_name="survey_user_input_id", + string="Sign Requests", + ) + sign_request_count = fields.Integer( + string="Sign request count", + compute="_compute_sign_request_count", + compute_sudo=True, + store=True, + ) + + @api.depends("sign_request_ids") + def _compute_sign_request_count(self): + request_data = self.env["sign.oca.request"].read_group( + [("survey_user_input_id", "in", self.ids)], + ["survey_user_input_id"], + ["survey_user_input_id"], + ) + mapped_data = { + x["survey_user_input_id"][0]: x["survey_user_input_id_count"] + for x in request_data + } + for item in self: + item.sign_request_count = mapped_data.get(item.id, 0) + + def action_view_sign_requests(self): + self.ensure_one() + result = self.env["ir.actions.act_window"]._for_xml_id( + "sign_oca.sign_oca_request_act_window" + ) + result["domain"] = [("id", "in", self.sign_request_ids.ids)] + ctx = dict(self.env.context) + ctx.update( + { + "default_maintenance_equipment_id": self.id, + "search_default_maintenance_equipment_id": self.id, + } + ) + result["context"] = ctx + return result + + def _process_generate_sign_oca_request(self, data): + """Generate request from template if owner has changed.""" + request_model = self.env["sign.oca.request"].sudo() + for item in self.filtered("partner_id"): + sign_template = ( + item.survey_id.user_id.company_id.survey_user_input_sign_oca_template_id + ) + old_partner_id = data[item.id] if item.id in data else False + if sign_template and item.partner_id != old_partner_id: + # Apply sudo because the user who creates the record may not have + # permissions on sign.oca.template + sign_template = sign_template.sudo() + request_model.create( + sign_template._prepare_sign_oca_request_vals_from_record(item) + ) + + @api.model_create_multi + def create(self, vals_list): + res = super().create(vals_list) + if any(item.partner_id for item in res): + res._process_generate_sign_oca_request({}) + return res diff --git a/survey_sign_oca/readme/CONFIGURE.md b/survey_sign_oca/readme/CONFIGURE.md new file mode 100644 index 00000000..9f68fb40 --- /dev/null +++ b/survey_sign_oca/readme/CONFIGURE.md @@ -0,0 +1,28 @@ +1. Go to Sign \> Settings \> Roles and create a new one with the following data if not + there: + + - For the survey participant + + - Partner type: Expression + - Expression: {{object.partner_id.id}} + + - For the survey responsible if you want + + - Partner type: Expression + - Expression: {{object.survey_id.user_id.partner_id.id}} + +2. Go to Sign \> Settings \> Fields and create a new one with the following data if not + there: + + - Field Type: text + - Default Value: survey + +3. Go to Sign \> Templates and create a template with the following data: + + - Model: Survey User Input + - In some of the elements you will have to set the previously created role[s]. + +4. Go to Settings \> Survey Sign OCA: + +5. Defines the template previously created (optional, only for automatic creation of + signature requests). diff --git a/survey_sign_oca/readme/CONTRIBUTORS.md b/survey_sign_oca/readme/CONTRIBUTORS.md new file mode 100644 index 00000000..bbd23bec --- /dev/null +++ b/survey_sign_oca/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- [Kencove](https://kencove.com) + - Mohamed Alkobrosli diff --git a/survey_sign_oca/readme/DESCRIPTION.md b/survey_sign_oca/readme/DESCRIPTION.md new file mode 100644 index 00000000..f58c4007 --- /dev/null +++ b/survey_sign_oca/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module allows you to make survey signature requests manually or +automatically. diff --git a/survey_sign_oca/readme/USAGE.md b/survey_sign_oca/readme/USAGE.md new file mode 100644 index 00000000..5df7921d --- /dev/null +++ b/survey_sign_oca/readme/USAGE.md @@ -0,0 +1,20 @@ +A smart-button will be displayed on the participations form view of the linked sign +requests. + +Manual Sign Request creation process: + + - Go to Surveys \> Participations and change to list view. + - Select the records that you want. + - Click on the "Sign from template" action. + - Select a template. + - Click on Generate. + - Sign Requests will have been generated (and sent) for the selected items. + +Automatic Sign Request creation process: + + - When an partner takes a survey, a sign request will be created automatically. + +For generated sign requests scoping survey, input values are populated automatically +with the survey answered values. + +Signers can still update the input values if they want. diff --git a/survey_sign_oca/static/description/icon.png b/survey_sign_oca/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..40f020bf123a698a47fa493342838af2317d5699 GIT binary patch literal 90087 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 buU&)Q3wrF1gT>vm^Af+sQH!zRTU-K>N0r| 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 z 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 + + + + +Survey Sign Oca + + + +

+

Survey Sign Oca

+ + +

Beta License: AGPL-3 OCA/sign Translate me on Weblate Try me on Runboat

+

This module allows you to make survey signature requests manually or +automatically.

+

Table of contents

+ +
+

Configuration

+
    +
  1. Go to Sign > Settings > Roles and create a new one with the following +data if not there:
      +
    • For the survey participant
        +
      • Partner type: Expression
      • +
      • Expression: {{object.partner_id.id}}
      • +
      +
    • +
    • For the survey responsible if you want
        +
      • Partner type: Expression
      • +
      • Expression: {{object.survey_id.user_id.partner_id.id}}
      • +
      +
    • +
    +
  2. +
  3. Go to Sign > Settings > Fields and create a new one with the +following data if not there:
      +
    • Field Type: text
    • +
    • Default Value: survey
    • +
    +
  4. +
  5. Go to Sign > Templates and create a template with the following data:
      +
    • Model: Survey User Input
    • +
    • In some of the elements you will have to set the previously created +role[s].
    • +
    +
  6. +
  7. Go to Settings > Survey Sign OCA:
  8. +
  9. Defines the template previously created (optional, only for automatic +creation of signature requests).
  10. +
+
+
+

Usage

+

A smart-button will be displayed on the participations form view of the +linked sign requests.

+

Manual Sign Request creation process:

+
+- Go to Surveys \> Participations and change to list view.
+- Select the records that you want.
+- Click on the "Sign from template" action.
+- Select a template.
+- Click on Generate.
+- Sign Requests will have been generated (and sent) for the selected items.
+
+

Automatic Sign Request creation process:

+
+- When an partner takes a survey, a sign request will be created automatically.
+
+

For generated sign requests scoping survey, input values are populated +automatically with the survey answered values.

+

Signers can still update the input values if they want.

+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Kencove
  • +
+
+
+

Contributors

+
    +
  • Kencove
      +
    • Mohamed Alkobrosli
    • +
    +
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

Kencove

+

This module is part of the OCA/sign project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/survey_sign_oca/static/src/text.esm.js b/survey_sign_oca/static/src/text.esm.js new file mode 100644 index 00000000..5b17a05f --- /dev/null +++ b/survey_sign_oca/static/src/text.esm.js @@ -0,0 +1,105 @@ +/** @odoo-module **/ +/** Copyright 2025 Kencove - Mohamed Alkobrosli + License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). **/ + +import core from "web.core"; +import {registry} from "@web/core/registry"; + +function patchSignOca() { + const SignRegistry = registry.category("sign_oca"); + const textSignOca = registry.category("sign_oca").get("text"); + const patchedTextSignOca = Object.assign({}, textSignOca); + + function applyDefaultValue({input, parent, item, signatureItem, changeFn}) { + if ( + item.default_value && + !item.value && + parent.info.partner[item.default_value] + ) { + let val = null; + if (item.default_value === "survey") { + const surveyValue = + parent.info.partner.survey?.[item.placeholder] || null; + if (surveyValue && surveyValue !== "Skipped") { + val = surveyValue; + } + } else { + val = parent.info.partner[item.default_value]; + } + if (val) { + changeFn(val, parent, item, signatureItem); + input.value = val; + } + } + } + + patchedTextSignOca.generate = function (parent, item, signatureItem) { + const input = $( + core.qweb.render("sign_oca.sign_iframe_field_text", { + item, + role_id: parent.info.role_id, + }) + )[0]; + // Apply default values immediately after creating inputs for survey related requests specifically. + if (parent.info.partner.survey) { + applyDefaultValue({ + input, + parent, + item, + signatureItem, + changeFn: this.change.bind(this), + }); + } + signatureItem[0].addEventListener("focus_signature", () => { + input.focus(); + }); + // Update the value of the focused input to the default + input.addEventListener("focus", (ev) => { + applyDefaultValue({ + input: ev.target, + parent, + item, + signatureItem, + changeFn: this.change.bind(this), + }); + }); + + input.addEventListener("change", (ev) => { + this.change(ev.target.value, parent, item, signatureItem); + }); + input.addEventListener("keydown", (ev) => { + if ((ev.keyCode || ev.which) !== 9) { + return true; + } + ev.preventDefault(); + const next_items = _.filter( + parent.info.items, + (i) => i.tabindex > item.tabindex && i.role_id === parent.info.role_id + ).sort((a, b) => a.tabindex - b.tabindex); + if (next_items.length > 0) { + ev.currentTarget.blur(); + const nextItem = next_items[0]; + if (nextItem && parent.items && parent.items[nextItem.id]) { + parent.items[nextItem.id].dispatchEvent( + new Event("focus_signature") + ); + } else { + console.warn("Missing next item or dispatch target", nextItem); + } + } + }); + return input; + }; + // Re-add the registry + SignRegistry.remove("text"); + SignRegistry.add("text", patchedTextSignOca); +} + +const interval = setInterval(() => { + const signOca = registry.category("sign_oca"); + const content = signOca.content; + if (content && content.text) { + clearInterval(interval); + patchSignOca(); + } +}, 100); diff --git a/survey_sign_oca/tests/__init__.py b/survey_sign_oca/tests/__init__.py new file mode 100644 index 00000000..e2b55b52 --- /dev/null +++ b/survey_sign_oca/tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2023 Kencove - Mohamed Alkobrosli +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). diff --git a/survey_sign_oca/views/res_config_settings_view.xml b/survey_sign_oca/views/res_config_settings_view.xml new file mode 100644 index 00000000..600fc3e3 --- /dev/null +++ b/survey_sign_oca/views/res_config_settings_view.xml @@ -0,0 +1,49 @@ + + + + + res.config.settings.view.form.inherit + res.config.settings + + + + +
+

Surveys Sign Template

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/survey_sign_oca/views/sign_oca_request_views.xml b/survey_sign_oca/views/sign_oca_request_views.xml new file mode 100644 index 00000000..64dddaeb --- /dev/null +++ b/survey_sign_oca/views/sign_oca_request_views.xml @@ -0,0 +1,24 @@ + + + + sign.oca.request.search + sign.oca.request + + + + + + + + + + + diff --git a/survey_sign_oca/views/survey_user_views.xml b/survey_sign_oca/views/survey_user_views.xml new file mode 100644 index 00000000..bc3530ea --- /dev/null +++ b/survey_sign_oca/views/survey_user_views.xml @@ -0,0 +1,22 @@ + + + + survey.user.input.view.form + survey.user_input + + +
+ +
+
+
+
diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000..e192291b --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo-addon-sign_oca @ git+https://github.com/OCA/sign.git@refs/pull/91/head#subdirectory=setup/sign_oca From ae6fcee66f7796a07e78866666a1735352671665 Mon Sep 17 00:00:00 2001 From: kobros-tech Date: Sat, 5 Apr 2025 10:16:37 +0300 Subject: [PATCH 2/9] [IMP] survey_sign_oca: populate check fields from survey answers --- survey_sign_oca/README.rst | 14 ++- survey_sign_oca/__manifest__.py | 2 + survey_sign_oca/data/sign_oca_role.xml | 8 +- survey_sign_oca/models/sign_oca_request.py | 28 +++++- survey_sign_oca/readme/CONFIGURE.md | 10 +- survey_sign_oca/readme/USAGE.md | 2 + survey_sign_oca/static/description/index.html | 10 ++ survey_sign_oca/static/src/check.esm.js | 96 +++++++++++++++++++ survey_sign_oca/static/src/text.esm.js | 8 +- 9 files changed, 170 insertions(+), 8 deletions(-) create mode 100644 survey_sign_oca/static/src/check.esm.js diff --git a/survey_sign_oca/README.rst b/survey_sign_oca/README.rst index bb4960d9..cf0545b9 100644 --- a/survey_sign_oca/README.rst +++ b/survey_sign_oca/README.rst @@ -55,8 +55,15 @@ Configuration 2. Go to Sign > Settings > Fields and create a new one with the following data if not there: - - Field Type: text - - Default Value: survey + - Text Survey Field + + - Field Type: text + - Default Value: survey + + - Check Survey Field + + - Field Type: check + - Default Value: survey 3. Go to Sign > Templates and create a template with the following data: @@ -95,6 +102,9 @@ Automatic Sign Request creation process: For generated sign requests scoping survey, input values are populated automatically with the survey answered values. +Answers of yes/no type are shown in text fields as Yes/No and in check +fields as checked/unchecked. + Signers can still update the input values if they want. Bug Tracker diff --git a/survey_sign_oca/__manifest__.py b/survey_sign_oca/__manifest__.py index 2414d9a9..4c8198e5 100644 --- a/survey_sign_oca/__manifest__.py +++ b/survey_sign_oca/__manifest__.py @@ -17,9 +17,11 @@ "assets": { "web.assets_backend": [ "survey_sign_oca/static/src/text.esm.js", + "survey_sign_oca/static/src/check.esm.js", ], "web.assets_frontend": [ "survey_sign_oca/static/src/text.esm.js", + "survey_sign_oca/static/src/check.esm.js", ], }, "installable": True, diff --git a/survey_sign_oca/data/sign_oca_role.xml b/survey_sign_oca/data/sign_oca_role.xml index 37474033..e76a44aa 100644 --- a/survey_sign_oca/data/sign_oca_role.xml +++ b/survey_sign_oca/data/sign_oca_role.xml @@ -1,10 +1,16 @@ - + Survey text survey + + Survey + check + survey + + Survey Participant expression diff --git a/survey_sign_oca/models/sign_oca_request.py b/survey_sign_oca/models/sign_oca_request.py index f93a6bb1..208f3423 100644 --- a/survey_sign_oca/models/sign_oca_request.py +++ b/survey_sign_oca/models/sign_oca_request.py @@ -3,6 +3,22 @@ from odoo import api, fields, models +class SurveyUtils: + @staticmethod + def is_yes_no_answer(value): + return str(value).strip().lower() in ["yes", "no"] + + @staticmethod + def answer_is_yes(value): + return str(value).strip().lower() == "yes" + + @staticmethod + def format_answer(answer): + if SurveyUtils.is_yes_no_answer(answer): + answer = SurveyUtils.answer_is_yes(answer) + return answer + + class SignOcaRequest(models.Model): _inherit = "sign.oca.request" @@ -37,10 +53,18 @@ def get_info(self, access_token=False): survey = {} for line in survey_participation.user_input_line_ids: if line.question_id.question_type == "matrix": + answer = line.suggested_answer_id.value survey.update( - {line.matrix_row_id.value: line.suggested_answer_id.value} + {line.matrix_row_id.value: SurveyUtils.format_answer(answer)} ) else: - survey.update({line.question_id.display_name: line.display_name}) + answer = line.display_name + survey.update( + { + line.question_id.display_name: SurveyUtils.format_answer( + answer + ) + } + ) vals["partner"].update({"survey": survey}) return vals diff --git a/survey_sign_oca/readme/CONFIGURE.md b/survey_sign_oca/readme/CONFIGURE.md index 9f68fb40..06d4ab8a 100644 --- a/survey_sign_oca/readme/CONFIGURE.md +++ b/survey_sign_oca/readme/CONFIGURE.md @@ -14,8 +14,14 @@ 2. Go to Sign \> Settings \> Fields and create a new one with the following data if not there: - - Field Type: text - - Default Value: survey + - Text Survey Field + + - Field Type: text + - Default Value: survey + + - Check Survey Field + - Field Type: check + - Default Value: survey 3. Go to Sign \> Templates and create a template with the following data: diff --git a/survey_sign_oca/readme/USAGE.md b/survey_sign_oca/readme/USAGE.md index 5df7921d..eb990c16 100644 --- a/survey_sign_oca/readme/USAGE.md +++ b/survey_sign_oca/readme/USAGE.md @@ -17,4 +17,6 @@ Automatic Sign Request creation process: For generated sign requests scoping survey, input values are populated automatically with the survey answered values. +Answers of yes/no type are shown in text fields as Yes/No and in check fields as checked/unchecked. + Signers can still update the input values if they want. diff --git a/survey_sign_oca/static/description/index.html b/survey_sign_oca/static/description/index.html index 36d65b70..13232c94 100644 --- a/survey_sign_oca/static/description/index.html +++ b/survey_sign_oca/static/description/index.html @@ -405,10 +405,18 @@

Configuration

  • Go to Sign > Settings > Fields and create a new one with the following data if not there:
      +
    • Text Survey Field
      • Field Type: text
      • Default Value: survey
    • +
    • Check Survey Field
        +
      • Field Type: check
      • +
      • Default Value: survey
      • +
      +
    • +
    +
  • Go to Sign > Templates and create a template with the following data:
    • Model: Survey User Input
    • In some of the elements you will have to set the previously created @@ -439,6 +447,8 @@

      Usage

      For generated sign requests scoping survey, input values are populated automatically with the survey answered values.

      +

      Answers of yes/no type are shown in text fields as Yes/No and in check +fields as checked/unchecked.

      Signers can still update the input values if they want.

      diff --git a/survey_sign_oca/static/src/check.esm.js b/survey_sign_oca/static/src/check.esm.js new file mode 100644 index 00000000..6babff3c --- /dev/null +++ b/survey_sign_oca/static/src/check.esm.js @@ -0,0 +1,96 @@ +/** @odoo-module **/ +/** Copyright 2025 Kencove - Mohamed Alkobrosli + License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). **/ + +import core from "web.core"; +import {registry} from "@web/core/registry"; + +function patchSignOca() { + const SignRegistry = registry.category("sign_oca"); + const textSignOca = registry.category("sign_oca").get("check"); + const patchedCheckSignOca = Object.assign({}, textSignOca); + + patchedCheckSignOca.generate = function (parent, item, signatureItem) { + const input = $( + core.qweb.render("sign_oca.sign_iframe_field_check", { + item: item, + role_id: parent.info.role_id, + }) + )[0]; + // Apply default values immediately after creating inputs for survey related requests specifically. + if (parent.info.partner.survey) { + if (item.default_value === "survey") { + const surveyValue = + parent.info.partner.survey?.[item.placeholder] || null; + if (surveyValue && surveyValue !== "Skipped") { + if (surveyValue === true) { + this.change( + parent.info.partner[item.default_value], + parent, + item, + signatureItem + ); + input.value = surveyValue; + input.checked = surveyValue; + } + } + } + } + signatureItem[0].addEventListener("focus_signature", () => { + input.focus(); + }); + // Update the value of the focused input to the default + input.addEventListener("focus", (ev) => { + if ( + item.default_value && + !item.value && + parent.info.partner[item.default_value] + ) { + this.change( + parent.info.partner[item.default_value], + parent, + item, + signatureItem + ); + ev.target.value = parent.info.partner[item.default_value]; + } + }); + input.addEventListener("change", (ev) => { + this.change(ev.srcElement.checked, parent, item, signatureItem); + }); + input.addEventListener("keydown", (ev) => { + if ((ev.keyCode || ev.which) !== 9) { + return true; + } + ev.preventDefault(); + var next_items = _.filter( + parent.info.items, + (i) => i.tabindex > item.tabindex && i.role_id === parent.info.role_id + ).sort((a, b) => a.tabindex - b.tabindex); + if (next_items.length > 0) { + ev.currentTarget.blur(); + const nextItem = next_items[0]; + if (nextItem && parent.items && parent.items[nextItem.id]) { + parent.items[nextItem.id].dispatchEvent( + new Event("focus_signature") + ); + } else { + console.warn("Missing next item or dispatch target", nextItem); + } + } + }); + return input; + }; + // Re-add the registry + SignRegistry.remove("check"); + SignRegistry.add("check", patchedCheckSignOca); +} + +const interval = setInterval(() => { + const signOca = registry.category("sign_oca"); + const content = signOca.content; + if (content && content.check) { + clearInterval(interval); + patchSignOca(); + } +}, 100); diff --git a/survey_sign_oca/static/src/text.esm.js b/survey_sign_oca/static/src/text.esm.js index 5b17a05f..920ffb92 100644 --- a/survey_sign_oca/static/src/text.esm.js +++ b/survey_sign_oca/static/src/text.esm.js @@ -21,7 +21,13 @@ function patchSignOca() { const surveyValue = parent.info.partner.survey?.[item.placeholder] || null; if (surveyValue && surveyValue !== "Skipped") { - val = surveyValue; + if (surveyValue === true) { + val = "Yes"; + } else if (surveyValue === false) { + val = "No"; + } else { + val = surveyValue; + } } } else { val = parent.info.partner[item.default_value]; From 2d44b6db629e270e8b793e52283f27c8928526eb Mon Sep 17 00:00:00 2001 From: kobros-tech Date: Sun, 6 Apr 2025 09:02:00 +0300 Subject: [PATCH 3/9] [IMP] survey_sign_oca: populate fields in backend --- survey_sign_oca/README.rst | 10 +- survey_sign_oca/__manifest__.py | 12 +- survey_sign_oca/data/sign_oca_role.xml | 10 +- survey_sign_oca/models/sign_oca_request.py | 44 ++++--- survey_sign_oca/readme/CONFIGURE.md | 6 + survey_sign_oca/readme/USAGE.md | 8 +- survey_sign_oca/static/description/index.html | 9 +- survey_sign_oca/static/src/check.esm.js | 96 --------------- survey_sign_oca/static/src/text.esm.js | 111 ------------------ 9 files changed, 67 insertions(+), 239 deletions(-) delete mode 100644 survey_sign_oca/static/src/check.esm.js delete mode 100644 survey_sign_oca/static/src/text.esm.js diff --git a/survey_sign_oca/README.rst b/survey_sign_oca/README.rst index cf0545b9..f3c43c22 100644 --- a/survey_sign_oca/README.rst +++ b/survey_sign_oca/README.rst @@ -65,6 +65,11 @@ Configuration - Field Type: check - Default Value: survey + - Signature Survey Field + + - Field Type: signature + - Default Value: survey + 3. Go to Sign > Templates and create a template with the following data: - Model: Survey User Input @@ -97,7 +102,7 @@ Automatic Sign Request creation process: :: - - When an partner takes a survey, a sign request will be created automatically. + - When a partner takes a survey, a sign request will be created automatically. For generated sign requests scoping survey, input values are populated automatically with the survey answered values. @@ -105,6 +110,9 @@ automatically with the survey answered values. Answers of yes/no type are shown in text fields as Yes/No and in check fields as checked/unchecked. +Answers of type binary can be trated as signature fields if the survey +question is the same as the signature placeholder in sign request. + Signers can still update the input values if they want. Bug Tracker diff --git a/survey_sign_oca/__manifest__.py b/survey_sign_oca/__manifest__.py index 4c8198e5..bf8517b9 100644 --- a/survey_sign_oca/__manifest__.py +++ b/survey_sign_oca/__manifest__.py @@ -7,23 +7,13 @@ "website": "https://github.com/OCA/sign", "author": "Kencove, Odoo Community Association (OCA)", "license": "AGPL-3", - "depends": ["sign_oca", "survey"], + "depends": ["sign_oca", "survey", "survey_question_type_binary"], "data": [ "views/survey_user_views.xml", "views/res_config_settings_view.xml", "views/sign_oca_request_views.xml", "data/sign_oca_role.xml", ], - "assets": { - "web.assets_backend": [ - "survey_sign_oca/static/src/text.esm.js", - "survey_sign_oca/static/src/check.esm.js", - ], - "web.assets_frontend": [ - "survey_sign_oca/static/src/text.esm.js", - "survey_sign_oca/static/src/check.esm.js", - ], - }, "installable": True, "maintainers": ["Kencove"], } diff --git a/survey_sign_oca/data/sign_oca_role.xml b/survey_sign_oca/data/sign_oca_role.xml index e76a44aa..6b1dd03b 100644 --- a/survey_sign_oca/data/sign_oca_role.xml +++ b/survey_sign_oca/data/sign_oca_role.xml @@ -1,16 +1,22 @@ - Survey + Survey Text text survey - Survey + Survey Check check survey + + Survey Signature + signature + survey + + Survey Participant expression diff --git a/survey_sign_oca/models/sign_oca_request.py b/survey_sign_oca/models/sign_oca_request.py index 208f3423..2f0e17ef 100644 --- a/survey_sign_oca/models/sign_oca_request.py +++ b/survey_sign_oca/models/sign_oca_request.py @@ -44,27 +44,41 @@ class SignOcaRequestSigner(models.Model): _inherit = "sign.oca.request.signer" - def get_info(self, access_token=False): - vals = super().get_info(access_token) - # send defaults for survey related sign requests + def get_related_survey_answers(self): + self.ensure_one() + # get survey answers for this sign request model_id = self.request_id.template_id.model_id survey_participation = self.request_id.record_ref + survey = {} if survey_participation and model_id and model_id.model == "survey.user_input": - survey = {} for line in survey_participation.user_input_line_ids: if line.question_id.question_type == "matrix": answer = line.suggested_answer_id.value - survey.update( - {line.matrix_row_id.value: SurveyUtils.format_answer(answer)} - ) + survey.update({line.matrix_row_id.value: answer}) + elif line.question_id.question_type == "binary": + answer = line.answer_binary_ids[:1].value_binary + survey.update({line.question_id.display_name: answer}) else: answer = line.display_name - survey.update( - { - line.question_id.display_name: SurveyUtils.format_answer( - answer - ) - } - ) - vals["partner"].update({"survey": survey}) + survey.update({line.question_id.display_name: answer}) + return survey + + def fill_survey_related_items(self, vals): + survey = self.get_related_survey_answers() + items = vals["items"] + for key in items: + item = items[key] + placeholder = item.get("placeholder") + if survey.get(placeholder) and item["role_id"] == self.role_id.id: + if survey.get(placeholder) and item["field_type"] == "text": + item["value"] = survey.get(placeholder) + elif survey.get(placeholder) and item["field_type"] == "check": + item["value"] = SurveyUtils.format_answer(survey.get(placeholder)) + elif survey.get(placeholder) and item["field_type"] == "signature": + item["value"] = survey.get(placeholder) + return vals + + def get_info(self, access_token=False): + vals = super().get_info(access_token) + vals = self.fill_survey_related_items(vals) return vals diff --git a/survey_sign_oca/readme/CONFIGURE.md b/survey_sign_oca/readme/CONFIGURE.md index 06d4ab8a..49faa479 100644 --- a/survey_sign_oca/readme/CONFIGURE.md +++ b/survey_sign_oca/readme/CONFIGURE.md @@ -20,9 +20,15 @@ - Default Value: survey - Check Survey Field + - Field Type: check - Default Value: survey + - Signature Survey Field + + - Field Type: signature + - Default Value: survey + 3. Go to Sign \> Templates and create a template with the following data: - Model: Survey User Input diff --git a/survey_sign_oca/readme/USAGE.md b/survey_sign_oca/readme/USAGE.md index eb990c16..321501c0 100644 --- a/survey_sign_oca/readme/USAGE.md +++ b/survey_sign_oca/readme/USAGE.md @@ -12,11 +12,15 @@ Manual Sign Request creation process: Automatic Sign Request creation process: - - When an partner takes a survey, a sign request will be created automatically. + - When a partner takes a survey, a sign request will be created automatically. For generated sign requests scoping survey, input values are populated automatically with the survey answered values. -Answers of yes/no type are shown in text fields as Yes/No and in check fields as checked/unchecked. +Answers of yes/no type are shown in text fields as Yes/No and in check fields as +checked/unchecked. + +Answers of type binary can be trated as signature fields if the survey question is the +same as the signature placeholder in sign request. Signers can still update the input values if they want. diff --git a/survey_sign_oca/static/description/index.html b/survey_sign_oca/static/description/index.html index 13232c94..940e3afe 100644 --- a/survey_sign_oca/static/description/index.html +++ b/survey_sign_oca/static/description/index.html @@ -415,6 +415,11 @@

      Configuration

    • Default Value: survey
  • +
  • Signature Survey Field
      +
    • Field Type: signature
    • +
    • Default Value: survey
    • +
    +
  • Go to Sign > Templates and create a template with the following data:
      @@ -443,12 +448,14 @@

      Usage

      Automatic Sign Request creation process:

      -- When an partner takes a survey, a sign request will be created automatically.
      +- When a partner takes a survey, a sign request will be created automatically.
       

      For generated sign requests scoping survey, input values are populated automatically with the survey answered values.

      Answers of yes/no type are shown in text fields as Yes/No and in check fields as checked/unchecked.

      +

      Answers of type binary can be trated as signature fields if the survey +question is the same as the signature placeholder in sign request.

      Signers can still update the input values if they want.

      diff --git a/survey_sign_oca/static/src/check.esm.js b/survey_sign_oca/static/src/check.esm.js deleted file mode 100644 index 6babff3c..00000000 --- a/survey_sign_oca/static/src/check.esm.js +++ /dev/null @@ -1,96 +0,0 @@ -/** @odoo-module **/ -/** Copyright 2025 Kencove - Mohamed Alkobrosli - License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). **/ - -import core from "web.core"; -import {registry} from "@web/core/registry"; - -function patchSignOca() { - const SignRegistry = registry.category("sign_oca"); - const textSignOca = registry.category("sign_oca").get("check"); - const patchedCheckSignOca = Object.assign({}, textSignOca); - - patchedCheckSignOca.generate = function (parent, item, signatureItem) { - const input = $( - core.qweb.render("sign_oca.sign_iframe_field_check", { - item: item, - role_id: parent.info.role_id, - }) - )[0]; - // Apply default values immediately after creating inputs for survey related requests specifically. - if (parent.info.partner.survey) { - if (item.default_value === "survey") { - const surveyValue = - parent.info.partner.survey?.[item.placeholder] || null; - if (surveyValue && surveyValue !== "Skipped") { - if (surveyValue === true) { - this.change( - parent.info.partner[item.default_value], - parent, - item, - signatureItem - ); - input.value = surveyValue; - input.checked = surveyValue; - } - } - } - } - signatureItem[0].addEventListener("focus_signature", () => { - input.focus(); - }); - // Update the value of the focused input to the default - input.addEventListener("focus", (ev) => { - if ( - item.default_value && - !item.value && - parent.info.partner[item.default_value] - ) { - this.change( - parent.info.partner[item.default_value], - parent, - item, - signatureItem - ); - ev.target.value = parent.info.partner[item.default_value]; - } - }); - input.addEventListener("change", (ev) => { - this.change(ev.srcElement.checked, parent, item, signatureItem); - }); - input.addEventListener("keydown", (ev) => { - if ((ev.keyCode || ev.which) !== 9) { - return true; - } - ev.preventDefault(); - var next_items = _.filter( - parent.info.items, - (i) => i.tabindex > item.tabindex && i.role_id === parent.info.role_id - ).sort((a, b) => a.tabindex - b.tabindex); - if (next_items.length > 0) { - ev.currentTarget.blur(); - const nextItem = next_items[0]; - if (nextItem && parent.items && parent.items[nextItem.id]) { - parent.items[nextItem.id].dispatchEvent( - new Event("focus_signature") - ); - } else { - console.warn("Missing next item or dispatch target", nextItem); - } - } - }); - return input; - }; - // Re-add the registry - SignRegistry.remove("check"); - SignRegistry.add("check", patchedCheckSignOca); -} - -const interval = setInterval(() => { - const signOca = registry.category("sign_oca"); - const content = signOca.content; - if (content && content.check) { - clearInterval(interval); - patchSignOca(); - } -}, 100); diff --git a/survey_sign_oca/static/src/text.esm.js b/survey_sign_oca/static/src/text.esm.js deleted file mode 100644 index 920ffb92..00000000 --- a/survey_sign_oca/static/src/text.esm.js +++ /dev/null @@ -1,111 +0,0 @@ -/** @odoo-module **/ -/** Copyright 2025 Kencove - Mohamed Alkobrosli - License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). **/ - -import core from "web.core"; -import {registry} from "@web/core/registry"; - -function patchSignOca() { - const SignRegistry = registry.category("sign_oca"); - const textSignOca = registry.category("sign_oca").get("text"); - const patchedTextSignOca = Object.assign({}, textSignOca); - - function applyDefaultValue({input, parent, item, signatureItem, changeFn}) { - if ( - item.default_value && - !item.value && - parent.info.partner[item.default_value] - ) { - let val = null; - if (item.default_value === "survey") { - const surveyValue = - parent.info.partner.survey?.[item.placeholder] || null; - if (surveyValue && surveyValue !== "Skipped") { - if (surveyValue === true) { - val = "Yes"; - } else if (surveyValue === false) { - val = "No"; - } else { - val = surveyValue; - } - } - } else { - val = parent.info.partner[item.default_value]; - } - if (val) { - changeFn(val, parent, item, signatureItem); - input.value = val; - } - } - } - - patchedTextSignOca.generate = function (parent, item, signatureItem) { - const input = $( - core.qweb.render("sign_oca.sign_iframe_field_text", { - item, - role_id: parent.info.role_id, - }) - )[0]; - // Apply default values immediately after creating inputs for survey related requests specifically. - if (parent.info.partner.survey) { - applyDefaultValue({ - input, - parent, - item, - signatureItem, - changeFn: this.change.bind(this), - }); - } - signatureItem[0].addEventListener("focus_signature", () => { - input.focus(); - }); - // Update the value of the focused input to the default - input.addEventListener("focus", (ev) => { - applyDefaultValue({ - input: ev.target, - parent, - item, - signatureItem, - changeFn: this.change.bind(this), - }); - }); - - input.addEventListener("change", (ev) => { - this.change(ev.target.value, parent, item, signatureItem); - }); - input.addEventListener("keydown", (ev) => { - if ((ev.keyCode || ev.which) !== 9) { - return true; - } - ev.preventDefault(); - const next_items = _.filter( - parent.info.items, - (i) => i.tabindex > item.tabindex && i.role_id === parent.info.role_id - ).sort((a, b) => a.tabindex - b.tabindex); - if (next_items.length > 0) { - ev.currentTarget.blur(); - const nextItem = next_items[0]; - if (nextItem && parent.items && parent.items[nextItem.id]) { - parent.items[nextItem.id].dispatchEvent( - new Event("focus_signature") - ); - } else { - console.warn("Missing next item or dispatch target", nextItem); - } - } - }); - return input; - }; - // Re-add the registry - SignRegistry.remove("text"); - SignRegistry.add("text", patchedTextSignOca); -} - -const interval = setInterval(() => { - const signOca = registry.category("sign_oca"); - const content = signOca.content; - if (content && content.text) { - clearInterval(interval); - patchSignOca(); - } -}, 100); From a34e1d365b80a441af0d4689aeeffe96aaf00a89 Mon Sep 17 00:00:00 2001 From: kobros-tech Date: Tue, 8 Apr 2025 06:15:20 +0300 Subject: [PATCH 4/9] [IMP] survey_sign_oca: depend on new survey signature type --- survey_sign_oca/models/sign_oca_request.py | 2 +- test-requirements.txt | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/survey_sign_oca/models/sign_oca_request.py b/survey_sign_oca/models/sign_oca_request.py index 2f0e17ef..613983c2 100644 --- a/survey_sign_oca/models/sign_oca_request.py +++ b/survey_sign_oca/models/sign_oca_request.py @@ -55,7 +55,7 @@ def get_related_survey_answers(self): if line.question_id.question_type == "matrix": answer = line.suggested_answer_id.value survey.update({line.matrix_row_id.value: answer}) - elif line.question_id.question_type == "binary": + elif line.question_id.question_type in ["binary", "signature"]: answer = line.answer_binary_ids[:1].value_binary survey.update({line.question_id.display_name: answer}) else: diff --git a/test-requirements.txt b/test-requirements.txt index e192291b..ff7a0095 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1 +1,2 @@ odoo-addon-sign_oca @ git+https://github.com/OCA/sign.git@refs/pull/91/head#subdirectory=setup/sign_oca +odoo-addon-survey_question_type_binary @ git+https://github.com/OCA/survey.git@refs/pull/157/head#subdirectory=setup/survey_question_type_binary From af9ea9f3b48b1cf048b17e3a1f8074a4778fb8c0 Mon Sep 17 00:00:00 2001 From: kobros-tech Date: Fri, 11 Apr 2025 17:09:56 +0300 Subject: [PATCH 5/9] [IMP] survey_sign_oca: make start button text editable --- survey_sign_oca/__manifest__.py | 2 ++ survey_sign_oca/models/__init__.py | 1 + survey_sign_oca/models/survey_survey.py | 9 +++++++++ survey_sign_oca/views/survey_survey_views.xml | 14 ++++++++++++++ survey_sign_oca/views/survey_templates.xml | 16 ++++++++++++++++ 5 files changed, 42 insertions(+) create mode 100644 survey_sign_oca/models/survey_survey.py create mode 100644 survey_sign_oca/views/survey_survey_views.xml create mode 100644 survey_sign_oca/views/survey_templates.xml diff --git a/survey_sign_oca/__manifest__.py b/survey_sign_oca/__manifest__.py index bf8517b9..c6a0bf47 100644 --- a/survey_sign_oca/__manifest__.py +++ b/survey_sign_oca/__manifest__.py @@ -12,6 +12,8 @@ "views/survey_user_views.xml", "views/res_config_settings_view.xml", "views/sign_oca_request_views.xml", + "views/survey_survey_views.xml", + "views/survey_templates.xml", "data/sign_oca_role.xml", ], "installable": True, diff --git a/survey_sign_oca/models/__init__.py b/survey_sign_oca/models/__init__.py index 1d665615..f50ada5e 100644 --- a/survey_sign_oca/models/__init__.py +++ b/survey_sign_oca/models/__init__.py @@ -2,3 +2,4 @@ from . import res_company from . import res_config_settings from . import sign_oca_request +from . import survey_survey diff --git a/survey_sign_oca/models/survey_survey.py b/survey_sign_oca/models/survey_survey.py new file mode 100644 index 00000000..bf1ff165 --- /dev/null +++ b/survey_sign_oca/models/survey_survey.py @@ -0,0 +1,9 @@ +# Copyright 2025 Kencove - Mohamed Alkobrosli +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import fields, models + + +class Survey(models.Model): + _inherit = "survey.survey" + + start_button_name = fields.Char("Survey Start Button Name", default="Start") diff --git a/survey_sign_oca/views/survey_survey_views.xml b/survey_sign_oca/views/survey_survey_views.xml new file mode 100644 index 00000000..2fdc0f47 --- /dev/null +++ b/survey_sign_oca/views/survey_survey_views.xml @@ -0,0 +1,14 @@ + + + + survey.survey.view.form + survey.survey + + + + + + diff --git a/survey_sign_oca/views/survey_templates.xml b/survey_sign_oca/views/survey_templates.xml new file mode 100644 index 00000000..ba8d0022 --- /dev/null +++ b/survey_sign_oca/views/survey_templates.xml @@ -0,0 +1,16 @@ + + + + From 5484dcd4a6a97b595cc521f5b628daf70ac738f1 Mon Sep 17 00:00:00 2001 From: kobros-tech Date: Thu, 17 Apr 2025 16:07:07 +0300 Subject: [PATCH 6/9] [IMP] survey_sign_oca: review changes --- survey_sign_oca/README.rst | 3 +++ survey_sign_oca/__manifest__.py | 2 +- survey_sign_oca/models/sign_oca_request.py | 9 ++++++++- survey_sign_oca/models/survey_invite.py | 4 ++-- survey_sign_oca/readme/USAGE.md | 3 +++ survey_sign_oca/static/description/index.html | 2 ++ survey_sign_oca/views/survey_survey_views.xml | 3 +-- 7 files changed, 20 insertions(+), 6 deletions(-) diff --git a/survey_sign_oca/README.rst b/survey_sign_oca/README.rst index f3c43c22..45e140df 100644 --- a/survey_sign_oca/README.rst +++ b/survey_sign_oca/README.rst @@ -113,6 +113,9 @@ fields as checked/unchecked. Answers of type binary can be trated as signature fields if the survey question is the same as the signature placeholder in sign request. +In that case make sure to have this module: +``survey_question_type_binary`` from OCA installed. + Signers can still update the input values if they want. Bug Tracker diff --git a/survey_sign_oca/__manifest__.py b/survey_sign_oca/__manifest__.py index c6a0bf47..a613ad21 100644 --- a/survey_sign_oca/__manifest__.py +++ b/survey_sign_oca/__manifest__.py @@ -7,7 +7,7 @@ "website": "https://github.com/OCA/sign", "author": "Kencove, Odoo Community Association (OCA)", "license": "AGPL-3", - "depends": ["sign_oca", "survey", "survey_question_type_binary"], + "depends": ["sign_oca", "survey"], "data": [ "views/survey_user_views.xml", "views/res_config_settings_view.xml", diff --git a/survey_sign_oca/models/sign_oca_request.py b/survey_sign_oca/models/sign_oca_request.py index 613983c2..880570b5 100644 --- a/survey_sign_oca/models/sign_oca_request.py +++ b/survey_sign_oca/models/sign_oca_request.py @@ -3,6 +3,8 @@ from odoo import api, fields, models +# This class is to format questions of type (yes, no) +# in case we need the answer as (True, False) in case of filling checkboxes class SurveyUtils: @staticmethod def is_yes_no_answer(value): @@ -22,7 +24,7 @@ def format_answer(answer): class SignOcaRequest(models.Model): _inherit = "sign.oca.request" - # This field is required for the inverse of maintenance.equipment. + # This field is required for the inverse of survey.user.input. survey_user_input_id = fields.Many2one( comodel_name="survey.user_input", compute="_compute_survey_user_input_id", @@ -52,6 +54,8 @@ def get_related_survey_answers(self): survey = {} if survey_participation and model_id and model_id.model == "survey.user_input": for line in survey_participation.user_input_line_ids: + # Questions of type matrix have questions and suggested answers like a matrix + # We map the answeres to the questions for each matrix type if line.question_id.question_type == "matrix": answer = line.suggested_answer_id.value survey.update({line.matrix_row_id.value: answer}) @@ -69,6 +73,9 @@ def fill_survey_related_items(self, vals): for key in items: item = items[key] placeholder = item.get("placeholder") + # According to placeholder we target the answer of a question + # having same text as the placeholder + # and we choose the answer format based on the item field_typ if survey.get(placeholder) and item["role_id"] == self.role_id.id: if survey.get(placeholder) and item["field_type"] == "text": item["value"] = survey.get(placeholder) diff --git a/survey_sign_oca/models/survey_invite.py b/survey_sign_oca/models/survey_invite.py index 2972534e..febb82eb 100644 --- a/survey_sign_oca/models/survey_invite.py +++ b/survey_sign_oca/models/survey_invite.py @@ -42,8 +42,8 @@ def action_view_sign_requests(self): ctx = dict(self.env.context) ctx.update( { - "default_maintenance_equipment_id": self.id, - "search_default_maintenance_equipment_id": self.id, + "default_survey_user_input_id": self.id, + "search_default_survey_user_input_id": self.id, } ) result["context"] = ctx diff --git a/survey_sign_oca/readme/USAGE.md b/survey_sign_oca/readme/USAGE.md index 321501c0..a1b85d64 100644 --- a/survey_sign_oca/readme/USAGE.md +++ b/survey_sign_oca/readme/USAGE.md @@ -23,4 +23,7 @@ checked/unchecked. Answers of type binary can be trated as signature fields if the survey question is the same as the signature placeholder in sign request. +In that case make sure to have this module: `survey_question_type_binary` from OCA +installed. + Signers can still update the input values if they want. diff --git a/survey_sign_oca/static/description/index.html b/survey_sign_oca/static/description/index.html index 940e3afe..6379a783 100644 --- a/survey_sign_oca/static/description/index.html +++ b/survey_sign_oca/static/description/index.html @@ -456,6 +456,8 @@

      Usage

      fields as checked/unchecked.

      Answers of type binary can be trated as signature fields if the survey question is the same as the signature placeholder in sign request.

      +

      In that case make sure to have this module: +survey_question_type_binary from OCA installed.

      Signers can still update the input values if they want.

      diff --git a/survey_sign_oca/views/survey_survey_views.xml b/survey_sign_oca/views/survey_survey_views.xml index 2fdc0f47..a78a21ba 100644 --- a/survey_sign_oca/views/survey_survey_views.xml +++ b/survey_sign_oca/views/survey_survey_views.xml @@ -5,8 +5,7 @@ survey.survey - -