Piermi: Odoo - Mois Anniversaire

Description High Level

But: Le client souhaite pouvoir enregistrer le mois de la date d'anniversaire du client dans odoo pour lui offrir automatiquement une réduction à l'approche de cette date (envoi massif à tous les clients né un mois de xxx).

Solution en V15:

Ajout d'un champ dans la fiche res.partner

Message dans le MyPortal pour inviter le client à transmettre son mois d'anniversaire

Campagne de bon de réduction + Template email dédié

Description Technique v15

Ajout d'un champ dans la fiche res.partner

Le champ a été initialement créé via Odoo Studio à une époque où j'étais débutant en Odoo. Il suivra en principe les différentes mises-à-jours d'Odoo.

Campagne de bon de réduction + template email

template email

Un nouveau template a été généré pour pouvoir contacter les clients. Paramètres → Technique → Modèles de courrier De info@lingerie-pierre.com Pour (partenaires) object.source_pos_order_id.partner_id.id_or_object.partner_id.id

<table role="presentation" style="box-sizing:border-box;border-collapse:collapse;width:570px;height:807px;" width="570px" height="807px" cellspacing="0" cellpadding="0" border="0" align="center"> <tbody><tr> <td style="background: url('https://www.lingerie-pierre.com/web/image/105740-93476e0d/confetti_570.jpeg?access_token=4c486a4a-a1e3-458b-8886-933dd03bfbfe')" width="570px" valign="top" height="807px" bgcolor="#ffffff”" background="https://www.lingerie-pierre.com/web/image/105740-93476e0d/confetti_570.jpeg?access_token=4c486a4a-a1e3-458b-8886-933dd03bfbfe" align="center"> <!--[if gte mso 9]> <v:image xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style=" border: 0;display: inline-block; width: 570pt; height: 807pt;" src="https://www.lingerie-pierre.com/web/image/105740-93476e0d/confetti_570.jpeg?access_token=4c486a4a-a1e3-458b-8886-933dd03bfbfe" ></v:image> <v:rect xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false" style=" border: 0;display: inline-block;position: absolute; width: 570pt; height:807pt;"> <v:fill opacity="0%" color="#ffffff” ></v:fill> <v:textbox inset="0,0,0,0"> <![endif]--> <div> <div style="font-size: 0;"> <table role="presentation" style="box-sizing:border-box;border-collapse:collapse;width:570px;height:307px;vertical-align: middle;margin-top:230px;" vertical-align="middle" width="570px" height="307px" cellspacing="0" cellpadding="0" border="0" align="center"> <tbody><tr> <td style="text-align: center; font-size: 14px;"> <t t-if="object.partner_id.name" data-oe-t-group="0" data-oe-t-group-active="true" data-oe-t-inline="true"> <strong style="box-sizing:border-box;font-weight:500;font-size: 20px;"> Félicitations <br> <t t-out="object.partner_id.name or ''" contenteditable="false" data-oe-t-inline="true">Brandon Freeman</t>, <br>C'est le mois de votre anniversaire, <br>La Lingerie Pierre vous offre <br> </strong> </t> <t t-if="object.program_id.reward_type == 'discount'" data-oe-t-group="1" data-oe-t-selectable="true" data-oe-t-group-active="true" data-oe-t-inline="true"> <t t-if="object.program_id.discount_type == 'fixed_amount'" data-oe-t-group="2" data-oe-t-selectable="true" data-oe-t-group-active="true" data-oe-t-inline="true"> <span style="font-size: 50px; color: #ED217B; font-weight: bold;" t-out="'%s' % format_amount(object.program_id.discount_fixed_amount, object.program_id.currency_id) or ''" contenteditable="false">$ 10.0</span><br> <strong style="box-sizing:border-box;font-weight:500;font-size: 20px;">sur votre prochaine commande</strong><br> </t> <t t-else="" data-oe-t-selectable="true" data-oe-t-group="2" data-oe-t-inline="true"> <span style="font-size: 50px; color: #ED217B; font-weight: bold;"> <t t-out="object.program_id.discount_percentage or ''" contenteditable="false" data-oe-t-inline="true">10.0</t>% </span> <t t-if="object.program_id.discount_apply_on == 'specific_products'" data-oe-t-group="3" data-oe-t-selectable="true" data-oe-t-group-active="true" data-oe-t-inline="true"> <br> <t t-if="len(object.program_id.discount_specific_product_ids) != 1" data-oe-t-group="4" data-oe-t-selectable="true" data-oe-t-group-active="true" data-oe-t-inline="true"> <t t-set="display_specific_products" t-value="True" data-oe-t-inline="true"> </t> <strong style="box-sizing:border-box;font-weight:500;font-size: 20px;"> sur certains produits* </strong> </t> <t t-else="" data-oe-t-selectable="true" data-oe-t-group="4" data-oe-t-inline="true"> <strong style="box-sizing:border-box;font-weight:500;font-size: 20px;" t-out="'on %s' % object.program_id.discount_specific_product_ids.name or ''" contenteditable="false">Protection Sol</strong> </t> </t> <t t-elif="object.program_id.discount_apply_on == 'cheapest_product'" data-oe-t-selectable="true" data-oe-t-group="3" data-oe-t-inline="true"> <br><strong style="box-sizing:border-box;font-weight:500;font-size: 20px;"> de remise sur l'article le moins cher </strong> </t> <t t-else="" data-oe-t-selectable="true" data-oe-t-group="3" data-oe-t-inline="true"> <br><strong style="box-sizing:border-box;font-weight:500;font-size: 20px;"> sur votre prochaine commande </strong> </t> <br> </t> </t> <t t-elif="object.program_id.reward_type == 'product'" data-oe-t-selectable="true" data-oe-t-group="1" data-oe-t-inline="true"> <span style="font-size: 36px; color: #875A7B; font-weight: bold;" t-out="'get %s free %s' % (object.program_id.reward_product_quantity, object.program_id.reward_product_id.name) or ''" contenteditable="false"> Protection Sol</span><br> <strong style="box-sizing:border-box;font-weight:500;font-size: 20px;"> sur votre prochaine commande</strong><br> </t> <t t-elif="object.program_id.reward_type == 'free_shipping'" data-oe-t-selectable="true" data-oe-t-group="1" data-oe-t-inline="true"> <span style="font-size: 36px; color: #875A7B; font-weight: bold;"> obtenez une livraison gratuite </span><br> <strong style="box-sizing:border-box;font-weight:500;font-size: 20px;"> sur votre prochaine commande</strong><br> </t> </td> </tr> <tr> <td style="text-align: center; font-size: 14px;" valign="top"> A utiliser <t t-if="object.expiration_date" data-oe-t-group="5" data-oe-t-group-active="true" data-oe-t-inline="true"> avant le <t t-out="object.expiration_date or ''" contenteditable="false" data-oe-t-inline="true"> 2021_06_05</t> </t><br> Valable en magasin et sur notre <a href="https://www.lingerie-pierre.com" style="text-decoration:none;box-sizing:border-box;background-color:transparent;color:#008f8c;">site web</a>. <p style="box-sizing:border-box;margin-top: 16px;"> <strong style="box-sizing:border-box;font-weight:500;padding: 16px 8px 16px 8px; border-radius: 3px; background-color: #F1F1F1;" t-out="object.code or ''" contenteditable="false">481399630193260690109548</strong> </p> <!--<img t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('QR', object.code, 75, 75)" style="border-style:none;box-sizing:border-box;vertical-align:middle;width: 0px; height: 0px;" width="0px" height="0">--> <t t-if="object.program_id.rule_min_quantity not in [0, 1]" data-oe-t-group="6" data-oe-t-group-active="true" data-oe-t-inline="true"> <span style="font-size: 14px;"> Achat minimum de <t t-out="object.program_id.rule_min_quantity or ''" contenteditable="false" data-oe-t-inline="true">10</t> articles </span><br> </t> <t t-if="object.program_id.rule_minimum_amount != 0.00" data-oe-t-group="7" data-oe-t-group-active="true" data-oe-t-inline="true"> <span style="font-size: 14px;"> Valide pour achat supérieur à € <t t-out="'%0.2f' % float(object.program_id.rule_minimum_amount) or ''" contenteditable="false" data-oe-t-inline="true">10.00</t> </span><br> </t> <t t-if="display_specific_products" data-oe-t-group="8" data-oe-t-group-active="true" data-oe-t-inline="true"> *Valide pour les articles suivants:<t t-out="', '.join(object.program_id.discount_specific_product_ids.mapped('name')) or ''" contenteditable="false" data-oe-t-inline="true"> Chaise de bureau Noire</t> <br> </t>&nbsp; &nbsp;<table style="box-sizing:border-box;border-collapse:collapse;"><tbody style="vertical-align: top;"></tbody></table> </td> </tr> </tbody></table> </div> </div> <!--[if gte mso 9]> </v:textbox> </v:fill> </v:rect> </v:image> <![endif]--> </td> </tr> </tbody></table>

