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

72 lines
2.7 KiB
Ruby

# app/models/consolidacao_veiculo.rb
# Unidade de FECHAMENTO por veículo dentro de uma consolidação. Espelha os padrões
# de ConsolidacaoMotorista (arquivamento reversível + valor_total recalculado dos
# pilares), mas o que ela controla é o estado "fechado/consolidado" de cada carro.
# O PAGAMENTO continua no motorista (ConsolidacaoMotorista) — ver [[consolidacao]].
class ConsolidacaoVeiculo < ApplicationRecord
# Nome da tabela fixado (mesmo motivo dos outros: inflector pt-BR).
self.table_name = 'consolidacao_veiculos'
# Bucket dos lançamentos sem veículo (termo/apontamento manual legado). Igual ao
# sentinel usado no controller e na migração — NULL quebraria o índice único.
SEM_VEICULO = '(sem veículo)'
belongs_to :consolidacao
belongs_to :fechador, class_name: 'User', foreign_key: :fechado_por, optional: true
belongs_to :arquivador, class_name: 'User', foreign_key: :arquivado_por, optional: true
validates :motorista_nome, presence: true
validates :vehicle, presence: true
validates :vehicle, uniqueness: { scope: %i[consolidacao_id motorista_nome] }
before_save :recalcular_valor
# ── Fechamento (consolidação do veículo, reversível) ────────
scope :fechados, -> { where.not(fechado_em: nil) }
scope :abertos, -> { where(fechado_em: nil) }
# ── Arquivamento (reversível) — sai do gate, mantém os dados ─
scope :ativos, -> { where(arquivado_em: nil) }
scope :arquivados, -> { where.not(arquivado_em: nil) }
def fechado?
fechado_em.present?
end
def arquivado?
arquivado_em.present?
end
# update_columns: não dispara before_save (o valor já está correto no fechamento).
def fechar!(user)
update_columns(fechado_em: Time.current, fechado_por: user&.id, updated_at: Time.current)
end
def reabrir!(_user)
update_columns(fechado_em: nil, fechado_por: nil, updated_at: Time.current)
end
def arquivar!(user)
update_columns(arquivado_em: Time.current, arquivado_por: user&.id, updated_at: Time.current)
end
def desarquivar!(_user)
update_columns(arquivado_em: nil, arquivado_por: nil, updated_at: Time.current)
end
# Soma dos pilares deste (motorista + veículo). Mesma regra do ConsolidacaoMotorista:
# o valor_aplicado capturado na classificação é a fonte da verdade e o desconto
# subtrai. O bucket "(sem veículo)" casa os pilares com vehicle NULL/vazio.
def recalcular_valor
self.valor_total = escopo_entregas
.sum { |e| e.desconto? ? -e.valor_aplicado : e.valor_aplicado }
end
private
def escopo_entregas
rel = consolidacao.consolidacao_entregas.where(motorista_nome: motorista_nome)
vehicle == SEM_VEICULO ? rel.where(vehicle: [nil, '']) : rel.where(vehicle: vehicle)
end
end