spree_core 2.2.14 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/{spree.js.coffee → spree.js.coffee.erb} +11 -2
  3. data/app/controllers/spree/base_controller.rb +1 -0
  4. data/app/helpers/spree/base_helper.rb +5 -6
  5. data/app/helpers/spree/orders_helper.rb +4 -0
  6. data/app/helpers/spree/products_helper.rb +8 -7
  7. data/app/mailers/spree/base_mailer.rb +2 -2
  8. data/app/mailers/spree/order_mailer.rb +2 -2
  9. data/app/mailers/spree/shipment_mailer.rb +1 -1
  10. data/app/mailers/spree/test_mailer.rb +1 -1
  11. data/app/models/spree/ability.rb +15 -16
  12. data/app/models/spree/address.rb +3 -6
  13. data/app/models/spree/adjustment.rb +2 -2
  14. data/app/models/spree/alert.rb +1 -1
  15. data/app/models/spree/app_configuration.rb +17 -20
  16. data/app/models/spree/asset.rb +2 -2
  17. data/app/models/spree/base.rb +9 -0
  18. data/app/models/spree/calculator.rb +1 -1
  19. data/app/models/spree/calculator/flat_rate.rb +1 -1
  20. data/app/models/spree/calculator/flexi_rate.rb +1 -1
  21. data/app/models/spree/calculator/price_sack.rb +1 -3
  22. data/app/models/spree/calculator/shipping/flat_rate.rb +1 -1
  23. data/app/models/spree/calculator/shipping/flexi_rate.rb +1 -1
  24. data/app/models/spree/calculator/shipping/per_item.rb +1 -1
  25. data/app/models/spree/calculator/shipping/price_sack.rb +1 -3
  26. data/app/models/spree/classification.rb +1 -1
  27. data/app/models/spree/configuration.rb +1 -1
  28. data/app/models/spree/country.rb +1 -1
  29. data/app/models/spree/credit_card.rb +8 -12
  30. data/app/models/spree/gateway.rb +0 -3
  31. data/app/models/spree/gateway/bogus.rb +2 -3
  32. data/app/models/spree/image.rb +3 -1
  33. data/app/models/spree/inventory_unit.rb +5 -6
  34. data/app/models/spree/item_adjustments.rb +3 -4
  35. data/app/models/spree/legacy_user.rb +1 -1
  36. data/app/models/spree/line_item.rb +6 -13
  37. data/app/models/spree/log_entry.rb +1 -1
  38. data/app/models/spree/option_type.rb +1 -1
  39. data/app/models/spree/option_value.rb +1 -3
  40. data/app/models/spree/order.rb +52 -70
  41. data/app/models/spree/order/checkout.rb +17 -10
  42. data/app/models/spree/order/currency_updater.rb +1 -1
  43. data/app/models/spree/order_contents.rb +7 -4
  44. data/app/models/spree/order_populator.rb +1 -1
  45. data/app/models/spree/order_updater.rb +8 -21
  46. data/app/models/spree/payment.rb +26 -12
  47. data/app/models/spree/payment/processing.rb +5 -16
  48. data/app/models/spree/payment_capture_event.rb +1 -1
  49. data/app/models/spree/payment_method.rb +2 -2
  50. data/app/models/spree/payment_method/check.rb +0 -2
  51. data/app/models/spree/preference.rb +1 -31
  52. data/app/models/spree/preferences/configuration.rb +2 -6
  53. data/app/models/spree/preferences/preferable.rb +46 -74
  54. data/app/models/spree/preferences/preferable_class_methods.rb +11 -46
  55. data/app/models/spree/preferences/scoped_store.rb +33 -0
  56. data/app/models/spree/preferences/store.rb +8 -7
  57. data/app/models/spree/price.rb +1 -3
  58. data/app/models/spree/product.rb +59 -87
  59. data/app/models/spree/product/scopes.rb +22 -13
  60. data/app/models/spree/product_option_type.rb +1 -1
  61. data/app/models/spree/product_property.rb +1 -3
  62. data/app/models/spree/product_scope/scopes.rb +1 -1
  63. data/app/models/spree/promotion.rb +4 -5
  64. data/app/models/spree/promotion/actions/create_adjustment.rb +11 -2
  65. data/app/models/spree/promotion/actions/create_item_adjustments.rb +19 -2
  66. data/app/models/spree/promotion/actions/create_line_items.rb +2 -12
  67. data/app/models/spree/promotion/rules/user.rb +5 -1
  68. data/app/models/spree/promotion_action.rb +1 -1
  69. data/app/models/spree/promotion_action_line_item.rb +1 -1
  70. data/app/models/spree/promotion_handler/cart.rb +2 -14
  71. data/app/models/spree/promotion_handler/coupon.rb +3 -13
  72. data/app/models/spree/promotion_rule.rb +1 -1
  73. data/app/models/spree/property.rb +1 -3
  74. data/app/models/spree/prototype.rb +1 -1
  75. data/app/models/spree/return_authorization.rb +4 -10
  76. data/app/models/spree/role.rb +1 -1
  77. data/app/models/spree/shipment.rb +1 -9
  78. data/app/models/spree/shipping_category.rb +3 -3
  79. data/app/models/spree/shipping_method.rb +1 -1
  80. data/app/models/spree/shipping_method_category.rb +2 -2
  81. data/app/models/spree/shipping_rate.rb +3 -3
  82. data/app/models/spree/state.rb +1 -1
  83. data/app/models/spree/state_change.rb +1 -1
  84. data/app/models/spree/stock/availability_validator.rb +7 -3
  85. data/app/models/spree/stock/package.rb +0 -23
  86. data/app/models/spree/stock/splitter/backordered.rb +1 -1
  87. data/app/models/spree/stock/splitter/shipping_category.rb +1 -1
  88. data/app/models/spree/stock/splitter/weight.rb +1 -1
  89. data/app/models/spree/stock_item.rb +7 -10
  90. data/app/models/spree/stock_location.rb +2 -6
  91. data/app/models/spree/stock_movement.rb +1 -3
  92. data/app/models/spree/stock_transfer.rb +1 -3
  93. data/app/models/spree/store.rb +33 -0
  94. data/app/models/spree/tax_category.rb +2 -2
  95. data/app/models/spree/tax_rate.rb +21 -52
  96. data/app/models/spree/taxon.rb +9 -8
  97. data/app/models/spree/taxonomy.rb +1 -1
  98. data/app/models/spree/tracker.rb +1 -1
  99. data/app/models/spree/variant.rb +13 -15
  100. data/app/models/spree/variant/scopes.rb +1 -1
  101. data/app/models/spree/zone.rb +22 -22
  102. data/app/models/spree/zone_member.rb +2 -2
  103. data/config/initializers/user_class_extensions.rb +0 -8
  104. data/config/locales/en.yml +7 -42
  105. data/db/default/spree/countries.rb +2 -3
  106. data/db/default/spree/stores.rb +9 -0
  107. data/db/migrate/20130611054351_rename_shipping_methods_zones_to_spree_shipping_methods_zones.rb +0 -5
  108. data/db/migrate/20130807024301_upgrade_adjustments.rb +4 -5
  109. data/db/migrate/20130807024302_rename_adjustment_fields.rb +5 -2
  110. data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +1 -1
  111. data/db/migrate/20140106065820_remove_value_type_from_spree_preferences.rb +8 -0
  112. data/db/migrate/20140227112348_add_preference_store_to_everything.rb +8 -0
  113. data/db/migrate/20140309023735_migrate_old_preferences.rb +23 -0
  114. data/db/migrate/20140309024355_create_spree_stores.rb +25 -0
  115. data/db/migrate/20140309033438_create_store_from_preferences.rb +30 -0
  116. data/db/migrate/20140315053743_add_timestamps_to_spree_assets.rb +6 -0
  117. data/db/migrate/20140331100557_add_additional_store_fields.rb +8 -0
  118. data/db/migrate/20140410141842_add_many_missing_indexes.rb +18 -0
  119. data/db/migrate/20140410150358_correct_some_polymorphic_index_and_add_more_missing.rb +66 -0
  120. data/db/migrate/20140508151342_change_spree_price_amount_precision.rb +1 -1
  121. data/db/migrate/20140518174634_add_token_to_spree_orders.rb +5 -0
  122. data/db/migrate/20140530024945_move_order_token_from_tokenized_permission.rb +29 -0
  123. data/db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb +5 -3
  124. data/db/migrate/20140604135309_drop_credit_card_first_name_and_last_name.rb +6 -0
  125. data/lib/generators/spree/dummy/dummy_generator.rb +1 -0
  126. data/lib/generators/spree/dummy/templates/initializers/devise.rb +3 -0
  127. data/lib/generators/spree/dummy/templates/rails/routes.rb +0 -1
  128. data/lib/generators/spree/install/install_generator.rb +8 -17
  129. data/lib/generators/spree/install/templates/config/initializers/spree.rb +2 -2
  130. data/lib/spree/core.rb +13 -9
  131. data/lib/spree/core/calculated_adjustments.rb +1 -1
  132. data/lib/spree/core/controller_helpers/auth.rb +27 -18
  133. data/lib/spree/core/controller_helpers/common.rb +2 -2
  134. data/lib/spree/core/controller_helpers/order.rb +15 -24
  135. data/lib/spree/core/controller_helpers/store.rb +19 -0
  136. data/lib/spree/core/delegate_belongs_to.rb +2 -2
  137. data/lib/spree/core/engine.rb +0 -10
  138. data/lib/spree/core/importer.rb +1 -0
  139. data/lib/spree/core/importer/order.rb +16 -44
  140. data/lib/spree/core/importer/product.rb +62 -0
  141. data/lib/spree/core/product_filters.rb +0 -4
  142. data/lib/spree/core/routes.rb +4 -6
  143. data/lib/spree/core/validators/email.rb +23 -1
  144. data/lib/spree/core/version.rb +1 -1
  145. data/lib/spree/money.rb +1 -169
  146. data/lib/spree/permitted_attributes.rb +6 -4
  147. data/lib/spree/testing_support/authorization_helpers.rb +23 -21
  148. data/lib/spree/testing_support/capybara_ext.rb +11 -21
  149. data/lib/spree/testing_support/common_rake.rb +3 -1
  150. data/lib/spree/testing_support/controller_requests.rb +0 -2
  151. data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
  152. data/lib/spree/testing_support/factories/line_item_factory.rb +4 -1
  153. data/lib/spree/testing_support/factories/order_factory.rb +5 -4
  154. data/lib/spree/testing_support/factories/product_factory.rb +0 -4
  155. data/lib/spree/testing_support/factories/promotion_factory.rb +5 -7
  156. data/lib/spree/testing_support/factories/shipment_factory.rb +0 -1
  157. data/lib/spree/testing_support/factories/stock_factory.rb +2 -2
  158. data/lib/spree/testing_support/factories/store_factory.rb +8 -0
  159. data/lib/spree/testing_support/preferences.rb +3 -3
  160. data/lib/tasks/core.rake +2 -2
  161. metadata +48 -39
  162. data/app/models/spree/stock/order_counter.rb +0 -55
  163. data/app/models/spree/tokenized_permission.rb +0 -6
  164. data/app/views/spree/shared/_routes.html.erb +0 -13
  165. data/db/migrate/20140804185157_add_default_to_shipment_cost.rb +0 -10
  166. data/db/migrate/20141021194502_add_state_lock_version_to_order.rb +0 -5
  167. data/lib/spree/core/adjustment_source.rb +0 -26
  168. data/lib/spree/core/mail_interceptor.rb +0 -22
  169. data/lib/spree/core/mail_method.rb +0 -27
  170. data/lib/spree/core/mail_settings.rb +0 -55
  171. data/lib/spree/core/ransackable_attributes.rb +0 -15
  172. data/lib/spree/core/token_resource.rb +0 -27
@@ -1,6 +1,4 @@
1
1
  require_dependency 'spree/shipping_calculator'
2
- # For #to_d method on Ruby 1.8
3
- require 'bigdecimal/util'
4
2
 
5
3
  module Spree
6
4
  module Calculator::Shipping
@@ -8,7 +6,7 @@ module Spree
8
6
  preference :minimal_amount, :decimal, default: 0
9
7
  preference :normal_amount, :decimal, default: 0
10
8
  preference :discount_amount, :decimal, default: 0
11
- preference :currency, :string, default: Spree::Config[:currency]
9
+ preference :currency, :string, default: ->{ Spree::Config[:currency] }
12
10
 
13
11
  def self.description
14
12
  Spree.t(:shipping_price_sack)
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class Classification < ActiveRecord::Base
2
+ class Classification < Spree::Base
3
3
  self.table_name = 'spree_products_taxons'
4
4
  acts_as_list
5
5
  belongs_to :product, class_name: "Spree::Product", inverse_of: :classifications
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class Configuration < ActiveRecord::Base
2
+ class Configuration < Spree::Base
3
3
 
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class Country < ActiveRecord::Base
2
+ class Country < Spree::Base
3
3
  has_many :states, -> { order('name ASC') }, dependent: :destroy
4
4
  has_many :addresses, dependent: :nullify
