Partage
  • Partager sur Facebook
  • Partager sur Twitter

Appeler une fonction sans surcharger une méthode

Odoo 10 - Python

Sujet résolu
    23 mai 2019 à 16:38:48

    Bonjour,

    Voici ma fonction : 

        @api.multi()
        def call_method_prepare_files_for_onde(self):
            for record in self:
                if record.school_statut == "valid":
                    if record.school_send_onde and record.school_date_status == fields.Date.today():
                        record.prepare_files_for_onde()


    Je souhaite appeler cette méthode call_method_prepare_files_for_onde() lorsque les champs suivants school_statut, school_send_onde, school_date_status sont touchés, mais après sauvegarde du formulaire (donc pas comme dans un onChange()) et sans surcharger de la méthode write(). 

    Est-ce possible ? 

    EDIT : 

    Ou alors surcharger la méthode write() et faire une mise à jour QUE si l'un des 3 champs sont touchés

    Merci

    -
    Edité par KévinH 23 mai 2019 à 16:59:15

    • Partager sur Facebook
    • Partager sur Twitter
      23 mai 2019 à 18:58:15

      Plusieurs possibilités :

      - La meilleure solution est probablement de faire la mise à jour dans le write, tu regardes ce qu'il y a dans vals pour savoir si les champs ont changé.

      - Avec un cron, mais ça ne sera pas immédiat

      - Avec api.constrains, ça peut s'avérer pratique mais je l'utilise rarement car ce n'est pas fait pour ça, et il faut faire gaffe aux appels récursifs.

      • Partager sur Facebook
      • Partager sur Twitter
        24 mai 2019 à 11:50:02

        Bonjour, 

        J'appelle donc cette méthode dans la méthode write() comme ceci : 

        # Appel cette méthode quand on modifie un enregistrement
            @api.multi
            def write(self, vals):
                result = super(ResPartnerSchool, self).write(vals)
                self.prepare_files_for_onde()
                return result


        Jusque là pas de problème. 

        Et si je comprend bien. Ici le vals vaut tous les champs de mon formulaire et les mets à jour. Et ce, pour chaques modifications des valeurs du formulaire.

        Maintenant, et en réfléchissant à la bonne procédure pour ma fonction, je souhaite que la méthode prepare_files_to_onde() soit appelée qu'une seule fois pour un partner dans la méthode write(). C'est à dire que si je re-modifie une seconde fois les valeurs du formulaire pour ce même partner, je ne souhaite pas appeler la méthode prepare_file_for_onde().

        Est ce que c'est possible ? 

        Merci pour ton aide ! 

        -
        Edité par KévinH 24 mai 2019 à 11:50:34

        • Partager sur Facebook
        • Partager sur Twitter
          24 mai 2019 à 11:58:36

          Là ça n'a pas tellement de sens... la seule manière c'est d'ajouter un champs type booléen pour savoir si le record a déjà été modifié.

          Mais ta demande était d'appeler la fonction seulement si certains champs sont modifiés, il faut donc regarder s'ils sont dans vals (vals ne contient en principe que les champs modifiés) :

              # Appel cette méthode quand on modifie un enregistrement
              @api.multi
              def write(self, vals):
                  result = super(ResPartnerSchool, self).write(vals)
                  if vals.keys() & {"school_statut", "school_send_onde", "school_date_status"}:
                      self.prepare_files_for_onde()
                  return result

          Parfois il suffit de modifier vals, par exemple si je veux qu'un champs s'enregistre toujours en majuscules :

              @api.multi
              def write(self, vals):
                  if vals.get("name"):
                      vals["name"] = vals["name"].upper()
                  return super(ResPartnerSchool, self).write(vals)
          



          Au fait utilises-tu pdb ? C'est hyper utile pour débuguer en python, je l'utilise tout le temps sur Odoo.

              @api.multi
              def write(self, vals):
                  import pdb; pdb.set_trace()  # code qui va marquer une pause et me permettre de faire ce que je veux
                  return super(ResPartnerSchool, self).write(vals)



          -
          Edité par thelinekioubeur 24 mai 2019 à 12:03:36

          • Partager sur Facebook
          • Partager sur Twitter
            24 mai 2019 à 14:14:09

            J'utilises PyCharm pour le debug mais merci je ne connaissais pas !

            Il y a une erreur par rapport à ton premier exemple. 

            Voici l'erreur :

            TypeError: unsupported operand type(s) for &: 'list' and 'set' 

            Voici mon code : peut être que je l'utilises mal ? 

            # Appel cette méthode quand on modifie un enregistrement
                @api.multi
                def write(self, vals):
                    result = super(ResPartnerSchool, self).write(vals)
                    self.no_duplicate_school_dates()
                    if not self.env.context.get('tracking_disable'):
                        self.smart_synchronization()
                        if vals.keys() & {"school_statut", "school_send_onde", "school_date_status"}:
                            self.prepare_files_for_onde()
                    return result



            Je travaille sous Odoo 10.

            EDIT : 

            J'ai résolu enfin mon problème d'appel de fonction : 

            Voici la réponse : 

                # Appel cette méthode quand on créé un nouvel enregistrement
                @api.model
                def create(self, vals):
                    record = super(ResPartnerSchool, self).create(vals)
                    record.no_duplicate_school_dates()
                    # Permet de ne pas appelé cette fonction si c'est une importation de données
                    if not self.env.context.get('tracking_disable'):
                        record.smart_synchronization()
                        if vals.get('school_statut') == "valid" and vals.get('school_send_onde'):
                            record.prepare_files_for_onde()
                    return record
            
            # Appel cette méthode quand on modifie un enregistrement
                @api.multi
                def write(self, vals):
                    result = super(ResPartnerSchool, self).write(vals)
                    self.no_duplicate_school_dates()
                    if not self.env.context.get('tracking_disable'):
                        self.smart_synchronization()
                        if vals.get('school_statut') == "valid" and vals.get('school_send_onde'):
                            self.prepare_files_for_onde()
                    return result
            

            Merci encore !

            -
            Edité par KévinH 24 mai 2019 à 14:40:35

            • Partager sur Facebook
            • Partager sur Twitter
              24 mai 2019 à 15:51:49

              Pour l'erreur j'avais oublié que keys renvoyait une liste sur python2, il faut mettre set(vals.keys()) à la place.

              Mais comme tu as fait c'est OK.

              • Partager sur Facebook
              • Partager sur Twitter

              Appeler une fonction sans surcharger une méthode

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown