Chapitre 6 : Création d’un module sur Odoo (part 15)

Enregistrement de séquence dans Odoo

En Odoo, le concept de « sequence record » fait référence à une séquence numérique ou un compteur utilisé pour générer des numéros de référence uniques pour les enregistrements. Il permet d’attribuer automatiquement des valeurs de séquence à des champs spécifiques dans les enregistrements.

L’utilisation d’une séquence record est courante dans de nombreux modules Odoo, notamment pour les numéros de facture, les codes de produits, les références de commande, etc. L’objectif est de garantir que chaque enregistrement possède un identifiant unique et ordonné.

Les séquences record peuvent être définies dans Odoo en utilisant le modèle de données « ir.sequence ». Vous pouvez créer une séquence en spécifiant différents paramètres tels que le préfixe, le suffixe, l’incrément, la longueur du nombre, etc.

Lorsqu’une séquence record est associée à un champ dans un modèle, chaque fois qu’un nouvel enregistrement est créé, la séquence génère automatiquement un numéro de référence unique et l’assigne au champ correspondant. Cela permet d’éviter les conflits de numérotation et facilite la recherche et l’identification des enregistrements.

Par exemple, si vous avez une séquence record définie pour les numéros de facture, chaque fois qu’une nouvelle facture est créée, la séquence générera automatiquement un numéro de facture unique pour cette facture, en respectant l’ordre de la séquence définie.

Les séquences record sont un mécanisme puissant dans Odoo pour gérer l’attribution automatique de numéros de référence uniques et ordonnés. Elles contribuent à la gestion efficace des données et à l’amélioration de la traçabilité des enregistrements.

La création de numéros de séquence est un processus très simple. Nous pouvons identifier chaque enregistrement à l’aide de son numéro de séquence, qui sera unique pour chaque enregistrement..

Pour cela, il faut tout d’abord créer un champ pour stocker la séquence

Exemple:

reference_no = fields.Char(string='Order Reference', required=True,
                          readonly=True, default=lambda self: _('New'))

Et ajoutez une fonction pour la séquence comme indiqué dans le code suivant.

@api.model
def create(self, vals):
   if vals.get('reference_no', _('New')) == _('New'):
       vals['reference_no'] = self.env['ir.sequence'].next_by_code(
           'hospital.patient') or _('New')
   res = super(HospitalPatient, self).create(vals)
   return res

Créez ensuite un enregistrement pour cela et créez un fichier XML pour cela.

<data>
   <record id="seq_hospital_patient" model="ir.sequence">
       <field name="name">Patient Sequence</field>
       <field name="code">hospital.patient</field>
       <field name="prefix">HP</field>
       <field name="padding">5</field>
       <field name="company_id" eval="False"/>
   </record>
</data>

Le code XML doit se trouver à l’intérieur d’une balise de données.

<record id="seq_hospital_patient" model="ir.sequence">

L’ID est l’ID de cet enregistrement, il est unique pour chaque enregistrement. Cet enregistrement sera stocké dans le tableau ir.sequence.

<field name="name">Patient Sequence</field>

name – est le nom de l’enregistrement qui sera créé sur le modèle spécifié.

<field name="code">hospital.patient</field>

Code – est le code de séquence de l’enregistrement.

<field name="prefix">HP</field>

Prefix – champ de caractères indiquant le préfixe de la séquence de l’enregistrement.

<field name="padding">5</field>

Padding – est la taille de la séquence. Nous pouvons décider de la taille.

Dans la capture d’écran ci-dessous, nous pouvons voir qu’un numéro de séquence est généré avec un préfixe HP et le numéro est 00001. Le premier numéro est automatiquement généré comme 1 et nous créons un autre enregistrement dans le même modèle qui sera 2 et ainsi de suite et nous pouvons également voir ici que le padding du numéro est 5 que nous allons mentionner dans le code.

how-to-create-sequence-number-in-odoo-15

Nous pouvons configurer le numéro de séquence à partir des paramètres généraux d’Odoo

Allez dans General Settings > Technical > Sequences & Identifiers > Sequences

