Refactoring Tickets

- Tickets now independent from registration
- Implemented money gem
#419
This commit is contained in:
Chrisbr 2014-08-28 15:21:05 +02:00
parent 5485fe0e7f
commit 5f8a8ac6d9
63 changed files with 1581 additions and 573 deletions

View file

@ -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){

View file

@ -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();
});
} );

View 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));
});
});

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View 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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,6 @@
class EventsRegistration < ActiveRecord::Base
attr_accessible :registration_id, :event_id
belongs_to :registration
belongs_to :event
end

View file

@ -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!

View file

@ -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

View file

@ -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
View 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

View 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

View file

@ -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

View file

@ -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');

View file

@ -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")

View file

@ -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>

View file

@ -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"}

View 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' }

View 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 }

View 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'

View 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 }

View 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'

View file

@ -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'

View file

@ -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'

View file

@ -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');

View 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

View 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

View 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)

View 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)

View file

@ -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'

View file

@ -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

View 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

View 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'