LatifaShi
LatifaShi

Reputation: 440

Odoo : Make changes on Survey module

I am working on editing the survey module in odoo. When I answer a survey which is composed of pages and then click on submit survey, it calculates the whole score of the survey and displays it. What I want is that it calculates the score of each page and display it when I click on submit survey for example:

It displays: Your score is: 200 points.
And I want it to display: Score of first page : 20 points, Second page: 50 points and so on...

Here is the code that I want to change but I don't know how should I change this function.

questionnaire.py (survey.py) : class survey_user_input

class survey_user_input(osv.Model):
''' Metadata for a set of one user's answers to a particular survey '''
_name = "questionnaire.user_input"
_rec_name = 'date_create'
_description = 'Survey User Input'

def _quizz_get_score(self, cr, uid, ids, name, args, context=None):
    ret = dict()
    for user_input in self.browse(cr, uid, ids, context=context):
        ret[user_input.id] = sum([uil.quizz_mark for uil in user_input.user_input_line_ids] or [0.0])
    return ret

_columns = {
    'survey_id': fields.many2one('questionnaire.questionnaire', 'Questionnaire', required=True,
                                 readonly=1, ondelete='restrict'),
    'date_create': fields.datetime('Date de creation', required=True,
                                   readonly=1, copy=False),
    'deadline': fields.datetime("Date limite",
                            oldname="date_deadline"),
    'type': fields.selection([('manually', 'Manuellement'), ('link', 'Lien')],
                             'Type de reponse', required=1, readonly=1,
                             oldname="response_type"),
    'state': fields.selection([('new', 'Pas encore commence'),
                               ('skip', 'Partiellement acheve'),
                               ('done', 'Termine')],
                              'Statut',
                              readonly=True),
    'test_entry': fields.boolean('Entree de test', readonly=1),
    'token': fields.char("Piece d'identite", readonly=1, required=1, copy=False),

    # Optional Identification data
    'partner_id': fields.many2one('res.partner', 'Partenaire', readonly=1),
    'email': fields.char("E-mail", readonly=1),

    # Displaying data
    'last_displayed_page_id': fields.many2one('questionnaire.page',
                                          'Derniere page affichee'),
    # The answers !
    'user_input_line_ids': fields.one2many('questionnaire.user_input_line',
                                           'user_input_id', 'Reponses', copy=True),

    # URLs used to display the answers
    'result_url': fields.related('survey_id', 'result_url', type='char',
                                 string="Lien public aux resultats du sondage"),
    'print_url': fields.related('survey_id', 'print_url', type='char',
                                string="Lien public au sondage vide"),

    'quizz_score': fields.function(_quizz_get_score, type="float", string="Score pour le quiz", store=True)
}
_defaults = {
    'date_create': fields.datetime.now,
    'type': 'manually',
    'state': 'new',
    'token': lambda s, cr, uid, c: uuid.uuid4().__str__(),
    'quizz_score': 0.0,
}

questionnaire.py (survey.py) : class survey_user_input_line

 _name = 'questionnaire.user_input_line'
_description = 'Survey User Input Line'
_rec_name = 'date_create'
_columns = {
    'user_input_id': fields.many2one('questionnaire.user_input', 'Entree de l\'utilisateur',
                                     ondelete='cascade', required=1),
    'question_id': fields.many2one('questionnaire.question', 'Question',
                                   ondelete='restrict', required=1),
    'page_id': fields.related('question_id', 'page_id', type='many2one',
                              relation='questionnaire.page', string="Page"),
    'survey_id': fields.related('user_input_id', 'survey_id',
                                type="many2one", relation="questionnaire.questionnaire",
                                string='Questionnaire', store=True),
    'date_create': fields.datetime('Date de creation', required=1),
    'skipped': fields.boolean('Ignore'),
    'answer_type': fields.selection([('text', 'Texte'),
                                     ('number', 'Nombre'),
                                     ('date', 'Date'),
                                     ('free_text', 'Texte Libre'),
                                     ('suggestion', 'Suggestion')],
                                    'Type de reponse'),
    'value_text': fields.char("Reponse texte"),
    'value_number': fields.float("Reponse numerique"),
    'value_date': fields.datetime("Reponse date"),
    'value_free_text': fields.text("Reponse texte libre"),
    'value_suggested': fields.many2one('questionnaire.label', "Reponse suggeree"),
    'value_suggested_row': fields.many2one('questionnaire.label', "Reponse en ligne"),
    'quizz_mark': fields.float("Score donne pour ce choix")
}

survey_templates.xml

<!-- "Thank you" message when the survey is completed -->
<template id="sfinished" name="Survey Finished">
    <t t-call="website.layout">
        <div class="wrap">
            <div class="container">
                <t t-call="questionnaire.back" />
                <div class="jumbotron mt32">
                    <h1>Thank you!</h1>
                    <div t-field="questionnaire.thank_you_message" class="oe_no_empty" />
                    <div> You scored <t t-esc="user_input.quizz_score" /> points.</div>
                    <div>If you want you can <a t-att-href="'/questionnaire/print/%s/%s' % (slug(questionnaire), token)">review your answers</a>.</div>
                </div>
            </div>
        </div>
    </t>
</template>

Upvotes: 1

Views: 1227

Answers (2)

LatifaShi
LatifaShi

Reputation: 440

Thank you so much @MICROCOM .. The line that display the score for each page is diplayed more than once ..

The result Of The code - 1

So i added a condition to just display the score of a certain page once (I don't know if it's correct but it works :p ) .. Here is the code :

<!-- First finding which page is related to the survey. This is a bit odd but I couldn't find any other way!! -->
                    <t t-set="pages" t-value="dict((l.id, l.page_id.title) for l in user_input.user_input_line_ids).values()" />
                    <!-- Then print the score per each page -->
                    <t t-set="previous" t-value="void" />
                    <t t-foreach='pages' t-as='p'>
                        <t t-if="p != previous">
                        <t t-set="page_score" t-value="sum([(uil.quizz_mark or 0.0) if uil.page_id.title == p else 0.0 for uil in user_input.user_input_line_ids])" />
                        <div> You scored <t t-esc="page_score" /> points in page <t t-esc="p" />.</div>
                        </t>
                        <t t-set="previous" t-value="p" />
                    </t>

The result Of The code - 2

Thank you so much for your help @MICROCOM ^^

Upvotes: 0

Ali Abdi
Ali Abdi

Reputation: 168

One alternative way is to use pure qweb rather than function field; like this:

<!-- First finding which page is related to the survey. This is a bit odd but I couldn't find any other way!! -->
<t t-set="pages" t-value="dict((l.id, l.page_id.id) for l in user_input.user_input_line_ids).values()" />

<!-- Then print the score per each page -->
<t t-foreach='pages' t-as='p'>
    <t t-set="page_score" t-value="sum([(uil.quizz_mark or 0.0) if uil.page_id.id == p else 0.0 for uil in user_input.user_input_line_ids])" />
    <div> You scored <t t-esc="page_score" /> points in page <t t-esc="p" />.</div>
</t>

I have not tested this code but logically it seems to work fine.

Upvotes: 0

Related Questions