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
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 }}