117 lines
5.1 KiB
Ruby
117 lines
5.1 KiB
Ruby
# app/controllers/motorista/dashboard_controller.rb
|
||
module Motorista
|
||
class DashboardController < ApplicationController
|
||
before_action :garantir_motorista
|
||
|
||
# GET /motorista
|
||
def index
|
||
nome = current_user.nome
|
||
|
||
# Card 1 — Valor ESTIMADO (mês atual): entregas ATENDIDAS × preco_entrega.
|
||
#
|
||
# 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.
|
||
@estimado_inicio = Date.current.beginning_of_month
|
||
@estimado_fim = Date.current
|
||
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
|
||
|
||
# Card 2 — Valor CONSOLIDADO: soma das consolidações finalizadas
|
||
@minhas_consolidacoes = Consolidacao.ativas
|
||
.joins(:consolidacao_motoristas)
|
||
.where(consolidacao_motoristas: { motorista_nome: nome, arquivado_em: nil })
|
||
.recentes
|
||
.distinct
|
||
|
||
@valor_consolidado = ConsolidacaoMotorista.ativos
|
||
.joins(:consolidacao)
|
||
.where(motorista_nome: nome,
|
||
consolidacoes: { status: :finalizada, deleted_at: nil })
|
||
.sum(:valor_total)
|
||
|
||
# Aviso in-app: pagamentos confirmados nos últimos 7 dias (notificação na
|
||
# própria página do motorista, além de WhatsApp/email).
|
||
@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?inicio=&fim=
|
||
#
|
||
# "Quanto eu fechei neste período e de onde vem esse valor". O card do painel
|
||
# mostra só o total acumulado; aqui o motorista escolhe o período, vê o total
|
||
# FECHADO (consolidações finalizadas) e a lista de consolidações que compõem
|
||
# o valor — a mesma conta que o admin vê em /consolidacoes/totais, montada
|
||
# pelo mesmo service para os dois números não poderem divergir.
|
||
def totais
|
||
@inicio, @fim = periodo_totais
|
||
@totais = totais_do_periodo
|
||
@consolidacoes = @totais.consolidacoes_de(current_user.nome)
|
||
end
|
||
|
||
# GET /motorista/totais/pdf — o extrato do período em PDF (com assinatura),
|
||
# para o motorista guardar ou mandar por WhatsApp.
|
||
def totais_pdf
|
||
inicio, fim = periodo_totais
|
||
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
|
||
|
||
def totais_do_periodo
|
||
Analytics::TotaisPorMotorista.new(
|
||
inicio: @inicio, fim: @fim, motorista: current_user.nome
|
||
)
|
||
end
|
||
|
||
# Default: mês corrente INTEIRO (fim = último dia do mês). O recorte pede 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 relatório do admin.
|
||
def periodo_totais
|
||
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
|