Junta faturas atrasadas do cliente numa renegociação: aplica desconto ou acréscimo, parcela em até 12x (com entrada opcional) e gera os boletos/PIX das parcelas. As faturas antigas são canceladas. A tela Financeiro → Renegociações é o acompanhamento; a renegociação se faz pelo contrato.
Na aba Faturas do contrato, marca as faturas atrasadas (checkbox) → Renegociar.




Mostra: entrada, parcelas (valor/vencimento), faturas canceladas, mensalidades mescladas e novas faturas. Marca "Confirmo" → Finalizar Renegociação.

Mescla inteligente: se uma parcela cai perto (±5 dias) de uma mensalidade futura, o sistema junta as duas (cancela a mensalidade e soma na parcela) — evita boleto duplicado.
Sem entrada: faturas antigas → canceladas, parcelas viram boletos/PIX na hora, renegociação fica Aprovada.
Com entrada: cria a fatura da entrada e fica Pendente (aguardando o cliente pagar a entrada). Quando a entrada é paga, o sistema cria as parcelas e a renegociação vira Aprovada.
As parcelas aparecem em Faturas como boletos normais.
| Status | Cor | Significa |
|---|---|---|
| Iniciada | 🔵 | Criada (sem entrada) |
| Pendente | 🟡 | Aguardando o pagamento da entrada |
| Aprovado | 🟢 | Entrada paga, parcelas geradas e ativas |
| Concluído | 🟢 | Todas as parcelas pagas |
| Cancelado | 🔴 | Cancelada (operador ou rotina automática — ver abaixo) |
Fluxo: Iniciada/Pendente → Aprovado → Concluído.
Status · Tipo (Desconto/Acréscimo) · Criado por · Data de criação · Data de conclusão.


Uma rotina roda todo dia às 03:00 e cancela apenas acordos COM entrada cuja entrada não foi paga no prazo. Serve pra limpar acordos que o cliente montou mas nunca confirmou (não pagou a entrada).
O que o robô faz:
Acordo já Aprovado (entrada paga, parcelas ativas) NUNCA é quebrado por essa rotina, mesmo com parcela vencida. Aí quem decide é o operador (cancelar / renegociar de novo).
Configurações → Configurações padrão → aba Contratos → seção "Cancelamento Automático de Acordos"
Comandos read-only pra rodar no servidor. Não alteram nada — só mostram.
Ver o prazo configurado hoje:
docker compose exec -T app php artisan tinker --execute="echo negotiationExpireDays().' dias';"
Ver todos os acordos de um contrato (troque 23035 pelo número do contrato):
docker compose exec -T app php artisan tinker --execute="
App\Models\Financial\Negotiation::where('subscription_id', 23035)
->orderBy('id')->get(['id','status','entry_amount','created_at','updated_at'])
->each(fn(\$n) => print(\"#{\$n->id} | {\$n->status->value} | entrada R\$ {\$n->entry_amount} | criado {\$n->created_at} | atualizado {\$n->updated_at}\n\"));
"
Ver quais acordos a rotina das 03:00 cancelou (nos logs):
docker compose exec -T app grep "CancelExpiredNegotiations" storage/logs/laravel.log | tail -50
Descobrir se um acordo foi cancelado pela rotina ou por uma pessoa (rotina = sem "causador"; pessoa = com nome/ID):
docker compose exec -T app php artisan tinker --execute="
Spatie\Activitylog\Models\Activity::where('subject_type','like','%Negotiation%')
->where('subject_id', 2355)
->get(['description','causer_id','created_at'])
->each(fn(\$a) => print(\"{\$a->created_at} | {\$a->description} | causador=\".(\$a->causer_id ?? 'ROTINA/sistema').\"\n\"));
"