event_question.py 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. from odoo import api, fields, models, _
  4. from odoo.exceptions import UserError
  5. class EventQuestion(models.Model):
  6. _name = 'event.question'
  7. _rec_name = 'title'
  8. _order = 'sequence,id'
  9. _description = 'Event Question'
  10. title = fields.Char(required=True, translate=True)
  11. question_type = fields.Selection([
  12. ('simple_choice', 'Selection'),
  13. ('text_box', 'Text Input')], default='simple_choice', string="Question Type", required=True)
  14. event_type_id = fields.Many2one('event.type', 'Event Type', ondelete='cascade')
  15. event_id = fields.Many2one('event.event', 'Event', ondelete='cascade')
  16. answer_ids = fields.One2many('event.question.answer', 'question_id', "Answers", copy=True)
  17. sequence = fields.Integer(default=10)
  18. once_per_order = fields.Boolean('Ask once per order',
  19. help="If True, this question will be asked only once and its value will be propagated to every attendees."
  20. "If not it will be asked for every attendee of a reservation.")
  21. is_mandatory_answer = fields.Boolean('Mandatory Answer')
  22. @api.constrains('event_type_id', 'event_id')
  23. def _constrains_event(self):
  24. if any(question.event_type_id and question.event_id for question in self):
  25. raise UserError(_('Question cannot belong to both the event category and itself.'))
  26. def write(self, vals):
  27. """ We add a check to prevent changing the question_type of a question that already has answers.
  28. Indeed, it would mess up the event.registration.answer (answer type not matching the question type). """
  29. if 'question_type' in vals:
  30. questions_new_type = self.filtered(lambda question: question.question_type != vals['question_type'])
  31. if questions_new_type:
  32. answer_count = self.env['event.registration.answer'].search_count([('question_id', 'in', questions_new_type.ids)])
  33. if answer_count > 0:
  34. raise UserError(_("You cannot change the question type of a question that already has answers!"))
  35. return super(EventQuestion, self).write(vals)
  36. @api.ondelete(at_uninstall=False)
  37. def _unlink_except_answered_question(self):
  38. if self.env['event.registration.answer'].search_count([('question_id', 'in', self.ids)]):
  39. raise UserError(_('You cannot delete a question that has already been answered by attendees.'))
  40. def action_view_question_answers(self):
  41. """ Allow analyzing the attendees answers to event questions in a convenient way:
  42. - A graph view showing counts of each suggestions for simple_choice questions
  43. (Along with secondary pivot and tree views)
  44. - A tree view showing textual answers values for text_box questions. """
  45. self.ensure_one()
  46. action = self.env["ir.actions.actions"]._for_xml_id("website_event_questions.action_event_registration_report")
  47. action['domain'] = [('question_id', '=', self.id)]
  48. if self.question_type == 'simple_choice':
  49. action['views'] = [(False, 'graph'), (False, 'pivot'), (False, 'tree')]
  50. elif self.question_type == 'text_box':
  51. action['views'] = [(False, 'tree')]
  52. return action
  53. class EventQuestionAnswer(models.Model):
  54. """ Contains suggested answers to a 'simple_choice' event.question. """
  55. _name = 'event.question.answer'
  56. _order = 'sequence,id'
  57. _description = 'Event Question Answer'
  58. name = fields.Char('Answer', required=True, translate=True)
  59. question_id = fields.Many2one('event.question', required=True, ondelete='cascade')
  60. sequence = fields.Integer(default=10)
  61. @api.ondelete(at_uninstall=False)
  62. def _unlink_except_selected_answer(self):
  63. if self.env['event.registration.answer'].search_count([('value_answer_id', 'in', self.ids)]):
  64. raise UserError(_('You cannot delete an answer that has already been selected by attendees.'))