/**
  * Add new transaction and update current balances.
  *
  * @param Request\Add $request
  *
  * @return Response\Add
  */
 public function add(Request\Add $request)
 {
     $result = new Response\Add();
     $debitAccId = $request->getDebitAccId();
     $creditAccId = $request->getCreditAccId();
     $operationId = $request->getOperationId();
     $dateApplied = $request->getDateApplied();
     $value = $request->getValue();
     $def = $this->_manTrans->begin();
     try {
         /* get account type for debit account */
         $debitAcc = $this->_repoAcc->getById($debitAccId);
         $debitAssetTypeId = $debitAcc->getAssetTypeId();
         /* get account type for credit account */
         $creditAcc = $this->_repoAcc->getById($creditAccId);
         $creditAssetTypeId = $creditAcc->getAssetTypeId();
         /* asset types should be equals */
         if (!is_null($debitAssetTypeId) && $debitAssetTypeId == $creditAssetTypeId) {
             /* add transaction */
             $toAdd = [Transaction::ATTR_OPERATION_ID => $operationId, Transaction::ATTR_DEBIT_ACC_ID => $debitAccId, Transaction::ATTR_CREDIT_ACC_ID => $creditAccId, Transaction::ATTR_VALUE => $value, Transaction::ATTR_DATE_APPLIED => $dateApplied];
             $idCreated = $this->_repoTrans->create($toAdd);
             $result->setTransactionId($idCreated);
         } else {
             throw new \Exception("Asset type (#{$debitAssetTypeId}) for debit account #{$debitAccId} is not equal to " . "asset type (#{$creditAssetTypeId}) for credit account {$creditAccId}.");
         }
         $this->_manTrans->commit($def);
         $result->markSucceed();
     } finally {
         $this->_manTrans->end($def);
     }
     return $result;
 }
 /**
  * Get account data or create new account if customer has no account for the requested asset.
  *
  * @param Request\Get $request
  *
  * @return Response\Get
  */
 public function get(Request\Get $request)
 {
     $result = new Response\Get();
     $this->_logger->info("'Get account' operation is called.");
     $accountId = $request->getAccountId();
     $customerId = $request->getCustomerId();
     $assetTypeId = $request->getAssetTypeId();
     $assetTypeCode = $request->getAssetTypeCode();
     $createNewAccIfMissed = $request->getCreateNewAccountIfMissed();
     /* accountId has the highest priority */
     if ($accountId) {
         $data = $this->_repoAccount->getById($accountId);
     } else {
         /* try to look up by customer id & asset type id */
         if (!$assetTypeId) {
             /* get asset type ID by asset code */
             $assetTypeId = $this->_repoTypeAsset->getIdByCode($assetTypeCode);
         }
         /* get account by customerId & assetTypeId */
         $data = $this->_repoAccount->getByCustomerId($customerId, $assetTypeId);
     }
     /* analyze found data */
     if ($data) {
         $result->setData($data);
         $result->markSucceed();
     } else {
         if ($createNewAccIfMissed) {
             /* not found - add new account */
             $data = [Account::ATTR_CUST_ID => $customerId, Account::ATTR_ASSET_TYPE_ID => $assetTypeId, Account::ATTR_BALANCE => 0];
             $accId = $this->_repoAccount->create($data);
             $data[Account::ATTR_ID] = $accId;
             $result->setData($data);
             $result->markSucceed();
             $this->_logger->info("There is no account for customer #{$customerId} and asset type #{$assetTypeId}. New account #{$accId} is created.");
         }
     }
     $this->_logger->info("'Get account' operation is completed.");
     return $result;
 }