/**
  * 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;
 }
 public function change(Request\Change $request)
 {
     $result = new Response\Reset();
     $accCustId = $request->getCustomerAccountId();
     $adminUserId = $request->getAdminUserId();
     $value = $request->getChangeValue();
     $def = $this->_manTrans->begin();
     try {
         /* get account's asset type by ID */
         $assetTypeId = $this->_repoAccount->getAssetTypeId($accCustId);
         /* get representative account id for given asset type */
         $accRepresId = $this->_repoMod->getRepresentativeAccountId($assetTypeId);
         /* get operation type by code and date performed */
         $operTypeId = $this->_repoTypeOper->getIdByCode(Cfg::CODE_TYPE_OPER_CHANGE_BALANCE);
         $dateNow = $this->_toolDate->getUtcNowForDb();
         /* create operation */
         $operation = new \Praxigento\Accounting\Data\Entity\Operation();
         $operation->setTypeId($operTypeId);
         $operation->setDatePerformed($dateNow);
         $operId = $this->_repoOperation->create($operation);
         /* create transaction */
         $trans = new \Praxigento\Accounting\Data\Entity\Transaction();
         $trans->setOperationId($operId);
         $trans->setDateApplied($dateNow);
         if ($value > 0) {
             $trans->setDebitAccId($accRepresId);
             $trans->setCreditAccId($accCustId);
         } else {
             $trans->setDebitAccId($accCustId);
             $trans->setCreditAccId($accRepresId);
         }
         $trans->setValue(abs($value));
         $this->_repoTransaction->create($trans);
         /* log details (operator name who performs the operation) */
         $log = new ELogChangeAdmin();
         $log->setOperationRef($operId);
         $log->setUserRef($adminUserId);
         $this->_repoLogChangeAdmin->create($log);
         $this->_manTrans->commit($def);
         $result->markSucceed();
     } finally {
         $this->_manTrans->end($def);
     }
     return $result;
 }
 public function getDataForWriteOff($calcId, $tsFrom, $tsTo)
 {
     /* aliases and tables */
     $asOper = 'pao';
     $asTrans = 'pat';
     $asAcc = 'paa';
     $asLog = 'pbblo';
     $tblOper = $this->_resource->getTableName(Operation::ENTITY_NAME);
     $tblTrans = $this->_resource->getTableName(Transaction::ENTITY_NAME);
     $tblAcc = $this->_resource->getTableName(Account::ENTITY_NAME);
     $tblLog = $this->_resource->getTableName(LogOpers::ENTITY_NAME);
     /* IDs for codes */
     $assetId = $this->_repoTypeAsset->getIdByCode(Cfg::CODE_TYPE_ASSET_PV);
     $operPvWriteOffId = $this->_repoTypeOper->getIdByCode(Cfg::CODE_TYPE_OPER_PV_WRITE_OFF);
     // SELECT FROM prxgt_acc_operation
     $query = $this->_conn->select();
     $cols = [Operation::ATTR_ID];
     $query->from([$asOper => $tblOper], $cols);
     // LEFT JOIN prxgt_acc_transaction pat ON pao.id = pat.operation_id
     $on = "{$asOper}." . Operation::ATTR_ID . "={$asTrans}." . Transaction::ATTR_OPERATION_ID;
     $cols = [Transaction::ATTR_DEBIT_ACC_ID, Transaction::ATTR_CREDIT_ACC_ID, Transaction::ATTR_VALUE];
     $query->joinLeft([$asTrans => $tblTrans], $on, $cols);
     // LEFT JOIN prxgt_acc_account paa ON pat.debit_acc_id = paa.id
     $on = "{$asTrans}." . Transaction::ATTR_DEBIT_ACC_ID . "={$asAcc}." . Account::ATTR_ID;
     $query->joinLeft([$asAcc => $tblAcc], $on, null);
     // LEFT JOIN prxgt_bon_base_log_opers pbblo ON pao.id = pbblo.oper_id
     $on = "{$asOper}." . Operation::ATTR_ID . "={$asLog}." . LogOpers::ATTR_OPER_ID;
     $query->joinLeft([$asLog => $tblLog], $on, null);
     // where
     $whereByAssetType = "{$asAcc}." . Account::ATTR_ASSET_TYPE_ID . "={$assetId}";
     $whereDateFrom = "{$asTrans}." . Transaction::ATTR_DATE_APPLIED . ">=" . $this->_conn->quote($tsFrom);
     $whereDateTo = "{$asTrans}." . Transaction::ATTR_DATE_APPLIED . "<=" . $this->_conn->quote($tsTo);
     $whereByOperType = "{$asOper}." . Operation::ATTR_TYPE_ID . "<>{$operPvWriteOffId}";
     $whereByCalcId = "({$asLog}." . LogOpers::ATTR_CALC_ID . " IS NULL OR {$asLog}." . LogOpers::ATTR_CALC_ID . "<>{$calcId})";
     $query->where("{$whereByAssetType} AND {$whereDateFrom} AND {$whereDateTo} AND {$whereByOperType} AND {$whereByCalcId}");
     // $sql = (string)$query;
     $result = $this->_conn->fetchAll($query);
     return $result;
 }