spree_core 2.4.10 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/app/assets/images/logo/spree_50.png +0 -0
  4. data/app/controllers/spree/base_controller.rb +1 -2
  5. data/app/helpers/spree/base_helper.rb +41 -131
  6. data/app/helpers/spree/products_helper.rb +1 -1
  7. data/app/models/concerns/spree/adjustment_source.rb +51 -15
  8. data/app/models/concerns/spree/calculated_adjustments.rb +1 -0
  9. data/app/models/concerns/spree/display_money.rb +32 -0
  10. data/app/models/concerns/spree/named_type.rb +1 -1
  11. data/app/models/concerns/spree/number_generator.rb +39 -0
  12. data/app/models/concerns/spree/user_reporting.rb +3 -8
  13. data/app/models/spree/address.rb +0 -2
  14. data/app/models/spree/adjustable/adjustments_updater.rb +70 -0
  15. data/app/models/spree/adjustable/promotion_accumulator.rb +75 -0
  16. data/app/models/spree/adjustment.rb +17 -26
  17. data/app/models/spree/app_configuration.rb +4 -33
  18. data/app/models/spree/base.rb +0 -3
  19. data/app/models/spree/calculator.rb +0 -5
  20. data/app/models/spree/classification.rb +1 -1
  21. data/app/models/spree/country.rb +10 -4
  22. data/app/models/spree/credit_card.rb +14 -15
  23. data/app/models/spree/customer_return.rb +18 -25
  24. data/app/models/spree/gateway/bogus.rb +0 -4
  25. data/app/models/spree/line_item.rb +2 -5
  26. data/app/models/spree/option_type.rb +2 -4
  27. data/app/models/spree/option_value.rb +0 -2
  28. data/app/models/spree/order.rb +74 -134
  29. data/app/models/spree/order/checkout.rb +1 -1
  30. data/app/models/spree/order_contents.rb +9 -8
  31. data/app/models/spree/order_updater.rb +8 -1
  32. data/app/models/spree/payment.rb +13 -23
  33. data/app/models/spree/payment/gateway_options.rb +86 -0
  34. data/app/models/spree/payment/processing.rb +8 -39
  35. data/app/models/spree/payment_method.rb +3 -6
  36. data/app/models/spree/price.rb +2 -6
  37. data/app/models/spree/product.rb +27 -16
  38. data/app/models/spree/product_property.rb +1 -5
  39. data/app/models/spree/promotion.rb +7 -15
  40. data/app/models/spree/promotion/actions/create_adjustment.rb +4 -45
  41. data/app/models/spree/promotion/actions/create_item_adjustments.rb +8 -63
  42. data/app/models/spree/promotion/actions/create_line_items.rb +3 -12
  43. data/app/models/spree/promotion/actions/free_shipping.rb +4 -24
  44. data/app/models/spree/promotion/rules/option_value.rb +49 -0
  45. data/app/models/spree/promotion_action.rb +6 -0
  46. data/app/models/spree/promotion_handler/cart.rb +14 -18
  47. data/app/models/spree/promotion_handler/coupon.rb +1 -1
  48. data/app/models/spree/promotion_rule.rb +0 -1
  49. data/app/models/spree/property.rb +0 -2
  50. data/app/models/spree/refund.rb +0 -15
  51. data/app/models/spree/reimbursement.rb +4 -4
  52. data/app/models/spree/reimbursement_type/credit.rb +1 -1
  53. data/app/models/spree/reimbursement_type/original_payment.rb +1 -1
  54. data/app/models/spree/return_authorization.rb +4 -11
  55. data/app/models/spree/return_item.rb +16 -11
  56. data/app/models/spree/return_item/eligibility_validator/default.rb +2 -0
  57. data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +16 -0
  58. data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +16 -0
  59. data/app/models/spree/shipment.rb +20 -31
  60. data/app/models/spree/shipment_handler.rb +1 -1
  61. data/app/models/spree/shipping_method.rb +12 -13
  62. data/app/models/spree/state.rb +7 -0
  63. data/app/models/spree/state_change.rb +1 -6
  64. data/app/models/spree/stock/availability_validator.rb +9 -10
  65. data/app/models/spree/stock/coordinator.rb +1 -1
  66. data/app/models/spree/stock/estimator.rb +6 -6
  67. data/app/models/spree/stock/quantifier.rb +1 -1
  68. data/app/models/spree/stock_item.rb +1 -7
  69. data/app/models/spree/stock_location.rb +3 -1
  70. data/app/models/spree/stock_movement.rb +1 -8
  71. data/app/models/spree/stock_transfer.rb +11 -5
  72. data/app/models/spree/store.rb +2 -2
  73. data/app/models/spree/tax_rate.rb +30 -55
  74. data/app/models/spree/taxon.rb +8 -8
  75. data/app/models/spree/taxonomy.rb +8 -13
  76. data/app/models/spree/tracker.rb +1 -1
  77. data/app/models/spree/variant.rb +6 -15
  78. data/app/models/spree/zone.rb +43 -9
  79. data/config/initializers/user_class_extensions.rb +0 -12
  80. data/config/locales/en.yml +76 -85
  81. data/config/routes.rb +1 -1
  82. data/db/default/spree/countries.rb +23 -13
  83. data/db/default/spree/states.rb +24 -12
  84. data/db/default/spree/stores.rb +1 -1
  85. data/db/migrate/20120831092320_spree_one_two.rb +36 -36
  86. data/db/migrate/20120831092359_spree_promo_one_two.rb +1 -1
  87. data/db/migrate/20130211190146_create_spree_stock_items.rb +1 -1
  88. data/db/migrate/20130211191120_create_spree_stock_locations.rb +1 -1
  89. data/db/migrate/20130301162924_create_shipping_method_categories.rb +1 -1
  90. data/db/migrate/20130304162240_create_spree_shipping_rates.rb +1 -1
  91. data/db/migrate/20130305143310_create_stock_movements.rb +1 -1
  92. data/db/migrate/20130418125341_create_spree_stock_transfers.rb +1 -1
  93. data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +1 -1
  94. data/db/migrate/20140309024355_create_spree_stores.rb +1 -1
  95. data/db/migrate/20140309033438_create_store_from_preferences.rb +0 -7
  96. data/db/migrate/20140625214618_create_spree_refunds.rb +1 -1
  97. data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +1 -1
  98. data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +1 -1
  99. data/db/migrate/20140713140527_create_spree_refund_reasons.rb +1 -1
  100. data/db/migrate/20140715182625_create_spree_promotion_categories.rb +1 -1
  101. data/db/migrate/20140718133010_create_spree_customer_returns.rb +1 -1
  102. data/db/migrate/20140725131539_create_spree_reimbursements.rb +1 -1
  103. data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +1 -1
  104. data/db/migrate/20140911173301_add_kind_to_zone.rb +11 -0
  105. data/db/migrate/20141215232040_remove_token_permissions_table.rb +6 -0
  106. data/db/migrate/20141215235502_remove_extra_products_slug_index.rb +5 -0
  107. data/db/migrate/20141217215630_update_product_slug_index.rb +6 -0
  108. data/db/migrate/20141218025915_rename_identifier_to_number_for_payment.rb +5 -0
  109. data/db/migrate/20150121022521_remove_environment_from_payment_method.rb +6 -0
  110. data/db/migrate/20150122145607_add_resellable_to_return_items.rb +5 -0
  111. data/db/migrate/20150122202432_add_code_to_spree_promotion_categories.rb +5 -0
  112. data/db/migrate/20150128032538_remove_environment_from_tracker.rb +6 -0
  113. data/db/migrate/20150128060325_remove_spree_configurations.rb +16 -0
  114. data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
  115. data/lib/generators/spree/install/templates/config/initializers/spree.rb +4 -0
  116. data/lib/spree/core.rb +2 -12
  117. data/lib/spree/core/controller_helpers/respond_with.rb +8 -18
  118. data/lib/spree/core/engine.rb +1 -7
  119. data/lib/spree/core/routes.rb +1 -1
  120. data/lib/spree/core/version.rb +1 -1
  121. data/lib/spree/money.rb +10 -10
  122. data/lib/spree/permitted_attributes.rb +4 -8
  123. data/lib/spree/testing_support/authorization_helpers.rb +3 -5
  124. data/lib/spree/testing_support/capybara_ext.rb +3 -3
  125. data/lib/spree/testing_support/common_rake.rb +2 -2
  126. data/lib/spree/testing_support/factories/order_factory.rb +3 -13
  127. data/lib/spree/testing_support/factories/payment_method_factory.rb +0 -3
  128. data/lib/spree/testing_support/factories/prototype_factory.rb +5 -0
  129. data/lib/spree/testing_support/factories/return_item_factory.rb +5 -1
  130. data/lib/spree/testing_support/factories/stock_location_factory.rb +3 -3
  131. data/lib/spree/testing_support/factories/tracker_factory.rb +0 -1
  132. data/lib/spree/testing_support/factories/user_factory.rb +1 -1
  133. data/lib/spree/testing_support/factories/zone_factory.rb +8 -0
  134. data/lib/tasks/core.rake +1 -1
  135. data/lib/tasks/email.rake +6 -3
  136. metadata +48 -35
  137. data/app/helpers/spree/checkout_helper.rb +0 -31
  138. data/app/helpers/spree/orders_helper.rb +0 -17
  139. data/app/helpers/spree/store_helper.rb +0 -16
  140. data/app/helpers/spree/taxons_helper.rb +0 -19
  141. data/app/models/concerns/spree/ransackable_attributes.rb +0 -19
  142. data/app/models/friendly_id/slug_decorator.rb +0 -3
  143. data/app/models/spree/billing_integration.rb +0 -21
  144. data/app/models/spree/configuration.rb +0 -5
  145. data/app/models/spree/item_adjustments.rb +0 -82
  146. data/app/models/spree/order_merger.rb +0 -65
  147. data/app/models/spree/order_populator.rb +0 -43
  148. data/app/models/spree/product_scope/scopes.rb +0 -47
  149. data/app/models/spree/variant/scopes.rb +0 -42
  150. data/db/migrate/20150515211137_fix_adjustment_order_id.rb +0 -70
  151. data/db/migrate/20150522181728_add_deleted_at_to_friendly_id_slugs.rb +0 -6
  152. data/db/migrate/20150707204155_enable_acts_as_paranoid_on_calculators.rb +0 -6
  153. data/lib/spree/core/controller_helpers/ssl.rb +0 -60
  154. data/lib/spree/core/permalinks.rb +0 -71
  155. data/lib/spree/testing_support/factories/configuration_factory.rb +0 -6
@@ -1,17 +0,0 @@
1
- require 'truncate_html'
2
- require 'app/helpers/truncate_html_helper'
3
-
4
- module Spree
5
- module OrdersHelper
6
- include TruncateHtmlHelper
7
-
8
- def truncated_product_description(product)
9
- truncate_html(raw(product.description))
10
- end
11
-
12
- def order_just_completed?(order)
13
- flash[:order_completed] && order.present?
14
- end
15
- end
16
- end
17
-
@@ -1,16 +0,0 @@
1
- # Methods added to this helper will be available to all templates in the frontend.
2
- module Spree
3
- module StoreHelper
4
-
5
- # helper to determine if its appropriate to show the store menu
6
- def store_menu?
7
- %w{thank_you}.exclude? params[:action]
8
- end
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
- "#{I18n.locale}/taxons/#{parts}"
14
- end
15
- end
16
- end
@@ -1,19 +0,0 @@
1
- module Spree
2
- module TaxonsHelper
3
- # Retrieves the collection of products to display when "previewing" a taxon. This is abstracted into a helper so
4
- # that we can use configurations as well as make it easier for end users to override this determination. One idea is
5
- # to show the most popular products for a particular taxon (that is an exercise left to the developer.)
6
- def taxon_preview(taxon, max=4)
7
- products = taxon.active_products.select("DISTINCT (spree_products.id), spree_products.*, spree_products_taxons.position").limit(max)
8
- if (products.size < max)
9
- products_arel = Spree::Product.arel_table
10
- taxon.descendants.each do |taxon|
11
- to_get = max - products.length
12
- products += taxon.active_products.select("DISTINCT (spree_products.id), spree_products.*, spree_products_taxons.position").where(products_arel[:id].not_in(products.map(&:id))).limit(to_get)
13
- break if products.size >= max
14
- end
15
- end
16
- products
17
- end
18
- end
19
- end
@@ -1,19 +0,0 @@
1
- module Spree::RansackableAttributes
2
- extend ActiveSupport::Concern
3
- included do
4
- class_attribute :whitelisted_ransackable_associations
5
- class_attribute :whitelisted_ransackable_attributes
6
-
7
- class_attribute :default_ransackable_attributes
8
- self.default_ransackable_attributes = %w[id name]
9
-
10
- def self.ransackable_associations(*args)
11
- self.whitelisted_ransackable_associations || []
12
- end
13
-
14
- def self.ransackable_attributes(*args)
15
- self.default_ransackable_attributes | (self.whitelisted_ransackable_attributes || [])
16
- end
17
- end
18
-
19
- end
@@ -1,3 +0,0 @@
1
- FriendlyId::Slug.class_eval do
2
- acts_as_paranoid
3
- end
@@ -1,21 +0,0 @@
1
- module Spree
2
- class BillingIntegration < PaymentMethod
3
- validates :name, presence: true
4
-
5
- preference :server, :string, default: 'test'
6
- preference :test_mode, :boolean, default: true
7
-
8
- def provider
9
- integration_options = options
10
- ActiveMerchant::Billing::Base.integration_mode = integration_options[:server].to_sym
11
- integration_options[:test] = true if integration_options[:test_mode]
12
- @provider ||= provider_class.new(integration_options)
13
- end
14
-
15
- def options
16
- options_hash = {}
17
- preferences.each { |key, value| options_hash[key.to_sym] = value }
18
- options_hash
19
- end
20
- end
21
- end
@@ -1,5 +0,0 @@
1
- module Spree
2
- class Configuration < Spree::Base
3
-
4
- end
5
- end
@@ -1,82 +0,0 @@
1
- module Spree
2
- # Manage (recalculate) item (LineItem or Shipment) adjustments
3
- class ItemAdjustments
4
- include ActiveSupport::Callbacks
5
- define_callbacks :promo_adjustments, :tax_adjustments
6
- attr_reader :item
7
-
8
- delegate :adjustments, :order, to: :item
9
-
10
- def initialize(item)
11
- @item = item
12
-
13
- # Don't attempt to reload the item from the DB if it's not there
14
- @item.reload if @item.instance_of?(Shipment) && @item.persisted?
15
- end
16
-
17
- def update
18
- update_adjustments if item.persisted?
19
- item
20
- end
21
-
22
- # TODO this should be probably the place to calculate proper item taxes
23
- # values after promotions are applied
24
- def update_adjustments
25
- # Promotion adjustments must be applied first, then tax adjustments.
26
- # This fits the criteria for VAT tax as outlined here:
27
- # http://www.hmrc.gov.uk/vat/managing/charging/discounts-etc.htm#1
28
- #
29
- # It also fits the criteria for sales tax as outlined here:
30
- # http://www.boe.ca.gov/formspubs/pub113/
31
- #
32
- # Tax adjustments come in not one but *two* exciting flavours:
33
- # Included & additional
34
-
35
- # Included tax adjustments are those which are included in the price.
36
- # These ones should not affect the eventual total price.
37
- #
38
- # Additional tax adjustments are the opposite, affecting the final total.
39
- promo_total = 0
40
- run_callbacks :promo_adjustments do
41
- promotion_total = adjustments.promotion.reload.map do |adjustment|
42
- adjustment.update!(@item)
43
- end.compact.sum
44
-
45
- unless promotion_total == 0
46
- choose_best_promotion_adjustment
47
- end
48
- promo_total = best_promotion_adjustment.try(:amount).to_f
49
- end
50
-
51
- included_tax_total = 0
52
- additional_tax_total = 0
53
- run_callbacks :tax_adjustments do
54
- tax = (item.respond_to?(:all_adjustments) ? item.all_adjustments : item.adjustments).tax
55
- included_tax_total = tax.is_included.reload.map(&:update!).compact.sum
56
- additional_tax_total = tax.additional.reload.map(&:update!).compact.sum
57
- end
58
-
59
- item.update_columns(
60
- :promo_total => promo_total,
61
- :included_tax_total => included_tax_total,
62
- :additional_tax_total => additional_tax_total,
63
- :adjustment_total => promo_total + additional_tax_total,
64
- :updated_at => Time.now,
65
- )
66
- end
67
-
68
- # Picks one (and only one) promotion to be eligible for this order
69
- # This promotion provides the most discount, and if two promotions
70
- # have the same amount, then it will pick the latest one.
71
- def choose_best_promotion_adjustment
72
- if best_promotion_adjustment
73
- other_promotions = self.adjustments.promotion.where.not(id: best_promotion_adjustment.id)
74
- other_promotions.update_all(:eligible => false)
75
- end
76
- end
77
-
78
- def best_promotion_adjustment
79
- @best_promotion_adjustment ||= adjustments.promotion.eligible.reorder("amount ASC, created_at DESC, id DESC").first
80
- end
81
- end
82
- end
@@ -1,65 +0,0 @@
1
- module Spree
2
- class OrderMerger
3
- attr_accessor :order
4
- delegate :updater, to: :order
5
-
6
- def initialize(order)
7
- @order = order
8
- end
9
-
10
- def merge!(other_order, user = nil)
11
- other_order.line_items.each do |other_order_line_item|
12
- next unless other_order_line_item.currency == order.currency
13
-
14
- current_line_item = find_matching_line_item(other_order_line_item)
15
- handle_merge(current_line_item, other_order_line_item)
16
- end
17
-
18
- set_user(user)
19
- persist_merge
20
-
21
- # So that the destroy doesn't take out line items which may have been re-assigned
22
- other_order.line_items.reload
23
- other_order.destroy
24
- end
25
-
26
- # Compare the line item of the other order with mine.
27
- # Make sure you allow any extensions to chime in on whether or
28
- # not the extension-specific parts of the line item match
29
- def find_matching_line_item(other_order_line_item)
30
- order.line_items.detect do |my_li|
31
- my_li.variant == other_order_line_item.variant &&
32
- order.line_item_comparison_hooks.all? do |hook|
33
- order.send(hook, my_li, other_order_line_item.serializable_hash)
34
- end
35
- end
36
- end
37
-
38
- def set_user(user = nil)
39
- order.associate_user!(user) if !order.user && !user.blank?
40
- end
41
-
42
- # The idea is the end developer can choose to override the merge
43
- # to their own choosing. Default is merge with errors.
44
- def handle_merge(current_line_item, other_order_line_item)
45
- if current_line_item
46
- current_line_item.quantity += other_order_line_item.quantity
47
- handle_error(current_line_item) unless current_line_item.save
48
- else
49
- other_order_line_item.order_id = order.id
50
- handle_error(other_order_line_item) unless other_order_line_item.save
51
- end
52
- end
53
-
54
- # Change the error messages as you choose.
55
- def handle_error(line_item)
56
- order.errors[:base] << line_item.errors.full_messages
57
- end
58
-
59
- def persist_merge
60
- updater.update_item_count
61
- updater.update_item_total
62
- updater.persist_totals
63
- end
64
- end
65
- end
@@ -1,43 +0,0 @@
1
- module Spree
2
- class OrderPopulator
3
- attr_accessor :order, :currency
4
- attr_reader :errors
5
-
6
- def initialize(order, currency)
7
- @order = order
8
- @currency = currency
9
- @errors = ActiveModel::Errors.new(self)
10
- end
11
-
12
- def populate(variant_id, quantity, options = {})
13
- ActiveSupport::Deprecation.warn "OrderPopulator is deprecated and will be removed from Spree 3, use OrderContents with order.contents.add instead.", caller
14
- # protect against passing a nil hash being passed in
15
- # due to an empty params[:options]
16
- attempt_cart_add(variant_id, quantity, options || {})
17
- valid?
18
- end
19
-
20
- def valid?
21
- errors.empty?
22
- end
23
-
24
- private
25
-
26
- def attempt_cart_add(variant_id, quantity, options = {})
27
- quantity = quantity.to_i
28
- # 2,147,483,647 is crazy.
29
- # See issue #2695.
30
- if quantity > 2_147_483_647
31
- errors.add(:base, Spree.t(:please_enter_reasonable_quantity, scope: :order_populator))
32
- return false
33
- end
34
-
35
- variant = Spree::Variant.find(variant_id)
36
- begin
37
- @order.contents.add(variant, quantity, options.merge(currency: currency))
38
- rescue ActiveRecord::RecordInvalid => e
39
- errors.add(:base, e.record.errors.messages.values.join(" "))
40
- end
41
- end
42
- end
43
- end
@@ -1,47 +0,0 @@
1
- module Spree
2
- class ProductScope < Spree::Base
3
- before_validation(:on => :create) do
4
- # Add default empty arguments so scope validates and errors aren't caused when previewing it
5
- if name && args = self.class.arguments_for_scope_name(name)
6
- self.arguments ||= ['']*args.length
7
- end
8
- end
9
-
10
- def self.all_scopes
11
- {
12
- # Scopes for selecting products based on taxon
13
- :taxon => {
14
- :taxons_name_eq => [:taxon_name],
15
- :in_taxons => [:taxon_names],
16
- },
17
- # product selection based on name, or search
18
- :search => {
19
- :in_name => [:words],
20
- :in_name_or_keywords => [:words],
21
- :in_name_or_description => [:words],
22
- :with_ids => [:ids]
23
- },
24
- # Scopes for selecting products based on option types and properties
25
- :values => {
26
- :with => [:value],
27
- :with_property => [:property],
28
- :with_property_value => [:property, :value],
29
- :with_option => [:option],
30
- :with_option_value => [:option, :value],
31
- },
32
- # product selection based upon master price
33
- :price => {
34
- :price_between => [:low, :high],
35
- :master_price_lte => [:amount],
36
- :master_price_gte => [:amount],
37
- },
38
- }
39
- end
40
-
41
- def self.arguments_for_scope_name(name)
42
- if group = all_scopes.detect { |k,v| v[name.to_sym] }
43
- group[1][name.to_sym]
44
- end
45
- end
46
- end
47
- end
@@ -1,42 +0,0 @@
1
- module Spree
2
- class Variant < Spree::Base
3
- #FIXME WARNING tested only under sqlite and postgresql
4
- scope :descend_by_popularity, -> {
5
- ActiveSupport::Deprecation.warn "Variant.descend_by_popularity is deprecated and will be removed from Spree 3.", caller
6
- order("COALESCE((SELECT COUNT(*) FROM #{LineItem.quoted_table_name} GROUP BY #{LineItem.quoted_table_name}.variant_id HAVING #{LineItem.quoted_table_name}.variant_id = #{Variant.quoted_table_name}.id), 0) DESC")
7
- }
8
-
9
- class << self
10
- # Returns variants that match a given option value
11
- #
12
- # Example:
13
- #
14
- # product.variants_including_master.has_option(OptionType.find_by(name: 'shoe-size'), OptionValue.find_by(name: '8'))
15
- def has_option(option_type, *option_values)
16
- ActiveSupport::Deprecation.warn "Variant.descend_by_popularity is deprecated and will be removed from Spree 3.", caller
17
- option_types = OptionType.table_name
18
-
19
- option_type_conditions = case option_type
20
- when OptionType then { "#{option_types}.name" => option_type.name }
21
- when String then { "#{option_types}.name" => option_type }
22
- else { "#{option_types}.id" => option_type }
23
- end
24
-
25
- relation = joins(:option_values => :option_type).where(option_type_conditions)
26
-
27
- option_values_conditions = option_values.each do |option_value|
28
- option_value_conditions = case option_value
29
- when OptionValue then { "#{OptionValue.table_name}.name" => option_value.name }
30
- when String then { "#{OptionValue.table_name}.name" => option_value }
31
- else { "#{OptionValue.table_name}.id" => option_value }
32
- end
33
- relation = relation.where(option_value_conditions)
34
- end
35
-
36
- relation
37
- end
38
-
39
- alias_method :has_options, :has_option
40
- end
41
- end
42
- end
@@ -1,70 +0,0 @@
1
- class FixAdjustmentOrderId < ActiveRecord::Migration
2
- def change
3
- say 'Populate order_id from adjustable_id where appropriate'
4
- execute(<<-SQL.squish)
5
- UPDATE
6
- spree_adjustments
7
- SET
8
- order_id = adjustable_id
9
- WHERE
10
- adjustable_type = 'Spree::Order'
11
- ;
12
- SQL
13
-
14
- # Submitter of change does not care about MySQL, as it is not officially supported.
15
- # Still spree officials decided to provide a working code path for MySQL users, hence
16
- # submitter made a AR code path he could validate on PostgreSQL.
17
- #
18
- # Whoever runs a big enough MySQL installation where the AR solution hurts:
19
- # Will have to write a better MySQL specific equivalent.
20
- if Spree::Order.connection.adapter_name.eql?('MySQL')
21
- Spree::Adjustment.where(adjustable_type: 'Spree::LineItem').find_each do |adjustment|
22
- adjustment.update_columns(order_id: Spree::LineItem.find(adjustment.adjustable_id).order_id)
23
- end
24
- else
25
- execute(<<-SQL.squish)
26
- UPDATE
27
- spree_adjustments
28
- SET
29
- order_id =
30
- (SELECT order_id FROM spree_line_items WHERE spree_line_items.id = spree_adjustments.adjustable_id)
31
- WHERE
32
- adjustable_type = 'Spree::LineItem'
33
- SQL
34
- end
35
-
36
- say 'Fix schema for spree_adjustments order_id column'
37
- change_table :spree_adjustments do |t|
38
- t.change :order_id, :integer, null: false
39
- end
40
-
41
- # Improved schema for postgresql, uncomment if you like it:
42
- #
43
- # # Negated Logical implication.
44
- # #
45
- # # When adjustable_type is 'Spree::Order' (p) the adjustable_id must be order_id (q).
46
- # #
47
- # # When adjustable_type is NOT 'Spree::Order' the adjustable id allowed to be any value (including of order_id in
48
- # # case foreign keys match). XOR does not work here.
49
- # #
50
- # # Postgresql does not have an operator for logical implication. So we need to build the following truth table
51
- # # via AND with OR:
52
- # #
53
- # # p q | CHECK = !(p -> q)
54
- # # -----------
55
- # # t t | t
56
- # # t f | f
57
- # # f t | t
58
- # # f f | t
59
- # #
60
- # # According to de-morgans law the logical implication q -> p is equivalent to !p || q
61
- # #
62
- # execute(<<-SQL.squish)
63
- # ALTER TABLE ONLY spree_adjustments
64
- # ADD CONSTRAINT fk_spree_adjustments FOREIGN KEY (order_id)
65
- # REFERENCES spree_orders(id) ON UPDATE RESTRICT ON DELETE RESTRICT,
66
- # ADD CONSTRAINT check_spree_adjustments_order_id CHECK
67
- # (adjustable_type <> 'Spree::Order' OR order_id = adjustable_id);
68
- # SQL
69
- end
70
- end