@@ -197,3 +197,51 @@ def clean(self, value):
197197 raise ValidationError (self .error_messages ['invalid' ])
198198
199199 return orig_value
200+
201+
202+ def mod_97_base10 (value ):
203+ return 98 - ((value * 100 % 97 ) % 97 )
204+
205+
206+ class BRProcessoField (CharField ):
207+ """
208+ A form field that validates a Legal Process(Processo) number or a Legal Process string.
209+ A Processo number is
210+ compounded by NNNNNNN-DD.AAAA.J.TR.OOOO. The two DD digits are check digits.
211+ More information:
212+ http://www.cnj.jus.br/atos-administrativos/12179:resolucao-no-65-de-16-de-dezembro-de-2008
213+ """
214+ default_error_messages = {
215+ 'invalid' : _ ("Invalid Process number." ),
216+ 'max_digits' : _ ("This field requires at most 20 digits or 25 characters." ),
217+ 'digits_only' : _ ("This field requires only numbers." ),
218+ }
219+
220+ def __init__ (self , max_length = 25 , min_length = 20 , * args , ** kwargs ):
221+ super (BRProcessoField , self ).__init__ (max_length , min_length , * args , ** kwargs )
222+
223+ def clean (self , value ):
224+ """
225+ Value can be either a string in the format NNNNNNN-DD.AAAA.J.TR.OOOO or an
226+ 20-digit number.
227+ """
228+ value = super (BRProcessoField , self ).clean (value )
229+ if value in EMPTY_VALUES :
230+ return ''
231+ orig_value = value [:]
232+ if not value .isdigit ():
233+ value = re .sub ("[-\. ]" , "" , value )
234+ try :
235+ int (value )
236+ except ValueError :
237+ raise ValidationError (self .error_messages ['digits_only' ])
238+ if len (value ) != 20 :
239+ raise ValidationError (self .error_messages ['max_digits' ])
240+ orig_dv = value [7 :9 ]
241+
242+ value_without_digits = int (value [0 :7 ] + value [9 :])
243+
244+ if str (mod_97_base10 (value_without_digits )).zfill (2 ) != orig_dv :
245+ raise ValidationError (self .error_messages ['invalid' ])
246+
247+ return orig_value
0 commit comments