spree 0.6.0 → 0.7.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 (181) hide show
  1. data/CHANGELOG +30 -0
  2. data/CONTRIBUTORS +38 -20
  3. data/app/controllers/admin/creditcard_payments_controller.rb +10 -3
  4. data/app/controllers/admin/orders_controller.rb +17 -16
  5. data/app/controllers/admin/products_controller.rb +12 -14
  6. data/app/controllers/admin/reports_controller.rb +12 -14
  7. data/app/controllers/admin/users_controller.rb +10 -5
  8. data/app/controllers/admin/zones_controller.rb +4 -1
  9. data/app/controllers/application.rb +0 -1
  10. data/app/controllers/checkout_controller.rb +96 -0
  11. data/app/controllers/content_controller.rb +11 -1
  12. data/app/controllers/orders_controller.rb +12 -33
  13. data/app/controllers/products_controller.rb +12 -7
  14. data/app/controllers/spree/base_controller.rb +1 -1
  15. data/app/controllers/states_controller.rb +14 -2
  16. data/app/controllers/taxons_controller.rb +6 -2
  17. data/app/controllers/users_controller.rb +9 -6
  18. data/app/helpers/application_helper.rb +1 -11
  19. data/app/helpers/products_helper.rb +3 -1
  20. data/app/helpers/spree/base_helper.rb +0 -26
  21. data/app/models/address.rb +3 -3
  22. data/app/models/app_configuration.rb +1 -0
  23. data/app/models/country.rb +4 -0
  24. data/app/models/creditcard.rb +6 -1
  25. data/app/models/creditcard_payment.rb +1 -1
  26. data/app/models/inventory_unit.rb +4 -1
  27. data/app/models/order.rb +37 -21
  28. data/app/models/product.rb +19 -8
  29. data/{vendor/extensions/shipping/app → app}/models/shipment.rb +20 -4
  30. data/{vendor/extensions/shipping/app → app}/models/shipping_category.rb +0 -0
  31. data/{vendor/extensions/shipping/app → app}/models/shipping_method.rb +6 -4
  32. data/app/models/state.rb +5 -0
  33. data/app/models/user.rb +4 -2
  34. data/app/models/variant.rb +19 -1
  35. data/app/presenters/checkout_presenter.rb +58 -0
  36. data/app/views/admin/creditcard_payments/edit.html.erb +1 -1
  37. data/app/views/admin/option_types/available.html.erb +1 -1
  38. data/app/views/admin/orders/index.html.erb +28 -18
  39. data/app/views/admin/orders/show.html.erb +1 -1
  40. data/app/views/admin/payments/index.html.erb +1 -1
  41. data/app/views/admin/products/_images.html.erb +1 -1
  42. data/app/views/admin/products/index.html.erb +17 -13
  43. data/app/views/admin/users/index.html.erb +8 -8
  44. data/app/views/admin/zones/index.html.erb +5 -2
  45. data/app/views/checkout/_form.html.erb +165 -0
  46. data/app/views/{creditcards → checkout}/cvv.html.erb +1 -1
  47. data/app/views/checkout/new.html.erb +6 -0
  48. data/app/views/layouts/admin.html.erb +2 -3
  49. data/app/views/layouts/application.html.erb +1 -1
  50. data/app/views/orders/_form.html.erb +6 -4
  51. data/app/views/orders/_google_order.html.erb +24 -0
  52. data/app/views/orders/_line_item.html.erb +2 -1
  53. data/app/views/orders/show.html.erb +4 -1
  54. data/app/views/products/index.html.erb +2 -1
  55. data/app/views/products/show.html.erb +4 -4
  56. data/app/views/shared/_footer.html.erb +12 -1
  57. data/app/views/shared/_login.html.erb +1 -1
  58. data/app/views/shared/_order_details.html.erb +8 -9
  59. data/app/views/shared/_products.html.erb +1 -1
  60. data/app/views/shared/_report_criteria.html.erb +28 -28
  61. data/app/views/states/index.js.erb +10 -1
  62. data/config/environment.rb +10 -4
  63. data/config/initializers/searchlogic.rb +6 -0
  64. data/config/locales/de.yml +14 -0
  65. data/config/locales/en-GB.yml +20 -6
  66. data/config/locales/en-US.yml +20 -4
  67. data/config/locales/es.yml +14 -0
  68. data/config/locales/fr-FR.yml +463 -0
  69. data/config/locales/fr-FR_rails.yml +115 -0
  70. data/config/locales/it.yml +14 -0
  71. data/config/locales/nb-NO.yml +457 -0
  72. data/config/locales/nb-NO_rails.yml +105 -0
  73. data/config/locales/pl.yml +14 -0
  74. data/config/locales/pt-BR.yml +14 -0
  75. data/config/locales/pt-PT.yml +14 -0
  76. data/config/locales/ru-RU.yml +458 -0
  77. data/config/locales/ru-RU_rails.yml +154 -0
  78. data/config/routes.rb +11 -4
  79. data/db/migrate/20090204200045_add_order_permalink.rb +13 -0
  80. data/db/migrate/20090225231119_add_more_needed_keys_items_and_conf.rb +19 -0
  81. data/db/migrate/20090302221152_give_all_users_user_role.rb +13 -0
  82. data/db/sample/orders.yml +1 -1
  83. data/lib/generators/instance/instance_generator.rb +1 -1
  84. data/lib/spree.rb +1 -1
  85. data/lib/spree/setup.rb +1 -1
  86. data/lib/tasks/database.rake +5 -2
  87. data/lib/tasks/release.rake +1 -1
  88. data/lib/tasks/upgrade.rake +11 -0
  89. data/public/assets/products/1009/mini/sean.jpg +0 -0
  90. data/public/assets/products/1009/original/sean.jpg +0 -0
  91. data/public/assets/products/1009/product/sean.jpg +0 -0
  92. data/public/assets/products/1009/small/sean.jpg +0 -0
  93. data/public/images/ajax_loader.gif +0 -0
  94. data/public/javascripts/checkout.js +284 -0
  95. data/public/javascripts/jquery-1.3.2.min.js +19 -0
  96. data/public/javascripts/jquery.validate.pack.js +15 -0
  97. data/public/stylesheets/checkout.css +25 -0
  98. data/public/stylesheets/spree-admin.css +6 -2
  99. data/public/stylesheets/spree.css +419 -432
  100. data/spec/controllers/countries_controller_spec.rb +3 -2
  101. data/spec/controllers/orders_controller_spec.rb +7 -5
  102. data/spec/controllers/states_controller_spec.rb +4 -2
  103. data/spec/models/creditcard_payment_spec.rb +6 -2
  104. data/spec/models/order_spec.rb +164 -157
  105. data/spec/models/product_spec.rb +2 -2
  106. data/vendor/extensions/payment_gateway/db/migrate/20090218091936_create_protx_gateway.rb +18 -0
  107. data/vendor/extensions/payment_gateway/lib/spree/payment_gateway.rb +7 -5
  108. data/vendor/extensions/shipping/app/controllers/admin/shipments_controller.rb +6 -5
  109. data/vendor/extensions/shipping/app/views/admin/shipments/index.html.erb +1 -1
  110. data/vendor/extensions/shipping/config/locales/nb-NO.yml +25 -0
  111. data/vendor/extensions/shipping/config/locales/ru-RU.yml +25 -0
  112. data/vendor/extensions/shipping/db/sample/shipping_methods.yml +5 -1
  113. data/vendor/extensions/shipping/db/sample/zone_members.yml +9 -1
  114. data/vendor/extensions/shipping/db/sample/zones.yml +4 -1
  115. data/vendor/extensions/shipping/lib/spree/shipping_calculator.rb +0 -16
  116. data/vendor/extensions/shipping/shipping_extension.rb +0 -15
  117. data/vendor/extensions/shipping/spec/models/shipping_method_spec.rb +16 -10
  118. data/vendor/extensions/shipping/spec/models/shipping_order_spec.rb +3 -17
  119. data/vendor/extensions/tax_calculator/config/locales/nb-NO.yml +30 -0
  120. data/vendor/extensions/tax_calculator/spec/models/{order_spec.rb → order_tax_calc_spec.rb} +2 -2
  121. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/.specification +3 -5
  122. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/LICENSE +0 -0
  123. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/README +9 -2
  124. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/Rakefile +0 -0
  125. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter.rb +0 -0
  126. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter/base.rb +38 -8
  127. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter/version.rb +1 -1
  128. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/tasks/doc.rake +0 -0
  129. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/tasks/gem.rake +0 -0
  130. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/test/base_test.rb +66 -30
  131. data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/test/test_helper.rb +36 -0
  132. data/vendor/plugins/attribute_fu/lib/attribute_fu/associated_form_helper.rb +12 -4
  133. data/vendor/plugins/find_by_param/MIT-LICENSE +1 -1
  134. data/vendor/plugins/find_by_param/{README → README.markdown} +7 -1
  135. data/vendor/plugins/find_by_param/init.rb +0 -1
  136. data/vendor/plugins/find_by_param/lib/find_by_param.rb +23 -87
  137. data/vendor/plugins/find_by_param/test/find_by_param_test.rb +22 -8
  138. data/vendor/plugins/find_by_param/test/test_helper.rb +0 -1
  139. metadata +65 -193
  140. data/app/controllers/creditcards_controller.rb +0 -73
  141. data/app/models/order_filter.rb +0 -28
  142. data/app/models/user_filter.rb +0 -6
  143. data/app/views/creditcards/_form_credit_card.html.erb +0 -30
  144. data/app/views/creditcards/new.html.erb +0 -25
  145. data/app/views/shared/_paginate.html.erb +0 -34
  146. data/lib/plugins/paginating_find/CHANGELOG +0 -120
  147. data/lib/plugins/paginating_find/README +0 -89
  148. data/lib/plugins/paginating_find/init.rb +0 -2
  149. data/lib/plugins/paginating_find/lib/paginating_find.rb +0 -138
  150. data/lib/plugins/paginating_find/lib/paging_enumerator.rb +0 -158
  151. data/lib/plugins/paginating_find/lib/paging_helper.rb +0 -47
  152. data/lib/plugins/paginating_find/test_app/Rakefile +0 -10
  153. data/lib/plugins/paginating_find/test_app/app/controllers/application.rb +0 -2
  154. data/lib/plugins/paginating_find/test_app/config/boot.rb +0 -44
  155. data/lib/plugins/paginating_find/test_app/config/database.yml +0 -6
  156. data/lib/plugins/paginating_find/test_app/config/environment.rb +0 -53
  157. data/lib/plugins/paginating_find/test_app/config/environments/test.rb +0 -19
  158. data/lib/plugins/paginating_find/test_app/config/routes.rb +0 -22
  159. data/lib/plugins/paginating_find/test_app/script/breakpointer +0 -3
  160. data/lib/plugins/paginating_find/test_app/script/console +0 -3
  161. data/lib/plugins/paginating_find/test_app/test/fixtures/articles.yml +0 -19
  162. data/lib/plugins/paginating_find/test_app/test/fixtures/authors.yml +0 -7
  163. data/lib/plugins/paginating_find/test_app/test/fixtures/edits.yml +0 -11
  164. data/lib/plugins/paginating_find/test_app/test/fixtures/models.rb +0 -18
  165. data/lib/plugins/paginating_find/test_app/test/test_helper.rb +0 -33
  166. data/lib/plugins/paginating_find/test_app/test/unit/abstract_test.rb +0 -7
  167. data/lib/plugins/paginating_find/test_app/test/unit/group_test.rb +0 -40
  168. data/lib/plugins/paginating_find/test_app/test/unit/paginating_find_test.rb +0 -194
  169. data/lib/plugins/paginating_find/test_app/test/unit/paging_enumerator_test.rb +0 -143
  170. data/public/assets/products/1012/mini/bt.jpg +0 -0
  171. data/public/assets/products/1012/original/bt.jpg +0 -0
  172. data/public/assets/products/1012/product/bt.jpg +0 -0
  173. data/public/assets/products/1012/small/bt.jpg +0 -0
  174. data/spec/views/products/index.html.erb_spec.rb +0 -46
  175. data/spec/views/products/show.html.erb_spec.rb +0 -46
  176. data/vendor/extensions/shipping/app/controllers/shipments_controller.rb +0 -96
  177. data/vendor/extensions/shipping/app/helpers/shipments_helper.rb +0 -20
  178. data/vendor/extensions/shipping/app/views/orders/fatal_shipping.html.erb +0 -6
  179. data/vendor/extensions/shipping/app/views/shipments/_form.html.erb +0 -46
  180. data/vendor/extensions/shipping/app/views/shipments/edit.html.erb +0 -57
  181. data/vendor/extensions/shipping/app/views/shipments/new.html.erb +0 -10
@@ -1,5 +1,5 @@
1
1
  class Admin::ShipmentsController < Admin::BaseController
2
- before_filter :load_data
2
+ before_filter :load_data, :except => :country_changed
3
3
  before_filter :load_shipment_presenter, :only => [:create, :update]
4
4
 
5
5
  resource_controller
@@ -14,10 +14,8 @@ class Admin::ShipmentsController < Admin::BaseController
14
14
  shipment.address = @shipment_presenter.address
15
15
  unless @shipment_presenter.valid? and shipment.save
16
16
  render :action => "new" and return
17
- end
18
- if params['mark_shipped']
19
- @order.ship!
20
17
  end
18
+ @order.state_events.create(:name => t('ship'), :user => current_user, :previous_state => @order.state) if params[:mark_shipped]
21
19
  flash[:notice] = t('created_successfully')
22
20
  redirect_to collection_url
23
21
  end
@@ -35,12 +33,15 @@ class Admin::ShipmentsController < Admin::BaseController
35
33
  @shipment.shipped_at = Time.now if params[:mark_shipped]
36
34
  unless @shipment_presenter.valid? and @shipment.save
37
35
  render :action => "edit" and return
38
- end
36
+ end
37
+ @order.state_events.create(:name => t('ship'), :user => current_user, :previous_state => @order.state) if params[:mark_shipped]
39
38
  flash[:notice] = t('updated_successfully')
