Fases 4, 5 e 6 — Job 1h + Auditoria + Consolidação + Wizard de validação
This commit is contained in:
@@ -1,59 +1,69 @@
|
||||
# app/models/user.rb
|
||||
class User < ApplicationRecord
|
||||
# Devise modules
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :validatable,
|
||||
:trackable, :lockable
|
||||
devise :database_authenticatable,
|
||||
:registerable,
|
||||
:recoverable,
|
||||
:rememberable,
|
||||
:validatable
|
||||
|
||||
# Roles
|
||||
# ── Roles ──────────────────────────────────────────────────
|
||||
enum role: { admin: 0, gerente: 1, operador: 2, motorista: 3 }
|
||||
|
||||
# Validações
|
||||
validates :name, presence: true
|
||||
validates :role, presence: true
|
||||
validates :pin_acesso,
|
||||
uniqueness: { allow_blank: true },
|
||||
length: { is: 4, allow_blank: true },
|
||||
format: { with: /\A\d{4}\z/, allow_blank: true, message: 'deve ter exatamente 4 dígitos numéricos' }
|
||||
ROLES_LABEL = {
|
||||
'admin' => 'Administrador',
|
||||
'gerente' => 'Gerente',
|
||||
'operador' => 'Operador',
|
||||
'motorista' => 'Motorista'
|
||||
}.freeze
|
||||
|
||||
validate :pin_obrigatorio_para_motorista
|
||||
# ── Validações ──────────────────────────────────────────────
|
||||
validates :nome, presence: true, length: { minimum: 3 }
|
||||
validates :role, presence: true
|
||||
validates :pin_code,
|
||||
length: { is: 4 },
|
||||
numericality: { only_integer: true },
|
||||
allow_nil: true,
|
||||
if: :motorista?
|
||||
|
||||
# Callbacks
|
||||
before_validation :normalizar_pin
|
||||
validate :pin_unico_para_motoristas, if: :motorista?
|
||||
|
||||
# Associações
|
||||
has_many :auditoria_logs, foreign_key: :user_id, dependent: :nullify
|
||||
has_many :consolidacao_motoristas, foreign_key: :user_id, dependent: :restrict_with_error
|
||||
# Motoristas podem não ter e-mail (login via PIN)
|
||||
def email_required?
|
||||
!motorista?
|
||||
end
|
||||
|
||||
# Scopes
|
||||
scope :ativos, -> { where(ativo: true) }
|
||||
scope :motoristas, -> { where(role: :motorista) }
|
||||
def password_required?
|
||||
!motorista? ? super : false
|
||||
end
|
||||
|
||||
# ── Escopos ─────────────────────────────────────────────────
|
||||
scope :ativos, -> { where(ativo: true) }
|
||||
scope :por_nome, -> { order(:nome) }
|
||||
scope :nao_motoristas, -> { where.not(role: :motorista) }
|
||||
|
||||
# ── Helpers ─────────────────────────────────────────────────
|
||||
def nome_display
|
||||
name.split.first.capitalize
|
||||
nome.presence || email
|
||||
end
|
||||
|
||||
def active?
|
||||
ativo?
|
||||
def role_label
|
||||
ROLES_LABEL[role] || role.humanize
|
||||
end
|
||||
|
||||
def pode_acessar_admin?
|
||||
def pode_ver_config?
|
||||
admin? || gerente?
|
||||
end
|
||||
|
||||
def pode_criar_consolidacao?
|
||||
def pode_consolidar?
|
||||
admin? || gerente? || operador?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def normalizar_pin
|
||||
self.pin_acesso = pin_acesso.to_s.strip.presence
|
||||
end
|
||||
def pin_unico_para_motoristas
|
||||
return if pin_code.blank?
|
||||
|
||||
def pin_obrigatorio_para_motorista
|
||||
if motorista? && pin_acesso.blank?
|
||||
errors.add(:pin_acesso, 'é obrigatório para motoristas')
|
||||
end
|
||||
conflito = User.motorista.where(pin_code: pin_code).where.not(id: id)
|
||||
errors.add(:pin_code, 'já está em uso por outro motorista') if conflito.exists?
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user