/** * @param array $data * @param \DDD\Domain\Booking\ChannelReservation $bookingDomain * @param $otherInfo * @param bool $isOverbooking * @return bool */ public function modifyReservation($data = [], $bookingDomain, $otherInfo, $isOverbooking = false) { /** * @var \DDD\Dao\ChannelManager\ReservationIdentificator $daoReservationIdentificator * @var Booking $bookingDao * @var Logger $logger * @var Availability $availabilityService * @var \DDD\Service\task $taskService */ if (empty($data) || !$bookingDomain) { $this->gr2err("Empty data In Modification reservation"); return false; } $bookingDao = $this->getServiceLocator()->get('dao_booking_booking'); $logger = $this->getServiceLocator()->get('ActionLogger'); $taskService = $this->getServiceLocator()->get('service_task'); $reservationId = $bookingDomain->getId(); // Modification: Customer/CC Creation $ccIssue = $emailOptions = []; // Send CC Details if one has provided if ($otherInfo['cc_provided'] == true) { $ccIssue['cc_provided'] = true; $customerData = $data['customer_data']; $customerId = $this->changeCCForModification($bookingDomain, $customerData); $data['customer_id'] = $customerId; } else { $ccIssue['cc_provided'] = false; } unset($data['customer_data']); if (isset($otherInfo['send_payment_modify'])) { $emailOptions['send_payment_modify'] = true; } /** * @var \DDD\Service\Booking\ReservationIssues $reservationIssuesService */ $reservationIssuesService = $this->getServiceLocator()->get('service_booking_reservation_issues'); $reservationIssuesService->checkReservationIssues($reservationId, $ccIssue); $apartmentId = $otherInfo['apartment_id']; // get apartel id $apartel = isset($otherInfo['apartel']['apartel_id']) && $otherInfo['apartel']['apartel_id'] ? $otherInfo['apartel']['apartel_id'] : false; // set identificator if ($apartel && isset($otherInfo['identificator'])) { $daoReservationIdentificator = $this->getServiceLocator()->get('dao_channel_manager_reservation_identificator'); $daoReservationIdentificator->save(['date_from' => $otherInfo['identificator']['dateFrom'], 'date_to' => $otherInfo['identificator']['dateTo'], 'room_id' => $otherInfo['identificator']['roomId'], 'rate_id' => $otherInfo['identificator']['rateId'], 'guest_name' => trim($otherInfo['identificator']['guestName'])], ['reservation_id' => $reservationId]); } if ($data['date_from'] != $bookingDomain->getDateFrom() || $data['date_to'] != $bookingDomain->getDateTo()) { // Rates data parsing $ratesData = $otherInfo['ratesData']; $ratesForChangeDate = $this->changeDateForModification($ratesData, $reservationId, false, $apartel, $isOverbooking); if ($ratesForChangeDate['status'] == 'error') { return false; } } $remarks = null; if (isset($data['remarks']) && !empty(trim($data['remarks']))) { $remarks = trim($data['remarks']); } unset($data['remarks']); if (isset($data['ip_address'])) { unset($data['ip_address']); } // Update reservation $bookingDao->save($data, ['id' => $reservationId]); // anyway update channel $availabilityService = $this->getServiceLocator()->get('service_availability'); $availabilityService->updateChannelByReservationId($reservationId); // Reservation modified $reservationModifiedMessage = 'Modification received from Channel Manager and processed successfully'; if ($data['date_from'] != $bookingDomain->getDateFrom() || $data['date_to'] != $bookingDomain->getDateTo()) { $reservationModifiedMessage .= ' : <br>'; $thereIsAlreadyDateChange = false; if ($data['date_from'] < $bookingDomain->getDateFrom()) { $thereIsAlreadyDateChange = true; $oldDateFromMinusOneDay = date('Y-m-d', strtotime('-1 day', strtotime($bookingDomain->getDateFrom()))); //change range is one day if ($oldDateFromMinusOneDay == $data['date_from']) { $reservationModifiedMessage .= 'Dates modified: Added new date ' . $oldDateFromMinusOneDay; } else { $reservationModifiedMessage .= 'Modified dates: Added new dates from ' . $data['date_from'] . ' to ' . $oldDateFromMinusOneDay; } } if ($data['date_from'] > $bookingDomain->getDateFrom()) { if ($thereIsAlreadyDateChange) { $reservationModifiedMessage .= ' , '; } $thereIsAlreadyDateChange = true; $newDateMinusOneDay = date('Y-m-d', strtotime('-1 day', strtotime($data['date_from']))); if ($newDateMinusOneDay == $bookingDomain->getDateFrom()) { $reservationModifiedMessage .= 'Modified dates: Updated with penalty and opened availability for ' . $newDateMinusOneDay; } else { $reservationModifiedMessage .= 'Modified dates: Updated with penalty and opened availability from ' . $bookingDomain->getDateFrom() . ' to ' . $newDateMinusOneDay; } } if ($data['date_to'] > $bookingDomain->getDateTo()) { $realNewDateTo = date('Y-m-d', strtotime('-1 day', strtotime($data['date_to']))); $realOldDateTo = date('Y-m-d', strtotime('-1 day', strtotime($bookingDomain->getDateTo()))); if ($thereIsAlreadyDateChange) { $reservationModifiedMessage .= ' , '; } $thereIsAlreadyDateChange = true; $oldDateFromPlusOneDay = date('Y-m-d', strtotime('+1 day', strtotime($realOldDateTo))); if ($oldDateFromPlusOneDay == $realNewDateTo) { $reservationModifiedMessage .= 'Modified dates: Added new date ' . $realNewDateTo; } else { $reservationModifiedMessage .= 'Modified dates: Added new dates from ' . $oldDateFromPlusOneDay . ' to ' . $realNewDateTo; } } if ($data['date_to'] < $bookingDomain->getDateTo()) { $realNewDateTo = date('Y-m-d', strtotime('-1 day', strtotime($data['date_to']))); $realOldDateTo = date('Y-m-d', strtotime('-1 day', strtotime($bookingDomain->getDateTo()))); if ($thereIsAlreadyDateChange) { $reservationModifiedMessage .= ' , '; } $newDatePlusOneDay = date('Y-m-d', strtotime('+1 day', strtotime($realNewDateTo))); if ($newDatePlusOneDay == $realOldDateTo) { $reservationModifiedMessage .= 'Modified dates: Updated with penalty and opened availability for ' . $newDatePlusOneDay; } else { $reservationModifiedMessage .= 'Modified dates: Updated with penalty and opened availability from ' . $newDatePlusOneDay . ' to ' . $realOldDateTo; } } } $logger->save(Logger::MODULE_BOOKING, $reservationId, Logger::ACTION_BOOKING_MODIFY, $reservationModifiedMessage); // create log for remarks if (!is_null($remarks)) { $actionLogDao = $this->getServiceLocator()->get('dao_action_logs_action_logs'); $preActionLog = $actionLogDao->fetchOne(['module_id' => Logger::MODULE_BOOKING, 'identity_id' => $reservationId, 'user_id' => UserService::USER_GUEST, 'action_id' => Logger::ACTION_COMMENT]); if ($preActionLog) { $actionLogDao->save(['value' => Helper::stripTages($remarks), 'timestamp' => date('Y-m-d H:i:s')], ['id' => $preActionLog['id']]); } else { $logger->save(Logger::MODULE_BOOKING, $reservationId, Logger::ACTION_COMMENT, Helper::stripTages($remarks), UserService::USER_GUEST); } } // if missing rate create task if (isset($otherInfo['rateMissingTask'])) { $taskService->createAutoTaskForMissingRate($reservationId); } $this->sendReservationEmail($reservationId, 'modification', $emailOptions, $apartel); $this->gr2info("Booking ticket successfully modify", ['cron' => 'ChannelManager', 'apartment_id' => $apartmentId, 'reservation_id' => $reservationId]); return true; }
public function saveCharge($data, $userId = false) { /** * @var \DDD\Dao\Booking\Booking $bookingDao * @var \Library\Authentication\BackofficeAuthenticationService $authenticationService * @var \DDD\Dao\Booking\Charge $chargingDao * @var \DDD\Dao\Booking\ChargeDeleted $chargeDeleteDao * @var \DDD\Dao\Booking\ReservationNightly $reservationNightlyDao * @var Logger $logger */ $authenticationService = $this->getServiceLocator()->get('library_backoffice_auth'); $chargingDao = $this->getServiceLocator()->get('dao_booking_charge'); $bookingDao = $this->getServiceLocator()->get('dao_booking_booking'); $chargeDeleteDao = $this->getServiceLocator()->get('dao_booking_charge_deleted'); $reservationNightlyDao = $this->getServiceLocator()->get('dao_booking_reservation_nightly'); $logger = $this->getServiceLocator()->get('ActionLogger'); $isBookingExist = $bookingDao->checkRowExist(DbTables::TBL_BOOKINGS, 'res_number', $data['res_number']); $parkingInventoryDao = $this->getServiceLocator()->get('dao_parking_spot_inventory'); $taskService = $this->getServiceLocator()->get('service_task'); if (!$isBookingExist) { return false; } $rowBooking = $bookingDao->getDataForCharge($data['res_number']); if ($userId) { $loggedInUserID = $userId; } else { $loggedInUserID = $authenticationService->getIdentity()->id; } $reservationId = $rowBooking['id']; $params = ['reservation_id' => $reservationId, 'date' => date('Y-m-d H:i:s'), 'user_id' => $loggedInUserID, 'comment' => Helper::setLog('commentWithoutData', Helper::stripTages($data['charge_comment'])), 'customer_currency' => Helper::stripTages($data['customerCurrency']), 'acc_currency' => Helper::stripTages($data['accommodationCurrency']), 'apartment_id' => (int) $data['accId'], 'type' => 'n']; try { $chargingDao->beginTransaction(); $check = false; $provideParking = []; $reverseProvideParking = []; // reverse charge if (isset($data['removed'])) { foreach ($data['removed'] as $row) { if ((int) $row > 0) { $removedId = $row; //see if it's parking, open availability for the spot $removedChargeInfo = $chargingDao->getChargeById($removedId); if ($removedChargeInfo->getAddons_type() == BookingAddon::ADDON_TYPE_PARKING && $removedChargeInfo->getReservationNightlyId() > 0 && $removedChargeInfo->getEntityId() > 0) { $parkingInventoryDao->save(['availability' => 1], ['spot_id' => $removedChargeInfo->getEntityId(), 'date' => $removedChargeInfo->getReservationNightlyDate()]); } if ($removedChargeInfo->getAddons_type() == BookingAddon::ADDON_TYPE_EXTRA_PERSON) { $newOccupancy = $rowBooking['occupancy'] - (int) $removedChargeInfo->getAddons_value(); $bookingDao->save(['occupancy' => $newOccupancy], ['id' => $rowBooking['id']]); $taskService->changeSubtaskOccupancy($rowBooking['id'], $newOccupancy); } $chargingDao->save(['status' => self::CHARGE_STATUS_DELETED], ['id' => $removedId]); $chargeDeleteDao->save(['reservation_id' => $reservationId, 'reservation_charge_id' => $removedId, 'date' => date('Y-m-d H:i:s'), 'user_id' => $loggedInUserID, 'comment' => Helper::setLog('commentWithoutData', Helper::stripTages($data['charge_comment']))]); $check = true; $chargeRowRemoved = $chargingDao->checkChargeTypeIsParking($removedId); if ($chargeRowRemoved) { if (!isset($reverseProvideParking[$removedChargeInfo->getRateName()])) { $reverseProvideParking[$removedChargeInfo->getRateName()] = []; } array_push($reverseProvideParking[$removedChargeInfo->getRateName()], $removedChargeInfo->getReservationNightlyDate()); } } } } // charge if (isset($data['accommodation_amount'])) { foreach ($data['accommodation_amount'] as $key => $value) { if (isset($data['entityId'][$key]) && (int) $data['entityId'][$key] > 0) { $endDate = end($data['nightDate']); if (strtotime('now') <= strtotime($endDate)) { if ((int) $data['addonstype'][$key] == Constants::ADDONS_PARKING) { $isAvailable = $parkingInventoryDao->getSpotInventoryAvailability($data['entityId'][$key], $data['nightDate'][$key]); if (!$isAvailable) { return false; } } } } } foreach ($data['accommodation_amount'] as $key => $row) { $price = number_format((double) $row, 2, '.', ''); $addonType = (int) $data['addonstype'][$key]; // 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; } // collection if (isset($data['new_addon_money_direction'][$key])) { $params['money_direction'] = (int) $data['new_addon_money_direction'][$key]; } else { $params['money_direction'] = 0; } // commission if (isset($data['new_addon_commission'][$key])) { $params['commission'] = $data['new_addon_commission'][$key]; } else { $params['commission'] = 0; } // Discount if ($addonType == BookingAddon::ADDON_TYPE_DISCOUNT) { $price *= -1; } // Compensation if ($addonType == BookingAddon::ADDON_TYPE_COMPENSATION) { $price *= -1; } $params['tax_type'] = isset($data['taxtype'][$key]) ? (double) $data['taxtype'][$key] : 0; $params['acc_amount'] = $price; $params['addons_value'] = isset($data['addons_value'][$key]) ? (double) $data['addons_value'][$key] : 0; $params['addons_type'] = $addonType; $params['status'] = 0; $chargingDao->save($params); if ((int) $data['addonstype'][$key] == Constants::ADDONS_PARKING) { if (!isset($provideParking[$params['rate_name']])) { $provideParking[$params['rate_name']] = []; } array_push($provideParking[$params['rate_name']], $params['reservation_nightly_date']); } // set reservation nightly price if (isset($data['reservation_nightly_ids'][$key]) && (int) $data['reservation_nightly_ids'][$key] > 0 && $addonType == BookingAddon::ADDON_TYPE_ACC) { // change reservation nightly price $priceNight = $chargingDao->getChargePriceByNightlyId((int) $data['reservation_nightly_ids'][$key]); if ($priceNight && isset($data['rateIds'][$key]) && (int) $data['rateIds'][$key] > 0) { $reservationNightlyDao->save(['price' => $priceNight, 'rate_id' => (int) $data['rateIds'][$key], 'rate_name' => $data['rateNames'][$key]], ['id' => (int) $data['reservation_nightly_ids'][$key]]); } } // Extra person charges if ($addonType == BookingAddon::ADDON_TYPE_EXTRA_PERSON && (int) $data['addons_value'][$key]) { $newOccupancy = $rowBooking['occupancy'] + (int) $data['addons_value'][$key]; $bookingDao->save(['occupancy' => $newOccupancy], ['id' => $rowBooking['id']]); $taskService->changeSubtaskOccupancy($rowBooking['id'], $newOccupancy); $logger->save(Logger::MODULE_BOOKING, $rowBooking['id'], Logger::ACTION_OCUPANCY_CHANGE, [$rowBooking['occupancy'], $newOccupancy]); } $check = true; } } $parkingChargesByDateRanges = $this->calculateDateRangesForSpot($provideParking); $reversedParkingChargesByDateRanges = $this->calculateDateRangesForSpot($reverseProvideParking); foreach ($parkingChargesByDateRanges as $parkingSpotRequested) { $logger->save(Logger::MODULE_BOOKING, $rowBooking['id'], Logger::ACTION_PROVIDE_PARKING, 'Provide Parking on ' . $parkingSpotRequested['date'] . ' for ' . $parkingSpotRequested['spot']); } foreach ($reversedParkingChargesByDateRanges as $parkingSpotReversed) { $logger->save(Logger::MODULE_BOOKING, $rowBooking['id'], Logger::ACTION_PROVIDE_PARKING, 'Do Not Provide Parking on ' . $parkingSpotReversed['date'] . ' for ' . $parkingSpotReversed['spot']); } if ($check) { $this->updateBalance($rowBooking['id'], true); } $chargingDao->commitTransaction(); return $data['res_number'] . '#fd'; } catch (\Exception $e) { $this->gr2logException($e, 'Transaction is not being created after charge', $data); $chargingDao->rollbackTransaction(); } return false; }
public function ajaxBlackListAction() { $request = $this->getRequest(); $result = ['status' => 'success', 'msg' => '']; try { if ($request->isXmlHttpRequest()) { /** * @var \DDD\Service\Booking $bookingService */ $bookingService = $this->getServiceLocator()->get('service_booking'); $num = (int) $request->getPost('num'); $reservationId = Helper::stripTages($request->getPost('reservation_id')); $response = $bookingService->saveBlackList($reservationId, $num); if ($response && $response['status'] == 'success') { $flash = ['success' => $response['msg']]; } else { $flash = ['error' => $response['msg']]; } Helper::setFlashMessage($flash); } } catch (\Exception $e) { $result['status'] = 'error'; $result['msg'] = TextConstants::ERROR; } return new JsonModel($result); }
public function bookingSave($data) { /** * @var \DDD\Domain\Booking\BookingTicket $rowBooking * @var \Library\Authentication\BackofficeAuthenticationService $authenticationService * @var \DDD\Service\Booking\BankTransaction $bankTransactionService * @var ChannelManager $serviceChannelManager * @var Inventory $serviceInventory * @var \DDD\Service\Fraud $serviceFraud * @var \DDD\Service\Partners $partnerService * @var \DDD\Service\Task $taskService * @var \DDD\Dao\Task\Task $taskDao * @var Logger $logger * @var \DDD\Dao\Booking\Booking $bookingDao * @var \DDD\Service\Booking\ReservationIssues $reservationIssuesService */ $authenticationService = $this->getServiceLocator()->get('library_backoffice_auth'); $cityService = $this->getServiceLocator()->get('service_location'); $serviceInventory = $this->getServiceLocator()->get('service_apartment_inventory'); $serviceFraud = $this->getServiceLocator()->get('service_fraud'); $taskService = $this->getServiceLocator()->get('service_task'); $taskDao = $this->getServiceLocator()->get('dao_task_task'); $logger = $this->getServiceLocator()->get('ActionLogger'); $bookingDao = $this->getServiceLocator()->get('dao_booking_booking'); $reservationIssuesService = $this->getServiceLocator()->get('service_booking_reservation_issues'); $addToBlackList = isset($data['addToBlackList']) ? $data['addToBlackList'] : 0; unset($data['addToBlackList']); $bookingDao->setEntity(new \DDD\Domain\Booking\BookingTicket()); $rowBooking = $bookingDao->getBookingTicketData((int) $data['booking_id']); $cub_status = ['status' => 'success']; $status = 'success'; $msg = ''; if (!$rowBooking) { return ['status' => 'error', 'msg' => TextConstants::ERROR_ROW, 'cub_status' => $cub_status]; } $hasFinanceRole = $authenticationService->hasRole(Roles::ROLE_RESERVATION_FINANCE); $hasCreditCardView = $authenticationService->hasRole(Roles::ROLE_CREDIT_CARD); $data['finance_paid_affiliate'] = isset($data['finance_paid_affiliate']) ? (int) $data['finance_paid_affiliate'] : 0; $params = ['guest_first_name' => Helper::stripTages($data['guest_name']), 'guest_last_name' => Helper::stripTages($data['guest_last_name']), 'guest_email' => Helper::stripTages($data['guest_email']), 'secondary_email' => Helper::stripTages($data['second_guest_email']), 'guest_country_id' => $data['guest_country'] > 0 ? (int) $data['guest_country'] : null, 'guest_city_name' => Helper::stripTages($data['guest_city']), 'guest_address' => Helper::stripTages($data['guest_address']), 'guest_zip_code' => Helper::stripTages($data['guest_zipcode']), 'guest_phone' => Helper::stripTages($data['guest_phone']), 'guest_travel_phone' => Helper::stripTages($data['guest_travel_phone']), 'partner_ref' => Helper::stripTages($data['booking_affiliate_reference']), 'partner_settled' => $data['finance_paid_affiliate'], 'no_collection' => (int) $data['finance_no_collection'], 'apartel_id' => (int) $data['apartel_id'], 'occupancy' => (int) $data['occupancy'], 'ki_viewed' => (int) $data['finance_key_instructions'], 'model' => (int) $data['model']]; if ($params['secondary_email'] == $params['guest_email']) { $params['secondary_email'] = null; } if ((int) $data['overbooking_status'] != $rowBooking->getOverbookingStatus()) { $changeOverbookingStatus = $this->changeOverbookingStatus((int) $data['booking_id'], (int) $data['overbooking_status']); if (!$changeOverbookingStatus) { if ((int) $data['overbooking_status'] != self::OVERBOOKING_STATUS_OVERBOOKED) { $status = 'error'; $msg .= TextConstants::OVERBOOKING_STATUS_CHANGE_ERROR; } elseif ((int) $data['overbooking_status'] == self::OVERBOOKING_STATUS_OVERBOOKED) { $status = 'error'; $msg .= TextConstants::OVERBOOKING_STATUS_CHANGE_NOT_OPEN_DAY; } } unset($data['overbooking_status']); } if (!empty($data['booking_arrival_time'])) { $params['guest_arrival_time'] = Helper::stripTages($data['booking_arrival_time']); } // if change partner if (isset($data['booking_partners']) && $data['booking_partners'] != $rowBooking->getPartnerId()) { $params['partner_id'] = $data['booking_partners']; $partnerService = $this->getServiceLocator()->get('service_partners'); $partnerData = $partnerService->getPartnerDataForReservation($params['partner_id'], $rowBooking->getApartmentIdAssigned(), true); $params['partner_commission'] = $partnerData->getCommission(); $params['partner_name'] = $partnerData->getPartnerName(); } if (isset($data['finance_booked_state']) && isset($data['finance_booked_state_changed']) && $data['finance_booked_state_changed'] == self::BOOKED_STATE_CHANGED) { $params['arrival_status'] = (int) $data['finance_booked_state']; if ($data['finance_booked_state'] > 0) { $params['ki_viewed'] = 1; } $currentDateCity = $cityService->getCurrentDateCity($rowBooking->getApartmentCityId()); switch ($data['finance_booked_state']) { case 1: // check in if (is_null($rowBooking->getActualArrivalDate())) { $params['arrival_date'] = $currentDateCity; } break; case 2: // check out if (is_null($rowBooking->getActualDepartureDate())) { $params['departure_date'] = $currentDateCity; // change cleaning task start date $taskService->changeTaskDate($rowBooking->getId(), $rowBooking->getApartmentIdAssigned(), $currentDateCity, strtotime($rowBooking->getDate_to()), Task::TYPE_CLEANING, Task::TASK_IS_HOUSEKEEPING); } break; case 4: // no show $taskService->createNoShowTask((int) $data['booking_id'], $authenticationService->getIdentity(), $rowBooking->getApartmentIdAssigned(), $rowBooking->getDate_from()); break; } } // Action Logging $this->setGinosiComment($rowBooking, $data, ['fin' => $hasFinanceRole, 'credit' => $hasCreditCardView]); // Destination status can't be booked or unknown $weirdStatusList = [BookingService::BOOKING_STATUS_BOOKED, BookingService::BOOKING_STATUS_CANCELLED_PENDING]; // Booking status was changed and assumes Cancellation if (isset($data['booking_statuses']) && in_array($rowBooking->getStatus(), $weirdStatusList) && !in_array($data['booking_statuses'], $weirdStatusList)) { // Only if reservation is not canceled-moved to "bad" reservation if ($status != 'error') { if (in_array($data['booking_statuses'], [BookingService::BOOKING_STATUS_CANCELLED_UNWANTED, BookingService::BOOKING_STATUS_CANCELLED_FRAUDULANT, BookingService::BOOKING_STATUS_CANCELLED_NOSHOW])) { $data['send_mail'] = false; } $serviceInventory->processCancellation($rowBooking->getResNumber(), true, $data['send_mail'], (int) $data['booking_statuses'], $data['selected-email']); } $taskWhere = new Where(); $taskWhere->equalTo('task_type', Task::TYPE_CCCA)->equalTo('res_id', $data['booking_id']); $taskDao->save(['task_status' => Task::STATUS_CANCEL], $taskWhere); } if (isset($data['booking_statuses']) && in_array($rowBooking->getStatus(), BookingService::$bookingCancelStatuses) && in_array($data['booking_statuses'], BookingService::$bookingCancelStatuses)) { $params['status'] = $data['booking_statuses']; } $params['ccca_verified'] = (int) $data['ccca_verified']; if ($params['ccca_verified'] != $rowBooking->getCccaVerified() && $params['ccca_verified'] == BookingService::CCCA_VERIFIED) { $reservationTasks = $taskDao->getReservationTasksByType($data['booking_id'], Task::TYPE_CCCA); if ($reservationTasks->count()) { $firstTaskId = $reservationTasks->current()->getId(); $taskDao->update(['task_status' => Task::STATUS_DONE], ['id' => $firstTaskId]); foreach ($reservationTasks as $task) { if ($task->getId() != $firstTaskId) { $taskDao->update(['task_status' => Task::STATUS_CANCEL], ['id' => $task->getId()]); } } } } if ($hasFinanceRole) { $params['payment_settled'] = (int) $data['finance_reservation_settled']; if (isset($data['finance_reservation_settled']) && $data['finance_reservation_settled'] == 1 && $rowBooking->getPayment_settled() != 1) { $params['settled_date'] = date("Y-m-d H:i:s"); $reservationIssuesService->resolveReservationAllIssues($data['booking_id'], TRUE); } elseif (isset($data['finance_reservation_settled']) && $data['finance_reservation_settled'] == 0) { $params['settled_date'] = '0000-00-00 00:00:00'; } } else { if ((int) $data['finance_no_collection'] == 1) { $params['payment_settled'] = 0; $params['settled_date'] = '0000-00-00 00:00:00'; } } if ($hasCreditCardView && isset($data['finance_valid_card'])) { $params['funds_confirmed'] = (int) $data['finance_valid_card']; } // If occupancy was changed if ($data['occupancy'] != $rowBooking->getOccupancy()) { $logger->save(Logger::MODULE_BOOKING, $data['booking_id'], Logger::ACTION_OCUPANCY_CHANGE, [$rowBooking->getOccupancy(), $data['occupancy']]); } // save Data $bookingDao->save($params, ['res_number' => $data['booking_res_number']]); if (isset($data['booking_statuses']) && $rowBooking->getStatus() != $data['booking_statuses']) { if ($data['booking_statuses'] == BookingService::BOOKING_STATUS_CANCELLED_FRAUDULANT) { $serviceFraud->saveFraudManual($data['booking_id']); } elseif ($data['booking_statuses'] == BookingService::BOOKING_STATUS_CANCELLED_UNWANTED && $addToBlackList) { $serviceFraud->saveFraudManual($data['booking_id'], false); } } $reservationIssuesService->checkReservationIssues($data['booking_id']); return ['status' => $status, 'msg' => $msg, 'cub_status' => $cub_status]; }
/** * @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; } }