/**
  * Add to shopping cart
  *
  * @param array $itemInfo
  *      integer object_id - required
  *      integer module - required
  *      string title - required
  *      string|integer slug - optional
  *      float cost - required
  *      float discount - optional
  *      integer count - required
  * @param \Payment\Handler\PaymentInterfaceHandler $paymentHandler
  * @return boolean
  */
 protected function addToShoppingCart($itemInfo, PaymentInterfaceHandler $paymentHandler)
 {
     // check an item existing in shopping cart
     if (null != ($itemId = $this->getModel()->inShoppingCart($itemInfo['object_id'], $itemInfo['module']))) {
         // delete an old item
         $this->getModel()->deleteFromShoppingCart($itemId);
     }
     $result = $this->getModel()->addToShoppingCart($itemInfo);
     if (is_numeric($result)) {
         // clear the item's discount
         if ((double) $itemInfo['discount']) {
             $paymentHandler->clearDiscount($itemInfo['object_id'], (double) $itemInfo['discount']);
         }
         return true;
     }
     return false;
 }
 /**
  * Update item globally
  *
  * @param integer $objectId
  * @param \Payment\Handler\PaymentInterfaceHandler $paymentHandler
  * @param ArrayObject $module
  *      integer countable
  *      integer module
  * @return boolean|string
  */
 public function updateItemGlobally($objectId, PaymentInterfaceHandler $paymentHandler, ArrayObject $module)
 {
     try {
         $this->adapter->getDriver()->getConnection()->beginTransaction();
         // get updated item's info
         $objectInfo = $paymentHandler->getItemInfo($objectId);
         $deleteItem = $module->countable == self::MODULE_COUNTABLE && $objectInfo['count'] <= 0;
         // delete item from the shopping cart and not paid transactions list
         if ($deleteItem) {
             $delete = $this->delete()->from('payment_shopping_cart')->where(['object_id' => $objectId, 'module' => $module->module]);
             $statement = $this->prepareStatementForSqlObject($delete);
             $statement->execute();
             $delete = $this->delete()->from('payment_transaction_item')->where(['object_id' => $objectId, 'module' => $module->module, 'paid' => self::TRANSACTION_NOT_PAID]);
             $statement = $this->prepareStatementForSqlObject($delete);
             $statement->execute();
         } else {
             // main item's info
             $data = ['title' => $objectInfo['title'], 'slug' => $objectInfo['slug']];
             $extraData = ['cost' => $objectInfo['cost']];
             if (isset($objectInfo['count'])) {
                 $extraData = array_merge($extraData, ['count' => new Expression('IF (`count` > ?, ?, `count`)', [$objectInfo['count'], $objectInfo['count']])]);
             }
             // update item's info in the shopping cart
             $update = $this->update()->table('payment_shopping_cart')->set(array_merge($data, $extraData))->where(['object_id' => $objectId, 'module' => $module->module]);
             $statement = $this->prepareStatementForSqlObject($update);
             $statement->execute();
             // update title and slug for all transactions
             $update = $this->update()->table('payment_transaction_item')->set($data)->where(['object_id' => $objectId, 'module' => $module->module]);
             $statement = $this->prepareStatementForSqlObject($update);
             $statement->execute();
             // update cost and count only for not paid transactions
             $update = $this->update()->table('payment_transaction_item')->set($extraData)->where(['object_id' => $objectId, 'module' => $module->module, 'paid' => self::TRANSACTION_NOT_PAID]);
             $statement = $this->prepareStatementForSqlObject($update);
             $statement->execute();
         }
         $this->adapter->getDriver()->getConnection()->commit();
     } catch (Exception $e) {
         $this->adapter->getDriver()->getConnection()->rollback();
         ApplicationErrorLogger::log($e);
         return $e->getMessage();
     }
     PaymentEvent::fireEditItemsEvent($objectId, $module->module);
     return true;
 }