Dans la capture d’écran ci-dessous, nous pouvons voir tous les numéros de séquence qui sont créés pour certains enregistrements. Nous pouvons directement créer un numéro de séquence à partir du frontend en cliquant sur le bouton de création.

how-to-create-sequence-number-in-odoo-15

Dans la capture d’écran ci-dessous, nous pouvons voir qu’un enregistrement est créé conformément au code ci-dessus.

how-to-create-sequence-number-in-odoo-15

Il contient les détails de l’enregistrement tels que le nom, le code, le préfixe, le suffixe, la taille de la séquence, le pas, le numéro suivant, etc.

Pour les numéros de séquence, il existe deux méthodes de mise en œuvre, à savoir 

  • Standard
  • Pas d’écart

Pas d’écart signifie qu’il n’y a pas d’écart entre les numéros de séquence de chaque enregistrement.

Par exemple, un enregistrement est créé pour la séquence Patient, le numéro de séquence est HP00001, et un autre enregistrement est créé, il s’agit de HP00002. Nous supprimons ensuite le deuxième enregistrement et en créons un troisième. Dans le cas de la méthode d’implémentation No gap, le numéro de séquence sera HP00001, mais dans le cas de l’implémentation standard, le numéro de séquence sera HP00003.  Dans la plupart des cas, nous utilisons l’implémentation standard.  

En activant l’option « Use subsequences per date_rage », nous pouvons définir la plage de dates pour les séquences.

how-to-create-sequence-number-in-odoo-15

Activité :

  1. Créez un fichier nommé sequence.xml dans le dossier data de votre module personnalisé. Assurez-vous que le chemin complet du fichier est nom_du_module/data/sequence.xml.
  2. Dans le fichier sequence.xml, ajoutez le code XML suivant pour définir votre séquence :
<odoo>
    <data>
        <record id="sequence_hospital_patient" model="ir.sequence">
            <field name="name">Patient Sequence</field>
            <field name="code">hospital.patient</field>
            <field name="prefix">PAT-</field>
            <field name="padding">4</field>
        </record>
    </data>
</odoo>

Dans cet exemple, nous avons défini une séquence nommée « Patient Sequence » avec le code hospital.patient.sequence. Le préfixe est défini comme « PAT- » et la longueur du nombre est de 4 chiffres. L’implémentation est configurée pour no_gap, ce qui signifie qu’il n’y aura pas de lacunes dans la séquence.

  1. Dans le fichier __manifest__.py, ajoutez le chemin du fichier sequence.xml à la liste des fichiers de données du module. Vous devez ajouter cette ligne dans la section data du fichier __manifest__.py, par exemple :
'data': [
    'data/sequence.xml',
],
  1. Mettez à jour votre application Odoo pour prendre en compte les modifications. Vous pouvez le faire en redémarrant le serveur Odoo ou en utilisant l’interface utilisateur d’Odoo pour mettre à jour le module.
  2. Une fois la mise à jour terminée, accédez à Odoo et allez dans Paramètres -> Technique -> Séquence. Vous devriez voir votre séquence « Patient Sequence » répertoriée. Vous pouvez vérifier les détails de la séquence, tels que le préfixe, la longueur du nombre, etc.

En suivant ces étapes, vous aurez créé un fichier sequence.xml qui définit une séquence personnalisée et l’aurez ajouté aux données de votre module. Après la mise à jour de l’application, vous pourrez vérifier l’existence de votre séquence dans les paramètres d’Odoo.

noupdata

L’attribut noupdate est utilisé dans la balise <data> pour indiquer que les enregistrements contenus dans cette section ne doivent pas être modifiés lors d’une mise à jour ultérieure du module.

Lorsque vous ajoutez l’attribut noupdate="1" à la balise <data>, vous indiquez à Odoo de ne pas mettre à jour les enregistrements contenus dans cette section lors de la mise à jour du module. Cela signifie que les enregistrements spécifiés dans la balise <data> seront préservés tels quels, sans modification ni suppression, même si le module est mis à jour.

Voici un exemple de l’utilisation de noupdate dans la balise <data> :

