/**
  * Creates an order for the specified user, and redirects to the edit page.
  *
  * @param \Drupal\user\UserInterface $user
  *   The user to create the order for.
  */
 public function createForUser(UserInterface $user)
 {
     $order = Order::create(['uid' => $user->id(), 'order_status' => uc_order_state_default('post_checkout')]);
     $order->save();
     uc_order_comment_save($order->id(), \Drupal::currentUser()->id(), $this->t('Order created by the administration.'), 'admin');
     return $this->redirect('entity.uc_order.edit_form', ['uc_order' => $order->id()]);
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     $items = \Drupal::service('uc_cart.manager')->get()->getContents();
     $paypal_config = $this->config('uc_paypal.settings');
     if (empty($items)) {
         drupal_set_message($this->t('You do not have any items in your shopping cart.'));
         return;
     }
     list($desc, $subtotal) = _uc_paypal_product_details($items);
     $order = Order::create(['uid' => $this->currentUser()->id()]);
     $order->save();
     $nvp_request = array('METHOD' => 'SetExpressCheckout', 'RETURNURL' => Url::fromRoute('uc_paypal.ec_review', [], ['absolute' => TRUE])->toString(), 'CANCELURL' => Url::fromRoute('uc_cart.cart', [], ['absolute' => TRUE])->toString(), 'AMT' => uc_currency_format($subtotal, FALSE, FALSE, '.'), 'CURRENCYCODE' => $order->getCurrency(), 'PAYMENTACTION' => $paypal_config->get('wpp_cc_txn_type') == 'authorize' ? 'Authorization' : 'Sale', 'DESC' => substr($desc, 0, 127), 'INVNUM' => $order->id() . '-' . REQUEST_TIME, 'REQCONFIRMSHIPPING' => $paypal_config->get('ec_rqconfirmed_addr'), 'BUTTONSOURCE' => 'Ubercart_ShoppingCart_EC_US', 'NOTIFYURL' => Url::fromRoute('uc_paypal.ipn', [], ['absolute' => TRUE])->toString(), 'LANDINGPAGE' => $paypal_config->get('ec_landingpage_style'));
     $order->products = $items;
     $order->save();
     $nvp_response = uc_paypal_api_request($nvp_request, $paypal_config->get('wpp_server'));
     if ($nvp_response['ACK'] != 'Success') {
         drupal_set_message($this->t('PayPal reported an error: @code: @message', ['@code' => $nvp_response['L_ERRORCODE0'], '@message' => $nvp_response['L_LONGMESSAGE0']]), 'error');
         return;
     }
     $session = \Drupal::service('session');
     $session->set('cart_order', $order->id());
     $session->set('TOKEN', $nvp_response['TOKEN']);
     $sandbox = '';
     if (strpos($paypal_config->get('wpp_server'), 'sandbox') > 0) {
         $sandbox = 'sandbox.';
     }
     header('Location: https://www.' . $sandbox . 'paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=' . $session->get('TOKEN'));
     exit;
 }
 /**
  * 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;
     }
 }
 /**
  * Tests customer overview.
  */
 public function testCustomerAdminPages()
 {
     $this->drupalLogin($this->adminUser);
     $country = Country::load('US');
     Order::create(array('uid' => $this->customer->id(), 'billing_country' => $country->id(), 'billing_zone' => 'AK'))->save();
     $this->drupalGet('admin/store/customers/view');
     $this->assertResponse(200);
     $this->assertLinkByHref('user/' . $this->customer->id());
     $this->assertText($country->getZones()['AK']);
     $this->assertText($country->label());
 }
 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');
 }
 /**
  * {@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 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.');
 }
 /**
  * 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());
 }
 /**
  * Link a completed sale to a user.
  *
  * @param \Drupal\uc_order\Entity\Order $order
  *   The order entity that has just been completed.
  */
 protected function completeSaleAccount($order)
 {
     // Order already has a user ID, so the user was logged in during checkout.
     if ($order->getOwnerId()) {
         $order->data->complete_sale = 'logged_in';
         return;
     }
     // Email address matches an existing account.
     if ($account = user_load_by_mail($order->getEmail())) {
         $order->setOwner($account);
         $order->data->complete_sale = 'existing_user';
         return;
     }
     // Set up a new user.
     $cart_config = \Drupal::config('uc_cart.settings');
     $fields = array('name' => uc_store_email_to_username($order->getEmail()), 'mail' => $order->getEmail(), 'init' => $order->getEmail(), 'pass' => user_password(), 'roles' => array(), 'status' => $cart_config->get('new_customer_status_active') ? 1 : 0);
     // Override the username, if specified.
     if (isset($order->data->new_user_name)) {
         $fields['name'] = $order->data->new_user_name;
     }
     // Create the account.
     $account = User::create($fields);
     $account->save();
     // Override the password, if specified.
     if (isset($order->data->new_user_hash)) {
         db_query('UPDATE {users_field_data} SET pass = :hash WHERE uid = :uid', [':hash' => $order->data->new_user_hash, ':uid' => $account->id()]);
         $account->password = t('Your password');
     } else {
         $account->password = $fields['pass'];
         $order->password = $fields['pass'];
     }
     // Send the customer their account details if enabled.
     if ($cart_config->get('new_customer_email')) {
         $type = $cart_config->get('new_customer_status_active') ? 'register_no_approval_required' : 'register_pending_approval';
         \Drupal::service('plugin.manager.mail')->mail('user', $type, $order->getEmail(), uc_store_mail_recipient_langcode($order->getEmail()), array('account' => $account), uc_store_email_from());
     }
     $order->setOwner($account);
     $order->data->new_user_name = $fields['name'];
     $order->data->complete_sale = 'new_user';
 }
 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;
     }
 }
Exemple #18
0
 protected function ucCreateOrder($customer)
 {
     $order = Order::create(array('uid' => $customer->id()));
     $order->save();
     uc_order_comment_save($order->id(), 0, t('Order created programmatically.'), 'admin');
     $order_ids = \Drupal::entityQuery('uc_order')->condition('order_id', $order->id())->execute();
     $this->assertTrue(in_array($order->id(), $order_ids), SafeMarkup::format('Found order ID @order_id', ['@order_id' => $order->id()]));
     $country_manager = \Drupal::service('country_manager');
     $country = array_rand($country_manager->getEnabledList());
     $zones = $country_manager->getZoneList($country);
     $delivery_address = new Address();
     $delivery_address->first_name = $this->randomMachineName(12);
     $delivery_address->last_name = $this->randomMachineName(12);
     $delivery_address->street1 = $this->randomMachineName(12);
     $delivery_address->street2 = $this->randomMachineName(12);
     $delivery_address->city = $this->randomMachineName(12);
     $delivery_address->zone = array_rand($zones);
     $delivery_address->postal_code = mt_rand(10000, 99999);
     $delivery_address->country = $country;
     $billing_address = new Address();
     $billing_address->first_name = $this->randomMachineName(12);
     $billing_address->last_name = $this->randomMachineName(12);
     $billing_address->street1 = $this->randomMachineName(12);
     $billing_address->street2 = $this->randomMachineName(12);
     $billing_address->city = $this->randomMachineName(12);
     $billing_address->zone = array_rand($zones);
     $billing_address->postal_code = mt_rand(10000, 99999);
     $billing_address->country = $country;
     $order->setAddress('delivery', $delivery_address)->setAddress('billing', $billing_address)->save();
     // Force the order to load from the DB instead of the entity cache.
     $db_order = \Drupal::entityManager()->getStorage('uc_order')->loadUnchanged($order->id());
     // Compare delivery and billing addresses to those loaded from the database.
     $db_delivery_address = $db_order->getAddress('delivery');
     $db_billing_address = $db_order->getAddress('billing');
     $this->assertEqual($delivery_address, $db_delivery_address, 'Delivery address is equal to delivery address in database.');
     $this->assertEqual($billing_address, $db_billing_address, 'Billing address is equal to billing address in database.');
     return $order;
 }
 /**
  * Displays the cart checkout page built of checkout panes from enabled modules.
  */
 public function checkout()
 {
     $cart_config = $this->config('uc_cart.settings');
     $items = $this->cartManager->get()->getContents();
     if (count($items) == 0 || !$cart_config->get('checkout_enabled')) {
         return $this->redirect('uc_cart.cart');
     }
     // Send anonymous users to login page when anonymous checkout is disabled.
     if ($this->currentUser()->isAnonymous() && !$cart_config->get('checkout_anonymous')) {
         drupal_set_message($this->t('You must login before you can proceed to checkout.'));
         if ($this->config('user.settings')->get('register') != USER_REGISTER_ADMINISTRATORS_ONLY) {
             drupal_set_message($this->t('If you do not have an account yet, you should <a href=":url">register now</a>.', [':url' => Url::fromRoute('user.register', [], ['query' => drupal_get_destination()])->toString()]));
         }
         return $this->redirect('user.page', [], ['query' => drupal_get_destination()]);
     }
     // Load an order from the session, if available.
     if ($this->session->has('cart_order')) {
         $order = $this->loadOrder();
         if ($order) {
             // Don't use an existing order if it has changed status or owner, or if
             // there has been no activity for 10 minutes (to prevent identity theft).
             if ($order->getStateId() != 'in_checkout' || $this->currentUser()->isAuthenticated() && $this->currentUser()->id() != $order->getOwnerId() || $order->getChangedTime() < REQUEST_TIME - CartInterface::CHECKOUT_TIMEOUT) {
                 if ($order->getStateId() == 'in_checkout' && $order->getChangedTime() < REQUEST_TIME - CartInterface::CHECKOUT_TIMEOUT) {
                     // Mark expired orders as abandoned.
                     $order->setStatusId('abandoned')->save();
                 }
                 unset($order);
             }
         } else {
             // Ghost session.
             $this->session->remove('cart_order');
             drupal_set_message($this->t('Your session has expired or is no longer valid.  Please review your order and try again.'));
             return $this->redirect('uc_cart.cart');
         }
     }
     // Determine whether the form is being submitted or built for the first time.
     if (isset($_POST['form_id']) && $_POST['form_id'] == 'uc_cart_checkout_form') {
         // If this is a form submission, make sure the cart order is still valid.
         if (!isset($order)) {
             drupal_set_message($this->t('Your session has expired or is no longer valid.  Please review your order and try again.'));
             return $this->redirect('uc_cart.cart');
         } elseif ($this->session->has('uc_cart_order_rebuild')) {
             drupal_set_message($this->t('Your shopping cart contents have changed. Please review your order and try again.'));
             return $this->redirect('uc_cart.cart');
         }
     } else {
         // Prepare the cart order.
         $rebuild = FALSE;
         if (!isset($order)) {
             // Create a new order if necessary.
             $order = Order::create(array('uid' => $this->currentUser()->id()));
             $order->save();
             $this->session->set('cart_order', $order->id());
             $rebuild = TRUE;
         } elseif ($this->session->has('uc_cart_order_rebuild')) {
             // Or, if the cart has changed, then remove old products and line items.
             $result = \Drupal::entityQuery('uc_order_product')->condition('order_id', $order->id())->execute();
             if (!empty($result)) {
                 $storage = $this->entityTypeManager()->getStorage('uc_order_product');
                 $entities = $storage->loadMultiple(array_keys($result));
                 $storage->delete($entities);
             }
             uc_order_delete_line_item($order->id(), TRUE);
             $rebuild = TRUE;
         }
         if ($rebuild) {
             // Copy the cart contents to the cart order.
             $order->products = array();
             foreach ($items as $item) {
                 $order->products[] = $item->toOrderProduct();
             }
             $this->session->remove('uc_cart_order_rebuild');
         } elseif (!uc_order_product_revive($order->products)) {
             drupal_set_message($this->t('Some of the products in this order are no longer available.'), 'error');
             return $this->redirect('uc_cart.cart');
         }
     }
     $min = $cart_config->get('minimum_subtotal');
     if ($min > 0 && $order->getSubtotal() < $min) {
         drupal_set_message($this->t('The minimum order subtotal for checkout is @min.', ['@min' => uc_currency_format($min)]), 'error');
         return $this->redirect('uc_cart.cart');
     }
     // Trigger the "Customer starts checkout" hook and event.
     $this->moduleHandler()->invokeAll('uc_cart_checkout_start', array($order));
     // rules_invoke_event('uc_cart_checkout_start', $order);
     return $this->formBuilder()->getForm('Drupal\\uc_cart\\Form\\CheckoutForm', $order);
 }
 /**
  * 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');
 }
Exemple #21
0
 /**
  * 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.');
     }
 }
 /**
  * {@inheritdoc}
  */
 public function submitForm(array &$form, FormStateInterface $form_state)
 {
     switch ($form_state->getValue('customer_type')) {
         case 'search':
             $uid = $form_state->getValue(['customer', 'uid']);
             break;
         case 'create':
             // Create new account.
             $email = trim($form_state->getValue(['customer', 'email']));
             $fields = array('name' => uc_store_email_to_username($email), 'mail' => $email, 'pass' => user_password(), 'status' => $this->config('uc_cart.settings')->get('new_customer_status_active') ? 1 : 0);
             $account = \Drupal\user\Entity\User::create($fields);
             $account->save();
             $uid = $account->id();
             if ($form_state->getValue(['customer', 'sendmail'])) {
                 // Manually set the password so it appears in the e-mail.
                 $account->password = $fields['pass'];
                 \Drupal::service('plugin.manager.mail')->mail('user', 'register_admin_created', $email, uc_store_mail_recipient_langcode($email), array('account' => $account), uc_store_email_from());
                 drupal_set_message(t('A welcome message has been e-mailed to the new user.'));
             }
             break;
         default:
             $uid = 0;
     }
     $order = \Drupal\uc_order\Entity\Order::create(array('uid' => $uid, 'order_status' => uc_order_state_default('post_checkout')));
     $order->save();
     uc_order_comment_save($order->id(), \Drupal::currentUser()->id(), t('Order created by the administration.'), 'admin');
     $form_state->setRedirect('entity.uc_order.edit_form', ['uc_order' => $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.');
     }
 }
Exemple #24
0
 /**
  * {@inheritdoc}
  */
 public function render(ResultRow $values)
 {
     $order = Order::load($this->getValue($values));
     return uc_order_actions($order, TRUE);
 }
 /**
  * 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.
 }