40
39
  redirect_to edit_object_url
41
40
  end
42
41
 
43
42
  def country_changed
43
+ @selected_country_id = params[:shipment_presenter][:address_country_id].to_i if params.has_key?('shipment_presenter')
44
+ @states = State.find_all_by_country_id(@selected_country_id, :order => 'name')
44
45
  render :partial => "shared/states", :locals => {:presenter_type => "shipment"}
45
46
  end
46
47
 
@@ -14,7 +14,7 @@
14
14
  <td><%= shipment.shipping_method.name if shipment.shipping_method %></td>
15
15
  <td><%= shipment.cost %></td>
16
16
  <td><%= shipment.tracking %></td>
17
- <td><%= shipment.shipped_at.to_s(:db) if shipment.shipped_at %></td>
17
+ <td><%= shipment.shipped_at.to_s(:date_time24) if shipment.shipped_at %></td>
18
18
  <td><%= link_to t('edit'), edit_admin_order_shipment_url(@order, shipment) %></td>
19
19
  </tr>
20
20
  <% end %>
@@ -0,0 +1,25 @@
1
+ ---
2
+ nb-NO:
3
+ activerecord:
4
+ attributes:
5
+ product:
6
+ shipping_category: "Fraktkategori"
7
+ models:
8
+ shipping_category:
9
+ one: "Fraktkategori"
10
+ other: "Fraktkategorier"
11
+ ext_shipping_calculator: Kalkulator
12
+ ext_shipping_cost: Kostnad
13
+ ext_shipping_editing_shipping_category: Endre fraktkategori
14
+ ext_shipping_editing_shipping_method: "Endre leveransemåte"
15
+ ext_shipping_mark_shipped: "Merk som levert"
16
+ ext_shipping_method: Leveransemåte
17
+ ext_shipping_new_shipping_category: "Ny fraktkategori"
18
+ ext_shipping_new_shipping_method: "Ny leveransemåte"
19
+ ext_shipping_shipment_number: "Leveransenummer"
20
+ ext_shipping_shipping_categories: "Fraktkategorier"
21
+ ext_shipping_shipping_categories_description: "Konfigurer fraktkategorier for å styre hvilke produkter som kan bruke de ulike leveransemåtene."
22
+ ext_shipping_shipping_methods: "Leveransemåter"
23
+ ext_shipping_shipping_methods_description: "Konfigurer leveransemåter."
24
+ ext_shipping_tracking: Sporing
25
+ select_preferred_shipping_option: "Velg ønsket leveransemåte"
@@ -0,0 +1,25 @@
1
+ ---
2
+ ru-RU:
3
+ activerecord:
4
+ attributes:
5
+ product:
6
+ shipping_category: "Категория доставки"
7
+ models:
8
+ shipping_category:
9
+ one: "Категория доставки"
10
+ other: "Категории доставки"
11
+ ext_shipping_calculator: Калькулятор
12
+ ext_shipping_cost: Стоимость
13
+ ext_shipping_editing_shipping_category: "Редактировать категорию доставки"
14
+ ext_shipping_editing_shipping_method: "Редактировать способ доставки"
15
+ ext_shipping_mark_shipped: "Отметить как доставленный"
16
+ ext_shipping_method: Способ
17
+ ext_shipping_new_shipping_category: "Новая категория доставки"
18
+ ext_shipping_new_shipping_method: "Новый способ доставки"
19
+ ext_shipping_shipment_number: "Доставка #"
20
+ ext_shipping_shipping_categories: "Категории доставки"
21
+ ext_shipping_shipping_categories_description: "Настройка категорий доставки - укажите, какие продукты могут быть доставлены какими способами"
22
+ ext_shipping_shipping_methods: "Способы доставки"
23
+ ext_shipping_shipping_methods_description: "Управление методами доставки"
24
+ ext_shipping_tracking: Отслеживание
25
+ select_preferred_shipping_option: "Выберите предпочитаемый способ доставки"
@@ -9,4 +9,8 @@ ups_two_day:
9
9
  ups_one_day:
