Speed / src /calculators /ipi.py
LesterCerioli's picture
Building Speed LLM
d9d7b41
Raw
History Blame Contribute Delete
6.04 kB
"""Calculadora de IPI (Imposto sobre Produtos Industrializados)."""
from __future__ import annotations
from dataclasses import dataclass
from decimal import Decimal
from typing import Optional
from src.calculators import ResultadoCalculo, arred
@dataclass
class ParametrosIPI:
valor_produtos: Decimal
aliquota: Decimal
cst: str = "50"
frete: Decimal = Decimal("0")
seguro: Decimal = Decimal("0")
outras_despesas: Decimal = Decimal("0")
desconto: Decimal = Decimal("0")
# Para operações por unidade (pauta)
quantidade: Decimal = Decimal("0")
valor_pauta_unidade: Optional[Decimal] = None
def calcular_ipi(p: ParametrosIPI) -> ResultadoCalculo:
# CSTs isentos/não tributados
if p.cst in {"51", "52", "53", "54", "55", "02", "03", "04", "05"}:
return ResultadoCalculo(
base_calculo=Decimal("0"),
aliquota=p.aliquota,
valor_tributo=Decimal("0"),
valor_a_recolher=Decimal("0"),
)
if p.cst == "03" and p.valor_pauta_unidade and p.quantidade:
# Tributação por pauta
base = arred(p.quantidade * p.valor_pauta_unidade)
else:
base = arred(
p.valor_produtos + p.frete + p.seguro + p.outras_despesas - p.desconto
)
valor = arred(base * p.aliquota / 100)
return ResultadoCalculo(
base_calculo=base,
aliquota=p.aliquota,
valor_tributo=valor,
valor_a_recolher=valor,
detalhes={"cst": p.cst},
)
def calcular_ipi_apuracao(
debitos: list[Decimal],
creditos: list[Decimal],
saldo_anterior: Decimal = Decimal("0"),
) -> ResultadoCalculo:
total_debitos = arred(sum(debitos))
total_creditos = arred(sum(creditos) + saldo_anterior)
valor_a_recolher = max(Decimal("0"), arred(total_debitos - total_creditos))
saldo_credor = max(Decimal("0"), arred(total_creditos - total_debitos))
return ResultadoCalculo(
base_calculo=total_debitos,
aliquota=Decimal("0"),
valor_tributo=total_debitos,
creditos=total_creditos,
valor_a_recolher=valor_a_recolher,
detalhes={
"total_debitos": total_debitos,
"total_creditos": total_creditos,
"saldo_credor": saldo_credor,
},
)
# Alíquotas IPI simplificadas por capítulo NCM (TIPI)
TIPI_ALIQUOTAS: dict[str, Decimal] = {
"01": Decimal("0"), # Animais vivos
"02": Decimal("0"), # Carnes e miudezas
"03": Decimal("0"), # Peixes e crustáceos
"04": Decimal("0"), # Leite, laticínios, ovos
"05": Decimal("0"), # Outros produtos de origem animal
"06": Decimal("0"), # Plantas vivas e produtos de floricultura
"07": Decimal("0"), # Produtos hortícolas
"08": Decimal("0"), # Frutas
"09": Decimal("0"), # Café, chá, mate
"10": Decimal("0"), # Cereais
"11": Decimal("0"), # Produtos da indústria de moagem
"12": Decimal("0"), # Sementes e frutos oleaginosos
"16": Decimal("0"), # Preparações de carne, peixe
"17": Decimal("5"), # Açúcares e produtos de confeitaria
"18": Decimal("5"), # Cacau e suas preparações
"19": Decimal("5"), # Preparações à base de cereais
"20": Decimal("5"), # Preparações de produtos hortícolas e frutas
"21": Decimal("5"), # Preparações alimentícias diversas
"22": Decimal("15"), # Bebidas, líquidos alcoólicos e vinagres
"24": Decimal("300"), # Tabaco e seus sucedâneos manufaturados
"25": Decimal("5"), # Sal; enxofre; terras e pedras
"27": Decimal("5"), # Combustíveis minerais, óleos minerais
"28": Decimal("5"), # Produtos químicos inorgânicos
"29": Decimal("5"), # Produtos químicos orgânicos
"30": Decimal("0"), # Produtos farmacêuticos
"31": Decimal("0"), # Adubos ou fertilizantes
"33": Decimal("7"), # Óleos essenciais e resinoides; cosméticos
"34": Decimal("5"), # Sabões, agentes orgânicos de superfície
"38": Decimal("5"), # Produtos diversos das indústrias químicas
"39": Decimal("15"), # Plásticos e suas obras
"40": Decimal("15"), # Borracha e suas obras
"41": Decimal("5"), # Peles, exceto peles com pelo
"42": Decimal("15"), # Obras de couro; artigos de seleiro
"44": Decimal("5"), # Madeira, carvão vegetal e obras de madeira
"48": Decimal("10"), # Papel e cartão
"49": Decimal("5"), # Livros, jornais, gravuras
"50": Decimal("10"), # Seda
"51": Decimal("10"), # Lã, pelos finos ou grosseiros
"52": Decimal("10"), # Algodão
"61": Decimal("20"), # Vestuário e seus acessórios (malha)
"62": Decimal("20"), # Vestuário e seus acessórios (exceto malha)
"64": Decimal("20"), # Calçados, polainas e artefatos semelhantes
"69": Decimal("15"), # Produtos cerâmicos
"70": Decimal("15"), # Vidro e suas obras
"72": Decimal("5"), # Ferro fundido, ferro e aço
"73": Decimal("10"), # Obras de ferro fundido, ferro ou aço
"74": Decimal("10"), # Cobre e suas obras
"76": Decimal("10"), # Alumínio e suas obras
"82": Decimal("10"), # Ferramentas, artefatos de cutelaria
"84": Decimal("10"), # Máquinas e aparelhos mecânicos
"85": Decimal("15"), # Máquinas e aparelhos elétricos
"86": Decimal("5"), # Veículos e material para vias férreas
"87": Decimal("25"), # Veículos automóveis, tratores
"88": Decimal("0"), # Aeronaves e aparelhos espaciais
"90": Decimal("15"), # Instrumentos e aparelhos de óptica
"91": Decimal("20"), # Instrumentos de relojoaria
"92": Decimal("25"), # Instrumentos musicais
"94": Decimal("15"), # Móveis; mobiliário médico-cirúrgico
"95": Decimal("25"), # Brinquedos, jogos, artigos para divertimento
"96": Decimal("10"), # Obras diversas
}
def obter_aliquota_ipi_ncm(ncm: str) -> Decimal:
capitulo = ncm[:2]
return TIPI_ALIQUOTAS.get(capitulo, Decimal("5"))