commerce_qb_webconnect-8.x-2.0-alpha7/tests/src/Kernel/SoapServiceTest.php
tests/src/Kernel/SoapServiceTest.php
<?php namespace Drupal\Tests\commerce_qb_webconnect\Kernel; use Drupal\commerce\Context; use Drupal\commerce_order\Adjustment; use Drupal\commerce_order\Entity\Order; use Drupal\commerce_order\Entity\OrderType; use Drupal\commerce_payment\Entity\Payment; use Drupal\commerce_payment\Entity\PaymentGateway; use Drupal\commerce_payment\Entity\PaymentMethod; use Drupal\commerce_price\Price; use Drupal\commerce_product\Entity\Product; use Drupal\commerce_product\Entity\ProductVariation; use Drupal\commerce_product\Entity\ProductVariationType; use Drupal\commerce_shipping\Entity\Shipment; use Drupal\commerce_shipping\Entity\ShippingMethod; use Drupal\commerce_shipping\ShipmentItem; use Drupal\Core\Database\Database; use Drupal\physical\Weight; use Drupal\profile\Entity\Profile; use Drupal\Tests\commerce\Kernel\CommerceKernelTestBase; /** * Tests exporting data to quickbooks. * * @requires module commerce_shipping * @requires module physical * @requires module commerce * @requires module commerce_product * @requires module commerce_order * @requires module commerce_tax * @requires module profile * @requires module state_machine * @requires module entity_reference_revisions * @requires module migrate_drupal_d8 * * @group commerce_qb_webconnect */ class SoapServiceTest extends CommerceKernelTestBase { /** * The customer list id. * * @var string */ protected $customerListId = '80000001-1431947192'; /** * The order list id. * * @var string */ protected $orderListId = '80000001-1431947193'; /** * The payment list id. * * @var string */ protected $paymentListId = '80000001-1431947194'; /** * The product list id. * * @var string */ protected $productListId = '80000001-1431947195'; /** * The variation list id. * * @var string */ protected $productVariationListId = '80000001-1431947196'; /** * The second variation list id. * * @var string */ protected $productVariationListId2 = '80000001-1431947197'; /** * {@inheritdoc} */ public static $modules = [ 'migrate_drupal_d8', 'migrate', 'commerce_qb_webconnect', 'entity_reference_revisions', 'profile', 'state_machine', 'commerce_product', 'commerce_order', 'commerce_payment', 'commerce_payment_example', 'commerce_tax', 'commerce_shipping', 'commerce_promotion', 'physical', 'path', ]; /** * Testing demo user. * * @var \Drupal\user\UserInterface */ public $user; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); $this->installEntitySchema('profile'); $this->installEntitySchema('commerce_order'); $this->installEntitySchema('commerce_order_item'); $this->installEntitySchema('commerce_payment'); $this->installEntitySchema('commerce_payment_method'); $this->installEntitySchema('commerce_payment_gateway'); $this->installEntitySchema('commerce_product'); $this->installEntitySchema('commerce_product_variation'); $this->installEntitySchema('commerce_shipment'); $this->installEntitySchema('commerce_shipping_method'); $this->installSchema('user', ['users_data']); $this->installConfig(self::$modules); // Install a "donation" order item type. $order_item_type_storage = $this->container->get('entity_type.manager')->getStorage('commerce_order_item_type'); $order_item_type_storage->create([ 'label' => 'Donation', 'id' => 'donation', 'purchasableEntityType' => '', 'orderType' => 'default', ])->save(); // Install the variation trait. $trait_manager = \Drupal::service('plugin.manager.commerce_entity_trait'); $trait = $trait_manager->createInstance('purchasable_entity_shippable'); $trait_manager->installTrait($trait, 'commerce_product_variation', 'default'); /** @var \Drupal\commerce_order\Entity\OrderTypeInterface $order_type */ $order_type = OrderType::load('default'); $order_type->setThirdPartySetting('commerce_shipping', 'shipment_type', 'default'); $order_type->save(); // Create the order field. $field_definition = commerce_shipping_build_shipment_field_definition($order_type->id()); \Drupal::service('commerce.configurable_field_manager')->createField($field_definition); $user = $this->createUser(['mail' => 'example@example.com', 'pass' => 'abc123'], ['access quickbooks soap service']); $this->user = $this->reloadEntity($user); // Needed to provide a db connection so we don't fallback to 'migrate'. // Otherwise it uses a non-existent connection named 'migrate'. $database = Database::getConnectionInfo('default')['default']; $config = [ 'target' => 'default', 'key' => 'default', 'database' => $database, ]; \Drupal::state()->set('qbe_test_db', $config); \Drupal::state()->set('migrate.fallback_state_key', 'qbe_test_db'); // Create profile data. $profile = Profile::create(['uid' => $this->user->id(), 'type' => 'customer']); $profile->address = [ 'country_code' => 'AD', 'locality' => 'Canillo', 'postal_code' => 'AD500', 'address_line1' => 'C. Prat de la Creu, 62-64', 'given_name' => 'John', 'family_name' => 'Smith', ]; $profile->save(); $profile = $this->reloadEntity($profile); // Create a second customer profile. $profile2 = Profile::create(['uid' => $this->user->id(), 'type' => 'customer']); $profile2->address = [ 'country_code' => 'NI', 'locality' => 'Leon', 'address_line1' => 'En frente de fue Bar Corinto', 'given_name' => 'Jane', 'family_name' => 'Pierce', ]; $profile2->save(); // Turn off title generation to allow explicit values to be used. $variation_type = ProductVariationType::load('default'); $variation_type->setGenerateTitle(FALSE); $variation_type->save(); // Add some products. $product = Product::create([ 'type' => 'default', 'title' => 'Default testing product', ]); $product->save(); $variation1 = ProductVariation::create([ 'type' => 'default', 'sku' => 'SKU1', 'title' => 'Variation1', 'status' => 1, 'price' => new Price('12.00', 'USD'), ]); $variation1->save(); $product->addVariation($variation1); $variation2 = ProductVariation::create([ 'type' => 'default', 'sku' => 'SKU2', 'title' => 'Variation2', 'status' => 1, 'price' => new Price('14.00', 'USD'), ]); $variation2->save(); $product->addVariation($variation2)->save(); // Add an order. /** @var \Drupal\commerce_order\OrderItemStorageInterface $order_item_storage */ $order_item_storage = $this->container->get('entity_type.manager')->getStorage('commerce_order_item'); $order_item1 = $order_item_storage->createFromPurchasableEntity($variation1); $order_item1->setQuantity(3); $order_item1->save(); $order_item2 = $order_item_storage->createFromPurchasableEntity($variation2); $order_item2->addAdjustment(new Adjustment([ 'type' => 'promotion', 'label' => 'Order Item Discount', 'amount' => new Price('-1.00', 'USD'), ])); $order_item2->save(); $order_item3 = $order_item_storage->create([ 'type' => 'donation', 'title' => 'Donation', 'unit_price' => new Price('10.00', 'USD'), ]); $order_item3->save(); $order = Order::create([ 'type' => 'default', 'state' => 'completed', 'billing_profile' => $profile, 'mail' => $this->user->getEmail(), 'uid' => $this->user->id(), 'ip_address' => '127.0.0.1', 'order_items' => [ $order_item1, $order_item2, $order_item3 ], ]); $order->addAdjustment(new Adjustment([ 'type' => 'tax', 'label' => 'State Tax %5', 'amount' => new Price('0.50', 'USD'), ])); $order->addAdjustment(new Adjustment([ 'type' => 'shipping', 'label' => 'Shipment #1', 'amount' => new Price('5.00', 'USD'), ])); $order->addAdjustment(new Adjustment([ 'type' => 'promotion', 'label' => 'Order Discount', 'amount' => new Price('-2.00', 'USD'), ])); $order->save(); $shipmentMethod = ShippingMethod::create([ 'stores' => $this->store->id(), 'plugin' => [ 'target_plugin_id' => 'flat_rate', 'target_plugin_configuration' => [], ], ]); $shipment = Shipment::create([ 'type' => 'default', 'order_id' => $order->id(), 'items' => [ new ShipmentItem([ 'order_item_id' => $order_item1->id(), 'title' => $order_item1->label(), 'quantity' => $order_item1->getQuantity(), 'weight' => new Weight('1', 'kg'), 'declared_value' => $this->container->get('commerce_order.price_calculator')->calculate($order_item1->getPurchasedEntity(), $order_item1->getQuantity(), new Context($this->user, $this->store)), ]), ], 'amount' => new Price('5', 'USD'), 'state' => 'draft', 'shipping_service' => 'Acme Corporation', 'shipping_profile' => $profile, 'title' => 'Shipment #1', 'shipping_method' => $shipmentMethod ]); $shipment->save(); $this->reloadEntity($shipment); $order->set('shipments', [$shipment]); $order->save(); // Add a payment. $payment_gateway = PaymentGateway::create([ 'id' => 'example', 'label' => 'Payment Gateway Example', 'plugin' => 'example_onsite', ]); $payment_gateway->save(); $payment_gateway = $this->reloadEntity($payment_gateway); /** @var \Drupal\commerce_payment\Entity\PaymentMethodInterface $payment_method */ $payment_method_active = PaymentMethod::create([ 'type' => 'credit_card', 'card_type' => 'visa', 'payment_gateway' => 'example', 'method_id' => 'test_payment', // Thu, 16 Jan 2020. 'expires' => '1579132800', 'uid' => $user->id(), ]); $payment_method_active->save(); $payment_method_active = $this->reloadEntity($payment_method_active); // Create an actual payment. $payment = Payment::create([ 'payment_gateway' => 'example', 'payment_method' => $payment_method_active->id(), 'type' => 'payment_default', 'remote_id' => '123456', 'order_id' => $order->id(), 'amount' => [ 'number' => '28.50', 'currency_code' => 'USD', ], 'state' => 'completed', 'test' => TRUE, ]); $payment->save(); } /** * Tests sales receipt data extraction. */ public function testSalesReceiptExport() { /** @var \Drupal\commerce_qb_webconnect\SoapBundle\Services\SoapService $soapService */ $soapService = \Drupal::service('commerce_qb_webconnect.soap_service'); $response = $this->assertProductExport(); // Test receipt migration. $response = $soapService->sendRequestXML($response); $result = str_replace(["\n", "\t"], '', $response->sendRequestXMLResult); $date = \Drupal::service('date.formatter')->format(\Drupal::time()->getRequestTime(), 'custom', 'Y-m-d'); $this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?><?qbxml version=\"13.0\"?><QBXML><QBXMLMsgsRq onError=\"stopOnError\"><SalesReceiptAddRq><SalesReceiptAdd><CustomerRef><ListID>80000001-1431947192</ListID><FullName>John Smith</FullName></CustomerRef><TxnDate>$date</TxnDate><RefNumber>1</RefNumber><BillAddress><Addr1>C. Prat de la Creu, 62-64</Addr1><City>Canillo</City><PostalCode>AD500</PostalCode><Country>AD</Country></BillAddress><ShipAddress><Addr1>C. Prat de la Creu, 62-64</Addr1><City>Canillo</City><PostalCode>AD500</PostalCode><Country>AD</Country></ShipAddress><PaymentMethodRef><FullName>Example</FullName></PaymentMethodRef><ShipMethodRef><FullName>Flat rate</FullName></ShipMethodRef><SalesReceiptLineAdd><ItemRef><ListID>{$this->productVariationListId}</ListID></ItemRef><Desc>Variation1</Desc><Quantity>3</Quantity><Rate>12.00</Rate></SalesReceiptLineAdd><SalesReceiptLineAdd><ItemRef><ListID>{$this->productVariationListId2}</ListID></ItemRef><Desc>Variation2</Desc><Quantity>1</Quantity><Rate>13.00</Rate></SalesReceiptLineAdd><SalesReceiptLineAdd><Desc>Donation</Desc><Quantity>1</Quantity><Rate>10.00</Rate></SalesReceiptLineAdd><SalesReceiptLineAdd><ItemRef><FullName>State Tax %5</FullName></ItemRef><Quantity>1</Quantity><Amount>0.50</Amount></SalesReceiptLineAdd><SalesReceiptLineAdd><ItemRef><FullName>Freight</FullName></ItemRef><Desc>Shipment #1</Desc><Quantity>1</Quantity><Amount>5.00</Amount></SalesReceiptLineAdd><SalesReceiptLineAdd><ItemRef><FullName>Discount</FullName></ItemRef><Desc>Order Discount</Desc><Quantity>1</Quantity><Amount>-2.00</Amount></SalesReceiptLineAdd></SalesReceiptAdd></SalesReceiptAddRq></QBXMLMsgsRq></QBXML>", $result); $response->response = "<TxnID>{$this->orderListId}</TxnID>"; $response = $soapService->receiveResponseXML($response); // We should be 100% done. $this->assertSame($response->receiveResponseXMLResult, 100); /** @var \Drupal\migrate\Plugin\Migration $migration */ $migration = \Drupal::service('plugin.manager.migration')->createInstance('qb_webconnect_order'); $db_row = $migration->getIdMap()->getRowBySource(['order_id' => 1]); $this->assertEquals($this->orderListId, $db_row['destid1']); } /** * Tests invoice data extraction. */ public function testInvoiceExport() { /** @var \Drupal\Core\Config\Config $config */ $config = \Drupal::service('config.factory')->getEditable('commerce_qb_webconnect.quickbooks_admin'); $exportables = $config->get('exportables'); $exportables['order_type'] = 'invoices'; $config->set('exportables', $exportables); $config->save(); /** @var \Drupal\commerce_qb_webconnect\SoapBundle\Services\SoapService $soapService */ $soapService = \Drupal::service('commerce_qb_webconnect.soap_service'); $response = $this->assertProductExport(); // Test invoice migration. $response = $soapService->sendRequestXML($response); $result = str_replace(["\n", "\t"], '', $response->sendRequestXMLResult); $date = \Drupal::service('date.formatter')->format(\Drupal::time()->getRequestTime(), 'custom', 'Y-m-d'); $this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?><?qbxml version=\"13.0\"?><QBXML><QBXMLMsgsRq onError=\"stopOnError\"><InvoiceAddRq><InvoiceAdd><CustomerRef><ListID>80000001-1431947192</ListID><FullName>John Smith</FullName></CustomerRef><TxnDate>$date</TxnDate><RefNumber>1</RefNumber><BillAddress><Addr1>C. Prat de la Creu, 62-64</Addr1><City>Canillo</City><PostalCode>AD500</PostalCode><Country>AD</Country></BillAddress><ShipAddress><Addr1>C. Prat de la Creu, 62-64</Addr1><City>Canillo</City><PostalCode>AD500</PostalCode><Country>AD</Country></ShipAddress><ShipMethodRef><FullName>Flat rate</FullName></ShipMethodRef><InvoiceLineAdd><ItemRef><ListID>{$this->productVariationListId}</ListID></ItemRef><Desc>Variation1</Desc><Quantity>3</Quantity><Rate>12</Rate></InvoiceLineAdd><InvoiceLineAdd><ItemRef><ListID>{$this->productVariationListId2}</ListID></ItemRef><Desc>Variation2</Desc><Quantity>1</Quantity><Rate>13</Rate></InvoiceLineAdd><InvoiceLineAdd><Desc>Donation</Desc><Quantity>1</Quantity><Rate>10</Rate></InvoiceLineAdd><InvoiceLineAdd><ItemRef><FullName>State Tax %5</FullName></ItemRef><Quantity>1</Quantity><Amount>0.50</Amount></InvoiceLineAdd><InvoiceLineAdd><ItemRef><FullName>Freight</FullName></ItemRef><Desc>Shipment #1</Desc><Quantity>1</Quantity><Amount>5.00</Amount></InvoiceLineAdd><InvoiceLineAdd><ItemRef><FullName>Discount</FullName></ItemRef><Desc>Order Discount</Desc><Quantity>1</Quantity><Amount>-2.00</Amount></InvoiceLineAdd></InvoiceAdd></InvoiceAddRq></QBXMLMsgsRq></QBXML>", $result); $response->response = "<TxnID>{$this->orderListId}</TxnID>"; $response = $soapService->receiveResponseXML($response); // We should be 85% done. $this->assertSame($response->receiveResponseXMLResult, 85); /** @var \Drupal\migrate\Plugin\Migration $migration */ $migration = \Drupal::service('plugin.manager.migration')->createInstance('qb_webconnect_order'); $db_row = $migration->getIdMap()->getRowBySource(['order_id' => 1]); $this->assertEquals($this->orderListId, $db_row['destid1']); // Test payment migration. $response = $soapService->sendRequestXML($response); $result = str_replace(["\n", "\t"], '', $response->sendRequestXMLResult); $date = \Drupal::service('date.formatter')->format(\Drupal::time()->getRequestTime(), 'custom', 'Y-m-d'); $this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?><?qbxml version=\"13.0\"?><QBXML><QBXMLMsgsRq onError=\"stopOnError\"><ReceivePaymentAddRq><ReceivePaymentAdd><CustomerRef><ListID>80000001-1431947192</ListID></CustomerRef><TxnDate>$date</TxnDate><RefNumber>123456</RefNumber><PaymentMethodRef><FullName>Payment Gateway Example</FullName></PaymentMethodRef><AppliedToTxnAdd><TxnID>80000001-1431947193</TxnID><PaymentAmount>28.50</PaymentAmount></AppliedToTxnAdd></ReceivePaymentAdd></ReceivePaymentAddRq></QBXMLMsgsRq></QBXML>", $result); $response->response = "<ListID>{$this->paymentListId}</ListID>"; $response = $soapService->receiveResponseXML($response); // We should be 100% done. $this->assertSame($response->receiveResponseXMLResult, 100); /** @var \Drupal\migrate\Plugin\Migration $migration */ $migration = \Drupal::service('plugin.manager.migration')->createInstance('qb_webconnect_payment'); $db_row = $migration->getIdMap()->getRowBySource(['payment_id' => 1]); $this->assertEquals($this->paymentListId, $db_row['destid1']); } /** * Asserts product export data. * * @return \stdClass * The response object. */ public function assertProductExport() { /** @var \Drupal\commerce_qb_webconnect\SoapBundle\Services\SoapService $soapService */ $soapService = \Drupal::service('commerce_qb_webconnect.soap_service'); $request = new \stdClass(); $request->ticket = 'UUID'; $request->strUserName = $this->user->getAccountName(); $request->strPassword = 'abc123'; $response = $soapService->authenticate($request); $this->assertNotEmpty($response->authenticateResult[0]); $this->assertEmpty($response->authenticateResult[1]); // Test profile migration. $response = $soapService->sendRequestXML($response); $response->response = "<ListID>$this->customerListId</ListID>"; $response = $soapService->receiveResponseXML($response); // Test second profile migration. $response = $soapService->sendRequestXML($response); $response->response = "<ListID>{$this->customerListId}</ListID>"; $response = $soapService->receiveResponseXML($response); // Test product migration. $response = $soapService->sendRequestXML($response); $result = str_replace(["\n", "\t"], '', $response->sendRequestXMLResult); $this->assertEquals('<?xml version="1.0" encoding="utf-8"?><?qbxml version="13.0"?><QBXML><QBXMLMsgsRq onError="stopOnError"><ItemInventoryAddRq><ItemInventoryAdd><Name>Default testing product</Name><IncomeAccountRef><FullName>Sales</FullName></IncomeAccountRef><COGSAccountRef><FullName>Cost of Goods Sold</FullName></COGSAccountRef><AssetAccountRef><FullName>Inventory Asset</FullName></AssetAccountRef></ItemInventoryAdd></ItemInventoryAddRq></QBXMLMsgsRq></QBXML>', $result); $response->response = "<ListID>{$this->productListId}</ListID>"; $response = $soapService->receiveResponseXML($response); /** @var \Drupal\migrate\Plugin\Migration $migration */ $migration = \Drupal::service('plugin.manager.migration')->createInstance('qb_webconnect_product'); $db_row = $migration->getIdMap()->getRowBySource(['product_id' => 1, 'langcode' => 'en']); $this->assertEquals($this->productListId, $db_row['destid1']); // Test product variation migration. $response = $soapService->sendRequestXML($response); $result = str_replace(["\n", "\t"], '', $response->sendRequestXMLResult); $this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?><?qbxml version=\"13.0\"?><QBXML><QBXMLMsgsRq onError=\"stopOnError\"><ItemInventoryAddRq><ItemInventoryAdd><Name>SKU1</Name><ParentRef><ListID>{$this->productListId}</ListID></ParentRef><SalesPrice>12.00</SalesPrice><IncomeAccountRef><FullName>Sales</FullName></IncomeAccountRef><COGSAccountRef><FullName>Cost of Goods Sold</FullName></COGSAccountRef><AssetAccountRef><FullName>Inventory Asset</FullName></AssetAccountRef></ItemInventoryAdd></ItemInventoryAddRq></QBXMLMsgsRq></QBXML>", $result); $response->response = "<ListID>{$this->productVariationListId}</ListID>"; $response = $soapService->receiveResponseXML($response); /** @var \Drupal\migrate\Plugin\Migration $migration */ $migration = \Drupal::service('plugin.manager.migration')->createInstance('qb_webconnect_product_variation'); $db_row = $migration->getIdMap()->getRowBySource(['variation_id' => 1, 'langcode' => 'en']); $this->assertEquals($this->productVariationListId, $db_row['destid1']); // 2nd product variation. $response = $soapService->sendRequestXML($response); $result = str_replace(["\n", "\t"], '', $response->sendRequestXMLResult); $this->assertEquals("<?xml version=\"1.0\" encoding=\"utf-8\"?><?qbxml version=\"13.0\"?><QBXML><QBXMLMsgsRq onError=\"stopOnError\"><ItemInventoryAddRq><ItemInventoryAdd><Name>SKU2</Name><ParentRef><ListID>{$this->productListId}</ListID></ParentRef><SalesPrice>14.00</SalesPrice><IncomeAccountRef><FullName>Sales</FullName></IncomeAccountRef><COGSAccountRef><FullName>Cost of Goods Sold</FullName></COGSAccountRef><AssetAccountRef><FullName>Inventory Asset</FullName></AssetAccountRef></ItemInventoryAdd></ItemInventoryAddRq></QBXMLMsgsRq></QBXML>", $result); $response->response = "<ListID>{$this->productVariationListId2}</ListID>"; $response = $soapService->receiveResponseXML($response); /** @var \Drupal\migrate\Plugin\Migration $migration */ $migration = \Drupal::service('plugin.manager.migration')->createInstance('qb_webconnect_product_variation'); $db_row = $migration->getIdMap()->getRowBySource(['variation_id' => 2, 'langcode' => 'en']); $this->assertEquals($this->productVariationListId2, $db_row['destid1']); return $response; } }