← Back to team overview

openerp-brazil-team team mailing list archive

lp:~santagada-proge/openerp.pt-br-localiz/l10n_br_inscr_est_refatorada into lp:openerp.pt-br-localiz

 

Leonardo Santagada @ Proge.com.br has proposed merging lp:~santagada-proge/openerp.pt-br-localiz/l10n_br_inscr_est_refatorada into lp:openerp.pt-br-localiz.

Requested reviews:
  OpenERP Brazil Team (openerp-brazil-team)

For more details, see:
https://code.launchpad.net/~santagada-proge/openerp.pt-br-localiz/l10n_br_inscr_est_refatorada/+merge/95037

Inscrições estaduais funcionando com um metodo parametrizavel ou com rotinas especificas caso elas se comportem muito diferente do modo comum.
-- 
https://code.launchpad.net/~santagada-proge/openerp.pt-br-localiz/l10n_br_inscr_est_refatorada/+merge/95037
Your team OpenERP Brazil Team is requested to review the proposed merge of lp:~santagada-proge/openerp.pt-br-localiz/l10n_br_inscr_est_refatorada into lp:openerp.pt-br-localiz.
=== modified file 'l10n_br_base/partner.py'
--- l10n_br_base/partner.py	2012-01-25 15:28:29 +0000
+++ l10n_br_base/partner.py	2012-02-28 20:27:21 +0000
@@ -18,10 +18,71 @@
 #################################################################################
 
 import re
-import string
-
 from osv import osv, fields
 
+parametros = {
+    'ac': {'tam': 13, 'val_tam': 11, 'starts_with': '01'},
+    'al': {'tam': 9, 'starts_with': '24'},
+    'am': {'tam': 8},
+    'ce': {'tam': 9},
+    'al': {'tam': 13, 'val_tam': 11, 'starts_with': '07'},
+    'es': {'tam': 9},
+    'ma': {'tam': 9, 'starts_with': '12'},
+    'ms': {'tam': 9, 'starts_with': '28'},
+    'mt': {'tam': 11},
+    'pa': {'tam': 9, 'starts_with': '15'},
+    'pb': {'tam': 9},
+    'pi': {'tam': 9},
+    'pr': {'tam': 10, 'val_tam': 8, 'prod': [3, 2, 7, 6, 5, 4, 3, 2]},
+    'rj': {'tam': 8, 'prod': [2, 7, 6, 5, 4, 3, 2]},
+    'rn': {'tam': [9, 10], 'val_tam': [8, 9]},
+    'rr': {'tam': 9, 'starts_with': '24', 'prod': [1, 2, 3, 4, 5, 6, 7, 8]},
+    'rs': {'tam': 10},
+    'sc': {'tam': 9},
+    'se': {'tam': 9},
+    }
+
+
+def validate_ie_param(uf, inscr_est):
+    if not uf in parametros:
+        return True
+
+    inscr_est = re.sub('[^0-9]', '', inscr_est)
+    tam = parametros[uf]['tam']
+    val_tam = parametros[uf].get('val_tam', tam - 1)
+
+    if isinstance(tam, list):
+        i = tam.find(len(inscr_est))
+        if i == -1:
+            return False
+        else:
+            val_tam = val_tam[i]
+    else:
+        if len(inscr_est) != tam:
+            return False
+
+    sw = parametros[uf].get('starts_with', '')
+    if not inscr_est.startswith(sw):
+        return False
+
+    inscr_est_ints = [int(c) for c in inscr_est]
+    nova_ie = inscr_est_ints[:val_tam]
+
+    prod = parametros[uf].get('prod', [5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2])
+    prod = prod[-val_tam:]
+    while len(nova_ie) < tam:
+        r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % 11
+        if r > 1:
+            f = 11 - r
+        else:
+            f = 0
+        nova_ie.append(f)
+        prod.insert(0, prod[0] + 1)
+
+    # Se o número gerado coincidir com o número original, é válido
+    return nova_ie == inscr_est_ints
+
+
 class res_partner(osv.osv):
 
     _inherit = 'res.partner'
@@ -33,17 +94,17 @@
         return result.keys()
 
     def _address_default_fs(self, cr, uid, ids, name, arg, context=None):
-        
+
         res = {}
         for partner in self.browse(cr, uid, ids, context=context):
             res[partner.id] = {'addr_fs_code': False}
