diff --git a/core/app/controllers/admin/line_items_controller.rb b/core/app/controllers/admin/line_items_controller.rb index f75b66261c4..6c24285e000 100644 --- a/core/app/controllers/admin/line_items_controller.rb +++ b/core/app/controllers/admin/line_items_controller.rb @@ -1,46 +1,64 @@ class Admin::LineItemsController < Admin::BaseController - resource_controller - belongs_to :order - actions :all, :except => :index + before_filter :load_order, :except => [:create] + before_filter :load_line_item, :only => [:destroy, :update] - create.flash nil - update.flash nil - destroy.flash nil - - #override r_c create action as we want to use order#add_variant instead of creating line_item def create - load_object - variant = Variant.find(params[:line_item][:variant_id]) - - before :create + @taxon = Taxon.find(params[:taxon][:parent_id]) + @taxonomy = Taxonomy.find params[:taxonomy_id] + variant = Variant.find(params[:line_item][:variant_id]) @order.add_variant(variant, params[:line_item][:quantity].to_i) if @order.save - after :create - set_flash :create - response_for :create + respond_to do |format| + format.html do + render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false + end + end else - after :create_fails - set_flash :create_fails - response_for :create_fails end + end + def destroy + if @line_item.destroy + respond_to do |format| + format.html { render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false } + end + else + respond_to do |format| + format.html do + render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false + end + end + end end - destroy.success.wants.html { render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false } - destroy.failure.wants.html { render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false } + def new + respond_to do |format| + format.html { render :action => :new, :layout => false } + end + end - new_action.response do |wants| - wants.html {render :action => :new, :layout => false} + def update + if @line_item.update_attributes(params[:line_item]) + respond_to do |format| + format.html { render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false} + end + else + respond_to do |format| + format.html { render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false} + end + end end - create.response do |wants| - wants.html { render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false} + + def load_order + @order = Order.find_by_number! params[:order_id] end - update.success.wants.html { render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false} - update.failure.wants.html { render :partial => "admin/orders/form", :locals => {:order => @order.reload}, :layout => false} + def load_line_item + @line_item = @order.line_items.find params[:id] + end end diff --git a/core/app/controllers/admin/orders_controller.rb b/core/app/controllers/admin/orders_controller.rb index 6e4a0da4384..af062fd9329 100644 --- a/core/app/controllers/admin/orders_controller.rb +++ b/core/app/controllers/admin/orders_controller.rb @@ -1,37 +1,49 @@ class Admin::OrdersController < Admin::BaseController require 'spree/gateway_error' - resource_controller before_filter :initialize_txn_partials before_filter :initialize_order_events - before_filter :load_object, :only => [:fire, :resend, :history, :user] + before_filter :load_order, :only => [:fire, :resend, :history, :user] before_filter :ensure_line_items, :only => [:update] - update do - flash nil - wants.html do - if !@order.line_items.empty? - unless @order.complete? + def index + load_orders + end + + def new + @order = Order.create + end - if params[:order].key?(:email) - @order.shipping_method = @order.available_shipping_methods(:front_end).first - @order.create_shipment! - redirect_to edit_admin_order_shipment_path(@order, @order.shipment) + def edit + load_order + end + + def update + respond_to do |format| + format.html do + if @order.update_attributes params[:order] + if !@order.line_items.empty? + unless @order.complete? + if params[:order].key?(:email) + shipping_method = @order.available_shipping_methods(:front_end).first + @order.shipping_method = shipping_method + @order.create_shipment! + redirect_to edit_admin_order_shipment_path(@order, @order.shipment) + else + redirect_to user_admin_order_path(@order) + end + else + redirect_to admin_order_path(@order) + end else - redirect_to user_admin_order_path(@order) + render :action => :new end - else - redirect_to admin_order_path(@order) + render :action => 'edit' end - else - render :action => :new end end end - def new - @order = @object = Order.create - end def fire # TODO - possible security check here but right now any admin can before any transition (and the state machine @@ -61,23 +73,23 @@ def user private - def object - @object ||= Order.find_by_number(params[:id], :include => :adjustments) if params[:id] - return @object || current_order + def load_order + @order ||= Order.find_by_number(params[:id], :include => :adjustments) if params[:id] + return @order || current_order end - def collection + def load_orders params[:search] ||= {} params[:search][:completed_at_is_not_null] ||= '1' if Spree::Config[:show_only_complete_orders_by_default] @show_only_completed = params[:search][:completed_at_is_not_null].present? params[:search][:meta_sort] ||= @show_only_completed ? 'completed_at.desc' : 'created_at.desc' - + @search = Order.metasearch(params[:search]) - + if !params[:search][:created_at_greater_than].blank? params[:search][:created_at_greater_than] = Time.zone.parse(params[:search][:created_at_greater_than]).beginning_of_day rescue "" end - + if !params[:search][:created_at_less_than].blank? params[:search][:created_at_less_than] = Time.zone.parse(params[:search][:created_at_less_than]).end_of_day rescue "" end @@ -86,8 +98,8 @@ def collection params[:search][:completed_at_greater_than] = params[:search].delete(:created_at_greater_than) params[:search][:completed_at_less_than] = params[:search].delete(:created_at_less_than) end - - @collection = Order.metasearch(params[:search]).paginate( + + @orders = Order.metasearch(params[:search]).paginate( :include => [:user, :shipments, :payments], :per_page => Spree::Config[:orders_per_page], :page => params[:page]) @@ -104,7 +116,7 @@ def initialize_order_events end def ensure_line_items - load_object + load_order if @order.line_items.empty? @order.errors.add(:line_items, t('errors.messages.blank')) render :edit diff --git a/core/app/controllers/admin/payments_controller.rb b/core/app/controllers/admin/payments_controller.rb index b1201b7872b..e4f2aa872b3 100644 --- a/core/app/controllers/admin/payments_controller.rb +++ b/core/app/controllers/admin/payments_controller.rb @@ -1,12 +1,23 @@ class Admin::PaymentsController < Admin::BaseController + before_filter :load_order, :only => [:create, :new, :index, :fire, :new] + before_filter :load_payment, :except => [:create, :new, :index] before_filter :load_data before_filter :load_amount, :except => :country_changed - resource_controller - belongs_to :order + + def index + @payments = @order.payments + end + + def new + @payment = Payment.new + end def create - build_object - load_object + @payment = Payment.new object_params + @payment.order = @order + if @payment.payment_method.is_a?(Gateway) && @payment.payment_method.payment_profiles_supported? && params[:card].present? and params[:card] != 'new' + @payment.source = Creditcard.find_by_id(params[:card]) + end begin unless @payment.save @@ -16,8 +27,8 @@ def create if @order.completed? @payment.process! - set_flash :create - redirect_to collection_path + flash[:notice] = I18n.t(:successfully_created, :resource => 'payment') + redirect_to admin_order_payments_path(@order) else #This is the first payment (admin created order) until @order.completed? @@ -29,13 +40,12 @@ def create rescue Spree::GatewayError => e flash[:error] = "#{e.message}" - redirect_to new_object_path + redirect_to new_admin_payment_path(@order) end end def fire # TODO: consider finer-grained control for this type of action (right now anyone in admin role can perform) - load_object return unless event = params[:e] and @payment.payment_source if @payment.payment_source.send("#{event}", @payment) flash.notice = t('payment_updated') @@ -45,16 +55,11 @@ def fire rescue Spree::GatewayError => ge flash[:error] = "#{ge.message}" ensure - redirect_to collection_path + redirect_to admin_order_payments_path(@order) end private - def object - @object ||= Payment.find(param) unless param.nil? - @object - end - def object_params if params[:payment] and params[:payment_source] and source_params = params.delete(:payment_source)[params[:payment][:payment_method_id]] params[:payment][:source_attributes] = source_params @@ -63,10 +68,9 @@ def object_params end def load_data - load_object @payment_methods = PaymentMethod.available(:back_end) - if object and object.payment_method - @payment_method = object.payment_method + if @payment and @payment.payment_method + @payment_method = @payment.payment_method else @payment_method = @payment_methods.first end @@ -77,13 +81,12 @@ def load_amount @amount = params[:amount] || @order.total end - def build_object - @object = model.new(object_params) - @object.order = parent_object - if @object.payment_method.is_a?(Gateway) and @object.payment_method.payment_profiles_supported? and params[:card].present? and params[:card] != 'new' - @object.source = Creditcard.find_by_id(params[:card]) - end - @object + def load_order + @order = Order.find_by_number! params[:order_id] + end + + def load_payment + @payment = Payment.find params[:id] end end diff --git a/core/app/controllers/admin/shipments_controller.rb b/core/app/controllers/admin/shipments_controller.rb index 537e1a53eff..a31c05799ac 100644 --- a/core/app/controllers/admin/shipments_controller.rb +++ b/core/app/controllers/admin/shipments_controller.rb @@ -1,29 +1,69 @@ class Admin::ShipmentsController < Admin::BaseController - before_filter :load_data, :except => [:country_changed, :index] + before_filter :load_order + before_filter :load_shipment, :only => [:destroy, :edit, :update] + before_filter :load_shipping_methods, :except => [:country_changed, :index] - resource_controller - belongs_to :order + def index + @shipments = @order.shipments + respond_to { |format| format.html } + end - update.wants.html do - if @order.completed? - redirect_to edit_object_url - else - redirect_to admin_order_adjustments_url(@order) - end + def new + build_shipment + @shipment.address ||= @order.ship_address + @shipment.address ||= Address.new(:country_id => Spree::Config[:default_country_id]) + @shipment.shipping_method = @order.shipping_method + respond_to { |format| format.html } end - create do - wants.html { redirect_to edit_object_url } + def create + build_shipment + assign_inventory_units + respond_to do |format| + format.html do + if @shipment.save + flash[:notice] = I18n.t(:successfully_created, :resource => 'shipment') + redirect_to edit_admin_order_shipment_path(@order, @shipment) + else + render :action => 'new' + end + end + end end - edit.before :edit_before - update.before :assign_inventory_units - update.after :update_after + def edit + @shipment.special_instructions = @order.special_instructions + respond_to do |format| + format.html { render :action => 'edit' } + end + end - create.before :assign_inventory_units + def update + assign_inventory_units + respond_to do |format| + format.html do + if @shipment.update_attributes params[:shipment] + update_after + flash[:notice] = I18n.t(:successfully_updated, :resource => I18n.t('shipment')) + if @order.completed? + redirect_to edit_admin_order_shipment_path(@order, @shipment) + else + redirect_to admin_order_adjustments_url(@order) + end + else + render :action => 'edit' + end + end + end + end - destroy.success.wants.js { render_js_for_destroy } + def destroy + @shipment.destroy + respond_to do |format| + format.js { render_js_for_destroy } + end + end def fire if @shipment.send("#{params[:e]}") @@ -35,24 +75,11 @@ def fire end private - def build_object - @object ||= end_of_association_chain.send parent? ? :build : :new - @object.address ||= @order.ship_address - @object.address ||= Address.new(:country_id => Spree::Config[:default_country_id]) - @object.shipping_method ||= @order.shipping_method - @object.attributes = object_params - @object - end - def load_data - load_object + def load_shipping_methods @shipping_methods = ShippingMethod.all_available(@order, :back_end) end - def edit_before # copy into instance variable before editing - @shipment.special_instructions = @order.special_instructions - end - def update_after # copy back to order if instructions are enabled @order.special_instructions = object_params[:special_instructions] if Spree::Config[:shipping_instructions] @order.shipping_method = @order.shipment.shipping_method @@ -64,4 +91,20 @@ def assign_inventory_units @shipment.inventory_unit_ids = params[:inventory_units].keys end + def load_order + @order = Order.find_by_number(params[:order_id]) + end + + def load_shipment + @shipment = Shipment.find_by_number(params[:id]) + end + + def build_shipment + @shipment = @order.shipments.build + @shipment.address ||= @order.ship_address + @shipment.address ||= Address.new(:country_id => Spree::Config[:default_country_id]) + @shipment.shipping_method ||= @order.shipping_method + @shipment.attributes = params[:shipment] + end + end diff --git a/core/app/controllers/admin/taxons_controller.rb b/core/app/controllers/admin/taxons_controller.rb index 705e79f3f9a..5e034fef1f1 100644 --- a/core/app/controllers/admin/taxons_controller.rb +++ b/core/app/controllers/admin/taxons_controller.rb @@ -1,20 +1,38 @@ class Admin::TaxonsController < Admin::BaseController include Railslove::Plugins::FindByParam::SingletonMethods - resource_controller - before_filter :load_object, :only => [:selected, :available, :remove] + before_filter :load_product, :only => [:selected, :available, :remove, :destroy, :update] before_filter :load_permalink_part, :only => :edit - belongs_to :product, :taxonomy - create.wants.html {render :text => @taxon.id} - update.wants.html {redirect_to edit_admin_taxonomy_url(@taxonomy)} - update.wants.json {render :json => @taxon.to_json()} + def create + @taxon = @product.taxons.create params[:taxon] + create_before + if @taxon.save + respond_to do |format| + format.html { render :text => @taxon.id } + end + else + respond_to do |format| + format.html { render :action => 'new' } + end + end + end - destroy.wants.html {render :text => ""} - destroy.success.wants.js { render_js_for_destroy } + def update + update_before + update_after + respond_to do |format| + format.html {redirect_to edit_admin_taxonomy_url(@taxonomy) } + format.json {render :json => @taxon.to_json } + end + end - create.before :create_before - update.before :update_before - update.after :update_after + def destroy + @taxon.destroy + respond_to do |format| + format.html { render :text => '' } + format.js { render_js_for_destroy } + end + end def selected @taxons = @product.taxons @@ -116,4 +134,12 @@ def update_after def load_permalink_part @permalink_part = object.permalink.split("/").last end + + def load_product + @product = Product.find_by_permalink! params[:product_id] + if params[:id] + @taxon = @product.taxons.find_by_id params[:id] + end + end + end diff --git a/core/app/helpers/admin/navigation_helper.rb b/core/app/helpers/admin/navigation_helper.rb index 55aeb293901..cd2b12472ba 100644 --- a/core/app/helpers/admin/navigation_helper.rb +++ b/core/app/helpers/admin/navigation_helper.rb @@ -43,6 +43,10 @@ def link_to_edit(resource, options={}) link_to_with_icon('edit', t("edit"), edit_object_url(resource), options) end + def link_to_edit_url(url, options={}) + link_to_with_icon('edit', t("edit"), url, options) + end + def link_to_clone(resource, options={}) link_to_with_icon('exclamation', t("clone"), clone_admin_product_url(resource), options) end diff --git a/core/app/models/shipping_method.rb b/core/app/models/shipping_method.rb index ae0557ffe1c..d64d5a9e7b6 100644 --- a/core/app/models/shipping_method.rb +++ b/core/app/models/shipping_method.rb @@ -6,11 +6,15 @@ class ShippingMethod < ActiveRecord::Base calculated_adjustments def available?(order, display_on=nil) - (self.display_on == display_on.to_s || self.display_on.blank?) && calculator.available?(order) + display_check = (self.display_on == display_on.to_s || self.display_on.blank?) + calculator_check = calculator.available?(order) + display_check && calculator_check end def available_to_order?(order, display_on=nil) - available?(order,display_on) && zone && zone.include?(order.ship_address) + availability_check = available?(order,display_on) + zone_check = zone && zone.include?(order.ship_address) + availability_check && zone_check end def self.all_available(order, display_on=nil) diff --git a/core/app/views/admin/orders/index.html.erb b/core/app/views/admin/orders/index.html.erb index 22ac6843f4f..873f5798369 100644 --- a/core/app/views/admin/orders/index.html.erb +++ b/core/app/views/admin/orders/index.html.erb @@ -33,7 +33,7 @@ <%- locals = {:order => order} %> <%= hook :admin_orders_index_rows, locals do %> <%= (@show_only_completed ? order.completed_at : order.created_at).to_date %> - <%= link_to order.number, object_url(order) %> + <%= link_to order.number, admin_order_path(order) %> <%= t("order_state.#{order.state.downcase}") %> <%= link_to t("payment_states.#{order.payment_state}"), admin_order_payments_path(order) if order.payment_state %> <%= link_to t("shipment_states.#{order.shipment_state}"), admin_order_shipments_path(order) if order.shipment_state %> @@ -42,7 +42,7 @@ <% end %> <%= hook :admin_orders_index_row_actions, locals do %> - <%= link_to_edit order, :title => "admin_edit_#{dom_id(order)}" %> + <%= link_to_edit_url edit_admin_order_path(order), :title => "admin_edit_#{dom_id(order)}" %> <% end %> diff --git a/core/app/views/admin/payments/new.html.erb b/core/app/views/admin/payments/new.html.erb index 9e622bcf9b6..c182475f2e8 100644 --- a/core/app/views/admin/payments/new.html.erb +++ b/core/app/views/admin/payments/new.html.erb @@ -1,10 +1,10 @@ <%= render :partial => 'admin/shared/order_tabs', :locals => {:current => "Payments"} %> -

