Criação da visão geral da consolidação por motorista

This commit is contained in:
2026-08-26 11:15:52 -03:00
parent 8d24a57579
commit cd99a22553
12 changed files with 841 additions and 3 deletions

View File

@@ -0,0 +1,92 @@
require 'rails_helper'
# Trava a conta do relatório "total por motorista" — a mesma que alimenta
# /consolidacoes/totais (admin) e /motorista/totais (motorista). As duas telas
# usam ESTE service justamente para não poderem divergir.
RSpec.describe Analytics::TotaisPorMotorista do
let(:inicio) { Date.new(2026, 6, 1) }
let(:fim) { Date.new(2026, 6, 30) }
# Uma consolidação com um motorista e `qtd` lançamentos de `valor` cada. As
# entregas vêm ANTES do ConsolidacaoMotorista porque é o before_save dele que
# calcula valor_total a partir delas.
def consolidar(motorista:, valor: 100.0, qtd: 1, status: :finalizada,
data_inicio: Date.new(2026, 6, 1), data_fim: Date.new(2026, 6, 30),
pago: false, arquivado: false)
c = create(:consolidacao, status: status, data_inicio: data_inicio, data_fim: data_fim)
qtd.times { create(:consolidacao_entrega, consolidacao: c, motorista_nome: motorista, valor_aplicado: valor) }
cm = create(:consolidacao_motorista, consolidacao: c, motorista_nome: motorista)
cm.update!(pago_em: Time.current, forma_pagamento: 'pix') if pago
cm.arquivar!(nil) if arquivado
[c, cm]
end
subject(:totais) { described_class.new(inicio: inicio, fim: fim) }
it 'soma por motorista só as consolidações finalizadas do período' do
consolidar(motorista: 'Carlos', valor: 100.0, qtd: 2) # 200
consolidar(motorista: 'Carlos', valor: 50.0, qtd: 1) # 50
consolidar(motorista: 'Pedro', valor: 30.0, qtd: 1) # 30
consolidar(motorista: 'Carlos', valor: 999.0, status: :rascunho) # fora (rascunho)
consolidar(motorista: 'Carlos', valor: 999.0, # fora (período)
data_inicio: Date.new(2026, 7, 1), data_fim: Date.new(2026, 7, 31))
expect(totais.linhas.map { |l| [l[:motorista], l[:valor_total]] })
.to eq([['Carlos', 250.0], ['Pedro', 30.0]])
expect(totais.total_geral).to eq(280.0)
expect(totais.total_consolidacoes).to eq(3)
end
it 'inclui rascunhos quando pedido' do
consolidar(motorista: 'Carlos', valor: 100.0)
consolidar(motorista: 'Carlos', valor: 40.0, status: :rascunho)
com_rascunho = described_class.new(inicio: inicio, fim: fim, incluir_rascunhos: true)
expect(totais.total_geral).to eq(100.0)
expect(com_rascunho.total_geral).to eq(140.0)
end
it 'separa pago de a receber' do
consolidar(motorista: 'Carlos', valor: 100.0, pago: true)
consolidar(motorista: 'Carlos', valor: 60.0)
linha = totais.linhas.first
expect(linha[:valor_pago]).to eq(100.0)
expect(linha[:valor_pendente]).to eq(60.0)
expect(totais.total_pago).to eq(100.0)
expect(totais.total_pendente).to eq(60.0)
end
it 'ignora motorista arquivado (mesmo conjunto que a consolidação paga)' do
consolidar(motorista: 'Carlos', valor: 100.0)
consolidar(motorista: 'Carlos', valor: 70.0, arquivado: true)
expect(totais.total_geral).to eq(100.0)
end
it 'lista as consolidações que compõem o total do motorista' do
c1, = consolidar(motorista: 'Carlos', valor: 100.0)
c2, = consolidar(motorista: 'Carlos', valor: 60.0, data_fim: Date.new(2026, 6, 15))
consolidar(motorista: 'Pedro', valor: 30.0)
composicao = totais.consolidacoes_de('Carlos')
expect(composicao.map(&:consolidacao_id)).to match_array([c1.id, c2.id])
expect(composicao.sum(&:valor_total)).to eq(160.0)
end
it 'recortado por motorista, só enxerga o dele (visão do painel do motorista)' do
consolidar(motorista: 'Carlos', valor: 100.0)
consolidar(motorista: 'Pedro', valor: 30.0)
meu = described_class.new(inicio: inicio, fim: fim, motorista: 'Carlos')
expect(meu.total_geral).to eq(100.0)
expect(meu.linhas.size).to eq(1)
end
it 'período sem fechamento fica vazio (e não quebra)' do
vazio = described_class.new(inicio: Date.new(2026, 1, 1), fim: Date.new(2026, 1, 31))
expect(vazio).to be_vazio
expect(vazio.total_geral).to eq(0)
expect(vazio.linhas).to eq([])
end
end