/**
  * 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;
 }
 /**
  * Add new customer to downline and new entry to change log.
  *
  * @param Request\Add $request
  *
  * @return Response\Add
  */
 public function add(Request\Add $request)
 {
     $result = new Response\Add();
     $customerId = $request->getCustomerId();
     $parentId = $request->getParentId();
     $humanReference = $request->getReference();
     $countryCode = $request->getCountryCode();
     $date = $request->getDate();
     $this->_logger->info("Add new customer #{$customerId} with parent #{$parentId} to downline tree.");
     $def = $this->_manTrans->begin();
     try {
         /* define referred parent */
         $parentId = $this->_subReferral->getReferredParentId($customerId, $parentId);
         if ($customerId == $parentId) {
             /* add root node */
             $this->_logger->info("This is root node (customer id is equal to parent id).");
             $path = Cfg::DTPS;
             $depth = Cfg::INIT_DEPTH;
         } else {
             /* get parent data by parent Mage id */
             $data = $this->_repoCustomer->getById($parentId);
             $parentPath = $data->getPath();
             $parentDepth = $data->getDepth();
             $path = $parentPath . $parentId . Cfg::DTPS;
             $depth = $parentDepth + 1;
         }
         /* add customer to downline */
         $toAdd = [Customer::ATTR_CUSTOMER_ID => $customerId, Customer::ATTR_PARENT_ID => $parentId, Customer::ATTR_DEPTH => $depth, Customer::ATTR_PATH => $path, Customer::ATTR_REFERRAL_CODE => $customerId];
         if (isset($humanReference)) {
             $toAdd[Customer::ATTR_HUMAN_REF] = $humanReference;
         }
         if (isset($countryCode)) {
             $toAdd[Customer::ATTR_COUNTRY_CODE] = $countryCode;
         } else {
             $toAdd[Customer::ATTR_COUNTRY_CODE] = $this->_subReferral->getDefaultCountryCode();
         }
         $this->_repoCustomer->create($toAdd);
         /* save log record to changes registry */
         $formatted = $date;
         $toLog = [Change::ATTR_CUSTOMER_ID => $customerId, Change::ATTR_PARENT_ID => $parentId, Change::ATTR_DATE_CHANGED => $formatted];
         $idLog = $this->_repoChange->create($toLog);
         if ($idLog) {
             $this->_logger->debug("Downline changes are logged in registry with date: {$formatted}.");
             $this->_logger->debug("New change log record #{$idLog} is inserted (customer: {$customerId}, parent: {$parentId}, date: {$formatted}).");
             $result->setData($toAdd);
             $result->markSucceed();
             $this->_manTrans->commit($def);
             $this->_logger->info("New customer #{$customerId} with parent #{$parentId} is added to downline tree.");
         }
     } finally {
         $this->_manTrans->end($def);
     }
     return $result;
 }
 /**
  * Add operation with list of transactions and change account balances.
  *
  * @param Request\Add $req
  *
  * @return Response\Add
  */
 public function add(Request\Add $req)
 {
     $result = new Response\Add();
     $operationTypeId = $req->getOperationTypeId();
     $operationTypeCode = $req->getOperationTypeCode();
     $datePerformed = $req->getDatePerformed();
     $note = $req->getOperationNote();
     $transactions = $req->getTransactions();
     $asRef = $req->getAsTransRef();
     $customerId = $req->getCustomerId();
     $adminUserId = $req->getAdminUserId();
     $def = $this->_manTrans->begin();
     try {
         /* add operation itself */
         if (!$operationTypeId) {
             $operationTypeId = $this->_repoTypeOper->getIdByCode($operationTypeCode);
         }
         $bindToAdd = [EntityOperation::ATTR_TYPE_ID => $operationTypeId, EntityOperation::ATTR_DATE_PREFORMED => $datePerformed];
         if (!is_null($note)) {
             $bindToAdd[EntityOperation::ATTR_NOTE] = $note;
         }
         $operId = $this->_repoOper->create($bindToAdd);
         if ($operId) {
             $transIds = $this->_subAdd->transactions($operId, $transactions, $datePerformed, $asRef);
             $result->setOperationId($operId);
             $result->setTransactionsIds($transIds);
             /* log customer link */
             if ($customerId) {
                 $log = new \Praxigento\Accounting\Data\Entity\Log\Change\Customer();
                 $log->setCustomerRef($customerId);
                 $log->setOperationRef($operId);
                 $this->_repoELogChangeCust->create($log);
             }
             /* log admin link */
             if ($adminUserId) {
                 $log = new \Praxigento\Accounting\Data\Entity\Log\Change\Admin();
                 $log->setUserRef($adminUserId);
                 $log->setOperationRef($operId);
                 $this->_repoELogChangeAdmin->create($log);
             }
             $this->_manTrans->commit($def);
             $result->markSucceed();
         }
     } finally {
         $this->_manTrans->end($def);
     }
     return $result;
 }