/**
  * @param Request\BonusOverride $request
  *
  * @return Response\BonusOverride
  */
 public function bonusOverride(Request\BonusOverride $request)
 {
     $result = new Response\BonusOverride();
     $scheme = $this->_getCalculationsScheme($request->getScheme());
     $datePerformed = $request->getDatePerformed();
     $dateApplied = $request->getDateApplied();
     $this->_logger->info("'Override Bonus' calculation is started ({$scheme} scheme).");
     if ($scheme == Def::SCHEMA_EU) {
         $calcTypeBase = Cfg::CODE_TYPE_CALC_COMPRESS_FOR_OI_EU;
         $calcType = Cfg::CODE_TYPE_CALC_BONUS_OVERRIDE_EU;
     } else {
         $calcTypeBase = Cfg::CODE_TYPE_CALC_COMPRESS_FOR_OI_DEF;
         $calcType = Cfg::CODE_TYPE_CALC_BONUS_OVERRIDE_DEF;
     }
     $reqGetPeriod = new PeriodGetForDependentCalcRequest();
     $reqGetPeriod->setBaseCalcTypeCode($calcTypeBase);
     $reqGetPeriod->setDependentCalcTypeCode($calcType);
     $respGetPeriod = $this->_callPeriod->getForDependentCalc($reqGetPeriod);
     if ($respGetPeriod->isSucceed()) {
         $def = $this->_manTrans->begin();
         try {
             /* working vars */
             $thisPeriodData = $respGetPeriod->getDependentPeriodData();
             $thisPeriodId = $thisPeriodData[Period::ATTR_ID];
             $thisCalcData = $respGetPeriod->getDependentCalcData();
             $thisCalcId = $thisCalcData[Calculation::ATTR_ID];
             $basePeriodData = $respGetPeriod->getBasePeriodData();
             $baseDsBegin = $basePeriodData->getDstampBegin();
             $baseDsEnd = $basePeriodData->getDstampEnd();
             $baseCalcData = $respGetPeriod->getBaseCalcData();
             $baseCalcId = $baseCalcData->getId();
             /* calculation itself */
             $this->_logger->info("Processing period #{$thisPeriodId} ({$baseDsBegin}-{$baseDsEnd})");
             /* get compressed data by calculation ID */
             $compressOi = $this->_subDb->getCompressedOiData($baseCalcId);
             /* get configuration for Override and Infinity bonuses */
             $cfgOverride = $this->_subDb->getCfgOverride();
             /* calculates bonus and save operation with transactions */
             $updates = $this->_subCalc->bonusOverride($compressOi, $scheme, $cfgOverride);
             /* prepare data for updates */
             $updatesForWallets = [];
             foreach ($updates as $item) {
                 $custId = $item[Calc::A_CUST_ID];
                 $bonusData = $item[Calc::A_ENTRIES];
                 foreach ($bonusData as $entry) {
                     $bonus = $entry[Calc::A_VALUE];
                     $childId = $entry[Calc::A_OTHER_ID];
                     if ($bonus > Cfg::DEF_ZERO) {
                         $updatesForWallets[] = [Calc::A_CUST_ID => $custId, Calc::A_VALUE => $bonus, Calc::A_OTHER_ID => $childId];
                     }
                 }
             }
             unset($updates);
             /* update wallets */
             $respAdd = $this->_subDb->saveOperationWalletActive($updatesForWallets, Cfg::CODE_TYPE_OPER_BONUS_OVERRIDE, $datePerformed, $dateApplied);
             $operId = $respAdd->getOperationId();
             $transIds = $respAdd->getTransactionsIds();
             /* save orders and correspondent transactions into the log */
             $this->_subDb->saveLogCustomers($updatesForWallets, $transIds);
             unset($updatesForWallets);
             /* save processed operation to calculations log and mark calculation as complete */
             $this->_subDb->saveLogOperations($operId, $thisCalcId);
             $this->_subDb->markCalcComplete($thisCalcId);
             /* finalize response as succeed */
             $this->_manTrans->commit($def);
             $result->markSucceed();
             $result->setPeriodId($thisPeriodId);
             $result->setCalcId($thisCalcId);
         } finally {
             $this->_manTrans->end($def);
         }
     }
     $this->_logMemoryUsage();
     $this->_logger->info("'Override Bonus' calculation is completed.");
     return $result;
 }
 public function test_bonusOverride()
 {
     /** === Test Data === */
     $COMPRESSED_OI = [[OiCompress::ATTR_CUSTOMER_ID => 1, Customer::ATTR_HUMAN_REF => 'ref01', OiCompress::ATTR_PARENT_ID => 1, OiCompress::ATTR_RANK_ID => 1, OiCompress::ATTR_PV => 100, Customer::ATTR_COUNTRY_CODE => 'LV'], [OiCompress::ATTR_CUSTOMER_ID => 2, Customer::ATTR_HUMAN_REF => 'ref02', OiCompress::ATTR_PARENT_ID => 1, OiCompress::ATTR_RANK_ID => 2, OiCompress::ATTR_PV => 100, Customer::ATTR_COUNTRY_CODE => 'LV']];
     /** === Mocks === */
     $mLogger = $this->_mockLogger();
     $mToolFormat = new \Praxigento\Core\Tool\IFormat();
     $mToolScheme = $this->_mockFor('\\Praxigento\\Bonus\\Hybrid\\Lib\\Tool\\IScheme');
     $mToolDownlineTree = new \Praxigento\Downline\Tool\Def\Tree();
     $mToolbox = $this->_mockToolbox(null, null, $mToolFormat, null, $mToolScheme, $mToolDownlineTree);
     $mCallDownlineSnap = $this->_mockFor('\\Praxigento\\Downline\\Service\\ISnap');
     // $mapTreeExp = $this->_getExpandedTreeSnap(
     // $respExt = $this->_callDownlineSnap->expandMinimal($reqExt);
     $mRespExt = new DataObject();
     $mCallDownlineSnap->expects($this->once())->method('expandMinimal')->willReturn($mRespExt);
     // $result = $respExt->getSnapData();
     $mRespExt->setSnapData([]);
     // $scheme = $this->_toolScheme->getSchemeByCustomer($one);
     $mToolScheme->expects($this->any())->method('getSchemeByCustomer')->willReturn(Def::SCHEMA_DEFAULT);
     /**
      * Prepare request and perform call.
      */
     /** @var  $sub Calc */
     $sub = new Calc($mLogger, $mToolbox, $mCallDownlineSnap);
     $res = $sub->bonusOverride($COMPRESSED_OI, Def::SCHEMA_DEFAULT, $this->CFG_OVERRIDE);
     $this->assertTrue(is_array($res));
 }