This commit is contained in:
Mauve
2026-10-12 15:15:50 +08:00
parent 32945d7469
commit 3a8a438668
74 changed files with 1490 additions and 2221 deletions
+1
View File
@@ -6,3 +6,4 @@
!/target/crm_mobile_runtime/ !/target/crm_mobile_runtime/
/.classpath /.classpath
/.project /.project
/crm_mobile_runtime/logs/
@@ -7,11 +7,6 @@
"offsetCol": 0, "offsetCol": 0,
"objClassName": "com.mgm.mcrm.common.dtos.data_import.booking.OtherBookingImportRow", "objClassName": "com.mgm.mcrm.common.dtos.data_import.booking.OtherBookingImportRow",
"columnDefs": [ "columnDefs": [
{
"columnHeader":"#",
"checkHeader":false,
"headerRowIdx":0
},
{ {
"columnHeader":"Staff Action", "columnHeader":"Staff Action",
"checkHeader":true, "checkHeader":true,
@@ -33,13 +28,6 @@
"attrName": "propertyName", "attrName": "propertyName",
"dataType": "String" "dataType": "String"
}, },
{
"columnHeader":"Confirmation No.",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "confirmationNo",
"dataType": "String"
},
{ {
"columnHeader":"Room Type", "columnHeader":"Room Type",
"checkHeader":true, "checkHeader":true,
@@ -47,6 +35,27 @@
"attrName": "roomName", "attrName": "roomName",
"dataType": "String" "dataType": "String"
}, },
{
"columnHeader":"Market Code",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "marketCodeName",
"dataType": "String"
},
{
"columnHeader":"Booking Type",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "bookingTypeName",
"dataType": "String"
},
{
"columnHeader":"Segment",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "segmentName",
"dataType": "String"
},
{ {
"columnHeader":"Check In Date", "columnHeader":"Check In Date",
"checkHeader":true, "checkHeader":true,
@@ -61,21 +70,6 @@
"attrName": "checkoutDate", "attrName": "checkoutDate",
"dataType": "String" "dataType": "String"
}, },
{
"columnHeader":"Change Check In Date",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Change Check Out Date",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Requested C/O Date",
"checkHeader":false,
"headerRowIdx":0
},
{ {
"columnHeader":"Player ID", "columnHeader":"Player ID",
"checkHeader":true, "checkHeader":true,
@@ -83,47 +77,6 @@
"attrName": "playerId", "attrName": "playerId",
"dataType": "String" "dataType": "String"
}, },
{
"columnHeader":"Title",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Last Name",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"First Name",
"checkHeader":false,
"headerRowIdx":0,
"attrName": "playerName",
"dataType": "String"
},
{
"columnHeader":"Tier",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Market Code",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "marketCodeName",
"dataType": "String"
},
{
"columnHeader":"Source Code",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "sourceCodeName",
"dataType": "String"
},
{
"columnHeader":"Booker",
"checkHeader":false,
"headerRowIdx":0
},
{ {
"columnHeader":"Booker Id", "columnHeader":"Booker Id",
"checkHeader":true, "checkHeader":true,
@@ -131,6 +84,13 @@
"attrName": "bookerId", "attrName": "bookerId",
"dataType": "String" "dataType": "String"
}, },
{
"columnHeader":"Approver ID",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "approverId",
"dataType": "String"
},
{ {
"columnHeader":"Sharer", "columnHeader":"Sharer",
"checkHeader":true, "checkHeader":true,
@@ -138,11 +98,6 @@
"attrName": "sharer", "attrName": "sharer",
"dataType": "String" "dataType": "String"
}, },
{
"columnHeader":"Sharer Name",
"checkHeader":false,
"headerRowIdx":0
},
{ {
"columnHeader":"Remark", "columnHeader":"Remark",
"checkHeader":true, "checkHeader":true,
@@ -151,45 +106,25 @@
"dataType": "String" "dataType": "String"
}, },
{ {
"columnHeader":"Approver", "columnHeader":"Confirmation No",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Approver ID",
"checkHeader":true, "checkHeader":true,
"headerRowIdx":0, "headerRowIdx":0,
"attrName": "approverId", "attrName": "confirmationNo",
"dataType": "String" "dataType": "String"
}, },
{ {
"columnHeader":"Approval Remark", "columnHeader":"Player Name",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Booking Type",
"checkHeader":true, "checkHeader":true,
"headerRowIdx":0, "headerRowIdx":0,
"attrName": "bookingTypeName", "attrName": "playerName",
"dataType": "String" "dataType": "String"
}, },
{ {
"columnHeader":"Segment", "columnHeader":"Source Code",
"checkHeader":true, "checkHeader":true,
"headerRowIdx":0, "headerRowIdx":0,
"attrName": "segmentName", "attrName": "sourceCodeName",
"dataType": "String" "dataType": "String"
},
{
"columnHeader":"ETA Time",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Create Date/Time",
"checkHeader":false,
"headerRowIdx":0
} }
] ]
}] }]
+1
View File
@@ -20,6 +20,7 @@
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>21</java.version> <java.version>21</java.version>
<tomcat.version>11.0.25</tomcat.version>
<netty.version>4.2.18.Final</netty.version> <netty.version>4.2.18.Final</netty.version>
<httpclient5.version>5.6.4</httpclient5.version> <httpclient5.version>5.6.4</httpclient5.version>
<httpclient5-win.version>5.2.3</httpclient5-win.version> <httpclient5-win.version>5.2.3</httpclient5-win.version>
@@ -9,7 +9,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
//@RequestMapping("/sso_callback")
@Controller @Controller
public class SSOCallbackController { public class SSOCallbackController {
@RequestMapping(value="/sso_callback/login",method = RequestMethod.GET) @RequestMapping(value="/sso_callback/login",method = RequestMethod.GET)
@@ -130,10 +130,9 @@ public class SSORestProcessController {
String paraRelying = StringUtils.isNotBlank(request.getParameter("relyingParty"))?request.getParameter("relyingParty"):relyingParty; String paraRelying = StringUtils.isNotBlank(request.getParameter("relyingParty"))?request.getParameter("relyingParty"):relyingParty;
String authorizedUrl = adfsHost+ "/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp="+paraRelying; String authorizedUrl = adfsHost+ "/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp="+paraRelying;
String requestClientId = request.getParameter("client_request_id"); String requestClientId = request.getParameter("client_request_id");
Map<String,String> cookieValues = new HashMap<String,String>();String origin = request.getHeader("Origin"); Map<String,String> cookieValues = new HashMap<String,String>();
String origin = request.getHeader("Origin");
LogUtil.info(SSORestProcessController.class,"URI:"+request.getRequestURI()+",Origin:"+origin); LogUtil.info(SSORestProcessController.class,"URI:"+request.getRequestURI()+",Origin:"+origin);
//
// String origin = request.getHeader("Origin");
String sanitizedOrigin = NetworkUtil.sanitizeCRLF(origin); String sanitizedOrigin = NetworkUtil.sanitizeCRLF(origin);
if(SysCommon.isAllowOriginSource(sanitizedOrigin)) { if(SysCommon.isAllowOriginSource(sanitizedOrigin)) {
response.setHeader("Access-Control-Allow-Origin", NetworkUtil.sanitizeCRLF(sanitizedOrigin)); response.setHeader("Access-Control-Allow-Origin", NetworkUtil.sanitizeCRLF(sanitizedOrigin));
@@ -609,6 +608,18 @@ public class SSORestProcessController {
httpResult.put("NextStep", "Callback"); httpResult.put("NextStep", "Callback");
httpResult.put("ErrorCode", statusCode); httpResult.put("ErrorCode", statusCode);
httpResult.put("ErrorMessage", "Unknown Response Result"); httpResult.put("ErrorMessage", "Unknown Response Result");
StringBuilder stringBuilder = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(clientResponse.getBody(), "UTF-8"));
String line = null;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line);
}
}catch(Exception err) {
LogUtil.info(SSORestProcessController.class,"Read Response Body Failed:"+err.getMessage());
}
String responseBody = stringBuilder.toString();
LogUtil.info(SSORestProcessController.class,"response failed with status: :"+statusCode + " Result body:"+responseBody);
} }
}else { }else {
isEnd=true; isEnd=true;
@@ -633,16 +644,17 @@ public class SSORestProcessController {
if(resHeaders!=null) { if(resHeaders!=null) {
resHeaders.forEach((key, value) -> { resHeaders.forEach((key, value) -> {
try { try {
//LogUtil.info(SSORestProcessController.class,"Res Header:"+key+" Value:"+value); LogUtil.info(SSORestProcessController.class,"Res Header:"+key+" Value:"+value);
response.setHeader(key, NetworkUtil.sanitizeCRLF(value)); response.setHeader(key, NetworkUtil.sanitizeCRLF(value));
}catch(Exception ignored) { }catch(Exception e) {
LogUtil.error(SSORestProcessController.class,"processResult function fail: ", e);
} }
}); });
} }
LogUtil.info(SSORestProcessController.class,"Next Step:"+nextStep);
if(Strings.CS.equals(nextStep, "ReturnResult")||Strings.CS.equals(nextStep, "Pending")) { if(Strings.CS.equals(nextStep, "ReturnResult")||Strings.CS.equals(nextStep, "Pending")) {
String responseBody = httpResult.get("ResponseBody")!=null?httpResult.get("ResponseBody").toString():""; String responseBody = httpResult.get("ResponseBody")!=null?httpResult.get("ResponseBody").toString():"";
//LogUtil.info(SSORestProcessController.class,"Response Body:"+responseBody); LogUtil.info(SSORestProcessController.class,"Response Body:"+responseBody);
byte[] outputData = responseBody.getBytes(); byte[] outputData = responseBody.getBytes();
long contentLength = outputData.length; long contentLength = outputData.length;
response.setHeader("Content-Length", Long.toString(contentLength)); response.setHeader("Content-Length", Long.toString(contentLength));
@@ -656,6 +668,8 @@ public class SSORestProcessController {
LogUtil.info(SSORestProcessController.class,"Redirect location:"+redirectUrl); LogUtil.info(SSORestProcessController.class,"Redirect location:"+redirectUrl);
response.setHeader("Location", NetworkUtil.sanitizeCRLF(redirectUrl)); response.setHeader("Location", NetworkUtil.sanitizeCRLF(redirectUrl));
} }
LogUtil.info(SSORestProcessController.class,"Send Redirect:"+redirectUrl);
response.setHeader("Origin","MGM_CRM_APP");
response.sendRedirect(redirectUrl); response.sendRedirect(redirectUrl);
}else { }else {
String redirectUrl = callbackUrl+"?"; String redirectUrl = callbackUrl+"?";
@@ -668,6 +682,7 @@ public class SSORestProcessController {
response.setHeader("Location", NetworkUtil.sanitizeCRLF(saintUrl)); response.setHeader("Location", NetworkUtil.sanitizeCRLF(saintUrl));
response.setHeader("Content-Length","0"); response.setHeader("Content-Length","0");
LogUtil.info(SSORestProcessController.class,"Callback with ErrorCode:"+saintUrl+" [errorMessage]:"+errorMessage); LogUtil.info(SSORestProcessController.class,"Callback with ErrorCode:"+saintUrl+" [errorMessage]:"+errorMessage);
response.setHeader("Origin","MGM_CRM_APP");
response.sendRedirect(saintUrl); response.sendRedirect(saintUrl);
} }
}else { }else {
@@ -948,6 +948,7 @@ public class ApprovalService {
newBooking.setApprovedBy(userName); newBooking.setApprovedBy(userName);
newBooking.setApprovedId(Long.valueOf(userId)); newBooking.setApprovedId(Long.valueOf(userId));
newBooking.setCategory("OTHER"); newBooking.setCategory("OTHER");
newBooking.setApprovalRemark(originBooking.getApprovalReason());
//获取other room status //获取other room status
CfgOtherRoomStatus roomStatus = roomStatusDao.findByStatusName("Pending"); CfgOtherRoomStatus roomStatus = roomStatusDao.findByStatusName("Pending");
if(roomStatus!=null) { if(roomStatus!=null) {
@@ -89,8 +89,8 @@ public class ConfigService {
public List<CfgProperties> listProperty(PropertyQueryRequest queryFilter) { public List<CfgProperties> listProperty(PropertyQueryRequest queryFilter) {
Specification<CfgProperties> listSpec = (root, criteriaQuery, cb) -> { Specification<CfgProperties> listSpec = (root, criteriaQuery, cb) -> {
List<Predicate> list = new ArrayList<>(); List<Predicate> list = new ArrayList<>();
// status=0 的记录不返回 // status=1 的记录才返回
list.add(cb.notEqual(root.get("status"), 0)); list.add(cb.equal(root.get("status"), 1));
if(StringUtils.isNotBlank(queryFilter.getSearchCode())) { if(StringUtils.isNotBlank(queryFilter.getSearchCode())) {
list.add(cb.equal(root.get("code") , queryFilter.getSearchCode())); list.add(cb.equal(root.get("code") , queryFilter.getSearchCode()));
} }
@@ -168,6 +168,10 @@ public class ConfigService {
Specification<CfgRoomFeatures> listSpec = (root, criteriaQuery, cb) -> { Specification<CfgRoomFeatures> listSpec = (root, criteriaQuery, cb) -> {
List<Predicate> list = new ArrayList<>(); List<Predicate> list = new ArrayList<>();
String category = queryFilter.getCategory(); String category = queryFilter.getCategory();
//TODO 对于这里 和Amy确认过之后 现在如果category是OTHER的话,直接去拿到OPERA的Special List By Corso 2026-10-07 用于修复
if (category!=null && Strings.CS.equals(category,"OTHER")) category = "OPERA";
list.add( list.add(
cb.or( cb.or(
cb.equal(root.get("category"), category) cb.equal(root.get("category"), category)
@@ -233,8 +237,8 @@ public class ConfigService {
resultList = getOtherCriteria( segmentId, sectionId, bookingTypeId, propertyId, roomId); resultList = getOtherCriteria( segmentId, sectionId, bookingTypeId, propertyId, roomId);
} }
if(!resultList.isEmpty()) { if(!resultList.isEmpty()||isDaylight) {
checkCriteriaBooking(resultList, playerId, userId, userName); checkCriteriaBooking(resultList, playerId, userId, userName, isDaylight?2:1);
} }
return resultList; return resultList;
@@ -509,7 +513,7 @@ public class ConfigService {
return resultList; return resultList;
} }
private Map<String,JSONObject> checkCriteriaBooking(Map<String,JSONObject> resultList,String playerId,String userId,String userName) throws Exception{ private Map<String,JSONObject> checkCriteriaBooking(Map<String,JSONObject> resultList,String playerId,String userId,String userName,int checkMode) throws Exception{
Date today = DateTimeUtil.getCurrentDateTime("yyyy-MM-dd"); Date today = DateTimeUtil.getCurrentDateTime("yyyy-MM-dd");
String maxDay = settingDao.getByKeys(SysConstants.MAX_ADVANCE_BOOKING_DAYS).getKeyValues(); String maxDay = settingDao.getByKeys(SysConstants.MAX_ADVANCE_BOOKING_DAYS).getKeyValues();
boolean enableProtection = Strings.CS.equals("1", settingDao.getByKeys(SysConstants.PROTECT_PERIOD_ENABLE).getKeyValues()); boolean enableProtection = Strings.CS.equals("1", settingDao.getByKeys(SysConstants.PROTECT_PERIOD_ENABLE).getKeyValues());
@@ -563,9 +567,12 @@ public class ConfigService {
while(checkInDate.getTime()<checkOutDate.getTime()) { while(checkInDate.getTime()<checkOutDate.getTime()) {
String getDate = DateTimeUtil.getDateByFormat(checkInDate, "yyyy-MM-dd"); String getDate = DateTimeUtil.getDateByFormat(checkInDate, "yyyy-MM-dd");
if(checkMode==2&&!resultList.containsKey(getDate)) {
resultList.put(getDate,newCalendarEntry(getDate));
}
if(resultList.containsKey(getDate)){ if(resultList.containsKey(getDate)){
JSONObject res = resultList.get(getDate); JSONObject res = resultList.get(getDate);
if(//StringUtils.isEmpty(book.getLastOperaStatus())|| if(
Strings.CS.equals(book.getLastOperaStatus(), "DUE_IN")|| Strings.CS.equals(book.getLastOperaStatus(), "DUE_IN")||
Strings.CS.equals(book.getLastOperaStatus(), "RESERVED")) { Strings.CS.equals(book.getLastOperaStatus(), "RESERVED")) {
res.put("reserved",1); res.put("reserved",1);
@@ -606,6 +613,9 @@ public class ConfigService {
} }
for(Date period:protectionPeriod) { for(Date period:protectionPeriod) {
String date = DateTimeUtil.getDateByFormat(period, "yyyy-MM-dd"); String date = DateTimeUtil.getDateByFormat(period, "yyyy-MM-dd");
if(checkMode==2&&!resultList.containsKey(date)) {
resultList.put(date,newCalendarEntry(date));
}
if(resultList.containsKey(date)){ if(resultList.containsKey(date)){
JSONObject res = resultList.get(date); JSONObject res = resultList.get(date);
res.put("protection",1); res.put("protection",1);
@@ -616,6 +626,16 @@ public class ConfigService {
return resultList; return resultList;
} }
//checkMode=2 时补充日历中缺失日期的默认条目,字段与 criteria 构造的条目保持一致
private JSONObject newCalendarEntry(String date) {
JSONObject res = new JSONObject();
res.put("bookDate",date);
res.put("isWaitlist",0);
res.put("sharer",0);
res.put("available",0);
return res;
}
public List<CfgSettings> listRoomSetting() { public List<CfgSettings> listRoomSetting() {
Sort sort = Sort.by(Direction.ASC, "keys"); Sort sort = Sort.by(Direction.ASC, "keys");
return settingDao.findAll(sort); return settingDao.findAll(sort);
@@ -85,8 +85,11 @@ public class MobileLoginController {
int loginTag = authService.checkLoginByLoginIdAndPasswordAndIp(userId, password, accessIp); int loginTag = authService.checkLoginByLoginIdAndPasswordAndIp(userId, password, accessIp);
if(loginTag>0) { if(loginTag>0) {
LoginUserInfo loginUser = new LoginUserInfo(); LoginUserInfo loginUser = new LoginUserInfo();
loginUser.setId(0L); BaseApiResponse<UserInfoApiRecord> serviceResult = mgmUserService.findUserInfoByUserId(userId);
if(serviceResult.isSuccess()) {
loginUser.setLoginId(userId); loginUser.setLoginId(userId);
loginUser.setGroupName(serviceResult.getData().getGroupName());
}
Token accessToken = JwtTokenUtil.generateTokenByLoginUser(request.getRequestURI(),loginUser, SysConstants.MOBILE_TOKEN_TYPE,false); Token accessToken = JwtTokenUtil.generateTokenByLoginUser(request.getRequestURI(),loginUser, SysConstants.MOBILE_TOKEN_TYPE,false);
userTokenService.saveToken(accessToken); userTokenService.saveToken(accessToken);
Token refreshToken = JwtTokenUtil.generateTokenByLoginUser(request.getRequestURI(),loginUser, SysConstants.MOBILE_TOKEN_TYPE,true); Token refreshToken = JwtTokenUtil.generateTokenByLoginUser(request.getRequestURI(),loginUser, SysConstants.MOBILE_TOKEN_TYPE,true);
@@ -171,6 +174,8 @@ public class MobileLoginController {
result.setRefreshToken(refreshToken.getToken()); result.setRefreshToken(refreshToken.getToken());
result.setUserData(userInfo); result.setUserData(userInfo);
result.setClientId(EncryptUtil.sha256(Base64Util.encode("mcrm_" + userId))); result.setClientId(EncryptUtil.sha256(Base64Util.encode("mcrm_" + userId)));
LogUtil.info(MobileLoginController.class,"UserId = "+result.getUserData()+",Token = "+result.getAccessToken());
}else { }else {
result.setSuccess(false); result.setSuccess(false);
result.setMessage(serviceResult.getMessage()); result.setMessage(serviceResult.getMessage());
@@ -0,0 +1,105 @@
package com.mgm.mcrm.authorization.controllers;
import com.mgm.mcrm.authorization.dtos.GetAuthTokenRequest;
import com.mgm.mcrm.authorization.dtos.GetAuthTokenResponse;
import com.mgm.mcrm.authorization.dtos.LoginUserInfo;
import com.mgm.mcrm.authorization.models.Token;
import com.mgm.mcrm.authorization.services.AuthorizationService;
import com.mgm.mcrm.authorization.services.UserTokenService;
import com.mgm.mcrm.authorization.utils.JwtTokenUtil;
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.utils.Base64Utils;
import com.mgm.mcrm.common.utils.EncryptUtil;
import com.mgm.mcrm.common.utils.LogUtil;
import com.mgm.mcrm.common.utils.NetworkUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.HtmlUtils;
import java.io.IOException;
@Tag(name = "Authorization", description = "APIs relate with ThirdParty authorization")
@RestController
@RequestMapping("/api")
public class ThirdPartyAuthorizationController {
private static final Logger logger = LoggerFactory.getLogger(ThirdPartyAuthorizationController.class);
@Resource
private AuthorizationService authService;
@Resource
private UserTokenService userTokenService;
@Operation(
summary = "Third Party Authorization",
description = "API to retrieve access token for third party caller, such as Service Button"
)
@ApiResponses({
@ApiResponse(responseCode = "200", description = "Access Token generated successful"),
@ApiResponse(responseCode = "401", description = "Authorization key not math")
})
@RequestMapping(value="/third_party/get_access_token", method = RequestMethod.POST, produces = "application/json;charset=UTF-8",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<BaseApiResponse<GetAuthTokenResponse>> getApiAccessToken(
HttpServletRequest request,
HttpServletResponse response,
@Parameter(description = "Third party requestor info", required = true) @Valid @RequestBody GetAuthTokenRequest requestData) throws IOException {
String authorizationKey = request.getHeader("Authorization");
String thirdPartyAccount = requestData.getRequesterId();
String origin = request.getHeader("Origin");
String sanitizedOrigin = NetworkUtil.sanitizeCRLF(origin);
if(SysCommon.isAllowOriginSource(sanitizedOrigin)) {
response.setHeader("Access-Control-Allow-Origin", NetworkUtil.sanitizeCRLF(sanitizedOrigin));
}else {
LogUtil.warn(ThirdPartyAuthorizationController.class, "Origin of ["+origin+"] is not allowed");
response.setHeader("Access-Control-Allow-Origin","");
//
String errorMessage = HtmlUtils.htmlEscape(("Origin of ["+origin+"] is not allowed"));
response.sendError(401, errorMessage);
}
if(authorizationKey!=null){
authorizationKey = authorizationKey.replace("Bearer ","").replace("bearer ","");
authorizationKey = EncryptUtil.sha256(authorizationKey);
}
if(authorizationKey!=null && authService.checkThirdPartyAuthorized(thirdPartyAccount, authorizationKey)){
LoginUserInfo thirdPartyUser = new LoginUserInfo();
thirdPartyUser.setLoginId(thirdPartyAccount);
thirdPartyUser.setGroupName("THIRD-PARTY");
Token accessToken = JwtTokenUtil.generateTokenByLoginUser(request.getRequestURI(),thirdPartyUser, SysConstants.THIRD_PARTY_TOKEN_TYPE,false);
userTokenService.saveToken(accessToken);
String encrypt = EncryptUtil.sha256(Base64Utils.encode("mcrm_"+thirdPartyAccount));
GetAuthTokenResponse getAuthTokenResponse = new GetAuthTokenResponse();
getAuthTokenResponse.setToken(accessToken.getToken());
getAuthTokenResponse.setClientId(encrypt);
BaseApiResponse<GetAuthTokenResponse> responseData = new BaseApiResponse<>();
responseData.setSuccess(true);
responseData.setCode("200");
responseData.setData(getAuthTokenResponse);
return ResponseEntity.status(HttpStatus.OK).body(responseData);
}else{
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null);
}
}
}
@@ -0,0 +1,15 @@
package com.mgm.mcrm.authorization.dtos;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
@Schema(description = "Request to get notification API access token")
public class GetAuthTokenRequest {
@Schema(description = "Requester ID of notification API caller")
@NotBlank(message = "Requester Id must not be empty")
private String requesterId;
}
@@ -0,0 +1,12 @@
package com.mgm.mcrm.authorization.dtos;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema
@Data
public class GetAuthTokenResponse {
private String token;
private String clientId;
}
@@ -1,9 +1,12 @@
package com.mgm.mcrm.authorization.dtos; package com.mgm.mcrm.authorization.dtos;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
@Data @Data
public class SsoLoginRequest { public class SsoLoginRequest {
@JsonProperty("SAMLResponse")
private String samlResponse; private String samlResponse;
private String idToken; private String idToken;
private String code; private String code;
@@ -21,6 +21,7 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull; import lombok.NonNull;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.apache.logging.log4j.util.Base64Util; import org.apache.logging.log4j.util.Base64Util;
import org.springframework.util.AntPathMatcher; import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.filter.OncePerRequestFilter;
@@ -58,6 +59,7 @@ public class JwtAuthFilter extends OncePerRequestFilter {
@NonNull FilterChain filterChain @NonNull FilterChain filterChain
) throws ServletException, IOException{ ) throws ServletException, IOException{
boolean validatePass = true; boolean validatePass = true;
String uri = request.getRequestURI();
try { try {
boolean refreshRequest = "/api/app/refresh_token".equals(request.getRequestURI()); boolean refreshRequest = "/api/app/refresh_token".equals(request.getRequestURI());
String token = request.getHeader(refreshRequest ? "RefreshToken" : "Authorization"); String token = request.getHeader(refreshRequest ? "RefreshToken" : "Authorization");
@@ -103,12 +105,20 @@ public class JwtAuthFilter extends OncePerRequestFilter {
if(clientId==null) { if(clientId==null) {
clientId=""; clientId="";
} }
LogUtil.info(JwtAuthFilter.class, "[preHandle] Pass Token:" + token);
LoginUserInfo user = JwtTokenUtil.parseUserFromToken(token); LoginUserInfo user = JwtTokenUtil.parseUserFromToken(token);
if(user!=null) { if(user!=null) {
String encrypt = EncryptUtil.sha256(Base64Util.encode("mcrm_"+user.getLoginId())); String encrypt = EncryptUtil.sha256(Base64Util.encode("mcrm_"+user.getLoginId()));
if(!clientId.equalsIgnoreCase(encrypt)) { if(!clientId.equalsIgnoreCase(encrypt)) {
sendErrorResponse(response,500, "Invalid Token"); sendErrorResponse(response,500, "Invalid Token");
validatePass=false; validatePass=false;
}else{
//-- Verify CMS token type
if(Strings.CS.startsWith(uri, "/api/web/") && dbToken.getTokenType()!=SysConstants.CMS_TOKEN_TYPE) {
LogUtil.info(JwtAuthFilter.class,"URL = " + uri);
sendErrorResponse(response,403, "Invalid Token Type");
validatePass=false;
}
} }
}else { }else {
LogUtil.info(JwtAuthFilter.class, "[preHandle] user null"); LogUtil.info(JwtAuthFilter.class, "[preHandle] user null");
@@ -133,13 +143,15 @@ public class JwtAuthFilter extends OncePerRequestFilter {
}else{ }else{
boolean canAccessIP = true; boolean canAccessIP = true;
String accessIp = NetworkUtil.getClientIpAddr(request); String accessIp = NetworkUtil.getClientIpAddr(request);
LogUtil.info(JwtAuthFilter.class, "[preHandle] accessIp: " + accessIp + "=----------------------------------");
if("INVALID_IP".equalsIgnoreCase(accessIp)){ if("INVALID_IP".equalsIgnoreCase(accessIp)){
sendErrorResponse(response,401, "Invalid IP in forward headers"); sendErrorResponse(response,401, "Invalid IP in forward headers");
validatePass = false; validatePass = false;
} }
boolean isInternal = NetworkUtil.isMatchInternal(accessIp); boolean isInternal = NetworkUtil.isMatchInternal(accessIp);
LogUtil.info(JwtAuthFilter.class, "[preHandle] isInternal: " + isInternal+"-------------------------------=");
if(!isInternal) { if(!isInternal) {
String uri = request.getRequestURI();
boolean isIgnoreUrl = false; boolean isIgnoreUrl = false;
for(String urlKey:ignoreCheckInternalUrl){ for(String urlKey:ignoreCheckInternalUrl){
if(uri.contains(urlKey)){ if(uri.contains(urlKey)){
@@ -0,0 +1,101 @@
package com.mgm.mcrm.authorization.interceptor;
import com.auth0.jwt.JWT;
import com.mgm.mcrm.authorization.services.SysGroupPermissionService;
import com.mgm.mcrm.common.annotation.security.VerifyPermission;
import com.mgm.mcrm.common.utils.LogUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Configuration
public class PermissionInterceptor implements HandlerInterceptor {
@Resource
private SysGroupPermissionService sysGroupPermissionService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {
if(isNeedVerifyPermission(object)){
try {
String uri = request.getRequestURI();
String token = request.getHeader("Authorization");
if (StringUtils.isNotBlank(token)) {
token = token.replace("Bearer ", "").replace("bearer ", "");
}
String method = request.getMethod();
if("OPTIONS".equalsIgnoreCase(method)) {
return true;
}else if(StringUtils.isNotBlank(token)) {
String groupName = JWT.decode(token).getClaim("group_name").asString();
if (!verifyPermission(object, groupName)) {
LogUtil.error(PermissionInterceptor.class, "[preHandle] No Permission for URL :" + uri);
response.sendError(403, "NO PERMISSION");
return false;
}
}
}
catch(Exception ex) {
LogUtil.error(PermissionInterceptor.class, "[preHandle] Permission Checking Exception Message:" + ex.getMessage());
response.sendError(500, ex.getMessage());
return false;
}
}
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
//--處理被調用時的邏輯
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
//--處理被調用后的邏輯
}
private boolean isNeedVerifyPermission(Object handler){
VerifyPermission annotation = null;
try {
if (handler instanceof HandlerMethod handlerMethod) {
annotation = handlerMethod.getMethodAnnotation(VerifyPermission.class);
if (annotation == null) {
annotation = handlerMethod.getBeanType().getAnnotation(VerifyPermission.class);
}
}
}catch(Exception ignore){}
return annotation!=null;
}
private boolean verifyPermission(Object handler, String groupName) {
if (!(handler instanceof HandlerMethod handlerMethod)) {
return true;
}
VerifyPermission annotation = handlerMethod.getMethodAnnotation(VerifyPermission.class);
if (annotation == null) {
annotation = handlerMethod.getBeanType().getAnnotation(VerifyPermission.class);
}
if (annotation == null) {
return true;
}
String[] permissionIds = annotation.permissionId();
if (permissionIds.length == 0) {
return true;
}
for (String permissionId : permissionIds) {
if (StringUtils.isNotBlank(permissionId) && sysGroupPermissionService.checkGroupPermission(groupName, permissionId)) {
return true;
}
}
return false;
}
}
@@ -30,4 +30,6 @@ public interface SysUserDao extends JpaRepository<SysUser, Long> {
@Query(value = "select count(1) as user_cnt from sys_users where upper(login_id) =?1 and password=?2 ",nativeQuery=true) @Query(value = "select count(1) as user_cnt from sys_users where upper(login_id) =?1 and password=?2 ",nativeQuery=true)
int countSysUserByLoginIdAndPassword(String loginId, String password); int countSysUserByLoginIdAndPassword(String loginId, String password);
SysUser findByLoginId(String thirdPartyAccount);
} }
@@ -1,7 +1,11 @@
package com.mgm.mcrm.authorization.services; package com.mgm.mcrm.authorization.services;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.mgm.mcrm.appsetting.services.SettingService; import com.mgm.mcrm.appsetting.services.SettingService;
import com.mgm.mcrm.authorization.models.SysUser; import com.mgm.mcrm.authorization.models.SysUser;
import com.mgm.mcrm.authorization.models.SysUserView;
import com.mgm.mcrm.authorization.models.Token;
import com.mgm.mcrm.authorization.repositories.SysGroupDataPermissionDao; import com.mgm.mcrm.authorization.repositories.SysGroupDataPermissionDao;
import com.mgm.mcrm.authorization.repositories.SysGroupPermissionDao; import com.mgm.mcrm.authorization.repositories.SysGroupPermissionDao;
import com.mgm.mcrm.authorization.repositories.SysRouterPermissionDao; import com.mgm.mcrm.authorization.repositories.SysRouterPermissionDao;
@@ -11,10 +15,13 @@ import com.mgm.mcrm.common.utils.LogUtil;
import com.mgm.mcrm.logging.models.SysLogLoginIp; import com.mgm.mcrm.logging.models.SysLogLoginIp;
import com.mgm.mcrm.logging.services.SysLogLoginIpService; import com.mgm.mcrm.logging.services.SysLogLoginIpService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.Strings;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.UUID;
@Service @Service
public class AuthorizationService { public class AuthorizationService {
@@ -156,4 +163,13 @@ public class AuthorizationService {
ipLog.setBanUntil(cal.getTime()); ipLog.setBanUntil(cal.getTime());
ipLog.setTryTimes(0); // 重置以便解封后计数 ipLog.setTryTimes(0); // 重置以便解封后计数
} }
public boolean checkThirdPartyAuthorized(String thirdPartyAccount, String authorizationKey) {
boolean isAuthorized = false;
SysUser thirdPartyUser = sysUserDao.findByLoginId(thirdPartyAccount);
if(thirdPartyUser!=null){
isAuthorized = Strings.CS.equals(authorizationKey, thirdPartyUser.getPassword());
}
return isAuthorized;
}
} }
@@ -27,11 +27,13 @@ import com.mgm.mcrm.common.dtos.mgm_api.UserInfoApiRecord;
import com.mgm.mcrm.common.dtos.mgm_api.UserInfoApiResult; import com.mgm.mcrm.common.dtos.mgm_api.UserInfoApiResult;
import com.mgm.mcrm.common.services.MGMEsbApiService; import com.mgm.mcrm.common.services.MGMEsbApiService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@Slf4j
@Service @Service
public class MgmUserService { public class MgmUserService {
@@ -97,6 +99,7 @@ public class MgmUserService {
}catch(Exception err) { }catch(Exception err) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage("Parse return data failed:"+err.getMessage()); result.setMessage("Parse return data failed:"+err.getMessage());
log.error("Parse return data failed", err);
} }
}else { }else {
@@ -203,9 +206,10 @@ public class MgmUserService {
private UserInfoApiRecord supplementInfoId(String userId,UserInfoApiRecord info) { private UserInfoApiRecord supplementInfoId(String userId,UserInfoApiRecord info) {
info.setCanViewCalendar(calendarPermissionMockEnabled); info.setCanViewCalendar(calendarPermissionMockEnabled);
// 待完善,有可能需要一层一层获得property,division,department,team // 待完善,有可能需要一层一层获得property,division,department,team
CfgProperties property = propertyDao.getByName(info.getProperty()); List<CfgProperties> property = propertyDao.getByName(info.getProperty());
if(property!=null) { if(property!=null) {
info.setPropertyId(property.getId()); info.setPropertyId(property.getFirst().getId());
} }
CfgBlocks block = blockDao.getByName(info.getBlock()); CfgBlocks block = blockDao.getByName(info.getBlock());
if(block!=null) { if(block!=null) {
@@ -15,6 +15,7 @@ import jakarta.servlet.http.HttpServletRequest;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
@@ -56,6 +57,9 @@ public class JwtTokenUtil {
Instant now = Instant.now(); Instant now = Instant.now();
Instant expDate = now.plus(Duration.ofMinutes(tokeExpiration)); Instant expDate = now.plus(Duration.ofMinutes(tokeExpiration));
String uuid = UUID.randomUUID().toString().replace("-",""); String uuid = UUID.randomUUID().toString().replace("-","");
user.setLoginId(Strings.CI.replace(user.getLoginId(),"@mgm.mo",""));
LogUtil.info(JwtTokenUtil.class,"User ID:"+user.getLoginId());
String tokenString = JWT.create() String tokenString = JWT.create()
.withIssuer(issueSource) .withIssuer(issueSource)
@@ -107,8 +111,13 @@ public class JwtTokenUtil {
}else { }else {
loginUser.setId(-1L); loginUser.setId(-1L);
} }
loginUser.setLoginId(decodeData.getClaim("login_id").asString());
String loginId = decodeData.getClaim("login_id").asString();
if(loginId!=null) loginId = StringUtils.replace(loginId, "@mgm.mo", "");
loginUser.setLoginId(loginId);
String groupName = decodeData.getClaim("group_name").asString(); String groupName = decodeData.getClaim("group_name").asString();
loginUser.setGroupName(groupName != null ? groupName : decodeData.getClaim("user_group").asString()); loginUser.setGroupName(groupName != null ? groupName : decodeData.getClaim("user_group").asString());
loginUser.setTokenUuid(decodeData.getId()); loginUser.setTokenUuid(decodeData.getId());
}catch(Exception err) { }catch(Exception err) {
@@ -0,0 +1,29 @@
package com.mgm.mcrm.basesetting.daylight.models;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name = "cfg_exception_comp_preset")
public class CfgExceptionCompPreset {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "exception_daylight_mapping_id", nullable = false)
private Long exceptionDaylightMappingId;
@Column(name = "dl_comp_preset_id", nullable = false, length = 100)
private String dlCompPresetId;
@Column(name = "comp_preset_content", length = 1000)
private String compPresetContent;
}
@@ -29,6 +29,24 @@ public class CfgExceptionDaylight implements Serializable {
private Long marketCodeId; private Long marketCodeId;
@Column(name="block_code_id") @Column(name="block_code_id")
private Long blockCodeId; private Long blockCodeId;
@Column(name = "approver", length = 255)
private String approver;
@Column(name = "comp_rule_category")
private Integer compRuleCategory;
@Column(name = "dl_comp_type_id", length = 100)
private String dlCompTypeId;
@Column(name = "comp_type_content", length = 1000)
private String compTypeContent;
@Column(name = "dl_payment_method_code_id", length = 100)
private String dlPaymentMethodCodeId;
@Column(name = "payment_method_code_content", length = 1000)
private String paymentMethodCodeContent;
@Column(name = "soft_limit", length = 50)
private String softLimit;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "exception_daylight_mapping_id", insertable = false, updatable = false)
@OrderBy("id ASC")
private List<CfgExceptionCompPreset> cfgCompPresetList;
@Column(name="created_at") @Column(name="created_at")
private Date createdAt; private Date createdAt;
@Column(name="created_by") @Column(name="created_by")
@@ -41,4 +59,8 @@ public class CfgExceptionDaylight implements Serializable {
private List<String> roomTypeIds; private List<String> roomTypeIds;
@Transient @Transient
private List<String> blockCodeIds; private List<String> blockCodeIds;
@Transient
private List<String> dlCompPresetIds;
@Transient
private List<String> compPresetContents;
} }
@@ -10,6 +10,7 @@ import org.hibernate.annotations.NotFoundAction;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.List;
import java.util.Set; import java.util.Set;
@Data @Data
@@ -23,7 +24,8 @@ import java.util.Set;
@NamedAttributeNode("rateCode"), @NamedAttributeNode("rateCode"),
@NamedAttributeNode("sourceCode"), @NamedAttributeNode("sourceCode"),
@NamedAttributeNode("marketCode"), @NamedAttributeNode("marketCode"),
@NamedAttributeNode("daylightRoomType") @NamedAttributeNode("daylightRoomType"),
@NamedAttributeNode("cfgCompPresetList")
} }
) )
public class CfgExceptionDaylightView implements Serializable { public class CfgExceptionDaylightView implements Serializable {
@@ -54,6 +56,26 @@ public class CfgExceptionDaylightView implements Serializable {
@Column(name="market_code_id") @Column(name="market_code_id")
private Long marketCodeId; private Long marketCodeId;
@Column(name = "approver", length = 255)
private String approver;
@Column(name = "comp_rule_category")
private Integer compRuleCategory;
@Column(name = "dl_comp_type_id", length = 100)
private String dlCompTypeId;
@Column(name = "comp_type_content", length = 1000)
private String compTypeContent;
@Column(name = "dl_payment_method_code_id", length = 100)
private String dlPaymentMethodCodeId;
@Column(name = "payment_method_code_content", length = 1000)
private String paymentMethodCodeContent;
@Column(name = "soft_limit", length = 50)
private String softLimit;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "exception_daylight_mapping_id", insertable = false, updatable = false)
@OrderBy("id ASC")
private List<CfgExceptionCompPreset> cfgCompPresetList;
@Column(name="created_at") @Column(name="created_at")
private Date createdAt; private Date createdAt;
@@ -47,4 +47,25 @@ public interface DaylightViewDao extends JpaRepository<CfgDaylightView, Long> {
@Param("bookingTypeId") Long bookingTypeId, @Param("bookingTypeId") Long bookingTypeId,
@Param("roomTypeId") Long roomTypeId @Param("roomTypeId") Long roomTypeId
); );
@Query("""
SELECT DISTINCT d.bookingTypeId
FROM CfgDaylightView d
JOIN d.daylightRoomType rt
JOIN d.marketCode mc
JOIN d.rateCode rc
WHERE d.sectionId = :sectionId
AND d.propertyId = :propertyId
AND rt.id = :roomTypeId
AND mc.code = :marketCode
AND rc.code = :rateCode
AND d.bookingTypeId IS NOT NULL
""")
List<Long> findBookingTypeIdsBySectionPropertyRoomTypeAndCodes(
@Param("sectionId") Long sectionId,
@Param("propertyId") Long propertyId,
@Param("roomTypeId") Long roomTypeId,
@Param("marketCode") String marketCode,
@Param("rateCode") String rateCode
);
} }
@@ -7,6 +7,8 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.EntityGraph; import org.springframework.data.jpa.repository.EntityGraph;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List; import java.util.List;
@@ -26,4 +28,42 @@ public interface ExceptionDaylightViewDao extends JpaRepository<CfgExceptionDayl
@EntityGraph(value = "graph.ExceptionDaylightMapping.fulldetails",type = EntityGraph.EntityGraphType.LOAD) @EntityGraph(value = "graph.ExceptionDaylightMapping.fulldetails",type = EntityGraph.EntityGraphType.LOAD)
List<CfgExceptionDaylightView> findByUserIdLikeAndPropertyIdAndBookingTypeId(String userId, Long propertyId, Long bookingTypeId); List<CfgExceptionDaylightView> findByUserIdLikeAndPropertyIdAndBookingTypeId(String userId, Long propertyId, Long bookingTypeId);
@EntityGraph(value = "graph.ExceptionDaylightMapping.fulldetails", type = EntityGraph.EntityGraphType.LOAD)
@Query("""
SELECT DISTINCT d
FROM CfgExceptionDaylightView d
JOIN d.daylightRoomType rt
WHERE d.userId = :userId
AND d.propertyId = :propertyId
AND d.bookingTypeId = :bookingTypeId
AND rt.id = :roomTypeId
""")
List<CfgExceptionDaylightView> findByUserPropertyBookingTypeRoomType(
@Param("userId") String userId,
@Param("propertyId") Long propertyId,
@Param("bookingTypeId") Long bookingTypeId,
@Param("roomTypeId") Long roomTypeId
);
@Query("""
SELECT DISTINCT d.bookingTypeId
FROM CfgExceptionDaylightView d
JOIN d.daylightRoomType rt
JOIN d.marketCode mc
JOIN d.rateCode rc
WHERE d.userId = :userId
AND d.propertyId = :propertyId
AND rt.id = :roomTypeId
AND mc.code = :marketCode
AND rc.code = :rateCode
AND d.bookingTypeId IS NOT NULL
""")
List<Long> findBookingTypeIdsByUserPropertyRoomTypeAndCodes(
@Param("userId") String userId,
@Param("propertyId") Long propertyId,
@Param("roomTypeId") Long roomTypeId,
@Param("marketCode") String marketCode,
@Param("rateCode") String rateCode
);
} }
@@ -199,17 +199,17 @@ public class DaylightApiService {
// 创建 reservation // 创建 reservation
if (jsonArray.size() == 1) { if (jsonArray.size() == 1) {
JSONObject resId = this.getResIdAndConfNo(jsonArray); JSONObject resultResIdAndConf = this.getResIdAndConfNo(jsonArray);
if (resId.isEmpty()) { if (resultResIdAndConf.isEmpty()) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage("Failed to create DayLight reservation, reservation id is empty"); result.setMessage("Failed to create DayLight reservation, reservation id is empty");
log.warn("Failed to create DayLight reservation, reservation id is empty, json: {}", jsonArray.toJSONString()); log.warn("Failed to create DayLight reservation, reservation id and confirmation no are empty, json: {}", jsonArray.toJSONString());
} else { } else {
result.setSuccess(true); result.setSuccess(true);
result.setData(resId); result.setData(resultResIdAndConf);
log.info("Create reservation successful, reservation id: {}", resId); log.info("Create reservation successful, reservation id and confirmation no json: {}", resultResIdAndConf);
} }
// 创建 reservation 并且创建了 profile // 创建 reservation 并且创建了 profile
@@ -1070,7 +1070,7 @@ public class DaylightApiService {
String url = "/api-gateway/aggregator/v1/reservations?pageNumber=1&pageSize=40&filter=profileId==" + profileId String url = "/api-gateway/aggregator/v1/reservations?pageNumber=1&pageSize=40&filter=profileId==" + profileId
+ ";(statusCode.code==DI,statusCode.code==RS,statusCode.code==DO,statusCode.code==IH,statusCode.code==CX)" + ";(statusCode.code==DI,statusCode.code==RS,statusCode.code==DO,statusCode.code==IH,statusCode.code==CX)"
// + ";departureDate=ge=" + currentDate // + ";departureDate=ge=" + currentDate
+ "&extend=PurchaseElements,CustomFields,Breakdown,DoorKeys&sort=-createdAt"; + "&extend=PurchaseElements,CustomFields,Breakdown,DoorKeys,Notes&sort=-createdAt";
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
try { try {
for (CfgProperties property : properties) { for (CfgProperties property : properties) {
@@ -1079,6 +1079,11 @@ public class DaylightApiService {
log.warn("[getBookingRecordByProfileId_Optimize] Skipping property with null/blank dlPropertyId, propertyName={}", property.getName()); log.warn("[getBookingRecordByProfileId_Optimize] Skipping property with null/blank dlPropertyId, propertyName={}", property.getName());
continue; continue;
} }
if (!Objects.equals(property.getDisplayType(), 1)) {
log.warn("[getBookingRecordByProfileId_Optimize] Skipping property because the displayType is disabled, propertyName={}", property.getName());
continue;
}
Header[] headers = HttpHeaderBuilder.custom() Header[] headers = HttpHeaderBuilder.custom()
.contentType("application/json") .contentType("application/json")
.ac_property_id(dlPropertyId) .ac_property_id(dlPropertyId)
@@ -1113,6 +1118,28 @@ public class DaylightApiService {
JSONObject bookingRes = bookings.getJSONObject(i); JSONObject bookingRes = bookings.getJSONObject(i);
BookingDto booking = new BookingDto(); BookingDto booking = new BookingDto();
JSONObject sc = bookingRes.getJSONObject("statusCode");
String daylightStatus = "CX".equalsIgnoreCase(sc.getString("code"))
? "CANCELED"
: EnumBookingStatus.getStatusByDaylightStatus(sc.getString("description"));
booking.setLastOperaStatus(daylightStatus);
booking.setApproveStatus("CANCELED".equalsIgnoreCase(daylightStatus) ? "C" : "N");
// 取消记录只保留本地匹配和状态同步需要的信息。
if ("CANCELED".equalsIgnoreCase(daylightStatus)) {
booking.setDlReservationId(bookingRes.getString("id"));
booking.setConfirmationNo(bookingRes.getString("confirmationNumber"));
booking.setDlPropertyId(dlPropertyId);
booking.setPropertyId(propertyId);
booking.setDataTime(currentTime);
JSONArray externalIds = bookingRes.getJSONArray("externalIds");
if (CollectionUtils.isNotEmpty(externalIds)) {
booking.setDlExternalNo(externalIds.getJSONObject(0).getString("number"));
}
bookingList.add(booking);
continue;
}
Date checkinDate = DateTimeUtil.getDateFromString(bookingRes.getString("arrivalDate"),"yyyy-MM-dd"); Date checkinDate = DateTimeUtil.getDateFromString(bookingRes.getString("arrivalDate"),"yyyy-MM-dd");
Date checkoutDate = DateTimeUtil.getDateFromString(bookingRes.getString("departureDate"),"yyyy-MM-dd"); Date checkoutDate = DateTimeUtil.getDateFromString(bookingRes.getString("departureDate"),"yyyy-MM-dd");
@@ -1162,13 +1189,6 @@ public class DaylightApiService {
booking.setDlBlockId(bookingRes.getString("blockId")); booking.setDlBlockId(bookingRes.getString("blockId"));
booking.setPropertyId(propertyId); booking.setPropertyId(propertyId);
JSONObject sc = bookingRes.getJSONObject("statusCode");
booking.setLastOperaStatus(EnumBookingStatus.getStatusByDaylightStatus(sc.getString("description").toUpperCase()));
String approveStatus = "CANCELED".equalsIgnoreCase(booking.getLastOperaStatus()) ? "C" : "N";
booking.setApproveStatus(approveStatus);
JSONObject embedded = bookingRes.getJSONObject("_embedded"); JSONObject embedded = bookingRes.getJSONObject("_embedded");
if (embedded == null) { if (embedded == null) {
log.warn("[convertBookingDtoList] _embedded is null for reservation id={}, confirmationNo={}, dlPropertyId={}", log.warn("[convertBookingDtoList] _embedded is null for reservation id={}, confirmationNo={}, dlPropertyId={}",
@@ -1242,6 +1262,20 @@ public class DaylightApiService {
} }
} }
} }
JSONObject noteJSON = embedded.getJSONObject("notes");
if (noteJSON != null) {
JSONArray notes = noteJSON.getJSONArray("results");
if (CollectionUtils.isNotEmpty(notes)) {
for (int j = 0; j < notes.size(); j++) {
JSONObject note = notes.getJSONObject(j);
if (note != null && "CAS".equals(note.getString("typeCode"))) {
booking.setOperaComment(note.getString("content"));
break;
}
}
}
}
} }
String eta = bookingRes.getString("eta"); String eta = bookingRes.getString("eta");
@@ -1403,6 +1437,18 @@ public class DaylightApiService {
String endDate, String endDate,
CfgDaylightView daylightView, CfgDaylightView daylightView,
String miscCharge String miscCharge
) {
return updateDaylightCompRule(dlAccountId, dlPropertyId, startDate, endDate, daylightView, null, miscCharge);
}
public BaseApiResponse<String> updateDaylightCompRule(
String dlAccountId,
String dlPropertyId,
String startDate,
String endDate,
CfgDaylightView daylightView,
CfgExceptionDaylightView exceptionDaylightView,
String miscCharge
) { ) {
BaseApiResponse<String> result = new BaseApiResponse<>(); BaseApiResponse<String> result = new BaseApiResponse<>();
@@ -1421,7 +1467,8 @@ public class DaylightApiService {
String failedMessage = null; String failedMessage = null;
try { try {
ComplimentaryRuleLimits crl = getMiscChargeComplimentaryRuleLimits( ComplimentaryRuleLimits crl = getMiscChargeComplimentaryRuleLimits(
startDate, endDate, miscCharge, daylightView.getSoftLimit()); startDate, endDate, miscCharge,
exceptionDaylightView != null ? exceptionDaylightView.getSoftLimit() : daylightView.getSoftLimit());
for (int i = 0; i < compRuleList.size(); i++) { for (int i = 0; i < compRuleList.size(); i++) {
JSONObject one = compRuleList.getJSONObject(i); JSONObject one = compRuleList.getJSONObject(i);
@@ -1482,6 +1529,7 @@ public class DaylightApiService {
String startDate, String startDate,
String endDate, String endDate,
List<CfgDaylightView> daylightViewList, List<CfgDaylightView> daylightViewList,
List<CfgExceptionDaylightView> exceptionDaylightViewList,
String miscCharge String miscCharge
) { ) {
@@ -1489,7 +1537,14 @@ public class DaylightApiService {
log.info("Start to create complimentary rule"); log.info("Start to create complimentary rule");
String dlBookingTypeName = daylightViewList.getFirst().getBookingType().getName(); boolean useExceptionDaylight = CollectionUtils.isNotEmpty(exceptionDaylightViewList);
if (!useExceptionDaylight && CollectionUtils.isEmpty(daylightViewList)) {
result.setMessage("Daylight config is empty");
return result;
}
String dlBookingTypeName = useExceptionDaylight
? exceptionDaylightViewList.getFirst().getBookingType().getName()
: daylightViewList.getFirst().getBookingType().getName();
if ("IM".equalsIgnoreCase(dlBookingTypeName)) { if ("IM".equalsIgnoreCase(dlBookingTypeName)) {
result.setSuccess(false); result.setSuccess(false);
@@ -1512,26 +1567,42 @@ public class DaylightApiService {
CfgDaylightView daylightViewRoomOnly = null; CfgDaylightView daylightViewRoomOnly = null;
CfgDaylightView daylightView = null; CfgDaylightView daylightView = null;
CfgExceptionDaylightView exceptionDaylightViewRoomOnly = null;
CfgExceptionDaylightView exceptionDaylightView = null;
if (useExceptionDaylight) {
for (CfgExceptionDaylightView d : exceptionDaylightViewList) {
if (Objects.equals(d.getCompRuleCategory(), 1)) {
exceptionDaylightViewRoomOnly = d;
continue;
}
if (Objects.equals(d.getCompRuleCategory(), 2)) {
exceptionDaylightView = d;
}
}
} else {
for (CfgDaylightView d : daylightViewList) { for (CfgDaylightView d : daylightViewList) {
if (d.getCompRuleCategory() == 1) { if (Objects.equals(d.getCompRuleCategory(), 1)) {
daylightViewRoomOnly = d; daylightViewRoomOnly = d;
continue; continue;
} }
if (d.getCompRuleCategory() == 2) { if (Objects.equals(d.getCompRuleCategory(), 2)) {
daylightView = d; daylightView = d;
} }
} }
}
if (daylightViewRoomOnly == null && daylightView == null) { if (daylightViewRoomOnly == null && daylightView == null
&& exceptionDaylightViewRoomOnly == null && exceptionDaylightView == null) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage("Daylight view room only and daylight view are null"); result.setMessage("Daylight/Exception Daylight view room only and Daylight/Exception Daylight view are null");
return result; return result;
} }
if (compRuleCount >= 2) { if (compRuleCount >= 2) {
try { try {
return updateDaylightCompRule(dlAccountId, dlPropertyId, startDate, endDate, daylightView, miscCharge); return updateDaylightCompRule(dlAccountId, dlPropertyId, startDate, endDate,
daylightView, exceptionDaylightView, miscCharge);
} catch (Exception e) { } catch (Exception e) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage(e.getMessage()); result.setMessage(e.getMessage());
@@ -1547,13 +1618,18 @@ public class DaylightApiService {
} }
try { try {
if (useExceptionDaylight && exceptionDaylightViewRoomOnly == null) {
result.setMessage("Exception Daylight room only config is empty");
return result;
}
String url = "/api-gateway/cashiering/v1/accounts/" + dlAccountId + "/complimentary-rules"; String url = "/api-gateway/cashiering/v1/accounts/" + dlAccountId + "/complimentary-rules";
Header[] headers = HttpHeaderBuilder.custom() Header[] headers = HttpHeaderBuilder.custom()
.contentType("application/json") .contentType("application/json")
.ac_property_id(dlPropertyId) .ac_property_id(dlPropertyId)
.build(); .build();
String approver = daylightViewRoomOnly.getApprover(); String approver = useExceptionDaylight
? exceptionDaylightViewRoomOnly.getApprover() : daylightViewRoomOnly.getApprover();
boolean isVillaOrMansion = isVillaOrMansionRoom(roomName); boolean isVillaOrMansion = isVillaOrMansionRoom(roomName);
String requestorUserId = StringUtils.isNotEmpty(approver) && isVillaOrMansion ? userId String requestorUserId = StringUtils.isNotEmpty(approver) && isVillaOrMansion ? userId
: StringUtils.isNotEmpty(approver) ? approver : userId; : StringUtils.isNotEmpty(approver) ? approver : userId;
@@ -1578,9 +1654,10 @@ public class DaylightApiService {
RequestorApproverResponse requestor = requestorResponse.getData(); RequestorApproverResponse requestor = requestorResponse.getData();
RequestorApproverResponse approverData = approverResponse.getData(); RequestorApproverResponse approverData = approverResponse.getData();
if (createRoomOnlyCompRule && daylightViewRoomOnly != null) { if (createRoomOnlyCompRule && (daylightViewRoomOnly != null || exceptionDaylightViewRoomOnly != null)) {
CreateCompRuleRequest roomOnlyCompRuleRequest = buildRoomOnlyCompRuleRequest( CreateCompRuleRequest roomOnlyCompRuleRequest = buildRoomOnlyCompRuleRequest(
profileId, startDate, endDate, requestor, approverData, daylightViewRoomOnly,false); profileId, startDate, endDate, requestor, approverData,
daylightViewRoomOnly, exceptionDaylightViewRoomOnly, false);
BaseApiResponse<String> createDefaultResult = createCompRule(url, headers, roomOnlyCompRuleRequest); BaseApiResponse<String> createDefaultResult = createCompRule(url, headers, roomOnlyCompRuleRequest);
if (!createDefaultResult.isSuccess()) { if (!createDefaultResult.isSuccess()) {
return createDefaultResult; return createDefaultResult;
@@ -1589,7 +1666,7 @@ public class DaylightApiService {
if (createDaylightViewCompRule) { if (createDaylightViewCompRule) {
BaseApiResponse<CreateCompRuleRequest> daylightViewCompRuleRequest = buildDaylightViewCompRuleRequest( BaseApiResponse<CreateCompRuleRequest> daylightViewCompRuleRequest = buildDaylightViewCompRuleRequest(
profileId, startDate, endDate, daylightView, requestor, approverData, miscCharge); profileId, startDate, endDate, daylightView, exceptionDaylightView, requestor, approverData, miscCharge);
if (!daylightViewCompRuleRequest.isSuccess()) { if (!daylightViewCompRuleRequest.isSuccess()) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage(daylightViewCompRuleRequest.getMessage()); result.setMessage(daylightViewCompRuleRequest.getMessage());
@@ -1617,8 +1694,9 @@ public class DaylightApiService {
} }
static boolean isVillaOrMansionRoom(String roomName) { static boolean isVillaOrMansionRoom(String roomName) {
return StringUtils.equalsAnyIgnoreCase(StringUtils.substringBefore(roomName, "-"), return false;
"V1", "V2", "V2M", "V3", "S3", "M1", "M2", "M3"); // return StringUtils.equalsAnyIgnoreCase(StringUtils.substringBefore(roomName, "-"),
// "V1", "V2", "V2M", "V3", "S3", "M1", "M2", "M3");
} }
public BaseApiResponse<String> createDaylightNewRoomOnlyCompRule( public BaseApiResponse<String> createDaylightNewRoomOnlyCompRule(
@@ -1699,19 +1777,43 @@ public class DaylightApiService {
RequestorApproverResponse approver, RequestorApproverResponse approver,
CfgDaylightView daylightView, CfgDaylightView daylightView,
boolean setRuleLimits) { boolean setRuleLimits) {
return buildRoomOnlyCompRuleRequest(profileId, startDate, endDate, requestor, approver,
daylightView, null, setRuleLimits);
}
private CreateCompRuleRequest buildRoomOnlyCompRuleRequest(
String profileId,
String startDate,
String endDate,
RequestorApproverResponse requestor,
RequestorApproverResponse approver,
CfgDaylightView daylightView,
CfgExceptionDaylightView exceptionDaylightView,
boolean setRuleLimits) {
CreateCompRuleRequest crr = new CreateCompRuleRequest(); CreateCompRuleRequest crr = new CreateCompRuleRequest();
crr.setComplimentaryTypeId(daylightView.getDlCompTypeId()); crr.setComplimentaryTypeId(exceptionDaylightView != null
crr.setPaymentMethodTransactionCodeId(daylightView.getDlPaymentMethodCodeId()); ? exceptionDaylightView.getDlCompTypeId() : daylightView.getDlCompTypeId());
crr.setPaymentMethodTransactionCodeId(exceptionDaylightView != null
? exceptionDaylightView.getDlPaymentMethodCodeId() : daylightView.getDlPaymentMethodCodeId());
crr.setExecutive(false); crr.setExecutive(false);
crr.setDoNotIssueInvoice(false); crr.setDoNotIssueInvoice(false);
crr.setProfileId(profileId); crr.setProfileId(profileId);
if(setRuleLimits) crr.setComplimentaryRuleLimits(getComplimentaryRuleLimits(startDate, endDate)); if(setRuleLimits) crr.setComplimentaryRuleLimits(getComplimentaryRuleLimits(startDate, endDate));
String compPresetId;
if (exceptionDaylightView != null) {
List<CfgExceptionCompPreset> compPresetList = exceptionDaylightView.getCfgCompPresetList();
if (CollectionUtils.isEmpty(compPresetList) || compPresetList.getFirst() == null
|| StringUtils.isBlank(compPresetList.getFirst().getDlCompPresetId())) {
throw new IllegalArgumentException("Exception Daylight comp preset id is empty");
}
compPresetId = compPresetList.getFirst().getDlCompPresetId();
} else {
List<CfgCompPreset> compPresetList = compPresetDao.findAllByDaylightMappingId(daylightView.getId()); List<CfgCompPreset> compPresetList = compPresetDao.findAllByDaylightMappingId(daylightView.getId());
CfgCompPreset compPreset = compPresetList.getFirst(); compPresetId = compPresetList.getFirst().getDlCompPresetId();
}
crr.setComplimentaryAccountingPresetsIds(List.of(compPreset.getDlCompPresetId())); crr.setComplimentaryAccountingPresetsIds(List.of(compPresetId));
crr.setJustification(""); crr.setJustification("");
crr.setRequestorId(requestor.getId()); crr.setRequestorId(requestor.getId());
crr.setApproverId(approver.getId()); crr.setApproverId(approver.getId());
@@ -1724,26 +1826,30 @@ public class DaylightApiService {
String startDate, String startDate,
String endDate, String endDate,
CfgDaylightView daylightView, CfgDaylightView daylightView,
CfgExceptionDaylightView exceptionDaylightView,
RequestorApproverResponse requestor, RequestorApproverResponse requestor,
RequestorApproverResponse approver, RequestorApproverResponse approver,
String miscCharge) { String miscCharge) {
BaseApiResponse<CreateCompRuleRequest> result = new BaseApiResponse<>(); BaseApiResponse<CreateCompRuleRequest> result = new BaseApiResponse<>();
if (daylightView == null) { if (daylightView == null && exceptionDaylightView == null) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage("Daylight config is empty"); result.setMessage("Daylight config is empty");
log.error("Daylight config is empty"); log.error("Daylight config is empty");
return result; return result;
} }
if (StringUtils.isBlank(daylightView.getDlCompTypeId())) { String compTypeId = exceptionDaylightView != null ? exceptionDaylightView.getDlCompTypeId() : daylightView.getDlCompTypeId();
String paymentMethodCodeId = exceptionDaylightView != null
? exceptionDaylightView.getDlPaymentMethodCodeId() : daylightView.getDlPaymentMethodCodeId();
if (StringUtils.isBlank(compTypeId)) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage("Daylight comp type id is empty"); result.setMessage("Daylight comp type id is empty");
log.error("Daylight comp type id is empty"); log.error("Daylight comp type id is empty");
return result; return result;
} }
if (StringUtils.isBlank(daylightView.getDlPaymentMethodCodeId())) { if (StringUtils.isBlank(paymentMethodCodeId)) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage("Daylight payment method code id is empty"); result.setMessage("Daylight payment method code id is empty");
log.error("Daylight payment method code id is empty"); log.error("Daylight payment method code id is empty");
@@ -1751,18 +1857,27 @@ public class DaylightApiService {
} }
List<String> capIds = new ArrayList<>(); List<String> capIds = new ArrayList<>();
if (CollectionUtils.isEmpty(daylightView.getCfgCompPresetList())) { if (exceptionDaylightView != null ? CollectionUtils.isEmpty(exceptionDaylightView.getCfgCompPresetList())
: CollectionUtils.isEmpty(daylightView.getCfgCompPresetList())) {
result.setSuccess(false); result.setSuccess(false);
result.setMessage("Daylight comp preset id is empty"); result.setMessage("Daylight comp preset id is empty");
log.error("Daylight comp preset id is empty"); log.error("Daylight comp preset id is empty");
return result; return result;
} }
if (exceptionDaylightView != null) {
for (CfgExceptionCompPreset cfgCompPreset : exceptionDaylightView.getCfgCompPresetList()) {
if (cfgCompPreset != null && StringUtils.isNotBlank(cfgCompPreset.getDlCompPresetId())) {
capIds.add(cfgCompPreset.getDlCompPresetId());
}
}
} else {
for (CfgCompPreset cfgCompPreset : daylightView.getCfgCompPresetList()) { for (CfgCompPreset cfgCompPreset : daylightView.getCfgCompPresetList()) {
if (cfgCompPreset != null && StringUtils.isNotBlank(cfgCompPreset.getDlCompPresetId())) { if (cfgCompPreset != null && StringUtils.isNotBlank(cfgCompPreset.getDlCompPresetId())) {
capIds.add(cfgCompPreset.getDlCompPresetId()); capIds.add(cfgCompPreset.getDlCompPresetId());
} }
} }
}
List<String> distinctCapIds = new ArrayList<>(new HashSet<>(capIds)); List<String> distinctCapIds = new ArrayList<>(new HashSet<>(capIds));
@@ -1774,19 +1889,21 @@ public class DaylightApiService {
} }
CreateCompRuleRequest crr = new CreateCompRuleRequest(); CreateCompRuleRequest crr = new CreateCompRuleRequest();
crr.setComplimentaryTypeId(daylightView.getDlCompTypeId()); crr.setComplimentaryTypeId(compTypeId);
crr.setPaymentMethodTransactionCodeId(daylightView.getDlPaymentMethodCodeId()); crr.setPaymentMethodTransactionCodeId(paymentMethodCodeId);
crr.setExecutive(false); crr.setExecutive(false);
crr.setDoNotIssueInvoice(false); crr.setDoNotIssueInvoice(false);
crr.setProfileId(profileId); crr.setProfileId(profileId);
crr.setComplimentaryRuleLimits( crr.setComplimentaryRuleLimits(
getMiscChargeComplimentaryRuleLimits(startDate, endDate, miscCharge, daylightView.getSoftLimit()) getMiscChargeComplimentaryRuleLimits(startDate, endDate, miscCharge,
exceptionDaylightView != null ? exceptionDaylightView.getSoftLimit() : daylightView.getSoftLimit())
); );
crr.setComplimentaryAccountingPresetsIds(distinctCapIds); crr.setComplimentaryAccountingPresetsIds(distinctCapIds);
crr.setJustification(""); crr.setJustification("");
crr.setRequestorId(requestor.getId()); crr.setRequestorId(requestor.getId());
String paymentMethodCodeContent = daylightView.getPaymentMethodCodeContent(); String paymentMethodCodeContent = exceptionDaylightView != null
? exceptionDaylightView.getPaymentMethodCodeContent() : daylightView.getPaymentMethodCodeContent();
if (StringUtils.isNotBlank(paymentMethodCodeContent) && if (StringUtils.isNotBlank(paymentMethodCodeContent) &&
"Comp Settlement - Comp Room Incidentals Settlement".equalsIgnoreCase(paymentMethodCodeContent) "Comp Settlement - Comp Room Incidentals Settlement".equalsIgnoreCase(paymentMethodCodeContent)
@@ -1902,8 +2019,10 @@ public class DaylightApiService {
public BaseApiResponse<RequestorApproverResponse> getDaylightRequestorApproverByUserId(final String propertyId, final String userId) { public BaseApiResponse<RequestorApproverResponse> getDaylightRequestorApproverByUserId(final String propertyId, final String userId) {
BaseApiResponse<RequestorApproverResponse> serviceResult = new BaseApiResponse<>(); BaseApiResponse<RequestorApproverResponse> serviceResult = new BaseApiResponse<>();
log.info("getDaylightRequestorApproverByUserId, propertyId: {}, userId: {}", propertyId, userId);
try { try {
String url = "/api-gateway/resource-management/v1/resource?filter=code==" + userId + ";isActive==true"; String url = "/api-gateway/resource-management/v1/resource?filter=(isActive==true;code==" + userId + ")";
// 获取对应的值 // 获取对应的值
Header[] headers = HttpHeaderBuilder.custom() Header[] headers = HttpHeaderBuilder.custom()
.contentType("application/json") .contentType("application/json")
@@ -2274,9 +2393,11 @@ public class DaylightApiService {
HttpResult submitResult = httpService.sslPost(url, headers,params); HttpResult submitResult = httpService.sslPost(url, headers,params);
String responseBody = submitResult.getResult(); String responseBody = submitResult.getResult();
if (submitResult.getStatusCode() == 200 || submitResult.getStatusCode() == 201 || submitResult.getStatusCode() == 202) { if (submitResult.getStatusCode() == 200 || submitResult.getStatusCode() == 201) {
result.setSuccess(true); result.setSuccess(true);
result.setData(bookings); result.setData(bookings);
} else if (submitResult.getStatusCode() == 202) {
} else { } else {
JSONObject rootNode = JSON.parseObject(responseBody); JSONObject rootNode = JSON.parseObject(responseBody);
String errorStr; String errorStr;
@@ -45,4 +45,6 @@ public class CfgProperties implements Serializable {
@Column(name = "status") @Column(name = "status")
private int status; private int status;
@Column(name = "display_type")
private int displayType;
} }
@@ -16,16 +16,7 @@ import java.util.List;
public interface PropertyDao extends JpaRepository<CfgProperties, Long> { public interface PropertyDao extends JpaRepository<CfgProperties, Long> {
@Query(value="select * from cfg_properties with (nolock) where name=?1",nativeQuery=true) @Query(value="select * from cfg_properties with (nolock) where name=?1",nativeQuery=true)
CfgProperties getByName(String name); List<CfgProperties> getByName(String name);
@Query(value="select * from cfg_properties with (nolock) where hotel_code=?1",nativeQuery=true)
CfgProperties getByHotelCode(String hotelCode);
@Query(value="select * from cfg_properties with (nolock) where code=?1",nativeQuery=true)
CfgProperties getByCode(String code);
@Query(value="select * from cfg_properties with (nolock) where hotel_code=?1",nativeQuery=true)
CfgProperties findByHotelCode(String hotelCode);
@Query(value="select top(1) * from cfg_properties with (nolock) where hotel_code=?1 and category=?2", nativeQuery=true) @Query(value="select top(1) * from cfg_properties with (nolock) where hotel_code=?1 and category=?2", nativeQuery=true)
CfgProperties findByHotelCodeAndCategory(String hotelCode, String category); CfgProperties findByHotelCodeAndCategory(String hotelCode, String category);
@@ -33,11 +24,8 @@ public interface PropertyDao extends JpaRepository<CfgProperties, Long> {
@Query(value="select * from cfg_properties with (nolock) where dl_property_id=?1",nativeQuery=true) @Query(value="select * from cfg_properties with (nolock) where dl_property_id=?1",nativeQuery=true)
CfgProperties getByDlPropertyId(String propertyId); CfgProperties getByDlPropertyId(String propertyId);
@Query(value="select Top(1) * from cfg_properties with (nolock) where name like %?1%",nativeQuery=true) @Query(value="select Top(1) * from cfg_properties with (nolock) where name like %?1% and category=?2",nativeQuery=true)
CfgProperties getByLikeName(String name); CfgProperties findByLikeNameAndCategory(String name, String category);
@Query(value="select * from cfg_properties with (nolock) where name=?1 and category = 'DAYLIGHT'",nativeQuery=true)
CfgProperties getByPropertyNameDaylight(String propertyId);
List<CfgProperties> findAll(Specification<CfgProperties> spec); List<CfgProperties> findAll(Specification<CfgProperties> spec);
List<CfgProperties> findAll(Specification<CfgProperties> spec, Sort sort); List<CfgProperties> findAll(Specification<CfgProperties> spec, Sort sort);
@@ -54,4 +42,6 @@ public interface PropertyDao extends JpaRepository<CfgProperties, Long> {
List<CfgProperties> findByCategory(String category); List<CfgProperties> findByCategory(String category);
List<CfgProperties> findByCalendarNameIn(Collection<String> calendarNames); List<CfgProperties> findByCalendarNameIn(Collection<String> calendarNames);
CfgProperties findByNameAndCategory(String propertyName, String category);
} }
@@ -20,9 +20,11 @@ import com.mgm.mcrm.booking.dtos.search.*;
import com.mgm.mcrm.booking.models.Bookings; import com.mgm.mcrm.booking.models.Bookings;
import com.mgm.mcrm.booking.models.BookingsView; import com.mgm.mcrm.booking.models.BookingsView;
import com.mgm.mcrm.booking.models.GamingData; import com.mgm.mcrm.booking.models.GamingData;
import com.mgm.mcrm.booking.repositories.BookingTypeDao;
import com.mgm.mcrm.booking.services.*; import com.mgm.mcrm.booking.services.*;
import com.mgm.mcrm.booking.services.mockup.BookingServiceMockup; import com.mgm.mcrm.booking.services.mockup.BookingServiceMockup;
import com.mgm.mcrm.common.annotation.logging.OperationLog; import com.mgm.mcrm.common.annotation.logging.OperationLog;
import com.mgm.mcrm.common.annotation.security.VerifyPermission;
import com.mgm.mcrm.common.constants.SysCommon; import com.mgm.mcrm.common.constants.SysCommon;
import com.mgm.mcrm.common.constants.SysConstants; import com.mgm.mcrm.common.constants.SysConstants;
import com.mgm.mcrm.common.dtos.BaseApiResponse; import com.mgm.mcrm.common.dtos.BaseApiResponse;
@@ -37,6 +39,7 @@ import com.mgm.mcrm.common.utils.DateTimeUtil;
import com.mgm.mcrm.common.utils.ExcelUtils; import com.mgm.mcrm.common.utils.ExcelUtils;
import com.mgm.mcrm.common.utils.LogUtil; import com.mgm.mcrm.common.utils.LogUtil;
import com.mgm.mcrm.common.utils.mockup.AjaxResultMockup; import com.mgm.mcrm.common.utils.mockup.AjaxResultMockup;
import com.mgm.mcrm.logging.services.SysBookingCacheService;
import com.mgm.mcrm.player.services.PlayerService; import com.mgm.mcrm.player.services.PlayerService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
@@ -88,6 +91,11 @@ public class BookingController {
@Resource @Resource
private SysGroupPermissionService sysGroupPermissionService; private SysGroupPermissionService sysGroupPermissionService;
@Resource
private SysBookingCacheService sysBookingCacheService;
@Autowired
private BookingTypeDao bookingTypeDao;
@RequestMapping(value = "/app/booking/get_bookings_by_nameId", method = RequestMethod.POST, produces = "application/json;charset=UTF-8",consumes = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/app/booking/get_bookings_by_nameId", method = RequestMethod.POST, produces = "application/json;charset=UTF-8",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<BaseApiResponse<Object>> getBookingsByNameId(HttpServletRequest request, public ResponseEntity<BaseApiResponse<Object>> getBookingsByNameId(HttpServletRequest request,
@@ -167,16 +175,9 @@ public class BookingController {
//--get group permissions //--get group permissions
boolean viewBooking = boolean viewBooking =
sysGroupPermissionService.checkGroupPermission(groupName, SysConstants.PERMISSION_APP_VIEW_BOOKING); sysGroupPermissionService.checkGroupPermission(groupName, SysConstants.PERMISSION_APP_VIEW_BOOKING);
boolean isMock = sysSettingService.isMockReplicate();
isMock = false;
viewBooking = true;
List<BookingsView> list; List<BookingsView> list;
if(isMock) {
list = bookingServiceMockup.getBookingByConfirmationNoMock(conf);
}else {
list = bookingService.getBookingByConfirmationNo(conf); list = bookingService.getBookingByConfirmationNo(conf);
}
if(!list.isEmpty() && StringUtils.isNotEmpty(userId)) { if(!list.isEmpty() && StringUtils.isNotEmpty(userId)) {
BaseApiResponse<PlayerProfileEntry> findPlayerResult = BaseApiResponse<PlayerProfileEntry> findPlayerResult =
playerService.findPlayerProfileByPlayerIdAndUserId(list.getFirst().getPlayerId(), userId); playerService.findPlayerProfileByPlayerIdAndUserId(list.getFirst().getPlayerId(), userId);
@@ -226,7 +227,7 @@ public class BookingController {
if(findPlayerProfileResult.isSuccess()) { if(findPlayerProfileResult.isSuccess()) {
PlayerProfileEntry profile = findPlayerProfileResult.getData(); PlayerProfileEntry profile = findPlayerProfileResult.getData();
Integer code = profile.getCodedFlag(); Integer code = profile.getCodedFlag();
viewBooking = true; // viewBooking = true;
if(code==1 && viewBooking) { if(code==1 && viewBooking) {
result.setSuccess(true); result.setSuccess(true);
result.setData(list); result.setData(list);
@@ -277,10 +278,10 @@ public class BookingController {
if(Strings.CS.equals(per.getId(), "10001_02") ) createBooking = true; if(Strings.CS.equals(per.getId(), "10001_02") ) createBooking = true;
} }
} }
createBooking = true; // createBooking = true;
String playerId = booking.getPlayerId(); String playerId = booking.getPlayerId();
BaseApiResponse<PlayerProfileEntry> findPlayerResult = playerService.findPlayerProfileByPlayerIdAndUserId(playerId, userId); BaseApiResponse<PlayerProfileEntry> findPlayerResult = playerService.findPlayerProfileByPlayerIdAndUserId(playerId, userId);
boolean testDaylight = true;
if(findPlayerResult.isSuccess()) { if(findPlayerResult.isSuccess()) {
PlayerProfileEntry profile = findPlayerResult.getData(); PlayerProfileEntry profile = findPlayerResult.getData();
Integer code = profile.getCodedFlag(); Integer code = profile.getCodedFlag();
@@ -322,15 +323,14 @@ public class BookingController {
BaseApiResponse<List<Bookings>> result = new BaseApiResponse<>(); BaseApiResponse<List<Bookings>> result = new BaseApiResponse<>();
result.setRequestData(booking); result.setRequestData(booking);
//--get group permissions //--get group permissions
//TODO Test
boolean editBooking = false; boolean editBooking = false;
// List<SysRouterPermission> userPermissions = sysGroupPermissionService.getRouterPermissionsByGroupName(groupName); List<SysRouterPermission> userPermissions = sysGroupPermissionService.getRouterPermissionsByGroupName(groupName);
// if(!userPermissions.isEmpty()) { if(!userPermissions.isEmpty()) {
// for(SysRouterPermission per:userPermissions) { for(SysRouterPermission per:userPermissions) {
// if(Strings.CS.equals(per.getId(), "10001_02") ) editBooking = true; if(Strings.CS.equals(per.getId(), "10001_02") ) editBooking = true;
// } }
// } }
editBooking = true; // editBooking = true;
//TODO Test //TODO Test
String playerId = booking.getPlayerId(); String playerId = booking.getPlayerId();
BaseApiResponse<PlayerProfileEntry> findPlayerResult = playerService.findPlayerProfileByPlayerIdAndUserId(playerId, userId); BaseApiResponse<PlayerProfileEntry> findPlayerResult = playerService.findPlayerProfileByPlayerIdAndUserId(playerId, userId);
@@ -465,6 +465,9 @@ public class BookingController {
String checkOutDate = bookingService.getSearchRecordCheckOutDate(currentDay); String checkOutDate = bookingService.getSearchRecordCheckOutDate(currentDay);
List<BookingDto> operaResult = new ArrayList<>(); List<BookingDto> operaResult = new ArrayList<>();
List<BookingDto> daylightResult = new ArrayList<>(); List<BookingDto> daylightResult = new ArrayList<>();
boolean isLoadDaylightFromCache = sysBookingCacheService.isDaylightBookingCacheValid(playerId);
String daylightProfileId = sysBookingCacheService.getDaylightProfileMappingFromCache(playerId);
if(StringUtils.isBlank(daylightProfileId)){
//去Daylight查ProfileId //去Daylight查ProfileId
stepStartTime = System.currentTimeMillis(); stepStartTime = System.currentTimeMillis();
BaseApiResponse<List<ProfileDetailResponse>> profileResult = daylightApiService.dayLightGetProfileByPlayerId(playerId); BaseApiResponse<List<ProfileDetailResponse>> profileResult = daylightApiService.dayLightGetProfileByPlayerId(playerId);
@@ -472,10 +475,23 @@ public class BookingController {
if (profileResult.isSuccess()) { if (profileResult.isSuccess()) {
//Daylight存在 则去Daylight查Record 在Daylight不存在的话 跳过 //Daylight存在 则去Daylight查Record 在Daylight不存在的话 跳过
ProfileDetailResponse profileDetailResponse = returnData.getFirst(); ProfileDetailResponse profileDetailResponse = returnData.getFirst();
daylightResult = daylightApiService.getBookingRecordByProfileId_Optimize(profileDetailResponse.getId(), playerId); daylightProfileId = profileDetailResponse.getId();
if(StringUtils.isNotBlank(daylightProfileId)){
sysBookingCacheService.updateDaylightProfileMapping(playerId, daylightProfileId);
}
} else { } else {
LogUtil.warn(BookingService.class, "[recordSearch] Daylight profile lookup failed, message=" + profileResult.getMessage() + ", playerId=" + playerId); LogUtil.warn(BookingService.class, "[recordSearch] Daylight profile lookup failed, message=" + profileResult.getMessage() + ", playerId=" + playerId);
} }
}
if(StringUtils.isNotBlank(daylightProfileId) && !isLoadDaylightFromCache){
LogUtil.info(BookingService.class, "[recordSearch] Load Daylight booking by call API, playerId=" + playerId +" profile Id:"+daylightProfileId);
daylightResult = daylightApiService.getBookingRecordByProfileId_Optimize(daylightProfileId, playerId);
sysBookingCacheService.updateDaylightBookingCacheLog(playerId);
}else if(isLoadDaylightFromCache){
//-- 查找出user 在DB 里的所有daylight类型的 DB booking
LogUtil.info(BookingService.class, "[recordSearch] Load Daylight booking from cache DB, playerId=" + playerId +" profile Id:"+daylightProfileId);
daylightResult = bookingService.getSearchPlayerDaylightDbRecord(startDate, checkOutDate, playerId);
}
LogUtil.info(BookingService.class, "[recordSearch] getBookingsByNameID:"); LogUtil.info(BookingService.class, "[recordSearch] getBookingsByNameID:");
LogUtil.info(BookingController.class, "[recordSearch] getDaylightBookings resultSize:" + daylightResult.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms"); LogUtil.info(BookingController.class, "[recordSearch] getDaylightBookings resultSize:" + daylightResult.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
stepStartTime = System.currentTimeMillis(); stepStartTime = System.currentTimeMillis();
@@ -496,6 +512,7 @@ public class BookingController {
LogUtil.info(BookingController.class, "[recordSearch] getBookingsByNameID resultSize:" + operaResult.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms"); LogUtil.info(BookingController.class, "[recordSearch] getBookingsByNameID resultSize:" + operaResult.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
if (!daylightResult.isEmpty()) { if (!daylightResult.isEmpty()) {
if(!isLoadDaylightFromCache){
//将Daylight Result 合并至DB //将Daylight Result 合并至DB
LogUtil.info(BookingService.class,"[recordSearch] before mergeDaylightRecordFromDB_Optimize, playerId=" LogUtil.info(BookingService.class,"[recordSearch] before mergeDaylightRecordFromDB_Optimize, playerId="
+ playerId + ", daylightResult.size=" + daylightResult.size()); + playerId + ", daylightResult.size=" + daylightResult.size());
@@ -506,8 +523,10 @@ public class BookingController {
bookingService.syncDaylightMergeBookingToDbAndPopulateIds_Optimize(dbDaylightResults); bookingService.syncDaylightMergeBookingToDbAndPopulateIds_Optimize(dbDaylightResults);
LogUtil.info(BookingController.class, "[recordSearch] syncDaylightDatabase resultSize:" + dbDaylightResults.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms"); LogUtil.info(BookingController.class, "[recordSearch] syncDaylightDatabase resultSize:" + dbDaylightResults.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
dbDaylightResults.removeIf(item -> "CANCELED".equalsIgnoreCase(item.getLastOperaStatus())); dbDaylightResults.removeIf(item -> "CANCELED".equalsIgnoreCase(item.getLastOperaStatus()));
allPropertiesResults.addAll(dbDaylightResults); allPropertiesResults.addAll(dbDaylightResults);
} else{
allPropertiesResults.addAll(daylightResult);
}
} else { } else {
LogUtil.warn(BookingService.class,"[recordSearch] daylightResult is empty, skipping Daylight merge"); LogUtil.warn(BookingService.class,"[recordSearch] daylightResult is empty, skipping Daylight merge");
} }
@@ -654,6 +673,15 @@ public class BookingController {
continue; continue;
} }
if (Strings.CS.equals(iPro.getLastOperaStatus(), "NO_SHOW")
|| Strings.CS.equals(iPro.getLastOperaStatus(), "CHECKED_OUT")) {
LogUtil.info(BookingService.class, "[recordSearch] FILTERED terminalStatus: id=" + iPro.getId()
+ ", confNo=" + iPro.getConfirmationNo() + ", approveStatus=" + iPro.getApproveStatus()
+ ", lastOperaStatus=" + iPro.getLastOperaStatus());
allPropertiesResults.remove(i);
continue;
}
if (Strings.CS.equals("C", iPro.getApproveStatus())) { if (Strings.CS.equals("C", iPro.getApproveStatus())) {
// LogUtil.info(BookingService.class, "[recordSearch] FILTERED approveStatus=C: id=" + iPro.getId() // LogUtil.info(BookingService.class, "[recordSearch] FILTERED approveStatus=C: id=" + iPro.getId()
// + ", confNo=" + iPro.getConfirmationNo() + ", lastOperaStatus=" + iPro.getLastOperaStatus()); // + ", confNo=" + iPro.getConfirmationNo() + ", lastOperaStatus=" + iPro.getLastOperaStatus());
@@ -672,7 +700,7 @@ public class BookingController {
//remove yesterday booking //remove yesterday booking
//只过滤「checkin<今天 && checkout<今天」的过去预订(即未入住就过期的 no-show 候选) //只过滤「checkin<今天 && checkout<今天」的过去预订(即未入住就过期的 no-show 候选)
//对于在住中的预订(checkin<今天 但 checkout>=今天),即使状态是 RESERVED/DUE_IN 也要展示 //对于在住中的预订(checkin<今天 但 checkout>=今天),即使状态是 RESERVED/DUE_IN 也要展示
//NO_SHOW / CANCELED 等终态状态由上面的规则(approveStatus=C / lastOperaStatus=CANCELED)处理 //NO_SHOW / CHECKED_OUT 由上面的 terminalStatus 规则处理,CANCELED 由 approveStatus=C / lastOperaStatus=CANCELED 处理
if(iPro.getCheckinDate().getTime()<curoffDate.getTime() if(iPro.getCheckinDate().getTime()<curoffDate.getTime()
&& (iPro.getCheckoutDate()==null || iPro.getCheckoutDate().getTime()<curoffDate.getTime()) && (iPro.getCheckoutDate()==null || iPro.getCheckoutDate().getTime()<curoffDate.getTime())
&& (Strings.CS.equals(iPro.getLastOperaStatus(), "RESERVED")|| && (Strings.CS.equals(iPro.getLastOperaStatus(), "RESERVED")||
@@ -696,6 +724,7 @@ public class BookingController {
return allPropertiesResults; return allPropertiesResults;
} }
@VerifyPermission(permissionId = {"00501_01", "00401_01"})
@RequestMapping(value = "/web/booking/get_page", produces = "application/json;charset=UTF-8",consumes = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/web/booking/get_page", produces = "application/json;charset=UTF-8",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<BaseApiResponse<DataTableResult<BookingsView>>> getBookingByPage( public ResponseEntity<BaseApiResponse<DataTableResult<BookingsView>>> getBookingByPage(
HttpServletRequest request, HttpServletRequest request,
@@ -709,6 +738,12 @@ public class BookingController {
queryFilter.setPermissionId(""); queryFilter.setPermissionId("");
}else if(StringUtils.isNotBlank(loginUser.getGroupName())) { }else if(StringUtils.isNotBlank(loginUser.getGroupName())) {
groupName = loginUser.getGroupName(); groupName = loginUser.getGroupName();
if (!StringUtils.isNotBlank(groupName)) {
BaseApiResponse<UserInfoApiRecord> serviceResult = mgmUserService.findUserInfoByUserId(loginUser.getLoginId());
if(serviceResult.isSuccess()) {
loginUser.setGroupName(serviceResult.getData().getGroupName());
}
}
} }
} }
queryFilter.setPermissionGroup(groupName); queryFilter.setPermissionGroup(groupName);
@@ -746,6 +781,7 @@ public class BookingController {
return result; return result;
} }
@VerifyPermission(permissionId = {"00501_01", "00401_01", "00402_01"})
@RequestMapping(value = "/web/bookings/search", method = RequestMethod.POST, produces = "application/json;charset=UTF-8",consumes = MediaType.APPLICATION_JSON_VALUE) @RequestMapping(value = "/web/bookings/search", method = RequestMethod.POST, produces = "application/json;charset=UTF-8",consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<BookingsView>> webRecordSearch(HttpServletRequest request, @RequestBody WebRecordSearchRequest params) throws Exception { public ResponseEntity<List<BookingsView>> webRecordSearch(HttpServletRequest request, @RequestBody WebRecordSearchRequest params) throws Exception {
// requireAnyWebPermission(request, "00501_01", "00401_01", "00402_01"); // requireAnyWebPermission(request, "00501_01", "00401_01", "00402_01");
@@ -825,6 +861,7 @@ public class BookingController {
return allPropertiesResults; return allPropertiesResults;
} }
@VerifyPermission(permissionId = {"00402_07"})
@RequestMapping(value = "/web/other_booking/import_batch", method = RequestMethod.POST) @RequestMapping(value = "/web/other_booking/import_batch", method = RequestMethod.POST)
public ResponseEntity<BaseApiResponse<ValidateResult>> batchImportRows(HttpServletRequest request, HttpServletResponse response, public ResponseEntity<BaseApiResponse<ValidateResult>> batchImportRows(HttpServletRequest request, HttpServletResponse response,
@RequestBody(required=false) List<OtherBookingImportRow> importRows) throws Exception{ @RequestBody(required=false) List<OtherBookingImportRow> importRows) throws Exception{
@@ -843,6 +880,7 @@ public class BookingController {
return ResponseEntity.status(HttpStatus.OK).body(result); return ResponseEntity.status(HttpStatus.OK).body(result);
} }
@VerifyPermission(permissionId = {"00402_07"})
@RequestMapping(value = "/web/other_booking/upload_excel", method = RequestMethod.POST) @RequestMapping(value = "/web/other_booking/upload_excel", method = RequestMethod.POST)
public ResponseEntity<BaseApiResponse<ValidateResult>> uploadExcel(HttpServletRequest request, HttpServletResponse response, public ResponseEntity<BaseApiResponse<ValidateResult>> uploadExcel(HttpServletRequest request, HttpServletResponse response,
@RequestBody(required=false) MultipartFile[] files) throws Exception{ @RequestBody(required=false) MultipartFile[] files) throws Exception{
@@ -873,6 +911,7 @@ public class BookingController {
return ResponseEntity.status(HttpStatus.OK).body(result); return ResponseEntity.status(HttpStatus.OK).body(result);
} }
@VerifyPermission(permissionId = {"00401_09"})
@RequestMapping(value = "/web/booking/get_gaming_data", produces = "application/json;charset=UTF-8", method = RequestMethod.POST) @RequestMapping(value = "/web/booking/get_gaming_data", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
public ResponseEntity<BaseApiResponse<List<String>>> getGamingData(HttpServletRequest request, public ResponseEntity<BaseApiResponse<List<String>>> getGamingData(HttpServletRequest request,
@RequestBody(required=true) BookingQueryRequest queryFilter) throws Exception { @RequestBody(required=true) BookingQueryRequest queryFilter) throws Exception {
@@ -250,6 +250,8 @@ public class BookingsView implements Serializable {
private String bookingApprovalReason; private String bookingApprovalReason;
@Column(name="source_code") @Column(name="source_code")
private String sourceCode; private String sourceCode;
@Column(name = "category")
private String category;
@Transient @Transient
private String status; private String status;
@@ -62,6 +62,22 @@ public interface BookingViewDao extends JpaRepository<BookingsView, Long> {
@Param("checkout_date") String checkoutDate @Param("checkout_date") String checkoutDate
); );
@Query(value = "select * from view_booking where player_id = :player_id "
+ "and checkin_date >= :checkin_date "
+ "and checkout_date <= :checkout_date "
+ "and checkout_date >= CAST(GETDATE() AS DATE) "
+ "and approve_status in ('N','C') "
+ "and category = 'DAYLIGHT' "
+ "and (last_opera_status not in ('CHECKED_OUT','NO_SHOW') or last_opera_status is null) "
+ "and revision_of is null "
+ "and segment_id is null",
nativeQuery = true)
List<BookingsView> findDaylightDbRecord(
@Param("player_id") String playerId,
@Param("checkin_date") String checkinDate,
@Param("checkout_date") String checkoutDate
);
@Query(value="select * from view_booking where confirmation_no=?1 and approve_status not in('WC','WF','WE') and player_id is not null",nativeQuery=true) @Query(value="select * from view_booking where confirmation_no=?1 and approve_status not in('WC','WF','WE') and player_id is not null",nativeQuery=true)
List<BookingsView> findBookingByConfirmationNo(String conf); List<BookingsView> findBookingByConfirmationNo(String conf);
@@ -329,7 +329,14 @@ public class BookingService {
booking.setBookingTypeId(bookingTypeId); booking.setBookingTypeId(bookingTypeId);
booking.setMember(JSONObject.toJSONString(member)); booking.setMember(JSONObject.toJSONString(member));
booking.setCategory(property.getCategory()); booking.setCategory(property.getCategory());
if (StringUtils.isNotBlank(sectionName)) {
booking.setSectionName(sectionName); booking.setSectionName(sectionName);
} else {
Bookings finalBooking = booking;
sectionDao.findById(sectionId).ifPresent(section -> {
finalBooking.setSectionName(section.getName());
});
}
booking.setEta(etaTime); booking.setEta(etaTime);
// 设置mischarge // 设置mischarge
@@ -1059,16 +1066,57 @@ public class BookingService {
} }
reservationDTO.setChannelId(channelId); reservationDTO.setChannelId(channelId);
List<CfgDaylightView> daylightViewList = daylightViewDao.findBySectionPropertyBookingTypeRoomType( List<CfgExceptionDaylightView> exceptionDaylightViewList = exceptionDaylightViewDao.findByUserPropertyBookingTypeRoomType(
userId,
booking.getPropertyId(),
booking.getBookingTypeId(),
roomTypeId
);
List<CfgDaylightView> daylightViewList = List.of();
if (CollectionUtils.isEmpty(exceptionDaylightViewList)) {
daylightViewList = daylightViewDao.findBySectionPropertyBookingTypeRoomType(
booking.getSectionId(), booking.getSectionId(),
booking.getPropertyId(), booking.getPropertyId(),
booking.getBookingTypeId(), booking.getBookingTypeId(),
roomTypeId roomTypeId
); );
}
CfgDaylightView daylightView = daylightViewList.getFirst(); if (CollectionUtils.isEmpty(exceptionDaylightViewList) && CollectionUtils.isEmpty(daylightViewList)) {
if (StringUtils.isNotBlank(booking.getDlExternalNo())
&& booking.getDlExternalNo().startsWith("CL-")
&& StringUtils.isEmpty(booking.getDlReservationId())) {
booking.setErrorMessage("Daylight view and exception daylight view not found");
booking.setApproveStatus("F");
CfgRateCodes rateCode = rateCodeDao.findById(daylightView.getRateCodeId()).orElse(null); Integer tryTime = booking.getTryTime();
if (tryTime == null) {
tryTime = 0;
}
booking.setProcessStatus(0);
booking.setTryTime(tryTime + 1);
bookingDao.save(booking);
}
processResult.setSuccess(false);
processResult.setMessage("Daylight view not found");
log.warn("Daylight view and exception daylight view not found, userId={}, sectionId={}, propertyId={}, bookingTypeId={}, roomTypeId={}",
userId,
booking.getSectionId(),
booking.getPropertyId(),
booking.getBookingTypeId(),
roomTypeId);
return processResult;
}
CfgExceptionDaylightView exceptionDaylightView = CollectionUtils.isNotEmpty(exceptionDaylightViewList)
? exceptionDaylightViewList.getFirst() : null;
CfgDaylightView daylightView = exceptionDaylightView == null ? daylightViewList.getFirst() : null;
Long rateCodeId = exceptionDaylightView != null ? exceptionDaylightView.getRateCodeId() : daylightView.getRateCodeId();
Long sourceCodeId = exceptionDaylightView != null ? exceptionDaylightView.getSourceCodeId() : daylightView.getSourceCodeId();
Long marketCodeId = exceptionDaylightView != null ? exceptionDaylightView.getMarketCodeId() : daylightView.getMarketCodeId();
CfgRateCodes rateCode = rateCodeDao.findById(rateCodeId).orElse(null);
// if (rateCode == null) { // if (rateCode == null) {
// booking.setApproveStatus("F"); // booking.setApproveStatus("F");
// booking.setErrorMessage("Rate Code not found"); // booking.setErrorMessage("Rate Code not found");
@@ -1211,7 +1259,7 @@ public class BookingService {
allocationDTO.setRoomTypeId(dlRoomTypeId); allocationDTO.setRoomTypeId(dlRoomTypeId);
reservationDTO.setAllocation(allocationDTO); reservationDTO.setAllocation(allocationDTO);
CfgSourceCodes sourceCode = sourceCodeDao.findById(daylightView.getSourceCodeId()).orElse(null); CfgSourceCodes sourceCode = sourceCodeDao.findById(sourceCodeId).orElse(null);
// if (sourceCode == null) { // if (sourceCode == null) {
// booking.setApproveStatus("F"); // booking.setApproveStatus("F");
// booking.setErrorMessage("Source code not found"); // booking.setErrorMessage("Source code not found");
@@ -1230,7 +1278,7 @@ public class BookingService {
reservationDTO.setNoPost(StringUtils.isBlank(booking.getMiscCharge())); reservationDTO.setNoPost(StringUtils.isBlank(booking.getMiscCharge()));
} }
CfgMarketCodes marketCode = marketCodeDao.findById(daylightView.getMarketCodeId()).orElse(null); CfgMarketCodes marketCode = marketCodeDao.findById(marketCodeId).orElse(null);
// if (marketCode == null) { // if (marketCode == null) {
// booking.setApproveStatus("F"); // booking.setApproveStatus("F");
// booking.setErrorMessage("Market code not found"); // booking.setErrorMessage("Market code not found");
@@ -1355,12 +1403,14 @@ public class BookingService {
customFields.put("WAIVEDEPOSIT", true); customFields.put("WAIVEDEPOSIT", true);
} }
if (booking.getWaitlistId() != null) { if (booking.getApprovalBookingId() != null) {
// customFields.put("App_Rea", "APP");
String approvalReason = booking.getApprovalReason();
customFields.put("App_Rea", approvalReason);
customFields.put("Approver", String.valueOf(booking.getApprovedId()));
} else if (booking.getWaitlistId() != null) {
customFields.put("App_Rea", "APP"); customFields.put("App_Rea", "APP");
customFields.put("Approver", booking.getApprovedBy()); customFields.put("Approver", booking.getApprovedBy());
} else if (booking.getApprovalBookingId() != null) {
customFields.put("App_Rea", "APP");
customFields.put("Approver", String.valueOf(booking.getApprovedId()));
} }
customFieldDTO.setLocation("ReservationHeader"); customFieldDTO.setLocation("ReservationHeader");
@@ -1425,9 +1475,9 @@ public class BookingService {
Integer trytime = booking.getTryTime()==null?0:(booking.getTryTime()+1); Integer trytime = booking.getTryTime()==null?0:(booking.getTryTime()+1);
booking.setApproveStatus("F"); booking.setApproveStatus("F");
booking.setTryTime(trytime); booking.setTryTime(trytime);
booking.setProcessStatus(0);
booking.setErrorMessage(createResponse.getMessage()); booking.setErrorMessage(createResponse.getMessage());
booking.setFailedAt(DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss")); booking.setFailedAt(DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));
booking.setProcessStatus(0);
bookingDao.save(booking); bookingDao.save(booking);
@@ -1459,8 +1509,8 @@ public class BookingService {
booking.setDlAccountId(daylightReservationByDlId.getAccountId()); booking.setDlAccountId(daylightReservationByDlId.getAccountId());
booking.setDlReservationId(reservationId); booking.setDlReservationId(reservationId);
booking.setConfirmationNo(confirmationNumber); booking.setConfirmationNo(confirmationNumber);
// booking.setLastOperaStatus("RESERVED"); booking.setLastOperaStatus("RESERVED");
// booking.setApproveStatus("N"); booking.setApproveStatus("N");
// //
bookingDao.save(booking); bookingDao.save(booking);
@@ -1477,7 +1527,7 @@ public class BookingService {
email.setCreatedBy(booking.getCreatedBy()); email.setCreatedBy(booking.getCreatedBy());
email = sendEmailService.sendCreateR2Y2NewEmail(booking, originBookingView,email,userId,booking.getCreatedByName(), false, true, emailAddress.getKeyValues()); email = sendEmailService.sendCreateR2Y2NewEmail(booking, originBookingView,email,userId,booking.getCreatedByName(), false, true, emailAddress.getKeyValues());
if (email.getStatus() == 1) { if (Objects.equals(email.getStatus(), 1)) {
emailDao.save(email); emailDao.save(email);
processResult.setSuccess(true); processResult.setSuccess(true);
}else{ }else{
@@ -1496,10 +1546,10 @@ public class BookingService {
checkinDateStr, checkinDateStr,
checkoutDateStr, checkoutDateStr,
daylightViewList, daylightViewList,
exceptionDaylightViewList,
booking.getMiscCharge() booking.getMiscCharge()
); );
//TODO For CCJ 这里create Comp rule之后需要通过 AC ID 去拿到 Comp Rule ID然后将Comp Rule Id 插入到Comp rule表中
//1.通过AC Id 拿到Comp rule ids 拿到compRuleIds 之后只需要复制给compRuleIds即可,后面逻辑已经写完 //1.通过AC Id 拿到Comp rule ids 拿到compRuleIds 之后只需要复制给compRuleIds即可,后面逻辑已经写完
List<String> compRuleIds = new ArrayList<>(); List<String> compRuleIds = new ArrayList<>();
BaseApiResponse<JSONArray> compRuleListResponse = BaseApiResponse<JSONArray> compRuleListResponse =
@@ -2248,7 +2298,7 @@ public class BookingService {
email = sendEmailService.sendExtendEmail(emailBook, originBook, email, userId, userName, emailAddress.getKeyValues()); email = sendEmailService.sendExtendEmail(emailBook, originBook, email, userId, userName, emailAddress.getKeyValues());
if (email.getStatus() == 1) { if (Objects.equals(email.getStatus(), 1)) {
processResult.setSuccess(true); processResult.setSuccess(true);
processResult.setCode("EMAIL"); processResult.setCode("EMAIL");
} else { } else {
@@ -2474,8 +2524,10 @@ public class BookingService {
Date originCheckinDate = DateTimeUtil.getDateFromString(dateArr.getFirst(), "yyyy-MM-dd"); Date originCheckinDate = DateTimeUtil.getDateFromString(dateArr.getFirst(), "yyyy-MM-dd");
Date checkinDate; Date checkinDate;
Date checkoutDate; Date checkoutDate;
String userId = param.getUser()!=null? param.getUser().getUserId():null; String userId = param.getUser() != null && param.getUser().getUserId() != null
String userName = param.getUserName(); ? param.getUser().getUserId() : param.getUserId();
String userName = param.getUser() != null && param.getUser().getUserName() != null
? param.getUser().getUserName() : param.getUserName();
Bookings booking = bookingDao.findById(bookId).orElse(null); Bookings booking = bookingDao.findById(bookId).orElse(null);
@@ -2639,7 +2691,7 @@ public class BookingService {
email.setCreatedBy(booking.getCreatedBy()); email.setCreatedBy(booking.getCreatedBy());
email = sendEmailService.sendExtendEmail(booking, originBookingView,email,userId,userName,emailAddress.getKeyValues()); email = sendEmailService.sendExtendEmail(booking, originBookingView,email,userId,userName,emailAddress.getKeyValues());
if(email.getStatus()==1) { if(Objects.equals(email.getStatus(), 1)) {
emailDao.save(email); emailDao.save(email);
processResult.setSuccess(true); processResult.setSuccess(true);
processResult.setData(resultBookings); processResult.setData(resultBookings);
@@ -3132,7 +3184,7 @@ public class BookingService {
LogUtil.info(BookingService.class,"[mergeDatabaseInfo][Opera Book Exist]"); LogUtil.info(BookingService.class,"[mergeDatabaseInfo][Opera Book Exist]");
Date now = new Date(); Date now = new Date();
Bookings book = new Bookings(); Bookings book = new Bookings();
CfgProperties operaProperty = propertyDao.getByHotelCode(operaBooking.getHotelCode()); CfgProperties operaProperty = propertyDao.findByHotelCodeAndCategory(operaBooking.getHotelCode(), "OPERA");
CfgRoomTypes operRoomType =roomTypeDao.findByCodeAndCategory(operaBooking.getRoomTypeCode(),operaBooking.getPropertyCategory()); CfgRoomTypes operRoomType =roomTypeDao.findByCodeAndCategory(operaBooking.getRoomTypeCode(),operaBooking.getPropertyCategory());
CfgRooms operaRoom = new CfgRooms(); CfgRooms operaRoom = new CfgRooms();
//set room type //set room type
@@ -3289,7 +3341,7 @@ public class BookingService {
LogUtil.info(BookingService.class,"[mergeDatabaseInfo][Opera Book Exist]"); LogUtil.info(BookingService.class,"[mergeDatabaseInfo][Opera Book Exist]");
Date now = new Date(); Date now = new Date();
Bookings book = new Bookings(); Bookings book = new Bookings();
CfgProperties operaProperty = propertyDao.getByPropertyNameDaylight(operaBooking.getPropertyName()); CfgProperties operaProperty = propertyDao.findByNameAndCategory(operaBooking.getPropertyName(), "DAYLIGHT");
CfgRoomTypes operRoomType =roomTypeDao.findByCodeAndCategory(operaBooking.getRoomTypeCode(), "DAYLIGHT"); CfgRoomTypes operRoomType =roomTypeDao.findByCodeAndCategory(operaBooking.getRoomTypeCode(), "DAYLIGHT");
CfgRooms operaRoom = new CfgRooms(); CfgRooms operaRoom = new CfgRooms();
//set room type //set room type
@@ -5061,6 +5113,11 @@ public class BookingService {
if (dbBooking == null) { if (dbBooking == null) {
return; return;
} }
// Booking Type 属于本地业务配置,搜索同步不能用普通 mapping 覆盖已有值。
daylightBooking.setBookingTypeId(dbBooking.getBookingTypeId());
if (StringUtils.isNotBlank(dbBooking.getCreatedBy())) {
daylightBooking.setCreatedBy(dbBooking.getCreatedBy());
}
if (dbBooking.getMiscCharge() != null) { if (dbBooking.getMiscCharge() != null) {
daylightBooking.setMiscCharge(dbBooking.getMiscCharge()); daylightBooking.setMiscCharge(dbBooking.getMiscCharge());
} }
@@ -5114,17 +5171,6 @@ public class BookingService {
// } // }
resolveDaylightBlockInfo(daylightBooking); resolveDaylightBlockInfo(daylightBooking);
resolveDaylightSourceCode(daylightBooking); resolveDaylightSourceCode(daylightBooking);
List<CfgMarketCodes> operaMarketCode = marketCodeDao.findByCodeAndCategory(daylightBooking.getMarketCode(), "DAYLIGHT");
List<CfgRateCodes> operRateCode = rateCodeDao.findByCodeAndCategory(daylightBooking.getRatePlanCode(), "DAYLIGHT");
if (!operaMarketCode.isEmpty() && !operRateCode.isEmpty()) {
Long operaMarketCodeId = operaMarketCode.getFirst().getId();
Long operaRateCodeId = operRateCode.getFirst().getId();
List<CfgDaylightView> bookingTypeOperas = daylightViewDao.findByMarketCodeIdAndRateCodeId(operaMarketCodeId, operaRateCodeId);
if (!bookingTypeOperas.isEmpty()) {
Long operaBookingTypeId = bookingTypeOperas.getFirst().getBookingTypeId();
daylightBooking.setBookingTypeId(operaBookingTypeId);
}
}
if ("CANCELED".equals(daylightBooking.getLastOperaStatus())) { if ("CANCELED".equals(daylightBooking.getLastOperaStatus())) {
// if (!"PN".equals(dbBookingView.getApproveStatus())) { // if (!"PN".equals(dbBookingView.getApproveStatus())) {
@@ -5203,8 +5249,7 @@ public class BookingService {
if (daylightBooking.getSectionId() == null && dbBooking.getSectionId() != null) { if (daylightBooking.getSectionId() == null && dbBooking.getSectionId() != null) {
daylightBooking.setSectionId(dbBooking.getSectionId()); daylightBooking.setSectionId(dbBooking.getSectionId());
} }
resolveMissingDaylightBookingType(daylightBooking);
int expMin = 20000; int expMin = 20000;
expMin = expMin * -1; expMin = expMin * -1;
@@ -5300,18 +5345,7 @@ public class BookingService {
daylightBooking.setSectionId(userInfo.getSectionId()); daylightBooking.setSectionId(userInfo.getSectionId());
} }
} }
//get Booking Type resolveMissingDaylightBookingType(daylightBooking);
List<CfgMarketCodes> operaMarketCode = marketCodeDao.findByCodeAndCategory(daylightBooking.getMarketCode(), "DAYLIGHT");
List<CfgRateCodes> operRateCode = rateCodeDao.findByCodeAndCategory(daylightBooking.getRatePlanCode(), "DAYLIGHT");
if(!operaMarketCode.isEmpty() && !operRateCode.isEmpty()) {
Long operaMarketCodeId = operaMarketCode.getFirst().getId();
Long operaRateCodeId = operRateCode.getFirst().getId();
List<CfgDaylightView> bookingTypeOperas = daylightViewDao.findByMarketCodeIdAndRateCodeId(operaMarketCodeId,operaRateCodeId);
if(!bookingTypeOperas.isEmpty()) {
Long daylightBookingTypeId = bookingTypeOperas.getFirst().getBookingTypeId();
daylightBooking.setBookingTypeId(daylightBookingTypeId);
}
}
// build datelist // build datelist
int numOfNight = Integer.parseInt(DateTimeUtil.getDiffDate(daylightBooking.getCheckinDate(), daylightBooking.getCheckoutDate(), "day")); int numOfNight = Integer.parseInt(DateTimeUtil.getDiffDate(daylightBooking.getCheckinDate(), daylightBooking.getCheckoutDate(), "day"));
List<String> dates = new ArrayList<>(); List<String> dates = new ArrayList<>();
@@ -5336,6 +5370,7 @@ public class BookingService {
@Transactional @Transactional
public List<BookingDto> mergeDaylightRecordFromDB_Optimize(List<BookingDto> pmsResult, PlayerProfileEntry member, String userId) throws Exception { public List<BookingDto> mergeDaylightRecordFromDB_Optimize(List<BookingDto> pmsResult, PlayerProfileEntry member, String userId) throws Exception {
Set<BookingDto> skippedCanceledDaylightBookings = Collections.newSetFromMap(new IdentityHashMap<>()); Set<BookingDto> skippedCanceledDaylightBookings = Collections.newSetFromMap(new IdentityHashMap<>());
Set<BookingDto> skippedNoShowDaylightBookings = Collections.newSetFromMap(new IdentityHashMap<>());
List<BookingDto> bookingsForReservationFallback = new ArrayList<>(); List<BookingDto> bookingsForReservationFallback = new ArrayList<>();
// ========== Pass 1: Match by dlExternalNo ========== // ========== Pass 1: Match by dlExternalNo ==========
@@ -5370,15 +5405,40 @@ public class BookingService {
} else { } else {
Bookings existingDaylightBooking = bookingDao.getByDlExternalNo(dlExternalNo); Bookings existingDaylightBooking = bookingDao.getByDlExternalNo(dlExternalNo);
if (existingDaylightBooking != null) { if (existingDaylightBooking != null) {
if (isCanceledDaylightBooking(daylightBooking)) {
updateMatchedCanceledBooking(daylightBooking, existingDaylightBooking);
skippedCanceledDaylightBookings.add(daylightBooking);
continue;
}
bookingExist = true; bookingExist = true;
matchDbBooking = toDaylightMergeBookingView(existingDaylightBooking); matchDbBooking = toDaylightMergeBookingView(existingDaylightBooking);
dbBookingViews.add(matchDbBooking); dbBookingViews.add(matchDbBooking);
} }
} }
if (isNoShowDaylightBooking(daylightBooking)) {
if (bookingExist && matchDbBooking != null) {
updateMatchedNoShowBooking(matchDbBooking);
skippedNoShowDaylightBookings.add(daylightBooking);
} else if (StringUtils.isNotBlank(daylightBooking.getDlReservationId())) {
bookingsForReservationFallback.add(daylightBooking);
} else {
skippedNoShowDaylightBookings.add(daylightBooking);
}
continue;
}
if (isCanceledDaylightBooking(daylightBooking)) {
if (bookingExist && matchDbBooking != null) {
updateMatchedCanceledBooking(daylightBooking, matchDbBooking);
skippedCanceledDaylightBookings.add(daylightBooking);
} else if (StringUtils.isNotBlank(daylightBooking.getDlReservationId())) {
bookingsForReservationFallback.add(daylightBooking);
} else {
skippedCanceledDaylightBookings.add(daylightBooking);
}
continue;
}
if (bookingExist && matchDbBooking != null) { if (bookingExist && matchDbBooking != null) {
mergeDaylightRowFromExistingDbBooking_Optimize(daylightBooking, matchDbBooking, dbBookingViews); mergeDaylightRowFromExistingDbBooking_Optimize(daylightBooking, matchDbBooking, dbBookingViews);
} else if (isCanceledDaylightBooking(daylightBooking)) {
skippedCanceledDaylightBookings.add(daylightBooking);
} else if (StringUtils.isNotBlank(daylightBooking.getDlReservationId())) { } else if (StringUtils.isNotBlank(daylightBooking.getDlReservationId())) {
bookingsForReservationFallback.add(daylightBooking); bookingsForReservationFallback.add(daylightBooking);
} else if (isLocalCanceledBooking(daylightBooking)) { } else if (isLocalCanceledBooking(daylightBooking)) {
@@ -5415,14 +5475,26 @@ public class BookingService {
matchDbBooking = existDlReservationDbBookingMap.get(dlReservationId); matchDbBooking = existDlReservationDbBookingMap.get(dlReservationId);
} }
} }
if (isNoShowDaylightBooking(daylightBooking)) {
if (bookingExist && matchDbBooking != null) {
updateMatchedNoShowBooking(matchDbBooking);
}
skippedNoShowDaylightBookings.add(daylightBooking);
continue;
}
if (isCanceledDaylightBooking(daylightBooking)) {
if (bookingExist && matchDbBooking != null) {
updateMatchedCanceledBooking(daylightBooking, matchDbBooking);
}
skippedCanceledDaylightBookings.add(daylightBooking);
continue;
}
if (bookingExist && matchDbBooking != null) { if (bookingExist && matchDbBooking != null) {
// Backfill dlExternalNo to DB record if missing // Backfill dlExternalNo to DB record if missing
if (StringUtils.isBlank(matchDbBooking.getDlExternalNo()) && StringUtils.isNotBlank(daylightBooking.getDlExternalNo())) { if (StringUtils.isBlank(matchDbBooking.getDlExternalNo()) && StringUtils.isNotBlank(daylightBooking.getDlExternalNo())) {
matchDbBooking.setDlExternalNo(daylightBooking.getDlExternalNo().trim()); matchDbBooking.setDlExternalNo(daylightBooking.getDlExternalNo().trim());
} }
mergeDaylightRowFromExistingDbBooking_Optimize(daylightBooking, matchDbBooking, reservationDbBookingViews); mergeDaylightRowFromExistingDbBooking_Optimize(daylightBooking, matchDbBooking, reservationDbBookingViews);
} else if (isCanceledDaylightBooking(daylightBooking)) {
skippedCanceledDaylightBookings.add(daylightBooking);
} else if (isLocalCanceledBooking(daylightBooking)) { } else if (isLocalCanceledBooking(daylightBooking)) {
skippedCanceledDaylightBookings.add(daylightBooking); skippedCanceledDaylightBookings.add(daylightBooking);
} else { } else {
@@ -5430,18 +5502,64 @@ public class BookingService {
} }
} }
if (skippedCanceledDaylightBookings.isEmpty()) { if (skippedCanceledDaylightBookings.isEmpty() && skippedNoShowDaylightBookings.isEmpty()) {
return pmsResult; return pmsResult;
} }
List<BookingDto> mergeableResults = new ArrayList<>(); List<BookingDto> mergeableResults = new ArrayList<>();
for (BookingDto daylightBooking : pmsResult) { for (BookingDto daylightBooking : pmsResult) {
if (!skippedCanceledDaylightBookings.contains(daylightBooking)) { if (!skippedCanceledDaylightBookings.contains(daylightBooking)
&& !skippedNoShowDaylightBookings.contains(daylightBooking)) {
mergeableResults.add(daylightBooking); mergeableResults.add(daylightBooking);
} }
} }
return mergeableResults; return mergeableResults;
} }
// 取消记录直接更新本地实体,不进入完整 DTO 合并及覆盖保存流程。
private void updateMatchedCanceledBooking(BookingDto daylightBooking, BookingsView matchedBookingView) {
if (matchedBookingView == null || matchedBookingView.getId() == null) {
return;
}
Bookings matchedBooking = bookingDao.findById(matchedBookingView.getId()).orElse(null);
if (matchedBooking == null) {
return;
}
updateMatchedCanceledBooking(daylightBooking, matchedBooking);
}
private void updateMatchedCanceledBooking(BookingDto daylightBooking, Bookings matchedBooking) {
boolean newlyCanceled = !"CANCELED".equalsIgnoreCase(matchedBooking.getLastOperaStatus());
matchedBooking.setLastOperaStatus("CANCELED");
matchedBooking.setApproveStatus("C");
matchedBooking.setUpdatedAt(daylightBooking.getDataTime());
bookingDao.save(matchedBooking);
if (newlyCanceled && matchedBooking.getRoomId() != null && matchedBooking.getBlockId() != null) {
processAllotment(matchedBooking.getRoomId(), matchedBooking.getCheckinDate(),
matchedBooking.getCheckoutDate(), matchedBooking.getPropertyId(), matchedBooking.getBlockId());
}
}
private boolean isNoShowDaylightBooking(BookingDto daylightBooking) {
return daylightBooking != null
&& "NO_SHOW".equalsIgnoreCase(StringUtils.trim(daylightBooking.getLastOperaStatus()));
}
private void updateMatchedNoShowBooking(BookingsView matchedBookingView) {
if (matchedBookingView == null || matchedBookingView.getId() == null) {
return;
}
Bookings matchedBooking = bookingDao.findById(matchedBookingView.getId()).orElse(null);
if (matchedBooking == null) {
return;
}
matchedBooking.setLastOperaStatus("NO_SHOW");
if ("PN".equalsIgnoreCase(matchedBooking.getApproveStatus())) {
matchedBooking.setApproveStatus("N");
}
bookingDao.save(matchedBooking);
}
private void resolveDaylightBlockInfo(BookingDto daylightBooking) { private void resolveDaylightBlockInfo(BookingDto daylightBooking) {
if (StringUtils.isBlank(daylightBooking.getDlBlockId())) { if (StringUtils.isBlank(daylightBooking.getDlBlockId())) {
return; return;
@@ -5466,6 +5584,46 @@ public class BookingService {
daylightBooking.setSourceCode(sourceCode.getCode()); daylightBooking.setSourceCode(sourceCode.getCode());
} }
private void resolveMissingDaylightBookingType(BookingDto booking) {
if (booking.getBookingTypeId() != null) {
return;
}
if (booking.getPropertyId() == null || booking.getRoomTypeId() == null || booking.getRoomTypeId() <= 0
|| StringUtils.isBlank(booking.getMarketCode()) || StringUtils.isBlank(booking.getRatePlanCode())) {
log.warn("Cannot resolve Daylight Booking Type: incomplete context, reservationId={}, propertyId={}, roomTypeId={}",
booking.getDlReservationId(), booking.getPropertyId(), booking.getRoomTypeId());
return;
}
if (StringUtils.isNotBlank(booking.getCreatedBy())) {
List<Long> exceptionBookingTypeIds = exceptionDaylightViewDao.findBookingTypeIdsByUserPropertyRoomTypeAndCodes(
booking.getCreatedBy(), booking.getPropertyId(), booking.getRoomTypeId(),
booking.getMarketCode(), booking.getRatePlanCode());
if (CollectionUtils.isNotEmpty(exceptionBookingTypeIds)) {
applyUniqueDaylightBookingType(booking, exceptionBookingTypeIds, "Exception Daylight");
return;
}
}
if (booking.getSectionId() != null) {
List<Long> bookingTypeIds = daylightViewDao.findBookingTypeIdsBySectionPropertyRoomTypeAndCodes(
booking.getSectionId(), booking.getPropertyId(), booking.getRoomTypeId(),
booking.getMarketCode(), booking.getRatePlanCode());
applyUniqueDaylightBookingType(booking, bookingTypeIds, "Daylight");
}
}
private void applyUniqueDaylightBookingType(BookingDto booking, List<Long> candidates, String mappingSource) {
List<Long> bookingTypeIds = candidates == null ? List.of()
: candidates.stream().filter(Objects::nonNull).distinct().toList();
if (bookingTypeIds.size() == 1) {
booking.setBookingTypeId(bookingTypeIds.getFirst());
} else {
log.warn("Cannot uniquely resolve Daylight Booking Type, source={}, reservationId={}, userId={}, sectionId={}, propertyId={}, roomTypeId={}, marketCode={}, rateCode={}, candidates={}",
mappingSource, booking.getDlReservationId(), booking.getCreatedBy(), booking.getSectionId(),
booking.getPropertyId(), booking.getRoomTypeId(), booking.getMarketCode(),
booking.getRatePlanCode(), bookingTypeIds);
}
}
private boolean isCanceledDaylightBooking(BookingDto daylightBooking) { private boolean isCanceledDaylightBooking(BookingDto daylightBooking) {
if (daylightBooking == null || daylightBooking.getLastOperaStatus() == null) { if (daylightBooking == null || daylightBooking.getLastOperaStatus() == null) {
return false; return false;
@@ -5524,6 +5682,7 @@ public class BookingService {
} }
view.setPropertyId(booking.getPropertyId()); view.setPropertyId(booking.getPropertyId());
view.setRoomTypeId(booking.getRoomTypeId());
view.setSectionId(booking.getSectionId()); view.setSectionId(booking.getSectionId());
view.setBookingTypeId(booking.getBookingTypeId() != null ? booking.getBookingTypeId().intValue() : null); view.setBookingTypeId(booking.getBookingTypeId() != null ? booking.getBookingTypeId().intValue() : null);
return view; return view;
@@ -5629,6 +5788,9 @@ public class BookingService {
} }
if ("CANCELED".equals(operaBooking.getLastOperaStatus())) { if ("CANCELED".equals(operaBooking.getLastOperaStatus())) {
operaBooking.setApproveStatus("C"); operaBooking.setApproveStatus("C");
} else if ("NO_SHOW".equals(operaBooking.getLastOperaStatus())
|| "CHECKED_OUT".equals(operaBooking.getLastOperaStatus())) {
} else { } else {
if ("C".equals(dbBooking.getApproveStatus())) { if ("C".equals(dbBooking.getApproveStatus())) {
operaBooking.setApproveStatus("N"); operaBooking.setApproveStatus("N");
@@ -5908,6 +6070,22 @@ public class BookingService {
currentBooking.setApproveStatus("N"); currentBooking.setApproveStatus("N");
} }
if ("DAYLIGHT".equalsIgnoreCase(currentBooking.getCategory())
|| StringUtils.isNotBlank(mergeBookingDto.getDlReservationId())) {
fillMissingMergeFieldsFromExistingBooking(mergedBooking, currentBooking);
if (currentBooking.getBookingTypeId() != null) {
mergedBooking.setBookingTypeId(currentBooking.getBookingTypeId());
}
if (StringUtils.isNotBlank(currentBooking.getCreatedBy())) {
mergedBooking.setCreatedBy(currentBooking.getCreatedBy());
}
mergeBookingDto.setBookingTypeId(mergedBooking.getBookingTypeId());
mergeBookingDto.setCreatedBy(mergedBooking.getCreatedBy());
mergeBookingDto.setSectionId(mergedBooking.getSectionId());
mergeBookingDto.setPropertyId(mergedBooking.getPropertyId());
mergeBookingDto.setRoomTypeId(mergedBooking.getRoomTypeId());
}
if ("N".equalsIgnoreCase(currentBooking.getApproveStatus())) { if ("N".equalsIgnoreCase(currentBooking.getApproveStatus())) {
insertCommentAndMiscChargeFromDaylight(mergeBookingDto, currentBooking.getMiscCharge()); insertCommentAndMiscChargeFromDaylight(mergeBookingDto, currentBooking.getMiscCharge());
mergedBooking.setOperaComment(mergeBookingDto.getOperaComment()); mergedBooking.setOperaComment(mergeBookingDto.getOperaComment());
@@ -6129,11 +6307,17 @@ public class BookingService {
String checkoutDateStr = DateTimeUtil.getDateByFormat(checkOutDate, "yyyy-MM-dd"); String checkoutDateStr = DateTimeUtil.getDateByFormat(checkOutDate, "yyyy-MM-dd");
DaylightReservationResponse daylightReservationByDlId = DaylightReservationResponse daylightReservationByDlId =
dlService.getDaylightReservationByDlId(bookings.getDlReservationId(), property.getDlPropertyId()); dlService.getDaylightReservationByDlId(bookings.getDlReservationId(), property.getDlPropertyId());
List<CfgDaylightView> daylightViewList = daylightViewDao.findBySectionPropertyBookingTypeRoomType( List<CfgExceptionDaylightView> exceptionDaylightViewList = exceptionDaylightViewDao.findByUserPropertyBookingTypeRoomType(
bookings.getCreatedBy(), bookings.getPropertyId(), bookings.getBookingTypeId(), bookings.getRoomTypeId()
);
List<CfgDaylightView> daylightViewList = List.of();
if (CollectionUtils.isEmpty(exceptionDaylightViewList)) {
daylightViewList = daylightViewDao.findBySectionPropertyBookingTypeRoomType(
bookings.getSectionId(), bookings.getPropertyId(), bookings.getBookingTypeId(), bookings.getRoomTypeId() bookings.getSectionId(), bookings.getPropertyId(), bookings.getBookingTypeId(), bookings.getRoomTypeId()
); );
}
if (CollectionUtils.isNotEmpty(daylightViewList)) { if (CollectionUtils.isNotEmpty(exceptionDaylightViewList) || CollectionUtils.isNotEmpty(daylightViewList)) {
dlService.createDaylightCompRule( dlService.createDaylightCompRule(
daylightReservationByDlId.getAccountId(), daylightReservationByDlId.getAccountId(),
daylightReservationByDlId.getProfileId(), daylightReservationByDlId.getProfileId(),
@@ -6143,6 +6327,7 @@ public class BookingService {
checkinDateStr, checkinDateStr,
checkoutDateStr, checkoutDateStr,
daylightViewList, daylightViewList,
exceptionDaylightViewList,
miscChargeValue miscChargeValue
); );
} }
@@ -6365,7 +6550,8 @@ public class BookingService {
} }
} }
return buildODExtendCommentContent(booking, newCheckoutDate, booker); return buildODExtendCommentContent(booking,
booking != null ? booking.getCheckoutDate() : null, newCheckoutDate, booker);
} }
private String buildIMDaylightExtendComment(Bookings booking, Date newCheckoutDate, String booker) { private String buildIMDaylightExtendComment(Bookings booking, Date newCheckoutDate, String booker) {
@@ -6427,7 +6613,8 @@ public class BookingService {
} }
private String buildOperaExtendComment(Bookings booking, Date originCheckoutDate, String booker) { private String buildOperaExtendComment(Bookings booking, Date originCheckoutDate, String booker) {
String comment = buildODExtendCommentContent(booking, originCheckoutDate, booker); String comment = buildODExtendCommentContent(booking, originCheckoutDate,
booking != null ? booking.getCheckoutDate() : null, booker);
if (comment == null) { if (comment == null) {
return null; return null;
} }
@@ -6449,12 +6636,13 @@ public class BookingService {
+ "\n" + amendLine; + "\n" + amendLine;
} }
private String buildODExtendCommentContent(Bookings booking, Date originCheckoutDate, String booker) { private String buildODExtendCommentContent(Bookings booking, Date originCheckoutDate,
Date newCheckoutDate, String booker) {
if (booking == null || originCheckoutDate == null) { if (booking == null || originCheckoutDate == null) {
return null; return null;
} }
String stayDate = formatExtStayDateRange(originCheckoutDate, booking.getCheckoutDate()); String stayDate = formatExtStayDateRange(originCheckoutDate, newCheckoutDate);
String bookerName = StringUtils.defaultIfBlank(booker, booking.getBooker()); String bookerName = StringUtils.defaultIfBlank(booker, booking.getBooker());
String extLine = "EXT " + stayDate + ",OD," + bookerName + "..APP"; String extLine = "EXT " + stayDate + ",OD," + bookerName + "..APP";
@@ -6471,10 +6659,15 @@ public class BookingService {
.replace("&#xA;", "\n") .replace("&#xA;", "\n")
.replace("&#x24;", "$"); .replace("&#x24;", "$");
int rmEndIndex = comment.indexOf("COMP ..APP"); // 兼容 APP/MSC 的 RM 头部及空格、大小写和空格实体差异,保留原始文本。
String headerSpacing = "(?:\\h|&nbsp;|&#0*(?:32|160);|&#x0*(?:20|a0);)*";
Matcher rmHeaderMatcher = Pattern.compile(
"\\(RM(?:\\+INC\\$[^)\\r\\n]*)?\\)" + headerSpacing
+ "COMP" + headerSpacing + "\\.\\.(?:APP|MSC)", Pattern.CASE_INSENSITIVE)
.matcher(comment);
if (rmEndIndex >= 0) { if (rmHeaderMatcher.find()) {
rmEndIndex += "COMP ..APP".length(); int rmEndIndex = rmHeaderMatcher.end();
newComment = comment.substring(0, rmEndIndex) newComment = comment.substring(0, rmEndIndex)
+ "\n\n" + "\n\n"
@@ -6489,7 +6682,7 @@ public class BookingService {
LogUtil.info(BookingService.class, LogUtil.info(BookingService.class,
"[buildODExtendCommentContent] bookingId=" + booking.getId() "[buildODExtendCommentContent] bookingId=" + booking.getId()
+ ", originCheckout=" + DateTimeUtil.getDateByFormat(originCheckoutDate, "yyyy-MM-dd") + ", originCheckout=" + DateTimeUtil.getDateByFormat(originCheckoutDate, "yyyy-MM-dd")
+ ", newCheckout=" + DateTimeUtil.getDateByFormat(booking.getCheckoutDate(), "yyyy-MM-dd") + ", newCheckout=" + DateTimeUtil.getDateByFormat(newCheckoutDate, "yyyy-MM-dd")
+ ", comment=" + extLine); + ", comment=" + extLine);
return newComment; return newComment;
@@ -6596,22 +6789,14 @@ public class BookingService {
private void insertCommentAndMiscChargeFromDaylight(BookingDto dto, String previousMiscCharge) { private void insertCommentAndMiscChargeFromDaylight(BookingDto dto, String previousMiscCharge) {
String dlReservationId = dto.getDlReservationId(); // String dlReservationId = dto.getDlReservationId();
String dlPropertyId = dto.getDlPropertyId(); // String dlPropertyId = dto.getDlPropertyId();
//
// if (StringUtils.isEmpty(dlReservationId) || StringUtils.isEmpty(dlPropertyId)) return;
// if (StringUtils.isNotEmpty(dto.getOperaComment())) return; String comment = dto.getOperaComment();
if (StringUtils.isBlank(comment)) return;
if (StringUtils.isEmpty(dlReservationId) || StringUtils.isEmpty(dlPropertyId)) return;
BaseApiResponse<ReservationNoteResponse> response
= dlService.daylightGetNoteListById(dlPropertyId, dlReservationId);
if (response.isSuccess()) {
ReservationNoteResponse data = response.getData();
if (data != null) {
String comment = data.getContent();
if (StringUtils.isNotBlank(comment)) {
Matcher miscChargeMatcher = Pattern Matcher miscChargeMatcher = Pattern
.compile("(?:\\$|&#x24;)\\s*([0-9]+(?:\\.[0-9]+)?)", Pattern.CASE_INSENSITIVE) .compile("(?:\\$|&#x24;)\\s*([0-9]+(?:\\.[0-9]+)?)", Pattern.CASE_INSENSITIVE)
.matcher(comment); .matcher(comment);
@@ -6622,15 +6807,33 @@ public class BookingService {
updateDaylightCompRule(dto, miscCharge); updateDaylightCompRule(dto, miscCharge);
} }
} }
comment = comment.replaceAll("(?i)<br\\s*/?>", "\n"); dto.setOperaComment(comment.replaceAll("(?i)<br\\s*/?>", "\n"));
}
dto.setOperaComment(comment);
}
}
} }
private void updateDaylightCompRule(BookingDto dto, String miscCharge) { private void updateDaylightCompRule(BookingDto dto, String miscCharge) {
if (StringUtils.isBlank(dto.getDlAccountId()) || dto.getCheckinDate() == null || dto.getCheckoutDate() == null) { if (StringUtils.isBlank(dto.getDlAccountId()) || dto.getCheckinDate() == null || dto.getCheckoutDate() == null
|| dto.getPropertyId() == null || dto.getRoomTypeId() == null || dto.getBookingTypeId() == null) {
return;
}
List<CfgExceptionDaylightView> exceptionDaylightViewList = StringUtils.isNotBlank(dto.getCreatedBy())
? exceptionDaylightViewDao.findByUserPropertyBookingTypeRoomType(
dto.getCreatedBy(), dto.getPropertyId(), dto.getBookingTypeId(), dto.getRoomTypeId())
: List.of();
if (CollectionUtils.isNotEmpty(exceptionDaylightViewList)) {
CfgExceptionDaylightView exceptionDaylightView = exceptionDaylightViewList.stream()
.filter(view -> Objects.equals(view.getCompRuleCategory(), 2))
.findFirst().orElse(null);
if (exceptionDaylightView == null) {
log.warn("Exception Daylight Misc Charge config is empty, reservationId={}, userId={}, bookingTypeId={}",
dto.getDlReservationId(), dto.getCreatedBy(), dto.getBookingTypeId());
return;
}
dlService.updateDaylightCompRule(
dto.getDlAccountId(), dto.getDlPropertyId(),
DateTimeUtil.getDateByFormat(dto.getCheckinDate(), "yyyy-MM-dd"),
DateTimeUtil.getDateByFormat(dto.getCheckoutDate(), "yyyy-MM-dd"),
null, exceptionDaylightView, miscCharge);
return; return;
} }
@@ -6705,4 +6908,16 @@ public class BookingService {
response.setData(bookView); response.setData(bookView);
return response; return response;
} }
public List<BookingDto> getSearchPlayerDaylightDbRecord(String checkinDate,
String checkoutDate,
String playerId) {
List<BookingsView> bookingsViews = bookingViewDao.findDaylightDbRecord(playerId, checkinDate,checkoutDate);
List<BookingDto> bookingDtos = bookingMapper.viewToBookingDtoList(bookingsViews);
Date currentTime = new Date();
for(BookingDto booking:bookingDtos){
booking.setDataTime(currentTime);
}
return bookingDtos;
}
} }
@@ -24,6 +24,7 @@ import com.mgm.mcrm.basesetting.room.repositories.OtherRoomStatusDao;
import com.mgm.mcrm.basesetting.room.repositories.RoomDao; import com.mgm.mcrm.basesetting.room.repositories.RoomDao;
import com.mgm.mcrm.basesetting.team.models.CfgOtherUserMapping; import com.mgm.mcrm.basesetting.team.models.CfgOtherUserMapping;
import com.mgm.mcrm.basesetting.team.repositories.OtherUserMappingDao; import com.mgm.mcrm.basesetting.team.repositories.OtherUserMappingDao;
import com.mgm.mcrm.basesetting.team.repositories.SectionDao;
import com.mgm.mcrm.booking.dtos.BookingDateEntry; import com.mgm.mcrm.booking.dtos.BookingDateEntry;
import com.mgm.mcrm.booking.dtos.BookingDto; import com.mgm.mcrm.booking.dtos.BookingDto;
import com.mgm.mcrm.booking.mappers.BookingMapper; import com.mgm.mcrm.booking.mappers.BookingMapper;
@@ -113,6 +114,8 @@ public class NonMGMBookingService {
private MgmUserService mgmUserService; private MgmUserService mgmUserService;
@Resource @Resource
private ApprovalService approvalService; private ApprovalService approvalService;
@Resource
private SectionDao sectionDao;
@Autowired @Autowired
private BookingMapper bookingMapper; private BookingMapper bookingMapper;
@@ -135,6 +138,7 @@ public class NonMGMBookingService {
String createdByName = userInfo.getUserName(); String createdByName = userInfo.getUserName();
String groupId = param.getGroupId(); String groupId = param.getGroupId();
Long sectionId = param.getSectionId(); Long sectionId = param.getSectionId();
String sectionName = param.getSectionName();
PlayerProfileEntry member = param.getMember(); PlayerProfileEntry member = param.getMember();
Long bedTypeMasterGroupId = param.getBedTypeId(); Long bedTypeMasterGroupId = param.getBedTypeId();
String bedTypeName = param.getBedTypeName(); String bedTypeName = param.getBedTypeName();
@@ -203,6 +207,15 @@ public class NonMGMBookingService {
booking.setEta(etaTime); booking.setEta(etaTime);
booking.setSourceCode("OD"); booking.setSourceCode("OD");
if (StringUtils.isNotBlank(sectionName)) {
booking.setSectionName(sectionName);
} else {
Bookings finalBooking = booking;
sectionDao.findById(sectionId).ifPresent(section -> {
finalBooking.setSectionName(section.getName());
});
}
if(groupId!=null) if(groupId!=null)
booking.setGroupId(groupId); booking.setGroupId(groupId);
@@ -0,0 +1,12 @@
package com.mgm.mcrm.common.annotation.security;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface VerifyPermission {
String[] permissionId() default {};
}
@@ -46,7 +46,16 @@ public class WebFilterConfig {
@Bean @Bean
public FilterRegistrationBean<ConfigHeaderFilter> registerHeaderFilter() { public FilterRegistrationBean<ConfigHeaderFilter> registerHeaderFilter() {
FilterRegistrationBean<ConfigHeaderFilter> registration = new FilterRegistrationBean<ConfigHeaderFilter>(); FilterRegistrationBean<ConfigHeaderFilter> registration = new FilterRegistrationBean<ConfigHeaderFilter>();
registration.setFilter(new ConfigHeaderFilter()); ConfigHeaderFilter filer = new ConfigHeaderFilter();
List<String> ignoreOriginPatterns = Arrays.asList(
"/sso_callback/login",
"/sso_callback/logout",
"/api/app/sso/export_folder",
"/api/app/sso/import_folder",
"/api/third_party/get_access_token"
);
filer.setIgnoreOriginPatterns(ignoreOriginPatterns);
registration.setFilter(filer);
registration.addUrlPatterns("/*"); registration.addUrlPatterns("/*");
registration.setName("ConfigHeaderFilter"); registration.setName("ConfigHeaderFilter");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE); registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
@@ -62,7 +71,10 @@ public class WebFilterConfig {
"/api/system/write_public_log", "/api/system/write_public_log",
"/api/system/sys_setting/get_public_login_settings", "/api/system/sys_setting/get_public_login_settings",
"/api/app/sso/*", "/api/app/sso/*",
"/sso_callback/login",
"/sso_callback/logout",
"/api/web/setting/get_public_setting_by_key", "/api/web/setting/get_public_setting_by_key",
"/api/third_party/get_access_token",
"/swagger*/*", "/swagger*/*",
"/v3/**", "/v3/**",
"/api-docs", "/api-docs",
@@ -6,8 +6,10 @@ import com.auth0.jwt.interfaces.DecodedJWT;
import com.mgm.mcrm.appsetting.models.SysSetting; import com.mgm.mcrm.appsetting.models.SysSetting;
import com.mgm.mcrm.authorization.dtos.LoginUserInfo; import com.mgm.mcrm.authorization.dtos.LoginUserInfo;
import com.mgm.mcrm.authorization.models.SysUser; import com.mgm.mcrm.authorization.models.SysUser;
import com.mgm.mcrm.authorization.services.MgmUserService;
import com.mgm.mcrm.booking.services.BookingService; import com.mgm.mcrm.booking.services.BookingService;
import com.mgm.mcrm.common.dtos.config.APIConfig; import com.mgm.mcrm.common.dtos.BaseApiResponse;
import com.mgm.mcrm.common.dtos.mgm_api.UserInfoApiRecord;
import com.mgm.mcrm.common.dtos.msg.AppSettingMsgData; import com.mgm.mcrm.common.dtos.msg.AppSettingMsgData;
import com.mgm.mcrm.common.dtos.msg.UpdateCfgItem; import com.mgm.mcrm.common.dtos.msg.UpdateCfgItem;
import com.mgm.mcrm.common.dtos.system.AppServerState; import com.mgm.mcrm.common.dtos.system.AppServerState;
@@ -25,6 +27,7 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.web.servlet.support.RequestContextUtils; import org.springframework.web.servlet.support.RequestContextUtils;
import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
@@ -36,6 +39,7 @@ import java.util.*;
public class SysCommon { public class SysCommon {
public static String runtime_path = ""; public static String runtime_path = "";
public static String serverIp=""; public static String serverIp="";
public static String serverName=""; public static String serverName="";
@@ -49,10 +53,6 @@ public class SysCommon {
public static int postTimeOut = 20; public static int postTimeOut = 20;
//for stress test //for stress test
public static int tokenExpMin = 5;
public static int refreshTokenExpDay = 30;
public static APIConfig apiConfig = new APIConfig();
private static Map<String,String> notifyTemplateMap = new HashMap<String,String>();
private static final Map<String,AppServerState> appServerStates = new HashMap<String,AppServerState>(); private static final Map<String,AppServerState> appServerStates = new HashMap<String,AppServerState>();
private static final List<String> allowOriginSource = new ArrayList<String>(); private static final List<String> allowOriginSource = new ArrayList<String>();
@Getter @Getter
@@ -85,7 +85,6 @@ public class SysCommon {
//--Server Info //--Server Info
serverIp = NetworkUtil.getInternalIp(); serverIp = NetworkUtil.getInternalIp();
serverName = NetworkUtil.getServerName(); serverName = NetworkUtil.getServerName();
loadAPIConfig(props);
} catch (Exception e) { } catch (Exception e) {
isLoaded = false; isLoaded = false;
LogUtil.error(SysCommon.class, "Load configuration error:" + e.getMessage()); LogUtil.error(SysCommon.class, "Load configuration error:" + e.getMessage());
@@ -388,18 +387,6 @@ public class SysCommon {
SysCommon.runtime_path = runtime_path; SysCommon.runtime_path = runtime_path;
} }
// Load API Config
public static void loadAPIConfig(Properties props) {
boolean isLoaded = true;
//SMS Config
SysCommon.apiConfig.setPort_SMTP(props.getProperty("mail_port", ""));
SysCommon.apiConfig.setHost_SMTP(props.getProperty("mail_smtp_host", ""));
SysCommon.apiConfig.setUsername_SMTP(props.getProperty("mail_sender", ""));
SysCommon.apiConfig.setPassword_SMTP(props.getProperty("mail_sender_password", ""));
SysCommon.apiConfig.setSend_to_SMTP(props.getProperty("mail_send_to", ""));
LogUtil.info(SysCommon.class, "Loaded API config.");
}
//-- Path Type 1= Class path 2=Application path 3=URI Path //-- Path Type 1= Class path 2=Application path 3=URI Path
public static String loadResFileContentByPath(String filePath, int pathType) { public static String loadResFileContentByPath(String filePath, int pathType) {
@@ -503,6 +490,7 @@ public class SysCommon {
LoginUserInfo loginUser = null; LoginUserInfo loginUser = null;
if(StringUtils.isNotBlank(tokenContent)) { if(StringUtils.isNotBlank(tokenContent)) {
try { try {
LogUtil.info(SysCommon.class, "Parse Token content:"+tokenContent);
tokenContent = tokenContent.replace("Bearer ", ""); tokenContent = tokenContent.replace("Bearer ", "");
DecodedJWT decodeData = JWT.decode(tokenContent); DecodedJWT decodeData = JWT.decode(tokenContent);
@@ -513,8 +501,14 @@ public class SysCommon {
}else { }else {
loginUser.setId(-1L); loginUser.setId(-1L);
} }
loginUser.setLoginId(decodeData.getClaim("login_id").asString());
loginUser.setGroupName(decodeData.getClaim("user_group").asString());
String loginId = decodeData.getClaim("login_id").asString();
if(loginId!=null) loginId = StringUtils.replace(loginId, "@mgm.mo", "");
loginUser.setLoginId(loginId);
loginUser.setGroupName(decodeData.getClaim("group_name").asString());
}catch(Exception err) { }catch(Exception err) {
LogUtil.error(SysCommon.class, "Parse Token failed:"+err.getMessage()); LogUtil.error(SysCommon.class, "Parse Token failed:"+err.getMessage());
loginUser =null; loginUser =null;
@@ -18,6 +18,7 @@ public class SysConstants {
public static final int CMS_TOKEN_TYPE=0; public static final int CMS_TOKEN_TYPE=0;
public static final int MOBILE_TOKEN_TYPE=1; public static final int MOBILE_TOKEN_TYPE=1;
public static final int THIRD_PARTY_TOKEN_TYPE=2;
public static final String PERMISSION_APP_VIEW_BOOKING="10001_01"; public static final String PERMISSION_APP_VIEW_BOOKING="10001_01";
public static final String PERMISSION_APP_NEW_BOOKING="10001_02"; public static final String PERMISSION_APP_NEW_BOOKING="10001_02";
@@ -1,17 +0,0 @@
package com.mgm.mcrm.common.dtos.config;
import lombok.Data;
@Data
public class APIConfig {
private boolean isLoaded = false;
//SMTP Config
private String port_SMTP= "";
private String host_SMTP= "";
private String username_SMTP= "";
private String password_SMTP= "";
private String send_to_SMTP= "";
}
@@ -1,34 +0,0 @@
package com.mgm.mcrm.common.dtos.excel_export;
public class ColumnDefine {
private String columnHeader;
private String dataType;
private String attrName;
private int columnWidth=0;
public String getColumnHeader() {
return columnHeader;
}
public void setColumnHeader(String columnHeader) {
this.columnHeader = columnHeader;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getAttrName() {
return attrName;
}
public void setAttrName(String attrName) {
this.attrName = attrName;
}
public int getColumnWidth() {
return columnWidth;
}
public void setColumnWidth(int columnWidth) {
this.columnWidth = columnWidth;
}
}
@@ -1,85 +0,0 @@
package com.mgm.mcrm.common.dtos.excel_export;
import java.util.List;
public class DataElement {
private int offsetRow=0;
private int offsetCol=0;
private int elementType=0;
private boolean isShowHeader=false;
private String objClassName;
private String headerAlign="center";
private String headerColor="";
private String textAlign="left";
private String textColor="";
private List<ColumnDefine> columnDefs;
private List blockData;
public int getElementType() {
return elementType;
}
public void setElementType(int elementType) {
this.elementType = elementType;
}
public List<ColumnDefine> getColumnDefs() {
return columnDefs;
}
public void setColumnDefs(List<ColumnDefine> columnDefs) {
this.columnDefs = columnDefs;
}
public boolean isShowHeader() {
return isShowHeader;
}
public void setShowHeader(boolean isShowHeader) {
this.isShowHeader = isShowHeader;
}
public int getOffsetRow() {
return offsetRow;
}
public void setOffsetRow(int offsetRow) {
this.offsetRow = offsetRow;
}
public int getOffsetCol() {
return offsetCol;
}
public void setOffsetCol(int offsetCol) {
this.offsetCol = offsetCol;
}
public String getObjClassName() {
return objClassName;
}
public void setObjClassName(String objClassName) {
this.objClassName = objClassName;
}
public String getHeaderAlign() {
return headerAlign;
}
public void setHeaderAlign(String headerAlign) {
this.headerAlign = headerAlign;
}
public String getHeaderColor() {
return headerColor;
}
public void setHeaderColor(String headerColor) {
this.headerColor = headerColor;
}
public String getTextAlign() {
return textAlign;
}
public void setTextAlign(String textAlign) {
this.textAlign = textAlign;
}
public String getTextColor() {
return textColor;
}
public void setTextColor(String textColor) {
this.textColor = textColor;
}
public List getBlockData() {
return blockData;
}
public void setBlockData(List blockData) {
this.blockData = blockData;
}
}
@@ -1,24 +0,0 @@
package com.mgm.mcrm.common.dtos.excel_export;
import java.util.List;
public class ExportDefination {
private List<ExportSheet> exportPages;
private String exportFileName;
public List<ExportSheet> getExportPages() {
return exportPages;
}
public void setExportPages(List<ExportSheet> exportPages) {
this.exportPages = exportPages;
}
public String getExportFileName() {
return exportFileName;
}
public void setExportFileName(String exportFileName) {
this.exportFileName = exportFileName;
}
}
@@ -1,26 +0,0 @@
package com.mgm.mcrm.common.dtos.excel_export;
import java.util.List;
public class ExportSheet {
private String sheetName;
private List<DataElement> dataElements;
public ExportSheet() {
}
public String getSheetName() {
return sheetName;
}
public void setSheetName(String sheetName) {
this.sheetName = sheetName;
}
public List<DataElement> getDataElements() {
return dataElements;
}
public void setDataElements(List<DataElement> dataElements) {
this.dataElements = dataElements;
}
}
@@ -1,12 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import lombok.Data;
@Data
public class GetLimoAccessTokenRequest {
private String LoginId;
private String password;
}
@@ -1,11 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import lombok.Data;
@Data
public class GetLimoFlightDetailsRequest {
private String flightNo;
private String pickupDateTime;
private String pickupAirportCode;
private String dropOffAirportCode;
}
@@ -1,10 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import lombok.Data;
@Data
public class GetLimoOverriderRequest {
private String OverriderIdOrName;
}
@@ -1,10 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import lombok.Data;
@Data
public class GetLimoTotalAmountRequest {
private String pickupPOIId;
private String dropoffPOIIds;
private String singleTripPrices;
}
@@ -1,10 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import lombok.Data;
@Data
public class GetPlayerInfoRequest {
private String playerId;
}
@@ -1,15 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import lombok.Data;
@Data
public class GetSimpleLimoBookingQualificationStatusRequest {
private String playerId;
private String bookingType;
private String bookingDate;
}
@@ -1,150 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class InternalCreateLimoBookingRequest {
private int createNotConfirmBooking;
private String bookingType;
private String greetType;
private String otherGreetType;
private String guestType;
private String tripType;
private String playerId;
private String ranking;
private String overrideBy;
private String complexOverrider;
private String roomNo;
private String employeeId;
private String lastName;
private String salution;
private String chineseLastName;
private String bookerContact;
private String tripContact;
private int adHoc;
private LocalDateTime pickupDatetime;
private Long carTypeId;
private Integer passengerNo;
private Long pickupPOIID;
private String pickup;
private Long pickupTripPriceId;
private String pickupRegion;
private Long dropoffPOIID;
private String dropoff;
private Long dropoffTripPriceId;
private String dropoffRegion;
private Long extraDropoffPOIID1;
private String extraDropoff1;
private Long extraDropoffTripPriceID1;
private String extraDropoffRegion1;
private Long extraDropoffPOIID2;
private String extraDropoff2;
private Long extraDropoffTripPriceID2;
private String extraDropoffRegion2;
private Long extraDropoffPOIID3;
private String extraDropoff3;
private Long extraDropoffTripPriceID3;
private String extraDropoffRegion3;
private Long extraDropoffPOIID4;
private String extraDropoff4;
private Long extraDropoffTripPriceID4;
private String extraDropoffRegion4;
private Long extraDropoffPOIID5;
private String extraDropoff5;
private Long extraDropoffTripPriceID5;
private String extraDropoffRegion5;
private Long extraDropoffPOIID6;
private String extraDropoff6;
private Long extraDropoffTripPriceID6;
private String extraDropoffRegion6;
private Long extraDropoffPOIID7;
private String extraDropoff7;
private Long extraDropoffTripPriceID7;
private String extraDropoffRegion7;
private Long extraDropoffPOIID8;
private String extraDropoff8;
private Long extraDropoffTripPriceID8;
private String extraDropoffRegion8;
private Long extraDropoffPOIID9;
private String extraDropoff9;
private Long extraDropoffTripPriceID9;
private String extraDropoffRegion9;
private Long extraDropoffPOIID10;
private String extraDropoff10;
private Long extraDropoffTripPriceID10;
private String extraDropoffRegion10;
private BigDecimal singleTripPrice;
private BigDecimal defaultTripPrice;
private BigDecimal defaultPublishTripPrice;
private BigDecimal hourlyRate;
private BigDecimal hourlyWaitingFee;
private Integer hour;
private Integer hourlyWaiting;
private BigDecimal extraDropoffPrice1;
private BigDecimal extraDropoffPrice2;
private BigDecimal extraDropoffPrice3;
private BigDecimal extraDropoffPrice4;
private BigDecimal extraDropoffPrice5;
private BigDecimal extraDropoffPrice6;
private BigDecimal extraDropoffPrice7;
private BigDecimal extraDropoffPrice8;
private BigDecimal extraDropoffPrice9;
private BigDecimal extraDropoffPrice10;
private String otherPriceRemark;
private BigDecimal otherPrice;
private String paymentMethod;
private BigDecimal totalAmount;
private Boolean highImportance;
private Boolean tenOut;
private Boolean butlerGreet;
private String bookedBy;
private String approvedBy;
private String bookingRemark;
private String driverRemark;
private String limoInternalRemark;
private String systemRemark;
private Boolean limoGreet;
private Boolean hostGreet;
private Boolean vipMeetNGreet;
private String otherGreet;
private String flightDetails;
private String signage;
public int getCreateNotConfirmBooking() {
return createNotConfirmBooking;
}
}
@@ -1,148 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
public class InternalUpdateLimoBookingRequest {
private Long id;
private Boolean createNotConfirmBooking;
private String bookingType;
private String greetType;
private String otherGreetType;
private String guestType;
private String tripType;
private String playerId;
private String ranking;
private String overrideBy;
private String complexOverrider;
private String roomNo;
private String employeeId;
private String lastName;
private String salution;
private String chineseLastName;
private String bookerContact;
private String tripContact;
private String adHoc;
private LocalDateTime pickupDatetime;
private Long carTypeId;
private Integer passengerNo;
private Long pickupPOIID;
private String pickup;
private Long pickupTripPriceID;
private String pickupRegion;
private Long dropoffPOIID;
private String dropoff;
private Long dropoffTripPriceID;
private String dropoffRegion;
private Long extraDropoffPOIID1;
private String extraDropoff1;
private Long extraDropoffTripPriceID1;
private String extraDropoffRegion1;
private Long extraDropoffPOIID2;
private String extraDropoff2;
private Long extraDropoffTripPriceID2;
private String extraDropoffRegion2;
private Long extraDropoffPOIID3;
private String extraDropoff3;
private Long extraDropoffTripPriceID3;
private String extraDropoffRegion3;
private Long extraDropoffPOIID4;
private String extraDropoff4;
private Long extraDropoffTripPriceID4;
private String extraDropoffRegion4;
private Long extraDropoffPOIID5;
private String extraDropoff5;
private Long extraDropoffTripPriceID5;
private String extraDropoffRegion5;
private Long extraDropoffPOIID6;
private String extraDropoff6;
private Long extraDropoffTripPriceID6;
private String extraDropoffRegion6;
private Long extraDropoffPOIID7;
private String extraDropoff7;
private Long extraDropoffTripPriceID7;
private String extraDropoffRegion7;
private Long extraDropoffPOIID8;
private String extraDropoff8;
private Long extraDropoffTripPriceID8;
private String extraDropoffRegion8;
private Long extraDropoffPOIID9;
private String extraDropoff9;
private Long extraDropoffTripPriceID9;
private String extraDropoffRegion9;
private Long extraDropoffPOIID10;
private String extraDropoff10;
private Long extraDropoffTripPriceID10;
private String extraDropoffRegion10;
private BigDecimal singleTripPrice;
private BigDecimal defaultTripPrice;
private BigDecimal defaultPublishTripPrice;
private BigDecimal hourlyRate;
private BigDecimal hourlyWaitingFee;
private Integer hour;
private Integer hourlyWaiting;
private BigDecimal extraDropoffPrice1;
private BigDecimal extraDropoffPrice2;
private BigDecimal extraDropoffPrice3;
private BigDecimal extraDropoffPrice4;
private BigDecimal extraDropoffPrice5;
private BigDecimal extraDropoffPrice6;
private BigDecimal extraDropoffPrice7;
private BigDecimal extraDropoffPrice8;
private BigDecimal extraDropoffPrice9;
private BigDecimal extraDropoffPrice10;
private String otherPriceRemark;
private BigDecimal otherPrice;
private String paymentMethod;
private BigDecimal totalAmount;
private Boolean highImportance;
private Boolean tenOut;
private Boolean butlerGreet;
private String bookedBy;
private String approvedBy;
private String bookingRemark;
private String driverRemark;
private String limoInternalRemark;
private String systemRemark;
private Boolean limoGreet;
private Boolean hostGreet;
private Boolean vipMeetNGreet;
private String otherGreet;
private String flightDetails;
private String signage;
}
@@ -1,23 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
public class ItemRecord {
private String ItemRecordDescription = null;
public ItemRecord() {
}
public String getItemRecordDescription() {
return ItemRecordDescription;
}
public void setItemRecordDescription(String itemRecordDescription) {
ItemRecordDescription = itemRecordDescription;
}
}
@@ -1,33 +0,0 @@
package com.mgm.mcrm.common.dtos.mgm_api;
import java.util.List;
public class NonMGMBookingApiResult {
private String statusCode;
private String statusDescription;
private List<NonMGMBookingRecord> records;
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public String getStatusDescription() {
return statusDescription;
}
public void setStatusDescription(String statusDescription) {
this.statusDescription = statusDescription;
}
public List<NonMGMBookingRecord> getRecords() {
return records;
}
public void setRecords(List<NonMGMBookingRecord> records) {
this.records = records;
}
}
@@ -25,7 +25,8 @@ public enum EnumBookingStatus {
DUE_OUT_UNDERSCORE("DUE_OUT", "DUE_OUT"), DUE_OUT_UNDERSCORE("DUE_OUT", "DUE_OUT"),
DUEOUT("DUEOUT", "DUE_OUT"), DUEOUT("DUEOUT", "DUE_OUT"),
CANCELED("CANCELED", "CANCELED"), CANCELED("CANCELED", "CANCELED"),
CANCELLED("CANCELLED", "CANCELED"); CANCELLED("CANCELLED", "CANCELED"),
NO_SHOW("No-Show", "NO_SHOW");
@Getter @Getter
private final String key; private final String key;
@@ -6,13 +6,19 @@ import com.mgm.mcrm.common.utils.NetworkUtil;
import jakarta.servlet.*; import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.springframework.util.AntPathMatcher;
import java.io.IOException; import java.io.IOException;
import java.util.List;
@Slf4j @Slf4j
public class ConfigHeaderFilter implements Filter { public class ConfigHeaderFilter implements Filter {
private final AntPathMatcher pathMatcher = new AntPathMatcher();
@Setter
private List<String> ignoreOriginPatterns;
@Override @Override
public void init(FilterConfig filterConfig) throws ServletException { public void init(FilterConfig filterConfig) throws ServletException {
@@ -23,15 +29,30 @@ public class ConfigHeaderFilter implements Filter {
} }
private boolean isIgnoreOriginChecking(HttpServletRequest request){
if (ignoreOriginPatterns == null) {
return false;
}
return ignoreOriginPatterns.stream()
.anyMatch(pattern -> pathMatcher.match(pattern, request.getRequestURI()));
}
@Override @Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request; HttpServletRequest req = (HttpServletRequest) request;
if (response instanceof HttpServletResponse httpServletResponse) { if (response instanceof HttpServletResponse httpServletResponse) {
if(httpServletResponse.getHeader("Server")!=null) {
httpServletResponse.setHeader("Server", "");
}
String origin = ((HttpServletRequest) request).getHeader("Origin"); String origin = ((HttpServletRequest) request).getHeader("Origin");
String sanitizedOrigin = NetworkUtil.sanitizeCRLF(origin); String sanitizedOrigin = NetworkUtil.sanitizeCRLF(origin);
if (SysCommon.isAllowOriginSource(sanitizedOrigin) || "OPTIONS".equalsIgnoreCase(req.getMethod())) {
if(isIgnoreOriginChecking((HttpServletRequest)request) || "OPTIONS".equalsIgnoreCase(req.getMethod())){
httpServletResponse.setHeader("Access-Control-Allow-Origin",sanitizedOrigin);
}else{
if (SysCommon.isAllowOriginSource(sanitizedOrigin)) {
httpServletResponse.setHeader("Access-Control-Allow-Origin", sanitizedOrigin); httpServletResponse.setHeader("Access-Control-Allow-Origin", sanitizedOrigin);
} else { } else {
LogUtil.warn(ConfigHeaderFilter.class, "Origin of [" + sanitizedOrigin + "] is not allowed"); LogUtil.warn(ConfigHeaderFilter.class, "Origin of [" + sanitizedOrigin + "] is not allowed");
@@ -45,9 +66,9 @@ public class ConfigHeaderFilter implements Filter {
req.getRemoteAddr(), req.getRemoteAddr(),
req.getHeader("X-Forwarded-For"), req.getHeader("X-Forwarded-For"),
req.getHeader("User-Agent")); req.getHeader("User-Agent"));
return; return;
} }
}
httpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD"); httpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
httpServletResponse.addHeader("Access-Control-Allow-Headers", "Content-Type,Authorization,ClientId,Refreshtoken"); httpServletResponse.addHeader("Access-Control-Allow-Headers", "Content-Type,Authorization,ClientId,Refreshtoken");
httpServletResponse.addHeader("Access-Control-Allow-Credentials", "true"); httpServletResponse.addHeader("Access-Control-Allow-Credentials", "true");
@@ -55,8 +55,6 @@ public class HttpRequestOptions {
*/ */
private HttpContext context; private HttpContext context;
// private Map<String, Object> map;
/** /**
* 以json格式作为输入参数 * 以json格式作为输入参数
*/ */
@@ -83,19 +81,19 @@ public class HttpRequestOptions {
private RequestConfig requestConfig; private RequestConfig requestConfig;
/** /**
* 解决多线程下载时,strean被close的问题 * 当前请求的输出流
*/ */
private static final ThreadLocal<OutputStream> outs = new ThreadLocal<OutputStream>(); private OutputStream out;
/** /**
* 解决多线程处理时,url被覆盖问题 * 当前请求的 URL
*/ */
private static final ThreadLocal<String> urls = new ThreadLocal<String>(); private String url;
/** /**
* 解决多线程处理时,url被覆盖问题 * 当前请求的参数,随实例保存,避免线程复用时混入上一次请求的数据
*/ */
private static final ThreadLocal<Map<String,Object>> maps = new ThreadLocal<Map<String,Object>>(); private Map<String, Object> parameters;
/** /**
* @param client HttpClient对象 * @param client HttpClient对象
@@ -111,7 +109,7 @@ public class HttpRequestOptions {
* @return 返回当前对象 * @return 返回当前对象
*/ */
public HttpRequestOptions url(String url) { public HttpRequestOptions url(String url) {
urls.set(url); this.url = url;
return this; return this;
} }
@@ -169,20 +167,13 @@ public class HttpRequestOptions {
* @return 返回当前对象 * @return 返回当前对象
*/ */
public HttpRequestOptions map(Map<String, Object> map) { public HttpRequestOptions map(Map<String, Object> map) {
// synchronized (getClass()) { if (map == null) {
// if(this.map==null || map==null){ parameters = null;
// this.map = map; } else if (parameters == null || map.isEmpty()) {
// }else { parameters = new HashMap<>(map);
// this.map.putAll(map);;
// }
// }
Map<String, Object> m = maps.get();
if(m == null || map.isEmpty()){
m = map;
} else { } else {
m.putAll(map); parameters.putAll(map);
} }
maps.set(m);
return this; return this;
} }
@@ -192,9 +183,8 @@ public class HttpRequestOptions {
*/ */
public HttpRequestOptions json(String json) { public HttpRequestOptions json(String json) {
this.json = json; this.json = json;
Map<String, Object> map = new HashMap<String, Object>(); parameters = new HashMap<>();
map.put(HttpEntityBuilder.ENTITY_JSON, json); parameters.put(HttpEntityBuilder.ENTITY_JSON, json);
maps.set(map);
return this; return this;
} }
@@ -222,23 +212,12 @@ public class HttpRequestOptions {
* @return 返回当前对象 * @return 返回当前对象
*/ */
public HttpRequestOptions files(String[] filePaths, String inputName, boolean forceRemoveContentTypeChraset) { public HttpRequestOptions files(String[] filePaths, String inputName, boolean forceRemoveContentTypeChraset) {
// synchronized (getClass()) { if (parameters == null) {
// if(this.map==null){ parameters = new HashMap<>();
// this.map= new HashMap<String, Object>();
// }
// }
// map.put(Utils.ENTITY_MULTIPART, filePaths);
// map.put(Utils.ENTITY_MULTIPART+".name", inputName);
// map.put(Utils.ENTITY_MULTIPART+".rmCharset", forceRemoveContentTypeChraset);
Map<String, Object> m = maps.get();
if(m.isEmpty()){
m = new HashMap<String, Object>();
} }
m.put(HttpEntityBuilder.ENTITY_MULTIPART, filePaths); parameters.put(HttpEntityBuilder.ENTITY_MULTIPART, filePaths);
m.put(HttpEntityBuilder.ENTITY_MULTIPART+".name", inputName); parameters.put(HttpEntityBuilder.ENTITY_MULTIPART+".name", inputName);
m.put(HttpEntityBuilder.ENTITY_MULTIPART+".rmCharset", forceRemoveContentTypeChraset); parameters.put(HttpEntityBuilder.ENTITY_MULTIPART+".rmCharset", forceRemoveContentTypeChraset);
maps.set(m);
return this; return this;
} }
@@ -273,7 +252,7 @@ public class HttpRequestOptions {
* @return 返回当前对象 * @return 返回当前对象
*/ */
public HttpRequestOptions out(OutputStream out) { public HttpRequestOptions out(OutputStream out) {
outs.set(out); this.out = out;
return this; return this;
} }
@@ -329,7 +308,7 @@ public class HttpRequestOptions {
} }
public String url() { public String url() {
return urls.get(); return url;
} }
public HttpMethods method() { public HttpMethods method() {
@@ -345,8 +324,7 @@ public class HttpRequestOptions {
} }
public Map<String, Object> map() { public Map<String, Object> map() {
// return map; return parameters;
return maps.get();
} }
public String json() { public String json() {
@@ -366,7 +344,7 @@ public class HttpRequestOptions {
} }
public OutputStream out() { public OutputStream out() {
return outs.get(); return out;
} }
public RequestConfig requestConfig() { public RequestConfig requestConfig() {
@@ -5,17 +5,10 @@ import com.mgm.mcrm.common.services.ConfigurableTrustHandler;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.ssl.SSLContexts;
import javax.net.ssl.*; import javax.net.ssl.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException; import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
/** /**
* SSL 工具类(基于 HttpClient 5) * SSL 工具类(基于 HttpClient 5)
@@ -105,33 +98,6 @@ public class HttpSslSupport {
} }
} }
/**
* 使用自定义证书(trustStore)初始化 SSLContext
*/
public HttpSslSupport customSSL(String keyStorePath, String keyStorepass) {
FileInputStream instream = null;
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
instream = new FileInputStream(new File(keyStorePath));
trustStore.load(instream, keyStorepass.toCharArray());
// 相信自己的 CA 和所有自签名证书
this.sc = SSLContexts.custom()
.loadTrustMaterial(trustStore, (chain, authType) -> true)
.build();
return this;
} catch (KeyManagementException | KeyStoreException |
NoSuchAlgorithmException | CertificateException | IOException e) {
throw new RuntimeException("初始化自定义 SSLContext 失败", e);
} finally {
if (instream != null) {
try {
instream.close();
} catch (IOException ignore) {
// ignore
}
}
}
}
/** /**
* 获取(或创建)指定协议版本的 {@link SSLContext} * 获取(或创建)指定协议版本的 {@link SSLContext}
@@ -77,6 +77,12 @@ public class BookingControlMsgConsumer {
Bookings.class Bookings.class
); );
// booking.setApproveStatus("F");
// Integer tryTime = booking.getTryTime() != null ? booking.getTryTime() : 0;
// booking.setTryTime(tryTime + 1);
//
// bookingDao.save(booking);
bookingDao.updateProcessStatus( bookingDao.updateProcessStatus(
booking.getId(), booking.getId(),
0 0
@@ -162,16 +162,16 @@ public class ADFSUtil {
if(decodeData.getClaim("upn")!=null) { if(decodeData.getClaim("upn")!=null) {
result.setLoginId(decodeData.getClaim("upn").asString()); result.setLoginId(decodeData.getClaim("upn").asString());
} }
if(decodeData.getClaim("user_group")!=null) { if(decodeData.getClaim("group_name")!=null) {
try { try {
List<String> groupNames = decodeData.getClaim("user_group").asList(String.class); List<String> groupNames = decodeData.getClaim("group_name").asList(String.class);
String groupNameVal = ""; String groupNameVal = "";
for(int i=0;i<groupNames.size();i++) { for(int i=0;i<groupNames.size();i++) {
groupNameVal += (i>0?";":"")+groupNames.get(i); groupNameVal += (i>0?";":"")+groupNames.get(i);
} }
result.setGroupName(groupNameVal); result.setGroupName(groupNameVal);
}catch(Exception err) { }catch(Exception err) {
result.setGroupName(decodeData.getClaim("user_group").asString()); result.setGroupName(decodeData.getClaim("group_name").asString());
} }
} }
}catch(Exception err) { }catch(Exception err) {
@@ -0,0 +1,36 @@
package com.mgm.mcrm.common.utils;
import java.util.Base64;
public class Base64Utils {
/**
* 使用Base64加密字符串
* @return 加密之后的字符串
*
*/
public static String encode(String data){
try {
return Base64.getEncoder().encodeToString(data.getBytes("utf8"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
* 使用Base64解密
* @return 解密之后的字符串
*
*/
public static String decode(String data){
try {
return new String(Base64.getDecoder().decode(data));
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
@@ -10,7 +10,6 @@ import com.mgm.mcrm.common.services.ConfigurableTrustHandler;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings; import org.apache.commons.lang3.Strings;
import org.apache.hc.client5.http.classic.methods.HttpDelete; import org.apache.hc.client5.http.classic.methods.HttpDelete;
import org.apache.hc.client5.http.classic.methods.HttpGet; import org.apache.hc.client5.http.classic.methods.HttpGet;
@@ -27,16 +26,13 @@ import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.protocol.HttpClientContext; import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.socket.ConnectionSocketFactory; import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.client5.http.ssl.TrustAllStrategy;
import org.apache.hc.core5.http.ContentType; import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.config.Registry; import org.apache.hc.core5.http.config.Registry;
import org.apache.hc.core5.http.config.RegistryBuilder; import org.apache.hc.core5.http.config.RegistryBuilder;
import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.io.entity.EntityUtils;
import org.apache.hc.core5.http.io.entity.StringEntity; import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.apache.hc.core5.util.Timeout; import org.apache.hc.core5.util.Timeout;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -93,12 +89,13 @@ public class HttpUtil {
if(Strings.CI.startsWith(requestUrl, "https://")) { if(Strings.CI.startsWith(requestUrl, "https://")) {
SSLContext sslContext = null; SSLContext sslContext = null;
try { try {
sslContext = SSLContextBuilder.create().loadTrustMaterial(TrustAllStrategy.INSTANCE).build(); //sslContext = SSLContextBuilder.create().loadTrustMaterial(TrustAllStrategy.INSTANCE).build();
sslContext = getSSLContext();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE )) .register("https", new SSLConnectionSocketFactory(sslContext, getTrustHandler()))
.build(); .build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
@@ -37,6 +37,11 @@ public class LogUtil {
getLogger(callClass).error(message); getLogger(callClass).error(message);
} }
public static void error(Class callClass,String message, Throwable e) {
if(SysCommon.appDebugLog == true)
getLogger(callClass).error(message, e);
}
public static String getObjectAttr(Object srcObj, String[] attrNames) { public static String getObjectAttr(Object srcObj, String[] attrNames) {
StringBuilder attrText = new StringBuilder(); StringBuilder attrText = new StringBuilder();
if(srcObj!=null && attrNames!=null) { if(srcObj!=null && attrNames!=null) {
@@ -88,8 +88,8 @@ public class NetworkUtil {
private static String getIpFromHeaders(HttpServletRequest request) { private static String getIpFromHeaders(HttpServletRequest request) {
String[] headerNames = { String[] headerNames = {
"X-Real-IP",
"X-Forwarded-For", "X-Forwarded-For",
"X-Real-IP",
"Proxy-Client-IP", "Proxy-Client-IP",
"WL-Proxy-Client-IP", "WL-Proxy-Client-IP",
"HTTP_CLIENT_IP", "HTTP_CLIENT_IP",
@@ -100,7 +100,7 @@ public class NetworkUtil {
String headerValue = request.getHeader(headerName); String headerValue = request.getHeader(headerName);
if (headerValue != null && !headerValue.isEmpty()) { if (headerValue != null && !headerValue.isEmpty()) {
isContainForwardHeader=true; isContainForwardHeader=true;
LogUtil.info(NetworkUtil.class,"Check header["+headerName+"] of value["+headerValue+"]"); LogUtil.info(NetworkUtil.class,"Check Forward header["+headerName+"] of value["+headerValue+"]");
String ip = extractValidIp(headerValue); String ip = extractValidIp(headerValue);
if (ip != null) { if (ip != null) {
return ip; return ip;
File diff suppressed because it is too large Load Diff
@@ -1185,7 +1185,7 @@ public class LimoService {
// --- Room / Employee --- // --- Room / Employee ---
limoBookingRequest.setRoomNo(""); limoBookingRequest.setRoomNo("");
limoBookingRequest.setEmployeeId(defaultString(request.getEmployeeId(), "")); // limoBookingRequest.setEmployeeId(defaultString(request.getEmployeeId(), ""));
// --- Contact --- // --- Contact ---
limoBookingRequest.setBookerContact(defaultString(request.getBookerContact(), "")); limoBookingRequest.setBookerContact(defaultString(request.getBookerContact(), ""));
@@ -0,0 +1,22 @@
package com.mgm.mcrm.logging.models;
import jakarta.persistence.*;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name="sys_booking_cache_log")
public class SysBookingCacheLog {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="category")
private String category;
@Column(name="cache_key")
private String cacheKey;
@Column(name="cached_time")
private LocalDateTime cachedTime;
}
@@ -0,0 +1,20 @@
package com.mgm.mcrm.logging.models;
import jakarta.persistence.*;
import lombok.Data;
@Data
@Entity
@Table(name="sys_booking_profile_mapping")
public class SysBookingProfileMapping {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name="category")
private String category;
@Column(name="player_id")
private String playerId;
@Column(name="profile_id")
private String profileId;
}
@@ -0,0 +1,11 @@
package com.mgm.mcrm.logging.repositories;
import com.mgm.mcrm.logging.models.SysBookingCacheLog;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface SysBookingCacheLogDao extends JpaRepository<SysBookingCacheLog, Long> {
List<SysBookingCacheLog> findAllByCategoryAndCacheKey(String category, String cacheKey);
}
@@ -0,0 +1,12 @@
package com.mgm.mcrm.logging.repositories;
import com.mgm.mcrm.logging.models.SysBookingCacheLog;
import com.mgm.mcrm.logging.models.SysBookingProfileMapping;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface SysBookingProfileMappingDao extends JpaRepository<SysBookingProfileMapping, Long> {
List<SysBookingProfileMapping> findAllByCategoryAndPlayerId(String category, String playerId);
}
@@ -0,0 +1,88 @@
package com.mgm.mcrm.logging.services;
import com.mgm.mcrm.logging.models.SysBookingCacheLog;
import com.mgm.mcrm.logging.models.SysBookingProfileMapping;
import com.mgm.mcrm.logging.repositories.SysBookingCacheLogDao;
import com.mgm.mcrm.logging.repositories.SysBookingProfileMappingDao;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
@Service
public class SysBookingCacheService {
@Value("${mcrm.daylight.booking-search-cache-seconds}")
private int daylightCacheSeconds;
@Resource
private SysBookingCacheLogDao sysBookingCacheLogDao;
@Resource
private SysBookingProfileMappingDao sysBookingProfileMappingDao;
public boolean isDaylightBookingCacheValid(String playerId){
boolean cacheValid = false;
List<SysBookingCacheLog> cacheLogs = sysBookingCacheLogDao.findAllByCategoryAndCacheKey("DAYLIGHT",playerId);
if(!cacheLogs.isEmpty()){
SysBookingCacheLog cacheLog = cacheLogs.getFirst();
for(int i=1;i<cacheLogs.size();i++){
sysBookingCacheLogDao.delete(cacheLogs.get(i));
}
LocalDateTime cacheExpiryTime = LocalDateTime.now().minusSeconds(daylightCacheSeconds);
if(cacheLog.getCachedTime().isAfter(cacheExpiryTime)){
cacheValid =true;
}
}
return cacheValid;
}
public void updateDaylightBookingCacheLog(String playerId){
List<SysBookingCacheLog> cacheLogs = sysBookingCacheLogDao.findAllByCategoryAndCacheKey("DAYLIGHT",playerId);
SysBookingCacheLog cacheLog = null;
if(!cacheLogs.isEmpty()){
cacheLog = cacheLogs.getFirst();
for(int i=1;i<cacheLogs.size();i++){
sysBookingCacheLogDao.delete(cacheLogs.get(i));
}
}else{
cacheLog = new SysBookingCacheLog();
cacheLog.setCategory("DAYLIGHT");
cacheLog.setCacheKey(playerId);
}
cacheLog.setCachedTime(LocalDateTime.now());
sysBookingCacheLogDao.save(cacheLog);
}
public String getDaylightProfileMappingFromCache(String playerId){
String profileId=null;
List<SysBookingProfileMapping> profileMappings = sysBookingProfileMappingDao.findAllByCategoryAndPlayerId("DAYLIGHT",playerId);
if(!profileMappings.isEmpty()){
SysBookingProfileMapping profileMapping = profileMappings.getFirst();
for(int i=1;i<profileMappings.size();i++){
sysBookingProfileMappingDao.delete(profileMappings.get(i));
}
profileId=profileMapping.getProfileId();
}
return profileId;
}
public void updateDaylightProfileMapping(String playerId, String profileId){
List<SysBookingProfileMapping> profileMappings = sysBookingProfileMappingDao.findAllByCategoryAndPlayerId("DAYLIGHT",playerId);
SysBookingProfileMapping profileMapping = null;
if(!profileMappings.isEmpty()){
profileMapping = profileMappings.getFirst();
for(int i=1;i<profileMappings.size();i++){
sysBookingProfileMappingDao.delete(profileMappings.get(i));
}
}else{
profileMapping = new SysBookingProfileMapping();
profileMapping.setCategory("DAYLIGHT");
profileMapping.setPlayerId(playerId);
}
profileMapping.setProfileId(profileId);
sysBookingProfileMappingDao.save(profileMapping);
}
}
@@ -166,41 +166,41 @@ public class EmailTemplateService {
String propertyName = typeList.getFirst().getPropertyEmailName(); String propertyName = typeList.getFirst().getPropertyEmailName();
if(Strings.CI.contains(propertyName, "mandarin")) propertyName="MO"; if(Strings.CI.contains(propertyName, "mandarin")) propertyName="MO";
String title = "Dear "+propertyName+" Team,"; String title = "Dear "+propertyName+" Team,";
String content = template.getContent(); StringBuilder content = new StringBuilder(template.getContent());
String table = ""; String table = "";
List bookIdList = new ArrayList(); List bookIdList = new ArrayList();
if(!StringUtils.isEmpty(template.getField())) { if(!StringUtils.isEmpty(template.getField())) {
//New Booking Request //New Booking Request
table = tableTemp; table = tableTemp;
String[] fieledList = template.getField().split(";"); String[] fieledList = template.getField().split(";");
String thread = "<th>No</th>"; StringBuilder thread = new StringBuilder("<th>No</th>");
for( String field : fieledList) { for( String field : fieledList) {
thread+="<th>"+field+"</th>"; thread.append("<th>").append(field).append("</th>");
} }
String tbody = ""; StringBuilder tbody = new StringBuilder();
int index = 1; int index = 1;
for(BookingsView bo:typeList) { for(BookingsView bo:typeList) {
tbody+="<tr><td>"+index+"</td>"; tbody.append("<tr><td>").append(index).append("</td>");
index++; index++;
bookIdList.add(String.valueOf(bo.getId())); bookIdList.add(String.valueOf(bo.getId()));
for( String field : fieledList) { for( String field : fieledList) {
String getFiled = getNewFiled(field, bo); String getFiled = getNewFiled(field, bo);
tbody+="<td>"+getFiled+"</td>"; tbody.append("<td>").append(getFiled).append("</td>");
} }
tbody+="</tr>"; tbody.append("</tr>");
} }
table = table.replace("{{thead}}", thread); table = table.replace("{{thead}}", thread.toString());
table = table.replace("{{tbody}}", tbody); table = table.replace("{{tbody}}", tbody.toString());
}else { }else {
content=""; content = new StringBuilder();
for(BookingsView bo:typeList) { for(BookingsView bo:typeList) {
bookIdList.add(String.valueOf(bo.getId())); bookIdList.add(String.valueOf(bo.getId()));
content+=getExtendFiled(bo,template.getContent())+"</br>"; content.append(getExtendFiled(bo, template.getContent())).append("</br>");
} }
} }
temp = temp.replace("{{title}}", title); temp = temp.replace("{{title}}", title);
temp = temp.replace("{{content}}", content); temp = temp.replace("{{content}}", content.toString());
temp = temp.replace("{{table}}", table); temp = temp.replace("{{table}}", table);
template.setShowTemp(temp); template.setShowTemp(temp);
template.setBookIds(String.join(";", bookIdList)); template.setBookIds(String.join(";", bookIdList));
@@ -254,7 +254,7 @@ public class EmailTemplateService {
field = book.getRoomEmailName()!=null?book.getRoomEmailName():""; field = book.getRoomEmailName()!=null?book.getRoomEmailName():"";
break; break;
case "Booker & Contact": case "Booker & Contact":
String booker = ""; String booker;
boolean isMo = Strings.CI.contains(book.getPropertyName(), "mandarin"); boolean isMo = Strings.CI.contains(book.getPropertyName(), "mandarin");
if(Strings.CS.equals("CCREL", book.getMarketCode())) { if(Strings.CS.equals("CCREL", book.getMarketCode())) {
booker = "CR"; booker = "CR";
@@ -2,11 +2,14 @@ package com.mgm.mcrm.notification.services;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.mgm.mcrm.authorization.services.MgmUserService;
import com.mgm.mcrm.booking.models.Bookings; import com.mgm.mcrm.booking.models.Bookings;
import com.mgm.mcrm.booking.models.BookingsView; import com.mgm.mcrm.booking.models.BookingsView;
import com.mgm.mcrm.common.dtos.BaseApiResponse;
import com.mgm.mcrm.common.dtos.EumnApprovalStatus; import com.mgm.mcrm.common.dtos.EumnApprovalStatus;
import com.mgm.mcrm.common.dtos.config.ApiGatewaySetting; import com.mgm.mcrm.common.dtos.config.ApiGatewaySetting;
import com.mgm.mcrm.common.dtos.http_util.HttpResponseResult; import com.mgm.mcrm.common.dtos.http_util.HttpResponseResult;
import com.mgm.mcrm.common.dtos.mgm_api.UserInfoApiRecord;
import com.mgm.mcrm.common.utils.DateTimeUtil; import com.mgm.mcrm.common.utils.DateTimeUtil;
import com.mgm.mcrm.common.utils.HttpUtil; import com.mgm.mcrm.common.utils.HttpUtil;
import com.mgm.mcrm.common.utils.LogUtil; import com.mgm.mcrm.common.utils.LogUtil;
@@ -32,11 +35,15 @@ public class SendEmailService {
@Value("${notification.default-email-receiver}") @Value("${notification.default-email-receiver}")
private String defaultEmailReceiver; private String defaultEmailReceiver;
@Resource
private MgmUserService mgmUserService;
@Resource @Resource
private ApiGatewaySetting apiGatewaySetting; private ApiGatewaySetting apiGatewaySetting;
private static final String emailTemp = "<div>Submission Date & Time:{{ttime}}</div>"+ private static final String emailTemp = "<div>Submission Date & Time:{{ttime}}</div>"+
"<div>Submitted User:{{tuser}}</div>"+ "<div>Submitted User:{{tuser}}</div>"+
"<div>Approver:{{tapprover}}</div>"+
"<br><br>" + "<br><br>" +
"<table border=\"1\" align=\"left\" cellspacing=\"0\" cellpadding=\"5\" width=\"auto\" style=\"font-family: Avenir, Helvetica, sans-serif;font-weight:500;background-color:#ffffff;color:#000000;border: 0;white-space: nowrap;width:auto;\">\r\n" + "<table border=\"1\" align=\"left\" cellspacing=\"0\" cellpadding=\"5\" width=\"auto\" style=\"font-family: Avenir, Helvetica, sans-serif;font-weight:500;background-color:#ffffff;color:#000000;border: 0;white-space: nowrap;width:auto;\">\r\n" +
" <thead style=\"color:#000000;font-size:14px;padding:10px 40px 0 40px;line-height:32px;background-color: #c8e2b6;white-space: nowrap;margin: 20px 0;\">\r\n" + " <thead style=\"color:#000000;font-size:14px;padding:10px 40px 0 40px;line-height:32px;background-color: #c8e2b6;white-space: nowrap;margin: 20px 0;\">\r\n" +
@@ -281,11 +288,22 @@ public class SendEmailService {
String content2 = ""; String content2 = "";
String tTime = RequestDate; String tTime = RequestDate;
userId = !StringUtils.isEmpty(userId)?userId:""; userId = StringUtils.isNotEmpty(userId)?userId:"";
userName = !StringUtils.isEmpty(userName)?userName:"";
String tUser = userId+" "+userName; if (StringUtils.isBlank(userName)) {
BaseApiResponse<UserInfoApiRecord> userInfoByUserId = mgmUserService.findUserInfoByUserId(userId);
userName = userInfoByUserId.isSuccess() ? userInfoByUserId.getData().getUserName() : "";
}
if (StringUtils.isBlank(book.getApprovedBy())) {
BaseApiResponse<UserInfoApiRecord> userInfoByUserId = mgmUserService.findUserInfoByUserId(String.valueOf(book.getApprovedId()));
book.setApprovedBy(userInfoByUserId.isSuccess() ? userInfoByUserId.getData().getUserName() : "") ;
}
String tUser = book.getCreatedBy()+" "+book.getCreatedByName();
String operaStatus = Strings.CS.replace(book.getLastOperaStatus(), "_", " "); String operaStatus = Strings.CS.replace(book.getLastOperaStatus(), "_", " ");
String tApprover = book.getApprovedId()+" "+book.getApprovedBy();
content2 += "<tr>"+ content2 += "<tr>"+
"<td>" "<td>"
+book.getConfirmationNo()+ +book.getConfirmationNo()+
@@ -325,6 +343,7 @@ public class SendEmailService {
content1 = content1.replace("{{tbody}}", content2); content1 = content1.replace("{{tbody}}", content2);
content1 = content1.replace("{{ttime}}", tTime); content1 = content1.replace("{{ttime}}", tTime);
content1 = content1.replace("{{tuser}}", tUser); content1 = content1.replace("{{tuser}}", tUser);
content1 = content1.replace("{{tapprover}}", tApprover);
emailRequest.setShowTemp(content1); emailRequest.setShowTemp(content1);
emailRequest.setContent(content1); emailRequest.setContent(content1);
JSONObject emailJson = new JSONObject(); JSONObject emailJson = new JSONObject();
@@ -18,6 +18,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
@@ -263,6 +264,7 @@ public class PlayerService {
resultObj.setDates(resultList); resultObj.setDates(resultList);
} }
} }
sortDatesAscending(resultObj.getDates());
result.setSuccess(true); result.setSuccess(true);
result.setData(resultObj); result.setData(resultObj);
return result; return result;
@@ -376,12 +378,22 @@ public class PlayerService {
resultObj.setDates(resultList); resultObj.setDates(resultList);
} }
} }
sortDatesAscending(resultObj.getDates());
result.setSuccess(true); result.setSuccess(true);
result.setData(resultObj); result.setData(resultObj);
return result; return result;
} }
private void sortDatesAscending(List<JSONObject> dates) {
if (dates == null || dates.size() < 2) {
return;
}
dates.sort(Comparator.comparing(
item -> item == null ? null : item.getString("date"),
Comparator.nullsLast(Comparator.naturalOrder())));
}
private void supplementProfileNameIds(PlayerProfileEntry profile) { private void supplementProfileNameIds(PlayerProfileEntry profile) {
boolean isMock = sysSettingService.isMockReplicate(); boolean isMock = sysSettingService.isMockReplicate();
if (isMock) { if (isMock) {
@@ -307,7 +307,7 @@ public class TodoService {
boolean isDaylight = Strings.CS.equals("DAYLIGHT", category); boolean isDaylight = Strings.CS.equals("DAYLIGHT", category);
boolean isOther = Strings.CS.equals("OTHER", category); boolean isOther = Strings.CS.equals("OTHER", category);
CfgProperties property = propertyDao.getByName(param.getPropertyName()); CfgProperties property = propertyDao.findByNameAndCategory(param.getPropertyName(), category);
String dlReservationId = null; String dlReservationId = null;
@@ -639,13 +639,13 @@ public class TodoService {
return missParameter(result); return missParameter(result);
} }
CfgProperties property = propertyDao.getByLikeName(hotelName); String category = bookingDao.findCategoryById(id);
CfgProperties property = propertyDao.findByLikeNameAndCategory(hotelName, category);
if (property == null) { if (property == null) {
return noRecord(result); return noRecord(result);
} }
String category = property.getCategory();
if (Strings.CI.equals("DAYLIGHT", category)) { if (Strings.CI.equals("DAYLIGHT", category)) {
return handleDaylightETA(etaTime, confNo, property, id); return handleDaylightETA(etaTime, confNo, property, id);
} }
@@ -15,11 +15,13 @@ import com.mgm.mcrm.roomcalendar.dtos.response.RoomCalendarApiResponse;
import com.mgm.mcrm.roomcalendar.dtos.response.RoomType; import com.mgm.mcrm.roomcalendar.dtos.response.RoomType;
import com.mgm.mcrm.roomcalendar.repositories.RoomCalendarRoomProjection; import com.mgm.mcrm.roomcalendar.repositories.RoomCalendarRoomProjection;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.*; import java.util.*;
@Slf4j
@Service @Service
public class RoomCalendarService { public class RoomCalendarService {
@org.springframework.beans.factory.annotation.Value("${calendar.data-mock-enabled:false}") @org.springframework.beans.factory.annotation.Value("${calendar.data-mock-enabled:false}")
@@ -85,7 +87,8 @@ public class RoomCalendarService {
allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent())); allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent()));
anySuccess = true; anySuccess = true;
} }
} catch (Exception ignored) { } catch (Exception e) {
log.error("Opera invokeRequestRoomCalendar failed", e);
} }
} }
@@ -97,7 +100,8 @@ public class RoomCalendarService {
allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent())); allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent()));
anySuccess = true; anySuccess = true;
} }
} catch (Exception ignored) { } catch (Exception e) {
log.error("Daylight invokeRequestRoomCalendar failed", e);
} }
} }
@@ -109,7 +113,8 @@ public class RoomCalendarService {
allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent())); allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent()));
anySuccess = true; anySuccess = true;
} }
} catch (Exception ignored) { } catch (Exception e) {
log.error("Other property invokeRequestRoomCalendar failed", e);
} }
} }
+4 -16
View File
@@ -58,20 +58,6 @@ spring:
jms: jms:
pub-sub-domain: false pub-sub-domain: false
security:
enabled: false
oauth2:
client:
registration:
adfs:
register-id: MCRM_OAUTH
client-id: 0fa96b30-f429-474e-ace4-34a82b816682
client-secret: L_7tIOfEL9iJlksST9L9dOPkUR5KHU405SMAAsNU
redirect-uri: https://mcrm.willtechmacau.com:9086/sso_callback/login
provider:
adfs:
token-uri: https://adserver.willtechmacau.com/adfs/oauth2/token
server: server:
port: 9086 port: 9086
tomcat: tomcat:
@@ -106,6 +92,8 @@ mcrm:
secret-key: SecretKeyWhichShouldBeLongEnoughToBeSecure67848563 secret-key: SecretKeyWhichShouldBeLongEnoughToBeSecure67848563
api-token-expiration: 5 # 分钟单位 api-token-expiration: 5 # 分钟单位
mobile-session-expiration: 43200 # 分钟单位 mobile-session-expiration: 43200 # 分钟单位
daylight:
booking-search-cache-seconds: 300
#============== Daylight Service =================== #============== Daylight Service ===================
api-gateway: api-gateway:
@@ -206,8 +194,8 @@ calendar:
#==================APP Config=================== #==================APP Config===================
notification: notification:
recent-hours: 6 recent-hours: 6
default-email-sender: test@test.com default-email-sender: 201249946@qq.com
default-email-receiver: missing@test.com default-email-receiver: mauve.chan@willtechmacau.com
limo: limo:
booking-draft: booking-draft: