Currency calculation

I’m thinking of experimenting with some currency conversion. However,
I’d like the conversions to be in synch with the current rates.
Anyone know (and this maybe out in left field) if there is some online
(perhaps xml) or other data stream I can connect with in my code to
output values based on user selection ?

TIA
Stuart

Dark A. wrote:

I’m thinking of experimenting with some currency conversion. However,
I’d like the conversions to be in synch with the current rates.
Anyone know (and this maybe out in left field) if there is some online
(perhaps xml) or other data stream I can connect with in my code to
output values based on user selection ?

TIA
Stuart

There’s this - http://www.oanda.com/products/fxml/index.shtml
but it’s not free, I think…

Cheers
Mohit

Hey Stuart. I’m looking forward to someone coming up
with a good source. :slight_smile:

Are you familiar with the Money gem? It lays a great
deal of groundwork for multi-currency handling, and
works great with AR composition.


– Tom M.

Tom,

I was not but will investigate it.
By AR composition you are referring to Accounts Receivable ? or
something else ?

Stuart

:slight_smile: well maybe I was thinking of entities for the currency domain :slight_smile:
Stuart

AR in context of ruby on rails means ActiveRecord

Craig

newbie question - been looking over the api for Money , they make some
sense to me but - Question:
I’ve done the gem install do I copy the lib files over to the lib
folder in my rails app ?

Stuart

gem help
gem help commands
gem unpack “whatever”

you don’t have to do any of that if you don’t want as the gem packages
are found within the ruby/gem installation but if you want your
application to lock into a specific version of a gem, you can unpack it
into your app tree.

Craig

On 6/18/06, Dark A. [email protected] wrote:

I’m thinking of experimenting with some currency conversion. However,
I’d like the conversions to be in synch with the current rates.
Anyone know (and this maybe out in left field) if there is some online
(perhaps xml) or other data stream I can connect with in my code to
output values based on user selection ?

I did a lot of experimenting with this and have a production site
using a free online rate service. I know that I experimented with
making a nicer implementation of this but can’t find it. Argg. Below
is stable for me but almost embarrassingly bad coding to actually
share. All the important bits are here though.

The important thing is you want to cache the current rate for a period
of time. Getting the current rate for every request is unnecessary and
super slow.

======= application_helper.rb ==============

Methods added to this helper will be available to all templates in

the application.
module ApplicationHelper

def get_rate()
cached_record = CurrencyRate.find_by_abbr(current_currency)
# cached records considered up-to-date for one hour
if cached_record && cached_record.updated_on > Time.now - 3600
return cached_record.last_rate
end

begin
  rate = Timeout::timeout(10) do |timeout_length|
    service =

