import pytest from decimal import Decimal from src.calculators import arred from src.calculators.icms import ( ParametrosICMS, calcular_icms, calcular_icms_apuracao, calcular_icms_credito_entrada, ) from src.calculators.ipi import ParametrosIPI, calcular_ipi, obter_aliquota_ipi_ncm from src.calculators.pis_cofins import ( CreditoPisCofins, ReceitaBruta, calcular_pis_cofins, calcular_pis_cofins_retencao, ) from src.calculators.irpj_csll import ( calcular_csll_lucro_presumido, calcular_csll_lucro_real, calcular_irpj_lucro_presumido, calcular_irpj_lucro_real, calcular_irpj_estimativa_mensal, ) from src.calculators.iss import ParametrosISS, calcular_iss, requer_retencao_iss from src.calculators.simples_nacional import ( calcular_das, calcular_fator_r, calcular_pgdas, determinar_anexo_servicos, ) from src.fiscal.entities import RegimeTributario # --------------------------------------------------------------------------- # ICMS # --------------------------------------------------------------------------- class TestICMS: def test_icms_basico(self): r = calcular_icms(ParametrosICMS( valor_mercadoria=Decimal("10000"), aliquota=Decimal("18"), )) assert r.base_calculo == Decimal("10000.00") assert r.valor_icms == Decimal("1800.00") assert r.valor_total_icms == Decimal("1800.00") def test_icms_com_frete(self): r = calcular_icms(ParametrosICMS( valor_mercadoria=Decimal("10000"), aliquota=Decimal("18"), frete=Decimal("500"), )) assert r.base_calculo == Decimal("10500.00") assert r.valor_icms == Decimal("1890.00") def test_icms_cst_40_isento(self): r = calcular_icms(ParametrosICMS( valor_mercadoria=Decimal("10000"), aliquota=Decimal("18"), cst="040", )) assert r.valor_icms == Decimal("0") assert r.valor_total_icms == Decimal("0") def test_icms_reducao_base(self): r = calcular_icms(ParametrosICMS( valor_mercadoria=Decimal("10000"), aliquota=Decimal("18"), cst="020", reducao_base=Decimal("30"), )) assert r.base_calculo == Decimal("7000.00") assert r.valor_icms == Decimal("1260.00") def test_icms_st_com_mva(self): r = calcular_icms(ParametrosICMS( valor_mercadoria=Decimal("1000"), aliquota=Decimal("12"), cst="010", uf_origem="SP", uf_destino="MG", mva=Decimal("40"), aliq_st=Decimal("18"), )) assert r.valor_icms > 0 assert r.valor_st > 0 assert r.base_st == Decimal("1400.00") def test_icms_apuracao(self): debitos = [Decimal("1000"), Decimal("2000")] creditos = [Decimal("500"), Decimal("800")] r = calcular_icms_apuracao(debitos, creditos) assert r.valor_a_recolher == Decimal("1700.00") assert r.detalhes["saldo_credor"] == Decimal("0") def test_icms_apuracao_saldo_credor(self): debitos = [Decimal("500")] creditos = [Decimal("1000")] r = calcular_icms_apuracao(debitos, creditos) assert r.valor_a_recolher == Decimal("0") assert r.detalhes["saldo_credor"] == Decimal("500.00") def test_credito_icms_entrada(self): credito = calcular_icms_credito_entrada( valor_nf=Decimal("5000"), aliquota=Decimal("12"), ) assert credito == Decimal("600.00") def test_icms_difal(self): r = calcular_icms(ParametrosICMS( valor_mercadoria=Decimal("10000"), aliquota=Decimal("12"), uf_origem="SP", uf_destino="BA", calcular_difal=True, consumidor_final=True, )) assert r.valor_difal_destino > 0 or r.valor_difal_origem > 0 # --------------------------------------------------------------------------- # IPI # --------------------------------------------------------------------------- class TestIPI: def test_ipi_basico(self): r = calcular_ipi(ParametrosIPI( valor_produtos=Decimal("10000"), aliquota=Decimal("5"), )) assert r.base_calculo == Decimal("10000.00") assert r.valor_tributo == Decimal("500.00") def test_ipi_cst_52_isento(self): r = calcular_ipi(ParametrosIPI( valor_produtos=Decimal("5000"), aliquota=Decimal("10"), cst="52", )) assert r.valor_tributo == Decimal("0") def test_ipi_cst_50_tributado(self): r = calcular_ipi(ParametrosIPI( valor_produtos=Decimal("2000"), aliquota=Decimal("15"), cst="50", )) assert r.valor_tributo == Decimal("300.00") def test_aliquota_ipi_ncm_farmaceutico(self): aliq = obter_aliquota_ipi_ncm("30050000") # Capítulo 30 = farmacêutico assert aliq == Decimal("0") def test_aliquota_ipi_ncm_automovel(self): aliq = obter_aliquota_ipi_ncm("87032310") # Capítulo 87 = automóveis assert aliq == Decimal("25") def test_ipi_com_frete(self): r = calcular_ipi(ParametrosIPI( valor_produtos=Decimal("1000"), aliquota=Decimal("10"), frete=Decimal("100"), )) assert r.base_calculo == Decimal("1100.00") assert r.valor_tributo == Decimal("110.00") # --------------------------------------------------------------------------- # PIS / COFINS # --------------------------------------------------------------------------- class TestPisCofins: def test_lucro_presumido_cumulativo(self): receitas = [ReceitaBruta("Vendas", Decimal("100000"))] r = calcular_pis_cofins(receitas, RegimeTributario.LUCRO_PRESUMIDO) assert r.regime == "Cumulativo" assert r.aliq_pis == Decimal("0.65") assert r.aliq_cofins == Decimal("3.00") assert r.pis_a_recolher == Decimal("650.00") assert r.cofins_a_recolher == Decimal("3000.00") def test_lucro_real_nao_cumulativo(self): receitas = [ReceitaBruta("Serviços", Decimal("50000"))] r = calcular_pis_cofins(receitas, RegimeTributario.LUCRO_REAL) assert r.regime == "Não-Cumulativo" assert r.aliq_pis == Decimal("1.65") assert r.aliq_cofins == Decimal("7.60") assert r.pis_a_recolher == Decimal("825.00") assert r.cofins_a_recolher == Decimal("3800.00") def test_creditos_reduzem_valor_a_recolher(self): receitas = [ReceitaBruta("Vendas", Decimal("100000"))] creditos = [CreditoPisCofins( descricao="Compras para revenda", base_calculo=Decimal("60000"), aliquota_pis=Decimal("1.65"), aliquota_cofins=Decimal("7.60"), )] r = calcular_pis_cofins(receitas, RegimeTributario.LUCRO_REAL, creditos) assert r.creditos_pis == Decimal("990.00") assert r.creditos_cofins == Decimal("4560.00") assert r.pis_a_recolher == Decimal("660.00") # debito=7600 - credito=4560 = 3040 (créditos reduzem mas não zeram) assert r.cofins_a_recolher == Decimal("3040.00") def test_cst_07_nao_tributado(self): receitas = [ ReceitaBruta("Exportação", Decimal("50000"), cst_pis="07", cst_cofins="07") ] r = calcular_pis_cofins(receitas, RegimeTributario.LUCRO_REAL) assert r.pis_a_recolher == Decimal("0.00") assert r.cofins_a_recolher == Decimal("0.00") def test_retencao_servicos(self): r = calcular_pis_cofins_retencao(valor_servico=Decimal("10000")) assert r["valor_pis"] == Decimal("65.00") assert r["valor_cofins"] == Decimal("300.00") assert r["total_retido"] > Decimal("10") def test_retencao_dispensada_valor_baixo(self): r = calcular_pis_cofins_retencao(valor_servico=Decimal("100")) assert r["total_retido"] == Decimal("0") assert "dispensada" in r["observacao"] # --------------------------------------------------------------------------- # IRPJ / CSLL # --------------------------------------------------------------------------- class TestIRPJCSLL: def test_irpj_lucro_presumido_comercio(self): r = calcular_irpj_lucro_presumido( receita_bruta=Decimal("100000"), atividade="venda_mercadorias", ) # Base = 100.000 × 8% = 8.000 → IRPJ = 8.000 × 15% = 1.200 assert r.base_calculo == Decimal("8000.00") assert r.valor_base == Decimal("1200.00") assert r.irpj_a_recolher == Decimal("1200.00") assert r.valor_adicional == Decimal("0") def test_irpj_lucro_presumido_servicos(self): r = calcular_irpj_lucro_presumido( receita_bruta=Decimal("100000"), atividade="servicos_em_geral", ) # Base = 100.000 × 32% = 32.000 → IRPJ = 32.000 × 15% = 4.800 assert r.base_calculo == Decimal("32000.00") assert r.valor_base == Decimal("4800.00") def test_irpj_adicional_10pct(self): r = calcular_irpj_lucro_presumido( receita_bruta=Decimal("1000000"), atividade="venda_mercadorias", ) # Base = 80.000 → excede 60.000 em 20.000 → adicional = 2.000 assert r.base_calculo == Decimal("80000.00") assert r.base_adicional == Decimal("20000.00") assert r.valor_adicional == Decimal("2000.00") def test_irpj_lucro_real_compensacao(self): r = calcular_irpj_lucro_real( lucro_antes_ir=Decimal("100000"), compensacoes_prejuizo=Decimal("50000"), ) # Limite compensação = 30% de 100.000 = 30.000 assert r.base_calculo == Decimal("70000.00") def test_csll_lucro_presumido_comercio(self): r = calcular_csll_lucro_presumido( receita_bruta=Decimal("100000"), atividade="comercio_industria", ) # Base = 100.000 × 12% = 12.000 → CSLL = 12.000 × 9% = 1.080 assert r.base_calculo == Decimal("12000.00") assert r.valor_csll == Decimal("1080.00") def test_csll_lucro_real(self): r = calcular_csll_lucro_real(lucro_antes_csll=Decimal("50000")) assert r.base_calculo == Decimal("50000.00") assert r.valor_csll == Decimal("4500.00") def test_estimativa_mensal(self): r = calcular_irpj_estimativa_mensal( receita_bruta_mes=Decimal("500000"), atividade="venda_mercadorias", ) assert r["base_estimada"] == Decimal("40000.00") assert r["irpj_aliquota_base"] == Decimal("6000.00") assert r["irpj_adicional"] == Decimal("2000.00") # --------------------------------------------------------------------------- # ISS # --------------------------------------------------------------------------- class TestISS: def test_iss_basico(self): r = calcular_iss(ParametrosISS( valor_servico=Decimal("10000"), codigo_servico="17", aliquota_municipal=Decimal("2"), )) assert r.base_calculo == Decimal("10000") assert r.aliquota == Decimal("2") assert r.valor_tributo == Decimal("200.00") def test_iss_aliquota_minima(self): r = calcular_iss(ParametrosISS( valor_servico=Decimal("5000"), codigo_servico="17", aliquota_municipal=Decimal("1"), # Menor que o mínimo de 2% )) assert r.aliquota == Decimal("2") def test_iss_aliquota_maxima(self): r = calcular_iss(ParametrosISS( valor_servico=Decimal("5000"), codigo_servico="22", aliquota_municipal=Decimal("6"), # Maior que o máximo de 5% )) assert r.aliquota == Decimal("5") def test_requer_retencao_ti(self): assert requer_retencao_iss("01") is True # TI sempre retém def test_requer_retencao_alimentacao(self): assert requer_retencao_iss("99") is False # --------------------------------------------------------------------------- # Simples Nacional # --------------------------------------------------------------------------- class TestSimplesNacional: def test_das_anexo_i_faixa_1(self): r = calcular_das( receita_bruta_mes=Decimal("15000"), receita_bruta_acumulada_12m=Decimal("100000"), anexo="I", ) assert r.faixa == 1 assert r.aliq_nominal == Decimal("4.00") assert r.aliq_efetiva == Decimal("4.00") assert r.valor_das == Decimal("600.00") def test_das_anexo_i_faixa_2(self): r = calcular_das( receita_bruta_mes=Decimal("30000"), receita_bruta_acumulada_12m=Decimal("250000"), anexo="I", ) assert r.faixa == 2 assert r.aliq_efetiva < r.aliq_nominal # Alíq efetiva < nominal por dedução def test_das_anexo_iii_servicos(self): r = calcular_das( receita_bruta_mes=Decimal("10000"), receita_bruta_acumulada_12m=Decimal("150000"), anexo="III", ) assert r.faixa == 1 assert r.aliq_nominal == Decimal("6.00") def test_fator_r(self): fator = calcular_fator_r( folha_12m=Decimal("84000"), rec_12m=Decimal("300000"), ) assert fator == Decimal("28.0000") def test_determinar_anexo_advocacia_fator_r_baixo(self): anexo = determinar_anexo_servicos(Decimal("20"), "advocacia") assert anexo == "V" def test_determinar_anexo_advocacia_fator_r_alto(self): anexo = determinar_anexo_servicos(Decimal("30"), "advocacia") assert anexo == "III" def test_pgdas_multiplas_atividades(self): r = calcular_pgdas( cnpj="11222333000181", periodo="2024-01", receitas_por_atividade=[ {"valor": "20000", "anexo": "I"}, {"valor": "10000", "anexo": "III"}, ], receita_acumulada_12m=Decimal("200000"), ) assert r.das_total > 0 assert len(r.das_por_estabelecimento) == 2 assert r.data_vencimento is not None def test_das_dentro_limite(self): r = calcular_das( receita_bruta_mes=Decimal("400000"), receita_bruta_acumulada_12m=Decimal("4800000"), anexo="I", ) assert r.dentro_limite is True def test_das_acima_limite(self): r = calcular_das( receita_bruta_mes=Decimal("500000"), receita_bruta_acumulada_12m=Decimal("5000000"), anexo="I", ) assert r.dentro_limite is False