|
|
| from __future__ import annotations |
|
|
| from dataclasses import dataclass |
| from datetime import date |
| from decimal import Decimal |
| from pathlib import Path |
| from typing import Optional |
|
|
| from src.calculators.pis_cofins import ( |
| CreditoPisCofins, |
| ReceitaBruta, |
| ResultadoPisCofins, |
| calcular_pis_cofins, |
| ) |
| from src.fiscal.entities import Empresa, NotaFiscal, PeriodoApuracao, RegimeTributario |
| from src.generators.sped_writer import ArquivoSPED, criar_registro |
|
|
| VERSAO_LEIAUTE = "006" |
|
|
|
|
| @dataclass |
| class ConfigEFDContrib: |
| versao: str = VERSAO_LEIAUTE |
| finalidade: str = "0" |
| ind_situacao_especial: str = "" |
|
|
|
|
| class GeradorEFDContribuicoes: |
| |
|
|
| def __init__( |
| self, |
| periodo: PeriodoApuracao, |
| creditos: Optional[list[CreditoPisCofins]] = None, |
| cfg: Optional[ConfigEFDContrib] = None, |
| ): |
| self.periodo = periodo |
| self.creditos = creditos or [] |
| self.cfg = cfg or ConfigEFDContrib() |
| self._arquivo = ArquivoSPED( |
| f"EFD_CONTRIB_{periodo.empresa.cnpj}_{periodo.data_inicio.strftime('%Y%m')}.txt" |
| ) |
|
|
| def _bloco_0(self) -> None: |
| emp = self.periodo.empresa |
| end = emp.endereco |
|
|
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "0000", |
| self.cfg.versao, |
| self.cfg.finalidade, |
| self.periodo.data_inicio, |
| self.periodo.data_fim, |
| emp.razao_social, |
| emp.cnpj, |
| emp.cnpj[:8], |
| emp.ie, |
| emp.im, |
| emp.suframa, |
| self.cfg.ind_situacao_especial, |
| emp.regime_tributario.value, |
| emp.endereco.uf.value, |
| )) |
|
|
| self._arquivo.adicionar_linha_raw(criar_registro("0001", "0")) |
|
|
| |
| ind_metodo_apropriacao = "1" |
| if emp.regime_tributario == RegimeTributario.LUCRO_REAL: |
| cod_inc_trib = "1" |
| elif emp.regime_tributario == RegimeTributario.LUCRO_PRESUMIDO: |
| cod_inc_trib = "2" |
| else: |
| cod_inc_trib = "3" |
|
|
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "0110", |
| cod_inc_trib, |
| ind_metodo_apropriacao, |
| "1", |
| )) |
|
|
| |
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "0140", |
| emp.cnpj, |
| emp.nome_fantasia or emp.razao_social, |
| end.uf.value, |
| emp.ie, |
| end.cod_municipio, |
| emp.im, |
| emp.suframa, |
| )) |
|
|
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "0990", self._arquivo.total_linhas() + 1 |
| )) |
|
|
| def _bloco_c(self) -> None: |
| |
| self._arquivo.adicionar_linha_raw(criar_registro("C001", "0")) |
|
|
| for nf in self.periodo.notas_saida: |
| tipo_oper = "1" |
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "C100", |
| tipo_oper, |
| "0", |
| nf.destinatario.cnpj, |
| nf.modelo, |
| nf.serie, |
| nf.numero, |
| nf.chave_acesso, |
| nf.data_emissao, |
| nf.data_saida_entrada, |
| nf.valor_produtos, |
| Decimal("0"), |
| nf.valor_ipi, |
| nf.valor_total, |
| )) |
|
|
| for item in nf.itens: |
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "C170", |
| item.numero_item, |
| item.produto.codigo, |
| item.produto.descricao, |
| item.quantidade, |
| item.produto.unidade, |
| item.valor_unitario, |
| item.desconto, |
| item.cfop, |
| item.produto.cst_pis, |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| item.produto.cst_cofins, |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| "", |
| )) |
|
|
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "C990", self._arquivo.total_linhas() |
| )) |
|
|
| def _bloco_m(self, resultado: ResultadoPisCofins) -> None: |
| |
| self._arquivo.adicionar_linha_raw(criar_registro("M001", "0")) |
|
|
| |
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "M100", |
| "01", |
| "1", |
| resultado.base_pis, |
| resultado.aliq_pis, |
| Decimal("0"), |
| Decimal("0"), |
| resultado.creditos_pis, |
| Decimal("0"), |
| resultado.creditos_pis, |
| Decimal("0"), |
| resultado.creditos_pis, |
| Decimal("0"), |
| Decimal("0"), |
| resultado.creditos_pis, |
| )) |
|
|
| |
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "M200", |
| resultado.valor_pis_debito, |
| Decimal("0"), |
| Decimal("0"), |
| resultado.creditos_pis, |
| resultado.pis_a_recolher, |
| Decimal("0"), |
| resultado.pis_a_recolher, |
| resultado.pis_a_recolher, |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| resultado.pis_a_recolher, |
| )) |
|
|
| |
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "M600", |
| resultado.valor_cofins_debito, |
| Decimal("0"), |
| Decimal("0"), |
| resultado.creditos_cofins, |
| resultado.cofins_a_recolher, |
| Decimal("0"), |
| resultado.cofins_a_recolher, |
| resultado.cofins_a_recolher, |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| Decimal("0"), |
| resultado.cofins_a_recolher, |
| )) |
|
|
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "M990", self._arquivo.total_linhas() |
| )) |
|
|
| def _bloco_1(self) -> None: |
| |
| self._arquivo.adicionar_linha_raw(criar_registro("1001", "1")) |
| self._arquivo.adicionar_linha_raw(criar_registro( |
| "1990", self._arquivo.total_linhas() |
| )) |
|
|
| def _bloco_9(self) -> None: |
| self._arquivo.adicionar_linha_raw(criar_registro("9001", "0")) |
| qt = self._arquivo.total_linhas() + 3 |
| self._arquivo.adicionar_linha_raw(criar_registro("9900", "0000", "1")) |
| self._arquivo.adicionar_linha_raw(criar_registro("9990", qt)) |
| self._arquivo.adicionar_linha_raw(criar_registro("9999", qt + 1)) |
|
|
| def gerar(self, diretorio: str | Path = ".") -> Path: |
| receitas = [ |
| ReceitaBruta( |
| descricao=f"Vendas NF {nf.numero}", |
| valor=nf.valor_produtos, |
| cst_pis="01", |
| cst_cofins="01", |
| ) |
| for nf in self.periodo.notas_saida |
| ] |
|
|
| resultado = calcular_pis_cofins( |
| receitas=receitas, |
| regime=self.periodo.empresa.regime_tributario, |
| creditos=self.creditos, |
| ) |
|
|
| self._bloco_0() |
| self._bloco_c() |
| self._bloco_m(resultado) |
| self._bloco_1() |
| self._bloco_9() |
|
|
| return self._arquivo.salvar(diretorio) |
|
|