Skip to content

About

Automações financeiras de cálculo de produção cooperativista

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Latest commit

 

History

1,234 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cálculo de produção cooperativista

ETL de produção cooperativista com conectores de dados, apuração econômica e publicação contábil separados por contratos de integração. O perfil padrão preserva o modelo operacional da LibreCode com Kimai, Nextcloud Profile Fields e Akaunting. Perfis adicionais podem definir outras métricas e políticas sem reutilizar implicitamente as regras financeiras da LibreCode.

Requisitos do perfil LibreCode

Sistema Descrição
Kimai Registro de horas trabalhadas por projeto, emissão de relatório de horas trabalhadas para clientes
Akaunting Gestão financeira
Nextcloud + Profile Fields Diretório interno dos cooperados com os campos customizados weight, tax_number e dependents usados na produção

Ambiente de desenvolvimento e homologação

Execute a apuração em uma instalação e bancos isolados dos produtivos. Os dados importados podem conter informações pessoais e financeiras: mantenha dumps, .env, CSVs e logs fora do Git, sob permissões privadas e uma política de retenção.

  1. Copie .env.example para .env e configure somente credenciais de desenvolvimento; não use tokens de escrita, senhas nem chaves de produção para homologar.
  2. Verifique que DATABASE_URL aponta para um banco intermediário próprio da homologação, DATABASE_AKAUNTING_URL para a cópia local do banco do Akaunting e AKAUNTING_API_BASE_URL para uma API local, nunca para o serviço de produção. O bootstrap de testes recusa bancos remotos e URLs de API não locais. Chamadas HTTP reais sob APP_ENV=test também são bloqueadas fora de serviços locais; clientes HTTP simulados não acessam a rede.
  3. Defina APP_ENV=dev (ou test para PHPUnit). Selecione COOPERATIVE_PROFILE=librecode somente para a política vigente; outros perfis exigem instância/banco próprios.
  4. Evite publicar portas de banco no host e não conecte o ETL a redes externas quando estiver testando snapshots. Configure a infraestrutura de homologação existente em vez de reutilizar bancos de desenvolvimento compartilhados.

O projeto usa duas bases distintas: a do ETL (transformações, importações e auditoria) e a do Akaunting (documentos contábeis). Restaurar apenas uma delas não reproduz a execução histórica. O Kimai e as demais integrações exigem fontes autorizadas, ou um snapshot previamente importado.

Ações para que tudo funcione

  • Emissão e consulta de NFS-e são responsabilidade do módulo fiscal do Akaunting e do Emissor Nacional. A importação da produção utiliza documentos financeiros do Akaunting, sem consultar portais municipais.
  • Nextcloud + Profile Fields
    • Criar no app profile_fields os campos weight, tax_number e dependents.
    • Preencher estes campos para cada cooperado; eles passam a ser a fonte oficial do peso, do CPF/CNPJ e da quantidade de dependentes usados no cálculo.
    • O Kimai fornece horas e uma referência de CPF/CNPJ para conciliação, mas não fornece mais dependentes: a importação exige o valor explícito no Profile Fields. Veja docs/member-data-authority.md.
  • Akaunting
    • Dados de clientes
      • Definir número de identificação fiscal (cpf/cnpj) para todo fornecedor/cliente. Quando houver nota emitida para mais de um setor de um mesmo CNPJ e figurarem diferentes contas na LibreCode (conta = contrato), concatenar da seguinte forma: <cpf/CNPJ>|<setor>
    • Receitas
      • Toda transação com nota fiscal emitida pela LibreCode deve conter o número da nota fiscal no campo referência.
      • Sempre que for receita vinda de cliente deve possuir a categoria Recorrência ou Serviço
    • Divisão de sobras
      • Criar uma fatura de venda com categoria Cliente > Interno > Cooperado > Produção > Distribuição de sobras
      • Colocar o cliente como LibreCode (é um cliente interno)
      • Inserir um item "Bruto produção" e remover a descrição padrão
      • No valor do item, inserir o valor que será dividido
      • Campo de anotações:
        • Colocar o motivo da divisão de sobras bem detalhado
        • Informar se é transaçâo para algum mês específico
      • Criar a fatura
      • Marcar fatura como enviada
      • Cancelar fatura. Após cancelada, a fatura não será contabilizada no mês mas será considerado o valor dela para distribuição de sobras.
    • Custos
      • Categorizar transação de saída como Cliente (custo) quando forem custos de clientes

      • Sempre que for custo reembolsável pelo cliente, adicionar <cpf/CNPJ>|<setor> na transação no campo Referência para que seja possível identificar qual cliente deverá reembolsar este custo de entrada. Lembrar de acrescentar o setor sempre que necessário.

      • Todo custo que deve descontar do líquido da fatura do cooperado precisa estar abaixo da categoria pai Cooperado > Produção > Desconto líquido

        • Exemplo: Cooperado > Produção > Desconto líquido > Plano de saúde
        • Exemplo: Cooperado > Produção > Desconto líquido > Telefonia
      • Configure o id da categoria pai em AKAUNTING_PARENT_DESCONTO_LIQUIDO_CATEGORY_ID

      • Categorias fora desta hierarquia são ignoradas.

      • No campo "nota" (descrição) de cada desconto líquido deve conter a divisão por cooperado. Exemplo:

        Cooperado: Hedy Lamarr; CPF: 00000000000; Valor: 781,95
        Cooperado: Grace Hopper; CPF: 11111111111; Valor: R$ 439,55
        Cooperado: Ada Lovelace, CPF: 22222222222, Valor: 1.592,65
        Cooperado: Radia Perlman, CPF: 33333333333, Valor: R$12.345,67

        Validação monetária: use vírgula como separador decimal e ponto apenas entre grupos de três dígitos para milhares. São aceitos 781,95, R$ 781,95, 1.592,65 e R$12.345,67. Um valor como 1592.65, com ponto decimal, interrompe o cálculo com uma mensagem de correção; não será interpretado como 159265. O formato é obrigatório: confira as notas antes de apurar a produção.

      • Customização da fatura (compra ou venda) ou transação deve ser inserida na descrição. Valores possíveis:

        Nome Descrição
        Transação do mês Mês onde esta transação será contabilizada. Formato: 2023-09
        CNPJ cliente CNPJ do cliente de quem será cobrado o valor
        Setor Setor do cliente, quando é um CNPJ com mais de um contrato
        Arquivar sim = Arquivar transação e não utilizá-la.
        Percentual desconto fixo Ignora a taxa administrativa (somatório de todas as despesas do mês incluindo valor de NFSe e custos da coop do mês) e aplica apenas este perentual de desconto no valor da nota.

        Valores customizados precisam ter o nome da propriedade separado do valor com dois pointos, exemplo:

        Transação do mês: 2023-05
        

Checklist de configuração da LibreCode

  • Cada contato de cooperado no Akaunting deve ter identificação fiscal válida e verificável.
  • Confira os IDs de categorias, itens e tributos no Akaunting e as variáveis correspondentes do .env, sem copiar credenciais de produção.
  • Antes de uma publicação, valide pesos, dependentes e identificação no Profile Fields, apontamentos do Kimai, recebimentos efetivos, categorias e despesas no Akaunting e eventuais campos manuais de competência.

Setup

Primeiro clone o repositório e entre nele.

Copie o arquivo .env.example para .env

Edite o arquivo .env preenchendo os dados necessários.

Em um terminal:

docker compose up

Em outro terminal:

docker compose exec php bash
composer install
php ./bin/console doctrine:migrations:migrate -n

O banco de ETL de produção não é descartável: além dos dados importados, ele mantém o histórico de tentativas de publicação financeira. Em instalações novas, as migrations são executadas em ordem sobre um banco vazio; em ambientes existentes, aplique apenas as migrations pendentes após backup e conferência. A retirada da tabela nfse exige confirmação de que ela está vazia. Não apague tabelas ou reinicie o histórico de migrations da Conceição para simplificar o PR.

Comandos

Prévia e publicação

