-
-
Notifications
You must be signed in to change notification settings - Fork 729
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
Fix Grumpy Cat on shop page (cart with items from a closed OC) #5440
Changes from all commits
c3f0c0e
52e7ca2
94bb958
493adc8
6827ce5
21d1a7b
ba58506
35824c7
a438317
f22eae7
1c749a8
ace73be
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# frozen_string_literal: false | ||
|
||
# Resets an order by verifying it's state and fixing any issues | ||
class OrderCartReset | ||
def initialize(order, distributor_id, current_user, current_customer) | ||
@order = order | ||
@distributor ||= Enterprise.is_distributor.find_by_permalink(distributor_id) || | ||
Enterprise.is_distributor.find(distributor_id) | ||
@current_user = current_user | ||
@current_customer = current_customer | ||
end | ||
|
||
def call | ||
reset_distributor | ||
reset_user_and_customer if current_user | ||
reset_order_cycle | ||
order.save! | ||
end | ||
|
||
private | ||
|
||
attr_reader :order, :distributor, :current_user, :current_customer | ||
|
||
def reset_distributor | ||
if order.distributor && order.distributor != distributor | ||
order.empty! | ||
order.set_order_cycle! nil | ||
end | ||
order.distributor = distributor | ||
end | ||
|
||
def reset_user_and_customer | ||
order.associate_user!(current_user) if order.user.blank? || order.email.blank? | ||
order.__send__(:associate_customer) if order.customer.nil? # Only associates existing customers | ||
end | ||
|
||
def reset_order_cycle | ||
listed_order_cycles = Shop::OrderCyclesList.new(distributor, current_customer).call | ||
|
||
if order_cycle_not_listed?(order.order_cycle, listed_order_cycles) | ||
order.order_cycle = nil | ||
order.empty! | ||
end | ||
|
||
select_default_order_cycle(order, listed_order_cycles) | ||
end | ||
|
||
def order_cycle_not_listed?(order_cycle, listed_order_cycles) | ||
order_cycle.present? && !listed_order_cycles.include?(order_cycle) | ||
end | ||
|
||
# If no OC is selected and there is only one in the list of OCs, selects it | ||
def select_default_order_cycle(order, listed_order_cycles) | ||
return unless order.order_cycle.blank? && listed_order_cycles.size == 1 | ||
|
||
order.order_cycle = listed_order_cycles.first | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
# Builds a new order based on the one specified. This implements the "continue | ||
# shopping" feature once an order is completed. | ||
class ResetOrderService | ||
# frozen_string_literal: false | ||
|
||
# Resets a completed order by building a new order based on the one specified. | ||
# This implements the "continue shopping" feature once an order is completed. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pretty useful 👌 |
||
class OrderCompletionReset | ||
# Constructor | ||
# | ||
# @param controller [#expire_current_order, #current_order] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,14 +3,15 @@ | |
describe EnterprisesController, type: :controller do | ||
describe "shopping for a distributor" do | ||
let(:order) { controller.current_order(true) } | ||
|
||
let(:line_item) { create(:line_item) } | ||
let!(:current_distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) } | ||
let!(:distributor) { create(:distributor_enterprise, with_payment_and_shipping: true) } | ||
let!(:order_cycle1) { create(:simple_order_cycle, distributors: [distributor], orders_open_at: 2.days.ago, orders_close_at: 3.days.from_now ) } | ||
let!(:order_cycle1) { create(:simple_order_cycle, distributors: [distributor], orders_open_at: 2.days.ago, orders_close_at: 3.days.from_now, variants: [line_item.variant] ) } | ||
let!(:order_cycle2) { create(:simple_order_cycle, distributors: [distributor], orders_open_at: 3.days.ago, orders_close_at: 4.days.from_now ) } | ||
|
||
before do | ||
order.set_distributor! current_distributor | ||
order.line_items << line_item | ||
end | ||
|
||
it "sets the shop as the distributor on the order when shopping for the distributor" do | ||
|
@@ -81,21 +82,16 @@ | |
end | ||
|
||
it "should not empty an order if returning to the same distributor" do | ||
product = create(:product) | ||
create(:simple_order_cycle, distributors: [current_distributor], variants: [product.variants.first]) | ||
line_item = create(:line_item, variant: product.variants.first) | ||
controller.current_order.line_items << line_item | ||
|
||
spree_get :shop, id: current_distributor | ||
|
||
expect(controller.current_order.distributor).to eq current_distributor | ||
expect(controller.current_order.line_items.first.variant).to eq product.variants.first | ||
expect(controller.current_order.line_items.first.variant).to eq line_item.variant | ||
end | ||
|
||
describe "when an out of stock item is in the cart" do | ||
let(:variant) { create(:variant, on_demand: false, on_hand: 10) } | ||
let(:line_item) { create(:line_item, variant: variant) } | ||
let(:order_cycle) { create(:simple_order_cycle, distributors: [distributor], variants: [variant]) } | ||
let(:order_cycle) { create(:simple_order_cycle, distributors: [current_distributor], variants: [variant]) } | ||
|
||
before do | ||
order.set_distribution! current_distributor, order_cycle | ||
|
@@ -112,6 +108,19 @@ | |
end | ||
end | ||
|
||
it "resets order if the order cycle of the current order is no longer open or visible" do | ||
order.distributor = distributor | ||
order.order_cycle = order_cycle1 | ||
order.save | ||
order_cycle1.update_attribute :orders_close_at, Time.zone.now | ||
|
||
spree_get :shop, id: distributor | ||
|
||
expect(controller.current_order.distributor).to eq(distributor) | ||
expect(controller.current_order.order_cycle).to eq(order_cycle2) | ||
expect(controller.current_order.line_items).to be_empty | ||
end | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you think it's worth adding specs for the cases here? master...Matt-Yorkley:enterprise-controller-stock
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was planning to do this as part of this PR but now that Pau moved it to Test Ready with the two approvals, we can probably get this into the release. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO it's fine as is. The services seem mostly covered with unit tests and we might just need to increase the integration coverage at controller level a little bit. |
||
|
||
it "sets order cycle if only one is available at the chosen distributor" do | ||
order_cycle2.destroy | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
# frozen_string_literal: true | ||
|
||
require 'spec_helper' | ||
|
||
describe OrderCartReset do | ||
let(:distributor) { create(:distributor_enterprise) } | ||
let(:order) { create(:order, :with_line_item, distributor: distributor) } | ||
|
||
context "if order distributor is not the requested distributor" do | ||
let(:new_distributor) { create(:distributor_enterprise) } | ||
|
||
it "empties order" do | ||
OrderCartReset.new(order, new_distributor.id.to_s, nil, nil).call | ||
|
||
expect(order.line_items).to be_empty | ||
end | ||
end | ||
|
||
context "if the order's order cycle is not in the list of visible order cycles" do | ||
let(:order_cycle) { create(:simple_order_cycle, distributors: [distributor]) } | ||
let(:order_cycle_list) { instance_double(Shop::OrderCyclesList) } | ||
|
||
before do | ||
expect(Shop::OrderCyclesList).to receive(:new).and_return(order_cycle_list) | ||
order.update_attribute :order_cycle, order_cycle | ||
end | ||
|
||
it "empties order and makes order cycle nil" do | ||
expect(order_cycle_list).to receive(:call).and_return([]) | ||
|
||
OrderCartReset.new(order, distributor.id.to_s, nil, nil).call | ||
|
||
expect(order.line_items).to be_empty | ||
expect(order.order_cycle).to be_nil | ||
end | ||
|
||
it "selects default Order Cycle if there's one" do | ||
other_order_cycle = create(:simple_order_cycle, distributors: [distributor]) | ||
expect(order_cycle_list).to receive(:call).and_return([other_order_cycle]) | ||
|
||
OrderCartReset.new(order, distributor.id.to_s, nil, nil).call | ||
|
||
expect(order.order_cycle).to eq other_order_cycle | ||
end | ||
end | ||
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.
You'll go to heaven for this 😍
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.
👼
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.
or 👿