Melhora na messagem de erro
[cascardo/irpf-gui.git] / src / contribuinte.py
1 #
2 #   Copyright 2013 Thadeu Lima de Souza Cascardo <cascardo@cascardo.info>
3 #
4 #   This program is free software: you can redistribute it and/or modify
5 #   it under the terms of the GNU General Public License as published by
6 #   the Free Software Foundation, either version 3 of the License, or
7 #   (at your option) any later version.
8 #
9 #   This program is distributed in the hope that it will be useful,
10 #   but WITHOUT ANY WARRANTY; without even the implied warranty of
11 #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 #   GNU General Public License for more details.
13 #
14 #   You should have received a copy of the GNU General Public License
15 #   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 # -*- mode: python; encoding: utf-8; -*-
17 import xml.dom.minidom
18
19 class Contribuinte:
20     def __init__(self, cpf):
21         self.cpf = self._minimize_cpf(cpf)
22         if not self._validate_cpf(self.cpf):
23             raise RuntimeError("Invalid CPF: " + self.cpf)
24         self.declaracao = self._find_id()
25         self.dados = xml.dom.minidom.parse("aplicacao/dados/%s/%s.xml" % (self.cpf, self.cpf))
26         self.contribuinte = self.dados.getElementsByTagName("contribuinte")[0]
27     def _find_id(self):
28         cpf = self._normalize_cpf(self.cpf)
29         self.declaracoes = xml.dom.minidom.parse("aplicacao/dados/iddeclaracoes.xml")
30         for i in self.declaracoes.childNodes[0].childNodes:
31             if "cpf" in i.attributes.keys():
32                 if i.attributes["cpf"].nodeValue == cpf:
33                     return i
34         return None
35     # CPF normalizado se parece com 000.000.000-00
36     def _normalize_cpf(self, cpf):
37         ncpf = ""
38         for i in cpf:
39             if len(ncpf) == 3 or len(ncpf) == 7:
40                 ncpf += '.'
41             if len(ncpf) == 11:
42                 ncpf += '-'
43             if len(ncpf) == 14:
44                 break
45             if ord(i) >= ord('0') and ord(i) <= ord('9'):
46                 ncpf += i
47         if len(ncpf) != 14:
48             raise RuntimeError("Invalid CPF")
49         return ncpf
50     # CPF minimizado se parece com 01234567890
51     def _minimize_cpf(self, cpf):
52         ncpf = bytearray(self._normalize_cpf(cpf))
53         del ncpf[11]
54         del ncpf[7]
55         del ncpf[3]
56         return str(ncpf)
57     def _validate_cpf(self, cpf):
58         ncpf = self._minimize_cpf(cpf)
59         if len(ncpf) != 11:
60             return False
61         v = (11 - sum(map(lambda x: x[0]*x[1], zip(range(10, 1, -1), map(lambda x: ord(x) - ord('0'), ncpf[0:9]))))) % 11
62         if v >= 10:
63             v = 0
64         if v != ord(ncpf[9]) - ord('0'):
65             return False
66         v = (11 - sum(map(lambda x: x[0]*x[1], zip(range(11, 1, -1), map(lambda x: ord(x) - ord('0'), ncpf[0:10]))))) % 11
67         if v >= 10:
68             v = 0
69         if v != ord(ncpf[10]) - ord('0'):
70             return False
71         return True
72     def save(self):
73         self.dados.writexml(open("aplicacao/dados/%s/%s.xml" % (self.cpf, self.cpf), "w"))
74         self.declaracoes.writexml(open("aplicacao/dados/iddeclaracoes.xml", "w"))
75     def _get_attr(self, el, attr):
76         if attr in el.attributes.keys():
77             return el.attributes[attr].nodeValue
78         return None
79     def _set_attr(self, el, attr, val):
80         el.attributes[attr].nodeValue = val
81     def get_declaracao(self, attr):
82         return self._get_attr(self.declaracao, attr)
83     def set_declaracao(self, attr, val):
84         self._set_attr(self.declaracao, attr, val)
85     def get_nome(self):
86         return self.get_declaracao("nome")
87     def set_nome(self, nome):
88         self.set_declaracao("nome", nome)
89     def get_contribuinte(self, attr):
90         if attr == "nome":
91             return self.get_nome()
92         return self._get_attr(self.contribuinte, attr)
93     def set_contribuinte(self, attr, val):
94         if attr == "nome":
95             self.set_nome(val)
96         self._set_attr(self.contribuinte, attr, val)
97
98 contribuinte_attributes = [
99         "nome",
100         "dataNascimento",
101         "tituloEleitor",
102         "doencaDeficiencia",
103         "exterior",
104         "pais",
105         "cep",
106         "uf",
107         "cidade",
108         "municipio",
109         "tipoLogradouro",
110         "logradouro",
111         "numero",
112         "complemento",
113         "bairro",
114         "bairroExt",
115         "cepExt",
116         "logradouroExt",
117         "numeroExt",
118         "complementoExt",
119         "ocupacaoPrincipal",
120         "codigoExterior",
121         "ddd",
122         "telefone",
123         "naturezaOcupacao",
124         ]
125
126 declaracao_attributes = [
127         "dataUltimoAcesso",
128         "declaracaoRetificadora",
129         "enderecoDiferente",
130         "enderecoMACRede",
131         "exercicio",
132         "nome",
133         "numReciboDecRetif",
134         "numeroReciboDecAnterior",
135         "resultadoDeclaracao",
136         "tipoDeclaracao",
137         "tipoDeclaracaoAES",
138         "transmitida",
139         "versaoBeta"
140         ]
141
142 if __name__ == '__main__':
143     import sys
144     contribuinte = Contribuinte(sys.argv[1])
145     print "Carregando CPF " + contribuinte._normalize_cpf(sys.argv[1])
146     if contribuinte._validate_cpf(sys.argv[1]):
147         print "CPF valido"
148     else:
149         print "CPF invalido"
150         sys.exit(1)
151     if len(sys.argv) == 4:
152         print "Valor anterior: " + contribuinte.get_contribuinte(sys.argv[2])
153         contribuinte.set_contribuinte(sys.argv[2], sys.argv[3])
154         print "Valor atual: " + contribuinte.get_contribuinte(sys.argv[2])
155         print "Salvando..."
156         contribuinte.save()
157     else:
158         print "\nCONTRIBUINTE:"
159         for i in contribuinte_attributes:
160             val = contribuinte.get_contribuinte(i)
161             if val == None:
162                 val = ""
163             print i + ": " + val
164         print "\nDECLARACAO:"
165         for i in declaracao_attributes:
166             val = contribuinte.get_declaracao(i)
167             if val == None:
168                 val = ""
169             print i + ": " + val
170
171 # vim:tabstop=4:expandtab:smartindent