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