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
|
|
@ -29,6 +29,7 @@
|
|||
//= require bootstrap-datetimepicker
|
||||
//= require osem-datepickers
|
||||
//= require osem-datatables
|
||||
//= require osem-tickets
|
||||
|
||||
$(document).ready(function() {
|
||||
$('a[disabled=disabled]').click(function(event){
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
$(function () {
|
||||
$(document).ready(function() {
|
||||
$('#registrations-datatable').dataTable();
|
||||
} );
|
||||
});
|
||||
$(document).ready(function() {
|
||||
$('#users-datatable').dataTable();
|
||||
} );
|
||||
});
|
||||
$(document).ready(function() {
|
||||
$('#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}"
|
||||
redirect_to admin_conference_registrations_path(@conference.short_title)
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
def edit; end
|
||||
|
||||
def update
|
||||
@registration.update_attributes(registration_params)
|
||||
|
|
@ -51,7 +51,7 @@ module Admin
|
|||
protected
|
||||
|
||||
def set_user
|
||||
@user = User.where('id = ?', @registration.user_id).first
|
||||
@user = User.find_by(id: @registration.user_id)
|
||||
end
|
||||
|
||||
def registration_params
|
||||
|
|
@ -63,10 +63,7 @@ module Admin
|
|||
qanswers_attributes: [],
|
||||
user_attributes: [
|
||||
:id, :name, :tshirt, :mobile, :volunteer_experience, :languages,
|
||||
:nickname, :affiliation ],
|
||||
supporter_registration_attributes: [
|
||||
:id, :supporter_level_id, :code
|
||||
])
|
||||
:nickname, :affiliation ])
|
||||
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
|
||||
load_resource :conference, find_by: :short_title
|
||||
authorize_resource :conference_registrations, class: Registration
|
||||
before_action :set_registration, only: [:edit, :update, :destroy]
|
||||
before_action :set_workshops, only: [:new, :edit, :update, :create]
|
||||
before_action :set_registration, only: [:edit, :update, :destroy, :show]
|
||||
|
||||
def new
|
||||
@registration = current_user.registrations.build(conference_id: @conference.id)
|
||||
@registration.build_supporter_registration
|
||||
end
|
||||
|
||||
def edit
|
||||
def show
|
||||
@workshops = @registration.workshops if @registration
|
||||
@total_price = Ticket.total_price(@conference, current_user)
|
||||
end
|
||||
|
||||
def edit; end
|
||||
|
||||
def create
|
||||
user_attributes = registration_params[:user_attributes]
|
||||
params[:registration].delete :user_attributes
|
||||
|
|
@ -24,16 +26,13 @@ class ConferenceRegistrationsController < ApplicationController
|
|||
# Trigger ahoy event
|
||||
ahoy.track 'Registered', title: 'New registration'
|
||||
|
||||
# Send registration mail
|
||||
if @conference.email_settings.send_on_registration?
|
||||
Mailbot.delay.registration_mail(@conference, current_user)
|
||||
if @conference.tickets.any?
|
||||
redirect_to conference_tickets_path(@conference.short_title),
|
||||
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
|
||||
|
||||
# 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
|
||||
flash[:alert] = "A error prohibited the registration for #{@conference.title}: "\
|
||||
"#{@registration.errors.full_messages.join('. ')}."
|
||||
|
|
@ -42,9 +41,9 @@ class ConferenceRegistrationsController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
if @registration.update(registration_params)
|
||||
redirect_to edit_conference_conference_registrations_path(@conference.short_title),
|
||||
notice: 'Registration was successfully updated.'
|
||||
if @registration.update_attributes(registration_params)
|
||||
redirect_to conference_conference_registrations_path(@conference.short_title),
|
||||
notice: 'Registration was successfully updated.'
|
||||
else
|
||||
flash[:alert] = "A error prohibited the registration for #{@conference.title}: "\
|
||||
"#{@registration.errors.full_messages.join('. ')}."
|
||||
|
|
@ -53,19 +52,20 @@ class ConferenceRegistrationsController < ApplicationController
|
|||
end
|
||||
|
||||
def destroy
|
||||
@registration.destroy
|
||||
redirect_to root_path,
|
||||
notice: "You are not registered for #{@conference.title} anymore!"
|
||||
if @registration.destroy
|
||||
redirect_to root_path,
|
||||
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
|
||||
|
||||
protected
|
||||
|
||||
def set_workshops
|
||||
@workshops = @conference.events.where('require_registration = ? AND state LIKE ?', true, 'confirmed')
|
||||
end
|
||||
|
||||
def set_registration
|
||||
@registration = current_user.registrations.where(conference_id: @conference.id).first
|
||||
@registration = current_user.registrations.find_by(conference_id: @conference.id)
|
||||
end
|
||||
|
||||
def registration_params
|
||||
|
|
@ -77,9 +77,7 @@ class ConferenceRegistrationsController < ApplicationController
|
|||
qanswers_attributes: [],
|
||||
event_ids: [],
|
||||
user_attributes: [
|
||||
:id, :name, :tshirt, :mobile, :volunteer_experience, :languages],
|
||||
supporter_registration_attributes: [
|
||||
:id, :supporter_level_id, :code
|
||||
])
|
||||
:id, :name, :tshirt, :mobile, :volunteer_experience, :languages]
|
||||
)
|
||||
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, Sponsor, 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 :index, Commercial, commercialable_type: 'Conference'
|
||||
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,
|
||||
:start_date, :end_date, :rooms_attributes, :tracks_attributes,
|
||||
:dietary_choices_attributes, :use_dietary_choices, :use_supporter_levels,
|
||||
:supporter_levels_attributes, :social_events_attributes, :event_types_attributes,
|
||||
:dietary_choices_attributes, :use_dietary_choices,
|
||||
:tickets_attributes, :social_events_attributes, :event_types_attributes,
|
||||
:logo, :questions_attributes,
|
||||
:question_ids, :answers_attributes, :answer_ids, :difficulty_levels_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 :call_for_papers, dependent: :destroy
|
||||
has_many :social_events, dependent: :destroy
|
||||
has_many :supporter_registrations, dependent: :destroy
|
||||
has_many :supporter_levels, dependent: :destroy
|
||||
has_many :ticket_purchases
|
||||
has_many :supporters, through: :ticket_purchases, source: :user
|
||||
has_many :tickets, 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 :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 :tracks, 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 :venue
|
||||
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 :sponsors, 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
|
||||
end
|
||||
|
||||
def speaker_names
|
||||
result = []
|
||||
speakers.each do |speaker|
|
||||
result.push(speaker.name)
|
||||
end
|
||||
result.to_sentence
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
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 :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 :events
|
||||
has_and_belongs_to_many :qanswers
|
||||
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,
|
||||
:using_affiliated_lodging, :arrival, :departure, :user_attributes, :attended,
|
||||
: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
|
||||
|
||||
accepts_nested_attributes_for :user
|
||||
accepts_nested_attributes_for :supporter_registration
|
||||
accepts_nested_attributes_for :social_events
|
||||
accepts_nested_attributes_for :qanswers
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ class Registration < ActiveRecord::Base
|
|||
|
||||
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
|
||||
created_at.strftime('%W').to_i
|
||||
|
|
@ -38,6 +38,16 @@ class Registration < ActiveRecord::Base
|
|||
|
||||
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
|
||||
self.week = created_at.strftime('%W')
|
||||
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 :events, -> { uniq }, through: :event_users
|
||||
has_many :registrations, dependent: :destroy
|
||||
has_many :ticket_purchases
|
||||
has_many :tickets, through: :ticket_purchases, source: :ticket
|
||||
has_many :votes, dependent: :destroy
|
||||
has_many :voted_events, through: :votes, source: :events
|
||||
has_many :subscriptions, dependent: :destroy
|
||||
|
|
@ -29,6 +31,13 @@ class User < ActiveRecord::Base
|
|||
|
||||
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.
|
||||
# ====Returns
|
||||
# * +User::ActiveRecord_Relation+ -> user
|
||||
|
|
|
|||
|
|
@ -12,10 +12,6 @@
|
|||
= u.input :nickname, as: :string
|
||||
= u.input :affiliation, placeholder: 'Company/User Group/nothing', as: :string
|
||||
= 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|
|
||||
%h5
|
||||
= "Q: #{q.title}"
|
||||
|
|
@ -33,10 +29,3 @@
|
|||
%br
|
||||
= 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' }
|
||||
: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 Name
|
||||
%th E-Mail
|
||||
%th Ticket
|
||||
%th Arrival
|
||||
%th Departure
|
||||
%th Attended
|
||||
|
|
@ -32,9 +31,6 @@
|
|||
= registration.name
|
||||
%td
|
||||
= registration.email
|
||||
%td
|
||||
- if registration.supporter_level
|
||||
= registration.supporter_level.title
|
||||
%td
|
||||
- if registration.arrival
|
||||
= 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'
|
||||
- else
|
||||
= 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?
|
||||
= render 'tickets'
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
%div.row
|
||||
%h3 Tickets
|
||||
-if !@conference.ticket_description.blank?
|
||||
-if @conference.ticket_description.present?
|
||||
.lead
|
||||
= markdown(@conference.ticket_description)
|
||||
- @conference.supporter_levels.each do |s|
|
||||
- @conference.tickets.each do |ticket|
|
||||
%div.col-md-6
|
||||
- if !s.title.blank?
|
||||
%h4 #{ s.title }
|
||||
-if !s.description.blank?
|
||||
.lead #{ s.description }
|
||||
- if !s.url.blank?
|
||||
%div.btn-group
|
||||
= link_to "Buy Ticket", s.url, class: 'btn btn-success', target: '_blank'
|
||||
- if !s.ticket_price.blank?
|
||||
= button_tag "#{s.ticket_price}", class: 'btn btn-success'
|
||||
- if ticket.title.present?
|
||||
%h4 #{ ticket.title }
|
||||
- if ticket.description.present?
|
||||
.lead
|
||||
= markdown(ticket.description)
|
||||
%div.btn-group
|
||||
= link_to "Buy Ticket", conference_tickets_path(@conference.short_title), class: 'btn btn-success'
|
||||
= button_tag "#{humanized_money_with_symbol ticket.price}", class: 'btn btn-success'
|
||||
|
|
|
|||
|
|
@ -14,22 +14,11 @@
|
|||
- if @conference.questions
|
||||
= render partial: 'questions', locals: { f: f }
|
||||
%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.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.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' }
|
||||
|
||||
: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"
|
||||
- elsif conference.cfp_open?
|
||||
= 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
|
||||
%li{:class=> active_nav_li(admin_conference_sponsors_path(@conference.short_title))}
|
||||
= link_to 'Sponsors', admin_conference_sponsors_path(@conference.short_title)
|
||||
- if can? :update, @conference.supporter_levels.build
|
||||
%li{ class: active_nav_li(admin_conference_supporter_levels_path(@conference.short_title)) }
|
||||
= link_to(admin_conference_supporter_levels_path(@conference.short_title)) do
|
||||
- if can? :update, @conference.tickets.build
|
||||
%li{ class: active_nav_li(admin_conference_tickets_path(@conference.short_title)) }
|
||||
= link_to(admin_conference_tickets_path(@conference.short_title)) do
|
||||
%span.fa.fa-usd
|
||||
Supporter Levels
|
||||
Tickets
|
||||
- if can? :update, @conference.email_settings
|
||||
%li{:class=> active_nav_li(admin_conference_emails_path(@conference.short_title))}
|
||||
= 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'
|
||||
Loading…
Add table
Add a link
Reference in a new issue