Atualização da função de adicionar entregas por fora da operação

This commit is contained in:
2026-06-19 14:59:26 -03:00
parent 79c0f646da
commit 7b83f2e248
13 changed files with 399 additions and 77 deletions

View File

@@ -160,6 +160,52 @@ class Consolidacao < ApplicationRecord
.distinct.count(:tracking_id)
end
# ── Apontamento manual ──────────────────────────────────────
# Adiciona uma entrega "por fora" (NF que chegou depois) com um ou mais pilares
# (tipos). O motorista vem da própria entrega e é incluído na consolidação se
# ainda não estiver. Retorna o nome do motorista. Idempotente por (tracking, tipo).
def adicionar_apontamento!(entrega, tipos, user)
tipos_validos = Array(tipos).map(&:to_s).select { |t| ConsolidacaoEntrega.tipos.key?(t) }.uniq
raise ArgumentError, 'Selecione ao menos uma classificação.' if tipos_validos.empty?
motorista = entrega.driver.to_s.strip
raise ArgumentError, 'Entrega sem motorista — não é possível apontar.' if motorista.blank?
transaction do
consolidacao_motoristas.find_or_create_by!(motorista_nome: motorista)
tipos_validos.each do |tipo|
ce = consolidacao_entregas.find_or_initialize_by(tracking_id: entrega.tracking_id, tipo: tipo)
next if ce.persisted? # pilar já existe — mantém
ce.assign_attributes(
motorista_nome: motorista,
valor_aplicado: ConsolidacaoEntrega.valor_para(tipo),
manual: true,
created_by: user&.id
)
ce.save!
end
recalcular_motorista!(motorista)
end
motorista
end
# Recalcula o valor de um motorista (soma dos pilares, desconto subtrai) e o
# total da consolidação. Fonte única usada pelo wizard e pelos apontamentos.
def recalcular_motorista!(nome)
cm = consolidacao_motoristas.find_by(motorista_nome: nome)
return unless cm
total = consolidacao_entregas.where(motorista_nome: nome).sum do |e|
e.desconto? ? -e.valor_aplicado : e.valor_aplicado
end
cm.update_column(:valor_total, total)
update_column(:valor_total, consolidacao_motoristas.sum(:valor_total))
end
private
def periodo_valido

View File

@@ -38,4 +38,16 @@ class ConsolidacaoEntrega < ApplicationRecord
def tipo_cor
TIPO_CORES[tipo] || TIPO_CORES['entrega_normal']
end
# Preço configurado para um pilar (tipo). Fonte única usada na classificação
# (controller) e no apontamento manual (Consolidacao#adicionar_apontamento!).
def self.valor_para(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
end

View File

@@ -129,6 +129,21 @@ class Entrega < ApplicationRecord
reference_id
end
# Resumo para o apontamento manual (modal de busca de NF). Fonte única usada
# pelos dois fluxos: apontar em consolidação existente e criar "nota avulsa".
def resumo_apontamento
{
tracking_id: tracking_id,
nf: numero_nf,
motorista: driver,
veiculo: vehicle,
local: local,
status: status,
pago: elegivel_pagamento?,
data: (checkout || planned_date)&.to_s
}
end
def local
contact_name.presence || address
end