File size: 6,040 Bytes
d9d7b41 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | """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"))
|