mirror of
https://github.com/openSUSE/osem.git
synced 2026-08-13 19:54:02 +00:00
Refactoring Tickets
- Tickets now independent from registration - Implemented money gem #419
This commit is contained in:
parent
5485fe0e7f
commit
5f8a8ac6d9
63 changed files with 1581 additions and 573 deletions
3
Gemfile
3
Gemfile
|
|
@ -105,6 +105,9 @@ gem 'whenever', :require => false
|
||||||
# We use daemons to run scripts
|
# We use daemons to run scripts
|
||||||
gem 'daemons'
|
gem 'daemons'
|
||||||
|
|
||||||
|
# We use money-rails to encapsulate money in objects
|
||||||
|
gem 'money-rails'
|
||||||
|
|
||||||
# Use guard and spring for testing in development
|
# Use guard and spring for testing in development
|
||||||
group :development do
|
group :development do
|
||||||
# rspec Guard rules
|
# rspec Guard rules
|
||||||
|
|
|
||||||
10
Gemfile.lock
10
Gemfile.lock
|
|
@ -195,6 +195,15 @@ GEM
|
||||||
minitest (5.4.0)
|
minitest (5.4.0)
|
||||||
momentjs-rails (2.8.1)
|
momentjs-rails (2.8.1)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
|
monetize (0.3.0)
|
||||||
|
money (~> 6.1.0.beta1)
|
||||||
|
money (6.1.1)
|
||||||
|
i18n (~> 0.6.4)
|
||||||
|
money-rails (0.12.0)
|
||||||
|
activesupport (>= 3.0)
|
||||||
|
monetize (~> 0.3.0)
|
||||||
|
money (~> 6.1.1)
|
||||||
|
railties (>= 3.0)
|
||||||
multi_json (1.10.1)
|
multi_json (1.10.1)
|
||||||
multi_xml (0.5.5)
|
multi_xml (0.5.5)
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
|
|
@ -436,6 +445,7 @@ DEPENDENCIES
|
||||||
letter_opener
|
letter_opener
|
||||||
mina
|
mina
|
||||||
momentjs-rails (>= 2.8.1)
|
momentjs-rails (>= 2.8.1)
|
||||||
|
money-rails
|
||||||
mysql2
|
mysql2
|
||||||
omniauth
|
omniauth
|
||||||
omniauth-facebook
|
omniauth-facebook
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
//= require bootstrap-datetimepicker
|
//= require bootstrap-datetimepicker
|
||||||
//= require osem-datepickers
|
//= require osem-datepickers
|
||||||
//= require osem-datatables
|
//= require osem-datatables
|
||||||
|
//= require osem-tickets
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('a[disabled=disabled]').click(function(event){
|
$('a[disabled=disabled]').click(function(event){
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
$(function () {
|
$(function () {
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#registrations-datatable').dataTable();
|
$('#registrations-datatable').dataTable();
|
||||||
} );
|
});
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#users-datatable').dataTable();
|
$('#users-datatable').dataTable();
|
||||||
} );
|
});
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('#events-datatable').dataTable();
|
$('#events-datatable').dataTable();
|
||||||
} );
|
});
|
||||||
|
$(document).ready(function() {
|
||||||
|
$('#buyers-datatable').dataTable();
|
||||||
|
});
|
||||||
} );
|
} );
|
||||||
|
|
|
||||||
25
app/assets/javascripts/osem-tickets.js
Normal file
25
app/assets/javascripts/osem-tickets.js
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
function update_price($this){
|
||||||
|
var id = $this.data('id');
|
||||||
|
|
||||||
|
// Calculate price for row
|
||||||
|
var value = $this.val();
|
||||||
|
var price = $('#price_' + id).text();
|
||||||
|
$('#total_row_' + id).text(value * price);
|
||||||
|
|
||||||
|
// Calculate total price
|
||||||
|
var total = 0;
|
||||||
|
$('.total_row').each(function( index ) {
|
||||||
|
total += parseInt($(this).text());
|
||||||
|
});
|
||||||
|
$('#total_price').text(total);
|
||||||
|
}
|
||||||
|
|
||||||
|
$( document ).ready(function() {
|
||||||
|
$('.quantity').each(function() {
|
||||||
|
update_price($(this));
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.quantity').change(function() {
|
||||||
|
update_price($(this));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -17,13 +17,13 @@ module Admin
|
||||||
flash[:notice] = "Successfully updated Attended for #{@user.email}"
|
flash[:notice] = "Successfully updated Attended for #{@user.email}"
|
||||||
redirect_to admin_conference_registrations_path(@conference.short_title)
|
redirect_to admin_conference_registrations_path(@conference.short_title)
|
||||||
else
|
else
|
||||||
flash[:notice] = "Update Attended for #{@user.email} failed!"
|
flash[:notice] = "Update Attended for #{@user.email} failed!" \
|
||||||
|
"#{@registration.errors.full_messages.join('. ')}"
|
||||||
redirect_to admin_conference_registrations_path(@conference.short_title)
|
redirect_to admin_conference_registrations_path(@conference.short_title)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def edit; end
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@registration.update_attributes(registration_params)
|
@registration.update_attributes(registration_params)
|
||||||
|
|
@ -51,7 +51,7 @@ module Admin
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def set_user
|
def set_user
|
||||||
@user = User.where('id = ?', @registration.user_id).first
|
@user = User.find_by(id: @registration.user_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_params
|
def registration_params
|
||||||
|
|
@ -63,10 +63,7 @@ module Admin
|
||||||
qanswers_attributes: [],
|
qanswers_attributes: [],
|
||||||
user_attributes: [
|
user_attributes: [
|
||||||
:id, :name, :tshirt, :mobile, :volunteer_experience, :languages,
|
:id, :name, :tshirt, :mobile, :volunteer_experience, :languages,
|
||||||
:nickname, :affiliation ],
|
:nickname, :affiliation ])
|
||||||
supporter_registration_attributes: [
|
|
||||||
:id, :supporter_level_id, :code
|
|
||||||
])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
module Admin
|
|
||||||
class SupporterLevelsController < Admin::BaseController
|
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
|
||||||
authorize_resource through: :conference
|
|
||||||
|
|
||||||
def index
|
|
||||||
authorize! :update, SupporterLevel.new(conference_id: @conference.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show
|
|
||||||
render :supporter_levels
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
begin
|
|
||||||
@conference.update_attributes!(params[:conference])
|
|
||||||
redirect_to(admin_conference_supporter_levels_path(conference_id: @conference.short_title), notice: 'Supporter levels were successfully updated.')
|
|
||||||
rescue => e
|
|
||||||
redirect_to(admin_conference_supporter_levels_path(conference_id: @conference.short_title), alert: "Supporter levels update failed: #{e.message}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
module Admin
|
|
||||||
class SupportersController < Admin::BaseController
|
|
||||||
load_and_authorize_resource :conference, find_by: :short_title
|
|
||||||
load_and_authorize_resource through: :conference
|
|
||||||
|
|
||||||
def index
|
|
||||||
respond_to do |format|
|
|
||||||
format.html
|
|
||||||
format.json { render json: DatatableSupporters.new(@conference.supporter_registrations, view_context) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
params[:supporter_registration][:conference_id] = @conference.id
|
|
||||||
SupporterRegistration.create!(params[:supporter_registration])
|
|
||||||
redirect_to(admin_conference_supporters_path(conference_id: @conference.short_title), notice: "Supporter added")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
54
app/controllers/admin/tickets_controller.rb
Normal file
54
app/controllers/admin/tickets_controller.rb
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
module Admin
|
||||||
|
class TicketsController < Admin::BaseController
|
||||||
|
load_and_authorize_resource :conference, find_by: :short_title
|
||||||
|
load_and_authorize_resource :ticket, through: :conference
|
||||||
|
|
||||||
|
def index
|
||||||
|
authorize! :update, Ticket.new(conference_id: @conference.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
@ticket = @conference.tickets.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@ticket = @conference.tickets.new(ticket_params)
|
||||||
|
if @ticket.save(ticket_params)
|
||||||
|
redirect_to(admin_conference_tickets_path(conference_id: @conference.short_title),
|
||||||
|
notice: 'Ticket successfully created.')
|
||||||
|
else
|
||||||
|
flash[:alert] = "Creating Ticket failed: #{@ticket.errors.full_messages.join('. ')}."
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit; end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @ticket.update_attributes(ticket_params)
|
||||||
|
redirect_to(admin_conference_tickets_path(conference_id: @conference.short_title),
|
||||||
|
notice: 'Ticket successfully updated.')
|
||||||
|
else
|
||||||
|
flash[:alert] = "Ticket update failed: #{@ticket.errors.full_messages.join('. ')}."
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
if @ticket.destroy
|
||||||
|
redirect_to(admin_conference_tickets_path(conference_id: @conference.short_title),
|
||||||
|
notice: 'Ticket successfully destroyed.')
|
||||||
|
else
|
||||||
|
redirect_to(admin_conference_tickets_path(conference_id: @conference.short_title),
|
||||||
|
alert: "Ticket was successfully destroyed." \
|
||||||
|
"#{@ticket.errors.full_messages.join('. ')}.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def ticket_params
|
||||||
|
params[:ticket]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -2,17 +2,19 @@ class ConferenceRegistrationsController < ApplicationController
|
||||||
before_filter :verify_user
|
before_filter :verify_user
|
||||||
load_resource :conference, find_by: :short_title
|
load_resource :conference, find_by: :short_title
|
||||||
authorize_resource :conference_registrations, class: Registration
|
authorize_resource :conference_registrations, class: Registration
|
||||||
before_action :set_registration, only: [:edit, :update, :destroy]
|
before_action :set_registration, only: [:edit, :update, :destroy, :show]
|
||||||
before_action :set_workshops, only: [:new, :edit, :update, :create]
|
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@registration = current_user.registrations.build(conference_id: @conference.id)
|
@registration = current_user.registrations.build(conference_id: @conference.id)
|
||||||
@registration.build_supporter_registration
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit
|
def show
|
||||||
|
@workshops = @registration.workshops if @registration
|
||||||
|
@total_price = Ticket.total_price(@conference, current_user)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit; end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
user_attributes = registration_params[:user_attributes]
|
user_attributes = registration_params[:user_attributes]
|
||||||
params[:registration].delete :user_attributes
|
params[:registration].delete :user_attributes
|
||||||
|
|
@ -24,16 +26,13 @@ class ConferenceRegistrationsController < ApplicationController
|
||||||
# Trigger ahoy event
|
# Trigger ahoy event
|
||||||
ahoy.track 'Registered', title: 'New registration'
|
ahoy.track 'Registered', title: 'New registration'
|
||||||
|
|
||||||
# Send registration mail
|
if @conference.tickets.any?
|
||||||
if @conference.email_settings.send_on_registration?
|
redirect_to conference_tickets_path(@conference.short_title),
|
||||||
Mailbot.delay.registration_mail(@conference, current_user)
|
notice: 'You are now registered and will be receiving E-Mail notifications.'
|
||||||
|
else
|
||||||
|
redirect_to conference_conference_registrations_path(@conference.short_title),
|
||||||
|
notice: 'You are now registered and will be receiving E-Mail notifications.'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Set subscription for the conference
|
|
||||||
Subscription.create(conference_id: @conference.id, user_id: current_user.id)
|
|
||||||
|
|
||||||
redirect_to edit_conference_conference_registrations_path(@conference.short_title),
|
|
||||||
notice: 'You are now registered and will be receiving E-Mail notifications.'
|
|
||||||
else
|
else
|
||||||
flash[:alert] = "A error prohibited the registration for #{@conference.title}: "\
|
flash[:alert] = "A error prohibited the registration for #{@conference.title}: "\
|
||||||
"#{@registration.errors.full_messages.join('. ')}."
|
"#{@registration.errors.full_messages.join('. ')}."
|
||||||
|
|
@ -42,9 +41,9 @@ class ConferenceRegistrationsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if @registration.update(registration_params)
|
if @registration.update_attributes(registration_params)
|
||||||
redirect_to edit_conference_conference_registrations_path(@conference.short_title),
|
redirect_to conference_conference_registrations_path(@conference.short_title),
|
||||||
notice: 'Registration was successfully updated.'
|
notice: 'Registration was successfully updated.'
|
||||||
else
|
else
|
||||||
flash[:alert] = "A error prohibited the registration for #{@conference.title}: "\
|
flash[:alert] = "A error prohibited the registration for #{@conference.title}: "\
|
||||||
"#{@registration.errors.full_messages.join('. ')}."
|
"#{@registration.errors.full_messages.join('. ')}."
|
||||||
|
|
@ -53,19 +52,20 @@ class ConferenceRegistrationsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
@registration.destroy
|
if @registration.destroy
|
||||||
redirect_to root_path,
|
redirect_to root_path,
|
||||||
notice: "You are not registered for #{@conference.title} anymore!"
|
notice: "You are not registered for #{@conference.title} anymore!"
|
||||||
|
else
|
||||||
|
redirect_to root_path,
|
||||||
|
alert: "A error prohibited deleting the registration for #{@conference.title}: "\
|
||||||
|
"#{@registration.errors.full_messages.join('. ')}."
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def set_workshops
|
|
||||||
@workshops = @conference.events.where('require_registration = ? AND state LIKE ?', true, 'confirmed')
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_registration
|
def set_registration
|
||||||
@registration = current_user.registrations.where(conference_id: @conference.id).first
|
@registration = current_user.registrations.find_by(conference_id: @conference.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_params
|
def registration_params
|
||||||
|
|
@ -77,9 +77,7 @@ class ConferenceRegistrationsController < ApplicationController
|
||||||
qanswers_attributes: [],
|
qanswers_attributes: [],
|
||||||
event_ids: [],
|
event_ids: [],
|
||||||
user_attributes: [
|
user_attributes: [
|
||||||
:id, :name, :tshirt, :mobile, :volunteer_experience, :languages],
|
:id, :name, :tshirt, :mobile, :volunteer_experience, :languages]
|
||||||
supporter_registration_attributes: [
|
)
|
||||||
:id, :supporter_level_id, :code
|
|
||||||
])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
29
app/controllers/ticket_purchases_controller.rb
Normal file
29
app/controllers/ticket_purchases_controller.rb
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
class TicketPurchasesController < ApplicationController
|
||||||
|
before_filter :verify_user
|
||||||
|
load_resource :conference, find_by: :short_title
|
||||||
|
authorize_resource :conference_registrations, class: Registration
|
||||||
|
|
||||||
|
def create
|
||||||
|
message = TicketPurchase.purchase(@conference, current_user, params[:tickets][0])
|
||||||
|
if message.blank?
|
||||||
|
redirect_to conference_conference_registrations_path(@conference.short_title),
|
||||||
|
notice: "Congratulations, you have successfully purchased a ticket! " \
|
||||||
|
"You can pay it cash on check in! Thank you for supporting #{@conference.title}!"
|
||||||
|
else
|
||||||
|
redirect_to conference_conference_registrations_path(@conference.short_title),
|
||||||
|
alert: "Oops, something went wrong with your purchase! #{message}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@ticket_purchases = current_user.ticket_purchases.find_by(ticket_id: params[:id])
|
||||||
|
if @ticket_purchases.destroy
|
||||||
|
redirect_to conference_conference_registrations_path(@conference.short_title),
|
||||||
|
notice: 'Ticket successfully destroyed.'
|
||||||
|
else
|
||||||
|
redirect_to conference_conference_registrations_path(@conference.short_title),
|
||||||
|
notice: "A error prohibited deleting your purchase! "\
|
||||||
|
"#{@ticket_purchases.errors.full_messages.join('. ')}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
8
app/controllers/tickets_controller.rb
Normal file
8
app/controllers/tickets_controller.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
class TicketsController < ApplicationController
|
||||||
|
before_filter :verify_user
|
||||||
|
load_resource :conference, find_by: :short_title
|
||||||
|
load_resource :tickets, class: Ticket
|
||||||
|
authorize_resource :conference_registrations, class: Registration
|
||||||
|
|
||||||
|
def index; end
|
||||||
|
end
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
module RegistrationHelper
|
|
||||||
def generate_supporter_level_js(conference)
|
|
||||||
str = ""
|
|
||||||
conference.supporter_levels.map do |t|
|
|
||||||
next if t.url.empty?
|
|
||||||
|
|
||||||
str += "if ($('#registration_supporter_registration_attributes_supporter_level_id option:selected').text() == '#{t.title}') {\n"
|
|
||||||
str += "console.log('#{t.title}');\n"
|
|
||||||
str += "str = 'If you have a confirmation or registration code, enter it here. Otherwise, you can purchase a <i>#{t.title}</i> ticket <a href=\"#{t.url}\" target=_new>here</a>, if you need to.';\n"
|
|
||||||
str += "}\n\n"
|
|
||||||
end.join("\n")
|
|
||||||
str
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -97,7 +97,7 @@ class Ability
|
||||||
can :manage, Room, conference_id: conf_ids_for_organizer + conf_ids_for_cfp
|
can :manage, Room, conference_id: conf_ids_for_organizer + conf_ids_for_cfp
|
||||||
can :manage, Sponsor, conference_id: conf_ids_for_organizer
|
can :manage, Sponsor, conference_id: conf_ids_for_organizer
|
||||||
can :manage, SponsorshipLevel, conference_id: conf_ids_for_organizer
|
can :manage, SponsorshipLevel, conference_id: conf_ids_for_organizer
|
||||||
can :manage, SupporterLevel, conference_id: conf_ids_for_organizer
|
can :manage, Ticket, conference_id: conf_ids_for_organizer
|
||||||
can :manage, Target, conference_id: conf_ids_for_organizer
|
can :manage, Target, conference_id: conf_ids_for_organizer
|
||||||
can :index, Commercial, commercialable_type: 'Conference'
|
can :index, Commercial, commercialable_type: 'Conference'
|
||||||
can :manage, Commercial, commercialable_type: 'Conference', commercialable_id: conf_ids_for_organizer
|
can :manage, Commercial, commercialable_type: 'Conference', commercialable_id: conf_ids_for_organizer
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ class Conference < ActiveRecord::Base
|
||||||
|
|
||||||
attr_accessible :title, :short_title, :timezone, :html_export_path,
|
attr_accessible :title, :short_title, :timezone, :html_export_path,
|
||||||
: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,
|
||||||
:supporter_levels_attributes, :social_events_attributes, :event_types_attributes,
|
:tickets_attributes, :social_events_attributes, :event_types_attributes,
|
||||||
: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,
|
||||||
|
|
@ -33,12 +33,25 @@ class Conference < ActiveRecord::Base
|
||||||
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
|
||||||
has_many :supporter_registrations, dependent: :destroy
|
has_many :ticket_purchases
|
||||||
has_many :supporter_levels, dependent: :destroy
|
has_many :supporters, through: :ticket_purchases, source: :user
|
||||||
|
has_many :tickets, dependent: :destroy
|
||||||
has_many :dietary_choices, dependent: :destroy
|
has_many :dietary_choices, dependent: :destroy
|
||||||
has_many :events, dependent: :destroy
|
has_many :events, dependent: :destroy do
|
||||||
|
def workshops
|
||||||
|
where(require_registration: true, state: :confirmed)
|
||||||
|
end
|
||||||
|
|
||||||
|
def confirmed
|
||||||
|
where(state: :confirmed)
|
||||||
|
end
|
||||||
|
end
|
||||||
has_many :event_users, through: :events
|
has_many :event_users, through: :events
|
||||||
has_many :speakers, -> { distinct }, through: :event_users, source: :user
|
has_many :speakers, -> { distinct }, through: :event_users, source: :user do
|
||||||
|
def confirmed
|
||||||
|
joins(:events).where(events: { state: :confirmed })
|
||||||
|
end
|
||||||
|
end
|
||||||
has_many :event_types, dependent: :destroy
|
has_many :event_types, dependent: :destroy
|
||||||
has_many :tracks, dependent: :destroy
|
has_many :tracks, dependent: :destroy
|
||||||
has_many :difficulty_levels, dependent: :destroy
|
has_many :difficulty_levels, dependent: :destroy
|
||||||
|
|
@ -62,7 +75,7 @@ class Conference < ActiveRecord::Base
|
||||||
accepts_nested_attributes_for :social_events, allow_destroy: true
|
accepts_nested_attributes_for :social_events, allow_destroy: true
|
||||||
accepts_nested_attributes_for :venue
|
accepts_nested_attributes_for :venue
|
||||||
accepts_nested_attributes_for :dietary_choices, allow_destroy: true
|
accepts_nested_attributes_for :dietary_choices, allow_destroy: true
|
||||||
accepts_nested_attributes_for :supporter_levels, allow_destroy: true
|
accepts_nested_attributes_for :tickets, allow_destroy: true
|
||||||
accepts_nested_attributes_for :sponsorship_levels, allow_destroy: true
|
accepts_nested_attributes_for :sponsorship_levels, allow_destroy: true
|
||||||
accepts_nested_attributes_for :sponsors, allow_destroy: true
|
accepts_nested_attributes_for :sponsors, allow_destroy: true
|
||||||
accepts_nested_attributes_for :event_types, allow_destroy: true
|
accepts_nested_attributes_for :event_types, allow_destroy: true
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
class DatatableSupporters < Datatable
|
|
||||||
def data
|
|
||||||
arr = []
|
|
||||||
items.each do |i|
|
|
||||||
item = []
|
|
||||||
if i.name.blank?
|
|
||||||
if !i.registration.nil? && !i.registration.user.nil?
|
|
||||||
item << i.registration.user.name
|
|
||||||
else
|
|
||||||
item << 'Unknown'
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
item << i.name
|
|
||||||
end
|
|
||||||
|
|
||||||
if i.email.blank?
|
|
||||||
if !i.registration.nil? && !i.registration.user.nil?
|
|
||||||
item << i.registration.user.email
|
|
||||||
else
|
|
||||||
item << 'Unknown'
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
item << i.email
|
|
||||||
end
|
|
||||||
|
|
||||||
item << i.supporter_level.title
|
|
||||||
item << i.code
|
|
||||||
item << i.code_is_valid
|
|
||||||
arr << item
|
|
||||||
end
|
|
||||||
|
|
||||||
arr
|
|
||||||
end
|
|
||||||
|
|
||||||
def columns
|
|
||||||
['name', 'email', 'name', 'name', 'name']
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -206,6 +206,14 @@ class Event < ActiveRecord::Base
|
||||||
alert
|
alert
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def speaker_names
|
||||||
|
result = []
|
||||||
|
speakers.each do |speaker|
|
||||||
|
result.push(speaker.name)
|
||||||
|
end
|
||||||
|
result.to_sentence
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def abstract_limit
|
def abstract_limit
|
||||||
|
|
|
||||||
6
app/models/events_registration.rb
Normal file
6
app/models/events_registration.rb
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
class EventsRegistration < ActiveRecord::Base
|
||||||
|
attr_accessible :registration_id, :event_id
|
||||||
|
|
||||||
|
belongs_to :registration
|
||||||
|
belongs_to :event
|
||||||
|
end
|
||||||
|
|
@ -3,21 +3,21 @@ class Registration < ActiveRecord::Base
|
||||||
belongs_to :conference
|
belongs_to :conference
|
||||||
belongs_to :dietary_choice
|
belongs_to :dietary_choice
|
||||||
|
|
||||||
has_one :supporter_registration
|
|
||||||
has_one :supporter_level, through: :supporter_registration
|
|
||||||
has_and_belongs_to_many :social_events
|
has_and_belongs_to_many :social_events
|
||||||
has_and_belongs_to_many :events
|
has_and_belongs_to_many :events
|
||||||
has_and_belongs_to_many :qanswers
|
has_and_belongs_to_many :qanswers
|
||||||
has_and_belongs_to_many :vchoices
|
has_and_belongs_to_many :vchoices
|
||||||
|
|
||||||
|
has_many :events_registrations
|
||||||
|
has_many :workshops, through: :events_registrations, source: :event
|
||||||
|
|
||||||
attr_accessible :user_id, :conference_id, :attending_social_events, :attending_with_partner,
|
attr_accessible :user_id, :conference_id, :attending_social_events, :attending_with_partner,
|
||||||
:using_affiliated_lodging, :arrival, :departure, :user_attributes, :attended,
|
:using_affiliated_lodging, :arrival, :departure, :user_attributes, :attended,
|
||||||
:other_dietary_choice, :dietary_choice_id, :handicapped_access_required,
|
:other_dietary_choice, :dietary_choice_id, :handicapped_access_required,
|
||||||
:supporter_registration_attributes, :social_event_ids, :other_special_needs,
|
:social_event_ids, :other_special_needs,
|
||||||
:event_ids, :volunteer, :vchoice_ids, :qanswer_ids, :qanswers_attributes
|
:event_ids, :volunteer, :vchoice_ids, :qanswer_ids, :qanswers_attributes
|
||||||
|
|
||||||
accepts_nested_attributes_for :user
|
accepts_nested_attributes_for :user
|
||||||
accepts_nested_attributes_for :supporter_registration
|
|
||||||
accepts_nested_attributes_for :social_events
|
accepts_nested_attributes_for :social_events
|
||||||
accepts_nested_attributes_for :qanswers
|
accepts_nested_attributes_for :qanswers
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ class Registration < ActiveRecord::Base
|
||||||
|
|
||||||
validates_uniqueness_of :user_id, scope: :conference_id, message: 'already Registered!'
|
validates_uniqueness_of :user_id, scope: :conference_id, message: 'already Registered!'
|
||||||
|
|
||||||
after_create :set_week
|
after_create :set_week, :subscribe_to_conference, :send_registration_mail
|
||||||
|
|
||||||
def week
|
def week
|
||||||
created_at.strftime('%W').to_i
|
created_at.strftime('%W').to_i
|
||||||
|
|
@ -38,6 +38,16 @@ class Registration < ActiveRecord::Base
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def subscribe_to_conference
|
||||||
|
Subscription.create(conference_id: conference.id, user_id: user.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_registration_mail
|
||||||
|
if conference.email_settings.send_on_registration?
|
||||||
|
Mailbot.delay.registration_mail(conference, user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def set_week
|
def set_week
|
||||||
self.week = created_at.strftime('%W')
|
self.week = created_at.strftime('%W')
|
||||||
save!
|
save!
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
class SupporterLevel < ActiveRecord::Base
|
|
||||||
belongs_to :conference
|
|
||||||
has_many :supporter_registrations
|
|
||||||
|
|
||||||
attr_accessible :conference, :title, :url, :description, :ticket_price, :conference_id
|
|
||||||
end
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
class SupporterRegistration < ActiveRecord::Base
|
|
||||||
belongs_to :supporter_level
|
|
||||||
belongs_to :registration
|
|
||||||
before_save :set_attributes_from_user
|
|
||||||
|
|
||||||
attr_accessible :registration, :supporter_level_id, :name, :email, :supporter_level, :code, :code_is_valid, :conference_id
|
|
||||||
|
|
||||||
def set_attributes_from_user
|
|
||||||
self.name ||= registration.try(:user).try(:name)
|
|
||||||
self.email ||= registration.try(:user).try(:email)
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
59
app/models/ticket.rb
Normal file
59
app/models/ticket.rb
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
class Ticket < ActiveRecord::Base
|
||||||
|
belongs_to :conference
|
||||||
|
has_many :ticket_purchases
|
||||||
|
has_many :buyers, -> { distinct }, through: :ticket_purchases, source: :user
|
||||||
|
|
||||||
|
attr_accessible :conference, :title, :url, :description, :conference_id, :price_cents, :price_currency, :price
|
||||||
|
monetize :price_cents, with_model_currency: :price_currency
|
||||||
|
|
||||||
|
# This validation is for the sake of simplicity.
|
||||||
|
# If we would allow different currencies per conference we also have to handle convertions between currencies!
|
||||||
|
validate :tickets_of_conference_have_same_currency
|
||||||
|
|
||||||
|
validates :price_cents, :price_currency, :title, presence: true
|
||||||
|
|
||||||
|
validates_numericality_of :price_cents, greater_than: 0
|
||||||
|
|
||||||
|
def bought?(user)
|
||||||
|
buyers.include?(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def paid?(user)
|
||||||
|
ticket_purchases.where(user_id: user.id, paid: false).count == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def quantity_bought_by(user)
|
||||||
|
result = ticket_purchases.where(user_id: user.id).first
|
||||||
|
result ? result.quantity : 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def total_price(user)
|
||||||
|
quantity_bought_by(user) * price
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.total_price(conference, user)
|
||||||
|
tickets = Ticket.where(conference_id: conference.id)
|
||||||
|
result = nil
|
||||||
|
begin
|
||||||
|
tickets.each do |ticket|
|
||||||
|
price = ticket.total_price(user)
|
||||||
|
if result
|
||||||
|
result += price unless price.zero?
|
||||||
|
else
|
||||||
|
result = price
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue Money::Bank::UnknownRate
|
||||||
|
result = Money.new(-1, 'USD')
|
||||||
|
end
|
||||||
|
result ? result : Money.new(0, 'USD')
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def tickets_of_conference_have_same_currency
|
||||||
|
unless Ticket.where(conference_id: conference_id).all?{|t| t.price_currency == self.price_currency }
|
||||||
|
errors.add(:price_currency, 'Currency is different from the exist ticktes of this conference.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
51
app/models/ticket_purchase.rb
Normal file
51
app/models/ticket_purchase.rb
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
class TicketPurchase < ActiveRecord::Base
|
||||||
|
belongs_to :ticket
|
||||||
|
belongs_to :user
|
||||||
|
belongs_to :conference
|
||||||
|
|
||||||
|
attr_accessible :ticket_id, :user_id, :conference_id, :paid, :quantity
|
||||||
|
|
||||||
|
validates :ticket_id, :user_id, :conference_id, :quantity, presence: true
|
||||||
|
|
||||||
|
validates_numericality_of :quantity, greater_than: 0
|
||||||
|
|
||||||
|
validates_uniqueness_of :user_id,
|
||||||
|
scope: :ticket_id,
|
||||||
|
message: 'already bought this ticket!'
|
||||||
|
|
||||||
|
def self.purchase(conference, user, purchases)
|
||||||
|
errors = []
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
conference.tickets.each do |ticket|
|
||||||
|
quantity = purchases[ticket.id.to_s].to_i
|
||||||
|
if ticket.bought?(user)
|
||||||
|
purchase = update_quantity(conference, quantity, ticket, user)
|
||||||
|
else
|
||||||
|
purchase = purchase_ticket(conference, quantity, ticket, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
if purchase && !purchase.save
|
||||||
|
errors.push(purchase.errors.full_messages)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
errors.join('. ')
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.purchase_ticket(conference, quantity, ticket, user)
|
||||||
|
purchase = new(ticket_id: ticket.id,
|
||||||
|
conference_id: conference.id,
|
||||||
|
user_id: user.id,
|
||||||
|
quantity: quantity) if quantity > 0
|
||||||
|
purchase
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.update_quantity(conference, quantity, ticket, user)
|
||||||
|
purchase = TicketPurchase.where(ticket_id: ticket.id,
|
||||||
|
conference_id: conference.id,
|
||||||
|
user_id: user.id).first
|
||||||
|
|
||||||
|
purchase.quantity = quantity if quantity > 0
|
||||||
|
purchase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -22,6 +22,8 @@ class User < ActiveRecord::Base
|
||||||
has_many :event_users, dependent: :destroy
|
has_many :event_users, dependent: :destroy
|
||||||
has_many :events, -> { uniq }, through: :event_users
|
has_many :events, -> { uniq }, through: :event_users
|
||||||
has_many :registrations, dependent: :destroy
|
has_many :registrations, dependent: :destroy
|
||||||
|
has_many :ticket_purchases
|
||||||
|
has_many :tickets, through: :ticket_purchases, source: :ticket
|
||||||
has_many :votes, dependent: :destroy
|
has_many :votes, dependent: :destroy
|
||||||
has_many :voted_events, through: :votes, source: :events
|
has_many :voted_events, through: :votes, source: :events
|
||||||
has_many :subscriptions, dependent: :destroy
|
has_many :subscriptions, dependent: :destroy
|
||||||
|
|
@ -29,6 +31,13 @@ class User < ActiveRecord::Base
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
|
||||||
|
# Returns the ticket purchased ticket
|
||||||
|
# ====Returns
|
||||||
|
# * +TicketUser::ActiveRecord_Relation+ -> user
|
||||||
|
def ticket(id)
|
||||||
|
ticket_purchases.where(ticket_id: id).first
|
||||||
|
end
|
||||||
|
|
||||||
# Searches for user based on email. Returns found user or new user.
|
# Searches for user based on email. Returns found user or new user.
|
||||||
# ====Returns
|
# ====Returns
|
||||||
# * +User::ActiveRecord_Relation+ -> user
|
# * +User::ActiveRecord_Relation+ -> user
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,6 @@
|
||||||
= u.input :nickname, as: :string
|
= u.input :nickname, as: :string
|
||||||
= u.input :affiliation, placeholder: 'Company/User Group/nothing', as: :string
|
= u.input :affiliation, placeholder: 'Company/User Group/nothing', as: :string
|
||||||
= f.inputs 'Registration Information' do
|
= f.inputs 'Registration Information' do
|
||||||
- if @conference.use_supporter_levels? and @conference.supporter_levels.length > 0
|
|
||||||
= f.semantic_fields_for :supporter_registration do |reg|
|
|
||||||
= reg.input :supporter_level, as: :select, collection: @conference.supporter_levels
|
|
||||||
%span#supporter-link.help-block
|
|
||||||
- @conference.questions.each do |q|
|
- @conference.questions.each do |q|
|
||||||
%h5
|
%h5
|
||||||
= "Q: #{q.title}"
|
= "Q: #{q.title}"
|
||||||
|
|
@ -33,10 +29,3 @@
|
||||||
%br
|
%br
|
||||||
= f.input :social_events, as: :check_boxes, label: false, collection: @conference.social_events
|
= f.input :social_events, as: :check_boxes, label: false, collection: @conference.social_events
|
||||||
= f.action :submit, button_html: { value: 'Edit Registration', class: 'btn btn-primary' }
|
= f.action :submit, button_html: { value: 'Edit Registration', class: 'btn btn-primary' }
|
||||||
:javascript
|
|
||||||
$("#registration_supporter_registration_attributes_supporter_level_id").change(function () {
|
|
||||||
var str = "";
|
|
||||||
#{generate_supporter_level_js @conference}
|
|
||||||
$("#supporter-link").html(str);
|
|
||||||
})
|
|
||||||
.trigger('change');
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@
|
||||||
%th #
|
%th #
|
||||||
%th Name
|
%th Name
|
||||||
%th E-Mail
|
%th E-Mail
|
||||||
%th Ticket
|
|
||||||
%th Arrival
|
%th Arrival
|
||||||
%th Departure
|
%th Departure
|
||||||
%th Attended
|
%th Attended
|
||||||
|
|
@ -32,9 +31,6 @@
|
||||||
= registration.name
|
= registration.name
|
||||||
%td
|
%td
|
||||||
= registration.email
|
= registration.email
|
||||||
%td
|
|
||||||
- if registration.supporter_level
|
|
||||||
= registration.supporter_level.title
|
|
||||||
%td
|
%td
|
||||||
- if registration.arrival
|
- if registration.arrival
|
||||||
= registration.arrival.strftime("%d %b %H:%M")
|
= registration.arrival.strftime("%d %b %H:%M")
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<div class="nested-fields">
|
|
||||||
<%= f.inputs do %>
|
|
||||||
<%= f.input :title%>
|
|
||||||
<%= f.input :url %>
|
|
||||||
<%= f.input :description, hint: markdown_hint, input_html: { data: { provide: "markdown-editable" } } %>
|
|
||||||
<%= f.input :ticket_price, hint: 'Please enter price with currency symbol.
|
|
||||||
For example, $200,₹300' %>
|
|
||||||
<%= remove_association_link :supporter_level, f %>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
.row
|
|
||||||
.col-md-8
|
|
||||||
= semantic_form_for(@conference, :url => admin_conference_supporter_level_path(@conference.short_title, @conference.supporter_levels)) do |f|
|
|
||||||
= f.input :use_supporter_levels, :label => false
|
|
||||||
= f.input :include_tickets_in_splash, hint: 'On setting this true you will enable the tickets to be displayed on the splash page'
|
|
||||||
= dynamic_association :supporter_levels, "Supporter Levels", f
|
|
||||||
= f.action :submit, :as => :button, :button_html => {:class => "btn btn-primary"}
|
|
||||||
5
app/views/admin/tickets/_form.html.haml
Normal file
5
app/views/admin/tickets/_form.html.haml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
= f.input :title
|
||||||
|
= f.input :description, input_html: { rows: 5, data: { provide: "markdown-editable" } }
|
||||||
|
= f.input :price
|
||||||
|
= f.input :price_currency, as: :select, class: 'form-control', collection: ['USD', 'EUR', 'GBP', 'INR', 'CNY'], include_blank: false
|
||||||
|
= f.action :submit, as: :button, button_html: { class: 'btn btn-primary' }
|
||||||
6
app/views/admin/tickets/edit.html.haml
Normal file
6
app/views/admin/tickets/edit.html.haml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
%h1
|
||||||
|
Edit Ticket
|
||||||
|
.row
|
||||||
|
.col-md-8
|
||||||
|
= semantic_form_for(@ticket, :url => admin_conference_ticket_path(@conference.short_title, @ticket)) do |f|
|
||||||
|
= render partial: 'form', locals: { f: f }
|
||||||
38
app/views/admin/tickets/index.html.haml
Normal file
38
app/views/admin/tickets/index.html.haml
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
%h1 Tickets
|
||||||
|
%p.lead
|
||||||
|
If you add Tickets to your Conference, people will be redirected after registration to a page where they can purchase tickets.
|
||||||
|
- if @conference.tickets.any?
|
||||||
|
.row
|
||||||
|
.col-md-12
|
||||||
|
%table.table
|
||||||
|
%thead
|
||||||
|
%th #
|
||||||
|
%th Title
|
||||||
|
%th Price
|
||||||
|
%th Buyer
|
||||||
|
%th Show
|
||||||
|
%th Edit
|
||||||
|
%th Delete
|
||||||
|
%tbody
|
||||||
|
- @conference.tickets.each_with_index do |ticket, index|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= index + 1
|
||||||
|
%td
|
||||||
|
= ticket.title
|
||||||
|
%td
|
||||||
|
= humanized_money_with_symbol ticket.price
|
||||||
|
%td
|
||||||
|
= ticket.buyers.count
|
||||||
|
%td
|
||||||
|
= link_to 'Show', admin_conference_ticket_path(@conference.short_title, ticket.id),
|
||||||
|
method: :get, class: 'btn btn-success'
|
||||||
|
%td
|
||||||
|
= link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, ticket.id),
|
||||||
|
method: :get, class: 'btn btn-primary'
|
||||||
|
%td
|
||||||
|
= link_to 'Delete', admin_conference_ticket_path(@conference.short_title, ticket.id),
|
||||||
|
method: :delete, class: 'btn btn-danger', data: { confirm: "Do you really want to delete the Ticket for #{ticket.title}?" }
|
||||||
|
|
||||||
|
= link_to 'Add Ticket', new_admin_conference_ticket_path, class: 'btn btn-success'
|
||||||
|
|
||||||
6
app/views/admin/tickets/new.html.haml
Normal file
6
app/views/admin/tickets/new.html.haml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
%h1
|
||||||
|
New Ticket
|
||||||
|
.row
|
||||||
|
.col-md-8
|
||||||
|
= semantic_form_for(@ticket, :url => admin_conference_tickets_path(@conference.short_title, @ticket)) do |f|
|
||||||
|
= render partial: 'form', locals: { f: f }
|
||||||
33
app/views/admin/tickets/show.html.haml
Normal file
33
app/views/admin/tickets/show.html.haml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
%h1
|
||||||
|
= @ticket.title
|
||||||
|
%small
|
||||||
|
= humanized_money_with_symbol @ticket.price
|
||||||
|
- if @ticket.description.present?
|
||||||
|
%p.lead
|
||||||
|
= markdown(@ticket.description)
|
||||||
|
|
||||||
|
%h4 The following persons bought this ticket:
|
||||||
|
%table.table#buyers-datatable
|
||||||
|
%thead
|
||||||
|
%th #
|
||||||
|
%th Name
|
||||||
|
%th E-Mail
|
||||||
|
%th Affiliation
|
||||||
|
%th Paid
|
||||||
|
%tbody
|
||||||
|
- @ticket.buyers.each_with_index do |buyer, index|
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
= index + 1
|
||||||
|
%td
|
||||||
|
= buyer.name
|
||||||
|
%span.label.label-success
|
||||||
|
= buyer.ticket_purchases.find_by(ticket_id: @ticket.id).quantity
|
||||||
|
%td
|
||||||
|
= buyer.email
|
||||||
|
%td
|
||||||
|
= buyer.affiliation
|
||||||
|
%td
|
||||||
|
= @ticket.paid?(buyer)
|
||||||
|
= link_to 'Edit', edit_admin_conference_ticket_path(@conference.short_title, @ticket.id),
|
||||||
|
method: :get, class: 'btn btn-primary'
|
||||||
|
|
@ -17,6 +17,6 @@
|
||||||
= link_to "Modify Registration for #{@conference.short_title}", edit_conference_conference_registrations_path(@conference.short_title), class: "btn btn-success btn-lg", target: '_blank'
|
= link_to "Modify Registration for #{@conference.short_title}", edit_conference_conference_registrations_path(@conference.short_title), class: "btn btn-success btn-lg", target: '_blank'
|
||||||
- else
|
- else
|
||||||
= link_to "Register for #{@conference.short_title}", new_conference_conference_registrations_path(@conference.short_title), class: "btn btn-success btn-lg", target: '_blank'
|
= link_to "Register for #{@conference.short_title}", new_conference_conference_registrations_path(@conference.short_title), class: "btn btn-success btn-lg", target: '_blank'
|
||||||
- if @conference.use_supporter_levels?
|
- if @conference.tickets.any?
|
||||||
- if @conference.include_tickets_in_splash?
|
- if @conference.include_tickets_in_splash?
|
||||||
= render 'tickets'
|
= render 'tickets'
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,15 @@
|
||||||
%div.row
|
%div.row
|
||||||
%h3 Tickets
|
%h3 Tickets
|
||||||
-if !@conference.ticket_description.blank?
|
-if @conference.ticket_description.present?
|
||||||
.lead
|
.lead
|
||||||
= markdown(@conference.ticket_description)
|
= markdown(@conference.ticket_description)
|
||||||
- @conference.supporter_levels.each do |s|
|
- @conference.tickets.each do |ticket|
|
||||||
%div.col-md-6
|
%div.col-md-6
|
||||||
- if !s.title.blank?
|
- if ticket.title.present?
|
||||||
%h4 #{ s.title }
|
%h4 #{ ticket.title }
|
||||||
-if !s.description.blank?
|
- if ticket.description.present?
|
||||||
.lead #{ s.description }
|
.lead
|
||||||
- if !s.url.blank?
|
= markdown(ticket.description)
|
||||||
%div.btn-group
|
%div.btn-group
|
||||||
= link_to "Buy Ticket", s.url, class: 'btn btn-success', target: '_blank'
|
= link_to "Buy Ticket", conference_tickets_path(@conference.short_title), class: 'btn btn-success'
|
||||||
- if !s.ticket_price.blank?
|
= button_tag "#{humanized_money_with_symbol ticket.price}", class: 'btn btn-success'
|
||||||
= button_tag "#{s.ticket_price}", class: 'btn btn-success'
|
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,11 @@
|
||||||
- if @conference.questions
|
- if @conference.questions
|
||||||
= render partial: 'questions', locals: { f: f }
|
= render partial: 'questions', locals: { f: f }
|
||||||
%br
|
%br
|
||||||
- if @conference.use_supporter_levels? && @conference.supporter_levels.length > 0
|
|
||||||
= f.semantic_fields_for :supporter_registration do |reg|
|
|
||||||
= reg.input :supporter_level, as: :select, collection: @conference.supporter_levels
|
|
||||||
%span#supporter-link.help-block
|
|
||||||
|
|
||||||
- if @workshops.count > 0
|
- if @conference.events.workshops.any?
|
||||||
=f.inputs 'Register to Workshops' do
|
=f.inputs 'Register to Workshops' do
|
||||||
= f.input :events, as: :check_boxes, label: false, collection: @workshops
|
= f.input :events, as: :check_boxes, label: false, collection: @conference.events.workshops
|
||||||
|
|
||||||
= f.inputs 'Travel Info' do
|
= f.inputs 'Travel Info' do
|
||||||
= f.input :arrival, as: :string, input_html: { value: (f.object.arrival.to_formatted_s(:db_without_seconds) unless f.object.arrival.nil?), id: 'registration-arrival-datepicker', readonly: 'readonly' }
|
= f.input :arrival, as: :string, input_html: { value: (f.object.arrival.to_formatted_s(:db_without_seconds) unless f.object.arrival.nil?), id: 'registration-arrival-datepicker', readonly: 'readonly' }
|
||||||
= f.input :departure, as: :string, input_html: { value: (f.object.departure.to_formatted_s(:db_without_seconds) unless f.object.departure.nil?), id: 'registration-departure-datepicker', readonly: 'readonly' }
|
= f.input :departure, as: :string, input_html: { value: (f.object.departure.to_formatted_s(:db_without_seconds) unless f.object.departure.nil?), id: 'registration-departure-datepicker', readonly: 'readonly' }
|
||||||
|
|
||||||
:javascript
|
|
||||||
$("#registration_supporter_registration_attributes_supporter_level_id").change(function () {
|
|
||||||
var str = "";
|
|
||||||
#{generate_supporter_level_js @conference}
|
|
||||||
$("#supporter-link").html(str);
|
|
||||||
}).trigger('change');
|
|
||||||
|
|
|
||||||
21
app/views/conference_registrations/_ticket.html.haml
Normal file
21
app/views/conference_registrations/_ticket.html.haml
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
%tr
|
||||||
|
%td.col-sm-8.col-md-6
|
||||||
|
.media
|
||||||
|
.media-body
|
||||||
|
%h4.media-heading
|
||||||
|
= ticket.title
|
||||||
|
%h5.media-heading
|
||||||
|
-if !ticket.description.blank?
|
||||||
|
= markdown(ticket.description)
|
||||||
|
%td.col-sm-1.col-md-1
|
||||||
|
= text_field_tag("tickets[][#{ticket.id}]", 0, type: 'number', min: 0,
|
||||||
|
class: 'form-control quantity', 'data-id' => ticket.id)
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
= ticket.price.symbol
|
||||||
|
%span{id: "price_#{ticket.id}"}
|
||||||
|
= humanized_money ticket.price
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%strong
|
||||||
|
= ticket.price.symbol
|
||||||
|
%span.total_row{id: "total_row_#{ticket.id}"}
|
||||||
|
0
|
||||||
26
app/views/conference_registrations/_tickets.html.haml
Normal file
26
app/views/conference_registrations/_tickets.html.haml
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
= form_tag(conference_ticket_purchases_path, method: :post) do |f|
|
||||||
|
%table.table.table-hover
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Ticket
|
||||||
|
%th Quantity
|
||||||
|
%th Price
|
||||||
|
%th Total
|
||||||
|
%tbody
|
||||||
|
- tickets.each do |ticket|
|
||||||
|
= render partial: 'ticket', f: f, locals: { ticket: ticket }
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%td
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%h4
|
||||||
|
Total
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%h4
|
||||||
|
%strong
|
||||||
|
%span{ id: 'total_price' }
|
||||||
|
0
|
||||||
|
%p
|
||||||
|
= button_tag(type: 'submit', class: 'btn btn-success btn-lg pull-right') do
|
||||||
|
Support
|
||||||
|
%i.fa.fa-shopping-cart
|
||||||
46
app/views/conference_registrations/_tickets_bought.html.haml
Normal file
46
app/views/conference_registrations/_tickets_bought.html.haml
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
%table.table.table-hover
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Ticket
|
||||||
|
%th.text-center Quantity
|
||||||
|
%th.text-center Price
|
||||||
|
%th.text-center Total
|
||||||
|
%th
|
||||||
|
%tbody
|
||||||
|
- tickets.each do |ticket|
|
||||||
|
%tr
|
||||||
|
%td.col-sm-8.col-md-6
|
||||||
|
.media
|
||||||
|
.media-body
|
||||||
|
%h4.media-heading
|
||||||
|
= ticket.title
|
||||||
|
%h5.media-heading
|
||||||
|
-if !ticket.description.blank?
|
||||||
|
= markdown(ticket.description)
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
= ticket.quantity_bought_by(current_user)
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
= humanized_money_with_symbol ticket.price
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%strong
|
||||||
|
= ticket.total_price(current_user)
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
= link_to conference_ticket_purchase_path(@conference.short_title, ticket.id),
|
||||||
|
method: :delete, class: 'btn btn-danger',
|
||||||
|
data: { confirm: "Do you really want to delete the #{ticket.title} for #{@conference.title}?" } do
|
||||||
|
Delete
|
||||||
|
%i.fa.fa-trash-o
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%td
|
||||||
|
%td
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%h4
|
||||||
|
Total
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%h4
|
||||||
|
%strong
|
||||||
|
- if @total_price.cents == -1
|
||||||
|
not-calculable
|
||||||
|
- else
|
||||||
|
= humanized_money_with_symbol Ticket.total_price(@conference, current_user)
|
||||||
126
app/views/conference_registrations/show.html.haml
Normal file
126
app/views/conference_registrations/show.html.haml
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
%h1
|
||||||
|
= @conference.title
|
||||||
|
%small
|
||||||
|
= date_string(@conference.start_date, @conference.end_date)
|
||||||
|
- if @conference.venue.name and @conference.venue.website and @conference.venue.address
|
||||||
|
%p
|
||||||
|
%small
|
||||||
|
at
|
||||||
|
= link_to @conference.venue.name, @conference.venue.website
|
||||||
|
,
|
||||||
|
\#{link_to @conference.venue.address, "http://maps.google.com/maps?q=#{@conference.venue.address}"}
|
||||||
|
.row
|
||||||
|
.col-md-4
|
||||||
|
.row
|
||||||
|
- if @conference.contact.facebook.present?
|
||||||
|
%div.col-md-3
|
||||||
|
= link_to "#{ @conference.contact.facebook }" do
|
||||||
|
%i.fa.fa-facebook-square.fa-2x
|
||||||
|
- if @conference.contact.twitter.present?
|
||||||
|
%div.col-md-3
|
||||||
|
= link_to "#{ @conference.contact.twitter }" do
|
||||||
|
%i.fa.fa-twitter.fa-2x
|
||||||
|
- if @conference.contact.instagram.present?
|
||||||
|
%div.col-md-3
|
||||||
|
= link_to "#{ @conference.contact.instagram }" do
|
||||||
|
%i.fa.fa-instagram.fa-2x
|
||||||
|
- if @conference.contact.googleplus.present?
|
||||||
|
%div.col-md-3
|
||||||
|
= link_to "#{ @conference.contact.googleplus }" do
|
||||||
|
%i.fa.fa-google-plus-square.fa-2x
|
||||||
|
|
||||||
|
%br
|
||||||
|
|
||||||
|
- if @conference.tickets.any?
|
||||||
|
%h3
|
||||||
|
Tickets
|
||||||
|
- if current_user.tickets.any?
|
||||||
|
%p
|
||||||
|
You have already purchased the following tickets:
|
||||||
|
%p
|
||||||
|
If you would like to buy more tickets, please click
|
||||||
|
= link_to 'here', conference_tickets_path(@conference.short_title)
|
||||||
|
= render partial: 'tickets_bought', locals: { tickets: current_user.tickets }
|
||||||
|
|
||||||
|
- else
|
||||||
|
= render partial: 'tickets', locals: { tickets: @conference.tickets }
|
||||||
|
%br
|
||||||
|
- if @conference.speakers.confirmed.any?
|
||||||
|
%h3
|
||||||
|
= pluralize(@conference.speakers.confirmed.count, 'Speaker')
|
||||||
|
- @conference.speakers.confirmed.limit(12).each_slice(4) do |slice|
|
||||||
|
.row
|
||||||
|
- slice.each do |speaker|
|
||||||
|
.col-md-3
|
||||||
|
.row
|
||||||
|
.col-md-3
|
||||||
|
= image_tag(speaker.gravatar_url(size: '25'),
|
||||||
|
title: "Yo #{speaker.name}!",
|
||||||
|
alt: '', 'class' => 'img-circle img-responsive text-center')
|
||||||
|
.col-md-9
|
||||||
|
%h4
|
||||||
|
= speaker.name
|
||||||
|
%hr
|
||||||
|
|
||||||
|
- if @conference.events.confirmed.any?
|
||||||
|
%h3
|
||||||
|
= pluralize(@conference.events.confirmed.count, 'Event')
|
||||||
|
%ul.list-unstyled
|
||||||
|
- @conference.events.confirmed.limit(10).each do |event|
|
||||||
|
%li
|
||||||
|
%h4
|
||||||
|
= link_to event.title, conference_proposal_path(@conference.short_title, event.id)
|
||||||
|
%strong
|
||||||
|
presented by
|
||||||
|
= event.speaker_names
|
||||||
|
%hr
|
||||||
|
|
||||||
|
- if @conference.participants.any?
|
||||||
|
%h3
|
||||||
|
= pluralize(@conference.participants.count, 'Participant')
|
||||||
|
- @conference.participants.limit(36).each_slice(12) do |slice|
|
||||||
|
.row
|
||||||
|
- slice.each do |participant|
|
||||||
|
.col-md-1
|
||||||
|
= image_tag(participant.gravatar_url(size: '25'),
|
||||||
|
title: "Yo #{participant.name}!",
|
||||||
|
alt: '', 'class' => 'img-circle img-responsive text-center')
|
||||||
|
%hr
|
||||||
|
|
||||||
|
- if @registration
|
||||||
|
%h2
|
||||||
|
Congratulations! You are now registered for
|
||||||
|
= "#{@conference.title}!"
|
||||||
|
|
||||||
|
- if @conference.questions.any?
|
||||||
|
%h3 Your answers to the registrations questions are:
|
||||||
|
- @conference.questions.each do |q|
|
||||||
|
%p
|
||||||
|
%b Question:
|
||||||
|
= q.title
|
||||||
|
|
||||||
|
%b Your Answer:
|
||||||
|
- @registration.qanswers.where(:question_id => q.id).each do |qa|
|
||||||
|
= qa.answer.title
|
||||||
|
%br
|
||||||
|
|
||||||
|
- if @workshops.any?
|
||||||
|
%h3 You are registered for the following workshops:
|
||||||
|
%ul.list-unstyled
|
||||||
|
- @workshops.each do |workshop|
|
||||||
|
%li
|
||||||
|
%h4
|
||||||
|
= link_to workshop.title, conference_proposal_path(@conference.short_title, workshop.id)
|
||||||
|
%strong
|
||||||
|
presented by
|
||||||
|
= workshop.speaker_names
|
||||||
|
%br
|
||||||
|
|
||||||
|
%div
|
||||||
|
= link_to 'Modify your Registration', edit_conference_conference_registrations_path(@conference.short_title), class: 'btn btn-success'
|
||||||
|
= link_to 'Unregister', conference_conference_registrations_path(@conference.short_title),
|
||||||
|
method: :delete, class: 'btn btn-danger', confirm: 'Are you sure you want to unregister?'
|
||||||
|
- else
|
||||||
|
%p.lead
|
||||||
|
= "Unfortunately you are not registered for #{@conference.title}. If you want to register click"
|
||||||
|
= link_to 'here.', new_conference_conference_registrations_path(@conference.short_title)
|
||||||
|
|
@ -39,3 +39,5 @@
|
||||||
= link_to "View My Proposals", conference_proposal_index_path(conference.short_title), :class =>"btn btn-default"
|
= link_to "View My Proposals", conference_proposal_index_path(conference.short_title), :class =>"btn btn-default"
|
||||||
- elsif conference.cfp_open?
|
- elsif conference.cfp_open?
|
||||||
= link_to "Submit Proposal", conference_proposal_index_path(conference.short_title), :class =>"btn btn-default"
|
= link_to "Submit Proposal", conference_proposal_index_path(conference.short_title), :class =>"btn btn-default"
|
||||||
|
- if !current_user.nil? && conference.tickets.any?
|
||||||
|
= link_to 'Support', conference_tickets_path(conference.short_title), class: 'btn btn-default'
|
||||||
|
|
@ -102,11 +102,11 @@
|
||||||
- if can? :update, @conference.sponsors.build
|
- if can? :update, @conference.sponsors.build
|
||||||
%li{:class=> active_nav_li(admin_conference_sponsors_path(@conference.short_title))}
|
%li{:class=> active_nav_li(admin_conference_sponsors_path(@conference.short_title))}
|
||||||
= link_to 'Sponsors', admin_conference_sponsors_path(@conference.short_title)
|
= link_to 'Sponsors', admin_conference_sponsors_path(@conference.short_title)
|
||||||
- if can? :update, @conference.supporter_levels.build
|
- if can? :update, @conference.tickets.build
|
||||||
%li{ class: active_nav_li(admin_conference_supporter_levels_path(@conference.short_title)) }
|
%li{ class: active_nav_li(admin_conference_tickets_path(@conference.short_title)) }
|
||||||
= link_to(admin_conference_supporter_levels_path(@conference.short_title)) do
|
= link_to(admin_conference_tickets_path(@conference.short_title)) do
|
||||||
%span.fa.fa-usd
|
%span.fa.fa-usd
|
||||||
Supporter Levels
|
Tickets
|
||||||
- if can? :update, @conference.email_settings
|
- if can? :update, @conference.email_settings
|
||||||
%li{:class=> active_nav_li(admin_conference_emails_path(@conference.short_title))}
|
%li{:class=> active_nav_li(admin_conference_emails_path(@conference.short_title))}
|
||||||
= link_to(admin_conference_emails_path(@conference.short_title)) do
|
= link_to(admin_conference_emails_path(@conference.short_title)) do
|
||||||
|
|
|
||||||
25
app/views/tickets/_ticket.html.haml
Normal file
25
app/views/tickets/_ticket.html.haml
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
%tr
|
||||||
|
%td.col-sm-8.col-md-6
|
||||||
|
.media
|
||||||
|
.media-body
|
||||||
|
%h4.media-heading
|
||||||
|
= ticket.title
|
||||||
|
%h5.media-heading
|
||||||
|
-if !ticket.description.blank?
|
||||||
|
= markdown(ticket.description)
|
||||||
|
%td.col-sm-1.col-md-1
|
||||||
|
- if ticket.bought?(current_user)
|
||||||
|
= text_field_tag("tickets[][#{ticket.id}]", ticket.quantity_bought_by(current_user),
|
||||||
|
type: 'number', min: 0, class: 'form-control quantity', 'data-id' => ticket.id)
|
||||||
|
- else
|
||||||
|
= text_field_tag("tickets[][#{ticket.id}]", 0, type: 'number', min: 0,
|
||||||
|
class: 'form-control quantity', 'data-id' => ticket.id)
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
= ticket.price.symbol
|
||||||
|
%span{id: "price_#{ticket.id}"}
|
||||||
|
= humanized_money ticket.price
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%strong
|
||||||
|
= ticket.price.symbol
|
||||||
|
%span.total_row{id: "total_row_#{ticket.id}"}
|
||||||
|
0
|
||||||
37
app/views/tickets/index.html.haml
Normal file
37
app/views/tickets/index.html.haml
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
.row
|
||||||
|
.col-sm-12.col-md-10.col-md-offset-1
|
||||||
|
%h1
|
||||||
|
Tickets
|
||||||
|
%p.lead
|
||||||
|
Please buy a ticket if you want to support
|
||||||
|
%b
|
||||||
|
= @conference.title
|
||||||
|
!
|
||||||
|
=form_tag(conference_ticket_purchases_path, method: :post) do |f|
|
||||||
|
%table.table.table-hover
|
||||||
|
%thead
|
||||||
|
%tr
|
||||||
|
%th Ticket
|
||||||
|
%th Quantity
|
||||||
|
%th Price
|
||||||
|
%th Total
|
||||||
|
%tbody
|
||||||
|
- @conference.tickets.each do |ticket|
|
||||||
|
= render partial: 'ticket', f: f, locals: {ticket: ticket}
|
||||||
|
%tr
|
||||||
|
%td
|
||||||
|
%td
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%h4
|
||||||
|
Total
|
||||||
|
%td.col-sm-1.col-md-1.text-center
|
||||||
|
%h4
|
||||||
|
%strong
|
||||||
|
%span{id: 'total_price'}
|
||||||
|
0
|
||||||
|
.pull-right
|
||||||
|
= button_tag(type: 'submit', class: 'btn btn-success btn-lg') do
|
||||||
|
Support
|
||||||
|
%i.fa.fa-shopping-cart
|
||||||
|
= link_to 'Continue without a Ticket!', conference_conference_registrations_path(@conference.short_title),
|
||||||
|
class: 'btn btn-danger btn-sm'
|
||||||
52
config/initializers/money.rb
Normal file
52
config/initializers/money.rb
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
# encoding : utf-8
|
||||||
|
|
||||||
|
MoneyRails.configure do |config|
|
||||||
|
|
||||||
|
# To set the default currency
|
||||||
|
#
|
||||||
|
config.default_currency = :usd
|
||||||
|
|
||||||
|
# Set default bank object
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# config.default_bank = EuCentralBank.new
|
||||||
|
|
||||||
|
# Add exchange rates to current money bank object.
|
||||||
|
# (The conversion rate refers to one direction only)
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# config.add_rate "USD", "CAD", 1.24515
|
||||||
|
# config.add_rate "CAD", "USD", 0.803115
|
||||||
|
|
||||||
|
# To handle the inclusion of validations for monetized fields
|
||||||
|
# The default value is true
|
||||||
|
#
|
||||||
|
# config.include_validations = true
|
||||||
|
|
||||||
|
# Default ActiveRecord migration configuration values for columns:
|
||||||
|
#
|
||||||
|
# config.amount_column = { prefix: '', # column name prefix
|
||||||
|
# postfix: '_cents', # column name postfix
|
||||||
|
# column_name: nil, # full column name (overrides prefix, postfix and accessor name)
|
||||||
|
# type: :integer, # column type
|
||||||
|
# present: true, # column will be created
|
||||||
|
# null: false, # other options will be treated as column options
|
||||||
|
# default: 0
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# config.currency_column = { prefix: '',
|
||||||
|
# postfix: '_currency',
|
||||||
|
# column_name: nil,
|
||||||
|
# type: :string,
|
||||||
|
# present: true,
|
||||||
|
# null: false,
|
||||||
|
# default: 'USD'
|
||||||
|
# }
|
||||||
|
|
||||||
|
# Set money formatted output globally.
|
||||||
|
# Default value is nil meaning "ignore this option".
|
||||||
|
# Options are nil, true, false.
|
||||||
|
#
|
||||||
|
# config.no_cents_if_whole = nil
|
||||||
|
# config.symbol = nil
|
||||||
|
end
|
||||||
|
|
@ -56,7 +56,7 @@ Osem::Application.routes.draw do
|
||||||
|
|
||||||
resources :social_events, only: [:show, :update, :index]
|
resources :social_events, only: [:show, :update, :index]
|
||||||
|
|
||||||
resources :supporter_levels, only: [:show, :update, :index]
|
resources :tickets
|
||||||
|
|
||||||
resources :emails, only: [:show, :update, :index]
|
resources :emails, only: [:show, :update, :index]
|
||||||
|
|
||||||
|
|
@ -83,8 +83,6 @@ Osem::Application.routes.draw do
|
||||||
end
|
end
|
||||||
resource :speaker, only: [:edit, :update]
|
resource :speaker, only: [:edit, :update]
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :supporters
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -99,6 +97,8 @@ Osem::Application.routes.draw do
|
||||||
end
|
end
|
||||||
|
|
||||||
resource :conference_registrations, path: 'register'
|
resource :conference_registrations, path: 'register'
|
||||||
|
resources :tickets, only: [:index]
|
||||||
|
resources :ticket_purchases, only: [:create, :destroy]
|
||||||
|
|
||||||
resource :schedule, only: [] do
|
resource :schedule, only: [] do
|
||||||
get "/" => "schedule#index"
|
get "/" => "schedule#index"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
class RenameSupporterLevelToTicket < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
rename_table :supporter_levels, :tickets
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
rename_table :tickets, :supporter_levels
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
class MigratingSupporterRegistrationsToTicketUsers < ActiveRecord::Migration
|
||||||
|
class TempSupporterRegistrations < ActiveRecord::Base
|
||||||
|
self.table_name = 'supporter_registrations'
|
||||||
|
attr_accessible :conference_id, :supporter_level_id, :registration_id, :user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
class TempUser < ActiveRecord::Base
|
||||||
|
self.table_name = 'users'
|
||||||
|
attr_accessible :user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
class TempRegistration < ActiveRecord::Base
|
||||||
|
self.table_name = 'registrations'
|
||||||
|
attr_accessible :user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def change
|
||||||
|
rename_column :supporter_registrations, :supporter_level_id, :ticket_id
|
||||||
|
rename_column :supporter_registrations, :code_is_valid, :paid
|
||||||
|
|
||||||
|
add_column :supporter_registrations, :quantity, :integer, default: 1
|
||||||
|
add_column :supporter_registrations, :user_id, :integer
|
||||||
|
|
||||||
|
deleted_user = TempUser.find_by(email: 'deleted@localhost.osem')
|
||||||
|
|
||||||
|
TempSupporterRegistrations.all.each do |s|
|
||||||
|
# Change relation from registration to user
|
||||||
|
registration = TempRegistration.find_by(id: s.registration_id)
|
||||||
|
if registration
|
||||||
|
user = TempUser.find_by(id: registration.user_id)
|
||||||
|
if user
|
||||||
|
s.user_id = user.id
|
||||||
|
s.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if !s.user_id
|
||||||
|
s.user_id = deleted_user.id
|
||||||
|
s.save
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sum up if a user has bought more than one ticket
|
||||||
|
TempSupporterRegistrations.all.each do |s|
|
||||||
|
sup_reg = TempSupporterRegistrations.where(
|
||||||
|
ticket_id: s.ticket_id,
|
||||||
|
user_id: s.user_id,
|
||||||
|
conference_id: s.conference_id)
|
||||||
|
quantity = sup_reg.count
|
||||||
|
|
||||||
|
if quantity > 1
|
||||||
|
# Save the amount in the first one
|
||||||
|
s.quantity = quantity
|
||||||
|
s.save
|
||||||
|
|
||||||
|
# Delete the other
|
||||||
|
sup_reg = sup_reg.where('id not in (?)', [s.id])
|
||||||
|
sup_reg.destroy_all
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_column :supporter_registrations, :registration_id
|
||||||
|
remove_column :supporter_registrations, :code
|
||||||
|
remove_column :supporter_registrations, :name
|
||||||
|
remove_column :supporter_registrations, :email
|
||||||
|
remove_column :conferences, :use_supporter_levels
|
||||||
|
|
||||||
|
rename_table :supporter_registrations, :ticket_purchases
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
class SplitTicketPriceInPriceAndCurrency < ActiveRecord::Migration
|
||||||
|
class TempTicket < ActiveRecord::Base
|
||||||
|
self.table_name = 'tickets'
|
||||||
|
attr_accessible :ticket_price, :price_cents, :price_currency
|
||||||
|
end
|
||||||
|
|
||||||
|
def change
|
||||||
|
add_money :tickets, :price
|
||||||
|
|
||||||
|
TempTicket.all.each do |ticket|
|
||||||
|
# Replace currency symbol with ISO Code
|
||||||
|
ticket.ticket_price.gsub!('€', 'EUR')
|
||||||
|
ticket.ticket_price.gsub!('$', 'USD')
|
||||||
|
ticket.ticket_price.gsub!('£', 'GBP')
|
||||||
|
ticket.ticket_price.gsub!('¥', 'CNY')
|
||||||
|
ticket.ticket_price.gsub!('₹', 'INR')
|
||||||
|
|
||||||
|
money = ticket.ticket_price.to_money
|
||||||
|
ticket.price_cents = money.cents
|
||||||
|
ticket.price_currency = money.currency_as_string
|
||||||
|
ticket.save
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_column :tickets, :ticket_price
|
||||||
|
remove_column :tickets, :url
|
||||||
|
end
|
||||||
|
end
|
||||||
282
db/schema.rb
282
db/schema.rb
|
|
@ -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: 20140820124117) do
|
ActiveRecord::Schema.define(version: 20140821103643) 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"
|
||||||
|
|
@ -21,27 +21,27 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.datetime "time"
|
t.datetime "time"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time", using: :btree
|
add_index "ahoy_events", ["time"], name: "index_ahoy_events_on_time"
|
||||||
add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id", using: :btree
|
add_index "ahoy_events", ["user_id"], name: "index_ahoy_events_on_user_id"
|
||||||
add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id", using: :btree
|
add_index "ahoy_events", ["visit_id"], name: "index_ahoy_events_on_visit_id"
|
||||||
|
|
||||||
create_table "answers", force: true do |t|
|
create_table "answers", force: true do |t|
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "call_for_papers", force: true do |t|
|
create_table "call_for_papers", force: true do |t|
|
||||||
t.date "start_date", null: false
|
t.date "start_date", null: false
|
||||||
t.date "end_date", null: false
|
t.date "end_date", null: false
|
||||||
t.text "description", limit: 16777215, null: false
|
t.text "description", null: false
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
t.boolean "schedule_changes", default: false
|
t.boolean "schedule_changes", default: false
|
||||||
t.integer "rating", default: 3
|
t.integer "rating", default: 3
|
||||||
t.boolean "schedule_public"
|
t.boolean "schedule_public"
|
||||||
t.boolean "include_cfp_in_splash", default: false
|
t.boolean "include_cfp_in_splash", default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "campaigns", force: true do |t|
|
create_table "campaigns", force: true do |t|
|
||||||
|
|
@ -57,22 +57,22 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "comments", force: true do |t|
|
create_table "comments", force: true do |t|
|
||||||
t.string "title", limit: 50, default: ""
|
t.string "title", limit: 50, default: ""
|
||||||
t.text "body", limit: 16777215
|
t.text "body"
|
||||||
t.integer "commentable_id"
|
t.integer "commentable_id"
|
||||||
t.string "commentable_type"
|
t.string "commentable_type"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
t.string "subject"
|
t.string "subject"
|
||||||
t.integer "parent_id"
|
t.integer "parent_id"
|
||||||
t.integer "lft"
|
t.integer "lft"
|
||||||
t.integer "rgt"
|
t.integer "rgt"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id", using: :btree
|
add_index "comments", ["commentable_id"], name: "index_comments_on_commentable_id"
|
||||||
add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type", using: :btree
|
add_index "comments", ["commentable_type"], name: "index_comments_on_commentable_type"
|
||||||
add_index "comments", ["user_id"], name: "index_comments_on_user_id", using: :btree
|
add_index "comments", ["user_id"], name: "index_comments_on_user_id"
|
||||||
|
|
||||||
create_table "commercials", force: true do |t|
|
create_table "commercials", force: true do |t|
|
||||||
t.string "commercial_id"
|
t.string "commercial_id"
|
||||||
|
|
@ -92,14 +92,13 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.date "start_date", null: false
|
t.date "start_date", null: false
|
||||||
t.date "end_date", null: false
|
t.date "end_date", null: false
|
||||||
t.integer "venue_id"
|
t.integer "venue_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
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"
|
||||||
t.datetime "logo_updated_at"
|
t.datetime "logo_updated_at"
|
||||||
t.boolean "use_dietary_choices", default: false
|
t.boolean "use_dietary_choices", default: false
|
||||||
t.boolean "use_supporter_levels", default: false
|
|
||||||
t.integer "revision"
|
t.integer "revision"
|
||||||
t.boolean "use_vpositions", default: false
|
t.boolean "use_vpositions", default: false
|
||||||
t.boolean "use_vdays", default: false
|
t.boolean "use_vdays", default: false
|
||||||
|
|
@ -111,12 +110,12 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
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"
|
||||||
|
|
@ -157,13 +156,13 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree
|
add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority"
|
||||||
|
|
||||||
create_table "dietary_choices", force: true do |t|
|
create_table "dietary_choices", force: true do |t|
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.string "title", null: false
|
t.string "title", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "difficulty_levels", force: true do |t|
|
create_table "difficulty_levels", force: true do |t|
|
||||||
|
|
@ -171,37 +170,37 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.string "color"
|
t.string "color"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "email_settings", force: true do |t|
|
create_table "email_settings", force: true do |t|
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.boolean "send_on_registration", default: false
|
t.boolean "send_on_registration", default: false
|
||||||
t.boolean "send_on_accepted", default: false
|
t.boolean "send_on_accepted", default: false
|
||||||
t.boolean "send_on_rejected", default: false
|
t.boolean "send_on_rejected", default: false
|
||||||
t.boolean "send_on_confirmed_without_registration", default: false
|
t.boolean "send_on_confirmed_without_registration", default: false
|
||||||
t.text "registration_email_template", limit: 16777215
|
t.text "registration_email_template"
|
||||||
t.text "accepted_email_template", limit: 16777215
|
t.text "accepted_email_template"
|
||||||
t.text "rejected_email_template", limit: 16777215
|
t.text "rejected_email_template"
|
||||||
t.text "confirmed_email_template", limit: 16777215
|
t.text "confirmed_email_template"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
t.string "registration_subject"
|
t.string "registration_subject"
|
||||||
t.string "accepted_subject"
|
t.string "accepted_subject"
|
||||||
t.string "rejected_subject"
|
t.string "rejected_subject"
|
||||||
t.string "confirmed_without_registration_subject"
|
t.string "confirmed_without_registration_subject"
|
||||||
t.boolean "send_on_updated_conference_dates", default: false
|
t.boolean "send_on_updated_conference_dates", default: false
|
||||||
t.string "updated_conference_dates_subject"
|
t.string "updated_conference_dates_subject"
|
||||||
t.text "updated_conference_dates_template"
|
t.text "updated_conference_dates_template"
|
||||||
t.boolean "send_on_updated_conference_registration_dates", default: false
|
t.boolean "send_on_updated_conference_registration_dates", default: false
|
||||||
t.string "updated_conference_registration_dates_subject"
|
t.string "updated_conference_registration_dates_subject"
|
||||||
t.text "updated_conference_registration_dates_template"
|
t.text "updated_conference_registration_dates_template"
|
||||||
t.boolean "send_on_venue_update", default: false
|
t.boolean "send_on_venue_update", default: false
|
||||||
t.string "venue_update_subject"
|
t.string "venue_update_subject"
|
||||||
t.text "venue_update_template"
|
t.text "venue_update_template"
|
||||||
t.boolean "send_on_call_for_papers_dates_updates", default: false
|
t.boolean "send_on_call_for_papers_dates_updates", default: false
|
||||||
t.boolean "send_on_call_for_papers_schedule_public", default: false
|
t.boolean "send_on_call_for_papers_schedule_public", default: false
|
||||||
t.string "call_for_papers_schedule_public_subject"
|
t.string "call_for_papers_schedule_public_subject"
|
||||||
t.string "call_for_papers_dates_updates_subject"
|
t.string "call_for_papers_dates_updates_subject"
|
||||||
t.text "call_for_papers_schedule_public_template"
|
t.text "call_for_papers_schedule_public_template"
|
||||||
|
|
@ -210,24 +209,14 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
|
|
||||||
create_table "event_attachments", force: true do |t|
|
create_table "event_attachments", force: true do |t|
|
||||||
t.integer "event_id"
|
t.integer "event_id"
|
||||||
t.string "title", null: false
|
t.string "title", null: false
|
||||||
t.string "attachment_file_name"
|
t.string "attachment_file_name"
|
||||||
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", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
|
||||||
|
|
||||||
create_table "event_people", force: true do |t|
|
|
||||||
t.integer "proposal_id"
|
|
||||||
t.integer "person_id"
|
|
||||||
t.integer "event_id"
|
|
||||||
t.string "event_role", default: "participant", null: false
|
|
||||||
t.string "comment"
|
|
||||||
t.datetime "created_at", null: false
|
|
||||||
t.datetime "updated_at", null: false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "event_types", force: true do |t|
|
create_table "event_types", force: true do |t|
|
||||||
|
|
@ -249,28 +238,28 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "events", force: true do |t|
|
create_table "events", force: true do |t|
|
||||||
t.string "guid", null: false
|
t.string "guid", null: false
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.integer "event_type_id"
|
t.integer "event_type_id"
|
||||||
t.string "title", null: false
|
t.string "title", null: false
|
||||||
t.string "subtitle"
|
t.string "subtitle"
|
||||||
t.integer "time_slots"
|
t.integer "time_slots"
|
||||||
t.string "state", default: "new", null: false
|
t.string "state", default: "new", null: false
|
||||||
t.string "progress", default: "new", null: false
|
t.string "progress", default: "new", null: false
|
||||||
t.string "language"
|
t.string "language"
|
||||||
t.datetime "start_time"
|
t.datetime "start_time"
|
||||||
t.text "abstract", limit: 16777215
|
t.text "abstract"
|
||||||
t.text "description", limit: 16777215
|
t.text "description"
|
||||||
t.boolean "public", default: true
|
t.boolean "public", default: true
|
||||||
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"
|
||||||
t.datetime "logo_updated_at"
|
t.datetime "logo_updated_at"
|
||||||
t.text "proposal_additional_speakers", limit: 16777215
|
t.text "proposal_additional_speakers"
|
||||||
t.integer "track_id"
|
t.integer "track_id"
|
||||||
t.integer "room_id"
|
t.integer "room_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
t.boolean "require_registration"
|
t.boolean "require_registration"
|
||||||
t.integer "difficulty_level_id"
|
t.integer "difficulty_level_id"
|
||||||
t.integer "week"
|
t.integer "week"
|
||||||
|
|
@ -303,29 +292,6 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "people", force: true do |t|
|
|
||||||
t.string "guid", null: false
|
|
||||||
t.text "first_name"
|
|
||||||
t.text "last_name"
|
|
||||||
t.text "public_name"
|
|
||||||
t.text "company"
|
|
||||||
t.string "email", null: false
|
|
||||||
t.boolean "email_public"
|
|
||||||
t.string "avatar_file_name"
|
|
||||||
t.string "avatar_content_type"
|
|
||||||
t.integer "avatar_file_size"
|
|
||||||
t.datetime "avatar_updated_at"
|
|
||||||
t.text "biography"
|
|
||||||
t.integer "user_id"
|
|
||||||
t.datetime "created_at", null: false
|
|
||||||
t.datetime "updated_at", null: false
|
|
||||||
t.string "irc_nickname"
|
|
||||||
t.text "volunteer_experience"
|
|
||||||
t.string "tshirt"
|
|
||||||
t.string "mobile"
|
|
||||||
t.string "languages"
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "photos", force: true do |t|
|
create_table "photos", force: true do |t|
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.string "picture_file_name"
|
t.string "picture_file_name"
|
||||||
|
|
@ -349,8 +315,8 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
|
|
||||||
create_table "question_types", force: true do |t|
|
create_table "question_types", force: true do |t|
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "questions", force: true do |t|
|
create_table "questions", force: true do |t|
|
||||||
|
|
@ -358,8 +324,8 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.integer "question_type_id"
|
t.integer "question_type_id"
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.boolean "global"
|
t.boolean "global"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "registration_periods", force: true do |t|
|
create_table "registration_periods", force: true do |t|
|
||||||
|
|
@ -373,18 +339,18 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
|
|
||||||
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
|
||||||
t.boolean "attending_with_partner", default: false
|
t.boolean "attending_with_partner", default: false
|
||||||
t.boolean "using_affiliated_lodging", default: false
|
t.boolean "using_affiliated_lodging", default: false
|
||||||
t.datetime "arrival"
|
t.datetime "arrival"
|
||||||
t.datetime "departure"
|
t.datetime "departure"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
t.integer "dietary_choice_id"
|
t.integer "dietary_choice_id"
|
||||||
t.text "other_dietary_choice", limit: 16777215
|
t.text "other_dietary_choice"
|
||||||
t.boolean "handicapped_access_required", default: false
|
t.boolean "handicapped_access_required", default: false
|
||||||
t.text "other_special_needs", limit: 16777215
|
t.text "other_special_needs"
|
||||||
t.boolean "attended", default: false
|
t.boolean "attended", default: false
|
||||||
t.boolean "volunteer"
|
t.boolean "volunteer"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.integer "week"
|
t.integer "week"
|
||||||
|
|
@ -402,22 +368,22 @@ ActiveRecord::Schema.define(version: 20140820124117) 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", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
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"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id", using: :btree
|
add_index "roles", ["name", "resource_type", "resource_id"], name: "index_roles_on_name_and_resource_type_and_resource_id"
|
||||||
add_index "roles", ["name"], name: "index_roles_on_name", using: :btree
|
add_index "roles", ["name"], name: "index_roles_on_name"
|
||||||
|
|
||||||
create_table "roles_users", id: false, force: true do |t|
|
create_table "roles_users", id: false, force: true do |t|
|
||||||
t.integer "role_id"
|
t.integer "role_id"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "roles_users", ["user_id", "role_id"], name: "index_roles_users_on_user_id_and_role_id", using: :btree
|
add_index "roles_users", ["user_id", "role_id"], name: "index_roles_users_on_user_id_and_role_id"
|
||||||
|
|
||||||
create_table "rooms", force: true do |t|
|
create_table "rooms", force: true do |t|
|
||||||
t.string "guid", null: false
|
t.string "guid", null: false
|
||||||
|
|
@ -462,25 +428,6 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "supporter_levels", force: true do |t|
|
|
||||||
t.integer "conference_id"
|
|
||||||
t.string "title", null: false
|
|
||||||
t.string "url"
|
|
||||||
t.text "description"
|
|
||||||
t.string "ticket_price"
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "supporter_registrations", force: true do |t|
|
|
||||||
t.integer "registration_id"
|
|
||||||
t.integer "supporter_level_id"
|
|
||||||
t.integer "conference_id"
|
|
||||||
t.string "name"
|
|
||||||
t.string "email"
|
|
||||||
t.string "code"
|
|
||||||
t.boolean "code_is_valid", default: false
|
|
||||||
t.datetime "created_at"
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "targets", force: true do |t|
|
create_table "targets", force: true do |t|
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.integer "campaign_id"
|
t.integer "campaign_id"
|
||||||
|
|
@ -491,14 +438,31 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "tracks", force: true do |t|
|
create_table "ticket_purchases", force: true do |t|
|
||||||
t.string "guid", null: false
|
t.integer "ticket_id"
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.string "name", null: false
|
t.boolean "paid", default: false
|
||||||
t.text "description", limit: 16777215
|
t.datetime "created_at"
|
||||||
|
t.integer "quantity", default: 1
|
||||||
|
t.integer "user_id"
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "tickets", force: true do |t|
|
||||||
|
t.integer "conference_id"
|
||||||
|
t.string "title", null: false
|
||||||
|
t.text "description"
|
||||||
|
t.integer "price_cents", default: 0, null: false
|
||||||
|
t.string "price_currency", default: "USD", null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "tracks", force: true do |t|
|
||||||
|
t.string "guid", null: false
|
||||||
|
t.integer "conference_id"
|
||||||
|
t.string "name", null: false
|
||||||
|
t.text "description"
|
||||||
t.string "color"
|
t.string "color"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "users", force: true do |t|
|
create_table "users", force: true do |t|
|
||||||
|
|
@ -516,8 +480,8 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.datetime "confirmed_at"
|
t.datetime "confirmed_at"
|
||||||
t.datetime "confirmation_sent_at"
|
t.datetime "confirmation_sent_at"
|
||||||
t.string "unconfirmed_email"
|
t.string "unconfirmed_email"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.boolean "email_public"
|
t.boolean "email_public"
|
||||||
t.text "biography"
|
t.text "biography"
|
||||||
|
|
@ -534,9 +498,9 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.boolean "is_admin", default: false
|
t.boolean "is_admin", default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
|
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||||
add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
|
add_index "users", ["email"], name: "index_users_on_email", unique: true
|
||||||
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree
|
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||||
|
|
||||||
create_table "vchoices", force: true do |t|
|
create_table "vchoices", force: true do |t|
|
||||||
t.integer "vday_id"
|
t.integer "vday_id"
|
||||||
|
|
@ -547,39 +511,39 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.date "day"
|
t.date "day"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
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"
|
||||||
t.string "offline_map_bounds"
|
t.string "offline_map_bounds"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
t.string "photo_file_name"
|
t.string "photo_file_name"
|
||||||
t.string "photo_content_type"
|
t.string "photo_content_type"
|
||||||
t.integer "photo_file_size"
|
t.integer "photo_file_size"
|
||||||
t.datetime "photo_updated_at"
|
t.datetime "photo_updated_at"
|
||||||
t.boolean "include_venue_in_splash", default: false
|
t.boolean "include_venue_in_splash", default: false
|
||||||
t.boolean "include_lodgings_in_splash", default: false
|
t.boolean "include_lodgings_in_splash", default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "versions", force: true do |t|
|
create_table "versions", force: true do |t|
|
||||||
t.string "item_type", null: false
|
t.string "item_type", null: false
|
||||||
t.integer "item_id", null: false
|
t.integer "item_id", null: false
|
||||||
t.string "event", null: false
|
t.string "event", null: false
|
||||||
t.string "whodunnit"
|
t.string "whodunnit"
|
||||||
t.text "object", limit: 16777215
|
t.text "object"
|
||||||
t.text "object_changes", limit: 16777215
|
t.text "object_changes"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id", using: :btree
|
add_index "versions", ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id"
|
||||||
|
|
||||||
create_table "visits", force: true do |t|
|
create_table "visits", force: true do |t|
|
||||||
t.uuid "visitor_id"
|
t.uuid "visitor_id"
|
||||||
|
|
@ -604,13 +568,13 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.datetime "started_at"
|
t.datetime "started_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "visits", ["user_id"], name: "index_visits_on_user_id", using: :btree
|
add_index "visits", ["user_id"], name: "index_visits_on_user_id"
|
||||||
|
|
||||||
create_table "votes", force: true do |t|
|
create_table "votes", force: true do |t|
|
||||||
t.integer "event_id"
|
t.integer "event_id"
|
||||||
t.integer "rating"
|
t.integer "rating"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -618,8 +582,8 @@ ActiveRecord::Schema.define(version: 20140820124117) do
|
||||||
t.integer "conference_id"
|
t.integer "conference_id"
|
||||||
t.string "title", null: false
|
t.string "title", null: false
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
FactoryGirl.define do
|
|
||||||
factory :supporter_level do
|
|
||||||
title 'Example Supporter Level'
|
|
||||||
url 'www.example.com'
|
|
||||||
conference
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
8
spec/factories/ticket_purchases.rb
Normal file
8
spec/factories/ticket_purchases.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
FactoryGirl.define do
|
||||||
|
factory :ticket_purchase do
|
||||||
|
user
|
||||||
|
conference
|
||||||
|
ticket
|
||||||
|
quantity 10
|
||||||
|
end
|
||||||
|
end
|
||||||
8
spec/factories/tickets.rb
Normal file
8
spec/factories/tickets.rb
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
FactoryGirl.define do
|
||||||
|
factory :ticket do
|
||||||
|
title 'Business Ticket'
|
||||||
|
price_cents 1000
|
||||||
|
price_currency 'USD'
|
||||||
|
conference
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -34,7 +34,7 @@ feature 'Has correct abilities' do
|
||||||
expect(page).to have_link('Lodgings', href: "/admin/conference/#{conference1.short_title}/lodgings")
|
expect(page).to have_link('Lodgings', href: "/admin/conference/#{conference1.short_title}/lodgings")
|
||||||
expect(page).to have_link('Sponsorship', href: "/admin/conference/#{conference1.short_title}/sponsorship_levels")
|
expect(page).to have_link('Sponsorship', href: "/admin/conference/#{conference1.short_title}/sponsorship_levels")
|
||||||
expect(page).to have_link('Sponsors', href: "/admin/conference/#{conference1.short_title}/sponsors")
|
expect(page).to have_link('Sponsors', href: "/admin/conference/#{conference1.short_title}/sponsors")
|
||||||
expect(page).to have_link('Supporter Levels', href: "/admin/conference/#{conference1.short_title}/supporter_levels")
|
expect(page).to have_link('Tickets', href: "/admin/conference/#{conference1.short_title}/tickets")
|
||||||
expect(page).to have_link('E-Mails', href: "/admin/conference/#{conference1.short_title}/emails")
|
expect(page).to have_link('E-Mails', href: "/admin/conference/#{conference1.short_title}/emails")
|
||||||
expect(page).to have_link('Call for papers', href: "/admin/conference/#{conference1.short_title}/callforpapers")
|
expect(page).to have_link('Call for papers', href: "/admin/conference/#{conference1.short_title}/callforpapers")
|
||||||
expect(page).to have_link('Tracks', href: "/admin/conference/#{conference1.short_title}/tracks")
|
expect(page).to have_link('Tracks', href: "/admin/conference/#{conference1.short_title}/tracks")
|
||||||
|
|
@ -70,8 +70,8 @@ feature 'Has correct abilities' do
|
||||||
visit admin_conference_sponsorship_levels_path(conference1.short_title)
|
visit admin_conference_sponsorship_levels_path(conference1.short_title)
|
||||||
expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference1.short_title))
|
expect(current_path).to eq(admin_conference_sponsorship_levels_path(conference1.short_title))
|
||||||
|
|
||||||
visit admin_conference_supporter_levels_path(conference1.short_title)
|
visit admin_conference_tickets_path(conference1.short_title)
|
||||||
expect(current_path).to eq(admin_conference_supporter_levels_path(conference1.short_title))
|
expect(current_path).to eq(admin_conference_tickets_path(conference1.short_title))
|
||||||
|
|
||||||
visit admin_conference_emails_path(conference1.short_title)
|
visit admin_conference_emails_path(conference1.short_title)
|
||||||
expect(current_path).to eq(admin_conference_emails_path(conference1.short_title))
|
expect(current_path).to eq(admin_conference_emails_path(conference1.short_title))
|
||||||
|
|
@ -141,7 +141,7 @@ feature 'Has correct abilities' do
|
||||||
visit admin_conference_sponsorship_levels_path(conference2.short_title)
|
visit admin_conference_sponsorship_levels_path(conference2.short_title)
|
||||||
expect(current_path).to eq(root_path)
|
expect(current_path).to eq(root_path)
|
||||||
|
|
||||||
visit admin_conference_supporter_levels_path(conference2.short_title)
|
visit admin_conference_tickets_path(conference2.short_title)
|
||||||
expect(current_path).to eq(root_path)
|
expect(current_path).to eq(root_path)
|
||||||
|
|
||||||
visit admin_conference_emails_path(conference2.short_title)
|
visit admin_conference_emails_path(conference2.short_title)
|
||||||
|
|
@ -212,7 +212,7 @@ feature 'Has correct abilities' do
|
||||||
visit admin_conference_sponsorship_levels_path(conference3.short_title)
|
visit admin_conference_sponsorship_levels_path(conference3.short_title)
|
||||||
expect(current_path).to eq(root_path)
|
expect(current_path).to eq(root_path)
|
||||||
|
|
||||||
visit admin_conference_supporter_levels_path(conference3.short_title)
|
visit admin_conference_tickets_path(conference3.short_title)
|
||||||
expect(current_path).to eq(root_path)
|
expect(current_path).to eq(root_path)
|
||||||
|
|
||||||
visit admin_conference_emails_path(conference3.short_title)
|
visit admin_conference_emails_path(conference3.short_title)
|
||||||
|
|
@ -284,7 +284,7 @@ feature 'Has correct abilities' do
|
||||||
visit admin_conference_sponsorship_levels_path(conference4.short_title)
|
visit admin_conference_sponsorship_levels_path(conference4.short_title)
|
||||||
expect(current_path).to eq(root_path)
|
expect(current_path).to eq(root_path)
|
||||||
|
|
||||||
visit admin_conference_supporter_levels_path(conference4.short_title)
|
visit admin_conference_tickets_path(conference4.short_title)
|
||||||
expect(current_path).to eq(root_path)
|
expect(current_path).to eq(root_path)
|
||||||
|
|
||||||
visit admin_conference_emails_path(conference4.short_title)
|
visit admin_conference_emails_path(conference4.short_title)
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,15 @@ feature Commercial do
|
||||||
let!(:conference) { create(:conference) }
|
let!(:conference) { create(:conference) }
|
||||||
let!(:organizer_role) { create(:organizer_role, resource: conference) }
|
let!(:organizer_role) { create(:organizer_role, resource: conference) }
|
||||||
let!(:organizer) { create(:user, role_ids: [organizer_role.id]) }
|
let!(:organizer) { create(:user, role_ids: [organizer_role.id]) }
|
||||||
|
let!(:participant) { create(:user) }
|
||||||
|
|
||||||
shared_examples 'adds and updates a commercial' do
|
context 'in admin area' do
|
||||||
scenario 'of a conference',
|
scenario 'adds, updates, deletes of a conference', feature: true, js: true do
|
||||||
feature: true, js: true do
|
|
||||||
|
|
||||||
expected_count = conference.commercials.count + 1
|
expected_count = conference.commercials.count + 1
|
||||||
|
|
||||||
sign_in organizer
|
sign_in organizer
|
||||||
|
|
||||||
visit admin_conference_commercials_path(conference.short_title)
|
visit admin_conference_commercials_path(conference.short_title)
|
||||||
|
|
||||||
click_link 'New Commercial'
|
click_link 'New Commercial'
|
||||||
|
|
||||||
# Create without an commercial id
|
# Create without an commercial id
|
||||||
|
|
@ -60,7 +58,87 @@ feature Commercial do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'organizer' do
|
context 'in public area' do
|
||||||
it_behaves_like 'adds and updates a commercial'
|
let!(:event) { create(:event, conference: conference, title: 'Example Proposal') }
|
||||||
|
|
||||||
|
before(:each) do
|
||||||
|
event.event_users = [create(:event_user,
|
||||||
|
user_id: participant.id,
|
||||||
|
event_id: event.id,
|
||||||
|
event_role: 'submitter')]
|
||||||
|
|
||||||
|
@expected_count = Commercial.count + 1
|
||||||
|
sign_in participant
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:each) do
|
||||||
|
sign_out
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'adds a invalid commercial to an event', feature: true, js: true do
|
||||||
|
visit edit_conference_proposal_path(conference.short_title, event.id)
|
||||||
|
|
||||||
|
click_link 'Commercials'
|
||||||
|
click_link 'Add Commercial'
|
||||||
|
|
||||||
|
select('SlideShare', from: 'commercial_commercial_type')
|
||||||
|
fill_in 'commercial_commercial_id', with: '12345'
|
||||||
|
|
||||||
|
click_button 'Create Commercial'
|
||||||
|
expect(flash).to eq('Commercial was successfully created.')
|
||||||
|
expect(event.commercials.count).to eq(@expected_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'adds a valid commercial to an event', feature: true, js: true do
|
||||||
|
visit edit_conference_proposal_path(conference.short_title, event.id)
|
||||||
|
click_link 'Commercials'
|
||||||
|
click_link 'Add Commercial'
|
||||||
|
|
||||||
|
select('SlideShare', from: 'commercial_commercial_type')
|
||||||
|
|
||||||
|
click_button 'Create Commercial'
|
||||||
|
expect(flash).to eq("A error prohibited this Commercial from being saved: Commercial can't be blank.")
|
||||||
|
expect(event.commercials.count).to eq(@expected_count - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'updates a valid commercial to an event', feature: true, js: true do
|
||||||
|
create(:commercial,
|
||||||
|
commercialable_id: event.id,
|
||||||
|
commercialable_type: 'Event')
|
||||||
|
visit edit_conference_proposal_path(conference.short_title, event.id)
|
||||||
|
click_link 'Commercials'
|
||||||
|
click_link 'Edit'
|
||||||
|
select('SlideShare', from: 'commercial_commercial_type')
|
||||||
|
fill_in 'commercial_commercial_id', with: '56789'
|
||||||
|
click_button 'Update Commercial'
|
||||||
|
expect(flash).to eq('Commercial was successfully updated.')
|
||||||
|
expect(event.commercials.count).to eq(@expected_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'updates a invalid commercial to an event', feature: true, js: true do
|
||||||
|
create(:commercial,
|
||||||
|
commercialable_id: event.id,
|
||||||
|
commercialable_type: 'Event')
|
||||||
|
visit edit_conference_proposal_path(conference.short_title, event.id)
|
||||||
|
click_link 'Commercials'
|
||||||
|
click_link 'Edit'
|
||||||
|
select('SlideShare', from: 'commercial_commercial_type')
|
||||||
|
fill_in 'commercial_commercial_id', with: ''
|
||||||
|
click_button 'Update Commercial'
|
||||||
|
expect(flash).to eq("A error prohibited this Commercial from being saved: Commercial can't be blank.")
|
||||||
|
expect(event.commercials.count).to eq(@expected_count)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'deletes a commercial to an event', feature: true, js: true do
|
||||||
|
create(:commercial,
|
||||||
|
commercialable_id: event.id,
|
||||||
|
commercialable_type: 'Event')
|
||||||
|
visit edit_conference_proposal_path(conference.short_title, event.id)
|
||||||
|
click_link 'Commercials'
|
||||||
|
click_link 'Delete'
|
||||||
|
page.driver.network_traffic
|
||||||
|
expect(flash).to eq('Commercial was successfully destroyed.')
|
||||||
|
expect(event.commercials.count).to eq(@expected_count - 1)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
52
spec/features/conference_registration_spec.rb
Normal file
52
spec/features/conference_registration_spec.rb
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature Registration do
|
||||||
|
let!(:conference) { create(:conference, registration_period: create(:registration_period, start_date: 3.days.ago)) }
|
||||||
|
let!(:participant) { create(:user) }
|
||||||
|
|
||||||
|
context 'as a participant' do
|
||||||
|
before(:each) do
|
||||||
|
sign_in participant
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:each) do
|
||||||
|
sign_out
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'who is already registered' do
|
||||||
|
let!(:registration) { create(:registration, user: participant, conference: conference) }
|
||||||
|
|
||||||
|
scenario 'updates conference registration', feature: true, js: true do
|
||||||
|
visit root_path
|
||||||
|
click_link 'Modify Registration'
|
||||||
|
|
||||||
|
expect(current_path).to eq(edit_conference_conference_registrations_path(conference.short_title))
|
||||||
|
click_button 'Update Registration'
|
||||||
|
|
||||||
|
expect(conference.user_registered?(participant)).to be(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'unregisters for a conference', feature: true, js: true do
|
||||||
|
visit root_path
|
||||||
|
click_link 'Modify Registration'
|
||||||
|
|
||||||
|
expect(current_path).to eq(edit_conference_conference_registrations_path(conference.short_title))
|
||||||
|
click_link 'Unregister'
|
||||||
|
|
||||||
|
expect(conference.user_registered?(participant)).to be(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'who is not registered' do
|
||||||
|
scenario 'registers for a conference', feature: true, js: true do
|
||||||
|
visit root_path
|
||||||
|
click_link 'Register'
|
||||||
|
|
||||||
|
expect(current_path).to eq(new_conference_conference_registrations_path(conference.short_title))
|
||||||
|
click_button 'Register'
|
||||||
|
|
||||||
|
expect(conference.user_registered?(participant)).to be(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -4,21 +4,76 @@ feature Event do
|
||||||
let!(:conference) { create(:conference) }
|
let!(:conference) { create(:conference) }
|
||||||
let!(:organizer_role) { create(:organizer_role, resource: conference) }
|
let!(:organizer_role) { create(:organizer_role, resource: conference) }
|
||||||
let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) }
|
let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) }
|
||||||
let!(:participant) { create(:user, biography: '') }
|
let!(:participant) { create(:user) }
|
||||||
|
let!(:participant_without_bio) { create(:user, biography: '') }
|
||||||
|
|
||||||
shared_examples 'proposal workflow' do
|
before(:each) do
|
||||||
scenario 'submitts a proposal, accepts and confirms',
|
conference.call_for_papers = create(:call_for_papers)
|
||||||
feature: true, js: true do
|
conference.event_types = [create(:event_type)]
|
||||||
|
|
||||||
|
@options = {}
|
||||||
|
@options[:send_mail] = 'false'
|
||||||
|
|
||||||
|
@event = create(:event, conference: conference, title: 'Example Proposal')
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:each) do
|
||||||
|
sign_out
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'as an conference organizer' do
|
||||||
|
before(:each) do
|
||||||
|
sign_in organizer
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'rejects a proposal', feature: true, js: true do
|
||||||
|
visit admin_conference_events_path(conference.short_title)
|
||||||
|
expect(page.has_content?('Example Proposal')).to be true
|
||||||
|
|
||||||
|
click_button 'New'
|
||||||
|
click_link "reject_event_#{@event.id}"
|
||||||
|
expect(flash).to eq('Event rejected!')
|
||||||
|
@event.reload
|
||||||
|
expect(@event.state).to eq('rejected')
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'accepts a proposal', feature: true, js: true do
|
||||||
|
visit admin_conference_events_path(conference.short_title)
|
||||||
|
expect(page.has_content?('Example Proposal')).to be true
|
||||||
|
|
||||||
|
click_button 'New'
|
||||||
|
click_link "accept_event_#{@event.id}"
|
||||||
|
expect(flash).to eq('Event accepted!')
|
||||||
|
expect(page.has_content?('Unconfirmed')).to be true
|
||||||
|
@event.reload
|
||||||
|
expect(@event.state).to eq('unconfirmed')
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'restarts review of a proposal', feature: true, js: true do
|
||||||
|
@event.reject!(@options)
|
||||||
|
visit admin_conference_events_path(conference.short_title)
|
||||||
|
expect(page.has_content?('Example Proposal')).to be true
|
||||||
|
|
||||||
|
click_button 'Rejected'
|
||||||
|
click_link "restart_event_#{@event.id}"
|
||||||
|
expect(flash).to eq('Review started!')
|
||||||
|
@event.reload
|
||||||
|
expect(@event.state).to eq('new')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'as a participant' do
|
||||||
|
before(:each) do
|
||||||
|
@event.accept!(@options)
|
||||||
|
@event.event_users = [create(:event_user,
|
||||||
|
user_id: participant.id,
|
||||||
|
event_id: @event.id,
|
||||||
|
event_role: 'submitter')]
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'submits a valid proposal', feature: true, js: true do
|
||||||
|
sign_in participant_without_bio
|
||||||
expected_count = Event.count + 1
|
expected_count = Event.count + 1
|
||||||
|
|
||||||
conference.call_for_papers = create(:call_for_papers)
|
|
||||||
conference.email_settings = create(:email_settings)
|
|
||||||
conference.event_types = [create(:event_type)]
|
|
||||||
|
|
||||||
# Submit a new proposal as participant
|
|
||||||
sign_in participant
|
|
||||||
|
|
||||||
visit conference_proposal_index_path(conference.short_title)
|
visit conference_proposal_index_path(conference.short_title)
|
||||||
click_link 'New Proposal'
|
click_link 'New Proposal'
|
||||||
|
|
||||||
|
|
@ -36,109 +91,31 @@ feature Event do
|
||||||
expect(flash).to eq('Event was successfully submitted. You should register for the conference now.')
|
expect(flash).to eq('Event was successfully submitted. You should register for the conference now.')
|
||||||
|
|
||||||
expect(current_path).to eq(new_conference_conference_registrations_path(conference.short_title))
|
expect(current_path).to eq(new_conference_conference_registrations_path(conference.short_title))
|
||||||
|
|
||||||
expect(Event.count).to eq(expected_count)
|
expect(Event.count).to eq(expected_count)
|
||||||
|
end
|
||||||
|
|
||||||
event = Event.where(title: 'Example Proposal').first
|
scenario 'confirms a proposal', feature: true, js: true do
|
||||||
|
|
||||||
visit conference_proposal_index_path(conference.short_title)
|
|
||||||
expect(page.has_content?('Example Proposal')).to be true
|
|
||||||
|
|
||||||
expected_count_commercial = Commercial.count + 1
|
|
||||||
# Add a invalid commercial
|
|
||||||
visit edit_conference_proposal_path(conference.short_title, event.id)
|
|
||||||
|
|
||||||
click_link 'Commercials'
|
|
||||||
click_link 'Add Commercial'
|
|
||||||
|
|
||||||
select('SlideShare', from: 'commercial_commercial_type')
|
|
||||||
|
|
||||||
click_button 'Create Commercial'
|
|
||||||
expect(flash).to eq("A error prohibited this Commercial from being saved: Commercial can't be blank.")
|
|
||||||
expect(event.commercials.count).to eq(expected_count_commercial - 1)
|
|
||||||
|
|
||||||
# Add a valid commercial
|
|
||||||
visit edit_conference_proposal_path(conference.short_title, event.id)
|
|
||||||
|
|
||||||
click_link 'Commercials'
|
|
||||||
click_link 'Add Commercial'
|
|
||||||
|
|
||||||
select('SlideShare', from: 'commercial_commercial_type')
|
|
||||||
fill_in 'commercial_commercial_id', with: '12345'
|
|
||||||
|
|
||||||
click_button 'Create Commercial'
|
|
||||||
expect(flash).to eq('Commercial was successfully created.')
|
|
||||||
expect(event.commercials.count).to eq(expected_count_commercial)
|
|
||||||
|
|
||||||
# Edit an invalid commercial
|
|
||||||
click_link 'Commercials'
|
|
||||||
click_link 'Edit'
|
|
||||||
|
|
||||||
select('SlideShare', from: 'commercial_commercial_type')
|
|
||||||
fill_in 'commercial_commercial_id', with: ''
|
|
||||||
|
|
||||||
click_button 'Update Commercial'
|
|
||||||
expect(flash).to eq("A error prohibited this Commercial from being saved: Commercial can't be blank.")
|
|
||||||
expect(event.commercials.count).to eq(expected_count_commercial)
|
|
||||||
|
|
||||||
# Edit a valid commercial
|
|
||||||
select('SlideShare', from: 'commercial_commercial_type')
|
|
||||||
fill_in 'commercial_commercial_id', with: '56789'
|
|
||||||
|
|
||||||
click_button 'Update Commercial'
|
|
||||||
expect(flash).to eq('Commercial was successfully updated.')
|
|
||||||
expect(event.commercials.count).to eq(expected_count_commercial)
|
|
||||||
|
|
||||||
# Delete a commercial
|
|
||||||
click_link 'Commercials'
|
|
||||||
click_link 'Delete'
|
|
||||||
page.driver.network_traffic
|
|
||||||
expect(flash).to eq('Commercial was successfully destroyed.')
|
|
||||||
expect(event.commercials.count).to eq(expected_count_commercial - 1)
|
|
||||||
|
|
||||||
sign_out
|
|
||||||
sign_in organizer
|
|
||||||
|
|
||||||
# Reject proposal
|
|
||||||
visit admin_conference_events_path(conference.short_title)
|
|
||||||
expect(page.has_content?('Example Proposal')).to be true
|
|
||||||
|
|
||||||
click_button 'New'
|
|
||||||
click_link "reject_event_#{event.id}"
|
|
||||||
expect(flash).to eq('Event rejected!')
|
|
||||||
click_button 'Rejected'
|
|
||||||
click_link "restart_event_#{event.id}"
|
|
||||||
expect(flash).to eq('Review started!')
|
|
||||||
|
|
||||||
# Start review
|
|
||||||
click_button 'New'
|
|
||||||
click_link "accept_event_#{event.id}"
|
|
||||||
expect(flash).to eq('Event accepted!')
|
|
||||||
expect(page.has_content?('Unconfirmed')).to be true
|
|
||||||
sign_out
|
|
||||||
|
|
||||||
# Confirm proposal as participant
|
|
||||||
sign_in participant
|
sign_in participant
|
||||||
visit conference_proposal_index_path(conference.short_title)
|
visit conference_proposal_index_path(conference.short_title)
|
||||||
expect(page.has_content?('Example Proposal')).to be true
|
expect(page.has_content?('Example Proposal')).to be true
|
||||||
expect(page.has_content?('Unconfirmed')).to be true
|
expect(page.has_content?('Unconfirmed')).to be true
|
||||||
click_link "confirm_proposal_#{event.id}"
|
click_link "confirm_proposal_#{@event.id}"
|
||||||
expect(flash).
|
expect(flash).
|
||||||
to eq('The proposal was confirmed. Please register to attend the conference.')
|
to eq('The proposal was confirmed. Please register to attend the conference.')
|
||||||
|
@event.reload
|
||||||
|
expect(@event.state).to eq('confirmed')
|
||||||
|
end
|
||||||
|
|
||||||
# Register for conference
|
scenario 'withdraw a proposal', feature: true, js: true do
|
||||||
find('#register').click
|
sign_in participant
|
||||||
expect(flash).to eq('You are now registered and will be receiving E-Mail notifications.')
|
@event.confirm!
|
||||||
|
|
||||||
# Withdraw proposal
|
|
||||||
visit conference_proposal_index_path(conference.short_title)
|
visit conference_proposal_index_path(conference.short_title)
|
||||||
|
expect(page.has_content?('Example Proposal')).to be true
|
||||||
expect(page.has_content?('Confirmed')).to be true
|
expect(page.has_content?('Confirmed')).to be true
|
||||||
click_link "delete_proposal_#{event.id}"
|
click_link "delete_proposal_#{@event.id}"
|
||||||
expect(flash).to eq('Proposal was successfully withdrawn.')
|
expect(flash).to eq('Proposal was successfully withdrawn.')
|
||||||
|
@event.reload
|
||||||
|
expect(@event.state).to eq('withdrawn')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'proposal' do
|
|
||||||
it_behaves_like 'proposal workflow'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
feature SupporterLevel do
|
|
||||||
let!(:conference) { create(:conference) }
|
|
||||||
let!(:organizer_role) { create(:organizer_role, resource: conference) }
|
|
||||||
let!(:user) { create(:user, role_ids: [organizer_role.id]) }
|
|
||||||
|
|
||||||
shared_examples 'supporter levels' do
|
|
||||||
scenario 'adds and updates supporter level', feature: true, js: true do
|
|
||||||
sign_in user
|
|
||||||
visit admin_conference_supporter_levels_path(conference_id: conference.short_title)
|
|
||||||
|
|
||||||
# Add supporter level
|
|
||||||
click_link 'Add supporter_level'
|
|
||||||
expect(page.all('div.nested-fields').count == 1).to be true
|
|
||||||
|
|
||||||
page.
|
|
||||||
find('div.nested-fields:nth-of-type(1) div:nth-of-type(1) input').
|
|
||||||
set('Example supporter level')
|
|
||||||
|
|
||||||
page.
|
|
||||||
find('div.nested-fields:nth-of-type(1) div:nth-of-type(2) input').
|
|
||||||
set('http://www.google.de')
|
|
||||||
|
|
||||||
click_button 'Update Conference'
|
|
||||||
|
|
||||||
# Validations
|
|
||||||
expect(flash).to eq('Supporter levels were successfully updated.')
|
|
||||||
expect(find('div.nested-fields:nth-of-type(1) div:nth-of-type(1) input').
|
|
||||||
value).to eq('Example supporter level')
|
|
||||||
expect(find('div.nested-fields:nth-of-type(1) div:nth-of-type(2) input').
|
|
||||||
value).to eq('http://www.google.de')
|
|
||||||
|
|
||||||
# Remove supporter level
|
|
||||||
click_link 'Remove supporter_level'
|
|
||||||
expect(page.all('div.nested-fields').count == 0).to be true
|
|
||||||
find('button', text: 'Update Conference').trigger('click')
|
|
||||||
expect(flash).to eq('Supporter levels were successfully updated.')
|
|
||||||
expect(page.all('div.nested-fields').count == 0).to be true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'organizer' do
|
|
||||||
it_behaves_like 'supporter levels'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
51
spec/features/ticket_purchases_spec.rb
Normal file
51
spec/features/ticket_purchases_spec.rb
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature Registration do
|
||||||
|
let!(:ticket) { create(:ticket) }
|
||||||
|
let!(:conference) { create(:conference, title: 'ExampleCon', tickets: [ticket]) }
|
||||||
|
let!(:participant) { create(:user) }
|
||||||
|
|
||||||
|
context 'as a participant' do
|
||||||
|
before(:each) do
|
||||||
|
sign_in participant
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:each) do
|
||||||
|
sign_out
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'who is not registered' do
|
||||||
|
|
||||||
|
scenario 'purchases a ticket', feature: true, js: true do
|
||||||
|
visit root_path
|
||||||
|
click_link 'Support'
|
||||||
|
|
||||||
|
fill_in "tickets__#{ticket.id}", with: '2'
|
||||||
|
expect(current_path).to eq(conference_tickets_path(conference.short_title))
|
||||||
|
|
||||||
|
click_button 'Support'
|
||||||
|
|
||||||
|
purchase = TicketPurchase.where(user_id: participant.id, ticket_id: ticket.id).first
|
||||||
|
expect(purchase.quantity).to eq(2)
|
||||||
|
expect(current_path).to eq(conference_conference_registrations_path(conference.short_title))
|
||||||
|
expect(flash).
|
||||||
|
to eq('Congratulations, you have successfully purchased a ticket! You can pay it cash on check in! Thank you for supporting ExampleCon!')
|
||||||
|
expect(page.has_content?('Business Ticket')).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'deletes a purchased ticket', feature: true, js: true do
|
||||||
|
create(:ticket_purchase,
|
||||||
|
user_id: participant.id,
|
||||||
|
ticket_id: ticket.id,
|
||||||
|
quantity: 2)
|
||||||
|
|
||||||
|
visit conference_conference_registrations_path(conference.short_title)
|
||||||
|
expect(page.has_content?('Business Ticket')).to be true
|
||||||
|
|
||||||
|
click_link 'Delete'
|
||||||
|
expect(flash).to eq('Ticket successfully destroyed.')
|
||||||
|
expect(TicketPurchase.count).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
86
spec/features/tickets_spec.rb
Normal file
86
spec/features/tickets_spec.rb
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature Ticket do
|
||||||
|
let!(:conference) { create(:conference, title: 'ExampleCon') }
|
||||||
|
let!(:organizer_role) { create(:organizer_role, resource: conference) }
|
||||||
|
let!(:organizer) { create(:user, email: 'admin@example.com', role_ids: [organizer_role.id]) }
|
||||||
|
|
||||||
|
context 'as a organizer' do
|
||||||
|
before(:each) do
|
||||||
|
sign_in organizer
|
||||||
|
end
|
||||||
|
|
||||||
|
after(:each) do
|
||||||
|
sign_out
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'add a valid ticket', feature: true, js: true do
|
||||||
|
visit admin_conference_tickets_path(conference.short_title)
|
||||||
|
click_link 'Add Ticket'
|
||||||
|
|
||||||
|
fill_in 'ticket_title', with: 'Business Ticket'
|
||||||
|
fill_in 'ticket_description', with: 'The business ticket'
|
||||||
|
fill_in 'ticket_price', with: '100'
|
||||||
|
|
||||||
|
click_button 'Create Ticket'
|
||||||
|
expect(flash).to eq('Ticket successfully created.')
|
||||||
|
expect(Ticket.count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'add a invalid ticket', feature: true, js: true do
|
||||||
|
visit admin_conference_tickets_path(conference.short_title)
|
||||||
|
click_link 'Add Ticket'
|
||||||
|
|
||||||
|
fill_in 'ticket_title', with: ''
|
||||||
|
fill_in 'ticket_price', with: '-1'
|
||||||
|
|
||||||
|
click_button 'Create Ticket'
|
||||||
|
expect(flash).to eq("Creating Ticket failed: Title can't be blank. Price cents must be greater than 0.")
|
||||||
|
expect(Ticket.count).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'Ticket already created' do
|
||||||
|
let!(:ticket) { create(:ticket, title: 'Business Ticket', price: 100, conference_id: conference.id) }
|
||||||
|
|
||||||
|
scenario 'edit valid ticket', feature: true, js: true do
|
||||||
|
visit admin_conference_tickets_path(conference.short_title)
|
||||||
|
click_link 'Edit'
|
||||||
|
|
||||||
|
fill_in 'ticket_title', with: 'Free Ticket'
|
||||||
|
fill_in 'ticket_price', with: '50'
|
||||||
|
|
||||||
|
click_button 'Update Ticket'
|
||||||
|
|
||||||
|
ticket.reload
|
||||||
|
expect(ticket.price).to eq(50)
|
||||||
|
expect(ticket.title).to eq('Free Ticket')
|
||||||
|
expect(flash).to eq('Ticket successfully updated.')
|
||||||
|
expect(Ticket.count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'edit invalid ticket', feature: true, js: true do
|
||||||
|
visit admin_conference_tickets_path(conference.short_title)
|
||||||
|
click_link 'Edit'
|
||||||
|
|
||||||
|
fill_in 'ticket_title', with: ''
|
||||||
|
fill_in 'ticket_price', with: '-5'
|
||||||
|
|
||||||
|
click_button 'Update Ticket'
|
||||||
|
|
||||||
|
ticket.reload
|
||||||
|
expect(ticket.price).to eq(100)
|
||||||
|
expect(ticket.title).to eq('Business Ticket')
|
||||||
|
expect(flash).to eq("Ticket update failed: Title can't be blank. Price cents must be greater than 0.")
|
||||||
|
expect(Ticket.count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'delete ticket', feature: true, js: true do
|
||||||
|
visit admin_conference_tickets_path(conference.short_title)
|
||||||
|
click_link 'Delete'
|
||||||
|
|
||||||
|
expect(flash).to eq('Ticket successfully destroyed.')
|
||||||
|
expect(Ticket.count).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
105
spec/models/ticket_purchase_spec.rb
Normal file
105
spec/models/ticket_purchase_spec.rb
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe TicketPurchase do
|
||||||
|
|
||||||
|
describe 'validations' do
|
||||||
|
it 'has a valid factory' do
|
||||||
|
expect(build(:ticket_purchase)).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid without a conference_id' do
|
||||||
|
should validate_presence_of(:conference_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid without a ticket_id' do
|
||||||
|
should validate_presence_of(:ticket_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid without a user_id' do
|
||||||
|
should validate_presence_of(:user_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid without a quantity' do
|
||||||
|
should validate_presence_of(:quantity)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid with a quantity equals zero' do
|
||||||
|
should_not allow_value(0).for(:quantity)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid with a quantity smaller than zero' do
|
||||||
|
should_not allow_value(-1).for(:quantity)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is valid with a quantity greater than zero' do
|
||||||
|
should allow_value(1).for(:quantity)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'self#purchase' do
|
||||||
|
let!(:participant) { create(:user) }
|
||||||
|
let!(:ticket_1) { create(:ticket) }
|
||||||
|
let!(:ticket_2) { create(:ticket) }
|
||||||
|
let!(:conference) { create(:conference, tickets: [ticket_1, ticket_2]) }
|
||||||
|
|
||||||
|
it 'creates a purchase for one ticket' do
|
||||||
|
tickets = { ticket_1.id.to_s => '1' }
|
||||||
|
message = TicketPurchase.purchase(conference, participant, tickets)
|
||||||
|
purchase = TicketPurchase.where(conference_id: conference.id,
|
||||||
|
user_id: participant.id,
|
||||||
|
ticket_id: ticket_1.id).first
|
||||||
|
|
||||||
|
expect(TicketPurchase.count).to eq(1)
|
||||||
|
expect(purchase.quantity).to eq(1)
|
||||||
|
expect(message.blank?).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates several purchases for more than one ticket' do
|
||||||
|
tickets = { ticket_1.id.to_s => '1', ticket_2.id.to_s => '1' }
|
||||||
|
message = TicketPurchase.purchase(conference, participant, tickets)
|
||||||
|
purchase_1 = TicketPurchase.where(conference_id: conference.id,
|
||||||
|
user_id: participant.id,
|
||||||
|
ticket_id: ticket_1.id).first
|
||||||
|
|
||||||
|
purchase_2 = TicketPurchase.where(conference_id: conference.id,
|
||||||
|
user_id: participant.id,
|
||||||
|
ticket_id: ticket_2.id).first
|
||||||
|
|
||||||
|
expect(TicketPurchase.count).to eq(2)
|
||||||
|
expect(purchase_1.quantity).to eq(1)
|
||||||
|
expect(purchase_2.quantity).to eq(1)
|
||||||
|
expect(message.blank?).to be true
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates no purchase if quantity is less than 1' do
|
||||||
|
tickets = { ticket_1.id.to_s => '-1' }
|
||||||
|
TicketPurchase.purchase(conference, participant, tickets)
|
||||||
|
|
||||||
|
expect(TicketPurchase.count).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates no purchase if quantity is 0' do
|
||||||
|
tickets = { ticket_1.id.to_s => '0' }
|
||||||
|
TicketPurchase.purchase(conference, participant, tickets)
|
||||||
|
|
||||||
|
expect(TicketPurchase.count).to eq(0)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'updates the quantity if the user already bought this ticket' do
|
||||||
|
purchase = create(:ticket_purchase,
|
||||||
|
conference: conference,
|
||||||
|
user: participant,
|
||||||
|
ticket: ticket_1,
|
||||||
|
quantity: 5)
|
||||||
|
|
||||||
|
tickets = { ticket_1.id.to_s => '10' }
|
||||||
|
message = TicketPurchase.purchase(conference, participant, tickets)
|
||||||
|
purchase.reload
|
||||||
|
|
||||||
|
expect(TicketPurchase.count).to eq(1)
|
||||||
|
expect(purchase.quantity).to eq(10)
|
||||||
|
expect(message.blank?).to be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
92
spec/models/ticket_spec.rb
Normal file
92
spec/models/ticket_spec.rb
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Ticket do
|
||||||
|
let(:conference) { create(:conference) }
|
||||||
|
let(:ticket) { create(:ticket, price: 50, conference: conference) }
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
describe 'validations' do
|
||||||
|
it 'has a valid factory' do
|
||||||
|
expect(build(:ticket)).to be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid without a title' do
|
||||||
|
should validate_presence_of(:title)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid without a price_cents' do
|
||||||
|
should validate_presence_of(:price_cents)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid without a price_currency' do
|
||||||
|
should validate_presence_of(:price_currency)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid with a price_cents equals zero' do
|
||||||
|
should_not allow_value(0).for(:price_cents)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is not valid with a price_cents smaller than zero' do
|
||||||
|
should_not allow_value(-1).for(:price_cents)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'is valid with a price_cents greater than zero' do
|
||||||
|
should allow_value(1).for(:price_cents)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#bought?' do
|
||||||
|
it 'returns true if the user has bought this ticket' do
|
||||||
|
create(:ticket_purchase,
|
||||||
|
user: user,
|
||||||
|
ticket: ticket)
|
||||||
|
expect(ticket.bought?(user)).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns true if the user has bought this ticket' do
|
||||||
|
expect(ticket.bought?(user)).to eq(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#quantity_bought_by' do
|
||||||
|
it 'returns the correct value if the user has bought this ticket' do
|
||||||
|
create(:ticket_purchase,
|
||||||
|
user: user,
|
||||||
|
ticket: ticket,
|
||||||
|
quantity: 20)
|
||||||
|
expect(ticket.quantity_bought_by(user)).to eq(20)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns zero if the user has not bought this ticket' do
|
||||||
|
expect(ticket.quantity_bought_by(user)).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#total_price' do
|
||||||
|
it 'returns the correct value if the user has bought this ticket' do
|
||||||
|
create(:ticket_purchase,
|
||||||
|
user: user,
|
||||||
|
ticket: ticket,
|
||||||
|
quantity: 20)
|
||||||
|
expect(ticket.total_price(user)).to eq(20 * 50)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns zero if the user has not bought this ticket' do
|
||||||
|
expect(ticket.total_price(user)).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'self#total_price' do
|
||||||
|
it 'returns the correct value if the user has bought this ticket' do
|
||||||
|
create(:ticket_purchase,
|
||||||
|
user: user,
|
||||||
|
ticket: ticket,
|
||||||
|
quantity: 20)
|
||||||
|
expect(Ticket.total_price(conference, user)).to eq(20 * 50)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns zero if the user has not bought this ticket' do
|
||||||
|
expect(Ticket.total_price(conference, user)).to eq(0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe 'admin/supporter_levels/index' do
|
|
||||||
|
|
||||||
it 'renders supporter levels' do
|
|
||||||
@support_level = create(:supporter_level)
|
|
||||||
assign :conference, @support_level.conference
|
|
||||||
render
|
|
||||||
expect(rendered).to include('Example Supporter Level')
|
|
||||||
expect(rendered).to include('www.example.com')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue