import datetime import calendar import pandas as pd from dateutil.relativedelta import relativedelta from src.tipo_ticker import TipoTicker from src.stuff import tipo_ticker, vendas_no_mes class CalculoIr(): df: pd.DataFrame vendas: dict = dict() prejuizo_acumulado: dict = {} datas: list = [] mes_do_relatorio : str def __init__(self, df): self.df = df def calcula(self): hoje = datetime.datetime.now().date() data_inicial = self.df['data'].min() + relativedelta(months=-1) data = data_inicial = datetime.date(data_inicial.year, data_inicial.month, 1) data_final = hoje + relativedelta(months=-1) data_final = datetime.date(data_final.year, data_final.month, calendar.monthrange(data_final.year,data_final.month)[1]) self.mes_do_relatorio = self.__get_date_key__(data_final) while data <= data_final: self.datas.append(data) data = data + relativedelta(months=1) self.prejuizo_acumulado = {} for tipo in TipoTicker: self.__seta_prejuizo_acumulado(data_inicial, tipo, 0.0) for index, data in enumerate(self.datas): self.__seta_vendas_no_mes(data, vendas_no_mes(self.df, data.year, data.month)) for tipo in TipoTicker: prejuizo_acumulado = self.calcula_prejuizo_acumulado(data, tipo) self.__seta_prejuizo_acumulado(data, tipo, prejuizo_acumulado) def calcula_prejuizo_acumulado(self, data, tipo): prejuizo_acumulado = self.calcula_prejuizo_por_tipo(data, tipo) if self.__tem_prejuizo_no_mes_anterior(tipo, data): prejuizo_acumulado = prejuizo_acumulado + self.__prejuizo_no_mes_anterior(tipo, data) return prejuizo_acumulado def calcula_ir_a_pagar_no_mes(self, data): ir_a_pagar = 0.0 for tipo in TipoTicker: prejuizo_acumulado = self.calcula_prejuizo_acumulado(data, tipo) ir_a_pagar += self.calcula_ir_a_pagar(prejuizo_acumulado, tipo) return ir_a_pagar def calcula_ir_a_pagar(self, lucro, tipo): if lucro > 0: if tipo == TipoTicker.ACAO: return lucro * 0.15 if tipo == TipoTicker.ETF: return lucro * 0.15 if tipo == TipoTicker.FII: return lucro * 0.2 return 0.0 def calcula_dedo_duro_no_mes(self, data): porcentagem_dedo_duro = 0.005 / 100.0 return sum(operacao_de_venda['preco_medio_venda'] * operacao_de_venda['qtd_vendida'] for operacao_de_venda in vendas_no_mes(self.df, data.year, data.month)) * porcentagem_dedo_duro def calcula_vendas_totais_no_mes(self, data): return vendas_no_mes(self.df, data.year, data.month) def calcula_prejuizo_por_tipo(self, data, tipo): return sum([venda['resultado_apurado'] for venda in self.vendas[self.__get_date_key__(data)][tipo]]) def __tem_prejuizo_no_mes_anterior(self, tipo, data): if self.__prejuizo_no_mes_anterior(tipo, data) < 0: return True return False def __prejuizo_no_mes_anterior(self, tipo, data): mes_anterior = self.__get_date_key__(data + relativedelta(months=-1)) if mes_anterior in self.prejuizo_acumulado: return self.prejuizo_acumulado[mes_anterior][tipo] return 0.0 def __get_date_key__(self, data): return str(data.month) + '/' + str(data.year) def __seta_prejuizo_acumulado(self, data, tipo, prejuizo): if not self.__get_date_key__(data) in self.prejuizo_acumulado: self.prejuizo_acumulado[self.__get_date_key__(data)] = {} self.prejuizo_acumulado[self.__get_date_key__(data)][tipo] = prejuizo def __seta_vendas_no_mes(self, data, vendas_no_mes): self.vendas[self.__get_date_key__(data)] = {} for tipo in TipoTicker: self.vendas[self.__get_date_key__(data)][tipo] = [] for venda in vendas_no_mes: ticker = venda['ticker'] self.vendas[self.__get_date_key__(data)][tipo_ticker(ticker)].append(venda) def get_vendas_no_mes_por_tipo(self, data): return self.vendas[self.__get_date_key__(data)] def possui_vendas_no_mes(self, data): for tipo in TipoTicker: if len(self.vendas[self.__get_date_key__(data)][tipo]): return True return False