+ """
+ if CONTEXT.debug:
+ print(("ETAPE.isValid ", self.nom))
+ if self.state == 'unchanged':
+ return self.valid
+ else:
+ valid = 1
+ # On marque les concepts CO pour verification ulterieure de leur
+ # bonne utilisation
+ l = self.getAllCo()
+ # On verifie que les concepts CO sont bien passes par typeSDProd
+ for c in l:
+ # if c.etape is self.parent:
+ if c.isTypCO() != 2:
+ # le concept est propriete de l'etape parent
+ # Il n'a pas ete transforme par typeSDProd
+ # Cette situation est interdite
+ # Pb: La macro-commande a passe le concept a une commande
+ # (macro ?) mal definie
+ if cr == 'oui':
+ self.cr.fatal("Macro-commande mal definie : le concept n'a pas ete type par un appel a typeSDProd pour %s" % c.nom)
+ valid = 0
+
+ valid = valid * self.validChild()
+ valid = valid * self.validRegles(cr)
+
+ if self.reste_val != {}:
+ if cr == 'oui':
+ self.cr.fatal(
+ "unknown keyword : %s" %','.join(list(self.reste_val.keys())))
+ valid = 0
+
+ if sd == "non":
+ # Dans ce cas, on ne calcule qu'une validite partielle, on ne modifie pas l'etat de self
+ # on retourne simplement l'indicateur valid
+ return valid
+
+ if self.sd != None:
+ valid = valid * self.validSdnom(cr)
+
+ if self.definition.reentrant == 'n' and self.reuse:
+ # Il ne peut y avoir de concept reutilise avec une MACRO non
+ # reentrante
+ if cr == 'oui': self.cr.fatal(
+ 'Macro-commande non reentrante : ne pas utiliser reuse')
+ valid = 0
+
+ if valid:
+ valid = self.updateSdprod(cr)
+
+ # Si la macro comprend des etapes internes, on teste leur validite
+ for e in self.etapes:
+ if not e.isValid():
+ valid = 0
+ break
+
+ self.setValid(valid)
+
+ return self.valid
+
+ def updateSdprod(self, cr='non'):
+ """
+ Cette methode met a jour le concept produit en fonction des conditions initiales :
+
+ 1. Il n'y a pas de concept retourne (self.definition.sd_prod == None)
+
+ 2. Le concept retourne n existait pas (self.sd == None)
+
+ 3. Le concept retourne existait. On change alors son type ou on le supprime
+
+ En cas d'erreur (exception) on retourne un indicateur de validite de 0 sinon de 1
+ """
+ sd_prod = self.definition.sd_prod
+ # On memorise le type retourne dans l attribut typret
+ self.typret = None
+ if type(sd_prod) == types.FunctionType:
+ # Type de concept retourne calcule
+ d = self.creeDictValeurs(self.mcListe)
+ try:
+ # la sd_prod d'une macro a l'objet lui meme en premier argument
+ # contrairement a une ETAPE ou PROC_ETAPE
+ # Comme sd_prod peut invoquer la methode typeSDProd qui ajoute
+ # les concepts produits dans self.sdprods, il faut le mettre a
+ # zero
+ self.sdprods = []
+ sd_prod = sd_prod(*(self,), **d)
+ except:
+ # Erreur pendant le calcul du type retourne
+ if CONTEXT.debug:
+ traceback.print_exc()
+ self.sd = None
+ if cr == 'oui':
+ l = traceback.format_exception(sys.exc_info()[0],
+ sys.exc_info()[1],
+ sys.exc_info()[2])
+ self.cr.fatal( 'Impossible d affecter un type au resultat\n%s' % ' '.join(l[2:]))
+ return 0
+ # on teste maintenant si la SD est reutilisee ou s'il faut la
+ # creer