diff --git a/src/main/java/itn/let/kakao/user/kakaoAt/service/KakaoAlimTalkService.java b/src/main/java/itn/let/kakao/user/kakaoAt/service/KakaoAlimTalkService.java index 9f17fec3..e218fd49 100644 --- a/src/main/java/itn/let/kakao/user/kakaoAt/service/KakaoAlimTalkService.java +++ b/src/main/java/itn/let/kakao/user/kakaoAt/service/KakaoAlimTalkService.java @@ -34,4 +34,8 @@ public interface KakaoAlimTalkService { //카카오(알림톡, 친구톡 통합) 전송 실패 환불리스트 조회 public void selectKakaoSentRefundList() throws Exception; + //카카오(알림톡, 친구톡 통합) 전송 실패 환불리스트 조회 + public List selectKakaoSentRefundListForSingle() throws Exception; + + public void kakaoSingleRefund(KakaoVO kakaoVO) throws Exception; } diff --git a/src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java b/src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java index 509acc30..58f312c4 100644 --- a/src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java +++ b/src/main/java/itn/let/kakao/user/kakaoAt/service/impl/KakaoAlimTalkServiceImpl.java @@ -1,7 +1,6 @@ package itn.let.kakao.user.kakaoAt.service.impl; import java.math.BigDecimal; -import java.math.RoundingMode; import java.text.SimpleDateFormat; import java.time.Duration; import java.time.Instant; @@ -11,8 +10,6 @@ import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; -import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Resource; @@ -22,12 +19,13 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl; import egovframework.rte.fdl.idgnr.EgovIdGnrService; import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper; import itn.com.cmm.LoginVO; -import itn.com.cmm.MjonMsgSendVO; import itn.com.utl.fcc.service.EgovStringUtil; import itn.let.kakao.kakaoComm.BizKakaoPriceVO; import itn.let.kakao.kakaoComm.KakaoSendAdvcVO; @@ -51,7 +49,6 @@ import itn.let.module.base.PriceAndPoint; import itn.let.sym.site.service.JoinSettingVO; import itn.let.sym.site.service.impl.SiteManagerDAO; import itn.let.uss.umt.service.EgovUserManageService; -import itn.let.uss.umt.service.UserManageVO; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -946,7 +943,7 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements private void handleRefund(KakaoVO vo, String msg) throws Exception { // mj_cash 테이블에 환불 내역 추가 및 회원 금액 업데이트 // eachPrice는 환불될 금액이므로 양수여야 합니다. - priceAndPoint.insertCashAndPoint( + priceAndPoint.insertCashAndPointNoUpdate( vo.getUserId(), Float.parseFloat(vo.getEachPrice()), // 환불 금액은 양수 msg, @@ -1126,8 +1123,33 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements return statusResponse; } - + @Override + public List selectKakaoSentRefundListForSingle() throws Exception{ + return kakaoAlimTalkDAO.selectKakaoSentRefundList(); + } + @Override + public void kakaoSingleRefund(KakaoVO kakaoVO) throws Exception { + + System.out.println(kakaoVO.getMsgGroupId() +"________결과 : " +kakaoVO.getRsltCode() +" 대체문자 전송 : "+kakaoVO.getSubMsgSendYn()); + kakaoVO.setMsgTypeTxt(AT_MSG_TYPE.equals(kakaoVO.getMsgType()) ? "알림톡" : "친구톡"); + + if(KAKAO_SUCCESS_CODE.equals(kakaoVO.getRsltCode())) { + //1.카카오톡 발송 성공 + processKakaoSendCharge(kakaoVO); + + }else if(RESEND_YN_YES.equals(kakaoVO.getSubMsgSendYn())) {//카카오톡 발송 실패, 대체문자 발송 신청 O + //2.카카오톡 발송 실패 + 대체문자 신청 O + handleAlternativeMessageScenario(kakaoVO); + + }else { + //3.카카오톡 발송 실패 + 대체문자 신청 X : 전액 환불 + handleRefund(kakaoVO, "카카오 " + kakaoVO.getMsgTypeTxt() + " 전송 실패로 인한 결제 금액 환불"); + } + + //모든 유형 환불 완료 처리 + mjonMsgDAO.updateRefundY(kakaoVO); + } // // 보유 금액이 충분한지 확인하는 메서드 // private boolean isCashSufficient(String userId, List kakaoSendAdvcListVO) throws Exception { @@ -1151,33 +1173,4 @@ public class KakaoAlimTalkServiceImpl extends EgovAbstractServiceImpl implements // } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - } diff --git a/src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java b/src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java index ed102a73..49607b2d 100644 --- a/src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java +++ b/src/main/java/itn/let/kakao/user/kakaoAt/web/KakaoAlimTalkSendController.java @@ -9,9 +9,11 @@ import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import javax.annotation.Resource; @@ -61,7 +63,6 @@ import itn.com.cmm.util.MJUtil; import itn.com.cmm.util.StringUtil; import itn.com.utl.fcc.service.EgovStringUtil; import itn.let.kakao.kakaoComm.KakaoReturnVO; -import itn.let.kakao.kakaoComm.KakaoSendAdvcVO; import itn.let.kakao.kakaoComm.KakaoSendUtil; import itn.let.kakao.kakaoComm.KakaoVO; import itn.let.kakao.kakaoComm.kakaoApi.KakaoApiJsonSave; @@ -79,6 +80,9 @@ import itn.let.mjo.msgdata.service.MjonMsgReturnVO; import itn.let.mjo.msgholiday.service.MsgAlarmSetVO; import itn.let.mjo.msgholiday.service.MsgHolidayService; import itn.let.mjo.msgholiday.service.MsgHolidayVO; +import itn.let.mjo.pay.service.MjonPayService; +import itn.let.mjo.pay.service.MjonPayVO; +import itn.let.org.web.OrgChartManageController; import itn.let.sym.site.service.EgovSiteManagerService; import itn.let.sym.site.service.JoinSettingVO; import itn.let.uss.umt.service.EgovUserManageService; @@ -102,6 +106,8 @@ import itn.let.uss.umt.service.UserManageVO; @Controller public class KakaoAlimTalkSendController { + private final OrgChartManageController orgChartManageController; + @Resource(name = "egovMjonMsgGroupIdGnrService") private EgovIdGnrService idgenMjonMsgGroupId; @@ -149,6 +155,13 @@ public class KakaoAlimTalkSendController { @Autowired private MjonCommon mjonCommon; + + @Resource(name = "mjonPayService") + private MjonPayService mjonPayService; + + KakaoAlimTalkSendController(OrgChartManageController orgChartManageController) { + this.orgChartManageController = orgChartManageController; + } @RequestMapping(value= {"/web/mjon/alimtalk/kakaoAlimtalkMsgDataView.do"}) public String KakaoAlimtalkMsgDataView(ModelMap model @@ -1541,6 +1554,25 @@ public class KakaoAlimTalkSendController { return "web/kakao/msgdata/at/KakaoAlimtalkMsgDataView_tmp"; } + public void kakaoRefundSingleTransaction() throws Exception{ + System.out.println("=============카카오 환불 싱글 트랜잭션 수행 ============="); + + List kakaoRefundList = kakaoAlimTalkService.selectKakaoSentRefundListForSingle(); + Set targetIdSet = new HashSet<>(); + + for(KakaoVO kakaoVO : kakaoRefundList) { + kakaoAlimTalkService.kakaoSingleRefund(kakaoVO); + targetIdSet.add(kakaoVO.getUserId()); + } + + MjonPayVO mjonPayVO = new MjonPayVO(); + for(String userId : targetIdSet) { + mjonPayVO.setUserId(userId); + mjonPayService.updateMemberCash(mjonPayVO); //회원정보 업데이트 + } + + } + /** * @Method Name : kakaoMsgSendRefundTestAjax * @작성일 : 2025. 8. 6. @@ -1555,7 +1587,7 @@ public class KakaoAlimTalkSendController { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("jsonView"); - kakaoAlimTalkService.selectKakaoSentRefundList(); + this.kakaoRefundSingleTransaction(); modelAndView.addObject("result", "success"); return modelAndView; diff --git a/src/main/java/itn/let/module/base/PriceAndPoint.java b/src/main/java/itn/let/module/base/PriceAndPoint.java index f640732f..4d9f0943 100644 --- a/src/main/java/itn/let/module/base/PriceAndPoint.java +++ b/src/main/java/itn/let/module/base/PriceAndPoint.java @@ -213,6 +213,36 @@ public class PriceAndPoint { kakaoAlimTalkDAO.insertKakaoSendPrice(kakaoVO); } - + + /** + * @methodName : insertCashAndPoint + * @author : 이지우 + * @date : 2025. 8. 14. + * @description : insertCashAndPoint 에서 updateMemberCash 제외 + * @return : void + * @param userId + * @param totPrice + * @param memo + * @param msgGroupId + * @param userData + * @throws Exception + * + */ + public void insertCashAndPointNoUpdate( + String userId + , float totPrice + , String memo + , String msgGroupId + , String userData + ) throws Exception { + + MjonPayVO mjonPayVO = buildPayVO(userId, totPrice, memo, msgGroupId); + +// 환불로 인해 userData가 추후 사용될 경우 여기에 처리 + if (StringUtils.isNotEmpty(userData)) { mjonPayVO.setOrderId(userData); } + + mjonPayDAO.insertCash(mjonPayVO); //캐시 + + } } \ No newline at end of file diff --git a/src/main/java/itn/let/schdlr/service/SchedulerUtil.java b/src/main/java/itn/let/schdlr/service/SchedulerUtil.java index c05da466..9f41537f 100644 --- a/src/main/java/itn/let/schdlr/service/SchedulerUtil.java +++ b/src/main/java/itn/let/schdlr/service/SchedulerUtil.java @@ -1,12 +1,16 @@ package itn.let.schdlr.service; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.annotation.Resource; import javax.sql.DataSource; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Profile; @@ -24,12 +28,15 @@ import itn.let.fax.admin.service.FaxAdmService; import itn.let.fax.admin.service.FaxStatVO; import itn.let.kakao.admin.kakaoAt.service.MjonKakaoAtStatVO; import itn.let.kakao.admin.statistics.service.KakaoStatisticsService; +import itn.let.kakao.kakaoComm.KakaoVO; +import itn.let.kakao.user.kakaoAt.service.KakaoAlimTalkService; import itn.let.lett.service.LetterService; import itn.let.mail.service.MailTemplateService; import itn.let.mjo.msg.service.MjonMsgService; import itn.let.mjo.msg.service.MjonMsgStatVO; -import itn.let.mjo.msg.service.MjonMsgVO; import itn.let.mjo.msgdata.service.impl.MjonMsgDataDAO; +import itn.let.mjo.pay.service.MjonPayVO; +import itn.let.mjo.pay.service.impl.MjonPayDAO; import itn.let.sts.com.StatsVO; import itn.let.sts.cst.service.EgovConectStatsService; import itn.let.uss.umt.service.EgovUserManageService; @@ -82,6 +89,12 @@ public class SchedulerUtil { @Resource(name="MjonMsgDataDAO") private MjonMsgDataDAO mjonMsgDataDAO; + @Resource(name="KakaoAlimTalkService") + private KakaoAlimTalkService kakaoAlimTalkService; + + @Autowired + private MjonPayDAO mjonPayDAO; + /** 설정값 가져오기 */ @Value("#{globalSettings['Globals.Env']}") private String GlobalsEnv; @@ -466,20 +479,26 @@ public class SchedulerUtil { return new JdbcTemplateLockProvider(dataSource); } - /** @Scheduled(cron = "0 0/3 * * * ?") // 3분마다 실행 @SchedulerLock(name = "runKakaoOneTime", lockAtMostForString = ONE_MIN, lockAtLeastForString = ONE_MIN) public void runKakaoOneTime() throws Exception { - // do something... - try { System.out.println("=============SchedulerUtil=====runKakaoOneTime =============>"); - schdlrManageService.kakaoFailPayBack(); - }catch(Exception ex) { - ex.printStackTrace(); - } + List kakaoRefundList = kakaoAlimTalkService.selectKakaoSentRefundListForSingle(); + Set targetIdSet = new HashSet<>(); + + for(KakaoVO kakaoVO : kakaoRefundList) { + kakaoAlimTalkService.kakaoSingleRefund(kakaoVO); + targetIdSet.add(kakaoVO.getUserId()); + } + + MjonPayVO mjonPayVO = new MjonPayVO(); + for(String userId : targetIdSet) { + mjonPayVO.setUserId(userId); + mjonPayDAO.updateMemberCash(mjonPayVO); //회원정보 업데이트 + } + } - */ //환불 실행 private void PayBack(String p_type) throws Exception { diff --git a/src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml b/src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml index 7aa178ef..fcc059e7 100644 --- a/src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml +++ b/src/main/resources/egovframework/sqlmap/let/mjo/kakao/Kakao_AT_SQL_Mysql.xml @@ -235,6 +235,7 @@ AND MMD.REFUND_YN = 'N' AND MMD.RESERVE_C_YN = 'N' AND MMD.MSG_TYPE IN(8, 9) + ORDER BY MMD.USER_ID ASC