O comando make:producao calcula sem publicar por padrão. Para conferir valores, use --csv: a prévia inclui agora o número esperado do documento PDC_...-AAAA-MM, permitindo conciliação por identificador, e não por posição da linha.

php bin/console make:producao --ano-mes=2026-08 --baixar-dados=0 --as-of=2026-10-07 --csv
  • --ano-mes=AAAA-MM identifica o mês trabalhado; 2026-08 corresponde à competência de documentos 2026-09, com pagamento previsto no mês seguinte.
  • --baixar-dados=1 (padrão) importa novamente as fontes externas e altera o banco intermediário. Para importar separadamente, use etl:sync --ano-mes=AAAA-MM.
  • --baixar-dados=0 apenas reutiliza dados já importados: não garante, sozinho, uma fotografia histórica, nem corrige importação incompleta. Aceita exclusivamente 0 ou 1.
  • --as-of=AAAA-MM-DD fixa a data de referência em uma prévia e não pode ser combinado com publicação.
  • --dias-uteis, --dia-util-pagamento e --percentual-maximo afetam o cálculo; use somente parâmetros aprovados.
  • --atualiza-producao publica documentos e tributos no Akaunting configurado; use apenas após conferência e autorização, nunca conectado à produção durante homologação.
  • --database não grava dados nem publica por conta própria e agora é recusado explicitamente. --ods foi removido: não havia exportação ODS implementada.

Uma prévia recalculada pode divergir de uma fatura paga por mudanças posteriores nas fontes, descontos, adiantamentos ou critérios. Não altere o valor histórico automaticamente para fazer os relatórios coincidirem.

O comando principal é composto pela execução independente de cada um dos comandos abaixo que você provavelmente não precisará usar:

Available commands:
 get
  get:categories                     Get categories
  get:customers                      Get customers
  get:invoices                       Get invoices
  get:projects                       Get projects
  get:taxes                          Get taxes
  get:timesheets                     Get timesheets
  get:transactions                   Get transactions
  get:users                          Get users

Rotina de conferência mensal

  1. Conferir as origens: fechamento das horas no Kimai, campos cadastrais no Profile Fields, identificação dos cooperados, pagamentos de clientes, notas, custos e categorias corretas no Akaunting. Campos livres como Transação do mês, Arquivar: sim e descontos fixos exigem conferência humana. Não use essas marcações para contornar uma diferença não investigada. Receitas e despesas vinculadas a clientes devem ter identificador explícito; referências ausentes não serão mais presumidas como o CNPJ da própria cooperativa.
  2. Importar e preservar o corte: execute etl:sync --ano-mes=AAAA-MM com acesso autorizado e gere audit:inputs --ano-mes=AAAA-MM --revision="$(git rev-parse HEAD)". Preserve snapshot intermediário e manifesto em área confidencial. Importar outra competência pode mudar as bases da anterior.
  3. Calcular sem publicar: make:producao --ano-mes=AAAA-MM --baixar-dados=0 --csv; use --as-of em auditoria histórica. Confira todos os números PDC_, bases, retenções, adiantamentos, descontos, FRRA, totais e datas. Guarde o CSV com acesso restrito.
  4. Conciliar em leitura com o Akaunting: compare document_number, situação (draft, paid ou cancelled), competência, itens e notas. Não sobrescreva faturas finalizadas. Toda divergência exige explicação sobre dados de origem, data de corte, política e eventuais ajustes posteriores.
  5. Aprovar ou bloquear: obtenha a revisão financeira/contábil aplicável antes de usar --atualiza-producao no ambiente aprovado. Ausência de horas, custos sem receita, capital elegível insuficiente ou inconsistência cadastral bloqueiam a publicação. Após uma falha de publicação, confira os registros existentes antes de repetir a operação.

Para o procedimento seguro de reconciliação e retomada após publicação parcial, consulte docs/publication-recovery.md. O histórico de tentativas de emissão é consultável por php bin/console publication:pending --limit=100; exige a nova migration do banco intermediário, preservada pelo reset do ETL.

