osem-fcy/app/models/conference.rb

941 lines
26 KiB
Ruby
Raw Normal View History

2014-04-08 21:02:10 +02:00
##
# This class represents a conference
# rubocop:disable Style/ClassLength
2013-01-07 09:04:09 +01:00
class Conference < ActiveRecord::Base
2014-06-13 00:20:18 +05:30
require 'uri'
serialize :events_per_week, Hash
2014-08-12 11:51:59 +03:00
resourcify # Needed to call 'Conference.with_role' in /models/ability.rb
2014-06-13 00:20:18 +05:30
2014-11-14 17:24:24 +01:00
default_scope { order('start_date DESC') }
has_paper_trail
2013-01-07 09:04:09 +01:00
2014-11-12 21:10:45 +02:00
has_and_belongs_to_many :questions
2014-02-09 18:05:57 +02:00
has_one :splashpage, dependent: :destroy
2014-07-31 18:49:46 +02:00
has_one :contact, dependent: :destroy
has_one :registration_period, dependent: :destroy
2014-06-24 12:14:53 +03:00
has_one :email_settings, dependent: :destroy
has_one :program, dependent: :destroy
has_one :venue, dependent: :destroy
2014-06-24 12:14:53 +03:00
has_many :social_events, dependent: :destroy
has_many :ticket_purchases, dependent: :destroy
has_many :supporters, through: :ticket_purchases, source: :user
has_many :tickets, dependent: :destroy
2014-06-24 12:14:53 +03:00
has_many :dietary_choices, dependent: :destroy
has_many :lodgings, dependent: :destroy
2014-06-24 12:14:53 +03:00
has_many :registrations, dependent: :destroy
has_many :participants, through: :registrations, source: :user
2014-06-24 12:14:53 +03:00
has_many :vdays, dependent: :destroy
has_many :vpositions, dependent: :destroy
has_many :sponsorship_levels, -> { order('position ASC') }, dependent: :destroy
2014-06-05 17:51:22 +05:30
has_many :sponsors, dependent: :destroy
2014-06-10 12:43:15 +05:30
has_many :photos, dependent: :destroy
has_many :targets, dependent: :destroy
has_many :campaigns, dependent: :destroy
has_many :commercials, as: :commercialable, dependent: :destroy
has_many :subscriptions, dependent: :destroy
2013-01-07 09:04:09 +01:00
2014-06-24 12:14:53 +03:00
accepts_nested_attributes_for :social_events, allow_destroy: true
2013-01-07 09:04:09 +01:00
accepts_nested_attributes_for :venue
2014-06-24 12:14:53 +03:00
accepts_nested_attributes_for :dietary_choices, allow_destroy: true
accepts_nested_attributes_for :tickets, allow_destroy: true
accepts_nested_attributes_for :sponsorship_levels, allow_destroy: true
accepts_nested_attributes_for :sponsors, allow_destroy: true
2013-01-14 08:49:49 +01:00
accepts_nested_attributes_for :email_settings
2014-06-24 12:14:53 +03:00
accepts_nested_attributes_for :questions, allow_destroy: true
accepts_nested_attributes_for :vdays, allow_destroy: true
accepts_nested_attributes_for :vpositions, allow_destroy: true
accepts_nested_attributes_for :photos, allow_destroy: true
accepts_nested_attributes_for :targets, allow_destroy: true
accepts_nested_attributes_for :campaigns, allow_destroy: true
2013-01-07 09:04:09 +01:00
2013-01-17 15:56:56 +01:00
has_attached_file :logo,
2014-06-20 18:41:08 +05:30
styles: { thumb: '100x100>', large: '300x300>' }
2013-01-17 15:56:56 +01:00
validates_attachment_content_type :logo,
2014-06-20 18:41:08 +05:30
content_type: [/jpg/, /jpeg/, /png/, /gif/],
size: { in: 0..500.kilobytes }
2013-01-17 15:56:56 +01:00
2013-01-07 09:04:09 +01:00
validates_presence_of :title,
:short_title,
2014-04-05 21:44:30 +05:30
:start_date,
:end_date
2014-06-13 00:20:18 +05:30
2013-01-07 09:04:09 +01:00
validates_uniqueness_of :short_title
2014-07-21 14:49:05 +02:00
validates_format_of :short_title, with: /\A[a-zA-Z0-9_-]*\z/
# This validation is needed since a conference with a start date greater than the end date is not possible
validate :valid_date_range?
2013-01-07 09:04:09 +01:00
before_create :generate_guid
before_create :add_color
before_create :create_email_settings
2013-01-07 09:04:09 +01:00
def date_range_string
2015-09-17 12:12:51 +02:00
startstr = 'Unknown - '
endstr = 'Unknown'
if start_date.month == end_date.month && start_date.year == end_date.year
2015-09-17 12:12:51 +02:00
startstr = start_date.strftime('%B %d - ')
endstr = end_date.strftime('%d, %Y')
elsif start_date.month != end_date.month && start_date.year == end_date.year
2015-09-17 12:12:51 +02:00
startstr = start_date.strftime('%B %d - ')
endstr = end_date.strftime('%B %d, %Y')
else
2015-09-17 12:12:51 +02:00
startstr = start_date.strftime('%B %d, %Y - ')
endstr = end_date.strftime('%B %d, %Y')
end
result = startstr + endstr
result
end
2014-04-08 21:02:10 +02:00
##
# Checks if the user is registered to the conference
#
# ====Args
# * +user+ -> The user we check for
2014-04-08 21:02:10 +02:00
# ====Returns
# * +false+ -> If the user is registered
# * +true+ - If the user isn't registered
2013-01-07 09:04:09 +01:00
def user_registered? user
2015-05-19 19:57:50 +02:00
user.present? && registrations.where(user_id: user.id).count > 0
2013-01-07 09:04:09 +01:00
end
2014-04-08 21:02:10 +02:00
##
# Checks if the registration for the conference is currently open
#
# ====Returns
# * +false+ -> If the conference dates are not set or today isn't in the
# registration period.
# * +true+ -> If today is in the registration period.
def registration_open?
registration_dates_given? &&
(registration_period.start_date..registration_period.end_date).cover?(Date.current)
2014-06-04 23:55:02 +05:30
end
2014-06-04 23:55:02 +05:30
##
# Checks if the registration dates for the conference are provided
#
# ====Returns
# * +false+ -> If the conference registration dates are not set
# * +true+ -> If conference registration dates are set
def registration_dates_given?
2015-05-21 18:53:27 +02:00
registration_period.present? &&
registration_period.start_date.present? &&
registration_period.end_date.present?
end
##
# Returns an array with the summarized event submissions per week.
#
# ====Returns
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0 events, second week 3 events.
def get_submissions_per_week
result = []
if program && program.cfp && program.events
submissions = program.events.group(:week).count
start_week = program.cfp.start_week
weeks = program.cfp.weeks
result = calculate_items_per_week(start_week, weeks, submissions)
end
result
end
2014-06-16 13:51:43 +02:00
##
# Returns an hash with submitted, confirmed and unconfirmed event submissions
# per week.
2014-06-16 13:51:43 +02:00
#
# ====Returns
# * +Array+ -> e.g. 'Submitted' => [0, 3, 3, 5] -> first week 0 events, second week 3 events.
def get_submissions_data
result = {}
if program && program.cfp && program.events
result = get_events_per_week_by_state
start_week = program.cfp.start_week
end_week = end_date.strftime('%W').to_i
weeks = weeks(start_week, end_week)
result.each do |state, values|
if state == 'Submitted'
result['Submitted'] = pad_array_left_kumulative(start_week, values)
else
result[state] = pad_array_left_not_kumulative(start_week, values)
end
end
result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0
2014-06-16 13:51:43 +02:00
end
result
end
##
# Returns an array with the summarized registrations per week.
#
# ====Returns
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 registrations
def get_registrations_per_week
result = []
if registrations &&
registration_period &&
registration_period.start_date &&
registration_period.end_date
reg = registrations.group(:week).count
start_week = get_registration_start_week
weeks = registration_weeks
result = calculate_items_per_week(start_week, weeks, reg)
end
result
end
##
# Calculates how many weeks the registration is.
#
# ====Returns
# * +Integer+ -> start week
def registration_weeks
result = 0
weeks = 0
if registration_period &&
registration_period.start_date &&
registration_period.end_date
weeks = Date.new(registration_period.start_date.year, 12, 31).
strftime('%W').to_i
result = get_registration_end_week - get_registration_start_week + 1
end
result < 0 ? result + weeks : result
end
##
# Calculates how many weeks call for papers is.
#
# ====Returns
# * +Integer+ -> weeks
def cfp_weeks
if program
program.cfp.weeks
2015-05-19 20:12:03 +02:00
else
0
end
end
##
# Calculates the end week of the registration
#
# ====Returns
# * +Integer+ -> start week
def get_registration_start_week
if registration_period
2015-05-19 20:12:03 +02:00
registration_period.start_date.strftime('%W').to_i
else
-1
end
end
##
# Calculates the start week of the registration
#
# ====Returns
# * +Integer+ -> start week
def get_registration_end_week
if registration_period
2015-05-19 20:12:03 +02:00
registration_period.end_date.strftime('%W').to_i
else
-1
end
end
##
# Checks if the conference is pending.
#
# ====Returns
# * +false+ -> If the conference start date is in the past.
# * +true+ -> If the conference start date is in the future.
def pending?
start_date > Date.today
end
##
# Returns a hash with booleans with the required conference options.
#
# ====Returns
# * +hash+ -> true -> filled / false -> missing
def get_status
result = {
registration: registration_date_set?,
cfp: cfp_set?,
venue: venue_set?,
rooms: rooms_set?,
tracks: tracks_set?,
event_types: event_types_set?,
difficulty_levels: difficulty_levels_set?,
splashpage: splashpage && splashpage.public?
}
result.update(
process: calculate_setup_progress(result),
short_title: short_title
).with_indifferent_access
end
##
2014-06-23 19:07:50 +03:00
# Returns a hash with user => submissions ordered by submissions for all conferences
#
# ====Returns
2014-06-23 19:07:50 +03:00
# * +hash+ -> user: submissions
def self.get_top_submitter(limit = 5)
2014-06-23 19:07:50 +03:00
submitter = EventUser.where('event_role = ?', 'submitter').limit(limit).group(:user_id)
counter = submitter.order('count_all desc').count
2014-06-23 19:07:50 +03:00
calculate_user_submission_hash(submitter, counter)
end
##
2014-06-23 19:07:50 +03:00
# Returns a hash with user => submissions ordered by submissions
#
# ====Returns
2014-06-23 19:07:50 +03:00
# * +hash+ -> user: submissions
def get_top_submitter(limit = 5)
2014-06-23 19:07:50 +03:00
submitter = EventUser.joins(:event).
where('event_role = ? and program_id = ?', 'submitter', Conference.find(id).program.id).
2014-06-23 19:07:50 +03:00
limit(limit).group(:user_id)
counter = submitter.order('count_all desc').count
2014-06-23 19:07:50 +03:00
Conference.calculate_user_submission_hash(submitter, counter)
end
##
# Returns a hash with event state => {value: count of event states, color: color}.
# The result is calculated over all conferences.
#
# ====Returns
# * +hash+ -> hash
def self.event_distribution
2015-06-16 23:09:47 +02:00
calculate_event_distribution_hash(Event.select(:state).group(:state).count)
end
##
# Returns a hash with event state => {value: count of event states, color: color}
#
# ====Returns
# * +hash+ -> hash
def event_distribution
Conference.calculate_event_distribution_hash(program.events.select(:state).group(:state).count)
end
##
# Returns a hash with user distribution => {value: count of user state, color: color}
# active: signed in during the last 3 months
# unconfirmed: registered but not confirmed
# dead: not signed in during the last year
#
# ====Returns
# * +hash+ -> hash
def self.user_distribution
active_user = User.where('last_sign_in_at > ?', Date.today - 3.months).count
unconfirmed_user = User.where('confirmed_at IS NULL').count
dead_user = User.where('last_sign_in_at < ?', Date.today - 1.year).count
calculate_user_distribution_hash(active_user, unconfirmed_user, dead_user)
end
2014-06-16 13:51:43 +02:00
##
# Calculates the overall program minutes
2014-06-16 13:51:43 +02:00
#
# ====Returns
# * +hash+ -> Fixnum minutes
def current_program_minutes
events_grouped = program.events.select(:event_type_id).group(:event_type_id)
2014-06-16 13:51:43 +02:00
events_counted = events_grouped.count
calculate_program_minutes(events_grouped, events_counted)
2014-06-16 13:51:43 +02:00
end
##
# Calculates the overall program hours
2014-06-16 13:51:43 +02:00
#
# ====Returns
# * +Fixnum+ -> Fixnum hours. Example: 1.5 gets rounded to 2. 1.3 gets rounded 1.
def current_program_hours
(current_program_minutes / 60.to_f).round
end
##
# Calculates the overall program minutes since date
#
# ====Returns
# * +hash+ -> Fixnum minutes
def new_program_minutes(date)
events_grouped = program.events.select(:event_type_id).where('created_at > ?', date).group(:event_type_id)
2014-06-16 13:51:43 +02:00
events_counted = events_grouped.count
calculate_program_minutes(events_grouped, events_counted)
end
##
# Calculates the overall program hours since date
#
# ====Returns
# * +Fixnum+ -> Fixnum hours
def new_program_hours(date)
(new_program_minutes(date) / 60.to_f).round
2014-06-16 13:51:43 +02:00
end
##
# Calculates the difficulty level distribution from all events.
#
# ====Returns
# * +hash+ -> difficulty level => {color, value}
def difficulty_levels_distribution(state = nil)
calculate_event_distribution(:difficulty_level_id, :difficulty_level, state)
end
##
# Calculates the event_type distribution from all events.
#
# ====Returns
# * +hash+ -> event_type => {color, value}
def event_type_distribution(state = nil)
calculate_event_distribution(:event_type_id, :event_type, state)
end
##
# Calculates the track distribution from all events.
#
# ====Returns
# * +hash+ -> track => {color, value}
def tracks_distribution(state = nil)
if state
tracks_grouped = program.events.select(:track_id).where('state = ?', state).group(:track_id)
2014-06-16 13:51:43 +02:00
else
tracks_grouped = program.events.select(:track_id).group(:track_id)
2014-06-16 13:51:43 +02:00
end
tracks_counted = tracks_grouped.count
calculate_track_distribution_hash(tracks_grouped, tracks_counted)
end
##
# Return all pending conferences. If there are no pending conferences, the last two
# past conferences are returned
#
# ====Returns
# * +ActiveRecord+
def self.get_active_conferences_for_dashboard
result = Conference.where('start_date > ?', Time.now).
select('id, short_title, color, start_date')
2014-06-16 13:51:43 +02:00
if result.length == 0
result = Conference.
select('id, short_title, color, start_date').limit(2).
2014-06-16 13:51:43 +02:00
order(start_date: :desc)
end
result
end
##
# Return all conferences minus the active conferences
#
# ====Returns
# * +ActiveRecord+
def self.get_conferences_without_active_for_dashboard(active_conferences)
result = Conference.select('id, short_title, color, start_date').order(start_date: :desc)
2014-06-16 13:51:43 +02:00
result - active_conferences
end
##
# A list with the three event states submitted, confirmed, unconfirmed with corresponding colors
#
# ====Returns
# * +List+
def self.get_event_state_line_colors
[
{ short_title: 'Submitted', color: 'blue' },
{ short_title: 'Confirmed', color: 'green' },
{ short_title: 'Unconfirmed', color: 'orange' }
]
2014-06-16 13:51:43 +02:00
end
##
# A map with all conference targets with progress in percent of a certain unit.
#
# ====Returns
# * +Map+ -> target => progress
def get_targets(target_unit)
conference_target = targets.where('unit = ?', target_unit)
result = {}
conference_target.each do |target|
result[target.to_s] = target.get_progress
end
result
end
##
# A map with all conference campaigns associated with targets.
#
# ====Returns
# * +Map+ -> campaign => {actual, target, progress}
def get_campaigns
result = {}
campaigns.each do |campaign|
campaign.targets.each do |target|
result["#{target} from #{campaign.name}"] = target.get_campaign
end
end
result
end
##
# Writes an snapshot of the actual event distribution to the database
# Triggered each every Sunday 11:55 pm form whenever (config/schedule.rb).
#
def self.write_event_distribution_to_db
week = DateTime.now.end_of_week
Conference.where('end_date > ?', Date.today).each do |conference|
result = {}
Event.state_machine.states.each do |state|
count = conference.program.events.where('state = ?', state.name).count
result[state.name] = count
end
if !conference.events_per_week
conference.events_per_week = {}
end
# Write to database
conference.events_per_week[week] = result
conference.save!
end
end
##
# Checks if conference is updated for email notifications.
#
# ====Returns
# * +True+ -> If conference is updated and all other parameters are set
# * +False+ -> Either conference is not updated or one or more parameter is not set
def notify_on_dates_changed?
(self.start_date_changed? || self.end_date_changed?) &&
self.email_settings.send_on_conference_dates_updated &&
!self.email_settings.conference_dates_updated_subject.blank? &&
self.email_settings.conference_dates_updated_body
end
##
# Checks if registration dates are updated for email notifications.
#
# ====Returns
# * +True+ -> If registration dates is updated and all other parameters are set
# * +False+ -> Either registration date is not updated or one or more parameter is not set
def notify_on_registration_dates_changed?
registration_period &&
(registration_period.start_date_changed? || registration_period.end_date_changed?) &&
email_settings.send_on_conference_registration_dates_updated &&
!email_settings.conference_registration_dates_updated_subject.blank? &&
email_settings.conference_registration_dates_updated_body
end
2013-01-07 09:04:09 +01:00
private
2014-07-31 18:49:46 +02:00
after_create do
self.create_contact
self.create_program
2014-07-31 18:49:46 +02:00
end
##
# Checks if start date of the conference is greater than the end date
#
# Reports an error when such a condition is found
def valid_date_range?
2016-01-21 13:05:27 +02:00
errors.add(:start_date, 'Start date is greater than End date') if start_date && end_date && start_date > end_date
end
##
# Calculates the weeks from a start and a end week.
#
# ====Returns
# * +Fixnum+ -> weeks
def weeks(start_week, end_week)
weeks = end_week - start_week + 1
weeks_of_year = Date.new(start_date.year, 12, 31).strftime('%W').to_i
weeks < 0 ? weeks + weeks_of_year : weeks
end
##
# Returns a Hash with the events with the state confirmend / unconfirmed per week.
#
# ====Returns
# * +Hash+ -> e.g. 'Confirmed' => { 3 => 5, 4 => 6 }
def get_events_per_week_by_state
result = {
'Submitted' => {},
'Confirmed' => {},
'Unconfirmed' => {}
}
# Completed weeks
events_per_week.each do |week, values|
values.each do |state, value|
if [:confirmed, :unconfirmed].include?(state)
if !result[state.to_s.capitalize]
result[state.to_s.capitalize] = {}
end
result[state.to_s.capitalize][week.strftime('%W').to_i] = value
end
end
end
# Actual week
this_week = Date.today.end_of_week.strftime('%W').to_i
result['Confirmed'][this_week] = program.events.where('state = ?', :confirmed).count
result['Unconfirmed'][this_week] = program.events.where('state = ?', :unconfirmed).count
result['Submitted'] = program.events.select(:week).group(:week).count
result['Submitted'][this_week] = program.events.where(week: this_week).count
result
end
##
# Returns an array from the hash values with left padding.
#
# ====Returns
# * +Array+ -> [0, 0, 1, 2, 3, 0, 0]
def pad_array_left_not_kumulative(start_week, hash)
hash = assert_keys_are_continuously(hash)
first_week = hash.keys[0]
left = pad_left(first_week, start_week)
left + hash.values
end
##
# Returns an array from the hash values with left padding.
#
# ====Returns
# * +Array+ -> [0, 0, 1, 2, 3, 3, 3]
def pad_array_left_kumulative(start_week, hash)
hash = assert_keys_are_continuously(hash)
result = cumulative_sum(hash.values)
first_week = hash.keys[0]
left = pad_left(first_week, start_week)
left + result
end
##
# Cumulative sums an array.
#
# ====Returns
# * +Array+ -> [1, 2, 3, 4] --> [1, 3, 7, 11]
def cumulative_sum(array)
sum = 0
array.map { |x| sum += x }
end
##
# Returns the left padding.
#
# ====Returns
# * +Array+
def pad_left(first_week, start_week)
left = []
if first_week > start_week
left = Array.new(first_week - start_week - 1, 0)
end
left
end
##
# Asserts that all keys in the hash are continuously.
# If not, the missing key is inserted with value 0.
#
# ====Returns
# * +Hash+ { 1 => 1, 2 => 0, 3 => 0, 4 => 3 }
def assert_keys_are_continuously(hash)
keys = hash.keys
(keys.min..keys.max).each do |key|
if !hash[key]
hash[key] = 0
end
end
Hash[ hash.sort ]
end
##
# Returns the progress of the set up conference list in percent
#
# ====Returns
# * +String+ -> Progress in Percent
def calculate_setup_progress(result)
(100 * result.values.count(true) / result.values.count).to_s
end
##
# Checks if there is a difficulty level.
#
# ====Returns
# * +True+ -> One difficulty level or more
# * +False+ -> No diffculty level
def difficulty_levels_set?
program.difficulty_levels.count > 0
end
##
# Checks if there is a difficulty level.
#
# ====Returns
# * +True+ -> One difficulty level or more
# * +False+ -> No diffculty level
def event_types_set?
program.event_types.count > 0
end
##
# Checks if there is a track.
#
# ====Returns
# * +True+ -> One track or more
# * +False+ -> No track
def tracks_set?
program.tracks.count > 0
end
##
# Checks if there is a room.
#
# ====Returns
# * +True+ -> One room or more
# * +False+ -> No room
def rooms_set?
2015-11-07 11:43:36 +02:00
venue.present? && venue.rooms.count > 0
end
# Checks if the conference has a venue object.
#
# ====Returns
# * +True+ -> If conference has a venue object.
# * +False+ -> IF conference has no venue object.
def venue_set?
!!venue
end
##
# Checks if the conference has a call for papers object.
#
# ====Returns
# * +True+ -> If conference has a cfp object.
# * +False+ -> If conference has no cfp object.
def cfp_set?
!!program.cfp
end
##
# Checks if conference has a start and a end date.
#
# ====Returns
# * +True+ -> If conference has a start and a end date.
# * +False+ -> If conference has no start or end date.
def registration_date_set?
!!registration_period && !!registration_period.start_date && !!registration_period.end_date
end
2014-06-16 13:51:43 +02:00
# Calculates the distribution from events.
#
# ====Returns
# * +hash+ -> object_type => {color, value}
def calculate_event_distribution(group_by_id, association_symbol, state = nil)
if state
grouped = program.events.select(group_by_id).where('state = ?', 'confirmed').group(group_by_id)
2014-06-16 13:51:43 +02:00
else
grouped = program.events.select(group_by_id).group(group_by_id)
2014-06-16 13:51:43 +02:00
end
counted = grouped.count
calculate_distribution_hash(grouped, counted, association_symbol)
end
##
# Helper method to calculate the correct data format for the doughnut charts.
#
# ====Returns
# * +hash+ -> object_type => {color, value}
def calculate_distribution_hash(grouped, counter, symbol)
result = {}
grouped.each do |event|
object = event.send(symbol)
if object
result[object.title] = {
'value' => counter[object.id],
'color' => object.color
}
end
end
result
end
##
# Helper method to calculate the correct data format for the doughnut charts
# for track distribution of events.
#
# ====Returns
# * +hash+ -> object_type => {color, value}
def calculate_track_distribution_hash(tracks_grouped, tracks_counter)
result = {}
tracks_grouped.each do |event|
if event.track
result[event.track.name] = {
'value' => tracks_counter[event.track_id],
'color' => event.track.color
}
end
end
result
end
##
# Helper method to calculate the program minutes.
2014-06-16 13:51:43 +02:00
#
# ====Returns
# * +Fixnums+ summed program minutes
def calculate_program_minutes(events_grouped, events_counted)
2014-06-16 13:51:43 +02:00
result = 0
events_grouped.each do |event|
result += events_counted[event.event_type_id] * event.event_type.length
end
result
end
##
# Helper method for calculating hash with corresponding colors of user distribution states.
#
# ====Returns
# * +hash+ -> hash
def self.calculate_user_distribution_hash(active_user, unconfirmed_user, dead_user)
result = {}
if active_user > 0
result['Active'] = {
'color' => 'green',
'value' => active_user
}
end
if unconfirmed_user > 0
result['Unconfirmed'] = {
'color' => 'red',
'value' => unconfirmed_user
}
end
if dead_user > 0
result['Dead'] = {
'color' => 'black',
'value' => dead_user
}
end
result
end
##
# Helper method. Calculates hash with corresponding colors of event state distribution.
#
# ====Returns
# * +hash+ -> hash
def self.calculate_event_distribution_hash(states)
result = {}
states.each do |key, value|
result[key.capitalize] =
{
'value' => value,
'color' => Event.get_state_color(key)
}
end
result
end
##
2014-06-23 19:07:50 +03:00
# Returns a hash with user => submissions ordered by submissions for all conferences
#
# ====Returns
2014-06-23 19:07:50 +03:00
# * +hash+ -> user: submissions
def self.calculate_user_submission_hash(submitters, counter)
result = ActiveSupport::OrderedHash.new
counter.each do |key, value|
2014-06-23 19:07:50 +03:00
submitter = submitters.where(user_id: key).first
if submitter
2014-06-23 19:07:50 +03:00
result[submitter.user] = value
end
end
result
end
2014-04-08 21:02:10 +02:00
##
# Creates a EmailSettings association proxy. Used as before_create.
#
2013-01-14 08:49:49 +01:00
def create_email_settings
build_email_settings
true
end
2014-04-08 21:02:10 +02:00
##
# Creates a UID for the conference. Used as before_create.
#
2013-01-07 09:04:09 +01:00
def generate_guid
2014-06-23 19:07:50 +03:00
guid = SecureRandom.urlsafe_base64
# begin
# guid = SecureRandom.urlsafe_base64
2014-06-24 12:14:53 +03:00
# end while User.where(:guid => guid).exists?
2013-01-07 09:04:09 +01:00
self.guid = guid
end
##
# Adds a random color to the conference
#
def add_color
if !color
2014-06-16 13:51:43 +02:00
self.color = get_color
end
end
def get_color
%w(
#000000 #0000FF #00FF00 #FF0000 #FFFF00 #9900CC
#CC0066 #00FFFF #FF00FF #C0C0C0 #00008B #FFD700
#FFA500 #FF1493 #FF00FF #F0FFFF #EE82EE #D2691E
#C0C0C0 #A52A2A #9ACD32 #9400D3 #8B008B #8B0000
#87CEEB #808080 #800080 #008B8B #006400
).sample
end
# Calculates items per week from a hash.
#
# ====Returns
# * +Array+ -> e.g. [1, 3, 3, 5] -> first week 1, second week 2 registrations
def calculate_items_per_week(start_week, weeks, items)
sum = 0
result = []
last_key = start_week - 1
if !items.empty? && start_week > items.keys[0].to_i
start_week = items.keys[0].to_i
weeks += start_week - items.keys[0].to_i + 1
end
items.each do |key, value|
# Padding
if last_key < (key.to_i - 1)
result += Array.new(key.to_i - last_key - 1, sum)
end
sum += value
result.push(sum)
last_key = key.to_i
end
# Padding right
if result.length < weeks
result += Array.new(weeks - result.length, sum)
end
result
end
end