<%= t('new') %> <%= t("activerecord.models.#{@object.class.to_s.underscore}.one") %>

+

<%= t('new') %> <%= t("activerecord.models.#{@payment.class.to_s.underscore}.one") %>

<%= render "shared/error_messages", :target => @payment %> -<%= form_for @payment, :url => collection_url do |f| %> +<%= form_for @payment, :url => admin_order_payments_path(@order) do |f| %> <%= render "form", :f => f %> diff --git a/core/app/views/admin/shipments/edit.html.erb b/core/app/views/admin/shipments/edit.html.erb index e97a33dd1dc..3195a2f2b84 100644 --- a/core/app/views/admin/shipments/edit.html.erb +++ b/core/app/views/admin/shipments/edit.html.erb @@ -23,16 +23,16 @@ <% end %> <%= hook :admin_shipment_edit_form do %> - <%= form_for(@shipment, :url => object_url, :html => { :method => :put }) do |shipment_form| %> + <%= form_for(@shipment, :url => admin_order_shipment_path(@order, @shipment), :html => { :method => :put }) do |shipment_form| %> <%= render :partial => "form", :locals => { :shipment_form => shipment_form } %> <%= hook :admin_shipment_edit_form_buttons do %>

<% if self.respond_to?(:current_user) && @shipment.editable_by?(current_user) %> <%= button @order.cart? ? t('continue') : t('update') %> - <%= t("or") %> <%= link_to t("cancel"), collection_url %> + <%= t("or") %> <%= link_to t("cancel"), admin_order_shipments_path(@order) %> <% else %> - <%= link_to raw("« #{t("back")}"), collection_url %> + <%= link_to raw("« #{t("back")}"), edit_admin_order_shipment_path(@order) %> <% end %>

