Merge pull request #445 from ChrisBr/refactor_registration_period

Introduces new registration period object
This commit is contained in:
Christian Bruckmayer 2014-08-18 15:26:52 +02:00
commit 206d121d3d
48 changed files with 529 additions and 1629 deletions

View file

@ -7,12 +7,12 @@ $(function () {
pickTime: false, pickTime: false,
format: "YYYY-MM-DD" format: "YYYY-MM-DD"
}); });
$("#conference-reg-start-datepicker").datetimepicker({ $("#registration-period-start-datepicker").datetimepicker({
format: "YYYY-MM-DD", format: "YYYY-MM-DD",
pickTime: false, pickTime: false,
pickSeconds: false pickSeconds: false
}); });
$("#conference-reg-end-datepicker").datetimepicker({ $("#registration-period-end-datepicker").datetimepicker({
format: "YYYY-MM-DD", format: "YYYY-MM-DD",
pickTime: false, pickTime: false,
pickSeconds: false pickSeconds: false

View file

@ -73,7 +73,6 @@ $(function () {
$('#' + $(this).data('name')).toggle(); $('#' + $(this).data('name')).toggle();
}); });
$(".comment-reply-link").click(function(){ $(".comment-reply-link").click(function(){
$(".comment-reply", $(this).parent()).toggle(); $(".comment-reply", $(this).parent()).toggle();
return false; return false;

View file

@ -80,12 +80,10 @@ module Admin
@conference = Conference.find_by(short_title: params[:id]) @conference = Conference.find_by(short_title: params[:id])
short_title = @conference.short_title short_title = @conference.short_title
@conference.assign_attributes(params[:conference]) @conference.assign_attributes(params[:conference])
send_mail_on_conf_update = @conference.notify_on_dates_change? send_mail_on_conf_update = @conference.notify_on_dates_changed?
send_mail_on_reg_update = @conference.notify_on_registration_dates_changed?
if @conference.update_attributes(params[:conference]) if @conference.update_attributes(params[:conference])
Mailbot.delay.conference_date_update_mail(@conference) if send_mail_on_conf_update Mailbot.delay.conference_date_update_mail(@conference) if send_mail_on_conf_update
Mailbot.delay.conference_registration_date_update_mail(@conference) if send_mail_on_reg_update
redirect_to(edit_admin_conference_path(id: @conference.short_title), redirect_to(edit_admin_conference_path(id: @conference.short_title),
notice: 'Conference was successfully updated.') notice: 'Conference was successfully updated.')
else else

View file

@ -0,0 +1,57 @@
module Admin
class RegistrationPeriodsController < ApplicationController
load_and_authorize_resource :conference, find_by: :short_title
load_and_authorize_resource through: :conference, singleton: true
def new
@registration_period = @conference.build_registration_period
end
def create
@registration_period = @conference.build_registration_period(registration_period)
send_mail_on_reg_update = @conference.notify_on_registration_dates_changed?
if @registration_period.save
Mailbot.delay.conference_registration_date_update_mail(@conference) if send_mail_on_reg_update
redirect_to admin_conference_registration_period_path(@conference.short_title),
notice: 'Registration Period successfully updated.'
else
flash[:alert] = "A error prohibited the Registration Period from being saved: #{@registration_period.errors.full_messages.join('. ')}."
render :new
end
end
def edit
end
def show
end
def update
@registration_period.assign_attributes(registration_period)
send_mail_on_reg_update = @conference.notify_on_registration_dates_changed?
if @registration_period.update(registration_period)
Mailbot.delay.conference_registration_date_update_mail(@conference) if send_mail_on_reg_update
redirect_to admin_conference_registration_period_path(@conference.short_title),
notice: 'Registration Period successfully updated.'
else
flash[:alert] = "A error prohibited the Registration Period from being saved: " \
"#{@registration_period.errors.full_messages.join('. ')}."
render :edit
end
end
def destroy
@registration_period.destroy
redirect_to admin_conference_registration_period_path,
notice: 'Registration Period was successfully destroyed.'
end
private
def registration_period
params[:registration_period]
end
end
end

View file

@ -1,232 +0,0 @@
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

View file

@ -106,6 +106,7 @@ class Ability
can :manage, Contact, conference_id: conf_ids_for_organizer can :manage, Contact, conference_id: conf_ids_for_organizer
can :manage, Campaign, conference_id: conf_ids_for_organizer can :manage, Campaign, conference_id: conf_ids_for_organizer
can :manage, Photo, conference_id: conf_ids_for_organizer can :manage, Photo, conference_id: conf_ids_for_organizer
can :manage, RegistrationPeriod, conference_id: conf_ids_for_organizer
end end
def guest def guest

View file

@ -10,11 +10,11 @@ class Conference < ActiveRecord::Base
:start_date, :end_date, :rooms_attributes, :tracks_attributes, :start_date, :end_date, :rooms_attributes, :tracks_attributes,
:dietary_choices_attributes, :use_dietary_choices, :use_supporter_levels, :dietary_choices_attributes, :use_dietary_choices, :use_supporter_levels,
:supporter_levels_attributes, :social_events_attributes, :event_types_attributes, :supporter_levels_attributes, :social_events_attributes, :event_types_attributes,
:registration_start_date, :registration_end_date, :logo, :questions_attributes, :logo, :questions_attributes,
:question_ids, :answers_attributes, :answer_ids, :difficulty_levels_attributes, :question_ids, :answers_attributes, :answer_ids, :difficulty_levels_attributes,
:use_difficulty_levels, :use_vpositions, :use_vdays, :vdays_attributes, :use_difficulty_levels, :use_vpositions, :use_vdays, :vdays_attributes,
:vpositions_attributes, :use_volunteers, :color, :vpositions_attributes, :use_volunteers, :color,
:description, :registration_description, :ticket_description, :description, :ticket_description,
:sponsorship_levels_attributes, :sponsors_attributes, :sponsorship_levels_attributes, :sponsors_attributes,
:sponsor_description, :sponsor_email, :lodging_description, :sponsor_description, :sponsor_email, :lodging_description,
:include_registrations_in_splash, :include_sponsors_in_splash, :include_registrations_in_splash, :include_sponsors_in_splash,
@ -29,7 +29,7 @@ class Conference < ActiveRecord::Base
has_and_belongs_to_many :questions has_and_belongs_to_many :questions
has_one :contact, dependent: :destroy has_one :contact, dependent: :destroy
has_one :registration_period, dependent: :destroy
has_one :email_settings, dependent: :destroy has_one :email_settings, dependent: :destroy
has_one :call_for_papers, dependent: :destroy has_one :call_for_papers, dependent: :destroy
has_many :social_events, dependent: :destroy has_many :social_events, dependent: :destroy
@ -128,8 +128,8 @@ class Conference < ActiveRecord::Base
# * +true+ -> If today is in the registration period. # * +true+ -> If today is in the registration period.
def registration_open? def registration_open?
today = Date.current today = Date.current
if registration_dates_given? if registration_period && registration_dates_given?
(registration_start_date..registration_end_date).cover?(today) (registration_period.start_date..registration_period.end_date).cover?(today)
else else
false false
end end
@ -142,7 +142,7 @@ class Conference < ActiveRecord::Base
# * +false+ -> If the conference registration dates are not set # * +false+ -> If the conference registration dates are not set
# * +true+ -> If conference registration dates are set # * +true+ -> If conference registration dates are set
def registration_dates_given? def registration_dates_given?
if registration_start_date.blank? || registration_end_date.blank? if registration_period && (registration_period.start_date.blank? || registration_period.end_date.blank?)
false false
else else
true true
@ -218,8 +218,9 @@ class Conference < ActiveRecord::Base
result = [] result = []
if registrations && if registrations &&
registration_start_date && registration_period &&
registration_end_date registration_period.start_date &&
registration_period.end_date
reg = registrations.group(:week).count reg = registrations.group(:week).count
start_week = get_registration_start_week start_week = get_registration_start_week
@ -237,8 +238,10 @@ class Conference < ActiveRecord::Base
def registration_weeks def registration_weeks
result = 0 result = 0
weeks = 0 weeks = 0
if registration_start_date && registration_end_date if registration_period &&
weeks = Date.new(registration_start_date.year, 12, 31). registration_period.start_date &&
registration_period.end_date
weeks = Date.new(registration_period.start_date.year, 12, 31).
strftime('%W').to_i strftime('%W').to_i
result = get_registration_end_week - get_registration_start_week + 1 result = get_registration_end_week - get_registration_start_week + 1
@ -265,7 +268,11 @@ class Conference < ActiveRecord::Base
# ====Returns # ====Returns
# * +Integer+ -> start week # * +Integer+ -> start week
def get_registration_start_week def get_registration_start_week
registration_start_date.strftime('%W').to_i result = -1
if registration_period
result = registration_period.start_date.strftime('%W').to_i
end
result
end end
## ##
@ -274,7 +281,11 @@ class Conference < ActiveRecord::Base
# ====Returns # ====Returns
# * +Integer+ -> start week # * +Integer+ -> start week
def get_registration_end_week def get_registration_end_week
registration_end_date.strftime('%W').to_i result = -1
if registration_period
result = registration_period.end_date.strftime('%W').to_i
end
result
end end
## ##
@ -430,13 +441,11 @@ class Conference < ActiveRecord::Base
# * +ActiveRecord+ # * +ActiveRecord+
def self.get_active_conferences_for_dashboard def self.get_active_conferences_for_dashboard
result = Conference.where('start_date > ?', Time.now). result = Conference.where('start_date > ?', Time.now).
select('id, short_title, color, start_date, select('id, short_title, color, start_date')
registration_end_date, registration_start_date')
if result.length == 0 if result.length == 0
result = Conference. result = Conference.
select('id, short_title, color, start_date, registration_end_date, select('id, short_title, color, start_date').limit(2).
registration_start_date').limit(2).
order(start_date: :desc) order(start_date: :desc)
end end
result result
@ -448,8 +457,7 @@ class Conference < ActiveRecord::Base
# ====Returns # ====Returns
# * +ActiveRecord+ # * +ActiveRecord+
def self.get_conferences_without_active_for_dashboard(active_conferences) def self.get_conferences_without_active_for_dashboard(active_conferences)
result = Conference.select('id, short_title, color, start_date, result = Conference.select('id, short_title, color, start_date').order(start_date: :desc)
registration_end_date, registration_start_date').order(start_date: :desc)
result - active_conferences result - active_conferences
end end
@ -525,11 +533,11 @@ class Conference < ActiveRecord::Base
# ====Returns # ====Returns
# * +True+ -> If conference is updated and all other parameters are set # * +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 # * +False+ -> Either conference is not updated or one or more parameter is not set
def notify_on_dates_change? def notify_on_dates_changed?
(self.start_date_changed? || self.end_date_changed?)\ (self.start_date_changed? || self.end_date_changed?) &&
&& self.email_settings.send_on_updated_conference_dates\ self.email_settings.send_on_updated_conference_dates &&
&& !self.email_settings.updated_conference_dates_subject.blank?\ !self.email_settings.updated_conference_dates_subject.blank? &&
&& self.email_settings.updated_conference_dates_template self.email_settings.updated_conference_dates_template
end end
## ##
@ -539,10 +547,11 @@ class Conference < ActiveRecord::Base
# * +True+ -> If registration dates is updated and all other parameters are set # * +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 # * +False+ -> Either registration date is not updated or one or more parameter is not set
def notify_on_registration_dates_changed? def notify_on_registration_dates_changed?
(self.registration_start_date_changed? || self.registration_end_date_changed?)\ registration_period &&
&& self.email_settings.send_on_updated_conference_registration_dates\ (registration_period.start_date_changed? || registration_period.end_date_changed?) &&
&& !self.email_settings.updated_conference_registration_dates_subject.blank?\ email_settings.send_on_updated_conference_registration_dates &&
&& self.email_settings.updated_conference_registration_dates_template !email_settings.updated_conference_registration_dates_subject.blank? &&
email_settings.updated_conference_registration_dates_template
end end
private private
@ -737,7 +746,7 @@ class Conference < ActiveRecord::Base
# * +True+ -> If conference has a start and a end date. # * +True+ -> If conference has a start and a end date.
# * +False+ -> If conference has no start or end date. # * +False+ -> If conference has no start or end date.
def registration_date_set? def registration_date_set?
!!registration_start_date && !!registration_end_date !!registration_period && !!registration_period.start_date && !!registration_period.end_date
end end
# Calculates the distribution from events. # Calculates the distribution from events.

View file

@ -19,8 +19,6 @@ class EmailSettings < ActiveRecord::Base
'conference' => conference.title, 'conference' => conference.title,
'conference_start_date' => conference.start_date, 'conference_start_date' => conference.start_date,
'conference_end_date' => conference.end_date, 'conference_end_date' => conference.end_date,
'registration_start_date' => conference.registration_start_date,
'registration_end_date' => conference.registration_end_date,
'venue' => conference.venue.name, 'venue' => conference.venue.name,
'venue_address' => conference.venue.address, 'venue_address' => conference.venue.address,
'registrationlink' => Rails.application.routes.url_helpers.register_conference_url( 'registrationlink' => Rails.application.routes.url_helpers.register_conference_url(
@ -33,6 +31,11 @@ class EmailSettings < ActiveRecord::Base
conference.short_title, host: CONFIG['url_for_emails']) conference.short_title, host: CONFIG['url_for_emails'])
} }
if conference.registration_period
h['registration_start_date'] = conference.registration_period.start_date
h['registration_end_date'] = conference.registration_period.end_date
end
if !event.nil? if !event.nil?
h['eventtitle'] = event.title h['eventtitle'] = event.title
h['proposalslink'] = Rails.application.routes.url_helpers.conference_proposal_url( h['proposalslink'] = Rails.application.routes.url_helpers.conference_proposal_url(

View file

@ -0,0 +1,7 @@
class RegistrationPeriod < ActiveRecord::Base
attr_accessible :description, :start_date, :end_date
validates :start_date, :end_date, presence: true
belongs_to :conference
end

View file

@ -20,9 +20,6 @@
= f.input :end_date, :as => :string, :input_html => { :id => "conference-end-datepicker", :readonly => "readonly" } = f.input :end_date, :as => :string, :input_html => { :id => "conference-end-datepicker", :readonly => "readonly" }
= f.inputs name: 'Registration' do = f.inputs name: 'Registration' do
= f.input :include_registrations_in_splash, hint: 'On setting this true you will enable the registrations to be displayed on the splash page' = f.input :include_registrations_in_splash, hint: 'On setting this true you will enable the registrations to be displayed on the splash page'
= f.input :registration_start_date, :as => :string, :input_html => { :id => "conference-reg-start-datepicker", :readonly => "readonly" }
= f.input :registration_end_date, :as => :string, :input_html => { :id => "conference-reg-end-datepicker", :readonly => "readonly" }
= f.input :registration_description, hint: markdown_hint("This description will appear in registration segment of the splash."), input_html: { rows: 5, data: { provide: "markdown-editable" } }
= f.input :ticket_description, hint: markdown_hint("This will appear in the Tickets segment of the splash."), input_html: { rows: 5, data: { provide: "markdown-editable" } } = f.input :ticket_description, hint: markdown_hint("This will appear in the Tickets segment of the splash."), input_html: { rows: 5, data: { provide: "markdown-editable" } }
= f.input :sponsor_description, hint: markdown_hint("This will appear in the sponsor segment of the splash."), input_html: { rows: 5, data: { provide: "markdown-editable" } } = f.input :sponsor_description, hint: markdown_hint("This will appear in the sponsor segment of the splash."), input_html: { rows: 5, data: { provide: "markdown-editable" } }
= f.input :sponsor_email, hint: 'This will appear in the sponsor segment of the splash for the sponsors to contact to the organizers' = f.input :sponsor_email, hint: 'This will appear in the sponsor segment of the splash for the sponsors to contact to the organizers'

View file

@ -8,8 +8,8 @@
= conference_progress['process'] + '%' = conference_progress['process'] + '%'
%li{'class'=>class_for_todo(conference_progress['registration'])} %li{'class'=>class_for_todo(conference_progress['registration'])}
%span{'class'=>icon_for_todo(conference_progress['registration'])} %span{'class'=>icon_for_todo(conference_progress['registration'])}
- if can? :update, @conference.registrations.build - if can? :update, @conference
= link_to 'Set up registration period', edit_admin_conference_path(conference_progress['short_title'], :anchor => 'conference-end-datepicker') = link_to 'Set up registration period', edit_admin_conference_registration_period_path(conference_progress['short_title'])
- else - else
Set up registration period Set up registration period
%li{'class'=>class_for_todo(conference_progress['cfp'])} %li{'class'=>class_for_todo(conference_progress['cfp'])}

View file

@ -0,0 +1,8 @@
%h1 Registration Period
.row
.col-md-8
= semantic_form_for(@registration_period, url: admin_conference_registration_period_path(@conference.short_title)) do |f|
= f.input :start_date, as: :string, input_html: { id: 'registration-period-start-datepicker', readonly: 'readonly' }
= f.input :end_date, as: :string, input_html: { id: 'registration-period-end-datepicker', readonly: 'readonly' }
= f.input :description, hint: markdown_hint('This will appear in the Tickets segment of the splash.'), input_html: { rows: 5, data: { provide: 'markdown-editable' } }
= f.submit 'Save Registration Period', class: 'btn btn-primary'

View file

@ -0,0 +1,27 @@
%h1 Registration Period
- if @registration_period
.row
.col-md-6
%dl.dl-horizontal
%dt
Start Date
%dd
= @registration_period.start_date
%dt
End Date
%dd
= @registration_period.end_date
%dt
Description
%dd
- if !@conference.registration_period.description.blank?
= markdown(@conference.registration_period.description)
- if can? :update, @registration_period
= link_to 'Edit', edit_admin_conference_registration_period_path, class: 'btn btn-primary'
- if can? :destroy, @registration_period
= link_to 'Delete', admin_conference_registration_period_path,
method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger'
- else
- if can? :create, @conference
= link_to 'New Registration Period', new_admin_conference_registration_period_path, class: 'btn btn-primary'

View file

@ -1,41 +0,0 @@
-if @events.count > 0
%h2{:style => "text-align: center"}
= "Events (#{@events.count})"
.row-fluid
%h3
%u Types per event state
- if !@conference.event_types.empty?
= render :partial => "events_types"
- else
%h4
%i There are no tracks defined for this conference!
.row-fluid
%h3
%u Tracks per event state
- if @no_track_all.count > 0
%i= " (#{pluralize(@no_track_all.count, 'event')} not assigned to a track)"
- if !@conference.tracks.empty?
= render :partial => "events_tracks"
- else
%h4
%i There are no tracks defined for this conference!
.row-fluid
.span12
%h3 Proposal Submissions over time
.row-fluid
.span12#events_time
= render :partial => "events_time"
.row-fluid
.span12
%br
%h3 Overview of all events
.row-fluid
.span12#events_table
= render :partial => "events_table"
- else
%h5 There are no submitted events yet.

View file

@ -1,34 +0,0 @@
%table.table.table-bordered.table-striped
%thead
%th
- @mystates.each do |state|
%th{:colspan => 2, :style => "text-align:center"}
State "#{state.name}"
%th{:colspan => 2, :style => "text-align:center"}
Total
%br
No & Time
%tr
%td
%b Total
- @mystates.each do |mystate|
%td
%b
= @eventstats["#{mystate.name}"]["count"]
%td
%b
#{@eventstats["#{mystate.name}"]["length"] / 60} h #{@eventstats["#{mystate.name}"]["length"] - @eventstats["#{mystate.name}"]["length"] / 60 * 60} m
%td
%b= @events.count
%td
%b= show_time(@eventstats["totallength"])
- @mytypes.each do |mytype|
%tr
%td= "#{mytype.title} (#{show_time(mytype.length)})"
- @mystates.each do |mystate|
%td= @eventstats["#{mytype.title}"]["#{mystate.name}"]["type_state_count"] unless @eventstats["#{mytype.title}"]["#{mystate.name}"] == nil
%td= show_time(@eventstats["#{mytype.title}"]["#{mystate.name}"]["type_state_length"]) unless @eventstats["#{mytype.title}"]["#{mystate.name}"] == nil
%td= @eventstats["#{mytype.title}"]["count"]
%td= show_time(@eventstats["#{mytype.title}"]["length"])

View file

@ -1,71 +0,0 @@
<script>
var events = '<%= h @events.count%>';
var data = <%=raw @events_time.to_json %>;
var valueLabelWidth = 10; // space reserved for value labels (right)
var barHeight = 24; // height of one bar
var barLabelWidth = 100; // space reserved for bar labels
var barLabelPadding = 8; // padding between bar and bar labels (left)
var gridLabelHeight = 18; // space reserved for gridline labels
var gridChartOffset = 3; // space between start of grid and first bar
var maxBarWidth = 420; // width of the bar with the max value
var color = d3.scale.category20();
// accessor functions
var barLabel = function(d) { return d['status']; };
var barValue = function(d) { return d['value'] / events * 100; };
var barValues = function(d) { return d['value']; };
// scales
var yScale = d3.scale.ordinal().domain(d3.range(0, data.length)).rangeBands([0, data.length * barHeight]);
var y = function(d, i) { return yScale(i); };
var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; };
var yMax = d3.max(data, function(d){ return barValue(d) + 15; });
var x = d3.scale.linear().domain([0, yMax]).range([0, maxBarWidth]);
var width = maxBarWidth + barLabelWidth + valueLabelWidth;
// svg container element
var chart = d3.select('#events_time').append("svg")
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
// bar labels
var labelsContainer = chart.append('g')
.attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')');
labelsContainer.selectAll('text').data(data).enter().append('text')
.attr('y', yText)
.attr('stroke', 'none')
.attr('fill', 'black')
.attr("dy", ".35em") // vertical-align: middle
.attr('text-anchor', 'end')
.text(barLabel);
// bars
var barsContainer = chart.append('g')
.attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')');
barsContainer.selectAll("rect").data(data).enter().append("rect")
.attr('y', y)
.attr('height', yScale.rangeBand())
.attr('width', function(d) { return x(barValue(d)); })
.attr('stroke', 'white')
.attr('fill', function(d) { return color(barValue(d)); });
// bar value labels
barsContainer.selectAll("text").data(data).enter().append("text")
.attr("x", 5)
.attr("y", yText)
.attr("dx", 3) // padding-left
.attr("dy", ".35em") // vertical-align: middle
.attr("text-anchor", "start") // text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(function(d) { return d3.round(barValues(d), 2) + " (" + d3.round(barValue(d), 0) + "%)"; });
// start line
barsContainer.append("line")
.attr("y1", -gridChartOffset)
.attr("y2", yScale.rangeExtent()[1] + gridChartOffset)
.style("stroke", "#000");
</script>

View file

@ -1,35 +0,0 @@
.row-fluid
- if !@track_state['new'].empty?
.span4
%h4 New Submissions
- if @no_track_new.count > 0
%h5= "#{pluralize(@no_track_new.count, 'event')} not assigned to a track"
- else
%h5
.row-fluid
.span12#events_tracks_new
= render :partial => "events_tracks_new"
- if !@track_state['unconfirmed'].empty?
.span4
%h4 Accepted (Unconfirmed)
- if @no_track_unconfirmed.count > 0
%h5= "#{pluralize(@no_track_unconfirmed.count, 'event')} not assigned to a track"
- else
%h5 All events assigned to track!
.row-fluid
.span12#events_tracks_unconfirmed
= render :partial => "events_tracks_unconfirmed"
- if !@track_state['confirmed'].empty?
.span4
%h4 Accepted (Confirmed)
- if @no_track_confirmed.count > 0
%h5= "#{pluralize(@no_track_confirmed.count, 'event')} not assigned to a track"
- else
%h5 All events assigned to track!
.row-fluid
.span12#events_tracks_confirmed
= render :partial => "events_tracks_confirmed"

View file

@ -1,79 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#5254a3", "#6b6ecf", "#9c9ede "]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_tracks_confirmed").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @track_state['confirmed'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_tracks_confirmed").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,79 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#5254a3", "#6b6ecf", "#9c9ede "]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_tracks_new").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @track_state['new'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_tracks_new").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,79 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#5254a3", "#6b6ecf", "#9c9ede "]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_tracks_unconfirmed").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @track_state['unconfirmed'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_tracks_unconfirmed").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,19 +0,0 @@
.row-fluid
- if !@type_state['new'].empty?
.span4
%h4 New Submissions: #{@type_state['new'].map{|x| x["value"]}.sum}
.row-fluid
.span12#events_types_new
= render :partial => "events_types_new"
- if !@type_state['unconfirmed'].empty?
.span4
%h4 Accepted (Unconfirmed): #{@type_state['unconfirmed'].map{|x| x["value"]}.sum}
.row-fluid
.span12#events_types_unconfirmed
= render :partial => "events_types_unconfirmed"
- if !@type_state['confirmed'].empty?
.span4
%h4 Accepted (Confirmed): #{@type_state['confirmed'].map{|x| x["value"]}.sum}
.row-fluid
.span12#events_types_confirmed
= render :partial => "events_types_confirmed"

View file

@ -1,78 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_types_confirmed").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @type_state['confirmed'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_types_confirmed").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,78 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.percent; });
// Where to put the chart
var svg = d3.select("#events_types_new").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @type_state['new'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_types_new").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,78 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#events_types_unconfirmed").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @type_state['unconfirmed'].to_json%>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.status; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#events_types_unconfirmed").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,70 +0,0 @@
<script>
var registered = '<%= h @registrations.count%>';
var data = <%=raw @other_info.to_json %>;
var valueLabelWidth = 70; // space reserved for value labels (right)
var barHeight = 24; // height of one bar
var barLabelWidth = 210; // space reserved for bar labels
var barLabelPadding = 8; // padding between bar and bar labels (left)
var gridLabelHeight = 18; // space reserved for gridline labels
var gridChartOffset = 3; // space between start of grid and first bar
var maxBarWidth = 350; // width of the bar with the max value
var color = d3.scale.category20();
// accessor functions
var barLabel = function(d) { return d['status']; };
var barValue = function(d) { return d['value'] / registered * 100; };
var barValues = function(d) { return d['value']; };
// scales
var yScale = d3.scale.ordinal().domain(d3.range(0, data.length)).rangeBands([0, data.length * barHeight]);
var y = function(d, i) { return yScale(i); };
var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; };
var yMax = d3.max(data, function(d){ return barValue(d) + 15; });
var x = d3.scale.linear().domain([0, yMax]).range([0, maxBarWidth]);
// svg container element
var chart = d3.select('#other_info').append("svg")
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
// bar labels
var labelsContainer = chart.append('g')
.attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')');
labelsContainer.selectAll('text').data(data).enter().append('text')
.attr('y', yText)
.attr('stroke', 'none')
.attr('fill', 'black')
.attr("dy", ".35em") // vertical-align: middle
.attr('text-anchor', 'end')
.text(barLabel);
// bars
var barsContainer = chart.append('g')
.attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')');
barsContainer.selectAll("rect").data(data).enter().append("rect")
.attr('y', y)
.attr('height', yScale.rangeBand())
.attr('width', function(d) { return x(barValue(d)); })
.attr('stroke', 'white')
.attr('fill', function(d) { return color(barLabel(d)); });
// bar value labels
barsContainer.selectAll("text").data(data).enter().append("text")
.attr("x", 5)
.attr("y", yText)
.attr("dx", 3) // padding-left
.attr("dy", ".35em") // vertical-align: middle
.attr("text-anchor", "start") // text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(function(d) { return d3.round(barValues(d), 2) + " (" + d3.round(barValue(d), 0) + "%)"; });
// start line
barsContainer.append("line")
.attr("y1", -gridChartOffset)
.attr("y2", yScale.rangeExtent()[1] + gridChartOffset)
.style("stroke", "#000");
</script>

