From 6180cb95a746330a80c9363d7e98735b436bfabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Wed, 26 Dec 2012 09:42:10 -0200 Subject: [PATCH 1/7] Fixing python shebangs --- exchangerate.py | 2 +- gsu_irpf.py | 2 +- sicalc.py | 2 +- tax.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exchangerate.py b/exchangerate.py index 4874f3d..7d43ca1 100755 --- a/exchangerate.py +++ b/exchangerate.py @@ -1,4 +1,4 @@ -#!/usr/local/homebrew/bin/python3 +#!/usr/bin/env python3 import argparse import logging diff --git a/gsu_irpf.py b/gsu_irpf.py index e250a16..5f5636d 100755 --- a/gsu_irpf.py +++ b/gsu_irpf.py @@ -1,4 +1,4 @@ -#!/usr/local/homebrew/bin/python3 +#!/usr/bin/env python3 import bisect import csv diff --git a/sicalc.py b/sicalc.py index d1c273f..515b094 100755 --- a/sicalc.py +++ b/sicalc.py @@ -1,4 +1,4 @@ -#!/usr/local/homebrew/bin/python3 +#!/usr/bin/env python3 from argparse import ArgumentParser, FileType from lxml.html import parse, submit_form, fromstring, tostring diff --git a/tax.py b/tax.py index 1274b8e..78c2fd4 100755 --- a/tax.py +++ b/tax.py @@ -1,4 +1,4 @@ -#!/usr/local/homebrew/bin/python3 +#!/usr/bin/env python3 # Crazy pickle wants this here class TaxTableEntry: From 244acce64bfa284af6a37fd260bca3aca936f3af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Wed, 26 Dec 2012 10:37:36 -0200 Subject: [PATCH 2/7] Adding contents to the README file --- README.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f73e8a2..0209a70 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,74 @@ darf -==== \ No newline at end of file +==== + +São 4 programinhas para calcular o valor do DARF a ser pago ao se receber +ações GOOG através de GSU. + +Dependências: + +* [Python 3.2][py] ou mais recente +* [dateutil][dateutil] +* [lxml][lxml] + +[py]: http://python.org/ +[dateutil]: http://labix.org/python-dateutil +[lxml]: http://lxml.de/ + +exchangerate.py +--------------- + +Usa UOL e Google Finance para pegar o valor da ação GOOG em uma certa data e o +valor do dólar no último dia útil da primeira quinzena do mês anterior. + + ./exchangerate.py 20-Jan-2012 + usdbrl@15-Dec-2011: 1.860800 goog@20-Jan-2012: 585.990000 + +A data pode ser digitada em qualquer formato suportado pelo +[`dateutil.parser.parse`][parse]. + +[parse]: http://labix.org/python-dateutil#head-a23e8ae0a661d77b89dfb3476f85b26f0b30349c + +tax.py +------ + +Realiza uma busca na tabela progressiva do imposto para fazer a mesma conta +que o [carnê-leão][carneleao] faz. + + ./tax.py 5000 2012-Jan + R$5000.000000 @Jan-2012 gives tax of R$618.470000 + +[carneleao]: http://www.receita.fazenda.gov.br/PessoaFisica/CarneLeao/default.htm + +sicalc.py +--------- + +Recebe o valor de imposto e usa o sicalc para gerar o DARF. + + # cpf com 12 dígitos, mês, valor + ./sicalc.py 12345678909 2012-Jan 618.47 + Darf written at carne-leao-2012-Jan-darf-para-2012-Aug.html + +gsu_irpf.py +----------- + +É a cola de todos os programas anteriores. Recebe o CPF e o arquivo CSV +*transaction history* (exportado do [benefitaccess.com][mssb]) e gera todos os +DARFs, incluindo multa e juros se aplicável. Basta apenas escolher os que não +foram pagos e pagá-los. + + ./gsu_irpf.py 12345678909 sample_benefit_access_csv.csv + + 2012-08-01: vested 3 shares for total value R$3847.95 (1 GSU = 628.75 + @2012-08-01, 1 USD = 2.04 @2012-07-13) + 2012-03-26: vested 5 shares for total value R$5564.37 (1 GSU = 647.02 + @2012-03-26, 1 USD = 1.72 @2012-02-15) + 2012-03-25: vested 5 shares for total value R$5584.24 (1 GSU = 649.33 + @2012-03-25, 1 USD = 1.72 @2012-02-15) + --- + carne leao 2012-03: exterior 11148.61 imposto devido: 2309.34 + carne leao 2012-08: exterior 3847.95 imposto devido: 301.66 + Generated darf carne-leao-2012-Mar-darf-para-2012-Aug.html + Generated darf carne-leao-2012-Aug-darf-para-2012-Aug.html + Point your browser to file:///Users/davi/code/darf/darfs/index.html + +[mssb]: http://benefitaccess.com/ From cae31fcc0c6963a67af0b81ddce73f13250d585a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Wed, 26 Dec 2012 10:38:16 -0200 Subject: [PATCH 3/7] Improving HTML regex to accept whitespace. --- tax.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tax.py b/tax.py index 78c2fd4..851e39a 100755 --- a/tax.py +++ b/tax.py @@ -41,19 +41,19 @@ def _crawlTaxTable(self, url): date = self._findDate(tree, v) celltype = i % 3 if celltype == 0: - m = re.search(' (\d\.\d\d\d),(\d\d)', txt) + m = re.search(' (\d\.\d\d\d),(\d\d)\s*', txt) assert(m) base = float(re.sub('\.', '', m.group(1))) + float(m.group(2))/100 if 'Acima' in txt: base = float("inf") elif celltype == 1: - m = re.search('>((\d?\d),(\d)|-)

', txt) + m = re.search(']*>\s*((\d?\d),(\d)|-)\s*

', txt) assert(m) tax = 0 if m.group(1) != '-': tax = float(m.group(2)) + float(m.group(3))/10 elif celltype == 2: - m = re.search('>((\d\d\d),(\d\d)|-)

', txt) + m = re.search(']*>\s*((\d\d\d),(\d\d)|-)\s*

', txt) assert(m) deduction = 0 if m.group(1) != '-': From e14de3d57e2317cf17fd6a58f80cfe2825332fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Wed, 26 Dec 2012 10:48:02 -0200 Subject: [PATCH 4/7] Updated README a little bit. --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 0209a70..a8db466 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ que o [carnê-leão][carneleao] faz. ./tax.py 5000 2012-Jan R$5000.000000 @Jan-2012 gives tax of R$618.470000 +O valor de entrada (no exemplo acima, 5000) corresponde à seguinte fórmula: + + num. de ações × valor da ação × cotação do dólar + [carneleao]: http://www.receita.fazenda.gov.br/PessoaFisica/CarneLeao/default.htm sicalc.py From 731f3c7dd5413908ef5ae018b3e617dcc648b6b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Wed, 26 Dec 2012 10:49:11 -0200 Subject: [PATCH 5/7] Since the serpro server has an expired SSL certificate, let's link to CSS and images using plain HTTP. --- sicalc.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sicalc.py b/sicalc.py index 515b094..233e075 100755 --- a/sicalc.py +++ b/sicalc.py @@ -82,6 +82,8 @@ def GenerateDarf(self, cpf, monthstr, main_tax): darf = darf.replace('./', 'https://pagamento.serpro.gov.br/Darf/') # Remove 404 darf = darf.replace('', '') + # pagamento.serpro.gov.br has an expired SSL certificate. + darf = darf.replace('https://', 'http://') return darf if __name__ == '__main__': From d0246a01441c260b664a359ebf926ecb3b83ed59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Wed, 26 Dec 2012 10:56:25 -0200 Subject: [PATCH 6/7] Since sicalc.py now replaces https with http, this notice about SSL fix can be removed. --- gsu_irpf.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gsu_irpf.py b/gsu_irpf.py index 5f5636d..0ae3e76 100755 --- a/gsu_irpf.py +++ b/gsu_irpf.py @@ -45,7 +45,6 @@ def __init__(self, output_dir): self.xchgdb = exchangerate.ExchangeRateDB('xchgrate') self.calculator = tax.LionTax('xchgrate') self.sicalc = sicalc.Sicalc() - self.darf_css='https://pagamento.serpro.gov.br/Darf/estiloDARF.css' def _ParseTransactions(self, benefit_access_csv): reader = csv.reader(benefit_access_csv) @@ -89,7 +88,7 @@ def Generate(self, benefit_access_csv, cpf, startdate): index_file = os.path.join(self.output_dir, 'index.html') index = open(index_file, 'w') - index.write('Click me to fix ssl permissions if having rendering issues.

' % self.darf_css) + index.write('') index.write('Tax computation log

' % os.path.abspath(self.logfile_name)) summary = {} From 01a5951084098e457e32efdf42ed4aacd5131a13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denilson=20S=C3=A1?= Date: Wed, 26 Dec 2012 11:09:08 -0200 Subject: [PATCH 7/7] Small updates to the README. --- README.md | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index a8db466..789b381 100644 --- a/README.md +++ b/README.md @@ -61,18 +61,14 @@ DARFs, incluindo multa e juros se aplicável. Basta apenas escolher os que não foram pagos e pagá-los. ./gsu_irpf.py 12345678909 sample_benefit_access_csv.csv - - 2012-08-01: vested 3 shares for total value R$3847.95 (1 GSU = 628.75 - @2012-08-01, 1 USD = 2.04 @2012-07-13) - 2012-03-26: vested 5 shares for total value R$5564.37 (1 GSU = 647.02 - @2012-03-26, 1 USD = 1.72 @2012-02-15) - 2012-03-25: vested 5 shares for total value R$5584.24 (1 GSU = 649.33 - @2012-03-25, 1 USD = 1.72 @2012-02-15) + 2012-08-01: vested 3 shares for total value R$3872.00 (1 GSU = 632.68 @2012-08-01, 1 USD = 2.04 @2012-07-13) + 2012-03-26: vested 5 shares for total value R$5584.24 (1 GSU = 649.33 @2012-03-26, 1 USD = 1.72 @2012-02-15) + 2012-03-25: vested 5 shares for total value R$5526.27 (1 GSU = 642.59 @2012-03-25, 1 USD = 1.72 @2012-02-15) --- - carne leao 2012-03: exterior 11148.61 imposto devido: 2309.34 - carne leao 2012-08: exterior 3847.95 imposto devido: 301.66 + carne leao 2012-03: exterior 11110.51 imposto devido: 2298.86 + carne leao 2012-08: exterior 3872.00 imposto devido: 308.27 Generated darf carne-leao-2012-Mar-darf-para-2012-Aug.html Generated darf carne-leao-2012-Aug-darf-para-2012-Aug.html - Point your browser to file:///Users/davi/code/darf/darfs/index.html + Point your browser to file://.../index.html [mssb]: http://benefitaccess.com/