/** * @return bool * @throws \Exception */ public function process() { /** * @var Expenses $expenseDao */ $expenseDao = $this->getServiceLocator()->get('dao_finance_expense_expenses'); $expenseDao->setEntity(new \ArrayObject()); $finance = new Finance($this->getServiceLocator()); $expenseList = $this->getExpenses(); if (!count($expenseList)) { throw new \Exception('No expense attached.'); } $transactionIdList = parent::processGeneralTransaction(); if (count($transactionIdList) > 1) { throw new \RuntimeException('It is impossible to store more than one transaction id for expense transaction.'); } else { $moneyTransactionId = array_shift($transactionIdList); } foreach ($expenseList as $expense) { $expenseData = $expenseDao->fetchOne(['id' => $expense['id']]); $expenseTicket = $finance->getExpense($expense['id']); $expenseTicket->prepare($this->getExpenseTicketData($expenseData, $expense['amount'])); $expenseTicket->addTransaction($this->getTransactionData($moneyTransactionId, $expense['amount'])); $expenseTicket->save(); } // Set as verified transaction $this->changeVerifyStatus($moneyTransactionId, self::IS_VERIFIED); return $moneyTransactionId; }
/** * @return bool */ public function process() { $dao = $this->getDao(); if (is_null($this->getMoneyTransactionId())) { $transactionIdList = parent::processGeneralTransaction(); } else { $transactionIdList = [$this->getMoneyTransactionId()]; } $moneyTransactionId = count($transactionIdList) ? $transactionIdList[0] : null; $dao->save(['money_transaction_id_1' => array_shift($transactionIdList), 'money_transaction_id_2' => array_shift($transactionIdList), 'creator_id' => $this->getUserId(), 'account_id_from' => $this->getAccountFrom()->getTransactionAccountId(), 'account_id_to' => $this->getAccountTo()->getTransactionAccountId(), 'transaction_date_from' => $this->getTransactionDateFrom(), 'transaction_date_to' => $this->getTransactionDateTo(), 'amount_from' => $this->getAccountFrom()->getAmount(), 'amount_to' => $this->getAccountTo()->getAmount(), 'description' => $this->getDescription(), 'creation_date' => $this->getCreationDate()]); $moneyAccountTypesThatNeedsToBeNotifiedOnTransfer = [MoneyAccount::TYPE_DEBIT_CARD, MoneyAccount::TYPE_PERSON, MoneyAccount::TYPE_CREDIT_CARD]; $accountTo = $this->getAccountTo(); if (in_array($accountTo->getAccount()['type'], $moneyAccountTypesThatNeedsToBeNotifiedOnTransfer)) { /** * @var Notifications $notificationsService * @var Currency $currencyService */ $notificationsService = $this->getServiceLocator()->get('service_notifications'); $currencyService = $this->getServiceLocator()->get('service_currency_currency'); $amountToCurrencyIsoCode = $currencyService->getCurrencyIsoCode($accountTo->getCurrency()); $messageTemplate = 'A new transfer has just been made to account %s you\'re possessing. ' . 'Transfer amount: %s %s. ' . 'You will receive this amount on %s'; $message = sprintf($messageTemplate, $accountTo->getAccount()['name'], $accountTo->getAmount(), $amountToCurrencyIsoCode, $this->getTransactionDateTo()); $notificationData = ['recipient' => $accountTo->getPossessorId(), 'sender' => Notifications::$transfer, 'message' => $message]; $notificationsService->createNotification($notificationData); } $this->setMinorTransferId($dao->lastInsertValue); return $moneyTransactionId; }
/** * @param Ticket $expenseTicket * @return bool|void * @throws \Exception */ public function save(Ticket $expenseTicket) { /** * @var Transactor\Expense $transaction */ if (!$this->finance instanceof Finance) { throw new \Exception('Finance not defined for expense transaction.'); } $transactionData = $this->getData(); $transaction = new Transactor\Expense(GeneralTransaction::ACCOUNT_MONEY_ACCOUNT, GeneralTransaction::getAccountTypeById($transactionData['accountTo']['type'])); $transaction->setServiceLocator($expenseTicket->getServiceLocator()); $transaction->setMode($this->getMode()); switch ($this->getMode()) { case self::MODE_ADD: $transaction->setAccountIdentity($transactionData['accountFrom']['id'], $transactionData['accountTo']['id']); $transaction->setIsRefund(isset($transactionData['isRefund']) ? $transactionData['isRefund'] : 0); $transaction->setTransactionAccountId($transactionData['accountTo']['transactionAccountId']); $transaction->setTransactionDate(isset($transactionData['date']) ? $transactionData['date'] : date('Y-m-d H:i:s')); $transaction->setDescription("Expense Transaction #{$expenseTicket->getExpenseId()}"); $transaction->setExpenseId($expenseTicket->getExpenseId()); $transaction->setAmount($transactionData['amount']); // If transaction is virtual it shouldn't have money_transaction_id if ($this->getMoneyTransactionId() !== false) { $transaction->setIsVirtual(); $transaction->setMoneyTransactionId($this->getMoneyTransactionId()); } $transaction->prepare(); break; case self::MODE_EDIT: $isVerified = $transactionData['isVerified']; $isVoided = $transactionData['isVoided']; if (!$isVerified && !$isVoided) { throw new \RuntimeException('Impossible to modify transaction.'); } $transaction->setTransactionId($this->getId()); if ($isVerified) { $transaction->setIsVerified(); $transaction->setVerifierId($expenseTicket->getCreatorId()); } if ($isVoided) { $transaction->setIsVoid(); $transaction->setVerifierId($expenseTicket->getCreatorId()); } $transaction->prepare(); break; case self::MODE_DELETE: throw new \RuntimeException('Impossible to delete transaction.'); break; } return $transaction->process(); }
/** * @return bool */ public function process() { $dao = $this->getDao(); $transactionIdList = parent::processGeneralTransaction(); if (count($transactionIdList) > 1) { throw new \RuntimeException('It is impossible to store more than one transaction id for expense transaction.'); } else { // Why array_shift is used because it returns first element of array or null if array is empty $moneyTransactionId = array_shift($transactionIdList); } $dao->save(['money_transaction_id' => $moneyTransactionId], ['id' => $this->getTransactorId()]); $this->setMinorTransferId($dao->lastInsertValue); return $moneyTransactionId; }
/** * @return bool * @throws \Exception */ public function process() { /** * @var ChargeTransaction $reservationTransactionDao */ $reservationTransactionDao = $this->getDao(); $virtualTransactionIdList = $this->getTransactions(); if (!count($virtualTransactionIdList)) { throw new \Exception('No transactions attached.'); } $transactionIdList = parent::processGeneralTransaction(); if (count($transactionIdList) > 1) { throw new \RuntimeException('It is impossible to store more than one transaction id for reservation transaction.'); } else { $moneyTransactionId = array_shift($transactionIdList); } foreach ($virtualTransactionIdList as $virtualTransactionId) { $reservationTransactionDao->save(['money_transaction_id' => $moneyTransactionId], ['id' => $virtualTransactionId]); } return $moneyTransactionId; }
/** * @return bool */ public function process() { // Prepare data and do relevant changes for transaction $this->preGeneralTransaction(); // General transaction (Money Transaction) should be created only for non virtual expense transactions otherwise // money transaction already exists and there is no need to create it twice if (!$this->getIsVirtual()) { // Process money transaction if ($this->getIsRefund()) { $this->getAccountTo()->forgetDirection(); } $transactionIdList = parent::processGeneralTransaction($this->getMoneyTransactionId(), $this->moneyTransactionData); if (count($transactionIdList) > 1) { throw new \RuntimeException('It is impossible to store more than one transaction id for expense transaction.'); } else { $this->setMoneyTransactionId(array_shift($transactionIdList)); } } // Finish expense transaction return $this->postGeneralTransaction(); }
/** * @todo: Put all into callback * * @return bool * @throws \Exception */ public function process() { /** * @var \DDD\Dao\Booking\Booking $bookingDao * @var \DDD\Dao\Booking\ChargeTransaction $bankTransactionDao * @var \Library\Authentication\BackofficeAuthenticationService $authenticationService * @var \DDD\Service\Booking\BookingTicket $bookingTicketService * @var \DDD\Dao\Currency\Currency $currencyDao * @var BookingTicket $bookingTicket * @var \DDD\Domain\Currency\Currency $currencyDomain * @var Logger $logger */ $authenticationService = $this->getServiceLocator()->get('library_backoffice_auth'); $bookingTicketService = $this->getServiceLocator()->get('service_booking_booking_ticket'); $currencyDao = $this->getServiceLocator()->get('dao_currency_currency'); $bookingDao = $this->getServiceLocator()->get('dao_booking_booking'); $logger = $this->getServiceLocator()->get('ActionLogger'); $currencyUtility = new Currency($currencyDao); $dao = $this->getDao(); $transactionIdList = parent::processGeneralTransaction(); if (count($transactionIdList) > 1) { throw new \RuntimeException('It is impossible to store more than one transaction id for expense transaction.'); } else { $moneyTransactionId = array_shift($transactionIdList); } $totalAmount = abs($this->getAccountTo()->getAmount()); $bankCurrency = $this->getAccountTo()->getCurrency(); $currencyDomain = $currencyDao->fetchOne(['id' => $bankCurrency]); $bankCurrencyCode = $currencyDomain->getCode(); if (count($this->getReservations())) { foreach ($this->getReservations() as $reservationId) { $bookingDao->setEntity(new BookingTicket()); $bookingTicket = $bookingDao->fetchOne(['id' => $reservationId]); if (!$bookingTicket) { throw new \Exception('Undefined reservation number.'); } $resNumber = $bookingTicket->getReservationNumber(); $bankAccountDetails = ['currency_rate' => null]; if (!$bankAccountDetails) { throw new \Exception("Problem during requested operation for R# {$resNumber} Partner bank account does not set for this apartment"); } $balances = $bookingTicketService->getSumAndBalanc($bookingTicket->getId()); $partnerBalanceInApartmentCurrency = $balances['partnerBalanceInApartmentCurrency']; $partnerBalanceInCustomerCurrency = $balances['partnerBalanceInCustomerCurrency']; // definitions $accAmount = abs($partnerBalanceInApartmentCurrency); $reservationData = ['partner_settled' => 1, 'partner_balance' => 0]; if ($totalAmount > 0) { if ($bookingTicket->getApartmentCurrencyCode() == $bankCurrencyCode) { if ($accAmount <= $totalAmount) { $bankAmount = $accAmount; $totalAmount -= $accAmount; } else { $reservationData['partner_balance'] = $accAmount - $totalAmount; $bankAmount = $totalAmount; $accAmount = $totalAmount; $totalAmount = 0; } } else { $bankAmount = $currencyUtility->convert($accAmount, $bookingTicket->getApartmentCurrencyCode(), $bankCurrencyCode); if ($bankAmount <= $totalAmount) { $totalAmount -= $bankAmount; } else { $bankAmount = $totalAmount; $accConvertedAmount = $currencyUtility->convert($totalAmount, $bankCurrencyCode, $bookingTicket->getApartmentCurrencyCode()); // In case of partly payment, partner balance cannot be equal to zero $reservationData['partner_balance'] = $accAmount - $accConvertedAmount; $accAmount = $accConvertedAmount; $totalAmount = 0; } } } else { $bankAmount = 0; } $dao->save(['money_transaction_id' => $moneyTransactionId, 'reservation_id' => $bookingTicket->getId(), 'user_id' => $authenticationService->getIdentity()->id, 'date' => date('Y-m-d H:i:s'), 'cache_user' => 0, 'type' => BankTransaction::BANK_TRANSACTION_TYPE_COLLECT, 'status' => BankTransaction::BANK_TRANSACTION_STATUS_APPROVED, 'money_direction' => BankTransaction::TRANSACTION_MONEY_DIRECTION_PARTNER_COLLECT, 'money_account_currency' => $bankCurrencyCode, 'money_account_id' => $this->getAccountTo()->getAccountId(), 'bank_rate' => null, 'bank_amount' => $bankAmount, 'acc_amount' => $accAmount, 'apartment_id' => $bookingTicket->getApartmentIdAssigned(), 'customer_amount' => -1 * $partnerBalanceInCustomerCurrency, 'comment' => "Automatic partner transaction was created after marking ticket as \"Partner Settled\".\n Based on bank transaction of {$this->getAccountTo()->getAmount()} amount."]); // It is inessention here, but let it be $this->setMinorTransferId($dao->lastInsertValue); $bookingDao->update($reservationData, ['id' => $reservationId]); $logger->save(Logger::MODULE_BOOKING, $bookingTicket->getId(), Logger::ACTION_PARTNER_SETTLED); } } return $moneyTransactionId; }
/** * Understand transaction possibility. * * @param string $method * @param array $arguments * * @return bool * @throws \InvalidArgumentException * @throws \BadMethodCallException */ public function __call($method, $arguments) { if (count($arguments) > 1) { if (strpos($method, 'is') === 0) { $accountFromTo = substr($method, 2); if (strpos($accountFromTo, 'To')) { list($accountFrom, $accountTo) = explode('To', $accountFromTo); $availableAccounts = Transaction::getAvailableAccounts(); if (in_array($accountFrom, $availableAccounts) && in_array($accountTo, $availableAccounts)) { $needleFrom = $arguments[0]; $needleTo = $arguments[1]; return $accountFrom == $needleFrom && $accountTo == $needleTo; } } } throw new \BadMethodCallException('Method not defined.'); } else { throw new \InvalidArgumentException('Required argument is missing.'); } }
/** * @return int Money Transaction Id * @throws \Exception */ public function process() { /** * @var \DDD\Dao\Booking\Booking $bookingDao * @var \DDD\Dao\Booking\ChargeTransaction $bankTransactionDao * @var \Library\Authentication\BackofficeAuthenticationService $authenticationService * @var \DDD\Service\Booking\BookingTicket $bookingTicketService * @var \DDD\Domain\Booking\BookingTicket $bookingTicket * @var \DDD\Dao\Currency\Currency $currencyDao * @var Logger $logger */ $authenticationService = $this->getServiceLocator()->get('library_backoffice_auth'); $bookingTicketService = $this->getServiceLocator()->get('service_booking_booking_ticket'); $bankTransactionDao = $this->getServiceLocator()->get('dao_booking_change_transaction'); $currencyDao = $this->getServiceLocator()->get('dao_currency_currency'); $bookingDao = $this->getServiceLocator()->get('dao_booking_booking'); $logger = $this->getServiceLocator()->get('ActionLogger'); $currencyUtility = new Currency($currencyDao); $transactionIdList = parent::processGeneralTransaction(); if (count($transactionIdList) > 1) { throw new \RuntimeException('It is impossible to store more than one transaction id for expense and/or reservation transaction.'); } else { $moneyTransactionId = array_shift($transactionIdList); } $totalAmount = abs($this->getAccountFrom()->getAmount()); $bankCurrency = $this->getAccountFrom()->getCurrency(); $currencyDomain = $currencyDao->fetchOne(['id' => $bankCurrency]); $bankCurrencyCode = $currencyDomain->getCode(); // For partner payment operation, expense should be created automatically based on existing data $expenseId = $this->createExpense($moneyTransactionId); // Set as verified transaction $this->changeVerifyStatus($moneyTransactionId, self::IS_VERIFIED); if (count($this->getReservations())) { foreach ($this->getReservations() as $reservationId) { $bookingDao->setEntity(new \DDD\Domain\Booking\BookingTicket()); $bookingTicket = $bookingDao->fetchOne(['id' => $reservationId]); if ($bookingTicket) { $balances = $bookingTicketService->getSumAndBalanc($bookingTicket->getId()); $partnerBalanceInApartmentCurrency = $balances['partnerBalanceInApartmentCurrency']; $partnerBalanceInCustomerCurrency = $balances['partnerBalanceInCustomerCurrency']; // definitions $apartmentId = $bookingTicket->getApartmentIdAssigned(); $accAmount = $partnerBalanceInApartmentCurrency; $reservationDescriptionSuffix = ''; $reservationData = ['partner_settled' => 1]; if ($totalAmount > 0) { // In case when everything ok, partner balance must be equal to zero $reservationData['partner_balance'] = 0; if ($bookingTicket->getApartmentCurrencyCode() == $bankCurrencyCode) { if ($accAmount <= $totalAmount) { $bankAmount = $accAmount; $totalAmount -= $accAmount; } else { $reservationData['partner_balance'] = $accAmount - $totalAmount; $bankAmount = $totalAmount; $accAmount = $totalAmount; $totalAmount = 0; } } else { $bankAmount = $currencyUtility->convert($accAmount, $bookingTicket->getApartmentCurrencyCode(), $bankCurrencyCode); if ($bankAmount <= $totalAmount) { $totalAmount -= $bankAmount; } else { $bankAmount = $totalAmount; $accConvertedAmount = $currencyUtility->convert($totalAmount, $bankCurrencyCode, $bookingTicket->getApartmentCurrencyCode()); // In case of partly payment, partner balance cannot be equal to zero $reservationData['partner_balance'] = $accAmount - $accConvertedAmount; $accAmount = $accConvertedAmount; $totalAmount = 0; } } } else { $reservationDescriptionSuffix = ' 0 amount of reservation means that general transaction\'s reservations is covering this reservation.'; $bankAmount = 0; } // Create transaction $bankTransactionDao->save(['money_transaction_id' => $moneyTransactionId, 'reservation_id' => $bookingTicket->getId(), 'date' => date('Y-m-d H:i:s'), 'user_id' => $authenticationService->getIdentity()->id, 'cache_user' => 0, 'type' => BankTransaction::BANK_TRANSACTION_TYPE_PAY, 'status' => BankTransaction::BANK_TRANSACTION_STATUS_APPROVED, 'money_account_id' => $this->getAccountFrom()->getAccountId(), 'exact_expense_id' => $expenseId, 'bank_rate' => null, 'money_account_currency' => $bankCurrencyCode, 'bank_amount' => $bankAmount, 'acc_amount' => -1 * $accAmount, 'customer_amount' => -1 * $partnerBalanceInCustomerCurrency, 'apartment_id' => $apartmentId, 'money_direction' => BankTransaction::TRANSACTION_MONEY_DIRECTION_PARTNER_COLLECT, 'comment' => "Automatic partner payment transaction was created after marking ticket as \"Partner Settled\"\n Based on bank transaction of {$this->getAccountFrom()->getAmount()}{$bankCurrencyCode} amount.{$reservationDescriptionSuffix}"]); // It is inessention here, but let it be $this->setMinorTransferId($bankTransactionDao->lastInsertValue); $bookingDao->update($reservationData, ['id' => $reservationId]); $logger->save(Logger::MODULE_BOOKING, $bookingTicket->getId(), Logger::ACTION_PARTNER_SETTLED); } // else { // throw new \Exception("Problem during requested operation for R# {$bookingTicket->getReservationNumber()}. Invalid R#"); // } } } return $moneyTransactionId; }