<% end %> diff --git a/core/app/views/admin/shipments/index.html.erb b/core/app/views/admin/shipments/index.html.erb index bc503141339..72ab1fc4eda 100644 --- a/core/app/views/admin/shipments/index.html.erb +++ b/core/app/views/admin/shipments/index.html.erb @@ -1,7 +1,7 @@

diff --git a/core/app/views/admin/shipments/new.html.erb b/core/app/views/admin/shipments/new.html.erb index 42560d3af42..50319e47e96 100644 --- a/core/app/views/admin/shipments/new.html.erb +++ b/core/app/views/admin/shipments/new.html.erb @@ -6,7 +6,7 @@ <% end %> <%= hook :admin_shipment_new_form do %> - <%= form_for(@shipment, :url => collection_url) do |shipment_form| %> + <%= form_for(@shipment, :url => admin_order_shipments_path(@order)) do |shipment_form| %> <%= render :partial => "form", :locals => { :shipment_form => shipment_form } %> <%= hook :admin_shipment_new_form_buttons do %> diff --git a/core/features/admin/orders/customer_details.feature b/core/features/admin/orders/customer_details.feature index 9bb87a90c38..5f861415571 100644 --- a/core/features/admin/orders/customer_details.feature +++ b/core/features/admin/orders/customer_details.feature @@ -2,6 +2,7 @@ Feature: Admin managing customer details @javascript Scenario: edit order + Given a shipping method exists with a display on of "front_end" Given all orders are deleted Given all line items are deleted Given the following orders exist: @@ -25,3 +26,20 @@ Feature: Admin managing customer details When I click first link from selector "table td.actions a" When I follow "Customer Details" Then the "order_ship_address_attributes_firstname" field should contain "John 99" + + @javascript + Scenario: edit order with validation error + Given a shipping method exists with a display on of "front_end" + Given all orders are deleted + Given all line items are deleted + Given the following orders exist: + |completed at | + |2011-02-01 12:36:15 | + |2010-02-01 17:36:42 | + Given custom line items associated with products + When I go to the admin home page + When I click first link from selector "table td.actions a" + When I follow "Customer Details" + When I press "Continue" + Then show me the page + Then I should see "Ship address firstname can't be blank" diff --git a/core/features/admin/orders/payments.feature b/core/features/admin/orders/payments.feature index 4984ad7b4e1..0932c365ebf 100644 --- a/core/features/admin/orders/payments.feature +++ b/core/features/admin/orders/payments.feature @@ -32,7 +32,7 @@ Feature: Admin managing payments When I click first link from selector "#new_shipment_section a" When I check first element with class "inventory_unit" When I press "Create" - Then I should see "Successfully created!" + Then I should see "successfully created!" When I follow "Shipments" Then verify data from "table.index" with following tabular values: | Shipment # | Shipping Method | Cost | Tracking | Status | Date/Time | Action | @@ -40,7 +40,7 @@ Feature: Admin managing payments When I click first link from selector "#new_shipment_section a" When I check first element with class "inventory_unit" When I press "Create" - Then I should see "Successfully created!" + Then I should see "successfully created!" When I follow "Shipments" Then verify data from "table.index" with following tabular values: | Shipment # | Shipping Method | Cost | Tracking | Status | Date/Time | Action | @@ -66,12 +66,12 @@ Feature: Admin managing payments When I click first link from selector "#new_shipment_section a" When I check first element with class "inventory_unit" When I press "Create" - Then I should see "Successfully created!" + Then I should see "successfully created!" When I follow "Shipments" When I click first link from selector "#new_shipment_section a" When I check first element with class "inventory_unit" When I press "Create" - Then I should see "Successfully created!" + Then I should see "successfully created!" When I follow "Shipments" When I follow "History" Then verify data from "table.index" with following tabular values: diff --git a/core/spec/controllers/admin/shipments_controller_spec.rb b/core/spec/controllers/admin/shipments_controller_spec.rb deleted file mode 100644 index e4cfdae4aba..00000000000 --- a/core/spec/controllers/admin/shipments_controller_spec.rb +++ /dev/null @@ -1,29 +0,0 @@ -require File.dirname(__FILE__) + '/../../spec_helper' - -describe Admin::ShipmentsController do - - let(:shipment) { mock_model Shipment } - let(:order) { mock_model(Order, :bill_address => nil) } - - before do - controller.stub :current_user => nil - Order.stub :find => order - order.stub_chain :shipments, :find_by_permalink => shipment - request.env["HTTP_REFERER"] = "http://localhost:3000" - end - - context "#fire" do - it "should fire the requested event on the payment" do - shipment.should_receive(:foo).and_return true - put :fire, {:order_id => "123", :id => "S456", :e => "foo"} - end - it "should respond with a flash message if the event cannot be fired" do - shipment.stub :foo => false - put :fire, {:order_id => "123", :id => "S456", :e => "foo"} - flash[:error].should_not be_nil - end - end - -end - -