Skip to content

Commit

Permalink
Sell multiple tickets in one go
Browse files Browse the repository at this point in the history
  • Loading branch information
feliciaan committed Aug 31, 2017
1 parent 3181f25 commit ec78243
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 47 deletions.
16 changes: 10 additions & 6 deletions app/controllers/payment_webhook_controller.rb
Expand Up @@ -8,16 +8,20 @@ def mollie
payment_id = params[:id]

payment = mollie.payments.get payment_id
registration = Registration.find_by_payment_id payment_id
registrations = Registration.where(payment_id: payment_id)

if payment.paid?
registration.paid = payment.amount
RegistrationMailer.ticket(registration).deliver_now
registration.save!
registrations.each do |reg|
reg.paid = payment.amount / reg.number_of_tickets
RegistrationMailer.ticket(reg).deliver_now
reg.save!
end
elsif ['cancelled', 'expired', 'failed'].include? payment.status
RegistrationMailer.payment_failed(registration, registration.event).deliver_now
RegistrationMailer.payment_failed(registrations.first, registrations.first.event).deliver_now

registration.destroy!
registrations.each do |reg|
reg.destroy!
end
end
render :nothing => true, :status => 200, :content_type => 'text/html'
end
Expand Down
117 changes: 85 additions & 32 deletions app/controllers/registrations_controller.rb
Expand Up @@ -73,7 +73,8 @@ def basic
authorize! :register, requested_access_level

# Make the registration
@registration = @event.registrations.new params.require(:registration).permit(:title, :email, :job_function, :firstname, :lastname, :student_number, :comment, :phone_number, :has_plus_one, :plus_one_title, :plus_one_firstname, :plus_one_lastname, :club_id, :payment_method)
@registration = @event.registrations.new params.require(:registration).permit(:title, :email, :job_function, :firstname, :lastname, :student_number, :comment, :phone_number, :has_plus_one, :plus_one_title, :plus_one_firstname, :plus_one_lastname, :club_id, :payment_method, :number_of_tickets)
@registration.sequence_number = 1
@registration.access_levels << requested_access_level
@registration.price = requested_access_level.price
@registration.paid = 0
Expand All @@ -83,43 +84,95 @@ def basic
if requested_access_level.requires_login?
@registration.student_number = current_user.cas_ugentStudentID
end
@registration.save

# Send the confirmation email.
if not @registration.errors.any?
if @event.allow_plus_one and @registration.has_plus_one
plus_one_registration = @event.registrations.new :title => @registration.plus_one_title, :email => @registration.email, :firstname => @registration.plus_one_firstname, :lastname => @registration.plus_one_lastname, :job_function => @registration.job_function, :comment => @registration.comment, :student_number=>@registration.student_number
plus_one_registration.access_levels << requested_access_level
plus_one_registration.price = requested_access_level.price
plus_one_registration.paid = 0

plus_one_registration.save!
plus_one_registration.generate_barcode
if plus_one_registration.is_paid
RegistrationMailer.ticket(plus_one_registration).deliver_now
else
RegistrationMailer.confirm_registration(plus_one_registration).deliver_now

if @registration.number_of_tickets > 1
if requested_access_level.tickets_left == nil or requested_access_level.tickets_left >= @registration.number_of_tickets
@registrations = [@registration] + 2.upto(@registration.number_of_tickets).map do |n|
reg = @event.registrations.new :title => @registration.title, :email => @registration.email, :firstname => @registration.firstname, :lastname => @registration.lastname, :job_function => @registration.job_function, :comment => @registration.comment, :student_number=>@registration.student_number, :club_id => @registration.club_id, :number_of_tickets => @registration.number_of_tickets
reg.access_levels << requested_access_level
reg.price = requested_access_level.price
reg.paid = 0
reg.sequence_number = n
reg.payment_method = 'mollie'
reg
end

Registration.transaction do
@registrations.each { |r| r.save! }
end

if not @registration.errors.any? and not @registrations.last.errors.any?
@registrations.each { |r| r.generate_barcode }

if @registration.is_paid
@registrations.each { |r| RegistrationMailer.ticket(r).deliver_now }
else
if @registration.payment_method == 'mollie'
mollie = Mollie::API::Client.new(Rails.application.secrets.mollie_api_key)

payment = mollie.payments.create(
amount: @registration.price*@registration.number_of_tickets,
description: "Ticket (#{@registration.number_of_tickets}): #{@registration.event.name}",
redirect_url: url_for(@registration.event),
webhook_url: url_for(controller: :payment_webhook, action: 'mollie'),
metadata: { registration_ids: @registrations.map { |r| r.id }}
)

@registrations.each do |r|
r.payment_id = payment.id
r.save!
end

redirect_to payment.payment_url
flash[:info] = t('flash.mollie')
return
end
end
end
end
@registration.generate_barcode

