Interpreta e salva dados do contribuinte
[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         def _find_id(self):
27                 cpf = self._normalize_cpf(self.cpf)
28                 self.declaracoes = xml.dom.minidom.parse("aplicacao/dados/iddeclaracoes.xml")
29                 for i in self.declaracoes.childNodes[0].childNodes:
30                         if "cpf" in i.attributes.keys():
31                                 if i.attributes["cpf"].nodeValue == cpf:
32                                         return i
33                 return None
34         # CPF normalizado se parece com 000.000.000-00
35         def _normalize_cpf(self, cpf):
36                 ncpf = ""
37                 for i in cpf:
38                         if len(ncpf) == 3 or len(ncpf) == 7:
39                                 ncpf += '.'
40                         if len(ncpf) == 11:
41                                 ncpf += '-'
42                         if len(ncpf) == 14:
43                                 break
44                         if ord(i) >= ord('0') and ord(i) <= ord('9'):
45                                 ncpf += i
46                 if len(ncpf) != 14:
47                         raise RuntimeError("Invalid CPF")
48                 return ncpf
49         # CPF minimizado se parece com 01234567890
50         def _minimize_cpf(self, cpf):
51                 ncpf = bytearray(self._normalize_cpf(cpf))
52                 del ncpf[11]
53                 del ncpf[7]
54                 del ncpf[3]
55                 return str(ncpf)
56         def _validate_cpf(self, cpf):
57                 ncpf = self._minimize_cpf(cpf)
58                 if len(ncpf) != 11:
59                         return False
60                 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
61                 if v >= 10:
62                         v = 0
63                 if v != ord(ncpf[9]) - ord('0'):
64                         return False
65                 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
66                 if v >= 10:
67                         v = 0
68                 if v != ord(ncpf[10]) - ord('0'):
69                         return False
70                 return True
71         def save(self):
72                 self.dados.writexml(open("aplicacao/dados/%s/%s.xml" % (self.cpf, self.cpf), "w"))
73                 self.declaracoes.writexml(open("aplicacao/dados/iddeclaracoes.xml", "w"))
74         def get_nome(self):
75                 if "nome" in self.declaracao.attributes.keys():
76                         return self.declaracao.attributes["nome"].nodeValue
77                 return None
78         def set_nome(self, nome):
79                 self.declaracao.attributes["nome"].nodeValue = nome
80
81 if __name__ == '__main__':
82         import sys
83         contribuinte = Contribuinte(sys.argv[1])
84         print contribuinte._normalize_cpf(sys.argv[1])
85         print contribuinte._minimize_cpf(sys.argv[1])
86         print contribuinte._validate_cpf(sys.argv[1])
87         contribuinte.set_nome(sys.argv[2])
88         print contribuinte.get_nome()
89         contribuinte.save()