10
10
  name: UPS One Day
11
11
  zone: available_shipping
12
- shipping_calculator: Spree::FlatRateShipping::Calculator
12
+ shipping_calculator: Spree::FlatRateShipping::Calculator
13
+ one_option:
14
+ name: Only one option
15
+ zone: one_ship_option
16
+ shipping_calculator: Spree::FlatRateShipping::Calculator
@@ -5,4 +5,12 @@ usa_member:
5
5
  canada_member:
6
6
  parent: available_shipping
7
7
  member_id: 35
8
- member_type: Country
8
+ member_type: Country
9
+ uk_one_ship_opt:
10
+ parent: one_ship_option
11
+ member_id: 213
12
+ member_type: Country
13
+ uae_one_ship_opt:
14
+ parent: one_ship_option
15
+ member_id: 212 # UAE, just cos it's close to US/UK in the list
16
+ member_type: Country
@@ -1,3 +1,6 @@
1
1
  available_shipping:
2
2
  name: North America
3
- description: USA + Canada
3
+ description: USA + Canada
4
+ one_ship_option:
5
+ name: Zone with one shipping option
6
+ description: Zone with one shipping option
@@ -1,22 +1,6 @@
1
1
  module Spree #:nodoc:
2
2
  module ShippingCalculator
3
3
 
