Esempio n. 1
0
 /**
  * @param array $data
  * @return bool
  */
 public function saveFrontierCharge($data)
 {
     /**
      * @var \DDD\Dao\Booking\Booking $bookingDao
      * @var \Library\Authentication\BackofficeAuthenticationService $authenticationService
      * @var \DDD\Dao\Booking\Charge $chargingDao
      * @var BankTransaction $serviceTransaction
      * @var Logger $logger
      * @var \DDD\Service\Booking\BookingAddon $addonService
      * @var \DDD\Dao\ApartmentGroup\ApartmentGroup $apartmentManagementDao
      */
     $addonService = $this->getServiceLocator()->get('service_booking_booking_addon');
     $serviceTransaction = $this->getServiceLocator()->get('service_booking_bank_transaction');
     $bookingDao = $this->getServiceLocator()->get('dao_booking_booking');
     $logger = $this->getServiceLocator()->get('ActionLogger');
     $apartmentManagementDao = $this->getServiceLocator()->get('dao_apartment_group_apartment_group');
     if (!isset($data['bookingId']) || !($rowBooking = $bookingDao->getBookingForFrontierCharge($data['bookingId'])) || !$data['cc_id']) {
         return false;
     }
     $authenticationService = $this->getServiceLocator()->get('library_backoffice_auth');
     $loggedInUserID = $authenticationService->getIdentity()->id;
     $chargingDao = $this->getServiceLocator()->get('dao_booking_charge');
     $parkingInventoryDao = $this->getServiceLocator()->get('dao_parking_spot_inventory');
     $addons = $addonService->getAddonsArray();
     $groupId = isset($data['groupId']) ? (int) $data['groupId'] : 0;
     $pspId = $apartmentManagementDao->getPsp($groupId);
     /**
      * @var Psp $pspService
      */
     $pspService = $this->getServiceLocator()->get('service_psp');
     $pspInfo = $pspService->getPspInfo($pspId);
     try {
         $chargingDao->beginTransaction();
         if (isset($data['accommodation_amount'])) {
             foreach ($data['accommodation_amount'] as $key => $value) {
                 if (isset($data['entityId'][$key]) && (int) $data['entityId'][$key] > 0) {
                     if ((int) $data['addonstype'][$key] == Constants::ADDONS_PARKING) {
                         $isAvailable = $parkingInventoryDao->getSpotInventoryAvailability($data['entityId'][$key], $data['nightDate'][$key]);
                         if (!$isAvailable) {
                             return false;
                         }
                     }
                 }
             }
             $params = ['reservation_id' => $rowBooking['id'], 'date' => date('Y-m-d H:i:s'), 'user_id' => $loggedInUserID, 'comment' => Helper::setLog('commentWithoutData', $data['charge_comment']), 'acc_currency' => $rowBooking['apartment_currency_code'], 'type' => 'n', 'apartment_id' => $rowBooking['apartment_id_assigned']];
             // set business model
             if ($rowBooking['model'] == PartnerService::BUSINESS_MODEL_GINOSI_COLLECT) {
                 $params['money_direction'] = Charge::CHARGE_MONEY_DIRECTION_GINOSI_COLLECT;
             } elseif (in_array($rowBooking['model'], PartnerService::partnerBusinessModel())) {
                 $params['money_direction'] = Charge::CHARGE_MONEY_DIRECTION_PARTNER_COLLECT;
             }
             $provideParking = [];
             foreach ($data['accommodation_amount'] as $key => $row) {
                 //nightly data
                 if (isset($data['reservation_nightly_ids'][$key]) && (int) $data['reservation_nightly_ids'][$key] > 0) {
                     $params['reservation_nightly_id'] = (int) $data['reservation_nightly_ids'][$key];
                     $params['rate_name'] = $data['rateNames'][$key];
                     $params['reservation_nightly_date'] = $data['nightDate'][$key];
                 } else {
                     $params['reservation_nightly_id'] = 0;
                     $params['rate_name'] = NUll;
                     $params['reservation_nightly_date'] = NULL;
                 }
                 //entityId is being used for parking now
                 if (isset($data['entityId'][$key]) && (int) $data['entityId'][$key] > 0) {
                     $params['entity_id'] = (int) $data['entityId'][$key];
                     if ((int) $data['addonstype'][$key] == Constants::ADDONS_PARKING) {
                         //close spot availability
                         $parkingInventoryDao->save(['availability' => 0], ['spot_id' => $params['entity_id'], 'date' => $params['reservation_nightly_date']]);
                     }
                 } else {
                     $params['entity_id'] = 0;
                 }
                 $params['acc_amount'] = number_format((double) $row, 2, '.', '');
                 $params['addons_type'] = (int) $data['addonstype'][$key];
                 $params['addons_value'] = (int) $data['addons_value'][$key];
                 $params['tax_type'] = isset($data['taxtype'][$key]) ? (double) $data['taxtype'][$key] : 0;
                 if (isset($addons[$params['addons_type']]['default_commission']) && $addons[$params['addons_type']]['default_commission']) {
                     $params['commission'] = $rowBooking['partner_commission'];
                 } else {
                     $params['commission'] = 0;
                 }
                 $params['status'] = 0;
                 $chargingDao->save($params);
                 if ($params['addons_type'] == Constants::ADDONS_PARKING) {
                     if (!isset($provideParking[$params['rate_name']])) {
                         $provideParking[$params['rate_name']] = [];
                     }
                     array_push($provideParking[$params['rate_name']], $params['reservation_nightly_date']);
                 }
             }
             $parkingChargesByDateRanges = $this->calculateDateRangesForSpot($provideParking);
             foreach ($parkingChargesByDateRanges as $parkingSpotRequested) {
                 $logger->save(Logger::MODULE_BOOKING, $rowBooking['id'], Logger::ACTION_PROVIDE_PARKING, 'Provide Parking on ' . $parkingSpotRequested['date'] . ' for ' . $parkingSpotRequested['spot']);
             }
             $bookingTicketService = $this->getServiceLocator()->get('service_booking_booking_ticket');
             $balanceAndSummaryArray = $bookingTicketService->getSumAndBalanc($rowBooking['id']);
             $bookingArray = ['guest_balance' => $balanceAndSummaryArray['ginosiBalanceInApartmentCurrency'], 'partner_balance' => $balanceAndSummaryArray['partnerBalanceInApartmentCurrency'], 'check_charged' => 1];
             // recalculatePenalty
             $newPenalty = $this->recalculatePenalty($rowBooking['id']);
             if ($newPenalty > 0) {
                 $bookingArray['penalty_fixed_amount'] = $newPenalty;
             }
             $bookingDao->save($bookingArray, ['res_number' => $rowBooking['res_number']]);
         }
         $transactionAmountInApartmentCurrency = doubleval($data['transaction_amount_apartment_currency']);
         if (is_float($transactionAmountInApartmentCurrency) && $transactionAmountInApartmentCurrency > 0) {
             $transactionAmountInCustomerCurrency = $transactionAmountInApartmentCurrency * $rowBooking['currency_rate'];
             // Transaction
             $transactionData = ['res_number' => $rowBooking['res_number'], 'transaction_type' => BankTransaction::BANK_TRANSACTION_TYPE_COLLECT, 'transaction_psp' => $pspId, 'reservation_id' => $rowBooking['id'], 'acc_currency_rate' => $rowBooking['acc_currency_rate'], 'transaction_acc_amount' => $transactionAmountInApartmentCurrency, 'transaction_customer_amount' => $transactionAmountInCustomerCurrency, 'transaction_money_account_currency' => $pspInfo['currency'], 'transaction_money_account_currency_rate' => $rowBooking['currency_rate'], 'transaction_charge_amount' => $transactionAmountInApartmentCurrency, 'transaction_money_account_id' => $pspInfo['money_account_id'], 'transaction_charge_comment' => $data['charge_comment'], 'accId' => $rowBooking['apartment_id_assigned'], 'transaction_status' => BankTransaction::BANK_TRANSACTION_STATUS_APPROVED, 'transaction_rrn' => '', 'transaction_auth_code' => '', 'cardId' => $data['cc_id']];
             $responseTransaction = $serviceTransaction->saveTransaction($transactionData, BankTransaction::TRANSACTION_MONEY_DIRECTION_GINOSI_COLLECT, true);
             if ($responseTransaction['status'] == 'error') {
                 $chargingDao->rollbackTransaction();
                 return false;
             }
         } else {
             $chargingDao->rollbackTransaction();
             return false;
         }
         $chargingDao->commitTransaction();
         return $rowBooking['res_number'];
     } catch (\Exception $e) {
         $chargingDao->rollbackTransaction();
     }
     return false;
 }
