Fedex Ruby Gem: Customs Value is required - how to add? - ruby

I'm working with the Ruby gem 'FedEx', https://github.com/jazminschroeder/fedex.
I've set up my code for a development mode and I'm testing making a shipment.
However, I get stuck with the following error:
C:/Ruby22/lib/ruby/gems/2.2.0/gems/fedex-.10.1/lib/fedex/request/shipment.rb:134:in 'failure_response': Customs Value is required. (Fedex:: RateError) from C: /Ruby22/lib/ruby/gems/2.2.0/gems/fedex-.10.1/lib/fedex/request/shipment.rb:32:in 'process_request' from C: /Ruby22/lib/ruby/gems/2.2.0/gems/fedex-3.10.1/lib/fedex/shipment.rb:57:in 'ship' from C: /Ruby22/bin/css_fedex_v1.rb:92:in ''
It seems that I need to parse a 'Customs Value', probably as part of my 'packages' hash. However, I'm unable to find the relevant field for me to enter this in. Anyone who's experienced this and found a solution?
My code is as below:
require 'fedex'
fedex = Fedex::Shipment.new(:key => '***',
:password => '***',
:account_number => '***',
:meter => '***',
:mode => 'development')
shipper = { :name => "***",
:company => "***",
:phone_number => "***",
:address => "***",
:city => "***",
:postal_code => "***",
:country_code => "DK" }
recipient = { :name => "***",
:company => "***",
:phone_number => "***",
:address => "***",
:city => "***",
:postal_code => "***",
:country_code => "GB",
:residential => "false" }
packages = []
packages << {:weight => {:units => "LB", :value => 1}}
shipping_options = {:packaging_type => "YOUR_PACKAGING",
:drop_off_type => "REGULAR_PICKUP"}
rate = fedex.rate(:shipper=>shipper,
:recipient => recipient,
:packages => packages,
:shipping_options => shipping_options)
ship = fedex.ship(:shipper=>shipper,
:recipient => recipient,
:packages => packages,
:service_type => "INTERNATIONAL_PRIORITY",
:shipping_options => shipping_options)
puts ship[:completed_shipment_detail][:operational_detail][:transit_time]

Customs value is declared in their docs:
https://github.com/jazminschroeder/fedex/commit/9f1d4c67b829aaa4eeba9090c1a45d3bd507aab3#diff-4f122efb7c0d98120d8b7f0cd00998e4R106
customs_value = { :currency => "USD",
:amount => "200" }
As I understand you can pass it into the commodities hash or keep it separate.

Related

Ruby/Highrise API - Not saving phone number?

So I've been using this same block of code for about 9 months and suddenly it has stopped saving a phone number into Highrise when a new Lead is generated... Any idea where things are going sideways? I never throws an error and happily saves the contact with everything except for the telephone number.
# create a contact Highrise from supplied information
#person = Highrise::Person.new(first_name: #lead.first_name.humanize,
last_name: #lead.last_name.humanize,
background: "automatically created by LSAL app",
contact_data: { email_addresses: [ { address: #lead.email, location: "Home" } ],
phones: [ { number: #lead.phone, location: "Mobile" } ] } )
#person.save # save contact
#person = Highrise::Person.create(:company_name => account.company, :first_name => account.first_name, :last_name => account.last_name, :contact_data => { :email_addresses => [{ :email_address => {:address => account.email, } }], :addresses => [{:address => {:city => account.city, :location =>"Work", :state => account.state, :country => account.country,:street => "#{account.address1} #{account.address2}" , :zip => account.zip} }], :phone_numbers => [{ :phone_number => { :number => number, :location =>"Work"}}] } )
Hope its helpful

How to make a Ruby application to send money to specific users?

I'm a Ruby user, who is trying to make a Ruby application that allows me to pay to my friends. My friends have Paypal account individually (i.e. sungpahfriend#hello.com ). I have a particular amount of money that I have to pay to my friends.
I have a business account. ( sungpah#hello.com ).
But I can't find how I can pay to my friend.
Do I have to put my credit card information or just my email address and amount of money? Also where should I put my friend's email address?
I really want to know how to this effectively. I'm looking forward to getting a feedback!
Best
require 'paypal-sdk-rest'
PayPal::SDK::Core::Config.load('config/paypal.yml', ENV['RACK_ENV'] || 'development')
PayPal::SDK.logger = Logger.new(STDERR)
PayPal::SDK.logger.level = Logger::INFO
PayPal::SDK.configure({
:mode => "sandbox",
:client_id => "xxx-xx",
:client_secret => "xx-xx"
})
#payment = PayPal::SDK::REST::Payment.new({
:intent => "sale",
:payer => {
:payment_method => "credit_card",
:funding_instruments => [{
:credit_card => {
:type => "visa",
:number => "4567516310777851",
:expire_month => "11",
:expire_year => "2018",
:cvv2 => "874",
:first_name => "Joe",
:last_name => "Shopper",
:billing_address => {
:line1 => "52 N Main ST",
:city => "Johnstown",
:state => "OH",
:postal_code => "43210",
:country_code => "US" }}}]},
:transactions => [{
:item_list => {
:items => [{
:name => "item",
:sku => "item",
:price => "1",
:currency => "USD",
:quantity => 1 }]},
:amount => {
:total => "1.00",
:currency => "USD" },
:description => "This is the payment transaction description." }]})
# Create Payment and return the status(true or false)
if #payment.create
#payment.id # Payment Id
else
#payment.error # Error Hash
end
This might be a good case for the Payouts API, which is also supported by the Ruby SDK.
To fund the payout with minimal fees, you'll want to have the payout amount already in your PayPal account or link to your bank account.

ruby-aws Amazon Mechanical Turk

I am trying to create a HIT with a pre-created form using the ruby-aws gem and keep getting a missing params error. I have limited the missing params to the params specific to my form.
It seems my request is not being formatted correctly and there are next to no examples from Amazon. My logs say the the following params are missing:
relationship, price, environmental_consciousness, age, occasion, gender, humor, experience, local, romance, additional_information
Any help is much appreciated!
Below is my current request:
hit = mturk.createHIT(
:Operation => 'CreateHIT',
:Title => 'Find a gift based on user scores',
:Description => 'Find a gift for an individual based on survey scores.',
:MaxAssignments => 3,
:Signature => signature,
:Timestamp => timestamp,
:Reward => { :Amount => 0.25, :CurrencyCode => 'USD' },
:HITLayoutId => '3AV6FF2M2GYMGLRQEKHZ7EBN4EZOJE',
:HitLayoutParameter => {'Name' => 'additional_information', 'Value' => 'TEST'},
:HitLayoutParameter => {'Name' => 'age', 'Value' => '22'},
:HitLayoutParameter => {'Name' => 'environmental_consciousness', 'Value' => '54'},
:HitLayoutParameter => {'Name' => 'experience', 'Value' => '32'},
:HitLayoutParameter => {'Name' => 'gender', 'Value' => 'male'},
:HitLayoutParameter => {'Name' => 'humor', 'Value' => '66'},
:HitLayoutParameter => {'Name' => 'local', 'Value' => '21'},
:HitLayoutParameter => {'Name' => 'occasion', 'Value' => '43'},
:HitLayoutParameter => {'Name' => 'price', 'Value' => '33'},
:HitLayoutParameter => {'Name' => 'relationship', 'Value' => '23'},
:HitLayoutParameter => {'Name' => 'romance', 'Value' => '23'},
:Keywords => 'data collection, gifting, gifts, shopping, gift listings, presents',
:AssignmentDurationInSeconds => 300,
:LifetimeInSeconds => 604800
)
I was able to resolive the issue - AWS has terrible naming conventions. The above example does use the correct format, however HitLayoutParameter must be HITLayoutParameter - Notice the CAPITAL HIT vs Hit.
Also, when submitting multiple parameters, the should only be one HITLayoutParameter that equals an array of Name/Value pairs. Working code below.
Hope this helps someone else!
Best,
~DFO~
hit = mturk.createHIT(
:Operation => 'CreateHIT',
:Title => 'Find a gift based on user scores',
:Description => 'Find a gift for an individual based on survey scores.',
:MaxAssignments => 3,
:Signature => signature,
:Timestamp => timestamp,
:Reward => { :Amount => 0.25, :CurrencyCode => 'USD' },
:HITLayoutId => '3AV6FF2M2GYMGLRQEKHZ7EBN4EZOJE',
:HITLayoutParameter => [
{:Name => 'additional_information', :Value => 'TEST'},
{:Name => 'age', :Value => '22'},
{:Name => 'environmental_consciousness', :Value => '54'},
{:Name => 'experience', :Value => '32'},
{:Name => 'gender', :Value => 'male'},
{:Name => 'humor', :Value => '66'},
{:Name => 'local', :Value => '21'},
{:Name => 'occasion', :Value => '43'},
{:Name => 'price', :Value => '33'},
{:Name => 'relationship', :Value => '23'},
{:Name => 'romance', :Value => '23'}
],
:Keywords => 'data collection, gifting, gifts, shopping, gift listings, presents',
:AssignmentDurationInSeconds => 300,
:LifetimeInSeconds => 604800
)

Nested hash iteration: How to iterate a merge over an ( (array of hashes) within a hash )

I'm trying to do as the title says. Here is my code:
school.each { |x| school[:students][x].merge!(semester:"Summer") }
I think I pinpointed the problem to the "[x]" above. If I substitute an array position such as "[2]" it works fine. How can make the iteration work?
If the info above is not enough or you'd like to offer a better solution, please see the details below. Thanks!
The error message I get:
file.rb:31:in []': no implicit conversion of Array into Integer (TypeError)
from file.rb:31:inblock in '
from file.rb:31:in each'
from file.rb:31:in'
The nested hash below before alteration:
school = {
:name => "Happy Funtime School",
:location => "NYC",
:instructors => [
{:name=>"Blake", :subject=>"being awesome" },
{:name=>"Ashley", :subject=>"being better than blake"},
{:name=>"Jeff", :subject=>"karaoke"}
],
:students => [
{:name => "Marissa", :grade => "B"},
{:name=>"Billy", :grade => "F"},
{:name => "Frank", :grade => "A"},
{:name => "Sophie", :grade => "C"}
]
}
I'm trying to append :semester=>"Summer" to each of the last four hashes. Here is what I'm trying to go for:
# ...preceding code is the same. Changed code below...
:students => [
{:name => "Marissa", :grade => "B", :semester => "Summer"},
{:name=>"Billy", :grade => "F", :semester => "Summer"},
{:name => "Frank", :grade => "A", :semester => "Summer"},
{:name => "Sophie", :grade => "C", :semester => "Summer"}
]
}
Just iterate over the students:
school[:students].each { |student| student[:semester] = "Summer" }
Or, using merge:
school[:students].each { |student| student.merge!(semester: "Summer") }
The issue is that when you do array.each {|x| do something}, x actually refers to each element in the array.
For example, in the first iteration of the loop,
x = {:name => "Marissa", :grade => "B"}
So what you are really doing is trying to reference:
school[:student][{:name => "Marissa", :grade => "B"}]
Which will not work
What you could do instead is create a for loop to track the index.
for i in 0 ... school[:student].count
school[:students][i].merge!(semester:"Summer")
end
Edit: Stefan's solution is much better than mine, but I will leave this up to show where you went wrong.
I would do as below using Hash#store :
require 'awesome_print'
school = {
:name => "Happy Funtime School",
:location => "NYC",
:instructors => [
{
:name => "Blake",
:subject => "being awesome"
},
{
:name => "Ashley",
:subject => "being better than blake"
},
{
:name => "Jeff",
:subject => "karaoke"
}
],
:students => [
{
:name => "Marissa",
:grade => "B"
},
{
:name => "Billy",
:grade => "F"
},
{
:name => "Frank",
:grade => "A"
},
{
:name => "Sophie",
:grade => "C"
}
]
}
school[:students].each{|h| h.store(:semester ,"Summer")}
ap school,:index => false,:indent => 10
output
{
:name => "Happy Funtime School",
:location => "NYC",
:instructors => [
{
:name => "Blake",
:subject => "being awesome"
},
{
:name => "Ashley",
:subject => "being better than blake"
},
{
:name => "Jeff",
:subject => "karaoke"
}
],
:students => [
{
:name => "Marissa",
:grade => "B",
:semester => "Summer"
},
{
:name => "Billy",
:grade => "F",
:semester => "Summer"
},
{
:name => "Frank",
:grade => "A",
:semester => "Summer"
},
{
:name => "Sophie",
:grade => "C",
:semester => "Summer"
}
]
}

What's the best way to replace a string inside a string in ruby?

I have a bunch of these:
'link' => "http://twitter.com/home?status=Check out "{title}" {url}",
And Want to replace the {title} and {url} bits.
I'm currently doing this with gsub:
l.gsub! "{url}", URI::encode(#opts[:url])
l.gsub! "{title}", URI::encode(#opts[:title])
But I have the feeling there's a much better way to do this than with gsub...
#
This is an edit / addition to clarify:
class SocialBookmarkMaker
require 'open-uri'
attr_accessor :opts
def initialize(opts)
#opts = ##default_opts.merge opts
end
##default_opts = {
:icon_folder => "/images/icons/social_aquatic/24 X 24",
:sites => ['facebook', 'twitter', 'delicious', 'digg', 'stumbleupon', 'reddit', 'technorati', ],
:ext => 'png',
:url => 'not provided',
:title => 'not provided',
}
##bookmarks = {
'yahoo' => {
'name' => 'Yahoo! My Web',
'link' => 'http://myweb2.search.yahoo.com/myresults/bookmarklet?u={url}&t={title}',
},
'google' => {
'name' => 'Google Bookmarks',
'link' => 'http://www.google.com/bookmarks/mark?op=edit&bkmk={url}&title={title}',
},
'windows' => {
'name' => 'Windows Live',
'link' => 'https://favorites.live.com/quickadd.aspx?url={url}&title={title}',
},
'facebook' => {
'name' => 'Facebook',
'link' => 'http://www.facebook.com/sharer.php?u={url}&t={title}',
},
'digg' => {
'name' => 'Digg',
'link' => 'http://digg.com/submit?phase=2&url={url}&title={title}',
},
'ask' => {
'name' => 'Ask',
'link' => 'http://myjeeves.ask.com/mysearch/BookmarkIt?v=1.2&t=webpages&url={url}&title={title}',
},
'technorati' => {
'name' => 'Technorati',
'link' => 'http://www.technorati.com/faves?add={url}',
},
'delicious' => {
'name' => 'del.icio.us',
'link' => 'http://del.icio.us/post?url={url}&title={title}',
},
'stumbleupon' => {
'name' => 'StumbleUpon',
'link' => 'http://www.stumbleupon.com/submit?url={url}&title={title}',
},
'squidoo' => {
'name' => 'Squidoo',
'link' => 'http://www.squidoo.com/lensmaster/bookmark?{url}'
},
'netscape' => {
'name' => 'Netscape',
'link' => 'http://www.netscape.com/submit/?U={url}&T={title}',
},
'slashdot' => {
'name' => 'Slashdot',
'link' => 'http://slashdot.org/bookmark.pl?url={url}&title={title}',
},
'reddit' => {
'name' => 'reddit',
'link' => 'http://reddit.com/submit?url={url}&title={title}',
},
'furl' => {
'name' => 'Furl',
'link' => 'http://furl.net/storeIt.jsp?u={url}&t={title}',
},
'blinklist' => {
'name' => 'BlinkList',
'link' => 'http://blinklist.com/index.php?Action=Blink/addblink.php&Url={url}&Title={title}',
},
'dzone' => {
'name' => 'dzone',
'link' => 'http://www.dzone.com/links/add.html?url={url}&title={title}',
},
'swik' => {
'name' => 'SWiK',
'link' => 'http://stories.swik.net/?submitUrl&url={url}'
},
'shoutwire' => {
'name' => 'Shoutwrie',
'link' => 'http://www.shoutwire.com/?p=submit&&link={url}',
},
'blinkbits' => {
'name' => 'Blinkbits',
'link' => 'http://www.blinkbits.com/bookmarklets/save.php?v=1&source_url={url}',
},
'spurl' => {
'name' => 'Spurl',
'link' => 'http://www.spurl.net/spurl.php?url={url}&title={title}',
},
'diigo' => {
'name' => 'Diigo',
'link' => 'http://www.diigo.com/post?url={url}&title={title}',
},
'tailrank' => {
'name' => 'Tailrank',
'link' => 'http://tailrank.com/share/?link_href={url}&title={title}',
},
'rawsugar' => {
'name' => 'Rawsugar',
'link' => 'http://www.rawsugar.com/tagger/?turl={url}&tttl={title}&editorInitialized=1',
},
'twitter' => {
'name' => 'Twitter',
'link' => "http://twitter.com/home?status=Check out "{title}" {url}",
},
}
def self.bookmarks
##bookmarks
end
def icon_loc(site)
"http://common-resources.---.net.s3.amazonaws.com#{#opts[:icon_folder]}/#{site}.#{#opts[:ext]}"
end
def link_url(site)
l = SocialBookmarkMaker.bookmarks[site]['link']
l.gsub! "{url}", URI::encode(#opts[:url])
l.gsub! "{title}", URI::encode(#opts[:title])
l
end
end
shared/social_bookmarks/standard.html.haml
- opts ||= {}
- opts.merge! :url => request.url
- opts.merge! :title => "---.net: #{#layout[:social_bookmark_title] || #layout[:title] || default_view_title}"
- b = SocialBookmarkMaker.new opts
- b.opts[:sites].each do |site|
= link_to(image_tag( b.icon_loc(site) ), b.link_url(site), :title => "Share on #{SocialBookmarkMaker.bookmarks[site]['name']}")
I then call this like this in my rails layout:
render :partial => "shared/social_bookmarks/standard", :locals => { :opts => {:icon_folder => "/images/icons/social_aquatic/48 X 48" }}
Either you change your string to look like
"http://twitter.com/home?status=Check out "%{title}" %{url}"
and then use printf with a Hash
s = "http://twitter.com/home?status=Check out "%{title}" %{url}"
# you can of course use #opts as the Hash here.
s = s % {:title => "abc", :url => "def"} # => "http://twitter.com/home?status=Check out "abc" def"
and accept that it only works with Ruby 1.9.2 and upwards, or you continue using gsub but using the block syntax to condense it:
s.gsub!(/\{(.+?)\}/) do |m|
#opts[$1.to_sym]
end
You can just embed the variables directly in the string
'link' => "http://twitter.com/home?status=Check out "#{title}" #{url}"

Resources