Files
mgm-daylight-mcrm-api-mobile/src/main/java/com/mgm/mcrm/player/services/TodoService.java
T
2026-10-12 15:15:50 +08:00

1095 lines
40 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.mgm.mcrm.player.services;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.google.gson.Gson;
import com.mgm.mcrm.appsetting.models.CfgSettings;
import com.mgm.mcrm.appsetting.services.SettingService;
import com.mgm.mcrm.appsetting.services.SysSettingService;
import com.mgm.mcrm.authorization.dtos.LoginUserInfo;
import com.mgm.mcrm.basesetting.daylight.dtos.response.ReservationDoorKeyResponse;
import com.mgm.mcrm.basesetting.daylight.dtos.response.ReservationQueueResponse;
import com.mgm.mcrm.basesetting.daylight.services.DaylightApiService;
import com.mgm.mcrm.basesetting.property.models.CfgProperties;
import com.mgm.mcrm.basesetting.property.repositories.PropertyDao;
import com.mgm.mcrm.basesetting.room.models.CfgOtherRoomStatus;
import com.mgm.mcrm.basesetting.room.repositories.OtherRoomStatusDao;
import com.mgm.mcrm.basesetting.room.services.OtherRoomStatusService;
import com.mgm.mcrm.booking.controllers.BookingController;
import com.mgm.mcrm.booking.dtos.BookingDto;
import com.mgm.mcrm.booking.dtos.opera.CancelBookingRequest;
import com.mgm.mcrm.booking.dtos.opera.FetchBookingRequest;
import com.mgm.mcrm.booking.dtos.opera.GuestRequestsRequest;
import com.mgm.mcrm.booking.dtos.opera.ModifyBookingRequest;
import com.mgm.mcrm.booking.mappers.BookingMapper;
import com.mgm.mcrm.booking.models.Bookings;
import com.mgm.mcrm.booking.models.BookingsView;
import com.mgm.mcrm.booking.repositories.BookingDao;
import com.mgm.mcrm.booking.repositories.BookingViewDao;
import com.mgm.mcrm.booking.services.*;
import com.mgm.mcrm.common.constants.SysCommon;
import com.mgm.mcrm.common.constants.SysConstants;
import com.mgm.mcrm.common.dtos.BaseApiResponse;
import com.mgm.mcrm.common.dtos.http_util.HttpResponseResult;
import com.mgm.mcrm.common.dtos.mgm_api.*;
import com.mgm.mcrm.common.services.HttpService;
import com.mgm.mcrm.common.services.MGMEsbApiService;
import com.mgm.mcrm.common.utils.DateTimeUtil;
import com.mgm.mcrm.common.utils.LogUtil;
import com.mgm.mcrm.logging.models.SysLogBooking;
import com.mgm.mcrm.logging.services.SysLogBookingService;
import com.mgm.mcrm.notification.models.Email;
import com.mgm.mcrm.notification.repositories.EmailDao;
import com.mgm.mcrm.notification.services.SendEmailService;
import com.mgm.mcrm.player.dtos.request.EtaRecordInfo;
import com.mgm.mcrm.player.dtos.request.TodoCancelBookingRequest;
import com.mgm.mcrm.player.dtos.request.TodoChangeDateRequest;
import com.mgm.mcrm.player.dtos.response.GetDashboardResponse;
import com.mgm.mcrm.player.dtos.response.GetTodoDetailResponse;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Slf4j
@Service
public class TodoService {
@Resource
private MGMEsbApiService mgmEsbApiService;
@Resource
private SysSettingService sysSettingService;
@Resource
private OperaDBBookingService operaDBBookingService;
@Resource
private BookingDao bookingDao;
@Resource
private BookingViewDao bookingViewDao;
@Resource
private PropertyDao propertyDao;
@Resource
private OtherRoomStatusDao otherRoomStatusDao;
@Resource
OperaService operaService;
@Resource
private NonMGMBookingService otherBookingService;
@Resource
private SettingService settingService;
@Resource
private EmailDao emailDao;
@Resource
private OtherRoomStatusService otherRoomStatusService;
@Resource
private SysLogBookingService sysLogBookingService;
@Resource
private OtherRoomStatusDao roomStatusDao;
@Resource
private WaitlistBookingService waitlistBookingService;
@Resource
private PlayerService playerService;
@Resource
private HttpService httpService;
@Resource
private BookingService bookingService;
@Resource
private DaylightApiService dlService;
@Resource
private BookingMapper bookingMapper;
@Resource
private SendEmailService sendEmailService;
public GetDashboardResponse getTodoDashboard(String userId) throws Exception {
GetDashboardResponse result = new GetDashboardResponse();
try {
HttpResponseResult httpResult = mgmEsbApiService.invokeGetTodoDashboard(userId, 0);
try {
TodoDashboardResult resultObj = JSONObject.parseObject(httpResult.getResponseContent(), TodoDashboardResult.class, Feature.SupportNonPublicField, Feature.IgnoreNotMatch);
if (Strings.CI.equals(resultObj.getStatusCode(), "OK")) {
result.setSuccess(true);
result.setReturnData(resultObj);
} else {
result.setSuccess(false);
result.setErrorCode(resultObj.getStatusDescription());
LogUtil.info(TodoService.class, "[GetDashboardData Error]" + resultObj.getStatusDescription());
}
} catch (Exception err) {
result.setSuccess(false);
result.setErrorCode("RETURN_DATA_ERROR");
LogUtil.info(TodoService.class, "[GetDashboardData Error]" + err.getMessage());
}
} catch (Exception err) {
result.setSuccess(false);
result.setErrorCode("INVOKE_TODODASHBOARD_API_ERROR");
LogUtil.info(TodoService.class, "[GetDashboardData Error]" + err.getMessage());
}
return result;
}
public GetTodoDetailResponse getTodoDetail(String playerId, String todoCategory, String todoSegment, String date) throws Exception {
GetTodoDetailResponse result = new GetTodoDetailResponse();
try {
HttpResponseResult httpResult = mgmEsbApiService.invokeGetTodoDetail(playerId, todoCategory, todoSegment, date, 1);
try {
TodoDetailResult resultObj = JSONObject.parseObject(httpResult.getResponseContent(), TodoDetailResult.class, Feature.SupportNonPublicField, Feature.IgnoreNotMatch);
if (Strings.CI.equals(resultObj.getStatusCode(), "OK")) {
if (resultObj.getDescriptions() != null) {
for (TodoDetailDescription detailRecord : resultObj.getDescriptions()) {
if ("Room".equalsIgnoreCase(detailRecord.getItemRecordType())) {
String recordDesc = detailRecord.getItemRecordDescription();
if (StringUtils.isNotBlank(recordDesc)) {
String confNum = null;
int index = recordDesc.indexOf("Conf#");
if (index != -1) {
String sub = recordDesc.substring(index + 5);
int pipeIndex = sub.indexOf("|");
if (pipeIndex != -1) {
confNum = sub.substring(0, pipeIndex).trim();
} else {
confNum = sub.trim();
}
}
if (StringUtils.isNotBlank(confNum)) {
if ("Inhouse".equalsIgnoreCase(todoCategory) || "Arrival".equalsIgnoreCase(todoCategory)) {
Bookings bookings = bookingDao.findFirstByConfirmationNoAndPropertyIdIsNotNull(confNum);
if (Objects.nonNull(bookings)) {
CfgProperties property = propertyDao.findById(bookings.getPropertyId()).orElse(null);
if (Objects.nonNull(property)) {
if ("Inhouse".equalsIgnoreCase(todoCategory)) {
// Parse checkinDate from recordDesc (e.g., "Jun 25 – Jul 1 ...")
LocalDate ciDate = null;
try {
String ciDatePart = recordDesc.split("–")[0].trim();
// Use the year from the 'date' parameter
int year = Integer.parseInt(date.substring(0, 4));
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM d yyyy", Locale.US);
ciDate = LocalDate.parse(ciDatePart + " " + year, formatter);
} catch (Exception e) {
LogUtil.warn(TodoService.class, "Parse checkinDate error: " + e.getMessage() + ", recordDesc: " + recordDesc);
}
if (ciDate != null) {
LocalDate today = LocalDate.now();
if (ciDate.isAfter(today)) {
// 当checkindate大于今天不用拿room number 和room ready
continue;
}
BaseApiResponse<ReservationDoorKeyResponse> doorKeyResult =
dlService.getReservationDoorKeyByConfirmationNumber(property.getDlPropertyId(), confNum);
ReservationDoorKeyResponse doorKeyData = doorKeyResult.getData();
if (doorKeyResult.isSuccess() && doorKeyData != null) {
String replaceStr = "Conf#" + confNum;
if (StringUtils.isNotBlank(doorKeyData.getRoomNumber())) {
detailRecord.setRoomNumber(doorKeyData.getRoomNumber());
replaceStr += " [Rm #" + doorKeyData.getRoomNumber() + "]";
}
if (ciDate.isEqual(today)) {
// 当今天的时候要检查room ready
boolean isRoomReady = StringUtils.isNotBlank(doorKeyData.getId())
&& !doorKeyData.isHasKey();
if (isRoomReady) {
replaceStr += " [Rm Ready]";
}
}
if (!replaceStr.equals("Conf#" + confNum)) {
detailRecord.setItemRecordDescription(recordDesc.replace("Conf#" + confNum, replaceStr));
}
}
}
}else{
BaseApiResponse<ReservationQueueResponse> queueResult =
dlService.getReservationQueueByConfirmationNumber(property.getDlPropertyId(), confNum);
ReservationQueueResponse queueData = queueResult.getData();
boolean isQueue = queueResult.isSuccess()
&& queueData != null
&& queueData.isQueue();
if (isQueue) {
detailRecord.setItemRecordDescription(recordDesc.replace("Conf#" + confNum, "Conf#" + confNum + " [In Queue]"));
}
}
}
} else {
// result.setSuccess(false);
// result.setErrorCode("BOOKING NOT FOUND");
// result.setErrorMessage("BOOKING NOT FOUND");
// LogUtil.warn(TodoService.class, "[GetTodoDetail] BOOKING NOT FOUND");
// return result;
}
}
}
}
}
}
}
result.setSuccess(true);
result.setReturnData(resultObj);
} else {
result.setSuccess(false);
result.setErrorCode(resultObj.getStatusDescription());
}
} catch (Exception err) {
result.setSuccess(false);
result.setErrorCode("RETURN_DATA_ERROR");
LogUtil.info(TodoService.class, "[GetTodoDetail Error]" + err.getMessage());
}
} catch (Exception err) {
result.setSuccess(false);
result.setErrorCode("INVOKE_TODOLISTDETAIL_API_ERROR");
LogUtil.info(TodoService.class, "[GetTodoDetail Error]" + err.getMessage());
}
return result;
}
public BaseApiResponse<Object> cancelBooking(TodoCancelBookingRequest param, HttpServletRequest request) throws Exception {
BaseApiResponse<Object> processResult= new BaseApiResponse<>();
Long bookId = param.getId();
String oStatus = "";
if (bookId == null) {
processResult.setSuccess(false);
processResult.setMessage("No Booking Id.");
processResult.setData(param);
return processResult;
}
Gson gson = new Gson();
BookingsView bookingView = bookingViewDao.findById(bookId).orElse(null);
boolean isMock =sysSettingService.isMockReplicate();
String userId = param.getUserId();
String userName = param.getUserName();
String category = bookingView.getPropertyCategory();
boolean isOpera = Strings.CS.equals("OPERA", category);
boolean isDaylight = Strings.CS.equals("DAYLIGHT", category);
boolean isOther = Strings.CS.equals("OTHER", category);
CfgProperties property = propertyDao.findByNameAndCategory(param.getPropertyName(), category);
String dlReservationId = null;
if (Strings.CS.equals(category,"DAYLIGHT")) {
dlReservationId = param.getDlReservationId();
}
if (isOther) {
// CancelOtherBooking Flow
// 获取setting表Cancel状态和时间区间
CfgSettings enAbleCancel = settingService.getSettingByKey("CAN_CANCEL_OTHERBOOKING");
// 判断状态是否启用
if(Strings.CS.equals(enAbleCancel.getKeyValues(), "1")) {
// 方法启用(==1),判断时间
// 状态启用判断现在时间是否再时间区间内
if(isPassTimeNow()) {
//Cancel Non MGM Booking
Bookings obooking = cancelOtherBooking(bookId,request);
if(obooking != null) {
processResult.setSuccess(true);
processResult.setData(bookingView);
}else {
processResult.setSuccess(false);
processResult.setCode("SYSTEM_ERROR");
processResult.setMessage("System error");
}
}else {
processResult.setSuccess(false);
processResult.setCode("ERR_CANCEL_TIME");
processResult.setData(param);
}
}else{
// 如果enAbleCancel方法没有启用(==0)直接cancelbooking
//Cancel Non MGM Booking
Bookings obooking = cancelOtherBooking(bookId,request);
if(obooking != null) {
processResult.setSuccess(true);
processResult.setData(bookingView);
}else {
processResult.setSuccess(false);
processResult.setCode("SYSTEM_ERROR");
processResult.setMessage("System error");
}
}
return processResult;
}
// 如果是模拟数据
if(isMock) {
Bookings booking = bookingDao.findById(bookId).orElse(null);
booking.setApproveStatus("C");
booking.setLastOperaStatus("CANCELED");
booking.setChangeCheckinDate(null);
booking.setChangeCheckoutDate(null);
bookingDao.save(booking);
processResult.setSuccess(true);
processResult.setData(booking);
TimeUnit.SECONDS.sleep(1L);
if (isDaylight) {
dlService.daylightCancelReservationNew(
dlReservationId,
property.getDlPropertyId(),
param.getDlSharerIds(),
param.getDlVersion()
);
}
return processResult;
}
if (isDaylight) {
Date newDate = DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss");
Bookings booking = bookingDao.findById(bookId).orElse(null);
booking.setApproveStatus("C");
booking.setLastOperaStatus("CANCELED");
booking.setCancelledBy(userId);
booking.setCancelledAt(newDate);
booking.setUpdatedAt(newDate);
booking.setUpdatedBy(userId);
bookingDao.save(booking);
BaseApiResponse<String> cancelResult =
dlService.daylightCancelReservationNew(
dlReservationId,
property.getDlPropertyId(),
param.getDlSharerIds(),
param.getDlVersion()
);
if (cancelResult.isSuccess()) {
LogUtil.info(TodoService.class, "[Cancel Booking] Cancel Success, bookingId=" + bookId);
processResult.setSuccess(true);
processResult.setData(dlReservationId);
}else {
LogUtil.warn(TodoService.class, "[Cancel Booking] Cancel Fail");
booking.setUpdatedAt(newDate);
booking.setCreatedAt(newDate);
booking.setApproveStatus("F");
booking.setErrorMessage("Call Daylight CANCEL_RESERVATION fail,Fail reason: "+cancelResult.getMessage());
bookingDao.save(booking);
processResult.setSuccess(false);
processResult.setData(cancelResult.getMessage());
}
return processResult;
}
if (isOpera) {
boolean hasShare = false;
List shareConfList = new ArrayList();
JSONObject fetchResponse = new JSONObject();
FetchBookingRequest owsReq = new FetchBookingRequest();
owsReq.setConfirmationNo(bookingView.getConfirmationNo());
fetchResponse = operaService.fetchBooking(owsReq);
if(fetchResponse.containsKey("shareConfList")) {
shareConfList = (List) fetchResponse.get("shareConfList");
hasShare = true;
}
CancelBookingRequest cancelRequest = new CancelBookingRequest();
JSONObject cancelResponse = new JSONObject();
cancelRequest.setHotelCode(bookingView.getHotelCode());
cancelRequest.setConfirmationNo(bookingView.getConfirmationNo());
LogUtil.info(BookingController.class, "[cancelBooking] cancelRequest begin" + gson.toJson(cancelRequest));
cancelResponse = operaService.cancelBooking(cancelRequest);
LogUtil.info(BookingController.class,
"[cancelBooking] Cancel Booking res" + gson.toJson(cancelResponse));
JSONObject errors = new JSONObject();
//cancel share booking
if (shareConfList!=null) {
for (int a = 0; a < shareConfList.size(); a++) {
String shareConfirmationNo = String.valueOf(shareConfList.get(a));
if(!StringUtils.isEmpty(shareConfirmationNo)) {
cancelRequest = new CancelBookingRequest();
cancelResponse = new JSONObject();
cancelRequest.setHotelCode(bookingView.getHotelCode());
cancelRequest.setConfirmationNo(shareConfirmationNo);
cancelResponse = operaService.cancelBooking(cancelRequest);
}
}
}
if (cancelResponse != null) {
processResult.setSuccess(true);
processResult.setData(bookingView);
}else {
Date newDate = DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss");
Bookings booking = bookingDao.findById(bookId).orElse(null);
errors = cancelResponse;
String errorMessage = errors != null && StringUtils.isNotBlank(errors.getString("message"))
? errors.getString("message") : "Cancel Booking Fail";
booking.setUpdatedAt(newDate);
booking.setCreatedAt(newDate);
booking.setApproveStatus("F");
booking.setErrorMessage(errorMessage);
processResult.setSuccess(false);
processResult.setMessage(errorMessage);
processResult.setCode("SYSTEM_ERROR");
processResult.setData(bookingView);
}
return processResult;
}
processResult.setSuccess(false);
processResult.setMessage("Cancel booking fail, invalid property");
return processResult;
}
public BaseApiResponse<TodoDateListResult> getTodoList(String userId, String category, String type, Date startDate, Date endDate) throws Exception {
BaseApiResponse<TodoDateListResult> result = new BaseApiResponse<>();
HttpResponseResult httpResult;
try {
// TODO 这里现在写死只拿daylight的todolist,后面会要拿到Opera的todoList,这个时候要改成两个都拿 by Mauve
httpResult = mgmEsbApiService.invokeGetTodoList(userId, category, type, startDate, endDate, 1);
} catch (Exception err) {
result.setSuccess(false);
result.setCode("INVOKE_TODOLISTDETAIL_API_ERROR");
LogUtil.info(TodoService.class, "[GetTodoList Error]" + err.getMessage());
return result;
}
try {
TodoListResult resultObj = JSONObject.parseObject(
httpResult.getResponseContent(),
TodoListResult.class,
Feature.SupportNonPublicField,
Feature.IgnoreNotMatch
);
if ("OK".equals(resultObj.getStatusCode())) {
List<TodoListRecord> recordList = resultObj.getRecords();
TodoDateListResult dateResult = new TodoDateListResult();
Map<String, TodoDateListRecord> dateMap = new LinkedHashMap<>();
for (TodoListRecord record : recordList) {
if (!dateMap.containsKey(record.getDate())) {
TodoDateListRecord dateRecord = new TodoDateListRecord();
dateRecord.setDate(record.getDate());
dateRecord.setDateRecords(new ArrayList<>());
dateMap.put(record.getDate(), dateRecord);
}
dateMap.get(record.getDate()).getDateRecords().add(record);
}
List<TodoDateListRecord> dateList = new ArrayList<>(dateMap.values());
// TODO daylight专用,后面要改 by Mauve
for (TodoDateListRecord todoDateListRecord : dateList) {
List<TodoListRecord> dateRecords = todoDateListRecord.getDateRecords();
for (TodoListRecord record : dateRecords) {
List<String> descriptions = record.getDescriptions();
if (CollectionUtils.isEmpty(descriptions)) {
continue;
}
try {
for (String description : descriptions) {
if (StringUtils.isBlank(description)) {
continue;
}
int confIndex = description.indexOf("Conf#");
if (confIndex == -1) {
continue;
}
String confPart = description.substring(confIndex + 5);
int pipeIndex = confPart.indexOf("|");
String confNum = (pipeIndex == -1 ? confPart : confPart.substring(0, pipeIndex)).trim();
if (StringUtils.isNotBlank(confNum)) {
if ("Inhouse".equalsIgnoreCase(category) || "Arrival".equalsIgnoreCase(category)) {
Bookings bookings = bookingDao.findFirstByConfirmationNoAndPropertyIdIsNotNull(confNum);
if (Objects.nonNull(bookings)) {
CfgProperties property = propertyDao.findById(bookings.getPropertyId()).orElse(null);
if (Objects.nonNull(property)) {
if ("Inhouse".equalsIgnoreCase(category)) {
BaseApiResponse<ReservationDoorKeyResponse> doorKeyResult =
dlService.getReservationDoorKeyByConfirmationNumber(property.getDlPropertyId(), confNum);
ReservationDoorKeyResponse doorKeyData = doorKeyResult.getData();
boolean isRoomReady = doorKeyResult.isSuccess()
&& doorKeyData != null
&& StringUtils.isNotBlank(doorKeyData.getId())
&& !doorKeyData.isHasKey();
if (isRoomReady) {
record.setRoomReady(true);
updateTodoRecordDescription(record, confNum, "[Rm Ready]");
}
} else {
BaseApiResponse<ReservationQueueResponse> queueResult =
dlService.getReservationQueueByConfirmationNumber(property.getDlPropertyId(), confNum);
ReservationQueueResponse queueData = queueResult.getData();
boolean isQueue = queueResult.isSuccess()
&& queueData != null
&& queueData.isQueue();
if (isQueue) {
record.setIsQueue(true);
updateTodoRecordDescription(record, confNum, "[In Queue]");
}
}
}
}
}
}
List<BookingsView> bookingByConfirmationNo = bookingService.getBookingByDaylightConf(confNum);
for (BookingsView bookingsView : bookingByConfirmationNo) {
if (StringUtils.isNotBlank(bookingsView.getEta())) {
String[] split2 = bookingsView.getEta().split(":");
record.setETA(split2[0] + ":" + split2[1]);
}
}
}
} catch (Exception e) {
log.warn("Failed to process todo descriptions={}", descriptions, e);
}
}
}
dateResult.setRecords(dateList);
result.setSuccess(true);
result.setData(dateResult);
} else {
result.setSuccess(false);
result.setCode(resultObj.getStatusDescription());
}
} catch (Exception err) {
result.setSuccess(false);
result.setCode("RETURN_DATA_ERROR");
LogUtil.info(TodoService.class, "[GetTodoList Error]" + err.getMessage());
}
return result;
}
public BaseApiResponse<Bookings> submitETA(String etaTime, List<EtaRecordInfo> recordInfos, Long id) throws Exception {
BaseApiResponse<Bookings> result = new BaseApiResponse<>();
boolean isMock = sysSettingService.isMockReplicate();
if (StringUtils.isBlank(etaTime) || CollectionUtils.isEmpty(recordInfos)) {
return missParameter(result);
}
for (EtaRecordInfo recordInfo : recordInfos) {
result = handleSingleRecord(etaTime, recordInfo, isMock, id); // 保持原逻辑:最终返回最后一条
}
return result;
}
private BaseApiResponse<Bookings> handleSingleRecord(
String etaTime,
EtaRecordInfo recordInfo,
boolean isMock,
Long id) throws Exception {
BaseApiResponse<Bookings> result = new BaseApiResponse<>();
String hotelName = StringUtils.trim(recordInfo.getHotelName());
String confNo = StringUtils.trim(recordInfo.getConfNo());
if (StringUtils.isBlank(hotelName) || StringUtils.isBlank(confNo)) {
return missParameter(result);
}
String category = bookingDao.findCategoryById(id);
CfgProperties property = propertyDao.findByLikeNameAndCategory(hotelName, category);
if (property == null) {
return noRecord(result);
}
if (Strings.CI.equals("DAYLIGHT", category)) {
return handleDaylightETA(etaTime, confNo, property, id);
}
if (Strings.CI.equals("OPERA", category)) {
return handleOperaETA(etaTime, confNo, property, isMock);
}
if (Strings.CI.equals("OTHER", category)) {
return handleOtherETA(etaTime, confNo, property);
}
return noRecord(result);
}
private BaseApiResponse<Bookings> handleOperaETA(
String etaTime,
String confNo,
CfgProperties property,
boolean isMock) throws Exception {
BaseApiResponse<Bookings> result = new BaseApiResponse<>();
Gson gson = new Gson();
Bookings booking = new Bookings();
booking.setConfirmationNo(confNo);
booking.setHotelCode(property.getHotelCode());
booking.setCategory("OPERA");
ModifyBookingRequest request = new ModifyBookingRequest();
request.setEta(etaTime);
request.setBooking(booking);
LogUtil.info(TodoService.class,
"[submitETA] OPERA submit begin " + gson.toJson(request));
if (isMock) {
// mock 环境:直接操作 DB
Bookings editBooking = bookingDao.getByConfNoForETA(confNo, property.getId());
if (editBooking == null) {
return noRecord(result);
}
editBooking.setEta(etaTime);
bookingDao.save(editBooking);
result.setSuccess(true);
result.setData(editBooking);
return result;
}
// dev / prod:调用 OPERA 接口
JSONObject response = operaService.modifyETA(request);
LogUtil.info(TodoService.class,
"[submitETA] OPERA submit res " + gson.toJson(response));
if (!response.containsKey("message")) {
result.setSuccess(true);
result.setData(booking);
} else {
result.setSuccess(false);
result.setCode(response.getString("message"));
result.setData(booking);
}
return result;
}
private BaseApiResponse<Bookings> handleDaylightETA(
String etaTime,
String confNo,
CfgProperties property,
Long id) throws Exception {
BaseApiResponse<Bookings> result = new BaseApiResponse<>();
Bookings booking;
if (id != null) {
booking = bookingDao.findById(id).orElse(null);
} else {
booking = bookingDao.getByConfNoForETA(confNo, property.getId());
}
booking.setEta(etaTime);
bookingDao.save(booking);
if (StringUtils.isNotBlank(confNo)) {
LogUtil.info(TodoService.class, "[submitETA] DAYLIGHT submit res");
BaseApiResponse<List<Bookings>> submitEta =
bookingService.callDaylightUpsertReservation(booking, "SUBMIT_ETA");
if (submitEta.isSuccess()) {
result.setSuccess(true);
result.setMessage(submitEta.getMessage());
} else {
result.setSuccess(false);
result.setMessage(submitEta.getMessage());
}
return result;
}
return noRecord(result);
}
private BaseApiResponse<Bookings> handleOtherETA(
String etaTime,
String confNo,
CfgProperties property) {
BaseApiResponse<Bookings> result = new BaseApiResponse<>();
Bookings editBooking = bookingDao.getByConfNoForETA(confNo, property.getId());
if (editBooking == null) {
return noRecord(result);
}
LogUtil.info(TodoService.class, "[submitETA] OTHER submit res");
editBooking.setEta(etaTime);
editBooking.setCategory("OTHER");
bookingDao.save(editBooking);
result.setSuccess(true);
result.setData(editBooking);
return result;
}
private BaseApiResponse<Bookings> missParameter(BaseApiResponse<Bookings> result) {
result.setSuccess(false);
result.setCode("MISS_PARAMETER");
result.setMessage("Miss Parameter");
return result;
}
private BaseApiResponse<Bookings> noRecord(BaseApiResponse<Bookings> result) {
result.setSuccess(false);
result.setCode("NO_RECORD");
result.setMessage("There are no corresponding booking records.");
return result;
}
public BaseApiResponse<BookingDto> changeBookingDate(TodoChangeDateRequest param, HttpServletRequest request) throws Exception {
BaseApiResponse<BookingDto> processResult = new BaseApiResponse<>();
Long bookId = param.getId();
String confNo = param.getConfirmationNo();
String ciDate = DateTimeUtil.getDateByFormat(param.getCheckinDate(), "yyyy-MM-dd");
String coDate = DateTimeUtil.getDateByFormat(param.getCheckoutDate(), "yyyy-MM-dd");
String userId = param.getUserId();
String userName = param.getUserName();
String playerId = param.getPlayerId();
PlayerProfileEntry profile = null;
BaseApiResponse<PlayerProfileEntry> res = playerService.findPlayerProfileByPlayerIdAndUserId(playerId, userId);
if (res.isSuccess()) {
profile = res.getData();
}
if (bookId != null) {
Gson gson = new Gson();
BookingsView bookingView;
if (confNo != null) {
List<BookingsView> bookingsViews = bookingViewDao.findByConfirmationNo(confNo);
bookingView = bookingsViews.getFirst();
} else {
bookingView = bookingViewDao.findById(bookId).orElse(null);
}
if (bookingView == null) {
processResult.setSuccess(false);
processResult.setMessage("Booking not found");
log.warn("booking not found");
return processResult;
}
Bookings booking = bookingDao.findById(bookingView.getId()).orElse(null);
boolean isMock = sysSettingService.isMockReplicate();
Date checkinDate = DateTimeUtil.getDateFromString(ciDate, "yyyy-MM-dd");
Date checkoutDate = DateTimeUtil.getDateFromString(coDate, "yyyy-MM-dd");
if ("DAYLIGHT".equals(bookingView.getPropertyCategory())) {
//Change Daylight Booking
booking.setCheckinDate(checkinDate);
booking.setCheckoutDate(checkoutDate);
bookingDao.save(booking);
processResult.setSuccess(true);
processResult.setData(bookingMapper.entityToDto(booking));
bookingService.daylightReservationChangeDate(param, profile, false, false);
LogUtil.info(TodoService.class, "[ChangeBookingDate] ID:"+bookingView.getDlReservationId());
return processResult;
} else if ("OPERA".equalsIgnoreCase(bookingView.getPropertyCategory())) {
boolean hasShare = false;
JSONObject fetchResponse = new JSONObject();
FetchBookingRequest owsReq = new FetchBookingRequest();
owsReq.setConfirmationNo(bookingView.getConfirmationNo());
fetchResponse = operaService.fetchBooking(owsReq);
if (fetchResponse.containsKey("shareConfList")) {
hasShare = true;
}
if (hasShare) {
//sendEmail
Email email = new Email();
email.setBookId(booking.getId());
email.setCreatedAt(DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));
email.setCreatedBy(userId);
booking.setChangeCheckinDate(ciDate);
booking.setChangeCheckoutDate(coDate);
bookingView = this.getEmailInfo(bookingView, userId);
CfgSettings emailAddress = settingService.getSettingByKey(SysConstants.MGM_EMAIL_ADDRESS);
email = sendEmailService.sendCancelEmail(booking, bookingView, email, userId, userName, emailAddress.getKeyValues());
if (email.getStatus() == 1) {
processResult.setSuccess(true);
} else {
processResult.setSuccess(false);
processResult.setCode("Send Email Failed.");
}
emailDao.save(email);
processResult.setData(bookingMapper.entityToDto(booking));
return processResult;
}
ModifyBookingRequest modifyBookingRequest = new ModifyBookingRequest();
JSONObject modifyBookingResponse = new JSONObject();
booking.setCheckinDate(checkinDate);
booking.setCheckoutDate(checkoutDate);
modifyBookingRequest.setBooking(booking);
LogUtil.info(TodoService.class, "[changeBookingDate] changeBookingDate begin" + gson.toJson(modifyBookingRequest));
modifyBookingResponse = operaService.changeBookingDate(modifyBookingRequest);
LogUtil.info(TodoService.class,
"[changeBookingDate] Change Booking res" + gson.toJson(modifyBookingResponse));
JSONObject errors = new JSONObject();
if (!modifyBookingResponse.containsKey("message")) {
String bookComment = operaService.makeChangeDateComment(booking);
CfgProperties property = propertyDao.findById(booking.getPropertyId()).orElse(null);
GuestRequestsRequest changeDateCommentRequest = new GuestRequestsRequest();
JSONObject changeDateCommentResponse = new JSONObject();
changeDateCommentRequest.setActionType("ADD");
changeDateCommentRequest.setProperty(property);
changeDateCommentRequest.setComment(bookComment);
changeDateCommentRequest.setConfirmationNo(booking.getConfirmationNo());
changeDateCommentRequest.setCommentType("CASHIER");
changeDateCommentResponse = operaService.guestRequests(changeDateCommentRequest);
processResult.setSuccess(true);
processResult.setData(bookingMapper.entityToDto(booking));
} else {
Date newDate = DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss");
String errorMsg = errors.getString("message") != null ? errors.getString("message") : "System Error";
errors = modifyBookingResponse;
booking.setUpdatedAt(newDate);
booking.setCreatedAt(newDate);
booking.setApproveStatus("F");
booking.setTryTime(5);
booking.setErrorMessage("Cancel booking fail.Error Message [ " + errorMsg + " ] ");
bookingDao.save(booking);
processResult.setSuccess(false);
processResult.setMessage(errors.getString("message") != null ? errors.getString("message") : "System Error");
processResult.setCode("SYSTEM_ERROR");
processResult.setData(bookingMapper.entityToDto(booking));
}
} else {
// 获取setting表Cancel状态和时间区间
CfgSettings enAbleCancel = settingService.getSettingByKey("CAN_CANCEL_OTHERBOOKING");
// 判断状态是否启用
if (Strings.CS.equals(enAbleCancel.getKeyValues(), "1")) {
// 方法启用(==1),判断时间
// 状态启用判断现在时间是否再时间区间内
if (isPassTimeNow()) {
//Change Non MGM Booking
Bookings obooking = changeOtherBooking(bookId, ciDate, coDate, request);
if (obooking != null) {
processResult.setSuccess(true);
processResult.setData(bookingMapper.entityToDto(obooking));
} else {
processResult.setSuccess(false);
processResult.setCode("SYSTEM_ERROR");
processResult.setMessage("System error");
}
} else {
processResult.setSuccess(false);
processResult.setCode("ERR_CANCEL_TIME");
processResult.setData(bookingMapper.changeDateRequestToDto(param));
}
} else {
// 如果enAbleCancel方法没有启用(==0)直接changedate
//Change Non MGM Booking
Bookings obooking = changeOtherBooking(bookId, ciDate, coDate, request);
if (obooking != null) {
processResult.setSuccess(true);
processResult.setData(bookingMapper.entityToDto(obooking));
} else {
processResult.setSuccess(false);
processResult.setCode("SYSTEM_ERROR");
processResult.setMessage("System error");
}
}
}
} else {
processResult.setSuccess(false);
processResult.setCode("No Booking Id.");
processResult.setData(bookingMapper.changeDateRequestToDto(param));
}
return processResult;
}
private Bookings cancelOtherBooking(Long bookId, HttpServletRequest request) {
Bookings oBooking = bookingDao.findById(bookId).orElse(null);
CfgOtherRoomStatus roomStatus = roomStatusDao.findByStatusName("Pending Cancel");
SysLogBooking logBooking = new SysLogBooking();
LoginUserInfo userInfo = SysCommon.parseUserFromToken(request);
String oStatus = oBooking.getLastOperaStatus();
Date now = new Date();
// CfgOtherRoomStatus roomStatus =
// oBooking.setCheckinDate(checkinDate);
// oBooking.setCheckinDate(checkoutDate);
oBooking.setOtherRoomStatusId(roomStatus.getId());
oBooking.setLastOperaStatus("Pending Cancel");
oBooking.setOtherFollowUpStatusId(Long.valueOf("5"));
LogUtil.info(BookingController.class,
"[changeBookingDate] Start Cancel Other Booking BookingId = " + oBooking.getId());
bookingDao.save(oBooking);
// 写入Audit Trail
logBooking.setOccurTime(now);
logBooking.setBookId(oBooking.getId());
logBooking.setEventCode("Room Status");
logBooking.setChangeFrom(oStatus);
logBooking.setChangeTo("Pending Cancel(CANCEL BOOKING)");
logBooking.setLoginId(userInfo.getLoginId());
logBooking.setLoginName(userInfo.getLoginId());
sysLogBookingService.save(logBooking);
// otherBookingService.processOtherAllotment(oBooking.getRoomId(), checkoutDate,
// checkinDate, oBooking.getPropertyId(), oBooking.getSegmentId());
return oBooking;
}
private Bookings changeOtherBooking(Long bookId, String checkInDate, String checkOutDate, HttpServletRequest request) throws Exception {
Bookings oBooking = bookingDao.findById(bookId).orElse(null);
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
CfgOtherRoomStatus roomStatus = otherRoomStatusDao.findByStatusName("Pending Cancel");
CfgOtherRoomStatus oRoomStatus = otherRoomStatusService.getOtherRoomStatusById(oBooking.getOtherRoomStatusId());
String oStatus = oBooking.getLastOperaStatus();
SysLogBooking logBooking = new SysLogBooking();
Date now = new Date();
LoginUserInfo userInfo = SysCommon.parseUserFromToken(request);
// 将String转换为Date
Date checkIn = dateFormat.parse(checkInDate);
Date checkOut = dateFormat.parse(checkOutDate);
oBooking.setChangeCheckinDate(checkInDate);
oBooking.setChangeCheckoutDate(checkOutDate);
oBooking.setLastOperaStatus("Pending Cancel");
oBooking.setOtherRoomStatusId(roomStatus.getId());
oBooking.setOtherFollowUpStatusId(Long.valueOf("5"));
LogUtil.info(BookingController.class,
"[changeBookingDate] Start Change Other Booking BookingId = " + oBooking.getId());
bookingDao.save(oBooking);
// 写入Audit Trail
logBooking.setOccurTime(now);
logBooking.setBookId(oBooking.getId());
logBooking.setEventCode("Status");
logBooking.setChangeFrom(oStatus);
logBooking.setChangeTo("Pending Cancel(CHANGE DATE)");
logBooking.setLoginId(userInfo.getLoginId());
logBooking.setLoginName(userInfo.getLoginId());
sysLogBookingService.save(logBooking);
otherBookingService.processOtherAllotment(oBooking.getRoomId(), checkOut,
checkIn, oBooking.getPropertyId(), oBooking.getSegmentId());
return oBooking;
}
private BookingsView getEmailInfo(BookingsView bookView, String userId) {
if (bookView != null) {
JSONArray dynList = !StringUtils.isEmpty(bookView.getSharer()) && !Strings.CS.equals("[]", bookView.getSharer()) ?
JSONArray.parseArray(bookView.getSharer()) : new JSONArray();
String sharerString = "";
if (!dynList.isEmpty()) {
for (int a = 0; a < dynList.size(); a++) {
Gson gson = new Gson();
JSONObject shareObj = (JSONObject) dynList.get(a);
String sharePlayerId = shareObj.getString("playerId");
String shareName = shareObj.getString("name");
LogUtil.info(BookingService.class,
"[editBooking] sharePlayerId " + gson.toJson(sharePlayerId));
LogUtil.info(BookingService.class,
"[editBooking] shareName " + gson.toJson(shareName));
if (!StringUtils.isEmpty(sharePlayerId)) {
sharerString += (sharePlayerId + " " + shareName) + " ";
} else if (!StringUtils.isEmpty(shareName)) {
sharerString += (shareName) + " ";
} else {
continue;
}
}
}
bookView.setSharerName(sharerString);
String playerId = bookView.getPlayerId() != null ? bookView.getPlayerId() : null;
BaseApiResponse<PlayerProfileEntry> findWebPlayerResult = playerService.findWebPlayerProfileByPlayerId(playerId);
if (findWebPlayerResult.isSuccess()) {
try {
PlayerProfileEntry profile = findWebPlayerResult.getData();
bookView.setMemberTier(profile.getTierName());
bookView.setMemberLastName(profile.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
return bookView;
}
// 判断时间是否超过viewYesterday Range
private boolean isPassTimeNow() {
boolean isPass = false;
CfgSettings cancelStart = settingService.getSettingByKey("OTHERBOOKING_CANCEL_START");
CfgSettings cancelEnd = settingService.getSettingByKey("OTHERBOOKING_CANCEL_END");
int startMinute = Integer.parseInt(cancelStart.getKeyValues().split(":")[0]) * 60
+ Integer.parseInt(cancelStart.getKeyValues().split(":")[1]);
int endMinute = Integer.parseInt(cancelEnd.getKeyValues().split(":")[0]) * 60
+ Integer.parseInt(cancelEnd.getKeyValues().split(":")[1]);
// 获跟当就的日期和时间
LocalDateTime currentDateTime = LocalDateTime.now();
int currentMinute = currentDateTime.getMinute() + currentDateTime.getHour() * 60;
if (currentMinute > startMinute && currentMinute < endMinute) {
isPass = true;
}
return isPass;
}
private void updateTodoRecordDescription(TodoListRecord record, String confNum, String tag) {
List<String> descriptions = record.getDescriptions();
if (CollectionUtils.isNotEmpty(descriptions)) {
for (int i = 0; i < descriptions.size(); i++) {
String desc = descriptions.get(i);
if (StringUtils.isNotBlank(desc) && desc.contains("Conf#" + confNum)) {
descriptions.set(i, desc.replace("Conf#" + confNum, "Conf#" + confNum + " " + tag));
}
}
}
}
}