Files
Reem-Notas/app/controllers/motorista/dashboard_controller.rb

131 lines
5.6 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# app/controllers/motorista/dashboard_controller.rb
module Motorista
class DashboardController < ApplicationController
before_action :garantir_motorista
# GET /motorista?inicio=&fim=
#
# UMA tela só: o motorista escolhe o período e vê, para aquele recorte, o que
# já foi FECHADO pela empresa, o que ainda é ESTIMATIVA e de onde vem cada
# centavo (os fechamentos que compõem o total). Antes o total ficava numa
# tela e a composição em outra — e nenhuma das duas tinha período.
def index
nome = current_user.nome
@inicio, @fim = periodo_selecionado
@faixa_total = faixa_completa(nome) # para o atalho "Tudo"
carregar_estimado(nome)
carregar_fechado(nome)
# Aviso in-app: pagamentos confirmados nos últimos 7 dias (notificação na
# própria página do motorista, além de WhatsApp/email). Independe do
# período escolhido — é um aviso, não um relatório.
@pagamentos_recentes = ConsolidacaoMotorista
.joins(:consolidacao)
.where(motorista_nome: nome,
consolidacoes: { status: :finalizada, deleted_at: nil })
.where.not(pago_em: nil)
.where('pago_em >= ?', 7.days.ago)
.order(pago_em: :desc)
.includes(:consolidacao)
end
# GET /motorista/totais/pdf?inicio=&fim= — o extrato do período (total,
# composição e assinaturas), para guardar ou mandar por WhatsApp. Mesmo
# service da tela, então o papel e o painel nunca divergem.
def totais_pdf
inicio, fim = periodo_selecionado
totais = Analytics::TotaisPorMotorista.new(
inicio: inicio, fim: fim, motorista: current_user.nome
)
arquivo = ['meu_total', current_user.nome.parameterize(separator: '_'),
inicio.strftime('%Y%m%d'), fim.strftime('%Y%m%d')].join('_')
send_data Pdf::TotaisMotoristaPdf.new(totais: totais).render,
filename: "#{arquivo}.pdf",
type: 'application/pdf',
disposition: 'attachment'
end
private
# Card ESTIMADO: entregas ATENDIDAS × preco_entrega dentro do período.
#
# Atendida = o motorista FOI ao local e fechou a visita, com sucesso
# ('completed') OU insucesso ('failed') — no insucesso o deslocamento
# aconteceu e teve custo, então a empresa paga os dois. É o MESMO recorte do
# dashboard administrativo e da consolidação (ver Entrega::STATUS_ATENDIDO e
# Entrega.contar_atendidas): usava `pagas` (só concluídas) e o motorista via
# um valor MENOR que o do fechamento, sem entender de onde vinha a diferença.
#
# ⚠️ O eixo é o CHECKOUT (data real da visita), não planned_date: falhada TEM
# checkout, e uma entrega planejada em 31/07 mas fechada em 01/08 pertence a
# agosto — igual ao que a consolidação considera elegível.
#
# O fim é limitado a HOJE: estimar entregas de dias que ainda não
# aconteceram não faz sentido (o período pode ir até o fim do mês).
def carregar_estimado(nome)
@estimado_inicio = @inicio
@estimado_fim = [@fim, Date.current].min
if @estimado_fim < @estimado_inicio
@entregas_concluidas = @entregas_falhadas = @entregas_mes = 0
@valor_estimado = 0
return
end
atendidas = Entrega.atendidas.da_conta_gade
.do_motorista(nome)
.no_periodo_checkout(@estimado_inicio, @estimado_fim)
@entregas_concluidas = atendidas.concluidas.count
@entregas_falhadas = atendidas.falhadas.count
@entregas_mes = @entregas_concluidas + @entregas_falhadas
@valor_estimado = @entregas_mes * Configuracao.preco_entrega
end
# Card FECHADO + composição: o mesmo service do modo "Por motorista" do
# admin, recortado neste motorista — os dois lados mostram o mesmo número.
def carregar_fechado(nome)
@totais = Analytics::TotaisPorMotorista.new(inicio: @inicio, fim: @fim, motorista: nome)
@consolidacoes = @totais.consolidacoes_de(nome)
@valor_consolidado = @totais.total_geral
end
# Primeira e última data de fechamento do motorista — alimenta o atalho
# "Tudo" com datas reais em vez de uma faixa inventada.
def faixa_completa(nome)
escopo = Consolidacao.ativas.finalizada
.joins(:consolidacao_motoristas)
.where(consolidacao_motoristas: { motorista_nome: nome, arquivado_em: nil })
inicio = escopo.minimum(:data_inicio)
fim = escopo.maximum(:data_fim)
return nil if inicio.nil? || fim.nil?
[inicio.to_date, fim.to_date]
end
# Default: mês corrente INTEIRO (fim = último dia do mês). O recorte exige a
# consolidação inteira dentro da faixa, então terminar em "hoje" esconderia
# um fechamento que vai até o fim do mês. Mesma regra do lado do admin.
def periodo_selecionado
inicio = parse_data(params[:inicio]) || Date.current.beginning_of_month
fim = parse_data(params[:fim]) || Date.current.end_of_month
inicio, fim = fim, inicio if fim < inicio
[inicio, fim]
end
def parse_data(str)
return nil if str.blank?
Date.parse(str)
rescue ArgumentError, TypeError
nil
end
def garantir_motorista
return if current_user.motorista?
redirect_to dashboard_path, alert: 'Área exclusiva dos motoristas.'
end
end
end