Can't change currency symbol on spree 3.0 - ruby-on-rails

I'm currently using Spree 3.0 and changed my currency to Colombian Peso (COP). Right now prices are shown like this: ₱80.000,00. I want them to look like this: $ 80.000. I have an idea on how to remove the two 0 after the comma but haven't been able to change the currency symbol for $. This is what I have so far:
in /config/initializers/spree.rb
Spree.config do |config|
config.logo = 'templo samadhi logo.png'
config.admin_interface_logo = 'templo samadhi logo.png'
country = Spree::Country.find_by_name('Colombia')
config.default_country_id = country.id if country.present?
config.checkout_zone = country.id
Money::Currency.register({
:priority => 1,
:iso_code => "COP",
:iso_numeric => country.id,
:name => "Colombia",
:symbol => "$ ",
:subunit => "Cent",
:subunit_to_unit => 100,
:separator => ".",
:delimiter => ","
})
end
This is somehow working because the ₱ symbol is getting removed but the $ is not showing up.
I appreciate if someone can help me with this.
UPDATE
I added the following and now I'm removing the two 0 after the comma but I'm also getting a $ after the price like this: 80.000 $.
So right now I don't know how to move the $ symbol before the price.
Spree::Money.class_eval do
def to_s
formatted = #money.format(#options)
formatted.gsub(/,00/, "")
formatted.symbol_position == :before
end
def to_html(options = { :html => true })
to_s
end
end

I was using this solution but found an issue when I try to process the payment through the stripe gateway, it actually needs the amount subunit to be "Cents" in order to make the currency conversion.
With the #luisjar answer you actually don't use subunits in the COP currency but they may be needed for some payment gateways like stripe. In order to use the COP currency (or any other currency) with a subunit but without showing it, you need to set the format property no_cents true. This is the way I show the amount in Colombian Peso currency like $ 10,000 COP.
Spree.config do |config|
#Change currency symbol for Colombia
country = Spree::Country.find_by_name('Colombia')
config.default_country_id = country.id if country.present?
config.checkout_zone = country.id
Spree::Money.class_eval do
def to_s
#money.format.gsub(/,00/, "")
#money.format(:symbol_position => :before, :with_currency => true, :no_cents => true)
end
def to_html(options = { :html => true })
to_s
end
end
Money::Currency.register({
:priority => 1,
:iso_code => "COP",
:iso_numeric => country.id,
:name => "Colombia",
:symbol => "$ ",
:subunit => "Cent",
:subunit_to_unit => 100,
:separator => ".",
:delimiter => ","
})
Spree::Price.update_all(currency: 'COP')
end
I hope this help to any other confused (like me) with the currencies in Spree.
You can read more about currency format in: https://github.com/RubyMoney/money/blob/master/lib/money/money/formatting.rb

With the code, you merely register another currency. Each product(-variant) has many prices, one per currency. You should make sure, probably in a migration, that all your prices on all your variants are updated to use the correct currency.
Spree::Price.update_all(currency: 'COP')
If you don't want to loose the Dollar prices, but instead want to add an additional price, you need to edit each one manually, or on a migration.
Spree::Price.find_each do |price|
Spree::Price.create(variant: price.variant, amount: price.amount * 1.337, currency: 'COP')
end
Where 1.337 is a conversion factor.

I finally found how to remove the two ceros after the comma, use the $ symbol but still use the Colombian peso Currency. This is the way I did it.
Spree.config do |config|
config.logo = 'templo samadhi logo.png'
config.admin_interface_logo = 'templo samadhi logo.png'
country = Spree::Country.find_by_name('Colombia')
config.default_country_id = country.id if country.present?
config.checkout_zone = country.id
Spree::Money.class_eval do
def to_s
#money.format.gsub(/,00/, "")
#money.format(:symbol_position => :before)
end
def to_html(options = { :html => true })
to_s
end
end
Money::Currency.register({
:priority => 1,
:iso_code => "COP",
:iso_numeric => country.id,
:name => "Colombia",
:symbol => "$ ",
:subunit => "Peso",
:subunit_to_unit => 1,
:separator => ".",
:delimiter => ","
})
end

