Auditoria de bugs + suíte de testes RSpec
Correções: - Erro de sintaxe em Admin::Usuarios#toggle_ativo (entidade: \'User\') que derrubava /admin/usuarios - Migration fase2 readicionava coluna `ativo` sem guard (db:migrate do zero quebrava); db:seed colidia no índice único de email para motoristas - Dashboard e HistoricoEstimado agora aplicam .da_conta_gade - ConsolidacaoMotorista#recalcular_valor usa valor_aplicado (fonte única) - Gate de finalização por motorista (antes soma agregada com >=) e validação de elegibilidade em classificar/classificar_em_massa - Remove coluna órfã pin_acesso; registra autor do arquivamento (arquivado_por/arquivado_em + belongs_to :arquivador) - Dashboard redireciona motorista; Date.parse tolerante - Remove MotoristaController + view órfãos (não roteados e quebrados) Testes: infra RSpec + factories + specs de models, policy e request. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
class Consolidacao < ApplicationRecord
|
||||
belongs_to :criador, class_name: 'User', foreign_key: :created_by
|
||||
belongs_to :finalizador, class_name: 'User', foreign_key: :finalizado_por, optional: true
|
||||
belongs_to :arquivador, class_name: 'User', foreign_key: :arquivado_por, optional: true
|
||||
|
||||
has_many :consolidacao_motoristas, dependent: :destroy
|
||||
has_many :consolidacao_entregas, dependent: :destroy
|
||||
@@ -30,7 +31,12 @@ class Consolidacao < ApplicationRecord
|
||||
# ── Métodos ─────────────────────────────────────────────────
|
||||
|
||||
def arquivar!(user)
|
||||
update!(deleted_at: Time.current, status: :arquivada)
|
||||
update!(
|
||||
deleted_at: Time.current,
|
||||
status: :arquivada,
|
||||
arquivado_por: user&.id,
|
||||
arquivado_em: Time.current
|
||||
)
|
||||
end
|
||||
|
||||
def finalizar!(user)
|
||||
@@ -43,12 +49,14 @@ class Consolidacao < ApplicationRecord
|
||||
)
|
||||
end
|
||||
|
||||
# Só está completa quando CADA motorista tem todas as suas entregas elegíveis
|
||||
# classificadas. (Antes era uma soma agregada com >=, que mascarava motoristas
|
||||
# pendentes quando outro tinha entregas a mais.)
|
||||
def todas_entregas_classificadas?
|
||||
total_entregas = ConsolidacaoMotorista
|
||||
.where(consolidacao_id: id)
|
||||
.sum { |cm| Entrega.contar_pagas(inicio: data_inicio, fim: data_fim, motorista: cm.motorista_nome) }
|
||||
|
||||
consolidacao_entregas.count >= total_entregas
|
||||
consolidacao_motoristas.all? do |cm|
|
||||
total = entregas_elegiveis_count(cm.motorista_nome)
|
||||
total.zero? || classificadas_count(cm.motorista_nome) >= total
|
||||
end
|
||||
end
|
||||
|
||||
def percentual_classificado
|
||||
@@ -58,10 +66,26 @@ class Consolidacao < ApplicationRecord
|
||||
|
||||
def total_entregas_estimadas
|
||||
@total_entregas_estimadas ||= consolidacao_motoristas.sum do |cm|
|
||||
Entrega.contar_pagas(inicio: data_inicio, fim: data_fim, motorista: cm.motorista_nome)
|
||||
entregas_elegiveis_count(cm.motorista_nome)
|
||||
end
|
||||
end
|
||||
|
||||
# Entregas pagas elegíveis para um motorista no período, respeitando o filtro
|
||||
# de rotas da consolidação (quando houver). Fonte única usada pelo wizard,
|
||||
# pela revisão e pelo gate de finalização.
|
||||
def entregas_elegiveis_count(motorista)
|
||||
Entrega.contar_pagas(
|
||||
inicio: data_inicio,
|
||||
fim: data_fim,
|
||||
motorista: motorista,
|
||||
route_id: route_ids.presence
|
||||
)
|
||||
end
|
||||
|
||||
def classificadas_count(motorista)
|
||||
consolidacao_entregas.where(motorista_nome: motorista).count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def periodo_valido
|
||||
|
||||
@@ -12,18 +12,12 @@ class ConsolidacaoMotorista < ApplicationRecord
|
||||
before_save :recalcular_valor
|
||||
|
||||
def recalcular_valor
|
||||
cfg = Configuracao
|
||||
# Fonte única de verdade: o valor_aplicado capturado no momento da
|
||||
# classificação (igual ao ConsolidacaoEntregasController#recalcular_motorista).
|
||||
# Recalcular pelos preços atuais de Configuracao divergiria caso os preços
|
||||
# mudassem depois das entregas já terem sido classificadas.
|
||||
self.valor_total = consolidacao_entregas
|
||||
.includes(:consolidacao)
|
||||
.where(motorista_nome: motorista_nome)
|
||||
.sum do |e|
|
||||
case e.tipo
|
||||
when 'entrega_normal' then cfg.preco_entrega
|
||||
when 'retirada' then cfg.preco_retirada
|
||||
when 'bonus' then cfg.preco_bonus
|
||||
when 'desconto' then -cfg.preco_desconto
|
||||
else 0
|
||||
end
|
||||
end
|
||||
.sum { |e| e.desconto? ? -e.valor_aplicado : e.valor_aplicado }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ class HistoricoEstimado < ApplicationRecord
|
||||
# Chamado pelo job a cada 1 hora (Whenever gem — Fase 4)
|
||||
def self.atualizar!
|
||||
preco = Configuracao.preco_entrega
|
||||
entregas = Entrega.pagas.where(planned_date: Date.current).count
|
||||
entregas = Entrega.da_conta_gade.pagas.where(planned_date: Date.current).count
|
||||
total = entregas * preco
|
||||
|
||||
create!(
|
||||
@@ -23,7 +23,7 @@ class HistoricoEstimado < ApplicationRecord
|
||||
# Cálculo ao vivo para o Dashboard (sem esperar o job)
|
||||
def self.calcular_ao_vivo(inicio: Date.current.beginning_of_month, fim: Date.current)
|
||||
preco = Configuracao.preco_entrega
|
||||
entregas = Entrega.pagas.where(planned_date: inicio..fim).count
|
||||
entregas = Entrega.da_conta_gade.pagas.where(planned_date: inicio..fim).count
|
||||
{
|
||||
valor: entregas * preco,
|
||||
entregas: entregas
|
||||
|
||||
Reference in New Issue
Block a user