Publicações de cooperados pessoa física cuja previsão de pagamento atravesse o ano civil ficam bloqueadas até revisão do período de incidência do IRRF. Consulte docs/tax-period-boundary.md. A prévia continua disponível; isso não homologa pagamentos dentro do mesmo exercício.

Logs e sigilo

O Monolog registra a execução em var/log/<APP_ENV>.log (por exemplo, var/log/dev.log) e os erros em var/log/calculation-errors.log, ambos com rotação. Acompanhe localmente com:

tail -f var/log/dev.log var/log/calculation-errors.log

Logs, relatórios CSV e snapshots podem conter dados pessoais ou financeiros. Nunca os anexe a um PR ou issue públicos.

Requisitos e qualidade

  • PHP: imagem de execução declarada uma única vez em ARG PHP_IMAGE de .docker/php/Dockerfile; os workflows leem esse valor automaticamente. O composer.json mantém apenas a versão mínima compatível.
  • Node.js: versão de execução de testes declarada em .nvmrc. O frontend usa JavaScript nativo, sem dependências npm instaladas.
  • Dependências: composer update -W no backend, com ferramentas de desenvolvimento isoladas em vendor-bin. O Dependabot acompanha Composer, GitHub Actions e Docker Compose; o Renovate acompanha o Dockerfile, .nvmrc e a imagem MySQL usada pelo CI. As atualizações exigem revisão e CI aprovada.
  • Modernização de PHP: composer run rector:check verifica as refatorações, e composer run rector:fix aplica as alterações.
  • Verificação: composer run test:unit, composer run cs:check e composer run psalm. Os testes de JavaScript usam node --test tests/js/*.test.cjs. A CI executa esses testes em um workflow separado, com limites mínimos de cobertura (90% de linhas, 80% de ramos e 75% de funções).
  • Testabilidade do frontend: regras de domínio JavaScript (competência e conciliação de fontes, seleção e arredondamento de cooperados, elegibilidade de vínculos, interpretação de documentos financeiros, validação de IDs e processamento SSE) são funções puras ou adaptadores independentes de DOM/HTTP. Use casos parametrizados (for com test() nomeado) em tests/js/*-rules.test.cjs para valores nulos, zero legítimo, identificadores inválidos, competência incorreta e operações concorrentes; mantenha testes de integração com DOM/HTTP simulados para validar efeitos e autorizações. O node:test nativo é suficiente; não introduza bibliotecas de UI quando uma regra puder ser testada sem navegador.

Arquitetura do ETL e apuração por competência

O pipeline mantém quatro limites: conectores de origem (Kimai e Akaunting), banco de transformação, apuração econômica e publicação opcional no Akaunting. As etapas de origem implementam SourceStep e são orquestradas por SourcePipeline, preservando a ordem das dependências. ProductionDistributionPlanner calcula a distribuição sem acessar APIs ou saldo bancário. O capital social é consultado separadamente e não integra receitas de clientes.

A competência mensal é validada como YYYY-MM. A importação completa do Kimai reconcilia alterações e exclusões. Em casos não cobertos pela reconciliação de lançamentos financeiros, utilize a reconstrução do banco intermediário e importe novamente. A nova classificação contraditória de percentuais fixos e móveis do mesmo cliente interrompe o cálculo para análise, em vez de permitir uma distribuição incompleta.

Audite os dados intermediários sem qualquer escrita financeira:

php bin/console audit:inputs --ano-mes=2025-04 --revision="$(git rev-parse HEAD)"

O relatório compacto mostra contagens e fingerprints SHA-256 de entradas, pesos e configurações (incluindo dependências e runtime), sem expor valores financeiros ou dados pessoais. Para preservar as entradas integrais de uma execução, adicione --save-bundle. O arquivo ficará em var/audit/ com permissão privada. Verifique posteriormente com php bin/console audit:verify --file=var/audit/AAAA-MM/NOME.json; a verificação detecta alterações no conteúdo em relação ao manifesto, mas não substitui armazenamento imutável externo nem uma assinatura digital independente. Contém dados pessoais e financeiros confidenciais: proteja o acesso, os backups e a retenção conforme a LGPD; não publique em Git ou PRs.

Simule o resultado de uma competência antiga com uma data de referência operacional definida:

php bin/console make:producao --ano-mes=2025-04 --baixar-dados=0 --as-of=2025-05-10

--as-of é exclusivo de prévias e não pode ser combinado com --atualiza-producao.

Os relatórios e arquivos de auditoria permitem conferir os dados efetivamente disponíveis na execução indicada, seus parâmetros e a versão do código. A análise de qualquer competência deve considerar o conjunto de comprovantes, políticas aprovadas e dados de origem aplicáveis ao período; a geração de um relatório não equivale, por si só, à certificação contábil da competência.

Arquitetura por perfis de cooperativa

  • Ingestão: cada integração implementa SourceStep. SourcePipeline seleciona somente as etapas declaradas pelo perfil, sem alterar os conectores existentes.
  • Perfil: CooperativeProfile declara as origens e a política de distribuição. ProfileRegistry seleciona o perfil por instalação usando COOPERATIVE_PROFILE (padrão: librecode). Não existe isolamento de múltiplas cooperativas no mesmo banco; cada cooperativa precisa de uma instalação/banco independente.
  • Métricas: MetricStrategy permite novas unidades de produção. As implementações de exemplo são elapsed-hours (horas registradas) e work-entries (quantidade de apontamentos faturáveis). Os dados importados do Kimai são normalizados por WorkMetricsReader; o perfil de exemplo usa BasicUsers, sem exigir CPF, Profile Fields ou vínculo prévio com o Akaunting.
  • Política de rateio: AllocationPolicy recebe valores elegíveis aprovados e medições normalizadas, sem depender do Akaunting. HoursProportionalPolicy é apenas um exemplo técnico de cálculo proporcional por cliente, não uma regra atribuída à Inovar ou a qualquer outra cooperativa.
  • Publicação: ProductionPublisher e PublicationRouter isolam a gravação. O único publicador homologado por padrão é o da LibreCode (produção, FRRA e tributos). Para outro perfil, a publicação fica bloqueada até que exista implementação e aprovação contábil específicas.

Configure COOPERATIVE_PROFILE=hours em uma instância de homologação própria, depois importe as origens desse perfil:

php bin/console etl:sync --ano-mes=2026-07

Forneça um arquivo JSON de bases elegíveis aprovadas. O programa não presume que saldo bancário, faturamento bruto ou valor de nota seja distribuível:

[
  {"customer_reference": "CLIENTE-EXEMPLO", "eligible_amount": 1200.00, "currency": "BRL"}
]

Execute a prévia com uma métrica configurada:

php bin/console allocation:preview --ano-mes=2026-07 --receipts-file=/caminho/restrito/bases.json --metric=elapsed-hours

A prévia inclui valores por cliente/cooperado, total elegível, total distribuído e fingerprint do arquivo de bases, sem emissão de documentos. work-entries demonstra uma métrica alternativa. Para usar outra política econômica, implemente a interface de rateio, o perfil e, quando aprovado, um publicador financeiro próprio; não altere diretamente os conectores Kimai ou as regras da LibreCode.

O comando make:producao e a interface de produção contábil existente permanecem exclusivos do perfil librecode. O Akaunting armazena os documentos financeiros; a emissão e a validação fiscal das NFS-e pertencem ao módulo fiscal do Akaunting e ao Emissor Nacional, fora deste ETL.

Implantação em produção

A instalação produtiva usa o Compose versionado e o procedimento operacional. As configurações da aplicação, Nginx e PHP ficam no Git; credenciais, bancos de dados e hashes do HTTP Basic Auth ficam exclusivamente no servidor.

Estilos

Edite os arquivos em resources/scss/, não os CSS gerados. Os arquivos compilados em public/css/ são versionados e servidos diretamente: Node.js/Sass não são exigidos na Conceição. Para desenvolver ou revisar os estilos, use:

npm ci --include=dev
npm run scss:format        # formata o código-fonte
npm run scss:format:check  # falha se o SCSS estiver fora do padrão
npm run scss:lint          # verifica erros e construções SCSS
npm run css:build          # atualiza os CSS versionados após editar o SCSS
npm run css:check          # compila em memória e compara sem alterar arquivos

O workflow Styles executa dois checks independentes em todo pull request: SCSS formatting and lint (Prettier + Stylelint) e Generated CSS matches SCSS (inclui testes para alterações manuais e CSS ausente/obsoleto). Se o segundo falhar, rode npm run css:build e inclua os CSS atualizados no commit. Não edite public/css/ manualmente; o verificador sempre recompila o SCSS em memória e compara byte a byte com o CSS versionado.

Nos SCSS, agrupe as regras de um componente sob seu seletor pai (por exemplo, .production-period-fields { .form-field { ... } label { ... } }) em vez de repetir o prefixo em cada regra. Para estados, use &:hover e &[data-state="..."]. Mantenha seletores compartilhados entre componentes fora desses blocos quando o agrupamento mudaria o escopo; evite hierarquias profundas que aumentem a especificidade. Formatação e compilação idêntica são verificadas pela CI, mas a decisão de aninhar deve preservar a semântica do CSS.

Configuração administrativa

Para editar integrações e regras, configure CONFIG_ADMIN_USERS no .env com os nomes autorizados na autenticação HTTP Basic. Credenciais são exibidas somente sob demanda e alterações são gravadas em var/admin-config/settings.json (privado, não versionado). O arquivo sobrepõe os parâmetros na próxima requisição ou execução CLI; proteja-o nos backups. Valores incorretos podem impedir a apuração ou a conexão com serviços externos.

Competência de fechamento e leitura das fontes

A competência é o mês das horas trabalhadas. Para a LibreCode, a regra configurável é trabalhar em M, faturar/receber em M+1 e fechar em M+2 (PRODUCAO_FECHAMENTO_DEFASAGEM_MESES=2). O formulário sugere essa competência, mas permite selecionar manualmente outros meses. Já os relatórios, sem data na URL, mostram a última competência de horas efetivamente importada, para evitar aparentar perda de dados após a virada do mês. Mudar a data sugerida nunca limpa a base.

A página de limpeza exibe o ambiente real: APP_DEPLOYMENT_STAGE pode ser production, staging ou development; na ausência desse parâmetro, APP_ENV=prod identifica produção. Quando o Symfony local usa APP_ENV=prod para cache e desempenho, configure explicitamente APP_DEPLOYMENT_STAGE=development; na instalação de produção, configure APP_DEPLOYMENT_STAGE=production. Ambiente de execução não é origem dos dados. Apenas em instalações não produtivas um administrador pode selecionar APP_DATA_SOURCE_PROFILE=production. Essa opção só aparece quando as dez variáveis SOURCE_PRODUCTION_* do exemplo estiverem configuradas separadamente. Configure o acesso SQL ao Akaunting de produção com usuário somente leitura, sem permissão de gravação. Não é permitido mudar de fonte enquanto qualquer tabela de importação possuir dados. O seletor de origem não é apresentado em produção.

Ao utilizar fontes de produção em desenvolvimento/homologação, atualizações de perfis Nextcloud e publicações no Akaunting são bloqueadas. Em desenvolvimento, outras gravações externas também ficam bloqueadas por padrão, salvo aprovação no servidor com APP_NONPROD_SOURCE_WRITES_ENABLED=1 e uso de fontes de homologação. Essa opção é para importação e conferência, não para alterar cadastros reais.

A meta PRODUCAO_META_LIQUIDA_MENSAL (R$ 50.000 por padrão), para PRODUCAO_META_HORAS_REFERENCIA (165 h por padrão), é uma simulação não vinculante. O cálculo estima a base necessária para uma pessoa física atingir o líquido proporcional às horas usando as tabelas de INSS/IRPF da competência. A comparação não desconta antecipações e descontos individuais nem altera o rateio atual, os pagamentos ou as sobras contábeis. Uma distribuição real limitada por teto e destinação de excedente exige uma política formal adicional, não implementada aqui.

About

Automações financeiras de cálculo de produção cooperativista

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Used by

Contributors

Languages