Atualização da função de adicionar entregas por fora da operação
This commit is contained in:
@@ -177,44 +177,22 @@ class ConsolidacaoEntregasController < ApplicationController
|
||||
if entregas.empty?
|
||||
render json: { ok: false, erro: "Nota #{nf} não encontrada na base de rastreio." }
|
||||
else
|
||||
render json: { ok: true, nf: nf, entregas: entregas.map { |e| entrega_json(e) } }
|
||||
render json: { ok: true, nf: nf, entregas: entregas.map(&:resumo_apontamento) }
|
||||
end
|
||||
end
|
||||
|
||||
# POST /consolidacoes/:consolidacao_id/consolidacao_entregas/apontar
|
||||
# Cria um apontamento manual a partir de um tracking_id encontrado pela NF.
|
||||
# Aceita um ou vários pilares (tipos[]) na mesma entrega.
|
||||
def apontar
|
||||
authorize @consolidacao, :update?
|
||||
|
||||
tipo = params[:tipo].to_s
|
||||
return render_apontamento_erro('Tipo inválido.') unless ConsolidacaoEntrega.tipos.key?(tipo)
|
||||
|
||||
entrega = Entrega.da_conta_gade.find_by(tracking_id: params[:tracking_id])
|
||||
return render_apontamento_erro('Entrega não encontrada na base de rastreio.') unless entrega
|
||||
|
||||
motorista = entrega.driver.to_s.strip
|
||||
return render_apontamento_erro('Entrega sem motorista — não é possível apontar.') if motorista.blank?
|
||||
|
||||
# Garante o motorista na consolidação (pode não estar, já que a NF veio por fora).
|
||||
@consolidacao.consolidacao_motoristas.find_or_create_by!(motorista_nome: motorista)
|
||||
|
||||
ce = @consolidacao.consolidacao_entregas
|
||||
.find_or_initialize_by(tracking_id: entrega.tracking_id, tipo: tipo)
|
||||
if ce.persisted?
|
||||
return render_apontamento_erro("Essa nota já está classificada como #{ConsolidacaoEntrega::TIPO_CORES[tipo][:label]} para #{motorista}.")
|
||||
end
|
||||
|
||||
ce.assign_attributes(
|
||||
motorista_nome: motorista,
|
||||
valor_aplicado: valor_para_tipo(tipo),
|
||||
manual: true,
|
||||
created_by: current_user.id
|
||||
)
|
||||
ce.save!
|
||||
|
||||
recalcular_motorista(motorista)
|
||||
motorista = @consolidacao.adicionar_apontamento!(entrega, tipos_param, current_user)
|
||||
auditar!(:editar, @consolidacao,
|
||||
dados_novos: { apontamento_manual: entrega.numero_nf, tipo: tipo, motorista: motorista })
|
||||
dados_novos: { apontamento_manual: entrega.numero_nf, tipos: tipos_param, motorista: motorista })
|
||||
|
||||
respond_to do |format|
|
||||
format.json { render json: resumo_json(motorista).merge(motorista: motorista) }
|
||||
@@ -223,29 +201,35 @@ class ConsolidacaoEntregasController < ApplicationController
|
||||
notice: "Apontamento da nota #{entrega.numero_nf} adicionado para #{motorista}."
|
||||
end
|
||||
end
|
||||
rescue ArgumentError => e
|
||||
render_apontamento_erro(e.message)
|
||||
end
|
||||
|
||||
# DELETE /consolidacoes/:consolidacao_id/consolidacao_entregas/remover_apontamento?id=1
|
||||
# Remove um apontamento manual. (Não passa pelo guard de elegibilidade, pois o
|
||||
# tracking está fora do período — por isso não reusa o toggle classificar.)
|
||||
# DELETE /consolidacoes/:consolidacao_id/consolidacao_entregas/remover_apontamento
|
||||
# Remove um apontamento manual — por ?id= (um pilar) ou por ?tracking_id=&motorista=
|
||||
# (todos os pilares daquela nota). Não passa pelo guard de elegibilidade, pois o
|
||||
# tracking está fora do período (por isso não reusa o toggle classificar).
|
||||
def remover_apontamento
|
||||
authorize @consolidacao, :update?
|
||||
|
||||
ce = @consolidacao.consolidacao_entregas.apontamentos.find_by(id: params[:id])
|
||||
return render_apontamento_erro('Apontamento não encontrado.') unless ce
|
||||
scope = @consolidacao.consolidacao_entregas.apontamentos
|
||||
registros = if params[:id].present?
|
||||
Array(scope.find_by(id: params[:id]))
|
||||
else
|
||||
scope.where(tracking_id: params[:tracking_id], motorista_nome: params[:motorista]).to_a
|
||||
end
|
||||
return render_apontamento_erro('Apontamento não encontrado.') if registros.empty?
|
||||
|
||||
motorista = ce.motorista_nome
|
||||
ce.destroy
|
||||
recalcular_motorista(motorista)
|
||||
motorista = registros.first.motorista_nome
|
||||
tracking = registros.first.tracking_id
|
||||
registros.each(&:destroy)
|
||||
@consolidacao.recalcular_motorista!(motorista)
|
||||
auditar!(:editar, @consolidacao,
|
||||
dados_novos: { remover_apontamento_manual: ce.tracking_id, motorista: motorista })
|
||||
dados_novos: { remover_apontamento_manual: tracking, motorista: motorista })
|
||||
|
||||
respond_to do |format|
|
||||
format.json { render json: resumo_json(motorista).merge(motorista: motorista) }
|
||||
format.html do
|
||||
redirect_to revisar_consolidacao_consolidacao_entregas_path(@consolidacao, motorista: motorista),
|
||||
notice: 'Apontamento removido.'
|
||||
end
|
||||
format.html { redirect_back fallback_location: consolidacao_path(@consolidacao), notice: 'Apontamento removido.' }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -285,18 +269,10 @@ class ConsolidacaoEntregasController < ApplicationController
|
||||
tracking_ids_elegiveis(motorista).include?(tracking_id)
|
||||
end
|
||||
|
||||
# Dados da entrega para o modal de apontamento (conferência antes de salvar).
|
||||
def entrega_json(e)
|
||||
{
|
||||
tracking_id: e.tracking_id,
|
||||
nf: e.numero_nf,
|
||||
motorista: e.driver,
|
||||
veiculo: e.vehicle,
|
||||
local: e.local,
|
||||
status: e.status,
|
||||
pago: e.elegivel_pagamento?,
|
||||
data: (e.checkout || e.planned_date)&.to_s
|
||||
}
|
||||
# Pilares (tipos) selecionados no modal — aceita tipos[] (vários) ou tipo (um).
|
||||
def tipos_param
|
||||
tipos = Array(params[:tipos]).presence || Array(params[:tipo])
|
||||
tipos.reject(&:blank?)
|
||||
end
|
||||
|
||||
def render_apontamento_erro(msg)
|
||||
@@ -317,24 +293,11 @@ class ConsolidacaoEntregasController < ApplicationController
|
||||
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
|
||||
ConsolidacaoEntrega.valor_para(tipo)
|
||||
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))
|
||||
@consolidacao.recalcular_motorista!(nome)
|
||||
end
|
||||
|
||||
def resumo_json(motorista)
|
||||
|
||||
@@ -101,10 +101,60 @@ class ConsolidacoesController < ApplicationController
|
||||
render json: Operacao.dados(params[:operacoes])
|
||||
end
|
||||
|
||||
# GET /consolidacoes/buscar_nf?nf=123 — busca a NF na SimpleRoute (nota avulsa).
|
||||
def buscar_nf
|
||||
authorize Consolidacao, :create?
|
||||
|
||||
nf = params[:nf].to_s.strip
|
||||
return render(json: { ok: false, erro: 'Informe o número da nota.' }, status: :unprocessable_entity) if nf.blank?
|
||||
|
||||
entregas = Entrega.da_conta_gade.por_nf(nf).order(:checkout)
|
||||
if entregas.empty?
|
||||
render json: { ok: false, erro: "Nota #{nf} não encontrada na base de rastreio." }
|
||||
else
|
||||
render json: { ok: true, nf: nf, entregas: entregas.map(&:resumo_apontamento) }
|
||||
end
|
||||
end
|
||||
|
||||
# POST /consolidacoes/avulsa — cria uma consolidação JÁ a partir de uma NF
|
||||
# avulsa (entrega que chegou por fora) e adiciona o apontamento ao motorista.
|
||||
def avulsa
|
||||
authorize Consolidacao, :create?
|
||||
|
||||
entrega = Entrega.da_conta_gade.find_by(tracking_id: params[:tracking_id])
|
||||
return redirect_to(consolidacoes_path, alert: 'Entrega não encontrada na base de rastreio.') unless entrega
|
||||
|
||||
data_ref = (entrega.checkout || entrega.planned_date)&.to_date || Date.current
|
||||
|
||||
consolidacao = nil
|
||||
ActiveRecord::Base.transaction do
|
||||
consolidacao = Consolidacao.create!(
|
||||
nome: "Avulsa nf#{entrega.numero_nf}",
|
||||
data_inicio: data_ref,
|
||||
data_fim: data_ref.end_of_month,
|
||||
created_by: current_user.id
|
||||
)
|
||||
consolidacao.adicionar_apontamento!(entrega, Array(params[:tipos]).reject(&:blank?), current_user)
|
||||
end
|
||||
|
||||
auditar!(:criar, consolidacao,
|
||||
dados_novos: { avulsa_nf: entrega.numero_nf, motorista: entrega.driver, tipos: params[:tipos] })
|
||||
redirect_to consolidacao_path(consolidacao),
|
||||
notice: "Consolidação avulsa criada para #{entrega.driver} (NF #{entrega.numero_nf})."
|
||||
rescue ArgumentError => e
|
||||
redirect_to consolidacoes_path, alert: e.message
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
redirect_to consolidacoes_path, alert: "Não foi possível criar a consolidação avulsa: #{e.message}"
|
||||
end
|
||||
|
||||
# GET /consolidacoes/:id — visão geral
|
||||
def show
|
||||
authorize @consolidacao
|
||||
@motoristas = @consolidacao.consolidacao_motoristas.order(:motorista_nome)
|
||||
# Apontamentos manuais agrupados por nota (tracking) p/ exibição e remoção.
|
||||
@apontamentos = @consolidacao.consolidacao_entregas.apontamentos
|
||||
.order(:motorista_nome, :tracking_id)
|
||||
.group_by { |ce| [ce.motorista_nome, ce.tracking_id] }
|
||||
end
|
||||
|
||||
# GET /consolidacoes/:id/wizard — PASSO 1: selecionar motorista
|
||||
|
||||
Reference in New Issue
Block a user