# 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