commit f7b6572dedd1ee04eb2d9c967c7cd08682b5616e Author: Suherdy Yacob Date: Mon Apr 20 16:44:36 2026 +0700 first commit diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..a0fdc10 --- /dev/null +++ b/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/__manifest__.py b/__manifest__.py new file mode 100644 index 0000000..699f83c --- /dev/null +++ b/__manifest__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. +{ + 'name': 'DISC Personality Test Survey', + 'version': '1.0', + 'category': 'Human Resources', + 'summary': 'DISC Personality Assessment Test in Survey module', + 'description': """ + This module adds a DISC Personality Test to the Odoo Survey module. + It includes 24 sets of questions where participants choose the 'Most' (Paling) + and 'Least' (Kurang) descriptive traits. + """, + 'depends': ['survey'], + 'data': [ + 'data/survey_data.xml', + 'views/survey_user_input_views.xml', + 'views/survey_templates.xml', + 'report/survey_disc_report.xml', + ], + 'installable': True, + 'application': True, + 'license': 'LGPL-3', +} diff --git a/__pycache__/__init__.cpython-312.pyc b/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..38910c9 Binary files /dev/null and b/__pycache__/__init__.cpython-312.pyc differ diff --git a/data/survey_data.xml b/data/survey_data.xml new file mode 100644 index 0000000..ada15d6 --- /dev/null +++ b/data/survey_data.xml @@ -0,0 +1,1092 @@ + + + + + DISC Personality Test + no_scoring + one_page + + + + + Set 1 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Gampangan, Mudah setuju + S + S + 1 + + + + Percaya, Mudah percaya pada orang + I + I + 2 + + + + Petualang, Mengambil resiko + D + D + 3 + + + + Toleran, Menghormati + C + C + 4 + + + + Set 2 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Lembut suara, Pendiam + C + C + 1 + + + + Optimistik, Visioner + I + I + 2 + + + + Pusat Perhatian, Suka gaul + * + * + 3 + + + + Pendamai, Membawa Harmoni + S + S + 4 + + + + Set 3 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Menyemangati orang + I + I + 1 + + + + Berusaha sempurna + C + C + 2 + + + + Bagian dari kelompok + S + S + 3 + + + + Ingin membuat tujuan + D + D + 4 + + + + Set 4 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Menjadi frustrasi + S + S + 1 + + + + Menyimpan perasaan saya + C + C + 2 + + + + Menceritakan sisi saya + I + I + 3 + + + + Siap beroposisi + D + D + 4 + + + + Set 5 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Hidup, Suka bicara + I + I + 1 + + + + Gerak cepat, Tekun + D + D + 2 + + + + Usaha menjaga keseimbangan + S + S + 3 + + + + Usaha mengikuti aturan + C + C + 4 + + + + Set 6 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Kelola waktu secara efisien + D + D + 1 + + + + Sering terburu-buru, Merasa tertekan + I + I + 2 + + + + Masalah sosial itu penting + S + S + 3 + + + + Suka selesaikan apa yang saya mulai + C + C + 4 + + + + Set 7 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Tolak perubahan mendadak + S + S + 1 + + + + Cenderung janji berlebihan + I + I + 2 + + + + Tarik diri di tengah tekanan + * + * + 3 + + + + Tidak takut bertempur + D + D + 4 + + + + Set 8 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Penyemangat yang baik + I + I + 1 + + + + Pendengar yang baik + S + S + 2 + + + + Penganalisa yang baik + C + C + 3 + + + + Delegator yang baik + D + D + 4 + + + + Set 9 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Hasil adalah penting + D + D + 1 + + + + Lakukan dengan benar, Akurasi penting + C + C + 2 + + + + Dibuat menyenangkan + I + I + 3 + + + + Mari kerjakan bersama + S + S + 4 + + + + Set 10 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Akan berjalan terus tanpa kontrol diri + D + D + 1 + + + + Akan membeli sesuai dorongan hati + * + * + 2 + + + + Akan menunggu, Tanpa tekanan + S + S + 3 + + + + Akan mengusahakan yang kuinginkan + I + I + 4 + + + + Set 11 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Ramah, Mudah bergabung + S + S + 1 + + + + Unik, Bosan rutinitas + C + C + 2 + + + + Aktif mengubah sesuatu + D + D + 3 + + + + Ingin hal-hal yang pasti + I + I + 4 + + + + Set 12 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Non-konfrontasi, Menyerah + S + S + 1 + + + + Dipenuhi hal detail + C + C + 2 + + + + Perubahan pada menit terakhir + I + I + 3 + + + + Menuntut, Kasar + D + D + 4 + + + + Set 13 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Ingin kemajuan + D + D + 1 + + + + Puas dengan segalanya + S + S + 2 + + + + Terbuka memperlihatkan perasaan + I + I + 3 + + + + Rendah hati, Sederhana + C + C + 4 + + + + Set 14 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Tenang, Pendiam + I + I + 1 + + + + Bahagia, Tanpa beban + C + C + 2 + + + + Menyenangkan, Baik hati + S + S + 3 + + + + Tak gentar, Berani + D + D + 4 + + + + Set 15 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Menggunakan waktu berkualitas dgn teman + I + I + 1 + + + + Rencanakan masa depan, Bersiap + C + C + 2 + + + + Bepergian demi petualangan baru + S + S + 3 + + + + Menerima ganjaran atas tujuan yg dicapai + D + D + 4 + + + + Set 16 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Aturan perlu dipertanyakan + D + D + 1 + + + + Aturan membuat adil + I + I + 2 + + + + Aturan membuat bosan + S + S + 3 + + + + Aturan membuat aman + C + C + 4 + + + + Set 17 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Pendidikan, Kebudayaan + * + * + 1 + + + + Prestasi, Ganjaran + I + I + 2 + + + + Keselamatan, keamanan + D + D + 3 + + + + Sosial, Perkumpulan kelompok + S + S + 4 + + + + Set 18 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Memimpin, Pendekatan langsung + D + D + 1 + + + + Suka bergaul, Antusias + I + I + 2 + + + + Dapat diramal, Konsisten + S + S + 3 + + + + Waspada, Hati-hati + C + C + 4 + + + + Set 19 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Tidak mudah dikalahkan + D + D + 1 + + + + Kerjakan sesuai perintah, Ikut pimpinan + C + C + 2 + + + + Mudah terangsang, Riang + I + I + 3 + + + + Ingin segalanya teratur, Rapi + S + S + 4 + + + + Set 20 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Saya akan pimpin mereka + D + D + 1 + + + + Saya akan melaksanakan + S + S + 2 + + + + Saya akan meyakinkan mereka + I + I + 3 + + + + Saya dapatkan fakta + C + C + 4 + + + + Set 21 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Memikirkan orang dahulu + S + S + 1 + + + + Kompetitif, Suka tantangan + D + D + 2 + + + + Optimis, Positif + I + I + 3 + + + + Pemikir logis, Sistematik + C + C + 4 + + + + Set 22 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Menyenangkan orang, Mudah setuju + I + I + 1 + + + + Tertawa lepas, Hidup + S + S + 2 + + + + Berani, Tak gentar + D + D + 3 + + + + Tenang, Pendiam + C + C + 4 + + + + Set 23 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Ingin otoritas lebih + D + D + 1 + + + + Ingin kesempatan baru + I + I + 2 + + + + Menghindari konflik + S + S + 3 + + + + Ingin petunjuk yang jelas + C + C + 4 + + + + Set 24 + + matrix + simple + + + P + 1 + + + + K + 2 + + + + + Dapat diandalkan, Dapata dipercaya + S + S + 1 + + + + Kreatif, Unik + C + C + 2 + + + + Garis dasar, Orientasi hasil + D + D + 3 + + + + Jalankan standar yang tinggi, Akurat + I + I + 4 + + + + \ No newline at end of file diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000..011c120 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- +from . import survey_question_answer +from . import survey_user_input diff --git a/models/__pycache__/__init__.cpython-312.pyc b/models/__pycache__/__init__.cpython-312.pyc new file mode 100644 index 0000000..612c1d6 Binary files /dev/null and b/models/__pycache__/__init__.cpython-312.pyc differ diff --git a/models/__pycache__/survey_question_answer.cpython-312.pyc b/models/__pycache__/survey_question_answer.cpython-312.pyc new file mode 100644 index 0000000..e236fbe Binary files /dev/null and b/models/__pycache__/survey_question_answer.cpython-312.pyc differ diff --git a/models/__pycache__/survey_user_input.cpython-312.pyc b/models/__pycache__/survey_user_input.cpython-312.pyc new file mode 100644 index 0000000..abb0c43 Binary files /dev/null and b/models/__pycache__/survey_user_input.cpython-312.pyc differ diff --git a/models/survey_question_answer.py b/models/survey_question_answer.py new file mode 100644 index 0000000..5ab6ac5 --- /dev/null +++ b/models/survey_question_answer.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields + +class SurveyQuestionAnswer(models.Model): + _inherit = 'survey.question.answer' + + disc_category_p = fields.Selection([ + ('D', 'Dominance'), + ('I', 'Influence'), + ('S', 'Steadiness'), + ('C', 'Conscientiousness'), + ('*', 'Star (No Score)'), + ], string='DISC Category (Most/P)') + + disc_category_k = fields.Selection([ + ('D', 'Dominance'), + ('I', 'Influence'), + ('S', 'Steadiness'), + ('C', 'Conscientiousness'), + ('*', 'Star (No Score)'), + ], string='DISC Category (Least/K)') diff --git a/models/survey_user_input.py b/models/survey_user_input.py new file mode 100644 index 0000000..2bac398 --- /dev/null +++ b/models/survey_user_input.py @@ -0,0 +1,122 @@ +from odoo import models, fields, api, _ +from odoo.exceptions import ValidationError + +class SurveyUserInput(models.Model): + _inherit = 'survey.user_input' + + # MOST (Graph 1) + p_d = fields.Integer('P: D', compute='_compute_disc_scores', store=True) + p_i = fields.Integer('P: I', compute='_compute_disc_scores', store=True) + p_s = fields.Integer('P: S', compute='_compute_disc_scores', store=True) + p_c = fields.Integer('P: C', compute='_compute_disc_scores', store=True) + p_star = fields.Integer('P: *', compute='_compute_disc_scores', store=True) + + # LEAST (Graph 2) + k_d = fields.Integer('K: D', compute='_compute_disc_scores', store=True) + k_i = fields.Integer('K: I', compute='_compute_disc_scores', store=True) + k_s = fields.Integer('K: S', compute='_compute_disc_scores', store=True) + k_c = fields.Integer('K: C', compute='_compute_disc_scores', store=True) + k_star = fields.Integer('K: *', compute='_compute_disc_scores', store=True) + + # CHANGE (Graph 3) + c_d = fields.Integer('C: D', compute='_compute_disc_scores', store=True) + c_i = fields.Integer('C: I', compute='_compute_disc_scores', store=True) + c_s = fields.Integer('C: S', compute='_compute_disc_scores', store=True) + c_c = fields.Integer('C: C', compute='_compute_disc_scores', store=True) + + disc_profile = fields.Char('DISC Profile', compute='_compute_disc_scores', store=True) + + def _mark_done(self): + """ Strictly enforce DISC validation: Exactly 1 P and 1 K per set. """ + for rec in self: + # Group lines by question + lines_by_question = {} + for line in rec.user_input_line_ids: + if not line.matrix_row_id or not line.suggested_answer_id: + continue + q_id = line.question_id + if q_id not in lines_by_question: + lines_by_question[q_id] = [] + lines_by_question[q_id].append(line) + + # We expect 24 sets + if len(lines_by_question) < 24: + raise ValidationError(_("You must answer all 24 sets of the assessment.")) + + for q_id, lines in lines_by_question.items(): + p_count = len([l for l in lines if l.suggested_answer_id.value == 'P']) + k_count = len([l for l in lines if l.suggested_answer_id.value == 'K']) + + if p_count != 1 or k_count != 1: + raise ValidationError( + _("Invalid selection in '%s'. You must select exactly one 'P' (Most) and one 'K' (Least).") % q_id.title + ) + return super(SurveyUserInput, self)._mark_done() + + @api.depends('user_input_line_ids', 'user_input_line_ids.suggested_answer_id') + def _compute_disc_scores(self): + for rec in self: + # Initialize counts + counts = { + 'p': {'D': 0, 'I': 0, 'S': 0, 'C': 0, '*': 0}, + 'k': {'D': 0, 'I': 0, 'S': 0, 'C': 0, '*': 0} + } + + # Group lines by question to check for multiple selections per set + lines_by_question = {} + for line in rec.user_input_line_ids: + if not line.matrix_row_id or not line.suggested_answer_id: + continue + q_id = line.question_id.id + if q_id not in lines_by_question: + lines_by_question[q_id] = [] + lines_by_question[q_id].append(line) + + # Process each question set + for q_id, lines in lines_by_question.items(): + p_selections = [l for l in lines if l.suggested_answer_id.value == 'P'] + k_selections = [l for l in lines if l.suggested_answer_id.value == 'K'] + + # Validation: We only count if exactly one P and one K are selected per set + # This enforces the "1 P and 1 K per set" rule + if len(p_selections) == 1: + line = p_selections[0] + cat = line.matrix_row_id.disc_category_p + if cat in counts['p']: + counts['p'][cat] += 1 + + if len(k_selections) == 1: + line = k_selections[0] + cat = line.matrix_row_id.disc_category_k + if cat in counts['k']: + counts['k'][cat] += 1 + + # Update fields + rec.p_d = counts['p']['D'] + rec.p_i = counts['p']['I'] + rec.p_s = counts['p']['S'] + rec.p_c = counts['p']['C'] + rec.p_star = counts['p']['*'] + + rec.k_d = counts['k']['D'] + rec.k_i = counts['k']['I'] + rec.k_s = counts['k']['S'] + rec.k_c = counts['k']['C'] + rec.k_star = counts['k']['*'] + + # Graph 3: Change (P - K) + rec.c_d = rec.p_d - rec.k_d + rec.c_i = rec.p_i - rec.k_i + rec.c_s = rec.p_s - rec.k_s + rec.c_c = rec.p_c - rec.k_c + + # Determine Profile (based on highest score in Graph 3) + scores = {'D': rec.c_d, 'I': rec.c_i, 'S': rec.c_s, 'C': rec.c_c} + top_trait = max(scores, key=scores.get) + profile_map = { + 'D': 'Director (Dominance)', + 'I': 'Influencer (Influence)', + 'S': 'Steady (Steadiness)', + 'C': 'Compliant (Compliance)' + } + rec.disc_profile = profile_map.get(top_trait, 'Mixed') diff --git a/report/survey_disc_report.xml b/report/survey_disc_report.xml new file mode 100644 index 0000000..f976792 --- /dev/null +++ b/report/survey_disc_report.xml @@ -0,0 +1,89 @@ + + + + DISC Assessment Result + survey.user_input + qweb-pdf + survey_disc_test.report_disc_result + survey_disc_test.report_disc_result + 'DISC_Result_%s' % (object.partner_id.name or 'User') + + report + + + + diff --git a/views/survey_templates.xml b/views/survey_templates.xml new file mode 100644 index 0000000..680183d --- /dev/null +++ b/views/survey_templates.xml @@ -0,0 +1,23 @@ + + + + diff --git a/views/survey_user_input_views.xml b/views/survey_user_input_views.xml new file mode 100644 index 0000000..d7858b3 --- /dev/null +++ b/views/survey_user_input_views.xml @@ -0,0 +1,45 @@ + + + + survey.user.input.view.form.inherit.disc + survey.user_input + + + + + + + +
+
+ + + + + + + +
+
+ + + + + + + +
+
+ + + + + + +
+
+
+
+
+
+