Campagne de bon de réduction

Dans “Ventes → Articles → Campagnes de bons de réduction”, une nouvelle campagne de bons de réduction a été créée.

Important, elle s'applique sur tous les produits, a une durée de 30 jours et octroie 10% de remise au client.

En cliquant sur générer les coupons, on peut choisir le “Nombre de clients sélectionnés” et définir des règles sur lesquels ces bons seront générés. Je crée un filtre de base (2) et je pointe le modèle email précédemment créé (3) et pour faire gagner du temps au client je sauvegarde ce formulaire modifié pour le rendre par défaut grâce au menu debugging (4)

Résultat: quand le vendeur aura défini le mois en question, il enverra en masse des bons à tous les clients ayant ce mois dans leurs données.

Message dans le MyPortal (Cassé actuellement)

En relisant les notes, je me rends compte que cette fonctionnalité ne fonctionne plus actuellement en V15. Techniquement, on rajoutant un bloc (à remplir par le client) dans le Portail User pour le guider à un mini formulaire pour envoyer l'anniversaire par email au magasin (limitation du modèle saas).

Vue dans My Portal

Créer une vue héritée à portal.portal_my_home

<?xml version="1.0"?> <data name="Show anniversary banner" customize_show="True" inherit_id="portal.portal_my_home" priority="20"> <xpath expr="//div[hasclass('o_portal_docs')]" position="before"> <t t-if="not user_id.partner_id.x_studio_mois_de_lanniversaire"> <div class="oe_structure" id="oe_structure_portal_my_home_1" data-editor-message="AJOUTE ICI DU CONTENU POUR L’ANNIVERSAIRE"/> </t> </xpath> </data>