Looking at documentation of class Currency (in gems/money_6.9.0/lib/money/currency.rb) I found better the following settings:
Money::Currency.register({
:priority => 1,
:iso_code => "COP",
:iso_numeric => country.id,
:name => "Peso",
:symbol => "$",
:html_entity => "$ ",
:symbol_first => true,
:subunit => "Cent",
:subunit_to_unit => 100,
:separator => ".",
:delimiter => ","
})
The "name" attribute is the name of the currency, not the name of the country. The space between the $ and the number goes inside the "html_entity" and not in the symbol. Finally, the "symbol_first" attribute controls where to place the symbol.

Related

How to configure decimal_mark and thousand_separator - Money Rails

I'm trying use the gem money-rails but with no success.
I live in Brazil and here the decimal mark is "," and the thousand separator is "."
So, I add the follow code in a money.rb initializer:
MoneyRails.configure do |config|
config.default_currency = :brl
config.register_currency = {
:id => :brl,
:priority => 1,
:iso_code => "BRL",
:name => "Real",
:symbol => "R$",
:symbol_first => true,
:subunit => "Cent",
:subunit_to_unit => 100,
:thousands_separator => ".",
:decimal_mark => ","
}
end
And in my model class "Produto":
class Produto < ApplicationRecord
attr_accessor :nome, :preco
monetize :preco_centavos
end
But when I try use this in Rails console I get a different behavior:
irb(main):001:0> p = Produto.new
=> #<Produto id: nil, nome: nil, preco_centavos: 0, preco_currency: "BRL", created_at: nil, updated_at: nil>
irb(main):002:0> p.preco = 1000.to_money
=> #<Money fractional:100 currency:BRL>
irb(main):003:0> p.preco.format
=> "R$1,000.00"
The format method return "R$1,000.00" when I expect "R$1.000,00".
Someone already passed for this?
PS: Sorry for my bad English
This is a bug (or at least a misleading feature) in the money-rails gem code. Set Money.use_i18n = false. Once you do this, then you won't need to do config.register_currency for the commas/decimals, at least. 1000.to_money('BRL').format yields "R$1.000,00".
See https://github.com/RubyMoney/money-rails/blob/4a35ae823843fba80c036e2332e80d6b9e06dcb5/lib/money-rails/active_model/validator.rb#L58 for why this is the case.

SpreeCommerce price format

I'm building a site for SpreeCommerce 2.1.3, and I'm stuck trying to figure out how to format the prices correctly.
The currency is DKK (Danish Kroner) and I'm looking for the following:
1000 => kr. 1.000,-
1000.50 => kr. 1.000,50
Spree formats my prices like this:
1000 => kr.1.000,00
1000.50 => kr.1.000,50
So there are two problems:
I need a space between kr. and the price.
When there arent any decimals, I would like the decimals rendered as ,- (example: 1.000,-)
How do I accomplish that?
Here's my configuration from config/initializers/spree.rb:
Spree.config do |config|
# [...]
config.currency = "DKK"
config.currency_symbol_position = "before"
config.currency_decimal_mark = ","
config.currency_thousands_separator = "."
end
Solution:
1) I added this decorator to Spree::Money (to replace ,00 with ,-):
Spree::Money.class_eval do
def to_s
formatted = #money.format(#options)
formatted.gsub(/,00$/, ",-")
end
def to_html(options = { :html => true })
to_s
end
end
2) I configured danish currency in my initializer (to add the space after kr.):
Money::Currency.register({
:priority => 1,
:iso_code => "DKK",
:iso_numeric => "208",
:name => "Danish krone",
:symbol => "kr. ",
:subunit => "Øre",
:subunit_to_unit => 100,
:separator => ".",
:delimiter => ","
})
You can customize https://github.com/spree/spree/blob/master/core/lib/spree/money.rb as you want by overriding it.

