From a173d0621988e8856af4698aab2e598a855ad719 Mon Sep 17 00:00:00 2001 From: Bartuz Date: Tue, 10 Jun 2014 17:05:52 +0200 Subject: [PATCH 1/2] Adds logic to swap items in cart on currency change --- app/controllers/spree/currency_controller.rb | 48 ++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/app/controllers/spree/currency_controller.rb b/app/controllers/spree/currency_controller.rb index 5cf5d19..0931d83 100644 --- a/app/controllers/spree/currency_controller.rb +++ b/app/controllers/spree/currency_controller.rb @@ -1,14 +1,56 @@ module Spree class CurrencyController < Spree::StoreController + def set - currency = supported_currencies.find { |currency| currency.iso_code == params[:currency] } + @currency = supported_currencies.find { |currency| currency.iso_code == params[:currency] } + # make shure that we update the current order, so the currency change is reflected + if current_order + update_order! + end session[:currency] = params[:currency] if Spree::Config[:allow_currency_change] respond_to do |format| - format.json { render :json => !currency.nil? } + format.json { render json: !@currency.nil? } format.html do - redirect_to root_path + # We want to go back to where we came from! + redirect_back_or_default(root_path) end end end + + private + + # Updates the order's prices and all line items prices + def update_order! + @order = current_order + if update_line_items! + @order.update_attributes!(currency: @currency.iso_code) + @order.update! + end + end + + # Updates prices of order's line items + def update_line_items! + return unless @order.line_items.any? + @order.line_items.each do |line_item| + update_line_item_price!(line_item) + end + end + + # Returns the price object from given item + def price_from_line_item(line_item) + return unless line_item.variant + line_item.variant.prices.detect { |p| p.currency == @currency.iso_code } + end + + # Updates price from given line item + def update_line_item_price!(line_item) + price = price_from_line_item(line_item) + if price + # Mass Assignment Protection \o/ + line_item.currency = price.currency + line_item.price = price.amount + line_item.save! + end + end end end From 356236e272cf1ccc68dbdc7b46992b134f43563d Mon Sep 17 00:00:00 2001 From: Bartuz Date: Wed, 18 Jun 2014 06:22:47 +0200 Subject: [PATCH 2/2] Adds test for cart currency change --- spec/features/order_prices_spec.rb | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 spec/features/order_prices_spec.rb diff --git a/spec/features/order_prices_spec.rb b/spec/features/order_prices_spec.rb new file mode 100644 index 0000000..9a21c8d --- /dev/null +++ b/spec/features/order_prices_spec.rb @@ -0,0 +1,25 @@ +require 'spec_helper' + +describe 'Order' do + let!(:product) {create(:product)} + + before do + reset_spree_preferences do |config| + config.supported_currencies = "USD,EUR,GBP" + config.allow_currency_change = true + config.show_currency_selector = true + end + create(:price, variant: product.master, currency: 'EUR', amount: 16.00) + create(:price, variant: product.master, currency: 'GBP', amount: 23.00) + end + + context 'when existing in the cart', :js => true do + it "changes its currency, if user switches the currency." do + visit spree.product_path(product) + click_button 'Add To Cart' + expect(page).to have_content("$19.99") + select "EUR", :from => "currency" + expect(page).to have_content("€16.00") + end + end +end