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

Payment methods display on boolean #1540

Merged
merged 8 commits into from
Nov 15, 2016

Conversation

gevann
Copy link

@gevann gevann commented Oct 19, 2016

This PR changes the display_on column of Spree::PaymentMethods to two boolean columns, available_to_users and available_to_admin. This allows clearer selection than the string-based display_on column, enabling usage of scopes on the model, and improving readability and intention of the affected code.
Closes #1532

This PR will be reworked into two-value logic after the merge of PR #1541, which fixes invalid specs for payment methods.

@gevann gevann force-pushed the payment-methods-display-on-boolean branch from 38ce73d to 5ac4ba6 Compare October 19, 2016 17:11
<%= label_tag nil, Spree::PaymentMethod.human_attribute_name(:available_to_users) %>
<ul>
<li>
<%= radio_button :payment_method, :available_to_users, true %>
Copy link
Contributor

Choose a reason for hiding this comment

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

A checkbox might be simpler than a radio button

Copy link
Author

Choose a reason for hiding this comment

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

agreed - will change

store.payment_methods
else
Spree::PaymentMethod
end
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 not ideal because the order is holding knowledge about what payments are available to what stores. This logic would be better in either the Payment or Store class.

I'd recommend adding a Payment.available_to_store(store) scope.

Copy link
Author

Choose a reason for hiding this comment

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

sounds good, I'll add that scope

(store.nil? || store.payment_methods.empty? || store.payment_methods.include?(p))
Spree::Deprecation.warn "Spree::PaymentMethod.available is deprecated."\
"Please use .active, .available_to_users, and .available_to_admin scopes instead."\
"For payment methods associated with a specific store, use your_store.payment_methods."
Copy link
Contributor

Choose a reason for hiding this comment

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

This isn't a precise replacement ,your_store.payment_methods won't return payments if none are associated (it should return all payments in this case). Payment.available_to_store(store) which I suggest above would solve this.

@@ -0,0 +1,28 @@
class AddAvailableToColumnsAndRemoveDisplayOnFromPaymentMethods < ActiveRecord::Migration[5.0]
def up
add_column(:spree_payment_methods, :available_to_users, :boolean, default: nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

What meaning does the default, nil, have?

I would prefer that the default to both be true (matching the old default behaviour) and that the column was null: false to avoid any tri-value logic.

Copy link
Author

Choose a reason for hiding this comment

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

I agree. Originally it was meant to be default: true and avoid tri-value logic, however the edge case of nil valued display_ons make tri-value logic necessary.

"WHERE (display_on='front_end' OR display_on='' OR display_on='both')")
execute("UPDATE spree_payment_methods "\
"SET available_to_admin='true' "\
"WHERE (display_on='back_end' OR display_on='' OR display_on='both')")
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Thank you for using plain SQL in the migration

when 'back_end'
active.available_to_admin
else
active.available_to_users.available_to_admin + active.nil_available_to_users.nil_available_to_admin
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't follow this line. I don't think it replicates the existing functionality.

Copy link
Author

Choose a reason for hiding this comment

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

In the existing core/spec/models/spree/payment_method_spec.rb file's describe .available specs, there are four payment methods created, with display_on values of 'front_end', 'back_end', 'both', and nil.
The existing functionality filters with (p.display_on == display_on.to_s || p.display_on.blank?). This behaviour of .blank? makes the live above (and the three value logic) necessary; the existing specs assert that there are two methods available for both. This should mean that there would be three each available for frontend and backend, as there are two for both and one each for those particular locations, however the specs show that this is not the case.

add_column(:spree_payment_methods, :available_to_admin, :boolean, default: nil)
execute("UPDATE spree_payment_methods "\
"SET available_to_users='true' "\
"WHERE (display_on='front_end' OR display_on='' OR display_on='both')")
Copy link
Contributor

Choose a reason for hiding this comment

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

'both' should not be included here.

@gevann gevann force-pushed the payment-methods-display-on-boolean branch from 5ac4ba6 to aeb6857 Compare October 20, 2016 00:33
"WHERE NOT (display_on='front_end' OR display_on='' OR display_on IS NULL)")
execute("UPDATE spree_payment_methods "\
"SET available_to_admin='false' "\
"WHERE NOT (display_on='back_end' OR display_on='' OR display_on IS NULL)")
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not 100% sure thats safe, I'd prefer something like:

