spree_core 1.2.0 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. data/app/assets/javascripts/admin/admin.js.erb +10 -9
  2. data/app/assets/javascripts/admin/checkouts/edit.js +4 -4
  3. data/app/assets/javascripts/admin/product_autocomplete.js.erb +5 -5
  4. data/app/assets/javascripts/admin/taxon_autocomplete.js.erb +34 -0
  5. data/app/assets/javascripts/admin/taxonomy.js +11 -11
  6. data/app/assets/javascripts/store/cart.js.coffee +5 -2
  7. data/app/assets/javascripts/store/checkout.js.coffee +8 -4
  8. data/app/assets/stylesheets/admin/admin-form.css.erb +4 -0
  9. data/app/assets/stylesheets/store/screen.css.scss +1 -1
  10. data/app/controllers/spree/admin/banners_controller.rb +2 -2
  11. data/app/controllers/spree/admin/mail_methods_controller.rb +7 -0
  12. data/app/controllers/spree/admin/orders_controller.rb +3 -1
  13. data/app/controllers/spree/admin/payment_methods_controller.rb +7 -1
  14. data/app/controllers/spree/admin/products_controller.rb +11 -6
  15. data/app/controllers/spree/admin/prototypes_controller.rb +1 -1
  16. data/app/controllers/spree/admin/search_controller.rb +11 -31
  17. data/app/controllers/spree/admin/taxons_controller.rb +8 -0
  18. data/app/controllers/spree/checkout_controller.rb +7 -1
  19. data/app/controllers/spree/home_controller.rb +1 -0
  20. data/app/controllers/spree/orders_controller.rb +18 -5
  21. data/app/controllers/spree/products_controller.rb +1 -0
  22. data/app/controllers/spree/taxons_controller.rb +1 -0
  23. data/app/helpers/spree/admin/general_settings_helper.rb +1 -1
  24. data/app/helpers/spree/base_helper.rb +1 -1
  25. data/app/models/spree/ability.rb +5 -0
  26. data/app/models/spree/app_configuration.rb +1 -0
  27. data/app/models/spree/calculator/price_sack.rb +5 -3
  28. data/app/models/spree/credit_card.rb +2 -2
  29. data/app/models/spree/image.rb +2 -1
  30. data/app/models/spree/inventory_unit.rb +11 -3
  31. data/app/models/spree/line_item.rb +3 -2
  32. data/app/models/spree/order.rb +52 -9
  33. data/app/models/spree/order/checkout.rb +5 -8
  34. data/app/models/spree/payment.rb +1 -1
  35. data/app/models/spree/payment/processing.rb +21 -16
  36. data/app/models/spree/payment_method.rb +1 -1
  37. data/app/models/spree/preference.rb +1 -1
  38. data/app/models/spree/preferences/preferable_class_methods.rb +2 -0
  39. data/app/models/spree/preferences/store.rb +20 -2
  40. data/app/models/spree/product.rb +16 -0
  41. data/app/models/spree/product/scopes.rb +19 -8
  42. data/app/models/spree/return_authorization.rb +1 -0
  43. data/app/models/spree/shipment.rb +6 -4
  44. data/app/models/spree/shipping_method.rb +5 -6
  45. data/app/models/spree/tax_rate.rb +4 -2
  46. data/app/models/spree/taxon.rb +7 -0
  47. data/app/models/spree/variant.rb +26 -15
  48. data/app/views/spree/admin/banners/_gateway.html.erb +14 -0
  49. data/app/views/spree/admin/general_settings/edit.html.erb +13 -4
  50. data/app/views/spree/admin/orders/_form.html.erb +1 -1
  51. data/app/views/spree/admin/orders/customer_details/_form.html.erb +1 -1
  52. data/app/views/spree/admin/product_properties/index.html.erb +1 -1
  53. data/app/views/spree/admin/products/_form.html.erb +7 -8
  54. data/app/views/spree/admin/products/new.html.erb +1 -1
  55. data/app/views/spree/admin/return_authorizations/_form.html.erb +17 -33
  56. data/app/views/spree/admin/search/users.rabl +32 -0
  57. data/app/views/spree/admin/shared/_head.html.erb +3 -13
  58. data/app/views/spree/admin/shared/_routes.html.erb +8 -0
  59. data/app/views/spree/admin/shared/_translations.html.erb +26 -0
  60. data/app/views/spree/admin/tax_rates/_form.html.erb +8 -0
  61. data/app/views/spree/admin/tax_rates/index.html.erb +5 -1
  62. data/app/views/spree/admin/taxonomies/edit.erb +2 -2
  63. data/app/views/spree/admin/taxonomies/get_children.json.erb +1 -1
  64. data/app/views/spree/admin/taxons/search.rabl +5 -0
  65. data/app/views/spree/checkout/_confirm.html.erb +1 -0
  66. data/app/views/spree/checkout/payment/_gateway.html.erb +1 -1
  67. data/app/views/spree/orders/_adjustments.html.erb +1 -1
  68. data/app/views/spree/orders/edit.html.erb +3 -1
  69. data/app/views/spree/products/_cart_form.html.erb +3 -3
  70. data/app/views/spree/products/_thumbnails.html.erb +1 -1
  71. data/app/views/spree/shared/_head.html.erb +0 -2
  72. data/app/views/spree/shared/_order_details.html.erb +2 -2
  73. data/app/views/spree/shared/_products.html.erb +1 -1
  74. data/app/views/spree/shared/_taxonomies.html.erb +1 -1
  75. data/app/views/spree/shipment_mailer/shipped_email.text.erb +1 -1
  76. data/config/initializers/check_for_orphaned_preferences.rb +1 -1
  77. data/config/initializers/rails_5868.rb +8 -0
  78. data/config/locales/en.yml +4 -0
  79. data/config/routes.rb +13 -0
  80. data/db/default/spree/countries.yml +6 -0
  81. data/db/migrate/20120905145253_add_tax_rate_label.rb +5 -0
  82. data/db/migrate/20120905151823_add_toggle_tax_rate_display.rb +5 -0
  83. data/db/migrate/20121009142519_add_lock_version_to_variant.rb +5 -0
  84. data/db/migrate/20121017010007_remove_not_null_constraint_from_products_on_hand.rb +11 -0
  85. data/lib/generators/spree/custom_user/custom_user_generator.rb +4 -1
  86. data/lib/spree/core.rb +3 -2
  87. data/lib/spree/core/mail_settings.rb +2 -1
  88. data/lib/spree/core/permalinks.rb +1 -2
  89. data/lib/spree/core/search/base.rb +1 -0
  90. data/lib/spree/core/testing_support/authorization_helpers.rb +30 -0
  91. data/lib/spree/core/testing_support/factories/product_factory.rb +1 -1
  92. data/lib/spree/core/testing_support/flash.rb +17 -0
  93. data/lib/spree/core/testing_support/preferences.rb +26 -0
  94. data/lib/spree/core/version.rb +1 -1
  95. data/lib/spree/money.rb +4 -1
  96. metadata +69 -46
  97. data/config/initializers/workarounds_for_ruby19.rb +0 -72
  98. data/lib/spree/core/testing_support/env.rb +0 -2
