-
Notifications
You must be signed in to change notification settings - Fork 24
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
Replace order simulator with something simpler #82
Conversation
eeea785
to
1978e5d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great!
Just a suggestion for extracting some of the inline controller code.
@order.transaction do | ||
build_address(params[:address]) | ||
@order.ensure_updated_shipments | ||
@order.email = "[email protected]" unless @order.email | ||
@order.contents.advance | ||
@paypal_order = SolidusPaypalCommercePlatform::PaypalOrder.new(@order).to_replace_json | ||
raise ActiveRecord::Rollback | ||
end | ||
|
||
render json: @paypal_order, status: :ok | ||
end | ||
|
||
private | ||
|
||
def build_address(address) | ||
country = ::Spree::Country.find_by(iso: address[:country_code]) | ||
# Also adds fake information for a few fields, so validations can run | ||
new_ship_address = ::Spree::Address.new( | ||
city: address[:city], | ||
state: country.states.find_by(abbr: address[:state]), | ||
state_name: address[:state], | ||
zipcode: address[:postal_code], | ||
country: country, | ||
address1: "123 Fake St.", | ||
phone: "123456789", | ||
firstname: "Fake" | ||
) | ||
|
||
@order.update(ship_address: new_ship_address) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about moving most of this to an external object and keep the controller a little slender?
Ideally the action should look more or less like this:
@paypal_order = SolidusPaypalCommercePlatform::PaypalOrder.new(@order)
render json: @paypal_order.to_replace_json(address: params[:address])
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the address update functionality to SPCP::PayPalAddress, since its responsibility is to format paypal addresses to Spree addresses. How does that look?
We were updating only the address when PayPal returns the users address, but we also need to make sure that the shipments are relevant to the new address also. This makes sure the shipments are regenerated when the address changes.
Previously when we got a partial address from PayPal, we would dup the order, and use it in its unsaved state to simulate the new address, so nothing would be actually changed or added to the DB. However, this does not play well with a lot of Solidus methods, like promotion activation (because it calls `create!` which doesn't work with unsaved objects). It was also becoming a bit too complex. This PR moves to simplify all of that by just wrapping the address change in an ActiveRecord transaction and rolling it back after we get the data we need to send back to PayPal. In essence, this will change the orders ship_address, generate new shipments, and format all of that to be sent to PayPal, and then undo all of the actions it just took to generate that data, leaving the order untouched at the end.
1978e5d
to
451ea98
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
No description provided.