Fases 4, 5 e 6 — Job 1h + Auditoria + Consolidação + Wizard de validação
This commit is contained in:
168
app/controllers/consolidacao_entregas_controller.rb
Normal file
168
app/controllers/consolidacao_entregas_controller.rb
Normal file
@@ -0,0 +1,168 @@
|
||||
# app/controllers/consolidacao_entregas_controller.rb
|
||||
class ConsolidacaoEntregasController < ApplicationController
|
||||
include Auditavel
|
||||
|
||||
before_action :set_consolidacao
|
||||
before_action :bloquear_se_finalizada, except: %i[validar revisar]
|
||||
|
||||
# GET /consolidacoes/:consolidacao_id/consolidacao_entregas/validar?motorista=X
|
||||
# WIZARD PASSO 2 — tela de validação com toggles
|
||||
def validar
|
||||
authorize @consolidacao, :show?
|
||||
@motorista = params[:motorista]
|
||||
|
||||
# Entregas pagas do período no banco existente (read-only)
|
||||
@entregas = Entrega.pagas
|
||||
.da_conta_gade
|
||||
.no_periodo(@consolidacao.data_inicio, @consolidacao.data_fim)
|
||||
.do_motorista(@motorista)
|
||||
@entregas = @entregas.da_rota(@consolidacao.route_ids) if @consolidacao.route_ids.present?
|
||||
@entregas = @entregas.order(:planned_date)
|
||||
|
||||
# Classificações já feitas — indexadas por tracking_id
|
||||
@classificacoes = @consolidacao.consolidacao_entregas
|
||||
.where(motorista_nome: @motorista)
|
||||
.index_by(&:tracking_id)
|
||||
|
||||
# Filtro "apenas não classificadas"
|
||||
if params[:apenas_pendentes] == '1'
|
||||
@entregas = @entregas.reject { |e| @classificacoes.key?(e.tracking_id) }
|
||||
end
|
||||
|
||||
@precos = {
|
||||
entrega_normal: Configuracao.preco_entrega,
|
||||
retirada: Configuracao.preco_retirada,
|
||||
bonus: Configuracao.preco_bonus,
|
||||
desconto: Configuracao.preco_desconto
|
||||
}
|
||||
end
|
||||
|
||||
# POST /consolidacoes/:consolidacao_id/consolidacao_entregas/classificar
|
||||
# Classifica UMA entrega (chamado pelo toggle via Turbo/fetch)
|
||||
def classificar
|
||||
authorize @consolidacao, :update?
|
||||
|
||||
ce = @consolidacao.consolidacao_entregas.find_or_initialize_by(tracking_id: params[:tracking_id])
|
||||
ce.motorista_nome = params[:motorista]
|
||||
ce.tipo = params[:tipo]
|
||||
ce.valor_aplicado = valor_para_tipo(params[:tipo])
|
||||
ce.created_by = current_user.id
|
||||
ce.save!
|
||||
|
||||
recalcular_motorista(params[:motorista])
|
||||
|
||||
respond_to do |format|
|
||||
format.json { render json: resumo_json(params[:motorista]) }
|
||||
format.html { redirect_back fallback_location: wizard_consolidacao_path(@consolidacao) }
|
||||
end
|
||||
end
|
||||
|
||||
# POST /consolidacoes/:consolidacao_id/consolidacao_entregas/classificar_em_massa
|
||||
# Ações em massa: marcar todos / marcar selecionados
|
||||
def classificar_em_massa
|
||||
authorize @consolidacao, :update?
|
||||
|
||||
tipo = params[:tipo]
|
||||
motorista = params[:motorista]
|
||||
tracking_ids = Array(params[:tracking_ids]).reject(&:blank?)
|
||||
|
||||
# "Marcar todos como Normal" → sem tracking_ids = todas do período
|
||||
if tracking_ids.empty?
|
||||
entregas = Entrega.pagas.da_conta_gade
|
||||
.no_periodo(@consolidacao.data_inicio, @consolidacao.data_fim)
|
||||
.do_motorista(motorista)
|
||||
entregas = entregas.da_rota(@consolidacao.route_ids) if @consolidacao.route_ids.present?
|
||||
tracking_ids = entregas.pluck(:tracking_id)
|
||||
end
|
||||
|
||||
valor = valor_para_tipo(tipo)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
tracking_ids.each do |tid|
|
||||
ce = @consolidacao.consolidacao_entregas.find_or_initialize_by(tracking_id: tid)
|
||||
ce.assign_attributes(motorista_nome: motorista, tipo: tipo,
|
||||
valor_aplicado: valor, created_by: current_user.id)
|
||||
ce.save!
|
||||
end
|
||||
end
|
||||
|
||||
recalcular_motorista(motorista)
|
||||
auditar!(:editar, @consolidacao,
|
||||
dados_novos: { acao_massa: tipo, qtd: tracking_ids.size, motorista: motorista })
|
||||
|
||||
respond_to do |format|
|
||||
format.json { render json: resumo_json(motorista) }
|
||||
format.html do
|
||||
redirect_to validar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: motorista),
|
||||
notice: "#{tracking_ids.size} entregas marcadas como #{tipo.humanize}."
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# GET /consolidacoes/:consolidacao_id/consolidacao_entregas/revisar?motorista=X
|
||||
# WIZARD PASSO 3 — revisão do motorista
|
||||
def revisar
|
||||
authorize @consolidacao, :show?
|
||||
@motorista = params[:motorista]
|
||||
|
||||
@classificacoes = @consolidacao.consolidacao_entregas
|
||||
.where(motorista_nome: @motorista)
|
||||
.order(:created_at)
|
||||
|
||||
@resumo = @classificacoes.group(:tipo).count
|
||||
@total = @classificacoes.sum do |c|
|
||||
c.tipo == 'desconto' ? -c.valor_aplicado : c.valor_aplicado
|
||||
end
|
||||
|
||||
# Próximo motorista pendente (para botão "Próximo Motorista")
|
||||
nomes_completos = @consolidacao.consolidacao_motoristas.map(&:motorista_nome)
|
||||
@proximo = nomes_completos.find do |nome|
|
||||
next false if nome == @motorista
|
||||
total = Entrega.contar_pagas(inicio: @consolidacao.data_inicio,
|
||||
fim: @consolidacao.data_fim, motorista: nome)
|
||||
@consolidacao.consolidacao_entregas.where(motorista_nome: nome).count < total
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_consolidacao
|
||||
@consolidacao = Consolidacao.find(params[:consolidacao_id])
|
||||
end
|
||||
|
||||
def bloquear_se_finalizada
|
||||
return unless @consolidacao.finalizada? && current_user.operador?
|
||||
redirect_to @consolidacao, alert: 'Consolidação finalizada — apenas admin/gerente podem editar.'
|
||||
end
|
||||
|
||||
def valor_para_tipo(tipo)
|
||||
case tipo.to_s
|
||||
when 'entrega_normal' then Configuracao.preco_entrega
|
||||
when 'retirada' then Configuracao.preco_retirada
|
||||
when 'bonus' then Configuracao.preco_bonus
|
||||
when 'desconto' then Configuracao.preco_desconto
|
||||
else 0
|
||||
end
|
||||
end
|
||||
|
||||
def recalcular_motorista(nome)
|
||||
cm = @consolidacao.consolidacao_motoristas.find_by(motorista_nome: nome)
|
||||
return unless cm
|
||||
|
||||
total = @consolidacao.consolidacao_entregas.where(motorista_nome: nome).sum do |e|
|
||||
e.tipo == 'desconto' ? -e.valor_aplicado : e.valor_aplicado
|
||||
end
|
||||
cm.update_column(:valor_total, total)
|
||||
@consolidacao.update_column(:valor_total, @consolidacao.consolidacao_motoristas.sum(:valor_total))
|
||||
end
|
||||
|
||||
def resumo_json(motorista)
|
||||
classificacoes = @consolidacao.consolidacao_entregas.where(motorista_nome: motorista)
|
||||
{
|
||||
ok: true,
|
||||
classificadas: classificacoes.count,
|
||||
por_tipo: classificacoes.group(:tipo).count,
|
||||
valor_total: classificacoes.sum { |e| e.tipo == 'desconto' ? -e.valor_aplicado : e.valor_aplicado }.to_f
|
||||
}
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user