2014-08-10 19:57:46 +03:00
class Conference < ActiveRecord :: Base
validates :title , presence : true , uniqueness : true
validates :email , presence : true , format : { with : / \ A[^@]+@[^@]+ \ z / }
validates :description , presence : true
2016-07-05 18:35:11 +03:00
validates :planned_cfp_end_date , presence : true
2014-08-10 19:57:46 +03:00
validates :start_date , presence : true
validates :end_date , presence : true
2014-11-04 21:16:06 +02:00
validate :start_date_is_before_end_date
2016-07-05 18:35:11 +03:00
validate :planned_cfp_end_date_is_before_start_date
2014-08-10 19:57:46 +03:00
2014-09-01 13:44:41 +03:00
translates :title , :description
2014-11-04 23:02:28 +02:00
has_many :tracks
has_many :halls
2015-07-19 20:01:52 +03:00
has_many :event_types
2015-08-14 23:58:19 +03:00
has_many :events
2016-10-13 08:59:22 +03:00
has_many :approved_events ,
- > { joins ( :proposition ) . where ( propositions : { status : Proposition . statuses [ :approved ] } ) } , class_name : 'Event'
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
2015-04-20 18:55:06 +03:00
has_one :call_for_participation , dependent : :destroy
2016-10-09 04:00:52 +03:00
has_many :participants , - > { uniq } , class_name : 'User' , through : :events
2016-10-08 22:40:56 +03:00
has_many :participant_profiles , class_name : 'PersonalProfile'
2015-10-17 19:34:17 +03:00
has_many :slots , through : :halls
2014-08-10 20:30:37 +03:00
2015-09-01 11:09:26 +03:00
accepts_nested_attributes_for :tracks , :halls , :event_types , :volunteer_teams ,
reject_if : :all_blank , allow_destroy : true
2014-10-14 18:27:28 +03:00
2015-05-23 18:47:08 +03:00
after_create :create_call_for_participation
2015-04-20 19:11:39 +03:00
def submissions_grouped_by_day
2015-08-10 21:18:12 +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
2015-10-22 00:04:38 +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?
2016-10-11 03:51:19 +03:00
vote_data_updated_at . present? and number_of_ballots_cast > 0
2016-10-11 01:52:19 +03:00
end
2016-10-11 02:33:39 +03:00
def has_voting_endpoint?
vote_data_endpoint . present?
end
2016-10-13 08:59:22 +03:00
def update_conflict_data!
update_vote_data! or raise ActiveRecord :: Rollback
events . all? { | event | event . update_conflict_data ( false ) } or raise ActiveRecord :: Rollback
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
2014-08-10 19:57:46 +03:00
private
2016-07-05 18:35:11 +03:00
def planned_cfp_end_date_is_before_start_date
if planned_cfp_end_date . present? and start_date . present? and planned_cfp_end_date > start_date
errors . add ( :planned_cfp_end_date , :cannot_be_after_start_date )
end
end
2014-11-04 21:16:06 +02:00
def start_date_is_before_end_date
2014-08-10 19:57:46 +03:00
if start_date . present? and end_date . present? and 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
@number_of_ballots || = remote_summary_data [ 'number_of_ballots' ]
end
def ranking
@ranking || = remote_summary_data [ 'ranking' ] . map { | ranking_entry | EventRanking . new ranking_entry }
end
2016-10-13 08:59:22 +03:00
def conflicts
@conflicts || = remote_summary_data [ 'conflicts' ] . map { | conflicts_entry | ConflictsForEvent . new conflicts_entry }
end
2016-10-11 01:52:19 +03:00
def save
conference . transaction do
2016-10-11 03:51:19 +03:00
conference . number_of_ballots_cast = number_of_ballots
2016-10-13 08:59:22 +03:00
conflicts . all? ( & :save ) or raise ActiveRecord :: Rollback
2016-10-11 01:52:19 +03:00
ranking . all? ( & :save ) or raise ActiveRecord :: Rollback
conference . touch :vote_data_updated_at
conference . save or raise ActiveRecord :: Rollback
end
end
private
2016-10-11 02:33:39 +03:00
def connection
@connection || = Faraday . new ( url : conference . vote_data_endpoint + '/summary.json' ,
2016-10-11 01:52:19 +03:00
headers : { 'Content-Type' = > 'application/json' } )
end
def remote_summary_data
2016-10-11 02:33:39 +03:00
@remote_summary_data || = JSON . parse ( connection . get do | request |
2016-10-11 03:23:24 +03:00
request . body = { summary : { talk_ids : conference . events . pluck ( :id ) } } . to_json
2016-10-11 01:52:19 +03:00
end . body )
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 )
@event . conflict_counts . destroy_all or raise ActiveRecord :: Rollback
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
end or raise ActiveRecord :: Rollback
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
2014-08-10 19:57:46 +03:00
end