Faire le formulaire de contact

Dans Sites Web → Configuration → des Pages puis ouvrir Contact et ouvrir la vue Contact Us.

Cloner cette vue avec le contenu ci-dessous

<t name="Contact Us" t-name="website.contactus"> <t t-call="website.layout"> <t t-set="logged_partner" t-value="request.env['website.visitor']._get_visitor_from_request().partner_id"/> <t t-set="contactus_form_values" t-value="{ 'email_to': res_company.email, 'name': request.params.get('name', ''), 'phone': request.params.get('phone', ''), 'email_from': request.params.get('email_from', ''), 'company': request.params.get('company', ''), 'subject': request.params.get('subject', ''), }"/> <span class="hidden" data-for="contactus_form" t-att-data-values="contactus_form_values"/> <div id="wrap" class="oe_structure oe_empty"> <section class="s_title parallax s_parallax_is_fixed bg-black-50 pt24 pb24 o_colored_level" data-vcss="001" data-snippet="s_title" data-scroll-background-ratio="1" data-name="Title" style="background-image: none;"> <span class="s_parallax_bg oe_img_bg" style="background-image: url('/web/image/website.s_banner_default_image'); background-position: 50% 0;"/> <div class="o_we_bg_filter bg-black-50"/> <div class="container"> <h1>Indiquez-nous votre mois d'anniversaire<br/></h1> </div> </section> <section class="s_text_block pt40 pb40 o_colored_level o_we_force_no_transition" data-snippet="s_text_block" data-name="Text" style="background-image: none;"> <div class="container s_allow_columns"> <div class="row" data-original-title="" title="" aria-describedby="tooltip736319"> <div class="col-lg-8 mt-4 mt-lg-0 o_colored_level"> <p>&amp;nbsp;Indiquez-nous le mois de votre naissance et recevez chaque à cette occasion chaque année une réduction de 10% à la Lingerie Pierre.<br/></p> <section class="s_website_form" data-vcss="001" data-snippet="s_website_form" data-name="Form"> <div class="container"> <form t-if="logged_partner" id="contactus_form" action="/website/form/" method="post" enctype="multipart/form-data" class="o_mark_required" data-mark="*" data-model_name="mail.mail" data-success-mode="redirect" data-success-page="/contactus-thank-you" data-pre-fill="true"> <div class="s_website_form_rows row s_col_no_bgcolor"> <div class="form-group col-12 s_website_form_field s_website_form_custom s_website_form_required" data-type="char" data-name="Field"> <!-- <div class="row s_col_no_resize s_col_no_bgcolor"> <label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="contact1"> <span class="s_website_form_label_content">Votre Nom</span> <span class="s_website_form_mark"> *</span> </label> <div class="col-sm">--> <input id="contact1" type="hidden" class="form-control s_website_form_input" name="name" required="" data-fill-with="name"/> <!-- </div> </div> </div> <div class="form-group col-12 s_website_form_field s_website_form_custom" data-type="char" data-name="Field" data-visibility-condition="" data-visibility-between=""> <div class="row s_col_no_resize s_col_no_bgcolor"> <label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="contact2"> <span class="s_website_form_label_content">Numéro de téléphone</span> </label> <div class="col-sm">--> <input id="contact2" type="hidden" class="form-control s_website_form_input" name="phone" data-fill-with="phone"/> <!-- </div> </div> </div> <div class="form-group col-12 s_website_form_field s_website_form_required" data-type="email" data-name="Field" data-visibility-condition="" data-visibility-between=""> <div class="row s_col_no_resize s_col_no_bgcolor"> <label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="contact3"> <span class="s_website_form_label_content">Votre adresse e-mail</span> <span class="s_website_form_mark"> *</span> </label> <div class="col-sm">--> <input id="contact3" type="hidden" class="form-control s_website_form_input" name="email_from" required="" data-fill-with="email"/> <!--</div> </div> </div> <div class="form-group col-12 s_website_form_field s_website_form_required" data-type="char" data-name="Field"> <div class="row s_col_no_resize s_col_no_bgcolor"> <label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="contact5"> </label> <div class="col-sm">--> <input id="contact5" type="hidden" class="form-control s_website_form_input" name="subject" value="Mise à jour du mois anniversaire" required=""/> <!-- </div> </div> </div> <div class="form-group col-12 s_website_form_field s_website_form_custom s_website_form_required" data-type="text" data-name="Field">--> <div class="row s_col_no_resize s_col_no_bgcolor"> <label class="col-form-label col-sm-auto s_website_form_label" style="width: 200px" for="contact6"> <span class="s_website_form_label_content">Mois de l'anniversaire</span> </label> <div class="col-sm"> <select id="contact6" name="description" required=""> <option value="Janvier">Janvier</option> <option value="Février">Février</option> <option value="Mars">Mars</option> <option value="Avril">Avril</option> <option value="Mai">Mai</option> <option value="Juin">Juin</option> <option value="Juillet">Juillet</option> <option value="Aout">Aout</option> <option value="Septembre">Septembre</option> <option value="Octobre">Octobre</option> <option value="Novembre">Novembre</option> <option value="Décembre">Décembre</option> </select> </div> </div> </div> <div class="form-group s_website_form_field col-12 s_website_form_dnone" data-name="Field"> <div class="row s_col_no_resize s_col_no_bgcolor"> <label class="col-form-label col-sm-auto s_website_form_label " style="width: 200px"> <span class="s_website_form_label_content"/> </label> <div class="col-sm"> <input type="hidden" class="form-control s_website_form_input" name="email_to" value="vincent@makeitsimple.be"/> <div class="s_website_form_field_description small form-text text-muted"> Séparez les adresses email par une virgule. </div> </div> </div> </div> <div class="form-group col-12 s_website_form_submit" data-name="Submit Button"> <div style="width: 200px;" class="s_website_form_label"/> <a href="#" role="button" class="btn btn-primary btn-lg s_website_form_send">Soumettre</a> <span id="s_website_form_result"/> </div> </div> </form> <t t-if="not logged_partner"> Vous devez être connecté pour mettre à jour votre mois d'anniversaire. </t> </div> </section> </div> <div class="col-lg-4 mt-4 mt-lg-0 o_colored_level o_we_force_no_transition"> <ul class="list-unstyled mb-0 pl-2"> <p> <span style="font-size: 24px;font-weight: bolder"> <font class="text-o-color-2" style="font-size: 24px">Lingerie PIERRE</font> </span> </p> <p> <i class="fa fa-map-marker fa-fw"/> <span style="font-size: 18px">Rue Haute 6 - 1300 Wavre - BELGIUM</span> <i class="fa fa-phone fa-fw o_we_force_no_transition" style="font-size: 18px" data-original-title="" title="" aria-describedby="tooltip776564"/> <span style="font-size: 18px">+ 32 (0)10 22 23 82</span> <br/> <i class="fa fa-1x fa-fw fa-envelope" style="font-size: 18px" data-original-title="" title="" aria-describedby="tooltip461111"/> <span style="font-size: 18px">info@lingerie-pierre.com</span> </p> <p> <br/> </p> <p> <span style="font-weight: bolder"> <font class="text-o-color-2" style="font-size: 24px">HORAIRE</font> </span> </p> <p>Lundi 9h - 18h</p> <p>Mardi 9h - 18h</p> <p>Mercredi 9h - 18h</p> <p>Jeudi 9h - 18h</p> <p>Vendredi 9h - 18h</p> <p>Samedi 9h - 18h</p> <li> <br/> </li> </ul> </div> </div> </div> </section> </div> </t> </t>