76 lines
3.0 KiB
Ruby
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
|