"SET available_to_admin=#{ActiveRecord::Base.connection.quote(true)}"

@gevann gevann force-pushed the payment-methods-display-on-boolean branch from aeb6857 to eb57967 Compare November 2, 2016 23:45
@peterberkenbosch
Copy link
Contributor

@gevann this needs a rebase with master.

@peterberkenbosch
Copy link
Contributor

LGTM! 👍

@gevann gevann force-pushed the payment-methods-display-on-boolean branch from eb57967 to eb4b1d7 Compare November 8, 2016 00:42
Graeme Nathan added 7 commits November 7, 2016 16:58
PaymentMethod.display_on column is split in to two boolean columns
available_to_users, and available_to_admin. Each value is set
based on the value in the display_on column. Finally, the display_on
column is removed.
Adjust Spree::Payment method creation in specs to use new boolean
columns (available_to_users, available_to_admin) rather than
string column 'display_on'

Update specs and factories to use new columns
@gevann gevann force-pushed the payment-methods-display-on-boolean branch from eb4b1d7 to fa94154 Compare November 8, 2016 00:59
This allows any existing code which used display_on to continue working.
It's likely that specs will be using this.
luukveenis pushed a commit to luukveenis/solidus that referenced this pull request Mar 27, 2017
The original implementation of `Spree::PaymentMethod.available` used
`.select` which would turn the ActiveRecord::Relation into an array and
meant we had to use `sort_by`.

In solidusio#1540 `available` was deprecated in favour of `available_to_users`
and `available_to_admin`, each of which returns an
ActiveRecord::Relation object. That means we can use `order` to do the
sorting in SQL, which also allows users to chain more scopes onto the
return value if they wish.
luukveenis pushed a commit to luukveenis/solidus that referenced this pull request Apr 7, 2017
Payment methods available on the backend used to be scope to active
methods only. Unfortunately that functionality was lost in solidusio#1540 because
the `available_to_admin` scope isn't limited to active payment methods.
luukveenis pushed a commit to luukveenis/solidus that referenced this pull request Apr 7, 2017
This was the original behaviour in Solidus < 2.1, but the active scope
got lost in solidusio#1540. Payment methods used to use the `available` filter
which was scoped to active payment methods only. The `available_to_admin`
scope isn't limited active payment methods, so we need to add it here.
jhawthorn pushed a commit to luukveenis/solidus that referenced this pull request Apr 10, 2017
I noticed that inactive payment methods were not being filtered out on
the frontend. This used to happen in `Spree::PaymentMethod.available`,
but in solidusio#1540 this filter was lost.
jhawthorn pushed a commit to luukveenis/solidus that referenced this pull request Apr 10, 2017
We use `Spree::Order#available_payment_methods` to determine which
payment methods should be displayed on the payment page in checkout. The
changes in solidusio#1540 accidentally dropped the scoping for active payment
methods, causing inactive payment methods to show up on the frontend.

This also required fixing the `available_to_store` scope, which behaved
incorrectly. Calling `self` from inside the scope returns the
`Spree::PaymentMethod` class itself and not the current scoping as the
code implied. This scope will now raise an error if the store parameter
is `nil`, return all payment methods in the current scope if the store
has no payment methods, and return the payment methods for the store if
it does have some.
jhawthorn pushed a commit to luukveenis/solidus that referenced this pull request Apr 10, 2017
Payment methods available on the backend used to be scope to active
methods only. Unfortunately that functionality was lost in solidusio#1540 because
the `available_to_admin` scope isn't limited to active payment methods.
jhawthorn pushed a commit to luukveenis/solidus that referenced this pull request Apr 10, 2017
This was the original behaviour in Solidus < 2.1, but the active scope
got lost in solidusio#1540. Payment methods used to use the `available` filter
which was scoped to active payment methods only. The `available_to_admin`
scope isn't limited active payment methods, so we need to add it here.
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.

RFC: Split Spree::PaymentMethod.display_on to two boolean columns
4 participants