From d465560dbab24ca2aea077ac1fc6d4dce3fb5bed Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 Aug 2013 10:49:42 +1000 Subject: [PATCH 01/15] Update selenium-webdriver (for test debugging with selenium) --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index e981d05df8..c5b8630b77 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -259,7 +259,7 @@ GEM faye-websocket (0.4.7) eventmachine (>= 0.12.0) ffaker (1.15.0) - ffi (1.4.0) + ffi (1.9.0) fog (1.14.0) builder excon (~> 0.25.0) @@ -309,7 +309,7 @@ GEM money (5.0.0) i18n (~> 0.4) json - multi_json (1.7.8) + multi_json (1.7.9) multi_xml (0.5.5) net-scp (1.1.2) net-ssh (>= 2.6.5) @@ -405,7 +405,7 @@ GEM tilt (~> 1.3) select2-rails (3.2.1) thor (~> 0.14) - selenium-webdriver (2.31.0) + selenium-webdriver (2.35.0) childprocess (>= 0.2.5) multi_json (~> 1.0) rubyzip From aab7176f2cc2fd1daaa7f8240334f43dfcf8dd3f Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 Aug 2013 11:21:49 +1000 Subject: [PATCH 02/15] Enterprise manager can bulk edit products --- .../javascripts/admin/bulk_product_update.js | 4 +- .../admin/products_controller_decorator.rb | 11 +++- .../spree/api/enterprises_controller.rb | 11 +--- .../api/products_controller_decorator.rb | 7 ++ app/models/spree/ability_decorator.rb | 2 +- config/routes.rb | 19 ++++-- .../admin/bulk_product_update_spec.rb | 66 ++++++++++++++++++- .../unit/bulk_product_update_spec.js | 4 +- spec/models/ability_spec.rb | 4 +- 9 files changed, 104 insertions(+), 24 deletions(-) create mode 100644 app/controllers/spree/api/products_controller_decorator.rb diff --git a/app/assets/javascripts/admin/bulk_product_update.js b/app/assets/javascripts/admin/bulk_product_update.js index b5e157d838..495db1db47 100644 --- a/app/assets/javascripts/admin/bulk_product_update.js +++ b/app/assets/javascripts/admin/bulk_product_update.js @@ -154,10 +154,10 @@ productsApp.controller('AdminBulkProductsCtrl', ["$scope", "$timeout", "$http", $scope.spree_api_key_ok = data.hasOwnProperty("success") && data["success"] == "Use of API Authorised"; if ($scope.spree_api_key_ok){ $http.defaults.headers.common['X-Spree-Token'] = spree_api_key; - dataFetcher('/api/enterprises?template=bulk_index;q[is_primary_producer_eq]=true').then(function(data){ + dataFetcher('/api/enterprises/managed?template=bulk_index&q[is_primary_producer_eq]=true').then(function(data){ $scope.suppliers = data; // Need to have suppliers before we get products so we can match suppliers to product.supplier - dataFetcher('/api/products?template=bulk_index').then(function(data){ + dataFetcher('/api/products/managed?template=bulk_index').then(function(data){ $scope.resetProducts(data); }); }); diff --git a/app/controllers/spree/admin/products_controller_decorator.rb b/app/controllers/spree/admin/products_controller_decorator.rb index 9af68d05fa..5c02970ed5 100644 --- a/app/controllers/spree/admin/products_controller_decorator.rb +++ b/app/controllers/spree/admin/products_controller_decorator.rb @@ -12,7 +12,7 @@ Spree::Admin::ProductsController.class_eval do product_set = Spree::ProductSet.new({:collection_attributes => collection_hash}) if product_set.save - redirect_to "/api/products?template=bulk_index" + redirect_to "/api/products/managed?template=bulk_index" else render :nothing => true end @@ -37,7 +37,7 @@ Spree::Admin::ProductsController.class_eval do params[:q][:s] ||= "name asc" - @search = super.ransack(params[:q]) + @search = Spree::Product.ransack(params[:q]) # this line is modified - hit Spree::Product instead of super, avoiding cancan error for fetching records with block permissions via accessible_by @collection = @search.result. managed_by(spree_current_user). # this line is added to the original spree code!!!!! group_by_products_id. @@ -52,10 +52,15 @@ Spree::Admin::ProductsController.class_eval do @collection end + def collection_actions + [:index, :bulk_edit, :bulk_update] + end + + private def load_spree_api_key current_user.generate_spree_api_key! unless spree_current_user.spree_api_key @spree_api_key = spree_current_user.spree_api_key end -end \ No newline at end of file +end diff --git a/app/controllers/spree/api/enterprises_controller.rb b/app/controllers/spree/api/enterprises_controller.rb index 545372a285..4057def67a 100644 --- a/app/controllers/spree/api/enterprises_controller.rb +++ b/app/controllers/spree/api/enterprises_controller.rb @@ -3,15 +3,10 @@ module Spree class EnterprisesController < Spree::Api::BaseController respond_to :json - def bulk_show - @enterprise = Enterprise.find(params[:id]) - respond_with(@enterprise) - end - - def bulk_index - @enterprises = Enterprise.ransack(params[:q]).result + def managed + @enterprises = Enterprise.ransack(params[:q]).result.managed_by(current_api_user) respond_with(@enterprises) end end end -end \ No newline at end of file +end diff --git a/app/controllers/spree/api/products_controller_decorator.rb b/app/controllers/spree/api/products_controller_decorator.rb new file mode 100644 index 0000000000..3fc46108ab --- /dev/null +++ b/app/controllers/spree/api/products_controller_decorator.rb @@ -0,0 +1,7 @@ +Spree::Api::ProductsController.class_eval do + def managed + @products = product_scope.ransack(params[:q]).result.managed_by(current_api_user).page(params[:page]).per(params[:per_page]) + respond_with(@products, default_template: :index) + end + +end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 7d20e417e8..ccd4252897 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -6,7 +6,7 @@ class AbilityDecorator #Enterprise User can only access products that they are a supplier for can [:create], Spree::Product - can [:admin, :read, :update, :bulk_edit, :clone, :destroy], Spree::Product do |product| + can [:admin, :read, :update, :bulk_edit, :bulk_update, :clone, :destroy], Spree::Product do |product| user.enterprises.include? product.supplier end diff --git a/config/routes.rb b/config/routes.rb index de946a2627..da48f1b6e1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,7 +9,7 @@ Openfoodweb::Application.routes.draw do end member do - get :shop_front #new world + get :shop_front # new world get :shop # old world end end @@ -52,9 +52,20 @@ Spree::Core::Engine.routes.prepend do match '/admin/reports/order_cycles' => 'admin/reports#order_cycles', :as => "order_cycles_admin_reports", :via => [:get, :post] match '/admin/products/bulk_edit' => 'admin/products#bulk_edit', :as => "bulk_edit_admin_products" - match '/api/users/authorise_api' => 'api/users#authorise_api', :via => :get, :defaults => { :format => 'json' } - match '/api/enterprises' => 'api/enterprises#bulk_index', :via => :get, :defaults => { :format => 'json' } - match '/api/enterprises/:id' => 'api/enterprises#bulk_show', :via => :get, :defaults => { :format => 'json' } + + namespace :api, :defaults => { :format => 'json' } do + resources :users do + get :authorise_api, on: :collection + end + + resources :products do + get :managed, on: :collection + end + + resources :enterprises do + get :managed, on: :collection + end + end namespace :admin do resources :products do diff --git a/spec/features/admin/bulk_product_update_spec.rb b/spec/features/admin/bulk_product_update_spec.rb index a6f84180f9..f1bc9f8721 100644 --- a/spec/features/admin/bulk_product_update_spec.rb +++ b/spec/features/admin/bulk_product_update_spec.rb @@ -31,7 +31,7 @@ feature %q{ page.should have_field "product_name", with: p2.name end - it "displays a select box for suppliers, with the appropriate supplier selected" do + it "displays a select box for suppliers, with the appropriate supplier selected" do s1 = FactoryGirl.create(:supplier_enterprise) s2 = FactoryGirl.create(:supplier_enterprise) s3 = FactoryGirl.create(:supplier_enterprise) @@ -421,4 +421,66 @@ feature %q{ end end end -end \ No newline at end of file + + context "as an enterprise manager" do + let(:s1) { create(:supplier_enterprise, name: 'First Supplier') } + let(:s2) { create(:supplier_enterprise, name: 'Another Supplier') } + let(:s3) { create(:supplier_enterprise, name: 'Yet Another Supplier') } + let(:d1) { create(:distributor_enterprise, name: 'First Distributor') } + let(:d2) { create(:distributor_enterprise, name: 'Another Distributor') } + let!(:product_supplied) { create(:product, supplier: s1, price: 10.0, on_hand: 6) } + let!(:product_not_supplied) { create(:product, supplier: s3) } + + before(:each) do + @enterprise_user = create_enterprise_user + @enterprise_user.enterprise_roles.build(enterprise: s1).save + @enterprise_user.enterprise_roles.build(enterprise: s2).save + @enterprise_user.enterprise_roles.build(enterprise: d1).save + + login_to_admin_as @enterprise_user + end + + it "shows only products that I supply" do + visit '/admin/products/bulk_edit' + + page.should have_field 'product_name', with: product_supplied.name + page.should_not have_field 'product_name', with: product_not_supplied.name + end + + it "shows only suppliers that I manage" do + visit '/admin/products/bulk_edit' + + page.should have_select 'supplier', with_options: [s1.name, s2.name], selected: s1.name + page.should_not have_select 'supplier', with_options: [s3.name] + end + + it "allows me to update a product" do + p = product_supplied + + visit '/admin/products/bulk_edit' + + page.should have_field "product_name", with: p.name + page.should have_select "supplier", selected: s1.name + page.should have_field "available_on", with: p.available_on.strftime("%F %T") + page.should have_field "price", with: "10.0" + page.should have_field "on_hand", with: "6" + + fill_in "product_name", with: "Big Bag Of Potatoes" + select s2.name, from: 'supplier' + fill_in "available_on", with: (Date.today-3).strftime("%F %T") + fill_in "price", with: "20" + fill_in "on_hand", with: "18" + + click_button 'Update' + page.find("span#update-status-message").should have_content "Update complete" + + visit '/admin/products/bulk_edit' + + page.should have_field "product_name", with: "Big Bag Of Potatoes" + page.should have_select "supplier", selected: s2.name + page.should have_field "available_on", with: (Date.today-3).strftime("%F %T") + page.should have_field "price", with: "20.0" + page.should have_field "on_hand", with: "18" + end + end +end diff --git a/spec/javascripts/unit/bulk_product_update_spec.js b/spec/javascripts/unit/bulk_product_update_spec.js index bc39fd22fe..549d602541 100644 --- a/spec/javascripts/unit/bulk_product_update_spec.js +++ b/spec/javascripts/unit/bulk_product_update_spec.js @@ -202,8 +202,8 @@ describe("AdminBulkProductsCtrl", function(){ it("gets a list of suppliers and then resets products with a list of data", function(){ httpBackend.expectGET('/api/users/authorise_api?token=api_key').respond( { "success": "Use of API Authorised" } ); - httpBackend.expectGET('/api/enterprises?template=bulk_index;q[is_primary_producer_eq]=true').respond("list of suppliers"); - httpBackend.expectGET('/api/products?template=bulk_index').respond("list of products"); + httpBackend.expectGET('/api/enterprises/managed?template=bulk_index&q[is_primary_producer_eq]=true').respond("list of suppliers"); + httpBackend.expectGET('/api/products/managed?template=bulk_index').respond("list of products"); spyOn(scope, "resetProducts"); scope.initialise('api_key'); httpBackend.flush(); diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index 05bb1d39ad..e4d04a69ab 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -32,11 +32,11 @@ module Spree let (:order) {create(:order, )} it "should be able to read/write their enterprises' products" do - should have_ability([:admin, :read, :update, :bulk_edit, :clone, :destroy], for: p1) + should have_ability([:admin, :read, :update, :bulk_edit, :bulk_update, :clone, :destroy], for: p1) end it "should not be able to read/write other enterprises' products" do - should_not have_ability([:admin, :read, :update, :bulk_edit, :clone, :destroy], for: p2) + should_not have_ability([:admin, :read, :update, :bulk_edit, :bulk_update, :clone, :destroy], for: p2) end it "should be able to create a new product" do From f870e705602324966fffae84b961ca7dede3bf7f Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 Aug 2013 11:40:33 +1000 Subject: [PATCH 03/15] Enterprise manager can edit and bulk edit enterprises they have access to --- .../admin/enterprises_controller.rb | 6 +++- app/models/spree/ability_decorator.rb | 3 +- spec/features/admin/enterprises_spec.rb | 28 ++++++++++++++++++- spec/models/ability_spec.rb | 4 +-- 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/app/controllers/admin/enterprises_controller.rb b/app/controllers/admin/enterprises_controller.rb index 981299a8ea..d524966d7c 100644 --- a/app/controllers/admin/enterprises_controller.rb +++ b/app/controllers/admin/enterprises_controller.rb @@ -24,7 +24,11 @@ module Admin end def collection - super.managed_by(spree_current_user).order('is_primary_producer DESC, is_distributor ASC, name') + Enterprise.managed_by(spree_current_user).order('is_primary_producer DESC, is_distributor ASC, name') + end + + def collection_actions + [:index, :bulk_update] end end end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index ccd4252897..5c674fea09 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -47,8 +47,9 @@ class AbilityDecorator can [:admin, :index, :read, :create, :edit, :update], ExchangeVariant can [:admin, :index, :read, :create, :edit, :update], Exchange can [:admin, :index, :read, :create, :edit, :update], ExchangeFee + can [:admin, :index], Enterprise - can [:read, :edit, :update], Enterprise do |enterprise| + can [:read, :edit, :update, :bulk_update], Enterprise do |enterprise| user.enterprises.include? enterprise end diff --git a/spec/features/admin/enterprises_spec.rb b/spec/features/admin/enterprises_spec.rb index db97f28b9f..211ca93bbd 100644 --- a/spec/features/admin/enterprises_spec.rb +++ b/spec/features/admin/enterprises_spec.rb @@ -105,6 +105,7 @@ feature %q{ click_button 'Update' flash_message.should == 'Enterprise "Eaterprises" has been successfully updated!' + page.should have_selector '#listing_enterprises a', text: 'Eaterprises' end @@ -128,7 +129,6 @@ feature %q{ end context 'as an Enterprise user' do - let(:supplier1) { create(:supplier_enterprise, name: 'First Supplier') } let(:supplier2) { create(:supplier_enterprise, name: 'Another Supplier') } let(:distributor1) { create(:distributor_enterprise, name: 'First Distributor') } @@ -153,5 +153,31 @@ feature %q{ page.should_not have_content supplier2.name page.should_not have_content distributor2.name end + + scenario "can edit enterprises I have permission to" do + click_link 'Enterprises' + within('#listing_enterprises tbody tr:first') { click_link 'Edit' } + + fill_in 'enterprise_name', :with => 'Eaterprises' + click_button 'Update' + + flash_message.should == 'Enterprise "Eaterprises" has been successfully updated!' + page.should have_selector '#listing_enterprises a', text: 'Eaterprises' + end + + scenario "can bulk edit enterprise collection dates/times for enterprises I have permission to" do + click_link 'Enterprises' + + fill_in 'enterprise_set_collection_attributes_0_next_collection_at', :with => 'One' + fill_in 'enterprise_set_collection_attributes_1_next_collection_at', :with => 'Two' + click_button 'Update' + + flash_message.should == 'Distributor collection times updated.' + + supplier1.reload.next_collection_at.should == 'One' + distributor1.reload.next_collection_at.should == 'Two' + supplier2.reload.next_collection_at.should be_nil + distributor2.reload.next_collection_at.should be_nil + end end end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index e4d04a69ab..b31258bfc2 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -151,11 +151,11 @@ module Spree end it 'should have the ability to read and edit enterprises that I manage' do - should have_ability([:read, :edit, :update], for: s1) + should have_ability([:read, :edit, :update, :bulk_update], for: s1) end it 'should not have the ability to read and edit enterprises that I do not manage' do - should_not have_ability([:read, :edit, :update], for: s2) + should_not have_ability([:read, :edit, :update, :bulk_update], for: s2) end it 'should have the ability administrate enterpises' do From 5b824c1e22261586e9af1d8b0cccea0421178ff1 Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 22 Aug 2013 11:31:07 +1000 Subject: [PATCH 04/15] Prevent exception when order has no payments --- lib/open_food_web/order_and_distributor_report.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/open_food_web/order_and_distributor_report.rb b/lib/open_food_web/order_and_distributor_report.rb index 04a3596441..6d9556cef7 100644 --- a/lib/open_food_web/order_and_distributor_report.rb +++ b/lib/open_food_web/order_and_distributor_report.rb @@ -21,7 +21,7 @@ module OpenFoodWeb order_and_distributor_details << [order.created_at, order.id, order.bill_address.full_name, order.email, order.bill_address.phone, order.bill_address.city, line_item.product.sku, line_item.product.name, line_item.variant.options_text, line_item.quantity, line_item.max_quantity, line_item.price * line_item.quantity, line_item.distribution_fee, - order.payments.first.payment_method.andand.name, + order.payments.first.andand.payment_method.andand.name, order.distributor.andand.name, order.distributor.address.address1, order.distributor.address.city, order.distributor.address.zipcode, order.special_instructions ] end end From 3d32e6480bc726f5db8e5936a4a75318d25ec3f4 Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 22 Aug 2013 11:49:18 +1000 Subject: [PATCH 05/15] Enterprise user can access all OFN reports --- .../spree/admin/base_controller_decorator.rb | 14 ++++++++++++++ app/models/spree/ability_decorator.rb | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 app/controllers/spree/admin/base_controller_decorator.rb diff --git a/app/controllers/spree/admin/base_controller_decorator.rb b/app/controllers/spree/admin/base_controller_decorator.rb new file mode 100644 index 0000000000..8e876513fa --- /dev/null +++ b/app/controllers/spree/admin/base_controller_decorator.rb @@ -0,0 +1,14 @@ +Spree::Admin::BaseController.class_eval do + # Override Spree method + # It's a shame Spree doesn't just let CanCan handle this in it's own way + def authorize_admin + if respond_to?(:model_class, true) && model_class + record = model_class + else + # this line changed to allow specificity for each non-resource controller (to be consistent with "authorize_resource :class => false", see https://github.com/ryanb/cancan/blob/60cf6a67ef59c0c9b63bc27ea0101125c4193ea6/lib/cancan/controller_resource.rb#L146) + record = self.class.to_s.sub("Controller", "").underscore.split('/').last.singularize.to_sym + end + authorize! :admin, record + authorize! action, record + end +end \ No newline at end of file diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index 5c674fea09..c6e187e205 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -17,7 +17,7 @@ class AbilityDecorator can [:admin, :index, :read, :search], Spree::Taxon can [:admin, :index, :read, :create, :edit], Spree::Classification - #User can only access orders that they are a distributor for + #Enterprise User can only access orders that they are a distributor for can [:index, :create], Spree::Order can [:admin, :read, :update, :fire, :resend ], Spree::Order do |order| user.enterprises.include? order.distributor @@ -53,6 +53,8 @@ class AbilityDecorator user.enterprises.include? enterprise end + #Enterprise User can access reports page + can [:admin, :index, :orders_and_distributors, :group_buys, :bulk_coop, :payments, :order_cycles], :report end end end From f1fa90d7c350646c024bf3b7fc3626c0e79aab4d Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 Aug 2013 16:53:11 +1000 Subject: [PATCH 06/15] Clone order cycles --- .../admin/order_cycles_controller.rb | 7 +++ app/models/exchange.rb | 25 ++++++++ app/models/order_cycle.rb | 11 ++++ app/views/admin/order_cycles/index.html.haml | 5 +- config/routes.rb | 1 + spec/features/admin/order_cycles_spec.rb | 16 ++++++ spec/models/exchange_spec.rb | 57 +++++++++++++++++++ spec/models/order_cycle_spec.rb | 15 +++++ 8 files changed, 135 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 924510dbfc..08556bd458 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -61,6 +61,13 @@ module Admin end end + def clone + @order_cycle = OrderCycle.find params[:order_cycle_id] + @order_cycle.clone! + redirect_to main_app.admin_order_cycles_path, :notice => "Your order cycle #{@order_cycle.name} has been cloned." + end + + protected def collection OrderCycle.managed_by(spree_current_user) diff --git a/app/models/exchange.rb b/app/models/exchange.rb index b56fef9e8b..3d5f89ba52 100644 --- a/app/models/exchange.rb +++ b/app/models/exchange.rb @@ -21,7 +21,32 @@ class Exchange < ActiveRecord::Base scope :to_enterprises, lambda { |enterprises| where('exchanges.receiver_id IN (?)', enterprises) } scope :with_variant, lambda { |variant| joins(:exchange_variants).where('exchange_variants.variant_id = ?', variant) } + def clone!(new_order_cycle) + exchange = self.dup + exchange.order_cycle = new_order_cycle + exchange.enterprise_fee_ids = self.enterprise_fee_ids + exchange.variant_ids = self.variant_ids + exchange.save! + exchange + end + def incoming? receiver == order_cycle.coordinator end + + def to_h(core=false) + h = attributes.merge({ 'variant_ids' => variant_ids, 'enterprise_fee_ids' => enterprise_fee_ids }) + h.reject! { |k| %w(id order_cycle_id created_at updated_at).include? k } if core + h + end + + def eql?(e) + if e.respond_to? :to_h + self.to_h(true) == e.to_h(true) + else + super e + end + end + + end diff --git a/app/models/order_cycle.rb b/app/models/order_cycle.rb index e52bb01dc8..2f48de84aa 100644 --- a/app/models/order_cycle.rb +++ b/app/models/order_cycle.rb @@ -28,6 +28,17 @@ class OrderCycle < ActiveRecord::Base end } + + def clone! + oc = self.dup + oc.name = "COPY OF #{oc.name}" + oc.orders_open_at = oc.orders_close_at = nil + oc.coordinator_fee_ids = self.coordinator_fee_ids + oc.save! + self.exchanges.each { |e| e.clone!(oc) } + oc.reload + end + def suppliers self.exchanges.where(:receiver_id => self.coordinator).map(&:sender).uniq end diff --git a/app/views/admin/order_cycles/index.html.haml b/app/views/admin/order_cycles/index.html.haml index 367f670849..745e19e92c 100644 --- a/app/views/admin/order_cycles/index.html.haml +++ b/app/views/admin/order_cycles/index.html.haml @@ -17,7 +17,7 @@ %th Suppliers %th Distributors %th Products - %th + %th.actions %tbody = f.fields_for :collection do |order_cycle_form| - order_cycle = order_cycle_form.object @@ -37,5 +37,6 @@ %td.products - order_cycle.variants.each do |v| = image_tag(v.images.first.attachment.url(:mini)) if v.images.present? - %td + %td.actions + = link_to '', main_app.admin_order_cycle_clone_path(order_cycle), class: 'clone-order-cycle icon-copy no-text' = f.submit 'Update' diff --git a/config/routes.rb b/config/routes.rb index da48f1b6e1..b828c2a902 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,6 +19,7 @@ Openfoodweb::Application.routes.draw do namespace :admin do resources :order_cycles do post :bulk_update, :on => :collection, :as => :bulk_update + get :clone end resources :enterprises do diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index 716894272b..0e03b69858 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -343,6 +343,22 @@ feature %q{ OrderCycle.all.map { |oc| oc.orders_close_at.sec }.should == [1, 3, 5] end + scenario "cloning an order cycle" do + # Given an order cycle + oc = create(:order_cycle) + + # When I clone it + login_to_admin_section + click_link 'Order Cycles' + first('a.clone-order-cycle').click + flash_message.should == "Your order cycle #{oc.name} has been cloned." + + # Then I should have clone of the order cycle + occ = OrderCycle.last + occ.name.should == "COPY OF #{oc.name}" + end + + context 'as an Enterprise user' do let(:supplier1) { create(:supplier_enterprise, name: 'First Supplier') } diff --git a/spec/models/exchange_spec.rb b/spec/models/exchange_spec.rb index 3dc72a8a2d..2215bd50a9 100644 --- a/spec/models/exchange_spec.rb +++ b/spec/models/exchange_spec.rb @@ -97,4 +97,61 @@ describe Exchange do Exchange.with_variant(v).should == [ex] end end + + it "clones itself" do + oc = create(:order_cycle) + new_oc = create(:simple_order_cycle) + + ex1 = oc.exchanges.last + ex2 = ex1.clone! new_oc + + ex1.eql?(ex2).should be_true + end + + describe "converting to hash" do + let(:oc) { create(:order_cycle) } + let(:exchange) do + exchange = oc.exchanges.last + exchange.payment_enterprise = Enterprise.last + exchange.save! + exchange + end + + it "converts to a hash" do + exchange.to_h.should == + {'id' => exchange.id, 'order_cycle_id' => oc.id, + 'sender_id' => exchange.sender_id, 'receiver_id' => exchange.receiver_id, + 'payment_enterprise_id' => exchange.payment_enterprise_id, 'variant_ids' => exchange.variant_ids, + 'enterprise_fee_ids' => exchange.enterprise_fee_ids, + 'pickup_time' => exchange.pickup_time, 'pickup_instructions' => exchange.pickup_instructions, + 'created_at' => exchange.created_at, 'updated_at' => exchange.updated_at} + end + + it "converts to a hash of core attributes only" do + exchange.to_h(true).should == + {'sender_id' => exchange.sender_id, 'receiver_id' => exchange.receiver_id, + 'payment_enterprise_id' => exchange.payment_enterprise_id, 'variant_ids' => exchange.variant_ids, + 'enterprise_fee_ids' => exchange.enterprise_fee_ids, + 'pickup_time' => exchange.pickup_time, 'pickup_instructions' => exchange.pickup_instructions} + end + end + + describe "comparing equality" do + it "compares Exchanges using to_h" do + e1 = Exchange.new + e2 = Exchange.new + + e1.stub(:to_h) { {'sender_id' => 456} } + e2.stub(:to_h) { {'sender_id' => 456} } + + e1.eql?(e2).should be_true + end + + it "compares other objects using super" do + exchange = Exchange.new + exchange_fee = ExchangeFee.new + + exchange.eql?(exchange_fee).should be_false + end + end end diff --git a/spec/models/order_cycle_spec.rb b/spec/models/order_cycle_spec.rb index e5a2c58970..8933e6a58c 100644 --- a/spec/models/order_cycle_spec.rb +++ b/spec/models/order_cycle_spec.rb @@ -141,6 +141,21 @@ describe OrderCycle do end end + it "clones itself" do + oc = create(:order_cycle) + occ = oc.clone! + + occ = OrderCycle.last + occ.name.should == "COPY OF #{oc.name}" + occ.orders_open_at.should be_nil + occ.orders_close_at.should be_nil + occ.coordinator.should == oc.coordinator + + occ.coordinator_fee_ids.should == oc.coordinator_fee_ids + + (0..occ.exchanges.count).all? { |i| occ.exchanges[i].eql? oc.exchanges[i] }.should be_true + end + describe "creating adjustments for a line item" do let(:oc) { OrderCycle.new } let(:line_item) { double(:line_item, variant: 123) } From 8a092697eef33c5079bd4ddd34bb8b79f37f7738 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 Aug 2013 17:11:53 +1000 Subject: [PATCH 07/15] Enterprise manager can clone an order cycle --- app/controllers/admin/order_cycles_controller.rb | 2 +- app/models/spree/ability_decorator.rb | 2 +- app/views/admin/order_cycles/index.html.haml | 2 +- config/routes.rb | 2 +- spec/features/admin/order_cycles_spec.rb | 12 ++++++++++++ spec/models/ability_spec.rb | 4 ++-- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/app/controllers/admin/order_cycles_controller.rb b/app/controllers/admin/order_cycles_controller.rb index 08556bd458..18ec545de2 100644 --- a/app/controllers/admin/order_cycles_controller.rb +++ b/app/controllers/admin/order_cycles_controller.rb @@ -62,7 +62,7 @@ module Admin end def clone - @order_cycle = OrderCycle.find params[:order_cycle_id] + @order_cycle = OrderCycle.find params[:id] @order_cycle.clone! redirect_to main_app.admin_order_cycles_path, :notice => "Your order cycle #{@order_cycle.name} has been cloned." end diff --git a/app/models/spree/ability_decorator.rb b/app/models/spree/ability_decorator.rb index c6e187e205..9b2647f45e 100644 --- a/app/models/spree/ability_decorator.rb +++ b/app/models/spree/ability_decorator.rb @@ -34,7 +34,7 @@ class AbilityDecorator user.enterprises.include? payment_method.distributor end - can [:admin, :index, :read, :edit, :update], OrderCycle do |order_cycle| + can [:admin, :index, :read, :edit, :update, :clone], OrderCycle do |order_cycle| user.enterprises.include? order_cycle.coordinator end diff --git a/app/views/admin/order_cycles/index.html.haml b/app/views/admin/order_cycles/index.html.haml index 745e19e92c..8ae14a8ee7 100644 --- a/app/views/admin/order_cycles/index.html.haml +++ b/app/views/admin/order_cycles/index.html.haml @@ -38,5 +38,5 @@ - order_cycle.variants.each do |v| = image_tag(v.images.first.attachment.url(:mini)) if v.images.present? %td.actions - = link_to '', main_app.admin_order_cycle_clone_path(order_cycle), class: 'clone-order-cycle icon-copy no-text' + = link_to '', main_app.clone_admin_order_cycle_path(order_cycle), class: 'clone-order-cycle icon-copy no-text' = f.submit 'Update' diff --git a/config/routes.rb b/config/routes.rb index b828c2a902..1a70152f5e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,7 +19,7 @@ Openfoodweb::Application.routes.draw do namespace :admin do resources :order_cycles do post :bulk_update, :on => :collection, :as => :bulk_update - get :clone + get :clone, on: :member end resources :enterprises do diff --git a/spec/features/admin/order_cycles_spec.rb b/spec/features/admin/order_cycles_spec.rb index 0e03b69858..01c1b6acad 100644 --- a/spec/features/admin/order_cycles_spec.rb +++ b/spec/features/admin/order_cycles_spec.rb @@ -426,6 +426,18 @@ feature %q{ order_cycle.coordinator.should == distributor1 end + scenario "cloning an order cycle" do + oc = create(:simple_order_cycle) + + click_link "Order Cycles" + first('a.clone-order-cycle').click + flash_message.should == "Your order cycle #{oc.name} has been cloned." + + # Then I should have clone of the order cycle + occ = OrderCycle.last + occ.name.should == "COPY OF #{oc.name}" + end + end end diff --git a/spec/models/ability_spec.rb b/spec/models/ability_spec.rb index b31258bfc2..b8140d29d7 100644 --- a/spec/models/ability_spec.rb +++ b/spec/models/ability_spec.rb @@ -126,11 +126,11 @@ module Spree let(:oc2) { create(:simple_order_cycle) } it "should be able to read/write OrderCycles they are the co-ordinator of" do - should have_ability([:admin, :index, :read, :edit], for: oc1) + should have_ability([:admin, :index, :read, :edit, :update, :clone], for: oc1) end it "should not be able to read/write OrderCycles they are not the co-ordinator of" do - should_not have_ability([:admin, :index, :read, :create, :edit], for: oc2) + should_not have_ability([:admin, :index, :read, :create, :edit, :update, :clone], for: oc2) end it "should be able to create OrderCycles" do From 1bfb54f31053fd8097632fc60ea878a836dfbb28 Mon Sep 17 00:00:00 2001 From: David Cook Date: Fri, 23 Aug 2013 13:25:10 +1000 Subject: [PATCH 08/15] Refactor authorisation to play nice with Spree instead of patching it (thanks to Rohan's suggestions) --- .../spree/admin/base_controller_decorator.rb | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 app/controllers/spree/admin/base_controller_decorator.rb diff --git a/app/controllers/spree/admin/base_controller_decorator.rb b/app/controllers/spree/admin/base_controller_decorator.rb deleted file mode 100644 index 8e876513fa..0000000000 --- a/app/controllers/spree/admin/base_controller_decorator.rb +++ /dev/null @@ -1,14 +0,0 @@ -Spree::Admin::BaseController.class_eval do - # Override Spree method - # It's a shame Spree doesn't just let CanCan handle this in it's own way - def authorize_admin - if respond_to?(:model_class, true) && model_class - record = model_class - else - # this line changed to allow specificity for each non-resource controller (to be consistent with "authorize_resource :class => false", see https://github.com/ryanb/cancan/blob/60cf6a67ef59c0c9b63bc27ea0101125c4193ea6/lib/cancan/controller_resource.rb#L146) - record = self.class.to_s.sub("Controller", "").underscore.split('/').last.singularize.to_sym - end - authorize! :admin, record - authorize! action, record - end -end \ No newline at end of file From 078bd033b60b5448f867b30a59d4b1ca4896d578 Mon Sep 17 00:00:00 2001 From: David Cook Date: Fri, 23 Aug 2013 13:25:42 +1000 Subject: [PATCH 09/15] Refactor authorisation to play nice with Spree instead of patching it (thanks to Rohan's suggestions) --- .../orders/customer_details_controller_decorator.rb | 10 +++++----- .../spree/admin/reports_controller_decorator.rb | 5 +++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/controllers/spree/admin/orders/customer_details_controller_decorator.rb b/app/controllers/spree/admin/orders/customer_details_controller_decorator.rb index fe98451154..bbccdf9174 100644 --- a/app/controllers/spree/admin/orders/customer_details_controller_decorator.rb +++ b/app/controllers/spree/admin/orders/customer_details_controller_decorator.rb @@ -1,8 +1,8 @@ Spree::Admin::Orders::CustomerDetailsController.class_eval do - #Override BaseController.authorize_admin to inherit CanCan permissions for the current order - def authorize_admin - load_order unless @order - authorize! :admin, @order - authorize! params[:action].to_sym, @order + # Inherit CanCan permissions for the current order + def model_class + load_order unless @order + @order end + end \ No newline at end of file diff --git a/app/controllers/spree/admin/reports_controller_decorator.rb b/app/controllers/spree/admin/reports_controller_decorator.rb index b4cf6c394c..244c62163f 100644 --- a/app/controllers/spree/admin/reports_controller_decorator.rb +++ b/app/controllers/spree/admin/reports_controller_decorator.rb @@ -11,6 +11,11 @@ Spree::Admin::ReportsController.class_eval do Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:payments => {:name => "Payment Reports", :description => "Reports for Payments"}}) Spree::Admin::ReportsController::AVAILABLE_REPORTS.merge!({:order_cycles => {:name => "Order Cycle Reports", :description => "Reports for Order Cycles"}}) + # Equivalent to CanCan's "authorize_resource :class => false" (see https://github.com/ryanb/cancan/blob/60cf6a67ef59c0c9b63bc27ea0101125c4193ea6/lib/cancan/controller_resource.rb#L146) + def model_class + self.class.to_s.sub("Controller", "").underscore.split('/').last.singularize.to_sym + end + def orders_and_distributors params[:q] = {} unless params[:q] From 02089541cd9ce213fca9bea8cf1696dd66171fe0 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 Aug 2013 12:16:57 +1000 Subject: [PATCH 10/15] Syntax tweaks --- .../admin/orders/customer_details_controller_decorator.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/spree/admin/orders/customer_details_controller_decorator.rb b/app/controllers/spree/admin/orders/customer_details_controller_decorator.rb index bbccdf9174..19dd3aae65 100644 --- a/app/controllers/spree/admin/orders/customer_details_controller_decorator.rb +++ b/app/controllers/spree/admin/orders/customer_details_controller_decorator.rb @@ -4,5 +4,4 @@ Spree::Admin::Orders::CustomerDetailsController.class_eval do load_order unless @order @order end - -end \ No newline at end of file +end From 2e1de9a6d37b59f3a28353391a7fbeb3e60fe07e Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 Aug 2013 13:12:36 +1000 Subject: [PATCH 11/15] Fix admin create order - remove override on spree address form, update to spree patched to fix respond_override (spree issue #2210), fix nil state error --- Gemfile.lock | 90 +++++++++---------- app/models/spree/address_decorator.rb | 6 +- app/views/admin/enterprises/_form.html.haml | 2 +- ...ml.haml => _address_form_simple.html.haml} | 0 4 files changed, 48 insertions(+), 50 deletions(-) rename app/views/spree/admin/shared/{_address_form.html.haml => _address_form_simple.html.haml} (100%) diff --git a/Gemfile.lock b/Gemfile.lock index c5b8630b77..b93b40b87c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -16,54 +16,12 @@ GIT GIT remote: git://github.com/eaterprises/spree-last-address.git - revision: f93ea5a6b06e4605ea9c3fc5ef8e71f8e6aa0ffc + revision: 39653f38429546f6367e376e823d2b5482d1cd8d branch: 1-3-stable specs: spree_last_address (1.1.0) spree_core (>= 1.1) -GIT - remote: git://github.com/eaterprises/spree.git - revision: 4fa1f51ba70519bfd3be0975e5b71f2ea73bbbd6 - branch: 1-3-stable - specs: - spree (1.3.3) - spree_api (= 1.3.3) - spree_cmd (= 1.3.3) - spree_core (= 1.3.3) - spree_promo (= 1.3.3) - spree_sample (= 1.3.3) - spree_api (1.3.3) - spree_core (= 1.3.3) - versioncake (= 0.4.0) - spree_cmd (1.3.3) - thor (>= 0.14.6) - spree_core (1.3.3) - activemerchant (~> 1.34) - acts_as_list (= 0.1.4) - awesome_nested_set (= 2.1.5) - aws-sdk (~> 1.3.4) - cancan (= 1.6.8) - deface (>= 0.9.0) - ffaker (~> 1.15.0) - highline (= 1.6.18) - jquery-rails (~> 2.2.0) - json (>= 1.5.5) - kaminari (= 0.13.0) - money (= 5.0.0) - paperclip (~> 2.8) - rabl (= 0.7.2) - rails (~> 3.2.14) - ransack (= 0.7.2) - select2-rails (= 3.2.1) - state_machine (= 1.1.2) - stringex (~> 1.3.2) - truncate_html (~> 0.5.5) - spree_promo (1.3.3) - spree_core (= 1.3.3) - spree_sample (1.3.3) - spree_core (= 1.3.3) - GIT remote: git://github.com/spree/deface.git revision: 1110a1336252109bce7f98f9182042e0bc2930ae @@ -107,6 +65,46 @@ GIT devise-encryptable (= 0.1.2) spree_core +PATH + remote: /home/rohan/work/rm/eaterprises/spree + specs: + spree (1.3.3) + spree_api (= 1.3.3) + spree_cmd (= 1.3.3) + spree_core (= 1.3.3) + spree_promo (= 1.3.3) + spree_sample (= 1.3.3) + spree_api (1.3.3) + spree_core (= 1.3.3) + versioncake (= 0.4.0) + spree_cmd (1.3.3) + thor (>= 0.14.6) + spree_core (1.3.3) + activemerchant (~> 1.34) + acts_as_list (= 0.1.4) + awesome_nested_set (= 2.1.5) + aws-sdk (~> 1.3.4) + cancan (= 1.6.8) + deface (>= 0.9.0) + ffaker (~> 1.15.0) + highline (= 1.6.18) + jquery-rails (~> 2.2.0) + json (>= 1.5.5) + kaminari (= 0.13.0) + money (= 5.0.0) + paperclip (~> 2.8) + rabl (= 0.7.2) + rails (~> 3.2.14) + ransack (= 0.7.2) + select2-rails (= 3.2.1) + state_machine (= 1.1.2) + stringex (~> 1.3.2) + truncate_html (~> 0.5.5) + spree_promo (1.3.3) + spree_core (= 1.3.3) + spree_sample (1.3.3) + spree_core (= 1.3.3) + PATH remote: lib/chili/eaterprises_feature specs: @@ -281,7 +279,7 @@ GEM httparty (0.11.0) multi_json (~> 1.0) multi_xml (>= 0.5.2) - i18n (0.6.4) + i18n (0.6.5) journey (1.0.4) jquery-rails (2.2.2) railties (>= 3.0, < 5.0) @@ -304,7 +302,7 @@ GEM mime-types (~> 1.16) treetop (~> 1.4.8) method_source (0.8.1) - mime-types (1.23) + mime-types (1.24) mini_portile (0.5.1) money (5.0.0) i18n (~> 0.4) @@ -431,7 +429,7 @@ GEM thor (0.18.1) tilt (1.4.1) timecop (0.6.2.2) - treetop (1.4.14) + treetop (1.4.15) polyglot polyglot (>= 0.3.1) truncate_html (0.5.5) diff --git a/app/models/spree/address_decorator.rb b/app/models/spree/address_decorator.rb index b007f3621b..3a06b54d18 100644 --- a/app/models/spree/address_decorator.rb +++ b/app/models/spree/address_decorator.rb @@ -4,11 +4,11 @@ Spree::Address.class_eval do geocoded_by :full_address after_validation :geocode - delegate :name, :to => :state, :prefix => true + delegate :name, :to => :state, :prefix => true, :allow_nil => true def full_address - full_address = [address1, address2, zipcode, city, country.name, state.name] + full_address = [address1, address2, zipcode, city, country.name, state.andand.name] filtered_address = full_address.select{ |field| !field.nil? && field != '' } filtered_address.compact.join(', ') end -end \ No newline at end of file +end diff --git a/app/views/admin/enterprises/_form.html.haml b/app/views/admin/enterprises/_form.html.haml index 1cd6efa5e0..4045349ee8 100644 --- a/app/views/admin/enterprises/_form.html.haml +++ b/app/views/admin/enterprises/_form.html.haml @@ -42,7 +42,7 @@ %legend Address %table = f.fields_for :address do |address_form| - = render 'spree/admin/shared/address_form', :f => address_form + = render 'spree/admin/shared/address_form_simple', :f => address_form %fieldset %legend Pickup details %table{"data-hook" => "distributors_pickup_details"} diff --git a/app/views/spree/admin/shared/_address_form.html.haml b/app/views/spree/admin/shared/_address_form_simple.html.haml similarity index 100% rename from app/views/spree/admin/shared/_address_form.html.haml rename to app/views/spree/admin/shared/_address_form_simple.html.haml From 2cab83cb29f850e316d4689e96414665b0f3cd5c Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 Aug 2013 13:13:26 +1000 Subject: [PATCH 12/15] Admin create order can set distributor and order cycle --- .../add_distribution_fields.html.haml.deface | 14 +++++ spec/features/admin/orders_spec.rb | 56 ++++++++++++++----- spec/spec_helper.rb | 1 + 3 files changed, 56 insertions(+), 15 deletions(-) create mode 100644 app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface new file mode 100644 index 0000000000..3f79fccc03 --- /dev/null +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -0,0 +1,14 @@ +/ insert_before "[data-hook='admin_order_form_buttons']" + +%fieldset.no-border-bottom + %legend{align => 'center'} Distribution + + .alpha.six.columns + .field + = f.label :distributor_id + = f.collection_select :distributor_id, Enterprise.is_distributor.managed_by(spree_current_user), :id, :name, include_blank: true + + .omega.six.columns + .field + = f.label :order_cycle_id + = f.collection_select :order_cycle_id, OrderCycle.managed_by(spree_current_user), :id, :name, include_blank: true diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index a7e8542be9..8c63627505 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -17,26 +17,52 @@ feature %q{ create :check_payment, order: @order, amount: @order.total end - context "managing orders" do - scenario "capture multiple payments from the orders index page" do - # d.cook: could also test for an order that has had payment voided, then a new check payment created but not yet captured. But it's not critical and I know it works anyway. + scenario "creating an order with distributor and order cycle", js: true do + order_cycle = create(:order_cycle) + distributor = order_cycle.distributors.first + product = order_cycle.products.first - login_to_admin_section + login_to_admin_section - click_link 'Orders' - current_path.should == spree.admin_orders_path + click_link 'Orders' + click_link 'New Order' - # click the 'capture' link for the order - page.find("[data-action=capture][href*=#{@order.number}]").click + page.should have_content 'ADD PRODUCT' + targetted_select2_search product.name, from: '#add_variant_id', dropdown_css: '.select2-drop' + click_link 'Add' + page.has_selector? "table.index tbody[data-hook='admin_order_form_line_items'] tr" # Wait for JS + page.should have_selector 'td', text: product.name - flash_message.should == "Payment Updated" + select distributor.name, from: 'order_distributor_id' + select order_cycle.name, from: 'order_order_cycle_id' + click_button 'Update' - # check the order was captured - @order.reload - @order.payment_state.should == "paid" + page.should have_selector 'h1', text: 'Customer Details' + o = Spree::Order.last + o.distributor.should == distributor + o.order_cycle.should == order_cycle + end - # we should still be on the same page - current_path.should == spree.admin_orders_path - end + it "can't change distributor and order cycle once order is created (or similar restriction)" + + scenario "capture multiple payments from the orders index page" do + # d.cook: could also test for an order that has had payment voided, then a new check payment created but not yet captured. But it's not critical and I know it works anyway. + + login_to_admin_section + + click_link 'Orders' + current_path.should == spree.admin_orders_path + + # click the 'capture' link for the order + page.find("[data-action=capture][href*=#{@order.number}]").click + + flash_message.should == "Payment Updated" + + # check the order was captured + @order.reload + @order.payment_state.should == "paid" + + # we should still be on the same page + current_path.should == spree.admin_orders_path end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 20d9668177..1d82a2b9fd 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -22,6 +22,7 @@ WebMock.disable_net_connect!(:allow_localhost => true) # in spec/support/ and its subdirectories. Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} require 'spree/core/testing_support/controller_requests' +require 'spree/core/testing_support/capybara_ext' require 'active_record/fixtures' fixtures_dir = File.expand_path('../../db/default', __FILE__) From 2a662e6b6f0b3bd90b0bd43841bf42210a89b9cb Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 Aug 2013 13:17:36 +1000 Subject: [PATCH 13/15] Switch from rvmrc to ruby-version/gemset --- .gitignore | 2 -- .ruby-gemset | 1 + .ruby-version | 1 + .rvmrc | 48 ------------------------------------------------ 4 files changed, 2 insertions(+), 50 deletions(-) create mode 100644 .ruby-gemset create mode 100644 .ruby-version delete mode 100644 .rvmrc diff --git a/.gitignore b/.gitignore index 12c35da681..873f37faea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ .bundle .rbenv-version -.ruby-version -.ruby-gemset .swp *.swo *.swp diff --git a/.ruby-gemset b/.ruby-gemset new file mode 100644 index 0000000000..193f1d15ab --- /dev/null +++ b/.ruby-gemset @@ -0,0 +1 @@ +openfoodweb diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000000..2aaf2528c3 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +ruby-1.9.3-p392 diff --git a/.rvmrc b/.rvmrc deleted file mode 100644 index 4a8ffc396b..0000000000 --- a/.rvmrc +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash - -# This is an RVM Project .rvmrc file, used to automatically load the ruby -# development environment upon cd'ing into the directory - -# First we specify our desired [@], the @gemset name is optional, -# Only full ruby name is supported here, for short names use: -# echo "rvm use 1.9.3" > .rvmrc -environment_id="ruby-1.9.3-p392@openfoodweb" - -# Uncomment the following lines if you want to verify rvm version per project -# rvmrc_rvm_version="1.18.21 (stable)" # 1.10.1 seams as a safe start -# eval "$(echo ${rvm_version}.${rvmrc_rvm_version} | awk -F. '{print "[[ "$1*65536+$2*256+$3" -ge "$4*65536+$5*256+$6" ]]"}' )" || { -# echo "This .rvmrc file requires at least RVM ${rvmrc_rvm_version}, aborting loading." -# return 1 -# } - -# First we attempt to load the desired environment directly from the environment -# file. This is very fast and efficient compared to running through the entire -# CLI and selector. If you want feedback on which environment was used then -# insert the word 'use' after --create as this triggers verbose mode. -if [[ -d "${rvm_path:-$HOME/.rvm}/environments" - && -s "${rvm_path:-$HOME/.rvm}/environments/$environment_id" ]] -then - \. "${rvm_path:-$HOME/.rvm}/environments/$environment_id" - [[ -s "${rvm_path:-$HOME/.rvm}/hooks/after_use" ]] && - \. "${rvm_path:-$HOME/.rvm}/hooks/after_use" || true -else - # If the environment file has not yet been created, use the RVM CLI to select. - rvm --create "$environment_id" || { - echo "Failed to create RVM environment '${environment_id}'." - return 1 - } -fi - -# If you use bundler, this might be useful to you: -# if [[ -s Gemfile ]] && { -# ! builtin command -v bundle >/dev/null || -# builtin command -v bundle | GREP_OPTIONS= \grep $rvm_path/bin/bundle >/dev/null -# } -# then -# printf "%b" "The rubygem 'bundler' is not installed. Installing it now.\n" -# gem install bundler -# fi -# if [[ -s Gemfile ]] && builtin command -v bundle >/dev/null -# then -# bundle install | GREP_OPTIONS= \grep -vE '^Using|Your bundle is complete' -# fi From 158cd6994bd84d1fbc833e8a6884396b1d5ef329 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 Aug 2013 13:18:27 +1000 Subject: [PATCH 14/15] Update spree, syntax fix --- Gemfile.lock | 82 +++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index b93b40b87c..b1b7b4846c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -22,6 +22,48 @@ GIT spree_last_address (1.1.0) spree_core (>= 1.1) +GIT + remote: git://github.com/eaterprises/spree.git + revision: 1c133672652e1ee8b6c8d694efe258e62378062e + branch: 1-3-stable + specs: + spree (1.3.3) + spree_api (= 1.3.3) + spree_cmd (= 1.3.3) + spree_core (= 1.3.3) + spree_promo (= 1.3.3) + spree_sample (= 1.3.3) + spree_api (1.3.3) + spree_core (= 1.3.3) + versioncake (= 0.4.0) + spree_cmd (1.3.3) + thor (>= 0.14.6) + spree_core (1.3.3) + activemerchant (~> 1.34) + acts_as_list (= 0.1.4) + awesome_nested_set (= 2.1.5) + aws-sdk (~> 1.3.4) + cancan (= 1.6.8) + deface (>= 0.9.0) + ffaker (~> 1.15.0) + highline (= 1.6.18) + jquery-rails (~> 2.2.0) + json (>= 1.5.5) + kaminari (= 0.13.0) + money (= 5.0.0) + paperclip (~> 2.8) + rabl (= 0.7.2) + rails (~> 3.2.14) + ransack (= 0.7.2) + select2-rails (= 3.2.1) + state_machine (= 1.1.2) + stringex (~> 1.3.2) + truncate_html (~> 0.5.5) + spree_promo (1.3.3) + spree_core (= 1.3.3) + spree_sample (1.3.3) + spree_core (= 1.3.3) + GIT remote: git://github.com/spree/deface.git revision: 1110a1336252109bce7f98f9182042e0bc2930ae @@ -65,46 +107,6 @@ GIT devise-encryptable (= 0.1.2) spree_core -PATH - remote: /home/rohan/work/rm/eaterprises/spree - specs: - spree (1.3.3) - spree_api (= 1.3.3) - spree_cmd (= 1.3.3) - spree_core (= 1.3.3) - spree_promo (= 1.3.3) - spree_sample (= 1.3.3) - spree_api (1.3.3) - spree_core (= 1.3.3) - versioncake (= 0.4.0) - spree_cmd (1.3.3) - thor (>= 0.14.6) - spree_core (1.3.3) - activemerchant (~> 1.34) - acts_as_list (= 0.1.4) - awesome_nested_set (= 2.1.5) - aws-sdk (~> 1.3.4) - cancan (= 1.6.8) - deface (>= 0.9.0) - ffaker (~> 1.15.0) - highline (= 1.6.18) - jquery-rails (~> 2.2.0) - json (>= 1.5.5) - kaminari (= 0.13.0) - money (= 5.0.0) - paperclip (~> 2.8) - rabl (= 0.7.2) - rails (~> 3.2.14) - ransack (= 0.7.2) - select2-rails (= 3.2.1) - state_machine (= 1.1.2) - stringex (~> 1.3.2) - truncate_html (~> 0.5.5) - spree_promo (1.3.3) - spree_core (= 1.3.3) - spree_sample (1.3.3) - spree_core (= 1.3.3) - PATH remote: lib/chili/eaterprises_feature specs: From 4f8014306e84c6dca7129304cecc06ea69ad1a42 Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Fri, 23 Aug 2013 13:58:59 +1000 Subject: [PATCH 15/15] Admin can't change distributor or order cycle once order has been finalized --- .../add_distribution_fields.html.haml.deface | 26 +++++++++++++------ spec/features/admin/orders_spec.rb | 12 ++++++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface index 3f79fccc03..b7c60863d4 100644 --- a/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface +++ b/app/overrides/spree/admin/orders/_form/add_distribution_fields.html.haml.deface @@ -3,12 +3,22 @@ %fieldset.no-border-bottom %legend{align => 'center'} Distribution - .alpha.six.columns - .field - = f.label :distributor_id - = f.collection_select :distributor_id, Enterprise.is_distributor.managed_by(spree_current_user), :id, :name, include_blank: true + - if @order.complete? + .alpha.six.columns + %p + %b Distributor: + = f.object.distributor.andand.name || "None" + .omega.six.columns + %p + %b Order cycle: + = f.object.order_cycle.andand.name || "None" - .omega.six.columns - .field - = f.label :order_cycle_id - = f.collection_select :order_cycle_id, OrderCycle.managed_by(spree_current_user), :id, :name, include_blank: true + - else + .alpha.six.columns + .field + = f.label :distributor_id + = f.collection_select :distributor_id, Enterprise.is_distributor.managed_by(spree_current_user), :id, :name, include_blank: true + .omega.six.columns + .field + = f.label :order_cycle_id + = f.collection_select :order_cycle_id, OrderCycle.managed_by(spree_current_user), :id, :name, include_blank: true diff --git a/spec/features/admin/orders_spec.rb b/spec/features/admin/orders_spec.rb index 8c63627505..72ea151d41 100644 --- a/spec/features/admin/orders_spec.rb +++ b/spec/features/admin/orders_spec.rb @@ -43,7 +43,17 @@ feature %q{ o.order_cycle.should == order_cycle end - it "can't change distributor and order cycle once order is created (or similar restriction)" + scenario "can't change distributor or order cycle once order has been finalized" do + login_to_admin_section + click_link 'Orders' + page.find('td.actions a.icon-edit').click + + page.should have_no_select 'order_distributor_id' + page.should have_no_select 'order_order_cycle_id' + + page.should have_selector 'p', text: "Distributor: #{@order.distributor.name}" + page.should have_selector 'p', text: 'Order cycle: None' + end scenario "capture multiple payments from the orders index page" do # d.cook: could also test for an order that has had payment voided, then a new check payment created but not yet captured. But it's not critical and I know it works anyway.