-            
+
             partner_addr = self.pool.get('res.partner').address_get(cr, uid, [partner.id], ['invoice'])
             if partner_addr:
                 partner_addr_default = self.pool.get('res.partner.address').browse(cr, uid, [partner_addr['invoice']])[0]
                 addr_fs_code = partner_addr_default.state_id and partner_addr_default.state_id.code or ''
                 res[partner.id]['addr_fs_code'] = addr_fs_code.lower()
-                
+
         return res
 
     _columns = {
@@ -53,11 +114,11 @@
                 'inscr_mun': fields.char('Inscr. Municipal', size=18),
                 'suframa': fields.char('Suframa', size=18),
                 'legal_name' : fields.char('Razão Social', size=128, help="nome utilizado em documentos fiscais"),
-                'addr_fs_code': fields.function(_address_default_fs, method=True, 
-                                                string='Address Federal State Code', 
+                'addr_fs_code': fields.function(_address_default_fs, method=True,
+                                                string='Address Federal State Code',
                                                 type="char", size=2, multi='all',
                                                 store={'res.partner.address': (_get_partner_address, ['country_id', 'state_id'], 20),}),
-                
+
                 }
 
     _defaults = {
@@ -69,7 +130,7 @@
         for partner in self.browse(cr, uid, ids):
             if not partner.cnpj_cpf:
                 continue
-    
+
             if partner.tipo_pessoa == 'J':
                 if not self._validate_cnpj(partner.cnpj_cpf):
                     return False
@@ -80,16 +141,16 @@
         return True
 
     def _validate_cnpj(self, cnpj):
-        
+
         # Limpando o cnpj
         if not cnpj.isdigit():
             import re
             cnpj = re.sub('[^0-9]', '', cnpj)
-           
+
         # verificando o tamano do  cnpj
         if len(cnpj) != 14:
             return False
-            
+
         # Pega apenas os 12 primeiros dígitos do CNPJ e gera os 2 dígitos que faltam
         cnpj= map(int, cnpj)
         novo = cnpj[:12]
@@ -107,11 +168,11 @@
         # Se o número gerado coincidir com o número original, é válido
         if novo == cnpj:
             return True
-            
+
         return False
-    
-    def _validate_cpf(self, cpf):  
-        
+
+    def _validate_cpf(self, cpf):
+
         if not cpf.isdigit():
             import re
             cpf = re.sub('[^0-9]', '', cpf)
@@ -135,11 +196,11 @@
         # Se o número gerado coincidir com o número original, é válido
         if novo == cpf:
             return True
-            
+
         return False
-    
+
     def _check_ie(self, cr, uid, ids):
-        """Checks if company register number in field insc_est is valid, 
+        """Checks if company register number in field insc_est is valid,
         this method call others methods because this validation is State wise
         @param self: The object pointer
         @param cr: the current row, from the database cursor,
@@ -149,324 +210,344 @@
         """
 
         for partner in self.browse(cr, uid, ids):
-            
-            validate = getattr(self, '_validate_ie_%s' % partner.addr_fs_code, None)
-
-            if not partner.inscr_est or partner.inscr_est == 'ISENTO' or not validate or partner.tipo_pessoa == 'F':
+            if not partner.inscr_est \
+                or partner.inscr_est == 'ISENTO' \
+                or partner.tipo_pessoa == 'F':
                 continue
 
-            if partner.tipo_pessoa == 'J':
-                if callable(validate):
-                    if not validate(partner.inscr_est):
-                        return False
-
-        return True
-
-    def _validate_ie_ac(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Acre
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_al(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Alagoas
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_am(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Amazonas
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
+            uf = partner.addr_fs_code
+            try:
+                validate = getattr(self, '_validate_ie_%s' % uf)
+                if not validate(partner.inscr_est):
+                    return False
+            except AttributeError:
+                if not validate_param(uf, partner.inscr_est):
+                    return False
+
+        return True
+
     def _validate_ie_ap(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Amapá
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
+        inscr_est = re.sub('[^0-9]', '', inscr_est)
+
+        # verificando o tamanho da inscrição estadual
+        if len(inscr_est) != 9:
+            return False
+
+        # verificando os dois primeiros dígitos
+        if not inscr_est.startswith('03'):
+            return False
+
+        # Pega apenas os 8 primeiros dígitos da inscrição estadual e
+        # define os valores de 'p' e 'd'
+        inscr_est_int = int(inscr_est[:8])
+        if inscr_est_int <= 3017000:
+            inscr_est_p = 5
+            inscr_est_d = 0
+        elif inscr_est_int <= 3019022:
+            inscr_est_p = 9
+            inscr_est_d = 1
+        else:
+            inscr_est_p = 0
+            inscr_est_d = 0
+
+        # Pega apenas os 8 primeiros dígitos da inscrição estadual e
+        # gera o dígito verificador
+        inscr_est = map(int, inscr_est)
+        nova_ie = inscr_est[:8]
+
+        prod = [9, 8, 7, 6, 5, 4, 3, 2]
+        r = (inscr_est_p + sum([x * y for (x, y) in zip(nova_ie, prod)])) % 11
+        if r > 1:
+            f = 11 - r
+        elif r == 1:
+            f = 0
+        else:
+            f = inscr_est_d
+        nova_ie.append(f)
+
+        return nova_ie == inscr_est
+
     def _validate_ie_ba(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Bahia
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_ce(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Ceará
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_df(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Distitro Federal
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False._check_ie
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_es(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Espirito Santo
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
+        inscr_est = re.sub('[^0-9]', '', inscr_est)
+        inscr_est = map(int, inscr_est)
+
+        # verificando o tamanho da inscrição estadual
+        if len(inscr_est) == 8:
+            tam = 8
+            val_tam = 6
+            test_digit = 0
+        elif len(inscr_est) == 9:
+            tam = 9
+            val_tam = 7
+            test_digit = 1
+        else:
+            return False
+
+        nova_ie = inscr_est[:val_tam]
+
+        prod = [8, 7, 6, 5, 4, 3, 2][-val_tam]
+
+        if inscr_est[test_digit] in [0, 1, 2, 3, 4, 5, 8]:
+            modulo = 10
+        else:
+            modulo = 11
+
+        while len(nova_ie) < tam:
+            r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % modulo
+            if r > 0:
+                f = modulo - r
+            else:
+                f = 0
+
+            if len(nova_ie) == val_tam:
+                nova_ie.append(f)
+            else:
+                nova_ie.insert(val_tam - 1, f)
+            prod.insert(0, prod[0] + 1)
+
+        return nova_ie == inscr_est
+
     def _validate_ie_go(self, inscr_est):
-        """Checks if company register number is val_check_ieid to Brazilian
-        state Goiais
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_ma(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Maranhão
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO_check_ie
-        return True
-    
+        inscr_est = re.sub('[^0-9]', '', inscr_est)
+
+        # verificando o tamanho da inscrição estadual
+        if len(inscr_est) != 9:
+            return False
+
+        # verificando os dois primeiros dígitos
+        if not inscr_est[:2] in ['10', '11', '15']:
+            return False
+
+        # Pega apenas os 8 primeiros dígitos da inscrição estadual e
+        # define os valores de 'p' e 'd'
+        inscr_est_int = int(inscr_est[:8])
+        if inscr_est_int >= 10103105 and inscr_est_int <= 10119997:
+            inscr_est_d = 1
+        else:
+            inscr_est_d = 0
+
+        # Pega apenas os 8 primeiros dígitos da inscrição estadual e
+        # gera o dígito verificador
+        inscr_est = map(int, inscr_est)
+        nova_ie = inscr_est[:8]
+
+        prod = [9, 8, 7, 6, 5, 4, 3, 2]
+        r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % 11
+        if r > 1:
+            f = 11 - r
+        elif r == 1:
+            f = inscr_est_d
+        else:
+            f = 0
+        nova_ie.append(f)
+
+        return nova_ie == inscr_est
+
     def _validate_ie_mg(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Minas Gerais
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_ms(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Mato Grosso do Sul
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_mt(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Mato Grosso
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_pa(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Pará
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_pb(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Paraíba
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
+        inscr_est = re.sub('[^0-9]', '', inscr_est)
+
+        # verificando o tamanho da inscrição estadual
+        if len(inscr_est) != 13:
+            return False
+
+        # Pega apenas os 11 primeiros dígitos da inscrição estadual e
+        # gera os dígitos verificadores
+        inscr_est = map(int, inscr_est)
+        nova_ie = inscr_est[:11]
+
+        nova_ie_aux = list(nova_ie)
+        nova_ie_aux.insert(3, 0)
+        prod = [1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
+        r = str([x * y for (x, y) in zip(nova_ie_aux, prod)])
+        r = re.sub('[^0-9]', '', r)
+        r = map(int, r)
+        r = sum(r)
+        r2 = (r / 10 + 1) * 10
+        r = r2 - r
+        nova_ie.append(r)
+
+        prod = [3, 2, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2]
+        r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % 11
+        if r > 1:
+            f = 11 - r
+        else:
+            f = 0
+        nova_ie.append(f)
+
+        return nova_ie == inscr_est
+
     def _validate_ie_pe(self, inscr_est):
-        """Check if number in insc_est is valid to Brazilian
-        state of Pernambuco
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_pi(self, inscr_est):
-        """Check if number in insc_est is valid to Brazilian
-        state of Piauí
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_pr(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Rio de Paraná
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_rj(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Rio de janeiro
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        
-        # Limpando o cnpj
-        if not inscr_est.isdigit():
-            inscr_est = re.sub('[^0-9]', '', inscr_est)
+        inscr_est = re.sub('[^0-9]', '', inscr_est)
 
-        # verificando o tamano do  cnpj
-        if len(inscr_est) != 8:
+        # verificando o tamanho da inscrição estadual
+        if (len(inscr_est) != 9) and (len(inscr_est) != 14):
             return False
 
-        # Pega apenas os 12 primeiros dígitos do CNPJ e gera os 2 dígitos que faltam
-        inscr_est= map(int, inscr_est)
-        nova_ie = inscr_est[:7]
-
-        prod = [2, 7, 6, 5, 4, 3, 2]
-        while len(nova_ie) < 8:
-            r = sum([x*y for (x, y) in zip(nova_ie, prod)]) % 11
-            if r > 1:
-                f = 11 - r
-            else:
-                f = 0
+        inscr_est = map(int, inscr_est)
+
+        # verificando o tamanho da inscrição estadual
+        if len(inscr_est) == 9:
+
+            # Pega apenas os 7 primeiros dígitos da inscrição estadual e
+            # gera os dígitos verificadores
+            inscr_est = map(int, inscr_est)
+            nova_ie = inscr_est[:7]
+
+            prod = [8, 7, 6, 5, 4, 3, 2]
+            while len(nova_ie) < 9:
+                r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % 11
+                if r > 1:
+                    f = 11 - r
+                else:
+                    f = 0
+                nova_ie.append(f)
+                prod.insert(0, 9)
+        elif len(inscr_est) == 14:
+
+            # Pega apenas os 13 primeiros dígitos da inscrição estadual e
+            # gera o dígito verificador
+            inscr_est = map(int, inscr_est)
+            nova_ie = inscr_est[:13]
+
+            prod = [5, 4, 3, 2, 1, 9, 8, 7, 6, 5, 4, 3, 2]
+            r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % 11
+            f = 11 - r
+            if f > 10:
+                f = f - 10
             nova_ie.append(f)
-            prod.insert(0, 6)
-
-        # Se o número gerado coincidir com o número original, é válido
-        if nova_ie == inscr_est:
-            return True
-
-        return False
-    
-    def _validate_ie_rn(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Rio Grande do Norte
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
+
+        return nova_ie == inscr_est
+
     def _validate_ie_ro(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Rondônia
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_rr(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Roraima
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_rs(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Rio Grande do Sul
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_sc(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Santa Catarina
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
-    def _validate_ie_se(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Sergipe
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
+        def gera_digito_ro(nova_ie, prod):
+            r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % 11
+            f = 11 - r
+            if f > 9:
+                f = f - 10
+            return f
+
+        inscr_est = re.sub('[^0-9]', '', inscr_est)
+        inscr_est = map(int, inscr_est)
+
+        # verificando o tamanho da inscrição estadual
+        if len(inscr_est) == 9:
+            # Despreza-se os 3 primeiros dígitos, pega apenas os 8 primeiros
+            # dígitos da inscrição estadual e gera o dígito verificador
+            nova_ie = inscr_est[3:8]
+
+            prod = [6, 5, 4, 3, 2]
+            f = gera_digito_ro(nova_ie, prod)
+            nova_ie.append(f)
+
+            nova_ie = inscr_est[0:3] + nova_ie
+        elif len(inscr_est) == 14:
+            # Pega apenas os 13 primeiros dígitos da inscrição estadual e
+            # gera o dígito verificador
+            nova_ie = inscr_est[:13]
+
+            prod = [6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2]
+            f = gera_digito_ro(nova_ie, prod)
+            nova_ie.append(f)
+        else:
+            return False
+
+        return nova_ie == inscr_est
+
     def _validate_ie_sp(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state São Paulo
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
+        def gera_digito_sp(nova_ie, prod):
+            r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % 11
+            if r < 10:
+                return r
+            elif r == 10:
+                return 0
+            else:
+                return 1
+
+        # Industriais e comerciais
+        if inscr_est[0] != 'P':
+
+            inscr_est = re.sub('[^0-9]', '', inscr_est)
+
+            # verificando o tamanho da inscrição estadual
+            if len(inscr_est) != 12:
+                return False
+
+            # Pega apenas os 8 primeiros dígitos da inscrição estadual e
+            # gera o primeiro dígito verificador
+            inscr_est = map(int, inscr_est)
+            nova_ie = inscr_est[:8]
+
+            prod = [1, 3, 4, 5, 6, 7, 8, 10]
+            f = gera_digito_sp(nova_ie, prod)
+            nova_ie.append(f)
+
+            # gera o segundo dígito verificador
+            nova_ie.extend(inscr_est[9:11])
+            prod = [3, 2, 10, 9, 8, 7, 6, 5, 4, 3, 2]
+            f = gera_digito_sp(nova_ie, prod)
+            nova_ie.append(f)
+
+        # Produtor rural
+        else:
+            inscr_est = re.sub('[^0-9]', '', inscr_est)
+
+            # verificando o tamanho da inscrição estadual
+            if len(inscr_est) != 12:
+                return False
+
+            # verificando o primeiro dígito depois do 'P'
+            if inscr_est[0] != '0':
+                return False
+
+            # Pega apenas os 8 primeiros dígitos da inscrição estadual e
+            # gera o dígito verificador
+            inscr_est = map(int, inscr_est)
+            nova_ie = inscr_est[:8]
+
+            prod = [1, 3, 4, 5, 6, 7, 8, 10]
+            f = gera_digito_sp(nova_ie, prod)
+            nova_ie.append(f)
+
+            nova_ie.extend(inscr_est[9:])
+
+        return nova_ie == inscr_est
+
     def _validate_ie_to(self, inscr_est):
-        """Checks if company register number is valid to Brazilian
-        state Tocantins
-        @param self: The object pointer
-        @param inscr_est: The company state number value,
-        @return: True or False.
-        """
-        #TODO
-        return True
-    
+        inscr_est = re.sub('[^0-9]', '', inscr_est)
+
+        # verificando o tamanho da inscrição estadual
+        if len(inscr_est) != 11:
+            return False
+
+        # verificando os dígitos 3 e 4
+        if not inscr_est[2:4] in ['01', '02', '03', '99']:
+            return False
+
+        # Pega apenas os dígitos que entram no cálculo
+        inscr_est = map(int, inscr_est)
+        nova_ie = inscr_est[:2] + inscr_est[4:10]
+
+        prod = [9, 8, 7, 6, 5, 4, 3, 2]
+        r = sum([x * y for (x, y) in zip(nova_ie, prod)]) % 11
+        if r > 1:
+            f = 11 - r
+        else:
+            f = 0
+        nova_ie.append(f)
+
+        nova_ie = nova_ie[:2] + inscr_est[2:4] + nova_ie[2:]
+
+        return nova_ie == inscr_est
+
     _constraints = [
                     (_check_cnpj_cpf, u'CNPJ/CPF invalido!', ['cnpj_cpf']),
                     (_check_ie, u'Inscrição Estadual inválida!', ['inscr_est'])
     ]
-    
+
     _sql_constraints = [
-                    ('res_partner_cnpj_cpf_uniq', 'unique (cnpj_cpf)', 
+                    ('res_partner_cnpj_cpf_uniq', 'unique (cnpj_cpf)',
                      u'Já existe um parceiro cadastrado com este CPF/CNPJ !'),
-                    ('res_partner_inscr_est_uniq', 'unique (inscr_est)', 
+                    ('res_partner_inscr_est_uniq', 'unique (inscr_est)',
                      u'Já existe um parceiro cadastrado com esta Inscrição Estadual/RG !')
     ]
 
@@ -477,18 +558,18 @@
         import re
         val = re.sub('[^0-9]', '', cnpj_cpf)
 
-        if tipo_pessoa == 'J' and len(val) == 14:            
+        if tipo_pessoa == 'J' and len(val) == 14:
             cnpj_cpf = "%s.%s.%s/%s-%s" % (val[0:2], val[2:5], val[5:8], val[8:12], val[12:14])
-        
+
         elif tipo_pessoa == 'F' and len(val) == 11:
             cnpj_cpf = "%s.%s.%s-%s" % (val[0:3], val[3:6], val[6:9], val[9:11])
-        
+
         return {'value': {'tipo_pessoa': tipo_pessoa, 'cnpj_cpf': cnpj_cpf}}
-    
+
 res_partner()
 
 class res_partner_address(osv.osv):
-    
+
     _inherit = 'res.partner.address'
 
     _columns = {
@@ -511,11 +592,11 @@
             result['value']['l10n_br_city_id'] = obj_city['id']
 
         return result
-    
+
     def onchange_mask_zip(self, cr, uid, ids, zip):
-        
+
         result = {'value': {'zip': False}}
-        
+
         if not zip:
             return result
 
@@ -527,20 +608,20 @@
         return result
 
     def zip_search(self, cr, uid, ids, context=None):
-        
+
         result = {
-                  'street': False, 
-                  'l10n_br_city_id': False, 
-                  'city': False, 
-                  'state_id': False, 
-                  'country_id': False, 
+                  'street': False,
+                  'l10n_br_city_id': False,
+                  'city': False,
+                  'state_id': False,
+                  'country_id': False,
                   'zip': False
                   }
 
         obj_zip = self.pool.get('l10n_br_base.zip')
-        
+
         for res_partner_address in self.browse(cr, uid, ids):
-            
+
             domain = []
             if res_partner_address.zip:
                 zip = re.sub('[^0-9]', '', res_partner_address.zip or '')
@@ -551,7 +632,7 @@
                 domain.append(('country_id','=',res_partner_address.country_id.id))
                 domain.append(('state_id','=',res_partner_address.state_id.id))
                 domain.append(('l10n_br_city_id','=',res_partner_address.l10n_br_city_id.id))
-            
+
             zip_id = obj_zip.search(cr, uid, domain)
 
             if not len(zip_id) == 1:
@@ -581,17 +662,17 @@
                 return result
 
             zip_read = obj_zip.read(cr, uid, zip_id, [
-                                                      'street_type', 
-                                                      'street','district', 
+                                                      'street_type',
+                                                      'street','district',
                                                       'code',
-                                                      'l10n_br_city_id', 
-                                                      'city', 'state_id', 
+                                                      'l10n_br_city_id',
+                                                      'city', 'state_id',
                                                       'country_id'], context=context)[0]
 
             zip = re.sub('[^0-9]', '', zip_read['code'] or '')
             if len(zip) == 8:
                 zip = '%s-%s' % (zip[0:5], zip[5:8])
-            
+
             result['street'] = ((zip_read['street_type'] or '') + ' ' + (zip_read['street'] or ''))
             result['district'] = zip_read['district']
             result['zip'] = zip

=== added file 'l10n_br_base/test/__init__.py'
=== added file 'l10n_br_base/test/test_partner.py'
--- l10n_br_base/test/test_partner.py	1970-01-01 00:00:00 +0000
+++ l10n_br_base/test/test_partner.py	2012-02-28 20:27:21 +0000
@@ -0,0 +1,21 @@
+from functools import partial
+import pytest
+
+
+def test_validate_ie_param():
+    from ..partner import validate_ie_param
+    assert validate_ie_param('rs', '096/0328009')
+    assert not validate_ie_param('rs', '096/0000009')
+
+
+def test_validate_ie_sp():
+    from ..partner import res_partner
+    validate_ie_sp = partial(res_partner._validate_ie_sp.im_func, None)
+    assert validate_ie_sp('674008473116')
+    assert not validate_ie_sp('074008473116')
+
+
+@pytest.mark.xfail
+def test_validate_ie_param_mt():
+    from ..partner import validate_ie_param
+    assert validate_ie_param('mt', '130693774')


Follow ups