Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solution for taking in consideration Store Credits #208

Open
LucasKuhn opened this issue Jan 23, 2019 · 1 comment
Open

Solution for taking in consideration Store Credits #208

LucasKuhn opened this issue Jan 23, 2019 · 1 comment

Comments

@LucasKuhn
Copy link

LucasKuhn commented Jan 23, 2019

You just need to edit the item_sum to consider the applied store credits (current_order.total_applied_store_credit)

item_sum = current_order.total - shipment_sum - current_order.additional_tax_total

item_sum = current_order.total - shipment_sum - current_order.additional_tax_total - order.total_applied_store_credit

And add and item with the store credit discount after adding items for all other adjustments

    if order.using_store_credit?
      items << {
        Name: "Store Credits",
        Quantity: 1,
        Amount: {
          currencyID: order.currency,
          value: order.total_applied_store_credit * -1
        }
      }
    end

Below my full file, besides the changes above everything else is the same. Store Credits working fine with only these small tweaks to express and payment details method

# app/controllers/spree/paypal_controller_decorator.rb

Spree::PaypalController.class_eval do
  def express
    order = current_order || raise(ActiveRecord::RecordNotFound)
    items = order.line_items.map(&method(:line_item))

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

    additional_adjustments.eligible.each do |adjustment|
      # Because PayPal doesn't accept $0 items at all. See #10
      # https://cms.paypal.com/uk/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ECCustomizing
      # "It can be a positive or negative value but not zero."
      next if adjustment.amount.zero?
      next if tax_adjustments.include?(adjustment) || shipping_adjustments.include?(adjustment)

      items << {
        Name: adjustment.label,
        Quantity: 1,
        Amount: {
          currencyID: order.currency,
          value: adjustment.amount
        }
      }
    end

    if order.using_store_credit?
      items << {
        Name: "Store Credits",
        Quantity: 1,
        Amount: {
          currencyID: order.currency,
          value: order.total_applied_store_credit * -1
        }
      }
    end

    pp_request = provider.build_set_express_checkout(express_checkout_request_details(order, items))

    begin
      pp_response = provider.set_express_checkout(pp_request)
      if pp_response.success?
        redirect_to provider.express_checkout_url(pp_response, useraction: 'commit')
      else
        flash[:error] = Spree.t('flash.generic_error', scope: 'paypal', reasons: pp_response.errors.map(&:long_message).join(" "))
        redirect_to checkout_state_path(:payment)
      end
    rescue SocketError
      flash[:error] = Spree.t('flash.connection_failed', scope: 'paypal')
      redirect_to checkout_state_path(:payment)
    end
  end

  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

    # 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 - current_order.total_applied_store_credit

    if item_sum.zero?
      # Paypal does not support no items or a zero dollar ItemTotal
      # This results in the order summary being simply "Current purchase"
      {
        OrderTotal: {
          currencyID: current_order.currency,
          value: current_order.total
        }
      }
    else
      {
        OrderTotal: {
          currencyID: current_order.currency,
          value: current_order.total - current_order.total_applied_store_credit
        },
        ItemTotal: {
          currencyID: current_order.currency,
          value: item_sum
        },
        ShippingTotal: {
          currencyID: current_order.currency,
          value: shipment_sum,
        },
        TaxTotal: {
          currencyID: current_order.currency,
          value: current_order.additional_tax_total
        },
        ShipToAddress: address_options,
        PaymentDetailsItem: items,
        ShippingMethod: "Shipping Method Name Goes Here",
        PaymentAction: "Sale"
      }
    end
  end
end
@chozandrias76
Copy link

Thank you for detailing this solution! I just spent about an hour looking into how to monkey patch a fix in and it is good to see that my solution matches yours!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants