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

Only credit back allowed amount #1603

Closed

Conversation

gmacdougall
Copy link
Member

@gmacdougall gmacdougall commented Nov 22, 2016

This fixes an issue with payment refunding. To reproduce:

  1. Give a user $100 in store credit
  2. Purchase an item with the user for less than $100.
  3. Refund a portion of the payment through the admin
  4. Attempt to cancel the order

This will result in an exception as it will attempt to give the user more
store credit than they could potentially have available.

This modifies the store credit payment cancel to give back the maximum allowed
rather than the full amount.

Additionally, this gets rid of some terrible logic which only works with currencies
that have two decimal places which multiplies and divides things by 100.

@gmacdougall gmacdougall force-pushed the store-credit-allowed-amount branch 2 times, most recently from f898e19 to b8abebe Compare November 22, 2016 15:16

context "when there are offsets" do
before do
payment.offsets.create(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer create! to ensure errors are raised in test setup.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -67,7 +67,7 @@ def credit(amount_in_cents, auth_code, gateway_options = {})
originator = gateway_options[:originator]

store_credit.credit(
amount_in_cents / 100.0.to_d,
::Money.new(amount_in_cents, currency).to_d,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the .to_d still required now that we're returning a Fixnum from amount_in_cents?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is creating a RubyMoney in order to reverse the amount_in_cents logic. Example:

[1] pry(main)> ::Money.new(1000, 'USD').to_d.to_s
=> "10.0"
[2] pry(main)> ::Money.new(1000, 'JPY').to_d.to_s
=> "1000.0"

amount_in_cents = (store_credit_event.amount * 100).round
credit(amount_in_cents, auth_code)
credit(
store_credit_event.originator.credit_allowed_in_cents,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the originator here ever be something other than a payment? I assume so, and cause this will break.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is going through the PaymentMethod I would hope not, but I should raise a more appropriate exception in that case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just assumed since a polymorphic association is used, we should expect it possible that something other than a payment method be the originator. Maybe that should be changed to not be polymorphic?

@@ -267,15 +267,17 @@
create(:store_credit_capture_event,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spacing here needs some help. Perhaps in a separate commit?


it_behaves_like "a spree payment method"

it "refunds the capture amount" do
expect { subject }.to change{ store_credit.reload.amount_remaining }.
from(original_amount - captured_amount).
to(original_amount)
from(90).to(100)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great improvement, thank you!

auth_code,
currency,
action_originator: originator
) if amount_in_cents > 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a regression test for this guard?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

@gmacdougall gmacdougall force-pushed the store-credit-allowed-amount branch 2 times, most recently from c8314ff to fbc2b60 Compare November 22, 2016 20:25
@gmacdougall
Copy link
Member Author

Going to do some additional work on this. There's an issue with cancelling an order containing a fully refunded store credit payment.

@gmacdougall gmacdougall force-pushed the store-credit-allowed-amount branch from d73f8f0 to d24ca62 Compare November 23, 2016 19:28
@gmacdougall
Copy link
Member Author

I have corrected the error which occurred when cancelling an order which was previously fully refunded.

#
# @return [Fixnum] The amount of this payment minus offets and refunds
# in cents.
def credit_allowed_in_cents
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the rational here for returning the in_cents rather than the money object and letting the caller do with it as it wishes?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gmacdougall could you follow up here?

This will not attempt to credit store credit for zero dollar amount,
which will trigger errors.
@gmacdougall gmacdougall force-pushed the store-credit-allowed-amount branch from d24ca62 to 793f44e Compare July 3, 2017 17:09
Gregor MacDougall added 2 commits July 3, 2017 13:12
Previously there was some unsafe math where numbers were multiplied and
divided by 100 in the store credit section. This is a step towards
getting rid of that.
When a payment is cancelled, previously it would attempt to return the
whole amount to the store credit even if it had been entirely or
partially refunded.
Copy link
Contributor

@cbrunsdon cbrunsdon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My feedback is resolved, thanks 👍

@gmacdougall
Copy link
Member Author

This was superseded by #2111

@gmacdougall gmacdougall closed this Oct 4, 2017
@gmacdougall gmacdougall deleted the store-credit-allowed-amount branch October 4, 2017 18:50
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

Successfully merging this pull request may close these issues.

4 participants