Submit social housing lettings and sales data (CORE)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

194 lines
5.8 KiB

class User < ApplicationRecord
# Include default devise modules. Others available are:
# :omniauthable
devise :database_authenticatable, :recoverable, :rememberable,
:trackable, :lockable, :two_factor_authenticatable, :confirmable, :timeoutable
# Marked as optional because we validate organisation_id below instead so that
# the error message is linked to the right field on the form
belongs_to :organisation, optional: true
has_many :owned_lettings_logs, through: :organisation
has_many :managed_lettings_logs, through: :organisation
has_many :owned_sales_logs, through: :organisation
has_many :legacy_users
has_many :bulk_uploads
validates :name, presence: true
validates :email, presence: true
validates :email, uniqueness: { allow_blank: true, case_sensitive: true, if: :will_save_change_to_email? }
validates :email, format: { with: Devise.email_regexp, allow_blank: true, if: :will_save_change_to_email? }
validates :password, presence: { if: :password_required? }
validates :password, confirmation: { if: :password_required? }
validates :password, length: { within: Devise.password_length, allow_blank: true }
after_validation :send_data_protection_confirmation_reminder, if: :is_dpo_changed?
validates :organisation_id, presence: true
has_paper_trail ignore: %w[last_sign_in_at
current_sign_in_at
current_sign_in_ip
last_sign_in_ip
failed_attempts
unlock_token
locked_at
reset_password_token
reset_password_sent_at
remember_created_at
sign_in_count
updated_at]
has_one_time_password(encrypted: true)
auto_strip_attributes :name
ROLES = {
data_provider: 1,
data_coordinator: 2,
support: 99,
}.freeze
enum role: ROLES
scope :search_by_name, ->(name) { where("users.name ILIKE ?", "%#{name}%") }
scope :search_by_email, ->(email) { where("email ILIKE ?", "%#{email}%") }
scope :filter_by_active, -> { where(active: true) }
scope :search_by, ->(param) { search_by_name(param).or(search_by_email(param)) }
scope :sorted_by_organisation_and_role, -> { joins(:organisation).order("organisations.name", role: :desc, name: :asc) }
def lettings_logs
if support?
LettingsLog.all
else
LettingsLog.filter_by_organisation(organisation)
end
end
def sales_logs
if support?
SalesLog.all
else
SalesLog.filter_by_organisation(organisation)
end
end
def is_key_contact?
is_key_contact
end
def is_key_contact!
update(is_key_contact: true)
end
def is_data_protection_officer?
is_dpo
end
def is_data_protection_officer!
update!(is_dpo: true)
end
MFA_TEMPLATE_ID = "6bdf5ee1-8e01-4be1-b1f9-747061d8a24c".freeze
RESET_PASSWORD_TEMPLATE_ID = "2c410c19-80a7-481c-a531-2bcb3264f8e6".freeze
CONFIRMABLE_TEMPLATE_ID = "3fc2e3a7-0835-4b84-ab7a-ce51629eb614".freeze
RECONFIRMABLE_TEMPLATE_ID = "bcdec787-f0a7-46e9-8d63-b3e0a06ee455".freeze
BETA_ONBOARDING_TEMPLATE_ID = "b48bc2cd-5887-4611-8296-d0ab3ed0e7fd".freeze
USER_REACTIVATED_TEMPLATE_ID = "ac45a899-490e-4f59-ae8d-1256fc0001f9".freeze
def reset_password_notify_template
RESET_PASSWORD_TEMPLATE_ID
end
def confirmable_template
if last_sign_in_at.present? && (unconfirmed_email.blank? || unconfirmed_email == email)
USER_REACTIVATED_TEMPLATE_ID
elsif was_migrated_from_softwire? && last_sign_in_at.blank?
BETA_ONBOARDING_TEMPLATE_ID
elsif initial_confirmation_sent
RECONFIRMABLE_TEMPLATE_ID
else
CONFIRMABLE_TEMPLATE_ID
end
end
def was_migrated_from_softwire?
legacy_users.any? || old_user_id.present?
end
def send_confirmation_instructions
return unless active?
super
update!(initial_confirmation_sent: true)
end
def need_two_factor_authentication?(_request)
return false if Rails.env.development?
return false if Rails.env.review?
support?
end
def send_two_factor_authentication_code(code)
template_id = MFA_TEMPLATE_ID
personalisation = { otp: code }
DeviseNotifyMailer.new.send_email(email, template_id, personalisation)
end
def assignable_roles
return {} unless data_coordinator? || support?
return ROLES if support?
ROLES.except(:support)
end
def logs_filters(specific_org: false)
if (support? && !specific_org) || organisation.has_managing_agents? || organisation.has_stock_owners?
%w[status years assigned_to user managing_organisation owning_organisation bulk_upload_id]
else
%w[status years assigned_to user bulk_upload_id]
end
end
delegate :name, to: :organisation, prefix: true
def self.download_attributes
%w[id email name organisation_name role old_user_id is_dpo is_key_contact active sign_in_count last_sign_in_at]
end
def self.to_csv
CSV.generate(headers: true) do |csv|
csv << download_attributes
all.find_each do |record|
csv << download_attributes.map { |attr| record.public_send(attr) }
end
end
end
def can_toggle_active?(user)
self != user && (support? || data_coordinator?)
end
def valid_for_authentication?
super && active?
end
protected
# Checks whether a password is needed or not. For validations only.
# Passwords are always required if it's a new record, or if the password
# or confirmation are being set somewhere.
def password_required?
!persisted? || !password.nil? || !password_confirmation.nil?
end
private
def send_data_protection_confirmation_reminder
return unless persisted?
return unless is_dpo?
DataProtectionConfirmationMailer.send_confirmation_email(self).deliver_later
end
end