4
- # modify the transitions in core - go to shipping first (before creditcard)
5
- fsm = Order.state_machines['state']
6
- fsm.states << "shipment"
7
- fsm.events['next'].transitions.delete_if { |t| t.options[:to] == "creditcard" && t.options[:from] == "in_progress" }
8
- fsm.events['next'].transition(:to => 'shipment', :from => 'in_progress')
9
- fsm.events['next'].transition(:to => 'shipping_method', :from => 'shipment')
10
- fsm.events['next'].transition(:to => 'creditcard', :from => 'shipping_method')
11
- # skip right to creditcard step if there are no shipping methods at all (ex. store sells only electronic downloads)
12
- fsm.after_transition :to => 'shipment', :do => lambda { |order| order.update_attribute(:state, "creditcard") if ShippingMethod.all.empty? }
13
- fsm.events['edit'].transition(:to => 'in_progress', :from => ['shipment', 'shipping_method'])
14
- fsm.after_transition :to => 'shipping_method', :do => lambda {|order| order.update_attribute(:tax_amount, order.calculate_tax)}
15
- fsm.after_transition :to => 'shipped', :do => :mark_shipped
16
-
17
- fsm.events['ship'] = PluginAWeek::StateMachine::Event.new(fsm, "ship")
18
- fsm.events['ship'].transition(:to => 'shipped', :from => 'paid')
19
-
20
4
  def mark_shipped
21
5
  inventory_units.each do |inventory_unit|
