496 lines
22 KiB
Java
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);
|
|
}
|
|
}
|
|
}
|