public function betweenCustomers(Request\BetweenCustomers $request)
 {
     $result = new Response\BetweenCustomers();
     /* constraints validation results */
     $isCountriesTheSame = false;
     $isTargetInDownline = false;
     /* extract input parameters */
     $custIdDebit = $request->getFromCustomerId();
     $custIdCredit = $request->getToCustomerId();
     $date = $request->getDateApplied();
     $value = $request->getValue();
     $condForceAll = $request->getConditionForceAll();
     $condForceCountry = $request->getConditionForceCountry();
     $condForceDownline = $request->getConditionForceDownline();
     if (is_null($date)) {
         $date = $this->_toolDate->getUtcNowForDb();
     }
     /* validate conditions */
     if (!$condForceAll) {
         /* validate customer countries */
         $downDebit = $this->_repoMod->getDownlineCustomerById($custIdDebit);
         $downCredit = $this->_repoMod->getDownlineCustomerById($custIdCredit);
         /* countries should be equals */
         $countryDebit = $downDebit->getCountryCode();
         $countryCredit = $downCredit->getCountryCode();
         if ($countryDebit == $countryCredit || $condForceCountry) {
             $isCountriesTheSame = true;
         }
         /* transfer is allowed to own subtree only */
         $path = $downCredit->getPath();
         $key = Cfg::DTPS . $downDebit->getCustomerId() . Cfg::DTPS;
         if (strpos($path, $key) !== false || $condForceDownline) {
             $isTargetInDownline = true;
         }
     }
     /* check validation results and perform transfer */
     if ($condForceAll || $isTargetInDownline && $isCountriesTheSame) {
         /* get PV-accounts */
         $reqAccGet = new AccountGetRequest();
         $reqAccGet->setCustomerId($custIdDebit);
         $reqAccGet->setAssetTypeCode(Cfg::CODE_TYPE_ASSET_PV);
         $reqAccGet->setCreateNewAccountIfMissed(true);
         $respAccDebit = $this->_callAccount->get($reqAccGet);
         $reqAccGet->setCustomerId($custIdCredit);
         $respAccCredit = $this->_callAccount->get($reqAccGet);
         /* add transfer operation */
         $reqAddOper = new OperationAddRequest();
         $reqAddOper->setOperationTypeCode(Cfg::CODE_TYPE_OPER_PV_TRANSFER);
         $reqAddOper->setDatePerformed($date);
         $reqAddOper->setTransactions([[Transaction::ATTR_DEBIT_ACC_ID => $respAccDebit->getId(), Transaction::ATTR_CREDIT_ACC_ID => $respAccCredit->getId(), Transaction::ATTR_VALUE => $value]]);
         $respAddOper = $this->_callOperation->add($reqAddOper);
         if ($respAddOper->isSucceed()) {
             $result->markSucceed();
         }
     }
     return $result;
 }
 private function _checkAccount($custId, $value)
 {
     $req = new RequestAccountGet();
     $req->setCustomerId($custId);
     $req->setAssetTypeCode(Cfg::CODE_TYPE_ASSET_PV);
     $resp = $this->_callAccount->get($req);
     $this->assertTrue($resp->isSucceed());
     $actualValue = $resp->getBalance();
     $this->assertEquals($value, $actualValue);
 }
 /**
  * Account PV on sale done.
  *
  * @param Request\AccountPv $request
  *
  * @return Response\AccountPv
  */
 public function accountPv(Request\AccountPv $request)
 {
     $result = new Response\AccountPv();
     $saleId = $request->getSaleOrderId();
     $customerId = $request->getCustomerId();
     $dateApplied = $request->getDateApplied();
     $this->_logger->info("PV accounting operation for sale order #{$saleId} is started.");
     $sale = $this->_repoSale->getById($saleId);
     $pvTotal = $sale->getTotal();
     /* get customer for sale order */
     if (is_null($customerId)) {
         $this->_logger->info("There is no customer ID in request, select customer ID from sale order data.");
         $customerId = $this->_repoMod->getSaleOrderCustomerId($saleId);
         $this->_logger->info("Order #{$saleId} is created by customer #{$customerId}.");
     }
     /* get PV account data for customer */
     $reqGetAccCust = new GetAccountRequest();
     $reqGetAccCust->setCustomerId($customerId);
     $reqGetAccCust->setAssetTypeCode(Cfg::CODE_TYPE_ASSET_PV);
     $reqGetAccCust->setCreateNewAccountIfMissed(true);
     $respGetAccCust = $this->_callAccount->get($reqGetAccCust);
     /* get PV account data for representative */
     $reqGetAccRepres = new GetAccountRepresentativeRequest();
     $reqGetAccRepres->setAssetTypeCode(Cfg::CODE_TYPE_ASSET_PV);
     $respGetAccRepres = $this->_callAccount->getRepresentative($reqGetAccRepres);
     /* create one operation with one transaction */
     $reqAddOper = new AddOperationRequest();
     $reqAddOper->setOperationTypeCode(Cfg::CODE_TYPE_OPER_PV_SALE_PAID);
     $trans = [Transaction::ATTR_DEBIT_ACC_ID => $respGetAccRepres->getId(), Transaction::ATTR_CREDIT_ACC_ID => $respGetAccCust->getId(), Transaction::ATTR_VALUE => $pvTotal, Transaction::ATTR_DATE_APPLIED => $dateApplied];
     $reqAddOper->setTransactions([$trans]);
     $respAddOper = $this->_callOperation->add($reqAddOper);
     $operId = $respAddOper->getOperationId();
     $result->setOperationId($operId);
     $result->markSucceed();
     $this->_logger->info("PV accounting operation for sale order #{$saleId} is completed.");
     return $result;
 }
 public function test_get_createNewAccountIfMissed()
 {
     /** === Test Data === */
     $assetTypeId = '12';
     $custId = '21';
     $accId = '34';
     /** === Setup Mocks === */
     // $data = $this->_repoAccount->getByCustomerId($customerId, $assetTypeId);
     $this->mRepoAccount->shouldReceive('getByCustomerId')->once()->andReturn([]);
     // $accId = $this->_repoAccount->create($data);
     $this->mRepoAccount->shouldReceive('create')->once()->andReturn($accId);
     /** === Call and asserts  === */
     $req = new Request\Get();
     $req->setCustomerId($custId);
     $req->setAssetTypeId($assetTypeId);
     $req->setCreateNewAccountIfMissed(true);
     $resp = $this->obj->get($req);
     $this->assertTrue($resp->isSucceed());
 }
 /**
  * @param Request\GetRepresentative $request
  *
  * @return Response\GetRepresentative
  */
 public function getRepresentative(Request\GetRepresentative $request)
 {
     $result = new Response\GetRepresentative();
     $typeId = $request->getAssetTypeId();
     $typeCode = $request->getAssetTypeCode();
     $this->_logger->info("'Get representative account' operation is called.");
     if (is_null($typeId)) {
         $typeId = $this->_repoTypeAsset->getIdByCode($typeCode);
     }
     if (!is_null($typeId)) {
         if (isset($this->_cachedRepresentAccs[$typeId])) {
             $result->setData($this->_cachedRepresentAccs[$typeId]);
             $result->markSucceed();
         } else {
             /* there is no cached data yet */
             /* get representative customer ID */
             $customerId = $this->_repoAccount->getRepresentativeCustomerId();
             /* get all accounts for the representative customer */
             $accounts = $this->_repoAccount->getAllByCustomerId($customerId);
             if ($accounts) {
                 $mapped = [];
                 foreach ($accounts as $one) {
                     $mapped[$one->getAssetTypeId()] = $one;
                 }
                 $this->_cachedRepresentAccs = $mapped;
             }
             /* check selected accounts */
             if (isset($this->_cachedRepresentAccs[$typeId])) {
                 $result->setData($this->_cachedRepresentAccs[$typeId]);
                 $result->markSucceed();
             } else {
                 /* there is no accounts yet */
                 $req = new Request\Get();
                 $req->setCustomerId($customerId);
                 $req->setAssetTypeId($typeId);
                 $req->setCreateNewAccountIfMissed();
                 $resp = $this->get($req);
                 $accData = $resp->getData();
                 $this->_cachedRepresentAccs[$accData[Account::ATTR_ASSET_TYPE_ID]] = new Account($accData);
                 $result->setData($accData);
                 $result->markSucceed();
             }
         }
     } else {
         $this->_logger->error("Asset type is not defined (asset code: {$typeCode}).");
     }
     if ($result->isSucceed()) {
         $repAccId = $result->getId();
         $this->_logger->info("Representative account #{$repAccId} is found.");
     }
     $this->_logger->info("'Get representative account' operation is completed.");
     return $result;
 }
 public function addToWalletActive(Request\AddToWalletActive $req)
 {
     $result = new Response\AddToWalletActive();
     $dateApplied = $req->getDateApplied();
     $datePerformed = $req->getDatePerformed();
     $operTypeCode = $req->getOperationTypeCode();
     $transData = $req->getTransData();
     $asAmount = $req->getAsAmount();
     $asCustId = $req->getAsCustomerId();
     $asRef = $req->getAsRef();
     $this->_logger->info("'Add to Wallet Active' operation is started.");
     /* prepare additional data */
     $datePerformed = is_null($datePerformed) ? $this->_toolDate->getUtcNowForDb() : $datePerformed;
     $dateApplied = is_null($dateApplied) ? $datePerformed : $dateApplied;
     /* get asset type ID */
     $assetTypeId = $this->_repoMod->getTypeAssetIdByCode(Cfg::CODE_TYPE_ASSET_WALLET_ACTIVE);
     /* get representative customer ID */
     $represAccId = $this->_getRepresentativeAccId($assetTypeId);
     /* save operation */
     $reqOperAdd = new \Praxigento\Accounting\Service\Operation\Request\Add();
     $reqOperAdd->setOperationTypeCode($operTypeCode);
     $reqOperAdd->setDatePerformed($datePerformed);
     $reqOperAdd->setAsTransRef($asRef);
     $trans = [];
     $reqGetAccount = new AccountGetRequest();
     $reqGetAccount->setCreateNewAccountIfMissed();
     $reqGetAccount->setAssetTypeId($assetTypeId);
     foreach ($transData as $item) {
         $custId = $item[$asCustId];
         $value = $item[$asAmount];
         if ($value > 0) {
             /* get WALLET_ACTIVE account ID for customer */
             $reqGetAccount->setCustomerId($custId);
             $respGetAccount = $this->_callAccount->get($reqGetAccount);
             $accId = $respGetAccount->getData(Account::ATTR_ID);
             $one = [Transaction::ATTR_DEBIT_ACC_ID => $represAccId, Transaction::ATTR_CREDIT_ACC_ID => $accId, Transaction::ATTR_DATE_APPLIED => $dateApplied, Transaction::ATTR_VALUE => $value];
             if (!is_null($asRef) && isset($item[$asRef])) {
                 $one[$asRef] = $item[$asRef];
             }
             $trans[] = $one;
             $this->_logger->debug("Transaction ({$value}) for customer #{$custId} (acc #{$accId}) is added to operation with type '{$operTypeCode}'.");
         } else {
             $this->_logger->debug("Transaction for customer #{$custId} is '{$value}'. Transaction is not included in operation with type '{$operTypeCode}'.");
         }
     }
     $reqOperAdd->setTransactions($trans);
     $respOperAdd = $this->_callOper->add($reqOperAdd);
     $operId = $respOperAdd->getOperationId();
     $this->_logger->debug("New operation (type id '{$operTypeCode}') is added with id={$operId} .");
     $result->setData($respOperAdd->getData());
     $result->markSucceed();
     $this->_logger->info("'Add to Wallet Active' operation is completed.");
     return $result;
 }
 public function payForSaleOrder(Request\PayForSaleOrder $req)
 {
     $result = new Response\PayForSaleOrder();
     /* extract request params */
     $custId = $req->getCustomerId();
     $value = $req->getBaseAmountToPay();
     $saleOrderId = $req->getOrderId();
     /* collect data */
     $reqGet = new \Praxigento\Accounting\Service\Account\Request\Get();
     $reqGet->setCustomerId($custId);
     $reqGet->setAssetTypeCode(Cfg::CODE_TYPE_ASSET_WALLET_ACTIVE);
     $reqGet->setCreateNewAccountIfMissed(true);
     $respGet = $this->_callAccount->get($reqGet);
     $accIdDebit = $respGet->getId();
     $assetTypeId = $respGet->getAssetTypeId();
     $reqGetRepres = new \Praxigento\Accounting\Service\Account\Request\GetRepresentative();
     $reqGetRepres->setAssetTypeId($assetTypeId);
     $respGetRepres = $this->_callAccount->getRepresentative($reqGetRepres);
     $accIdCredit = $respGetRepres->getId();
     /* compose transaction data */
     $transaction = new \Praxigento\Accounting\Data\Entity\Transaction();
     $transaction->setDebitAccId($accIdDebit);
     $transaction->setCreditAccId($accIdCredit);
     $transaction->setValue($value);
     /* create operation using service call */
     $reqAddOper = new \Praxigento\Accounting\Service\Operation\Request\Add();
     $reqAddOper->setOperationTypeCode(Cfg::CODE_TYPE_OPER_WALLET_SALE);
     $reqAddOper->setTransactions([$transaction]);
     $reqAddOper->setCustomerId($custId);
     $respAddOper = $this->_callOper->add($reqAddOper);
     $operId = $respAddOper->getOperationId();
     $result->setOperationId($operId);
     //        /* log sale order operation */
     //        $log = new \Praxigento\Wallet\Data\Entity\Log\Sale();
     //        $log->setOperationRef($operId);
     //        $log->setSaleOrderRef($saleOrderId);
     if ($respAddOper->isSucceed()) {
         $result->markSucceed();
     }
     return $result;
 }
 /**
  * @param      $updates array [[Calc::A_CUST_ID, Calc::A_VALUE], ...]
  * @param      $operTypeCode
  * @param null $datePerformed
  * @param null $dateApplied
  *
  * @return \Praxigento\Accounting\Service\Operation\Response\Add
  */
 public function saveOperationWalletActive($updates, $operTypeCode, $datePerformed = null, $dateApplied = null)
 {
     /* prepare additional data */
     $datePerformed = is_null($datePerformed) ? $this->_toolDate->getUtcNowForDb() : $datePerformed;
     $dateApplied = is_null($dateApplied) ? $datePerformed : $dateApplied;
     /* get asset type ID */
     $assetTypeId = $this->_repoTypeAsset->getIdByCode(Cfg::CODE_TYPE_ASSET_WALLET_ACTIVE);
     /* get representative account data */
     $reqAccRepres = new AccountGetRepresentativeRequest();
     $reqAccRepres->setAssetTypeId($assetTypeId);
     $respAccRepres = $this->_callAccount->getRepresentative($reqAccRepres);
     $represAccId = $respAccRepres->getData(Account::ATTR_ID);
     /* save operation */
     $req = new OperationAddRequest();
     $req->setOperationTypeCode($operTypeCode);
     $req->setDatePerformed($datePerformed);
     $trans = [];
     $reqGetAccount = new AccountGetRequest();
     $reqGetAccount->setCreateNewAccountIfMissed();
     $reqGetAccount->setAssetTypeId($assetTypeId);
     foreach ($updates as $item) {
         $customerId = $item[Calc::A_CUST_ID];
         $value = $item[Calc::A_VALUE];
         if ($value > 0) {
             /* get WALLET_ACTIVE account ID for customer */
             $reqGetAccount->setCustomerId($customerId);
             $respGetAccount = $this->_callAccount->get($reqGetAccount);
             $accId = $respGetAccount->getData(Account::ATTR_ID);
             /* skip representative account */
             if ($accId == $represAccId) {
                 continue;
             }
             $trans[] = [Transaction::ATTR_DEBIT_ACC_ID => $represAccId, Transaction::ATTR_CREDIT_ACC_ID => $accId, Transaction::ATTR_DATE_APPLIED => $dateApplied, Transaction::ATTR_VALUE => $value];
             $this->_logger->debug("Transaction ({$value}) for customer #{$customerId} (acc #{$accId}) is added to operation '{$operTypeCode}'.");
         } else {
             $this->_logger->debug("Transaction for customer #{$customerId} is 0.00. Transaction is not included in operation '{$operTypeCode}'.");
         }
     }
     $req->setTransactions($trans);
     $result = $this->_callOper->add($req);
     $operId = $result->getOperationId();
     $this->_logger->debug("New '{$operTypeCode}' operation is added with id={$operId}.");
     return $result;
 }
 private function _createAccounts()
 {
     /* create account for Customer 1 */
     $custId = $this->_mapCustomerMageIdByIndex[1];
     $req = new AccountGetRequest();
     $req->setData(AccountGetRequest::CUSTOMER_ID, $custId);
     $req->setData(AccountGetRequest::ASSET_TYPE_ID, $this->typeAssetId);
     $req->setData(AccountGetRequest::CREATE_NEW_ACCOUNT_IF_MISSED, true);
     $resp = $this->_callAccount->get($req);
     $this->assertTrue($resp->isSucceed());
     $this->acc1 = $resp->getData();
     /* create account for Customer 2 */
     $custId = $this->_mapCustomerMageIdByIndex[2];
     $req->setData(AccountGetRequest::CUSTOMER_ID, $custId);
     $resp = $this->_callAccount->get($req);
     $this->assertTrue($resp->isSucceed());
     $this->acc2 = $resp->getData();
     $accFirstId = $this->acc1[Account::ATTR_ID];
     $accSecondId = $this->acc2[Account::ATTR_ID];
     $this->_logger->debug("2 customer accounts are created (#{$accFirstId}, #{$accSecondId}).");
 }