diff --git a/src/EarlyOrderProcessor.php b/src/EarlyOrderProcessor.php index 97fbc74..4877179 100644 --- a/src/EarlyOrderProcessor.php +++ b/src/EarlyOrderProcessor.php @@ -88,15 +88,11 @@ class EarlyOrderProcessor implements OrderProcessorInterface { } $rates = $this->shipmentManager->calculateRates($shipment); - // There is no rates for shipping. "reset" the rate... + // There is no rates for shipping. "clear" the rate... // Note that we don't remove the shipment to prevent data loss (we're // mainly interested in preserving the shipping profile). if (empty($rates)) { - // @todo: Move that logic to a method on the ShipmentManager? - $shipment->set('amount', NULL); - $shipment->set('original_amount', NULL); - $shipment->set('shipping_method', NULL); - $shipment->set('shipping_service', NULL); + $shipment->clearRate(); continue; } $rate = $this->shipmentManager->selectDefaultRate($shipment, $rates); diff --git a/src/Entity/Shipment.php b/src/Entity/Shipment.php index 44fabf0..f857b19 100644 --- a/src/Entity/Shipment.php +++ b/src/Entity/Shipment.php @@ -83,6 +83,17 @@ class Shipment extends ContentEntityBase implements ShipmentInterface { return $uri_route_parameters; } + /** + * {@inheritdoc} + */ + public function clearRate() { + $fields = ['amount', 'original_amount', 'shipping_method', 'shipping_service']; + foreach ($fields as $field) { + $this->set($field, NULL); + } + return $this; + } + /** * {@inheritdoc} */ diff --git a/src/Entity/ShipmentInterface.php b/src/Entity/ShipmentInterface.php index 33be3f9..1537c8d 100644 --- a/src/Entity/ShipmentInterface.php +++ b/src/Entity/ShipmentInterface.php @@ -17,6 +17,13 @@ use Drupal\profile\Entity\ProfileInterface; */ interface ShipmentInterface extends ContentEntityInterface, EntityAdjustableInterface, EntityChangedInterface { + /** + * Clears the shipment's rate, its shipping service & method. + * + * @return $this + */ + public function clearRate(); + /** * Populates the shipment from the given proposed shipment. * diff --git a/tests/src/Kernel/Entity/ShipmentTest.php b/tests/src/Kernel/Entity/ShipmentTest.php index 53a450b..62d5b6d 100644 --- a/tests/src/Kernel/Entity/ShipmentTest.php +++ b/tests/src/Kernel/Entity/ShipmentTest.php @@ -344,4 +344,45 @@ class ShipmentTest extends ShippingKernelTestBase { $shipment->save(); } + /** + * @covers ::clearRate + */ + public function testClearRate() { + $fields = ['amount', 'original_amount', 'shipping_method', 'shipping_service']; + $user = $this->createUser(['mail' => $this->randomString() . '@example.com']); + /** @var \Drupal\commerce_order\Entity\OrderInterface $order */ + $order = Order::create([ + 'type' => 'default', + 'state' => 'draft', + 'mail' => $user->getEmail(), + 'uid' => $user->id(), + 'store_id' => $this->store->id(), + ]); + $order->setRefreshState(Order::REFRESH_SKIP); + $order->save(); + $order = $this->reloadEntity($order); + /** @var \Drupal\commerce_shipping\Entity\ShippingMethodInterface $shipping_method */ + $shipping_method = ShippingMethod::create([ + 'name' => $this->randomString(), + 'status' => 1, + ]); + $shipping_method->save(); + $shipping_method = $this->reloadEntity($shipping_method); + $shipment = Shipment::create([ + 'amount' => new Price('0', 'USD'), + 'original_amount' => new Price('0', 'USD'), + 'shipping_service' => $this->randomString(), + 'order_id' => $order->id(), + 'type' => 'default', + ]); + $shipment->setShippingMethod($shipping_method); + foreach ($fields as $field) { + $this->assertFalse($shipment->get($field)->isEmpty()); + } + $shipment->clearRate(); + foreach ($fields as $field) { + $this->assertTrue($shipment->get($field)->isEmpty()); + } + } + }