spree_core 0.40.4 → 0.50.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 (251) hide show
  1. data/README.md +6 -1
  2. data/app/controllers/admin/base_controller.rb +0 -57
  3. data/app/controllers/admin/configurations_controller.rb +1 -1
  4. data/app/controllers/admin/general_settings_controller.rb +1 -1
  5. data/app/controllers/admin/images_controller.rb +18 -8
  6. data/app/controllers/admin/inventory_settings_controller.rb +1 -1
  7. data/app/controllers/admin/mail_settings_controller.rb +1 -1
  8. data/app/controllers/admin/option_types_controller.rb +11 -0
  9. data/app/controllers/admin/orders_controller.rb +16 -20
  10. data/app/controllers/admin/overview_controller.rb +1 -1
  11. data/app/controllers/admin/payment_methods_controller.rb +6 -6
  12. data/app/controllers/admin/product_groups_controller.rb +10 -11
  13. data/app/controllers/admin/product_properties_controller.rb +5 -5
  14. data/app/controllers/admin/product_scopes_controller.rb +12 -4
  15. data/app/controllers/admin/products_controller.rb +17 -12
  16. data/app/controllers/admin/properties_controller.rb +7 -7
  17. data/app/controllers/admin/prototypes_controller.rb +15 -15
  18. data/app/controllers/admin/reports_controller.rb +12 -11
  19. data/app/controllers/admin/shipments_controller.rb +0 -5
  20. data/app/controllers/admin/shipping_categories_controller.rb +6 -6
  21. data/app/controllers/admin/shipping_methods_controller.rb +1 -2
  22. data/app/controllers/admin/states_controller.rb +12 -12
  23. data/app/controllers/admin/tax_categories_controller.rb +2 -2
  24. data/app/controllers/admin/tax_rates_controller.rb +8 -8
  25. data/app/controllers/admin/tax_settings_controller.rb +1 -1
  26. data/app/controllers/admin/taxonomies_controller.rb +3 -3
  27. data/app/controllers/admin/taxons_controller.rb +1 -8
  28. data/app/controllers/admin/trackers_controller.rb +1 -1
  29. data/app/controllers/admin/users_controller.rb +6 -9
  30. data/app/controllers/admin/variants_controller.rb +13 -2
  31. data/app/controllers/admin/zones_controller.rb +9 -9
  32. data/app/controllers/checkout_controller.rb +5 -5
  33. data/app/controllers/products_controller.rb +1 -1
  34. data/app/controllers/taxons_controller.rb +3 -1
  35. data/app/helpers/admin/navigation_helper.rb +36 -19
  36. data/app/helpers/admin/payments_helper.rb +1 -1
  37. data/app/helpers/admin/product_groups_helper.rb +1 -1
  38. data/app/helpers/admin/product_properties_helper.rb +5 -5
  39. data/app/helpers/admin/products_helper.rb +2 -2
  40. data/app/helpers/admin/users_helper.rb +5 -2
  41. data/app/helpers/hook_helper.rb +3 -3
  42. data/app/helpers/products_helper.rb +0 -19
  43. data/app/helpers/spree/base_helper.rb +33 -2
  44. data/app/helpers/taxons_helper.rb +3 -3
  45. data/app/mailers/order_mailer.rb +2 -2
  46. data/app/mailers/shipment_mailer.rb +2 -2
  47. data/app/models/address.rb +42 -9
  48. data/app/models/adjustment.rb +8 -8
  49. data/app/models/app_configuration.rb +0 -6
  50. data/app/models/billing_integration.rb +1 -1
  51. data/app/models/calculator/sales_tax.rb +3 -3
  52. data/app/models/configuration.rb +1 -1
  53. data/app/models/country.rb +4 -5
  54. data/app/models/creditcard.rb +38 -31
  55. data/app/models/gateway.rb +14 -14
  56. data/app/models/gateway/beanstream.rb +4 -4
  57. data/app/models/gateway/bogus.rb +6 -6
  58. data/app/models/gateway/braintree.rb +88 -0
  59. data/app/models/gateway/eway.rb +3 -3
  60. data/app/models/image.rb +5 -4
  61. data/app/models/option_type.rb +1 -0
  62. data/app/models/order.rb +60 -21
  63. data/app/models/payment.rb +5 -32
  64. data/app/models/preference.rb +7 -7
  65. data/app/models/product.rb +22 -7
  66. data/app/models/product_group.rb +22 -26
  67. data/app/models/product_property.rb +5 -5
  68. data/app/models/product_scope.rb +26 -6
  69. data/app/models/property.rb +1 -1
  70. data/app/models/state.rb +2 -3
  71. data/app/models/tax_category.rb +1 -0
  72. data/app/models/tax_rate.rb +1 -2
  73. data/app/models/taxon.rb +12 -10
  74. data/app/models/taxonomy.rb +7 -4
  75. data/app/models/tracker.rb +1 -1
  76. data/app/models/user.rb +4 -0
  77. data/app/models/variant.rb +1 -1
  78. data/app/models/zone.rb +1 -1
  79. data/app/models/zone_member.rb +3 -3
  80. data/app/views/admin/{shared → adjustments}/_adjustments_table.html.erb +7 -4
  81. data/app/views/admin/adjustments/edit.html.erb +1 -1
  82. data/app/views/admin/adjustments/index.html.erb +2 -2
  83. data/app/views/admin/adjustments/new.html.erb +2 -1
  84. data/app/views/admin/general_settings/edit.html.erb +4 -12
  85. data/app/views/admin/general_settings/show.html.erb +0 -5
  86. data/app/views/admin/images/index.html.erb +8 -5
  87. data/app/views/admin/inventory_settings/show.html.erb +1 -1
  88. data/app/views/admin/mail_methods/index.html.erb +4 -4
  89. data/app/views/admin/option_types/_form.html.erb +4 -4
  90. data/app/views/admin/option_types/_option_value_fields.html.erb +2 -2
  91. data/app/views/admin/option_types/edit.html.erb +4 -2
  92. data/app/views/admin/option_types/index.html.erb +5 -5
  93. data/app/views/admin/orders/_line_item.html.erb +2 -1
  94. data/app/views/admin/orders/history.html.erb +6 -2
  95. data/app/views/admin/orders/index.html.erb +22 -19
  96. data/app/views/admin/orders/show.html.erb +1 -1
  97. data/app/views/admin/orders/user.html.erb +1 -1
  98. data/app/views/admin/payment_methods/index.html.erb +7 -5
  99. data/app/views/admin/payments/_list.html.erb +3 -3
  100. data/app/views/admin/payments/index.html.erb +1 -1
  101. data/app/views/admin/payments/show.html.erb +2 -2
  102. data/app/views/admin/product_groups/edit.html.erb +7 -7
  103. data/app/views/admin/product_groups/index.html.erb +5 -3
  104. data/app/views/admin/product_groups/update.js.erb +4 -3
  105. data/app/views/admin/product_properties/_product_property_fields.html.erb +3 -3
  106. data/app/views/admin/product_properties/index.html.erb +10 -5
  107. data/app/views/admin/product_scopes/destroy.js.erb +1 -0
  108. data/app/views/admin/products/index.html.erb +32 -33
  109. data/app/views/admin/properties/_form.html.erb +2 -2
  110. data/app/views/admin/properties/index.html.erb +4 -4
  111. data/app/views/admin/prototypes/index.html.erb +4 -4
  112. data/app/views/admin/shared/_address_form.html.erb +1 -1
  113. data/app/views/admin/shared/_calculator_fields.html.erb +1 -1
  114. data/app/views/admin/shared/_destroy.js.erb +15 -2
  115. data/app/views/admin/shared/_order_tabs.html.erb +1 -1
  116. data/app/views/admin/shared/_report_criteria.html.erb +1 -1
  117. data/app/views/admin/shipments/_form.html.erb +6 -2
  118. data/app/views/admin/shipments/edit.html.erb +1 -1
  119. data/app/views/admin/shipments/index.html.erb +4 -2
  120. data/app/views/admin/shipping_methods/_form.html.erb +2 -0
  121. data/app/views/admin/shipping_methods/index.html.erb +3 -2
  122. data/app/views/admin/states/_state_list.html.erb +11 -5
  123. data/app/views/admin/tax_categories/index.html.erb +9 -4
  124. data/app/views/admin/tax_settings/show.html.erb +2 -2
  125. data/app/views/admin/taxonomies/_list.html.erb +4 -2
  126. data/app/views/admin/taxonomies/index.html.erb +2 -2
  127. data/app/views/admin/taxons/_form.html.erb +1 -1
  128. data/app/views/admin/trackers/index.html.erb +5 -5
  129. data/app/views/admin/users/_form.html.erb +3 -4
  130. data/app/views/admin/users/index.html.erb +7 -6
  131. data/app/views/admin/users/show.html.erb +3 -3
  132. data/app/views/admin/variants/index.html.erb +21 -6
  133. data/app/views/admin/zones/_form.html.erb +9 -9
  134. data/app/views/admin/zones/_member_type.html.erb +5 -5
  135. data/app/views/admin/zones/index.html.erb +7 -5
  136. data/app/views/checkout/_address.html.erb +2 -2
  137. data/app/views/checkout/_payment.html.erb +3 -6
  138. data/app/views/layouts/admin.html.erb +3 -9
  139. data/app/views/layouts/spree_application.html.erb +2 -1
  140. data/app/views/orders/_line_item.html.erb +1 -1
  141. data/app/views/orders/edit.html.erb +17 -16
  142. data/app/views/orders/show.html.erb +1 -1
  143. data/app/views/shared/_admin_head.html.erb +1 -1
  144. data/app/views/shared/_error_messages.html.erb +2 -2
  145. data/app/views/shared/_filters.html.erb +4 -4
  146. data/app/views/shared/_head.html.erb +2 -2
  147. data/app/views/shared/_nav_bar.html.erb +2 -2
  148. data/app/views/shared/_products.html.erb +4 -2
  149. data/app/views/shared/_taxonomies.html.erb +15 -8
  150. data/app/views/shipment_mailer/shipped_email.text.erb +2 -2
  151. data/config/cucumber.yml +10 -0
  152. data/config/initializers/form_builder.rb +1 -5
  153. data/config/initializers/workarounds_for_ruby19.rb +5 -5
  154. data/config/locales/en.yml +33 -6
  155. data/config/routes.rb +18 -13
  156. data/db/migrate/20090923100315_add_count_on_hand_to_variants_and_products.rb +5 -5
  157. data/db/migrate/20091213222815_creditcard_last_four_digits.rb +5 -5
  158. data/db/migrate/20100105132138_shipment_id_for_inventory_units.rb +2 -2
  159. data/db/migrate/20100209025806_create_payment_methods.rb +3 -3
  160. data/db/migrate/20100209144531_polymorphic_payments.rb +1 -1
  161. data/db/migrate/20100214212536_assign_creditcard_txns_to_payment.rb +2 -2
  162. data/db/migrate/20100224153127_deleted_at_for_payment_methods.rb +1 -1
  163. data/db/migrate/20100506185838_add_description_to_taxons.rb +1 -1
  164. data/db/migrate/20100816212146_shipping_method_id_for_orders.rb +1 -1
  165. data/db/migrate/20101026184808_migrate_checkout_to_orders.rb +2 -2
  166. data/db/migrate/20101223215658_add_position_to_variants.rb +9 -0
  167. data/db/migrate/20110110130847_add_next_state_to_state_events.rb +9 -0
  168. data/db/migrate/20110111122537_add_position_to_option_types.rb +9 -0
  169. data/db/migrate/20110314192118_remove_trailing_slashes_in_taxon_permalinks.rb +17 -0
  170. data/lib/custom_fixtures.rb +1 -1
  171. data/lib/{seo_assist.rb → middleware/seo_assist.rb} +14 -8
  172. data/lib/product_filters.rb +49 -43
  173. data/lib/redirect_legacy_product_url.rb +5 -5
  174. data/lib/scopes.rb +2 -2
  175. data/lib/scopes/dynamic.rb +9 -16
  176. data/lib/scopes/product.rb +33 -16
  177. data/lib/scopes/variant.rb +4 -3
  178. data/lib/spree/calculated_adjustments.rb +5 -2
  179. data/lib/spree/config.rb +2 -0
  180. data/lib/spree/current_order.rb +4 -4
  181. data/lib/spree/mail_settings.rb +3 -2
  182. data/lib/spree/search/base.rb +9 -10
  183. data/lib/spree_base.rb +22 -23
  184. data/lib/spree_core.rb +10 -69
  185. data/lib/spree_core/authorize_net_cim_hack.rb +1 -1
  186. data/lib/spree_core/delegate_belongs_to.rb +18 -24
  187. data/lib/spree_core/enumerable_constants.rb +38 -38
  188. data/lib/spree_core/find_by_param.rb +8 -6
  189. data/lib/spree_core/preferences/preference_definition.rb +7 -7
  190. data/lib/spree_core/railtie.rb +58 -0
  191. data/lib/spree_core/ssl_requirement.rb +4 -3
  192. data/lib/spree_core/testing_support/factories.rb +13 -0
  193. data/lib/spree_core/testing_support/factories/address_factory.rb +20 -0
  194. data/lib/spree_core/testing_support/factories/adjustment_factory.rb +6 -0
  195. data/lib/spree_core/testing_support/factories/calculator_factory.rb +5 -0
  196. data/lib/spree_core/testing_support/factories/configuraion_factory.rb +4 -0
  197. data/lib/spree_core/testing_support/factories/country_factory.rb +7 -0
  198. data/lib/spree_core/testing_support/factories/creditcard_factory.rb +11 -0
  199. data/lib/spree_core/testing_support/factories/inventory_unit_factory.rb +7 -0
  200. data/lib/spree_core/testing_support/factories/line_item_factory.rb +8 -0
  201. data/lib/spree_core/testing_support/factories/mail_method_factory.rb +4 -0
  202. data/lib/spree_core/testing_support/factories/options_factory.rb +10 -0
  203. data/lib/spree_core/testing_support/factories/order_factory.rb +18 -0
  204. data/lib/spree_core/testing_support/factories/payment_factory.rb +26 -0
  205. data/lib/spree_core/testing_support/factories/payment_method_factory.rb +17 -0
  206. data/lib/spree_core/testing_support/factories/product_factory.rb +16 -0
  207. data/lib/spree_core/testing_support/factories/product_group_factory.rb +3 -0
  208. data/lib/spree_core/testing_support/factories/product_option_type_factory.rb +4 -0
  209. data/lib/spree_core/testing_support/factories/product_property_factory.rb +4 -0
  210. data/lib/spree_core/testing_support/factories/product_scope_factory.rb +6 -0
  211. data/lib/spree_core/testing_support/factories/property_factory.rb +4 -0
  212. data/lib/spree_core/testing_support/factories/prototype_factory.rb +4 -0
  213. data/lib/spree_core/testing_support/factories/return_authorization_factory.rb +8 -0
  214. data/lib/spree_core/testing_support/factories/role_factory.rb +9 -0
  215. data/lib/spree_core/testing_support/factories/shipment_factory.rb +9 -0
  216. data/lib/spree_core/testing_support/factories/shipping_category_factory.rb +5 -0
  217. data/lib/spree_core/testing_support/factories/shipping_method_factory.rb +7 -0
  218. data/lib/spree_core/testing_support/factories/state_factory.rb +11 -0
  219. data/lib/spree_core/testing_support/factories/tax_category_factory.rb +8 -0
  220. data/lib/spree_core/testing_support/factories/tax_rate_factory.rb +5 -0
  221. data/lib/spree_core/testing_support/factories/taxon_factory.rb +5 -0
  222. data/lib/spree_core/testing_support/factories/taxonomy_factory.rb +3 -0
  223. data/lib/spree_core/testing_support/factories/tracker_factory.rb +5 -0
  224. data/lib/spree_core/testing_support/factories/user_factory.rb +15 -0
  225. data/lib/spree_core/testing_support/factories/variant_factory.rb +14 -0
  226. data/lib/spree_core/testing_support/factories/zone_factory.rb +18 -0
  227. data/lib/spree_core/theme_support/hook.rb +1 -1
  228. data/lib/spree_core/theme_support/more_patches.rb +20 -20
  229. data/lib/spree_core/version.rb +5 -0
  230. data/lib/tasks/common.rb +30 -0
  231. data/lib/tasks/install.rake +1 -1
  232. data/lib/tasks/rake_util.rb +19 -0
  233. data/lib/tasks/taxon.rake +14 -0
  234. data/public/images/reorder.jpg +0 -0
  235. data/public/javascripts/admin.js +0 -6
  236. data/public/javascripts/admin/unobtrusive_handlers.js +28 -0
  237. data/public/javascripts/checkout.js +3 -3
  238. data/public/stylesheets/admin/admin-forms.css +1 -6
  239. data/public/stylesheets/admin/admin.css +0 -28
  240. data/public/stylesheets/screen.css +0 -280
  241. metadata +81 -43
  242. data/app/controllers/countries_controller.rb +0 -11
  243. data/app/models/spree/alert.rb +0 -13
  244. data/app/models/state_monitor.rb +0 -25
  245. data/app/views/admin/shared/_alert.html.erb +0 -6
  246. data/app/views/countries/index.js.erb +0 -1
  247. data/app/views/shared/_doc_and_xmlns.html.erb +0 -2
  248. data/app/views/users/edit.html.erb +0 -9
  249. data/app/views/users/show.html.erb +0 -46
  250. data/lib/spree_core/validation_group.rb +0 -143
  251. data/public/stylesheets/scaffold.css +0 -54
