# app/models/consolidacao.rb class Consolidacao < ApplicationRecord belongs_to :criador, class_name: 'User', foreign_key: :created_by belongs_to :finalizador, class_name: 'User', foreign_key: :finalizado_por, optional: true has_many :consolidacao_motoristas, dependent: :destroy has_many :consolidacao_entregas, dependent: :destroy # ── Enums ─────────────────────────────────────────────────── enum status: { rascunho: 0, finalizada: 1, arquivada: 2 } # ── Soft delete ───────────────────────────────────────────── scope :ativas, -> { where(deleted_at: nil) } scope :arquivadas, -> { where.not(deleted_at: nil) } # ── Validações ────────────────────────────────────────────── validates :nome, presence: true validates :data_inicio, presence: true validates :data_fim, presence: true validates :created_by, presence: true validate :periodo_valido # ── Callbacks ─────────────────────────────────────────────── before_save :recalcular_valor_total # ── Escopos ───────────────────────────────────────────────── scope :recentes, -> { order(created_at: :desc) } scope :no_periodo, ->(i, f) { where('data_inicio >= ? AND data_fim <= ?', i, f) } # ── Métodos ───────────────────────────────────────────────── def arquivar!(user) update!(deleted_at: Time.current, status: :arquivada) end def finalizar!(user) return false unless todas_entregas_classificadas? update!( status: :finalizada, finalizado_por: user.id, finalizado_em: Time.current ) end def todas_entregas_classificadas? total_entregas = ConsolidacaoMotorista .where(consolidacao_id: id) .sum { |cm| Entrega.contar_pagas(inicio: data_inicio, fim: data_fim, motorista: cm.motorista_nome) } consolidacao_entregas.count >= total_entregas end def percentual_classificado return 0 if total_entregas_estimadas.zero? ((consolidacao_entregas.count.to_f / total_entregas_estimadas) * 100).round end def total_entregas_estimadas @total_entregas_estimadas ||= consolidacao_motoristas.sum do |cm| Entrega.contar_pagas(inicio: data_inicio, fim: data_fim, motorista: cm.motorista_nome) end end private def periodo_valido return unless data_inicio && data_fim errors.add(:data_fim, 'deve ser após a data de início') if data_fim < data_inicio end def recalcular_valor_total self.valor_total = consolidacao_motoristas.sum(:valor_total) end end