diff --git a/ssi_partner/menu.xml b/ssi_partner/menu.xml index 35d087b..9c6a70e 100644 --- a/ssi_partner/menu.xml +++ b/ssi_partner/menu.xml @@ -9,11 +9,12 @@ sequence="4" web_icon="contacts,static/description/icon.png" /> + Partner + + Partner - Workflow + + + + + Partner - Data Ownership + + + + + + Partner - Configurator + + + + + Partner - Wizard + + + + + Partner - Report + + + Partner - Configurator diff --git a/ssi_partner_evaluation/README.rst b/ssi_partner_evaluation/README.rst new file mode 100644 index 0000000..61547c1 --- /dev/null +++ b/ssi_partner_evaluation/README.rst @@ -0,0 +1,46 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +================== +Partner Evaluation +================== + + +Installation +============ + +To install this module, you need to: + +1. Clone the branch 14.0 of the repository https://github.com/open-synergy/ssi-partner +2. Add the path to this repository in your configuration (addons-path) +3. Update the module list (Must be on developer mode) +4. Go to menu *Apps -> Apps -> Main Apps* +5. Search For *Partner Evaluation* +6. Install the module + +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 smash it by providing detailed and welcomed feedback. + + +Credits +======= + +Contributors +------------ + +* Andhitia Rama + +Maintainer +---------- + +.. image:: https://simetri-sinergi.id/logo.png + :alt: PT. Simetri Sinergi Indonesia + :target: https://simetri-sinergi.id.com + +This module is maintained by the PT. Simetri Sinergi Indonesia. diff --git a/ssi_partner_evaluation/__init__.py b/ssi_partner_evaluation/__init__.py new file mode 100644 index 0000000..f173d58 --- /dev/null +++ b/ssi_partner_evaluation/__init__.py @@ -0,0 +1,7 @@ +# Copyright 2024 OpenSynergy Indonesia +# Copyright 2024 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import ( + models, +) diff --git a/ssi_partner_evaluation/__manifest__.py b/ssi_partner_evaluation/__manifest__.py new file mode 100644 index 0000000..932f6ce --- /dev/null +++ b/ssi_partner_evaluation/__manifest__.py @@ -0,0 +1,46 @@ +# Copyright 2024 OpenSynergy Indonesia +# Copyright 2024 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Partner Evaluation", + "version": "14.0.1.0.0", + "website": "https://simetri-sinergi.id", + "author": "PT. Simetri Sinergi Indonesia, OpenSynergy Indonesia", + "license": "AGPL-3", + "installable": True, + "depends": [ + "ssi_partner", + "ssi_master_data_mixin", + "ssi_transaction_confirm_mixin", + "ssi_transaction_done_mixin", + "ssi_transaction_cancel_mixin", + "ssi_transaction_open_mixin", + "ssi_transaction_date_duration_mixin", + "ssi_m2o_configurator_mixin", + "ssi_localdict_mixin", + "ssi_transaction_partner_mixin", + ], + "data": [ + "security/ir_module_category_data.xml", + "security/res_groups_data.xml", + "security/res_groups/partner_evaluation.xml", + "security/ir.model.access.csv", + "security/ir_model_access/partner_evaluation.xml", + "security/ir_rule/partner_evaluation.xml", + "data/ir_sequence/partner_evaluation.xml", + "data/sequence_template/partner_evaluation.xml", + "data/policy_template/partner_evaluation.xml", + "data/approval_template/partner_evaluation.xml", + "menu.xml", + "views/partner_evaluation_type_views.xml", + "views/partner_evaluation_result_views.xml", + "views/partner_evaluation_value_item_views.xml", + "views/partner_evaluation_value_set_views.xml", + "views/partner_evaluation_question_type_views.xml", + "views/partner_evaluation_views.xml", + "views/res_partner_views.xml", + ], + "demo": [], + "images": [], +} diff --git a/ssi_partner_evaluation/data/approval_template/partner_evaluation.xml b/ssi_partner_evaluation/data/approval_template/partner_evaluation.xml new file mode 100644 index 0000000..ed2841e --- /dev/null +++ b/ssi_partner_evaluation/data/approval_template/partner_evaluation.xml @@ -0,0 +1,27 @@ + + + + + + Standard + + + use_python + result = True + + + + + use_group + + + + diff --git a/ssi_partner_evaluation/data/ir_sequence/partner_evaluation.xml b/ssi_partner_evaluation/data/ir_sequence/partner_evaluation.xml new file mode 100644 index 0000000..7408863 --- /dev/null +++ b/ssi_partner_evaluation/data/ir_sequence/partner_evaluation.xml @@ -0,0 +1,18 @@ + + + + + + Partner Evaluation + partner_evaluation + EV/%(range_year)s/ + + + + + + + + diff --git a/ssi_partner_evaluation/data/policy_template/partner_evaluation.xml b/ssi_partner_evaluation/data/policy_template/partner_evaluation.xml new file mode 100644 index 0000000..e987b57 --- /dev/null +++ b/ssi_partner_evaluation/data/policy_template/partner_evaluation.xml @@ -0,0 +1,206 @@ + + + + + + Standard + + + + result=True + + + + + + + + + + use_group + + + + + + + + + + + + use_group + + + + + + + + + + + + + result = False +if env.user.id in document.active_approver_user_ids.ids: + result = True + + + + + + + + + + + + result = False +if env.user.id in document.active_approver_user_ids.ids: + result = True + + + + + + + + + + + use_group + + + result = False +if not document.approval_template_id: + result = True + + + + + + + + + + + use_group + + + + + + + + + + + + use_group + + + + + + + + + + + + use_group + + + + + diff --git a/ssi_partner_evaluation/data/sequence_template/partner_evaluation.xml b/ssi_partner_evaluation/data/sequence_template/partner_evaluation.xml new file mode 100644 index 0000000..4ca8c1e --- /dev/null +++ b/ssi_partner_evaluation/data/sequence_template/partner_evaluation.xml @@ -0,0 +1,28 @@ + + + + + + Standard + + + / + + + use_python + result=True + + use_sequence + + + + + diff --git a/ssi_partner_evaluation/menu.xml b/ssi_partner_evaluation/menu.xml new file mode 100644 index 0000000..045217d --- /dev/null +++ b/ssi_partner_evaluation/menu.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + diff --git a/ssi_partner_evaluation/models/__init__.py b/ssi_partner_evaluation/models/__init__.py new file mode 100644 index 0000000..34a4736 --- /dev/null +++ b/ssi_partner_evaluation/models/__init__.py @@ -0,0 +1,17 @@ +# Copyright 2024 OpenSynergy Indonesia +# Copyright 2024 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import ( + partner_evaluation_type, + partner_evaluation_type_question, + partner_evaluation_result, + partner_evaluation_value_item, + partner_evaluation_value_set, + partner_evaluation_value_set_item, + partner_evaluation_question_type, + partner_evaluation, + partner_evaluation_question, + res_partner_evaluation_result, + res_partner, +) diff --git a/ssi_partner_evaluation/models/partner_evaluation.py b/ssi_partner_evaluation/models/partner_evaluation.py new file mode 100644 index 0000000..6660109 --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation.py @@ -0,0 +1,198 @@ +# Copyright 2024 OpenSynergy Indonesia +# Copyright 2024 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models +from odoo.tools.safe_eval import safe_eval + +from odoo.addons.ssi_decorator import ssi_decorator + + +class PartnerEvaluation(models.Model): + _name = "partner_evaluation" + _description = "Partner Evaluation" + _inherit = [ + "mixin.transaction_cancel", + "mixin.transaction_done", + "mixin.transaction_confirm", + "mixin.transaction_open", + "mixin.transaction_date_duration", + "mixin.many2one_configurator", + "mixin.transaction_partner", + "mixin.localdict", + ] + _order = "date desc, id" + + # Multiple Approval Attribute + _approval_from_state = "open" + _approval_to_state = "done" + _approval_state = "confirm" + _after_approved_method = "action_done" + + # Attributes related to add element on view automatically + _automatically_insert_view_element = True + _automatically_insert_multiple_approval_page = True + _automatically_insert_done_policy_fields = False + _automatically_insert_done_button = False + + _method_to_run_from_wizard = "action_cancel" + + _statusbar_visible_label = "draft,open,confirm,done" + _policy_field_order = [ + "open_ok", + "confirm_ok", + "approve_ok", + "reject_ok", + "restart_approval_ok", + "cancel_ok", + "restart_ok", + "done_ok", + "manual_number_ok", + ] + + _header_button_order = [ + "action_open", + "action_confirm", + "action_approve_approval", + "action_reject_approval", + "%(ssi_transaction_cancel_mixin.base_select_cancel_reason_action)d", + "action_restart", + ] + + # Attributes related to add element on search view automatically + _state_filter_order = [ + "dom_draft", + "dom_open", + "dom_confirm", + "dom_reject", + "dom_done", + "dom_cancel", + ] + + # Sequence attribute + _create_sequence_state = "open" + + type_id = fields.Many2one( + comodel_name="partner_evaluation_type", + string="Type", + required=True, + ondelete="restrict", + readonly=True, + states={"draft": [("readonly", False)]}, + ) + date = fields.Date( + string="Date", + required=True, + ondelete="restrict", + readonly=True, + states={"draft": [("readonly", False)]}, + ) + question_ids = fields.One2many( + comodel_name="partner_evaluation.question", + inverse_name="evaluation_id", + string="Questions", + readonly=True, + states={"open": [("readonly", False)]}, + ) + automatic_result_id = fields.Many2one( + string="Automatic Result", + comodel_name="partner_evaluation_result", + compute="_compute_automatic_result_id", + store=True, + compute_sudo=True, + ) + manual_result_id = fields.Many2one( + string="Manual Result", + comodel_name="partner_evaluation_result", + readonly=True, + states={"open": [("readonly", False)]}, + ) + final_result_id = fields.Many2one( + string="Final Result", + comodel_name="partner_evaluation_result", + compute="_compute_final_result_id", + store=True, + compute_sudo=True, + ) + dissenting_opinion = fields.Text( + string="Dissenting Opinion", + readonly=True, + states={"open": [("readonly", False)]}, + ) + + @api.depends( + "question_ids", + "question_ids.qualitative_value_id", + "question_ids.quantitative_value", + ) + def _compute_automatic_result_id(self): + for record in self: + result = False + localdict = record._get_default_localdict() + try: + safe_eval( + self.type_id.result_computation_code, + localdict, + mode="exec", + nocopy=True, + ) + result = localdict["result"] + except Exception: + result = False + + record.automatic_result_id = result + + @api.depends( + "automatic_result_id", + "manual_result_id", + ) + def _compute_final_result_id(self): + for record in self: + result = record.automatic_result_id + if record.manual_result_id: + result = record.manual_result_id + record.final_result_id = result + + @ssi_decorator.post_open_action() + def _01_create_questions(self): + self.ensure_one() + for question in self.type_id.question_ids: + question._create_evaluation_question(self) + + @ssi_decorator.post_done_action() + def _01_create_partner_evaluation_result(self): + self.ensure_one() + if not self.partner_id._get_partner_evaluation_result(self.type_id): + data = { + "partner_id": self.partner_id.id, + "type_id": self.type_id.id, + } + self.env["res.partner.evaluation_result"].create(data) + + @ssi_decorator.post_cancel_action() + def _01_delete_question(self): + self.ensure_one() + self.question_ids.unlink() + + @api.model + def _get_policy_field(self): + res = super(PartnerEvaluation, self)._get_policy_field() + policy_field = [ + "open_ok", + "confirm_ok", + "approve_ok", + "cancel_ok", + "done_ok", + "reject_ok", + "restart_ok", + "restart_approval_ok", + "manual_number_ok", + ] + res += policy_field + return res + + @ssi_decorator.insert_on_form_view() + def _insert_form_element(self, view_arch): + if self._automatically_insert_view_element: + view_arch = self._reconfigure_statusbar_visible(view_arch) + return view_arch diff --git a/ssi_partner_evaluation/models/partner_evaluation_item.py b/ssi_partner_evaluation/models/partner_evaluation_item.py new file mode 100644 index 0000000..6e6be2e --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_item.py @@ -0,0 +1,13 @@ +# Copyright 2024 OpenSynergy Indonesia +# Copyright 2024 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class PartnerEvaluationItem(models.Model): + _name = "partner_evaluation_result" + _description = "Partner Evaluation Result" + _inherit = [ + "mixin.master_data", + ] diff --git a/ssi_partner_evaluation/models/partner_evaluation_question.py b/ssi_partner_evaluation/models/partner_evaluation_question.py new file mode 100644 index 0000000..d48ca3e --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_question.py @@ -0,0 +1,155 @@ +# Copyright 2022 OpenSynergy Indonesia +# Copyright 2022 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models +from odoo.tools.safe_eval import safe_eval + + +class PartnerEvaluationQuestion(models.Model): + _name = "partner_evaluation.question" + _description = "Partner Evaluation - Question" + _inherit = [ + "mixin.localdict", + ] + _order = "evaluation_id, sequence" + + evaluation_id = fields.Many2one( + string="# Evaluation", + comodel_name="partner_evaluation", + required=True, + ondelete="cascade", + ) + sequence = fields.Integer( + string="Sequence", + required=True, + default=5, + readonly=True, + ) + question_type_id = fields.Many2one( + string="Question Type", + comodel_name="partner_evaluation_question_type", + required=True, + ) + type = fields.Selection( + related="question_type_id.type", + store=False, + ) + mode = fields.Selection( + related="question_type_id.mode", + store=False, + ) + manual_qualitative_value_id = fields.Many2one( + string="Manual Qualitative Value", + comodel_name="partner_evaluation_value_item", + ) + automatic_qualitative_value_id = fields.Many2one( + string="Automatic Qualitative Value", + comodel_name="partner_evaluation_value_item", + compute="_compute_automatic_value", + store=True, + compute_sudo=True, + ) + qualitative_value_id = fields.Many2one( + string="Qualitative Value", + comodel_name="partner_evaluation_value_item", + compute="_compute_qualitative_value_id", + store=True, + compute_sudo=True, + ) + manual_quantitative_value = fields.Float( + string="Manual Quantitative Value", + ) + automatic_quantitative_value = fields.Float( + string="Automatic Quantitative Value", + compute="_compute_automatic_value", + store=True, + compute_sudo=True, + ) + quantitative_value = fields.Float( + string="Quantitative Value", + compute="_compute_quantitative_value", + store=True, + compute_sudo=True, + ) + value = fields.Char( + string="Value", + compute="_compute_value", + store=False, + ) + + @api.depends( + "manual_qualitative_value_id", + "automatic_qualitative_value_id", + "mode", + ) + def _compute_qualitative_value_id(self): + for record in self: + result = False + if record.mode == "manual": + result = record.manual_qualitative_value_id + else: + result = record.automatic_qualitative_value_id + record.qualitative_value_id = result + + @api.depends( + "manual_quantitative_value", + "automatic_quantitative_value", + "mode", + ) + def _compute_quantitative_value(self): + for record in self: + result = 0.0 + if record.mode == "manual": + result = record.manual_quantitative_value + else: + result = record.automatic_quantitative_value + record.quantitative_value = result + + @api.depends( + "question_type_id", + "type", + "mode", + ) + def _compute_automatic_value(self): + for record in self: + result = False + + if record.mode != "auto": + record.automatic_qualitative_value_id = result + record.automatic_quantitative_value = result + + localdict = record._get_default_localdict() + try: + safe_eval( + self.question_type_id.computation_code, + localdict, + mode="exec", + nocopy=True, + ) + result = localdict["result"] + except Exception: + result = False + + if record.type == "qualitative": + record.automatic_qualitative_value_id = result + else: + record.automatic_quantitative_value = result + + @api.depends( + "type", + "qualitative_value_id", + "quantitative_value", + ) + def _compute_value(self): + for record in self: + result = "" + if record.type == "quantitative": + result = record.quantitative_value + else: + result = ( + record.qualitative_value_id + and record.qualitative_value_id.display_name + or "" + ) + record.value = result diff --git a/ssi_partner_evaluation/models/partner_evaluation_question_type.py b/ssi_partner_evaluation/models/partner_evaluation_question_type.py new file mode 100644 index 0000000..cfeba41 --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_question_type.py @@ -0,0 +1,40 @@ +# Copyright 2022 OpenSynergy Indonesia +# Copyright 2022 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class PartnerEvaluationQuestionType(models.Model): + _name = "partner_evaluation_question_type" + _description = "Partner Evaluation - Question" + _inherit = [ + "mixin.master_data", + ] + + type = fields.Selection( + string="Type", + selection=[ + ("qualitative", "Qualitative"), + ("quantitative", "Quantitative"), + ], + required=True, + default="qualitative", + ) + set_id = fields.Many2one( + string="Value Set", + comodel_name="partner_evaluation_value_set", + readonly=False, + ) + mode = fields.Selection( + string="Mode", + selection=[ + ("manual", "Manual"), + ("auto", "Automatic"), + ], + required=True, + default="manual", + ) + computation_code = fields.Text( + string="Computation Code", + ) diff --git a/ssi_partner_evaluation/models/partner_evaluation_result.py b/ssi_partner_evaluation/models/partner_evaluation_result.py new file mode 100644 index 0000000..fcc4dfe --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_result.py @@ -0,0 +1,13 @@ +# Copyright 2024 OpenSynergy Indonesia +# Copyright 2024 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class PartnerEvaluationResult(models.Model): + _name = "partner_evaluation_result" + _description = "Partner Evaluation Result" + _inherit = [ + "mixin.master_data", + ] diff --git a/ssi_partner_evaluation/models/partner_evaluation_type.py b/ssi_partner_evaluation/models/partner_evaluation_type.py new file mode 100644 index 0000000..fd9cba0 --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_type.py @@ -0,0 +1,30 @@ +# Copyright 2024 OpenSynergy Indonesia +# Copyright 2024 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class PartnerEvaluationType(models.Model): + _name = "partner_evaluation_type" + _description = "Partner Evaluation Type" + _inherit = [ + "mixin.master_data", + ] + + result_ids = fields.Many2many( + string="Allowed Results", + comodel_name="partner_evaluation_result", + relation="rel_partner_evaluation_type_2_result", + column1="type_id", + column2="result_id", + ) + result_computation_code = fields.Text( + string="Result Computation Code", + required=True, + ) + question_ids = fields.One2many( + comodel_name="partner_evaluation_type.question", + inverse_name="type_id", + string="Questions", + ) diff --git a/ssi_partner_evaluation/models/partner_evaluation_type_question.py b/ssi_partner_evaluation/models/partner_evaluation_type_question.py new file mode 100644 index 0000000..7264d16 --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_type_question.py @@ -0,0 +1,39 @@ +# Copyright 2022 OpenSynergy Indonesia +# Copyright 2022 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class PartnerEvaluationTypeQuestion(models.Model): + _name = "partner_evaluation_type.question" + _description = "Partner Evaluation Type - Question" + _order = "type_id, sequence" + + type_id = fields.Many2one( + string="Partner Evaluation Type", + comodel_name="partner_evaluation_type", + required=True, + ondelete="cascade", + ) + sequence = fields.Integer( + string="Sequence", + required=True, + default=5, + readonly=True, + ) + question_type_id = fields.Many2one( + string="Question Type", + comodel_name="partner_evaluation_question_type", + required=True, + ) + + def _create_evaluation_question(self, evaluation): + self.ensure_one() + self.env["partner_evaluation.question"].create( + { + "evaluation_id": evaluation.id, + "sequence": self.sequence, + "question_type_id": self.question_type_id.id, + } + ) diff --git a/ssi_partner_evaluation/models/partner_evaluation_value_item.py b/ssi_partner_evaluation/models/partner_evaluation_value_item.py new file mode 100644 index 0000000..9bdbe87 --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_value_item.py @@ -0,0 +1,11 @@ +# Copyright 2022 OpenSynergy Indonesia +# Copyright 2022 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import models + + +class PartnerEvaluationValueItem(models.Model): + _name = "partner_evaluation_value_item" + _inherit = ["mixin.master_data"] + _description = "Partner Evaluation Value Item" diff --git a/ssi_partner_evaluation/models/partner_evaluation_value_set.py b/ssi_partner_evaluation/models/partner_evaluation_value_set.py new file mode 100644 index 0000000..ad78b6a --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_value_set.py @@ -0,0 +1,17 @@ +# Copyright 2022 OpenSynergy Indonesia +# Copyright 2022 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class PartnerEvaluationValueSet(models.Model): + _name = "partner_evaluation_value_set" + _inherit = ["mixin.master_data"] + _description = "Partner Evaluation Value Set" + + value_ids = fields.One2many( + string="Values", + comodel_name="partner_evaluation_value_set.item", + inverse_name="set_id", + ) diff --git a/ssi_partner_evaluation/models/partner_evaluation_value_set_item.py b/ssi_partner_evaluation/models/partner_evaluation_value_set_item.py new file mode 100644 index 0000000..dff0bf7 --- /dev/null +++ b/ssi_partner_evaluation/models/partner_evaluation_value_set_item.py @@ -0,0 +1,28 @@ +# Copyright 2022 OpenSynergy Indonesia +# Copyright 2022 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class PartnerEvaluationValueSetItem(models.Model): + _name = "partner_evaluation_value_set.item" + _description = "Partner Evaluation Value Set - Item" + + set_id = fields.Many2one( + string="Value Set", + comodel_name="partner_evaluation_value_set", + required=True, + ondelete="cascade", + ) + sequence = fields.Integer( + string="Sequence", + required=True, + default=5, + ) + item_id = fields.Many2one( + string="Item", + comodel_name="partner_evaluation_value_item", + required=True, + ondelete="restrict", + ) diff --git a/ssi_partner_evaluation/models/res_partner.py b/ssi_partner_evaluation/models/res_partner.py new file mode 100644 index 0000000..e30213e --- /dev/null +++ b/ssi_partner_evaluation/models/res_partner.py @@ -0,0 +1,35 @@ +# Copyright 2023 OpenSynergy Indonesia +# Copyright 2023 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResPartner(models.Model): + _name = "res.partner" + _inherit = "res.partner" + + partner_evaluation_result_ids = fields.One2many( + string="Partner Evaluation Results", + comodel_name="res.partner.evaluation_result", + inverse_name="partner_id", + readonly=True, + ) + + partner_evaluation_ids = fields.One2many( + string="Partner Evaluations", + comodel_name="partner_evaluation", + inverse_name="partner_id", + readonly=True, + ) + + def _get_partner_evaluation_result(self, evaluation_type): + self.ensure_one() + result = False + evaluations = self.partner_evaluation_result_ids.filtered( + lambda r: r.type_id.id == evaluation_type.id + ) + if evaluations: + result = evaluations[0] + + return result diff --git a/ssi_partner_evaluation/models/res_partner_evaluation_result.py b/ssi_partner_evaluation/models/res_partner_evaluation_result.py new file mode 100644 index 0000000..912d811 --- /dev/null +++ b/ssi_partner_evaluation/models/res_partner_evaluation_result.py @@ -0,0 +1,56 @@ +# Copyright 2023 OpenSynergy Indonesia +# Copyright 2023 PT. Simetri Sinergi Indonesia +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class ResPartnerEvaluationResult(models.Model): + _name = "res.partner.evaluation_result" + _description = "res.partner - Evaluation Result" + + partner_id = fields.Many2one( + string="Partner", + comodel_name="res.partner", + ondelete="cascade", + required=True, + ) + type_id = fields.Many2one( + string="Evaluation Type", + comodel_name="partner_evaluation_type", + ondelete="restrict", + required=True, + ) + latest_evaluation_id = fields.Many2one( + string="Latest Evaluation", + comodel_name="partner_evaluation", + compute="_compute_latest_evaluation_id", + store=True, + compute_sudo=True, + ) + result_id = fields.Many2one( + string="Result", + related="latest_evaluation_id.final_result_id", + store=True, + ) + date = fields.Date( + related="latest_evaluation_id.date", + store=True, + ) + + @api.depends( + "partner_id", + "partner_id.partner_evaluation_ids", + "partner_id.partner_evaluation_ids.type_id", + "partner_id.partner_evaluation_ids.state", + "partner_id.partner_evaluation_ids.final_result_id", + ) + def _compute_latest_evaluation_id(self): + for record in self: + result = False + evaluations = record.partner_id.partner_evaluation_ids.filtered( + lambda r: r.state == "done" and r.type_id.id == record.type_id.id + ) + if evaluations: + result = evaluations[0] + record.latest_evaluation_id = result diff --git a/ssi_partner_evaluation/security/ir.model.access.csv b/ssi_partner_evaluation/security/ir.model.access.csv new file mode 100644 index 0000000..b3be69d --- /dev/null +++ b/ssi_partner_evaluation/security/ir.model.access.csv @@ -0,0 +1,16 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_partner_evaluation_type_configurator,partner_evaluation_type - configurator,model_partner_evaluation_type,partner_evaluation_type_group,1,1,1,1 +access_partner_evaluation_type_all,partner_evaluation_type - all,model_partner_evaluation_type,,1,0,0,0 +access_partner_evaluation_type_question_configurator,partner_evaluation_type_question - configurator,model_partner_evaluation_type_question,partner_evaluation_type_group,1,1,1,1 +access_partner_evaluation_type_question_all,partner_evaluation_type_question - all,model_partner_evaluation_type_question,,1,0,0,0 +access_partner_evaluation_result_configurator,partner_evaluation_result - configurator,model_partner_evaluation_result,partner_evaluation_result_group,1,1,1,1 +access_partner_evaluation_result_all,partner_evaluation_result - all,model_partner_evaluation_result,,1,0,0,0 +access_partner_evaluation_value_item_configurator,partner_evaluation_value_item - configurator,model_partner_evaluation_value_item,partner_evaluation_value_item_group,1,1,1,1 +access_partner_evaluation_value_item_all,partner_evaluation_value_item - all,model_partner_evaluation_value_item,,1,0,0,0 +access_partner_evaluation_value_set_configurator,partner_evaluation_value_set - configurator,model_partner_evaluation_value_set,partner_evaluation_value_set_group,1,1,1,1 +access_partner_evaluation_value_set_all,partner_evaluation_value_set - all,model_partner_evaluation_value_set,,1,0,0,0 +access_partner_evaluation_value_set_item_configurator,partner_evaluation_value_set_item - configurator,model_partner_evaluation_value_set_item,partner_evaluation_value_set_group,1,1,1,1 +access_partner_evaluation_value_set_item_all,partner_evaluation_value_set_item - all,model_partner_evaluation_value_set_item,,1,0,0,0 +access_partner_evaluation_question_type_configurator,partner_evaluation_question_type - configurator,model_partner_evaluation_question_type,partner_evaluation_question_type_group,1,1,1,1 +access_partner_evaluation_question_type_all,partner_evaluation_question_type - all,model_partner_evaluation_question_type,,1,0,0,0 +access_res_partner_evaluation_result_all,res.partner.evaluation_result - all,model_res_partner_evaluation_result,,1,1,1,1 diff --git a/ssi_partner_evaluation/security/ir_model_access/partner_evaluation.xml b/ssi_partner_evaluation/security/ir_model_access/partner_evaluation.xml new file mode 100644 index 0000000..b1acaba --- /dev/null +++ b/ssi_partner_evaluation/security/ir_model_access/partner_evaluation.xml @@ -0,0 +1,41 @@ + + + + + partner_evaluation - all + + + + + + + + partner_evaluation - user + + + + + + + + + + partner_evaluation.question - all + + + + + + + + partner_evaluation.question - user + + + + + + + + diff --git a/ssi_partner_evaluation/security/ir_module_category_data.xml b/ssi_partner_evaluation/security/ir_module_category_data.xml new file mode 100644 index 0000000..a109b0b --- /dev/null +++ b/ssi_partner_evaluation/security/ir_module_category_data.xml @@ -0,0 +1,21 @@ + + + + + + Partner Evaluation + + + + + Partner Evaluation + + + + + diff --git a/ssi_partner_evaluation/security/ir_rule/partner_evaluation.xml b/ssi_partner_evaluation/security/ir_rule/partner_evaluation.xml new file mode 100644 index 0000000..0f55a8c --- /dev/null +++ b/ssi_partner_evaluation/security/ir_rule/partner_evaluation.xml @@ -0,0 +1,51 @@ + + + + + Partner Evaluation - Internal Users + + + [('user_id','=',user.id)] + + + + + + + + Partner Evaluation - Responsible to company data + + + [('company_id','=',user.company_id.id)] + + + + + + + + Partner Evaluation - Responsible to company and all child companies data + + + [('company_id','in',user.company_ids.ids)] + + + + + + + + Partner Evaluation - Responsible to all data + + + [(1,'=',1)] + + + + + + diff --git a/ssi_partner_evaluation/security/res_groups/partner_evaluation.xml b/ssi_partner_evaluation/security/res_groups/partner_evaluation.xml new file mode 100644 index 0000000..bf83935 --- /dev/null +++ b/ssi_partner_evaluation/security/res_groups/partner_evaluation.xml @@ -0,0 +1,50 @@ + + + + + Viewer + + + + + User + + + + + + Validator + + + + + + + Company + + + + + Company and All Child Companies + + + + + + All + + + + + diff --git a/ssi_partner_evaluation/security/res_groups_data.xml b/ssi_partner_evaluation/security/res_groups_data.xml new file mode 100644 index 0000000..ec4f6f6 --- /dev/null +++ b/ssi_partner_evaluation/security/res_groups_data.xml @@ -0,0 +1,50 @@ + + + + + Partner Evaluation Type + + + + + + Partner Evaluation Question Type + + + + + + Partner Evaluation Result + + + + + + Partner Evaluation Value Item + + + + + + Partner Evaluation Value Set + + + + diff --git a/ssi_partner_evaluation/static/description/icon.png b/ssi_partner_evaluation/static/description/icon.png new file mode 100644 index 0000000..4c8e112 Binary files /dev/null and b/ssi_partner_evaluation/static/description/icon.png differ diff --git a/ssi_partner_evaluation/views/partner_evaluation_question_type_views.xml b/ssi_partner_evaluation/views/partner_evaluation_question_type_views.xml new file mode 100644 index 0000000..5f49ccf --- /dev/null +++ b/ssi_partner_evaluation/views/partner_evaluation_question_type_views.xml @@ -0,0 +1,70 @@ + + + + + + + partner_evaluation_question_type - Tree + partner_evaluation_question_type + primary + + + + + + + + partner_evaluation_question_type - Search + partner_evaluation_question_type + primary + + + + + + + + partner_evaluation_question_type - Form + partner_evaluation_question_type + primary + + + + + + + + + + + + + + + + + + + Partner Evaluation Question Types + partner_evaluation_question_type + tree,form + + + + diff --git a/ssi_partner_evaluation/views/partner_evaluation_result_views.xml b/ssi_partner_evaluation/views/partner_evaluation_result_views.xml new file mode 100644 index 0000000..98c20e9 --- /dev/null +++ b/ssi_partner_evaluation/views/partner_evaluation_result_views.xml @@ -0,0 +1,54 @@ + + + + + + + partner_evaluation_result - Tree + partner_evaluation_result + primary + + + + + + + + partner_evaluation_result - Search + partner_evaluation_result + primary + + + + + + + + partner_evaluation_result - Form + partner_evaluation_result + primary + + + + + + + + + Partner Evaluation Results + partner_evaluation_result + tree,form + + + + diff --git a/ssi_partner_evaluation/views/partner_evaluation_type_views.xml b/ssi_partner_evaluation/views/partner_evaluation_type_views.xml new file mode 100644 index 0000000..7a1dfb4 --- /dev/null +++ b/ssi_partner_evaluation/views/partner_evaluation_type_views.xml @@ -0,0 +1,70 @@ + + + + + + + partner_evaluation_type - Tree + partner_evaluation_type + primary + + + + + + + + partner_evaluation_type - Search + partner_evaluation_type + primary + + + + + + + + partner_evaluation_type - Form + partner_evaluation_type + primary + + + + + + + + + + + + + + + + + + + + + + + + + Partner Evaluation Types + partner_evaluation_type + tree,form + + + + diff --git a/ssi_partner_evaluation/views/partner_evaluation_value_item_views.xml b/ssi_partner_evaluation/views/partner_evaluation_value_item_views.xml new file mode 100644 index 0000000..065c825 --- /dev/null +++ b/ssi_partner_evaluation/views/partner_evaluation_value_item_views.xml @@ -0,0 +1,54 @@ + + + + + + + partner_evaluation_value_item - Tree + partner_evaluation_value_item + primary + + + + + + + + partner_evaluation_value_item - Search + partner_evaluation_value_item + primary + + + + + + + + partner_evaluation_value_item - Form + partner_evaluation_value_item + primary + + + + + + + + + Partner Evaluation Value Items + partner_evaluation_value_item + tree,form + + + + diff --git a/ssi_partner_evaluation/views/partner_evaluation_value_set_views.xml b/ssi_partner_evaluation/views/partner_evaluation_value_set_views.xml new file mode 100644 index 0000000..6484429 --- /dev/null +++ b/ssi_partner_evaluation/views/partner_evaluation_value_set_views.xml @@ -0,0 +1,64 @@ + + + + + + + partner_evaluation_value_set - Tree + partner_evaluation_value_set + primary + + + + + + + + partner_evaluation_value_set - Search + partner_evaluation_value_set + primary + + + + + + + + partner_evaluation_value_set - Form + partner_evaluation_value_set + primary + + + + + + + + + + + + + + + + + + + Partner Evaluation Value Sets + partner_evaluation_value_set + tree,form + + + + diff --git a/ssi_partner_evaluation/views/partner_evaluation_views.xml b/ssi_partner_evaluation/views/partner_evaluation_views.xml new file mode 100644 index 0000000..f6a0a5d --- /dev/null +++ b/ssi_partner_evaluation/views/partner_evaluation_views.xml @@ -0,0 +1,118 @@ + + + + + + + partner_evaluation - Tree + partner_evaluation + + primary + + + + + + + + + + + + + + + + partner_evaluation - Search + partner_evaluation + + + + + + + + partner_evaluation - Form + partner_evaluation + + primary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Partner Evaluations + partner_evaluation + tree,form + + + + diff --git a/ssi_partner_evaluation/views/res_partner_views.xml b/ssi_partner_evaluation/views/res_partner_views.xml new file mode 100644 index 0000000..e3757de --- /dev/null +++ b/ssi_partner_evaluation/views/res_partner_views.xml @@ -0,0 +1,30 @@ + + + + res.partner.education.level.form + res.partner + + + + + + + + + + + + + + + + + + + + + diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000..923f172 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1,8 @@ +odoo14-addon-ssi-localdict-mixin +odoo14-addon-ssi-m2o-configurator-mixin +odoo14-addon-ssi-transaction-cancel-mixin +odoo14-addon-ssi-transaction-confirm-mixin +odoo14-addon-ssi-transaction-open-mixin +odoo14-addon-ssi-transaction-date-duration-mixin +odoo14-addon-ssi-transaction-done-mixin +odoo14-addon-ssi-transaction-partner-mixin