22
6
  inventory_unit.ship!
@@ -8,21 +8,6 @@ class ShippingExtension < Spree::Extension
8
8
 
9
9
  def activate
10
10
 
11
- Order.class_eval do
12
- has_many :shipments, :dependent => :destroy
13
- include Spree::ShippingCalculator
14
-
15
- # convenience method since many stores will not allow user to create multiple shipments
16
- def shipment
17
- shipments.last
18
- end
19
-
20
- def ship_address
21
- return nil if shipments.empty?
22
- return shipment.address
23
- end
24
- end
25
-
26
11
  Admin::ConfigurationsController.class_eval do
27
12
  before_filter :add_shipping_links, :only => :index
28
13
  def add_shipping_links
@@ -1,30 +1,36 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
 
3
- class MockCalculator
3
+ class MockCalculator
4
+ def available?(order)
5
+ true
6
+ end
4
7
  def calculate_shipping(order)
5
8
  2.5
6
9
  end
7
10
  end
8
11
 
12
+ class MockUnavailableCalculator
13
+ def available?(order)
14
+ false
15
+ end
16
+ end
17
+
9
18
  describe ShippingMethod do
10
19
  before(:each) do
20
+ @calculator = MockCalculator.new
21
+ MockCalculator.stub!(:new).and_return(@calculator)
11
22
  @zone = mock_model(Zone)
12
23
  @address = mock_model(Address)
13
24
  @shipping_method = ShippingMethod.new(:zone => @zone, :shipping_calculator => "MockCalculator")
14
25
  @order = mock_model(Order, :address => @address)
15
26
  end
16
27
 
17
- describe "available?" do
18
- it "should check the shipping address against the zone" do
19
- @zone.should_receive(:include?).with(@address)
20
- @shipping_method.available?(@order)
21
- end
22
- it "should be true if the shipping address is located within the method's zone" do
23
- @zone.stub!(:include?).with(@address).and_return(true)
28
+ describe "available?" do
29
+ it "should return true if the calculator indicates method is supported" do
24
30
  @shipping_method.available?(@order).should be_true
25
31
  end
26
- it "should be false if the shipping address is located outside of the method's zone" do
27
- @zone.stub!(:include?).with(@address).and_return(false)
32
+ it "should return false if the calculator indicates method is not supported" do
33
+ @shipping_method = ShippingMethod.new(:zone => @zone, :shipping_calculator => "MockUnavailableCalculator")
28
34
  @shipping_method.available?(@order).should be_false
29
35
  end
30
36
  end
@@ -79,26 +79,12 @@ describe Order do
79
79
  @order.state.should == "creditcard"
80
80
  end
81
81
  end
82
- describe "when there is only one shipping method" do
83
- before :each do
82
+ describe "when there is more then one shipping method" do
83
+ it "next! should transition to 'shipping_method'" do
84
84
  @order.state = "shipment"
85
- @shipping_method = ShippingMethod.new(:shipping_calculator => "MockCalculator")
86
- @order.stub!(:shipping_methods).and_return([@shipping_method])
87
- end
88
- it "next! should transition to 'creditcard'" do
89
- @order.next!
90
- @order.state.should == "creditcard"
91
- end
92
- it "should automatically calculate the shipping cost using the single shipping method" do
93
- @order.next!
94
- @order.shipments.first.shipping_method.should == @shipping_method
95
- end
96
- end
97
- describe "when there is only one shipping method" do
98
- it "next! should transition to 'shipment'" do
99
85
  @order.stub!(:shipping_methods).and_return([ShippingMethod.new, ShippingMethod.new])
100
86
  @order.next!
101
- @order.state.should == "shipment"
87
+ @order.state.should == "shipping_method"
102
88
  end
103
89
  end
104
90
  end
@@ -0,0 +1,30 @@
1
+ ---
2
+ nb-NO:
3
+ activerecord:
4
+ attributes:
5
+ product:
6
+ tax_category: "Momskategori"
7
+ tax_category:
8
+ description: Beskrivelse
9
+ name: Navn
10
+ tax_rate:
11
+ amount: Momsnivå
12
+ models:
13
+ tax_category:
14
+ one: "Momskategori"
15
+ other: "Momskategorier"
16
+ tax_rate:
17
+ one: "Momsnivå"
18
+ other: "Momsnivå"
19
+ ext_tax_calculator_action: Aksjon
20
+ ext_tax_calculator_amount: Beløp
21
+ ext_tax_calculator_category: Kategori
22
+ ext_tax_calculator_create: Opprett
23
+ ext_tax_calculator_delete: Slett
24
+ ext_tax_calculator_edit: Endre
25
+ ext_tax_calculator_editing_tax_rate: "Endre momsnivå"
26
+ ext_tax_calculator_new_tax_rate: "Nytt momsnivå"
27
+ ext_tax_calculator_tax_rates: "Momsnivå"
28
+ ext_tax_calculator_tax_rates_description: "Konfigurer momsnivå."
29
+ ext_tax_calculator_tax_type: "Momstype"
30
+ ext_tax_calculator_zone: Sone
@@ -7,11 +7,11 @@ describe Order do
7
7
  end
8
8
 
9
9
  describe "with address state" do
10
- before(:each) {@order.state = 'address'}
10
+ before(:each) {@order.state = 'shipment'}
11
11
  describe "next" do
12
12
  it "should transition to credit_card_payment state" do
13
13
  @order.next
14
- @order.state.should == "creditcard_payment"
14
+ @order.state.should == "shipping_method"
15
15
  end
16
16
  it "should calculate the tax during the transition" do
17
17
  @order.should_receive(:calculate_tax)
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_presenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Golick & Daniel Haran
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-09-01 00:00:00 -04:00
12
+ date: 2009-01-22 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -40,8 +40,6 @@ post_install_message:
40
40
  rdoc_options: []
41
41
 
42
42
  require_paths:
43
- - bin
44
- - bin
45
43
  - lib
46
44
  required_ruby_version: !ruby/object:Gem::Requirement
47
45
  requirements:
@@ -58,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
58
56
  requirements: []
59
57
 
60
58
  rubyforge_project: active_presenter
61
- rubygems_version: 1.2.0
59
+ rubygems_version: 1.3.1
62
60
  signing_key:
63
61
  specification_version: 2
64
62
  summary: ActivePresenter is the presenter library you already know! (...if you know ActiveRecord)
@@ -25,9 +25,9 @@ Or get the source from github:
25
25
  Creating a presenter is as simple as subclassing ActivePresenter::Base. Use the presents method to indicate which models the presenter should present.
26
26
 
27
27
  class SignupPresenter < ActivePresenter::Base
28
- presents User, Account
28
+ presents :user, :account
29
29
  end
30
-
30
+
31
31
  === Instantiation
32
32
 
33
33
  Then, you can instantiate the presenter using either, or both of two forms.
@@ -66,6 +66,12 @@ Both of these methods are compatible with error_messages_for. It just depends wh
66
66
 
67
67
  You can save your presenter the same way you'd save an ActiveRecord object. Both #save, and #save! behave the same way they do on a normal AR model.
68
68
 
69
+ === Callbacks
70
+
71
+ Callbacks work exactly like ActiveRecord callbacks. before_save, and after_save are available.
72
+
73
+ Note that if any of your after_save callbacks return false, the rest of them will not be run. This is consistent with AR behavior.
74
+
69
75
  == Credits
70
76
 
