diff --git a/.rubocop.yml b/.rubocop.yml index 235aa49a..4eaad6ea 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -108,6 +108,21 @@ Style/BracesAroundHashParameters: Style/CaseEquality: Enabled: true +Style/ClassAndModuleChildren: + Enabled: true + +# Offense count: 577 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +Style/StringLiterals: + Enabled: false + +Style/TrailingBlankLines: + Enabled: true + +Style/TrailingWhitespace: + Enabled: true + AllCops: Include: - '**/Rakefile' @@ -115,3 +130,4 @@ AllCops: Exclude: - 'db/schema.rb' - 'vendor/bundle/**/*' + - 'bundle/**/*' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 5cb90241..9624f5f8 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -5,11 +5,6 @@ # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 20 -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/ClassAndModuleChildren: - Enabled: true - # Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. @@ -258,32 +253,15 @@ Style/SpaceInsideBrackets: Style/SpaceInsideHashLiteralBraces: Enabled: false -# Offense count: 577 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/StringLiterals: - Enabled: false - # Offense count: 1 Style/Tab: Enabled: false -# Offense count: 1 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -Style/TrailingBlankLines: - Enabled: false - # Offense count: 24 # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. Style/TrailingComma: Enabled: false -# Offense count: 38 -# Cop supports --auto-correct. -Style/TrailingWhitespace: - Enabled: false - # Offense count: 8 # Cop supports --auto-correct. Style/WordArray: diff --git a/app/controllers/admin/photos_controller.rb b/app/controllers/admin/photos_controller.rb index 14c5dc17..bde977a0 100644 --- a/app/controllers/admin/photos_controller.rb +++ b/app/controllers/admin/photos_controller.rb @@ -51,4 +51,3 @@ module Admin end end end - diff --git a/app/controllers/admin/stats_controller.rb b/app/controllers/admin/stats_controller.rb new file mode 100644 index 00000000..a98d3aab --- /dev/null +++ b/app/controllers/admin/stats_controller.rb @@ -0,0 +1,231 @@ +module Admin + class StatsController < Admin::BaseController + load_and_authorize_resource + load_and_authorize_resource :conference, find_by: :short_title + + def index + @registrations = @conference.registrations.includes(:user) + @registrations = @registrations.order('registrations.created_at ASC') + @registered = @conference.registrations.count + @attendees = @conference.registrations.where('attended = ?', true).count + @pre_registered = @conference.registrations + @pre_registered = @pre_registered.where('created_at < ?', @conference.start_date).count + @pre_registered_attended = @conference.registrations.where('created_at < ? AND attended = ?', + @conference.start_date, true).count + + @registered_with_partner = @conference.registrations.where('attending_with_partner = ?', + true).count + @attended_with_partner = @conference.registrations.where( + 'attending_with_partner = ? AND attended = ?', true, true).count + + @handicapped_access = @conference.registrations.where(handicapped_access_required: true).count + @handicapped_access_attended = @conference.registrations.where(handicapped_access_required: + true) + @handicapped_access_attended = @handicapped_access_attended.where(attended: true).count + @suggested_hotel_stay = @conference.registrations.where('using_affiliated_lodging = ?', + true).count + + @events = @conference.events + # Events charts + @machine_states = [['confirmed'], ['cancelled'], ['rejected'], ['withdrawn'], + ['new', 'review'], ['unconfirmed', 'accepted']] + # Types distribution per state + @type_state = {} + @machine_states.each do |state| + @type_state[state[0]] = var_state_func(@conference.event_types, 'event_type', state) + end + + # Tracks distribution per state + @no_track_all = @events.where(track_id: nil) + @no_track_new = @events.where(track_id: nil).where(state: ['new', 'review']) + @no_track_unconfirmed = @events.where(track_id: nil).where(state: 'unconfirmed') + @no_track_confirmed = @events.where(track_id: nil).where(state: 'confirmed') + @track_state = {} + @machine_states.each do |state| + @track_state[state[0]] = var_state_func(@conference.tracks, 'track', state) + end + + # Events_time chart + if @events.count > 0 + start_date = @events.minimum('created_at').strftime('%Y-%m-%d') + end_date = @events.maximum('created_at').strftime('%Y-%m-%d') + unless start_date.nil? || end_date.nil? + @events_time = var_time(start_date, end_date, @events, 'created_at') + end + end + + # Code for the table in events + @mystates = [] + @mytypes = [] + @eventstats = {} + @totallength = 0 + # Get totals per state + @events.state_machine.states.map.each do |mystate| + length = 0 + events_mystate = @events.where('state' => mystate.name) + if events_mystate.count > 0 + @mystates << mystate + events_mystate.each do |myevent| + length += myevent.event_type.length + end + @eventstats["#{mystate.name}"] = { 'count' => events_mystate.count, 'length' => length } + end + end + + @conference.event_types.each do |mytype| + events_mytype = @events.where('event_type_id' => mytype.id) + if events_mytype.count > 0 + @mytypes << mytype + end + end + @mytypes.each do |mytype| + @mystates.each do |mystate| + events_mytype = @events.where('event_type_id' => mytype.id) + events_mytype_mystate = events_mytype.where('state' => mystate.name) + typelength = 0 + if events_mytype_mystate.count > 0 + events_mytype_mystate.each do |myevent| + typelength += myevent.event_type.length + @totallength += myevent.event_type.length + end + if @eventstats[mytype.title].nil? + @eventstats[mytype.title] = { 'count' => events_mytype.count, + 'length' => events_mytype.count * mytype.length } + end + + tmp = { "#{mystate.name}" => { 'type_state_count' => events_mytype_mystate.count, + 'type_state_length' => typelength } } + @eventstats[mytype.title].merge!(tmp) + end + end + end + @eventstats['totallength'] = @totallength + + # SPEAKERS stats + @speakers = User.joins(:events).where('events.conference_id = ? AND events.state LIKE ?', + @conference.id, 'confirmed').uniq + @speaker_fields_user = %w(name email affiliation) + @speaker_fields_reg = %w(arrival departure) + # TICKETS stats + @supporter_levels = @conference.supporter_levels + @tickets = @conference.registrations.joins(supporter_registration: :supporter_level) + @tickets = @tickets.where('supporter_levels.title NOT LIKE ? ', '%Free%') + + @tickets_time = [] + + if @conference.registration_start_date && @conference.end_date && @registered > 0 && @supporter_levels + start_date = @conference.registration_start_date + end_date = @conference.end_date + levels = [] + @conference.supporter_levels.each do |level| + @tickets_time << { 'key' => level.title, 'values' => [] } + levels << ["#{level.title}"] + end + + (start_date..end_date).each do |day| + if @tickets.where('supporter_registrations.created_at LIKE ?', "%#{day}%").where( + 'supporter_levels.title' => levels).count != 0 + @conference.supporter_levels.each do |level| + + day_ticket_count = @tickets.where('supporter_registrations.created_at LIKE ? + AND supporter_levels.title LIKE ?', + "%#{day}%", "%#{level.title}%").count + + index = @tickets_time.index { |v| v['key'] == "#{level.title}" } + @tickets_time[index]['values'] << { 'label' => "#{day}", 'value' => day_ticket_count } + end + end + end + end + @tickets_distribution = [] + @tickets_time.each do |ticket| + value = ticket['values'].map { |x| x['value'] }.sum + percent = (value.to_f / @tickets.count * 100).round(2) + @tickets_distribution << { 'status' => ticket['key'], + 'value' => value, 'percent' => percent } + end + + # OTHER_INFO chart / To be 'Questions' + @other_info = [ + { 'status' => 'with partner (registered)', 'value' => @registered_with_partner }, + { 'status' => 'with partner (attended)', 'value' => @attended_with_partner }, + { 'status' => 'handicapped (registered)', 'value' => @handicapped_access }, + { 'status' => 'handicapped (attended)', 'value' => @handicapped_access_attended }, + { 'status' => 'stay at suggested hotel', 'value' => @suggested_hotel_stay } + ] + + # REGISTRATIONS, registered_time + if @conference.registration_start_date && @conference.end_date && @registered > 0 + start_date = @conference.registration_start_date + end_date = @conference.end_date + @registered_time = var_time(start_date, end_date, @registrations, 'created_at') + end + + respond_to do |format| + format.html + format.json { render json: @tickets_time.to_json } + end + end + # FUNCTIONS + def var_time(start_date, end_date, var, field) + result = [] + (start_date..end_date).each do |day| + day_var_count = var.where("#{field} LIKE ?", "%#{day}%").count + if day_var_count != 0 + result << { 'status' => "#{day}", 'value' => day_var_count } + end + end + result + end + + def var_state_func(vars, field, mystate) + result = [] + + vars.each do |myvar| + # Find events per track and state + value = @conference.events.where("#{field}_id" => myvar.id).where(state: mystate).count + # Find all events in that state + total = @conference.events.where(state: mystate).count + status = "#{myvar.name}" + + percent = 0 # rubocop:disable Lint/UselessAssignment + if value != 0 + percent = (value.to_f / total * 100).round(2) + result << { 'status' => status, 'value' => value, 'percent' => percent } + end + end + # Get no of events for which the field is not set (So that pie shows half piece for 50%) + sum = result.inject(0) { |s, hash| s + hash['value'] } + value = total - sum + if sum != 0 && value != 0 + percent = (value.to_f / total * 100).round(2) + result << { 'status' => "no #{field} set", 'value' => value, 'percent' => percent } + end + + result + end + + def speaker_reg(speaker) + speaker.registrations.where('conference_id = ? AND user_id = ?', + @conference.id, speaker.id).first + end + + def speaker_diet(reg) + @conference.dietary_choices.find(reg.dietary_choice_id) + end + + def diet_count(diet) + @conference.registrations.where('dietary_choice_id = ?', diet) + end + + def social_event_count(event) + @conference.registrations.joins(:social_events).where( + 'registrations_social_events.social_event_id = ?', event).count + end + + helper_method :speaker_reg + helper_method :speaker_diet + helper_method :diet_count + helper_method :social_event_count + end +end diff --git a/app/models/answer.rb b/app/models/answer.rb index fa0894fd..0a38d33c 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -1,6 +1,6 @@ class Answer < ActiveRecord::Base attr_accessible :title - + has_many :qanswers has_many :questions, through: :qanswers diff --git a/app/models/qanswer.rb b/app/models/qanswer.rb index 3376814d..bcb72da9 100644 --- a/app/models/qanswer.rb +++ b/app/models/qanswer.rb @@ -3,6 +3,6 @@ class Qanswer < ActiveRecord::Base belongs_to :question belongs_to :answer, dependent: :delete - + has_and_belongs_to_many :registrations end diff --git a/app/models/question_type.rb b/app/models/question_type.rb index 1326c5b2..4d349253 100644 --- a/app/models/question_type.rb +++ b/app/models/question_type.rb @@ -1,5 +1,5 @@ class QuestionType < ActiveRecord::Base attr_accessible :title, :description - + has_many :questions end diff --git a/config/environments/test.rb b/config/environments/test.rb index 5fe68d99..df75cb36 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -11,7 +11,7 @@ Osem::Application.configure do config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" - # Do not eager load code on boot. + # Do not eager load code on boot. config.eager_load = false # Show full error reports and disable caching diff --git a/db/migrate/20121223135240_create_roles_table.rb b/db/migrate/20121223135240_create_roles_table.rb index b9417255..2fa3e899 100644 --- a/db/migrate/20121223135240_create_roles_table.rb +++ b/db/migrate/20121223135240_create_roles_table.rb @@ -5,7 +5,7 @@ class CreateRolesTable < ActiveRecord::Migration t.timestamps end end - + def self.down drop_table :roles end diff --git a/db/migrate/20121223135447_user_roles_table.rb b/db/migrate/20121223135447_user_roles_table.rb index 1f23cbb1..459b3172 100644 --- a/db/migrate/20121223135447_user_roles_table.rb +++ b/db/migrate/20121223135447_user_roles_table.rb @@ -4,7 +4,7 @@ class UserRolesTable < ActiveRecord::Migration t.references :role, :user end end - + def self.down drop_table :roles_users end diff --git a/db/migrate/20130104142209_create_comments.rb b/db/migrate/20130104142209_create_comments.rb index f52c0c2b..23abf7f6 100644 --- a/db/migrate/20130104142209_create_comments.rb +++ b/db/migrate/20130104142209_create_comments.rb @@ -1,7 +1,7 @@ class CreateComments < ActiveRecord::Migration def self.up create_table :comments do |t| - t.string :title, limit: 50, default: "" + t.string :title, limit: 50, default: "" t.text :comment t.references :commentable, polymorphic: true t.references :user diff --git a/db/migrate/20130104142839_acts_as_commentable_upgrade_migration.rb b/db/migrate/20130104142839_acts_as_commentable_upgrade_migration.rb index d89ae1f6..d70bee0f 100644 --- a/db/migrate/20130104142839_acts_as_commentable_upgrade_migration.rb +++ b/db/migrate/20130104142839_acts_as_commentable_upgrade_migration.rb @@ -5,15 +5,13 @@ class ActsAsCommentableUpgradeMigration < ActiveRecord::Migration add_column :comments, :parent_id, :integer add_column :comments, :lft, :integer add_column :comments, :rgt, :integer - end - + def self.down rename_column :comments, :body, :comment remove_column :comments, :subject remove_column :comments, :parent_id remove_column :comments, :lft remove_column :comments, :rgt - end end diff --git a/db/migrate/20140212175251_add_use_difficulty_levels_to_conference.rb b/db/migrate/20140212175251_add_use_difficulty_levels_to_conference.rb index 00df5c25..c60721e4 100644 --- a/db/migrate/20140212175251_add_use_difficulty_levels_to_conference.rb +++ b/db/migrate/20140212175251_add_use_difficulty_levels_to_conference.rb @@ -1,5 +1,5 @@ class AddUseDifficultyLevelsToConference < ActiveRecord::Migration def change - add_column :conferences, :use_difficulty_levels, :boolean, default: false + add_column :conferences, :use_difficulty_levels, :boolean, default: false end end diff --git a/db/migrate/20140305102505_use_vdays_vpositions_defaults.rb b/db/migrate/20140305102505_use_vdays_vpositions_defaults.rb index c579854e..4ab07be9 100644 --- a/db/migrate/20140305102505_use_vdays_vpositions_defaults.rb +++ b/db/migrate/20140305102505_use_vdays_vpositions_defaults.rb @@ -5,7 +5,7 @@ class UseVdaysVpositionsDefaults < ActiveRecord::Migration end def down - change_column :conferences, :use_vpositions, :boolean, default: nil - change_column :conferences, :use_vdays, :boolean, default: nil + change_column :conferences, :use_vpositions, :boolean, default: nil + change_column :conferences, :use_vdays, :boolean, default: nil end end diff --git a/spec/support/database_cleaner.rb b/spec/support/database_cleaner.rb index 4fb7551f..e0dbc9aa 100644 --- a/spec/support/database_cleaner.rb +++ b/spec/support/database_cleaner.rb @@ -6,7 +6,7 @@ RSpec.configure do |config| config.before(:each) do DatabaseCleaner.strategy = :transaction end - + config.before(:each, js: true) do DatabaseCleaner.strategy = :truncation end