2 # person_in_charge: mathieu.courtois at edf.fr
3 # ======================================================================
4 # COPYRIGHT (C) 1991 - 2015 EDF R&D WWW.CODE-ASTER.ORG
5 # THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
6 # IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
7 # THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
8 # (AT YOUR OPTION) ANY LATER VERSION.
10 # THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
11 # WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
12 # MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
13 # GENERAL PUBLIC LICENSE FOR MORE DETAILS.
15 # YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
16 # ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
17 # 1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
20 # ======================================================================
24 Ce module contient la classe mixin ETAPE qui porte les méthodes
25 nécessaires pour réaliser la validation d'un objet de type ETAPE
28 Une classe mixin porte principalement des traitements et est
29 utilisée par héritage multiple pour composer les traitements.
39 from Noyau import MAXSIZE, MAXSIZE_MSGCHK
40 from Noyau.N_Exception import AsException
41 from Noyau.N_utils import AsType
42 from Noyau.strfunc import ufmt
43 from Extensions.i18n import tr
47 class ETAPE(V_MCCOMPO.MCCOMPO):
52 def valid_child(self):
53 """ Cette methode teste la validite des mots cles de l'etape """
54 for child in self.mc_liste:
55 if not child.isvalid():
59 def valid_regles(self, cr):
60 """ Cette methode teste la validite des regles de l'etape """
61 text_erreurs, test_regles = self.verif_regles()
65 _(u"Règle(s) non respectée(s) : %s"), text_erreurs)
69 def valid_sdnom(self, cr):
70 """ Cette methode teste la validite du nom du concept produit par l'etape """
72 if self.sd.nom != None:
73 if self.jdc and self.jdc.definition.code == 'ASTER' and len(self.sd.nom) > 8:
74 # le nom de la sd doit avoir une longueur <= 8 caractères pour
78 _(u"Le nom de concept %s est trop long (8 caractères maxi)"),
81 if self.sd.nom.find('sansnom') != -1:
82 # la SD est 'sansnom' : --> erreur
84 #self.cr.fatal(_(u"Pas de nom pour le concept retourné"))
85 self.cr.fatal(_("object must have a name"))
87 elif re.search('^SD_[0-9]*$', self.sd.nom):
88 # la SD est 'SD_' cad son nom = son id donc pas de nom donné
89 # par utilisateur : --> erreur
92 #_(u"Nom de concept invalide ('SD_' est réservé)"))
93 _("invalid name ('SD_' is a reserved keyword)"))
98 if hasattr(self, 'valid'):
104 def set_valid(self, valid):
105 old_valid = self.get_valid()
107 self.state = 'unchanged'
108 if not old_valid or old_valid != self.valid:
111 def isvalid(self, sd='oui', cr='non'):
113 Methode pour verifier la validité de l'objet ETAPE. Cette méthode
114 peut etre appelée selon plusieurs modes en fonction de la valeur
117 Si cr vaut oui elle crée en plus un compte-rendu.
119 Cette méthode a plusieurs fonctions :
121 - mettre à jour l'état de self (update)
123 - retourner un indicateur de validité 0=non, 1=oui
125 - produire un compte-rendu : self.cr
129 print "ETAPE.isvalid ", self.nom
130 if self.state == 'unchanged':
133 valid = self.valid_child()
134 valid = valid * self.valid_regles(cr)
136 if self.reste_val != {}:
139 #_(u"Mots clés inconnus : %s"), ','.join(self.reste_val.keys()))
140 _("unknown keywords : %s"), ','.join(self.reste_val.keys()))
144 # Dans ce cas, on ne teste qu'une validité partielle (sans tests sur le concept produit)
145 # Conséquence : on ne change pas l'état ni l'attribut valid, on retourne simplement
146 # l'indicateur de validité valid
149 if self.definition.reentrant == 'n' and self.reuse:
150 # Il ne peut y avoir de concept reutilise avec un OPER non
154 _(u'Opérateur non réentrant : ne pas utiliser reuse'))
158 # Le concept produit n'existe pas => erreur
160 # self.cr.fatal(_(u"Concept retourné non défini"))
161 self.cr.fatal(_("Concept is not defined"))
164 valid = valid * self.valid_sdnom(cr)
167 valid = self.update_sdprod(cr)
169 self.set_valid(valid)
173 def update_sdprod(self, cr='non'):
175 Cette méthode met à jour le concept produit en fonction des conditions initiales :
177 1. Il n'y a pas de concept retourné (self.definition.sd_prod == None)
179 2. Le concept retourné n existait pas (self.sd == None)
181 3. Le concept retourné existait. On change alors son type ou on le supprime
183 En cas d'erreur (exception) on retourne un indicateur de validité de 0 sinon de 1
185 sd_prod = self.definition.sd_prod
186 if type(sd_prod) == types.FunctionType: # Type de concept retourné calculé
187 d = self.cree_dict_valeurs(self.mc_liste)
189 sd_prod = apply(sd_prod, (), d)
191 # Erreur pendant le calcul du type retourné
193 traceback.print_exc()
196 l = traceback.format_exception(sys.exc_info()[0],
200 #_(u'Impossible d affecter un type au résultat\n %s'), ' '.join(l[2:]))
201 _('unable to affect type to concept\n %s'), ' '.join(l[2:]))
203 # on teste maintenant si la SD est r\351utilis\351e ou s'il faut la
207 if AsType(self.reuse) != sd_prod:
210 _(u'Type de concept réutilisé incompatible avec type produit'))
213 if self.sdnom[0] != '_' and self.reuse.nom != self.sdnom:
214 # Le nom de la variable de retour (self.sdnom) doit etre le
215 # meme que celui du concept reutilise (self.reuse.nom)
217 self.cr.fatal(_(u'Concept réutilisé : le nom de la variable de '
218 u'retour devrait être %s et non %s'),
219 self.reuse.nom, self.sdnom)
224 if sd_prod == None: # Pas de concept retourné
225 # Que faut il faire de l eventuel ancien sd ?
229 # Un sd existe deja, on change son type
231 print "changement de type:", self.sd, sd_prod
232 if self.sd.__class__ != sd_prod:
233 self.sd.change_type(sd_prod)
235 # Le sd n existait pas , on ne le crée pas
237 self.cr.fatal(_(u"Concept retourné non défini"))
239 if self.definition.reentrant == 'o':
242 _(u'Commande obligatoirement réentrante : spécifier reuse=concept'))
248 Methode pour generation d un rapport de validite
250 #self.cr = self.CR(debut=u'Etape : ' + self.nom
251 # + u' ligne : ' + `self.appel[0]`
252 # + u' fichier : ' + `self.appel[1]`,
253 # fin=u'Fin Etape : ' + self.nom)
254 self.cr = self.CR(debut=u'Command : ' + tr(self.nom)
255 + u' line : ' + `self.appel[0]`
256 + u' file : ' + `self.appel[1]`,
257 fin=u'End Command : ' + tr(self.nom))
258 self.state = 'modified'
260 self.isvalid(cr='oui')
261 except AsException, e:
263 traceback.print_exc()
264 #self.cr.fatal(_(u'Etape : %s ligne : %r fichier : %r %s'),
265 # self.nom, self.appel[0], self.appel[1], e)
266 self.cr.fatal(_(u'Command : %s line : %r file : %r %s'),
267 tr(self.nom), self.appel[0], self.appel[1], e)
269 for child in self.mc_liste:
272 print(MAXSIZE_MSGCHK.format(MAXSIZE, len(self.mc_liste)))
274 self.cr.add(child.report())