SOAP::RPC::Driver.new(“http://www.webservicex.net/CurrencyConvertor.asmx","http://www.webserviceX.NET/”)
service.default_encodingstyle =
SOAP::EncodingStyle::ASPDotNetHandler::Namespace
service.add_method_with_soapaction(“ConversionRate”,
http://www.webserviceX.NET/ConversionRate”, “FromCurrency”,
“ToCurrency”)

    rate = service.ConversionRate("CAD",current_currency).to_f

    rate
  end
rescue Timeout::Error
  @notice = "Sorry, the live currency conversion service is not

available at the moment.
You are now browsing in Canadian dollars."
session[:currency] = “CAD”
return
rescue
@notice = “Sorry, there was an error with the live currency
conversion service.
You are now browsing in Canadian dollars.”
session[:currency] = “CAD”
return
end

# save the rate to the database
if cached_record
  cached_record.last_rate = rate
  cached_record.save
else
  CurrencyRate.create(:abbr=>current_currency, :last_rate=>rate)
end

rate

end

def fmt_price(can_amt)
# TODO check in available currencies
if current_currency != “CAD”
rate=get_rate
end

case current_currency
when "USD"
  sprintf("$%0.2f US", can_amt*rate)
when "GBP"
  sprintf("£%0.2f", can_amt*rate)
when "EUR"
  sprintf("?%0.2f", can_amt*rate)
when "AUD"
  sprintf("$%0.2f AUS", can_amt*rate)
when "MXN"
  sprintf("%0.2f Mx Pesos", can_amt*rate)
else
  sprintf("$%0.2f CAN", can_amt)
end

end

def current_currency
session[:currency] ||= “CAD”
end

def currency_map

[

#[“Select”, “”],

[“Canadian Dollars”, “CAN”],

[“US Dollars”, “US”],

[“Pounds Sterling”, “POUNDS”],

[“Euro”, “EURO”],

[“Australian Dollars”, “AUS”],

[“Mexican Pesos”, “PESO”]

]

[
  ["currency/can.png", "CAD"],
  ["currency/us.png", "USD"],
  ["currency/uk.png", "GBP"],
  ["currency/euro.png", "EUR"],
  ["currency/aus.png", "AUD"],
  ["currency/mex.png", "MXN"]
]

end

end

====== DATABASE DDL ==============

DROP TABLE IF EXISTS currency_rates;

CREATE TABLE currency_rates (

id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
abbr VARCHAR(255) NOT NULL,
last_rate DECIMAL(10,4) NOT NULL,
updated_on DATETIME NOT NULL
);

========= currency.rb model (haha. A model, yeah right.) =============

class CurrencyRate < ActiveRecord::Base
end

========= in layout to allow for currency change ===================
=== note two options here to go with the commented out array in
currency_map

<% if false %>
<%= form_tag :action=>“change_currency” %>
Currency:

<% currency_map.each do |c| %>
<option value=“<%=c[1]%>” <%=“selected="selected"” if
c[1]==current_currency%>><%=c[0]%>
<% end %>


<%= submit_tag “Change Currency” %>

<%= end_form_tag %>
<% end %>

Choose your currency: <% currency_map.each do |c| -%> <%= link_to (image_tag(c[0]), {:action=>"change_currency", :currency=>c[1]}) -%> <% end -%>

========= in views ====================

<%= fmt_price(cart_item.price) %>

========= in controller ==============

def change_currency
session[:currency]=params[:currency]
redirect_to :back
end


I think that is everything I used. It looks like a mess but there is
some logic.
I know I got around to storing more info in the database currency_rate
table but I can’t find it. Argg.

How do I search inside all text files on a Mac OS X 10.3 for the word
“currency”?

Peter

On Sunday, June 18, 2006, at 10:24 AM, Dark A. wrote:

[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails

Take a look at the ‘units’ gem, I think it has some online conversion
capabilities.

_Kevin

On 6/18/06, Peter M. [email protected] wrote:

On 6/18/06, Dark A. [email protected] wrote:

I’m thinking of experimenting with some currency conversion. However,
I’d like the conversions to be in synch with the current rates.
Anyone know (and this maybe out in left field) if there is some online
(perhaps xml) or other data stream I can connect with in my code to
output values based on user selection ?

It looks like my nicer version is gone.

I just found this on my computer. Could be another service to try.
Perhaps good to have two SOAP services incase one is down. This is a
chunk of applescript you could pick apart

(* Currency Converter.applescript *)

(* This is an enhanced version of Currency Converter that utilizes
SOAP services to enable getting the current exchange rate. *)

(* ==== Event Handlers ==== *)

– The “action” event handler is called when the user choosing a
country from the popup button. We will call the “getRate” event
handler to use a SOAP service to get the rate.

on action theObject
set contents of text field “rate” of window of theObject to
getRate(title of theObject as string)
end action

– The “clicked” event handler is called when the user clicks on the
“Convert” button. This will do a simple calculatin of “rate * dollars”
and put the result in the “total” field.

on clicked theObject
tell window of theObject
set theRate to contents of text field “rate” as real
set theDollars to contents of text field “dollars” as real
set contents of text field “total” to theRate * theDollars
end tell
end clicked

– The “awake from nib” event handler is called the popup button is
loaded form the nib. In this example we will use this opportunity to
get the rate (based on the default selection of the popup button).

on awake from nib theObject
set contents of text field “rate” of window of theObject to
getRate(title of theObject)
end awake from nib

(* ==== Handlers ==== *)

– This handler is called to get the current exchange rate for the
given country. It does this by using the “call soap” command to
communicate with a SOAP web service.

on getRate(forCountry)
– Initialize the result to a known value
set theRate to 1.0

-- We always convert from the US
set fromCountry to "USA"

-- Talk to the soap service
tell application "http://services.xmethods.net:80/soap"
	-- Call the "getRate" method of the soap service returning the current 

rate
set theRate to call soap {method name:“getRate”, method namespace
uri:“urn:xmethods-CurrencyExchange”, parameters:{country1:fromCountry,
country2:forCountry}, SOAPAction:“”}
end tell

-- Return the result
return theRate

end getRate

– This is a utility handler to get the given unicode text as plain
text (not styled text)

on getPlainText(fromUnicodeString)
set styledText to fromUnicodeString as string
set styledRecord to styledText as record
return «class ktxt» of styledRecord
end getPlainText

On Jun 18, 2006, at 10:06 AM, Dark A. wrote:

I was not but will investigate it.
By AR composition you are referring to Accounts Receivable ? or
something else ?

ActiveRecord. :slight_smile:


– Tom M.

Hi Peter,

With your code listing that you have provided, I was keen to learn how
the admin side of things works. Do you simply enter the cost of an item
in USD in the admin, which users can then convert on the product view?

Thanks,
Neil.

On 6/21/06, Neil B. [email protected] wrote:

With your code listing that you have provided, I was keen to learn how
the admin side of things works. Do you simply enter the cost of an item
in USD in the admin, which users can then convert on the product view?

Hi Neil,

I was storing the prices in the database in Canadian dollars only.
Then as users wanted to see the prices in other currencies I cached
the exchange rates in the database. These cached values are considered
valid for one hour.

Peter