@@ -1,5 +1,5 @@
1
1
  class ProductsController < Spree::BaseController
2
- HTTP_REFERER_REGEXP = /^https?:\/\/[^\/]+\/t\/([a-z0-9\-\/]+\/)$/
2
+ HTTP_REFERER_REGEXP = /^https?:\/\/[^\/]+\/t\/([a-z0-9\-\/]+)$/
3
3
 
4
4
  #prepend_before_filter :reject_unknown_object, :only => [:show]
5
5
  before_filter :load_data, :only => :show
@@ -4,17 +4,19 @@ class TaxonsController < Spree::BaseController
4
4
  resource_controller
5
5
  actions :show
6
6
  helper :products
7
+ rescue_from ActiveRecord::RecordNotFound, :with => :render_404
7
8
 
8
9
  private
9
10
  def load_data
10
11
  @taxon ||= object
12
+ render_404 and return if @taxon.nil?
11
13
  params[:taxon] = @taxon.id
12
14
  @searcher = Spree::Config.searcher_class.new(params)
13
15
  @products = @searcher.retrieve_products
14
16
  end
15
17
 
16
18
  def object
17
- @object ||= end_of_association_chain.find_by_permalink(params[:id] + "/")
19
+ @object ||= end_of_association_chain.find_by_permalink(params[:id])
18
20
  end
