/** * Processes a payment POST from the CyberSource Hosted Order Page API. */ public static function post() { if (!uc_cybersource_hop_include()) { \Drupal::logger('uc_cybersource_hop')->error('Unable to receive HOP POST due to missing or unreadable HOP.php file.'); drupal_add_http_header('Status', '503 Service unavailable'); print $this->t('The site was unable to receive a HOP post because of a missing or unreadble HOP.php'); exit; } $verify = VerifyTransactionSignature($_POST); \Drupal::logger('uc_cybersource_hop')->notice('Receiving payment notification at URL for order @orderNumber', array('@orderNumber' => $_POST['orderNumber'])); if (!isset($_POST['orderNumber'])) { \Drupal::logger('uc_cybersource_hop')->error('CS HOP attempted with invalid order number.'); return; } if (!$verify) { \Drupal::logger('uc_cybersource_hop')->notice('Receiving invalid payment notification at URL for order @orderNumber. <pre>@debug</pre>', array('@orderNumber' => $_POST['orderNumber'], '@debug' => print_r($_POST, TRUE))); return; } // Assign posted variables to local variables. $decision = SafeMarkup::checkPlain($_POST['decision']); $reason_code = SafeMarkup::checkPlain($_POST['reasonCode']); $reason = _parse_cs_reason_code($reason_code); $payment_amount = SafeMarkup::checkPlain($_POST['orderAmount']); $payment_currency = SafeMarkup::checkPlain($_POST['paymentCurrency']); $request_id = SafeMarkup::checkPlain($_POST['requestID']); $request_token = SafeMarkup::checkPlain($_POST['orderPage_requestToken']); $reconciliation_id = SafeMarkup::checkPlain($_POST['reconciliationID']); $order_id = SafeMarkup::checkPlain($_POST['orderNumber']); $payer_email = SafeMarkup::checkPlain($_POST['billTo_email']); $order = Order::load($_POST['orderNumber']); switch ($decision) { case 'ACCEPT': \Drupal::logger('uc_cybersource_hop')->notice('CyberSource verified successful payment.'); $duplicate = (bool) db_query_range('SELECT 1 FROM {uc_payment_cybersource_hop_post} WHERE order_id = :order_id AND decision = :decision', 0, 1, array(':order_id' => $order_id, ':decision' => 'ACCEPT'))->fetchField(); if ($duplicate) { \Drupal::logger('uc_cybersource_hop')->notice('CS HOP transaction for order @order-id has been processed before.', array('@order_id' => $order_id)); return; } db_insert('uc_payment_cybersource_hop_post')->fields(array('order_id' => $order_id, 'request_id' => $request_id, 'request_token' => $request_token, 'reconciliation_id' => $reconciliation_id, 'gross' => $payment_amount, 'decision' => $decision, 'reason_code' => $reason_code, 'payer_email' => $payer_email, 'received' => REQUEST_TIME))->execute(); $comment = $this->t('CyberSource request ID: @txn_id', array('@txn_id' => $request_id)); uc_payment_enter($order_id, 'cybersource_hop', $payment_amount, $order->getUserId(), NULL, $comment); uc_cart_complete_sale($order); uc_order_comment_save($order_id, 0, $this->t('Payment of @amount @currency submitted through CyberSource with request ID @rid.', array('@amount' => $payment_amount, '@currency' => $payment_currency, '@rid' => $request_id)), 'order', 'payment_received'); break; case 'ERROR': uc_order_comment_save($order_id, 0, $this->t("Payment error:@reason with request ID @rid", array('@reason' => $reason, '@rid' => '@request_id')), 'admin'); break; case 'REJECT': uc_order_comment_save($order_id, 0, $this->t("Payment is rejected:@reason with request ID @rid", array('@reason' => $reason, '@rid' => '@request_id')), 'admin'); break; case 'REVIEW': $order->setStatusId('review')->save(); uc_order_comment_save($order_id, 0, $this->t('Payment is in review & not complete: @reason. Request ID @rid', array('@reason' => $reason, '@rid' => '@request_id')), 'admin'); break; } }
public function testCheckoutFileDownload() { $this->drupalLogin($this->adminUser); $method = $this->createPaymentMethod('other'); // Add file download to the test product. $filename = $this->getTestFile(); $this->drupalPostForm('node/' . $this->product->id() . '/edit/features', array('feature' => 'file'), t('Add')); $this->drupalPostForm(NULL, array('uc_file_filename' => $filename), t('Save feature')); // Process an anonymous, shippable order. $order = $this->createOrder(['uid' => 0, 'payment_method' => $method['id']]); $order->products[1]->data->shippable = 1; $order->save(); uc_payment_enter($order->id(), $method['id'], $order->getTotal()); // Find the order uid. $uid = db_query('SELECT uid FROM {uc_orders} ORDER BY order_id DESC')->fetchField(); // @todo Re-enable when Rules is available. // $account = User::load($uid); // $this->assertTrue($account->hasFile($fid), 'New user was granted file.'); $order = Order::load($order->id()); $this->assertEqual($order->getStatusId(), 'payment_received', 'Shippable order was set to payment received.'); // Test that the file shows up on the user's purchased files list. //$this->drupalGet('user/' . $uid . '/purchased-files'); //$this->assertText($filename, 'File found in list of purchased files.'); // 4 e-mails: new account, customer invoice, admin invoice, file download. $this->assertMailString('subject', 'Account details', 4, 'New account email was sent'); $this->assertMailString('subject', 'Your Order at Ubercart', 4, 'Customer invoice was sent'); $this->assertMailString('subject', 'New Order at Ubercart', 4, 'Admin notification was sent'); // @todo Re-enable when Rules is available. // $this->assertMailString('subject', 'File Downloads', 4, 'File download notification was sent'); \Drupal::state()->set('system.test_email_collector', []); // Test again with an existing authenticated user and a non-shippable order. $order = $this->createOrder(array('uid' => 0, 'primary_email' => $this->customer->getEmail(), 'payment_method' => $method['id'])); $order->products[2]->data->shippable = 0; $order->save(); uc_payment_enter($order->id(), $method['id'], $order->getTotal()); $account = User::load($this->customer->id()); // @todo Re-enable when Rules is available. // $this->assertTrue($account->hasFile($fid), 'Existing user was granted file.'); $order = Order::load($order->id()); $this->assertEqual($order->getStatusId(), 'completed', 'Non-shippable order was set to completed.'); // 3 e-mails: customer invoice, admin invoice, file download. $this->assertNoMailString('subject', 'Account details', 3, 'New account email was sent'); $this->assertMailString('subject', 'Your Order at Ubercart', 3, 'Customer invoice was sent'); $this->assertMailString('subject', 'New Order at Ubercart', 3, 'Admin notification was sent'); // @todo Re-enable when Rules is available. // $this->assertMailString('subject', 'File Downloads', 3, 'File download notification was sent'); }
public function testShipmentsUI() { $this->drupalLogin($this->adminUser); $method = $this->createPaymentMethod('other'); // Process an anonymous, shippable order. $order = Order::create(['uid' => 0, 'primary_email' => $this->randomString() . '@example.org', 'payment_method' => $method['id']]); // Add three more products to use for our tests. $products = array(); for ($i = 1; $i <= 4; $i++) { $product = $this->createProduct(array('uid' => $this->adminUser->id(), 'promote' => 0)); $order->products[$i] = OrderProduct::create(array('nid' => $product->nid->target_id, 'title' => $product->title->value, 'model' => $product->model, 'qty' => 1, 'cost' => $product->cost->value, 'price' => $product->price->value, 'weight' => $product->weight, 'data' => [])); $order->products[$i]->data->shippable = 1; } $order->save(); $order = Order::load($order->id()); uc_payment_enter($order->id(), $method['id'], $order->getTotal()); // Now quickly package all the products in this order. $this->drupalGet('admin/store/orders/' . $order->id() . '/packages'); $this->drupalPostForm(NULL, array('shipping_types[small_package][table][1][checked]' => 1, 'shipping_types[small_package][table][2][checked]' => 1, 'shipping_types[small_package][table][3][checked]' => 1, 'shipping_types[small_package][table][4][checked]' => 1), t('Create one package')); // Test "Ship" operations for this package. $this->drupalGet('admin/store/orders/' . $order->id() . '/packages'); $this->assertLink(t('Ship')); $this->clickLink(t('Ship')); $this->assertUrl('admin/store/orders/' . $order->id() . '/shipments/new?pkgs=1'); foreach ($order->products as $sequence => $item) { $this->assertText($item->qty->value . ' x ' . $item->model->value, 'Product quantity x SKU found.'); // Test for weight here too? How do we compute this? } // We're shipping a specific package, so it should already be checked. foreach ($order->products as $sequence => $item) { $this->assertFieldByName('shipping_types[small_package][table][1][checked]', 1, 'Package is available for shipping.'); } $this->assertFieldByName('method', 'manual', 'Manual shipping method selected.'); // // Test presence and operation of ship operation on order admin View. // $this->drupalGet('admin/store/orders/view'); $this->assertLinkByHref('admin/store/orders/' . $order->id() . '/shipments'); // Test action. $this->clickLink(t('Ship')); $this->assertResponse(200); $this->assertUrl('admin/store/orders/' . $order->id() . '/shipments/new'); $this->assertText('No shipments have been made for this order.', 'Ship action found.'); $this->assertText($order->products[1]->qty->value . ' x ' . $order->products[1]->model->value, 'Product quantity x SKU found.'); $this->assertFieldByName('method', 'manual', 'Manual shipping method selected.'); // Test reaching this through the shipments tab too ... }
/** * Finalizes 2checkout transaction. */ public function complete($cart_id = 0) { $cart_config = \Drupal::config('uc_cart.settings'); $module_config = \Drupal::config('uc_2checkout.settings'); \Drupal::logger('2Checkout')->notice('Receiving new order notification for order !order_id.', array('!order_id' => SafeMarkup::checkPlain($_REQUEST['merchant_order_id']))); $order = Order::load($_REQUEST['merchant_order_id']); if (!$order || $order->getStateId() != 'in_checkout') { return t('An error has occurred during payment. Please contact us to ensure your order has submitted.'); } $key = $_REQUEST['key']; $order_number = $module_config->get('demo') ? 1 : $_REQUEST['order_number']; $valid = md5($module_config->get('secret_word') . $_REQUEST['sid'] . $order_number . $_REQUEST['total']); if (Unicode::strtolower($key) != Unicode::strtolower($valid)) { uc_order_comment_save($order->id(), 0, t('Attempted unverified 2Checkout completion for this order.'), 'admin'); throw new AccessDeniedHttpException(); } if ($_REQUEST['demo'] == 'Y' xor $module_config->get('demo')) { \Drupal::logger('uc_2checkout')->error('The 2checkout payment for order <a href="@order_url">@order_id</a> demo flag was set to %flag, but the module is set to %mode mode.', array('@order_url' => url('admin/store/orders/' . $order->id()), '@order_id' => $order->id(), '%flag' => $_REQUEST['demo'] == 'Y' ? 'Y' : 'N', '%mode' => $module_config->get('demo') ? 'Y' : 'N')); if (!$module_config->get('demo')) { throw new AccessDeniedHttpException(); } } $order->billing_street1 = $_REQUEST['street_address']; $order->billing_street2 = $_REQUEST['street_address2']; $order->billing_city = $_REQUEST['city']; $order->billing_postal_code = $_REQUEST['zip']; $order->billing_phone = $_REQUEST['phone']; $order->billing_zone = $_REQUEST['state']; $order->billing_country = $_REQUEST['country']; $order->save(); if (Unicode::strtolower($_REQUEST['email']) !== Unicode::strtolower($order->getEmail())) { uc_order_comment_save($order->id(), 0, t('Customer used a different e-mail address during payment: !email', array('!email' => SafeMarkup::checkPlain($_REQUEST['email']))), 'admin'); } if ($_REQUEST['credit_card_processed'] == 'Y' && is_numeric($_REQUEST['total'])) { $comment = t('Paid by !type, 2Checkout.com order #!order.', array('!type' => $_REQUEST['pay_method'] == 'CC' ? t('credit card') : t('echeck'), '!order' => SafeMarkup::checkPlain($_REQUEST['order_number']))); uc_payment_enter($order->id(), '2checkout', $_REQUEST['total'], 0, NULL, $comment); } else { drupal_set_message(t('Your order will be processed as soon as your payment clears at 2Checkout.com.')); uc_order_comment_save($order->id(), 0, t('!type payment is pending approval at 2Checkout.com.', array('!type' => $_REQUEST['pay_method'] == 'CC' ? t('Credit card') : t('eCheck'))), 'admin'); } // Empty that cart... uc_cart_empty($cart_id); // Add a comment to let sales team know this came in through the site. uc_order_comment_save($order->id(), 0, t('Order created through website.'), 'admin'); $build = uc_cart_complete_sale($order, $cart_config->get('new_customer_login')); return $build; }
/** * {@inheritdoc} */ public function render(ResultRow $values) { $oid = $values->{$this->aliases['order_id']}; $order = Order::load($oid); $total = 0; foreach ($order->products as $product) { $unit_conversion = uc_weight_conversion($product->weight_units, $this->options['weight_units']); $total += $product->qty * $product->weight * $unit_conversion; } $this->field_alias = 'order_weight'; $values->{$this->field_alias} = $total; if ($this->options['format'] == 'numeric') { return parent::render($values); } if ($this->options['format'] == 'uc_weight') { return uc_weight_format($values->{$this->field_alias}, $this->options['weight_units']); } }
public function testCheckoutRoleAssignment() { // Add role assignment to the test product. $rid = $this->drupalCreateRole(array('access content')); $this->drupalLogin($this->adminUser); $this->drupalPostForm('node/' . $this->product->id() . '/edit/features', array('feature' => 'role'), t('Add')); $this->drupalPostForm(NULL, array('uc_role_role' => $rid), t('Save feature')); // Process an anonymous, shippable order. $order = $this->createOrder(); $order->products[1]->data->shippable = 1; $order->save(); uc_payment_enter($order->id(), 'SimpleTest', $order->getTotal()); // Find the order uid. $uid = db_query('SELECT uid FROM {uc_orders} ORDER BY order_id DESC')->fetchField(); $account = User::load($uid); // @todo Re-enable when Rules is available. // $this->assertTrue($account->hasRole($rid), 'New user was granted role.'); $order = Order::load($order->id()); $this->assertEqual($order->getStatusId(), 'payment_received', 'Shippable order was set to payment received.'); // 4 e-mails: new account, customer invoice, admin invoice, role assignment $this->assertMailString('subject', 'Account details', 4, 'New account email was sent'); $this->assertMailString('subject', 'Your Order at Ubercart', 4, 'Customer invoice was sent'); $this->assertMailString('subject', 'New Order at Ubercart', 4, 'Admin notification was sent'); // @todo Re-enable when Rules is available. // $this->assertMailString('subject', 'role granted', 4, 'Role assignment notification was sent'); \Drupal::state()->set('system.test_email_collector', []); // Test again with an existing authenticated user and a non-shippable order. $order = $this->createOrder(array('primary_email' => $this->customer->getEmail())); $order->products[2]->data->shippable = 0; $order->save(); uc_payment_enter($order->id(), 'SimpleTest', $order->getTotal()); $account = User::load($this->customer->id()); // @todo Re-enable when Rules is available. // $this->assertTrue($account->hasRole($rid), 'Existing user was granted role.'); $order = Order::load($order->id()); $this->assertEqual($order->getStatusId(), 'completed', 'Non-shippable order was set to completed.'); // 3 e-mails: customer invoice, admin invoice, role assignment $this->assertNoMailString('subject', 'Account details', 4, 'New account email was sent'); $this->assertMailString('subject', 'Your Order at Ubercart', 4, 'Customer invoice was sent'); $this->assertMailString('subject', 'New Order at Ubercart', 4, 'Admin notification was sent'); // @todo Re-enable when Rules is available. // $this->assertMailString('subject', 'role granted', 4, 'Role assignment notification was sent'); }
public function testEntityHooks() { \Drupal::service('module_installer')->install(array('entity_crud_hook_test')); $GLOBALS['entity_crud_hook_test'] = []; $order = Order::create(); $order->save(); $this->assertHookMessage('entity_crud_hook_test_entity_presave called for type uc_order'); $this->assertHookMessage('entity_crud_hook_test_entity_insert called for type uc_order'); $GLOBALS['entity_crud_hook_test'] = []; $order = Order::load($order->id()); $this->assertHookMessage('entity_crud_hook_test_entity_load called for type uc_order'); $GLOBALS['entity_crud_hook_test'] = []; $order->save(); $this->assertHookMessage('entity_crud_hook_test_entity_presave called for type uc_order'); $this->assertHookMessage('entity_crud_hook_test_entity_update called for type uc_order'); $GLOBALS['entity_crud_hook_test'] = []; $order->delete(); $this->assertHookMessage('entity_crud_hook_test_entity_delete called for type uc_order'); }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $uid = $this->currentUser()->id(); if (!$form_state->isValueEmpty('order_comment')) { uc_order_comment_save($form_state->getValue('order_id'), $uid, $form_state->getValue('order_comment'), 'order', $form_state->getValue('status'), $form_state->getValue('notify')); } if (!$form_state->isValueEmpty('admin_comment')) { uc_order_comment_save($form_state->getValue('order_id'), $uid, $form_state->getValue('admin_comment')); } if ($form_state->getValue('status') != $form_state->getValue('current_status')) { Order::load($form_state->getValue('order_id'))->setStatusId($form_state->getValue('status'))->save(); if ($form_state->isValueEmpty('order_comment')) { uc_order_comment_save($form_state->getValue('order_id'), $uid, '-', 'order', $form_state->getValue('status'), $form_state->getValue('notify')); } } // Let Rules send email if requested. // if ($form_state->getValue('notify')) { // $order = Order::load($form_state->getValue('order_id')); // rules_invoke_event('uc_order_status_email_update', $order); // } drupal_set_message($this->t('Order updated.')); }
/** * Tests for CashOnDelivery payment method. */ public function testCashOnDelivery() { $this->drupalGet('admin/store/config/payment/add/cod'); $this->assertFieldByName('settings[policy]', 'Full payment is expected upon delivery or prior to pick-up.', 'Default COD policy found.'); $cod = $this->createPaymentMethod('cod', ['settings[policy]' => $this->randomString()]); // @todo: Test enabling delivery date on settings page. // Test checkout page. $this->drupalGet('cart/checkout'); $this->assertFieldByName('panes[payment][payment_method]', $cod['id'], 'COD payment method is selected at checkout.'); $this->assertEscaped($cod['settings[policy]'], 'COD policy found at checkout.'); // Test review order page. $this->drupalPostForm(NULL, array(), 'Review order'); $this->assertText('Cash on delivery', 'COD payment method found on review page.'); $this->drupalPostForm(NULL, array(), 'Submit order'); // Test user order view. $order = Order::load(1); $this->assertEqual($order->getPaymentMethodId(), $cod['id'], 'Order has COD payment method.'); $this->drupalGet('user/' . $order->getOwnerId() . '/orders/' . $order->id()); $this->assertText('Method: Cash on delivery', 'COD payment method displayed.'); // Test admin order view. $this->drupalGet('admin/store/orders/' . $order->id()); $this->assertText('Method: Cash on delivery', 'COD payment method displayed.'); }
/** * Tests for Other payment method. */ public function testOther() { $other = $this->createPaymentMethod('other'); // Test checkout page $this->drupalGet('cart/checkout'); $this->assertFieldByName('panes[payment][payment_method]', $other['id'], 'Other payment method is selected at checkout.'); // Test review order page $this->drupalPostForm(NULL, array(), 'Review order'); $this->assertText('Other', 'Other payment method found on review page.'); $this->drupalPostForm(NULL, array(), 'Submit order'); // Test user order view $order = Order::load(1); $this->assertEqual($order->getPaymentMethodId(), $other['id'], 'Order has other payment method.'); $this->drupalGet('user/' . $order->getOwnerId() . '/orders/' . $order->id()); $this->assertText('Method: Other', 'Other payment method displayed.'); // Test admin order view $this->drupalGet('admin/store/orders/' . $order->id()); $this->assertText('Method: Other', 'Other payment method displayed.'); $this->drupalGet('admin/store/orders/' . $order->id() . '/edit'); $this->assertFieldByName('payment_method', $other['id'], 'Other payment method is selected in the order edit form.'); $edit = array('payment_details[description]' => $this->randomString()); $this->drupalPostForm(NULL, array(), 'Save changes'); // @todo: Test storage of payment details. }
/** * Tests for Other payment method. */ public function testOther() { $this->drupalGet('admin/store/config/payment'); $this->assertText('Other', 'Other payment method found.'); $this->assertFieldByName('methods[other][status]', 0, 'Other payment method is disabled by default.'); $edit = array('methods[other][status]' => 1, 'methods[other][weight]' => -10); $this->drupalPostForm(NULL, $edit, 'Save configuration'); // Test checkout page $this->drupalGet('cart/checkout'); $this->assertFieldByName('panes[payment][payment_method]', 'other', 'Other payment method is selected at checkout.'); // Test review order page $this->drupalPostForm(NULL, array(), 'Review order'); $this->assertText('Other', 'Other payment method found on review page.'); $this->drupalPostForm(NULL, array(), 'Submit order'); // Test user order view $order = \Drupal\uc_order\Entity\Order::load(1); $this->assertEqual($order->getPaymentMethodId(), 'other', 'Order has other payment method.'); $this->drupalGet('user/' . $order->getUserId() . '/orders/' . $order->id()); $this->assertText('Method: Other', 'Other payment method displayed.'); // Test admin order view $this->drupalGet('admin/store/orders/' . $order->id()); $this->assertText('Method: Other', 'Other payment method displayed.'); $this->drupalGet('admin/store/orders/' . $order->id() . '/edit'); $this->assertFieldByName('payment_method', 'other', 'Other payment method is selected in the order edit form.'); $edit = array('payment_details[description]' => $this->randomString()); $this->drupalPostForm(NULL, array(), 'Save changes'); // @todo: Test storage of payment details. }
/** * Creates a new order directly, without going through checkout. */ protected function createOrder($edit = []) { if (empty($edit['primary_email'])) { $edit['primary_email'] = $this->randomString() . '@example.org'; } $order = Order::create($edit); if (!isset($edit['products'])) { $order->products[] = OrderProduct::create(array('nid' => $this->product->nid->target_id, 'title' => $this->product->title->value, 'model' => $this->product->model, 'qty' => 1, 'cost' => $this->product->cost->value, 'price' => $this->product->price->value, 'weight' => $this->product->weight, 'data' => [])); } $order->save(); return Order::load($order->id()); }
public function testPackagesUI() { $this->drupalLogin($this->adminUser); $method = $this->createPaymentMethod('other'); // Process an anonymous, shippable order. $order = Order::create(['uid' => 0, 'primary_email' => $this->randomString() . '@example.org', 'payment_method' => $method['id']]); // Add three more products to use for our tests. $products = array(); for ($i = 1; $i <= 4; $i++) { $product = $this->createProduct(array('uid' => $this->adminUser->id(), 'promote' => 0)); $order->products[$i] = OrderProduct::create(array('nid' => $product->nid->target_id, 'title' => $product->title->value, 'model' => $product->model, 'qty' => 1, 'cost' => $product->cost->value, 'price' => $product->price->value, 'weight' => $product->weight, 'data' => [])); $order->products[$i]->data->shippable = 1; } $order->save(); $order = Order::load($order->id()); uc_payment_enter($order->id(), $method['id'], $order->getTotal()); // Order with 4 products shippable products. (where do we test not-shippable?) // Check all, make one package, verify we're on packages page with only one packge. // Try create package link, should see there are no products message. // Delete package. // Check all, make shipment, verify we're on packages page with N packages. // Delete packages. // How does Sep work? how does making 2 packages out of 4 products work? // Check all, cancel, verify we're on order page. // After packages made and check for # (check make one and make shipment, use sep. as well) // Can use edit/delete actions to package then start over with the same order. // and check for full table at /packages and check for action on /packages page, // goto shipments tab and look for No shipments have been made for this order. as well as a list of all the packages. // // Test presence and operation of package operation on order admin View. // $this->drupalGet('admin/store/orders/view'); $this->assertLinkByHref('admin/store/orders/' . $order->id() . '/packages'); // Test action. $this->clickLink(t('Package')); $this->assertResponse(200); $this->assertText('This order\'s products have not been organized into packages.', 'Package action found.'); // Now package the products in this order. $this->drupalGet('admin/store/orders/' . $order->id() . '/packages'); $this->assertUrl('admin/store/orders/' . $order->id() . '/packages/new'); // First time through we'll be verbose - skip this on subsequent tests. foreach ($order->products as $sequence => $item) { $this->assertText($item->title->value, 'Product title found.'); $this->assertText($item->model->value, 'Product SKU found.'); $this->assertFieldByName('shipping_types[small_package][table][' . $sequence . '][checked]', 0, 'Product is available for packaging.'); } // Select all products and test the "Cancel" button. $this->drupalPostForm(NULL, array('shipping_types[small_package][table][1][checked]' => 1, 'shipping_types[small_package][table][2][checked]' => 1, 'shipping_types[small_package][table][3][checked]' => 1, 'shipping_types[small_package][table][4][checked]' => 1), t('Cancel')); // Go back to Packages tab and try something else. $this->assertUrl('admin/store/orders/' . $order->id()); $this->clickLink(t('Packages')); $this->assertUrl('admin/store/orders/' . $order->id() . '/packages/new'); $this->assertText('This order\'s products have not been organized into packages.', 'Package action found.'); // Now test the "Create one package" button without selecting anything. $this->drupalPostForm(NULL, array(), t('Create one package')); $this->assertUrl('admin/store/orders/' . $order->id() . '/packages/new'); $this->assertText('Packages must contain at least one product.', 'Validation that there must be products in a package.'); // Now test the "Create one package" button with all products selected. $this->drupalPostForm(NULL, array('shipping_types[small_package][table][1][checked]' => 1, 'shipping_types[small_package][table][2][checked]' => 1, 'shipping_types[small_package][table][3][checked]' => 1, 'shipping_types[small_package][table][4][checked]' => 1), t('Create one package')); // Check that we're now on the package list page. $this->assertUrl('admin/store/orders/' . $order->id() . '/packages'); foreach ($order->products as $sequence => $item) { $this->assertText($item->qty->value . ' x ' . $item->model->value, 'Product quantity x SKU found.'); } // The "Create packages" local action should now be available too. $this->assertLink(t('Create packages')); $this->clickLink(t('Create packages')); $this->assertUrl('admin/store/orders/' . $order->id() . '/packages/new'); // But we've already packaged everything... $this->assertText('There are no products available for this type of package.', 'Create packages local action found.'); // // Test "Ship", "Edit", and "Delete" operations for this package. // // First "Ship". $this->drupalGet('admin/store/orders/' . $order->id() . '/packages'); $this->assertLink(t('Ship')); $this->clickLink(t('Ship')); $this->assertUrl('admin/store/orders/' . $order->id() . '/shipments/new?pkgs=1'); foreach ($order->products as $sequence => $item) { $this->assertText($item->qty->value . ' x ' . $item->model->value, 'Product quantity x SKU found.'); } // Second, "Edit". $this->drupalGet('admin/store/orders/' . $order->id() . '/packages'); // (Use Href to distinguish Edit operation from Edit tab.) $this->assertLinkByHref('admin/store/orders/' . $order->id() . '/packages/1/edit'); $this->drupalGet('admin/store/orders/' . $order->id() . '/packages/1/edit'); // We're editing the package we already made, so all the // products should be checked. foreach ($order->products as $sequence => $item) { $this->assertFieldByName('products[' . $sequence . '][checked]', 1, 'Product is available for packaging.'); } // Third, "Delete". $this->drupalGet('admin/store/orders/' . $order->id() . '/packages'); $this->assertLink(t('Delete')); $this->clickLink(t('Delete')); // Delete takes us to confirm page. $this->assertUrl('admin/store/orders/' . $order->id() . '/packages/1/delete'); $this->assertText('The products it contains will be available for repackaging.', 'Deletion confirm question found.'); // "Cancel" returns to the package list page. $this->clickLink(t('Cancel')); $this->assertLinkByHref('admin/store/orders/' . $order->id() . '/packages'); // Again with the "Delete". $this->clickLink(t('Delete')); $this->drupalPostForm(NULL, array(), t('Delete')); // Delete returns to new packages page with all packages unchecked. $this->assertUrl('admin/store/orders/' . $order->id() . '/packages/new'); $this->assertText('Package 1 has been deleted.', 'Package deleted message found.'); foreach ($order->products as $sequence => $item) { $this->assertFieldByName('shipping_types[small_package][table][' . $sequence . '][checked]', 0, 'Product is available for packaging.'); } // Back to no packages. Now test making more than one package. // Now test the "Create one package" button with all products selected. $this->drupalPostForm(NULL, array('shipping_types[small_package][table][1][checked]' => 1, 'shipping_types[small_package][table][2][checked]' => 1), t('Create one package')); // Check that we're now on the package list page. $this->assertUrl('admin/store/orders/' . $order->id() . '/packages'); $this->assertText($order->products[1]->qty->value . ' x ' . $order->products[1]->model->value, 'Product quantity x SKU found.'); $this->assertText($order->products[2]->qty->value . ' x ' . $order->products[2]->model->value, 'Product quantity x SKU found.'); $this->assertNoText($order->products[3]->qty->value . ' x ' . $order->products[3]->model->value, 'Product quantity x SKU not found.'); $this->assertNoText($order->products[4]->qty->value . ' x ' . $order->products[4]->model->value, 'Product quantity x SKU not found.'); // Use "Create packages" to create a second package. $this->assertLink(t('Create packages')); $this->clickLink(t('Create packages')); $this->assertUrl('admin/store/orders/' . $order->id() . '/packages/new'); $this->assertNoText($order->products[1]->model->value, 'Product SKU not found.'); $this->assertNoText($order->products[2]->model->value, 'Product SKU not found.'); $this->assertText($order->products[3]->model->value, 'Product SKU found.'); $this->assertText($order->products[4]->model->value, 'Product SKU found.'); $this->drupalPostForm(NULL, array('shipping_types[small_package][table][3][checked]' => 1, 'shipping_types[small_package][table][4][checked]' => 1), t('Create one package')); $this->assertLinkByHref('admin/store/orders/' . $order->id() . '/packages'); foreach ($order->products as $sequence => $item) { $this->assertText($item->qty->value . ' x ' . $item->model->value, 'Product quantity x SKU found.'); } // How do we test for two packages? Look for two "Ship" links $this->assertLinkByHref('admin/store/orders/' . $order->id() . '/shipments/new?pkgs=2'); $this->assertLinkByHref('admin/store/orders/' . $order->id() . '/shipments/new?pkgs=3'); // Now delete both packages. $this->clickLink(t('Delete')); $this->drupalPostForm(NULL, array(), t('Delete')); $this->assertText('Package 2 has been deleted.', 'Package deleted message found.'); // There's still one left to delete... $this->clickLink(t('Delete')); $this->drupalPostForm(NULL, array(), t('Delete')); $this->assertUrl('admin/store/orders/' . $order->id() . '/packages/new'); $this->assertText('Package 3 has been deleted.', 'Package deleted message found.'); // Back to no packages. Now test "Make packages" button. $this->drupalPostForm(NULL, array('shipping_types[small_package][table][1][checked]' => 1, 'shipping_types[small_package][table][2][checked]' => 1, 'shipping_types[small_package][table][3][checked]' => 1, 'shipping_types[small_package][table][4][checked]' => 1), t('Make packages')); // Check that we're now on the package list page. $this->assertUrl('admin/store/orders/' . $order->id() . '/packages'); foreach ($order->products as $sequence => $item) { $this->assertText($item->qty->value . ' x ' . $item->model->value, 'Product quantity x SKU found.'); } }
public function testTaxDisplay() { $this->drupalLogin($this->adminUser); // Enable a payment method for the payment preview checkout pane. $edit = array('methods[check][status]' => 1); $this->drupalPostForm('admin/store/config/payment', $edit, t('Save configuration')); // Create a 20% inclusive tax rate. $rate = (object) array('name' => $this->randomMachineName(8), 'rate' => 0.2, 'taxed_product_types' => array('product'), 'taxed_line_items' => array(), 'weight' => 0, 'shippable' => 0, 'display_include' => 1, 'inclusion_text' => ''); uc_tax_rate_save($rate); $this->drupalGet('admin/store/config/taxes'); $this->assertText($rate->name, 'Tax was saved successfully.'); // $this->drupalGet("admin/store/config/taxes/manage/uc_tax_$rate->id"); // $this->assertText(t('Conditions'), 'Rules configuration linked to tax.'); $this->addToCart($this->product); // Manually step through checkout. $this->checkout() doesn't know about taxes. $this->drupalPostForm('cart', array(), 'Checkout'); $this->assertText(t('Enter your billing address and information here.'), 'Viewed cart page: Billing pane has been displayed.'); $this->assertRaw($rate->name, 'Tax line item displayed.'); $this->assertRaw(uc_currency_format($rate->rate * $this->product->price->value), 'Correct tax amount displayed.'); // Submit the checkout page. $edit = $this->populateCheckoutForm(); $this->drupalPostForm('cart/checkout', $edit, t('Review order')); $this->assertRaw(t('Your order is almost complete.')); $this->assertRaw($rate->name, 'Tax line item displayed.'); $this->assertRaw(uc_currency_format($rate->rate * $this->product->price->value), 'Correct tax amount displayed.'); // Complete the review page. $this->drupalPostForm(NULL, array(), t('Submit order')); $order_ids = \Drupal::entityQuery('uc_order')->condition('delivery_first_name', $edit['panes[delivery][first_name]'])->execute(); $order_id = reset($order_ids); if ($order_id) { $this->pass(SafeMarkup::format('Order %order_id has been created', ['%order_id' => $order_id])); $this->drupalGet('admin/store/orders/' . $order_id . '/edit'); $this->assertTaxLineCorrect($this->loadTaxLine($order_id), $rate->rate, 'on initial order load'); $this->drupalPostForm('admin/store/orders/' . $order_id . '/edit', array(), t('Save changes')); $this->assertText(t('Order changes saved.')); $this->assertTaxLineCorrect($this->loadTaxLine($order_id), $rate->rate, 'after saving order'); // Change tax rate and ensure order doesn't change. $oldrate = $rate->rate; $rate->rate = 0.1; $rate = uc_tax_rate_save($rate); // Save order because tax changes are only updated on save. $this->drupalPostForm('admin/store/orders/' . $order_id . '/edit', array(), t('Save changes')); $this->assertText(t('Order changes saved.')); $this->assertTaxLineCorrect($this->loadTaxLine($order_id), $oldrate, 'after rate change'); // Change taxable products and ensure order doesn't change. $class = $this->createProductClass(); $rate->taxed_product_types = array($class->getEntityTypeId()); uc_tax_rate_save($rate); // entity_flush_caches(); $this->drupalPostForm('admin/store/orders/' . $order_id . '/edit', array(), t('Save changes')); $this->assertText(t('Order changes saved.')); $this->assertTaxLineCorrect($this->loadTaxLine($order_id), $oldrate, 'after applicable product change'); // Change order Status back to in_checkout and ensure tax-rate changes now update the order. \Drupal\uc_order\Entity\Order::load($order_id)->setStatusId('in_checkout')->save(); $this->drupalPostForm('admin/store/orders/' . $order_id . '/edit', array(), t('Save changes')); $this->assertText(t('Order changes saved.')); $this->assertFalse($this->loadTaxLine($order_id), 'The tax line was removed from the order when order status changed back to in_checkout.'); // Restore taxable product and ensure new tax is added. $rate->taxed_product_types = array('product'); uc_tax_rate_save($rate); $this->drupalPostForm('admin/store/orders/' . $order_id . '/edit', array(), t('Save changes')); $this->assertText(t('Order changes saved.')); $this->assertTaxLineCorrect($this->loadTaxLine($order_id), $rate->rate, 'when order status changed back to in_checkout'); } else { $this->fail('No order was created.'); } }
/** * Processes Instant Payment Notifications from PayPal. * * @param array $ipn * The IPN data. */ protected function processIpn($ipn) { $amount = $ipn['mc_gross']; $email = !empty($ipn['business']) ? $ipn['business'] : $ipn['receiver_email']; $txn_id = $ipn['txn_id']; if (!isset($ipn['invoice'])) { \Drupal::logger('uc_paypal')->error('IPN attempted with invalid order ID.'); return; } // Extract order and cart IDs. $order_id = $ipn['invoice']; if (strpos($order_id, '-') > 0) { list($order_id, $cart_id) = explode('-', $order_id); \Drupal::service('session')->set('uc_cart_id', $cart_id); } $order = Order::load($order_id); if (!$order) { \Drupal::logger('uc_paypal')->error('IPN attempted for non-existent order @order_id.', ['@order_id' => $order_id]); return; } // @todo Send method name and order ID in the IPN URL? $config = \Drupal::service('plugin.manager.uc_payment.method')->createFromOrder($order)->getConfiguration(); // Optionally log IPN details. if (!empty($config['wps_debug_ipn'])) { \Drupal::logger('uc_paypal')->notice('Receiving IPN at URL for order @order_id. <pre>@debug</pre>', ['@order_id' => $order_id, '@debug' => print_r($ipn, TRUE)]); } // Express Checkout IPNs may not have the WPS email stored. But if it is, // make sure that the right account is being paid. if (!empty($config['wps_email']) && Unicode::strtolower($email) != Unicode::strtolower($config['wps_email'])) { \Drupal::logger('uc_paypal')->error('IPN for a different PayPal account attempted.'); return; } // Determine server. if (empty($data['test_ipn'])) { $host = 'https://www.paypal.com/cgi-bin/webscr'; } else { $host = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; } // POST IPN data back to PayPal to validate. try { $response = \Drupal::httpClient()->request('POST', $host, ['form_params' => ['cmd' => '_notify-validate'] + $ipn]); } catch (TransferException $e) { \Drupal::logger('uc_paypal')->error('IPN validation failed with HTTP error %error.', ['%error' => $e->getMessage()]); return; } // Check IPN validation response to determine if the IPN was valid.. if ($response->getBody() != 'VERIFIED') { \Drupal::logger('uc_paypal')->error('IPN transaction failed verification.'); uc_order_comment_save($order_id, 0, $this->t('An IPN transaction failed verification for this order.'), 'admin'); return; } // Check for a duplicate transaction ID. $duplicate = (bool) db_query_range('SELECT 1 FROM {uc_payment_paypal_ipn} WHERE txn_id = :id AND status <> :status', 0, 1, [':id' => $txn_id, ':status' => 'Pending'])->fetchField(); if ($duplicate) { if ($order->getPaymentMethodId() != 'credit') { \Drupal::logger('uc_paypal')->notice('IPN transaction ID has been processed before.'); } return; } db_insert('uc_payment_paypal_ipn')->fields(array('order_id' => $order_id, 'txn_id' => $txn_id, 'txn_type' => $ipn['txn_type'], 'mc_gross' => $amount, 'status' => $ipn['payment_status'], 'receiver_email' => $email, 'payer_email' => $ipn['payer_email'], 'received' => REQUEST_TIME))->execute(); switch ($ipn['payment_status']) { case 'Canceled_Reversal': uc_order_comment_save($order_id, 0, $this->t('PayPal has canceled the reversal and returned @amount @currency to your account.', ['@amount' => uc_currency_format($amount, FALSE), '@currency' => $ipn['mc_currency']]), 'admin'); break; case 'Completed': if (abs($amount - $order->getTotal()) > 0.01) { \Drupal::logger('uc_paypal')->warning('Payment @txn_id for order @order_id did not equal the order total.', ['@txn_id' => $txn_id, '@order_id' => $order->id(), 'link' => Link::createFromRoute($this->t('view'), 'entity.uc_order.canonical', ['uc_order' => $order->id()])->toString()]); } $comment = $this->t('PayPal transaction ID: @txn_id', ['@txn_id' => $txn_id]); uc_payment_enter($order_id, 'paypal_wps', $amount, $order->getOwnerId(), NULL, $comment); uc_order_comment_save($order_id, 0, $this->t('PayPal IPN reported a payment of @amount @currency.', ['@amount' => uc_currency_format($amount, FALSE), '@currency' => $ipn['mc_currency']])); break; case 'Denied': uc_order_comment_save($order_id, 0, $this->t("You have denied the customer's payment."), 'admin'); break; case 'Expired': uc_order_comment_save($order_id, 0, $this->t('The authorization has failed and cannot be captured.'), 'admin'); break; case 'Failed': uc_order_comment_save($order_id, 0, $this->t("The customer's attempted payment from a bank account failed."), 'admin'); break; case 'Pending': $order->setStatusId('paypal_pending')->save(); uc_order_comment_save($order_id, 0, $this->t('Payment is pending at PayPal: @reason', ['@reason' => $this->pendingMessage($ipn['pending_reason'])]), 'admin'); break; // You, the merchant, refunded the payment. // You, the merchant, refunded the payment. case 'Refunded': $comment = $this->t('PayPal transaction ID: @txn_id', ['@txn_id' => $txn_id]); uc_payment_enter($order_id, 'paypal_wps', $amount, $order->getOwnerId(), NULL, $comment); break; case 'Reversed': \Drupal::logger('uc_paypal')->error('PayPal has reversed a payment!'); uc_order_comment_save($order_id, 0, $this->t('Payment has been reversed by PayPal: @reason', ['@reason' => $this->reversalMessage($ipn['reason_code'])]), 'admin'); break; case 'Processed': uc_order_comment_save($order_id, 0, $this->t('A payment has been accepted.'), 'admin'); break; case 'Voided': uc_order_comment_save($order_id, 0, $this->t('The authorization has been voided.'), 'admin'); break; } }
/** * Tests basic flatrate shipping quote functionality. */ public function testQuote() { // Create product and quotes. $product = $this->createProduct(); $quote1 = $this->createQuote(); $quote2 = $this->createQuote(array(), array('LABEL' => 'quote_conditions', 'PLUGIN' => 'and', 'REQUIRES' => array('rules'), 'USES VARIABLES' => array('order' => array('type' => 'uc_order', 'label' => 'Order')), 'AND' => array(array('data_is' => array('data' => array('order:delivery-address:country'), 'value' => 'US'))))); // Define strings to test for. $qty = mt_rand(2, 100); foreach ([$quote1, $quote2] as $quote) { $quote->amount = uc_currency_format($quote->base_rate + $quote->product_rate * $qty); $quote->option_text = $quote->label . ': ' . $quote->amount; $quote->total = uc_currency_format($product->price->value * $qty + $quote->base_rate + $quote->product_rate * $qty); } // Add product to cart, update qty, and go to checkout page. $this->addToCart($product); $this->drupalPostForm('cart', array('items[0][qty]' => $qty), t('Checkout')); $this->assertText($quote1->option_text, 'The default quote option is available'); $this->assertText($quote2->option_text, 'The second quote option is available'); $this->assertText($quote1->total, 'Order total includes the default quote.'); // Select a different quote and ensure the total updates correctly. Currently, we have to do this // by examining the ajax return value directly (rather than the page contents) because drupalPostAjaxForm() can // only handle replacements via the 'wrapper' property, and the ajax callback may use a command with a selector. $edit = array('panes[quotes][quotes][quote_option]' => 'flatrate_2---0'); $edit = $this->populateCheckoutForm($edit); $result = $this->ucPostAjax(NULL, $edit, $edit); $this->assertText($quote2->total, 'The order total includes the selected quote.'); // @todo Re-enable when shipping quote conditions are available. // Switch to a different country and ensure the ajax updates the page correctly. // $edit['panes[delivery][country]'] = 'CA'; // $result = $this->ucPostAjax(NULL, $edit, 'panes[delivery][country]'); // $this->assertText($quote1->option_text, 'The default quote is still available after changing the country.'); // $this->assertNoText($quote2->option_text, 'The second quote is no longer available after changing the country.'); // $this->assertText($quote1->total, 'The total includes the default quote.'); // Proceed to review page and ensure the correct quote is present. $edit['panes[quotes][quotes][quote_option]'] = 'flatrate_1---0'; $edit = $this->populateCheckoutForm($edit); $this->drupalPostForm(NULL, $edit, t('Review order')); $this->assertRaw(t('Your order is almost complete.')); $this->assertText($quote1->total, 'The total is correct on the order review page.'); // Submit the review order page. $this->drupalPostForm(NULL, [], t('Submit order')); $order_ids = \Drupal::entityQuery('uc_order')->condition('delivery_first_name', $edit['panes[delivery][first_name]'])->execute(); $order_id = reset($order_ids); if ($order_id) { $order = \Drupal\uc_order\Entity\Order::load($order_id); foreach ($order->line_items as $line) { if ($line['type'] == 'shipping') { break; } } // Verify line item is correct. $this->assertEqual($line['type'], 'shipping', 'The shipping line item was saved to the order.'); $this->assertEqual($quote1->amount, uc_currency_format($line['amount']), 'Stored shipping line item has the correct amount.'); // Verify order total is correct on order-view form. $this->drupalGet('admin/store/orders/' . $order_id); $this->assertText($quote1->total, 'The total is correct on the order admin view page.'); // Verify shipping line item is correct on order edit form. $this->drupalGet('admin/store/orders/' . $order_id . '/edit'); $this->assertFieldByName('line_items[' . $line['line_item_id'] . '][title]', $quote1->label, 'Found the correct shipping line item title.'); $this->assertFieldByName('line_items[' . $line['line_item_id'] . '][amount]', substr($quote1->amount, 1), 'Found the correct shipping line item title.'); // Verify that the "get quotes" button works as expected. $result = $this->ucPostAjax('admin/store/orders/' . $order_id . '/edit', [], ['op' => t('Get shipping quotes')]); $this->assertText($quote1->option_text, 'The default quote is available on the order-edit page.'); // @todo Change to assertNoText when shipping quote conditions are available. $this->assertText($quote2->option_text, 'The second quote is available on the order-edit page.'); } else { $this->fail('No order was created.'); } }
/** * React on INS messages from 2Checkout. * * @param \Symfony\Component\HttpFoundation\Request $request * The request of the page. */ public function notification(Request $request) { $values = $request->request; \Drupal::logger('uc_2checkout')->notice('Received 2Checkout notification with following data: @data', ['@data' => print_r($values->all(), TRUE)]); $module_config = $this->config('uc_2checkout.settings'); if ($values->has('message_type') && $values->has('md5_hash') && $values->has('message_id')) { // Validate the hash $secret_word = $module_config->get('secret_word'); $sid = $module_config->get('sid'); $twocheckout_order_id = $values->get('sale_id'); $twocheckout_invoice_id = $values->get('invoice_id'); $hash = strtoupper(md5($twocheckout_order_id . $sid . $twocheckout_invoice_id . $secret_word)); if ($hash != $values->get('md5_hash')) { \Drupal::logger('uc_2checkout')->notice('2Checkout notification #@num had a wrong hash.', ['@num' => $values->get('message_id')]); die('Hash Incorrect'); } $order_id = $values->get('vendor_order_id'); $order = Order::load($order_id); if ($values->get('message_type') == 'FRAUD_STATUS_CHANGED') { switch ($values->get('fraud_status')) { // @todo: I think this still needs a lot of work, I don't see anywhere that it // validates the INS against an order in the DB then changes order status if the // payment was successful, like PayPal IPN does ... case 'pass': break; case 'wait': break; case 'fail': // @todo uc_order_update_status($order_id, uc_order_state_default('canceled')); $order->setStatusId('canceled')->save(); uc_order_comment_save($order_id, 0, $this->t('Order have not passed 2Checkout fraud review.')); die('fraud'); break; } } elseif ($values->get('message_type') == 'REFUND_ISSUED') { // @todo uc_order_update_status($order_id, uc_order_state_default('canceled')); $order->setStatusId('canceled')->save(); uc_order_comment_save($order_id, 0, $this->t('Order have been refunded through 2Checkout.')); die('refund'); } } die('ok'); }
/** * {@inheritdoc} */ public function render(ResultRow $values) { $order = Order::load($this->getValue($values)); return uc_order_actions($order, TRUE); }
/** * Tests for Check payment method. */ public function testCheck() { $this->drupalGet('admin/store/config/payment/add/check'); $this->assertText('Check'); $this->assertFieldByName('settings[policy]', 'Personal and business checks will be held for up to 10 business days to ensure payment clears before an order is shipped.', 'Default check payment policy found.'); $edit = ['id' => strtolower($this->randomMachineName()), 'label' => $this->randomString(), 'settings[policy]' => $this->randomString()]; // Fill in and save the check address settings. $address = new Address(); $address->first_name = $this->randomMachineName(6); $address->company = $this->randomMachineName(10); $address->street1 = mt_rand(100, 1000) . ' ' . $this->randomMachineName(10); $address->street2 = 'Suite ' . mt_rand(100, 999); $address->city = $this->randomMachineName(10); $address->postal_code = mt_rand(10000, 99999); $country_id = array_rand(\Drupal::service('country_manager')->getEnabledList()); $address->country = $country_id; $this->drupalPostAjaxForm(NULL, ['settings[address][country]' => $address->country], 'settings[address][country]'); $edit += array('settings[name]' => $address->first_name, 'settings[address][company]' => $address->company, 'settings[address][street1]' => $address->street1, 'settings[address][street2]' => $address->street2, 'settings[address][city]' => $address->city, 'settings[address][country]' => $address->country, 'settings[address][postal_code]' => $address->postal_code); // Don't try to set the zone unless the country has zones! $zone_list = \Drupal::service('country_manager')->getZoneList($country_id); if (!empty($zone_list)) { $address->zone = array_rand($zone_list); $edit += array('settings[address][zone]' => $address->zone); } $this->drupalPostForm(NULL, $edit, 'Save'); // Test that check settings show up on checkout page. $this->drupalGet('cart/checkout'); $this->assertFieldByName('panes[payment][payment_method]', $edit['id'], 'Check payment method is selected at checkout.'); $this->assertText('Checks should be made out to:'); $this->assertRaw((string) $address, 'Properly formatted check mailing address found.'); $this->assertEscaped($edit['settings[policy]'], 'Check payment policy found at checkout.'); // Test that check settings show up on review order page. $this->drupalPostForm(NULL, array(), 'Review order'); $this->assertText('Check', 'Check payment method found on review page.'); $this->assertText('Mail to', 'Check payment method help text found on review page.'); $this->assertRaw((string) $address, 'Properly formatted check mailing address found.'); $this->drupalPostForm(NULL, array(), 'Submit order'); // Test user order view. $order = Order::load(1); $this->assertEqual($order->getPaymentMethodId(), $edit['id'], 'Order has check payment method.'); $this->drupalGet('user/' . $order->getOwnerId() . '/orders/' . $order->id()); $this->assertText('Method: Check', 'Check payment method displayed.'); // Test admin order view - receive check. $this->drupalGet('admin/store/orders/' . $order->id()); $this->assertText('Method: Check', 'Check payment method displayed.'); $this->assertLink('Receive Check'); $this->clickLink('Receive Check'); $this->assertFieldByName('amount', number_format($order->getTotal(), 2, '.', ''), 'Amount field defaults to order total.'); // Random receive date between tomorrow and 1 year from now. $receive_date = strtotime('now +' . mt_rand(1, 365) . ' days'); $formatted = \Drupal::service('date.formatter')->format($receive_date, 'uc_store'); $edit = array('comment' => $this->randomString(), 'clear_date[date]' => date('Y-m-d', $receive_date)); $this->drupalPostForm(NULL, $edit, 'Receive check'); $this->assertNoLink('Receive Check'); $this->assertText('Clear Date: ' . $formatted, 'Check clear date found.'); // Test that user order view shows check received. $this->drupalGet('user/' . $order->getOwnerId() . '/orders/' . $order->id()); $this->assertText('Check received'); $this->assertText('Expected clear date:'); $this->assertText($formatted, 'Check clear date found.'); }