Quebra de linha entre funções
[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     if contribuinte._validate_cpf(sys.argv[1]):
159         print "CPF valido"
160     else:
161         print "CPF invalido"
162         sys.exit(1)
163     if len(sys.argv) == 4:
164         print "Valor anterior: " + contribuinte.get_contribuinte(sys.argv[2])
165         contribuinte.set_contribuinte(sys.argv[2], sys.argv[3])
166         print "Valor atual: " + contribuinte.get_contribuinte(sys.argv[2])
167         print "Salvando..."
168         contribuinte.save()
169     else:
170         print "\nCONTRIBUINTE:"
171         for i in contribuinte_attributes:
172             val = contribuinte.get_contribuinte(i)
173             if val == None:
174                 val = ""
175             print i + ": " + val
176         print "\nDECLARACAO:"
177         for i in declaracao_attributes:
178             val = contribuinte.get_declaracao(i)
179             if val == None:
180                 val = ""
181             print i + ": " + val
182
183 # vim:tabstop=4:expandtab:smartindent