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/
/.classpath
/.project
/crm_mobile_runtime/logs/
@@ -7,11 +7,6 @@
"offsetCol": 0,
"objClassName": "com.mgm.mcrm.common.dtos.data_import.booking.OtherBookingImportRow",
"columnDefs": [
{
"columnHeader":"#",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Staff Action",
"checkHeader":true,
@@ -33,13 +28,6 @@
"attrName": "propertyName",
"dataType": "String"
},
{
"columnHeader":"Confirmation No.",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "confirmationNo",
"dataType": "String"
},
{
"columnHeader":"Room Type",
"checkHeader":true,
@@ -47,6 +35,27 @@
"attrName": "roomName",
"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",
"checkHeader":true,
@@ -61,21 +70,6 @@
"attrName": "checkoutDate",
"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",
"checkHeader":true,
@@ -83,47 +77,6 @@
"attrName": "playerId",
"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",
"checkHeader":true,
@@ -131,6 +84,13 @@
"attrName": "bookerId",
"dataType": "String"
},
{
"columnHeader":"Approver ID",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "approverId",
"dataType": "String"
},
{
"columnHeader":"Sharer",
"checkHeader":true,
@@ -138,11 +98,6 @@
"attrName": "sharer",
"dataType": "String"
},
{
"columnHeader":"Sharer Name",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Remark",
"checkHeader":true,
@@ -151,45 +106,25 @@
"dataType": "String"
},
{
"columnHeader":"Approver",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Approver ID",
"columnHeader":"Confirmation No",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "approverId",
"attrName": "confirmationNo",
"dataType": "String"
},
{
"columnHeader":"Approval Remark",
"checkHeader":false,
"headerRowIdx":0
},
{
"columnHeader":"Booking Type",
"columnHeader":"Player Name",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "bookingTypeName",
"attrName": "playerName",
"dataType": "String"
},
{
"columnHeader":"Segment",
"columnHeader":"Source Code",
"checkHeader":true,
"headerRowIdx":0,
"attrName": "segmentName",
"attrName": "sourceCodeName",
"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>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>21</java.version>
<tomcat.version>11.0.25</tomcat.version>
<netty.version>4.2.18.Final</netty.version>
<httpclient5.version>5.6.4</httpclient5.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.PrintWriter;
//@RequestMapping("/sso_callback")
@Controller
public class SSOCallbackController {
@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 authorizedUrl = adfsHost+ "/adfs/ls/IdpInitiatedSignOn.aspx?loginToRp="+paraRelying;
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);
//
// String origin = request.getHeader("Origin");
String sanitizedOrigin = NetworkUtil.sanitizeCRLF(origin);
if(SysCommon.isAllowOriginSource(sanitizedOrigin)) {
response.setHeader("Access-Control-Allow-Origin", NetworkUtil.sanitizeCRLF(sanitizedOrigin));
@@ -609,6 +608,18 @@ public class SSORestProcessController {
httpResult.put("NextStep", "Callback");
httpResult.put("ErrorCode", statusCode);
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 {
isEnd=true;
@@ -633,16 +644,17 @@ public class SSORestProcessController {
if(resHeaders!=null) {
resHeaders.forEach((key, value) -> {
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));
}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")) {
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();
long contentLength = outputData.length;
response.setHeader("Content-Length", Long.toString(contentLength));
@@ -656,6 +668,8 @@ public class SSORestProcessController {
LogUtil.info(SSORestProcessController.class,"Redirect location:"+redirectUrl);
response.setHeader("Location", NetworkUtil.sanitizeCRLF(redirectUrl));
}
LogUtil.info(SSORestProcessController.class,"Send Redirect:"+redirectUrl);
response.setHeader("Origin","MGM_CRM_APP");
response.sendRedirect(redirectUrl);
}else {
String redirectUrl = callbackUrl+"?";
@@ -668,6 +682,7 @@ public class SSORestProcessController {
response.setHeader("Location", NetworkUtil.sanitizeCRLF(saintUrl));
response.setHeader("Content-Length","0");
LogUtil.info(SSORestProcessController.class,"Callback with ErrorCode:"+saintUrl+" [errorMessage]:"+errorMessage);
response.setHeader("Origin","MGM_CRM_APP");
response.sendRedirect(saintUrl);
}
}else {
@@ -948,6 +948,7 @@ public class ApprovalService {
newBooking.setApprovedBy(userName);
newBooking.setApprovedId(Long.valueOf(userId));
newBooking.setCategory("OTHER");
newBooking.setApprovalRemark(originBooking.getApprovalReason());
//获取other room status
CfgOtherRoomStatus roomStatus = roomStatusDao.findByStatusName("Pending");
if(roomStatus!=null) {
@@ -89,8 +89,8 @@ public class ConfigService {
public List<CfgProperties> listProperty(PropertyQueryRequest queryFilter) {
Specification<CfgProperties> listSpec = (root, criteriaQuery, cb) -> {
List<Predicate> list = new ArrayList<>();
// status=0 的记录不返回
list.add(cb.notEqual(root.get("status"), 0));
// status=1 的记录才返回
list.add(cb.equal(root.get("status"), 1));
if(StringUtils.isNotBlank(queryFilter.getSearchCode())) {
list.add(cb.equal(root.get("code") , queryFilter.getSearchCode()));
}
@@ -168,6 +168,10 @@ public class ConfigService {
Specification<CfgRoomFeatures> listSpec = (root, criteriaQuery, cb) -> {
List<Predicate> list = new ArrayList<>();
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(
cb.or(
cb.equal(root.get("category"), category)
@@ -233,8 +237,8 @@ public class ConfigService {
resultList = getOtherCriteria( segmentId, sectionId, bookingTypeId, propertyId, roomId);
}
if(!resultList.isEmpty()) {
checkCriteriaBooking(resultList, playerId, userId, userName);
if(!resultList.isEmpty()||isDaylight) {
checkCriteriaBooking(resultList, playerId, userId, userName, isDaylight?2:1);
}
return resultList;
@@ -509,7 +513,7 @@ public class ConfigService {
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");
String maxDay = settingDao.getByKeys(SysConstants.MAX_ADVANCE_BOOKING_DAYS).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()) {
String getDate = DateTimeUtil.getDateByFormat(checkInDate, "yyyy-MM-dd");
if(checkMode==2&&!resultList.containsKey(getDate)) {
resultList.put(getDate,newCalendarEntry(getDate));
}
if(resultList.containsKey(getDate)){
JSONObject res = resultList.get(getDate);
if(//StringUtils.isEmpty(book.getLastOperaStatus())||
if(
Strings.CS.equals(book.getLastOperaStatus(), "DUE_IN")||
Strings.CS.equals(book.getLastOperaStatus(), "RESERVED")) {
res.put("reserved",1);
@@ -606,6 +613,9 @@ public class ConfigService {
}
for(Date period:protectionPeriod) {
String date = DateTimeUtil.getDateByFormat(period, "yyyy-MM-dd");
if(checkMode==2&&!resultList.containsKey(date)) {
resultList.put(date,newCalendarEntry(date));
}
if(resultList.containsKey(date)){
JSONObject res = resultList.get(date);
res.put("protection",1);
@@ -616,6 +626,16 @@ public class ConfigService {
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() {
Sort sort = Sort.by(Direction.ASC, "keys");
return settingDao.findAll(sort);
@@ -85,8 +85,11 @@ public class MobileLoginController {
int loginTag = authService.checkLoginByLoginIdAndPasswordAndIp(userId, password, accessIp);
if(loginTag>0) {
LoginUserInfo loginUser = new LoginUserInfo();
loginUser.setId(0L);
loginUser.setLoginId(userId);
BaseApiResponse<UserInfoApiRecord> serviceResult = mgmUserService.findUserInfoByUserId(userId);
if(serviceResult.isSuccess()) {
loginUser.setLoginId(userId);
loginUser.setGroupName(serviceResult.getData().getGroupName());
}
Token accessToken = JwtTokenUtil.generateTokenByLoginUser(request.getRequestURI(),loginUser, SysConstants.MOBILE_TOKEN_TYPE,false);
userTokenService.saveToken(accessToken);
Token refreshToken = JwtTokenUtil.generateTokenByLoginUser(request.getRequestURI(),loginUser, SysConstants.MOBILE_TOKEN_TYPE,true);
@@ -171,6 +174,8 @@ public class MobileLoginController {
result.setRefreshToken(refreshToken.getToken());
result.setUserData(userInfo);
result.setClientId(EncryptUtil.sha256(Base64Util.encode("mcrm_" + userId)));
LogUtil.info(MobileLoginController.class,"UserId = "+result.getUserData()+",Token = "+result.getAccessToken());
}else {
result.setSuccess(false);
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;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class SsoLoginRequest {
@JsonProperty("SAMLResponse")
private String samlResponse;
private String idToken;
private String code;
@@ -21,6 +21,7 @@ import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.apache.logging.log4j.util.Base64Util;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
@@ -58,6 +59,7 @@ public class JwtAuthFilter extends OncePerRequestFilter {
@NonNull FilterChain filterChain
) throws ServletException, IOException{
boolean validatePass = true;
String uri = request.getRequestURI();
try {
boolean refreshRequest = "/api/app/refresh_token".equals(request.getRequestURI());
String token = request.getHeader(refreshRequest ? "RefreshToken" : "Authorization");
@@ -103,12 +105,20 @@ public class JwtAuthFilter extends OncePerRequestFilter {
if(clientId==null) {
clientId="";
}
LogUtil.info(JwtAuthFilter.class, "[preHandle] Pass Token:" + token);
LoginUserInfo user = JwtTokenUtil.parseUserFromToken(token);
if(user!=null) {
String encrypt = EncryptUtil.sha256(Base64Util.encode("mcrm_"+user.getLoginId()));
if(!clientId.equalsIgnoreCase(encrypt)) {
sendErrorResponse(response,500, "Invalid Token");
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 {
LogUtil.info(JwtAuthFilter.class, "[preHandle] user null");
@@ -133,13 +143,15 @@ public class JwtAuthFilter extends OncePerRequestFilter {
}else{
boolean canAccessIP = true;
String accessIp = NetworkUtil.getClientIpAddr(request);
LogUtil.info(JwtAuthFilter.class, "[preHandle] accessIp: " + accessIp + "=----------------------------------");
if("INVALID_IP".equalsIgnoreCase(accessIp)){
sendErrorResponse(response,401, "Invalid IP in forward headers");
validatePass = false;
}
boolean isInternal = NetworkUtil.isMatchInternal(accessIp);
LogUtil.info(JwtAuthFilter.class, "[preHandle] isInternal: " + isInternal+"-------------------------------=");
if(!isInternal) {
String uri = request.getRequestURI();
boolean isIgnoreUrl = false;
for(String urlKey:ignoreCheckInternalUrl){
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)
int countSysUserByLoginIdAndPassword(String loginId, String password);
SysUser findByLoginId(String thirdPartyAccount);
}
@@ -1,7 +1,11 @@
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.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.SysGroupPermissionDao;
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.services.SysLogLoginIpService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.Strings;
import org.springframework.stereotype.Service;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
@Service
public class AuthorizationService {
@@ -156,4 +163,13 @@ public class AuthorizationService {
ipLog.setBanUntil(cal.getTime());
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.services.MGMEsbApiService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@Service
public class MgmUserService {
@@ -97,6 +99,7 @@ public class MgmUserService {
}catch(Exception err) {
result.setSuccess(false);
result.setMessage("Parse return data failed:"+err.getMessage());
log.error("Parse return data failed", err);
}
}else {
@@ -203,9 +206,10 @@ public class MgmUserService {
private UserInfoApiRecord supplementInfoId(String userId,UserInfoApiRecord info) {
info.setCanViewCalendar(calendarPermissionMockEnabled);
// 待完善,有可能需要一层一层获得property,division,department,team
CfgProperties property = propertyDao.getByName(info.getProperty());
List<CfgProperties> property = propertyDao.getByName(info.getProperty());
if(property!=null) {
info.setPropertyId(property.getId());
info.setPropertyId(property.getFirst().getId());
}
CfgBlocks block = blockDao.getByName(info.getBlock());
if(block!=null) {
@@ -15,6 +15,7 @@ import jakarta.servlet.http.HttpServletRequest;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import java.time.Duration;
import java.time.Instant;
@@ -56,6 +57,9 @@ public class JwtTokenUtil {
Instant now = Instant.now();
Instant expDate = now.plus(Duration.ofMinutes(tokeExpiration));
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()
.withIssuer(issueSource)
@@ -107,8 +111,13 @@ public class JwtTokenUtil {
}else {
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();
loginUser.setGroupName(groupName != null ? groupName : decodeData.getClaim("user_group").asString());
loginUser.setTokenUuid(decodeData.getId());
}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;
@Column(name="block_code_id")
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")
private Date createdAt;
@Column(name="created_by")
@@ -41,4 +59,8 @@ public class CfgExceptionDaylight implements Serializable {
private List<String> roomTypeIds;
@Transient
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.util.Date;
import java.util.List;
import java.util.Set;
@Data
@@ -23,7 +24,8 @@ import java.util.Set;
@NamedAttributeNode("rateCode"),
@NamedAttributeNode("sourceCode"),
@NamedAttributeNode("marketCode"),
@NamedAttributeNode("daylightRoomType")
@NamedAttributeNode("daylightRoomType"),
@NamedAttributeNode("cfgCompPresetList")
}
)
public class CfgExceptionDaylightView implements Serializable {
@@ -54,6 +56,26 @@ public class CfgExceptionDaylightView implements Serializable {
@Column(name="market_code_id")
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")
private Date createdAt;
@@ -47,4 +47,25 @@ public interface DaylightViewDao extends JpaRepository<CfgDaylightView, Long> {
@Param("bookingTypeId") Long bookingTypeId,
@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.repository.EntityGraph;
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;
@@ -26,4 +28,42 @@ public interface ExceptionDaylightViewDao extends JpaRepository<CfgExceptionDayl
@EntityGraph(value = "graph.ExceptionDaylightMapping.fulldetails",type = EntityGraph.EntityGraphType.LOAD)
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
if (jsonArray.size() == 1) {
JSONObject resId = this.getResIdAndConfNo(jsonArray);
JSONObject resultResIdAndConf = this.getResIdAndConfNo(jsonArray);
if (resId.isEmpty()) {
if (resultResIdAndConf.isEmpty()) {
result.setSuccess(false);
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 {
result.setSuccess(true);
result.setData(resId);
log.info("Create reservation successful, reservation id: {}", resId);
result.setData(resultResIdAndConf);
log.info("Create reservation successful, reservation id and confirmation no json: {}", resultResIdAndConf);
}
// 创建 reservation 并且创建了 profile
@@ -1070,7 +1070,7 @@ public class DaylightApiService {
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)"
// + ";departureDate=ge=" + currentDate
+ "&extend=PurchaseElements,CustomFields,Breakdown,DoorKeys&sort=-createdAt";
+ "&extend=PurchaseElements,CustomFields,Breakdown,DoorKeys,Notes&sort=-createdAt";
Map<String, Object> map = new HashMap<>();
try {
for (CfgProperties property : properties) {
@@ -1079,6 +1079,11 @@ public class DaylightApiService {
log.warn("[getBookingRecordByProfileId_Optimize] Skipping property with null/blank dlPropertyId, propertyName={}", property.getName());
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()
.contentType("application/json")
.ac_property_id(dlPropertyId)
@@ -1113,6 +1118,28 @@ public class DaylightApiService {
JSONObject bookingRes = bookings.getJSONObject(i);
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 checkoutDate = DateTimeUtil.getDateFromString(bookingRes.getString("departureDate"),"yyyy-MM-dd");
@@ -1162,13 +1189,6 @@ public class DaylightApiService {
booking.setDlBlockId(bookingRes.getString("blockId"));
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");
if (embedded == null) {
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");
@@ -1403,6 +1437,18 @@ public class DaylightApiService {
String endDate,
CfgDaylightView daylightView,
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<>();
@@ -1421,7 +1467,8 @@ public class DaylightApiService {
String failedMessage = null;
try {
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++) {
JSONObject one = compRuleList.getJSONObject(i);
@@ -1482,6 +1529,7 @@ public class DaylightApiService {
String startDate,
String endDate,
List<CfgDaylightView> daylightViewList,
List<CfgExceptionDaylightView> exceptionDaylightViewList,
String miscCharge
) {
@@ -1489,7 +1537,14 @@ public class DaylightApiService {
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)) {
result.setSuccess(false);
@@ -1512,26 +1567,42 @@ public class DaylightApiService {
CfgDaylightView daylightViewRoomOnly = null;
CfgDaylightView daylightView = null;
CfgExceptionDaylightView exceptionDaylightViewRoomOnly = null;
CfgExceptionDaylightView exceptionDaylightView = null;
for (CfgDaylightView d : daylightViewList) {
if (d.getCompRuleCategory() == 1) {
daylightViewRoomOnly = d;
continue;
if (useExceptionDaylight) {
for (CfgExceptionDaylightView d : exceptionDaylightViewList) {
if (Objects.equals(d.getCompRuleCategory(), 1)) {
exceptionDaylightViewRoomOnly = d;
continue;
}
if (Objects.equals(d.getCompRuleCategory(), 2)) {
exceptionDaylightView = d;
}
}
if (d.getCompRuleCategory() == 2) {
daylightView = d;
} else {
for (CfgDaylightView d : daylightViewList) {
if (Objects.equals(d.getCompRuleCategory(), 1)) {
daylightViewRoomOnly = d;
continue;
}
if (Objects.equals(d.getCompRuleCategory(), 2)) {
daylightView = d;
}
}
}
if (daylightViewRoomOnly == null && daylightView == null) {
if (daylightViewRoomOnly == null && daylightView == null
&& exceptionDaylightViewRoomOnly == null && exceptionDaylightView == null) {
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;
}
if (compRuleCount >= 2) {
try {
return updateDaylightCompRule(dlAccountId, dlPropertyId, startDate, endDate, daylightView, miscCharge);
return updateDaylightCompRule(dlAccountId, dlPropertyId, startDate, endDate,
daylightView, exceptionDaylightView, miscCharge);
} catch (Exception e) {
result.setSuccess(false);
result.setMessage(e.getMessage());
@@ -1547,13 +1618,18 @@ public class DaylightApiService {
}
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";
Header[] headers = HttpHeaderBuilder.custom()
.contentType("application/json")
.ac_property_id(dlPropertyId)
.build();
String approver = daylightViewRoomOnly.getApprover();
String approver = useExceptionDaylight
? exceptionDaylightViewRoomOnly.getApprover() : daylightViewRoomOnly.getApprover();
boolean isVillaOrMansion = isVillaOrMansionRoom(roomName);
String requestorUserId = StringUtils.isNotEmpty(approver) && isVillaOrMansion ? userId
: StringUtils.isNotEmpty(approver) ? approver : userId;
@@ -1578,9 +1654,10 @@ public class DaylightApiService {
RequestorApproverResponse requestor = requestorResponse.getData();
RequestorApproverResponse approverData = approverResponse.getData();
if (createRoomOnlyCompRule && daylightViewRoomOnly != null) {
if (createRoomOnlyCompRule && (daylightViewRoomOnly != null || exceptionDaylightViewRoomOnly != null)) {
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);
if (!createDefaultResult.isSuccess()) {
return createDefaultResult;
@@ -1589,7 +1666,7 @@ public class DaylightApiService {
if (createDaylightViewCompRule) {
BaseApiResponse<CreateCompRuleRequest> daylightViewCompRuleRequest = buildDaylightViewCompRuleRequest(
profileId, startDate, endDate, daylightView, requestor, approverData, miscCharge);
profileId, startDate, endDate, daylightView, exceptionDaylightView, requestor, approverData, miscCharge);
if (!daylightViewCompRuleRequest.isSuccess()) {
result.setSuccess(false);
result.setMessage(daylightViewCompRuleRequest.getMessage());
@@ -1617,8 +1694,9 @@ public class DaylightApiService {
}
static boolean isVillaOrMansionRoom(String roomName) {
return StringUtils.equalsAnyIgnoreCase(StringUtils.substringBefore(roomName, "-"),
"V1", "V2", "V2M", "V3", "S3", "M1", "M2", "M3");
return false;
// return StringUtils.equalsAnyIgnoreCase(StringUtils.substringBefore(roomName, "-"),
// "V1", "V2", "V2M", "V3", "S3", "M1", "M2", "M3");
}
public BaseApiResponse<String> createDaylightNewRoomOnlyCompRule(
@@ -1699,19 +1777,43 @@ public class DaylightApiService {
RequestorApproverResponse approver,
CfgDaylightView daylightView,
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();
crr.setComplimentaryTypeId(daylightView.getDlCompTypeId());
crr.setPaymentMethodTransactionCodeId(daylightView.getDlPaymentMethodCodeId());
crr.setComplimentaryTypeId(exceptionDaylightView != null
? exceptionDaylightView.getDlCompTypeId() : daylightView.getDlCompTypeId());
crr.setPaymentMethodTransactionCodeId(exceptionDaylightView != null
? exceptionDaylightView.getDlPaymentMethodCodeId() : daylightView.getDlPaymentMethodCodeId());
crr.setExecutive(false);
crr.setDoNotIssueInvoice(false);
crr.setProfileId(profileId);
if(setRuleLimits) crr.setComplimentaryRuleLimits(getComplimentaryRuleLimits(startDate, endDate));
List<CfgCompPreset> compPresetList = compPresetDao.findAllByDaylightMappingId(daylightView.getId());
CfgCompPreset compPreset = compPresetList.getFirst();
crr.setComplimentaryAccountingPresetsIds(List.of(compPreset.getDlCompPresetId()));
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());
compPresetId = compPresetList.getFirst().getDlCompPresetId();
}
crr.setComplimentaryAccountingPresetsIds(List.of(compPresetId));
crr.setJustification("");
crr.setRequestorId(requestor.getId());
crr.setApproverId(approver.getId());
@@ -1724,26 +1826,30 @@ public class DaylightApiService {
String startDate,
String endDate,
CfgDaylightView daylightView,
CfgExceptionDaylightView exceptionDaylightView,
RequestorApproverResponse requestor,
RequestorApproverResponse approver,
String miscCharge) {
BaseApiResponse<CreateCompRuleRequest> result = new BaseApiResponse<>();
if (daylightView == null) {
if (daylightView == null && exceptionDaylightView == null) {
result.setSuccess(false);
result.setMessage("Daylight config is empty");
log.error("Daylight config is empty");
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.setMessage("Daylight comp type id is empty");
log.error("Daylight comp type id is empty");
return result;
}
if (StringUtils.isBlank(daylightView.getDlPaymentMethodCodeId())) {
if (StringUtils.isBlank(paymentMethodCodeId)) {
result.setSuccess(false);
result.setMessage("Daylight payment method code id is empty");
log.error("Daylight payment method code id is empty");
@@ -1751,16 +1857,25 @@ public class DaylightApiService {
}
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.setMessage("Daylight comp preset id is empty");
log.error("Daylight comp preset id is empty");
return result;
}
for (CfgCompPreset cfgCompPreset : daylightView.getCfgCompPresetList()) {
if (cfgCompPreset != null && StringUtils.isNotBlank(cfgCompPreset.getDlCompPresetId())) {
capIds.add(cfgCompPreset.getDlCompPresetId());
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()) {
if (cfgCompPreset != null && StringUtils.isNotBlank(cfgCompPreset.getDlCompPresetId())) {
capIds.add(cfgCompPreset.getDlCompPresetId());
}
}
}
@@ -1774,19 +1889,21 @@ public class DaylightApiService {
}
CreateCompRuleRequest crr = new CreateCompRuleRequest();
crr.setComplimentaryTypeId(daylightView.getDlCompTypeId());
crr.setPaymentMethodTransactionCodeId(daylightView.getDlPaymentMethodCodeId());
crr.setComplimentaryTypeId(compTypeId);
crr.setPaymentMethodTransactionCodeId(paymentMethodCodeId);
crr.setExecutive(false);
crr.setDoNotIssueInvoice(false);
crr.setProfileId(profileId);
crr.setComplimentaryRuleLimits(
getMiscChargeComplimentaryRuleLimits(startDate, endDate, miscCharge, daylightView.getSoftLimit())
getMiscChargeComplimentaryRuleLimits(startDate, endDate, miscCharge,
exceptionDaylightView != null ? exceptionDaylightView.getSoftLimit() : daylightView.getSoftLimit())
);
crr.setComplimentaryAccountingPresetsIds(distinctCapIds);
crr.setJustification("");
crr.setRequestorId(requestor.getId());
String paymentMethodCodeContent = daylightView.getPaymentMethodCodeContent();
String paymentMethodCodeContent = exceptionDaylightView != null
? exceptionDaylightView.getPaymentMethodCodeContent() : daylightView.getPaymentMethodCodeContent();
if (StringUtils.isNotBlank(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) {
BaseApiResponse<RequestorApproverResponse> serviceResult = new BaseApiResponse<>();
log.info("getDaylightRequestorApproverByUserId, propertyId: {}, userId: {}", propertyId, userId);
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()
.contentType("application/json")
@@ -2274,10 +2393,12 @@ public class DaylightApiService {
HttpResult submitResult = httpService.sslPost(url, headers,params);
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.setData(bookings);
}else{
} else if (submitResult.getStatusCode() == 202) {
} else {
JSONObject rootNode = JSON.parseObject(responseBody);
String errorStr;
@@ -45,4 +45,6 @@ public class CfgProperties implements Serializable {
@Column(name = "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> {
@Query(value="select * from cfg_properties with (nolock) where name=?1",nativeQuery=true)
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);
List<CfgProperties> getByName(String name);
@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);
@@ -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)
CfgProperties getByDlPropertyId(String propertyId);
@Query(value="select Top(1) * from cfg_properties with (nolock) where name like %?1%",nativeQuery=true)
CfgProperties getByLikeName(String name);
@Query(value="select * from cfg_properties with (nolock) where name=?1 and category = 'DAYLIGHT'",nativeQuery=true)
CfgProperties getByPropertyNameDaylight(String propertyId);
@Query(value="select Top(1) * from cfg_properties with (nolock) where name like %?1% and category=?2",nativeQuery=true)
CfgProperties findByLikeNameAndCategory(String name, String category);
List<CfgProperties> findAll(Specification<CfgProperties> spec);
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> 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.BookingsView;
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.mockup.BookingServiceMockup;
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.SysConstants;
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.LogUtil;
import com.mgm.mcrm.common.utils.mockup.AjaxResultMockup;
import com.mgm.mcrm.logging.services.SysBookingCacheService;
import com.mgm.mcrm.player.services.PlayerService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
@@ -88,6 +91,11 @@ public class BookingController {
@Resource
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)
public ResponseEntity<BaseApiResponse<Object>> getBookingsByNameId(HttpServletRequest request,
@@ -167,16 +175,9 @@ public class BookingController {
//--get group permissions
boolean viewBooking =
sysGroupPermissionService.checkGroupPermission(groupName, SysConstants.PERMISSION_APP_VIEW_BOOKING);
boolean isMock = sysSettingService.isMockReplicate();
isMock = false;
viewBooking = true;
List<BookingsView> list;
if(isMock) {
list = bookingServiceMockup.getBookingByConfirmationNoMock(conf);
}else {
list = bookingService.getBookingByConfirmationNo(conf);
}
list = bookingService.getBookingByConfirmationNo(conf);
if(!list.isEmpty() && StringUtils.isNotEmpty(userId)) {
BaseApiResponse<PlayerProfileEntry> findPlayerResult =
playerService.findPlayerProfileByPlayerIdAndUserId(list.getFirst().getPlayerId(), userId);
@@ -226,7 +227,7 @@ public class BookingController {
if(findPlayerProfileResult.isSuccess()) {
PlayerProfileEntry profile = findPlayerProfileResult.getData();
Integer code = profile.getCodedFlag();
viewBooking = true;
// viewBooking = true;
if(code==1 && viewBooking) {
result.setSuccess(true);
result.setData(list);
@@ -277,10 +278,10 @@ public class BookingController {
if(Strings.CS.equals(per.getId(), "10001_02") ) createBooking = true;
}
}
createBooking = true;
// createBooking = true;
String playerId = booking.getPlayerId();
BaseApiResponse<PlayerProfileEntry> findPlayerResult = playerService.findPlayerProfileByPlayerIdAndUserId(playerId, userId);
boolean testDaylight = true;
if(findPlayerResult.isSuccess()) {
PlayerProfileEntry profile = findPlayerResult.getData();
Integer code = profile.getCodedFlag();
@@ -322,15 +323,14 @@ public class BookingController {
BaseApiResponse<List<Bookings>> result = new BaseApiResponse<>();
result.setRequestData(booking);
//--get group permissions
//TODO Test
boolean editBooking = false;
// List<SysRouterPermission> userPermissions = sysGroupPermissionService.getRouterPermissionsByGroupName(groupName);
// if(!userPermissions.isEmpty()) {
// for(SysRouterPermission per:userPermissions) {
// if(Strings.CS.equals(per.getId(), "10001_02") ) editBooking = true;
// }
// }
editBooking = true;
List<SysRouterPermission> userPermissions = sysGroupPermissionService.getRouterPermissionsByGroupName(groupName);
if(!userPermissions.isEmpty()) {
for(SysRouterPermission per:userPermissions) {
if(Strings.CS.equals(per.getId(), "10001_02") ) editBooking = true;
}
}
// editBooking = true;
//TODO Test
String playerId = booking.getPlayerId();
BaseApiResponse<PlayerProfileEntry> findPlayerResult = playerService.findPlayerProfileByPlayerIdAndUserId(playerId, userId);
@@ -465,17 +465,33 @@ public class BookingController {
String checkOutDate = bookingService.getSearchRecordCheckOutDate(currentDay);
List<BookingDto> operaResult = new ArrayList<>();
List<BookingDto> daylightResult = new ArrayList<>();
//去Daylight查ProfileId
stepStartTime = System.currentTimeMillis();
BaseApiResponse<List<ProfileDetailResponse>> profileResult = daylightApiService.dayLightGetProfileByPlayerId(playerId);
List<ProfileDetailResponse> returnData = profileResult.getData();
if (profileResult.isSuccess()) {
//Daylight存在 则去Daylight查Record 在Daylight不存在的话 跳过
ProfileDetailResponse profileDetailResponse = returnData.getFirst();
daylightResult = daylightApiService.getBookingRecordByProfileId_Optimize(profileDetailResponse.getId(), playerId);
} else {
LogUtil.warn(BookingService.class, "[recordSearch] Daylight profile lookup failed, message=" + profileResult.getMessage() + ", playerId=" + playerId);
}
boolean isLoadDaylightFromCache = sysBookingCacheService.isDaylightBookingCacheValid(playerId);
String daylightProfileId = sysBookingCacheService.getDaylightProfileMappingFromCache(playerId);
if(StringUtils.isBlank(daylightProfileId)){
//去Daylight查ProfileId
stepStartTime = System.currentTimeMillis();
BaseApiResponse<List<ProfileDetailResponse>> profileResult = daylightApiService.dayLightGetProfileByPlayerId(playerId);
List<ProfileDetailResponse> returnData = profileResult.getData();
if (profileResult.isSuccess()) {
//Daylight存在 则去Daylight查Record 在Daylight不存在的话 跳过
ProfileDetailResponse profileDetailResponse = returnData.getFirst();
daylightProfileId = profileDetailResponse.getId();
if(StringUtils.isNotBlank(daylightProfileId)){
sysBookingCacheService.updateDaylightProfileMapping(playerId, daylightProfileId);
}
} else {
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(BookingController.class, "[recordSearch] getDaylightBookings resultSize:" + daylightResult.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
stepStartTime = System.currentTimeMillis();
@@ -496,18 +512,21 @@ public class BookingController {
LogUtil.info(BookingController.class, "[recordSearch] getBookingsByNameID resultSize:" + operaResult.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
if (!daylightResult.isEmpty()) {
//将Daylight Result 合并至DB
LogUtil.info(BookingService.class,"[recordSearch] before mergeDaylightRecordFromDB_Optimize, playerId="
+ playerId + ", daylightResult.size=" + daylightResult.size());
stepStartTime = System.currentTimeMillis();
List<BookingDto> dbDaylightResults = bookingService.mergeDaylightRecordFromDB_Optimize(daylightResult,memberInfo,userId);
LogUtil.info(BookingController.class, "[recordSearch] mergeDaylightDatabaseInfo resultSize:" + dbDaylightResults.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
stepStartTime = System.currentTimeMillis();
bookingService.syncDaylightMergeBookingToDbAndPopulateIds_Optimize(dbDaylightResults);
LogUtil.info(BookingController.class, "[recordSearch] syncDaylightDatabase resultSize:" + dbDaylightResults.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
dbDaylightResults.removeIf(item -> "CANCELED".equalsIgnoreCase(item.getLastOperaStatus()));
allPropertiesResults.addAll(dbDaylightResults);
if(!isLoadDaylightFromCache){
//将Daylight Result 合并至DB
LogUtil.info(BookingService.class,"[recordSearch] before mergeDaylightRecordFromDB_Optimize, playerId="
+ playerId + ", daylightResult.size=" + daylightResult.size());
stepStartTime = System.currentTimeMillis();
List<BookingDto> dbDaylightResults = bookingService.mergeDaylightRecordFromDB_Optimize(daylightResult,memberInfo,userId);
LogUtil.info(BookingController.class, "[recordSearch] mergeDaylightDatabaseInfo resultSize:" + dbDaylightResults.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
stepStartTime = System.currentTimeMillis();
bookingService.syncDaylightMergeBookingToDbAndPopulateIds_Optimize(dbDaylightResults);
LogUtil.info(BookingController.class, "[recordSearch] syncDaylightDatabase resultSize:" + dbDaylightResults.size() + " spendTime:" + (System.currentTimeMillis() - stepStartTime) + "ms");
dbDaylightResults.removeIf(item -> "CANCELED".equalsIgnoreCase(item.getLastOperaStatus()));
allPropertiesResults.addAll(dbDaylightResults);
} else{
allPropertiesResults.addAll(daylightResult);
}
} else {
LogUtil.warn(BookingService.class,"[recordSearch] daylightResult is empty, skipping Daylight merge");
}
@@ -654,6 +673,15 @@ public class BookingController {
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())) {
// LogUtil.info(BookingService.class, "[recordSearch] FILTERED approveStatus=C: id=" + iPro.getId()
// + ", confNo=" + iPro.getConfirmationNo() + ", lastOperaStatus=" + iPro.getLastOperaStatus());
@@ -672,7 +700,7 @@ public class BookingController {
//remove yesterday booking
//只过滤「checkin<今天 && checkout<今天」的过去预订(即未入住就过期的 no-show 候选)
//对于在住中的预订(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()
&& (iPro.getCheckoutDate()==null || iPro.getCheckoutDate().getTime()<curoffDate.getTime())
&& (Strings.CS.equals(iPro.getLastOperaStatus(), "RESERVED")||
@@ -696,6 +724,7 @@ public class BookingController {
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)
public ResponseEntity<BaseApiResponse<DataTableResult<BookingsView>>> getBookingByPage(
HttpServletRequest request,
@@ -709,6 +738,12 @@ public class BookingController {
queryFilter.setPermissionId("");
}else if(StringUtils.isNotBlank(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);
@@ -746,6 +781,7 @@ public class BookingController {
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)
public ResponseEntity<List<BookingsView>> webRecordSearch(HttpServletRequest request, @RequestBody WebRecordSearchRequest params) throws Exception {
// requireAnyWebPermission(request, "00501_01", "00401_01", "00402_01");
@@ -825,6 +861,7 @@ public class BookingController {
return allPropertiesResults;
}
@VerifyPermission(permissionId = {"00402_07"})
@RequestMapping(value = "/web/other_booking/import_batch", method = RequestMethod.POST)
public ResponseEntity<BaseApiResponse<ValidateResult>> batchImportRows(HttpServletRequest request, HttpServletResponse response,
@RequestBody(required=false) List<OtherBookingImportRow> importRows) throws Exception{
@@ -843,6 +880,7 @@ public class BookingController {
return ResponseEntity.status(HttpStatus.OK).body(result);
}
@VerifyPermission(permissionId = {"00402_07"})
@RequestMapping(value = "/web/other_booking/upload_excel", method = RequestMethod.POST)
public ResponseEntity<BaseApiResponse<ValidateResult>> uploadExcel(HttpServletRequest request, HttpServletResponse response,
@RequestBody(required=false) MultipartFile[] files) throws Exception{
@@ -873,6 +911,7 @@ public class BookingController {
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)
public ResponseEntity<BaseApiResponse<List<String>>> getGamingData(HttpServletRequest request,
@RequestBody(required=true) BookingQueryRequest queryFilter) throws Exception {
@@ -250,6 +250,8 @@ public class BookingsView implements Serializable {
private String bookingApprovalReason;
@Column(name="source_code")
private String sourceCode;
@Column(name = "category")
private String category;
@Transient
private String status;
@@ -62,6 +62,22 @@ public interface BookingViewDao extends JpaRepository<BookingsView, Long> {
@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)
List<BookingsView> findBookingByConfirmationNo(String conf);
@@ -329,7 +329,14 @@ public class BookingService {
booking.setBookingTypeId(bookingTypeId);
booking.setMember(JSONObject.toJSONString(member));
booking.setCategory(property.getCategory());
booking.setSectionName(sectionName);
if (StringUtils.isNotBlank(sectionName)) {
booking.setSectionName(sectionName);
} else {
Bookings finalBooking = booking;
sectionDao.findById(sectionId).ifPresent(section -> {
finalBooking.setSectionName(section.getName());
});
}
booking.setEta(etaTime);
// 设置mischarge
@@ -1059,16 +1066,57 @@ public class BookingService {
}
reservationDTO.setChannelId(channelId);
List<CfgDaylightView> daylightViewList = daylightViewDao.findBySectionPropertyBookingTypeRoomType(
booking.getSectionId(),
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.getPropertyId(),
booking.getBookingTypeId(),
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) {
// booking.setApproveStatus("F");
// booking.setErrorMessage("Rate Code not found");
@@ -1211,7 +1259,7 @@ public class BookingService {
allocationDTO.setRoomTypeId(dlRoomTypeId);
reservationDTO.setAllocation(allocationDTO);
CfgSourceCodes sourceCode = sourceCodeDao.findById(daylightView.getSourceCodeId()).orElse(null);
CfgSourceCodes sourceCode = sourceCodeDao.findById(sourceCodeId).orElse(null);
// if (sourceCode == null) {
// booking.setApproveStatus("F");
// booking.setErrorMessage("Source code not found");
@@ -1230,7 +1278,7 @@ public class BookingService {
reservationDTO.setNoPost(StringUtils.isBlank(booking.getMiscCharge()));
}
CfgMarketCodes marketCode = marketCodeDao.findById(daylightView.getMarketCodeId()).orElse(null);
CfgMarketCodes marketCode = marketCodeDao.findById(marketCodeId).orElse(null);
// if (marketCode == null) {
// booking.setApproveStatus("F");
// booking.setErrorMessage("Market code not found");
@@ -1355,12 +1403,14 @@ public class BookingService {
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("Approver", booking.getApprovedBy());
} else if (booking.getApprovalBookingId() != null) {
customFields.put("App_Rea", "APP");
customFields.put("Approver", String.valueOf(booking.getApprovedId()));
}
customFieldDTO.setLocation("ReservationHeader");
@@ -1425,9 +1475,9 @@ public class BookingService {
Integer trytime = booking.getTryTime()==null?0:(booking.getTryTime()+1);
booking.setApproveStatus("F");
booking.setTryTime(trytime);
booking.setProcessStatus(0);
booking.setErrorMessage(createResponse.getMessage());
booking.setFailedAt(DateTimeUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss"));
booking.setProcessStatus(0);
bookingDao.save(booking);
@@ -1459,8 +1509,8 @@ public class BookingService {
booking.setDlAccountId(daylightReservationByDlId.getAccountId());
booking.setDlReservationId(reservationId);
booking.setConfirmationNo(confirmationNumber);
// booking.setLastOperaStatus("RESERVED");
// booking.setApproveStatus("N");
booking.setLastOperaStatus("RESERVED");
booking.setApproveStatus("N");
//
bookingDao.save(booking);
@@ -1477,7 +1527,7 @@ public class BookingService {
email.setCreatedBy(booking.getCreatedBy());
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);
processResult.setSuccess(true);
}else{
@@ -1496,10 +1546,10 @@ public class BookingService {
checkinDateStr,
checkoutDateStr,
daylightViewList,
exceptionDaylightViewList,
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即可,后面逻辑已经写完
List<String> compRuleIds = new ArrayList<>();
BaseApiResponse<JSONArray> compRuleListResponse =
@@ -2248,7 +2298,7 @@ public class BookingService {
email = sendEmailService.sendExtendEmail(emailBook, originBook, email, userId, userName, emailAddress.getKeyValues());
if (email.getStatus() == 1) {
if (Objects.equals(email.getStatus(), 1)) {
processResult.setSuccess(true);
processResult.setCode("EMAIL");
} else {
@@ -2474,8 +2524,10 @@ public class BookingService {
Date originCheckinDate = DateTimeUtil.getDateFromString(dateArr.getFirst(), "yyyy-MM-dd");
Date checkinDate;
Date checkoutDate;
String userId = param.getUser()!=null? param.getUser().getUserId():null;
String userName = param.getUserName();
String userId = param.getUser() != null && param.getUser().getUserId() != null
? 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);
@@ -2639,7 +2691,7 @@ public class BookingService {
email.setCreatedBy(booking.getCreatedBy());
email = sendEmailService.sendExtendEmail(booking, originBookingView,email,userId,userName,emailAddress.getKeyValues());
if(email.getStatus()==1) {
if(Objects.equals(email.getStatus(), 1)) {
emailDao.save(email);
processResult.setSuccess(true);
processResult.setData(resultBookings);
@@ -3132,7 +3184,7 @@ public class BookingService {
LogUtil.info(BookingService.class,"[mergeDatabaseInfo][Opera Book Exist]");
Date now = new Date();
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());
CfgRooms operaRoom = new CfgRooms();
//set room type
@@ -3289,7 +3341,7 @@ public class BookingService {
LogUtil.info(BookingService.class,"[mergeDatabaseInfo][Opera Book Exist]");
Date now = new Date();
Bookings book = new Bookings();
CfgProperties operaProperty = propertyDao.getByPropertyNameDaylight(operaBooking.getPropertyName());
CfgProperties operaProperty = propertyDao.findByNameAndCategory(operaBooking.getPropertyName(), "DAYLIGHT");
CfgRoomTypes operRoomType =roomTypeDao.findByCodeAndCategory(operaBooking.getRoomTypeCode(), "DAYLIGHT");
CfgRooms operaRoom = new CfgRooms();
//set room type
@@ -5061,6 +5113,11 @@ public class BookingService {
if (dbBooking == null) {
return;
}
// Booking Type 属于本地业务配置,搜索同步不能用普通 mapping 覆盖已有值。
daylightBooking.setBookingTypeId(dbBooking.getBookingTypeId());
if (StringUtils.isNotBlank(dbBooking.getCreatedBy())) {
daylightBooking.setCreatedBy(dbBooking.getCreatedBy());
}
if (dbBooking.getMiscCharge() != null) {
daylightBooking.setMiscCharge(dbBooking.getMiscCharge());
}
@@ -5114,17 +5171,6 @@ public class BookingService {
// }
resolveDaylightBlockInfo(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 (!"PN".equals(dbBookingView.getApproveStatus())) {
@@ -5203,8 +5249,7 @@ public class BookingService {
if (daylightBooking.getSectionId() == null && dbBooking.getSectionId() != null) {
daylightBooking.setSectionId(dbBooking.getSectionId());
}
resolveMissingDaylightBookingType(daylightBooking);
int expMin = 20000;
expMin = expMin * -1;
@@ -5300,18 +5345,7 @@ public class BookingService {
daylightBooking.setSectionId(userInfo.getSectionId());
}
}
//get Booking Type
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);
}
}
resolveMissingDaylightBookingType(daylightBooking);
// build datelist
int numOfNight = Integer.parseInt(DateTimeUtil.getDiffDate(daylightBooking.getCheckinDate(), daylightBooking.getCheckoutDate(), "day"));
List<String> dates = new ArrayList<>();
@@ -5336,6 +5370,7 @@ public class BookingService {
@Transactional
public List<BookingDto> mergeDaylightRecordFromDB_Optimize(List<BookingDto> pmsResult, PlayerProfileEntry member, String userId) throws Exception {
Set<BookingDto> skippedCanceledDaylightBookings = Collections.newSetFromMap(new IdentityHashMap<>());
Set<BookingDto> skippedNoShowDaylightBookings = Collections.newSetFromMap(new IdentityHashMap<>());
List<BookingDto> bookingsForReservationFallback = new ArrayList<>();
// ========== Pass 1: Match by dlExternalNo ==========
@@ -5370,15 +5405,40 @@ public class BookingService {
} else {
Bookings existingDaylightBooking = bookingDao.getByDlExternalNo(dlExternalNo);
if (existingDaylightBooking != null) {
if (isCanceledDaylightBooking(daylightBooking)) {
updateMatchedCanceledBooking(daylightBooking, existingDaylightBooking);
skippedCanceledDaylightBookings.add(daylightBooking);
continue;
}
bookingExist = true;
matchDbBooking = toDaylightMergeBookingView(existingDaylightBooking);
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) {
mergeDaylightRowFromExistingDbBooking_Optimize(daylightBooking, matchDbBooking, dbBookingViews);
} else if (isCanceledDaylightBooking(daylightBooking)) {
skippedCanceledDaylightBookings.add(daylightBooking);
} else if (StringUtils.isNotBlank(daylightBooking.getDlReservationId())) {
bookingsForReservationFallback.add(daylightBooking);
} else if (isLocalCanceledBooking(daylightBooking)) {
@@ -5415,14 +5475,26 @@ public class BookingService {
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) {
// Backfill dlExternalNo to DB record if missing
if (StringUtils.isBlank(matchDbBooking.getDlExternalNo()) && StringUtils.isNotBlank(daylightBooking.getDlExternalNo())) {
matchDbBooking.setDlExternalNo(daylightBooking.getDlExternalNo().trim());
}
mergeDaylightRowFromExistingDbBooking_Optimize(daylightBooking, matchDbBooking, reservationDbBookingViews);
} else if (isCanceledDaylightBooking(daylightBooking)) {
skippedCanceledDaylightBookings.add(daylightBooking);
} else if (isLocalCanceledBooking(daylightBooking)) {
skippedCanceledDaylightBookings.add(daylightBooking);
} else {
@@ -5430,18 +5502,64 @@ public class BookingService {
}
}
if (skippedCanceledDaylightBookings.isEmpty()) {
if (skippedCanceledDaylightBookings.isEmpty() && skippedNoShowDaylightBookings.isEmpty()) {
return pmsResult;
}
List<BookingDto> mergeableResults = new ArrayList<>();
for (BookingDto daylightBooking : pmsResult) {
if (!skippedCanceledDaylightBookings.contains(daylightBooking)) {
if (!skippedCanceledDaylightBookings.contains(daylightBooking)
&& !skippedNoShowDaylightBookings.contains(daylightBooking)) {
mergeableResults.add(daylightBooking);
}
}
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) {
if (StringUtils.isBlank(daylightBooking.getDlBlockId())) {
return;
@@ -5466,6 +5584,46 @@ public class BookingService {
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) {
if (daylightBooking == null || daylightBooking.getLastOperaStatus() == null) {
return false;
@@ -5524,6 +5682,7 @@ public class BookingService {
}
view.setPropertyId(booking.getPropertyId());
view.setRoomTypeId(booking.getRoomTypeId());
view.setSectionId(booking.getSectionId());
view.setBookingTypeId(booking.getBookingTypeId() != null ? booking.getBookingTypeId().intValue() : null);
return view;
@@ -5629,6 +5788,9 @@ public class BookingService {
}
if ("CANCELED".equals(operaBooking.getLastOperaStatus())) {
operaBooking.setApproveStatus("C");
} else if ("NO_SHOW".equals(operaBooking.getLastOperaStatus())
|| "CHECKED_OUT".equals(operaBooking.getLastOperaStatus())) {
} else {
if ("C".equals(dbBooking.getApproveStatus())) {
operaBooking.setApproveStatus("N");
@@ -5908,6 +6070,22 @@ public class BookingService {
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())) {
insertCommentAndMiscChargeFromDaylight(mergeBookingDto, currentBooking.getMiscCharge());
mergedBooking.setOperaComment(mergeBookingDto.getOperaComment());
@@ -6129,11 +6307,17 @@ public class BookingService {
String checkoutDateStr = DateTimeUtil.getDateByFormat(checkOutDate, "yyyy-MM-dd");
DaylightReservationResponse daylightReservationByDlId =
dlService.getDaylightReservationByDlId(bookings.getDlReservationId(), property.getDlPropertyId());
List<CfgDaylightView> daylightViewList = daylightViewDao.findBySectionPropertyBookingTypeRoomType(
bookings.getSectionId(), bookings.getPropertyId(), bookings.getBookingTypeId(), bookings.getRoomTypeId()
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()
);
}
if (CollectionUtils.isNotEmpty(daylightViewList)) {
if (CollectionUtils.isNotEmpty(exceptionDaylightViewList) || CollectionUtils.isNotEmpty(daylightViewList)) {
dlService.createDaylightCompRule(
daylightReservationByDlId.getAccountId(),
daylightReservationByDlId.getProfileId(),
@@ -6143,6 +6327,7 @@ public class BookingService {
checkinDateStr,
checkoutDateStr,
daylightViewList,
exceptionDaylightViewList,
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) {
@@ -6427,7 +6613,8 @@ public class BookingService {
}
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) {
return null;
}
@@ -6449,12 +6636,13 @@ public class BookingService {
+ "\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) {
return null;
}
String stayDate = formatExtStayDateRange(originCheckoutDate, booking.getCheckoutDate());
String stayDate = formatExtStayDateRange(originCheckoutDate, newCheckoutDate);
String bookerName = StringUtils.defaultIfBlank(booker, booking.getBooker());
String extLine = "EXT " + stayDate + ",OD," + bookerName + "..APP";
@@ -6471,10 +6659,15 @@ public class BookingService {
.replace("&#xA;", "\n")
.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) {
rmEndIndex += "COMP ..APP".length();
if (rmHeaderMatcher.find()) {
int rmEndIndex = rmHeaderMatcher.end();
newComment = comment.substring(0, rmEndIndex)
+ "\n\n"
@@ -6489,7 +6682,7 @@ public class BookingService {
LogUtil.info(BookingService.class,
"[buildODExtendCommentContent] bookingId=" + booking.getId()
+ ", originCheckout=" + DateTimeUtil.getDateByFormat(originCheckoutDate, "yyyy-MM-dd")
+ ", newCheckout=" + DateTimeUtil.getDateByFormat(booking.getCheckoutDate(), "yyyy-MM-dd")
+ ", newCheckout=" + DateTimeUtil.getDateByFormat(newCheckoutDate, "yyyy-MM-dd")
+ ", comment=" + extLine);
return newComment;
@@ -6596,41 +6789,51 @@ public class BookingService {
private void insertCommentAndMiscChargeFromDaylight(BookingDto dto, String previousMiscCharge) {
String dlReservationId = dto.getDlReservationId();
String dlPropertyId = dto.getDlPropertyId();
// String dlReservationId = dto.getDlReservationId();
// 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
.compile("(?:\\$|&#x24;)\\s*([0-9]+(?:\\.[0-9]+)?)", Pattern.CASE_INSENSITIVE)
.matcher(comment);
if (miscChargeMatcher.find()) {
String miscCharge = miscChargeMatcher.group(1);
if (!Objects.equals(previousMiscCharge, miscCharge)) {
dto.setMiscCharge(miscCharge);
updateDaylightCompRule(dto, miscCharge);
}
}
comment = comment.replaceAll("(?i)<br\\s*/?>", "\n");
}
dto.setOperaComment(comment);
Matcher miscChargeMatcher = Pattern
.compile("(?:\\$|&#x24;)\\s*([0-9]+(?:\\.[0-9]+)?)", Pattern.CASE_INSENSITIVE)
.matcher(comment);
if (miscChargeMatcher.find()) {
String miscCharge = miscChargeMatcher.group(1);
if (!Objects.equals(previousMiscCharge, miscCharge)) {
dto.setMiscCharge(miscCharge);
updateDaylightCompRule(dto, miscCharge);
}
}
dto.setOperaComment(comment.replaceAll("(?i)<br\\s*/?>", "\n"));
}
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;
}
@@ -6705,4 +6908,16 @@ public class BookingService {
response.setData(bookView);
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.team.models.CfgOtherUserMapping;
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.BookingDto;
import com.mgm.mcrm.booking.mappers.BookingMapper;
@@ -113,6 +114,8 @@ public class NonMGMBookingService {
private MgmUserService mgmUserService;
@Resource
private ApprovalService approvalService;
@Resource
private SectionDao sectionDao;
@Autowired
private BookingMapper bookingMapper;
@@ -135,6 +138,7 @@ public class NonMGMBookingService {
String createdByName = userInfo.getUserName();
String groupId = param.getGroupId();
Long sectionId = param.getSectionId();
String sectionName = param.getSectionName();
PlayerProfileEntry member = param.getMember();
Long bedTypeMasterGroupId = param.getBedTypeId();
String bedTypeName = param.getBedTypeName();
@@ -203,6 +207,15 @@ public class NonMGMBookingService {
booking.setEta(etaTime);
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)
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
public FilterRegistrationBean<ConfigHeaderFilter> registerHeaderFilter() {
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.setName("ConfigHeaderFilter");
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
@@ -62,7 +71,10 @@ public class WebFilterConfig {
"/api/system/write_public_log",
"/api/system/sys_setting/get_public_login_settings",
"/api/app/sso/*",
"/sso_callback/login",
"/sso_callback/logout",
"/api/web/setting/get_public_setting_by_key",
"/api/third_party/get_access_token",
"/swagger*/*",
"/v3/**",
"/api-docs",
@@ -6,8 +6,10 @@ import com.auth0.jwt.interfaces.DecodedJWT;
import com.mgm.mcrm.appsetting.models.SysSetting;
import com.mgm.mcrm.authorization.dtos.LoginUserInfo;
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.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.UpdateCfgItem;
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.web.servlet.support.RequestContextUtils;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
@@ -36,6 +39,7 @@ import java.util.*;
public class SysCommon {
public static String runtime_path = "";
public static String serverIp="";
public static String serverName="";
@@ -49,10 +53,6 @@ public class SysCommon {
public static int postTimeOut = 20;
//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 List<String> allowOriginSource = new ArrayList<String>();
@Getter
@@ -85,7 +85,6 @@ public class SysCommon {
//--Server Info
serverIp = NetworkUtil.getInternalIp();
serverName = NetworkUtil.getServerName();
loadAPIConfig(props);
} catch (Exception e) {
isLoaded = false;
LogUtil.error(SysCommon.class, "Load configuration error:" + e.getMessage());
@@ -388,18 +387,6 @@ public class SysCommon {
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
public static String loadResFileContentByPath(String filePath, int pathType) {
@@ -503,6 +490,7 @@ public class SysCommon {
LoginUserInfo loginUser = null;
if(StringUtils.isNotBlank(tokenContent)) {
try {
LogUtil.info(SysCommon.class, "Parse Token content:"+tokenContent);
tokenContent = tokenContent.replace("Bearer ", "");
DecodedJWT decodeData = JWT.decode(tokenContent);
@@ -513,8 +501,14 @@ public class SysCommon {
}else {
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) {
LogUtil.error(SysCommon.class, "Parse Token failed:"+err.getMessage());
loginUser =null;
@@ -18,6 +18,7 @@ public class SysConstants {
public static final int CMS_TOKEN_TYPE=0;
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_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"),
DUEOUT("DUEOUT", "DUE_OUT"),
CANCELED("CANCELED", "CANCELED"),
CANCELLED("CANCELLED", "CANCELED");
CANCELLED("CANCELLED", "CANCELED"),
NO_SHOW("No-Show", "NO_SHOW");
@Getter
private final String key;
@@ -6,13 +6,19 @@ import com.mgm.mcrm.common.utils.NetworkUtil;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.AntPathMatcher;
import java.io.IOException;
import java.util.List;
@Slf4j
public class ConfigHeaderFilter implements Filter {
private final AntPathMatcher pathMatcher = new AntPathMatcher();
@Setter
private List<String> ignoreOriginPatterns;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
@@ -23,30 +29,45 @@ 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
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
if (response instanceof HttpServletResponse httpServletResponse) {
if(httpServletResponse.getHeader("Server")!=null) {
httpServletResponse.setHeader("Server", "");
}
String origin = ((HttpServletRequest) request).getHeader("Origin");
String sanitizedOrigin = NetworkUtil.sanitizeCRLF(origin);
if (SysCommon.isAllowOriginSource(sanitizedOrigin) || "OPTIONS".equalsIgnoreCase(req.getMethod())) {
httpServletResponse.setHeader("Access-Control-Allow-Origin", sanitizedOrigin);
} else {
LogUtil.warn(ConfigHeaderFilter.class, "Origin of [" + sanitizedOrigin + "] is not allowed");
httpServletResponse.setHeader("Access-Control-Allow-Origin", "");
log.warn("Blocked request: method={}, uri={}, query={}, origin={}, referer={}, ip={}, xff={}, userAgent={}",
req.getMethod(),
req.getRequestURI(),
req.getQueryString(),
req.getHeader("Origin"),
req.getHeader("Referer"),
req.getRemoteAddr(),
req.getHeader("X-Forwarded-For"),
req.getHeader("User-Agent"));
return;
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);
} else {
LogUtil.warn(ConfigHeaderFilter.class, "Origin of [" + sanitizedOrigin + "] is not allowed");
httpServletResponse.setHeader("Access-Control-Allow-Origin", "");
log.warn("Blocked request: method={}, uri={}, query={}, origin={}, referer={}, ip={}, xff={}, userAgent={}",
req.getMethod(),
req.getRequestURI(),
req.getQueryString(),
req.getHeader("Origin"),
req.getHeader("Referer"),
req.getRemoteAddr(),
req.getHeader("X-Forwarded-For"),
req.getHeader("User-Agent"));
return;
}
}
httpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
httpServletResponse.addHeader("Access-Control-Allow-Headers", "Content-Type,Authorization,ClientId,Refreshtoken");
@@ -55,8 +55,6 @@ public class HttpRequestOptions {
*/
private HttpContext context;
// private Map<String, Object> map;
/**
* 以json格式作为输入参数
*/
@@ -83,19 +81,19 @@ public class HttpRequestOptions {
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对象
@@ -111,7 +109,7 @@ public class HttpRequestOptions {
* @return 返回当前对象
*/
public HttpRequestOptions url(String url) {
urls.set(url);
this.url = url;
return this;
}
@@ -169,20 +167,13 @@ public class HttpRequestOptions {
* @return 返回当前对象
*/
public HttpRequestOptions map(Map<String, Object> map) {
// synchronized (getClass()) {
// if(this.map==null || map==null){
// this.map = map;
// }else {
// this.map.putAll(map);;
// }
// }
Map<String, Object> m = maps.get();
if(m == null || map.isEmpty()){
m = map;
}else {
m.putAll(map);
if (map == null) {
parameters = null;
} else if (parameters == null || map.isEmpty()) {
parameters = new HashMap<>(map);
} else {
parameters.putAll(map);
}
maps.set(m);
return this;
}
@@ -192,9 +183,8 @@ public class HttpRequestOptions {
*/
public HttpRequestOptions json(String json) {
this.json = json;
Map<String, Object> map = new HashMap<String, Object>();
map.put(HttpEntityBuilder.ENTITY_JSON, json);
maps.set(map);
parameters = new HashMap<>();
parameters.put(HttpEntityBuilder.ENTITY_JSON, json);
return this;
}
@@ -222,23 +212,12 @@ public class HttpRequestOptions {
* @return 返回当前对象
*/
public HttpRequestOptions files(String[] filePaths, String inputName, boolean forceRemoveContentTypeChraset) {
// synchronized (getClass()) {
// if(this.map==null){
// 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>();
if (parameters == null) {
parameters = new HashMap<>();
}
m.put(HttpEntityBuilder.ENTITY_MULTIPART, filePaths);
m.put(HttpEntityBuilder.ENTITY_MULTIPART+".name", inputName);
m.put(HttpEntityBuilder.ENTITY_MULTIPART+".rmCharset", forceRemoveContentTypeChraset);
maps.set(m);
parameters.put(HttpEntityBuilder.ENTITY_MULTIPART, filePaths);
parameters.put(HttpEntityBuilder.ENTITY_MULTIPART+".name", inputName);
parameters.put(HttpEntityBuilder.ENTITY_MULTIPART+".rmCharset", forceRemoveContentTypeChraset);
return this;
}
@@ -273,7 +252,7 @@ public class HttpRequestOptions {
* @return 返回当前对象
*/
public HttpRequestOptions out(OutputStream out) {
outs.set(out);
this.out = out;
return this;
}
@@ -329,7 +308,7 @@ public class HttpRequestOptions {
}
public String url() {
return urls.get();
return url;
}
public HttpMethods method() {
@@ -345,8 +324,7 @@ public class HttpRequestOptions {
}
public Map<String, Object> map() {
// return map;
return maps.get();
return parameters;
}
public String json() {
@@ -366,7 +344,7 @@ public class HttpRequestOptions {
}
public OutputStream out() {
return outs.get();
return out;
}
public RequestConfig requestConfig() {
@@ -5,17 +5,10 @@ import com.mgm.mcrm.common.services.ConfigurableTrustHandler;
import lombok.Getter;
import lombok.Setter;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.ssl.SSLContexts;
import javax.net.ssl.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
/**
* 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}
@@ -77,6 +77,12 @@ public class BookingControlMsgConsumer {
Bookings.class
);
// booking.setApproveStatus("F");
// Integer tryTime = booking.getTryTime() != null ? booking.getTryTime() : 0;
// booking.setTryTime(tryTime + 1);
//
// bookingDao.save(booking);
bookingDao.updateProcessStatus(
booking.getId(),
0
@@ -162,16 +162,16 @@ public class ADFSUtil {
if(decodeData.getClaim("upn")!=null) {
result.setLoginId(decodeData.getClaim("upn").asString());
}
if(decodeData.getClaim("user_group")!=null) {
if(decodeData.getClaim("group_name")!=null) {
try {
List<String> groupNames = decodeData.getClaim("user_group").asList(String.class);
List<String> groupNames = decodeData.getClaim("group_name").asList(String.class);
String groupNameVal = "";
for(int i=0;i<groupNames.size();i++) {
groupNameVal += (i>0?";":"")+groupNames.get(i);
}
result.setGroupName(groupNameVal);
}catch(Exception err) {
result.setGroupName(decodeData.getClaim("user_group").asString());
result.setGroupName(decodeData.getClaim("group_name").asString());
}
}
}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 lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Strings;
import org.apache.hc.client5.http.classic.methods.HttpDelete;
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.protocol.HttpClientContext;
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.TrustAllStrategy;
import org.apache.hc.core5.http.ContentType;
import org.apache.hc.core5.http.HttpEntity;
import org.apache.hc.core5.http.config.Registry;
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.StringEntity;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.apache.hc.core5.util.Timeout;
import org.springframework.web.multipart.MultipartFile;
@@ -93,12 +89,13 @@ public class HttpUtil {
if(Strings.CI.startsWith(requestUrl, "https://")) {
SSLContext sslContext = null;
try {
sslContext = SSLContextBuilder.create().loadTrustMaterial(TrustAllStrategy.INSTANCE).build();
//sslContext = SSLContextBuilder.create().loadTrustMaterial(TrustAllStrategy.INSTANCE).build();
sslContext = getSSLContext();
} catch (Exception e) {
e.printStackTrace();
}
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE ))
.register("https", new SSLConnectionSocketFactory(sslContext, getTrustHandler()))
.build();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
@@ -37,6 +37,11 @@ public class LogUtil {
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) {
StringBuilder attrText = new StringBuilder();
if(srcObj!=null && attrNames!=null) {
@@ -88,8 +88,8 @@ public class NetworkUtil {
private static String getIpFromHeaders(HttpServletRequest request) {
String[] headerNames = {
"X-Forwarded-For",
"X-Real-IP",
"X-Forwarded-For",
"Proxy-Client-IP",
"WL-Proxy-Client-IP",
"HTTP_CLIENT_IP",
@@ -100,7 +100,7 @@ public class NetworkUtil {
String headerValue = request.getHeader(headerName);
if (headerValue != null && !headerValue.isEmpty()) {
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);
if (ip != null) {
return ip;
File diff suppressed because it is too large Load Diff
@@ -1185,7 +1185,7 @@ public class LimoService {
// --- Room / Employee ---
limoBookingRequest.setRoomNo("");
limoBookingRequest.setEmployeeId(defaultString(request.getEmployeeId(), ""));
// limoBookingRequest.setEmployeeId(defaultString(request.getEmployeeId(), ""));
// --- Contact ---
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();
if(Strings.CI.contains(propertyName, "mandarin")) propertyName="MO";
String title = "Dear "+propertyName+" Team,";
String content = template.getContent();
StringBuilder content = new StringBuilder(template.getContent());
String table = "";
List bookIdList = new ArrayList();
if(!StringUtils.isEmpty(template.getField())) {
//New Booking Request
table = tableTemp;
String[] fieledList = template.getField().split(";");
String thread = "<th>No</th>";
StringBuilder thread = new StringBuilder("<th>No</th>");
for( String field : fieledList) {
thread+="<th>"+field+"</th>";
thread.append("<th>").append(field).append("</th>");
}
String tbody = "";
StringBuilder tbody = new StringBuilder();
int index = 1;
for(BookingsView bo:typeList) {
tbody+="<tr><td>"+index+"</td>";
tbody.append("<tr><td>").append(index).append("</td>");
index++;
bookIdList.add(String.valueOf(bo.getId()));
for( String field : fieledList) {
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("{{tbody}}", tbody);
table = table.replace("{{thead}}", thread.toString());
table = table.replace("{{tbody}}", tbody.toString());
}else {
content="";
content = new StringBuilder();
for(BookingsView bo:typeList) {
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("{{content}}", content);
temp = temp.replace("{{content}}", content.toString());
temp = temp.replace("{{table}}", table);
template.setShowTemp(temp);
template.setBookIds(String.join(";", bookIdList));
@@ -254,7 +254,7 @@ public class EmailTemplateService {
field = book.getRoomEmailName()!=null?book.getRoomEmailName():"";
break;
case "Booker & Contact":
String booker = "";
String booker;
boolean isMo = Strings.CI.contains(book.getPropertyName(), "mandarin");
if(Strings.CS.equals("CCREL", book.getMarketCode())) {
booker = "CR";
@@ -2,11 +2,14 @@ package com.mgm.mcrm.notification.services;
import com.alibaba.fastjson.JSON;
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.BookingsView;
import com.mgm.mcrm.common.dtos.BaseApiResponse;
import com.mgm.mcrm.common.dtos.EumnApprovalStatus;
import com.mgm.mcrm.common.dtos.config.ApiGatewaySetting;
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.HttpUtil;
import com.mgm.mcrm.common.utils.LogUtil;
@@ -32,11 +35,15 @@ public class SendEmailService {
@Value("${notification.default-email-receiver}")
private String defaultEmailReceiver;
@Resource
private MgmUserService mgmUserService;
@Resource
private ApiGatewaySetting apiGatewaySetting;
private static final String emailTemp = "<div>Submission Date & Time:{{ttime}}</div>"+
"<div>Submitted User:{{tuser}}</div>"+
"<div>Approver:{{tapprover}}</div>"+
"<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" +
" <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,10 +288,21 @@ public class SendEmailService {
String content2 = "";
String tTime = RequestDate;
userId = !StringUtils.isEmpty(userId)?userId:"";
userName = !StringUtils.isEmpty(userName)?userName:"";
String tUser = userId+" "+userName;
String operaStatus = Strings.CS.replace(book.getLastOperaStatus(), "_", " ");
userId = StringUtils.isNotEmpty(userId)?userId:"";
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 tApprover = book.getApprovedId()+" "+book.getApprovedBy();
content2 += "<tr>"+
"<td>"
@@ -325,6 +343,7 @@ public class SendEmailService {
content1 = content1.replace("{{tbody}}", content2);
content1 = content1.replace("{{ttime}}", tTime);
content1 = content1.replace("{{tuser}}", tUser);
content1 = content1.replace("{{tapprover}}", tApprover);
emailRequest.setShowTemp(content1);
emailRequest.setContent(content1);
JSONObject emailJson = new JSONObject();
@@ -18,6 +18,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Random;
@@ -263,6 +264,7 @@ public class PlayerService {
resultObj.setDates(resultList);
}
}
sortDatesAscending(resultObj.getDates());
result.setSuccess(true);
result.setData(resultObj);
return result;
@@ -376,12 +378,22 @@ public class PlayerService {
resultObj.setDates(resultList);
}
}
sortDatesAscending(resultObj.getDates());
result.setSuccess(true);
result.setData(resultObj);
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) {
boolean isMock = sysSettingService.isMockReplicate();
if (isMock) {
@@ -307,7 +307,7 @@ public class TodoService {
boolean isDaylight = Strings.CS.equals("DAYLIGHT", category);
boolean isOther = Strings.CS.equals("OTHER", category);
CfgProperties property = propertyDao.getByName(param.getPropertyName());
CfgProperties property = propertyDao.findByNameAndCategory(param.getPropertyName(), category);
String dlReservationId = null;
@@ -639,13 +639,13 @@ public class TodoService {
return missParameter(result);
}
CfgProperties property = propertyDao.getByLikeName(hotelName);
String category = bookingDao.findCategoryById(id);
CfgProperties property = propertyDao.findByLikeNameAndCategory(hotelName, category);
if (property == null) {
return noRecord(result);
}
String category = property.getCategory();
if (Strings.CI.equals("DAYLIGHT", category)) {
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.repositories.RoomCalendarRoomProjection;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.*;
@Slf4j
@Service
public class RoomCalendarService {
@org.springframework.beans.factory.annotation.Value("${calendar.data-mock-enabled:false}")
@@ -85,7 +87,8 @@ public class RoomCalendarService {
allRecords.addAll(parseRoomCalendarResponse(response.getResponseContent()));
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()));
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()));
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:
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:
port: 9086
tomcat:
@@ -106,6 +92,8 @@ mcrm:
secret-key: SecretKeyWhichShouldBeLongEnoughToBeSecure67848563
api-token-expiration: 5 # 分钟单位
mobile-session-expiration: 43200 # 分钟单位
daylight:
booking-search-cache-seconds: 300
#============== Daylight Service ===================
api-gateway:
@@ -206,8 +194,8 @@ calendar:
#==================APP Config===================
notification:
recent-hours: 6
default-email-sender: test@test.com
default-email-receiver: missing@test.com
default-email-sender: 201249946@qq.com
default-email-receiver: mauve.chan@willtechmacau.com
limo:
booking-draft: