Merge master
This commit is contained in:
commit
7586112f72
217 changed files with 2853 additions and 3035 deletions
BIN
app/models/.lodging.rb.swp
Normal file
BIN
app/models/.lodging.rb.swp
Normal file
Binary file not shown.
|
|
@ -31,10 +31,23 @@ class Ability
|
|||
event.state == 'confirmed'
|
||||
end
|
||||
|
||||
can [:show, :events, :app], Schedule do |schedule|
|
||||
schedule.program.schedule_public
|
||||
end
|
||||
|
||||
# can view Commercials of confirmed Events
|
||||
can :show, Commercial, commercialable_type: 'Event', commercialable_id: Event.where(state: 'confirmed').pluck(:id)
|
||||
can :show, Commercial, commercialable: Event.where(state: 'confirmed')
|
||||
can [:show, :create], User
|
||||
unless ENV['OSEM_ICHAIN_ENABLED'] == 'true'
|
||||
|
||||
can [:index, :show], Survey, surveyable_type: 'Conference'
|
||||
|
||||
# Things that are possible without ichain enabled that are **not*+ possible with ichain mode enabled.
|
||||
if ENV['OSEM_ICHAIN_ENABLED'] != 'true'
|
||||
# There is no reliable way for this workflow (enable not logged in users to fill out a form, then telling
|
||||
# them to sign up once they submit) in ichain. So enable it only without ichain.
|
||||
|
||||
# FIXME: The following abilities need to be checked. Are they about the type of workflow mentioned above? Or are
|
||||
# they just here because they worked in development mode (without ichain). We are suspicious that it's the latter!
|
||||
can :show, Registration do |registration|
|
||||
registration.new_record?
|
||||
end
|
||||
|
|
@ -51,12 +64,6 @@ class Ability
|
|||
can [:new, :create], Event do |event|
|
||||
event.program.cfp_open? && event.new_record?
|
||||
end
|
||||
|
||||
can [:show, :events], Schedule do |schedule|
|
||||
schedule.program.schedule_public
|
||||
end
|
||||
|
||||
can [:index, :show], Survey, surveyable_type: 'Conference'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -117,10 +117,7 @@ class AdminAbility
|
|||
can :manage, Commercial, commercialable_type: 'Conference',
|
||||
commercialable_id: conf_ids
|
||||
can :manage, Registration, conference_id: conf_ids
|
||||
can :manage, RegistrationPeriod do |registration_period|
|
||||
conference = registration_period.conference
|
||||
conf_ids.include?(conference.id) && conference.tickets.for_registration.any?
|
||||
end
|
||||
can :manage, RegistrationPeriod, conference_id: conf_ids
|
||||
can :manage, Booth, conference_id: conf_ids
|
||||
can :manage, Question, conference_id: conf_ids
|
||||
can :manage, Question do |question|
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class Cfp < ApplicationRecord
|
|||
in: TYPES
|
||||
},
|
||||
uniqueness: {
|
||||
scope: :program,
|
||||
scope: :program_id,
|
||||
case_sensitive: false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,11 +29,7 @@ class Conference < ApplicationRecord
|
|||
has_many :ticket_purchases, dependent: :destroy
|
||||
has_many :payments, dependent: :destroy
|
||||
has_many :supporters, through: :ticket_purchases, source: :user
|
||||
has_many :tickets, dependent: :destroy do
|
||||
def for_registration
|
||||
where(registration_ticket: true)
|
||||
end
|
||||
end
|
||||
has_many :tickets, dependent: :destroy
|
||||
has_many :resources, dependent: :destroy
|
||||
has_many :booths, dependent: :destroy
|
||||
has_many :confirmed_booths, -> { where(state: 'confirmed') }, class_name: 'Booth'
|
||||
|
|
@ -84,7 +80,8 @@ class Conference < ApplicationRecord
|
|||
:start_hour,
|
||||
:end_hour,
|
||||
:ticket_layout,
|
||||
:organization, presence: true
|
||||
:organization,
|
||||
:timezone, presence: true
|
||||
|
||||
validates :short_title, uniqueness: true
|
||||
validates :short_title, format: { with: /\A[a-zA-Z0-9_-]*\z/ }
|
||||
|
|
@ -118,7 +115,7 @@ class Conference < ApplicationRecord
|
|||
# Delete all EventSchedules that are not in the hours range
|
||||
# After the conference has been successfully updated
|
||||
def delete_event_schedules
|
||||
if start_hour_changed? || end_hour_changed?
|
||||
if saved_change_to_start_hour? || saved_change_to_end_hour?
|
||||
event_schedules = program.event_schedules.select do |event_schedule|
|
||||
event_schedule.start_time.hour < start_hour ||
|
||||
event_schedule.end_time.hour > end_hour ||
|
||||
|
|
@ -176,24 +173,22 @@ class Conference < ApplicationRecord
|
|||
# ====Returns
|
||||
# * +Array+ -> e.g. 'Submitted' => [0, 3, 3, 5] -> first week 0 events, second week 3 events.
|
||||
def get_submissions_data
|
||||
result = {}
|
||||
if program&.cfp && program&.events
|
||||
result = get_events_per_week_by_state
|
||||
return [] unless program&.cfp && program&.events
|
||||
|
||||
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
|
||||
start_week = program.cfp.start_week
|
||||
get_events_per_week_by_state.collect do |state, values|
|
||||
if state == 'Submitted'
|
||||
{
|
||||
name: 'Submitted',
|
||||
data: add_week_indices(pad_array_left_kumulative(start_week, values))
|
||||
}
|
||||
else
|
||||
{
|
||||
name: state,
|
||||
data: add_week_indices(pad_array_left_not_kumulative(start_week, values))
|
||||
}
|
||||
end
|
||||
result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -202,19 +197,15 @@ class Conference < ApplicationRecord
|
|||
# ====Returns
|
||||
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 registrations
|
||||
def get_registrations_per_week
|
||||
result = []
|
||||
return [] unless registrations &&
|
||||
registration_period &&
|
||||
registration_period.start_date &&
|
||||
registration_period.end_date
|
||||
|
||||
if registrations &&
|
||||
registration_period &&
|
||||
registration_period.start_date &&
|
||||
registration_period.end_date
|
||||
|
||||
reg = registrations.group(:week).order(:week).count
|
||||
start_week = get_registration_start_week
|
||||
weeks = registration_weeks
|
||||
result = calculate_items_per_week(start_week, weeks, reg)
|
||||
end
|
||||
result
|
||||
reg = registrations.group(:week).order(:week).count
|
||||
start_week = get_registration_start_week
|
||||
weeks = registration_weeks
|
||||
calculate_items_per_week(start_week, weeks, reg)
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -223,15 +214,12 @@ class Conference < ApplicationRecord
|
|||
# ====Returns
|
||||
# * +Array+ -> e.g. [0, 3, 3, 5] -> first week 0, second week 3 tickets sold
|
||||
def get_tickets_sold_per_week
|
||||
result = []
|
||||
return [] unless tickets && ticket_purchases && registration_period
|
||||
|
||||
if tickets && ticket_purchases && registration_period
|
||||
tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity)
|
||||
start_week = get_registration_start_week
|
||||
weeks = registration_weeks
|
||||
result = calculate_items_per_week(start_week, weeks, tickets_sold)
|
||||
end
|
||||
result
|
||||
tickets_sold = ticket_purchases.paid.group(:week).sum(:quantity)
|
||||
start_week = get_registration_start_week
|
||||
weeks = registration_weeks
|
||||
calculate_items_per_week(start_week, weeks, tickets_sold)
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -241,33 +229,32 @@ class Conference < ApplicationRecord
|
|||
# ====Returns
|
||||
# * +Array+ -> e.g. 'Free Access' => [0, 3, 3, 5] -> first week 0 tickets sold, second week 3 tickets sold.
|
||||
def get_tickets_data
|
||||
result = {}
|
||||
if tickets && ticket_purchases && registration_period
|
||||
tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity)
|
||||
return [] unless tickets && ticket_purchases && registration_period
|
||||
|
||||
start_week = get_registration_start_week
|
||||
weeks = registration_weeks
|
||||
tickets_per_ticket_id_and_week = ticket_purchases.paid.group(:ticket_id, :week).sum(:quantity)
|
||||
|
||||
tickets_by_id_per_week = {}
|
||||
start_week = get_registration_start_week
|
||||
weeks = registration_weeks
|
||||
|
||||
tickets.each do |ticket|
|
||||
tickets_by_id_per_week[ticket.id] = {}
|
||||
(start_week...(start_week + weeks)).each do |week|
|
||||
tickets_by_id_per_week[ticket.id][week] = 0
|
||||
end
|
||||
tickets_by_id_per_week = {}
|
||||
|
||||
tickets.each do |ticket|
|
||||
tickets_by_id_per_week[ticket.id] = {}
|
||||
(start_week...(start_week + weeks)).each do |week|
|
||||
tickets_by_id_per_week[ticket.id][week] = 0
|
||||
end
|
||||
|
||||
tickets_per_ticket_id_and_week.each do |ticket_week, value|
|
||||
tickets_by_id_per_week[ticket_week[0]][ticket_week[1]] = value
|
||||
end
|
||||
|
||||
tickets_by_id_per_week.each do |ticket, values|
|
||||
result[Ticket.find(ticket).title] = pad_array_left_not_kumulative(start_week, values)
|
||||
end
|
||||
|
||||
result['Weeks'] = weeks > 0 ? (1..weeks).to_a : 0
|
||||
end
|
||||
result
|
||||
|
||||
tickets_per_ticket_id_and_week.each do |ticket_week, value|
|
||||
tickets_by_id_per_week[ticket_week[0]][ticket_week[1]] = value
|
||||
end
|
||||
|
||||
tickets_by_id_per_week.collect do |ticket, values|
|
||||
{
|
||||
name: Ticket.find(ticket).title,
|
||||
data: add_week_indices(pad_array_left_not_kumulative(start_week, values))
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -400,7 +387,9 @@ class Conference < ApplicationRecord
|
|||
# ====Returns
|
||||
# * +hash+ -> hash
|
||||
def event_distribution
|
||||
Conference.calculate_event_distribution_hash(program.events.select(:state).group(:state).count)
|
||||
Conference.calculate_event_distribution_hash(
|
||||
program.events.select(:state).group(:state).count
|
||||
)
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -465,22 +454,6 @@ class Conference < ApplicationRecord
|
|||
result
|
||||
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
|
||||
|
||||
##
|
||||
# Returns a hash with per ticket sales => { "Title" => { value: number of tickets sold,
|
||||
# color: generated from the title using a hash function }, ...}
|
||||
|
|
@ -669,7 +642,7 @@ class Conference < ApplicationRecord
|
|||
def notify_on_dates_changed?
|
||||
return false unless email_settings.send_on_conference_dates_updated
|
||||
# do not notify unless one of the dates changed
|
||||
return false unless start_date_changed? || end_date_changed?
|
||||
return false unless saved_change_to_start_date? || saved_change_to_end_date?
|
||||
|
||||
# do not notify unless the mail content is set up
|
||||
(email_settings.conference_dates_updated_subject.present? && email_settings.conference_dates_updated_body.present?)
|
||||
|
|
@ -686,7 +659,7 @@ class Conference < ApplicationRecord
|
|||
# do not notify unless we allow a registration
|
||||
return false unless registration_period
|
||||
# do not notify unless one of the dates changed
|
||||
return false unless registration_period.start_date_changed? || registration_period.end_date_changed?
|
||||
return false unless registration_period.saved_change_to_start_date? || registration_period.saved_change_to_end_date?
|
||||
|
||||
# do not notify unless the mail content is set up
|
||||
(email_settings.conference_registration_dates_updated_subject.present? && email_settings.conference_registration_dates_updated_body.present?)
|
||||
|
|
@ -1110,20 +1083,19 @@ class Conference < ApplicationRecord
|
|||
end
|
||||
|
||||
##
|
||||
# Helper method. Calculates hash with corresponding colors of event state distribution.
|
||||
# Helper method. Calculates hash of all event states in a consistent order.
|
||||
#
|
||||
# ====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
|
||||
def self.calculate_event_distribution_hash(counts)
|
||||
return {} if counts.values.sum == 0
|
||||
|
||||
Hash[
|
||||
Event.state_machine.states.collect do |state|
|
||||
state_name = state.name.to_s
|
||||
[state_name.capitalize, counts[state_name] || 0]
|
||||
end
|
||||
]
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -1148,7 +1120,6 @@ class Conference < ApplicationRecord
|
|||
#
|
||||
def create_email_settings
|
||||
build_email_settings
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -1211,6 +1182,12 @@ class Conference < ApplicationRecord
|
|||
result += Array.new(weeks - result.length, sum)
|
||||
end
|
||||
|
||||
result
|
||||
add_week_indices(result)
|
||||
end
|
||||
|
||||
def add_week_indices(values)
|
||||
Hash[
|
||||
values.collect.with_index { |value, index| ["Wk #{index + 1}", value] }
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ class Event < ApplicationRecord
|
|||
validates :abstract, presence: true
|
||||
validates :event_type, presence: true
|
||||
validates :program, presence: true
|
||||
validates :speakers, presence: true
|
||||
validates :max_attendees, numericality: { only_integer: true, greater_than_or_equal_to: 1, allow_nil: true }
|
||||
|
||||
validate :max_attendees_no_more_than_room_size
|
||||
|
|
@ -83,6 +82,15 @@ class Event < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
COLORS = {
|
||||
new: '#0000FF', # blue
|
||||
withdrawn: '#FF8000', # orange
|
||||
unconfirmed: '#FFFF00', # yellow
|
||||
confirmed: '#00FF00', # green
|
||||
canceled: '#848484', # grey
|
||||
rejected: '#FF0000' # red
|
||||
}.freeze
|
||||
|
||||
##
|
||||
# Checkes if the event has a start_time and a room for the selected schedule if there is any
|
||||
# ====Returns
|
||||
|
|
@ -176,16 +184,7 @@ class Event < ApplicationRecord
|
|||
end
|
||||
|
||||
def self.get_state_color(state)
|
||||
color = {
|
||||
new: '#0000FF', # blue
|
||||
withdrawn: '#FF8000', # orange
|
||||
confirmed: '#00FF00', # green
|
||||
unconfirmed: '#FFFF00', # yellow
|
||||
rejected: '#FF0000', # red
|
||||
canceled: '#848484' # grey
|
||||
}[state.to_sym]
|
||||
|
||||
color || '#00FFFF' # azure
|
||||
COLORS[state.to_sym] || '#00FFFF' # azure
|
||||
end
|
||||
|
||||
def update_state(transition, mail = false, subject = false, send_mail = false, send_mail_param)
|
||||
|
|
|
|||
|
|
@ -72,8 +72,8 @@ class Program < ApplicationRecord
|
|||
|
||||
after_create :create_event_types
|
||||
after_create :create_difficulty_levels
|
||||
after_save :unschedule_unfit_events, if: :schedule_interval_changed?
|
||||
after_save :normalize_event_types_length, if: :schedule_interval_changed?
|
||||
after_save :unschedule_unfit_events, if: :saved_change_to_schedule_interval?
|
||||
after_save :normalize_event_types_length, if: :saved_change_to_schedule_interval?
|
||||
validate :check_languages_format
|
||||
|
||||
# Returns all event_schedules for the selected schedule ordered by start_time
|
||||
|
|
@ -211,7 +211,6 @@ class Program < ApplicationRecord
|
|||
EventType.create(title: 'Workshop', length: 60, color: '#0000FF', description: 'Interactive hands-on practice',
|
||||
minimum_abstract_length: 0,
|
||||
maximum_abstract_length: 500, program_id: id)
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
|
|
@ -227,7 +226,6 @@ class Program < ApplicationRecord
|
|||
DifficultyLevel.create(title: 'Hard',
|
||||
description: 'Events require expert knowledge of the topic.',
|
||||
color: '#EF6E69', program_id: id)
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class Registration < ApplicationRecord
|
|||
validate :registration_to_events_only_if_present
|
||||
|
||||
validates :accepted_code_of_conduct, acceptance: {
|
||||
if: -> { conference.code_of_conduct.present? }
|
||||
if: -> { conference.try(:code_of_conduct).present? }
|
||||
}
|
||||
|
||||
after_create :set_week, :subscribe_to_conference, :send_registration_mail
|
||||
|
|
@ -76,7 +76,7 @@ class Registration < ApplicationRecord
|
|||
end
|
||||
|
||||
def registration_limit_not_exceed
|
||||
if conference.registration_limit > 0 && conference.registrations(:reload).count >= conference.registration_limit
|
||||
if conference.registration_limit > 0 && conference.registrations.count >= conference.registration_limit
|
||||
errors.add(:base, 'Registration limit exceeded')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -18,6 +18,6 @@ class Role < ApplicationRecord
|
|||
|
||||
# Needed to ensure that removing all user from role doesn't remove role.
|
||||
def cancel
|
||||
false
|
||||
throw(:abort)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class SurveyQuestion < ActiveRecord::Base
|
|||
ICONS = { boolean: 'dot-circle-o', choice: 'check-square-o', string: 'edit', text: 'align-left', datetime: 'clock-o', numeric: 'slack' }.freeze
|
||||
|
||||
validates :title, presence: true
|
||||
validates :possible_answers, :max_choices, :min_choices, presence: true, if: 'choice?'
|
||||
validates :possible_answers, :max_choices, :min_choices, presence: true, if: :choice?
|
||||
validates :min_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true
|
||||
validates :max_choices, numericality: { greater_than_or_equal_to: 1 }, allow_blank: true
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ class Ticket < ApplicationRecord
|
|||
|
||||
monetize :price_cents, with_model_currency: :price_currency
|
||||
|
||||
scope :for_registration, -> { where(registration_ticket: true) }
|
||||
|
||||
# This validation is for the sake of simplicity.
|
||||
# If we would allow different currencies per conference we also have to handle convertions between currencies!
|
||||
validate :tickets_of_conference_have_same_currency
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class Track < ApplicationRecord
|
|||
scope :cfp_active, -> { where(cfp_active: true) }
|
||||
scope :self_organized, -> { where.not(submitter: nil) }
|
||||
|
||||
state_machine initial: :pending do
|
||||
state_machine initial: :new do
|
||||
state :new
|
||||
state :to_accept
|
||||
state :accepted
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ class User < ApplicationRecord
|
|||
# prevent N+1 queries with has_cached_role? by preloading roles *always*
|
||||
default_scope { preload(:roles) }
|
||||
|
||||
has_many :ticket_purchases, dependent: :destroy
|
||||
has_many :physical_tickets, through: :ticket_purchases do
|
||||
def by_conference(conference)
|
||||
where('ticket_purchases.conference_id = ?', conference)
|
||||
|
|
@ -32,6 +33,13 @@ class User < ApplicationRecord
|
|||
# add scope
|
||||
scope :comment_notifiable, ->(conference) {joins(:roles).where('roles.name IN (?)', [:organizer, :cfp]).where('roles.resource_type = ? AND roles.resource_id = ?', 'Conference', conference.id)}
|
||||
|
||||
# scopes for user distributions
|
||||
scope :recent, lambda {
|
||||
where('last_sign_in_at > ?', Date.today - 3.months).where(is_disabled: false)
|
||||
}
|
||||
scope :unconfirmed, -> { where('confirmed_at IS NULL') }
|
||||
scope :dead, -> { where('last_sign_in_at < ?', Date.today - 1.year) }
|
||||
|
||||
# Include default devise modules. Others available are:
|
||||
# :token_authenticatable, :confirmable,
|
||||
# :lockable, :timeoutable and :omniauthable
|
||||
|
|
@ -60,7 +68,6 @@ class User < ApplicationRecord
|
|||
end
|
||||
end
|
||||
has_many :events_registrations, through: :registrations
|
||||
has_many :ticket_purchases, dependent: :destroy
|
||||
has_many :payments, dependent: :destroy
|
||||
has_many :tickets, through: :ticket_purchases, source: :ticket do
|
||||
def for_registration conference
|
||||
|
|
@ -79,7 +86,9 @@ class User < ApplicationRecord
|
|||
accepts_nested_attributes_for :roles
|
||||
|
||||
scope :admin, -> { where(is_admin: true) }
|
||||
scope :active, -> { where(is_disabled: false) }
|
||||
scope :active, lambda {
|
||||
where(is_disabled: false)
|
||||
}
|
||||
|
||||
validates :email, presence: true
|
||||
|
||||
|
|
@ -91,6 +100,12 @@ class User < ApplicationRecord
|
|||
|
||||
validate :biography_limit
|
||||
|
||||
DISTRIBUTION_COLORS = {
|
||||
'Active' => 'green',
|
||||
'Unconfirmed' => 'red',
|
||||
'Dead' => 'black'
|
||||
}.freeze
|
||||
|
||||
##
|
||||
# Checkes if the user attended the event
|
||||
# This is used for events that require registration
|
||||
|
|
@ -152,6 +167,22 @@ class User < ApplicationRecord
|
|||
user
|
||||
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.distribution
|
||||
{
|
||||
'Active' => User.recent.count,
|
||||
'Unconfirmed' => User.unconfirmed.count,
|
||||
'Dead' => User.dead.count
|
||||
}
|
||||
end
|
||||
|
||||
def self.find_for_database_authentication(warden_conditions)
|
||||
conditions = warden_conditions.dup
|
||||
login = conditions.delete(:login)
|
||||
|
|
@ -237,12 +268,14 @@ class User < ApplicationRecord
|
|||
proposals(conference).count
|
||||
end
|
||||
|
||||
def self.empty?
|
||||
User.count == 1 && User.first.email == 'deleted@localhost.osem'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def setup_role
|
||||
if User.count == 1 && User.first.email == 'deleted@localhost.osem'
|
||||
self.is_admin = true
|
||||
end
|
||||
self.is_admin = true if User.empty?
|
||||
end
|
||||
|
||||
def touch_events
|
||||
|
|
@ -257,4 +290,8 @@ class User < ApplicationRecord
|
|||
errors.add(:biography, 'is limited to 150 words.') if biography.split.length > 150
|
||||
end
|
||||
end
|
||||
|
||||
def send_devise_notification(notification, *args)
|
||||
devise_mailer.send(notification, self, *args).deliver_later
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class Venue < ApplicationRecord
|
|||
def notify_on_venue_changed?
|
||||
return false unless conference.try(:email_settings).try(:send_on_venue_updated)
|
||||
# do not notify unless the address changed
|
||||
return false unless name_changed? || street_changed? || city_changed? || country_changed?
|
||||
return false unless saved_change_to_name? || saved_change_to_street? || saved_change_to_city? || saved_change_to_country?
|
||||
|
||||
# do not notify unless the mail content is set up
|
||||
(!conference.email_settings.venue_updated_subject.blank? && !conference.email_settings.venue_updated_body.blank?)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue