spree_core 2.1.12 → 2.2.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/helpers/spree/base_helper.rb +4 -7
  3. data/app/helpers/spree/products_helper.rb +11 -9
  4. data/app/helpers/spree/store_helper.rb +5 -0
  5. data/app/models/spree/ability.rb +4 -0
  6. data/app/models/spree/address.rb +6 -6
  7. data/app/models/spree/adjustment.rb +40 -61
  8. data/app/models/spree/app_configuration.rb +1 -14
  9. data/app/models/spree/calculator.rb +12 -4
  10. data/app/models/spree/calculator/default_tax.rb +42 -38
  11. data/app/models/spree/calculator/flat_percent_item_total.rb +2 -4
  12. data/app/models/spree/calculator/free_shipping.rb +5 -2
  13. data/app/models/spree/calculator/percent_on_line_item.rb +15 -0
  14. data/app/models/spree/calculator/percent_per_item.rb +3 -0
  15. data/app/models/spree/classification.rb +3 -2
  16. data/app/models/spree/credit_card.rb +7 -25
  17. data/app/models/spree/gateway/bogus.rb +5 -5
  18. data/app/models/spree/gateway/bogus_simple.rb +0 -8
  19. data/app/models/spree/image.rb +0 -9
  20. data/app/models/spree/inventory_unit.rb +10 -4
  21. data/app/models/spree/item_adjustments.rb +65 -0
  22. data/app/models/spree/legacy_user.rb +1 -0
  23. data/app/models/spree/line_item.rb +33 -13
  24. data/app/models/spree/option_type.rb +2 -2
  25. data/app/models/spree/option_value.rb +1 -1
  26. data/app/models/spree/order.rb +109 -89
  27. data/app/models/spree/order/checkout.rb +48 -0
  28. data/app/models/spree/order_contents.rb +72 -37
  29. data/app/models/spree/order_inventory.rb +65 -68
  30. data/app/models/spree/order_populator.rb +3 -17
  31. data/app/models/spree/order_updater.rb +63 -44
  32. data/app/models/spree/payment.rb +20 -5
  33. data/app/models/spree/payment/processing.rb +19 -25
  34. data/app/models/spree/payment_capture_event.rb +9 -0
  35. data/app/models/spree/payment_method/check.rb +0 -2
  36. data/app/models/spree/price.rb +1 -1
  37. data/app/models/spree/product.rb +14 -16
  38. data/app/models/spree/product/scopes.rb +4 -6
  39. data/app/models/spree/product_option_type.rb +2 -2
  40. data/app/models/spree/product_property.rb +2 -2
  41. data/app/models/spree/promotion.rb +71 -50
  42. data/app/models/spree/promotion/actions/create_adjustment.rb +31 -32
  43. data/app/models/spree/promotion/actions/create_item_adjustments.rb +83 -0
  44. data/app/models/spree/promotion/actions/free_shipping.rb +36 -0
  45. data/app/models/spree/promotion/rules/first_order.rb +4 -0
  46. data/app/models/spree/promotion/rules/item_total.rb +5 -1
  47. data/app/models/spree/promotion/rules/product.rb +4 -0
  48. data/app/models/spree/promotion/rules/user.rb +5 -6
  49. data/app/models/spree/promotion/rules/user_logged_in.rb +4 -0
  50. data/app/models/spree/promotion_action.rb +1 -5
  51. data/app/models/spree/promotion_handler/cart.rb +38 -0
  52. data/app/models/spree/promotion_handler/coupon.rb +76 -0
  53. data/app/models/spree/promotion_handler/free_shipping.rb +31 -0
  54. data/app/models/spree/promotion_handler/page.rb +24 -0
  55. data/app/models/spree/promotion_rule.rb +15 -7
  56. data/app/models/spree/property.rb +1 -1
  57. data/app/models/spree/return_authorization.rb +7 -1
  58. data/app/models/spree/shipment.rb +113 -49
  59. data/app/models/spree/shipping_calculator.rb +4 -5
  60. data/app/models/spree/shipping_category.rb +2 -2
  61. data/app/models/spree/shipping_method.rb +12 -6
  62. data/app/models/spree/shipping_rate.rb +27 -7
  63. data/app/models/spree/stock/availability_validator.rb +1 -1
  64. data/app/models/spree/stock/estimator.rb +13 -1
  65. data/app/models/spree/stock/package.rb +11 -7
  66. data/app/models/spree/stock/packer.rb +3 -3
  67. data/app/models/spree/stock/quantifier.rb +9 -1
  68. data/app/models/spree/stock_item.rb +11 -6
  69. data/app/models/spree/stock_movement.rb +1 -2
  70. data/app/models/spree/tax_category.rb +6 -1
  71. data/app/models/spree/tax_rate.rb +57 -49
  72. data/app/models/spree/taxon.rb +10 -5
  73. data/app/models/spree/taxonomy.rb +5 -2
  74. data/app/models/spree/variant.rb +33 -16
  75. data/app/models/spree/zone.rb +24 -24
  76. data/app/views/spree/shared/_routes.html.erb +3 -0
  77. data/config/locales/en.yml +42 -26
  78. data/db/migrate/20130213191427_create_default_stock.rb +3 -3
  79. data/db/migrate/20130413230529_add_name_to_spree_credit_cards.rb +5 -0
  80. data/db/migrate/20130414000512_update_name_fields_on_spree_credit_cards.rb +13 -0
  81. data/db/migrate/20130417120035_update_adjustment_states.rb +2 -2
  82. data/db/migrate/20130417123427_add_shipping_rates_to_shipments.rb +1 -1
  83. data/db/migrate/20130509115210_add_number_to_stock_transfer.rb +1 -1
  84. data/db/migrate/20130611054351_rename_shipping_methods_zones_to_spree_shipping_methods_zones.rb +0 -5
  85. data/db/migrate/20130802022321_migrate_tax_categories_to_line_items.rb +7 -5
  86. data/db/migrate/20130807024301_upgrade_adjustments.rb +39 -0
  87. data/db/migrate/20130807024302_rename_adjustment_fields.rb +17 -0
  88. data/db/migrate/20130813004002_add_shipment_total_to_spree_orders.rb +5 -0
  89. data/db/migrate/20130813232134_rename_activators_to_promotions.rb +5 -0
  90. data/db/migrate/20130815000406_add_adjustment_total_to_line_items.rb +5 -0
  91. data/db/migrate/20130815024413_add_adjustment_total_to_shipments.rb +5 -0
  92. data/db/migrate/20130828234942_add_tax_total_to_line_items_shipments_and_orders.rb +8 -0
  93. data/db/migrate/20130830001159_migrate_old_shipping_calculators.rb +1 -1
  94. data/db/migrate/20130903183026_add_code_to_spree_promotion_rules.rb +5 -0
  95. data/db/migrate/20130917024658_remove_promotions_event_name_field.rb +5 -0
  96. data/db/migrate/20130924040529_add_promo_total_to_line_items_and_shipments_and_orders.rb +7 -0
  97. data/db/migrate/20131001013410_remove_unused_credit_card_fields.rb +7 -3
  98. data/db/migrate/20131107132123_add_tax_category_to_variants.rb +6 -0
  99. data/db/migrate/20131118043959_add_included_to_adjustments.rb +5 -0
  100. data/db/migrate/20131118050234_rename_tax_total_fields.rb +11 -0
  101. data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +21 -0
  102. data/db/migrate/20131127001002_add_position_to_classifications.rb +5 -0
  103. data/db/migrate/20131211112807_create_spree_orders_promotions.rb +8 -0
  104. data/db/migrate/20131218054603_add_item_count_to_spree_orders.rb +5 -0
  105. data/db/migrate/20140106224208_rename_permalink_to_slug_for_products.rb +5 -0
  106. data/db/migrate/20140124023232_rename_activator_id_in_rules_and_actions_to_promotion_id.rb +6 -0
  107. data/db/migrate/20140203161722_add_approver_id_and_approved_at_to_orders.rb +6 -0
  108. data/db/migrate/20140204115338_add_confirmation_delivered_to_spree_orders.rb +5 -0
  109. data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +12 -0
  110. data/db/migrate/20140205144710_add_uncaptured_amount_to_payments.rb +5 -0
  111. data/db/migrate/20140207085910_add_tax_category_id_to_shipping_methods.rb +5 -0
  112. data/db/migrate/20140207093021_add_tax_rate_id_to_shipping_rates.rb +5 -0
  113. data/db/migrate/20140211040159_add_pre_tax_amount_to_line_items_and_shipments.rb +6 -0
  114. data/db/migrate/20140213184916_add_more_indexes.rb +13 -0
  115. data/db/migrate/20140219060952_add_considered_risky_to_orders.rb +5 -0
  116. data/lib/generators/spree/dummy/dummy_generator.rb +1 -6
  117. data/lib/generators/spree/install/install_generator.rb +6 -6
  118. data/lib/generators/spree/install/templates/{app/assets/javascripts/admin → vendor/assets/javascripts/spree/backend}/all.js +3 -3
  119. data/lib/generators/spree/install/templates/{app/assets/javascripts/store → vendor/assets/javascripts/spree/frontend}/all.js +3 -3
  120. data/lib/generators/spree/install/templates/{app/assets/stylesheets/store → vendor/assets/stylesheets/spree/backend}/all.css +3 -3
  121. data/lib/generators/spree/install/templates/{app/assets/stylesheets/admin → vendor/assets/stylesheets/spree/frontend}/all.css +3 -3
  122. data/lib/spree/core.rb +21 -8
  123. data/lib/spree/core/calculated_adjustments.rb +0 -40
  124. data/lib/spree/core/controller_helpers.rb +5 -0
  125. data/lib/spree/core/controller_helpers/auth.rb +2 -2
  126. data/lib/spree/core/controller_helpers/common.rb +0 -5
  127. data/lib/spree/core/controller_helpers/order.rb +8 -9
  128. data/lib/spree/core/engine.rb +10 -17
  129. data/lib/spree/core/permalinks.rb +1 -1
  130. data/lib/spree/core/product_duplicator.rb +3 -8
  131. data/lib/spree/core/user_address.rb +1 -1
  132. data/lib/spree/core/validators/email.rb +23 -1
  133. data/lib/spree/core/version.rb +1 -1
  134. data/lib/spree/money.rb +1 -1
  135. data/lib/spree/permitted_attributes.rb +2 -2
  136. data/lib/spree/testing_support/caching.rb +47 -0
  137. data/lib/spree/testing_support/factories/adjustment_factory.rb +11 -2
  138. data/lib/spree/testing_support/factories/credit_card_factory.rb +2 -1
  139. data/lib/spree/testing_support/factories/order_factory.rb +10 -5
  140. data/lib/spree/testing_support/factories/payment_factory.rb +2 -2
  141. data/lib/spree/testing_support/factories/payment_method_factory.rb +3 -3
  142. data/lib/spree/testing_support/factories/promotion_factory.rb +16 -1
  143. data/lib/spree/testing_support/factories/shipment_factory.rb +8 -4
  144. data/lib/spree/testing_support/factories/shipping_method_factory.rb +1 -3
  145. data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
  146. data/lib/spree/testing_support/factories/tax_rate_factory.rb +2 -2
  147. data/lib/spree/testing_support/order_walkthrough.rb +1 -1
  148. data/lib/tasks/core.rake +2 -2
  149. data/vendor/assets/fonts/FontAwesome.otf +0 -0
  150. data/vendor/assets/fonts/fontawesome-webfont.eot +0 -0
  151. data/vendor/assets/fonts/fontawesome-webfont.svg +399 -0
  152. data/vendor/assets/fonts/fontawesome-webfont.ttf +0 -0
  153. data/vendor/assets/fonts/fontawesome-webfont.woff +0 -0
  154. data/vendor/assets/stylesheets/font-awesome.scss +1475 -0
  155. metadata +73 -44
  156. data/app/assets/javascripts/admin/handlebar_extensions.js +0 -9
  157. data/app/helpers/spree/admin/adjustments_helper.rb +0 -26
  158. data/app/helpers/spree/admin/images_helper.rb +0 -18
  159. data/app/helpers/spree/promotion_rules_helper.rb +0 -13
  160. data/app/models/spree/activator.rb +0 -29
  161. data/app/models/spree/calculator/per_item.rb +0 -41
  162. data/app/models/spree/stock/remaining_packer.rb +0 -22
  163. data/app/views/spree/payments/_payment.html.erb +0 -18
  164. data/db/migrate/20131118041203_add_tax_total_to_spree_orders.rb +0 -5
  165. data/db/migrate/20131118043021_add_order_id_to_spree_adjustments.rb +0 -6
  166. data/db/migrate/20131118074808_add_included_to_spree_adjustments.rb +0 -5
  167. data/db/migrate/20140415041315_add_user_id_created_by_id_index_to_order.rb +0 -5
  168. data/lib/spree/core/gateway_error.rb +0 -5
  169. data/lib/spree/core/preference_rescue.rb +0 -25
  170. data/lib/spree/core/s3_support.rb +0 -25
  171. data/lib/spree/promo/coupon_applicator.rb +0 -71
  172. data/lib/spree/testing_support/factories/activator_factory.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 413409a6e11793b4c41aac79f57541c2b4b6c8b4
4
- data.tar.gz: 61e14410d4987119dd34a5694b97acefb0578cb3
3
+ metadata.gz: bec161c547d1c0a301e068937cff9a461ff7a6cc
4
+ data.tar.gz: 5ea11fca1a903043e7776db55c5092a676a31c40
5
5
  SHA512:
6
- metadata.gz: 2c6a19efdbfd4a44dde5cf6a42532c2c59e95fe94e6700aaf6816b47312a46ee1987376cb13646701ba0c8b0195c842abf8cc129e40cb23faf63b71372a52294
7
- data.tar.gz: a69ffad30b460d6e910f825c0b60e346030a0c120d361bdbebd27ff324eb9783e34d243cca4d7a8ac4c80aca0ed031bfc5639f3a08fd608529e4ad6752f6b0cd
6
+ metadata.gz: 1f618e1c470a7a552a2b6b97d72b2702c52d8beba2298d6ab6400982f024a466bc9b857af1e3b447ca5ab8c079d8d44bac78877516baa1a8962ef7f9eac0b244
7
+ data.tar.gz: 3be703d2a9d163edb81d227463859a7cb5a181091539780f5b0eb4173ad2f69cf8ff74e824361d312e6571ffbbedef6c8f12eb06fb6649cd2902771f5f537754
@@ -13,16 +13,14 @@ module Spree
13
13
  end
14
14
 
15
15
  def link_to_cart(text = nil)
16
- return "" if current_spree_page?(spree.cart_path)
17
-
18
16
  text = text ? h(text) : Spree.t('cart')
19
17
  css_class = nil
20
18
 
21
- if current_order.nil? or current_order.item_count.zero?
19
+ if simple_current_order.nil? or simple_current_order.item_count.zero?
22
20
  text = "#{text}: (#{Spree.t('empty')})"
23
21
  css_class = 'empty'
24
22
  else
25
- text = "#{text}: (#{current_order.item_count}) <span class='amount'>#{current_order.display_total.to_html}</span>".html_safe
23
+ text = "#{text}: (#{simple_current_order.item_count}) <span class='amount'>#{simple_current_order.display_total.to_html}</span>".html_safe
26
24
  css_class = 'full'
27
25
  end
28
26
 
@@ -120,7 +118,7 @@ module Spree
120
118
  countries.collect do |country|
121
119
  country.name = Spree.t(country.iso, scope: 'country_names', default: country.name)
122
120
  country
123
- end.sort_by { |c| c.name.parameterize }
121
+ end.sort { |a, b| a.name.parameterize <=> b.name.parameterize }
124
122
  end
125
123
 
126
124
  def seo_url(taxon)
@@ -164,10 +162,9 @@ module Spree
164
162
  end
165
163
 
166
164
  private
167
-
168
165
  # Returns style of image or nil
169
166
  def image_style_from_method_name(method_name)
170
- if method_name.to_s.match(/_image$/) && style = method_name.to_s.sub(/_image$/, '')
167
+ if style = method_name.to_s.sub(/_image$/, '')
171
168
  possible_styles = Spree::Image.attachment_definitions[:attachment][:styles]
172
169
  style if style.in? possible_styles.with_indifferent_access
173
170
  end
@@ -12,13 +12,14 @@ module Spree
12
12
 
13
13
  # returns the formatted price for the specified variant as a difference from product price
14
14
  def variant_price_diff(variant)
15
- variant_amount = variant.amount_in(current_currency)
16
- product_amount = variant.product.amount_in(current_currency)
17
- return if variant_amount == product_amount || product_amount.nil?
18
- diff = variant.amount_in(current_currency) - product_amount
19
- amount = Spree::Money.new(diff.abs, currency: current_currency).to_html
20
- label = diff > 0 ? :add : :subtract
21
- "(#{Spree.t(label)}: #{amount})".html_safe
15
+ diff = variant.amount_in(current_currency) - variant.product.amount_in(current_currency)
16
+ return nil if diff == 0
17
+ amount = Spree::Money.new(diff.abs, { currency: current_currency }).to_html
18
+ if diff > 0
19
+ "(#{Spree.t(:add)}: #{amount})".html_safe
20
+ else
21
+ "(#{Spree.t(:subtract)}: #{amount})".html_safe
22
+ end
22
23
  end