Ruby On Rails Mail Routine Not sending

I Have a ROR IF statement that is supposed to look up a record and then send emails based on the login can anyone tell me what is wrong in the syntax?
this is now working but there is two test cases that return ActiveRecord::RecordNotFound (Couldn't find SignOn with userw1 = xxx#example.com):
app/models/order.rb:219:in `submit_order'
class Order < ActiveRecord::Base
# NOTE: ensure that you always setup methods here to include and filter on
# query_account_number as a security measure.
establish_connection "web_#{RAILS_ENV}"
has_many :order_details, :dependent => :destroy, :order => 'id DESC'
def self.delete_item query_account_number, login, id
order = Order.first(:conditions => {:account_number => query_account_number, :login => login})
detail = order.order_details.first(:conditions => {:id => id})
detail.destroy if detail
# Here we would delete the order, but have chosen to leave it so they do not have
# questionable gaps in IDs.
end
def self.verify_upc1 upc_rule, upc1
"Invalid UPC Prefix" unless Item.first(:conditions => ["rul31c = ? AND CONCAT(TRIM(comi1c), 'A') = ?", upc_rule, upc1 + "A"],
:select => "style")
end
def self.verify_upc2 upc_rule, upc1, upc2
"Invalid UPC Prefix or Subnumber" unless Item.first(:conditions => ["rul31c = ? AND CONCAT(TRIM(comi1c), CONCAT(TRIM(arsb1c), 'A')) = ?", upc_rule, upc1 + upc2 + "A"],
:select => "style")
end
def self.verify_style upc_rule, style
"Invalid Style" unless Item.first(:conditions => ["rul31c = ? AND CONCAT(TRIM(style), 'A') = ?", upc_rule, style + "A"],
:select => "style")
end
def self.update_quantity query_account_number, login, id, quantity
if quantity.to_i > 0
order = Order.first(:conditions => {:account_number => query_account_number, :login => login})
detail = order.order_details.first(:conditions => {:id => id})
if detail
detail.quantity = quantity.to_i
detail.save
end
end
end
def self.update_order_note query_account_number, login, order_note
order = Order.first(:conditions => {:account_number => query_account_number, :login => login})
order.note = order_note
order.save
end
def self.update_order_item_note query_account_number, login, id, note
order = Order.first(:conditions => {:account_number => query_account_number, :login => login})
detail = order.order_details.first(:conditions => {:id => id})
if detail
detail.note = note
detail.save
end
end
def self.add_item query_account_number, login, quantity, upc1, upc2, price_code, upc_rule
if quantity.to_i > 0
order = Order.first(:conditions => {:account_number => query_account_number, :login => login})
order = Order.add_order_header(query_account_number, login) if order.blank?
if order
item = Item.first(:conditions => ["rul31c = ? AND CONCAT(TRIM(comi1c), CONCAT(TRIM(arsb1c), 'A')) = ?", upc_rule, upc1 + upc2 + "A"],
:select => "style, color, size, pnum35, cono35, comi1c, arsb1c, ptyp35")
price = Price.first(:conditions => {:catnwp => item.pnum35, :conowp => item.cono35, :listwp => price_code}, :select => "prcewp") unless item.blank?
if item and price
order_detail = OrderDetail.new(:style => item.style,
:order_id => order.id,
:quantity => quantity,
:color => item.color,
:size => item.size)
order_detail.save
# Return a cart item hash
cart_contents = []
cart_contents << {:style => item.style,
:color => item.color,
:size => item.size,
:quantity => quantity,
:name => ProItem.short_description(item.style),
:price => price.prcewp,
:type => item.ptyp35,
:upc => item.comi1c + item.arsb1c,
:id => order_detail.id}
end
end
end
end
def self.order_info_update query_account_number, login, info
order = Order.first(:conditions => {:account_number => query_account_number, :login => login})
if order
if info.has_key?("name")
order.name = info[:name]
order.address1 = info[:address1]
order.address2 = info[:address2]
order.address3 = info[:address3]
order.city = info[:city]
order.state = info[:state]
order.zip = info[:zip]
end
if info.has_key?("po_number")
order.po_number = info[:po_number]
end
order.save
# where does po number go???
end
end
def self.mailing_address query_account_number, login
o = Order.first(:conditions => {:account_number => query_account_number, :login => login})
{:name => o.name, :address1 => o.address1, :address2 => o.address2, :address3 => o.address3, :city => o.city, :state => o.state, :zip => o.zip} if o
end
def self.order_note query_account_number, login
o = Order.first(:conditions => {:account_number => query_account_number, :login => login}, :select => "note")
o.note if o
end
def self.cart_contents query_account_number, login, price_code, upc_rule
# TODO: what to do if item changed since they put it in cart?
# Perhaps we expire a cart after a while, but, that still is not a perfect solution.
# Ideally here we go through each style, make sure it is still valid for the customer, and
# check color/size as well.
order_items = Order.first(:conditions => {:account_number => query_account_number, :login => login} )
if order_items
cart_contents = []
order_items.order_details.each do |oi|
as400_item = Item.first(:conditions => {:rul31c => upc_rule, :style => oi.style.ljust(9), :color => oi.color, :size => oi.size },
:select => "pnum35, cono35, ptyp35, comi1c, arsb1c")
price = Price.first(:conditions => {:catnwp => as400_item.pnum35, :conowp => as400_item.cono35, :listwp => price_code}, :select => "prcewp") unless as400_item.blank?
cart_contents << {:style => oi.style,
:color => oi.color,
:size => oi.size,
:quantity => oi.quantity,
:name => ProItem.short_description(oi.style),
:price => price.prcewp,
:type => as400_item.ptyp35,
:note => oi.note,
:upc => as400_item.comi1c + as400_item.arsb1c,
:id => oi.id} if as400_item and price
end unless order_items.blank?
cart_contents
end
end
def self.cart_contents_count query_account_number, login
order_items = Order.first(:conditions => {:account_number => query_account_number, :login => login} )
count = 0
order_items.order_details.each {|oi| count += oi.quantity } if order_items
count
end
def self.cart_contents_total query_account_number, login, price_code, upc_rule
order_items = Order.first(:conditions => {:account_number => query_account_number, :login => login} )
total = 0
order_items.order_details.each do |oi|
as400_item = Item.first(:conditions => {:rul31c => upc_rule, :style => oi.style.ljust(9), :color => oi.color, :size => oi.size },
:select => "pnum35, cono35, ptyp35")
price = 0
if !as400_item.blank?
price = Price.first(:conditions => {:catnwp => as400_item.pnum35, :conowp => as400_item.cono35, :listwp => price_code}, :select => "prcewp")
total += (oi.quantity * price.prcewp.to_f)
end
end if order_items
total
end
def self.add_order_details query_account_number, login, items, notes = Hash.new
result = false
if items
# If there is not an order record, create one. Basically we only
# allow one open order per login at a time, and if there is
# one already, we continue to append order_detail records to it.
order = Order.first(:conditions => {:account_number => query_account_number, :login => login.upcase})
order = Order.add_order_header(query_account_number, login) if order.blank?
items.each do |key, value|
if value.to_i > 0
result = true
style = key[0..8]
color = key[9..11]
size = key[12..14]
order_detail = OrderDetail.new(:style => style,
:order_id => order.id,
:quantity => value,
:color => color,
:size => size,
:note => (notes ? notes[key] : ''))
order_detail.save
end
end if order
end
result
end
def self.submit_order query_account_number, login, price_code, distributor_number
o = Order.first(:conditions => {:account_number => query_account_number, :login => login})
# TODO: transaction or some error handling
if o
# Find all associated records we need.
customer = Customer.first(:conditions => {:cusn05 => query_account_number}, :select => "cono05, cgp405, slmn05, list20" )
sign_on = SignOn.first(:conditions => {:userw1 => login.upcase},
:select => "idnow1, bsnamw1, accntw1, prfdstw1, cntacw1, bsadd1w1, bsadd2w1, bsadd3w1, bscityw1, bsstcdw1, bszipw1, acctypw1")
distributor = Distributor.first(:conditions => {:cusnp1 => distributor_number}, :select => "cnam05, emailp1")
if sign_on.acctypw1.strip == "DS"
rec = SignOn.find_by_userw1!(login)
webid = rec.prfdstw1
elsif sign_on.acctypw1.strip == "DSD"
rec = SignOn.find_by_userw1!(login)
webid = rec.prfdstw1
end
#cnt = Weboel23.count(:all,:conditions => {:act223 => mp})
weboel23 = Weboel23.first(:conditions => {:act223 => webid}, :select => "emal23")
#cnt=weboel23.count
approval0=Weboel23.get_email_by_account0(webid)
approval1=Weboel23.get_email_by_account1(webid)
approval2=Weboel23.get_email_by_account2(webid)
approval3=Weboel23.get_email_by_account3(webid)
approval4=Weboel23.get_email_by_account4(webid)
# weboel23 = Weboel23.each(:conditions => {:act223 => mp}, :select => "emal23")
#approval = weboel23.emal23
#f=File.open("/var/www/onlineordering.coastalpet.com/log/debug3.txt")
#establish_connection "as400_#{RAILS_ENV}"
#f.puts "prfdstw1"
#f.puts rec = SignOn.find_by_userw1!(login)
#f.puts "type="+elephant
#f.puts "email="+approval0
#f.close
# s = find_by_sql ["SELECT EMAL23 emal23 FROM WEBOEL23 WHERE ACT223 = ?", distributor_number]
# d << { :id => s[0].emal23 } unless s.blank?
if customer and sign_on
as400_order_id = "WB" + o.id.to_s.rjust(8, "0")
total = 0
count = 0
line = 1 # Start at 1 per Ron Hoopes 2/14/2011
o.order_details.each do |oi|
item = Item.first(:conditions => {:rul31c => customer.cgp405, :style => oi.style.ljust(9), :color => oi.color, :size => oi.size },
:select => "comi1c, arsb1c, chdt1c, pnum35, cono35, pdes35")
price = Price.first(:conditions => {:catnwp => item.pnum35, :conowp => item.cono35, :listwp => price_code}, :select => "prcewp") unless item.blank?
if item and price
WebOrderDetail.create(:conowd => customer.cono05,
:uniqwd => as400_order_id,
:linewd => line,
:itemwd => oi.style.ljust(9) + oi.color + oi.size,
:barcwd => item.comi1c.strip + item.arsb1c.strip + item.chdt1c.strip,
:altiwd => "",
:itmdwd => item.pdes35,
:qtywd => oi.quantity,
:uprcwd => price.prcewp.to_f.round_to(2),
:listwd => customer.list20,
:dtdrwd => "0",
:dcd1wd => "",
:dsc1wd => "0",
:dcd2wd => "",
:dsc2wd => "0")
# Create any order ITEM notes.
unless oi.note.blank?
oi.note.scan(/.{1,70}/).each_with_index do |note, index|
WebOrderNote.create(:conown => customer.cono05,
:textwn => note,
:uniqwn => as400_order_id,
:linewn => line,
:seqwn => index)
end
end
count += oi.quantity.to_i
total += oi.quantity.to_i * price.prcewp.to_f.round_to(2)
line += 1
end
end
# Create any order notes.
unless o.note.blank?
o.note.scan(/.{1,70}/).each_with_index do |note, index|
WebOrderNote.create(:conown => customer.cono05,
:textwn => note,
:uniqwn => as400_order_id,
:linewn => 0,
:seqwn => index)
end
end
# Coastal's definition a current century is off by one, hence the math for the date.
as400_order_header = WebOrder.new(:conowc => customer.cono05,
:uniqwc => as400_order_id,
:idnowc => sign_on.idnow1,
:namewc => o.name,
:addr1wc => o.address1,
:addr2wc => o.address2,
:addr3wc => o.address3,
:citywc => o.city,
:statewc => o.state,
:zipcdwc => o.zip,
:cusnwc => query_account_number,
:dtordwc => Utilities.to_db2_date(Date.today),
:shpdtwc => Utilities.to_db2_date(Date.today),
:cusowc => o.po_number.blank? ? as400_order_id : o.po_number,
:slmnwc => customer.slmn05,
:rulewc => customer.cgp405,
:listwc => customer.list20,
:valuewc => total.to_f.round_to(2),
:statwc => "")
if as400_order_header.save
# Sent confirmation email, if required. Only send it for users that chose a distributor,
# whether they had to choose one or not. We determine this by looking at the account number
# in the sign_on and comparing it with the order number we are using for the order. If
# that is different, it indicates that they chose a distributor.
# These are used in the email body, key for the hash is the replacement tags, capitalized, &
# prepended and appended with '##', e.g. ##NAME## - and any underlines are replaced with space
email_details = {"name" => sign_on.bsnamw1,
"order_number" => as400_order_id,
"order_total" => format('$%.2f', total),
"order_count" => count.to_s,
"order_date" => Date.today.to_s,
"distributor_name" => (distributor ? distributor.cnam05 : ""),
"distributor_contact" => "UNKNOWN",
"customer_name" => sign_on.bsnamw1,
"customer_address" => sign_on.bsadd1w1.strip + (!sign_on.bsadd2w1.blank? ? "<br>" + sign_on.bsadd2w1.strip : "") + (!sign_on.bsadd3w1.blank? ? "<br>" + sign_on.bsadd3w1.strip : ""),
"customer_city" => sign_on.bscityw1,
"customer_state" => sign_on.bsstcdw1,
"customer_zip" => sign_on.bszipw1,
"customer_contact" => sign_on.cntacw1}
Mailer.deliver_order_coastal_notify_email("Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
# Per Dana 6/30/2012, JUST DS
if sign_on.acctypw1.strip == "DS" or sign_on.acctypw1.strip == "DSD"
# If there is no distributor email address, the mailer model will substitute in the admin's email from their settings
Mailer.deliver_order_distributor_approval_email(distributor ? distributor.emailp1 : "", "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation #{approval0} #{approval1}", email_details)
if approval0!=""
Mailer.deliver_order_confirmation_email(login, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
Mailer.deliver_order_distributor_approval_email(approval0, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation ", email_details)
Mailer.deliver_order_coastal_notify_email("Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
end
if approval1!=""
Mailer.deliver_order_confirmation_email(login, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
Mailer.deliver_order_distributor_approval_email(approval1, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation ", email_details)
Mailer.deliver_order_coastal_notify_email("Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
end
if approval2!=""
Mailer.deliver_order_confirmation_email(login, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
Mailer.deliver_order_distributor_approval_email(approval2, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation ", email_details)
Mailer.deliver_order_coastal_notify_email("Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
end
if approval3!=""
Mailer.deliver_order_confirmation_email(login, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
Mailer.deliver_order_distributor_approval_email(approval3, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation ", email_details)
Mailer.deliver_order_coastal_notify_email("Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
end
if approval4!=""
Mailer.deliver_order_confirmation_email(login, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
Mailer.deliver_order_distributor_approval_email(approval4, "Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation ", email_details)
Mailer.deliver_order_coastal_notify_email("Coastal Pet Online Ordering<noreply#coastalpet.com>", "Order Confirmation", email_details)
end
Mailer.deliver_order_distributor_approval_email(weboel23 ? weboel23.emal23: "", "Coastal Pet Online Ordering<noreply#coastalpet.com>", "*Order Confirmation", email_details)
Mailer.deliver_order_distributor_approval_email("robert.kendall#coastalpet.com", "Coastal Pet Online Ordering<noreply#coastalpet.com>", "*Order Confirmation", email_details)
end
# Al ways notify Coastal staff
# Update the last ordered date (used for reminders)
User.update_last_order_date(login)
o.destroy
as400_order_id
end
end
end
end
def self.count_user_orders query_account_number, login
count = Order.first(:conditions => {:account_number => query_account_number, :login => login})
count.order_details.count unless count.blank? or count == 0
end
def self.reorder(order_number, login, query_account_number, upc_rule, price_code, mode)
warnings = ""
# If we are not in check mode, then blank out cart
self.empty_cart(query_account_number, login) if mode != "check"
# Get the previous order
oo = WebOrder.get_previous_order(order_number, login)
# Go through each line item
oo.each do |ooi|
# Verify it still exists in the AS400 and is same price
# Note that this reports back a -1 if it cannot find the
# same style+color+size option, otherwise just reports
# price if it finds it.
current_price = Item.check_item_exists(query_account_number, ooi[:style], ooi[:color], ooi[:size], upc_rule, price_code)
# If item was not found, we can't add it.
# We could spend more time to determine if it was the color, or size, or that
# the style itself is not available, but it seems reasonable enough to
# present it this way. Really should not be doing this "presentation" in
# the model, but we don't have views setup for Ajax so we have to give the
# controller the text we want rendered.
if current_price == -1
warnings += "SKU "+ ooi[:style].to_s + ooi[:color].to_s + ooi[:size].to_s + " is no longer available<br />"
else
# If price did not match, append to list of warnings
if current_price.to_f.round_to(2) != ooi[:price].to_f.round_to(2)
warnings += "SKU "+ ooi[:style].to_s + ooi[:color].to_s + ooi[:size].to_s + " price is " +
ActionController::Base.helpers.number_to_currency(current_price) + " and it was " +
ActionController::Base.helpers.number_to_currency(ooi[:price]) + "<br />"
end
# If not in check mode, add item to cart
# In this case, we don't care that the price did
# not match, we still add it.
populate_cart(query_account_number, login, ooi[:style], ooi[:color], ooi[:size], ooi[:quantity], ooi[:line_item_note], ooi[:order_note]) if mode != "check"
end
end
mode == "check" ? warnings : ""
end
def self.empty_cart query_account_number, login
order = Order.first(:conditions => {:account_number => query_account_number, :login => login})
order.destroy if order
end
def self.populate_cart query_account_number, login, style, color, size, quantity, note, order_note
# If there is not an order record, create one. Basically we only
# allow one open order per login at a time, and if there is
# one already, we continue to append order_detail records to it.
order = Order.first(:conditions => {:account_number => query_account_number, :login => login.upcase})
order = Order.add_order_header(query_account_number, login) if order.blank?
# These can be null for kits, and we don't like nulls in the database for this
color = "" if color.blank?
size = "" if size.blank?
if order
order.note = order_note # yeah we do this each time but while inefficient it works
order.save
order_detail = OrderDetail.new(:style => style,
:order_id => order.id,
:quantity => quantity,
:color => color,
:size => size,
:note => note)
order_detail.save
end
end
private
def self.add_order_header query_account_number, login
# Default address info to sign_on
sign_on = SignOn.first(:conditions => {:userw1 => login.upcase}, :select => "bsnamw1, bsadd1w1, bsadd2w1, bsadd3w1, bscityw1, bsstcdw1, bszipw1")
if sign_on
order = Order.new(:login => login,
:account_number => query_account_number,
:name => sign_on.bsnamw1,
:address1 => sign_on.bsadd1w1,
:address2 => sign_on.bsadd2w1,
:address3 => sign_on.bsadd3w1,
:city => sign_on.bscityw1,
:state => sign_on.bsstcdw1,
:zip => sign_on.bszipw1)
order.save
order
end
end
end

money-rails set custom currency

I am in a rails 3.2.6 app using the gems money and money-rails.
For money-rails I have set-up an initializer with this data:
MoneyRails.configure do |config|
config.default_currency = :eur
config.register_currency = {
:id => :euc,
:priority => 1,
:iso_code => "EUR",
:name => "Euro with Comma decimal mark",
:symbol => "€",
:symbol_first => true,
:subunit => "Cent",
:subunit_to_unit => 100,
:thousands_separator => ".",
:decimal_mark => ","
}
end
Note I have created a new currency :euc, because I want to display the euro currency with the comma decimal separator,
but the problem is the money object doesn't display yet the comma, for example:
amount = Money.new(100, 'EUR')
amount.to_s
or in a view:
<%= humanized_money amount %>
it display "1.00 instead of "1,00"
where am I doing wrong?
Try using amount.format(decimal_mark: ",") for now. It seems like a bug.
Try
100.to_money('EUR')
Money.new(100) considers 100 to be in cents.

String to Array and Hash with Regexp

I would like to turn a string with opening hours like this:
"Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
Into this:
[ {:period => "Monday-Friday", :hours => "10:00-18:00"}, {:period => "Saturday", :hours => "12:00-17:00"}, {:period => "Sunday", :hours => "12:00-15:00"} ]
I'm trying it with the String.scan() method but can't figure out the Regexp.
Also if you have any suggestions of how to do it in reverse the best way (i.e. when getting the opening hours from a form.)
Update - Thank you all found perfect solutions! Right now I'm using (thanks kejadlen):
str.scan(/([\w-]+)>([\d:-]+)-([\d:]+)/).map { |(p,o,c)| {:period => p, :opens => o, :closes => c} }
But now how about reversing it =) So given:
[ {:opens=>"10:00", :closes=>"18:00", :period=>"Monday-Friday"},
{:opens=>"12:00", :closes=>"17:00", :period=>"Saturday"},
{:opens=>"12:00", :closes=>"15:00", :period=>"Sunday"} ]
I want to merge it to:
"Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
If you prefer one-liners:
s = "Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
s.split(/;/).map{|i| Hash[[[:period, :hours], i.split(/>/)].transpose]}
# or
s.split(/;/).map{|i| p, h = i.split(/>/); {:period => p, :hours => h}}
#=> [{:period=>"Monday-Friday", :hours=>"10:00-18:00"}, {:period=>"Saturday", :hours=>"12:00-17:00"}, {:period=>"Sunday", :hours=>"12:00-15:00"}]
Edit:
Regarding the reverse, this should do the job:
a.map{|i| "#{i[:period]}>#{i[:opens]}-#{i[:closes]}"}.join(';')
=> "Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
this is how I would do it
str="Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
periods = str.split(';')
#=> ["Monday-Friday>10:00-18:00", "Saturday>12:00-17:00", "Sunday>12:00-15:00"]
period_array=[]
periods.each do |period|
period_with_hours = period.split('>')
period_array << {:period => period_with_hours.first, :hours => period_with_hours.last}
end
period_array
#=> [{:period=>"Monday-Friday", :hours=>"10:00-18:00"}, {:period=>"Saturday", :hours=>"12:00-17:00"}, {:period=>"Sunday", :hours=>"12:00-15:00"}]
Try this:
String S = ([^\>]*)\>([^\;]*)\;
String T = " {:period => $1, :hours => $2}, "
originalString.replaceAll(S,T);
Might have to play with the regexp a little more but that should about do it.
Edit - Well, you asked for the answer in the context of ruby and I gave you the Java answer but the regular expression should work anyway...
This looks like it works
the_input.split(';').collect{|pair|
period, hours = pair.split('>')
{:period => period, :hours => hours}
}
=> [{:hours=>"10:00-18:00", :period=>"Monday-Friday"}, {:hours=>"12:00-17:00", :
period=>"Saturday"}, {:hours=>"12:00-15:00", :period=>"Sunday"}]
str.scan(/([\w-]+)>([\d:-]+)/).map {|(p,h)| {:period => p, :hours => h }}

Resources