5
5
 
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class CreditCard < ActiveRecord::Base
2
+ class CreditCard < Spree::Base
3
3
  belongs_to :payment_method
4
4
  has_many :payments, as: :source
5
5
 
@@ -110,11 +110,11 @@ module Spree
110
110
  # Looking at the ActiveMerchant source code we should probably be calling #to_active_merchant before passing
111
111
  # the object to ActiveMerchant but this should do for now.
112
112
  def first_name
113
- super || name.to_s.split(/[[:space:]]/, 2)[0]
113
+ name.to_s.split(/[[:space:]]/, 2)[0]
114
114
  end
115
115
 
116
116
  def last_name
117
- super || name.to_s.split(/[[:space:]]/, 2)[1]
117
+ name.to_s.split(/[[:space:]]/, 2)[1]
118
118
  end
119
119
 
120
120
  def to_active_merchant
@@ -123,8 +123,8 @@ module Spree
123
123
  :month => month,
124
124
  :year => year,
125
125
  :verification_value => verification_value,
126
- :first_name => first_name || name.to_s.split(/[[:space:]]/, 2)[0],
127
- :last_name => last_name || name.to_s.split(/[[:space:]]/, 2)[1]
126
+ :first_name => first_name,
127
+ :last_name => last_name,
128
128
  )