19
21
 
20
22
  def accurate_title
@@ -39,15 +39,15 @@ module Admin::NavigationHelper
39
39
  link_to_with_icon('add', t("new"), edit_object_url(resource))
40
40
  end
41
41
 
42
- def link_to_edit(resource)
43
- link_to_with_icon('edit', t("edit"), edit_object_url(resource))
42
+ def link_to_edit(resource, options={})
43
+ link_to_with_icon('edit', t("edit"), edit_object_url(resource), options)
44
44
  end
45
45
 
46
- def link_to_clone(resource)
47
- link_to_with_icon('exclamation', t("clone"), clone_admin_product_url(resource))
46
+ def link_to_clone(resource, options={})
47
+ link_to_with_icon('exclamation', t("clone"), clone_admin_product_url(resource), options)
48
48
  end
49
49
 
50
- def link_to_delete(resource, options = {})
50
+ def link_to_delete(resource, options = {}, html_options={})
51
51
  options.assert_valid_keys(:url, :caption, :title, :dataType, :success, :name)
52
52
 
53
53
  options.reverse_merge! :url => object_url(resource) unless options.key? :url
@@ -57,25 +57,42 @@ module Admin::NavigationHelper
57
57
  options.reverse_merge! :success => "function(r){ jQuery('##{dom_id resource}').fadeOut('hide'); }"