Esempio n. 2
0
 /**
  * @param array $data
  * @param int $moneyDirection
  * @param bool $isFrontier
  *
  * @return bool|string
  */
 public function saveTransaction($data, $moneyDirection = self::TRANSACTION_MONEY_DIRECTION_GINOSI_COLLECT, $isFrontier = false)
 {
     /**
      * @var \DDD\Dao\Booking\ChargeTransaction $bankTransactionDao
      * @var \Library\Authentication\BackofficeAuthenticationService $authenticationService
      * @var \DDD\Service\Booking\BookingTicket $bookingTicketService
      * @var \DDD\Domain\Booking\ForCharge $rowBooking
      * @var ForCharge $bookingDao
      * @var \DDD\Service\Fraud $serviceFraud
      * @var \DDD\Dao\Psp\Psp $pspDao
      * @var Logger $logger
      */
     $transactionDate = date('Y-m-d H:i:s');
     $bankTransactionDao = $this->getServiceLocator()->get('dao_booking_change_transaction');
     $pspDao = $this->getServiceLocator()->get('dao_psp_psp');
     $transactionType = (int) $data['transaction_type'];
     $transactionStatus = isset($data['transaction_status']) ? (int) $data['transaction_status'] : 0;
     $errorRespond = ['status' => 'error', 'msg' => TextConstants::ERROR_CHARGED];
     $error = '';
     $transactionTypesWhichRequireCreditCard = [self::BANK_TRANSACTION_TYPE_COLLECT, self::BANK_TRANSACTION_TYPE_REFUND, self::BANK_TRANSACTION_TYPE_VALIDATION];
     if (in_array($transactionType, $transactionTypesWhichRequireCreditCard) && (!isset($data['cardId']) || !(int) $data['cardId'])) {
         return ['status' => 'error', 'msg' => TextConstants::ERROR_NO_CARD];
     }
     $creditCardId = intval($data['cardId']);
     /**
      * @var \DDD\Dao\Booking\Booking $bookingDao
      */
     $bookingDao = $this->getServiceLocator()->get('dao_booking_booking');
     $bookingDao->setEntity(new \DDD\Domain\Booking\ForCharge());
     $rowBooking = $bookingDao->fetchOne(['res_number' => $data['res_number']], ['id', 'partner_id', 'customer_id']);
     if (!$rowBooking) {
         return $errorRespond;
     }
     try {
         if (!$isFrontier) {
             $bankTransactionDao->beginTransaction();
         }
         $authenticationService = $this->getServiceLocator()->get('library_backoffice_auth');
         $bookingTicketService = $this->getServiceLocator()->get('service_booking_booking_ticket');
         $loggedInUserID = $authenticationService->getIdentity()->id;
         $transactionApartmentAmount = $data['transaction_acc_amount'];
         $accAmount = number_format(doubleval($transactionApartmentAmount), 2, '.', '');
         if ($transactionType == self::BANK_TRANSACTION_TYPE_DEDUCTED_SALARY) {
             $bankAmount = 0;
             $bankRate = 0;
             $moneyAccountCurrency = $data['acc_currency'];
             $cashUser = (int) $data['userCache_id'];
         } else {
             $moneyAccountCurrency = $data['transaction_money_account_currency'];
             $bankRate = $data['transaction_money_account_currency_rate'];
             $bankAmount = number_format($data['transaction_charge_amount'], 2, '.', '');
             $cashUser = 0;
         }
         // Calculate exact bank amount
         $bankAmount = $this->applyPercentDeductionByPSP($bankAmount, $data['transaction_psp']);
         if ($transactionType == self::BANK_TRANSACTION_TYPE_DEDUCTED_SALARY) {
             $moneyAccountId = 0;
         } elseif (in_array($transactionType, [self::BANK_TRANSACTION_TYPE_CASH, self::BANK_TRANSACTION_TYPE_CASH_REFUND])) {
             $moneyAccountId = (int) $data['personal_account_id'];
         } elseif (in_array($transactionType, [self::BANK_TRANSACTION_TYPE_CHARGEBACK_DISPUTE, self::BANK_TRANSACTION_TYPE_CHARGEBACK_FRAUD, self::BANK_TRANSACTION_TYPE_CHARGEBACK_OTHER])) {
             $moneyAccountId = (int) $data['transaction_chargeback_bank'];
         } elseif ($transactionType == self::BANK_TRANSACTION_TYPE_BANK_DEPOSIT) {
             $moneyAccountId = (int) $data['money_account_deposit_id'];
             $moneyDirection = (int) $data['money_direction_received'];
         } else {
             $moneyAccountId = (int) $data['transaction_money_account_id'];
         }
         if ($transactionType == self::BANK_TRANSACTION_TYPE_BANK_DEPOSIT) {
             $moneyDirection = self::TRANSACTION_MONEY_DIRECTION_GINOSI_COLLECT;
         }
         // All Refunds and Chargebacks
         if (in_array($transactionType, [self::BANK_TRANSACTION_TYPE_REFUND, self::BANK_TRANSACTION_TYPE_CHARGEBACK_FRAUD, self::BANK_TRANSACTION_TYPE_CHARGEBACK_DISPUTE, self::BANK_TRANSACTION_TYPE_CHARGEBACK_OTHER, self::BANK_TRANSACTION_TYPE_CASH_REFUND])) {
             if ($transactionType != self::BANK_TRANSACTION_TYPE_CASH_REFUND) {
                 $bankAmount = -$bankAmount;
             }
             $accAmount = -$accAmount;
         }
         $params = ['reservation_id' => $data['reservation_id'], 'money_account_id' => $moneyAccountId, 'date' => $transactionDate, 'user_id' => $loggedInUserID, 'bank_amount' => $bankAmount, 'money_account_currency' => $moneyAccountCurrency, 'acc_amount' => $accAmount, 'bank_rate' => $bankRate, 'comment' => Helper::setLog('commentWithoutData', Helper::stripTages($data['transaction_charge_comment'])), 'type' => $transactionType, 'cache_user' => $cashUser, 'apartment_id' => (int) $data['accId'], 'money_direction' => $moneyDirection];
         if (in_array($transactionType, [self::BANK_TRANSACTION_TYPE_CASH, self::BANK_TRANSACTION_TYPE_CASH_REFUND, self::BANK_TRANSACTION_TYPE_BANK_DEPOSIT, self::BANK_TRANSACTION_TYPE_DEDUCTED_SALARY])) {
             $params['cc_id'] = 0;
         } else {
             $params['cc_id'] = $creditCardId;
         }
         if ($transactionType == self::BANK_TRANSACTION_TYPE_COLLECT) {
             $cardStatus = $transactionStatus + 1;
             /**
              * @var CardService $cardService
              */
             $cardService = $this->getServiceLocator()->get('service_card');
             $cardPartnerBusinessModel = $cardService->getCardPartnerBusinessModel($creditCardId);
             // check card partner business model
             if ($cardPartnerBusinessModel && $cardPartnerBusinessModel == Partners::BUSINESS_MODEL_GINOSI_COLLECT_PARTNER) {
                 $params['money_direction'] = self::TRANSACTION_MONEY_DIRECTION_PARTNER_COLLECT;
                 if ($transactionStatus == self::BANK_TRANSACTION_STATUS_APPROVED) {
                     $cardStatus = CardService::CC_STATUS_DO_NOT_USE;
                 }
             }
             // update card status
             $cardService->changeCardStatus($creditCardId, $cardStatus);
         }
         // Define Transaction Status
         if ($transactionType == self::BANK_TRANSACTION_TYPE_CASH || $transactionType == self::BANK_TRANSACTION_TYPE_CASH_REFUND) {
             $params['status'] = self::BANK_TRANSACTION_STATUS_PENDING;
         } elseif ($transactionStatus) {
             $params['status'] = $transactionStatus;
         } else {
             $params['status'] = self::BANK_TRANSACTION_STATUS_PENDING;
         }
         if (in_array($transactionType, [self::BANK_TRANSACTION_TYPE_COLLECT, self::BANK_TRANSACTION_TYPE_REFUND, self::BANK_TRANSACTION_TYPE_VALIDATION, self::BANK_TRANSACTION_TYPE_BANK_DEPOSIT])) {
             $params['psp_id'] = $data['transaction_psp'];
             if ($transactionStatus == self::BANK_TRANSACTION_STATUS_DECLINED) {
                 if (isset($data['transaction_error_code']) && $data['transaction_error_code']) {
                     $params['error_code'] = $data['transaction_error_code'];
                 }
             }
             if ($transactionStatus == self::BANK_TRANSACTION_STATUS_APPROVED) {
                 if (isset($data['transaction_auth_code']) && $data['transaction_auth_code']) {
                     $params['auth_code'] = $data['transaction_auth_code'];
                 }
                 if (isset($data['transaction_rrn']) && $data['transaction_rrn']) {
                     $params['rrn'] = $data['transaction_rrn'];
                 }
             }
         }
         // Frontier charge
         if ($isFrontier) {
             $params['status'] = self::BANK_TRANSACTION_STATUS_PENDING;
             $params['reviewed'] = self::FRONTIER_TRANSACTION_REVIEWED;
         }
         //            }
         // save transaction
         $bankTransactionDao->save($params);
         $transactorId = $bankTransactionDao->lastInsertValue;
         // after transaction save, we must recalculate balance and update it in reservations table
         $balances = $bookingTicketService->getSumAndBalanc($rowBooking->getId());
         $updateReservationData = ['guest_balance' => number_format($balances['ginosiBalanceInApartmentCurrency'], 2, '.', ''), 'partner_balance' => number_format($balances['partnerBalanceInApartmentCurrency'], 2, '.', '')];
         if (in_array($transactionType, [self::BANK_TRANSACTION_TYPE_COLLECT, self::BANK_TRANSACTION_TYPE_REFUND, self::BANK_TRANSACTION_TYPE_VALIDATION]) && $transactionStatus == self::BANK_TRANSACTION_STATUS_APPROVED) {
             $updateReservationData['funds_confirmed'] = BookingTicket::CC_STATUS_VALID;
         }
         $bookingDao->save($updateReservationData, ['res_number' => $data['res_number']]);
         // in case when transaction is chargeback and it's reason of fraud, we must update data in black list table
         if ($transactionType == self::BANK_TRANSACTION_TYPE_CHARGEBACK_FRAUD && $transactionStatus == self::BANK_TRANSACTION_STATUS_APPROVED) {
             $serviceFraud = $this->getServiceLocator()->get('service_fraud');
             $fraud = $serviceFraud->saveFraudManual($rowBooking->getId());
             if (isset($fraud['status']) && $fraud['status'] != 'success' && isset($fraud['msg'])) {
                 $error .= $fraud['msg'];
             }
         }
         // Make money transaction
         $transactionTypesToSkip = [self::BANK_TRANSACTION_TYPE_DEDUCTED_SALARY, self::BANK_TRANSACTION_TYPE_VALIDATION];
         $pspDao->setEntity(new \ArrayObject());
         $isBatch = $pspDao->fetchOne(['id' => $data['transaction_psp']], ['batch']);
         $isBatch = $isBatch ? $isBatch['batch'] : false;
         // For some cases money transaction is not acceptable
         if (!in_array($transactionType, $transactionTypesToSkip) && $params['status'] != self::BANK_TRANSACTION_STATUS_DECLINED && !$isBatch) {
             if ($transactionStatus != self::BANK_TRANSACTION_STATUS_DECLINED) {
                 $transactionDate = $this->changeDateForSomePSP($transactionDate, $data['transaction_psp']);
             }
             $reservationTransaction = new Reservation(TransactionBase::ACCOUNT_CUSTOMER, TransactionBase::ACCOUNT_MONEY_ACCOUNT);
             $reservationTransaction->setServiceLocator($this->getServiceLocator());
             $reservationTransaction->setAccountIdentity($rowBooking->getCustomerId(), $moneyAccountId);
             $reservationTransaction->setTransactorId($transactorId);
             $reservationTransaction->setTransactionDate($transactionDate);
             $reservationTransaction->setDescription("Reservation Transaction #{$data['res_number']}.");
             $reservationTransaction->setAmount($bankAmount);
             $reservationTransaction->setStatus($params['status']);
             $reservationTransaction->prepare();
             if (!$reservationTransaction->process()) {
                 throw new \Exception('Cannot process money transaction.');
             }
         }
         if (!$isFrontier) {
             $bankTransactionDao->commitTransaction();
         }
         if ($error) {
             $status = 'warning';
             $msg = TextConstants::SUCCESS_TRANSACTED . $error;
         } else {
             $status = 'success';
             $msg = TextConstants::SUCCESS_TRANSACTED;
         }
         return ['status' => $status, 'msg' => $msg];
     } catch (\Exception $ex) {
         if (!$isFrontier) {
             $bankTransactionDao->rollbackTransaction();
         }
         return $errorRespond;
     }
 }