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.