class User < ActiveRecord::Base MAX_AVATAR_SIZE_KB = 1024 acts_as_loggable # Include default devise modules. Others available are: # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :lockable #TODO ,:confirmable # Setup accessible (or protected) attributes for your model attr_accessible :email, :password, :password_confirmation, :remember_me, :first_name, :last_name, :bike_id, :user_profiles_attributes, :username, :avatar has_many :transactions, as: :customer has_many :transaction_logs, through: :transactions, source: :logs has_many :user_profiles accepts_nested_attributes_for :user_profiles, allow_destroy: false has_many :user_role_joins, :conditions => ["ends IS NULL OR ends > ?", Time.now] has_many :roles, through: :user_role_joins belongs_to :bike has_attached_file :avatar, :styles => {:thumb => '100x100>'} default_scope order('username ASC') validates :username, :presence => true, uniqueness: true validates :first_name, :presence => true validates :last_name, :presence => true validates_attachment :avatar, :content_type => {:content_type => %w{ image/jpeg image/gif image/png }}, :file_name => {:matches => [/png\Z/, /jpe?g\Z/, /gif\Z/]}, :size => {:in => 0..MAX_AVATAR_SIZE_KB.kilobytes} def to_s "#{first_name} #{last_name}" end def email_required? false end def full_name to_s end def role?(role) if role.kind_of?(String) or role.kind_of?(Symbol) role = Role.find_by_role(role.to_s) end roles.include?(role) end # try keeping the email field in DB clear and consistent, without empty strings (NULLs instead) def email=(other) super(other.blank? ? nil : other) end ### TODO methods below probably belong somewhere else def completed_build_bikes #default BUILDBIKE/CLASS ID is 5 purpose_id = 5 Bike.find_by_sql(" SELECT * FROM bikes INNER JOIN( SELECT * FROM transactions WHERE customer_id = #{self.id} ) AS transactions ON bikes.id = transactions.bike_id WHERE bike_purpose_id = #{purpose_id}") end def total_credits total_earned_credits - total_credits_spent end def total_credits_spent log_action_id = 1 #TIME transaction_logs. where( "log_action_id = ? AND log_action_type = ?", log_action_id, ::ActsAsLoggable::TransactionAction.to_s). sum{ |r| r.description.to_i }.round(2) end def total_earned_credits volunteer_id = 1 staff_id = 3 # Find the first credit conversion which has a created_at date before the # log's created_at date and join it to the log's row so we can calculate # the credits earned from that log entry (each log could have a different # conversion rate) # # The DISTINCT ON, and ORDER BY are important to getting the # single conversion rate that applies to the respective log. ::ActsAsLoggable::Log.find_by_sql([" SELECT DISTINCT ON (logs.created_at) start_date, end_date, conversion.conversion, conversion.created_at FROM logs INNER JOIN( SELECT conversion, created_at FROM credit_conversions ) AS conversion ON logs.created_at > conversion.created_at WHERE logs.loggable_id = :id AND logs.loggable_type = 'User' AND (log_action_id IN (:credit_actions) AND log_action_type = :log_action_type) ORDER BY logs.created_at, conversion.created_at DESC", {id: self.id, credit_actions: [volunteer_id, staff_id], log_action_type: ::ActsAsLoggable::UserAction.to_s}]). sum{ |l| ((l.end_date - l.start_date)/3600) * l.conversion.to_i}.round(2) end def total_hours log_action_id = 4 #CHECKIN logs.where("log_action_id != ? AND log_action_type = ?", log_action_id, ::ActsAsLoggable::UserAction.to_s).sum { |l| (l.end_date - l.start_date)/3600 }.round(2) end def current_month_hours log_action_id = 4 #CHECKIN #TODO need to prevent users from saving logs across months, force to create a new log if crossing month current_month_range = (Time.now.beginning_of_month..Time.now.end_of_month) logs.where("log_action_id != ? AND log_action_type = ?", log_action_id, ::ActsAsLoggable::UserAction.to_s) .where( :start_date => current_month_range) .where( :end_date => current_month_range) .sum { |l| (l.end_date - l.start_date)/3600 } .round(2) end def checked_in? #default CHECKIN log action is id, yea yea should be a constant log_action_id = 4 checked = logs.where( log_action_id: log_action_id). where("start_date >= ?", Time.zone.now.beginning_of_day). where("start_date = end_date") !checked.empty? end def checkin #default CHECKIN log action is id, yea yea should be a constant log_action_id = 4 time = Time.now logs.create( logger_id: self.id, logger_type: self.class.to_s, start_date: time, end_date: time, log_action_id: log_action_id, log_action_type: ::ActsAsLoggable::UserAction.to_s) save end def checkout #default CHECKIN log action is id, yea yea should be a constant log_action_id = 4 checked = logs.where( log_action_id: log_action_id). where("start_date >= ?", Time.zone.now.beginning_of_day). where("start_date = end_date").first checked.end_date = Time.now checked.save end end