PayPal Express Checkout with multiple items with active merchant in rails - ruby-on-rails

I am trying to use PayPal ExpressCheckout button with multiple items but with no success.I am using NetBeans IDE, rails 4 and MySQL db.Here is what I did so far:
In my production.rb file I have:
Rails.application.configure do
config/application.rb.
config.after_initialize do
ActiveMerchant::Billing::Base.mode = :test
paypal_options = {
:login => "xxxx",
:password => "xxxx ",
:signature => "xxxx "
}
::STANDARD_GATEWAY = ActiveMerchant::Billing::PaypalGateway.new(paypal_options)
::EXPRESS_GATEWAY = ActiveMerchant::Billing::PaypalExpressGateway.new(paypal_options)
end
In my transaction.rb model I have:
def valid_purchase
if express_token.blank?
standard_purchase
else
express_token
end
def express_purchase
# price_in_cents = total
response = EXPRESS_GATEWAY.purchase(total, express_purchase_options)
if response.success?
self.status = "processed"
else
errors.add(:transactions, "---- #{response.message}.")
end
end
def express_token=(token)
self[:express_token] = token
if new_record? && !token.blank?
details = EXPRESS_GATEWAY.details_for(token)
self.express_payer_id = details.payer_id
self.ship_to_first_name = details.params["first_name"]
self.ship_to_last_name = details.params["last_name"]
end
end
private
def express_purchase_options
{
:ip => customer_ip,
:token => express_token,
:payer_id => express_payer_id
}
end
And in my transaction_controller.rb I have:
def express_checkout
order_items =[]
postage_rate=nil
item = Hash.new
#order = Order.find(session[:order_id])
#receipts = Receipt.where(:order_id=>#order.id)
#receipts.each do |r|
postage_rate = r.postage_rate * 100
end
#cart = Cart.find(#order.cart_id)
#cart.cart_items.each do |i|
#product = Product.find(i.product_id)
item = {
name: #product.product_name,
quantity: i.amount,
description: "ORDER_ID: #{#order.id}",
amount: #product.selling_price * 100 ,
shipping: postage_rate/#cart.cart_items.size
}
order_items << item
end
price_in_cents = (#order.total_p_pr * 100).round(2)
options = {
:ip => request.remote_ip,
:return_url => url_for(:action=>:new, :only_path => false),
:cancel_return_url => catalogs_traders_url,
:currency => "USD",
:allow_guest_checkout=> true,
:items => order_items # this line outputs: [{:name=>"owl potty", :quantity=>1, :description=>"ORDER_ID: 249", :amount=>2808.0, :shipping=>332.0}, {:name=>"a bag", :quantity=>1, :description=>"ORDER_ID: 249", :amount=>1260.0, :shipping=>332.0}, {:name=>"bracelet", :quantity=>1, :description=>"ORDER_ID: 249", :amount=>120.0, :shipping=>332.0}, {:name=>"beautiful woman", :quantity=>1, :description=>"ORDER_ID: 249", :amount=>74352.0, :shipping=>332.0}]
}
#passing the cost of the order
response = EXPRESS_GATEWAY.setup_purchase(price_in_cents,options )
redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end
def new
#transaction = Transaction.new(:express_token => params[:token])
end
I get:
Any help will be more than welcome. Thank you!

I red this post very,very carefully
setting tax amount in Active Merchant / PayPal Express Checkout
and I understood my mistakes. Here is my corrected transaction_controller:
# to redirect to PayPay site
def express_checkout
pr = nil
tp = nil
items =[]
postage_r=[]
total_p = []
order_items =[]
postage_rate=nil
item = Hash.new
#order = Order.find(session[:order_id])
#receipts = Receipt.where(:order_id=>#order.id)
#receipts.each do |r|
total_p << r.total_price
postage_r << r.postage_rate
end
tp = total_p.inject{|sum,x| sum + x }
pr = postage_r.inject{|sum,x| sum + x }
#cart = Cart.find(#order.cart_id)
#cart.cart_items.each do |i|
#product = Product.find(i.product_id)
item = {
name: #product.product_name,
quantity: i.amount,
description: "ORDER_ID: #{#order.id}",
amount: #product.selling_price * 100 ,
}
order_items << item
end
price_in_cents = (#order.total_p_pr * 100).round(2)
options = {
:subtotal => tp * 100,
:shipping => pr * 100,
:handling => 0,
:tax => 0,
:ip => request.remote_ip,
:return_url => url_for(:action=>:new, :only_path => false),
:cancel_return_url => catalogs_traders_url,
:currency => "USD",
:allow_guest_checkout=> true,
:items => order_items
}
#passing the cost of the order
response = EXPRESS_GATEWAY.setup_purchase(price_in_cents,options )
redirect_to EXPRESS_GATEWAY.redirect_url_for(response.token)
end
It worked. I hope my post will be useful for someone who want to integrate Express Checkout button. Thank you for all your help!

Related

Stripe Coupon code with one-time use

I have followed the stripe instructions to add coupons to my app. The coupons work great but I want to make a coupon that works all the time but can only be used once per user.
My coupon model
Coupon.rb
class Coupon
include Mongoid::Document
has_many :charges
has_one :manager
validates_presence_of :code, :discount_percent, :coupon_count, :description
validates_uniqueness_of :code
field :code, type: String
field :discount_percent, type: Integer
field :expires_at, type: Date
field :coupon_count, type: Integer
field :description, type: String
def self.get(code)
where(
:code => (normalize_code(code)),
:$and => [
{
:$or => [
{ :coupon_count.gte => 1 },
{ :coupon_count => nil }
]
}, {
:$or => [
{ :expires_at.gte => Date.today },
{ :expires_at => nil }
]
}
]
).first
end
def apply_discount(amount)
discount = amount * (self.discount_percent * 0.01)
(amount - discount.to_i)
end
def discount_percent_human
if discount_percent.present?
discount_percent.to_s + '%'
end
end
def generate_subscription_code(manager)
# Random, unguessable number as a base20 string
# .reverse ensures we don't use first character (which may not take all values)
raw_string = SecureRandom.random_number( 2**80 ).to_s( 20 ).reverse
# Convert Ruby base 20 to better characters for user experience
long_code = raw_string.tr( '0123456789abcdefghij', '234679QWERTYUPADFGHX' )
# Format the code for printing
short_code = long_code[0..3] + '-' + long_code[4..7] + '-' + long_code[8..11]
self.code = short_code
self.discount_percent = 100
self.expires_at = DateTime.now + 1.year
self.coupon_count = 120
self.description = "#{manager.email} Annual Subscription"
save
end
private
def self.normalize_code(code)
code.gsub(/ +/, '').upcase
end
end
Here is my charges controller also
charges_controller.rb
class Managers::ChargesController < ApplicationController
before_filter :authenticate_manager!
def new
#reportapproval = Reportapproval.find(params[:id])
#manager = current_manager
#amount = #reportapproval.manager_request_report_type
end
def create
# Amount in cents
#reportapproval = Reportapproval.find params[:reportapproval_id]
#manager = current_manager
#amount = #reportapproval.manager_request_report_type
#final_amount = #amount
#code = params[:couponCode]
if !#code.blank?
#coupon = Coupon.get(#code)
if #coupon.nil?
flash[:error] = 'Coupon code is not valid or expired.'
redirect_to new_managers_charge_path(id: #reportapproval.id)
return
elsif #coupon.discount_percent == 100
#reportapproval.report_paid = true
#reportapproval.free_coupon_used = true
#reportapproval.save!
#coupon.coupon_count = #coupon.coupon_count - 1
#coupon.save!
redirect_to managers_dashboard_path, :notice => "You have successfully requested a pre-paid report from #{#reportapproval.tenant_last_name} with a 'No-Pay' coupon."
return
else
#final_amount = #coupon.apply_discount(#amount.to_i)
#discount_amount = (#amount.to_i - #final_amount.to_i)
end
if #coupon.present?
charge_metadata = {
:coupon_code => #coupon.code,
:coupon_discount => #coupon.discount_percent_human
}
end
end
charge_metadata ||= {}
customer = Stripe::Customer.create(
:email => #manager.email,
:card => params[:stripeToken]
)
stripe_charge = Stripe::Charge.create(
:customer => customer.id,
:amount => #final_amount,
:description => 'Manager Paid Report',
:currency => 'usd',
:metadata => charge_metadata
)
#charge = Charge.create!(amount: #final_amount, coupon: #coupon, stripe_id: stripe_charge.id)
#reportapproval.report_paid = true
#reportapproval.save!
if #coupon.present?
#coupon.coupon_count = #coupon.coupon_count - 1
#coupon.save!
else
redirect_to managers_dashboard_path, :notice => "You have successfully requested a pre-paid report from #{#reportapproval.tenant_last_name}."
return
end
rescue Stripe::CardError => e
flash[:error] = e.message
redirect_to managers_charges_path
end
end
How can I add the ability to check if the manager has used the coupon before and only allow them to use once?

Podio Ruby Rails shows "nomethoderror"

I'm having problems with the Podio_rails_sample. I've included my leadsController and leads.rb files. The line that gets hung up is field['config']['settings']['allowed_values'].
Line 25 is the problematic one:
NoMethodError in LeadsController#new
undefined method `[]' for nil:NilClass
Extracted source (around line #25):
23 app = Podio::Application.find(APP_ID)
24 field = app.fields.find { |field| field['external_id'] == 'status' }
25 field['config']['settings']['allowed_values']
26 end
27
28 def self.create_from_params(params)
Rails.root: c:/Sites/podio_rails_sample
app = Podio::Application.find(APP_ID)
field = app.fields.find { |field| field['external_id'] == 'status' }
field['config']['settings']['allowed_values']
end
def self.create_from_params(params)
Rails.root: c:/Sites/podio_rails_sample
-----------------------------------
class LeadsController < ApplicationController
before_filter :load_collections, :only => [:new, :edit]
def index
#leads = Lead.all
end
def new
#lead = Lead.new
end
def create
Lead.create_from_params(params['lead'])
redirect_to leads_path, :notice => 'Lead created'
end
def edit
#lead = Lead.find_basic(params[:id])
end
def update
Lead.update_from_params(params[:id], params['lead'])
redirect_to leads_path, :notice => 'Lead updated'
end
def destroy
Lead.delete(params[:id])
redirect_to leads_path, :notice => 'Lead deleted'
end
#protected
def load_collections
#lead_contacts = Lead.space_contacts
#sales_contacts = Lead.users
#statuses = Lead.statuses
end
end
-------------------------------------
- leads.rb file
class Lead < Podio::Item
APP_ID =12328033
SPACE_ID =3204114
# Find all items in the Leads app
def self.all
collection = self.find_all(APP_ID)
collection[:all]
end
# Find valid lead contacts in the space
def self.space_contacts
Podio::Contact.find_all_for_space(SPACE_ID, :order => 'contact', :limit => 12, :contact_type => 'space,connection', :exclude_self => false) rescue []
end
# Find valid sales contacts in the space
def self.users
Podio::Contact.find_all_for_space(SPACE_ID, :order => 'contact', :limit => 12, :contact_type => 'user', :exclude_self => false) rescue []
end
# Find valid statuses
def self.statuses
app = Podio::Application.find(APP_ID)
field = app.fields.find { |field| field['external_id'] == 'status' }
field['config']['settings']['allowed_values']
end
def self.create_from_params(params)
# raise fields.inspect
self.create(APP_ID, { :fields => fields_from_params(params) })
end
def self.update_from_params(id, params)
self.update(id, { :fields => fields_from_params(params) })
end
#
# Map the field values return by the Podio API to simple getters
#
def organization
field_values_by_external_id('company-or-organisation', :simple => true)
end
def lead_contact
field_values_by_external_id('contacts', :simple => true).try(:[], 'name')
end
def sales_contact
field_values_by_external_id('sales-contact', :simple => true).try(:[], 'name')
end
def potential_revenue_value
field_values_by_external_id('potential-revenue').try(:first).try(:[], 'value').to_i
end
def potential_revenue_currency
field_values_by_external_id('potential-revenue').try(:first).try(:[], 'currency')
end
def probability
field_values_by_external_id('probability-of-sale', :simple => true)
end
def status
field_values_by_external_id('status', :simple => true)
end
def followup_at
field_values_by_external_id('next-follow-up').try(:first).try(:[], 'start').try(:to_datetime)
end
protected
def field_values_by_external_id(external_id, options = {})
if self.fields.present?
field = self.fields.find { |field| field['external_id'] == external_id }
if field
values = field['values']
if options[:simple]
values.first['value']
else
values
end
else
nil
end
else
nil
end
end
def self.fields_from_params(params)
{
'company-or-organisation' => params[:organization],
'contacts' => (params[:lead_contact].present? ? params[:lead_contact].to_i : nil),
'sales-contact' => (params[:sales_contact].present? ? params[:sales_contact].to_i : nil),
'potential-revenue' => { :value => params['potential_revenue_value'], :currency => params['potential_revenue_currency'] },
'probability-of-sale' => params[:probability].to_i,
'status' => params[:status],
'next-follow-up' => DateTime.new(params['followup_at(1i)'].to_i, params['followup_at(2i)'].to_i, params['followup_at(3i)'].to_i).to_s(:db)
}.delete_if { |k, v| v.nil? }
end
end

Displaying unique transactions in Ruby on Rails

Currently there are multiple transactions with the same txnid. But for each transaction the payment mode is credit card, debit card or net banking.
If the customer has to pay $3000 he might pay that $3000 like $1000 with Credit card, $1000 with Debit Card, $1000 with Net banking.
Currently am displaying all those 3 transactions in 3 rows but with the same txnid. But I want to display those 3 transactions in a single row by mentioning in the payment mode column ($1000- Credit Card, $1000 Debit Card, $1000 Net bank)
Thanks for your help .
transactions.html.erb
<tr>
<th>Merchant Name</th>
<th>Transaction ID</th>
<th>Payment Mode</th>
<th>Amount</th>
<th>Status</th>
<th>Transaction Fee</th>
<th>Discount</th>
<th>Additional Charges</th>
<th>Added On</th>
</tr>
</thead>
<tbody id="details">
<% #all_settlement_details.map(&:txnid).uniq.each do |sd| %>
<tr>
<td><%= sd.merchantname %></td>
<td><%= sd.txnid %></td>
<td><%= get_mode_ui.value(sd.mode) %></td>
<td><%= sd.amount %></td>
<td><%= get_status(sd.status) %></td>
<td><%= sd.mer_service_fee %></td>
<td><%= sd.discount %></td>
<td><%= sd.additional_charges%></td>
<td><%= get_added_on_date sd.addedon %></td>
</tr>
<% end %>
</tbody>
trasactions.helper.rb
INDEX_OPTIONS = {'dashboard' => 'get_dashboard_data', 'merchants' => 'get_merchants', 'transactions' => 'get_transactions',
'admin' => 'get_admin_data', 'profile' => 'get_merchant_data'}
INDEX_PARTIAL = {'dashboard' => 'dashboard', 'merchants' => 'merchant_list', 'transactions' => 'transactions',
'admin' => 'admin', 'profile' => 'merchant_profile'}
AJAX_OPTIONS = {'stat-board' => 'get_stats', 'transactions' => 'get_graph_transactions', 'payment-methods' => 'get_payment_method_graph_data',
'merchants' => 'get_merchant_graph_data', 'merchant_profile' => 'get_merchant_profile_data', 'load_more' => 'load_more',
'merchant_list' => 'get_merchants'}
AJAX_PARTIAL = {'stat-board' => 'stat_board', 'transactions' => 'transactions_graph', 'payment-methods' => 'payment_methods_graph',
'merchants' => 'merchant_graphs', 'load_more' => 'transaction_details', 'merchant_profile' => 'merchant_profile_detail',
'merchant_list' => 'filtered_merchants',}
STATUS={"dropped"=>0,"bounced"=>1,"captured"=>2,"auth"=>3,"failed"=>4,"usercancelled"=>5,"pending"=>6}
MODE={'CC'=>0,'DC'=>1,'NB'=>2,'EMI'=>3,'CASH'=>4,'IVR'=>5,'COD'=>6}
MODE_UI = {'CC'=>'Credit Card','DC'=>'Debit Card','NB'=>'Net Banking','EMI'=>'EMI','CASH'=>'Cash','IVR'=>'IVR','COD'=>'Cash on Delivery'}
PG_MODE = {'Credit Card'=>0,'Debit Card'=>1,'Net Banking'=>2,'EMI'=>3,'Cash'=>4,'IVR'=>5,'Cash on Delivery'=>6,'Others'=>nil}
STATUS_UI={"Dropped"=>0,"Bounced"=>1,"Captured"=>2,"Authenticated"=>3,"Failed"=>4,"User Cancelled"=>5,"Pending"=>6}
CARDTYPE={'domestic'=>1,'international'=>2}
TRANSACTIONS = ["Merchant Name", "Transaction ID", "Payment Mode","Amount","Status","Transaction Fee","Discount","Additional Charges","Added On"]
TXN_SUCCESS_STATUS = [2,3]
TXN_FAILURE_STATUS = [0,1,4,5]
TXN_PENDING_STATUS = 6
PARTNER_PANEL_REDMINE_STATUS_MAPPING = {
16 => "In Process",
3 => "In Process",
69 => "In Process",
11 => "Line of Business Rejected",
14 => "Live",
42 => "In Process",
51 => "In Process",
15 => "In Process",
17 => "In Process",
64 => "In Process",
46 => "In Process",
62 => "Line of Business Rejected",
65 => "In Process",
18 => "Assigned to Sales",
79 => "In Process",
61 => "In Process",
5 => "In Process",
70 => "In Process",
71 => "In Process",
50 => "Line of Business Rejected",
32 => "Contacted",
48 => "In Process",
59 => "In Process",
49 => "In Process",
47 => "In Process",
60 => "In Process",
29 => "Line of Business Rejected",
78 => "Assigned to Sales"
}
PARTNER_PANEL_REDMINE_STATUS_MAPPING_UI = {
"In Process" => "16,3,69,42,51,15,17,64,46,65,79,61,5,70,71,48,59,49,47,60",
"Line of Business Rejected" => "11,62,50,29",
"Assigned to Sales" => "78,18",
"Live" => "14",
"Contacted" => "32"
}
def get_status _status_flag
STATUS.key(_status_flag)
end
def get_mode _mode_flag
MODE.key(_mode_flag)
end
def get_mode_ui
PG_MODE
end
def get_transactions_ui
TRANSACTIONS
end
def get_status_ui
STATUS_UI
end
def get_merchant_status_ui
PARTNER_PANEL_REDMINE_STATUS_MAPPING_UI
end
def status_merchant
PARTNER_PANEL_REDMINE_STATUS_MAPPING
end
def get_added_on_date _date
_date.strftime("%A, %d %B\'%y %H:%M")
end
def link_to_add_issues(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_issues(this, \"#{association}\", \"#{escape_javascript(fields)}\")")
end
def link_to_remove_issues(name, f)
f.hidden_field(:_destroy) + link_to_function(name, "remove_issues(this)")
end
def get_issue_object _partner
_partner.issues.blank? ? _partner.class.reflect_on_association(:issues).klass.new : _partner.issues
end
def get_contact_detail_object issue
issue.contact_detail.blank? ? issue.class.reflect_on_association(:contact_detail).klass.new : issue.contact_detail
end
def issue_contact_detail issue, contact_column_name
issue.contact_detail ? issue.contact_detail.send(contact_column_name) : ""
end
def options_for_state(issue)
options_for_select(Setting[:states].split(/\r\n/).sort, issue.state).html_safe
end
# First Landing page for a Partner
def get_dashboard_data
get_stats
get_merchants
end
# Merchant list for a Partner
def get_merchants
_merchant_filter_scope = {'merchant_status' => ["merchant_status", (params[:merchant_status].split(',') rescue nil)],
'merchant_email' => ["merchant_mail", params[:merchant_email]],
'merchant_url' => ["merchant_url", params[:merchant_url]],
'merchant_mid' => ['payu_mid', params[:merchant_mid]],
'merchant_name' => ['merchant_name', params[:merchant_name]],
'order' => ['order_issue', params[:order]]
}
method_array = [['issues'],["page", params[:page]],["per", per_page_option],["date_filter", #start_date, #end_date]]
#partner_merchants = call_scope_methods_dynamically(method_array, _merchant_filter_scope)
end
# Transactions for a Partner
def get_transactions
#get more records to load
load_more
end
# Merchant Profile page for a Partner
def get_merchant_data
get_stats
load_more
end
# Admin page for Partners
def get_admin_data
#partners = Partner.where(partner_admin: false)
end
# Stat Board tab on Dashboard
def get_stats
method_array = [['settlement_details'],['stat_board_details'],['count_as_graph_data']]
method_array << ['merchant_mid', #merchant_mid] if #merchant_mid
method_array = add_date_or_hour_filter method_array
data1 = call_methods(method_array)
method_array << ['group_by_settlements_date']
data2 = call_methods(method_array)
#graph_data = [data1, data2]
end
# Merchant tab on Dashboard
def get_merchant_graph_data
method_array = [['issues']]
method_array = add_date_or_hour_filter method_array
method_array << ['group_by_merchant_date']
data1 = #bank_partner.issues.date_filter(#start_date, #end_date).group_by(&:status_id)
data2 = call_methods(method_array)
#merchant_status_hash = {}
data1.each{|key, value| get_partner_status_hash(get_merchant_status(key), value.count)}
[#merchant_status_hash, data2]
end
def get_merchant_status redmine_status
PARTNER_PANEL_REDMINE_STATUS_MAPPING[redmine_status] || 'In Process'
end
def get_partner_status_hash key, value
#merchant_status_hash.update({key => value}){|k, ov, nv| ov + nv}
end
# Transaction tab on Dashboard
def get_graph_transactions
method_array = [['settlement_details'],['count_as_graph_data']]
method_array << ['merchant_mid', #merchant_mid] if #merchant_mid
method_array = add_date_or_hour_filter method_array
method_array << ['group_by_settlements_date']
#data1 = call_methods(method_array << ["status", TXN_SUCCESS_STATUS])
#data2 = call_methods(method_array << ["status", TXN_FAILURE_STATUS])
#data3 = call_methods(method_array << ["status", TXN_PENDING_STATUS])
[#data1, #data2, #data3]
end
# Payment Method tab on Dashboard
def get_payment_method_graph_data
method_array = [['settlement_details'],["date_filter", #start_date, #end_date],['payment_mode']]
method_array << ['merchant_mid', #merchant_mid] if #merchant_mid
method_array << ['count']
call_methods(method_array)
end
def get_transaction_graph_hash successful, failure, pending
data_array= []
successful_hash = {}
failure_hash = {}
pending_hash = {}
successful.each{|d| successful_hash.merge!({(d.hour rescue d.date) => d.graph_data})}
failure.each{|d| failure_hash.merge!({(d.hour rescue d.date) => d.graph_data})}
pending.each{|d| pending_hash.merge!({(d.hour rescue d.date) => d.graph_data})}
(successful_hash.keys + failure_hash.keys + pending_hash.keys).uniq.each do |datetime|
data_array << {'datetime'=> "#{datetime}",'successful'=> (successful_hash[datetime] || 0) ,'unsuccessful'=> (failure_hash[datetime] || 0) ,'pending'=> (pending_hash[datetime] || 0)}
end
data_array
end
private
def load_more
#all_settlement_details = get_all_settlement_details || []
end
def get_all_settlement_details
# Offset increments by 10 and Limit remains 11
_txn_filter_scope = {'transaction_status' => ["status", (params[:transaction_status].split(',') rescue nil)],
'payment_options' => ["payment_options", (params[:payment_options].split(',') rescue nil)],
'transaction_id' => ['transaction_id', params[:transaction_id]],
'transaction_amount' => ['amount_range', ((params[:transaction_amount].split(',')[0] || 0) rescue nil), ((params[:transaction_amount].split(',')[1] || 100000000) rescue nil)],
'merchant_mid' => ['merchant_mid',params[:merchant_mid]],
'merchant_name' => ['merchant_name', params[:merchant_name]],
'clicks' => ['txn_offset', ((params[:clicks].to_i)*10 rescue 0)]
}
method_array = [['settlement_details'],["date_filter", #start_date, #end_date]]
method_array << ["txn_limit", 11] unless #csv_format
method_array << ['merchant_mid', #merchant_mid] if #merchant_mid
records = call_scope_methods_dynamically(method_array, _txn_filter_scope)
records.empty? ? nil : records
end
# extend Object to introduce the call_methods method
def call_methods(methods)
methods.inject(#bank_partner) do |obj, method|
case method.count
when 3
obj.send(method.first, method[1], method[2])
when 2
obj.send(method.first, method.last)
when 1
obj.send(method.first)
else
obj
end
end
end
def call_scope_methods_dynamically(_method_array, _method_hash)
method_array = _method_array
_dynamic_method_hash = _method_hash
# Add scopes in the methods array to call dynamically
params.each{|key, value| method_array << _dynamic_method_hash[key]}
call_methods(method_array.compact)
end
def add_date_or_hour_filter _method_array
if #start_date == #end_date
#end_date = (Date.parse(#end_date) + 1.day).strftime("%Y/%m/%d")
_method_array << ['hour_filter']
end
_method_array << ["date_filter", #start_date, #end_date]
_method_array
end
My final output should be look like.
Txnid payment mode Amount
23234XS24XS $1000Credit Card, $3000
$1000 Debit Card,
$1000 Net bank
Some one said I need to create a helper method for that. But I am not sure how!
Thanks for your help!
I don't know what all those files you posted are for. You say that you want the following in the db:
"$1000- Credit Card, $1000 Debit Card, $1000 Net bank"
First, you would never write that format to the db. Instead, you would try to use a consistent format, like:
Credit Card:1000,Debit Card:1000,Net Bank:1000
Then you can retrieve that column and store it in a variable:
payment_mode = "Credit Card: 1000, Debit Card: 1000, Net Bank: 1000"
Then you can do:
payments = Hash[
payment_mode
.split(',')
.map{|mode| mode.split(':')}
]
p payments
total = payment_by.values.sum
#total = payments.values.map(&:to_i).inject(:+)
taxnid = 123
first_line = true
puts "Taxnid\tPayment mode\t\tTotal"
payments.each_pair do |type, amount|
if first_line
puts "#{taxnid}\t#{type} #{amount}\t#{total}"
first_line = false
else
puts "\t#{type} #{amount}"
end
end
--output:--
Taxnid Payment mode Total
123 Credit Card 1000 3000
Debit Card 1000
Net Bank 1000
If you actually want to create some html that displays that format, then substitute <td>'s and <tr>'sin the appropriate places:

Error "No Method" when using delayed job

I'm trying to import 90k lines of xml into my ruby app. herokus timeout limit is 30s so i'm trying to use delayed job.
The import class works wonderfully in around 48-hippopotomuses locally. When i add the line
handle_asynchronously :save_races
I get the error "undefined method save_races' for classXmltube'"
What am i doing wrong with DJ and how can i get this to work?
Full class code below
require "rexml/document"
class Xmltube
def self.convert_save(xml_data)
doc = REXML::Document.new xml_data.read
doc.elements.each("Meeting") do |meeting_element|
meeting = save_meeting(meeting_element)
save_races(meeting_element, meeting)
Rails.logger.info "all done"
end
end
def self.save_races(meeting_element, meeting)
meeting_element.elements.each("Races/Race") do |race_element|
race = save_race(race_element, meeting)
save_race_entrants(race_element, race)
end
end
def self.save_race_entrants(race_element, race)
race_element.elements.each("RaceEntries/RaceEntry") do |entry_element|
horse = save_horse(entry_element)
jockey = save_jockey(entry_element)
start = save_start(entry_element, horse, jockey, race)
save_sumaries(entry_element, start)
end
end
def self.save_track(meeting_element)
# there is only one track, but still, each? wtf.
t = {}
meeting_element.elements.each("Track") do |track|
t = {
:name => track.attributes["VenueName"],
:track_code => track.attributes["VenueCode"],
:condition => track.elements['TrackRating'].text,
:club_id => save_club(meeting_element.elements["Club"]).id
}
end
track = Track.where(:track_code => t[:track_code] ).first
if track
Track.update(track.id, t)
else
Track.create(t)
end
end
def self.save_meeting meeting_element
t = {
:meet_code => meeting_element.attributes['MeetCode'],
:stage => meeting_element.elements["MeetingStage"].text,
:phase => meeting_element.elements["MeetingPhase"].text,
:nominations_close_at => meeting_element.elements["NominationsClose"].text,
:acceptance_close_at => meeting_element.elements["AcceptanceClose"].text,
:riders_close_at => meeting_element.elements["RidersClose"].text,
:weights_published_at => meeting_element.elements["WeightsPublishing"].text,
:club_id => save_club(meeting_element.elements["Club"]).id ,
:track_id => save_track(meeting_element).id,
:tab_status => meeting_element.elements["TabStatus"].text,
:state => meeting_element.elements["StateDesc"].text,
:day_night => meeting_element.elements["DayNight"].text,
:number_of_races => meeting_element.elements["NumOfRaces"].text,
:meet_date => meeting_element.elements["MeetDate"].text,
}
meeting = Meeting.where(:meet_code => t[:meet_code] ).first
if meeting
Meeting.update(meeting.id, t)
else
Meeting.create(t)
end
end
############################################################
def self.save_sumaries entry_element, start
entry_element.elements.each('Form/ResultsSummaries/ResultsSummary') do | element |
s = {
:name => element.attributes['Name'],
:start_id => start.id,
:starts => element.attributes['Starts'],
:wins => element.attributes['Wins'],
:seconds => element.attributes['Seconds'],
:thirds => element.attributes['Thirds'],
:prize_money => element.attributes['PrizeMoney'],
}
sum = Summary.where(:name => s[:name] ).where(:start_id => s[:start_id]).first
if sum
Summary.update(sum.id, s)
else
Summary.create(s)
end
end
end
def self.save_start entry_element, horse, jockey, race
s = {
:horse_id => horse.id,
:jockey_id => jockey.id,
:race_id => race.id,
:silk => entry_element.elements["JockeySilksImage"].attributes["FileName_NoExt"],
:start_code => entry_element.attributes['RaceEntryCode'],
:handicap_weight => entry_element.elements['HandicapWeight'].text,
}
# Rails.logger.info entry_element['HandicapWeight'].text
start = Start.where(:start_code => s[:start_code] ).first
if start
Start.update(start.id, s)
else
Start.create(s)
end
end
def self.save_jockey entry_element
j={
:name => entry_element.elements['JockeyRaceEntry/Name'].text,
:jockey_code => entry_element.elements['JockeyRaceEntry'].attributes["JockeyCode"],
}
jockey = Jockey.where(:jockey_code => j[:jockey_code] ).first
if jockey
Jockey.update(jockey.id, j)
else
Jockey.create(j)
end
end
def self.save_horse entry_element
trainer = save_trainer entry_element
h= {
:name => entry_element.elements['Horse'].attributes["HorseName"],
:color => entry_element.elements['Horse'].attributes["Colour"],
:dob => entry_element.elements['Horse'].attributes["FoalDate"],
:sex => entry_element.elements['Horse'].attributes["Sex"],
:trainer_id => trainer.id,
:horse_code => entry_element.elements['Horse'].attributes["HorseCode"],
}
horse = Horse.where(:horse_code => h[:horse_code] ).first
if horse
Horse.update(horse.id, h)
else
Horse.create(h)
end
end
def self.save_trainer entry_element
t= {
:name => entry_element.elements['Trainer/Name'].text,
:trainer_code => entry_element.elements['Trainer'].attributes["TrainerCode"]
}
trainer = Trainer.where(:trainer_code => t[:trainer_code] ).first
if trainer
Trainer.update(trainer.id, t)
else
Trainer.create(t)
end
end
def self.save_club element
t = {}
t = {
:club_code => element.attributes['ClubCode'],
:title => element.attributes["Title"],
}
club = Club.where(:club_code => t[:club_code] ).first
if club
Club.update(club.id, t)
else
Club.create(t)
end
end
def self.save_race element, meeting
r = {
:name => element.elements['NameRaceFull'].text,
:occur => element.elements['RaceStartTime'].attributes["TimeAtVenue"],
:distance => element.elements['RaceDistance'].text,
:race_type => element.elements['RaceType'].text,
:track_id => meeting.track_id,
:race_code => element.attributes["RaceCode"],
:meeting_id => meeting.id
}
race = Race.where(:race_code => r[:race_code] ).first
if race
Race.update(race.id, r)
else
Race.create(r)
end
end
handle_asynchronously :save_races
end
Since your save_races is a class method, you should call handle_asynchronously on Xmltube's singleton class:
class << self
handle_asynchronously :save_races
end
This just worked as I would expect
class Foo
def self.bar(s)
Rails.logger.info "From Foo.bar('#{s}')"
end
end
# then ...
Foo.delay.bar('hello')
I was running 4.0.4 of DJ with ruby 2.1

How to get gateway response from model into controller - Ruby on Rails

My application uses activemerchant to process payments. I'm using Eway as my payment gateway. I'm storing credit card details with Eway to keep them out of my application database.
I'm using a method store which returns a response with a customer billing id that I can use at a later time to process the order.
http://rdoc.info/github/Shopify/active_merchant/master/ActiveMerchant/Billing/EwayManagedGateway
My main issue is how do I get the response value into my controller so I can save it to the member model.
I've created a simple ruby file to test this all works and it does. I just need to convert this code to work inside my rails app.
require "rubygems"
gem 'activemerchant', '1.15.0'
require 'activemerchant'
ActiveMerchant::Billing::Base.mode = :production
gateway = ActiveMerchant::Billing::EwayManagedGateway.new(
:login => '12345678',
:username => 'mylogin#example.com',
:password => 'mypassword'
)
credit_card = ActiveMerchant::Billing::CreditCard.new(
:type => "visa",
:number => "4444333322221111",
:verification_value => "123",
:month => "11",
:year => "2011",
:first_name => "John",
:last_name => "Citizen"
)
options = {
:order_id => '1230123',
:ip => "127.0.0.1",
:email => 'john.citizen#example.com',
:billing_address => { :title => "Mr.",
:address1 => '123 Sample Street',
:city => 'Sampleville',
:state => 'NSW',
:country => 'AU',
:zip => '2000'
},
:description => 'purchased items'
}
if credit_card.valid?
response = gateway.store(credit_card, options)
if response.success?
puts "Credit Card Stored. #{response.message}"
customer = response.params['CreateCustomerResult']
puts "Customer Id: #{customer}"
else
puts "Error: #{response.message}"
end
else
puts "Error, credit card is not valid. #{credit_card.errors.full_messages.join('. ')}"
end
Here is the relevant code in my order model.
serialize :params
cattr_accessor :gateway
def response=(response)
self.success = response.success?
self.message = response.message
self.params = response.params
self.billing_id = response.params['CreateCustomerResult']
rescue ActiveMerchant::ActiveMerchantError => e
self.success = false
self.message = e.message
self.params = {}
self.billing_id = nil
end
def store
response = Order.gateway.store(credit_card, options)
end
Here is my order controller create code.
def create
#member = current_member
#order_deal = Deal.find(params[:deal_id])
#order = #order_deal.orders.build(params[:order])
#order.member_id = current_member.id
#order.ip_address = request.remote_ip
#deal = #order_deal
if #order.save
if #order.store
render :action => "success"
flash[:notice] = "Successfully processed your order."
else
render :action => "new"
end
else
render :action => 'new'
end
end
So essentially I want to get the
response.params['CreateCustomerResult']
and add it to my member model under
member.billing_id = response.params['CreateCustomerResult]
How can I do this?

Resources