Files
odoo_source/addons/website_slides_survey/models/survey_user.py
T
Olivier Dony 3e5880236e [FIX] survey*: add missing index FKs for performance
1) `survey_user_input.slide_partner_id`: this is a sparse column (so using
`btree_not_null` means a very small footprint). But it makes a ton of
difference when trying to delete a slide.slide.partner entry.
e.g. on a db with 500k survey inputs, the deletion of 1000
`slide.slide.partner` records goes from 40s to 100ms (400x speedup)

2) `survey_user_input_line.survey_id`: this is the inverse field of the
`survey_user_input.user_input_line_ids` O2M field, so the index is
always useful to retrieve the O2M lines. It will also marginally help
for cascading the deletion of any `survey_user_input` record from
case 1).

closes odoo/odoo#116875

X-original-commit: 2dc929cd530ba4fd80c17f91af2bfad02a819dd6
Signed-off-by: Olivier Dony (odo) <odo@odoo.com>
2023-03-29 23:37:17 +02:00

66 lines
2.8 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import fields, models, api
from odoo.osv import expression
class SurveyUserInput(models.Model):
_inherit = 'survey.user_input'
slide_id = fields.Many2one('slide.slide', 'Related course slide',
help="The related course slide when there is no membership information")
slide_partner_id = fields.Many2one('slide.slide.partner', 'Subscriber information',
help="Slide membership information for the logged in user",
index='btree_not_null') # index useful for deletions in comodel
@api.model_create_multi
def create(self, vals_list):
records = super(SurveyUserInput, self).create(vals_list)
records._check_for_failed_attempt()
return records
def write(self, vals):
res = super(SurveyUserInput, self).write(vals)
if 'state' in vals:
self._check_for_failed_attempt()
return res
def _check_for_failed_attempt(self):
""" If the user fails their last attempt at a course certification,
we remove them from the members of the course (and they have to enroll again).
They receive an email in the process notifying them of their failure and suggesting
they enroll to the course again.
The purpose is to have a 'certification flow' where the user can re-purchase the
certification when they have failed it."""
if self:
user_inputs = self.search([
('id', 'in', self.ids),
('state', '=', 'done'),
('scoring_success', '=', False),
('slide_partner_id', '!=', False)
])
if user_inputs:
for user_input in user_inputs:
removed_memberships_per_partner = {}
if user_input.survey_id._has_attempts_left(user_input.partner_id, user_input.email, user_input.invite_token):
# skip if user still has attempts left
continue
self.env.ref('website_slides_survey.mail_template_user_input_certification_failed').send_mail(
user_input.id, email_layout_xmlid="mail.mail_notification_light"
)
removed_memberships = removed_memberships_per_partner.get(
user_input.partner_id,
self.env['slide.channel']
)
removed_memberships |= user_input.slide_partner_id.channel_id
removed_memberships_per_partner[user_input.partner_id] = removed_memberships
for partner_id, removed_memberships in removed_memberships_per_partner.items():
removed_memberships._remove_membership(partner_id.ids)