<data noupdate="1">
    <!-- Enregistrements à ne pas mettre à jour -->
    <record id="sequence_hospital_patient" model="ir.sequence">
         <field name="name">Patient Sequence</field>
         <field name="code">hospital.patient.sequence</field>
         <field name="prefix">PAT-</field>
         <field name="padding">4</field>
         <field name="implementation">no_gap</field>

    </record>

    <record id="my_record_1" model="my.model">
        <!-- Champs et valeurs -->
    </record>
    <record id="my_record_2" model="my.model">
        <!-- Champs et valeurs -->
    </record>
    <!-- Autres enregistrements -->
</data>

Dans cet exemple, les enregistrements avec les identifiants my_record_1 et my_record_2 ne seront pas modifiés lors de la mise à jour du module, car ils sont inclus dans la balise <data> avec l’attribut noupdate="1".

L’utilisation de noupdate peut être utile lorsque vous souhaitez conserver certains enregistrements spécifiques dans votre module, même lors de mises à jour ultérieures. Cela vous permet de préserver les données ou les configurations personnalisées associées à ces enregistrements.

Activité :

  1. Ouvrez le fichier « patient.py » correspondant au modèle « HospitalPatient ».
  2. Ajoutez le champ « ref » avec les attributs nécessaires dans la classe « HospitalPatient ».
   ref = fields.Char(string='Reference', default=lambda self: _('new'))

Dans cet exemple, nous utilisons un champ de type « Char » avec une étiquette « Reference ». La valeur par défaut est définie en utilisant une fonction lambda qui renvoie simplement la chaîne « new ». De plus, nous avons ajouté l’attribut « readonly=True » pour rendre le champ en lecture seule.

  1. Ouvrez le fichier XML correspondant à la vue formulaire du modèle « patient ».
  2. Ajoutez les balises <oe_title> et <h1> autour du champ « ref » pour l’afficher de manière stylisée.
   <record id="view_hospital_patient_form" model="ir.ui.view">
       <field name="name">hospital.patient.form</field>
       <field name="model">hospital.patient</field>
       <field name="arch" type="xml">
           <form>
               <sheet>
                   <div class="oe_title">
                       <h1>
                           <field name="ref" readonly="1"/>
                       </h1>
                   </div>
                   <!-- Autres champs du formulaire -->
               </sheet>
           </form>
       </field>
   </record>

Dans cet exemple, nous avons enveloppé le champ « ref » avec les balises <oe_title> et <h1>. Le paramètre « readonly » est défini sur « 1 » pour rendre le champ en lecture seule.

  1. Enregistrez les modifications apportées aux fichiers « patient.py » et au fichier XML de la vue formulaire, puis mettez à jour votre application pour prendre en compte les modifications.

Maintenant, lorsque vous affichez le formulaire du patient, le champ « ref » sera affiché avec une mise en forme spéciale en utilisant les balises <oe_title> et <h1>, et il sera en lecture seule, ce qui signifie qu’il ne pourra pas être modifié.

Activité :

  1. Ouvrez le fichier « patient.py » correspondant au modèle « HospitalPatient ».
  1. Dans la classe « HospitalPatient », ajoutez une nouvelle méthode « create » pour remplacer la méthode par défaut.
   @api.model
   def create(self, vals_list):
       for vals in vals_list:
           vals['ref'] = self.env['ir.sequence'].next_by_code('hospital.patient')
       return super(HospitalPatient, self).create(vals_list)

Dans cet exemple, nous utilisons la méthode « next_by_code » de la classe « ir.sequence » pour récupérer le prochain numéro de séquence basé sur le code « hospital.patient ». Ensuite, nous mettons à jour le dictionnaire « vals » avec la valeur de « ref » avant d’appeler la méthode « create » de la classe parente.

  1. Enregistrez les modifications apportées au fichier « patient.py ».

Maintenant, lorsque vous créez un nouveau patient, le champ « ref » sera automatiquement rempli avec le prochain numéro de séquence généré par le fichier de séquence associé au code « hospital.patient ».