Speed / src /generators /sped_writer.py
LesterCerioli's picture
Building Speed LLM
d9d7b41
Raw
History Blame Contribute Delete
2.97 kB
from __future__ import annotations
import hashlib
from datetime import date
from decimal import Decimal
from pathlib import Path
from typing import Any
def _fmt_data(d: date | None) -> str:
if d is None:
return ""
return d.strftime("%d%m%Y")
def _fmt_decimal(v: Decimal | None, casas: int = 2) -> str:
if v is None or v == 0:
return ""
return f"{v:.{casas}f}".replace(".", ",")
def _fmt_str(v: Any) -> str:
if v is None:
return ""
return str(v).strip()
class RegistroSPED:
def __init__(self, tipo: str):
self.tipo = tipo
self._campos: list[str] = []
def add(self, valor: Any, tipo_campo: str = "str", casas: int = 2) -> "RegistroSPED":
if valor is None or valor == "":
self._campos.append("")
elif tipo_campo == "data":
self._campos.append(_fmt_data(valor))
elif tipo_campo == "decimal":
self._campos.append(_fmt_decimal(Decimal(str(valor)), casas))
elif tipo_campo == "int":
self._campos.append(str(int(valor)))
else:
self._campos.append(str(valor).strip())
return self
def to_line(self) -> str:
campos = [self.tipo] + self._campos
return "|" + "|".join(campos) + "|\n"
class ArquivoSPED:
def __init__(self, nome_arquivo: str):
self.nome_arquivo = nome_arquivo
self._linhas: list[str] = []
self._contadores: dict[str, int] = {}
def _add_linha(self, linha: str) -> None:
self._linhas.append(linha)
tipo = linha.split("|")[1] if "|" in linha else ""
self._contadores[tipo] = self._contadores.get(tipo, 0) + 1
def adicionar_registro(self, reg: RegistroSPED) -> None:
self._add_linha(reg.to_line())
def adicionar_linha_raw(self, linha: str) -> None:
if not linha.endswith("\n"):
linha += "\n"
self._add_linha(linha)
def total_linhas(self) -> int:
return len(self._linhas)
def conteudo(self) -> str:
return "".join(self._linhas)
def salvar(self, diretorio: str | Path = ".") -> Path:
caminho = Path(diretorio) / self.nome_arquivo
caminho.parent.mkdir(parents=True, exist_ok=True)
caminho.write_text(self.conteudo(), encoding="utf-8")
return caminho
def hash_md5(self) -> str:
return hashlib.md5(self.conteudo().encode("utf-8")).hexdigest()
def criar_registro(tipo: str, *campos) -> str:
partes = [tipo]
for campo in campos:
if campo is None:
partes.append("")
elif isinstance(campo, date):
partes.append(_fmt_data(campo))
elif isinstance(campo, Decimal):
partes.append(_fmt_decimal(campo))
elif isinstance(campo, float):
partes.append(_fmt_decimal(Decimal(str(campo))))
else:
partes.append(str(campo).strip())
return "|" + "|".join(partes) + "|\n"