View file

@ -1,85 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#9ECAE1", "#6baed6", "#DEEBF7"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#preregistered_onsite").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var total = '<%= h @registrations.count %>';
var pre_registered = '<%= h @pre_registered %>';
var onsite = '<%= h @registrations.count - @pre_registered %>';
var data = [
{"status":"onsite","value": onsite, "percent": d3.round(onsite / total * 100)},
{"status":"pre_registered","value":pre_registered, "percent": d3.round(pre_registered / total * 100)}
];
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.percent +"%"; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#preregistered_onsite").append("svg")
.attr("class", "legend")
.attr("width", radius * 2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,85 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#9ECAE1", "#6baed6", "#DEEBF7"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#registered_attended").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var registered = '<%= h @pre_registered%>';
var attended = '<%= h @pre_registered_attended %>';
var not_attended = '<%= h @pre_registered - @pre_registered_attended %>';
var data = [
{"status":"did not attend","value":not_attended, "percent": d3.round(not_attended / registered * 100)},
{"status":"attended","value": attended, "percent": d3.round(attended / registered * 100)}
];
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.percent +"%"; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#registered_attended").append("svg")
.attr("class", "legend")
.attr("width", radius*2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1,71 +0,0 @@
<script>
var registered = '<%= h @registrations.count%>';
var data = <%=raw @registered_time.to_json %>;
var valueLabelWidth = 10; // space reserved for value labels (right)
var barHeight = 24; // height of one bar
var barLabelWidth = 100; // space reserved for bar labels
var barLabelPadding = 8; // padding between bar and bar labels (left)
var gridLabelHeight = 18; // space reserved for gridline labels
var gridChartOffset = 3; // space between start of grid and first bar
var maxBarWidth = 420; // width of the bar with the max value
var color = d3.scale.category20();
// accessor functions
var barLabel = function(d) { return d['status']; };
var barValue = function(d) { return d['value'] / registered * 100; };
var barValues = function(d) { return d['value']; };
// scales
var yScale = d3.scale.ordinal().domain(d3.range(0, data.length)).rangeBands([0, data.length * barHeight]);
var y = function(d, i) { return yScale(i); };
var yText = function(d, i) { return y(d, i) + yScale.rangeBand() / 2; };
var yMax = d3.max(data, function(d){ return barValue(d) + 15; });
var x = d3.scale.linear().domain([0, yMax]).range([0, maxBarWidth]);
var width = maxBarWidth + barLabelWidth + valueLabelWidth;
// svg container element
var chart = d3.select('#registered_time').append("svg")
.attr('width', maxBarWidth + barLabelWidth + valueLabelWidth)
.attr('height', gridLabelHeight + gridChartOffset + data.length * barHeight);
// bar labels
var labelsContainer = chart.append('g')
.attr('transform', 'translate(' + (barLabelWidth - barLabelPadding) + ',' + (gridLabelHeight + gridChartOffset) + ')');
labelsContainer.selectAll('text').data(data).enter().append('text')
.attr('y', yText)
.attr('stroke', 'none')
.attr('fill', 'black')
.attr("dy", ".35em") // vertical-align: middle
.attr('text-anchor', 'end')
.text(barLabel);
// bars
var barsContainer = chart.append('g')
.attr('transform', 'translate(' + barLabelWidth + ',' + (gridLabelHeight + gridChartOffset) + ')');
barsContainer.selectAll("rect").data(data).enter().append("rect")
.attr('y', y)
.attr('height', yScale.rangeBand())
.attr('width', function(d) { return x(barValue(d)); })
.attr('stroke', 'white')
.attr('fill', function(d) { return color(barValue(d)); });
// bar value labels
barsContainer.selectAll("text").data(data).enter().append("text")
.attr("x", 5)
.attr("y", yText)
.attr("dx", 3) // padding-left
.attr("dy", ".35em") // vertical-align: middle
.attr("text-anchor", "start") // text-align: right
.attr("fill", "black")
.attr("stroke", "none")
.text(function(d) { return d3.round(barValues(d), 2) + " (" + d3.round(barValue(d), 0) + "%)"; });
// start line
barsContainer.append("line")
.attr("y1", -gridChartOffset)
.attr("y2", yScale.rangeExtent()[1] + gridChartOffset)
.style("stroke", "#000");
</script>

View file

@ -1,41 +0,0 @@
.row
.col-md-4
- if @registered > 0
- if @attendees > 0
%h4{:style => "text-indent: 25px"}= "Registrations - Attendees (#{(@attendees.to_f / @registered * 100).round }%)"
- else
%h4{:style => "text-indent: 25px"}= "Registrations - Attendees"
.row-fluid
.span12#registrations_attendees
= render :partial => "registrations_attendees"
- else
%h5 There are no registrations yet.
.col-md-4
- if @registered > 0
%h4{:style => "text-indent: 10px"}= "Attendance of pre-registered"
.row-fluid
.span12#registered_attended
= render :partial => "registered_attended"
.col-md-4
- if @registered > 0
%h4{:style => "text-indent: 25px"}= "% of pre-registered"
.row-fluid
.span12#preregistered_onsite
= render :partial => "preregistered_onsite"
.row
.col-md-6
- if @registered > 0
%h4= "Other Info"
.row-fluid
.span12#other_info
= render :partial => "other_info"
.col-md-6
- if @registered > 0
%h4{:style => "text-indent: 98px"}= "Registrations over time"
.row-fluid
.span12#registered_time
= render :partial => "registered_time"

View file

@ -1,77 +0,0 @@
<script>
var w = 250,
h = 250,
r = Math.min(w, h) / 2 - 10,
inner = 80,
color = d3.scale.category20c();
var registrations = '<%= h @registered %>';
var attendees = '<%= h @attendees %>';
var data = [
{"status":"Did Not Attend","value": registrations-attendees, "percent": ""},
{"status":"Attended","value": attendees, "percent": d3.round(attendees/registrations * 100)+"%"}
];
var vis = d3.select("#registrations_attendees")
.append("svg:svg")
.data([data])
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(" + r * 1.1 + "," + r * 1.1 + ")")
var textTop = vis.append("text")
.attr("dy", ".35em")
.style("text-anchor", "middle")
.attr("class", "textTop")
.text( "Registered: " + registrations)
.attr("y", -10),
textBottom = vis.append("text")
.attr("dy", ".35em")
.style("text-anchor", "middle")
.attr("class", "textBottom")
.text("Attended: " + attendees)
.attr("y", 10);
var arc = d3.svg.arc()
.innerRadius(inner)
.outerRadius(r);
var arcOver = d3.svg.arc()
.innerRadius(inner + 5)
.outerRadius(r + 5);
var pie = d3.layout.pie()
.value(function(d) { return d.value; });
var arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("svg:g")
.attr("class", "slice");
arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); } )
.attr("d", arc);
var legend = d3.select("#registrations_attendees").append("svg")
.attr("class", "legend")
.attr("width", r * 2)
.attr("height", r)
.selectAll("g")
.data(data)
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", function(d, i) { return color(i); });
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".35em")
.text(function(d) { return "Total " + d.status + " (" + d.value + ")"; });
</script>