@@ -5,6 +5,7 @@ module Spree
5
5
 
6
6
  def index
7
7
  @searcher = Spree::Config.searcher_class.new(params)
8
+ @searcher.current_user = try_spree_current_user
8
9
  @products = @searcher.retrieve_products
9
10
  respond_with(@products)
10
11
  end
@@ -1,5 +1,7 @@
1
1
  module Spree
2
2
  class OrdersController < BaseController
3
+ ssl_required :show
4
+
3
5
  rescue_from ActiveRecord::RecordNotFound, :with => :render_404
4
6
  helper 'spree/products'
5
7
 
@@ -13,9 +15,18 @@ module Spree
13
15
  def update
14
16
  @order = current_order
15
17
  if @order.update_attributes(params[:order])
16
- @order.line_items = @order.line_items.select {|li| li.quantity > 0 }
18
+ @order.line_items = @order.line_items.select { |li| li.quantity > 0 }
17
19
  fire_event('spree.order.contents_changed')
18
- respond_with(@order) { |format| format.html { redirect_to cart_path } }
20
+ respond_with(@order) do |format|
21
+ format.html do
22
+ if params.has_key?(:checkout)
23
+ @order.next_transition.run_callbacks
24
+ redirect_to checkout_state_path(@order.checkout_steps.first)
25
+ else
26
+ redirect_to cart_path
27
+ end
28
+ end
29
+ end
19
30
  else
20
31
  respond_with(@order)
21
32
  end