58
58
  options.reverse_merge! :name => icon("delete") + ' ' + t("delete")
59
59
 
60
- #link_to_with_icon('delete', t("delete"), object_url(resource), :confirm => t('are_you_sure'), :method => :delete )
60
+ link_to_function_delete(options, html_options)
61
+ #link_to_function_delete_native(options, html_options)
62
+ end
63
+
64
+ # this function does not use jConfirm
65
+ def link_to_function_delete_native(options, html_options)
66
+ fn = %Q{
67
+ var answer = confirm("are you sure?");
68
+ if (!!answer) { #{link_to_function_delete_ajax(options)} };
69
+ }
70
+ link_to_function options[:name], fn, html_options
71
+ end
72
+
73
+ def link_to_function_delete(options, html_options)
61
74
  link_to_function options[:name], "jConfirm('#{options[:caption]}', '#{options[:title]}', function(r) {
62
- if(r){
63
- jQuery.ajax({
64
- type: 'POST',
65
- url: '#{options[:url]}',
66
- data: ({_method: 'delete', authenticity_token: AUTH_TOKEN}),
67
- dataType:'#{options[:dataType]}',
68
- success: #{options[:success]}
69
- });
70
- }
71
- });"
75
+ if(r){ #{link_to_function_delete_ajax(options)} }
76
+ });", html_options
77
+ end
78
+
79
+ def link_to_function_delete_ajax(options)
80
+ %Q{
81
+ jQuery.ajax({
82
+ type: 'POST',
83
+ url: '#{options[:url]}',
84
+ data: ({_method: 'delete', authenticity_token: AUTH_TOKEN}),
85
+ dataType:'#{options[:dataType]}',
86
+ success: #{options[:success]}
87
+ });
88
+ }
72
89
  end