129
129
  end
130
130
 
@@ -132,13 +132,9 @@ module Spree
132
132
 
133
133
  def expiry_not_in_the_past
134
134
  if year.present? && month.present?
135
- if month.to_i < 1 || month.to_i > 12
136
- errors.add(:base, :expiry_invalid)
137
- else
138
- current = Time.current
139
- if year.to_i < current.year or (year.to_i == current.year and month.to_i < current.month)
140
- errors.add(:base, :card_expired)
141
- end
135
+ time = Time.zone.parse("#{year}-#{month}-1")
136
+ if time < Time.zone.now.to_time.beginning_of_month
137
+ errors.add(:base, :card_expired)
142
138
  end
143
139
  end
144
140
  end
@@ -75,8 +75,5 @@ module Spree
75
75
  end
76
76
  end
77
77
  end
78
-
79
- # for backwards compatibility
80
- alias_method :source_with_profiles, :reusable_sources
81
78
  end
82
79
  end
@@ -19,9 +19,8 @@ module Spree
19
19
 
20
20
  def create_profile(payment)
21
21
  # simulate the storage of credit card profile using remote service
22
- if success = VALID_CCS.include?(payment.source.number)
23
- payment.source.update_attributes(:gateway_customer_profile_id => generate_profile_id(success))
24
- end
22
+ success = VALID_CCS.include? payment.source.number
23
+ payment.source.update_attributes(:gateway_customer_profile_id => generate_profile_id(success))
25
24
  end
26
25
 
27
26
  def authorize(money, credit_card, options = {})
@@ -1,6 +1,5 @@
1
1
  module Spree
2
2
  class Image < Asset
3
- validates_attachment_presence :attachment
4
3
  validate :no_attachment_errors
5
4
 
6
5
  has_attached_file :attachment,
@@ -9,6 +8,9 @@ module Spree
9
8
  url: '/spree/products/:id/:style/:basename.:extension',
10
9
  path: ':rails_root/public/spree/products/:id/:style/:basename.:extension',
11
10
  convert_options: { all: '-strip -auto-orient -colorspace sRGB' }
11
+ validates_attachment :attachment,
12
+ :presence => true,
13
+ :content_type => { :content_type => %w(image/jpeg image/jpg image/png image/gif) }
12
14
 
13
15
  # save the w,h of the original image (from which others can be calculated)
14
16
  # we need to look at the write-queue for images which have not been saved yet
@@ -1,9 +1,9 @@
1
1
  module Spree
2
- class InventoryUnit < ActiveRecord::Base
2
+ class InventoryUnit < Spree::Base
3
3
  belongs_to :variant, class_name: "Spree::Variant", inverse_of: :inventory_units
