From f1fa90d7c350646c024bf3b7fc3626c0e79aab4d Mon Sep 17 00:00:00 2001 From: Rohan Mitchell Date: Thu, 22 Aug 2013 16:53:11 +1000 Subject: [PATCH] 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) }