73
90
 
74
91
  def link_to_with_icon(icon_name, text, url, options = {})
75
92
  options[:class] = (options[:class].to_s + " icon_link").strip
76
93
  link_to(icon(icon_name) + ' ' + text, url, options)
77
94
  end
78
-
95
+
79
96
  def icon(icon_name)
80
97
  icon_name ? image_tag("/images/admin/icons/#{icon_name}.png") : ''
81
98
  end
@@ -85,8 +102,8 @@ module Admin::NavigationHelper
85
102
  end
86
103
 
87
104
  def button_link_to(text, url, html_options = {})
88
- if (html_options[:method] &&
89
- html_options[:method].to_s.downcase != 'get' &&
105
+ if (html_options[:method] &&
106
+ html_options[:method].to_s.downcase != 'get' &&
90
107
  !html_options[:remote])
91
108
  form_tag(url, :method => html_options[:method]) do
92
109
  button(text, html_options[:icon])
@@ -2,6 +2,6 @@ module Admin::PaymentsHelper
2
2
  def payment_method_name(payment)
3
3
  # hack to allow us to retrieve the name of a "deleted" payment method
4
4
  id = payment.payment_method_id
5
- PaymentMethod.find_with_destroyed(id).name
5
+ PaymentMethod.find_with_destroyed(id).name
6
6
  end
7
7
  end
@@ -7,5 +7,5 @@ module Admin::ProductGroupsHelper
7
7
  helper_method_for_scope = Scopes::Product::ATTRIBUTE_HELPER_METHODS[product_scope.name.to_sym] || :text_field_tag
8
8
  send(helper_method_for_scope, name, value)
9
9
  end
10
-
10
+
11
11
  end
@@ -1,13 +1,13 @@
1
1
  module Admin::ProductPropertiesHelper
2
-
3
- # Generates the appropriate field name for attribute_fu. Normally attribute_fu handles this but we've got a
4
- # special case where we need text_field_with_autocomplete and we have to recreate attribute_fu's naming
2
+
3
+ # Generates the appropriate field name for attribute_fu. Normally attribute_fu handles this but we've got a
4
+ # special case where we need text_field_with_autocomplete and we have to recreate attribute_fu's naming
5
5
  # scheme manually.
6
6
  def property_fu_name(product_property, number)
7
7
  if product_property.new_record?
8
8
  "product[product_property_attributes][new][#{number}][property_name]"
9
9
  else
10
- "product[product_property_attributes][#{product_property.id}][property_name]"
10
+ "product[product_property_attributes][#{product_property.id}][property_name]"
11
11
  end
12
12
  end
13
13
 
@@ -15,7 +15,7 @@ module Admin::ProductPropertiesHelper
15
15
  if product_property.new_record?
16
16
  "product[product_property_attributes][new][#{number}][value]"
17
17
  else
18
- "product[product_property_attributes][#{product_property.id}][value]"
18
+ "product[product_property_attributes][#{product_property.id}][value]"
19
19
  end
20
20
  end
21
21
  end
@@ -1,7 +1,7 @@
1
1
  module Admin::ProductsHelper
2
2
  def option_type_select(so)
3
- select(:new_variant,
4
- so.option_type.presentation,
3
+ select(:new_variant,
4
+ so.option_type.presentation,
5
5
  so.option_type.option_values.collect {|ov| [ ov.presentation, ov.id ] })
6
6
  end
7
7
 
@@ -1,5 +1,8 @@
1
- module Admin::UsersHelper
1
+ module Admin::UsersHelper
2
+
2
3
  def list_roles(user)
3
- user.roles.collect {|role| role.name}.join ", "
4
+ # while testing spree-core itself user model does not have method roles
5
+ user.respond_to?(:roles) ? user.roles.collect {|role| role.name}.join(", ") : []
4
6
  end
7
+
5
8
  end
@@ -1,13 +1,13 @@
1
1
  module HookHelper
2
-
2
+
3
3
  # Allow hooks to be used in views like this:
4
- #
4
+ #
5
5
  # <%= hook :some_hook %>
6
6
  #
7
7
  # <%= hook :some_hook do %>
8
8
  # <p>Some HTML</p>
9
9
  # <% end %>
10
- #
10
+ #
11
11
  def hook(hook_name, locals = {}, &block)
12
12
  content = block_given? ? capture(&block) : ''
13
13
  Spree::ThemeSupport::Hook.render_hook(hook_name, content, self, locals)
@@ -22,28 +22,9 @@ module ProductsHelper
22
22
  options.delete(:format_as_currency) ? format_price(amount, options) : amount
23
23
  end
24
24
 
25
- def format_price(price, options={})
26
- options.assert_valid_keys(:show_vat_text)
27
- options.reverse_merge! :show_vat_text => Spree::Config[:show_price_inc_vat]
28
- formatted_price = number_to_currency(price)
29
- if options[:show_vat_text]
30
- I18n.t(:price_with_vat_included, :price => formatted_price)
31
- else
32
- formatted_price
33
- end
34
- end
35
-
36
25
  # converts line breaks in product description into <p> tags (for html display purposes)
37
26
  def product_description(product)
38
27
  raw(product.description.gsub(/^(.*)$/, '<p>\1</p>'))
39
28
  end
40
29
 
41
- # generates nested url to product based on supplied taxon
42
- def seo_url(taxon, product = nil)
43
- return '/t/' + taxon.permalink if product.nil?
44
- warn "DEPRECATION: the /t/taxon-permalink/p/product-permalink urls are "+
45
- "not used anymore. Use product_url instead. (called from #{caller[0]})"
46
- return product_url(product)
47
- end
48
-
49
30
  end
@@ -34,7 +34,6 @@ module Spree::BaseHelper
34
34
  utc_to_local(Time.now.utc.yesterday).to_ordinalized_s(:stub)
35
35
  end
36
36
 
37
-
38
37
  # human readable list of variant options
39
38
  def variant_options(v, allow_back_orders = Spree::Config[:allow_backorders], include_style = true)
40
39
  list = v.options_text
@@ -42,7 +41,7 @@ module Spree::BaseHelper
42
41
  list
43
42
  end
44
43
 
45
- [:mini, :small, :product, :large].each do |style|
44
+ Image.attachment_definitions[:attachment][:styles].each do |style, v|
46
45
  define_method "#{style}_image" do |product, *options|
47
46
  options = options.first || {}
48
47
  if product.images.empty?
@@ -83,5 +82,37 @@ module Spree::BaseHelper
83
82
  def logo(image_path=Spree::Config[:logo])
84
83
  link_to image_tag(image_path), root_path
85
84
  end
85
+
86
+ def available_countries
87
+ return Country.all unless zone = Zone.find_by_name(Spree::Config[:checkout_zone])
88
+ zone.country_list
89
+ end
90
+
91
+ def format_price(price, options={})
92
+ options.assert_valid_keys(:show_vat_text)
93
+ options.reverse_merge! :show_vat_text => Spree::Config[:show_price_inc_vat]
94
+ formatted_price = number_to_currency(price)
95
+ if options[:show_vat_text]
96
+ I18n.t(:price_with_vat_included, :price => formatted_price)
97
+ else
98
+ formatted_price
99
+ end
100
+ end
86
101
 
102
+ # generates nested url to product based on supplied taxon
103
+ def seo_url(taxon, product = nil)
104
+ return '/t/' + taxon.permalink if product.nil?
105
+ warn "DEPRECATION: the /t/taxon-permalink/p/product-permalink urls are "+
106
+ "not used anymore. Use product_url instead. (called from #{caller[0]})"
107
+ return product_url(product)
108
+ end
109
+
110
+ def current_orders_product_count
111
+ if current_order.blank? || current_order.item_count < 1
112
+ return 0
113
+ else
114
+ return current_order.item_count
115
+ end
116
+ end
117
+
87
118
  end
@@ -18,12 +18,12 @@ module TaxonsHelper
18
18
  # Retrieves the collection of products to display when "previewing" a taxon. This is abstracted into a helper so
19
19
  # that we can use configurations as well as make it easier for end users to override this determination. One idea is
20
20
  # to show the most popular products for a particular taxon (that is an exercise left to the developer.)
21
- def taxon_preview(taxon, max=5)
22
- products = taxon.products.active.limit(max)
21
+ def taxon_preview(taxon, max=4)
22
+ products = taxon.active_products.limit(max)
23
23
  if (products.size < max) && Spree::Config[:show_descendents]
24
24
  taxon.descendants.each do |taxon|
25
25
  to_get = max - products.length
26
- products += taxon.products.active.limit(to_get)
26
+ products += taxon.active_products.limit(to_get)
27
27
  break if products.size >= max
28
28
  end
29
29
  end
@@ -4,7 +4,7 @@ class OrderMailer < ActionMailer::Base
4
4
  def confirm_email(order, resend=false)
5
5
  @order = order
6
6
  subject = (resend ? "[RESEND] " : "")
7
- subject += "#{Spree::Config[:site_name]} Order Confirmation ##{order.number}"
7
+ subject += "#{Spree::Config[:site_name]} #{t('subject', :scope =>'order_mailer.confirm_email')} ##{order.number}"
8
8
  mail(:to => order.email,
9
9
  :subject => subject)
10
10
  end
@@ -12,7 +12,7 @@ class OrderMailer < ActionMailer::Base
12
12
  def cancel_email(order, resend=false)
13
13
  @order = order
14
14
  subject = (resend ? "[RESEND] " : "")
15
- subject += "#{Spree::Config[:site_name]} Cancellation of Order ##{order.number}"
15
+ subject += "#{Spree::Config[:site_name]} #{t('subject', :scope => 'order_mailer.cancel_email')} ##{order.number}"
16
16
  mail(:to => order.email,
17
17
  :subject => subject)
18
18
  end
@@ -4,8 +4,8 @@ class ShipmentMailer < ActionMailer::Base
4
4
  def shipped_email(shipment, resend=false)
5
5
  @shipment = shipment
6
6
  subject = (resend ? "[RESEND] " : "")
7
- subject += "#{Spree::Config[:site_name]} Shipment Notification ##{shipment.order.number}"
7
+ subject += "#{Spree::Config[:site_name]} #{t('subject', :scope => 'shipment_mailer.shipped_email')} ##{shipment.order.number}"
8
8
  mail(:to => shipment.order.email,
9
9
  :subject => subject)
10
10
  end
11
- end
11
+ end
@@ -5,9 +5,7 @@ class Address < ActiveRecord::Base
5
5
  has_many :shipments
6
6
 
7
7
  validates :firstname, :lastname, :address1, :city, :zipcode, :country, :phone, :presence => true
8
- validates :state, :presence => true, :if => Proc.new { |address| address.state_name.blank? && Spree::Config[:address_requires_state] }
9
- validates :state_name, :presence => true, :if => Proc.new { |address| address.state.blank? && Spree::Config[:address_requires_state] }
10
- validate :state_name_validate, :if => Proc.new { |address| address.state.blank? && Spree::Config[:address_requires_state] }
8
+ validate :state_validate
11
9
 
12
10
  # disconnected since there's no code to display error messages yet OR matching client-side validation
13
11
  def phone_validate
@@ -19,12 +17,47 @@ class Address < ActiveRecord::Base
19
17
  end
20
18
  end
21
19
 
22
- def state_name_validate
23
- country = country_id ? Country.find(country_id) : nil
24
- return if country.blank? || country.states.empty?
25
- if state_name.blank? || country.states.where(["name = ? OR abbr = ?", state_name, state_name]).empty?
26
- errors.add(:state, :invalid)
20
+ def state_validate
21
+ #skip state validation without country (also required)
22
+ #or when disabled by perfernce
23
+ return if self.country_id.blank? || !Spree::Config[:address_requires_state]
24
+
25
+ #ensure associated state belongs to country
26
+ if self.state_id.present?
27
+ if self.state.country_id == self.country_id
28
+
29
+ self.state_name = nil #not required as we have a valid state and country combo
30
+ else
31
+ if self.state_name.present?
32
+
33
+ self.state_id = nil
34
+ else
35
+ errors.add(:state, :invalid)
36
+ end
37
+ end
38
+ end
39
+
40
+ #ensure state_name belongs to country without states, or that it matches a predefined state name/abbr
41
+ if self.state_name.present?
42
+ country = Country.where(:id => self.country_id).try(:first)
43
+
44
+ if country.states.present?
45
+ states = country.states.where(["name = ? OR abbr = ?",self.state_name, self.state_name])
46
+
47
+ if states.size == 1
48
+ self.state = states.first
49
+ self.state_name = nil
50
+ else
51
+ errors.add(:state, :invalid)
52
+ end
53
+ end
27
54
  end
55
+
56
+ #ensure at least one state field is populated
57
+ if self.state_id.blank? && self.state_name.blank?
58
+ errors.add(:state, :blank)
59
+ end
60
+
28
61
  end
29
62
 
30
63
  def self.default
@@ -77,6 +110,6 @@ class Address < ActiveRecord::Base
77
110
  end
78
111
 
79
112
  def empty?
80
- attributes.except("id", "created_at", "updated_at", "order_id", "country_id").all? {|k,v| v.nil?}
113
+ attributes.except("id", "created_at", "updated_at", "order_id", "country_id").all? {|_,v| v.nil?}
81
114
  end
82
115
  end
@@ -3,14 +3,15 @@
3
3
  #
4
4
  # +mandatory+
5
5
  #
6
- # The charge is required and will not be removed from the order, even if the amount is zero. This is
7
- # useful for representing things such as shipping and tax charges where you may want to make it explicitly
6
+ # If this flag is set to true then it means the the charge is required and will not be removed from the
7
+ # order, even if the amount is zero. In other words a record will be created even if the amount is zero.
8
+ # This is useful for representing things such as shipping and tax charges where you may want to make it explicitly
8
9
  # clear that no charge was made for such things.
9
10
  #
10
- # +frozen+
11
+ # +locked+
11
12
  #
12
13
  # The charge is never to be udpated. Typically you would want to freeze certain adjustments after checkout.
13
- # One use case for this is if you want to freeze a shipping adjustment so that its value does not change
14
+ # One use case for this is if you want to lock a shipping adjustment so that its value does not change
14
15
  # in the future when making other trivial edits to the order (like an email change).
15
16
  class Adjustment < ActiveRecord::Base
16
17
  belongs_to :order
@@ -24,9 +25,8 @@ class Adjustment < ActiveRecord::Base
24
25
  scope :shipping, lambda { where(:label => I18n.t(:shipping)) }
25
26
  scope :optional, where(:mandatory => false)
26
27
 
27
- # update the order totals, etc.
28
- after_save {order.update!}
29
- after_destroy {order.update!}
28
+ after_save { order.update! }
29
+ after_destroy { order.update! }
30
30
 
31
31
  # Checks if adjustment is applicable for the order. Should return _true_ if adjustment should be preserved and
32
32
  # _false_ if removed. Default behaviour is to preserve adjustment if amount is present and non 0. Exceptions
@@ -41,7 +41,7 @@ class Adjustment < ActiveRecord::Base
41
41
  # to use this method in an after_save hook for other models without causing an infinite recursion problem. If there
42
42
  # is no +originator+ then this method will have no effect.
43
43
  def update!
44
- return if locked? or originator.nil?
44
+ return if locked? || originator.nil?
45
45
  originator.update_adjustment(self, source)
46
46
  end
47
47
  end