clarion/app/models/conference.rb

156 lines
5.3 KiB
Ruby
Raw Normal View History

class Conference < ActiveRecord::Base
validates :title, presence: true, uniqueness: true
validates :email, presence: true, format: {with: /\A[^@]+@[^@]+\z/}
validates :description, presence: true
validates :planned_cfp_end_date, presence: true
validates :start_date, presence: true
validates :end_date, presence: true
validate :start_date_is_before_end_date
validate :planned_cfp_end_date_is_before_start_date
2014-09-01 13:44:41 +03:00
translates :title, :description
has_many :tracks
has_many :halls
has_many :event_types
2015-08-14 23:58:19 +03:00
has_many :events
2019-04-28 21:10:54 +03:00
has_many :approved_events, -> { joins(:proposition).approved }, class_name: "Event"
2016-10-13 08:59:22 +03:00
has_many :conflict_counts, through: :events
2015-09-01 11:09:26 +03:00
has_many :volunteer_teams
2015-10-21 23:13:39 +03:00
has_many :volunteers
has_one :call_for_participation
2019-04-28 21:10:54 +03:00
has_many :participants, -> { distinct }, class_name: "User", through: :events
has_many :participant_profiles, class_name: "PersonalProfile"
2015-10-17 19:34:17 +03:00
has_many :slots, through: :halls
has_many :feedbacks, as: :feedback_receiving
2019-04-28 21:10:54 +03:00
has_many :editions, primary_key: :host_name, foreign_key: :host_name, class_name: "Conference"
has_many :events_of_all_editions, through: :editions, source: :events
2015-09-01 11:09:26 +03:00
accepts_nested_attributes_for :tracks, :halls, :event_types, :volunteer_teams,
2019-04-28 21:10:54 +03:00
reject_if: :all_blank, allow_destroy: true
2014-10-14 18:27:28 +03:00
after_create :create_call_for_participation
2015-04-20 19:11:39 +03:00
def submissions_grouped_by_day
2019-04-28 21:10:54 +03:00
submissions = events.group("date(events.created_at)").select("date(events.created_at) as created_at, count(events.id) as number")
2015-04-20 19:11:39 +03:00
submissions.group_by { |s| s.created_at.to_date }
end
def submissions_grouped_by_confirmation_day
2019-04-28 21:10:54 +03:00
submissions = events.joins(:proposition).approved.confirmed.group("date(propositions.confirmed_at)").select("date(propositions.confirmed_at) as confirmed_at, count(events.id) as number")
2015-04-20 19:11:39 +03:00
submissions.group_by { |s| s.confirmed_at.to_date }
end
2016-10-11 01:52:19 +03:00
def update_vote_data!
ConferenceVoteSummary.new(conference: self).save
end
def has_vote_results?
2019-04-28 21:10:54 +03:00
vote_data_updated_at.present? && (number_of_ballots_cast > 0)
2016-10-11 01:52:19 +03:00
end
def has_voting_endpoint?
vote_data_endpoint.present?
end
2016-10-13 08:59:22 +03:00
def update_conflict_data!
2019-04-28 21:10:54 +03:00
update_vote_data! || raise(ActiveRecord::Rollback)
events.all? { |event| event.update_conflict_data(false) } || raise(ActiveRecord::Rollback)
2016-10-13 08:59:22 +03:00
end
def most_conflicts
conflict_counts.order(number_of_conflicts: :desc).first.try(:number_of_conflicts) || 0
end
def least_conflicts
conflict_counts.unscoped.order(number_of_conflicts: :asc).first.try(:number_of_conflicts) || 0
end
def most_conflicts_between_approved_events
conflict_counts.unscoped.where(left: approved_events, right: approved_events).order(number_of_conflicts: :desc).first.try(:number_of_conflicts) || 0
end
def least_conflicts_between_approved_events
conflict_counts.unscoped.where(left: approved_events, right: approved_events).order(number_of_conflicts: :asc).first.try(:number_of_conflicts) || 0
end
private
def planned_cfp_end_date_is_before_start_date
2019-04-28 21:10:54 +03:00
if planned_cfp_end_date.present? && start_date.present? && (planned_cfp_end_date > start_date)
errors.add(:planned_cfp_end_date, :cannot_be_after_start_date)
end
end
def start_date_is_before_end_date
2019-04-28 21:10:54 +03:00
if start_date.present? && end_date.present? && (start_date > end_date)
errors.add(:end_date, :cannot_be_before_start_date)
end
end
2016-10-11 01:52:19 +03:00
class ConferenceVoteSummary
include ActiveModel::Model
attr_accessor :conference
def number_of_ballots
2019-04-28 21:10:54 +03:00
@number_of_ballots ||= remote_summary_data["number_of_ballots"]
2016-10-11 01:52:19 +03:00
end
def ranking
2019-04-28 21:10:54 +03:00
@ranking ||= remote_summary_data["ranking"].map { |ranking_entry| EventRanking.new ranking_entry }
2016-10-11 01:52:19 +03:00
end
2016-10-13 08:59:22 +03:00
def conflicts
2019-04-28 21:10:54 +03:00
@conflicts ||= remote_summary_data["conflicts"].map { |conflicts_entry| ConflictsForEvent.new conflicts_entry }
2016-10-13 08:59:22 +03:00
end
2016-10-11 01:52:19 +03:00
def save
conference.transaction do
conference.number_of_ballots_cast = number_of_ballots
2019-04-28 21:10:54 +03:00
conflicts.all?(&:save) || raise(ActiveRecord::Rollback)
ranking.all?(&:save) || raise(ActiveRecord::Rollback)
2016-10-11 01:52:19 +03:00
conference.touch :vote_data_updated_at
2019-04-28 21:10:54 +03:00
conference.save || raise(ActiveRecord::Rollback)
2016-10-11 01:52:19 +03:00
end
end
private
def connection
2019-04-28 21:10:54 +03:00
@connection ||= Faraday.new(url: conference.vote_data_endpoint + "/summary.json",
headers: {"Content-Type" => "application/json"})
2016-10-11 01:52:19 +03:00
end
def remote_summary_data
2019-04-28 21:10:54 +03:00
@remote_summary_data ||= JSON.parse(connection.get { |request|
request.body = {summary: {talk_ids: conference.events.pluck(:id)}}.to_json
2019-04-28 21:10:54 +03:00
}.body)
2016-10-11 01:52:19 +03:00
end
2016-10-13 08:59:22 +03:00
class ConflictsForEvent
include ActiveModel::Model
attr_accessor :talk_id, :conflicts
def save
@event = Event.find(talk_id)
2019-04-28 21:10:54 +03:00
@event.conflict_counts.destroy_all || raise(ActiveRecord::Rollback)
2016-10-13 08:59:22 +03:00
conflicts.all? do |right_event_id, number_of_conflicts|
ConflictCount.create left_id: talk_id, right_id: right_event_id, number_of_conflicts: number_of_conflicts
2019-04-28 21:10:54 +03:00
end || raise(ActiveRecord::Rollback)
2016-10-13 08:59:22 +03:00
end
end
2016-10-11 01:52:19 +03:00
class EventRanking
include ActiveModel::Model
attr_accessor :talk_id, :votes, :place
def save
2016-10-13 08:59:22 +03:00
Event.where(id: talk_id).update_all(number_of_votes: votes, rank: place)
2016-10-11 01:52:19 +03:00
end
end
end
end