diff --git a/.gitignore b/.gitignore index 53c65de..f1730be 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ !/target/crm_mobile_runtime/ /.classpath /.project +/crm_mobile_runtime/logs/ diff --git a/crm_mobile_runtime/convert/bin/DaylightReservationService.class b/crm_mobile_runtime/convert/bin/DaylightReservationService.class new file mode 100644 index 0000000..0c2a1a6 Binary files /dev/null and b/crm_mobile_runtime/convert/bin/DaylightReservationService.class differ diff --git a/crm_mobile_runtime/excel_define/import/import_other_booking.json b/crm_mobile_runtime/excel_define/import/import_other_booking.json index c8805e6..5c1d774 100644 --- a/crm_mobile_runtime/excel_define/import/import_other_booking.json +++ b/crm_mobile_runtime/excel_define/import/import_other_booking.json @@ -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 } ] }] diff --git a/pom.xml b/pom.xml index 07e7bed..e347e1f 100644 --- a/pom.xml +++ b/pom.xml @@ -20,6 +20,7 @@ UTF-8 21 + 11.0.25 4.2.18.Final 5.6.4 5.2.3 diff --git a/src/main/java/com/mgm/mcrm/adfs/controllers/SSOCallbackController.java b/src/main/java/com/mgm/mcrm/adfs/controllers/SSOCallbackController.java index e9d92eb..9e01ee6 100644 --- a/src/main/java/com/mgm/mcrm/adfs/controllers/SSOCallbackController.java +++ b/src/main/java/com/mgm/mcrm/adfs/controllers/SSOCallbackController.java @@ -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) @@ -32,7 +31,7 @@ public class SSOCallbackController { response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); out.print(text); - out.close(); + out.close(); return null; } } diff --git a/src/main/java/com/mgm/mcrm/adfs/controllers/SSORestProcessController.java b/src/main/java/com/mgm/mcrm/adfs/controllers/SSORestProcessController.java index f58435f..c55d1d8 100644 --- a/src/main/java/com/mgm/mcrm/adfs/controllers/SSORestProcessController.java +++ b/src/main/java/com/mgm/mcrm/adfs/controllers/SSORestProcessController.java @@ -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 cookieValues = new HashMap();String origin = request.getHeader("Origin"); + Map cookieValues = new HashMap(); + 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 { diff --git a/src/main/java/com/mgm/mcrm/approval/service/ApprovalService.java b/src/main/java/com/mgm/mcrm/approval/service/ApprovalService.java index 8b4605b..001bb84 100644 --- a/src/main/java/com/mgm/mcrm/approval/service/ApprovalService.java +++ b/src/main/java/com/mgm/mcrm/approval/service/ApprovalService.java @@ -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) { diff --git a/src/main/java/com/mgm/mcrm/appsetting/services/ConfigService.java b/src/main/java/com/mgm/mcrm/appsetting/services/ConfigService.java index 9204617..4648e49 100644 --- a/src/main/java/com/mgm/mcrm/appsetting/services/ConfigService.java +++ b/src/main/java/com/mgm/mcrm/appsetting/services/ConfigService.java @@ -89,8 +89,8 @@ public class ConfigService { public List listProperty(PropertyQueryRequest queryFilter) { Specification listSpec = (root, criteriaQuery, cb) -> { List 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 listSpec = (root, criteriaQuery, cb) -> { List 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 checkCriteriaBooking(Map resultList,String playerId,String userId,String userName) throws Exception{ + private Map checkCriteriaBooking(Map 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() listRoomSetting() { Sort sort = Sort.by(Direction.ASC, "keys"); return settingDao.findAll(sort); diff --git a/src/main/java/com/mgm/mcrm/authorization/controllers/MobileLoginController.java b/src/main/java/com/mgm/mcrm/authorization/controllers/MobileLoginController.java index dbf537f..e323776 100644 --- a/src/main/java/com/mgm/mcrm/authorization/controllers/MobileLoginController.java +++ b/src/main/java/com/mgm/mcrm/authorization/controllers/MobileLoginController.java @@ -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 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()); diff --git a/src/main/java/com/mgm/mcrm/authorization/controllers/ThirdPartyAuthorizationController.java b/src/main/java/com/mgm/mcrm/authorization/controllers/ThirdPartyAuthorizationController.java new file mode 100644 index 0000000..f3e6b99 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/authorization/controllers/ThirdPartyAuthorizationController.java @@ -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> 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 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); + } + } + +} diff --git a/src/main/java/com/mgm/mcrm/authorization/dtos/GetAuthTokenRequest.java b/src/main/java/com/mgm/mcrm/authorization/dtos/GetAuthTokenRequest.java new file mode 100644 index 0000000..3ad6dbe --- /dev/null +++ b/src/main/java/com/mgm/mcrm/authorization/dtos/GetAuthTokenRequest.java @@ -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; + +} diff --git a/src/main/java/com/mgm/mcrm/authorization/dtos/GetAuthTokenResponse.java b/src/main/java/com/mgm/mcrm/authorization/dtos/GetAuthTokenResponse.java new file mode 100644 index 0000000..97adf3d --- /dev/null +++ b/src/main/java/com/mgm/mcrm/authorization/dtos/GetAuthTokenResponse.java @@ -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; +} diff --git a/src/main/java/com/mgm/mcrm/authorization/dtos/SsoLoginRequest.java b/src/main/java/com/mgm/mcrm/authorization/dtos/SsoLoginRequest.java index 1bd5828..58dbccc 100644 --- a/src/main/java/com/mgm/mcrm/authorization/dtos/SsoLoginRequest.java +++ b/src/main/java/com/mgm/mcrm/authorization/dtos/SsoLoginRequest.java @@ -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; diff --git a/src/main/java/com/mgm/mcrm/authorization/filters/JwtAuthFilter.java b/src/main/java/com/mgm/mcrm/authorization/filters/JwtAuthFilter.java index 955ac77..e7d7fc0 100644 --- a/src/main/java/com/mgm/mcrm/authorization/filters/JwtAuthFilter.java +++ b/src/main/java/com/mgm/mcrm/authorization/filters/JwtAuthFilter.java @@ -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)){ diff --git a/src/main/java/com/mgm/mcrm/authorization/interceptor/PermissionInterceptor.java b/src/main/java/com/mgm/mcrm/authorization/interceptor/PermissionInterceptor.java new file mode 100644 index 0000000..f7cbf65 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/authorization/interceptor/PermissionInterceptor.java @@ -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; + } + +} diff --git a/src/main/java/com/mgm/mcrm/authorization/repositories/SysUserDao.java b/src/main/java/com/mgm/mcrm/authorization/repositories/SysUserDao.java index e7ee32e..e6b62ab 100644 --- a/src/main/java/com/mgm/mcrm/authorization/repositories/SysUserDao.java +++ b/src/main/java/com/mgm/mcrm/authorization/repositories/SysUserDao.java @@ -30,4 +30,6 @@ public interface SysUserDao extends JpaRepository { @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); } diff --git a/src/main/java/com/mgm/mcrm/authorization/services/AuthorizationService.java b/src/main/java/com/mgm/mcrm/authorization/services/AuthorizationService.java index ce96282..7982481 100644 --- a/src/main/java/com/mgm/mcrm/authorization/services/AuthorizationService.java +++ b/src/main/java/com/mgm/mcrm/authorization/services/AuthorizationService.java @@ -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; + } } diff --git a/src/main/java/com/mgm/mcrm/authorization/services/MgmUserService.java b/src/main/java/com/mgm/mcrm/authorization/services/MgmUserService.java index 1ecd722..d90c5a3 100644 --- a/src/main/java/com/mgm/mcrm/authorization/services/MgmUserService.java +++ b/src/main/java/com/mgm/mcrm/authorization/services/MgmUserService.java @@ -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 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) { diff --git a/src/main/java/com/mgm/mcrm/authorization/utils/JwtTokenUtil.java b/src/main/java/com/mgm/mcrm/authorization/utils/JwtTokenUtil.java index d89942c..3a96654 100644 --- a/src/main/java/com/mgm/mcrm/authorization/utils/JwtTokenUtil.java +++ b/src/main/java/com/mgm/mcrm/authorization/utils/JwtTokenUtil.java @@ -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) { diff --git a/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionCompPreset.java b/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionCompPreset.java new file mode 100644 index 0000000..fa4ae69 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionCompPreset.java @@ -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; +} diff --git a/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionDaylight.java b/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionDaylight.java index ccfd794..bc72a6f 100644 --- a/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionDaylight.java +++ b/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionDaylight.java @@ -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 cfgCompPresetList; @Column(name="created_at") private Date createdAt; @Column(name="created_by") @@ -41,4 +59,8 @@ public class CfgExceptionDaylight implements Serializable { private List roomTypeIds; @Transient private List blockCodeIds; + @Transient + private List dlCompPresetIds; + @Transient + private List compPresetContents; } diff --git a/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionDaylightView.java b/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionDaylightView.java index 061a508..23052c5 100644 --- a/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionDaylightView.java +++ b/src/main/java/com/mgm/mcrm/basesetting/daylight/models/CfgExceptionDaylightView.java @@ -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 cfgCompPresetList; + @Column(name="created_at") private Date createdAt; @@ -146,4 +168,4 @@ public class CfgExceptionDaylightView implements Serializable { @Transient private String marketCodeName; -} \ No newline at end of file +} diff --git a/src/main/java/com/mgm/mcrm/basesetting/daylight/repositories/DaylightViewDao.java b/src/main/java/com/mgm/mcrm/basesetting/daylight/repositories/DaylightViewDao.java index e5e0ff1..4406c71 100644 --- a/src/main/java/com/mgm/mcrm/basesetting/daylight/repositories/DaylightViewDao.java +++ b/src/main/java/com/mgm/mcrm/basesetting/daylight/repositories/DaylightViewDao.java @@ -47,4 +47,25 @@ public interface DaylightViewDao extends JpaRepository { @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 findBookingTypeIdsBySectionPropertyRoomTypeAndCodes( + @Param("sectionId") Long sectionId, + @Param("propertyId") Long propertyId, + @Param("roomTypeId") Long roomTypeId, + @Param("marketCode") String marketCode, + @Param("rateCode") String rateCode + ); } diff --git a/src/main/java/com/mgm/mcrm/basesetting/daylight/repositories/ExceptionDaylightViewDao.java b/src/main/java/com/mgm/mcrm/basesetting/daylight/repositories/ExceptionDaylightViewDao.java index e445f65..1019d15 100644 --- a/src/main/java/com/mgm/mcrm/basesetting/daylight/repositories/ExceptionDaylightViewDao.java +++ b/src/main/java/com/mgm/mcrm/basesetting/daylight/repositories/ExceptionDaylightViewDao.java @@ -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 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 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 findBookingTypeIdsByUserPropertyRoomTypeAndCodes( + @Param("userId") String userId, + @Param("propertyId") Long propertyId, + @Param("roomTypeId") Long roomTypeId, + @Param("marketCode") String marketCode, + @Param("rateCode") String rateCode + ); + } diff --git a/src/main/java/com/mgm/mcrm/basesetting/daylight/services/DaylightApiService.java b/src/main/java/com/mgm/mcrm/basesetting/daylight/services/DaylightApiService.java index 2378e68..8c85f70 100644 --- a/src/main/java/com/mgm/mcrm/basesetting/daylight/services/DaylightApiService.java +++ b/src/main/java/com/mgm/mcrm/basesetting/daylight/services/DaylightApiService.java @@ -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 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 updateDaylightCompRule( + String dlAccountId, + String dlPropertyId, + String startDate, + String endDate, + CfgDaylightView daylightView, + CfgExceptionDaylightView exceptionDaylightView, + String miscCharge ) { BaseApiResponse 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 daylightViewList, + List 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 createDefaultResult = createCompRule(url, headers, roomOnlyCompRuleRequest); if (!createDefaultResult.isSuccess()) { return createDefaultResult; @@ -1589,7 +1666,7 @@ public class DaylightApiService { if (createDaylightViewCompRule) { BaseApiResponse 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 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 compPresetList = compPresetDao.findAllByDaylightMappingId(daylightView.getId()); - CfgCompPreset compPreset = compPresetList.getFirst(); - - crr.setComplimentaryAccountingPresetsIds(List.of(compPreset.getDlCompPresetId())); + String compPresetId; + if (exceptionDaylightView != null) { + List 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 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 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 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 getDaylightRequestorApproverByUserId(final String propertyId, final String userId) { BaseApiResponse 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; diff --git a/src/main/java/com/mgm/mcrm/basesetting/property/models/CfgProperties.java b/src/main/java/com/mgm/mcrm/basesetting/property/models/CfgProperties.java index c835857..9974a20 100644 --- a/src/main/java/com/mgm/mcrm/basesetting/property/models/CfgProperties.java +++ b/src/main/java/com/mgm/mcrm/basesetting/property/models/CfgProperties.java @@ -45,4 +45,6 @@ public class CfgProperties implements Serializable { @Column(name = "status") private int status; + @Column(name = "display_type") + private int displayType; } diff --git a/src/main/java/com/mgm/mcrm/basesetting/property/repositories/PropertyDao.java b/src/main/java/com/mgm/mcrm/basesetting/property/repositories/PropertyDao.java index e435a12..135ea51 100644 --- a/src/main/java/com/mgm/mcrm/basesetting/property/repositories/PropertyDao.java +++ b/src/main/java/com/mgm/mcrm/basesetting/property/repositories/PropertyDao.java @@ -16,16 +16,7 @@ import java.util.List; public interface PropertyDao extends JpaRepository { @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 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 { @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 findAll(Specification spec); List findAll(Specification spec, Sort sort); @@ -54,4 +42,6 @@ public interface PropertyDao extends JpaRepository { List findByCategory(String category); List findByCalendarNameIn(Collection calendarNames); + + CfgProperties findByNameAndCategory(String propertyName, String category); } diff --git a/src/main/java/com/mgm/mcrm/booking/controllers/BookingController.java b/src/main/java/com/mgm/mcrm/booking/controllers/BookingController.java index 7566bf7..b6ddc2e 100644 --- a/src/main/java/com/mgm/mcrm/booking/controllers/BookingController.java +++ b/src/main/java/com/mgm/mcrm/booking/controllers/BookingController.java @@ -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> 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 list; - if(isMock) { - list = bookingServiceMockup.getBookingByConfirmationNoMock(conf); - }else { - list = bookingService.getBookingByConfirmationNo(conf); - } + list = bookingService.getBookingByConfirmationNo(conf); if(!list.isEmpty() && StringUtils.isNotEmpty(userId)) { BaseApiResponse 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 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> result = new BaseApiResponse<>(); result.setRequestData(booking); //--get group permissions - //TODO Test boolean editBooking = false; -// List userPermissions = sysGroupPermissionService.getRouterPermissionsByGroupName(groupName); -// if(!userPermissions.isEmpty()) { -// for(SysRouterPermission per:userPermissions) { -// if(Strings.CS.equals(per.getId(), "10001_02") ) editBooking = true; -// } -// } - editBooking = true; + List 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 findPlayerResult = playerService.findPlayerProfileByPlayerIdAndUserId(playerId, userId); @@ -465,17 +465,33 @@ public class BookingController { String checkOutDate = bookingService.getSearchRecordCheckOutDate(currentDay); List operaResult = new ArrayList<>(); List daylightResult = new ArrayList<>(); - //去Daylight查ProfileId - stepStartTime = System.currentTimeMillis(); - BaseApiResponse> profileResult = daylightApiService.dayLightGetProfileByPlayerId(playerId); - List 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> profileResult = daylightApiService.dayLightGetProfileByPlayerId(playerId); + List 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 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 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()>> 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 serviceResult = mgmUserService.findUserInfoByUserId(loginUser.getLoginId()); + if(serviceResult.isSuccess()) { + loginUser.setGroupName(serviceResult.getData().getGroupName()); + } + } } } queryFilter.setPermissionGroup(groupName); @@ -745,7 +780,8 @@ public class BookingController { result.setMessage("Query Success"); 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> webRecordSearch(HttpServletRequest request, @RequestBody WebRecordSearchRequest params) throws Exception { // requireAnyWebPermission(request, "00501_01", "00401_01", "00402_01"); @@ -824,7 +860,8 @@ public class BookingController { return allPropertiesResults; } - + + @VerifyPermission(permissionId = {"00402_07"}) @RequestMapping(value = "/web/other_booking/import_batch", method = RequestMethod.POST) public ResponseEntity> batchImportRows(HttpServletRequest request, HttpServletResponse response, @RequestBody(required=false) List importRows) throws Exception{ @@ -842,7 +879,8 @@ public class BookingController { result.setLogMessage(LogUtil.getAjaxFormatLog(result, "Import Other Booking", null, null)); return ResponseEntity.status(HttpStatus.OK).body(result); } - + + @VerifyPermission(permissionId = {"00402_07"}) @RequestMapping(value = "/web/other_booking/upload_excel", method = RequestMethod.POST) public ResponseEntity> uploadExcel(HttpServletRequest request, HttpServletResponse response, @RequestBody(required=false) MultipartFile[] files) throws Exception{ @@ -872,7 +910,8 @@ 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>> getGamingData(HttpServletRequest request, @RequestBody(required=true) BookingQueryRequest queryFilter) throws Exception { diff --git a/src/main/java/com/mgm/mcrm/booking/models/BookingsView.java b/src/main/java/com/mgm/mcrm/booking/models/BookingsView.java index 303a111..ef339eb 100644 --- a/src/main/java/com/mgm/mcrm/booking/models/BookingsView.java +++ b/src/main/java/com/mgm/mcrm/booking/models/BookingsView.java @@ -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; diff --git a/src/main/java/com/mgm/mcrm/booking/repositories/BookingViewDao.java b/src/main/java/com/mgm/mcrm/booking/repositories/BookingViewDao.java index ffaa036..6c65d46 100644 --- a/src/main/java/com/mgm/mcrm/booking/repositories/BookingViewDao.java +++ b/src/main/java/com/mgm/mcrm/booking/repositories/BookingViewDao.java @@ -61,6 +61,22 @@ public interface BookingViewDao extends JpaRepository { @Param("checkin_date") String checkinDate, @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 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 findBookingByConfirmationNo(String conf); diff --git a/src/main/java/com/mgm/mcrm/booking/services/BookingService.java b/src/main/java/com/mgm/mcrm/booking/services/BookingService.java index 8efe4f9..69c132f 100644 --- a/src/main/java/com/mgm/mcrm/booking/services/BookingService.java +++ b/src/main/java/com/mgm/mcrm/booking/services/BookingService.java @@ -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 daylightViewList = daylightViewDao.findBySectionPropertyBookingTypeRoomType( - booking.getSectionId(), + List exceptionDaylightViewList = exceptionDaylightViewDao.findByUserPropertyBookingTypeRoomType( + userId, booking.getPropertyId(), booking.getBookingTypeId(), roomTypeId ); + List 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 compRuleIds = new ArrayList<>(); BaseApiResponse 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 operaMarketCode = marketCodeDao.findByCodeAndCategory(daylightBooking.getMarketCode(), "DAYLIGHT"); - List operRateCode = rateCodeDao.findByCodeAndCategory(daylightBooking.getRatePlanCode(), "DAYLIGHT"); - if (!operaMarketCode.isEmpty() && !operRateCode.isEmpty()) { - Long operaMarketCodeId = operaMarketCode.getFirst().getId(); - Long operaRateCodeId = operRateCode.getFirst().getId(); - List 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 operaMarketCode = marketCodeDao.findByCodeAndCategory(daylightBooking.getMarketCode(), "DAYLIGHT"); - List operRateCode = rateCodeDao.findByCodeAndCategory(daylightBooking.getRatePlanCode(), "DAYLIGHT"); - if(!operaMarketCode.isEmpty() && !operRateCode.isEmpty()) { - Long operaMarketCodeId = operaMarketCode.getFirst().getId(); - Long operaRateCodeId = operRateCode.getFirst().getId(); - List 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 dates = new ArrayList<>(); @@ -5336,6 +5370,7 @@ public class BookingService { @Transactional public List mergeDaylightRecordFromDB_Optimize(List pmsResult, PlayerProfileEntry member, String userId) throws Exception { Set skippedCanceledDaylightBookings = Collections.newSetFromMap(new IdentityHashMap<>()); + Set skippedNoShowDaylightBookings = Collections.newSetFromMap(new IdentityHashMap<>()); List 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 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 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 bookingTypeIds = daylightViewDao.findBookingTypeIdsBySectionPropertyRoomTypeAndCodes( + booking.getSectionId(), booking.getPropertyId(), booking.getRoomTypeId(), + booking.getMarketCode(), booking.getRatePlanCode()); + applyUniqueDaylightBookingType(booking, bookingTypeIds, "Daylight"); + } + } + + private void applyUniqueDaylightBookingType(BookingDto booking, List candidates, String mappingSource) { + List 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 daylightViewList = daylightViewDao.findBySectionPropertyBookingTypeRoomType( - bookings.getSectionId(), bookings.getPropertyId(), bookings.getBookingTypeId(), bookings.getRoomTypeId() + List exceptionDaylightViewList = exceptionDaylightViewDao.findByUserPropertyBookingTypeRoomType( + bookings.getCreatedBy(), bookings.getPropertyId(), bookings.getBookingTypeId(), bookings.getRoomTypeId() ); + List 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(" ", "\n") .replace("$", "$"); - int rmEndIndex = comment.indexOf("COMP ..APP"); + // 兼容 APP/MSC 的 RM 头部及空格、大小写和空格实体差异,保留原始文本。 + String headerSpacing = "(?:\\h| |�*(?:32|160);|�*(?: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 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("(?:\\$|$)\\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)", "\n"); - } - dto.setOperaComment(comment); + Matcher miscChargeMatcher = Pattern + .compile("(?:\\$|$)\\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)", "\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 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 getSearchPlayerDaylightDbRecord(String checkinDate, + String checkoutDate, + String playerId) { + List bookingsViews = bookingViewDao.findDaylightDbRecord(playerId, checkinDate,checkoutDate); + List bookingDtos = bookingMapper.viewToBookingDtoList(bookingsViews); + Date currentTime = new Date(); + for(BookingDto booking:bookingDtos){ + booking.setDataTime(currentTime); + } + return bookingDtos; + } } diff --git a/src/main/java/com/mgm/mcrm/booking/services/NonMGMBookingService.java b/src/main/java/com/mgm/mcrm/booking/services/NonMGMBookingService.java index 7489199..8a96b5f 100644 --- a/src/main/java/com/mgm/mcrm/booking/services/NonMGMBookingService.java +++ b/src/main/java/com/mgm/mcrm/booking/services/NonMGMBookingService.java @@ -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); diff --git a/src/main/java/com/mgm/mcrm/common/annotation/security/VerifyPermission.java b/src/main/java/com/mgm/mcrm/common/annotation/security/VerifyPermission.java new file mode 100644 index 0000000..64d7b77 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/common/annotation/security/VerifyPermission.java @@ -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 {}; +} diff --git a/src/main/java/com/mgm/mcrm/common/config/WebFilterConfig.java b/src/main/java/com/mgm/mcrm/common/config/WebFilterConfig.java index b8f8099..caa363a 100644 --- a/src/main/java/com/mgm/mcrm/common/config/WebFilterConfig.java +++ b/src/main/java/com/mgm/mcrm/common/config/WebFilterConfig.java @@ -46,7 +46,16 @@ public class WebFilterConfig { @Bean public FilterRegistrationBean registerHeaderFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(); - registration.setFilter(new ConfigHeaderFilter()); + ConfigHeaderFilter filer = new ConfigHeaderFilter(); + List 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", diff --git a/src/main/java/com/mgm/mcrm/common/constants/SysCommon.java b/src/main/java/com/mgm/mcrm/common/constants/SysCommon.java index 74b791f..85ccb94 100644 --- a/src/main/java/com/mgm/mcrm/common/constants/SysCommon.java +++ b/src/main/java/com/mgm/mcrm/common/constants/SysCommon.java @@ -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 notifyTemplateMap = new HashMap(); private static final Map appServerStates = new HashMap(); private static final List allowOriginSource = new ArrayList(); @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; diff --git a/src/main/java/com/mgm/mcrm/common/constants/SysConstants.java b/src/main/java/com/mgm/mcrm/common/constants/SysConstants.java index 826a664..14dedde 100644 --- a/src/main/java/com/mgm/mcrm/common/constants/SysConstants.java +++ b/src/main/java/com/mgm/mcrm/common/constants/SysConstants.java @@ -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"; diff --git a/src/main/java/com/mgm/mcrm/common/dtos/config/APIConfig.java b/src/main/java/com/mgm/mcrm/common/dtos/config/APIConfig.java deleted file mode 100644 index 6af10e6..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/config/APIConfig.java +++ /dev/null @@ -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= ""; - -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ColumnDefine.java b/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ColumnDefine.java deleted file mode 100644 index efecda2..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ColumnDefine.java +++ /dev/null @@ -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; - } - -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/excel_export/DataElement.java b/src/main/java/com/mgm/mcrm/common/dtos/excel_export/DataElement.java deleted file mode 100644 index 7af5a93..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/excel_export/DataElement.java +++ /dev/null @@ -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 columnDefs; - private List blockData; - - public int getElementType() { - return elementType; - } - public void setElementType(int elementType) { - this.elementType = elementType; - } - public List getColumnDefs() { - return columnDefs; - } - public void setColumnDefs(List 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; - } -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ExportDefination.java b/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ExportDefination.java deleted file mode 100644 index 53d3881..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ExportDefination.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.mgm.mcrm.common.dtos.excel_export; - -import java.util.List; - -public class ExportDefination { - private List exportPages; - private String exportFileName; - - public List getExportPages() { - return exportPages; - } - - public void setExportPages(List exportPages) { - this.exportPages = exportPages; - } - - public String getExportFileName() { - return exportFileName; - } - - public void setExportFileName(String exportFileName) { - this.exportFileName = exportFileName; - } -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ExportSheet.java b/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ExportSheet.java deleted file mode 100644 index e37a7d6..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/excel_export/ExportSheet.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.mgm.mcrm.common.dtos.excel_export; - -import java.util.List; - -public class ExportSheet { - private String sheetName; - private List dataElements; - - public ExportSheet() { - - } - - public String getSheetName() { - return sheetName; - } - public void setSheetName(String sheetName) { - this.sheetName = sheetName; - } - public List getDataElements() { - return dataElements; - } - public void setDataElements(List dataElements) { - this.dataElements = dataElements; - } - -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoAccessTokenRequest.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoAccessTokenRequest.java deleted file mode 100644 index 5bf60d5..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoAccessTokenRequest.java +++ /dev/null @@ -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; - -} \ No newline at end of file diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoFlightDetailsRequest.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoFlightDetailsRequest.java deleted file mode 100644 index 4aec774..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoFlightDetailsRequest.java +++ /dev/null @@ -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; -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoOverriderRequest.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoOverriderRequest.java deleted file mode 100644 index 8175d14..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoOverriderRequest.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.mgm.mcrm.common.dtos.mgm_api; - -import lombok.Data; - -@Data -public class GetLimoOverriderRequest { - - private String OverriderIdOrName; - -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoTotalAmountRequest.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoTotalAmountRequest.java deleted file mode 100644 index 368d3b0..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetLimoTotalAmountRequest.java +++ /dev/null @@ -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; -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetPlayerInfoRequest.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetPlayerInfoRequest.java deleted file mode 100644 index 6f44d19..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetPlayerInfoRequest.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.mgm.mcrm.common.dtos.mgm_api; - -import lombok.Data; - -@Data -public class GetPlayerInfoRequest { - - private String playerId; - -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetSimpleLimoBookingQualificationStatusRequest.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetSimpleLimoBookingQualificationStatusRequest.java deleted file mode 100644 index 273966e..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/GetSimpleLimoBookingQualificationStatusRequest.java +++ /dev/null @@ -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; - - -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/InternalCreateLimoBookingRequest.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/InternalCreateLimoBookingRequest.java deleted file mode 100644 index a46d51c..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/InternalCreateLimoBookingRequest.java +++ /dev/null @@ -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; - } -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/InternalUpdateLimoBookingRequest.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/InternalUpdateLimoBookingRequest.java deleted file mode 100644 index 8476b76..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/InternalUpdateLimoBookingRequest.java +++ /dev/null @@ -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; -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/ItemRecord.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/ItemRecord.java deleted file mode 100644 index 8430761..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/ItemRecord.java +++ /dev/null @@ -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; - } - - - -} diff --git a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/NonMGMBookingApiResult.java b/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/NonMGMBookingApiResult.java deleted file mode 100644 index a0688fd..0000000 --- a/src/main/java/com/mgm/mcrm/common/dtos/mgm_api/NonMGMBookingApiResult.java +++ /dev/null @@ -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 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 getRecords() { - return records; - } - public void setRecords(List records) { - this.records = records; - } - - - - - -} diff --git a/src/main/java/com/mgm/mcrm/common/enums/EnumBookingStatus.java b/src/main/java/com/mgm/mcrm/common/enums/EnumBookingStatus.java index 14d16ae..a01d954 100644 --- a/src/main/java/com/mgm/mcrm/common/enums/EnumBookingStatus.java +++ b/src/main/java/com/mgm/mcrm/common/enums/EnumBookingStatus.java @@ -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; diff --git a/src/main/java/com/mgm/mcrm/common/filters/ConfigHeaderFilter.java b/src/main/java/com/mgm/mcrm/common/filters/ConfigHeaderFilter.java index 9f10e6b..4407946 100644 --- a/src/main/java/com/mgm/mcrm/common/filters/ConfigHeaderFilter.java +++ b/src/main/java/com/mgm/mcrm/common/filters/ConfigHeaderFilter.java @@ -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 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"); diff --git a/src/main/java/com/mgm/mcrm/common/httpclient/HttpRequestOptions.java b/src/main/java/com/mgm/mcrm/common/httpclient/HttpRequestOptions.java index 98dcd79..e4318fb 100644 --- a/src/main/java/com/mgm/mcrm/common/httpclient/HttpRequestOptions.java +++ b/src/main/java/com/mgm/mcrm/common/httpclient/HttpRequestOptions.java @@ -55,8 +55,6 @@ public class HttpRequestOptions { */ private HttpContext context; - // private Map map; - /** * 以json格式作为输入参数 */ @@ -83,19 +81,19 @@ public class HttpRequestOptions { private RequestConfig requestConfig; /** - * 解决多线程下载时,strean被close的问题 + * 当前请求的输出流 */ - private static final ThreadLocal outs = new ThreadLocal(); + private OutputStream out; /** - * 解决多线程处理时,url被覆盖问题 + * 当前请求的 URL */ - private static final ThreadLocal urls = new ThreadLocal(); + private String url; /** - * 解决多线程处理时,url被覆盖问题 + * 当前请求的参数,随实例保存,避免线程复用时混入上一次请求的数据 */ - private static final ThreadLocal> maps = new ThreadLocal>(); + private Map 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 map) { -// synchronized (getClass()) { -// if(this.map==null || map==null){ -// this.map = map; -// }else { -// this.map.putAll(map);; -// } -// } - Map 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 map = new HashMap(); - 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(); -// } -// } -// map.put(Utils.ENTITY_MULTIPART, filePaths); -// map.put(Utils.ENTITY_MULTIPART+".name", inputName); -// map.put(Utils.ENTITY_MULTIPART+".rmCharset", forceRemoveContentTypeChraset); - - Map m = maps.get(); - if(m.isEmpty()){ - m = new HashMap(); + 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 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() { diff --git a/src/main/java/com/mgm/mcrm/common/httpclient/HttpSslSupport.java b/src/main/java/com/mgm/mcrm/common/httpclient/HttpSslSupport.java index 6c6277b..7d90437 100644 --- a/src/main/java/com/mgm/mcrm/common/httpclient/HttpSslSupport.java +++ b/src/main/java/com/mgm/mcrm/common/httpclient/HttpSslSupport.java @@ -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} diff --git a/src/main/java/com/mgm/mcrm/common/jms/BookingControlMsgConsumer.java b/src/main/java/com/mgm/mcrm/common/jms/BookingControlMsgConsumer.java index 4713c5d..13fcd7d 100644 --- a/src/main/java/com/mgm/mcrm/common/jms/BookingControlMsgConsumer.java +++ b/src/main/java/com/mgm/mcrm/common/jms/BookingControlMsgConsumer.java @@ -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 diff --git a/src/main/java/com/mgm/mcrm/common/utils/ADFSUtil.java b/src/main/java/com/mgm/mcrm/common/utils/ADFSUtil.java index 8713a4b..3cdcdaa 100644 --- a/src/main/java/com/mgm/mcrm/common/utils/ADFSUtil.java +++ b/src/main/java/com/mgm/mcrm/common/utils/ADFSUtil.java @@ -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 groupNames = decodeData.getClaim("user_group").asList(String.class); + List groupNames = decodeData.getClaim("group_name").asList(String.class); String groupNameVal = ""; for(int i=0;i0?";":"")+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) { diff --git a/src/main/java/com/mgm/mcrm/common/utils/Base64Utils.java b/src/main/java/com/mgm/mcrm/common/utils/Base64Utils.java new file mode 100644 index 0000000..7225aa6 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/common/utils/Base64Utils.java @@ -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; + } + +} diff --git a/src/main/java/com/mgm/mcrm/common/utils/HttpUtil.java b/src/main/java/com/mgm/mcrm/common/utils/HttpUtil.java index cc51bfe..a2929ee 100644 --- a/src/main/java/com/mgm/mcrm/common/utils/HttpUtil.java +++ b/src/main/java/com/mgm/mcrm/common/utils/HttpUtil.java @@ -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 registry = RegistryBuilder.create() - .register("https", new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE )) + .register("https", new SSLConnectionSocketFactory(sslContext, getTrustHandler())) .build(); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); diff --git a/src/main/java/com/mgm/mcrm/common/utils/LogUtil.java b/src/main/java/com/mgm/mcrm/common/utils/LogUtil.java index 4c6147f..17ec6e0 100644 --- a/src/main/java/com/mgm/mcrm/common/utils/LogUtil.java +++ b/src/main/java/com/mgm/mcrm/common/utils/LogUtil.java @@ -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) { diff --git a/src/main/java/com/mgm/mcrm/common/utils/NetworkUtil.java b/src/main/java/com/mgm/mcrm/common/utils/NetworkUtil.java index c434e61..e1990ba 100644 --- a/src/main/java/com/mgm/mcrm/common/utils/NetworkUtil.java +++ b/src/main/java/com/mgm/mcrm/common/utils/NetworkUtil.java @@ -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; diff --git a/src/main/java/com/mgm/mcrm/common/utils/SendEmail.java b/src/main/java/com/mgm/mcrm/common/utils/SendEmail.java deleted file mode 100644 index 1aa4199..0000000 --- a/src/main/java/com/mgm/mcrm/common/utils/SendEmail.java +++ /dev/null @@ -1,1117 +0,0 @@ -package com.mgm.mcrm.common.utils; - -import com.alibaba.fastjson.JSONObject; -import com.mgm.mcrm.booking.models.Bookings; -import com.mgm.mcrm.booking.models.BookingsView; -import com.mgm.mcrm.common.constants.SysCommon; -import com.mgm.mcrm.common.dtos.EumnApprovalStatus; -import com.mgm.mcrm.notification.models.CfgEmailTemplate; -import com.mgm.mcrm.notification.models.Email; -import jakarta.mail.Session; -import jakarta.mail.internet.MimeMessage; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.Strings; -import org.springframework.mail.javamail.JavaMailSenderImpl; -import org.springframework.mail.javamail.MimeMessageHelper; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Properties; - -public class SendEmail { - - - public static int mail_port=25; - public static String mail_smtp_host=""; - public static String mail_sender=""; - public static String mail_sender_password=""; - public static String mail_to=""; - public static String mail_Bcc=""; - - private static String emailTemp = "
Submission Date & Time:{{ttime}}
"+ - "
Submitted User:{{tuser}}
"+ - "

" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " {{tbody}}"+ - " \r\n" + - "
\r\n" + - " Conf#\r\n" + - " \r\n" + - " Booking Status\r\n" + - " \r\n" + - " Member ID\r\n" + - " \r\n" + - " Member Name\r\n" + - " \r\n" + - " Tier\r\n" + - " \r\n" + - " Property\r\n" + - " \r\n" + - " Room Type\r\n" + - " \r\n" + - " Sharer\r\n" + - " \r\n" + - " Original C/I\r\n" + - " \r\n" + - " Original C/O\r\n" + - " \r\n" + - " Extending C/O\r\n" + - "
"; - - private static String emailApprovalTemp = "
Submission Date & Time:{{ttime}}
"+ - "
Submitted and Approver:{{tuser}}
"+ - "

" + - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" +" \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " {{tbody}}"+ - " \r\n" + - "
\r\n" + - " Booking Status\r\n" + - " \r\n" + - " Conf#\r\n" + - " \r\n" + - " Member ID\r\n" + - " \r\n" + - " Member Name\r\n" + - " \r\n" + - " Tier\r\n" + - " \r\n" + - " Property\r\n" + - " \r\n" + - " Room Type\r\n" + - " \r\n" + - " Sharer\r\n" + - " \r\n" + - " Type\r\n" + - " \r\n" + - " Requested C/I\r\n" + - " \r\n" + - " Requested C/O\r\n" + - " \r\n" + - " Approved Property\r\n" + - " \r\n" + - " Approved Room Type\r\n" + - " \r\n" + - " Approved C/I\r\n" + - " \r\n" + - " Approved C/O\r\n" + - " \r\n" + - " Booker Team\r\n" + - " \r\n" + - " Booker ID\r\n" + - " \r\n" + - " Booker Name\r\n" + - " \r\n" + - " Approval Remark\r\n" + - " \r\n" + - " Remark\r\n" + - "
"; - - private static String emailNewApprovalTemp = "
Submission Date & Time:{{ttime}}
"+ - "
Submitted and Approver:{{tuser}}
"+ - "

" + - "{{content}}"+ - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " {{tbody}}"+ - " \r\n" + - "
\r\n" + - " Booking Status\r\n" + - " \r\n" + - " Member ID\r\n" + - " \r\n" + - " Member Name\r\n" + - " \r\n" + - " Tier\r\n" + - " \r\n" + - " Property\r\n" + - " \r\n" + - " Room Type\r\n" + - " \r\n" + - " Sharer\r\n" + - " \r\n" + - " Type\r\n" + - " \r\n" + - " Requested C/I\r\n" + - " \r\n" + - " Requested C/O\r\n" + - " \r\n" + - " Booker Team\r\n" + - " \r\n" + - " Booker ID\r\n" + - " \r\n" + - " Booker Name\r\n" + - " \r\n" + - " Approval Remark\r\n" + - " \r\n" + - " Remark\r\n" + - "
"; - - private static String cancelEmailTemp = "
Submission Date & Time:{{ttime}}
"+ - "
Submitted User:{{tuser}}
"+ - "

" + - "{{content}}"+ - "\r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " \r\n" + - " {{tbody}}"+ - " \r\n" + - "
\r\n" + - " Conf#\r\n" + - " \r\n" + - " Booking Status\r\n" + - " \r\n" + - " Member ID\r\n" + - " \r\n" + - " Member Name\r\n" + - " \r\n" + - " Tier\r\n" + - " \r\n" + - " Property\r\n" + - " \r\n" + - " Room Type\r\n" + - " \r\n" + - " Sharer\r\n" + - " \r\n" + - " Type\r\n" + - " \r\n" + - " Original C/I\r\n" + - " \r\n" + - " Original C/O\r\n" + - " \r\n" + - " Change C/I\r\n" + - " \r\n" + - " Change C/O\r\n" + - "
"; - - - public static Email sendExtendEmail(Bookings book, BookingsView originBook, Email emailObj, String userId, String userName, String emailTo) { - String content1 = emailTemp; - try { - JavaMailSenderImpl sender = new JavaMailSenderImpl(); - if(StringUtils.isEmpty(mail_smtp_host)) { - mail_smtp_host = SysCommon.apiConfig.getHost_SMTP(); - } - mail_port = Integer.valueOf(SysCommon.apiConfig.getPort_SMTP()); - if(StringUtils.isEmpty(mail_sender)) { - mail_sender = SysCommon.apiConfig.getUsername_SMTP(); - } - if(StringUtils.isEmpty(mail_sender_password)) { - mail_sender_password = SysCommon.apiConfig.getPassword_SMTP(); - } - if(!StringUtils.isEmpty(emailTo)) { - mail_to = emailTo; - }else { - mail_to = SysCommon.apiConfig.getSend_to_SMTP(); - } - - sender.setHost(mail_smtp_host); - sender.setPort(mail_port); // 默认就是25 - sender.setUsername(mail_sender); - sender.setPassword(mail_sender_password);// - sender.setDefaultEncoding("UTF-8"); - - // 配置文件对象 - Properties props = new Properties(); - props.put("mail.smtp.auth", "false"); // 是否进行验证 - Session session = Session.getInstance(props); - sender.setSession(session); // 为发送器指定会话 - - MimeMessage mail = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mail, true); - - String subTitle = ""; - helper.setSubject("[Urgent] Extension Request from Mobile CRM APP"+subTitle); // 标题 - helper.setFrom(mail_sender); // 来自 - - SimpleDateFormat sf = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); - SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); - String RequestDate = sf.format(new Date()); - - 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(), "_", " "); - - content2 += ""+ - "" - +book.getConfirmationNo()+ - " "+ - "" - +operaStatus+ - " " + - "" - +book.getPlayerId()+ - " " + - "" - +book.getMemberLastName()+ - " " + - "" - +(originBook.getMemberTier()!=null?originBook.getMemberTier():"")+ - " " + - "" - +(originBook.getPropertyName()!=null?originBook.getPropertyName():"")+ - " " + - "" - +(originBook.getRoom()!=null?originBook.getRoom():"")+ - " "+ - "" - +(originBook.getSharerName()!=null?originBook.getSharerName():"")+ - " "+ - "" - +format.format(originBook.getCheckinDate())+ - " " + - "" - +format.format(originBook.getCheckoutDate())+ - " " + - "" - +format.format(book.getCheckoutDate())+ - " " + - " "; - - content1 = content1.replace("{{tbody}}", content2); - content1 = content1.replace("{{ttime}}", tTime); - content1 = content1.replace("{{tuser}}", tUser); - helper.setText(content1,true); // 邮件内容,第二个参数指定发送的是HTML格式 - JSONObject emailJson = new JSONObject(); - emailJson.put("conf", book.getConfirmationNo()); - emailJson.put("memberId", book.getPlayerId()); - emailJson.put("memberName", book.getMemberLastName()); - emailJson.put("tier", originBook.getMemberTier()); - emailJson.put("property", originBook.getPropertyName()); - emailJson.put("roomType", originBook.getRoom()); - emailJson.put("checkin", format.format(originBook.getCheckinDate())); - emailJson.put("checkout", format.format(originBook.getCheckoutDate())); - emailJson.put("extCheckout", format.format(book.getCheckoutDate())); - - emailObj.setSendObject(emailJson.toJSONString()); - emailObj.setContent(content1); - emailObj.setSendTo(mail_to); - String[] mailToArr = StringUtils.split(mail_to,";"); - if(mailToArr.length>1) { - for (String str : mailToArr) { - helper.setTo(str); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+str+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - } - - } - }else { - helper.setTo(mail_to); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - LogUtil.info(SendEmail.class, "---mgmEmail.sendExtendEmail--OK!"); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+mail_to+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - LogUtil.error(SendEmail.class, "---mgmEmail.sendExtendEmail--Failed!"+e.getMessage()); - } - } - - } catch (Exception e) { - LogUtil.error(SendEmail.class,"---mgmEmail.sendExtenEmail--Exception-->>"+e.getMessage()); - emailObj.setMessage(e.getMessage()); - emailObj.setStatus(0); - } - - return emailObj; - } - - public static Email sendApprovalNewEmail(Bookings book,BookingsView bookView,Email emailObj,String userId,String userName,boolean isOverBook,boolean isConnectRoom,String emailTo) { - String content1 = emailNewApprovalTemp; - try { - JavaMailSenderImpl sender = new JavaMailSenderImpl(); - if(StringUtils.isEmpty(mail_smtp_host)) { - mail_smtp_host = SysCommon.apiConfig.getHost_SMTP(); - } - mail_port = Integer.valueOf(SysCommon.apiConfig.getPort_SMTP()); - if(StringUtils.isEmpty(mail_sender)) { - mail_sender = SysCommon.apiConfig.getUsername_SMTP(); - } - if(StringUtils.isEmpty(mail_sender_password)) { - mail_sender_password = SysCommon.apiConfig.getPassword_SMTP(); - } - if(!StringUtils.isEmpty(emailTo)) { - mail_to = emailTo; - }else { - mail_to = SysCommon.apiConfig.getSend_to_SMTP(); - } - sender.setHost(mail_smtp_host); - sender.setPort(mail_port); // 默认就是25 - sender.setUsername(mail_sender); - sender.setPassword(mail_sender_password);// - sender.setDefaultEncoding("UTF-8"); - - // 配置文件对象 - Properties props = new Properties(); - props.put("mail.smtp.auth", "false"); // 是否进行验证 - Session session = Session.getInstance(props); - sender.setSession(session); // 为发送器指定会话 - - MimeMessage mail = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mail, true); - - String mainTitle; - if(isConnectRoom) { - mainTitle = "[R2/Y2]"; - }else if(isOverBook) { - mainTitle = "[Overbook]"; - }else { - mainTitle = "[Urgent]"; - } - helper.setSubject(mainTitle+"Waitlist Approval from Mobile CRM APP"); // 标题 - helper.setFrom(mail_sender); // 来自 - - SimpleDateFormat sf = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); - SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); - String RequestDate = sf.format(new Date()); - - String content2 = ""; - String tTime = RequestDate; - userId = !StringUtils.isEmpty(userId)?userId:""; - userName = !StringUtils.isEmpty(userName)?userName:""; - String tUser = userId+" "+userName; - String approvalStatus = EumnApprovalStatus.getApprovalStatusByDBValue(book.getApproveStatus()); - - content2 += ""+ - "" - +approvalStatus+ - " "+ - "" - +bookView.getPlayerId()+ - " " + - "" - +bookView.getMemberLastName()+ - " " + - "" - +(bookView.getMemberTier()!=null?bookView.getMemberTier():"")+ - " " + - "" - +(bookView.getPropertyName()!=null?bookView.getPropertyName():"")+ - " " + - "" - +(bookView.getRoom()!=null?bookView.getRoom():"")+ - " "+ - "" - +(bookView.getSharerName()!=null?bookView.getSharerName():"")+ - " " + - "" - +"New"+ - " "+ - "" - +format.format(bookView.getCheckinDate())+ - " " + - "" - +format.format(bookView.getCheckoutDate())+ - " " + - "" - +(bookView.getSectionName()!=null?bookView.getSectionName():"")+ - " " + - "" - +bookView.getCreatedBy()+ - " " + - "" - +bookView.getCreatedByName()+ - " " + - "" - +(bookView.getApprovalRemark()!=null?bookView.getApprovalRemark():"")+ - " " + - "" - +(bookView.getRemark()!=null?bookView.getRemark():"")+ - " " + - " "; - - String mailContent = isConnectRoom?"Please create TT/YY booking for below approved booking

":""; - content1 = content1.replace("{{tbody}}", content2); - content1 = content1.replace("{{ttime}}", tTime); - content1 = content1.replace("{{tuser}}", tUser); - content1 = content1.replace("{{content}}", mailContent); - helper.setText(content1,true); // 邮件内容,第二个参数指定发送的是HTML格式 - JSONObject emailJson = new JSONObject(); - emailJson.put("approvalStatus", approvalStatus); - emailJson.put("memberId", bookView.getPlayerId()); - emailJson.put("memberName", bookView.getMemberLastName()); - emailJson.put("tier", bookView.getMemberTier()); - emailJson.put("property", bookView.getPropertyName()); - emailJson.put("roomType", bookView.getRoom()); - emailJson.put("type", "New"); - emailJson.put("checkin", format.format(bookView.getCheckinDate())); - emailJson.put("checkout", format.format(bookView.getCheckoutDate())); - emailJson.put("bookerTeam", bookView.getBookerTeam()); - emailJson.put("bookerId", bookView.getCreatedBy()); - emailJson.put("bookerName", bookView.getCreatedByName()); - emailJson.put("approvalRemark", bookView.getApprovalRemark()); - emailJson.put("remark", bookView.getRemark()); - - emailObj.setSendObject(emailJson.toJSONString()); - emailObj.setContent(content1); - emailObj.setSendTo(mail_to); - String[] mailToArr = StringUtils.split(mail_to,";"); - if(mailToArr.length>1) { - for (String str : mailToArr) { - helper.setTo(str); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+str+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - } - - } - }else { - helper.setTo(mail_to); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - LogUtil.info(SendEmail.class, "---mgmEmail.sendApprovalNewEmail--OK!"); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+mail_to+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - LogUtil.error(SendEmail.class, "---mgmEmail.sendApprovalNewEmail--Failed!"+e.getMessage()); - } - } - - } catch (Exception e) { - LogUtil.error(SendEmail.class,"---mgmEmail.sendApprovalNewEmail--Exception-->>"+e.getMessage()); - emailObj.setMessage(e.getMessage()); - emailObj.setStatus(0); - } - - return emailObj; - } - - public static Email sendCreateR2Y2NewEmail(Bookings book,BookingsView bookView,Email emailObj,String userId,String userName,boolean isOverBook,boolean isConnectRoom,String emailTo) { - String content1 = emailNewApprovalTemp; - try { - JavaMailSenderImpl sender = new JavaMailSenderImpl(); - if(StringUtils.isEmpty(mail_smtp_host)) { - mail_smtp_host = SysCommon.apiConfig.getHost_SMTP(); - } - mail_port = Integer.valueOf(SysCommon.apiConfig.getPort_SMTP()); - if(StringUtils.isEmpty(mail_sender)) { - mail_sender = SysCommon.apiConfig.getUsername_SMTP(); - } - if(StringUtils.isEmpty(mail_sender_password)) { - mail_sender_password = SysCommon.apiConfig.getPassword_SMTP(); - } - if(!StringUtils.isEmpty(emailTo)) { - mail_to = emailTo; - }else { - mail_to = SysCommon.apiConfig.getSend_to_SMTP(); - } - sender.setHost(mail_smtp_host); - sender.setPort(mail_port); // 默认就是25 - sender.setUsername(mail_sender); - sender.setPassword(mail_sender_password);// - sender.setDefaultEncoding("UTF-8"); - - // 配置文件对象 - Properties props = new Properties(); - props.put("mail.smtp.auth", "false"); // 是否进行验证 - Session session = Session.getInstance(props); - sender.setSession(session); // 为发送器指定会话 - - MimeMessage mail = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mail, true); - - String mainTitle; - if(isConnectRoom) { - mainTitle = "[R2/Y2]"; - }else if(isOverBook) { - mainTitle = "[Overbook]"; - }else { - mainTitle = "[Urgent]"; - } - helper.setSubject(mainTitle+"Booking Creation from Mobile CRM APP"); // 标题 - helper.setFrom(mail_sender); // 来自 - - SimpleDateFormat sf = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); - SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); - String RequestDate = sf.format(new Date()); - - String content2 = ""; - String tTime = RequestDate; - userId = !StringUtils.isEmpty(userId)?userId:""; - userName = !StringUtils.isEmpty(userName)?userName:""; - String tUser = userId+" "+userName; - String approvalStatus = EumnApprovalStatus.getApprovalStatusByDBValue(book.getApproveStatus()); - - - content2 += ""+ - "" - +approvalStatus+ - " "+ - "" - +bookView.getPlayerId()+ - " " + - "" - +bookView.getMemberLastName()+ - " " + - "" - +(bookView.getMemberTier()!=null?bookView.getMemberTier():"")+ - " " + - "" - +(bookView.getPropertyName()!=null?bookView.getPropertyName():"")+ - " " + - "" - +(bookView.getRoom()!=null?bookView.getRoom():"")+ - " "+ - "" - +(bookView.getSharerName()!=null?bookView.getSharerName():"")+ - " " + - "" - +"New"+ - " "+ - "" - +format.format(bookView.getCheckinDate())+ - " " + - "" - +format.format(bookView.getCheckoutDate())+ - " " + - "" - +(bookView.getSectionName()!=null?bookView.getSectionName():"")+ - " " + - "" - +bookView.getCreatedBy()+ - " " + - "" - +bookView.getCreatedByName()+ - " " + - "" - +(bookView.getApprovalRemark()!=null?bookView.getApprovalRemark():"")+ - " " + - "" - +(bookView.getRemark()!=null?bookView.getRemark():"")+ - " " + - " "; - - String mailContent = isConnectRoom?"Please create TT/YY booking for below approved booking

":""; - content1 = content1.replace("{{tbody}}", content2); - content1 = content1.replace("{{ttime}}", tTime); - content1 = content1.replace("{{tuser}}", tUser); - content1 = content1.replace("{{content}}", mailContent); - helper.setText(content1,true); // 邮件内容,第二个参数指定发送的是HTML格式 - JSONObject emailJson = new JSONObject(); - emailJson.put("approvalStatus", approvalStatus); - emailJson.put("memberId", bookView.getPlayerId()); - emailJson.put("memberName", bookView.getMemberLastName()); - emailJson.put("tier", bookView.getMemberTier()); - emailJson.put("property", bookView.getPropertyName()); - emailJson.put("roomType", bookView.getRoom()); - emailJson.put("type", "New"); - emailJson.put("checkin", format.format(bookView.getCheckinDate())); - emailJson.put("checkout", format.format(bookView.getCheckoutDate())); - emailJson.put("bookerTeam", bookView.getBookerTeam()); - emailJson.put("bookerId", bookView.getCreatedBy()); - emailJson.put("bookerName", bookView.getCreatedByName()); - emailJson.put("approvalRemark", bookView.getApprovalRemark()); - emailJson.put("remark", bookView.getRemark()); - - emailObj.setSendObject(emailJson.toJSONString()); - emailObj.setContent(content1); - emailObj.setSendTo(mail_to); - String[] mailToArr = StringUtils.split(mail_to,";"); - if(mailToArr.length>1) { - for (String str : mailToArr) { - helper.setTo(str); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+str+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - } - - } - }else { - helper.setTo(mail_to); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - LogUtil.info(SendEmail.class, "---mgmEmail.sendApprovalNewEmail--OK!"); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+mail_to+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - LogUtil.error(SendEmail.class, "---mgmEmail.sendApprovalNewEmail--Failed!"+e.getMessage()); - } - } - - } catch (Exception e) { - LogUtil.error(SendEmail.class,"---mgmEmail.sendApprovalNewEmail--Exception-->>"+e.getMessage()); - emailObj.setMessage(e.getMessage()); - emailObj.setStatus(0); - } - - return emailObj; - } - - public static Email sendApprovalExtendEmail(Bookings book,BookingsView originBook,Email emailObj,String userId,String userName,BookingsView viewBook,boolean isOverBook,String emailTo) { - String content1 = emailApprovalTemp; - try { - JavaMailSenderImpl sender = new JavaMailSenderImpl(); - if(StringUtils.isEmpty(mail_smtp_host)) { - mail_smtp_host = SysCommon.apiConfig.getHost_SMTP(); - } - mail_port = Integer.valueOf(SysCommon.apiConfig.getPort_SMTP()); - if(StringUtils.isEmpty(mail_sender)) { - mail_sender = SysCommon.apiConfig.getUsername_SMTP(); - } - if(StringUtils.isEmpty(mail_sender_password)) { - mail_sender_password = SysCommon.apiConfig.getPassword_SMTP(); - } - if(!StringUtils.isEmpty(emailTo)) { - mail_to = emailTo; - }else { - mail_to = SysCommon.apiConfig.getSend_to_SMTP(); - } - sender.setHost(mail_smtp_host); - sender.setPort(mail_port); // 默认就是25 - sender.setUsername(mail_sender); - sender.setPassword(mail_sender_password);// - sender.setDefaultEncoding("UTF-8"); - - // 配置文件对象 - Properties props = new Properties(); - props.put("mail.smtp.auth", "true"); // 是否进行验证 - Session session = Session.getInstance(props); - sender.setSession(session); // 为发送器指定会话 - - MimeMessage mail = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mail, true); - - String subTitle = ""; - String mainTitle = isOverBook?"[Overbook]":"[Urgent]"; - helper.setSubject(mainTitle+"Waitlist Approval from Mobile CRM APP"+subTitle); // 标题 - helper.setFrom(mail_sender); // 来自 - - SimpleDateFormat sf = new SimpleDateFormat("dd-MMM-yyyy HH:mm"); - SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); - String RequestDate = sf.format(new Date()); - - String content2 = ""; - String tTime = RequestDate; - userId = !StringUtils.isEmpty(userId)?userId:""; - userName = !StringUtils.isEmpty(userName)?userName:""; - String tUser = userId+" "+userName; - String approvalStatus = EumnApprovalStatus.getApprovalStatusByDBValue(book.getApproveStatus()); - String changeProperty = ""; - String changeRoom = ""; - String changeCheckInDate = ""; - if(!Strings.CS.equals(viewBook.getPropertyName(), originBook.getPropertyName()) || - !Strings.CS.equals(viewBook.getRoom(), originBook.getRoom()) || - viewBook.getCheckinDate().getTime()!=originBook.getCheckoutDate().getTime()) { - changeProperty = viewBook.getPropertyName()!=null?viewBook.getPropertyName():""; - changeRoom = viewBook.getRoom()!=null?viewBook.getRoom():""; - changeCheckInDate = viewBook.getCheckinDate()!=null?format.format(viewBook.getCheckinDate()):""; - } - - - content2 += ""+ - "" - +approvalStatus+ - " "+ - "" - +originBook.getConfirmationNo()+ - " "+ - "" - +originBook.getPlayerId()+ - " " + - "" - +originBook.getMemberLastName()+ - " " + - "" - +(originBook.getMemberTier()!=null?originBook.getMemberTier():"")+ - " " + - "" - +(originBook.getPropertyName()!=null?originBook.getPropertyName():"")+ - " " + - "" - +(originBook.getRoom()!=null?originBook.getRoom():"")+ - " "+ - "" - +(originBook.getSharerName()!=null?originBook.getSharerName():"")+ - " "+ - "" - +"Extend"+ - " "+ - "" - +format.format(originBook.getCheckinDate())+ - " " + - "" - +format.format(originBook.getCheckoutDate())+ - " " + - "" - +changeProperty+ - " " + - "" - +changeRoom+ - " " + - "" - +changeCheckInDate+ - " " + - "" - +format.format(book.getCheckoutDate())+ - " " + - "" - +(viewBook.getSectionName()!=null?viewBook.getSectionName():"")+ - " " + - "" - +originBook.getCreatedBy()+ - " " + - "" - +originBook.getCreatedByName()+ - " " + - "" - +(book.getApprovalRemark()!=null?book.getApprovalRemark():"")+ - " " + - "" - +(book.getRemark()!=null?book.getRemark():"")+ - " " + - " "; - - content1 = content1.replace("{{tbody}}", content2); - content1 = content1.replace("{{ttime}}", tTime); - content1 = content1.replace("{{tuser}}", tUser); - helper.setText(content1,true); // 邮件内容,第二个参数指定发送的是HTML格式 - JSONObject emailJson = new JSONObject(); - emailJson.put("approvalStatus", approvalStatus); - emailJson.put("conf", book.getConfirmationNo()); - emailJson.put("memberId", book.getPlayerId()); - emailJson.put("memberName", book.getMemberLastName()); - emailJson.put("tier", originBook.getMemberTier()); - emailJson.put("property", originBook.getPropertyName()); - emailJson.put("roomType", originBook.getRoom()); - emailJson.put("type", "Extend"); - emailJson.put("checkin", format.format(originBook.getCheckinDate())); - emailJson.put("checkout", format.format(originBook.getCheckoutDate())); - emailJson.put("changeProperty", changeProperty); - emailJson.put("changeRoom", changeRoom); - emailJson.put("changeCheckin", changeCheckInDate); - emailJson.put("changeCheckout", format.format(book.getCheckoutDate())); - emailJson.put("bookerTeam", viewBook.getBookerTeam()); - emailJson.put("bookerId", originBook.getCreatedBy()); - emailJson.put("bookerName", originBook.getCreatedByName()); - emailJson.put("approvalRemark", book.getApprovalRemark()); - emailJson.put("remark", book.getRemark()); - - emailObj.setSendObject(emailJson.toJSONString()); - emailObj.setContent(content1); - emailObj.setSendTo(mail_to); - String[] mailToArr = StringUtils.split(mail_to,";"); - if(mailToArr.length>1) { - for (String str : mailToArr) { - helper.setTo(str); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+str+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - } - - } - }else { - helper.setTo(mail_to); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - LogUtil.info(SendEmail.class, "---mgmEmail.sendApprovalExtendEmail--OK!"); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+mail_to+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - LogUtil.error(SendEmail.class, "---mgmEmail.sendApprovalExtendEmail--Failed!"+e.getMessage()); - } - } - - } catch (Exception e) { - LogUtil.error(SendEmail.class,"---mgmEmail.sendApprovalExtendEmail--Exception-->>"+e.getMessage()); - emailObj.setMessage(e.getMessage()); - emailObj.setStatus(0); - } - - return emailObj; - } - - public static Email sendCancelEmail(Bookings book,BookingsView bookingsView,Email emailObj,String userId,String userName,String emailTo) { - String content1 = cancelEmailTemp; - try { - JavaMailSenderImpl sender = new JavaMailSenderImpl(); - if(StringUtils.isEmpty(mail_smtp_host)) { - mail_smtp_host = SysCommon.apiConfig.getHost_SMTP(); - } - mail_port = Integer.valueOf(SysCommon.apiConfig.getPort_SMTP()); - if(StringUtils.isEmpty(mail_sender)) { - mail_sender = SysCommon.apiConfig.getUsername_SMTP(); - } - if(StringUtils.isEmpty(mail_sender_password)) { - mail_sender_password = SysCommon.apiConfig.getPassword_SMTP(); - } - if(!StringUtils.isEmpty(emailTo)) { - mail_to = emailTo; - }else { - mail_to = SysCommon.apiConfig.getSend_to_SMTP(); - } - - sender.setHost(mail_smtp_host); - sender.setPort(mail_port); // 默认就是25 - sender.setUsername(mail_sender); - sender.setPassword(mail_sender_password);// - sender.setDefaultEncoding("UTF-8"); - - // 配置文件对象 - Properties props = new Properties(); - props.put("mail.smtp.auth", "false"); // 是否进行验证 - Session session = Session.getInstance(props); - sender.setSession(session); // 为发送器指定会话 - - MimeMessage mail = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mail, true); - - String subTitle = ""; - - helper.setSubject("[Urgent] Modify Request from Mobile CRM APP"+subTitle); // 标题 - helper.setFrom(mail_sender); // 来自 - - SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); - String RequestDate = sf.format(new Date()); - - String tTime = RequestDate; - userId = !StringUtils.isEmpty(userId)?userId:""; - userName = !StringUtils.isEmpty(userName)?userName:""; - String tUser = userId+" "+userName; - String content2 = ""; - userId = !StringUtils.isEmpty(userId)?userId:""; - userName = !StringUtils.isEmpty(userName)?userName:""; - String approvalStatus = EumnApprovalStatus.getApprovalStatusByDBValue(book.getApproveStatus()); - - content2 += ""+ - "" - +bookingsView.getConfirmationNo()+ - " "+ - "" - +approvalStatus+ - " "+ - "" - +bookingsView.getPlayerId()+ - " " + - "" - +bookingsView.getMemberLastName()+ - " " + - "" - +(bookingsView.getTier()!=null?bookingsView.getTier():"")+ - " " + - "" - +(bookingsView.getPropertyName()!=null?bookingsView.getPropertyName():"")+ - " " + - "" - +(bookingsView.getRoom()!=null?bookingsView.getRoom():"")+ - " "+ - "" - +(bookingsView.getSharerName()!=null?bookingsView.getSharerName():"")+ - " "+ - "" - +"Cancel"+ - " "+ - "" - +format.format(bookingsView.getCheckinDate())+ - " " + - "" - +format.format(bookingsView.getCheckoutDate())+ - " " + - "" - +book.getChangeCheckinDate()+ - " " + - "" - +book.getChangeCheckoutDate()+ - " "; - - - String content = "Please cancel Conf#"+book.getConfirmationNo()+" under "+book.getMemberLastName(); - - content1 = content1.replace("{{tbody}}", content2); - content1 = content1.replace("{{ttime}}", tTime); - content1 = content1.replace("{{tuser}}", tUser); - content1 = content1.replace("{{content}}", content); - helper.setText(content1,true); // 邮件内容,第二个参数指定发送的是HTML格式 - JSONObject emailJson = new JSONObject(); - emailJson.put("conf", book.getConfirmationNo()); - emailJson.put("memberId", book.getPlayerId()); - emailJson.put("memberName", book.getMemberLastName()); - - emailObj.setSendObject(emailJson.toJSONString()); - emailObj.setContent(content1); - emailObj.setSendTo(mail_to); - String[] mailToArr = StringUtils.split(mail_to,";"); - if(mailToArr.length>1) { - for (String str : mailToArr) { - helper.setTo(str); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+str+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - } - - } - }else { - helper.setTo(mail_to); - try { - sender.send(mail); // 发送 - emailObj.setStatus(1); - LogUtil.info(SendEmail.class, "---mgmEmail.sendCancelEmail--OK!"); - } catch (Exception e) { - emailObj.setMessage("Send Email to "+mail_to+" Failed:"+e.getMessage()); - emailObj.setStatus(0); - LogUtil.error(SendEmail.class, "---mgmEmail.sendCancelEmail--Failed!"+e.getMessage()); - } - } - - } catch (Exception e) { - LogUtil.error(SendEmail.class,"---mgmEmail.sendCancelEmail--Exception-->>"+e.getMessage()); - emailObj.setMessage(e.getMessage()); - emailObj.setStatus(0); - } - - return emailObj; - } - - public static boolean sendOtherBookingEmail(CfgEmailTemplate emailTemplate) { - Boolean status = false; - try { - JavaMailSenderImpl sender = new JavaMailSenderImpl(); - if(StringUtils.isEmpty(mail_smtp_host)) { - mail_smtp_host = SysCommon.apiConfig.getHost_SMTP(); - } - mail_port = Integer.valueOf(SysCommon.apiConfig.getPort_SMTP()); -// if(StringUtils.isEmpty(mail_sender)) { -// mail_sender = SysCommon.apiConfig.getUsername_SMTP(); -// } - if(StringUtils.isEmpty(mail_sender_password)) { - mail_sender_password = SysCommon.apiConfig.getPassword_SMTP(); - } - mail_to = SysCommon.apiConfig.getSend_to_SMTP(); - mail_sender = emailTemplate.getSender(); - sender.setHost(mail_smtp_host); - sender.setPort(mail_port); // 默认就是25 - sender.setUsername(mail_sender); - sender.setPassword(mail_sender_password);// - sender.setDefaultEncoding("UTF-8"); - - // 配置文件对象 - Properties props = new Properties(); - props.put("mail.smtp.auth", "false"); // 是否进行验证 - Session session = Session.getInstance(props); - sender.setSession(session); // 为发送器指定会话 - - MimeMessage mail = sender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mail, true); - - String subject = emailTemplate.getSubject(); - subject = Strings.CI.replace(subject, "[TODAY]", DateTimeUtil.getCurrentDate("dd MMM")); - helper.setSubject(subject); // 标题 - helper.setFrom(mail_sender); // 来自 - - helper.setCc(StringUtils.split(emailTemplate.getCc(),";")); - helper.setText(emailTemplate.getShowTemp(),true); // 邮件内容,第二个参数指定发送的是HTML格式 - String[] mailToArr = StringUtils.split(emailTemplate.getTo(),";"); - helper.setTo(mailToArr); - try { - sender.send(mail); // 发送 - LogUtil.info(SendEmail.class, "---mgmEmail.sendOtherBookingEmail--OK!"); - status=true; - } catch (Exception e) { - LogUtil.error(SendEmail.class, "send email failed:" + e.getMessage()); - status=false; - } - } catch (Exception e) { - LogUtil.error(SendEmail.class,"---mgmEmail.sendOtherBookingEmail--Exception-->>"+e.getMessage()); - status=false; - } - - return status; - } -} diff --git a/src/main/java/com/mgm/mcrm/limo/services/LimoService.java b/src/main/java/com/mgm/mcrm/limo/services/LimoService.java index a416f08..7a7bb2e 100644 --- a/src/main/java/com/mgm/mcrm/limo/services/LimoService.java +++ b/src/main/java/com/mgm/mcrm/limo/services/LimoService.java @@ -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(), "")); diff --git a/src/main/java/com/mgm/mcrm/logging/models/SysBookingCacheLog.java b/src/main/java/com/mgm/mcrm/logging/models/SysBookingCacheLog.java new file mode 100644 index 0000000..d97acb0 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/logging/models/SysBookingCacheLog.java @@ -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; +} diff --git a/src/main/java/com/mgm/mcrm/logging/models/SysBookingProfileMapping.java b/src/main/java/com/mgm/mcrm/logging/models/SysBookingProfileMapping.java new file mode 100644 index 0000000..1188880 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/logging/models/SysBookingProfileMapping.java @@ -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; +} diff --git a/src/main/java/com/mgm/mcrm/logging/repositories/SysBookingCacheLogDao.java b/src/main/java/com/mgm/mcrm/logging/repositories/SysBookingCacheLogDao.java new file mode 100644 index 0000000..a0f2922 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/logging/repositories/SysBookingCacheLogDao.java @@ -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 { + List findAllByCategoryAndCacheKey(String category, String cacheKey); +} diff --git a/src/main/java/com/mgm/mcrm/logging/repositories/SysBookingProfileMappingDao.java b/src/main/java/com/mgm/mcrm/logging/repositories/SysBookingProfileMappingDao.java new file mode 100644 index 0000000..c97bbd0 --- /dev/null +++ b/src/main/java/com/mgm/mcrm/logging/repositories/SysBookingProfileMappingDao.java @@ -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 { + List findAllByCategoryAndPlayerId(String category, String playerId); +} diff --git a/src/main/java/com/mgm/mcrm/logging/services/SysBookingCacheService.java b/src/main/java/com/mgm/mcrm/logging/services/SysBookingCacheService.java new file mode 100644 index 0000000..13ab95c --- /dev/null +++ b/src/main/java/com/mgm/mcrm/logging/services/SysBookingCacheService.java @@ -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 cacheLogs = sysBookingCacheLogDao.findAllByCategoryAndCacheKey("DAYLIGHT",playerId); + if(!cacheLogs.isEmpty()){ + SysBookingCacheLog cacheLog = cacheLogs.getFirst(); + for(int i=1;i cacheLogs = sysBookingCacheLogDao.findAllByCategoryAndCacheKey("DAYLIGHT",playerId); + SysBookingCacheLog cacheLog = null; + if(!cacheLogs.isEmpty()){ + cacheLog = cacheLogs.getFirst(); + for(int i=1;i profileMappings = sysBookingProfileMappingDao.findAllByCategoryAndPlayerId("DAYLIGHT",playerId); + if(!profileMappings.isEmpty()){ + SysBookingProfileMapping profileMapping = profileMappings.getFirst(); + for(int i=1;i profileMappings = sysBookingProfileMappingDao.findAllByCategoryAndPlayerId("DAYLIGHT",playerId); + SysBookingProfileMapping profileMapping = null; + if(!profileMappings.isEmpty()){ + profileMapping = profileMappings.getFirst(); + for(int i=1;iNo"); for( String field : fieledList) { - thread+=""+field+""; + thread.append("").append(field).append(""); } - String tbody = ""; + StringBuilder tbody = new StringBuilder(); int index = 1; for(BookingsView bo:typeList) { - tbody+=""+index+""; + tbody.append("").append(index).append(""); index++; bookIdList.add(String.valueOf(bo.getId())); for( String field : fieledList) { String getFiled = getNewFiled(field, bo); - tbody+=""+getFiled+""; + tbody.append("").append(getFiled).append(""); } - tbody+=""; + tbody.append(""); } - 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())+"
"; + content.append(getExtendFiled(bo, template.getContent())).append("
"); } } 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"; diff --git a/src/main/java/com/mgm/mcrm/notification/services/SendEmailService.java b/src/main/java/com/mgm/mcrm/notification/services/SendEmailService.java index f8dcba4..857cd78 100644 --- a/src/main/java/com/mgm/mcrm/notification/services/SendEmailService.java +++ b/src/main/java/com/mgm/mcrm/notification/services/SendEmailService.java @@ -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 = "
Submission Date & Time:{{ttime}}
"+ "
Submitted User:{{tuser}}
"+ + "
Approver:{{tapprover}}
"+ "

" + "\r\n" + " \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 userInfoByUserId = mgmUserService.findUserInfoByUserId(userId); + userName = userInfoByUserId.isSuccess() ? userInfoByUserId.getData().getUserName() : ""; + } + + if (StringUtils.isBlank(book.getApprovedBy())) { + BaseApiResponse 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 += ""+ "
" @@ -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(); diff --git a/src/main/java/com/mgm/mcrm/player/services/PlayerService.java b/src/main/java/com/mgm/mcrm/player/services/PlayerService.java index 402a0ab..cd562b8 100644 --- a/src/main/java/com/mgm/mcrm/player/services/PlayerService.java +++ b/src/main/java/com/mgm/mcrm/player/services/PlayerService.java @@ -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 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) { diff --git a/src/main/java/com/mgm/mcrm/player/services/TodoService.java b/src/main/java/com/mgm/mcrm/player/services/TodoService.java index 5687783..6f8e9a8 100644 --- a/src/main/java/com/mgm/mcrm/player/services/TodoService.java +++ b/src/main/java/com/mgm/mcrm/player/services/TodoService.java @@ -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); } diff --git a/src/main/java/com/mgm/mcrm/roomcalendar/services/RoomCalendarService.java b/src/main/java/com/mgm/mcrm/roomcalendar/services/RoomCalendarService.java index 453545a..c7c215f 100644 --- a/src/main/java/com/mgm/mcrm/roomcalendar/services/RoomCalendarService.java +++ b/src/main/java/com/mgm/mcrm/roomcalendar/services/RoomCalendarService.java @@ -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); } } diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 95b2e1d..90eeef0 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -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: