def test_envia_relatorio_html_por_email(self): data = [{ 'ticker': 'MAXR11', 'qtd': 100, 'data': datetime.date(2019, 3, 11), 'preco': 100, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'PETR4', 'qtd': 100, 'data': datetime.date(2019, 4, 11), 'preco': 100, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'XPLG11', 'qtd': 100, 'data': datetime.date(2019, 4, 12), 'preco': 200, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'XPLG11', 'qtd': -50, 'data': datetime.date(2019, 5, 12), 'preco': 220, 'aquisicao_via': 'HomeBroker' }] df = create_testing_dataframe(data) calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() assert envia_relatorio_html_por_email('assunto - teste unitário', relatorio_html(calculo_ir))
def test_relatorio_txt(self): from src.dropbox_files import download_dropbox_file download_dropbox_file() df = get_operations() df = df.tail(60) calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() with open("relatorio.txt", "w") as relatorio: relatorio.write(relatorio_txt(calculo_ir))
def test_relatorio_html(self): from src.dropbox_files import download_dropbox_file download_dropbox_file() df = get_operations_dataframe() df = df.tail(150) calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() from py_w3c.validators.html.validator import HTMLValidator assert HTMLValidator().validate_fragment(relatorio_html(calculo_ir))
def do_calculo_ir(): from src.dropbox_files import download_dropbox_file download_dropbox_file() df = get_operations() from src.stuff import calcula_custodia calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() print(relatorio_txt(calculo_ir)) envia_relatorio_html_por_email(assunto(calculo_ir), relatorio_html(calculo_ir))
def do_calculo_ir(): from src.dropbox_files import download_dropbox_file download_dropbox_file() df = get_operations_dataframe() from src.stuff import calcula_custodia calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() print(relatorio_txt(calculo_ir)) envia_relatorio_html_por_email( 'Calculo de IR - ' + calculo_ir.mes_do_relatorio + ' - CPF: ' + os.environ['CPF'] + ' - ' + datetime.now().strftime("%H:%M:%S"), relatorio_html(calculo_ir))
def relatorio_html(ir): relatorio = '<html>' relatorio += __h1('RELATORIO') relatorio += __p('') relatorio += __h2('Custódia') custodia = calcula_custodia(ir.df, datetime.datetime.now().date()) custodia = custodia[custodia.valor > 0] total_na_carteira = custodia['valor'].sum() custodia['valorizacao'] = custodia.apply(lambda row: '{:.2f}'.format(float(row.valorizacao)), axis=1) custodia['valor'] = custodia.apply(lambda row: '{:.2f}'.format(row.valor), axis=1) custodia['preco_atual'] = custodia.apply(lambda row: '{:.2f}'.format(row.preco_atual), axis=1) custodia['preco_medio_compra'] = custodia.apply(lambda row: '{:.2f}'.format(row.preco_medio_compra), axis=1) custodia['ultimo_yield'] = custodia.apply(lambda row: '' if row.ultimo_yield is None else '{:.2f}'.format(row.ultimo_yield), axis=1) headers = ['ticker', 'qtd', 'valor (R$)', 'Preco Atual (R$)', 'Preco Medio Compra (R$)', 'valorizacao (%)', 'Ultimo Yield [%]', 'tipo', 'Dt.Compra'] columns = ['ticker', 'qtd', 'valor', 'preco_atual', 'preco_medio_compra', 'valorizacao', 'ultimo_yield', 'tipo', 'data_primeira_compra'] custodia = custodia[columns] custodia.columns = headers relatorio += build_table(custodia, __cor_tabela()) relatorio += __p('Total na carteira : ' + __format(total_na_carteira)) relatorio += __hr() for data in ir.datas: if ir.possui_vendas_no_mes(data): relatorio += __p('') relatorio += __h3('MES : ' + str(data.month) + '/' + str(data.year)) relatorio += __p('Vendas:', tab=1) vendas_no_mes_por_tipo = ir.get_vendas_no_mes_por_tipo(data) for tipo in TipoTicker: if len(vendas_no_mes_por_tipo[tipo]): relatorio += __p(tipo.name + ':', tab=2) df_mes_por_tipo = pd.DataFrame(columns=['ticker', 'Qtd Vendida [#]', 'Preco Médio de Compra [R$]', 'Preco Médio de Venda [R$]', 'Resultado Apurado [R$]']) for venda in vendas_no_mes_por_tipo[tipo]: df_mes_por_tipo.loc[len(df_mes_por_tipo)] = [venda['ticker'], str(int(venda['qtd_vendida'])), __format(venda['preco_medio_compra']), __format(venda['preco_medio_venda']), __format(venda['resultado_apurado'])] relatorio += __p(build_table(df_mes_por_tipo, __cor_tabela(tipo)), tab=3) relatorio += __p('Lucro/Prejuizo no mês: ' + __format(ir.calcula_prejuizo_por_tipo(data, tipo)), tab=3) relatorio += __p('Lucro/Prejuizo acumulado: ' + __format(ir.calcula_prejuizo_acumulado(data, tipo)), tab=3) relatorio += __p('IR no mês para ' + tipo.name + ': ' + __format(ir.calcula_ir_a_pagar(ir.calcula_prejuizo_acumulado(data, tipo), tipo)), tab=3) relatorio += __p('Dedo-Duro TOTAL no mês: ' + __format(ir.calcula_dedo_duro_no_mes(data)), tab=2) relatorio += __p('IR a pagar TOTAL no mês: ' + __format(ir.calcula_ir_a_pagar_no_mes(data)), tab=2) relatorio += __hr() relatorio += __close_html() return ''.join(relatorio)
def test_relatorio_html(self): data = [{ 'ticker': 'MAXR11', 'qtd': 100, 'data': datetime.date(2019, 3, 11), 'preco': 100, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'PETR4', 'qtd': 100, 'data': datetime.date(2019, 4, 11), 'preco': 100, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'XPLG11', 'qtd': 100, 'data': datetime.date(2019, 4, 12), 'preco': 200, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'XPLG11', 'qtd': -50, 'data': datetime.date(2019, 5, 12), 'preco': 220, 'aquisicao_via': 'HomeBroker' }] df = create_testing_dataframe(data) calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() from py_w3c.validators.html.validator import HTMLValidator assert HTMLValidator().validate_fragment(relatorio_html(calculo_ir))
def test_relatorio_txt(self): from src.dropbox_files import download_dropbox_file download_dropbox_file(OPERACOES_DE_TESTE) df = get_operations(OPERACOES_DE_TESTE) assert len(df.count()) > 0 df = df.tail(60) custodia = calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() with open("temp/relatorio_teste.txt", "w") as relatorio: relatorio.write( relatorio_txt(custodia, calculo_ir, datetime.date.today(), False))
def relatorio_txt(ir): relatorio = [] relatorio.append('RELATORIO') relatorio.append('') relatorio.append('Custódia') custodia = calcula_custodia(ir.df, datetime.datetime.now().date()) columns = ['ticker', 'qtd', 'valor', 'preco_atual', 'preco_medio_compra', 'valorizacao', 'ultimo_yield', 'tipo', 'data_primeira_compra'] headers = ['ticker', 'qtd', 'valor (R$)', 'Preco Atual (R$)', 'Preco Medio Compra (R$)', 'valorizacao (%)', 'Ultimo Yield [%]', 'tipo', 'Dt.Compra'] custodia = custodia[columns] custodia = custodia[custodia.valor > 0] total_na_carteira = custodia['valor'].sum() custodia['valorizacao'] = custodia.apply(lambda row: '{:.2f}'.format(float(row.valorizacao)), axis=1) custodia['valor'] = custodia.apply(lambda row: '{:.2f}'.format(row.valor), axis=1) custodia['preco_atual'] = custodia.apply(lambda row: '{:.2f}'.format(row.preco_atual), axis=1) custodia['preco_medio_compra'] = custodia.apply(lambda row: '{:.2f}'.format(row.preco_medio_compra), axis=1) custodia['ultimo_yield'] = custodia.apply(lambda row: '' if row.ultimo_yield is None else '{:.2f}'.format(row.ultimo_yield), axis=1) relatorio.append(tabulate(custodia, showindex=False, headers=headers, tablefmt='psql')) relatorio.append('Total na carteira : ' + __format(total_na_carteira)) for data in ir.datas: if ir.possui_vendas_no_mes(data): relatorio.append('') relatorio.append(__tab(1) + 'MES : ' + str(data.month) + '/' + str(data.year)) relatorio.append(__tab(1) + 'Vendas:') vendas_no_mes_por_tipo = ir.get_vendas_no_mes_por_tipo(data) for tipo in TipoTicker: if len(vendas_no_mes_por_tipo[tipo]): relatorio.append(__tab(2) + tipo.name + ':') df_mes_por_tipo = pd.DataFrame(columns=['ticker', 'Qtd Vendida [#]', 'Preco Médio de Compra [R$]', 'Preco Médio de Venda [R$]', 'Resultado Apurado [R$]']) for venda in vendas_no_mes_por_tipo[tipo]: df_mes_por_tipo.loc[len(df_mes_por_tipo)] = [venda['ticker'], str(int(venda['qtd_vendida'])), __format(venda['preco_medio_compra']), __format(venda['preco_medio_venda']), __format(venda['resultado_apurado'])] relatorio.append(__tab(3) + tabulate(df_mes_por_tipo, headers=df_mes_por_tipo.columns, showindex=False, tablefmt='psql').replace('\n', '\n' + __tab(3))) relatorio.append(__tab(3) + 'Lucro/Prejuizo no mês: ' + __format(ir.calcula_prejuizo_por_tipo(data, tipo))) relatorio.append(__tab(3) + 'Lucro/Prejuizo acumulado: ' + __format(ir.calcula_prejuizo_acumulado(data, tipo))) relatorio.append(__tab(3) + 'IR no mês para ' + tipo.name + ': ' + __format(ir.calcula_ir_a_pagar(ir.calcula_prejuizo_acumulado(data, tipo), tipo))) relatorio.append(__tab(2) + 'Dedo-Duro TOTAL no mês: ' + __format(ir.calcula_dedo_duro_no_mes(data))) relatorio.append(__tab(2) + 'IR a pagar TOTAL no mês: ' + __format(ir.calcula_ir_a_pagar_no_mes(data))) return '\n'.join(relatorio)
def test_calcula_custodia(self): from src.dropbox_files import download_dropbox_file download_dropbox_file() df = get_operations_dataframe() data = datetime.datetime.now().date() custodia = calcula_custodia(df, data) assert type(custodia) is pd.DataFrame assert 'preco_medio_compra' in custodia.columns assert 'ticker' in custodia.columns assert 'qtd' in custodia.columns assert 'preco_atual' in custodia.columns assert 'valorizacao' in custodia.columns assert 'valor' in custodia.columns assert 'tipo' in custodia.columns assert 'data_primeira_compra' in custodia.columns
def relatorio_html(ir): relatorio = '<html>' relatorio += __h1('RELATORIO') relatorio += __p('') relatorio += __h2('Custódia') custodia = calcula_custodia(ir.df, datetime.datetime.now().date()) custodia = custodia[custodia.valor > 0] total_na_carteira = custodia['valor'].sum() custodia['valorizacao'] = custodia.apply(lambda row: '{:.2f}'.format(float(row.valorizacao)), axis=1) custodia['valor'] = custodia.apply(lambda row: '{:.2f}'.format(row.valor), axis=1) custodia['preco_atual'] = custodia.apply(lambda row: '{:.2f}'.format(row.preco_atual), axis=1) custodia['preco_medio_compra'] = custodia.apply(lambda row: '{:.2f}'.format(row.preco_medio_compra), axis=1) headers = ['ticker', 'qtd', 'valor (R$)', 'Preco Atual (R$)', 'Preco Medio Compra (R$)', 'valorizacao (%)', 'tipo', 'Primeira Compra'] columns = ['ticker', 'qtd', 'valor', 'preco_atual', 'preco_medio_compra', 'valorizacao', 'tipo', 'data_primeira_compra'] custodia = custodia[columns] custodia.columns = headers relatorio += custodia.to_html(index=False) relatorio += __p('Total na carteira : ' + __format(total_na_carteira), tab=3) relatorio += __hr() for data in ir.datas: if ir.possui_vendas_no_mes(data): relatorio += __p('') relatorio += __h3('MES : ' + str(data.month) + '/' + str(data.year)) relatorio += __p('Vendas:', tab=2) vendas_no_mes_por_tipo = ir.get_vendas_no_mes_por_tipo(data) for tipo in TipoTicker: if len(vendas_no_mes_por_tipo[tipo]): relatorio += __p(tipo.name + ':', tab=3) for venda in vendas_no_mes_por_tipo[tipo]: relatorio += __p(__format_venda(venda), tab=4) relatorio += __p('Lucro/Prejuizo no mês: ' + __format(ir.calcula_prejuizo_por_tipo(data, tipo)), tab=4) relatorio += __p('Lucro/Prejuizo acumulado: ' + __format(ir.calcula_prejuizo_acumulado(data, tipo)), tab=4) relatorio += __p('IR no mês para ' + tipo.name + ': ' + __format(ir.calcula_ir_a_pagar(ir.calcula_prejuizo_acumulado(data, tipo), tipo)), tab=4) relatorio += __p('Dedo-Duro TOTAL no mês: ' + __format(ir.calcula_dedo_duro_no_mes(data)), tab=3) relatorio += __p('IR a pagar TOTAL no mês: ' + __format(ir.calcula_ir_a_pagar_no_mes(data)), tab=3) relatorio += __hr() relatorio += __close_html() return ''.join(relatorio)
def test_calcula_custodia(self): from src.dropbox_files import download_dropbox_file download_dropbox_file(OPERACOES_DE_TESTE) df = get_operations(OPERACOES_DE_TESTE) assert len(df) > 0 df = df.tail(80) data = datetime.datetime.now().date() custodia = calcula_custodia(df, data) assert type(custodia) is pd.DataFrame assert 'preco_medio_compra' in custodia.columns assert 'ticker' in custodia.columns assert 'qtd' in custodia.columns assert 'preco_atual' in custodia.columns assert 'valorizacao' in custodia.columns assert 'ultimo_yield' in custodia.columns assert 'valor' in custodia.columns assert 'tipo' in custodia.columns assert 'data_primeira_compra' in custodia.columns
def relatorio_txt(ir): relatorio = [] relatorio.append('RELATORIO') relatorio.append('') relatorio.append('Custódia') custodia = calcula_custodia(ir.df, datetime.datetime.now().date()) columns = ['ticker', 'qtd', 'valor', 'preco_atual', 'preco_medio_compra', 'valorizacao', 'tipo', 'data_primeira_compra'] headers = ['ticker', 'qtd', 'valor (R$)', 'PrecoAtual(R$)', 'PrecoMedioCompra(R$)', 'valorizacao (%)', 'tipo', 'PrimeiraCompra'] custodia = custodia[columns] custodia = custodia[custodia.valor > 0] total_na_carteira = custodia['valor'].sum() custodia['valorizacao'] = custodia.apply(lambda row: '{:.2f}'.format(float(row.valorizacao)), axis=1) custodia['valor'] = custodia.apply(lambda row: '{:.2f}'.format(row.valor), axis=1) custodia['preco_atual'] = custodia.apply(lambda row: '{:.2f}'.format(row.preco_atual), axis=1) custodia['preco_medio_compra'] = custodia.apply(lambda row: '{:.2f}'.format(row.preco_medio_compra), axis=1) relatorio.append(tabulate(custodia, showindex=False, headers=headers, tablefmt='psql')) relatorio.append('Total na carteira : ' + __format(total_na_carteira)) for data in ir.datas: if ir.possui_vendas_no_mes(data): relatorio.append('') relatorio.append(__tab(1) + 'MES : ' + str(data.month) + '/' + str(data.year)) relatorio.append(__tab(2) + 'Vendas:') vendas_no_mes_por_tipo = ir.get_vendas_no_mes_por_tipo(data) for tipo in TipoTicker: if len(vendas_no_mes_por_tipo[tipo]): relatorio.append(__tab(3) + tipo.name + ':') for venda in vendas_no_mes_por_tipo[tipo]: relatorio.append(__tab(4) + __format_venda(venda)) relatorio.append(__tab(4) + 'Lucro/Prejuizo no mês: ' + __format(ir.calcula_prejuizo_por_tipo(data, tipo))) relatorio.append(__tab(4) + 'Lucro/Prejuizo acumulado: ' + __format(ir.calcula_prejuizo_acumulado(data, tipo))) relatorio.append(__tab(4) + 'IR no mês para ' + tipo.name + ': ' + __format(ir.calcula_ir_a_pagar(ir.calcula_prejuizo_acumulado(data, tipo), tipo))) relatorio.append(__tab(3) + 'Dedo-Duro TOTAL no mês: ' + __format(ir.calcula_dedo_duro_no_mes(data))) relatorio.append(__tab(3) + 'IR a pagar TOTAL no mês: ' + __format(ir.calcula_ir_a_pagar_no_mes(data))) return '\n'.join(relatorio)
def do_calculo_ir(): from src.dropbox_files import download_dropbox_file download_dropbox_file(OPERATIONS_FILEPATH) df = get_operations(filepath=OPERATIONS_FILEPATH) first_year = df['data'].min().year last_year = df['data'].max().year # Permite separar as outras operações de forma organizada for f in [ 'outras_operacoes.txt', 'custos.txt', 'ofertas_publicas.txt', 'subscricoes.txt' ]: for year in range(first_year, last_year + 1): outros = get_operations(WORK_DIR + str(year) + '/' + f, operations=df) df = merge_outros(df, outros) outros = get_operations(WORK_DIR + f, operations=df) df = merge_outros(df, outros) df.reset_index(drop=True, inplace=True) df = ajusta_datas(df, 'data') df.drop(df[df['data'] > data_referencia].index, inplace=True) df = verifica_conversoes(df, first_year, last_year) if len(df) == 0: raise Exception("Não existem dados para processar até a data : " + str(data_referencia)) df_to_csv(df, WORK_DIR + nome_com_referencia('combinado.txt')) do_diario(df.copy(), first_year, last_year) from src.stuff import calcula_custodia # Custódia e IR são gerados somente uma vez e passados para os relatórios custodia = calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() declaracao_anual = data_referencia.strftime('%m%d') == '1231' adicionais = {} if declaracao_anual: # final do ano gerar relatorio para facilitar IRPF Anual print("*** GERANDO RELATORIO PARA IRPF") try: carteira_cei = pd.read_csv(WORK_DIR + nome_com_referencia('carteira_cei.txt'), sep='\t', header=0) carteira_cei = carteira_cei.groupby('ticker', as_index=False, sort=True).agg({'qtd': 'sum'}) for a, ra in custodia.iterrows(): carteira_cei['qtd'] = carteira_cei.apply( lambda row: row.qtd - ra.qtd if row.ticker == ra.ticker else row.qtd, axis=1) # Verificando se tem itens na custodia que não estão na carteira cei filtro = carteira_cei[carteira_cei['ticker'] == ra.ticker] if len(filtro) == 0: print("*** " + ra.ticker + " não está na carteira CEI") carteira_cei = carteira_cei.append( { 'ticker': ra.ticker, 'qtd': ra.qtd * -1 }, ignore_index=True) carteira_cei = carteira_cei[carteira_cei['qtd'] != 0] if len(carteira_cei) > 0: print("*** ERRO NA COMPARACAO COM CARTEIRA CEI : ") print(carteira_cei) adicionais['diferenca_carteira_cei'] = carteira_cei except FileNotFoundError: pass except Exception as e: print("Erro lendo carteira_cei.txt ") print(e) salva_planilha_irpf(WORK_DIR + nome_com_referencia('custodia.xlsx'), custodia, adicionais) txt = relatorio_txt(custodia.copy(), calculo_ir, data_referencia, declaracao_anual) save_to_daily_file("txt", txt) print(txt) html = relatorio_html(custodia.copy(), calculo_ir, data_referencia, declaracao_anual) save_to_daily_file("html", html) envia_relatorio_html_por_email(assunto(calculo_ir), html)
def test_deve_retornar_relatorio_html_com_todos_os_meses(self): data = [{ 'ticker': 'MAXR11', 'qtd': 100, 'data': datetime.date(2019, 3, 11), 'preco': 100, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'PETR4', 'qtd': 100, 'data': datetime.date(2019, 4, 11), 'preco': 100, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'XPLG11', 'qtd': 100, 'data': datetime.date(2019, 4, 12), 'preco': 200, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'XPLG11', 'qtd': -50, 'data': datetime.date(2019, 5, 12), 'preco': 220, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'MAXR11', 'qtd': 100, 'data': datetime.date(2019, 6, 11), 'preco': 100, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'PETR4', 'qtd': 100, 'data': datetime.date(2019, 10, 11), 'preco': 100, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'XPLG11', 'qtd': 100, 'data': datetime.date(2019, 10, 12), 'preco': 200, 'aquisicao_via': 'HomeBroker' }, { 'ticker': 'XPLG11', 'qtd': -50, 'data': datetime.date(2019, 11, 12), 'preco': 220, 'aquisicao_via': 'HomeBroker' }] df = create_testing_dataframe(data) calcula_custodia(df) calculo_ir = CalculoIr(df=df) calculo_ir.calcula() from py_w3c.validators.html.validator import HTMLValidator html = relatorio_html(calculo_ir) assert HTMLValidator().validate_fragment(html) assert 'MES : 05/2019' in html assert 'MES : 11/2019' in html