@@ -64,8 +75,10 @@ module Spree
64
75
  redirect_to spree.cart_path
65
76
  end
66
77
 
67
- def accurate_titles
68
- @order && @order.completed? ? "#{Order.model_name.human} #{@order.number}" : t(:shopping_cart)
69
- end
78
+ private
79
+
80
+ def accurate_title
81
+ @order && @order.completed? ? "#{Order.model_name.human} #{@order.number}" : t(:shopping_cart)
82
+ end
70
83
  end
71
84
  end
@@ -8,6 +8,7 @@ module Spree
8
8
 
9
9
  def index
10
10
  @searcher = Config.searcher_class.new(params)
11
+ @searcher.current_user = try_spree_current_user
11
12
  @products = @searcher.retrieve_products
12
13
  respond_with(@products)
13
14
  end
@@ -10,6 +10,7 @@ module Spree
10
10
  return unless @taxon
11
11
 
12
12
  @searcher = Spree::Config.searcher_class.new(params.merge(:taxon => @taxon.id))
13
+ @searcher.current_user = try_spree_current_user
13
14
  @products = @searcher.retrieve_products
14
15
 
15
16
  respond_with(@taxon)
@@ -6,7 +6,7 @@ module Spree
6
6
  iso = details[:iso_code]
7
7
  [iso, "#{details[:name]} (#{iso})"]
8
8
  end
9
- options_from_collection_for_select(currencies, :first, :last)
9
+ options_from_collection_for_select(currencies, :first, :last, Spree::Config[:currency])
10
10
  end
11
11
  end
12
12
  end
@@ -87,7 +87,7 @@ module Spree
87
87
  end
88
88
 
89
89
  def flash_messages(opts = {})
90
- opts[:ignore_types] = [:commerce_tracking].concat(opts[:ignore_types] || [])
90
+ opts[:ignore_types] = [:commerce_tracking].concat(Array(opts[:ignore_types]) || [])
91
91
 
92
92
  flash.each do |msg_type, text|
93
93
  unless opts[:ignore_types].include?(msg_type)
@@ -51,6 +51,11 @@ module Spree
51
51
  order.user == user || order.token && token == order.token
52
52
  end
53
53
  can :create, Order
54
+
55
+ can :read, Address do |address|
56
+ address.user == user
57
+ end
58
+
54
59
  #############################
55
60
  can :read, Product
56
61
  can :index, Product
@@ -42,6 +42,7 @@ module Spree
42
42
  preference :company, :boolean, :default => false # Request company field for billing and shipping addr
43
43
  preference :create_inventory_units, :boolean, :default => true # should only be false when track_inventory_levels is false, also disables RMA's
44
44
  preference :currency, :string, :default => "USD"
45
+ preference :currency_symbol_position, :string, :default => "before"
45
46
  preference :display_currency, :boolean, :default => false
46
47
  preference :default_country_id, :integer, :default => 214
47
48
  preference :default_locale, :string, :default => Rails.application.config.i18n.default_locale || :en
@@ -1,4 +1,6 @@
1
1
  require_dependency 'spree/calculator'
2
+ # For #to_d method on Ruby 1.8
3
+ require 'bigdecimal/util'
2
4
 
3
5
  module Spree
4
6
  class Calculator::PriceSack < Calculator
@@ -17,12 +19,12 @@ module Spree
17
19
  # as object we always get line items, as calculable we have Coupon, ShippingMethod
18
20
  def compute(object)
19
21
  if object.is_a?(Array)
20
- base = object.map { |o| o.respond_to?(:amount) ? o.amount : o.to_d }.sum
22
+ base = object.map { |o| o.respond_to?(:amount) ? o.amount : BigDecimal(o.to_s) }.sum
21
23
  else
22
- base = object.respond_to?(:amount) ? object.amount : object.to_d
24
+ base = object.respond_to?(:amount) ? object.amount : BigDecimal(object.to_s)
23
25
  end
24
26
 
25
- if base >= self.preferred_minimal_amount
27
+ if base < self.preferred_minimal_amount
26
28
  self.preferred_normal_amount
27
29
  else
28
30
  self.preferred_discount_amount
@@ -1,6 +1,6 @@
1
1
  module Spree
2
2
  class CreditCard < ActiveRecord::Base
3
- has_many :payments
3
+ has_many :payments, :as => :source
4
4
 
5
5
  before_save :set_last_digits
6
6
  after_validation :set_card_type
@@ -63,7 +63,7 @@ module Spree
63
63
  cc_type
64
64
  end
65
65
 
66
- scope :with_payment_profile, where('gateway_customer_profile_id IS NOT NULL')
66
+ scope :with_payment_profile, lambda { where('gateway_customer_profile_id IS NOT NULL') }
67
67
 
68
68
  def actions
69
69
  %w{capture void credit}
@@ -9,7 +9,8 @@ module Spree
9
9
  :styles => { :mini => '48x48>', :small => '100x100>', :product => '240x240>', :large => '600x600>' },
10
10
  :default_style => :product,
11
11
  :url => '/spree/products/:id/:style/:basename.:extension',
12
- :path => ':rails_root/public/spree/products/:id/:style/:basename.:extension'
12
+ :path => ':rails_root/public/spree/products/:id/:style/:basename.:extension',
13
+ :convert_options => { :all => '-strip' }
13
14
  # save the w,h of the original image (from which others can be calculated)
14
15
  # we need to look at the write-queue for images which have not been saved yet
15
16
  after_post_process :find_dimensions
@@ -5,7 +5,13 @@ module Spree
5
5
  belongs_to :shipment
6
6
  belongs_to :return_authorization
7
7
 
8
- scope :backorder, where(:state => 'backordered')
8
+ scope :backordered, lambda { where(:state => 'backordered') }
9
+ scope :shipped, lambda { where(:state => 'shipped') }
10
+
11
+ def self.backorder
12
+ warn "[SPREE] Spree::InventoryUnit.backorder will be deprecated in Spree 1.3. Please use Spree::Product.backordered instead."
13
+ backordered
14
+ end
9
15
 
10
16
  attr_accessible :shipment
11
17
 
@@ -107,8 +113,10 @@ module Spree
107
113
  end
108
114
 
109
115
  def restock_variant
110
- variant.on_hand += 1
111
- variant.save
116
+ if Spree::Config[:track_inventory_levels]
117
+ variant.on_hand += 1
118
+ variant.save
119
+ end
112
120
  end
113
121
  end
114
122
  end
@@ -10,7 +10,7 @@ module Spree
10
10
  before_validation :copy_price
11
11
 
12
12
  validates :variant, :presence => true
13
- validates :quantity, :numericality => { :only_integer => true, :message => I18n.t('validation.must_be_int') }
13
+ validates :quantity, :numericality => { :only_integer => true, :message => I18n.t('validation.must_be_int'), :greater_than => -1 }
14
14
  validates :price, :numericality => true
15
15
  validate :stock_availability
16
16
  validate :quantity_no_less_than_shipped
@@ -80,6 +80,7 @@ module Spree
80
80
 
81
81
  def update_order
82
82
  # update the order totals, etc.
83
+ order.create_tax_charge!
83
84
  order.update!
84
85
  end
85
86
 
@@ -97,7 +98,7 @@ module Spree
97
98
  end
98
99
 
99
100
  def quantity_no_less_than_shipped
100
- already_shipped = order.shipments.reduce(0) { |acc,s| acc + s.inventory_units.select { |i| i.variant == variant }.count }
101
+ already_shipped = order.shipments.reduce(0) { |acc, s| acc + s.inventory_units.shipped.where(:variant_id => variant_id).count }
101
102
  unless quantity >= already_shipped
102
103
  errors.add(:quantity, I18n.t('validation.cannot_be_less_than_shipped_units'))
103
104
  end
@@ -63,7 +63,6 @@ module Spree
63
63
  before_create :link_by_email
64
64
  after_create :create_tax_charge!
65
65
 
66
- # TODO: validate the format of the email as well (but we can't rely on authlogic anymore to help with validation)
67
66
  validates :email, :presence => true, :email => true, :if => :require_email
68
67
  validate :has_available_shipment
69
68
  validate :has_available_payment
@@ -128,6 +127,7 @@ module Spree
128
127
 
129
128
  # Is this a free order in which case the payment step should be skipped
130
129
  def payment_required?
130
+ update_totals
131
131
  total.to_f > 0.0
132
132
  end
133
133
 
@@ -144,7 +144,7 @@ module Spree
144
144
  # Indicates whether there are any backordered InventoryUnits associated with the Order.
145
145
  def backordered?