71
77
  ActivePresenter was created, and is maintained by {Daniel Haran}[http://danielharan.com] and {James Golick}[http://jamesgolick.com] on the train ride to {RubyFringe}[http://rubyfringe.com] from Montreal.
@@ -73,3 +79,4 @@ ActivePresenter was created, and is maintained by {Daniel Haran}[http://danielha
73
79
  == License
74
80
 
75
81
  ActivePresenter is available under the {MIT License}[http://en.wikipedia.org/wiki/MIT_License]
82
+
@@ -2,6 +2,9 @@ module ActivePresenter
2
2
  # Base class for presenters. See README for usage.
3
3
  #
4
4
  class Base
5
+ include ActiveSupport::Callbacks
6
+ define_callbacks :before_save, :after_save
7
+
5
8
  class_inheritable_accessor :presented
6
9
  self.presented = {}
7
10
 
@@ -9,19 +12,25 @@ module ActivePresenter
9
12
  # i.e.
10
13
  #
11
14
  # class SignupPresenter < ActivePresenter::Base
12
- # presents User, Account
15
+ # presents :user, :account
13
16
  # end
14
17
  #
15
18
  #
16
19
  def self.presents(*types)
17
- attr_accessor *types
20
+ #attr_accessor *types
18
21
 
19
22
  types.each do |t|
20
23
  define_method("#{t}_errors") do
21
24
  send(t).errors
22
25
  end
23
-
24
- presented[t] = t.to_s.tableize.classify.constantize
26
+ if t.is_a? Hash
27
+ key = t.keys.first
28
+ presented[key] = t[key]
29
+ attr_accessor key
30
+ else
31
+ presented[t] = t.to_s.tableize.classify.constantize
32
+ attr_accessor t
33
+ end
25
34
  end
26
35
  end
27
36
 
@@ -56,7 +65,7 @@ module ActivePresenter
56
65
 
57
66
  self.attributes = args
58
67
  end
59
-
68
+
60
69
  # Set the attributes of the presentable instances using the type_attribute form (i.e. user_login => 'james')
61
70
  #
62
71
  def attributes=(attrs)
@@ -101,12 +110,14 @@ module ActivePresenter
101
110
  saved = false
102
111
 
103
112
  ActiveRecord::Base.transaction do
104
- if valid?
113
+ if valid? && run_callbacks_with_halt(:before_save)
105
114
  saved = presented_instances.map { |i| i.save(false) }.all?
106
115
  raise ActiveRecord::Rollback unless saved # TODO: Does this happen implicitly?
107
116
  end
108
117
  end
109
118
 
119
+ run_callbacks_with_halt(:after_save) if saved
120
+
110
121
  saved
111
122
  end
112
123
 
@@ -115,10 +126,14 @@ module ActivePresenter
115
126
  # Returns true on success, will raise otherwise.
116
127
  #
117
128
  def save!
129
+ raise ActiveRecord::RecordNotSaved unless run_callbacks_with_halt(:before_save)
130
+
118
131
  ActiveRecord::Base.transaction do
119
132
  valid? # collect errors before potential exception raise
120
133
  presented_instances.each { |i| i.save! }
121
134
  end
135
+
136
+ run_callbacks_with_halt(:after_save)
122
137
  end
123
138
 
124
139
  # Update attributes, and save the presentables
@@ -130,6 +145,15 @@ module ActivePresenter
130
145
  save
131
146
  end
132
147
 
148
+ # We define #id and #new_record? to play nice with form_for(@presenter) in Rails
149
+ def id # :nodoc:
150
+ nil
151
+ end
152
+
153
+ def new_record?
154
+ true
155
+ end
156
+
133
157
  protected
134
158
  def presented_instances
135
159
  presented.keys.map { |key| send(key) }
@@ -141,7 +165,7 @@ module ActivePresenter
141
165
  end
142
166
 
143
167
  def presentable_for(method_name)
144
- presented.keys.detect do |type|
168
+ presented.keys.sort_by { |k| k.to_s.size }.reverse.detect do |type|
145
169
  method_name.to_s.starts_with?(attribute_prefix(type))
146
170
  end
147
171
  end
@@ -161,14 +185,20 @@ module ActivePresenter
161
185
 
162
186
  def merge_errors(presented_inst, type)
163
187
  presented_inst.errors.each do |att,msg|
164
- errors.add(attribute_prefix(type)+att, msg.to_s)
188
+ errors.add(attribute_prefix(type)+att, msg)
165
189
  end
166
190
  end
167
191
 
168
192
  def attribute_protected?(name)
193
+ return false # HACK - We're not using any sensitive objects in presenter and the multiple Address models in one presenter was breaking
169
194
  presentable = presentable_for(name)
195
+ return false unless presentable
170
196
  flat_attribute = {flatten_attribute_name(name, presentable) => ''} #remove_att... normally takes a hash, so we use a ''
171
197
  presentable.to_s.tableize.classify.constantize.new.send(:remove_attributes_protected_from_mass_assignment, flat_attribute).empty?
172
198
  end
199
+
200
+ def run_callbacks_with_halt(callback)
201
+ run_callbacks(callback) { |result, object| result == false }
202
+ end
173
203
  end
174
204
  end