View file

@ -1,37 +0,0 @@
- count =0
%h3
Speakers (#{@speakers.length})
%table.table.table-striped.table-bordered.table-hover#speakertable
%thead
%th
ID
- (@speaker_fields_user + @speaker_fields_reg).each do |field|
%th
= field.capitalize
- @speakers.each do |speaker|
%tr
%td
= count +=1
- @speaker_fields_user.each do |field|
%td
= speaker.send(field.to_sym)
- @speaker_fields_reg.each do |field|
%td
- reg = speaker_reg(speaker)
- if !reg.nil?
- if field == "diet"
- if reg.dietary_choice_id
= speaker_diet(reg).title
%br
= reg.other_dietary_choice
- elsif field == 'arrival' || field == 'departure'
= getdatetime(reg, field)
- else
= reg.send(field.to_sym)
:javascript
$(document).ready(function(){
$('#speakertable').dataTable({
"bPaginate": false
});
});

View file

@ -1,22 +0,0 @@
- if @tickets.length > 0
.row-fluid
.span12
%h2
= "Non-Free Tickets (#{@tickets.count})"
.row-fluid
.span4
%h4 Ticket distribution
.row-fluid
.span12#tickets_distribution
= render :partial => "tickets_distribution"
.row-fluid
.span10
%h4 Ticket sales over time
.row-fluid
.span12#tickets_time
= render :partial => "tickets_time"
- else
- if @conference.use_supporter_levels
%h5 No tickets have been bought yet.
- else
%h5 There are no tickets set for this conference.

View file

@ -1,79 +0,0 @@
<style>
.arc path {
stroke: #fff;
}
</style>
<script>
var width = 250,
height = 250,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#9ECAE1", "#6baed6", "#DEEBF7"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.value; });
// Where to put the chart
var svg = d3.select("#tickets_distribution").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var data = <%=raw @tickets_distribution.to_json %>;
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.status); });
// Put text inside every piece of the pie-chart
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.percent +"%"; });
// Title of chart
svg.append("text")
.attr("class", "title")
.attr("x", radius)
.attr("y", -radius+10)
.text("% of pre-registered");
// Create & position legend
var legend = d3.select("#tickets_distribution").append("svg")
.attr("class", "legend")
.attr("width", radius * 2)
.attr("height", radius)
.selectAll("g")
.data(color.domain().slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("width", 18)
.attr("height", 18)
.style("fill", color);
legend.append("text")
.attr("x", 24)
.attr("y", 9)
.attr("dy", ".15em")
.text(function(d) { return d + " (" + data.filter(function(v){return v.status === d;})[0].value + " or " + data.filter(function(v){return v.status === d;})[0].percent + "%)" ; });
</script>

View file

@ -1 +0,0 @@
(Not yet implemented)

View file

@ -1,27 +0,0 @@
.row
.col-md-12
%ul.nav.nav-tabs#myTab
%li.active
%a{:href=>"#registrations", "data-toggle"=>"tab"} Registrations
%li
%a{:href=>"#events", "data-toggle"=>"tab"} Events
%li
%a{:href=>"#speakers", "data-toggle"=>"tab"} Speakers
%li
%a{:href=>"#tickets", "data-toggle"=>"tab"} Tickets
.tab-content
.tab-pane.active#registrations
= render :partial => 'registrations'
.tab-pane#events
= render :partial => 'events'
.tab-pane#speakers
= render :partial => 'speakers'
.tab-pane#tickets
= render :partial => 'tickets'
:javascript
$('#myTab a').click(function (e) {
e.preventDefault();
$(this).tab('show');
})

View file

@ -4,14 +4,14 @@
%div.container.text-center %div.container.text-center
%div.row %div.row
%h1 Registration %h1 Registration
- if !@conference.registration_description.blank? - if @conference.registration_period && !@conference.registration_period.description.blank?
.lead .lead
= markdown(@conference.registration_description) = markdown(@conference.registration_period.description)
- if @conference.registration_dates_given? - if @conference.registration_dates_given?
-if @conference.registration_end_date >= Date.today -if @conference.registration_period.end_date >= Date.today
%h4 Registration period #{ date_string(@conference.registration_start_date, @conference.registration_end_date) } %h4 Registration period #{ date_string(@conference.registration_period.start_date, @conference.registration_period.end_date) }
-else -else
%h4 Registration is Closed, it was from #{ date_string(@conference.registration_start_date, @conference.registration_end_date) } %h4 Registration is Closed, it was from #{ date_string(@conference.registration_period.start_date, @conference.registration_period.end_date) }
- if @conference.registration_open? - if @conference.registration_open?
= link_to "Register for #{@conference.short_title}", conference_register_path(@conference.short_title), :class =>"btn btn-success btn-lg", target: '_blank' = link_to "Register for #{@conference.short_title}", conference_register_path(@conference.short_title), :class =>"btn btn-success btn-lg", target: '_blank'
- if @conference.use_supporter_levels? - if @conference.use_supporter_levels?

View file

@ -48,6 +48,11 @@
= link_to(admin_conference_photos_path(@conference.short_title)) do = link_to(admin_conference_photos_path(@conference.short_title)) do
%span.fa.fa-picture-o %span.fa.fa-picture-o
Photos Photos
- if can? :update, @conference
%li{:class=> active_nav_li( admin_conference_registration_period_path (@conference.short_title))}
= link_to( admin_conference_registration_period_path (@conference.short_title)) do
%span.fa.fa-male
Registration Period
- if can? :update, @conference.events.build - if can? :update, @conference.events.build
%li{:class=> active_nav_li(admin_conference_events_path(@conference.short_title))} %li{:class=> active_nav_li(admin_conference_events_path(@conference.short_title))}
= link_to(admin_conference_events_path(@conference.short_title)) do = link_to(admin_conference_events_path(@conference.short_title)) do

View file

@ -30,6 +30,8 @@ Osem::Application.routes.draw do
patch '/registrations/change_field' => 'registrations#change_field' patch '/registrations/change_field' => 'registrations#change_field'
resources :registrations resources :registrations
resource :registration_period
resources :difficulty_levels, only: [:show, :update, :index] resources :difficulty_levels, only: [:show, :update, :index]
resources :rooms, only: [:show, :update, :index] resources :rooms, only: [:show, :update, :index]

View file

@ -0,0 +1,16 @@
class CreateRegistrationPeriods < ActiveRecord::Migration
def up
create_table :registration_periods do |t|
t.integer :conference_id
t.date :start_date
t.date :end_date
t.text :description
t.timestamps
end
end
def down
drop_table :registration_periods
end
end

View file

@ -0,0 +1,33 @@
class MoveConferenceRegistrationDataToRegistrationPeriods < ActiveRecord::Migration
class TempConference < ActiveRecord::Base
self.table_name = 'conferences'
end
class TempRegistrationPeriod < ActiveRecord::Base
self.table_name = 'registration_periods'
attr_accessible :conference_id, :start_date, :end_date, :description
end
def up
# Move all the settings to the new object
TempConference.all.each do |conference|
unless TempRegistrationPeriod.exists?(conference_id: conference.id)
TempRegistrationPeriod.create(conference_id: conference.id,
start_date: conference.registration_start_date,
end_date: conference.registration_end_date,
description: conference.registration_description)
end
end
# Remove Columns
remove_column :conferences, :registration_start_date
remove_column :conferences, :registration_end_date
remove_column :conferences, :registration_description
end
def down
add_column :conferences, :registration_start_date, :date
add_column :conferences, :registration_end_date, :date
add_column :conferences, :registration_description, :text
end
end

View file

@ -11,7 +11,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20140801170430) do ActiveRecord::Schema.define(version: 20140812065531) do
create_table "ahoy_events", force: true do |t| create_table "ahoy_events", force: true do |t|
t.uuid "visit_id" t.uuid "visit_id"
@ -94,8 +94,6 @@ ActiveRecord::Schema.define(version: 20140801170430) do
t.integer "venue_id" t.integer "venue_id"
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.date "registration_start_date"
t.date "registration_end_date"
t.string "logo_file_name" t.string "logo_file_name"
t.string "logo_content_type" t.string "logo_content_type"
t.integer "logo_file_size" t.integer "logo_file_size"
@ -109,17 +107,16 @@ ActiveRecord::Schema.define(version: 20140801170430) do
t.boolean "use_volunteers" t.boolean "use_volunteers"
t.string "color" t.string "color"
t.text "description" t.text "description"
t.text "registration_description"
t.text "ticket_description" t.text "ticket_description"
t.text "sponsor_description" t.text "sponsor_description"
t.string "sponsor_email" t.string "sponsor_email"
t.text "lodging_description" t.text "lodging_description"
t.boolean "make_conference_public", default: false
t.boolean "include_registrations_in_splash", default: false t.boolean "include_registrations_in_splash", default: false
t.boolean "include_sponsors_in_splash", default: false t.boolean "include_sponsors_in_splash", default: false
t.boolean "include_tracks_in_splash", default: false t.boolean "include_tracks_in_splash", default: false
t.boolean "include_tickets_in_splash", default: false t.boolean "include_tickets_in_splash", default: false
t.boolean "include_program_in_splash", default: false t.boolean "include_program_in_splash", default: false
t.boolean "make_conference_public", default: false
t.string "banner_photo_file_name" t.string "banner_photo_file_name"
t.string "banner_photo_content_type" t.string "banner_photo_content_type"
t.integer "banner_photo_file_size" t.integer "banner_photo_file_size"
@ -218,7 +215,7 @@ ActiveRecord::Schema.define(version: 20140801170430) do
t.string "attachment_content_type" t.string "attachment_content_type"
t.integer "attachment_file_size" t.integer "attachment_file_size"
t.datetime "attachment_updated_at" t.datetime "attachment_updated_at"
t.boolean "public", default: true t.boolean "public", default: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
end end
@ -332,6 +329,15 @@ ActiveRecord::Schema.define(version: 20140801170430) do
t.datetime "updated_at" t.datetime "updated_at"
end end
create_table "registration_periods", force: true do |t|
t.integer "conference_id"
t.date "start_date"
t.date "end_date"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "registrations", force: true do |t| create_table "registrations", force: true do |t|
t.integer "conference_id" t.integer "conference_id"
t.boolean "attending_social_events", default: true t.boolean "attending_social_events", default: true
@ -363,11 +369,11 @@ ActiveRecord::Schema.define(version: 20140801170430) do
create_table "roles", force: true do |t| create_table "roles", force: true do |t|
t.string "name" t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
t.string "description" t.string "description"
t.integer "resource_id" t.integer "resource_id"
t.string "resource_type" t.string "resource_type"
t.datetime "created_at"
t.datetime "updated_at"
end end
add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id" add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id"
@ -514,8 +520,8 @@ ActiveRecord::Schema.define(version: 20140801170430) do
create_table "venues", force: true do |t| create_table "venues", force: true do |t|
t.string "guid" t.string "guid"
t.text "name" t.text "name", limit: 255
t.text "address" t.text "address", limit: 255
t.string "website" t.string "website"
t.text "description" t.text "description"
t.string "offline_map_url" t.string "offline_map_url"