if @registration.is_paid
RegistrationMailer.ticket(@registration).deliver_now
else
if @registration.payment_method == 'mollie'
payment = create_mollie_payment
redirect_to payment.payment_url
flash[:info] = t('flash.mollie')
return
@registration.errors.add(:number_of_tickets, "Not enough tickets available.")
end
render "events/show"
else
@registration.save

# Send the confirmation email.
if not @registration.errors.any?
if @event.allow_plus_one and @registration.has_plus_one
plus_one_registration = @event.registrations.new :title => @registration.plus_one_title, :email => @registration.email, :firstname => @registration.plus_one_firstname, :lastname => @registration.plus_one_lastname, :job_function => @registration.job_function, :comment => @registration.comment, :student_number=>@registration.student_number
plus_one_registration.access_levels << requested_access_level
plus_one_registration.price = requested_access_level.price
plus_one_registration.paid = 0

plus_one_registration.save!
plus_one_registration.generate_barcode
if plus_one_registration.is_paid
RegistrationMailer.ticket(plus_one_registration).deliver_now
else
RegistrationMailer.confirm_registration(plus_one_registration).deliver_now
end
end
@registration.generate_barcode

if @registration.is_paid
RegistrationMailer.ticket(@registration).deliver_now
else
RegistrationMailer.confirm_registration(@registration).deliver_now
if @registration.payment_method == 'mollie'
payment = create_mollie_payment
redirect_to payment.payment_url
flash[:info] = t('flash.mollie')
return
else
RegistrationMailer.confirm_registration(@registration).deliver_now
end
end
end

flash[:success] = t('flash.succes') # or further payment information."
respond_with @event
else
render "events/show"
flash[:success] = t('flash.succes') # or further payment information."
respond_with @event
else
render "events/show"
end
end
end

Expand Down
16 changes: 14 additions & 2 deletions app/mailers/registration_mailer.rb
Expand Up @@ -10,6 +10,12 @@ def confirm_registration(registration)
def ticket(registration)
@registration = registration

if @registration.number_of_tickets == 1
subject = t('mailers.registration.subjects.ticket', :event => registration.event.name)
else
subject = t('mailers.registration.subjects.multiple_ticket', :event => registration.event.name, :number_of_tickets => @registration.number_of_tickets, :sequence_number => @registration.sequence_number)
end

barcode = Barcodes.create('EAN13', data: registration.barcode_data, bar_width: 35, bar_height: 1500, caption_height: 300, caption_size: 275 ) # required: height > size

image = Barcodes::Renderer::Image.new(barcode).render
Expand All @@ -18,7 +24,7 @@ def ticket(registration)
tilted_image = Magick::Image.from_blob(image).first.rotate!(-90).to_blob
attachments.inline['barcode-tilted.png'] = tilted_image

mail to: "#{registration.lastname} #{registration.firstname} <#{registration.email}>", subject: t('mailers.registration.subjects.ticket', :event => registration.event.name)
mail to: "#{registration.lastname} #{registration.firstname} <#{registration.email}>", subject: subject
end

def notify_overpayment(registration)
Expand All @@ -37,6 +43,12 @@ def payment_failed(registration, event)
@registration = registration
@event = event

mail to: "#{registration.lastname} #{registration.firstname} <#{registration.email}>", subject: t('mailers.registration.subjects.failed', :event => registration.event.name)
if @registration.number_of_tickets == 1
subject = t('mailers.registration.subjects.failed', :event => registration.event.name)
else
subject = t('mailers.registration.subjects.multiple_failed', :event => registration.event.name, :number_of_tickets => @registration.number_of_tickets)
end

mail to: "#{registration.lastname} #{registration.firstname} <#{registration.email}>", subject: subject
end
end
6 changes: 6 additions & 0 deletions app/views/registration_mailer/payment_failed.erb
Expand Up @@ -34,6 +34,12 @@
<td><strong>Website</strong></td>
<td><a href="<%= @event.website %>"><%= @event.website %></a></td>
</tr>
<% if @registration.number_of_tickets > 1%>
<tr>
<td><strong>Number of tickets</strong></td>
<td><%= @registration.number_of_tickets %> tickets</td>
</tr>
<% end %>
</tbody>
</table>

Expand Down
2 changes: 1 addition & 1 deletion app/views/registration_mailer/ticket.html.erb
Expand Up @@ -40,7 +40,7 @@
<table cellspacing="0" cellpadding="0" align="right">
<tbody>
<tr>
<td class="pr-15" style="font: 17px/18px Arial, Helvetica, sans-serif; color: #007dd6;"><strong><%= @registration.event.name %></strong><br /> <span style="font-size: 14px;"><%= nice_date @registration.event.start_date %></span></td>
<td class="pr-15" style="font: 17px/18px Arial, Helvetica, sans-serif; color: #007dd6;"><strong><%= @registration.event.name %></strong><br /> <span style="font-size: 14px;"><%= nice_date @registration.event.start_date %></span><%if @registration.number_of_tickets > 1 %><br/>Ticket <%= @registration.sequence_number%>/<%= @registration.number_of_tickets %><%end%></td>
</tr>
</tbody>
</tbody>
Expand Down
1 change: 1 addition & 0 deletions app/views/registrations/_basic.html.erb
Expand Up @@ -28,6 +28,7 @@
<%= form_text_field f, :plus_one_lastname %>
</div>
<% end %>
<%= form_collection_select f, :number_of_tickets, (1..10), :to_i, :to_s %>
<%# <%= form_text_area f, :comment, @event.comment_title %>
<%# <%= javascript_tag do % >
window.ticketsWithComments = <%= @event.access_levels.find_all(&:has_comment).map(&:id).to_json % >
Expand Down
22 changes: 17 additions & 5 deletions config/locales/en.yml
Expand Up @@ -4,11 +4,16 @@ en:
attributes:
registration:
access_levels: Ticket
club_id: Association
comment: Comments
email: E-mail
firstname: Firstname
has_plus_one: Accompanied by partner?
job_function: Job function
lastname: Lastname
name: Name
number_of_tickets: Number of tickets
payment_method: Payment method
phone_number: Phone number
plus_one_firstname: Partner first name
plus_one_lastname: Partner last name
Expand Down Expand Up @@ -36,16 +41,19 @@ en:
end_date: End date
location: Location
organisation: Organisation
payment_methods:
mollie: debit cards
wiretransfer: bank transfer
payments: Payments are only possible through debit cards and bitcoin.
register: Register
start_date: Start date
website: Website
registration:
club:
info: Het Stichtingsbal is een initiatief voor en door studentenverenigingen. U schenkt €1 per ticket aan de vereniging die u hieronder selecteert. Heeft u geen vereniging van uw voorkeur kiest u gewoon ‘Universiteit Gent’.
payments: Payments are only possible through debit cards and bitcoin.
info: The foundation ball (Stichtingsbal) is an initiative by en through the student associations. You donate €1 per ticket to the selected association.
start_date: Start date
website: Website
flash:
succes: Registration successful. Please check your mailbox for your ticket.
mollie: Registration is being processed, check your mailbox for the current status.
succes: Registration successful. Please check your mailbox for your ticket.
forms:
field:
telephone:
Expand All @@ -65,8 +73,12 @@ en:
subjects:
cancel: Cancel registration for %{event}
confirm: Register for %{event}
failed: Aankoop ticket voor %{event} mislukt
multiple_failed: Buying %{number_of_tickets } tickets for %{event} failed
multiple_ticket: Ticket for %{event} %{sequence_number}/%{number_of_tickets}
overpayment: Overpayment for %{event}
ticket: Ticket for %{event}
payment_method: Payment method
plus_one_title: Partner title
registration:
titles:
Expand Down
3 changes: 3 additions & 0 deletions config/locales/nl.yml
Expand Up @@ -21,6 +21,7 @@ nl:
plus_one_lastname: Partner achternaam
club_id: Vereniging
payment_method: Betalingswijze
number_of_tickets: Aantal tickets
datagrid:
table:
order:
Expand Down Expand Up @@ -76,7 +77,9 @@ nl:
confirm: Registratie voor %{event}
overpayment: Teveel betaald voor %{event}
ticket: Ticket voor %{event}
multiple_ticket: Ticket voor %{event} %{sequence_number}/%{number_of_tickets}
failed: Aankoop ticket voor %{event} mislukt
multiple_failed: Aankoop %{number_of_tickets } tickets voor %{event} mislukt
registration:
titles:
dr: dr.
Expand Down
6 changes: 6 additions & 0 deletions db/migrate/20170831210541_add_more_tickets_in_one_sale.rb
@@ -0,0 +1,6 @@
class AddMoreTicketsInOneSale < ActiveRecord::Migration
def change
add_column :registrations, :number_of_tickets, :integer, :default => 1
add_column :registrations, :sequence_number, :integer, :default => 1
end
end
4 changes: 3 additions & 1 deletion db/schema.rb
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20170817125038) do
ActiveRecord::Schema.define(version: 20170831210541) do

create_table "access_levels", force: :cascade do |t|
t.string "name"
Expand Down Expand Up @@ -195,6 +195,8 @@
t.integer "club_id"
t.string "payment_method"
t.string "payment_id"
t.integer "number_of_tickets", default: 1
t.integer "sequence_number", default: 1
end

add_index "registrations", ["event_id"], name: "index_registrations_on_event_id"
Expand Down

0 comments on commit ec78243

Please sign in to comment.