Odoo · Survey · Integración
El módulo Survey de Odoo sirve para mucho más que encuestas de satisfacción: tests de cribado, cuestionarios clínicos, exámenes online. La clave para integrarlo es vincular cada respuesta (survey.user_input) a un registro de tu modelo y reaccionar cuando el participante termina. Veamos el patrón completo.
Modelos
El mapa de Survey
| Modelo | Qué representa |
|---|---|
survey.survey | La encuesta/test (plantilla de preguntas) |
survey.question | Cada pregunta y su tipo |
survey.user_input | Un intento concreto de un participante |
survey.user_input.line | Cada respuesta individual del intento |
Vinculación
Conectar el intento a tu modelo
class DiagnosticTest(models.Model):
_inherit = 'diagnostic.test'
survey_id = fields.Many2one('survey.survey', string='Cuestionario')
user_input_id = fields.Many2one('survey.user_input',
string='Intento', readonly=True)
def action_start_survey(self):
self.ensure_one()
answer = self.survey_id._create_answer(partner=self.partner_id)
self.user_input_id = answer.id
return {
'type': 'ir.actions.act_url',
'url': answer.get_start_url(),
'target': 'self',
}
_create_answer genera el survey.user_input y get_start_url() devuelve el enlace con el token. Guardamos el intento en nuestro registro para correlacionar resultados después.
Reacción
Actuar al completar el test
class SurveyUserInput(models.Model):
_inherit = 'survey.user_input'
def _mark_done(self):
res = super()._mark_done()
for ui in self:
test = self.env['diagnostic.test'].search(
[('user_input_id', '=', ui.id)], limit=1)
if test:
test.write({
'state': 'completed',
'score': ui.scoring_percentage,
})
return res
scoring_percentage ya calculado.
Lectura
Extraer respuestas concretas
def _get_answer_for_question(self, ui, question_xmlid):
question = self.env.ref(question_xmlid)
line = ui.user_input_line_ids.filtered(
lambda l: l.question_id == question)
return line.value_char or line.suggested_answer_id.value
Cada user_input.line guarda el valor según el tipo de pregunta: value_char, value_numerical_box, value_date o suggested_answer_id para opciones. Referencia las preguntas por XML ID para no depender de su orden.
survey.user_input y evita exponer respuestas en vistas accesibles a usuarios sin permiso. Enlaza con la entrada de RGPD de esta serie.
Resumen
Crea el intento con _create_answer, guárdalo en tu modelo, reacciona en _mark_done para actualizar estado y puntuación, y lee respuestas individuales desde user_input_line_ids referenciando preguntas por XML ID. Así Survey se convierte en un motor de tests integrado en tu flujo, no en un silo aparte.