Files
Reem-Notas/app/models/consolidacao.rb

76 lines
3.0 KiB
Ruby

# 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