4
4
  belongs_to :order, class_name: "Spree::Order", inverse_of: :inventory_units
5
5
  belongs_to :shipment, class_name: "Spree::Shipment", touch: true, inverse_of: :inventory_units
6
- belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization", inverse_of: :inventory_units
6
+ belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization"
7
7
  belongs_to :line_item, class_name: "Spree::LineItem", inverse_of: :inventory_units
8
8
 
9
9
  scope :backordered, -> { where state: 'backordered' }
@@ -21,7 +21,7 @@ module Spree
21
21
  event :fill_backorder do
22
22
  transition to: :on_hand, from: :backordered
23
23
  end
24
- after_transition on: :fill_backorder, do: :fulfill_order
24
+ after_transition on: :fill_backorder, do: :update_order
25
25
 
26
26
  event :ship do
27
27
  transition to: :shipped, if: :allow_ship?
@@ -69,9 +69,8 @@ module Spree
69
69
  Spree::Config[:allow_backorder_shipping] || self.on_hand?
70
70
  end
71
71
 
72
- def fulfill_order
73
- self.reload
74
- order.fulfill!
72
+ def update_order
73
+ order.update!
75
74
  end
76
75
  end
77
76
  end
@@ -47,9 +47,8 @@ module Spree
47
47
  included_tax_total = 0
48
48
  additional_tax_total = 0
49
49
  run_callbacks :tax_adjustments do
50
- tax = (item.respond_to?(:all_adjustments) ? item.all_adjustments : item.adjustments).tax
51
- included_tax_total = tax.included.reload.map(&:update!).compact.sum
52
- additional_tax_total = tax.additional.reload.map(&:update!).compact.sum
50
+ included_tax_total = adjustments.tax.included.reload.map(&:update!).compact.sum
51
+ additional_tax_total = adjustments.tax.additional.reload.map(&:update!).compact.sum
53
52
  end
54
53
 
