public function test_calc()
 {
     /** === Test Data === */
     $CUST_1 = 1;
     $PARENT_1 = 101;
     $ORDR_1 = 10;
     $PV_1 = 100;
     $RANK_1 = 2;
     $PERCENT_1 = 0.01;
     $BONUS_1 = 'bonus';
     $TREE = 'tree';
     $TREE_EXP = [$CUST_1 => [Snap::ATTR_PATH => 'path1']];
     $MAP_RANKS = [$PARENT_1 => $RANK_1];
     $ORDERS = [[Cfg::E_SALE_ORDER_A_CUSTOMER_ID => $CUST_1, PvSale::ATTR_SALE_ID => $ORDR_1, PvSale::ATTR_TOTAL => $PV_1]];
     $PARAMS = [];
     $PERCENTS = [$RANK_1 => [1 => $PERCENT_1]];
     $PARENTS = [$PARENT_1];
     /** === Setup Mocks === */
     // $mapTreeExp = $this->_expandTree($tree);
     // $resp = $this->_callDownlineSnap->expandMinimal($req);
     $this->mCallDownlineSnap->shouldReceive('expandMinimal')->once()->andReturn(new DataObject(['SnapData' => $TREE_EXP]));
     // $mapRankById = $this->_rankQualifier->qualifyCustomers($tree, $params);
     $this->mRankQualifier->shouldReceive('qualifyCustomers')->once()->andReturn($MAP_RANKS);
     // $parents = $this->_toolDownlineTree->getParentsFromPathReversed($path);
     $this->mToolDownlineTree->shouldReceive('getParentsFromPathReversed')->once()->andReturn($PARENTS);
     // $bonus = $this->_toolFormat->roundBonus($bonus);
     $this->mToolFormat->shouldReceive('roundBonus')->once()->with($PV_1 * $PERCENT_1)->andReturn($BONUS_1);
     /** === Call and asserts  === */
     $resp = $this->sub->calc($TREE, $ORDERS, $PARAMS, $PERCENTS);
     $this->assertEquals($BONUS_1, $resp[$PARENT_1][$ORDR_1]);
 }
 /**
  * @param Request\Bonus $req
  *
  * @return Response\Bonus
  */
 public function bonus(Request\Bonus $req)
 {
     $result = new Response\Bonus();
     $datePerformed = $req->getDatePerformed();
     $dateApplied = $req->getDateApplied();
     $this->_logger->info("'Loyalty Bonus' calculation is started. Performed at: {$datePerformed}, applied at: {$dateApplied}.");
     $reqGetPeriod = new PeriodGetForDependentCalcRequest();
     $calcTypeBase = Cfg::CODE_TYPE_CALC_QUALIFICATION;
     $calcType = Cfg::CODE_TYPE_CALC_BONUS;
     $reqGetPeriod->setBaseCalcTypeCode($calcTypeBase);
     $reqGetPeriod->setDependentCalcTypeCode($calcType);
     $respGetPeriod = $this->_callBasePeriod->getForDependentCalc($reqGetPeriod);
     if ($respGetPeriod->isSucceed()) {
         $def = $this->_manTrans->begin();
         try {
             $periodDataDepend = $respGetPeriod->getDependentPeriodData();
             $calcDataDepend = $respGetPeriod->getDependentCalcData();
             $calcIdDepend = $calcDataDepend->getId();
             $dsBegin = $periodDataDepend->getDstampBegin();
             $dsEnd = $periodDataDepend->getDstampEnd();
             /* collect data to process bonus */
             $calcTypeIdCompress = $this->_repoBonusTypeCalc->getIdByCode(Cfg::CODE_TYPE_CALC_COMPRESSION);
             $calcDataCompress = $this->_repoBonusService->getLastCalcForPeriodByDates($calcTypeIdCompress, $dsBegin, $dsEnd);
             $calcIdCompress = $calcDataCompress->getId();
             $params = $this->_repoMod->getConfigParams();
             $percents = $this->_repoMod->getBonusPercents();
             $treeCompressed = $this->_repoMod->getCompressedTreeWithQualifications($calcIdCompress);
             $orders = $this->_repoMod->getSalesOrdersForPeriod($dsBegin, $dsEnd);
             /* calculate bonus */
             $updates = $this->_subBonus->calc($treeCompressed, $orders, $params, $percents);
             /* create new operation with bonus transactions and save sales log */
             $respAdd = $this->_createBonusOperation($updates);
             $transLog = $respAdd->getTransactionsIds();
             $this->_repoMod->saveLogSaleOrders($transLog);
             /* mark calculation as completed and finalize bonus */
             $this->_repoBonusService->markCalcComplete($calcIdDepend);
             $this->_manTrans->commit($def);
             $result->setPeriodId($periodDataDepend->getId());
             $result->setCalcId($calcIdDepend);
             $result->markSucceed();
         } finally {
             $this->_manTrans->end($def);
         }
     }
     $this->_logger->info("'Loyalty Bonus' calculation is complete.");
     return $result;
 }