spree_core 2.4.10 → 3.0.0.rc1

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 (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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 920d1116f3ab6e3411d25cbb20a68d9a3219dc54
4
- data.tar.gz: 5ce011d689d7dc2c8b5daa7af24fa35cda922a75
3
+ metadata.gz: 599174c8bcc4c415e7a65af40048eeff77e07147
4
+ data.tar.gz: f0b4346703e8ff979bc55c7ba86204e5878d163c
5
5
  SHA512:
6
- metadata.gz: 1904b47e5b0daea447eac9c638e2ea0b781758ed32e8f8e30f07e361bfa1e8bfbdce55d100f2678043d6bbe80a2ef3a130628d5b619790d615d6cd1830108392
7
- data.tar.gz: bcad22a5914ca2dfc426588ec7ccaaefe6169801d4f8b3e0366e3f71b517e1042e84a60d819bd0eed13d39b76ca435c93359fc1dafa854c05f9303e0832ed227
6
+ metadata.gz: a20e56fe585721fd0daea6ae733b0cadcd53273e9f44aaf0e783e62b11bf1bf8d2dc1c00e06e5cc6d2de55099e54b1ed62f6162e402039946f00c547a75e8334
7
+ data.tar.gz: 0547cb6578f56c46bbbe61fdb6a920e74cca7e79b5fbcca9d8dfab376b5ae97a827571a3ba9a4737ac99dd6765797f69f4538604af0c9009b33493a7a371e7ce
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007-2014, Spree Commerce, Inc. and other contributors
1
+ Copyright (c) 2007-2015, Spree Commerce, Inc. and other contributors
2
2
  All rights reserved.
3
3
 
4
4
  Redistribution and use in source and binary forms, with or without modification,
@@ -4,7 +4,6 @@ require_dependency 'spree/core/controller_helpers/strong_parameters'
4
4
  class Spree::BaseController < ApplicationController
5
5
  include Spree::Core::ControllerHelpers::Auth
6
6
  include Spree::Core::ControllerHelpers::RespondWith
7
- include Spree::Core::ControllerHelpers::SSL
8
7
  include Spree::Core::ControllerHelpers::Common
9
8
  include Spree::Core::ControllerHelpers::Search
10
9
  include Spree::Core::ControllerHelpers::Store
@@ -13,4 +12,4 @@ class Spree::BaseController < ApplicationController
13
12
  respond_to :html
14
13
  end
15
14
 
16
- require 'spree/i18n/initializer'
15
+ require 'spree/i18n/initializer'
@@ -1,35 +1,37 @@
1
1
  module Spree
2
2
  module BaseHelper
3
3
 
4
- # Defined because Rails' current_page? helper is not working when Spree is mounted at root.
5
- def current_spree_page?(url)
6
- path = request.fullpath.gsub(/^\/\//, '/')
7
- if url.is_a?(String)
8
- return path == url
9
- elsif url.is_a?(Hash)
10
- return path == spree.url_for(url)
4
+ def available_countries
5
+ checkout_zone = Zone.find_by(name: Spree::Config[:checkout_zone])
6
+
7
+ if checkout_zone && checkout_zone.kind == 'country'
8
+ countries = checkout_zone.country_list
9
+ else
10
+ countries = Country.all
11
11
  end
12
- return false
12
+
13
+ countries.collect do |country|
14
+ country.name = Spree.t(country.iso, scope: 'country_names', default: country.name)
15
+ country
16
+ end.sort_by { |c| c.name.parameterize }
13
17
  end
14
18
 
15
- def link_to_cart(text = nil)
16
- text = text ? h(text) : Spree.t('cart')
17
- css_class = nil
19
+ def display_price(product_or_variant)
20
+ product_or_variant.price_in(current_currency).display_price.to_html
21
+ end
18
22
 
19
- if simple_current_order.nil? or simple_current_order.item_count.zero?
20
- text = "#{text}: (#{Spree.t('empty')})"
21
- css_class = 'empty'
23
+ def link_to_tracking(shipment, options = {})
24
+ return unless shipment.tracking && shipment.shipping_method
25
+
26
+ if shipment.tracking_url
27
+ link_to(shipment.tracking, shipment.tracking_url, options)
22
28
  else
23
- text = "#{text}: (#{simple_current_order.item_count}) <span class='amount'>#{simple_current_order.display_total.to_html}</span>"
24
- css_class = 'full'
29
+ content_tag(:span, shipment.tracking)
25
30
  end
26
-
27
- link_to text.html_safe, spree.cart_path, :class => "cart-info #{css_class}"
28
31
  end
29
32
 
30
- # human readable list of variant options
31
- def variant_options(v, options={})
32
- v.options_text
33
+ def logo(image_path=Spree::Config[:logo])
34
+ link_to image_tag(image_path), spree.root_path
33
35
  end
34
36
 
35
37
  def meta_data
@@ -58,101 +60,6 @@ module Spree
58
60
  end.join("\n")
59
61
  end
60
62
 
61
- def body_class
62
- @body_class ||= content_for?(:sidebar) ? 'two-col' : 'one-col'
63
- @body_class
64
- end
65
-
66
- def logo(image_path=Spree::Config[:logo])
67
- link_to image_tag(image_path), spree.root_path
68
- end
69
-
70
- def flash_messages(opts = {})
71
- ignore_types = ["order_completed"].concat(Array(opts[:ignore_types]).map(&:to_s) || [])
72
-
73
- flash.each do |msg_type, text|
74
- unless ignore_types.include?(msg_type)
75
- concat(content_tag :div, text, class: "flash #{msg_type}")
76
- end
77
- end
78
- nil
79
- end
80
-
81
- def breadcrumbs(taxon, separator="&nbsp;&raquo;&nbsp;", breadcrumb_class="inline")
82
- return "" if current_page?("/") || taxon.nil?
83
-
84
- crumbs = [[Spree.t(:home), spree.root_path]]
85
-
86
- if taxon
87
- crumbs << [Spree.t(:products), products_path]
88
- crumbs += taxon.ancestors.collect { |a| [a.name, spree.nested_taxons_path(a.permalink)] } unless taxon.ancestors.empty?
89
- crumbs << [taxon.name, spree.nested_taxons_path(taxon.permalink)]
90
- else
91
- crumbs << [Spree.t(:products), products_path]
92
- end
93
-
94
- separator = raw(separator)
95
-
96
- crumbs.map! do |crumb|
97
- content_tag(:li, itemscope:"itemscope", itemtype:"http://data-vocabulary.org/Breadcrumb") do
98
- link_to(crumb.last, itemprop: "url") do
99
- content_tag(:span, crumb.first, itemprop: "title")
100
- end + (crumb == crumbs.last ? '' : separator)
101
- end
102
- end
103
-
104
- content_tag(:nav, content_tag(:ul, raw(crumbs.map(&:mb_chars).join), class: breadcrumb_class), id: 'breadcrumbs', class: 'sixteen columns')
105
- end
106
-
107
- def taxons_tree(root_taxon, current_taxon, max_level = 1)
108
- return '' if max_level < 1 || root_taxon.leaf?
109
- content_tag :ul, class: 'taxons-list' do
110
- root_taxon.children.map do |taxon|
111
- css_class = (current_taxon && current_taxon.self_and_ancestors.include?(taxon)) ? 'current' : nil
112
- content_tag :li, class: css_class do
113
- link_to(taxon.name, seo_url(taxon)) +
114
- taxons_tree(taxon, current_taxon, max_level - 1)
115
- end
116
- end.join("\n").html_safe
117
- end
118
- end
119
-
120
- def available_countries
121
- checkout_zone = Zone.find_by(name: Spree::Config[:checkout_zone])
122
-
123
- if checkout_zone && checkout_zone.kind == 'country'
124
- countries = checkout_zone.country_list
125
- else
126
- countries = Country.all
127
- end
128
-
129
- countries.collect do |country|
130
- country.name = Spree.t(country.iso, scope: 'country_names', default: country.name)
131
- country
132
- end.sort_by { |c| c.name.parameterize }
133
- end
134
-
135
- def seo_url(taxon)
136
- return spree.nested_taxons_path(taxon.permalink)
137
- end
138
-
139
- def gem_available?(name)
140
- Gem::Specification.find_by_name(name)
141
- rescue Gem::LoadError
142
- false
143
- rescue
144
- Gem.available?(name)
145
- end
146
-
147
- def display_price(product_or_variant)
148
- product_or_variant.price_in(current_currency).display_price.to_html
149
- end
150
-
151
- def pretty_time(time)
152
- [I18n.l(time.to_date, format: :long),
153
- time.strftime("%l:%M %p")].join(" ")
154
- end
155
-
156
63
  def method_missing(method_name, *args, &block)
157
64
  if image_style = image_style_from_method_name(method_name)
158
65
  define_image_method(image_style)
@@ -162,26 +69,21 @@ module Spree
162
69
  end
163
70
  end
164
71
 
165
- def link_to_tracking(shipment, options = {})
166
- return unless shipment.tracking && shipment.shipping_method
167
-
168
- if shipment.tracking_url
169
- link_to(shipment.tracking, shipment.tracking_url, options)
170
- else
171
- content_tag(:span, shipment.tracking)
172
- end
72
+ def pretty_time(time)
73
+ [I18n.l(time.to_date, format: :long), time.strftime("%l:%M %p")].join(" ")
173
74
  end
174
75
 
175
- private
76
+ def seo_url(taxon)
77
+ return spree.nested_taxons_path(taxon.permalink)
78
+ end
176
79
 
177
- # Returns style of image or nil
178
- def image_style_from_method_name(method_name)
179
- if method_name.to_s.match(/_image$/) && style = method_name.to_s.sub(/_image$/, '')
180
- possible_styles = Spree::Image.attachment_definitions[:attachment][:styles]
181
- style if style.in? possible_styles.with_indifferent_access
182
- end
80
+ # human readable list of variant options
81
+ def variant_options(v, options={})
82
+ v.options_text
183
83
  end
184
84
 
85
+ private
86
+
185
87
  def create_product_image_tag(image, product, options, style)
186
88
  options.reverse_merge! alt: image.alt.blank? ? product.name : image.alt
187
89
  image_tag image.attachment.url(style), options
@@ -205,5 +107,13 @@ module Spree
205
107
  end
206
108
  end
207
109
  end
110
+
111
+ # Returns style of image or nil
112
+ def image_style_from_method_name(method_name)
113
+ if method_name.to_s.match(/_image$/) && style = method_name.to_s.sub(/_image$/, '')
114
+ possible_styles = Spree::Image.attachment_definitions[:attachment][:styles]
115
+ style if style.in? possible_styles.with_indifferent_access
116
+ end
117
+ end
208
118
  end
209
119
  end
@@ -45,7 +45,7 @@ module Spree
45
45
 
46
46
  def line_item_description_text description_text
47
47
  if description_text.present?
48
- truncate(strip_tags(description_text.gsub('&nbsp;', ' ').squish), length: 100)
48
+ truncate(strip_tags(description_text.gsub('&nbsp;', ' ')), length: 100)
49
49
  else
50
50
  Spree.t(:product_has_no_description)
51
51
  end
@@ -3,21 +3,57 @@ module Spree
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  included do
6
- def deals_with_adjustments_for_deleted_source
7
- adjustment_scope = self.adjustments.includes(:order).references(:spree_orders)
8
-
9
- # For incomplete orders, remove the adjustment completely.
10
- adjustment_scope.where("spree_orders.completed_at IS NULL").destroy_all
11
-
12
- # For complete orders, the source will be invalid.
13
- # Therefore we nullify the source_id, leaving the adjustment in place.
14
- # This would mean that the order's total is not altered at all.
15
- adjustment_scope.where("spree_orders.completed_at IS NOT NULL").each do |adjustment|
16
- adjustment.update_columns(
17
- source_id: nil,
18
- updated_at: Time.now,
19
- )
20
- end
6
+ has_many :adjustments, as: :source
7
+ before_destroy :deals_with_adjustments_for_deleted_source
8
+ end
9
+
10
+ protected
11
+
12
+ def create_adjustment(order, adjustable, included = nil)
13
+ amount = compute_amount(adjustable)
14
+ return if amount == 0
15
+ adjustments.new(order: order,
16
+ adjustable: adjustable,
17
+ label: label(amount),
18
+ amount: amount,
19
+ included: included).save
20
+ end
21
+
22
+ def create_unique_adjustment(order, adjustable)
23
+ return if already_adjusted?(adjustable)
24
+ create_adjustment(order, adjustable)
25
+ end
26
+
27
+ def create_unique_adjustments(order, adjustables)
28
+ adjustables.where.not(id: already_adjusted_ids(order)).map do |adjustable|
29
+ create_adjustment(order, adjustable) if !block_given? || yield(adjustable)
30
+ end.any?
31
+ end
32
+
33
+ private
34
+
35
+ def already_adjusted_ids(order)
36
+ adjustments.where(order: order).pluck(:adjustable_id)
37
+ end
38
+
39
+ def already_adjusted?(adjustable)
40
+ adjustments.where(adjustable: adjustable).exists?
41
+ end
42
+
43
+ def deals_with_adjustments_for_deleted_source
44
+ adjustment_scope = adjustments.includes(:order).references(:spree_orders)
45
+
46
+ # For incomplete orders, remove the adjustment completely.
47
+ adjustment_scope.where("spree_orders.completed_at IS NULL").destroy_all
48
+
49
+ # For complete orders, the source will be invalid.
50
+ # Therefore we nullify the source_id, leaving the adjustment in place.
51
+ # This would mean that the order's total is not altered at all.
52
+ adjustment_scope.where("spree_orders.completed_at IS NOT NULL").each do |adjustment|
53
+ adjustment.update_columns(
54
+ source_id: nil,
55
+ updated_at: Time.now,
56
+ )
21
57
  end
22
58
  end
23
59
  end
@@ -6,6 +6,7 @@ module Spree
6
6
  has_one :calculator, class_name: "Spree::Calculator", as: :calculable, inverse_of: :calculable, dependent: :destroy, autosave: true
7
7
  accepts_nested_attributes_for :calculator
8
8
  validates :calculator, presence: true
9
+ delegate :compute, to: :calculator
9
10
 
10
11
  def self.calculators
11
12
  spree_calculators.send model_name_without_spree_namespace
@@ -0,0 +1,32 @@
1
+ module Spree
2
+ module DisplayMoney
3
+ ##
4
+ # Takes a list of methods that the base object wants to be able to use
5
+ # to display with Spree::Money, and turns them into display_* methods.
6
+ # Intended to help clean up some of the presentational logic that exists
7
+ # at the model layer.
8
+ #
9
+ #
10
+ # ==== Examples
11
+ # Decorate a method, with the default option of using the base object's
12
+ # currency
13
+ #
14
+ # extend Spree::DisplayMoney
15
+ # money_methods :tax_amount, :price
16
+ #
17
+ # Decorate a method, but with some additional options
18
+ # extend Spree::DisplayMoney
19
+ # money_methods tax_amount: { currency: "CAD", no_cents: true }, :price
20
+ def money_methods(*args)
21
+ args.each do |money_method|
22
+ money_method = { money_method => {} } unless money_method.is_a? Hash
23
+ money_method.each do |method_name, opts|
24
+ define_method("display_#{method_name}") do
25
+ default_opts = respond_to?(:currency) ? { currency: currency } : {}
26
+ Spree::Money.new(send(method_name), default_opts.merge(opts))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -4,7 +4,7 @@ module Spree
4
4
 
5
5
  included do
6
6
  scope :active, -> { where(active: true) }
7
- default_scope -> { order("LOWER(#{self.table_name}.name)") }
7
+ default_scope { order("LOWER(#{self.table_name}.name)") }
8
8
 
9
9
  validates :name, presence: true, uniqueness: { case_sensitive: false }
10
10
  end
@@ -0,0 +1,39 @@
1
+ module Spree
2
+ module NumberGenerator
3
+ extend ActiveSupport::Concern
4
+
5
+ NUMBER_LENGTH = 9
6
+ NUMBER_LETTERS = false
7
+ NUMBER_PREFIX = 'N'
8
+
9
+ included do
10
+ before_validation :generate_number, on: :create # generate number before make_permalink
11
+ validates :number, uniqueness: true
12
+ end
13
+
14
+ def self.by_number(number)
15
+ where(number: number)
16
+ end
17
+
18
+ def generate_number(options = {})
19
+ options[:length] ||= NUMBER_LENGTH
20
+ options[:letters] ||= NUMBER_LETTERS
21
+ options[:prefix] ||= NUMBER_PREFIX
22
+
23
+ possible = (0..9).to_a
24
+ possible += ('A'..'Z').to_a if options[:letters]
25
+
26
+ self.number ||= loop do
27
+ # Make a random number.
28
+ random = "#{options[:prefix]}#{(0...options[:length]).map { possible.shuffle.first }.join}"
29
+ # Use the random number if no other order exists with it.
30
+ if self.class.exists?(number: random)
31
+ # If over half of all possible options are taken add another digit.
32
+ options[:length] += 1 if self.class.count > (10 ** options[:length] / 2)
33
+ else
34
+ break random
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -1,13 +1,12 @@
1
1
  module Spree
2
2
  module UserReporting
3
+ extend DisplayMoney
4
+ money_methods :lifetime_value, :average_order_value
5
+
3
6
  def lifetime_value
4
7
  spree_orders.complete.pluck(:total).sum
5
8
  end
6
9
 
7
- def display_lifetime_value
8
- Spree::Money.new(lifetime_value)
9
- end
10
-
11
10
  def order_count
12
11
  BigDecimal(spree_orders.complete.count)
13
12
  end
@@ -19,9 +18,5 @@ module Spree
19
18
  BigDecimal("0.00")
20
19
  end
21
20
  end
22
-
23
- def display_average_order_value
24
- Spree::Money.new(average_order_value)
25
- end
26
21
  end
27
22
  end