Skip to content

Commit 6b07b2c

Browse files
Move create_proposed_shipments to OrderShipping
Spree::OrderShipping is a configurable class, which increases the extensibility for this system behaviour. The Spree::Order model also shouldn't need to be responsible for the creation of its own shipments. Separating this concern will allow us to refactor the underlying stock coordination implementation without introducing additional churn on the already heavy Spree::Order class. Co-authored-by: Adam Mueller<adam@super.gd>
1 parent a0746e6 commit 6b07b2c

4 files changed

Lines changed: 63 additions & 54 deletions

File tree

core/app/models/spree/order.rb

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ def self.find_by_param!(value)
164164

165165
delegate :recalculate, to: :recalculator
166166

167+
delegate :create_proposed_shipments, to: :shipping
168+
167169
delegate :name, to: :bill_address, prefix: true, allow_nil: true
168170
alias_method :billing_name, :bill_address_name
169171

@@ -501,17 +503,6 @@ def billing_address_required?
501503
Spree::Config.billing_address_required
502504
end
503505

504-
def create_proposed_shipments
505-
if completed?
506-
raise CannotRebuildShipments.new(I18n.t("spree.cannot_rebuild_shipments_order_completed"))
507-
elsif shipments.any? { |shipment| !shipment.pending? }
508-
raise CannotRebuildShipments.new(I18n.t("spree.cannot_rebuild_shipments_shipments_not_pending"))
509-
else
510-
shipments.destroy_all
511-
shipments.push(*Spree::Config.stock.coordinator_class.new(self).shipments)
512-
end
513-
end
514-
515506
def create_shipments_for_line_item(line_item)
516507
units = Spree::Config.stock.inventory_unit_builder_class.new(self).missing_units_for_line_item(line_item)
517508

core/app/models/spree/order_shipping.rb

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,23 @@ def initialize(order)
88
@order = order
99
end
1010

11+
# A method that destroys the current shipments on an order, creates new
12+
# shipments for the line items, and assigns them to the order.
13+
#
14+
# @return [Array<Spree::Shipment>] The created shipments
15+
# @raise [Spree::Order::CannotRebuildShipments] raised if order is completed
16+
# or there are any non-pending shipments.
17+
def create_proposed_shipments
18+
if @order.completed?
19+
raise Spree::Order::CannotRebuildShipments.new(I18n.t("spree.cannot_rebuild_shipments_order_completed"))
20+
elsif @order.shipments.any? { |shipment| !shipment.pending? }
21+
raise Spree::Order::CannotRebuildShipments.new(I18n.t("spree.cannot_rebuild_shipments_shipments_not_pending"))
22+
else
23+
@order.shipments.destroy_all
24+
@order.shipments.push(*Spree::Config.stock.coordinator_class.new(@order).shipments)
25+
end
26+
end
27+
1128
# A shortcut method that ships *all* inventory units in a shipment in a single
1229
# carton. See also {#ship}.
1330
#

core/spec/models/spree/order_shipping_spec.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,50 @@ def emails
5353
end
5454
end
5555

56+
describe "#create_proposed_shipments" do
57+
subject(:order) { create(:order) }
58+
59+
it "assigns the coordinator returned shipments to its shipments" do
60+
shipment = build(:shipment)
61+
allow_any_instance_of(Spree::Stock::SimpleCoordinator).to receive(:shipments).and_return([shipment])
62+
order.shipping.create_proposed_shipments
63+
expect(order.shipments).to eq [shipment]
64+
end
65+
66+
it "raises an error if any shipments are ready" do
67+
shipment = create(:shipment, order:, state: "ready")
68+
69+
expect {
70+
expect {
71+
order.shipping.create_proposed_shipments
72+
}.to raise_error(Spree::Order::CannotRebuildShipments)
73+
}.not_to change { order.reload.shipments.pluck(:id) }
74+
75+
expect { shipment.reload }.not_to raise_error
76+
end
77+
78+
it "raises an error if any shipments are shipped" do
79+
shipment = create(:shipment, order:, state: "shipped")
80+
expect {
81+
expect {
82+
order.shipping.create_proposed_shipments
83+
}.to raise_error(Spree::Order::CannotRebuildShipments)
84+
}.not_to change { order.reload.shipments.pluck(:id) }
85+
86+
expect { shipment.reload }.not_to raise_error
87+
end
88+
89+
context "when the order is already completed" do
90+
let(:order) { create(:completed_order_with_pending_payment) }
91+
92+
it "raises an error" do
93+
expect {
94+
order.shipping.create_proposed_shipments
95+
}.to raise_error(Spree::Order::CannotRebuildShipments)
96+
end
97+
end
98+
end
99+
56100
describe "#ship" do
57101
subject do
58102
order.shipping.ship(

core/spec/models/spree/order_spec.rb

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,49 +1247,6 @@ def call
12471247
end
12481248
end
12491249

1250-
describe "#create_proposed_shipments" do
1251-
subject(:order) { create(:order) }
1252-
it "assigns the coordinator returned shipments to its shipments" do
1253-
shipment = build(:shipment)
1254-
allow_any_instance_of(Spree::Stock::SimpleCoordinator).to receive(:shipments).and_return([shipment])
1255-
subject.create_proposed_shipments
1256-
expect(subject.shipments).to eq [shipment]
1257-
end
1258-
1259-
it "raises an error if any shipments are ready" do
1260-
shipment = create(:shipment, order: subject, state: "ready")
1261-
1262-
expect {
1263-
expect {
1264-
subject.create_proposed_shipments
1265-
}.to raise_error(Spree::Order::CannotRebuildShipments)
1266-
}.not_to change { subject.reload.shipments.pluck(:id) }
1267-
1268-
expect { shipment.reload }.not_to raise_error
1269-
end
1270-
1271-
it "raises an error if any shipments are shipped" do
1272-
shipment = create(:shipment, order: subject, state: "shipped")
1273-
expect {
1274-
expect {
1275-
subject.create_proposed_shipments
1276-
}.to raise_error(Spree::Order::CannotRebuildShipments)
1277-
}.not_to change { subject.reload.shipments.pluck(:id) }
1278-
1279-
expect { shipment.reload }.not_to raise_error
1280-
end
1281-
1282-
context "when the order is already completed" do
1283-
let(:order) { create(:completed_order_with_pending_payment) }
1284-
1285-
it "raises an error" do
1286-
expect {
1287-
order.create_proposed_shipments
1288-
}.to raise_error(Spree::Order::CannotRebuildShipments)
1289-
end
1290-
end
1291-
end
1292-
12931250
describe "#all_inventory_units_returned?" do
12941251
let(:order) { create(:order_with_line_items, line_items_count: 3) }
12951252

0 commit comments

Comments
 (0)