View file

@ -48,16 +48,6 @@ describe Admin::ConferenceController do
conference.reload conference.reload
allow(Mailbot).to receive(:conference_date_update_mail).and_return(mailer) allow(Mailbot).to receive(:conference_date_update_mail).and_return(mailer)
end end
it 'sends email notification on conference registration date update' do
mailer = double
allow(mailer).to receive(:deliver)
conference.email_settings = create(:email_settings)
patch :update, id: conference.short_title, conference:
attributes_for(:conference, registration_start_date: Date.today + 2.days, registration_end_date: Date.today + 4.days)
conference.reload
allow(Mailbot).to receive(:conference_registration_date_update_mail).and_return(mailer)
end
end end
context 'invalid attributes' do context 'invalid attributes' do
@ -141,13 +131,13 @@ describe Admin::ConferenceController do
describe 'GET #edit' do describe 'GET #edit' do
it 'assigns the requested conference to conference' do it 'assigns the requested conference to conference' do
get :show, id: conference.short_title get :edit, id: conference.short_title
expect(assigns(:conference)).to eq conference expect(assigns(:conference)).to eq conference
end end
it 'renders the show template' do it 'renders the show template' do
get :show, id: conference.short_title get :edit, id: conference.short_title
expect(response).to render_template :show expect(response).to render_template :edit
end end
end end