146
146
  return false unless Spree::Config[:track_inventory_levels]
147
- inventory_units.backorder.present?
147
+ inventory_units.backordered.present?
148
148
  end
149
149
 
150
150
  # Returns the relevant zone (if any) to be used for taxation purposes. Uses default tax zone
@@ -230,7 +230,7 @@ module Spree
230
230
 
231
231
  def allow_cancel?
232
232
  return false unless completed? and state != 'canceled'
233
- %w{ready backorder pending}.include? shipment_state
233
+ shipment_state.nil? || %w{ready backorder pending}.include?(shipment_state)
234
234
  end
235
235
 
236
236
  def allow_resume?
@@ -239,6 +239,10 @@ module Spree
239
239
  true
240
240
  end
241
241
 
242
+ def awaiting_returns?
243
+ return_authorizations.any? { |return_authorization| return_authorization.authorized? }
244
+ end
245
+
242
246
  def add_variant(variant, quantity = 1)
243
247
  current_item = find_line_item_by_variant(variant)
244
248
  if current_item
@@ -350,8 +354,16 @@ module Spree
350
354
  def finalize!
351
355
  touch :completed_at
352
356
  InventoryUnit.assign_opening_inventory(self)
353
- # lock any optional adjustments (coupon promotions, etc.)
354
- adjustments.optional.each { |adjustment| adjustment.update_column('locked', true) }
357
+
358
+ # lock all adjustments (coupon promotions, etc.)
359
+ adjustments.each { |adjustment| adjustment.update_column('locked', true) }
360
+
361
+ # update payment and shipment(s) states, and save
362
+ update_payment_state
363
+ shipments.each { |shipment| shipment.update!(self) }
364
+ update_shipment_state
365
+ save
366
+
355
367
  deliver_order_confirmation_email
356
368
 
357
369
  self.state_changes.create({
@@ -379,8 +391,23 @@ module Spree
379
391
  end
380
392
 
381
393
  def rate_hash
382
- @rate_hash ||= available_shipping_methods(:front_end).collect do |ship_method|
383
- next unless cost = ship_method.calculator.compute(self)
394
+ return @rate_hash if @rate_hash.present?
395
+
396
+ # reserve one slot for each shipping method computation
397
+ computed_costs = Array.new(available_shipping_methods(:front_end).size)
398
+
399
+ # create all the threads and kick off their execution
400
+ threads = available_shipping_methods(:front_end).each_with_index.map do |ship_method, index|
401
+ Thread.new { computed_costs[index] = [ship_method, ship_method.calculator.compute(self)] }
402
+ end
403
+
404
+ # wait for all threads to finish
405
+ threads.map(&:join)
406
+
407
+ # now consolidate and memoize the threaded results
408
+ @rate_hash ||= computed_costs.map do |pair|
409
+ ship_method,cost = *pair
410
+ next unless cost
384
411
  ShippingRate.new( :id => ship_method.id,
385
412
  :shipping_method => ship_method,
386
413
  :name => ship_method.name,
@@ -408,9 +435,21 @@ module Spree
408
435
  end
409
436
  end
410
437
 
438
+ def pending_payments
439
+ payments.select {|p| p.state == "checkout"}
440
+ end
441
+
411
442
  def process_payments!
412
443
  begin
413
- payments.each(&:process!)
444
+ pending_payments.each do |payment|
445
+ break if payment_total >= total
446
+
447
+ payment.process!
448
+
449
+ if payment.completed?
450
+ self.payment_total += payment.amount
451
+ end
452
+ end
414
453
  rescue Core::GatewayError
415
454
  !!Spree::Config[:allow_checkout_on_gateway_error]
416
455
  end
@@ -428,6 +467,10 @@ module Spree
428
467
  line_items.map { |li| li.variant.product }
429
468
  end
430
469
 
470
+ def variants
471
+ line_items.map(&:variant)
472
+ end
473
+
431
474
  def insufficient_stock_lines
432
475
  line_items.select &:insufficient_stock?
433
476
  end
@@ -505,7 +548,7 @@ module Spree
505
548
  #
506
549
  # The +payment_state+ value helps with reporting, etc. since it provides a quick and easy way to locate Orders needing attention.
507
550
  def update_payment_state
508
-
551
+
509
552
  #line_item are empty when user empties cart
510
553
  if self.line_items.empty? || round_money(payment_total) < round_money(total)
511
554
  self.payment_state = 'balance_due'
@@ -51,7 +51,7 @@ module Spree
51
51
  end
52
52
 
53
53
  event :return do
54
- transition :to => :returned, :from => :awaiting_return
54
+ transition :to => :returned, :from => :awaiting_return, :unless => :awaiting_returns?
55
55
  end
56
56
 
57
57
  event :resume do
@@ -64,7 +64,7 @@ module Spree
64
64
 
65
65
  before_transition :to => :complete do |order|
66
66
  begin
67
- order.process_payments!
67
+ order.process_payments! if order.payment_required?
68
68
  rescue Spree::Core::GatewayError
69
69
  !!Spree::Config[:allow_checkout_on_gateway_error]
70
70
  end
@@ -83,15 +83,12 @@ module Spree
83
83
 
84
84
  def self.go_to_state(name, options={})
85
85
  self.checkout_steps[name] = options
86
+ previous_states.each do |state|
87
+ add_transition({:from => state, :to => name}.merge(options))
88
+ end
86
89
  if options[:if]
87
- previous_states.each do |state|
88
- add_transition({:from => state, :to => name}.merge(options))
89
- end
90
90
  self.previous_states << name
91
91
  else
92
- previous_states.each do |state|
93
- add_transition({:from => state, :to => name}.merge(options))
94
- end
95
92
  self.previous_states = [name]
96
93
  end
97
94
  end
@@ -18,7 +18,7 @@ module Spree
18
18
 
19
19
  attr_accessible :amount, :payment_method_id, :source_attributes
20
20
 
21
- scope :from_credit_card, where(:source_type => 'Spree::CreditCard')
21
+ scope :from_credit_card, lambda { where(:source_type => 'Spree::CreditCard') }
22
22
  scope :with_state, lambda { |s| where(:state => s) }
23
23
  scope :completed, with_state('completed')
24
24
  scope :pending, with_state('pending')
@@ -28,6 +28,7 @@ module Spree
28
28
  end
29
29
 
30
30
  def capture!
31
+ return true if completed?
31
32
  protect_from_connection_error do
32
33
  check_environment
33
34
 
@@ -47,6 +48,7 @@ module Spree
47
48
  end
48
49
 
49
50
  def void_transaction!
51
+ return true if void?
50
52
  protect_from_connection_error do
51
53
  check_environment
52
54
 
@@ -104,6 +106,25 @@ module Spree
104
106
  credit!(amount)
105
107
  end
106
108
 
109
+ def gateway_options
110
+ options = { :email => order.email,
111
+ :customer => order.email,
112
+ :ip => '192.168.1.100', # TODO: Use an actual IP
113
+ :order_id => order.number }
114
+
115
+ options.merge!({ :shipping => order.ship_total * 100,
116
+ :tax => order.tax_total * 100,
117
+ :subtotal => order.item_total * 100 })
118
+
119
+ options.merge!({ :currency => payment_method.preferences[:currency_code] }) if payment_method && payment_method.preferences[:currency_code]
120
+
121
+ options.merge!({ :billing_address => order.bill_address.try(:active_merchant_hash),
122
+ :shipping_address => order.ship_address.try(:active_merchant_hash) })
123
+
124
+ options.merge!(:discount => promo_total) if respond_to?(:promo_total)
125
+ options
126
+ end
127
+
107
128
  private
108
129
 
109
130
  def gateway_action(source, action, success_state)
@@ -136,22 +157,6 @@ module Spree
136
157
  log_entries.create({:details => response.to_yaml}, :without_protection => true)
137
158
  end
138
159
 
139
- def gateway_options
140
- options = { :email => order.email,
141
- :customer => order.email,
142
- :ip => '192.168.1.100', # TODO: Use an actual IP
143
- :order_id => order.number }
144
-
145
- options.merge!({ :shipping => order.ship_total * 100,
146
- :tax => order.tax_total * 100,
147
- :subtotal => order.item_total * 100 })
148
-
149
- options.merge!({ :currency => payment_method.preferences[:currency_code] }) if payment_method && payment_method.preferences[:currency_code]
150
-
151
- options.merge({ :billing_address => order.bill_address.try(:active_merchant_hash),
152
- :shipping_address => order.ship_address.try(:active_merchant_hash) })
153
- end
154
-
155
160
  def protect_from_connection_error
156
161
  begin
157
162
  yield