public function bonusCourtesy(Request\BonusCourtesy $request)
 {
     $result = new Response\BonusCourtesy();
     $courtesyPercent = $request->getCourtesyBonusPercent();
     $datePerformed = $request->getDatePerformed();
     $dateApplied = $request->getDateApplied();
     $this->_logger->info("'Courtesy Bonus' calculation is started.");
     $reqGetPeriod = new PeriodGetForDependentCalcRequest();
     $reqGetPeriod->setBaseCalcTypeCode(Cfg::CODE_TYPE_CALC_VALUE_TV);
     $reqGetPeriod->setDependentCalcTypeCode(Cfg::CODE_TYPE_CALC_BONUS_COURTESY);
     $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();
             /* get PTC Compression calculation ID for this period */
             $ptcCompressCalcId = $this->_subDb->getLastCalculationIdForPeriod(Cfg::CODE_TYPE_CALC_COMPRESS_FOR_PTC, $baseDsBegin, $baseDsEnd);
             /* calculation itself */
             $this->_logger->info("Processing period #{$thisPeriodId} ({$baseDsBegin}-{$baseDsEnd})");
             /* get compressed data by calculation ID */
             $compressPtc = $this->_subDb->getCompressedPtcData($ptcCompressCalcId);
             /* get levels to calculate Personal and Team bonuses */
             $levelsPersonal = $this->_subDb->getBonusLevels(Cfg::CODE_TYPE_CALC_BONUS_PERSONAL_DEF);
             $levelsTeam = $this->_subDb->getBonusLevels(Cfg::CODE_TYPE_CALC_BONUS_TEAM_DEF);
             /* calculates bonus and save operation with transactions */
             $updates = $this->_subCalc->bonusCourtesy($compressPtc, $courtesyPercent, $levelsPersonal, $levelsTeam);
             /* prepare data for updates */
             $updatesForWallets = [];
             foreach ($updates as $custId => $items) {
                 foreach ($items as $item) {
                     $bonus = $item[Calc::A_VALUE];
                     $childId = $item[Calc::A_OTHER_ID];
                     if ($bonus > Cfg::DEF_ZERO) {
                         $updatesForWallets[] = [Calc::A_CUST_ID => $custId, Calc::A_VALUE => $bonus, Calc::A_OTHER_ID => $childId];
                     }
                 }
             }
             $respAdd = $this->_subDb->saveOperationWalletActive($updatesForWallets, Cfg::CODE_TYPE_OPER_BONUS_COURTESY, $datePerformed, $dateApplied);
             $operId = $respAdd->getOperationId();
             $transIds = $respAdd->getTransactionsIds();
             /* save orders and correspondent transactions into the log */
             $this->_subDb->saveLogCustomers($updatesForWallets, $transIds);
             /* 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("'Courtesy Bonus' calculation is completed.");
     return $result;
 }