Skip to content

Instantly share code, notes, and snippets.

@cliche2004
Created February 14, 2013 21:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cliche2004/4956594 to your computer and use it in GitHub Desktop.
Save cliche2004/4956594 to your computer and use it in GitHub Desktop.
heroku throwing AbstractionError
<%= form_tag process_order_payments_url(subdomain: 'secure', domain: Settings.domain),
method: 'post', class: "ticket_form",
id: 'ticketSelectionForm' do %>
<%= render partial: 'events/ticket', collection: @tickets %>
<%= hidden_field_tag :event_id, @event.id %>
<%= hidden_field_tag :promo_code, @promoter.promoter_code if @promoter %>
<%= hidden_field_tag :session_id, cookies[:order_session_id] %>
<%= hidden_field_tag :custom_domain, @custom_domain.present? %>
<% if @event.is_active? && @tickets.present? %>
<div class="submit" align="center"><%= submit_tag '', class: "pay-now" %></div>
<% end %>
<% end %>
2013-02-14T18:58:02+00:00 app[web.2]: Started POST "/payments/process_order" for 10.104.73.195 at 2013-02-14 10:58:02 -0800
2013-02-14T18:58:02+00:00 heroku[router]: at=info method=POST path=/payments/process_order host=secure.thedreamvine.com fwd=10.220.123.127 dyno=web.2 queue=0 wait=0ms connect=1ms service=106ms status=301 bytes=120
2013-02-14T18:58:04+00:00 app[web.2]: Started GET "/payments/process_order" for 10.140.66.67 at 2013-02-14 10:58:04 -0800
2013-02-14T18:58:04+00:00 app[web.2]:
2013-02-14T18:58:04+00:00 app[web.2]: AbstractController::ActionNotFound (The action 'show' could not be found for PaymentsController):
2013-02-14T18:58:04+00:00 app[web.2]: .bundle/gems/ruby/1.9.1/gems/actionpack-3.2.11/lib/abstract_controller/base.rb:116:in `process'
2013-02-14T18:58:04+00:00 app[web.2]: .bundle/gems/ruby/1.9.1/gems/actionpack-3.2.11/lib/abstract_controller/rendering.rb:45:in `process'
class PaymentsController < MainController
skip_before_filter :set_promoter, only: [:server_time]
before_filter :set_event, only: [:index, :create]
def process_order
session[:order_id] = nil
session[:reserved_ticket] = {}
session[:transaction_session] = nil
transaction_session, proceed_with_transaction = nil, true
session['from.unbounce'] = false
event_id = params[:event_id]
promoter_code = params[:promo_code] || ""
order_tickets = params[:tickets]
is_a_custom_domain = params[:custom_domain]
session_id = params[:session_id]
alert_message = ""
total = 0
if order_tickets.present?
order_tickets.delete_if {|key, purchase_quantity| purchase_quantity.to_i < 1 } # scrub ticket with 0 qty
end
# redirect_to :back, alert: "Please select a ticket first!" and return false if order_tickets.blank?
redirect_to_back(session_id, "Please select a ticket first!", is_a_custom_domain) and return false if order_tickets.blank?
transaction_session = { tickets: [], event_id: event_id, promoter_code: promoter_code,
total: total, created_at: Time.now, discount_code: nil }
order_tickets.each do |key, purchase_quantity|
purchase_quantity = purchase_quantity.to_i
if purchase_quantity > 0
ticket, total_ticket_left, ticket_threshold, reserved_ticket = set_or_get_ticket_information(key)
logger.info "ticket left: #{total_ticket_left}"
logger.info "reserved ticket: #{reserved_ticket}"
if total_ticket_left > 0 && total_ticket_left >= purchase_quantity
# normal transaction with available ticket
# transaction_session[:tickets].merge!({ key => purchase_quantity })
unix_time = (Time.now + 10.minutes).to_i
$redis.hset("reserved_tickets-#{key.to_s}", unix_time , purchase_quantity) # do ticket reservation!
# store reserved key and value to have reference
session[:reserved_ticket].merge!({ unix_time => purchase_quantity })
ticket_reservation = $redis.hgetall("reserved_tickets-#{key.to_s}")
logger.info "===================="
logger.info session[:reserved_ticket].inspect
logger.info "===================="
ticket_details = ticket.price_and_percent_off(@promoter, @event)
ticket_price = ticket_details[:ticket_price].to_f
ticket_fee = ticket.ticket_fee(ticket_price)
ticket_total = (ticket_price + ticket.ticket_fee(ticket_price)) * purchase_quantity.to_i
# build transaction_session ticket
transaction_session[:tickets] << { id: key, name: ticket.name, qty: purchase_quantity,
ticket_price: ticket_price, ticket_fee: ticket_fee,
total: ticket_total, discount: 0
}
transaction_session[:total] += ticket_total
else
proceed_with_transaction = false
if total_ticket_left > 0 && total_ticket_left <= purchase_quantity
alert_message = "There are only #{total_ticket_left} tickets left."
elsif total_ticket_left <= 0 && reserved_ticket > 0
alert_message = "Sorry, There are no tickets available right now. There are a few on hold. Please try again later."
elsif total_ticket_left <= 0 && reserved_ticket <= 0
alert_message = "Sorry, There are no tickets available"
end
end
end
end
if proceed_with_transaction
# order = Order.build_order_and_details user: current_user, promoter: @promoter,
# transaction_session: transaction_session
logger.info "===================="
logger.info transaction_session.inspect
logger.info "===================="
# session[:order_id] = order.id
session[:transaction_session] = transaction_session
payment_options = { subdomain: 'secure', domain: Settings.domain }
payment_options.merge!({ promo_code: promoter_code }) if promoter_code.present?
redirect_to payments_url(payment_options)
else
# redirect_to :back, alert: alert_message
redirect_to_back(session_id, alert_message, is_a_custom_domain)
end
rescue Redis::CannotConnectError
# redirect_to :back, alert: "Sorry, there was an error processing your order. Please try again in a bit"
redirect_to_back(session_id, "Sorry, there was an error processing your order. Please try again in a bit", is_a_custom_domain)
end
def index
session['user.in'] = 'checkout'
@payment_detail = PaymentDetail.new
if current_user.present?
@payment_detail.email_address = current_user.email
@payment_detail.last_name = current_user.last_name
@payment_detail.first_name = current_user.first_name
end
end
def create
discount_code = params[:discount_code]
begin
@order = create_or_update_order_transaction
@payment_detail = PaymentDetail.new(params[:payment_detail])
@payment_detail.delivery_method = @payment_detail.delivery_method_temp
# check if promoter code is provided
if @order && discount_code.present?
discount_codes = DiscountCode.where("event_id = ? AND user_id = ? AND lower(code) = ? AND deleted = false AND (start_at <= ? AND ends_at >= ?)",
@order.event_id, @order.promoter_user_id, discount_code.downcase, Date.today, Date.today)
if discount_codes.present?
logger.info discount_codes.inspect
# if existing and valid
@order.update_column(:discount_code_id, discount_codes.first.id)
@order.apply_discounts(discount_codes)
@order.update_sales_info
else
flash[:alert] = "Sorry, the Group Code you entered is not valid."
end
end
# checking up user
if current_user; @user = current_user
else
# register or find user here
unless @user = User.find_by_email(@payment_detail.email_address)
@user = User.initialize_buyer_information(@payment_detail, @promoter)
end
end
if @payment_detail.valid? && @user.valid?
@user.save if @user.new_record? # save user if new record?
sign_in(@user) # let user login once created or provided
@order.apply_shipment(@payment_detail.delivery_method_temp)
# log to braintree logger before transmitting it to braintree
BraintreeMongoLogger.dirty(@order, @order_details, @payment_detail, params)
@result = @order.transact_braintree({ payment_detail: @payment_detail })
if @result.success? && @order.present?
logger.info "--- braintree transaction success"
@payment_detail.order_id = @order.id
@payment_detail.save!
@order.update_transaction(@result, @user)
@order.update_attribute(:orig_trans_id, @result.transaction.id)
@order.add_to_histories(@order.status)
@order.update_reserved_tickets(session[:reserved_ticket])
@payment_detail.send_emailer
session[:transaction_session] = session[:order_id] = session[:reserved_ticket] = nil
redirect_to thank_you_payments_url(:tr => @order.transaction_id, subdomain: false, protocol: 'http')
else
all_level_error = []
braintree_error_message = "Sorry, there was an error processing your order. Please try again in a bit."
# from braintree result
if @result.transaction
all_level_error << case @result.transaction.status
when 'gateway_rejected'; @result.message
when 'processor_declined'; "There was a problem processing your credit card, please double check your data and try again."
#@result.transaction.processor_response_text
else
@result.transaction.processor_response_text
end
end
# get all level error
@result.errors.each do |error|
all_level_error << error.message
end
logger.debug "--- al level"
logger.debug all_level_error
braintree_error_message = all_level_error.join("<br />") if all_level_error
flash[:alert] = braintree_error_message
render 'index'
end
else
# payment details validation
render 'index'
end
rescue Braintree::DownForMaintenanceError => e # for downtime
@delivery_methods = DeliveryMethod.all
flash[:alert] = I18n.t('gateway.errors.on_maintenance').to_s
render 'index'
rescue SocketError => e # for socket error
flash[:alert] = I18n.t('gateway.errors.cannot_communicate').to_s
render 'index'
# rescue Exception => e # for exception
#
# logger.error e.message
#
# if @result && @result.success?
# flash[:alert] = "Sorry, your order went through but something unexpected happened to our processing system. We will contact you as soon as possible."
# else
# flash[:alert] = "Sorry, there was an error processing your order. Please try again in a bit."
# end
#
# ErrorLogger.logs(@order, @payment_detail, e)
#
# render :index
end
end
def remove_ticket
ticket_id = params[:id]
order_id = session[:transaction_session][:order_id]
event_id = session[:transaction_session][:event_id]
# remove it on the db if order already created!
if order_id.present?
detail = OrderDetail.includes(:order)
.where({ order_id: order_id, ticket_id: ticket_id }).first
detail.destroy
# @order = detail.order
# @order_details = @order.details
# @promoter = @order.promoter
# @event = @order.event
detail.order.update_sales_info
end
# remove ticket in the session
session[:transaction_session][:tickets].each_with_index do |detail, index|
session[:transaction_session][:tickets].delete_at(index) if detail[:id].to_i == ticket_id.to_i
end
update_transaction_order_total
@event = Event.find(event_id)
@transaction_order = session[:transaction_session]
@tickets = @transaction_order[:tickets]
end
def apply_discount
@event = Event.find(params[:event_id])
if @event.present? && params[:promoter_id].present?
@promoter = User.find(params[:promoter_id])
@discount_codes = DiscountCode.where("event_id = ? AND user_id = ? AND lower(code) = ? AND deleted = false AND (start_at <= ? AND ends_at >= ?)",
@event.id, @promoter.id, params[:discount_code].downcase, Date.today, Date.today)
end
if @discount_codes.present?
session[:transaction_session][:discount_code] = @discount_codes.first.code
@discount_codes.each do |discount|
session[:transaction_session][:tickets].each_with_index do |detail, index|
if detail[:id].to_i == discount.ticket_id
discount_amount = discount.amount_applied(detail[:ticket_price])
new_total = ((detail[:ticket_price] + detail[:ticket_fee]) * detail[:qty].to_i) - (discount_amount.to_f * detail[:qty].to_i)
session[:transaction_session][:tickets][index][:discount] = discount_amount
session[:transaction_session][:tickets][index][:total] = new_total
end
end
end
update_transaction_order_total
end
@transaction_order = session[:transaction_session]
@tickets = @transaction_order[:tickets]
end
def server_time
render text: Time.now.strftime('%B %e, %Y %k:%M:%S')
end
def thank_you
begin
@order = Order.includes({:details => :ticket}, :event).find_by_transaction_id(params[:tr])
@event = @order.event
rescue Exception => e
redirect_to '/'
end
end
private
def set_event
@transaction_order = session[:transaction_session]
raise ActiveRecord::RecordNotFound if @transaction_order.blank?
@tickets = @transaction_order[:tickets]
@event = Event.find(@transaction_order[:event_id])
if @promoter.present?
user_id = @promoter.id
@has_discount_codes = DiscountCode.where({ event_id: @event.id, user_id: user_id, deleted: false }).present?
end
# if @transaction_order[:created_at] > (Time.now - 10.minutes)
# flash[:alert] = "Cannot find Order"
# raise ActiveRecord::RecordNotFound, 'Order already Expired'
# end
# rescue ActiveRecord::RecordNotFound
# logger.info "Record Not Found!"
# redirect_to :back #, root_path(subdomain: false)
end
def create_or_update_order_transaction
if @transaction_order[:order_id].blank?
order = Order.build_order_and_details user: current_user,
promoter: @promoter,
transaction_session: @transaction_order
@transaction_order.merge!({ order_id: order.id }) if order
return order
else
return Order.find(@transaction_order[:order_id])
end
end
def update_transaction_order_total
total = 0
session[:transaction_session][:tickets].each do |detail|
total += detail[:total]
end
session[:transaction_session][:total] = total
end
# return the following ticket information
# ticket info, total ticket left, ticket threshold and the reserved_ticket
def set_or_get_ticket_information(key)
# check ticket in cache else find it on db
ticket = Ticket.find_in_cache(key)
total_ticket_left = ticket.redis_total_ticket_left
ticket_threshold = ticket.redis_ticket_threshold
reserved_ticket = ticket.redis_reserved_tickets_count
return ticket, total_ticket_left.to_i, ticket_threshold.to_i, reserved_ticket.to_i
end
def redirect_to_back(session, alert_message, custom_domain)
if custom_domain
logger.info "-- set alert message for custom domain"
Rails.cache.write(session, alert_message, expires_in: 1.minutes)
redirect_to :back
else
redirect_to :back, alert: alert_message
end
end
end
resources :payments do
post :process_order, on: :collection
get :thank_you, on: :collection
get :expire, on: :member
get :server_time, on: :collection
post :apply_discount, on: :collection
delete :remove_ticket, on: :member
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment