159 lines
7.4 KiB
Python
159 lines
7.4 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import base64
|
|
import qrcode
|
|
from io import BytesIO
|
|
from odoo import models, fields, api
|
|
from odoo.addons.survey.models import survey_survey as survey
|
|
|
|
|
|
class InheritSurvey(survey.Survey):
|
|
_inherit = 'survey.survey'
|
|
|
|
|
|
config_ids = fields.One2many("tx.survey.config", "survey_id", string="配置项")
|
|
qrcode_img = fields.Image(string="问卷二维码")
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
surveys = super().create(vals_list)
|
|
for survey in surveys:
|
|
url = f"{self.get_base_url()}/survey/start/{survey.access_token}"
|
|
data = BytesIO()
|
|
qrcode.make(url.encode(), box_size=2).save(data, optimise=True, format='PNG')
|
|
survey.qrcode_img = base64.b64encode(data.getvalue()).decode()
|
|
|
|
return surveys
|
|
|
|
# 生成二维码
|
|
def create_qrcode(self):
|
|
redirect_uri = f"{self.get_base_url()}/survey/start/{self.access_token}"
|
|
url = f"https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx925514211e6b37d9&redirect_uri={redirect_uri}&response_type=code&scope=snsapi_base&state=1#wechat_redirect"
|
|
# url = f"https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx925514211e6b37d9&redirect_uri={redirect_uri}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
|
|
data = BytesIO()
|
|
qrcode.make(url.encode(), box_size=2).save(data, optimise=True, format='PNG')
|
|
self.qrcode_img = base64.b64encode(data.getvalue()).decode()
|
|
|
|
@api.model
|
|
def _get_pages_or_questions(self, user_input):
|
|
""" Returns the pages or questions (depending on the layout) that will be shown
|
|
to the user taking the survey.
|
|
In 'page_per_question' layout, we also want to show pages that have a description. """
|
|
|
|
result = self.env['survey.question']
|
|
if self.questions_layout == 'page_per_section':
|
|
result = self.page_ids
|
|
elif self.questions_layout == 'page_per_question':
|
|
if self.questions_selection == 'random' and not self.session_state:
|
|
result = user_input.predefined_question_ids
|
|
elif user_input.survey_id.config_ids.__len__():
|
|
result = self._get_config_pages_and_questions_to_show(user_input)
|
|
else:
|
|
result = self._get_pages_and_questions_to_show()
|
|
|
|
return result
|
|
|
|
def _get_config_pages_and_questions_to_show(self, user_input):
|
|
config_ids = self.config_ids
|
|
config_question = []
|
|
for config_id in config_ids:
|
|
if config_id.question_id.id not in config_question:
|
|
config_question.append(config_id.question_id.id)
|
|
|
|
if user_input.user_input_line_ids.__len__() == 0:
|
|
return self.question_ids.filtered(lambda x: x.config_ids.__len__() == 0)
|
|
|
|
no_config_questions = self.question_ids.filtered(lambda x: x.config_ids.__len__() == 0)
|
|
targetIds = no_config_questions.ids
|
|
|
|
user_input_line_ids = user_input.user_input_line_ids.filtered(lambda x: x.question_id.id in config_question)
|
|
for line_id in user_input_line_ids:
|
|
question_id = line_id.question_id
|
|
answer_id = line_id.suggested_answer_id
|
|
config_id = config_ids.filtered(lambda x: x.question_id.id == question_id.id and x.answer_id.id == answer_id.id)
|
|
targetIds += config_id.show_question_ids.ids
|
|
|
|
questions_ids = self.env['survey.question'].sudo().search([("id", "in", targetIds)])
|
|
return questions_ids
|
|
|
|
def _get_next_page_or_question(self, user_input, page_or_question_id, go_back=False):
|
|
survey = user_input.survey_id
|
|
pages_or_questions = survey._get_pages_or_questions(user_input)
|
|
Question = self.env['survey.question']
|
|
|
|
# Get Next
|
|
if not go_back:
|
|
if not pages_or_questions:
|
|
return Question
|
|
# First page
|
|
if page_or_question_id == 0:
|
|
return pages_or_questions[0]
|
|
|
|
current_page_index = pages_or_questions.ids.index(page_or_question_id)
|
|
|
|
# Get previous and we are on first page OR Get Next and we are on last page
|
|
if (go_back and current_page_index == 0) or (not go_back and current_page_index == len(pages_or_questions) - 1):
|
|
return Question
|
|
|
|
# Conditional Questions Management
|
|
triggering_answer_by_question, triggered_questions_by_answer, selected_answers = user_input._get_conditional_values()
|
|
inactive_questions = user_input._get_inactive_conditional_questions()
|
|
if survey.questions_layout == 'page_per_question':
|
|
question_candidates = pages_or_questions[0:current_page_index] if go_back \
|
|
else pages_or_questions[current_page_index + 1:]
|
|
for question in question_candidates.sorted(reverse=go_back):
|
|
# pages with description are potential questions to display (are part of question_candidates)
|
|
if question.is_page:
|
|
contains_active_question = any(
|
|
sub_question not in inactive_questions for sub_question in question.question_ids)
|
|
is_description_section = not question.question_ids and not is_html_empty(question.description)
|
|
if contains_active_question or is_description_section:
|
|
return question
|
|
else:
|
|
triggering_answer = triggering_answer_by_question.get(question)
|
|
if not triggering_answer or triggering_answer in selected_answers:
|
|
# question is visible because not conditioned or conditioned by a selected answer
|
|
return question
|
|
elif survey.questions_layout == 'page_per_section':
|
|
section_candidates = pages_or_questions[0:current_page_index] if go_back \
|
|
else pages_or_questions[current_page_index + 1:]
|
|
for section in section_candidates.sorted(reverse=go_back):
|
|
contains_active_question = any(question not in inactive_questions for question in section.question_ids)
|
|
is_description_section = not section.question_ids and not is_html_empty(section.description)
|
|
if contains_active_question or is_description_section:
|
|
return section
|
|
return Question
|
|
|
|
|
|
class InheritQuestion(models.Model):
|
|
_inherit = "survey.question"
|
|
|
|
config_ids = fields.Many2many("tx.survey.config", "survey_config_question_ref", "question_id", "config_id", string="配置项")
|
|
|
|
|
|
class InheritSurveyQuestionAnswer(models.Model):
|
|
_inherit = "survey.question.answer"
|
|
|
|
votes = fields.Integer(string="投票数量")
|
|
|
|
|
|
class SurveyConfig(models.Model):
|
|
_name = "tx.survey.config"
|
|
_description = "调查项配置"
|
|
|
|
survey_id = fields.Many2one("survey.survey", string="调查")
|
|
question_id = fields.Many2one("survey.question", string="问题")
|
|
answer_id = fields.Many2one("survey.question.answer", string="答案")
|
|
show_question_ids = fields.Many2many("survey.question", "survey_config_question_ref", "config_id", "question_id", string="显示问题")
|
|
|
|
|
|
class InheritSurveyUserInputLine(models.Model):
|
|
_inherit = "survey.user_input.line"
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
res = super().create(vals_list)
|
|
for r in res:
|
|
if r.question_id.question_type in ['simple_choice', 'multiple_choice', 'matrix']:
|
|
r.suggested_answer_id.votes += 1
|
|
return res |