View file

@ -0,0 +1,165 @@
require 'spec_helper'
describe Admin::RegistrationPeriodsController do
# It is necessary to use bang version of let to build roles before user
let(:conference) { create(:conference) }
let!(:first_user) { create(:user) }
let!(:organizer_role) { create(:role, name: 'organizer', resource: conference) }
let(:organizer) { create(:user, role_ids: organizer_role.id) }
let(:organizer2) { create(:user, email: 'organizer2@email.osem', role_ids: organizer_role.id) }
let(:participant) { create(:user) }
shared_examples 'access as administration or organizer' do
before do
conference.registration_period = create(:registration_period)
end
describe 'PATCH #update' do
context 'valid attributes' do
it 'locates the requested audience object' do
patch :update, conference_id: conference.short_title, conference: attributes_for(:registration_period)
expect(assigns(:registration_period)).to eq(conference.registration_period)
end
it 'changes audience attributes' do
patch :update, conference_id: conference.short_title, registration_period:
attributes_for(:registration_period,
description: 'Test')
conference.reload
expect(conference.registration_period.description).to eq('Test')
end
it 'redirects to the updated conference' do
patch :update, conference_id: conference.short_title, registration_period:
attributes_for(:registration_period)
conference.reload
expect(response).to redirect_to admin_conference_registration_period_path(
conference.short_title)
end
it 'sends email notification on conference registration date update' do
mailer = double
allow(mailer).to receive(:deliver)
conference.email_settings = create(:email_settings)
conference.registration_period = create(:registration_period,
start_date: Date.today,
end_date: Date.today + 2.days)
patch :update, conference_id: conference.short_title, registration_period:
attributes_for(:registration_period,
start_date: Date.today + 2.days,
end_date: Date.today + 4.days)
conference.reload
allow(Mailbot).to receive(:conference_registration_date_update_mail).and_return(mailer)
end
end
end
describe 'POST #create' do
context 'with valid attributes' do
it 'saves the registration period to the database' do
expected = expect do
post :create,
conference_id: conference.short_title,
registration_period: attributes_for(:registration_period)
end
expected.to change { RegistrationPeriod.count }.by 1
end
it 'redirects to registration_periods#show' do
post :create,
conference_id: conference.short_title,
registration_period: attributes_for(:registration_period)
expect(response).to redirect_to admin_conference_registration_period_path(
assigns[:conference].short_title)
end
end
context 'with invalid attributes' do
it 'does not save the conference to the database' do
expected = expect do
post :create,
conference_id: conference.short_title,
registration_period: attributes_for(:registration_period,
start_date: nil,
end_date: nil)
end
expected.to_not change { Conference.count }
end
it 're-renders the new template' do
post :create,
conference_id: conference.short_title,
registration_period: attributes_for(:registration_period,
start_date: nil,
end_date: nil)
expect(response).to be_success
end
end
end
describe 'GET #edit' do
it 'assigns the requested conference to conference' do
get :edit, conference_id: conference.short_title
expect(assigns(:registration_period)).to eq conference.registration_period
end
it 'renders the show template' do
get :edit, conference_id: conference.short_title
expect(response).to render_template :edit
end
end
describe 'GET #show' do
it 'assigns the requested registration period to registration period' do
get :show, conference_id: conference.short_title
expect(assigns(:registration_period)).to eq conference.registration_period
end
it 'renders the show template' do
get :show, conference_id: conference.short_title
expect(response).to render_template :show
end
end
describe 'GET #new' do
it 'assigns a new conference to conference' do
get :new, conference_id: conference.short_title
expect(assigns(:registration_period)).to be_a_new(RegistrationPeriod)
end
it 'renders the :new template' do
get :new, conference_id: conference.short_title
expect(response).to render_template :new
end
end
describe 'DELETE #destroy' do
it 'it deletes the registration period' do
expect { delete :destroy, conference_id: conference.short_title }.to change(RegistrationPeriod, :count).by(-1)
end
it 'redirects to users#show' do
delete :destroy, conference_id: conference.short_title
expect(response).to redirect_to admin_conference_registration_period_path
end
end
end
describe 'organizer access' do
before(:each) do
sign_in(organizer)
end
it_behaves_like 'access as administration or organizer'
end
end

