ShippedOrderFixture.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <?php
  2. /**
  3. * Refer to LICENSE.txt distributed with the Temando Shipping module for notice of license
  4. */
  5. namespace Temando\Shipping\Test\Integration\Fixture;
  6. use Magento\Catalog\Api\ProductRepositoryInterface;
  7. use Magento\Catalog\Model\ProductRepository;
  8. use Magento\Framework\Api\SearchCriteriaBuilder;
  9. use Magento\Sales\Api\Data\ShipmentInterface;
  10. use Magento\Sales\Model\Order\Address as OrderAddress;
  11. use Magento\Sales\Model\Order\ShipmentRepository;
  12. use Magento\Sales\Model\OrderRepository;
  13. use Magento\TestFramework\Helper\Bootstrap;
  14. use Temando\Shipping\Api\Data\Shipment\ShipmentReferenceInterface;
  15. use Temando\Shipping\Model\ResourceModel\Shipment\ShipmentReferenceRepository;
  16. use Temando\Shipping\Model\Shipment\ShipmentReference;
  17. /**
  18. * ShippedOrderFixture
  19. *
  20. * @package Temando\Shipping\Test
  21. * @author Christoph Aßmann <christoph.assmann@netresearch.de>
  22. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  23. * @link http://www.temando.com/
  24. */
  25. final class ShippedOrderFixture
  26. {
  27. /**
  28. * @var string
  29. */
  30. private static $orderIncrementId = '0000000303';
  31. /**
  32. * @var string
  33. */
  34. private static $shipmentIncrementId = '0000000505';
  35. /**
  36. * @var string[]
  37. */
  38. private static $shipmentReferenceData = [
  39. 'id' => '00000000-5000-0005-0000-000000000000',
  40. 'location' => '00000000-6000-0006-0000-000000000000',
  41. 'tracking' => '00000000-7000-0007-0000-000000000000',
  42. 'tracking_url' => 'https://example.org/foo.pdf',
  43. ];
  44. /**
  45. * @var string[]
  46. */
  47. private $customerData = [
  48. 'email' => 'foo@example.org',
  49. 'firstname' => 'Foo',
  50. 'lastname' => 'Example',
  51. 'company' => 'Temando',
  52. 'street' => '550 Montgomery St.',
  53. 'city' => 'California',
  54. 'postcode' => '94111',
  55. 'country' => 'US',
  56. 'phone' => '911',
  57. ];
  58. /**
  59. * @var string[]
  60. */
  61. private $productData = [
  62. 'FX-24-MB03' => [
  63. 'name' => 'Crown Summit Fixture Backpack',
  64. 'qty' => 1,
  65. 'weight' => 0.95,
  66. 'unit_price' => 38,
  67. ],
  68. 'FX-24-WG03' => [
  69. 'name' => 'Clamber Fixture Watch',
  70. 'qty' => 2,
  71. 'weight' => 0.43,
  72. 'unit_price' => 54,
  73. ],
  74. ];
  75. /**
  76. * @param string $addressType
  77. * @return OrderAddress
  78. */
  79. private function getOrderAddress($addressType)
  80. {
  81. $address = Bootstrap::getObjectManager()->create(OrderAddress::class, ['data' => [
  82. 'address_type' => $addressType,
  83. 'email' => $this->customerData['email'],
  84. 'firstname' => $this->customerData['firstname'],
  85. 'lastname' => $this->customerData['lastname'],
  86. 'company' => $this->customerData['company'],
  87. 'street' => $this->customerData['street'],
  88. 'city' => $this->customerData['city'],
  89. 'postcode' => $this->customerData['postcode'],
  90. 'country_id' => $this->customerData['country'],
  91. 'telephone' => $this->customerData['phone'],
  92. ]]);
  93. return $address;
  94. }
  95. /**
  96. * @param string $orderIncrementId
  97. * @param string $quoteId
  98. * @param string $storeId
  99. * @param string $currency
  100. * @return \Magento\Sales\Model\Order
  101. */
  102. private function getOrder($orderIncrementId, $quoteId, $storeId = '1', $currency = 'USD')
  103. {
  104. $orderDate = date('Y-m-d H:i:s');
  105. $shippingCost = 7.95;
  106. $subTotal = 0;
  107. /** @var \Magento\Sales\Model\Order $order */
  108. $order = Bootstrap::getObjectManager()->create(\Magento\Sales\Model\Order::class, ['data' => [
  109. 'increment_id' => $orderIncrementId,
  110. 'quote_id' => $quoteId,
  111. 'store_id' => $storeId,
  112. 'created_at' => $orderDate,
  113. 'updated_at' => $orderDate,
  114. 'shipping_amount' => $shippingCost,
  115. 'base_shipping_amount' => $shippingCost,
  116. 'base_currency_code' => $currency,
  117. 'store_currency_code' => $currency,
  118. 'customer_email' => $this->customerData['email'],
  119. 'customer_firstname' => $this->customerData['firstname'],
  120. 'customer_lastname' => $this->customerData['lastname'],
  121. 'shipping_method' => \Temando\Shipping\Model\Shipping\Carrier::CODE . '_foo',
  122. ]]);
  123. foreach ($this->productData as $sku => $productData) {
  124. $orderItemQty = $productData['qty'];
  125. $orderItemUnitPrice = $productData['unit_price'];
  126. $orderItem = Bootstrap::getObjectManager()->create(\Magento\Sales\Model\Order\Item::class, ['data' => [
  127. 'created_at' => $orderDate,
  128. 'store_id' => $storeId,
  129. 'is_virtual' => false,
  130. 'sku' => $sku,
  131. 'name' => $productData['name'],
  132. 'product_id' => $productData['entity_id'],
  133. 'qty' => $orderItemQty,
  134. 'price' => $orderItemUnitPrice,
  135. 'base_price' => $orderItemUnitPrice,
  136. 'row_total' => $orderItemQty * $orderItemUnitPrice,
  137. 'base_row_total' => $orderItemQty * $orderItemUnitPrice,
  138. 'product_type' => 'simple',
  139. 'price_incl_tax' => $orderItemUnitPrice,
  140. 'base_price_incl_tax' => $orderItemUnitPrice,
  141. 'row_total_incl_tax' => $orderItemQty * $orderItemUnitPrice,
  142. 'base_row_total_incl_tax' => $orderItemQty * $orderItemUnitPrice,
  143. 'qty_ordered' => $productData['qty'],
  144. 'qty_shipped' => $productData['qty'],
  145. 'qty_refunded' => 0,
  146. 'qty_canceled' => 0,
  147. ]]);
  148. $order->addItem($orderItem);
  149. $subTotal += ($orderItemQty * $orderItemUnitPrice);
  150. }
  151. $order->setTotalItemCount(count($order->getItems()));
  152. $order->setSubtotal($subTotal);
  153. $order->setBaseSubtotal($subTotal);
  154. $order->setGrandTotal($subTotal + $shippingCost);
  155. $order->setBaseGrandTotal($subTotal + $shippingCost);
  156. return $order;
  157. }
  158. /**
  159. * @param string $shipmentIncrementId
  160. * @param \Magento\Sales\Api\Data\OrderInterface $order
  161. * @return ShipmentInterface
  162. */
  163. private function getShipment($shipmentIncrementId, $order)
  164. {
  165. $shipmentDate = date('Y-m-d H:i:s');
  166. /** @var \Magento\Sales\Model\Order\Shipment $shipment */
  167. $shipment = Bootstrap::getObjectManager()->create(ShipmentInterface::class, ['data' => [
  168. 'increment_id' => $shipmentIncrementId,
  169. 'order_id' => $order->getEntityId(),
  170. 'store_id' => $order->getStoreId(),
  171. 'created_at' => $shipmentDate,
  172. 'updated_at' => $shipmentDate,
  173. 'total_weight' => null,
  174. 'total_qty' => $order->getTotalItemCount(),
  175. 'email_sent' => 1,
  176. 'send_email' => 1,
  177. ]]);
  178. foreach ($order->getItems() as $orderItem) {
  179. $shipmentItem = Bootstrap::getObjectManager()->create(
  180. \Magento\Sales\Model\Order\Shipment\Item::class,
  181. ['data' => [
  182. 'price' => $orderItem->getPrice(),
  183. 'weight' => $orderItem->getWeight(),
  184. 'qty' => $orderItem->getQtyOrdered(),
  185. 'product_id' => $orderItem->getProductId(),
  186. 'order_item_id' => $orderItem->getItemId(),
  187. 'name' => $orderItem->getName(),
  188. 'sku' => $orderItem->getSku(),
  189. ]]
  190. );
  191. $shipment->addItem($shipmentItem);
  192. }
  193. return $shipment;
  194. }
  195. // ---------- GETTERS FOR ASSERTIONS / LOADING FIXTURE ENTITIES --------- //
  196. /**
  197. * @return string
  198. */
  199. public static function getOrderIncrementId()
  200. {
  201. return self::$orderIncrementId;
  202. }
  203. /**
  204. * @return string
  205. */
  206. public static function getShipmentIncrementId()
  207. {
  208. return self::$shipmentIncrementId;
  209. }
  210. /**
  211. * @return string[]
  212. */
  213. public static function getShipmentReferenceData()
  214. {
  215. return self::$shipmentReferenceData;
  216. }
  217. // ------------------------- PUBLIC ENTRYPOINTS ------------------------- //
  218. /**
  219. * @return \Magento\Sales\Api\Data\OrderInterface
  220. */
  221. public function createOrderAndShipment()
  222. {
  223. $orderIncrementId = $this->getOrderIncrementId();
  224. $shipmentIncrementId = $this->getShipmentIncrementId();
  225. // save products
  226. /** @var ProductRepositoryInterface $productRepository */
  227. $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
  228. foreach ($this->productData as $sku => &$productData) {
  229. $product = Bootstrap::getObjectManager()->create(\Magento\Catalog\Model\Product::class, ['data' => [
  230. 'attribute_set_id' => '4',
  231. 'type_id' => 'simple',
  232. 'sku' => $sku,
  233. 'name' => $productData['name'],
  234. 'price' => $productData['unit_price'],
  235. ]]);
  236. $product = $productRepository->save($product);
  237. $productData['entity_id'] = $product->getId();
  238. }
  239. // save order
  240. $orderRepository = Bootstrap::getObjectManager()->get(OrderRepository::class);
  241. $order = $this->getOrder($orderIncrementId, null);
  242. $orderBillingAddress = $this->getOrderAddress(OrderAddress::TYPE_BILLING);
  243. $orderShippingAddress = $this->getOrderAddress(OrderAddress::TYPE_SHIPPING);
  244. $payment = Bootstrap::getObjectManager()->create(\Magento\Sales\Model\Order\Payment::class, ['data' => [
  245. 'method' => 'checkmo',
  246. ]]);
  247. $order->setBillingAddress($orderBillingAddress);
  248. $order->setShippingAddress($orderShippingAddress);
  249. $order->setPayment($payment);
  250. $orderRepository->save($order);
  251. // save shipment
  252. $shipmentRepository = Bootstrap::getObjectManager()->get(ShipmentRepository::class);
  253. $shipment = $this->getShipment($shipmentIncrementId, $order);
  254. $shipment->setBillingAddressId($orderBillingAddress->getId());
  255. $shipment->setShippingAddressId($orderShippingAddress->getId());
  256. $shipmentRepository->save($shipment);
  257. // save external shipment reference
  258. /** @var ShipmentReferenceRepository $shipmentReferenceRepository */
  259. $shipmentReferenceRepository = Bootstrap::getObjectManager()->get(ShipmentReferenceRepository::class);
  260. $shipmentReference = Bootstrap::getObjectManager()->create(ShipmentReference::class, ['data' => [
  261. ShipmentReferenceInterface::SHIPMENT_ID => $shipment->getEntityId(),
  262. ShipmentReferenceInterface::EXT_SHIPMENT_ID => self::$shipmentReferenceData['id'],
  263. ShipmentReferenceInterface::EXT_LOCATION_ID => self::$shipmentReferenceData['location'],
  264. ShipmentReferenceInterface::EXT_TRACKING_REFERENCE => self::$shipmentReferenceData['tracking'],
  265. ShipmentReferenceInterface::EXT_TRACKING_URL => self::$shipmentReferenceData['tracking_url'],
  266. ]]);
  267. $shipmentReferenceRepository->save($shipmentReference);
  268. return $order;
  269. }
  270. public function rollbackOrderAndShipment()
  271. {
  272. $orderIncrementId = $this->getOrderIncrementId();
  273. /** @var OrderRepository $orderRepository */
  274. $orderRepository = Bootstrap::getObjectManager()->get(OrderRepository::class);
  275. /** @var ProductRepositoryInterface|ProductRepository $productRepository */
  276. $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
  277. /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
  278. $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class);
  279. $searchCriteriaBuilder->addFilter('increment_id', $orderIncrementId);
  280. $searchCriteriaBuilder->setPageSize(1);
  281. $searchResult = $orderRepository->getList($searchCriteriaBuilder->create());
  282. foreach ($searchResult as $order) {
  283. $orderRepository->delete($order);
  284. }
  285. $skus = array_keys($this->productData);
  286. /** @var SearchCriteriaBuilder $searchCriteriaBuilder */
  287. $searchCriteriaBuilder = Bootstrap::getObjectManager()->create(SearchCriteriaBuilder::class);
  288. $searchCriteriaBuilder->addFilter('sku', $skus, 'in');
  289. $searchResult = $productRepository->getList($searchCriteriaBuilder->create());
  290. foreach ($searchResult->getItems() as $product) {
  291. $productRepository->delete($product);
  292. }
  293. $productRepository->cleanCache();
  294. }
  295. // ------------------------- STATIC ENTRYPOINTS ------------------------- //
  296. /**
  297. * Create fixtures:
  298. * - products
  299. * - order with order items
  300. * - shipment with shipment items
  301. */
  302. public static function createOrderAndShipmentFixture()
  303. {
  304. /** @var ShippedOrderFixture $self */
  305. $self = Bootstrap::getObjectManager()->create(static::class);
  306. $self->createOrderAndShipment();
  307. }
  308. /**
  309. * Rollback fixtures:
  310. * - order (incl. shipment and ext shipment reference)
  311. * - products
  312. */
  313. public static function createOrderAndShipmentFixtureRollback()
  314. {
  315. /** @var ShippedOrderFixture $self */
  316. $self = Bootstrap::getObjectManager()->create(static::class);
  317. $self->rollbackOrderAndShipment();
  318. }
  319. }