# -*- 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