55
54
  item.update_columns(
@@ -72,7 +71,7 @@ module Spree
72
71
  end
73
72
 
74
73
  def best_promotion_adjustment
75
- @best_promotion_adjustment ||= adjustments.promotion.eligible.reorder("amount ASC, created_at DESC, id DESC").first
74
+ @best_promotion_adjustment ||= adjustments.promotion.eligible.reorder("amount ASC, created_at DESC").first
76
75
  end
77
76
  end
78
77
  end
@@ -1,6 +1,6 @@
1
1
  # Default implementation of User. This class is intended to be modified by extensions (ex. spree_auth_devise)
2
2
  module Spree
3
- class LegacyUser < ActiveRecord::Base
3
+ class LegacyUser < Spree::Base
4
4
  include Core::UserAddress
5
5
  include Core::UserPaymentSource
6
6
 
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class LineItem < ActiveRecord::Base
2
+ class LineItem < Spree::Base
3
3
  before_validation :adjust_quantity
4
4
  belongs_to :order, class_name: "Spree::Order", inverse_of: :line_items, touch: true
5
5
  belongs_to :variant, class_name: "Spree::Variant", inverse_of: :line_items
@@ -30,13 +30,10 @@ module Spree
30
30
 
31
31
  after_create :update_tax_charge
32
32
 
33
- delegate :name, :description, :should_track_inventory?, to: :variant
33
+ delegate :name, :description, :sku, :should_track_inventory?, to: :variant
34
34
 
35
35
  attr_accessor :target_shipment
36
36
 
37
- self.whitelisted_ransackable_associations = ['variant']
38
- self.whitelisted_ransackable_attributes = ['variant_id']
39
-
40
37
  def copy_price
41
38
  if variant
42
39
  self.price = variant.price if price.nil?
@@ -88,10 +85,6 @@ module Spree
88
85
  !sufficient_stock?
89
86
  end
90
87
 
91
- def assign_stock_changes_to=(shipment)
92
- @preferred_shipment = shipment
93
- end
94
-
95
88
  # Remove product default_scope `deleted_at: nil`
96
89
  def product
97
90
  variant.product
@@ -104,14 +97,14 @@ module Spree
104
97
 
105
98
  private
106
99
  def update_inventory
107
- if changed?
100
+ if changed? || target_shipment.present?
108
101
  Spree::OrderInventory.new(self.order, self).verify(target_shipment)
109
102
  end
110
103
  end
111
104
 
112
105
  def update_adjustments
113
106
  if quantity_changed?
114
- update_tax_charge # Called to ensure pre_tax_amount is updated.
107
+ update_tax_charge # Called to ensure pre_tax_amount is updated.
115
108
  recalculate_adjustments
116
109
  end
117
110
  end
@@ -121,12 +114,12 @@ module Spree
121
114
  end
122
115
 
123
116
  def update_tax_charge
124
- Spree::TaxRate.adjust(order, [self])
117
+ Spree::TaxRate.adjust(order.tax_zone, [self])
125
118
  end
126
119
 
127
120
  def ensure_proper_currency
128
121
  unless currency == order.currency
129
- errors.add(:currency, :must_match_order_currency)
122
+ errors.add(:currency, t(:must_match_order_currency))
130
123
  end
131
124
  end
132
125
  end
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class LogEntry < ActiveRecord::Base
2
+ class LogEntry < Spree::Base
3
3
  belongs_to :source, polymorphic: true
4
4
 
5
5
  # Fix for #1767
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class OptionType < ActiveRecord::Base
2
+ class OptionType < Spree::Base
3
3
  has_many :option_values, -> { order(:position) }, dependent: :destroy, inverse_of: :option_type
4
4
  has_many :product_option_types, dependent: :destroy, inverse_of: :option_type
5
5
  has_many :products, through: :product_option_types
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class OptionValue < ActiveRecord::Base
2
+ class OptionValue < Spree::Base
3
3
  belongs_to :option_type, class_name: 'Spree::OptionType', touch: true, inverse_of: :option_values
4
4
  acts_as_list scope: :option_type
5
5
  has_and_belongs_to_many :variants, join_table: 'spree_option_values_variants', class_name: "Spree::Variant"
@@ -8,8 +8,6 @@ module Spree
8
8
 
9
9
  after_touch :touch_all_variants
10
10
 
11
- self.whitelisted_ransackable_attributes = ['presentation']
12
-
13
11
  def touch_all_variants
14
12
  # This can cause a cascade of products to be updated
15
13
  # To disable it in Rails 4.1, we can do this:
@@ -2,24 +2,25 @@ require 'spree/core/validators/email'
2
2
  require 'spree/order/checkout'
3
3
 
4
4
  module Spree
5
- class Order < ActiveRecord::Base
6
- include Spree::Order::Checkout
7
- include Spree::Order::CurrencyUpdater
5
+ class Order < Spree::Base
6
+ include Checkout
7
+ include CurrencyUpdater
8
8
 
9
9
  checkout_flow do
10
10
  go_to_state :address
11
11
  go_to_state :delivery
12
- go_to_state :payment, if: ->(order) { order.payment_required? }
12
+ go_to_state :payment, if: ->(order) do
13
+ # TODO there should be a better fix work around for the issues this is
14
+ # resolving we shouldn't be setting shipments cost every time a order
15
+ # object is loaded
16
+ order.set_shipments_cost if order.shipments.any?
17
+ order.payment_required?
18
+ end
13
19
  go_to_state :confirm, if: ->(order) { order.confirmation_required? }
14
20
  go_to_state :complete
15
21
  remove_transition from: :delivery, to: :confirm
16
22
  end
17
23
 
18
- token_resource
19
-
20
- self.whitelisted_ransackable_associations = %w[shipments user promotions bill_address ship_address line_items]
21
- self.whitelisted_ransackable_attributes = %w[completed_at created_at email number state payment_state shipment_state total]
22
-
23
24
  attr_reader :coupon_code
24
25
 
25
26
  if Spree.user_class
@@ -41,9 +42,9 @@ module Spree
41
42
  alias_attribute :ship_total, :shipment_total
42
43
 
43
44
  has_many :state_changes, as: :stateful
44
- has_many :line_items, -> { order("#{LineItem.table_name}.created_at ASC") }, dependent: :destroy, inverse_of: :order
45
+ has_many :line_items, -> { order('created_at ASC') }, dependent: :destroy, inverse_of: :order
45
46
  has_many :payments, dependent: :destroy
46
- has_many :return_authorizations, dependent: :destroy, inverse_of: :order
47
+ has_many :return_authorizations, dependent: :destroy
47
48
  has_many :adjustments, -> { order("#{Adjustment.table_name}.created_at ASC") }, as: :adjustable, dependent: :destroy
48
49
  has_many :line_item_adjustments, through: :line_items, source: :adjustments
49
50
  has_many :shipment_adjustments, through: :shipments, source: :adjustments
@@ -71,12 +72,13 @@ module Spree
71
72
  before_validation :clone_billing_address, if: :use_billing?
72
73
  attr_accessor :use_billing
73
74
 
75
+
76
+ before_create :create_token
74
77
  before_create :link_by_email
75
78
  before_update :homogenize_line_item_currencies, if: :currency_changed?
76
79
 
77
80
  validates :email, presence: true, if: :require_email
78
81
  validates :email, email: true, if: :require_email, allow_blank: true
79
- validates :number, uniqueness: true
80
82
  validate :has_available_shipment
81
83
 
82
84
  make_permalink field: :number
@@ -92,12 +94,6 @@ module Spree
92
94
 
93
95
  scope :created_between, ->(start_date, end_date) { where(created_at: start_date..end_date) }
94
96
  scope :completed_between, ->(start_date, end_date) { where(completed_at: start_date..end_date) }
95
- scope :reverse_chronological, -> { order(created_at: :desc) }
96
-
97
- def self.between(start_date, end_date)
98
- ActiveSupport::Deprecation.warn("Order#between will be deprecated in Spree 2.3, please use either Order#created_between or Order#completed_between instead.")
99
- self.created_between(start_date, end_date)
100
- end
101
97
 
102
98
  def self.by_customer(customer)
103
99
  joins(:user).where("#{Spree.user_class.table_name}.email" => customer)
@@ -213,14 +209,6 @@ module Spree
213
209
  @tax_zone ||= Zone.match(tax_address) || Zone.default_tax
214
210
  end
215
211
 
216
- # Indicates whether tax should be backed out of the price calcualtions in
217
- # cases where prices include tax but the customer is not required to pay
218
- # taxes in that case.
219
- def exclude_tax?
220
- return false unless Spree::Config[:prices_inc_tax]
221
- tax_zone != Zone.default_tax
222
- end
223
-
224
212
  # Returns the address for taxation based on configuration
225
213
  def tax_address
226
214
  Spree::Config[:tax_using_ship_address] ? ship_address : bill_address
@@ -270,18 +258,15 @@ module Spree
270
258
  end
271
259
  end
272
260
 
273
- def generate_order_number(digits = 9)
274
- self.number ||= loop do
275
- # Make a random number.
276
- random = "R#{Array.new(digits){rand(10)}.join}"
277
- # Use the random number if no other order exists with it.
278
- if self.class.exists?(number: random)
279
- # If over half of all possible options are taken add another digit.
280
- digits += 1 if self.class.count > (10 ** digits / 2)
281
- else
282
- break random
283
- end
284
- end
261
+ # FIXME refactor this method and implement validation using validates_* utilities
262
+ def generate_order_number
263
+ record = true
264
+ while record
265
+ random = "R#{Array.new(9){rand(9)}.join}"
266
+ record = self.class.where(number: random).first
267
+ end
268
+ self.number = random if self.number.blank?
269
+ self.number
285
270
  end
286
271
 
287
272
  def shipped_shipments
@@ -304,16 +289,14 @@ module Spree
304
289
  # Creates new tax charges if there are any applicable rates. If prices already
305
290
  # include taxes then price adjustments are created instead.
306
291
  def create_tax_charge!
307
- Spree::TaxRate.adjust(self, line_items)
308
- Spree::TaxRate.adjust(self, shipments) if shipments.any?
292
+ # We want to only look up the applicable tax zone once and pass it to TaxRate calculation to avoid duplicated lookups.
293
+ order_tax_zone = self.tax_zone
294
+ Spree::TaxRate.adjust(order_tax_zone, line_items)
295
+ Spree::TaxRate.adjust(order_tax_zone, shipments) if shipments.any?
309
296
  end
310
297
 
311
298
  def outstanding_balance
312
- if self.state == 'canceled' && self.payments.present? && self.payments.completed.size > 0
313
- -1 * payment_total
314
- else
315
- total - payment_total
316
- end
299
+ total - payment_total
317
300
  end
318
301
 
319
302
  def outstanding_balance?
@@ -359,12 +342,6 @@ module Spree
359
342
  consider_risk
360
343
  end
361
344
 
362
- def fulfill!
363
- shipments.each { |shipment| shipment.update!(self) if shipment.persisted? }
364
- updater.update_shipment_state
365
- save!
366
- end
367
-
368
345
  def deliver_order_confirmation_email
369
346
  OrderMailer.confirm_email(self.id).deliver
370
347
  update_column(:confirmation_delivered, true)
@@ -388,26 +365,25 @@ module Spree
388
365
  # success or failure of the 'complete' event for the order
389
366
  #
390
367
  # Returns:
368
+ #
391
369
  # - true if all pending_payments processed successfully
370
+ #
392
371
  # - true if a payment failed, ie. raised a GatewayError
393
372
  # which gets rescued and converted to TRUE when
394
373
  # :allow_checkout_gateway_error is set to true
374
+ #
395
375
  # - false if a payment failed, ie. raised a GatewayError
396
376
  # which gets rescued and converted to FALSE when
397
377
  # :allow_checkout_on_gateway_error is set to false
398
378
  #
399
379
  def process_payments!
400
- if pending_payments.empty?
401
- raise Core::GatewayError.new Spree.t(:no_pending_payments)
402
- else
403
- pending_payments.each do |payment|
404
- break if payment_total >= total
380
+ pending_payments.each do |payment|
381
+ break if payment_total >= total
405
382
 
406
- payment.process!
383
+ payment.process!
407
384
 
408
- if payment.completed?
409
- self.payment_total += payment.amount
410
- end
385
+ if payment.completed?
386
+ self.payment_total += payment.amount
411
387
  end
412
388
  end
413
389
  rescue Core::GatewayError => e
@@ -427,17 +403,10 @@ module Spree
427
403
  line_items.select(&:insufficient_stock?)
428
404
  end
429
405
 
430
- def ensure_line_items_are_in_stock
431
- if insufficient_stock_lines.present?
432
- errors.add(:base, Spree.t(:insufficient_stock_lines_present)) and return false
433
- end
434
- end
435
-
436
406
  def merge!(order, user = nil)
437
407
  order.line_items.each do |line_item|
438
408
  next unless line_item.currency == currency
439
409
  current_line_item = self.line_items.find_by(variant: line_item.variant)
440
-
441
410
  if current_line_item
442
411
  current_line_item.quantity += line_item.quantity
443
412
  current_line_item.save
@@ -564,7 +533,6 @@ module Spree
564
533
  self.update_columns(
565
534
  approver_id: user.id,
566
535
  approved_at: Time.now,
567
- considered_risky: false,
568
536
  )
569
537
  end
570
538
  end
@@ -604,11 +572,15 @@ module Spree
604
572
  self.ensure_updated_shipments
605
573
  end
606
574
 
607
- def reload(options=nil)
575
+ def reload
608
576
  remove_instance_variable(:@tax_zone) if defined?(@tax_zone)
609
577
  super
610
578
  end
611
579
 
580
+ def tax_total
581
+ included_tax_total + additional_tax_total
582
+ end
583
+
612
584
  private
613
585
 
614
586
  def link_by_email
@@ -635,6 +607,9 @@ module Spree
635
607
 
636
608
  def ensure_available_shipping_rates
637
609
  if shipments.empty? || shipments.any? { |shipment| shipment.shipping_rates.blank? }
610
+ # After this point, order redirects back to 'address' state and asks user to pick a proper address
611
+ # Therefore, shipments are not necessary at this point.
612
+ shipments.delete_all
638
613
  errors.add(:base, Spree.t(:items_cannot_be_shipped)) and return false
639
614
  end
640
615
  end
@@ -642,8 +617,9 @@ module Spree
642
617
  def after_cancel
643
618
  shipments.each { |shipment| shipment.cancel! }
644
619
  payments.completed.each { |payment| payment.cancel! }
620
+
645
621
  send_cancel_email
646
- self.update!
622
+ self.update_column(:payment_state, 'credit_owed') unless shipped?
647
623
  end
648
624
 
649
625
  def send_cancel_email
@@ -663,5 +639,11 @@ module Spree
663
639
  self.currency = Spree::Config[:currency] if self[:currency].nil?
664
640
  end
665
641
 
642
+ def create_token
643
+ self.guest_token ||= loop do
644
+ random_token = SecureRandom.urlsafe_base64(nil, false)
645
+ break random_token unless self.class.exists?(guest_token: random_token)
646
+ end
647
+ end
666
648
  end
667
649
  end