Fases 4, 5 e 6 — Job 1h + Auditoria + Consolidação + Wizard de validação

This commit is contained in:
2026-06-11 12:02:50 -03:00
parent b77fc0122c
commit 90ed705ed8
29 changed files with 1617 additions and 616 deletions

View File

@@ -1,34 +1,75 @@
# app/models/consolidacao.rb
class Consolidacao < ApplicationRecord
# Soft delete
acts_as_paranoid if respond_to?(:acts_as_paranoid)
belongs_to :criador, class_name: 'User', foreign_key: :created_by
belongs_to :finalizador, class_name: 'User', foreign_key: :finalizado_por, optional: true
enum status: { aberta: 0, em_revisao: 1, fechada: 2, aprovada: 3, cancelada: 4 }
belongs_to :criado_por, class_name: 'User', foreign_key: :user_id
has_many :consolidacao_motoristas, dependent: :destroy
has_many :consolidacao_entregas, through: :consolidacao_motoristas
has_many :motoristas, through: :consolidacao_motoristas, source: :user
has_many :consolidacao_entregas, dependent: :destroy
validates :referencia_mes, presence: true
validates :status, presence: true
# ── Enums ───────────────────────────────────────────────────
enum status: { rascunho: 0, finalizada: 1, arquivada: 2 }
scope :do_mes, ->(data = Date.today) {
where(referencia_mes: data.beginning_of_month..data.end_of_month)
}
# ── Soft delete ─────────────────────────────────────────────
scope :ativas, -> { where(deleted_at: nil) }
scope :arquivadas, -> { where.not(deleted_at: nil) }
scope :abertas, -> { where(status: :aberta) }
scope :fechadas, -> { where(status: [:fechada, :aprovada]) }
# ── Validações ──────────────────────────────────────────────
validates :nome, presence: true
validates :data_inicio, presence: true
validates :data_fim, presence: true
validates :created_by, presence: true
validate :periodo_valido
def progresso_percentual
return 0 if consolidacao_motoristas.none?
# ── Callbacks ───────────────────────────────────────────────
before_save :recalcular_valor_total
finalizados = consolidacao_motoristas.where(finalizado: true).count
total = consolidacao_motoristas.count
((finalizados.to_f / total) * 100).round
# ── 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 mes_label
referencia_mes&.strftime('%B/%Y')&.capitalize
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