23
24
 
24
25
  # returns the formatted full price for the variant, if at least one variant price differs from product price
@@ -52,8 +53,9 @@ module Spree
52
53
  end
53
54
  end
54
55
 
55
- def get_taxonomies
56
- @taxonomies ||= Spree::Taxonomy.includes(root: :children)
56
+ def cache_key_for_products
57
+ max_updated_at = @products.maximum(:updated_at).to_s(:number)
58
+ "#{current_currency}/spree/products/all-#{params[:page]}-#{max_updated_at}"
57
59
  end
58
60
  end
59
61
  end
@@ -7,5 +7,10 @@ module Spree
7
7
  %w{thank_you}.exclude? params[:action]
8
8
  end
9
9
 
10
+ def cache_key_for_taxons
11
+ max_updated_at = @taxons.maximum(:updated_at).to_i
12
+ parts = [@taxon.try(:id), max_updated_at].compact.join("-")
13
+ "taxons/#{parts}"
14
+ end
10
15
  end
11
16
  end
@@ -47,6 +47,10 @@ module Spree
47
47
  can :update, Order do |order, token|
48
48
  order.user == user || order.token && token == order.token
49
49
  end
50
+ can [:create, :read], Address
51
+ can :update, Address do |address|
52
+ user.bill_address == address || user.ship_address == address
53
+ end
50
54
  can [:index, :read], Product
51
55
  can [:index, :read], ProductProperty
52
56
  can [:index, :read], Property
@@ -3,7 +3,7 @@ module Spree
3
3
  belongs_to :country, class_name: "Spree::Country"
4
4
  belongs_to :state, class_name: "Spree::State"
5
5
 
6
- has_many :shipments
6
+ has_many :shipments, inverse_of: :address
7
7
 
8
8
  validates :firstname, :lastname, :address1, :city, :country, presence: true
9
9
  validates :zipcode, presence: true, if: :require_zipcode?
@@ -19,11 +19,6 @@ module Spree
19
19
  new(country: country)
20
20
  end
21
21
 
22
- # Can modify an address if it's not been used in an order (but checkouts controller has finer control)
23
- # def editable?
24
- # new_record? || (shipments.empty? && checkouts.empty?)
25
- # end
26
-
27
22
  def self.default(user = nil, kind = "bill")
28
23
  if user
29
24
  user.send(:"#{kind}_address") || build_default
@@ -32,6 +27,11 @@ module Spree
32
27
  end
33
28
  end
34
29
 
30
+ # Can modify an address if it's not been used in an order (but checkouts controller has finer control)
31
+ # def editable?
32
+ # new_record? || (shipments.empty? && checkouts.empty?)
33
+ # end
34
+
35
35
  def full_name
36
36
  "#{firstname} #{lastname}".strip
37
37
  end
@@ -1,10 +1,8 @@
1
1
  # Adjustments represent a change to the +item_total+ of an Order. Each adjustment
2
2
  # has an +amount+ that can be either positive or negative.
3
3
  #
4
- # Adjustments can be open/closed/finalized
5
- #
6
- # Once an adjustment is finalized, it cannot be changed, but an adjustment can
7
- # toggle between open/closed as needed
4
+ # Adjustments can be "opened" or "closed".
5
+ # Once an adjustment is closed, it will not be automatically updated.
8
6
  #
9
7
  # Boolean attributes:
10
8
  #
@@ -26,83 +24,67 @@ module Spree
26
24
  class Adjustment < ActiveRecord::Base
27
25
  belongs_to :adjustable, polymorphic: true
28
26
  belongs_to :source, polymorphic: true
29
- belongs_to :originator, polymorphic: true
30
- belongs_to :order, :class_name => 'Spree::Order'
27
+ belongs_to :order, :class_name => "Spree::Order"
31
28
 