View file

@ -7,8 +7,6 @@ FactoryGirl.define do
timezone 'Amsterdam' timezone 'Amsterdam'
start_date { Date.today } start_date { Date.today }
end_date { 6.days.from_now } end_date { 6.days.from_now }
registration_start_date { 3.days.from_now }
registration_end_date { 5.days.from_now }
make_conference_public true make_conference_public true
venue venue
end end

View file

@ -0,0 +1,9 @@
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :registration_period do
start_date { 3.days.from_now }
end_date { 5.days.from_now }
description 'Lorem ipsum dolorem ...'
end
end

View file

@ -0,0 +1,47 @@
require 'spec_helper'
feature RegistrationPeriod do
# It is necessary to use bang version of let to build roles before user
let!(:conference) { create(:conference) }
let!(:organizer_role) { create(:organizer_role, resource: conference) }
let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) }
shared_examples 'successfully' do
scenario 'create and update registration period', js: true do
sign_in organizer
visit admin_conference_registration_period_path(
conference_id: conference.short_title)
click_link 'New Registration Period'
fill_in 'registration_period_description', with: 'The description'
click_button 'Save Registration Period'
expect(flash).
to eq("A error prohibited the Registration Period from being saved: " \
"Start date can't be blank. End date can't be blank.")
page.
execute_script("$('#registration-period-start-datepicker').val('" +
"#{Date.today.strftime('%d/%m/%Y')}')")
page.
execute_script("$('#registration-period-end-datepicker').val('" +
"#{(Date.today + 7).strftime('%d/%m/%Y')}')")
click_button 'Save Registration Period'
expect(flash).to eq('Registration Period successfully updated.')
expect(current_path).to eq(admin_conference_registration_period_path(conference.short_title))
registration_period = RegistrationPeriod.where(conference_id: conference.id).first
registration_period.reload
expect(registration_period.start_date).to eq(Date.today)
expect(registration_period.end_date).to eq(Date.today + 7)
expect(registration_period.description).to eq('The description')
end
end
describe 'organizer' do
it_behaves_like 'successfully'
end
end

