Permite que outros dados do contribuinte sejam lidos e gravados
[cascardo/irpf-gui.git] / 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")
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_nome(self):
82                 return self._get_attr(self.declaracao, "nome")
83         def set_nome(self, nome):
84                 self._set_attr(self.declaracao, "nome", nome)
85         def get_contribuinte(self, attr):
86                 if attr == "nome":
87                         return self.get_nome()
88                 return self._get_attr(self.contribuinte, attr)
89         def set_contribuinte(self, attr, val):
90                 if attr == "nome":
91                         self.set_nome(val)
92                 self._set_attr(self.contribuinte, attr, val)
93
94 attributes = [
95         "nome",
96         "dataNascimento",
97         "tituloEleitor",
98         "doencaDeficiencia",
99         "exterior",
100         "pais",
101         "cep",
102         "uf",
103         "cidade",
104         "municipio",
105         "tipoLogradouro",
106         "logradouro",
107         "numero",
108         "complemento",
109         "bairro",
110         "bairroExt",
111         "cepExt",
112         "logradouroExt",
113         "numeroExt",
114         "complementoExt",
115         "ocupacaoPrincipal",
116         "codigoExterior",
117         "ddd",
118         "telefone",
119         "naturezaOcupacao",
120 ]
121
122 if __name__ == '__main__':
123         import sys
124         contribuinte = Contribuinte(sys.argv[1])
125         print "Carregando CPF " + contribuinte._normalize_cpf(sys.argv[1])
126         if contribuinte._validate_cpf(sys.argv[1]):
127                 print "CPF valido"
128         else:
129                 print "CPF invalido"
130                 sys.exit(1)
131         if len(sys.argv) == 4:
132                 print "Valor anterior: " + contribuinte.get_contribuinte(sys.argv[2])
133                 contribuinte.set_contribuinte(sys.argv[2], sys.argv[3])
134                 print "Valor atual: " + contribuinte.get_contribuinte(sys.argv[2])
135                 print "Salvando..."
136                 contribuinte.save()
137         else:
138                 for i in attributes:
139                         print i + ": " + contribuinte.get_contribuinte(i)