Com a verificação no construtor, o if é inútil
[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
28     def _find_id(self):
29         cpf = self._normalize_cpf(self.cpf)
30         self.declaracoes = xml.dom.minidom.parse("aplicacao/dados/iddeclaracoes.xml")
31         for i in self.declaracoes.childNodes[0].childNodes:
32             if "cpf" in i.attributes.keys():
33                 if i.attributes["cpf"].nodeValue == cpf:
34                     return i
35         return None
36
37     # CPF normalizado se parece com 000.000.000-00
38     def _normalize_cpf(self, cpf):
39         ncpf = ""
40         for i in cpf:
41             if len(ncpf) == 3 or len(ncpf) == 7:
42                 ncpf += '.'
43             if len(ncpf) == 11:
44                 ncpf += '-'
45             if len(ncpf) == 14:
46                 break
47             if ord(i) >= ord('0') and ord(i) <= ord('9'):
48                 ncpf += i
49         if len(ncpf) != 14:
50             raise RuntimeError("Invalid CPF")
51         return ncpf
52
53     # CPF minimizado se parece com 01234567890
54     def _minimize_cpf(self, cpf):
55         ncpf = bytearray(self._normalize_cpf(cpf))
56         del ncpf[11]
57         del ncpf[7]
58         del ncpf[3]
59         return str(ncpf)
60
61     def _validate_cpf(self, cpf):
62         ncpf = self._minimize_cpf(cpf)
63         if len(ncpf) != 11:
64             return False
65         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
66         if v >= 10:
67             v = 0
68         if v != ord(ncpf[9]) - ord('0'):
69             return False
70         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
71         if v >= 10:
72             v = 0
73         if v != ord(ncpf[10]) - ord('0'):
74             return False
75         return True
76
77     def save(self):
78         self.dados.writexml(open("aplicacao/dados/%s/%s.xml" % (self.cpf, self.cpf), "w"))
79         self.declaracoes.writexml(open("aplicacao/dados/iddeclaracoes.xml", "w"))
80     def _get_attr(self, el, attr):
81         if attr in el.attributes.keys():
82             return el.attributes[attr].nodeValue
83         return None
84
85     def _set_attr(self, el, attr, val):
86         el.attributes[attr].nodeValue = val
87
88     def get_declaracao(self, attr):
89         return self._get_attr(self.declaracao, attr)
90
91     def set_declaracao(self, attr, val):
92         self._set_attr(self.declaracao, attr, val)
93
94     def get_nome(self):
95         return self.get_declaracao("nome")
96
97     def set_nome(self, nome):
98         self.set_declaracao("nome", nome)
99
100     def get_contribuinte(self, attr):
101         if attr == "nome":
102             return self.get_nome()
103         return self._get_attr(self.contribuinte, attr)
104
105     def set_contribuinte(self, attr, val):
106         if attr == "nome":
107             self.set_nome(val)
108         self._set_attr(self.contribuinte, attr, val)
109
110 contribuinte_attributes = [
111         "nome",
112         "dataNascimento",
113         "tituloEleitor",
114         "doencaDeficiencia",
115         "exterior",
116         "pais",
117         "cep",
118         "uf",
119         "cidade",
120         "municipio",
121         "tipoLogradouro",
122         "logradouro",
123         "numero",
124         "complemento",
125         "bairro",
126         "bairroExt",
127         "cepExt",
128         "logradouroExt",
129         "numeroExt",
130         "complementoExt",
131         "ocupacaoPrincipal",
132         "codigoExterior",
133         "ddd",
134         "telefone",
135         "naturezaOcupacao",
136         ]
137
138 declaracao_attributes = [
139         "dataUltimoAcesso",
140         "declaracaoRetificadora",
141         "enderecoDiferente",
142         "enderecoMACRede",
143         "exercicio",
144         "nome",
145         "numReciboDecRetif",
146         "numeroReciboDecAnterior",
147         "resultadoDeclaracao",
148         "tipoDeclaracao",
149         "tipoDeclaracaoAES",
150         "transmitida",
151         "versaoBeta"
152         ]
153
154 if __name__ == '__main__':
155     import sys
156     contribuinte = Contribuinte(sys.argv[1])
157     print "Carregando CPF " + contribuinte._normalize_cpf(sys.argv[1])
158
159     if len(sys.argv) == 4:
160         print "Valor anterior: " + contribuinte.get_contribuinte(sys.argv[2])
161         contribuinte.set_contribuinte(sys.argv[2], sys.argv[3])
162         print "Valor atual: " + contribuinte.get_contribuinte(sys.argv[2])
163         print "Salvando..."
164         contribuinte.save()
165     else:
166         print "\nCONTRIBUINTE:"
167         for i in contribuinte_attributes:
168             val = contribuinte.get_contribuinte(i)
169             if val == None:
170                 val = ""
171             print i + ": " + val
172         print "\nDECLARACAO:"
173         for i in declaracao_attributes:
174             val = contribuinte.get_declaracao(i)
175             if val == None:
176                 val = ""
177             print i + ": " + val
178
179 # vim:tabstop=4:expandtab:smartindent