View file

@ -964,8 +964,6 @@ describe Conference do
end end
it 'calculates correct for new conference' do it 'calculates correct for new conference' do
subject.registration_start_date = nil
subject.registration_end_date = nil
subject.call_for_papers = nil subject.call_for_papers = nil
subject.venue = nil subject.venue = nil
subject.rooms = [] subject.rooms = []
@ -978,8 +976,9 @@ describe Conference do
end end
it 'calculates correct for conference with registration' do it 'calculates correct for conference with registration' do
subject.registration_start_date = Date.today subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.today + 14 start_date: Date.today,
end_date: Date.today + 14)
subject.call_for_papers = nil subject.call_for_papers = nil
subject.rooms = [] subject.rooms = []
subject.tracks = [] subject.tracks = []
@ -994,8 +993,9 @@ describe Conference do
end end
it 'calculates correct for conference with registration, cfp' do it 'calculates correct for conference with registration, cfp' do
subject.registration_start_date = Date.today subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.today + 14 start_date: Date.today,
end_date: Date.today + 14)
subject.call_for_papers = create(:call_for_papers) subject.call_for_papers = create(:call_for_papers)
subject.rooms = [] subject.rooms = []
subject.tracks = [] subject.tracks = []
@ -1011,8 +1011,9 @@ describe Conference do
end end
it 'calculates correct for conference with registration, cfp, venue' do it 'calculates correct for conference with registration, cfp, venue' do
subject.registration_start_date = Date.today subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.today + 14 start_date: Date.today,
end_date: Date.today + 14)
subject.call_for_papers = create(:call_for_papers) subject.call_for_papers = create(:call_for_papers)
subject.venue = create(:venue) subject.venue = create(:venue)
subject.rooms = [] subject.rooms = []
@ -1031,8 +1032,9 @@ describe Conference do
it 'calculates correct for conference with registration, cfp, venue, rooms' do it 'calculates correct for conference with registration, cfp, venue, rooms' do
subject.rooms = [create(:room)] subject.rooms = [create(:room)]
subject.registration_start_date = Date.today subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.today + 14 start_date: Date.today,
end_date: Date.today + 14)
subject.call_for_papers = create(:call_for_papers) subject.call_for_papers = create(:call_for_papers)
subject.venue = create(:venue) subject.venue = create(:venue)
subject.tracks = [] subject.tracks = []
@ -1052,8 +1054,9 @@ describe Conference do
it 'calculates correct for conference with registration, cfp, venue, rooms, tracks' do it 'calculates correct for conference with registration, cfp, venue, rooms, tracks' do
subject.rooms = [create(:room)] subject.rooms = [create(:room)]
subject.tracks = [create(:track)] subject.tracks = [create(:track)]
subject.registration_start_date = Date.today subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.today + 14 start_date: Date.today,
end_date: Date.today + 14)
subject.call_for_papers = create(:call_for_papers) subject.call_for_papers = create(:call_for_papers)
subject.venue = create(:venue) subject.venue = create(:venue)
subject.event_types = [] subject.event_types = []
@ -1075,8 +1078,9 @@ describe Conference do
subject.rooms = [create(:room)] subject.rooms = [create(:room)]
subject.tracks = [create(:track)] subject.tracks = [create(:track)]
subject.event_types = [create(:event_type)] subject.event_types = [create(:event_type)]
subject.registration_start_date = Date.today subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.today + 14 start_date: Date.today,
end_date: Date.today + 14)
subject.call_for_papers = create(:call_for_papers) subject.call_for_papers = create(:call_for_papers)
subject.venue = create(:venue) subject.venue = create(:venue)
subject.difficulty_levels = [] subject.difficulty_levels = []
@ -1098,8 +1102,9 @@ describe Conference do
subject.tracks = [create(:track)] subject.tracks = [create(:track)]
subject.event_types = [create(:event_type)] subject.event_types = [create(:event_type)]
subject.difficulty_levels = [create(:difficulty_level)] subject.difficulty_levels = [create(:difficulty_level)]
subject.registration_start_date = Date.today subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.today + 14 start_date: Date.today,
end_date: Date.today + 14)
subject.venue = create(:venue) subject.venue = create(:venue)
subject.call_for_papers = create(:call_for_papers) subject.call_for_papers = create(:call_for_papers)
subject.venue = create(:venue) subject.venue = create(:venue)
@ -1112,26 +1117,30 @@ describe Conference do
describe '#registration_weeks' do describe '#registration_weeks' do
it 'calculates new year' do it 'calculates new year' do
subject.registration_start_date = Date.new(2013, 12, 31) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2013, 12, 30) + 6 start_date: Date.new(2013, 12, 31),
end_date: Date.new(2013, 12, 30) + 6)
expect(subject.registration_weeks).to eq(1) expect(subject.registration_weeks).to eq(1)
end end
it 'is one if start and end are 6 days apart' do it 'is one if start and end are 6 days apart' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 6 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 6)
expect(subject.registration_weeks).to eq(1) expect(subject.registration_weeks).to eq(1)
end end
it 'is one if start and end date are the same' do it 'is one if start and end date are the same' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26))
expect(subject.registration_weeks).to eq(1) expect(subject.registration_weeks).to eq(1)
end end
it 'is two if start and end are 10 days apart' do it 'is two if start and end are 10 days apart' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 10 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 10)
expect(subject.registration_weeks).to eq(2) expect(subject.registration_weeks).to eq(2)
end end
end end
@ -1263,15 +1272,17 @@ describe Conference do
describe '#get_registrations_per_week' do describe '#get_registrations_per_week' do
it 'pads with zeros if there are no registrations' do it 'pads with zeros if there are no registrations' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 21 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 21)
expect(subject.get_registrations_per_week).to eq([0, 0, 0, 0]) expect(subject.get_registrations_per_week).to eq([0, 0, 0, 0])
end end
it 'summarized correct if there are no registrations in one week' do it 'summarized correct if there are no registrations in one week' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 28 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 28)
create(:registration, conference: subject, create(:registration, conference: subject,
created_at: Date.new(2014, 05, 26) + 7) created_at: Date.new(2014, 05, 26) + 7)
@ -1284,8 +1295,9 @@ describe Conference do
end end
it 'returns [1] if there is one registration on the first day' do it 'returns [1] if there is one registration on the first day' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 7 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 7)
create(:registration, conference: subject, create(:registration, conference: subject,
created_at: Date.new(2014, 05, 26)) created_at: Date.new(2014, 05, 26))
@ -1293,8 +1305,9 @@ describe Conference do
end end
it 'summarized correct if there are registrations every week' do it 'summarized correct if there are registrations every week' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 21 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 21)
create(:registration, conference: subject, created_at: Date.new(2014, 05, 26)) create(:registration, conference: subject, created_at: Date.new(2014, 05, 26))
create(:registration, conference: subject, create(:registration, conference: subject,
@ -1306,8 +1319,9 @@ describe Conference do
end end
it 'summarized correct if there are registrations every week except the first' do it 'summarized correct if there are registrations every week except the first' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 28 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 28)
create(:registration, conference: subject, create(:registration, conference: subject,
created_at: Date.new(2014, 05, 26) + 7) created_at: Date.new(2014, 05, 26) + 7)
@ -1320,8 +1334,9 @@ describe Conference do
end end
it 'pads left' do it 'pads left' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 35 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 35)
create(:registration, conference: subject, create(:registration, conference: subject,
created_at: Date.new(2014, 05, 26) + 21) created_at: Date.new(2014, 05, 26) + 21)
@ -1334,8 +1349,9 @@ describe Conference do
end end
it 'pads middle' do it 'pads middle' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 35 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 35)
create(:registration, conference: subject, create(:registration, conference: subject,
created_at: Date.new(2014, 05, 26)) created_at: Date.new(2014, 05, 26))
@ -1346,8 +1362,9 @@ describe Conference do
end end
it 'pads right' do it 'pads right' do
subject.registration_start_date = Date.new(2014, 05, 26) subject.registration_period = create(:registration_period,
subject.registration_end_date = Date.new(2014, 05, 26) + 35 start_date: Date.new(2014, 05, 26),
end_date: Date.new(2014, 05, 26) + 35)
create(:registration, conference: subject, create(:registration, conference: subject,
created_at: Date.new(2014, 05, 26)) created_at: Date.new(2014, 05, 26))
@ -1389,8 +1406,10 @@ describe Conference do
context 'open registration' do context 'open registration' do
before do before do
subject.registration_start_date = Date.today - 1 enrollment = create(:registration_period,
subject.registration_end_date = Date.today + 7 start_date: Date.today - 1,
end_date: Date.today + 7)
subject.registration_period = enrollment
end end
it '#registration_open? is true' do it '#registration_open? is true' do

