Skip to content

Commit

Permalink
fix payments with refunded VAT, fix #17
Browse files Browse the repository at this point in the history
  • Loading branch information
alepore committed Nov 29, 2014
1 parent b40f213 commit ba5b802
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 14 deletions.
23 changes: 15 additions & 8 deletions app/controllers/spree/paypal_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ def express
items = order.line_items.map(&method(:line_item))

additional_adjustments = order.all_adjustments.additional
tax_adjustments = additional_adjustments.tax
shipping_adjustments = additional_adjustments.shipping

# we remove taxes refunds (negative amounts) from taxes
# because paypal doesn't accept negative taxes
@tax_adjustments, @negative_tax_adjustments = additional_adjustments.tax.partition { |a| a.amount >= 0 }

additional_adjustments.eligible.each do |adjustment|
next if (tax_adjustments + shipping_adjustments).include?(adjustment)
next if (@tax_adjustments + shipping_adjustments).include?(adjustment)
items << {
:Name => adjustment.label,
:Quantity => 1,
Expand Down Expand Up @@ -87,8 +90,9 @@ def line_item(item)
}
end

def express_checkout_request_details order, items
{ :SetExpressCheckoutRequestDetails => {
def express_checkout_request_details(order, items)
{
:SetExpressCheckoutRequestDetails => {
:InvoiceID => order.number,
:ReturnURL => confirm_paypal_url(:payment_method_id => params[:payment_method_id], :utm_nooverride => 1),
:CancelURL => cancel_paypal_url,
Expand All @@ -97,7 +101,8 @@ def express_checkout_request_details order, items
:cppheaderimage => payment_method.preferred_logourl.present? ? payment_method.preferred_logourl : "",
:NoShipping => 1,
:PaymentDetails => [payment_details(items)]
}}
}
}
end

def payment_method
Expand All @@ -108,15 +113,17 @@ def provider
payment_method.provider
end

def payment_details items
def payment_details(items)
# This retrieves the cost of shipping after promotions are applied
# For example, if shippng costs $10, and is free with a promotion, shipment_sum is now $10
shipment_sum = current_order.shipments.map(&:discounted_cost).sum

negative_tax_adjustments_sum = @negative_tax_adjustments.map(&:amount).sum
tax_adjustments_sum = @tax_adjustments.map(&:amount).sum
# This calculates the item sum based upon what is in the order total, but not for shipping
# or tax. This is the easiest way to determine what the items should cost, as that
# functionality doesn't currently exist in Spree core
item_sum = current_order.total - shipment_sum - current_order.additional_tax_total
item_sum = current_order.total - shipment_sum - current_order.additional_tax_total + negative_tax_adjustments_sum

if item_sum.zero?
# Paypal does not support no items or a zero dollar ItemTotal
Expand All @@ -143,7 +150,7 @@ def payment_details items
},
:TaxTotal => {
:currencyID => current_order.currency,
:value => current_order.additional_tax_total
:value => tax_adjustments_sum
},
:ShipToAddress => address_options,
:PaymentDetailsItem => items,
Expand Down
43 changes: 37 additions & 6 deletions spec/features/paypal_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -275,26 +275,26 @@ def fill_in_guest
end
end

context "can process an order with Tax included prices" do
context "can process an order with VAT included prices" do
let(:tax_rate) { create(:tax_rate, name: 'VAT Tax', amount: 0.1,
zone: Spree::Zone.first, included_in_price: true) }
zone: Spree::Zone.last, included_in_price: true) }
let(:tax_category) { create(:tax_category, tax_rates: [tax_rate]) }
let(:product3) { FactoryGirl.create(:product, name: 'EU Charger', tax_category: tax_category) }
let(:tax_string) { "VAT Tax 10.0%" }
let(:tax_string) { "VAT Tax 10.0% (Included in Price)" }

# Regression test for #129
context "on countries where the Tax is applied" do
context "from countries where VAT is applied" do

before do
Spree::Zone.first.update_attribute(:default_tax, true)
Spree::Zone.last.update_attribute(:default_tax, true)
end

specify do
add_to_cart(product3)
visit '/cart'

within("#cart_adjustments") do
page.should have_content("#{tax_string} (Included in Price)")
page.should have_content(tax_string)
end

click_button 'Checkout'
Expand All @@ -311,10 +311,41 @@ def fill_in_guest

login_to_paypal
click_button "Pay Now"

page.should have_content("Your order has been processed successfully")
end
end

# Regression test for #17
context "from countries where VAT is refunded" do
# this is required, but we will not use this zone on this checkout
let!(:default_tax_zone) { create(:zone, default_tax: true) }

specify do
add_to_cart(product3)
click_button 'Checkout'
fill_in_guest
fill_in_billing
click_button "Save and Continue"

within("#checkout-summary") do
page.should have_content("Refund #{tax_string}")
end

click_button "Save and Continue"
find("#paypal_button").click

within_transaction_cart do
# included taxes should not reach paypal
page.should have_content(tax_string)
end

login_to_paypal
click_button "Pay Now"

page.should have_content("Your order has been processed successfully")
end
end
end

context "as an admin" do
Expand Down

0 comments on commit ba5b802

Please sign in to comment.