32
29
  validates :label, presence: true
33
30
  validates :amount, numericality: true
34
31
 
35
- after_save :update_adjustable
36
- after_destroy :update_adjustable
37
-
38
32
  state_machine :state, initial: :open do
39
33
  event :close do
40
34
  transition from: :open, to: :closed
41
35
  end
42
36
 
43
- event :open do
44
- transition from: :closed, to: :open
45
- end
46
-
47
- event :finalize do
48
- transition from: [:open, :closed], to: :finalized
37
+ event :close do
38
+ transition from: :close, to: :open
49
39
  end
50
40
  end
51
41
 
52
- scope :tax, -> { where(originator_type: 'Spree::TaxRate') }
42
+ after_create :update_adjustable_adjustment_total
43
+
44
+ scope :open, -> { where(state: 'open') }
45
+ scope :tax, -> { where(source_type: 'Spree::TaxRate') }
53
46
  scope :price, -> { where(adjustable_type: 'Spree::LineItem') }
54
- scope :shipping, -> { where(originator_type: 'Spree::ShippingMethod') }
47
+ scope :shipping, -> { where(adjustable_type: 'Spree::Shipment') }
55
48
  scope :optional, -> { where(mandatory: false) }
56
49
  scope :eligible, -> { where(eligible: true) }
57
50
  scope :charge, -> { where("#{quoted_table_name}.amount >= 0") }
58
51
  scope :credit, -> { where("#{quoted_table_name}.amount < 0") }
59
- scope :promotion, -> { where(originator_type: 'Spree::PromotionAction') }
60
- scope :manual, -> { where(originator_type: nil) }
52
+ scope :promotion, -> { where(source_type: 'Spree::PromotionAction') }
61
53
  scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") }
62
54
  scope :included, -> { where(included: true) }
63
55
  scope :additional, -> { where(included: false) }
64
56
 
65
- def promotion?
66
- originator_type == 'Spree::PromotionAction'
67
- end
68
-
69
- # Update the boolean _eligible_ attribute which determines which adjustments
70
- # count towards the order's adjustment_total.
71
- def set_eligibility
72
- result = mandatory || ((amount != 0 || promotion?) && eligible_for_originator?)
73
- update_column(:eligible, result)
57
+ def closed?
58
+ state == "closed"
74
59
  end
75
60
 
76
- # Allow originator of the adjustment to perform an additional eligibility of the adjustment
77
- # Should return _true_ if originator is absent or doesn't implement _eligible?_
78
- def eligible_for_originator?
79
- return true if originator.nil?
80
- !originator.respond_to?(:eligible?) || originator.eligible?(source)
61
+ def promotion?
62
+ source.class < Spree::PromotionAction
81
63
  end
82
64
 
83
- # Update both the eligibility and amount of the adjustment. Adjustments
84
- # delegate updating of amount to their Originator when present, but only if
85
- # +locked+ is false. Adjustments that are +locked+ will never change their amount.
65
+ # Recalculate amount given a target e.g. Order, Shipment, LineItem
86
66
  #
87
- # Adjustments delegate updating of amount to their Originator when present,
88
- # but only if when they're in "open" state, closed or finalized adjustments
89
- # are not recalculated.
67
+ # Passing a target here would always be recommended as it would avoid
68
+ # hitting the database again and would ensure you're compute values over
69
+ # the specific object amount passed here.
90
70
  #
91
- # It receives +calculable+ as the updated source here so calculations can be
92
- # performed on the current values of that source. If we used +source+ it
93
- # could load the old record from db for the association. e.g. when updating
94
- # more than on line items at once via accepted_nested_attributes the order
95
- # object on the association would be in a old state and therefore the
96
- # adjustment calculations would not performed on proper values
97
- def update!(calculable = nil)
98
- return if immutable?
99
- # Fix for #3381
100
- # If we attempt to call 'source' before the reload, then source is currently
101
- # the order object. After calling a reload, the source is the Shipment.
102
- reload
103
- calculable = source unless calculable == source
104
- originator.update_adjustment(self, calculable) if originator.present?
105
- set_eligibility
71
+ # Noop if the adjustment is locked.
72
+ #
73
+ # If the adjustment has no source, do not attempt to re-calculate the amount.
74
+ # Chances are likely that this was a manually created adjustment in the admin backend.
75
+ def update!(target = nil)
76
+ return amount if closed?
77
+ if source.present?
78
+ amount = source.compute_amount(target || adjustable)
79
+ self.update_columns(
80
+ amount: amount,
81
+ updated_at: Time.now,
82
+ )
83
+ if promotion?
84
+ self.update_column(:eligible, source.promotion.eligible?(adjustable))
85
+ end
86
+ end
87
+ amount
106
88
  end
