correção de bugs
This commit is contained in:
118
lib/tasks/entregas_motorista.rake
Normal file
118
lib/tasks/entregas_motorista.rake
Normal file
@@ -0,0 +1,118 @@
|
||||
# lib/tasks/entregas_motorista.rake
|
||||
#
|
||||
# Lista as entregas de um motorista num período lendo o ESPELHO LOCAL
|
||||
# (model Entrega / tabela db_reem_simplerout_2026) — sem tocar na API do
|
||||
# SimpliRoute, logo sem precisar de SIMPLIROUTE_TOKEN.
|
||||
#
|
||||
# Por que aqui e não na API: a API não tem filtro de intervalo nem de motorista
|
||||
# (ver bin/entregas_do_motorista), então um período vira N requisições de vários
|
||||
# MB. No espelho é uma query só. O preço é a defasagem da sync — se precisar do
|
||||
# estado AO VIVO, use bin/entregas_do_motorista.
|
||||
#
|
||||
# SÓ LEITURA: Entrega#readonly? é true; nada aqui escreve.
|
||||
#
|
||||
# rake "entregas:motorista[JOSE DA SILVA,2026-08-01,2026-08-14]"
|
||||
# rake "entregas:motorista[JOSE DA SILVA,2026-08-01,2026-08-14,/tmp/saida.csv]"
|
||||
# rake "entregas:motoristas[2026-08-01,2026-08-14]" # quem operou no período
|
||||
#
|
||||
# ⚠️ O nome tem que ser a grafia EXATA da coluna `driver` (do_motorista usa
|
||||
# igualdade). Rode `entregas:motoristas` primeiro para ver a lista; se o nome
|
||||
# passado não bater exatamente, a task sugere os parecidos em vez de devolver
|
||||
# vazio silenciosamente.
|
||||
#
|
||||
# ⚠️ Período pelo `planned_date` (dia planejado da visita), que é o mesmo eixo
|
||||
# do dashboard. As análises FINANCEIRAS usam `checkout` (data real da entrega) —
|
||||
# são recortes diferentes; passe FONTE=checkout para usar esse outro eixo.
|
||||
|
||||
namespace :entregas do
|
||||
desc 'Entregas de um motorista no período, lidas do espelho local (sem API)'
|
||||
task :motorista, %i[nome inicio fim csv] => :environment do |_t, args|
|
||||
nome = args[:nome].to_s.strip
|
||||
inicio = args[:inicio].to_s.strip
|
||||
fim = args[:fim].to_s.strip
|
||||
|
||||
if nome.empty? || inicio.empty? || fim.empty?
|
||||
abort 'Uso: rake "entregas:motorista[NOME,YYYY-MM-DD,YYYY-MM-DD,/caminho/opcional.csv]"'
|
||||
end
|
||||
|
||||
d1 = Date.parse(inicio)
|
||||
d2 = Date.parse(fim)
|
||||
abort 'Início é depois do fim.' if d1 > d2
|
||||
|
||||
# planned_date = dia planejado; checkout = dia em que a entrega ocorreu.
|
||||
por_checkout = ENV['FONTE'].to_s.casecmp('checkout').zero?
|
||||
base = Entrega.da_conta_gade
|
||||
base = por_checkout ? base.no_periodo_checkout(d1, d2) : base.no_periodo(d1, d2)
|
||||
|
||||
entregas = base.do_motorista(nome).order(:planned_date, :checkout).to_a
|
||||
|
||||
if entregas.empty?
|
||||
puts "Nenhuma entrega de #{nome.inspect} entre #{d1.strftime('%d/%m/%Y')} e #{d2.strftime('%d/%m/%Y')}."
|
||||
# Nome quase certo é o erro mais comum aqui — mostrar o vizinho evita
|
||||
# concluir "o motorista não rodou" quando na verdade a grafia divergiu.
|
||||
alvo = nome.upcase
|
||||
parecidos = Entrega.motoristas_ativos(inicio: d1, fim: d2)
|
||||
.select { |n| n.upcase.include?(alvo) || alvo.include?(n.upcase) }
|
||||
puts "Nomes parecidos no período: #{parecidos.inspect}" if parecidos.any?
|
||||
puts 'Rode: rake "entregas:motoristas[' + "#{d1},#{d2}" + ']" para ver a grafia exata.'
|
||||
next
|
||||
end
|
||||
|
||||
eixo = por_checkout ? 'checkout (data real)' : 'planned_date (dia planejado)'
|
||||
puts "#{'─' * 104}"
|
||||
puts "#{entregas.size} entrega(s) de #{nome} · #{d1.strftime('%d/%m/%Y')} a #{d2.strftime('%d/%m/%Y')} · eixo: #{eixo}"
|
||||
puts '─' * 104
|
||||
printf("%-11s %-10s %-10s %-10s %-17s %-38s\n", 'DATA', 'NF', 'VEÍCULO', 'STATUS', 'CHECKOUT', 'DESTINO')
|
||||
entregas.each do |e|
|
||||
printf("%-11s %-10s %-10s %-10s %-17s %-38s\n",
|
||||
e.planned_date&.strftime('%d/%m/%Y').to_s,
|
||||
e.reference_id.to_s[0, 10],
|
||||
e.vehicle.to_s[0, 10],
|
||||
e.status.to_s[0, 10],
|
||||
e.checkout&.strftime('%d/%m %H:%M').to_s,
|
||||
e.local.to_s[0, 38])
|
||||
end
|
||||
puts '─' * 104
|
||||
|
||||
por_status = entregas.group_by { |e| e.status.to_s }.transform_values(&:size)
|
||||
puts "Total: #{entregas.size} " + por_status.sort_by { |_, n| -n }.map { |s, n| "#{s}=#{n}" }.join(' ')
|
||||
# "Atendidas" = foi ao local (sucesso OU insucesso) com checkout — é o
|
||||
# conjunto elegível da consolidação, e não o mesmo que "entregues".
|
||||
puts "Entregues (completed + checkout) ..... #{entregas.count { |e| e.concluida? && e.checkout_registrado? }}"
|
||||
puts "Insucessos (failed) .................. #{entregas.count(&:falhada?)}"
|
||||
puts "Atendidas (foi ao local c/ checkout) . #{entregas.count { |e| Entrega::STATUS_ATENDIDO.include?(e.status) && e.checkout_registrado? }}"
|
||||
puts "Dias com entrega ..................... #{entregas.map { |e| e.planned_date&.to_date }.compact.uniq.size}"
|
||||
puts "Veículos ............................. #{entregas.map(&:vehicle).compact.reject(&:empty?).uniq.join(', ')}"
|
||||
|
||||
if args[:csv].present?
|
||||
require 'csv'
|
||||
CSV.open(args[:csv], 'w') do |csv|
|
||||
csv << ['Data planejada', 'NF', 'Tracking', 'Motorista', 'Veículo', 'Status', 'Checkout', 'Local', 'Endereço', 'Motivo']
|
||||
entregas.each do |e|
|
||||
csv << [e.planned_date, e.reference_id, e.tracking_id, e.driver, e.vehicle,
|
||||
e.status, e.checkout, e.local, e.try(:address), e.try(:observation)]
|
||||
end
|
||||
end
|
||||
puts "\nCSV gravado em #{args[:csv]}"
|
||||
end
|
||||
end
|
||||
|
||||
desc 'Motoristas que aparecem no espelho dentro do período (grafia exata + volume)'
|
||||
task :motoristas, %i[inicio fim] => :environment do |_t, args|
|
||||
abort 'Uso: rake "entregas:motoristas[YYYY-MM-DD,YYYY-MM-DD]"' if args[:inicio].blank? || args[:fim].blank?
|
||||
|
||||
d1 = Date.parse(args[:inicio])
|
||||
d2 = Date.parse(args[:fim])
|
||||
|
||||
contagem = Entrega.da_conta_gade.no_periodo(d1, d2)
|
||||
.where.not(driver: [nil, '']).group(:driver).count
|
||||
|
||||
if contagem.empty?
|
||||
puts "Nenhuma entrega no espelho entre #{d1.strftime('%d/%m/%Y')} e #{d2.strftime('%d/%m/%Y')}."
|
||||
next
|
||||
end
|
||||
|
||||
puts "Motoristas · #{d1.strftime('%d/%m/%Y')} a #{d2.strftime('%d/%m/%Y')} (#{contagem.values.sum} entregas)"
|
||||
contagem.sort_by { |_, n| -n }.each { |nome, n| puts " #{n.to_s.rjust(5)} #{nome}" }
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user