View file

@ -2,9 +2,7 @@ require 'spec_helper'
describe 'conference/show.html.haml' do describe 'conference/show.html.haml' do
before(:each) do before(:each) do
allow(view).to receive(:date_string).and_return("January 17 - 21 2014") allow(view).to receive(:date_string).and_return("January 17 - 21 2014")
@conference = create(:conference, registration_description: 'Lorem Ipsum Dolor', @conference = create(:conference,
registration_start_date: Date.today,
registration_end_date: Date.tomorrow,
description: 'Lorem Ipsum', description: 'Lorem Ipsum',
sponsor_description: 'Lorem Ipsum Dolor', sponsor_description: 'Lorem Ipsum Dolor',
sponsor_email: 'example@example.com', sponsor_email: 'example@example.com',
@ -20,6 +18,10 @@ describe 'conference/show.html.haml' do
twitter: 'http://twitter.com', twitter: 'http://twitter.com',
public: true public: true
) )
@conference.registration_period = create(:registration_period,
description: 'Lorem Ipsum Dolor',
start_date: Date.today,
end_date: Date.tomorrow)
@conference.call_for_papers = create(:call_for_papers, conference: @conference, @conference.call_for_papers = create(:call_for_papers, conference: @conference,
include_cfp_in_splash: true) include_cfp_in_splash: true)
@conference.call_for_papers = create(:call_for_papers, conference: @conference, @conference.call_for_papers = create(:call_for_papers, conference: @conference,
@ -45,7 +47,7 @@ describe 'conference/show.html.haml' do
end end
it 'renders registration partial' do it 'renders registration partial' do
expect(view.content_for(:splash)).to include("#{@conference.registration_description}") expect(view.content_for(:splash)).to include("#{@conference.registration_period.description}")
expect(view).to render_template(partial: 'conference/_registration') expect(view).to render_template(partial: 'conference/_registration')
end end