diff --git a/__manifest__.py b/__manifest__.py index 364f78e3bfa33228bdede9f0c3a7a8e0d4c25212..e0f9f7749a76340d7541e26961883e4ee31f948a 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -4,7 +4,7 @@ "summary": "Link survey to training", "license": "AGPL-3", "author": "Le Filament", - "depends": ["training", "survey"], + "depends": ["training", "survey", "survey_xlsx"], "contributors": [ "Benjamin <benjamin@le-filament.com>", ], @@ -15,8 +15,7 @@ "security/ir.model.access.csv", # datas "data/mail_aeci.xml", - "data/mail_aect.xml", - "data/mail_satisfaction.xml", + "data/mail_end_training.xml", # templates # views "views/survey.xml", diff --git a/data/mail_aect.xml b/data/mail_end_training.xml similarity index 76% rename from data/mail_aect.xml rename to data/mail_end_training.xml index ccb15aa22389f81514cc00dda53d7cdaee8c3800..26fbb2fc34f73561326fb4bb196bb7e5288edd27 100644 --- a/data/mail_aect.xml +++ b/data/mail_end_training.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <odoo> - <record id="mail_template_training_aect" model="mail.template"> + <record id="mail_template_training_end" model="mail.template"> <field name="name">CG Scop - Formation - AECT</field> <field name="model_id" ref="training.model_training_student" /> <field name="subject">Formation {{ object.training_id.program_id.name }} - Questionnaire AECT</field> @@ -31,8 +31,16 @@ </t> <br /> je t’adresse les liens vers deux formulaires en ligne que tu voudras bien renseigner : - <br /> - <a class="btn btn-info" t-att-href="env.context.get('survey_user_input').get_start_url()">Autoévaluation des compétences terminales</a> + <ul> + <li> + <a t-att-href="env.context.get('aect_answer').get_start_url()">Autoévaluation des compétences terminales</a> + </li> + <li> + <a t-att-href="env.context.get('satisfaction_answer').get_start_url()">Evaluation de ta satisfaction</a> + </li> + </ul> + <br /><br /> + Je te prie de bien vouloir trouver en pièce jointe ton <t t-out="object.get_certification_name()"/> <br /><br /> Je te remercie et te souhaite bonne réception de ce courriel. <br /><br /> @@ -42,9 +50,10 @@ Déléguée à la formation professionnelle </p> </div> - </field> + </field> + <field name="report_template" ref="training.report_attestation_pdf" /> <field name="lang">fr_FR</field> - <field name="auto_delete" eval="True" /> - </record> + <field name="auto_delete" eval="True" /> + </record> </odoo> diff --git a/data/mail_satisfaction.xml b/data/mail_satisfaction.xml deleted file mode 100644 index 2430b7110112ffec9d7a112c41fe45bd16c3e61d..0000000000000000000000000000000000000000 --- a/data/mail_satisfaction.xml +++ /dev/null @@ -1,52 +0,0 @@ -<?xml version="1.0" encoding="utf-8" ?> -<odoo> - <record id="mail_template_training_satisfaction" model="mail.template"> - <field name="name">CG Scop - Formation - Satisfaction</field> - <field name="model_id" ref="training.model_training_student" /> - <field name="subject">Formation {{ object.training_id.program_id.name }} - {{ object.get_certification_name() }}</field> - <field name="email_from">lbrien@scop.coop <Laurence BRIEN></field> - <field name="email_to">{{ (object.partner_id.email or object.email) }}</field> - <field name="description">Mail envoyé au stagiaire pour fe certificat ou l'attestation de formation</field> - <field name="body_html" type="html"> -<div style="margin: 0px; padding: 0px; font-size: 13px;"> - <p style="margin: 0px; padding: 0px; font-size: 13px;"> - Bonjour, - <br /><br /> - Pour donner suite à ta participation à la formation <t t-out="object.training_id.program_id.name">Nom Formation</t> - qui s’est tenue - <t t-if="len(object.training_id.slot_ids) == 1"> - le <t t-out="object.training_id.slot_ids[0].date_start" t-options="{'widget': 'date', 'format': 'dd/MM/YYYY'}">05/05/2024</t> de - <t t-out="object.training_id.slot_ids[0].date_start" t-options="{'widget': 'datetime', 'format': 'HH:mm'}">09:00</t> à - <t t-out="object.training_id.slot_ids[0].date_end" t-options="{'widget': 'datetime', 'format': 'HH:mm'}">12:00</t> - </t> - <t t-else=""> - aux dates suivantes : - <ul> - <li t-foreach="object.training_id.slot_ids" t-as="slot"> - <t t-out="slot.date_start" t-options="{'widget': 'date', 'format': 'dd/MM/YYYY'}">05/05/2024</t> de - <t t-out="slot.date_start" t-options="{'widget': 'datetime', 'format': 'HH:mm'}">09:00</t> à - <t t-out="slot.date_end" t-options="{'widget': 'datetime', 'format': 'HH:mm'}">12:00</t> - </li> - </ul> - </t> - je te prie de bien vouloir trouver en pièce jointe ton <t t-out="object.get_certification_name()"/> - <br /><br /> - Je t’adresse un lien vers le formulaire en ligne que tu voudras bien renseigner: - <a class="btn btn-info" t-att-href="env.context.get('survey_user_input').get_start_url()">Evaluation de ta satisfaction</a> - <br /><br /> - Je te remercie et te souhaite bonne réception de ce courriel. - <br /><br /> - Bonne journée. - <br /> - Laurence Brien<br /> - Déléguée à la formation professionnelle - </p> -</div> - </field> - <field name="report_template" ref="training.report_attestation_pdf" /> - <field name="report_name">{{ object.get_certification_name() }} - {{ object.partner_id.name }}</field> - <field name="lang">fr_FR</field> - <field name="auto_delete" eval="True" /> - </record> - -</odoo> diff --git a/models/training.py b/models/training.py index f0716f730be93813a0070d3db119742768ba42dd..54c61a88051a2bbbfec8649997e35d99d7e4f456 100644 --- a/models/training.py +++ b/models/training.py @@ -57,6 +57,22 @@ class Training(models.Model): # ------------------------------------------------------ # Actions # ------------------------------------------------------ + def action_export_registration(self): + if self.registration_survey_id: + return self._get_survey_xlsx(self.registration_survey_id) + + def action_export_aeci(self): + if self.aeci_survey_id: + return self._get_survey_xlsx(self.aeci_survey_id) + + def action_export_aect(self): + if self.aect_survey_id: + return self._get_survey_xlsx(self.aect_survey_id) + + def action_export_satisfaction(self): + if self.satisfaction_survey_id: + return self._get_survey_xlsx(self.satisfaction_survey_id) + def action_view_survey(self): self.ensure_one() return { @@ -68,16 +84,22 @@ class Training(models.Model): "context": {"create": 0, "delete": 0}, } - def action_send_aect(self): + def action_send_end_training_data(self): self.ensure_one() - aect_template_id = self.env.ref("training_survey.mail_template_training_aect") + self.action_done() + end_template_id = self.env.ref("training_survey.mail_template_training_end") student_ids = self.student_ids.filtered(lambda s: s.state == "confirmed") for student in student_ids: - student._create_and_send_survey( - self.aect_survey_id, aect_template_id + aect_answer = student._create_answer(self.aect_survey_id) + satisfaction_answer = student._create_answer(self.satisfaction_survey_id) + end_template_id.with_context( + aect_answer=aect_answer, satisfaction_answer=satisfaction_answer + ).send_mail( + student.id, + email_layout_xmlid="training.mail_training_layout", ) self.message_post( - subject="Questionnaire AECT envoyé", + subject="Questionnaires AECT et Satisfaction envoyés", body=f"Participants : {', '.join(student_ids.mapped('partner_id.name'))}", ) @@ -105,5 +127,7 @@ class Training(models.Model): super().action_valid() # ------------------------------------------------------ - # Buttons + # Business function # ------------------------------------------------------ + def _get_survey_xlsx(self, survey_id): + return self.env.ref("survey_xlsx.report_survey_xlsx").report_action(survey_id) diff --git a/models/training_student.py b/models/training_student.py index 5f8207278975ab427c337914a5d3294a8c876b55..dabc563c4d855fe4d8f9eff350e1ccb3d492a0a5 100644 --- a/models/training_student.py +++ b/models/training_student.py @@ -13,12 +13,30 @@ class TrainingStudent(models.Model): inverse_name="student_id", string="Questionnaires", ) + registration_survey_id = fields.Many2one( + comodel_name="survey.user_input", + string="Inscription/Positionnement", + compute="_compute_registration_survey", + ) + registration_state = fields.Selection( + [("new", "Pas commencé"), ("in_progress", "En cours"), ("done", "Terminé")], + compute="_compute_registration_survey", + string="Statut inscription", + store=False, + ) survey_count = fields.Integer(compute="_compute_survey_count") aeci_sent = fields.Boolean(compute="_compute_aeci_sent") # ------------------------------------------------------ # Compute # ------------------------------------------------------ + def _compute_registration_survey(self): + for student in self: + student.registration_survey_id = student.student_survey_ids.filtered( + lambda ui: ui.survey_id.training_survey_type == "subscribe" + ) + student.registration_state = student.registration_survey_id.state + def _compute_survey_count(self): for student in self: student.survey_count = student.student_survey_ids.__len__() @@ -46,6 +64,17 @@ class TrainingStudent(models.Model): "context": {"create": 0, "delete": 0}, } + def action_view_registration(self): + self.ensure_one() + return { + "name": f"Questionnaire Inscription {self.partner_id.name}", + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "survey.user_input", + "res_id": self.registration_survey_id.id, + "context": {"create": 0, "delete": 0}, + } + def action_create_aeci(self): aeci_template_id = self.env.ref("training_survey.mail_template_training_aeci") self._create_and_send_survey( @@ -57,7 +86,9 @@ class TrainingStudent(models.Model): # ------------------------------------------------------ def get_certification_name(self): self.ensure_one() - if self.training_id.training_type_id == self.env.ref("training.training_type_present"): + if self.training_id.training_type_id == self.env.ref( + "training.training_type_present" + ): return "Attestation de fin de formation" else: return "Certificat de réalisation" @@ -83,6 +114,8 @@ class TrainingStudent(models.Model): ) if not student_answer: return self._init_answer(survey_id) + elif len(student_answer) == 1: + return student_answer else: raise UserError( _( diff --git a/views/training.xml b/views/training.xml index ba1718f815ef4c5211f3976086818b6bf34a715f..2443ee813d6cd0ad4cd9a928007e7decf046d375 100644 --- a/views/training.xml +++ b/views/training.xml @@ -8,24 +8,14 @@ <field name="arch" type="xml"> <xpath expr="//header" position="inside"> <button - name="action_send_aect" - type="object" - icon="fa-question-circle-o" - class="btn-info" - confirm="Valider l'envoi des questionnaires AECT ?" - attrs="{'invisible': ['|', ('is_passed', '=', False), ('is_filled', '=', False)]}" - > - Envoyer les questionnaires AECT - </button> - <button - name="action_send_satisfaction" + name="action_send_end_training_data" type="object" icon="fa-graduation-cap" class="btn-info" - confirm="Valider l'envoi des certificats/attestations ?" + confirm="Cette action va envoyer à chaque participant les questionnaires d'inscription et de satisfaction, le certificat ou l'attestation, et passer la formation à l'état Terminé" attrs="{'invisible': ['|', ('is_passed', '=', False), ('is_filled', '=', False)]}" > - Envoyer certificats/attestations + Envoyer questionnaires AECT/Satisfaction et certificats/attestations </button> </xpath> <xpath expr="//div[@name='button_box']" position="inside"> @@ -40,15 +30,69 @@ </xpath> <xpath expr="//notebook" position="inside"> <page string="Questionnaires" name="survey"> - <group> + <p class="o_horizontal_separator"> + Inscription/Positionnement + </p> + <p> + <field name="registration_survey_id" class="me-4" /> + <button + name="action_export_registration" + type="object" + icon="fa-file-o" + class="btn-outline-primary" + title="Exporter réponses positionnement" + attrs="{'invisible': [('registration_survey_id', '=', False)]}" + /> + </p> + + <p class="o_horizontal_separator"> + AECI + </p> + <p> + <field name="aeci_survey_id" class="me-4" /> + <button + name="action_export_aeci" + type="object" + icon="fa-file-o" + class="btn-outline-primary" + title="Export réponses AECI" + attrs="{'invisible': [('aeci_survey_id', '=', False)]}" + /> + </p> + + <p class="o_horizontal_separator"> + AECT + </p> + <p> + <field name="aect_survey_id" class="me-4" /> + <button + name="action_export_aect" + type="object" + icon="fa-file-o" + class="btn-outline-primary" + title="Export réponses AECT" + attrs="{'invisible': [('aect_survey_id', '=', False)]}" + /> + </p> + + <p class="o_horizontal_separator"> + Satisfaction + </p> + <p> <field name="satisfaction_survey_id" + class="me-4" options="{'no_create': 1, 'no_edit': 1}" /> - <field name="registration_survey_id" /> - <field name="aeci_survey_id" /> - <field name="aect_survey_id" /> - </group> + <button + name="action_export_satisfaction" + type="object" + icon="fa-file-o" + class="btn-outline-primary" + title="Export réponses satisfaction" + attrs="{'invisible': [('satisfaction_survey_id', '=', False)]}" + /> + </p> </page> </xpath> </field> diff --git a/views/training_program.xml b/views/training_program.xml index b4d0bfd016b4aadba579d82d96a16a80118ee52c..25cad67bad013bd0e9253bea2021e1ed5dbe5051 100644 --- a/views/training_program.xml +++ b/views/training_program.xml @@ -16,11 +16,11 @@ options="{'no_create': 1, 'no_edit': 1}" /> <field - name="aect_survey_id" + name="aeci_survey_id" options="{'no_create': 1, 'no_edit': 1}" /> <field - name="aeci_survey_id" + name="aect_survey_id" options="{'no_create': 1, 'no_edit': 1}" /> </group> diff --git a/views/training_student.xml b/views/training_student.xml index 5d8088d764031d8d1c3d3fa3bfa1cdb74d47b87e..54a2f58e8d8a05576cc8423b9129df659ab66824 100644 --- a/views/training_student.xml +++ b/views/training_student.xml @@ -35,9 +35,9 @@ /> <field name="student_survey_ids" readonly="1"> <tree> - <field name="create_date"/> - <field name="survey_id"/> - <field name="state"/> + <field name="create_date" /> + <field name="survey_id" /> + <field name="state" /> </tree> </field> </page> @@ -53,6 +53,23 @@ <field name="inherit_id" ref="training.training_student_tree" /> <field name="arch" type="xml"> <xpath expr="//field[@name='student_company']" position="after"> + <field name="registration_survey_id" invisible="1" /> + <button + name="action_view_registration" + type="object" + icon="fa-sign-in" + class="text-end" + title="Voir le questionnaire d'inscription" + attrs="{'invisible': [('registration_survey_id', '=', False)]}" + /> + <field + name="registration_state" + string="Quest. inscription" + widget="badge" + decoration-success="registration_state == 'done'" + decoration-warning="registration_state == 'new'" + decoration-info="registration_state == 'in_progress'" + /> <field name="aeci_sent" invisible="1" /> <button name="action_create_aeci" @@ -62,6 +79,12 @@ attrs="{'invisible': ['|', ('aeci_sent', '=', True), ('state', '!=', 'confirmed')]}" /> </xpath> +<!-- <xpath expr="//button[@name='action_confirmed']" position="attributes">--> +<!-- <attribute name="attrs">{'invisible': ['|', ('state', '=', 'confirmed'), ('registration_state', '!=', 'done')]}</attribute>--> +<!-- </xpath>--> +<!-- <xpath expr="//button[@name='action_unsuitable']" position="attributes">--> +<!-- <attribute name="attrs">{'invisible': ['|', ('state', '=', 'unsuitable'), ('registration_state', '!=', 'done')]}</attribute>--> +<!-- </xpath>--> </field> </record>