Files
mgm-daylight-mcrm-api-mobile/src/main/java/com/mgm/mcrm/roomcalendar/services/RoomCalendarService.java
T
2026-09-28 10:28:04 +08:00

496 lines
22 KiB
Java

package com.mgm.mcrm.roomcalendar.services;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mgm.mcrm.basesetting.property.models.CfgProperties;
import com.mgm.mcrm.basesetting.property.repositories.PropertyDao;
import com.mgm.mcrm.basesetting.room.models.CfgRooms;
import com.mgm.mcrm.basesetting.room.repositories.RoomDao;
import com.mgm.mcrm.common.dtos.http_util.HttpResponseResult;
import com.mgm.mcrm.common.services.MGMEsbApiService;
import com.mgm.mcrm.roomcalendar.dtos.RoomCalendarQualification;
import com.mgm.mcrm.roomcalendar.dtos.response.GetPropertyRoomTypeListResponse;
import com.mgm.mcrm.roomcalendar.dtos.response.GetPropertyRoomTypeResponse;
import com.mgm.mcrm.roomcalendar.dtos.response.RoomCalendarApiResponse;
import com.mgm.mcrm.roomcalendar.dtos.response.RoomType;
import com.mgm.mcrm.roomcalendar.repositories.RoomCalendarRoomProjection;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class RoomCalendarService {
@org.springframework.beans.factory.annotation.Value("${calendar.data-mock-enabled:false}")
private boolean calendarDataMockEnabled;
@Resource
private MGMEsbApiService mgmEsbApiService;
@Resource
private PropertyDao propertyDao;
@Resource
private RoomDao roomDao;
public RoomCalendarApiResponse<List<RoomCalendarQualification>> getRoomCalendar(Map<String, Object> params) throws Exception {
RoomCalendarApiResponse<List<RoomCalendarQualification>> result = new RoomCalendarApiResponse<>();
String playerId;
String property;
String roomType;
String startDate;
String endDate;
try {
playerId = getOptionalString(params, "playerId", "PlayerId");
property = getRequiredString(params, "property", "Property");
roomType = getRequiredString(params, "roomType", "RoomType");
startDate = getRequiredString(params, "startDate", "StartDate");
endDate = getRequiredString(params, "endDate", "EndDate");
} catch (IllegalArgumentException ex) {
result.setSuccess(false);
result.setMessage(ex.getMessage());
return result;
}
if (calendarDataMockEnabled) {
try {
result.setData(CalendarMockData.records(playerId, property, roomType, startDate, endDate));
result.setSuccess(true);
result.setCode("200");
result.setMessage("CALENDAR_MOCK_DATA");
} catch (java.time.DateTimeException | IllegalArgumentException ex) {
result.setSuccess(false);
result.setMessage(ex.getMessage());
}
return result;
}
CalendarVisibilityCheck visibility = validateCalendarVisibility(property, roomType);
if (visibility.errorCode != null) {
result.setSuccess(false);
result.setMessage(visibility.errorMessage);
result.setCalendarErrorCode(visibility.errorCode);
result.setData(new ArrayList<>());
return result;
}
List<RoomCalendarQualification> allRecords = new ArrayList<>();
boolean anySuccess = false;
if (StringUtils.isNotBlank(visibility.operaProperty) && StringUtils.isNotBlank(visibility.operaRoomType)) {
try {
HttpResponseResult response = mgmEsbApiService.invokeRequestRoomCalendar(
playerId, visibility.operaProperty, visibility.operaRoomType, startDate, endDate, 0);
if (response.getStatusCode() == 200) {
allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent()));
anySuccess = true;
}
} catch (Exception ignored) {
}
}
if (StringUtils.isNotBlank(visibility.daylightProperty) && StringUtils.isNotBlank(visibility.daylightRoomType)) {
try {
HttpResponseResult response = mgmEsbApiService.invokeRequestRoomCalendar(
playerId, visibility.daylightProperty, visibility.daylightRoomType, startDate, endDate, 1);
if (response.getStatusCode() == 200) {
allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent()));
anySuccess = true;
}
} catch (Exception ignored) {
}
}
if (StringUtils.isNotBlank(visibility.otherProperty) && StringUtils.isNotBlank(visibility.otherRoomType)) {
try {
HttpResponseResult response = mgmEsbApiService.invokeRequestRoomCalendar(
playerId, visibility.otherProperty, visibility.otherRoomType, startDate, endDate, 0);
if (response.getStatusCode() == 200) {
allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent()));
anySuccess = true;
}
} catch (Exception ignored) {
}
}
if (!anySuccess) {
result.setSuccess(false);
result.setMessage("RequestRoomCalendar failed");
result.setData(new ArrayList<>());
return result;
}
result.setData(allRecords);
result.setSuccess(true);
result.setCode("200");
return result;
}
private CalendarVisibilityCheck validateCalendarVisibility(String property, String roomType) {
List<String> propertyNames = parseDelimitedValues(property);
List<String> roomTypeNames = parseDelimitedValues(roomType);
List<CfgProperties> properties = propertyDao.findByCalendarNameIn(propertyNames);
List<CfgProperties> visibleProperties = new ArrayList<>();
for (String propertyName : propertyNames) {
CfgProperties cfgProperty = findByCalendarName(properties, propertyName);
if (isShowCalendar(cfgProperty)) {
visibleProperties.add(cfgProperty);
}
}
if (visibleProperties.isEmpty()) {
return CalendarVisibilityCheck.failure("PROPERTYNOSHOW", "Property no show in calendar");
}
List<String> propertyIds = new ArrayList<>();
for (CfgProperties cfgProperty : visibleProperties) {
propertyIds.add(String.valueOf(cfgProperty.getId()));
}
List<CfgRooms> rooms = roomDao.findByPropertyIdInAndCalendarNameIn(propertyIds, roomTypeNames);
String operaProperty = "";
String operaRoomType = "";
String daylightProperty = "";
String daylightRoomType = "";
String otherProperty = "";
String otherRoomType = "";
List<String> operaIds = new ArrayList<>();
List<String> operaCodes = new ArrayList<>();
List<String> daylightIds = new ArrayList<>();
List<String> daylightCodes = new ArrayList<>();
List<String> otherIds = new ArrayList<>();
List<String> otherCodes = new ArrayList<>();
for (CfgProperties cfgProperty : visibleProperties) {
String category = cfgProperty.getCategory();
if (StringUtils.equalsIgnoreCase(category, "OPERA")) {
operaIds.add(String.valueOf(cfgProperty.getId()));
operaCodes.add(cfgProperty.getCode());
} else if (StringUtils.equalsIgnoreCase(category, "DAYLIGHT")) {
daylightIds.add(String.valueOf(cfgProperty.getId()));
daylightCodes.add(cfgProperty.getCode());
} else if (StringUtils.equalsIgnoreCase(category, "OTHER")) {
otherIds.add(String.valueOf(cfgProperty.getId()));
otherCodes.add(cfgProperty.getCode());
}
}
if (!operaIds.isEmpty()) {
List<String> visibleOperaRoomTypes = filterVisibleRoomTypes(roomTypeNames, rooms, operaIds);
if (!visibleOperaRoomTypes.isEmpty()) {
operaProperty = StringUtils.join(operaCodes, ",");
operaRoomType = StringUtils.join(visibleOperaRoomTypes, ",");
}
}
if (!daylightIds.isEmpty()) {
List<String> visibleDaylightRoomTypes = filterVisibleRoomTypes(roomTypeNames, rooms, daylightIds);
if (!visibleDaylightRoomTypes.isEmpty()) {
daylightProperty = StringUtils.join(daylightCodes, ",");
daylightRoomType = StringUtils.join(visibleDaylightRoomTypes, ",");
}
}
if (!otherIds.isEmpty()) {
List<String> visibleOtherRoomTypes = filterVisibleRoomTypes(roomTypeNames, rooms, otherIds);
if (!visibleOtherRoomTypes.isEmpty()) {
otherProperty = StringUtils.join(otherCodes, ",");
otherRoomType = StringUtils.join(visibleOtherRoomTypes, ",");
}
}
if (StringUtils.isBlank(operaRoomType) && StringUtils.isBlank(daylightRoomType)
&& StringUtils.isBlank(otherRoomType)) {
return CalendarVisibilityCheck.failure("ROOMTYPENOSHOW", "Room type no show in calendar");
}
return CalendarVisibilityCheck.success(operaProperty, operaRoomType,
daylightProperty, daylightRoomType, otherProperty, otherRoomType);
}
public GetPropertyRoomTypeListResponse getPropertyRoomType() {
if (calendarDataMockEnabled) return CalendarMockData.metadata();
GetPropertyRoomTypeListResponse response = new GetPropertyRoomTypeListResponse();
List<CfgProperties> properties = propertyDao.findAll();
Map<String, List<RoomCalendarRoomProjection>> roomsByPropertyId = buildCalendarRoomsByPropertyId(properties);
List<GetPropertyRoomTypeResponse> propertyList = new ArrayList<>();
List<GetPropertyRoomTypeResponse> otherProperties = new ArrayList<>();
properties.sort(Comparator.comparing(RoomCalendarService::getPropertyCalendarOrder));
for (CfgProperties property : properties) {
if (!isShowCalendar(property)) {
continue;
}
List<RoomType> roomTypes = buildRoomTypes(property, roomsByPropertyId);
String calendarName = StringUtils.defaultIfBlank(property.getCalendarName(), property.getName());
if (StringUtils.equalsIgnoreCase(property.getCategory(), "OPERA")
|| StringUtils.equalsIgnoreCase(property.getCategory(), "DAYLIGHT")) {
propertyList.add(buildPropertyRoomTypeResponse(calendarName, calendarName, null, roomTypes));
} else if (StringUtils.equalsIgnoreCase(property.getCategory(), "OTHER")) {
otherProperties.add(buildPropertyRoomTypeResponse(
calendarName,
calendarName,
StringUtils.defaultIfBlank(property.getName(), property.getCalendarName()),
roomTypes));
}
}
if (!otherProperties.isEmpty()) {
GetPropertyRoomTypeResponse otherGroup = buildPropertyRoomTypeResponse(
"OTHER", "Other Property", null, new ArrayList<>());
otherGroup.setDefaultRoomTypes(buildDefaultProperties(otherProperties));
otherGroup.setOtherProperties(otherProperties);
propertyList.add(otherGroup);
}
response.setPropertyList(propertyList);
response.setSuccess(true);
response.setCode("200");
return response;
}
private Map<String, List<RoomCalendarRoomProjection>> buildCalendarRoomsByPropertyId(List<CfgProperties> properties) {
List<String> propertyIds = new ArrayList<>();
for (CfgProperties property : properties) {
if (isShowCalendar(property) && property.getId() != null) {
propertyIds.add(String.valueOf(property.getId()));
}
}
Map<String, List<RoomCalendarRoomProjection>> roomsByPropertyId = new HashMap<>();
if (propertyIds.isEmpty()) {
return roomsByPropertyId;
}
for (RoomCalendarRoomProjection room : roomDao.queryCalendarRoomsByPropertyIds(propertyIds)) {
if (room == null || StringUtils.isBlank(room.getPropertyId())) {
continue;
}
roomsByPropertyId.computeIfAbsent(room.getPropertyId(), key -> new ArrayList<>()).add(room);
}
return roomsByPropertyId;
}
private static List<RoomType> buildRoomTypes(
CfgProperties property,
Map<String, List<RoomCalendarRoomProjection>> roomsByPropertyId) {
List<RoomCalendarRoomProjection> rooms = new ArrayList<>(
roomsByPropertyId.getOrDefault(String.valueOf(property.getId()), new ArrayList<>()));
rooms.sort(Comparator.comparing(RoomCalendarService::getRoomCalendarOrder));
List<RoomType> roomTypes = new ArrayList<>();
for (RoomCalendarRoomProjection room : rooms) {
String calendarName = StringUtils.defaultIfBlank(room.getCalendarName(), room.getName());
if (StringUtils.isBlank(calendarName)) {
continue;
}
RoomType existing = findRoomType(roomTypes, calendarName);
if (existing != null) {
if (isDefaultShowCalendar(room.getDefaultShowCalendar())) {
existing.setDefaultShowCalendar(1);
}
continue;
}
RoomType item = new RoomType();
item.setCode(calendarName);
item.setLabel(calendarName);
item.setDefaultShowCalendar(isDefaultShowCalendar(room.getDefaultShowCalendar()) ? 1 : 0);
roomTypes.add(item);
}
return roomTypes;
}
private static GetPropertyRoomTypeResponse buildPropertyRoomTypeResponse(
String code, String name, String displayName, List<RoomType> roomTypes) {
GetPropertyRoomTypeResponse item = new GetPropertyRoomTypeResponse();
item.setCode(StringUtils.defaultString(code));
item.setName(StringUtils.defaultString(name));
item.setDisplayName(displayName);
item.setRoomTypes(roomTypes);
item.setDefaultRoomTypes(buildDefaultRoomTypes(roomTypes));
return item;
}
private static List<String> buildDefaultRoomTypes(List<RoomType> roomTypes) {
List<String> defaults = new ArrayList<>();
for (RoomType roomType : roomTypes) {
if (defaults.size() >= 3) {
break;
}
if (isDefaultShowCalendar(roomType.getDefaultShowCalendar()) && StringUtils.isNotBlank(roomType.getCode())) {
defaults.add(roomType.getCode());
}
}
return defaults;
}
private static List<String> buildDefaultProperties(List<GetPropertyRoomTypeResponse> properties) {
List<String> defaults = new ArrayList<>();
for (GetPropertyRoomTypeResponse property : properties) {
if (defaults.size() >= 3) {
break;
}
if (property.getDefaultRoomTypes() != null
&& !property.getDefaultRoomTypes().isEmpty()
&& StringUtils.isNotBlank(property.getCode())) {
defaults.add(property.getCode());
}
}
return defaults;
}
static List<RoomCalendarQualification> parseRoomCalendarResponse(String responseContent) {
JSONObject resultObj = JSONObject.parseObject(responseContent);
if (!StringUtils.equals("OK", resultObj.getString("StatusCode"))) {
throw new IllegalArgumentException(StringUtils.defaultIfBlank(
resultObj.getString("StatusDescription"), "RequestRoomCalendar failed"));
}
JSONArray records = resultObj.getJSONArray("Records");
List<RoomCalendarQualification> result = new ArrayList<>();
if (records == null) {
return result;
}
for (int i = 0; i < records.size(); i++) {
JSONObject item = records.getJSONObject(i);
RoomCalendarQualification record = new RoomCalendarQualification();
record.setProperty(item.getString("Property"));
record.setRoomType(item.getString("RoomType"));
record.setDate(normalizeDate(item.getString("Date")));
record.setRoomCriteria(item.getString("RoomCriteria"));
record.setRoomCount(item.getInteger("RoomCount"));
record.setPropertyLeader(item.getString("PropertyLeader"));
record.setBookingDateQualificationFlag(item.getInteger("BookingDateQualificationFlag"));
result.add(record);
}
return result;
}
private static List<String> filterVisibleRoomTypes(List<String> requestedNames, List<CfgRooms> rooms, List<String> propertyIds) {
Set<String> propertyIdSet = new LinkedHashSet<>(propertyIds);
Set<String> visible = new LinkedHashSet<>();
for (String requestedName : requestedNames) {
for (CfgRooms room : rooms) {
if (StringUtils.equals(requestedName, room.getCalendarName())
&& isShowCalendar(room)
&& propertyIdSet.contains(room.getPropertyId())) {
visible.add(requestedName);
break;
}
}
}
return new ArrayList<>(visible);
}
private static CfgProperties findByCalendarName(List<CfgProperties> properties, String name) {
for (CfgProperties property : properties) {
if (StringUtils.equals(property.getCalendarName(), name)) {
return property;
}
}
return null;
}
private static RoomType findRoomType(List<RoomType> roomTypes, String code) {
for (RoomType roomType : roomTypes) {
if (StringUtils.equals(roomType.getCode(), code)) {
return roomType;
}
}
return null;
}
private static List<String> parseDelimitedValues(String value) {
List<String> values = new ArrayList<>();
for (String item : StringUtils.split(StringUtils.defaultString(value), ",")) {
if (StringUtils.isNotBlank(item)) {
values.add(StringUtils.trim(item));
}
}
return values;
}
private static String getRequiredString(Map<String, Object> params, String lowerKey, String upperKey) {
Object value = params.get(lowerKey);
if (value == null) {
value = params.get(upperKey);
}
if (value == null || StringUtils.isBlank(String.valueOf(value))) {
throw new IllegalArgumentException("Missing parameter: " + lowerKey);
}
return String.valueOf(value);
}
private static String getOptionalString(Map<String, Object> params, String lowerKey, String upperKey) {
Object value = params.get(lowerKey);
if (value == null) {
value = params.get(upperKey);
}
return value == null || StringUtils.isBlank(String.valueOf(value)) ? "" : String.valueOf(value);
}
private static String normalizeDate(String value) {
if (StringUtils.isBlank(value)) {
return "";
}
return value.length() >= 10 ? value.substring(0, 10) : value;
}
private static boolean isShowCalendar(CfgProperties property) {
return property != null && Integer.valueOf(1).equals(property.getShowCalendar());
}
private static boolean isShowCalendar(CfgRooms room) {
return room != null && Integer.valueOf(1).equals(room.getShowCalendar());
}
private static boolean isDefaultShowCalendar(Integer value) {
return Integer.valueOf(1).equals(value);
}
private static Integer getPropertyCalendarOrder(CfgProperties property) {
return property == null || property.getCalendarOrder() == null ? Integer.MAX_VALUE : property.getCalendarOrder();
}
private static Integer getRoomCalendarOrder(RoomCalendarRoomProjection room) {
return room == null || room.getCalendarOrder() == null ? Integer.MAX_VALUE : room.getCalendarOrder();
}
private static final class CalendarVisibilityCheck {
private final String errorCode;
private final String errorMessage;
private final String operaProperty;
private final String operaRoomType;
private final String daylightProperty;
private final String daylightRoomType;
private final String otherProperty;
private final String otherRoomType;
private CalendarVisibilityCheck(String errorCode, String errorMessage,
String operaProperty, String operaRoomType,
String daylightProperty, String daylightRoomType,
String otherProperty, String otherRoomType) {
this.errorCode = errorCode;
this.errorMessage = errorMessage;
this.operaProperty = operaProperty;
this.operaRoomType = operaRoomType;
this.daylightProperty = daylightProperty;
this.daylightRoomType = daylightRoomType;
this.otherProperty = otherProperty;
this.otherRoomType = otherRoomType;
}
private static CalendarVisibilityCheck success(String operaProperty, String operaRoomType,
String daylightProperty, String daylightRoomType,
String otherProperty, String otherRoomType) {
return new CalendarVisibilityCheck(null, null, operaProperty, operaRoomType,
daylightProperty, daylightRoomType, otherProperty, otherRoomType);
}
private static CalendarVisibilityCheck failure(String errorCode, String errorMessage) {
return new CalendarVisibilityCheck(errorCode, errorMessage, null, null, null, null, null, null);
}
}
}