/**
  * Process cost
  *
  * @param float|integer $cost
  * @param boolean $rounding
  * @return string
  */
 public function __invoke($cost, $rounding = false)
 {
     $exchangeRates = PaymentService::getExchangeRates();
     $activeShoppingCurrency = PaymentService::getShoppingCartCurrency();
     // convert cost
     if (isset($exchangeRates[$activeShoppingCurrency])) {
         $cost = $cost * $exchangeRates[$activeShoppingCurrency]['rate'];
     }
     if ($rounding) {
         $cost = PaymentService::roundingCost($cost);
     }
     return $this->getView()->currencyFormat($cost, $activeShoppingCurrency);
 }
 /**
  * Get widget content
  *
  * @return string|boolean
  */
 public function getContent()
 {
     $userId = UserIdentityService::getCurrentUserIdentity()['user_id'];
     // process post actions
     if ($this->getRequest()->isPost() && ApplicationCsrfUtility::isTokenValid($this->getRequest()->getPost('csrf')) && $this->getRequest()->getPost('form_name') == 'transactions') {
         $transactions = $this->getRequest()->getPost('transactions');
         if ($transactions && is_array($transactions)) {
             switch ($this->getRequest()->getQuery('action')) {
                 // delete selected transactions
                 case 'delete':
                     return $this->deleteTransactions($transactions, $userId);
                 default:
             }
         }
     }
     // get pagination options
     list($pageParamName, $perPageParamName, $orderByParamName, $orderTypeParamName) = $this->getPaginationParams();
     $page = $this->getView()->applicationRoute()->getQueryParam($pageParamName, 1);
     $perPage = $this->getView()->applicationRoute()->getQueryParam($perPageParamName);
     $orderBy = $this->getView()->applicationRoute()->getQueryParam($orderByParamName);
     $orderType = $this->getView()->applicationRoute()->getQueryParam($orderTypeParamName);
     $filters = [];
     $fieldsPostfix = '_' . $this->widgetConnectionId;
     // get a filter form
     $filterForm = $this->getServiceLocator()->get('Application\\Form\\FormManager')->getInstance('Payment\\Form\\PaymentUserTransactionFilter')->setFieldsPostfix($fieldsPostfix);
     $request = $this->getRequest();
     $filterForm->getForm()->setData($request->getQuery(), false);
     // validate the filter form
     if ($this->getRequest()->isXmlHttpRequest() || $this->getView()->applicationRoute()->getQueryParam('form_name') == $filterForm->getFormName()) {
         // check the filter form validation
         if ($filterForm->getForm()->isValid()) {
             $filters = $filterForm->getData();
         }
     }
     // get data
     $paginator = $this->getModel()->getUserTransactions($userId, $page, $perPage, $orderBy, $orderType, $filters, $fieldsPostfix);
     $dataGridWrapper = 'transactions-page-wrapper';
     // get data grid
     $dataGrid = $this->getView()->partial('payment/widget/transaction-history', ['current_currency' => PaymentService::getPrimaryCurrency(), 'payment_types' => $this->getModel()->getPaymentsTypes(false, true), 'filter_form' => $filterForm->getForm(), 'paginator' => $paginator, 'order_by' => $orderBy, 'order_type' => $orderType, 'per_page' => $perPage, 'page_param_name' => $pageParamName, 'per_page_param_name' => $perPageParamName, 'order_by_param_name' => $orderByParamName, 'order_type_param_name' => $orderTypeParamName, 'widget_connection' => $this->widgetConnectionId, 'widget_position' => $this->widgetPosition, 'data_grid_wrapper' => $dataGridWrapper]);
     if ($this->getRequest()->isXmlHttpRequest()) {
         return $dataGrid;
     }
     return $this->getView()->partial('payment/widget/transaction-history-wrapper', ['data_grid_wrapper' => $dataGridWrapper, 'data_grid' => $dataGrid]);
 }
 /**
  * Cost format
  *
  * @param float|integer|array $cost
  * @param array $options
  * @param boolean $rounding
  * @return string
  */
 public function __invoke($cost, array $options = [], $rounding = true)
 {
     $value = null;
     $currency = null;
     // extract data from the array
     if (!is_numeric($cost)) {
         $value = !empty($cost['cost']) ? $cost['cost'] : null;
         $currency = !empty($cost['currency']) ? $cost['currency'] : null;
     } else {
         $value = $cost;
     }
     // get a currency code from the options
     if (!empty($options['currency'])) {
         $currency = $options['currency'];
     }
     if (!$value && !$currency) {
         return;
     }
     if ($rounding) {
         $value = PaymentService::roundingCost($value);
     }
     return $this->getView()->currencyFormat($value, $currency);
 }
 /**
  * Activate a discount coupon
  */
 public function ajaxActivateDiscountCouponAction()
 {
     $refreshPage = false;
     $discountForm = $this->getServiceLocator()->get('Application\\Form\\FormManager')->getInstance('Payment\\Form\\PaymentDiscountForm')->setModel($this->getModel());
     $request = $this->getRequest();
     if ($request->isPost()) {
         $discountForm->getForm()->setData($request->getPost(), false);
         if ($discountForm->getForm()->isValid()) {
             // activate a discount coupon
             $couponCode = $discountForm->getForm()->getData()['coupon'];
             // save the activated discount coupon's ID in sessions
             PaymentService::setDiscountCouponId($this->getModel()->getCouponInfo($couponCode, 'slug')['id']);
             // fire the activate discount coupon event
             PaymentEvent::fireActivateDiscountCouponEvent($couponCode);
             $this->flashMessenger()->setNamespace('success')->addMessage($this->getTranslator()->translate('The coupon code has been activated'));
             $refreshPage = true;
         }
     }
     $view = new ViewModel(['discount_form' => $discountForm->getForm(), 'refresh_page' => $refreshPage]);
     return $view;
 }
 /**
  * Get primary currency
  *
  * @return array
  */
 public function getPrimaryCurrency()
 {
     return PaymentService::getPrimaryCurrency();
 }
 /**
  * Get current discount
  *
  * @return integer
  */
 public function getCurrentDiscount()
 {
     return PaymentService::getDiscountCouponInfo() ? PaymentService::getDiscountCouponInfo()['discount'] : 0;
 }
 /**
  * Add a new transaction
  *
  * @param integer $userId
  * @param array $transactionInfo
  *      integer payment_type - required
  *      string comments - optional
  *      string first_name - required
  *      string last_name - required
  *      string email - required
  *      string phone - required
  *      string address - optional
  * @param array $items
  *      integer object_id
  *      integer module
  *      string title
  *      string slug
  *      float cost
  *      float discount
  *      integer count
  * @return integer|string
  */
 public function addTransaction($userId, array $transactionInfo, array $items)
 {
     try {
         $this->adapter->getDriver()->getConnection()->beginTransaction();
         $basicData = ['user_hidden' => self::TRANSACTION_USER_NOT_HIDDEN, 'paid' => self::TRANSACTION_NOT_PAID, 'language' => $this->getCurrentLanguage(), 'date' => time(), 'currency' => PaymentService::getPrimaryCurrency()['id']];
         // add the user id
         if (UserBaseModel::DEFAULT_GUEST_ID != $userId) {
             $basicData['user_id'] = $userId;
         }
         // add the discount id
         if (PaymentService::getDiscountCouponInfo()) {
             $basicData['discount_coupon'] = PaymentService::getDiscountCouponInfo()['id'];
         }
         if (!$transactionInfo['comments']) {
             $transactionInfo['comments'] = null;
         }
         $insert = $this->insert()->into('payment_transaction_list')->values(array_merge($transactionInfo, $basicData));
         $statement = $this->prepareStatementForSqlObject($insert);
         $statement->execute();
         $transactionId = $this->adapter->getDriver()->getLastGeneratedValue();
         // generate a random slug
         $update = $this->update()->table('payment_transaction_list')->set(['slug' => strtoupper($this->generateSlug($transactionId, $this->generateRandString(self::TRANSACTION_MIN_SLUG_LENGTH, self::ALLOWED_SLUG_CHARS), 'payment_transaction_list', 'id'))])->where(['id' => $transactionId]);
         $statement = $this->prepareStatementForSqlObject($update);
         $statement->execute();
         // update the discount coupon info
         if (PaymentService::getDiscountCouponInfo()) {
             $update = $this->update()->table('payment_discount_coupon')->set(['used' => self::COUPON_USED])->where(['id' => PaymentService::getDiscountCouponInfo()['id']]);
             $statement = $this->prepareStatementForSqlObject($update);
             $statement->execute();
         }
         // add  transaction's items
         foreach ($items as $item) {
             $insert = $this->insert()->into('payment_transaction_item')->values(['transaction_id' => $transactionId, 'object_id' => $item['object_id'], 'module' => $item['module'], 'title' => $item['title'], 'slug' => $item['slug'], 'cost' => $item['cost'], 'discount' => $item['discount'], 'count' => $item['count'], 'paid' => self::TRANSACTION_NOT_PAID, 'extra_options' => !empty($item['extra_options']) ? $item['extra_options'] : null]);
             $statement = $this->prepareStatementForSqlObject($insert);
             $statement->execute();
         }
         $this->adapter->getDriver()->getConnection()->commit();
     } catch (Exception $e) {
         $this->adapter->getDriver()->getConnection()->rollback();
         ApplicationErrorLogger::log($e);
         return $e->getMessage();
     }
     // fire the add payment transaction event
     PaymentEvent::fireAddPaymentTransactionEvent($transactionId, $transactionInfo);
     return $transactionId;
 }
 /**
  * Get widget content
  *
  * @return string|boolean
  */
 public function getContent()
 {
     // get list of shopping cart's items
     $shoppingCartItems = PaymentService::getActiveShoppingCartItems();
     if (!count($shoppingCartItems)) {
         return $this->getView()->partial('payment/widget/checkout-message', ['message' => $this->translate('Shopping cart is empty')]);
     }
     // check additional params
     if (UserIdentityService::isGuest()) {
         foreach ($shoppingCartItems as $item) {
             if ($item['must_login'] == PaymentBaseModel::MODULE_MUST_LOGIN) {
                 $this->getFlashMessenger()->setNamespace('error')->addMessage($this->translate('Some of the items in your shopping cart requires you to be logged in'));
                 // get the login page url
                 $loginPageUrl = $this->getView()->pageUrl('login');
                 if (false !== $loginPageUrl) {
                     return $this->redirectTo(['page_name' => $loginPageUrl], false, ['back_url' => $this->getView()->url('page', ['page_name' => $this->getView()->pageUrl('checkout')], ['force_canonical' => true])]);
                 }
                 // redirect to home page
                 return $this->redirectTo(['page_name' => $this->getView()->pageUrl('home')]);
             }
         }
     }
     // get shopping cart items amount
     $amount = (double) paymentService::roundingCost(paymentService::getActiveShoppingCartItemsAmount(true));
     $transactionPayable = $amount > 0;
     // get payments types
     if (null == ($paymentsTypes = $this->getModel()->getPaymentsTypes()) && $transactionPayable) {
         return $this->getView()->partial('payment/widget/checkout-message', ['message' => $this->translate('No available payment types. Please try again later')]);
     }
     // get a form instance
     $checkoutForm = $this->getServiceLocator()->get('Application\\Form\\FormManager')->getInstance('Payment\\Form\\PaymentCheckout')->setPaymentsTypes($paymentsTypes)->hidePaymentType(!$transactionPayable);
     // set default values
     if (!UserIdentityService::isGuest()) {
         $checkoutForm->getForm()->setData(['first_name' => UserIdentityService::getCurrentUserIdentity()['first_name'], 'last_name' => UserIdentityService::getCurrentUserIdentity()['last_name'], 'email' => UserIdentityService::getCurrentUserIdentity()['email'], 'phone' => UserIdentityService::getCurrentUserIdentity()['phone'], 'address' => UserIdentityService::getCurrentUserIdentity()['address']], false);
     }
     // validate the form
     if ($this->getRequest()->isPost() && $this->getRequest()->getPost('form_name') == $checkoutForm->getFormName()) {
         // fill form with received values
         $checkoutForm->getForm()->setData($this->getRequest()->getPost());
         if ($checkoutForm->getForm()->isValid()) {
             $formData = $checkoutForm->getForm()->getData();
             $userId = UserIdentityService::getCurrentUserIdentity()['user_id'];
             // add a new transaction
             $result = $this->getModel()->addTransaction($userId, $formData, $shoppingCartItems);
             if (is_numeric($result)) {
                 // clear the shopping cart items
                 if (null != ($items = $this->getModel()->getAllShoppingCartItems(false))) {
                     // delete all items
                     foreach ($items as $itemInfo) {
                         $this->getModel()->deleteFromShoppingCart($itemInfo['id']);
                     }
                 }
                 // get created transaction info
                 $transactionInfo = $this->getModel()->getTransactionInfo($result);
                 // redirect to the buying page
                 if ($transactionPayable) {
                     $buyItemsPageUrl = $this->getView()->pageUrl('buy-items', [], null, true);
                     if (false !== $buyItemsPageUrl) {
                         return $this->redirectTo(['page_name' => $buyItemsPageUrl, 'slug' => $transactionInfo['slug']], false, ['payment_name' => $transactionInfo['payment_name']]);
                     }
                     $this->getFlashMessenger()->setNamespace('error')->addMessage($this->translate('Sorry you cannot see the buy items page'));
                 } else {
                     // activate the transaction and redirect to the success page
                     if (true === ($result = $this->getModel()->activateTransaction($transactionInfo))) {
                         $successPageUrl = $this->getView()->pageUrl('successful-payment');
                         if (false !== $successPageUrl) {
                             return $this->redirectTo(['page_name' => $successPageUrl]);
                         }
                         $this->getFlashMessenger()->setNamespace('error')->addMessage($this->translate('Sorry you cannot see the payment success page'));
                     } else {
                         $this->getFlashMessenger()->setNamespace('error')->addMessage($this->translate('Transaction activation error'));
                     }
                 }
             } else {
                 $this->getFlashMessenger()->setNamespace('error')->addMessage($this->translate('Error occurred'));
             }
             return $this->reloadPage();
         }
     }
     return $this->getView()->partial('payment/widget/checkout', ['checkout_form' => $checkoutForm->getForm()]);
 }