107
89
 
108
90
  def currency
@@ -113,14 +95,11 @@ module Spree
113
95
  Spree::Money.new(amount, { currency: currency })
114
96
  end
115
97
 
116
- def immutable?
117
- state != "open"
118
- end
119
-
120
98
  private
121
99
 
122
- def update_adjustable
123
- adjustable.update! if adjustable.is_a? Order
124
- end
100
+ def update_adjustable_adjustment_total
101
+ # Cause adjustable's total to be recalculated
102
+ Spree::ItemAdjustments.new(adjustable).update if adjustable
103
+ end
125
104
  end
126
105
  end
@@ -35,6 +35,7 @@ module Spree
35
35
  preference :always_include_confirm_step, :boolean, default: false # Ensures confirmation step is always in checkout_progress bar, but does not force a confirm step if your payment methods do not support it.
36
36
  preference :always_put_site_name_in_title, :boolean, default: true
37
37
  preference :auto_capture, :boolean, default: false # automatically capture the credit card (as opposed to just authorize and capture later)
38
+ preference :binary_inventory_cache, :boolean, default: false # only invalidate product cache when a stock item changes whether it is in_stock
38
39
  preference :check_for_spree_alerts, :boolean, default: true
39
40
  preference :checkout_zone, :string, default: nil # replace with the name of a zone if you would like to limit the countries
40
41
  preference :company, :boolean, default: false # Request company field for billing and shipping addr
@@ -70,20 +71,6 @@ module Spree
70
71
  preference :tax_using_ship_address, :boolean, default: true
71
72
  preference :track_inventory_levels, :boolean, default: true # Determines whether to track on_hand values for variants / products.
72
73
 
73
- # Preferences related to image settings
74
- preference :attachment_default_url, :string, default: '/spree/products/:id/:style/:basename.:extension'
75
- preference :attachment_path, :string, default: ':rails_root/public/spree/products/:id/:style/:basename.:extension'
76
- preference :attachment_url, :string, default: '/spree/products/:id/:style/:basename.:extension'
77
- preference :attachment_styles, :string, default: "{\"mini\":\"48x48>\",\"small\":\"100x100>\",\"product\":\"240x240>\",\"large\":\"600x600>\"}"
78
- preference :attachment_default_style, :string, default: 'product'
79
- preference :s3_access_key, :string
80
- preference :s3_bucket, :string
81
- preference :s3_secret, :string
82
- preference :s3_headers, :string, default: "{\"Cache-Control\":\"max-age=31557600\"}"
83
- preference :use_s3, :boolean, default: false # Use S3 for images rather than the file system
84
- preference :s3_protocol, :string
85
- preference :s3_host_alias, :string
86
-
87
74
  # Default mail headers settings
88
75
  preference :enable_mail_delivery, :boolean, :default => false
89
76
  preference :send_core_emails, :boolean, :default => true
@@ -2,11 +2,19 @@ module Spree
2
2
  class Calculator < ActiveRecord::Base
3
3
  belongs_to :calculable, polymorphic: true
4
4
 
5
- # This method must be overriden in concrete calculator.
5
+ # This method calls a compute_<computable> method. must be overriden in concrete calculator.
6
6
  #
7
- # It should return amount computed based on #calculable and/or optional parameter
8
- def compute(something = nil)
9
- raise NotImplementedError, 'please use concrete calculator'
7
+ # It should return amount computed based on #calculable and the computable parameter
8
+ def compute(computable)
9
+ # Spree::LineItem -> :compute_line_item
10
+ computable_name = computable.class.name.demodulize.underscore
11
+ method = "compute_#{computable_name}".to_sym
12
+ calculator_class = self.class
13
+ begin
14
+ self.send(method, computable)
15
+ rescue NoMethodError
16
+ raise NotImplementedError, "Please implement '#{method}(#{computable_name})' in your calculator: #{calculator_class.name}"
17
+ end
10
18
  end
11
19
 
12
20
  # overwrite to provide description for your calculators
@@ -6,54 +6,58 @@ module Spree
6
6
  Spree.t(:default_tax)
7
7
  end
8
8
 
9
- def compute(computable)
10
- case computable
11
- when Spree::Order
12
- compute_order(computable)
13
- when Spree::LineItem
14
- compute_line_item(computable)
9
+ # Default tax calculator still needs to support orders for legacy reasons
10
+ # Orders created before Spree 2.1 had tax adjustments applied to the order, as a whole.
11
+ # Orders created with Spree 2.2 and after, have them applied to the line items individually.
12
+ def compute_order(order)
13
+
14
+ matched_line_items = order.line_items.select do |line_item|
15
+ line_item.tax_category == rate.tax_category
16
+ end
17
+
18
+ line_items_total = matched_line_items.sum(&:total)
19
+ if rate.included_in_price
20
+ round_to_two_places(line_items_total - ( line_items_total / (1 + rate.amount) ) )
21
+ else
22
+ round_to_two_places(line_items_total * rate.amount)
15
23
  end
16
24
  end
17
25
 
26
+ # When it comes to computing shipments or line items: same same.
27
+ def compute_shipment_or_line_item(item)
28
+ if rate.included_in_price
29
+ deduced_total_by_rate(item.pre_tax_amount, rate)
30
+ else
31
+ round_to_two_places(item.discounted_amount * rate.amount)
32
+ end
33
+ end
18
34
 
19
- private
35
+ alias_method :compute_shipment, :compute_shipment_or_line_item
36
+ alias_method :compute_line_item, :compute_shipment_or_line_item
20
37
 
21
- def rate
22
- self.calculable
38
+ def compute_shipping_rate(shipping_rate)
39
+ if rate.included_in_price
40
+ pre_tax_amount = shipping_rate.cost / (1 + rate.amount)
41
+ deduced_total_by_rate(pre_tax_amount, rate)
42
+ else
43
+ with_tax_amount = shipping_rate.cost * rate.amount
44
+ round_to_two_places(with_tax_amount)
23
45
  end
46
+ end
24
47
 
25
- def compute_order(order)
26
- matched_line_items = order.line_items.select do |line_item|
27
- line_item.tax_category == rate.tax_category
28
- end
29
-
30
- line_items_total = matched_line_items.sum(&:total)
31
- if rate.included_in_price
32
- deduced_total_by_rate(line_items_total, rate)
33
- else
34
- round_to_two_places(line_items_total * rate.amount)
35
- end
36
- end
48
+ private
37
49
 
38
- def compute_line_item(line_item)
39
- if line_item.tax_category == rate.tax_category
40
- if rate.included_in_price
41
- deduced_total_by_rate(line_item.total, rate)
42
- else
43
- round_to_two_places(line_item.total * rate.amount)
44
- end
45
- else
46
- 0
47
- end
48
- end
50
+ def rate
51
+ self.calculable
52
+ end
49
53
 
50
- def round_to_two_places(amount)
51
- BigDecimal.new(amount.to_s).round(2, BigDecimal::ROUND_HALF_UP)
52
- end
54
+ def round_to_two_places(amount)
55
+ BigDecimal.new(amount.to_s).round(2, BigDecimal::ROUND_HALF_UP)
56
+ end
53
57
 
54
- def deduced_total_by_rate(total, rate)
55
- round_to_two_places(total - ( total / (1 + rate.amount) ) )
56
- end
58
+ def deduced_total_by_rate(pre_tax_amount, rate)
59
+ round_to_two_places(pre_tax_amount * rate.amount)
60
+ end
57
61
 
58
62
  end
59
63
  end
@@ -8,10 +8,8 @@ module Spree
8
8
  Spree.t(:flat_percent)
9
9
  end
10
10
 
11
- def compute(object)
12
- return unless object.present? and object.respond_to?(:item_total)
13
- item_total = object.item_total
14
- value = item_total * BigDecimal(self.preferred_flat_percent.to_s) / 100.0
11
+ def compute(line_item)
12
+ value = line_item.amount * BigDecimal(self.preferred_flat_percent.to_s) / 100.0
15
13
  (value * 100).round.to_f / 100
16
14
  end
17
15
  end