초기소스

This commit is contained in:
jazz
2025-10-29 17:08:05 +09:00
parent e531aa9540
commit 439a379a02
7551 changed files with 1234427 additions and 3 deletions

View File

@@ -0,0 +1,77 @@
package com.wb.domainserver.domain.gcone.pos.easywell;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Getter
public enum EasyWellErrCode {
EXPIRED_PAYMENT_CODE("1001","바코드 유효시간이 초과 되었습니다", "만료된 결제코드"),
PAYMENT_CODE_DOES_NOT_EXIST("1002", "유효하지 않는 바코드입니다", "존재하지 않는 결제코드"),
PAYMENT_PASSWORD_MISMATCH("1003", "결제비밀번호가 일치하지 않습니다", "결제비밀번호 불일치"),
PAYMENT_CODE_USER_INFO_MISMATCH("1004", "유효하지 않는 바코드입니다", "결제코드의 사용자 정보 불일치"),
DEVICE_ID_MISMATCH("1005","등록되지 않은 기기 입니다.", "디바이스 아이디 불일치"),
CUSTOMERS_DO_NOT_USE_DIRECT_PAY("1006","일시적인 오류가 발생했습니다.", "직결제 미사용 고객사"),
PAY_CD_USED("1007","유효하지 않는 바코드입니다","사용된 결제코드"),
AFFILIATE_INFO_MISMATCH_IN_PAY_CD("1008","이용할 수 없는 제휴사 바코드 형식입니다.","결제코드의 제휴사 정보 불일치"),
INSUFFICIENT_PAY_AMT("2001","복지포인트가 부족하여 이용할 수 없습니다","결제가능금액 부족"),
ORIGIN_ORDR_APPRV_NUM_INFO_DO_NOT_EXIST("2002","일시적인 오류가 발생했습니다.","원주문 승인번호 내역 미존재"),
ORIGIN_ORDR_AFFILIATE_INFO_MISMATCH("2003","일시적인 오류가 발생했습니다.","원주문 제휴사 정보 불일치"),
ORIGIN_ORDR_NUM_MISMATCH("2004","일시적인 오류가 발생했습니다.","원주문번호 불일치"),
CANCEL_AMT_AND_PAY_AMT_DO_NOT_MATCH("2005","일시적인 오류가 발생했습니다.","취소금액과 결제금액 불일치"),
ORIGIN_ORDR_INFO_DOES_NOT_EXIST("2006","일시적인 오류가 발생했습니다.","원주문정보 미존재"),
CANCEL_CASE("2007","이미 취소된 결제내역 입니다","기취소건"),
ORIGIN_ORDR_PAY_CD_MISMATCH("2010","원주문 바코드가 일치하지 않습니다","원주문 결제코드 불일치"),
ORIGIN_ORDR_USER_INFO_MISMATCH("2011","일시적인 오류가 발생했습니다.","원주문 사용자 정보 불일치"),
UNABLE_STORES("2012","이용할 수 없는 가맹점입니다","이용할 수 없는 가맹점"),
NOT_EXIST_PARTNER("2013","일시적인 오류가 발생했습니다.","존재하지 않는 파트너"),
NOT_EXIST_AFFILIATE("2017","일시적인 오류가 발생했습니다.","존재하지 않는 제휴사"),
TEST_USER_PAY_NOT_POSSIBLE("2094","테스트 사용자는 결제 할 수 없습니다","테스트사용자 결제불가"),
UNABLE_BEFORE_SYSTEM_OPENING("2095","제도기간이 아니므로 이용할 수 없습니다","제도오픈전 이용불가"),
UNABLE_AFTER_SYSTEM_CLOSE("2096","제도기간이 아니므로 이용할 수 없습니다","제도마감후 이용불가"),
CHK_ABLE_POINTS_ERR("2097","일시적인 오류가 발생했습니다.","사용가능포인트 조회중 오류발생"),
PROC_PAY_CANCEL_ERR("2098","일시적인 오류가 발생했습니다.","결제취소 처리중 오류발생"),
DURING_PAY_PROC("2099","일시적인 오류가 발생했습니다.","결제처리중 오류발생"),
CUSTOMERS_CANNOT_USE_EASYWELLPAY("4006","일시적인 오류가 발생했습니다.","이지웰페이 이용불가 고객사"),
NO_PAY_PWD("4007","일시적인 오류가 발생했습니다.","결제비밀번호 없음"),
NOT_EXIST_MERCHANT_ID("9002","일시적인 오류가 발생했습니다.","존재하지 않는 가맹점 ID"),
AFFILIATE_COMMUNICATION_FAILURE("9992","제휴사와 통신이 원활하지 않습니다. 잠시 후 다시 시도해 주세요.","제휴사 통신 장애"),
NO_CUSTOMER_INFO("9994","일시적인 오류가 발생했습니다.","고객사 정보 없음"),
PARTNER_REGIST_INFO_ERR("9995","일시적인 오류가 발생했습니다.","파트너 등록정보 오류"),
INCORRECT_PARAM("9997","일시적인 오류가 발생했습니다.","부정확한 파라메터"),
NO_REQUIRED_PARAM("9998","일시적인 오류가 발생했습니다.","필수 파라메터 없음"),
ERR_DURING_PROC("9999","일시적인 오류가 발생했습니다.","처리중 에러"),
SERVER_RESPONSE_EMPTY("9990", "일시적인 오류가 발생했습니다.", "이지웰서버 데이터 수신 불가")//이지웰측 에러정의 코드 아닌 내부 커스텀 에러
;
private final String errCode;
private final String errMsg;
private final String errInfo;
EasyWellErrCode(final String errCode, final String errMsg, final String errInfo) {
this.errCode = errCode;
this.errMsg = errMsg;
this.errInfo = errInfo;
}
private static final Map<String, EasyWellErrCode> SELECT_ERR_CODE =
Stream.of(values()).collect(Collectors.toMap(EasyWellErrCode::getErrCode, e -> e));
public static EasyWellErrCode valueOfErrCode(String errCode) {
if(SELECT_ERR_CODE.containsKey(errCode)) {
return SELECT_ERR_CODE.get(errCode);
}else{
return SELECT_ERR_CODE.get("9999");
}
}
}

View File

@@ -0,0 +1,21 @@
package com.wb.domainserver.domain.gcone.pos.easywell.mapper;
import com.wb.domainserver.util.dataaccess.DataMap;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.Map;
@Mapper
@Repository
public interface EasyWellMapper {
/*이지웰로그 저장*/
void insertEasyWellLog(Map<String, Object> reqMap);
/*이지웰로그 수정*/
void updateEasyWellLog(Map<String, Object> reqMap);
/*이지웰로그 조회*/
DataMap selectEasyWellLog(Map<String, Object> reqMap);
}

View File

@@ -0,0 +1,714 @@
package com.wb.domainserver.domain.gcone.pos.easywell.service;
import com.wb.domainserver.common.prop.PropertyService;
import com.wb.domainserver.domain.gcone.pos.easywell.EasyWellErrCode;
import com.wb.domainserver.domain.gcone.pos.easywell.mapper.EasyWellMapper;
import com.wb.domainserver.exception.WnbtPosRestException;
import com.wb.domainserver.exception.code.PosCode;
import com.wb.domainserver.util.dataaccess.DataMap;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
@Service
@RequiredArgsConstructor
public class EasyWellService {
private final EasyWellMapper mapper;
/**
* 이지웰페이 조회
* @param reqMap 요청값
* @return 조회결과
*/
@Transactional(noRollbackFor = WnbtPosRestException.class)
public Map<String, Object> ew_check(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
//TODO :: BOPosController 변경시 반영
// Map<String, Object> data = new HashMap<>();
resultMap = ew_comm(reqMap);
// resultMap.put("data", data);
return resultMap;
}
/**
* 이지웰페이 사용
* @param reqMap 요청값
* @return 조회결과
*/
@Transactional(noRollbackFor = WnbtPosRestException.class)
public Map<String, Object> ew_use(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
//TODO :: BOPosController 변경시 반영
// Map<String, Object> data = new HashMap<>();
resultMap = ew_comm(reqMap);
// resultMap.put("data", data);
return resultMap;
}
/**
* 이지웰페이 사용취소
* @param reqMap 요청값
* @return 조회결과
*/
@Transactional(noRollbackFor = WnbtPosRestException.class)
public Map<String, Object> ew_cancel(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
//TODO :: BOPosController 변경시 반영
// Map<String, Object> data = new HashMap<>();
resultMap = ew_comm(reqMap);
// resultMap.put("data", data);
return resultMap;
}
/**
* 이지웰페이 공통 통신 및 로그 저장
* @param reqMap 요청값
* @return 조회결과
*/
@Transactional
protected Map<String, Object> ew_comm(Map<String, Object> reqMap){
Map<String, Object> resultMap = new HashMap<>();
Map<String, Object> returnMsg = new HashMap<>();
//서버 설정정보 조회
String sopmalCd = String.valueOf(reqMap.get("sopmalCd"));
Map<String,String> serverInfo = easyWellServerInfo(sopmalCd);
log.debug("serverInfo {}", serverInfo);
//입력값 검사 및 추가정보 세팅
reqInputValidChk(reqMap);
String ew_act = String.valueOf(reqMap.get("ew_act"));
String reqInputStr = "";
//개발서버 - 뉴트리코어 테스트 바코드
// reqMap.put("ew_code", "5633724739591234");
//개발서버 - gcbio 테스트 바코드
// reqMap.put("ew_code", "5633724739581234");
//전문생성
reqInputStr = switch (ew_act) {
case "check" -> reqMsgCheck(reqMap, serverInfo);
case "use" -> reqMsgUse(reqMap, serverInfo);
case "cancel" -> reqMsgCancel(reqMap, serverInfo);
default -> throw new WnbtPosRestException(PosCode.CMD_FAIL);
};
log.debug("reqInputStr {}", reqInputStr);
//DB에 저장 및 로그고유번호 리턴
easywellInsert(reqMap);
log.debug("EasyWellService easywellInsert reqMap {}", reqMap);
//http connection
String response = "";
try{
//소켓통신
log.info("socketEasyWell before");
response = socketEasyWell(reqInputStr, serverInfo);
log.info("socketEasyWell after");
}catch (Exception e){
log.error(e.getMessage());
}
// 포인트 조회 오류
// response = "0415E7T00003625010701 10slbiotech 10067521 E7T000036 016jLShRZg8K6cJyFZcOegJTT8oRxttpnabpgzKIjvV8c= 2025010716161900 00000000002013일시적인 오류가 발생했습니다.";
// 포인트 사용 정상
// response = "048620250108000001 20slbiotech 10067521 E7T000036 016jLShRZg8K6cJyFZcOegJTT8oRxttpnabpgzKIjvV8c= 2025010817472300 E7T00003625010801000001 100000390001000013300 000061000";
// 사용취소 정상
// response = "029320250109000002 30slbiotech 10067521 E7T000036 016jLShRZg8K6cJyFZcOegJTT8oRxttpnabpgzKIjvV8c= 20250109164417E7T00003625010901000001 100001330700000350001000013308 0000855000 ";
// 사용취소 오류
// response = "029320250109000002 30slbiotech 10067521 E7T000036 016jLShRZg8K6cJyFZcOegJTT8oRxttpnabpgzKIjvV8c= 20250109163901E7T00003625010901000001 00000000000000035000 2002일시적인 오류가 발생했습니다.";
//리턴 메시지 추출
returnMsg = socketEasyWellResponseParser(response, ew_act);
//DB저장시 받은 로그 고유번호 저장
returnMsg.put("ezwellLogInnb", Integer.parseInt(String.valueOf(reqMap.get("ezwellLogInnb"))));
//리턴메시지 logcode 코드 분기로 성공여부 확인
String status = "";
String msg = "";
String logcode = "";
//성공시
if("0000".equals(returnMsg.get("logcode"))){
status = "Y";
resultMap.put("ew_remain",returnMsg.get("ew_remain"));
if(returnMsg.containsKey("ew_order")){
resultMap.put("ew_order",returnMsg.get("ew_order"));
}
if(returnMsg.containsKey("ew_price")){
resultMap.put("ew_price",returnMsg.get("ew_price"));
}
if(returnMsg.containsKey("ew_approv")){
resultMap.put("ew_approv",returnMsg.get("ew_approv"));
}
if(returnMsg.containsKey("ew_member")){
resultMap.put("ew_member",returnMsg.get("ew_member"));
}
}else{ //실패시
status = "N";
msg = String.valueOf(returnMsg.get("msg"));
logcode = String.valueOf(returnMsg.get("logcode"));
}
//통신결과 DB 업데이트 (성공실패 유무 상관없음)
easywellUpdate(returnMsg);
//실패시 에러 처리
if("N".equals(status)){
throw new WnbtPosRestException("N", msg, "null", logcode);
}
log.debug("resutMap {}", resultMap);
return resultMap;
}
/**
* 입력값 체크 및 추가정보 세팅
* @param reqMap 요청정보
*/
private void reqInputValidChk(Map<String, Object> reqMap){
// ew_code 바코드, storecode 검사
if(!reqMap.containsKey("ew_code") || ObjectUtils.isEmpty(reqMap.get("ew_code"))){
throw new WnbtPosRestException(PosCode.INPUT_CHECK, "바코드번호", "ew_code");
}
//이지웰페이 적용 매장 검사
String ewApplcHdqrtrs = PropertyService.getProperty("easywell.applc-hdqrtrs");
//이지웰 페이 적용 매장이 아닐 경우
String pgubun = String.valueOf(reqMap.get("pgubun"));
if(!ewApplcHdqrtrs.contains(pgubun)){
throw new WnbtPosRestException(PosCode.NO_EW_STORE);
}
//ezwellpay 전송
//ezwellpay 구분값에 따른 param 세팅
String cmd = String.valueOf(reqMap.get("cmd"));
String ew_act = cmd.split("_")[1];
reqMap.put("ew_act", ew_act);
String ew_act_cd = switch (ew_act) {
case "check" -> "01";
case "use" -> "02";
case "cancel" -> "03";
default -> throw new WnbtPosRestException(PosCode.CMD_FAIL);
};
reqMap.put("ew_act_cd", ew_act_cd);
String pnumb = "";
if(reqMap.containsKey("pnumb")){
pnumb = String.valueOf(reqMap.get("pnumb"));
}
//order_code 생성
//오늘날짜
SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
String currentDate = dateFormat.format(new Date());
reqMap.put("order_code", reqMap.get("storecode") + currentDate + reqMap.get("poscode") + pnumb);
// ew_order_code 생성
// CH + 현재 시간 (포맷: yyMMddHHmmss)
SimpleDateFormat dateFormatEzOrderCode = new SimpleDateFormat("yyMMddHHmmss");
String currentDateTime = reqMap.get("sopmalCd") + dateFormatEzOrderCode.format(new Date());
// ew_code 문자열 자르기 (1부터 10개의 문자)
String ewCode = String.valueOf(reqMap.get("ew_code"));
String truncatedEwCode = ewCode.substring(1, Math.min(11, ewCode.length())); // 1~10 자르기
String ewOrderCode = currentDateTime + truncatedEwCode;
reqMap.put("ew_order_code",ewOrderCode);
}
/**
* 전문 생성 - 이지웰페이 포인트 조회
* @param reqMap 요청값
* @param serverInfo 서버정보
* @return 요청 전문
*/
public String reqMsgCheck(Map<String, Object> reqMap, Map<String, String> serverInfo){
String ordrCd = String.valueOf(reqMap.get("order_code"));
String storeCode = String.valueOf(reqMap.get("storecode"));
String ewCode = String.valueOf(reqMap.get("ew_code"));
String cipher = serverInfo.get("cipher");
String key = serverInfo.get("key");
String iv = serverInfo.get("iv");
String companyCd = serverInfo.get("companyCd");
String brandCd = serverInfo.get("brandCd");
// 암호화 수행
String encryptedGoodsCode = encrypt(ewCode, cipher, key, iv);
// 전문 생성
StringBuilder reqStr = new StringBuilder();
reqStr.append(repeat(ordrCd, 30)); // 거래번호
reqStr.append("10"); // 업무구분
reqStr.append(companyCd); // 회사코드
reqStr.append(brandCd); // 브랜드코드
reqStr.append(repeat(storeCode, 20)); // 점포코드
reqStr.append("01"); // POS번호
reqStr.append(repeat(encryptedGoodsCode, 60)); // 암호화된 바코드
reqStr.append("2"); // 입력구분
reqStr.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); // 거래일시
reqStr.append("00"); // 상품카테고리코드 길이
reqStr.append(repeat(" ", 100)); // 상품카테고리코드 (옵션)
return String.format("%04d", reqStr.length()) + reqStr;
}
/**
* 전문 생성 - 이지웰페이 포인트 사용
* @param reqMap 요청값
* @param serverInfo 서버정보
* @return 요청 전문
*/
public String reqMsgUse(Map<String, Object> reqMap, Map<String, String> serverInfo){
String oCd = String.valueOf(reqMap.get("ocode"));//주문코드
String storeCode = String.valueOf(reqMap.get("storecode"));//점포코드
String ewCode = String.valueOf(reqMap.get("ew_code"));//바코드
String ordrCd = String.valueOf(reqMap.get("order_code"));//주문코드(취소시 필요)
String ewPrice = String.valueOf(reqMap.get("ew_price"));//결제금액
int mileage = 0;
if(reqMap.containsKey("mileage")){
if(!"0".equals(reqMap.get("mileage"))){
mileage = Integer.parseInt(reqMap.get("mileage").toString());//적립금액
}
}
String cipher = serverInfo.get("cipher");
String key = serverInfo.get("key");
String iv = serverInfo.get("iv");
String companyCd = serverInfo.get("companyCd");
String brandCd = serverInfo.get("brandCd");
// 암호화 수행
String encryptedGoodsCode = encrypt(ewCode, cipher, key, iv);
// 전문 생성
StringBuilder reqStr = new StringBuilder();
reqStr.append(repeat(oCd, 30)); // 거래번호 (AN 30)
reqStr.append("20"); // 업무구분 (N 2)
reqStr.append(companyCd); // 회사코드 (AN 10)
reqStr.append(brandCd); // 브랜드코드 (AN 10)
reqStr.append(repeat(storeCode, 20)); // 점포코드
reqStr.append("01"); // POS번호 (2)
reqStr.append(repeat(encryptedGoodsCode, 60)); // 암호화된 바코드
reqStr.append("2"); // 입력구분 (1:바코드, 2:직접입력)
reqStr.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); // 거래일시 (14)
reqStr.append("00"); // 상품카테고리코드 길이 (2)
reqStr.append(repeat(" ", 100)); // 상품카테고리코드 (옵션)
reqStr.append(repeat(ordrCd, 30)); // 주문번호 (AN 30)
reqStr.append("1"); // 결제구분 (포인트 구매 : 1)
reqStr.append(String.format("%010d", Integer.parseInt(ewPrice))); // 결제요청금액
reqStr.append(String.format("%010d", mileage)); // 결제 성공시 적립예정 적립금 금액
return String.format("%04d", reqStr.length()) + reqStr;
}
/**
* 전문 생성 - 이지웰페이 포인트 사용 취소
* @param reqMap 요청값
* @param serverInfo 서버정보
* @return 요청 전문
*/
public String reqMsgCancel(Map<String, Object> reqMap, Map<String, String> serverInfo){
DataMap selectLog = mapper.selectEasyWellLog(reqMap);
if(selectLog.containsKey("ewUseCanclAmt")){
reqMap.put("ew_price", selectLog.get("ewUseCanclAmt"));
}
String oCd = String.valueOf(reqMap.get("ocode"));//주문코드
String storeCode = String.valueOf(reqMap.get("storecode"));//점포코드
String ewCode = String.valueOf(reqMap.get("ew_code"));//바코드
String ordrCd = String.valueOf(reqMap.get("org_order"));//주문코드(취소시 필요)
String ewPrice = String.valueOf(reqMap.get("ew_price"));//취소요청금액
int succCd = 0; //거래승인 번호
if(reqMap.containsKey("org_approv")){
if(!"0".equals(reqMap.get("org_approv"))){
succCd = Integer.parseInt(reqMap.get("org_approv").toString());
}
}
int mileage = 0; //취소 성공시 적립금 금액
if(reqMap.containsKey("mileage")){
if(!"0".equals(reqMap.get("mileage"))){
mileage = Integer.parseInt(reqMap.get("mileage").toString());
}
}
String cipher = serverInfo.get("cipher");
String key = serverInfo.get("key");
String iv = serverInfo.get("iv");
String companyCd = serverInfo.get("companyCd");
String brandCd = serverInfo.get("brandCd");
// 암호화 수행
String encryptedGoodsCode = encrypt(ewCode, cipher, key, iv);
// 전문 생성
StringBuilder reqStr = new StringBuilder();
reqStr.append(repeat(oCd, 30)); // 거래번호 (AN 30)
reqStr.append("30"); // 업무구분 (N 2) : 30 (결제취소)
reqStr.append(companyCd); // 회사코드 (AN 10)
reqStr.append(brandCd); // 브랜드코드 (AN 10)
reqStr.append(repeat(storeCode, 20)); // 점포코드
reqStr.append("01"); // POS번호 (2)
reqStr.append(repeat(encryptedGoodsCode, 60)); // 암호화된 바코드
reqStr.append("2"); // 입력구분 (1:바코드, 2:직접입력)
reqStr.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())); // 거래일시 (14)
reqStr.append(repeat(ordrCd, 30)); // 원거래 주문번호 (AN 30)
reqStr.append(String.format("%010d", succCd)); // 거래승인번호
reqStr.append(String.format("%010d", Integer.parseInt(ewPrice))); // 취소요청금액
reqStr.append(String.format("%010d", mileage)); // 결제취소시 적립금 금액
return String.format("%04d", reqStr.length()) + reqStr;
}
/**
* 암호화 함수
* @param data 암호화 대상 데이터
* @param cipherAlgorithm 알고리즘
* @param key 암호화키
* @param iv 초기화벡터
* @return 암호데이터
*/
private String encrypt(String data,String cipherAlgorithm,String key, String iv) {
try{
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encrypted); // Base64 인코딩
}catch (Exception e){
log.error(e.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
}
/**
* 이지웰페이 소켓 통신 반복 채우기 함수
* 문자열을 왼쪽정렬하고 갯수를 확인하여 모자를 경우 그 만큼 공백 추가
* @param input 반복 채우기 대상
* @param count 갯수
* @return String
*/
private String repeat(String input, int count) {
//목표길이보다 길경우 자르기 (필요시 주석해제)
// if (input.length() > count) {
// return input.substring(0, count);
// }
return String.format("%-" + count + "s", input);
}
/**
* 이지웰페이 소켓 통신 응답값 파서
* @param returnData 응답데이터
* @param ewAct 이지웰페이 구분
* @return Map<String, Object>
*/
private Map<String, Object> socketEasyWellResponseParser(String returnData, String ewAct) {
log.debug("socketEasyWellResponseParser returnData {}", returnData);
Map<String, Object> result = new HashMap<>();
// 에러처리 - 이지웰측 서버로부터 데이터 수신 못하였을 경우
if(returnData.equals("serverResponseEmpty")){
String responseEmptyErrCode = "9990";
EasyWellErrCode err = EasyWellErrCode.valueOfErrCode(responseEmptyErrCode);
String errInfo = "(" +err.getErrInfo() + ")";
result.put("logcode", responseEmptyErrCode);
result.put("msg", err.getErrMsg() + errInfo);
return result;
}
try {
switch (ewAct) {
case "check":
result.put("ew_remain", Integer.parseInt(returnData.substring(355, 365).trim()));
result.put("logcode", returnData.substring(365, 369));
result.put("msg", returnData.substring(369).trim());
break;
case "use":
result.put("logcode", returnData.substring(436, 440));
if ("0000".equals(result.get("logcode"))) {
result.put("ew_remain", Integer.parseInt(returnData.substring(440).trim()));
result.put("ew_order", returnData.substring(355, 385).trim());
result.put("ew_price", Integer.parseInt(returnData.substring(386, 396).trim()));
result.put("ew_approv", returnData.substring(396, 406));
result.put("ew_member", returnData.substring(406, 436).trim());
} else {
result.put("msg", returnData.substring(440).trim());
}
break;
case "cancel":
result.put("logcode", returnData.substring(243, 247));
if ("0000".equals(result.get("logcode"))) {
result.put("ew_remain", Integer.parseInt(returnData.substring(247).trim()));
result.put("ew_order", returnData.substring(153, 183).trim());
result.put("ew_price", Integer.parseInt(returnData.substring(193, 203).trim()));
result.put("ew_approv", returnData.substring(203, 213));
result.put("ew_member", returnData.substring(213, 243).trim());
} else {
result.put("msg", returnData.substring(247).trim());
}
break;
}
log.info("easywell response errcode {}", result.get("logcode"));
String errCode = String.valueOf(result.get("logcode"));
//에러처리 - 정상이 아닐 경우 에러정보 세팅
if(!errCode.equals("0000")){
EasyWellErrCode err = EasyWellErrCode.valueOfErrCode(errCode);
String errmsg = "";
if(result.containsKey("msg")){
errmsg = result.get("msg").toString();
}else{
errmsg = err.getErrMsg();
}
String errInfo = "(" +err.getErrInfo() + ")";
result.put("logcode", errCode);
result.put("msg", errmsg + errInfo);
return result;
}
} catch (Exception e){
log.error(e.getMessage());
}
log.debug("socketEasyWellResponseParser resultMap {}", result);
return result;
}
/**
* 이지웰페이 소켓 통신
* @param reqStr 요청데이터
* @param serverInfo 요청 서버정보
* @return response
*/
private String socketEasyWell(String reqStr, Map<String, String> serverInfo) {
String res = "";
Charset charset = StandardCharsets.UTF_8;
String serverIp = serverInfo.get("ip");
int serverPort = Integer.parseInt(serverInfo.get("port"));
// 소켓 생성 및 연결
try (Socket socket = new Socket(serverIp, serverPort);
OutputStream out = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(out);
InputStream in = socket.getInputStream();
DataInputStream dis = new DataInputStream(in)) {
//read Timeout setting
socket.setSoTimeout(5000);
// 요청 데이터 전송
dos.write(reqStr.getBytes(charset));
dos.flush();
// 응답 데이터 수신
// 데이터를 저장할 byte 배열 생성
byte[] buffer = new byte[1024]; // 최대 1024 바이트 읽기
int bytesRead = dis.read(buffer); // 읽은 바이트 수 반환
// 받은 데이터 출력
if (bytesRead > 0) {
byte[] receivedData = Arrays.copyOf(buffer, bytesRead); // 실제 읽은 데이터만 복사
log.debug("받은 데이터: {}", new String(receivedData, "EUC-KR")); // byte[]를 문자열로 변환
res = new String(receivedData, "EUC-KR");
} else {
log.info("이지웰 서버로 부터 데이터를 받지 못했습니다. (serverResponseEmpty)");
res = "serverResponseEmpty";
}
log.debug("bufferedReader res {}", res);
return res;
}catch (SocketException | SocketTimeoutException se){
log.error(se.getMessage());
throw new WnbtPosRestException(PosCode.SOCKET_TIME_OUT);
}
catch (IOException e) {
log.error(e.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
} catch (Exception e) {
log.error(e.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
}
/**
* 이지웰페이 소켓 서버정보
* @param sopmalCd 쇼핑몰 구분
* @return serverInfo
*/
private Map<String, String> easyWellServerInfo(String sopmalCd){
Map<String, String> serverInfo = new HashMap<>();
if("NC".equalsIgnoreCase(sopmalCd)){
sopmalCd = "nc";
}else{
sopmalCd ="other";
}
String infoProperties = "easywell.server." + sopmalCd;
serverInfo.put("ip", PropertyService.getProperty(infoProperties +".ip"));
serverInfo.put("port", PropertyService.getProperty(infoProperties +".port"));
serverInfo.put("companyCd",repeat(PropertyService.getProperty(infoProperties +".company-code"), 10));
serverInfo.put("brandCd",repeat(PropertyService.getProperty(infoProperties +".brand-code"), 10));
serverInfo.put("cipher",PropertyService.getProperty(infoProperties +".cipher"));
serverInfo.put("key",PropertyService.getProperty(infoProperties +".key"));
serverInfo.put("iv",PropertyService.getProperty(infoProperties +".iv"));
return serverInfo;
}
/**
* 이지웰페이 로그저장
* @param reqMap 소켓통신 요청정보
* @return 로그고유번호
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
protected void easywellInsert(Map<String, Object> reqMap){
try{
mapper.insertEasyWellLog(reqMap);
}catch (RuntimeException re){
log.error(re.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
catch (Exception e){
log.error(e.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
}
/**
* 이지웰페이 로그 수정
* @param returnMsg 소켓통신결과
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
protected void easywellUpdate(Map<String, Object> returnMsg){
try{
mapper.updateEasyWellLog(returnMsg);
}catch (RuntimeException re){
log.error(re.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}catch (Exception e){
log.error(e.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
}
}

View File

@@ -0,0 +1,246 @@
package com.wb.domainserver.domain.gcone.pos.pos.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.wb.domainserver.common.prop.PaginationProperties;
import com.wb.domainserver.domain.gcone.common.service.BOCommonService;
import com.wb.domainserver.domain.gcone.pos.pos.response.PosResponse;
import com.wb.domainserver.domain.gcone.pos.pos.service.PosOrderService;
import com.wb.domainserver.domain.gcone.pos.pos.service.PosService;
import com.wb.domainserver.exception.WnbtPosRestException;
import com.wb.domainserver.exception.code.PosCode;
import com.wb.domainserver.response.ApiResponse;
import com.wb.domainserver.security.authorization.annotation.AuthPolicy;
import com.wb.domainserver.security.authorization.annotation.Policy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.http.HttpStatus;
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.RestController;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/gcone/pos/pos")
public class BOPosController {
@Autowired
private PosService service;
@Autowired
private PosOrderService orderService;
@Autowired
private PaginationProperties paginationProperties;
@Autowired
private BOCommonService boCommonService;
/**
* 포스정보 검색
* @param reqMap
* @return
*/
@Policy(AuthPolicy.PUBLIC)
@RequestMapping(value = "/selectBOPosInfo")
public ResponseEntity<?> selectBOPosInfo(@RequestBody Map<String, Object> reqMap) {
log.debug("reqMap {}", reqMap);
//시크릿 키 set (공통)
String secretKey = boCommonService.selectSecretkey();
reqMap.put("secretKey",secretKey);
String cmd = reqMap.get("cmd").toString();
service.selectBOPosCommChk(reqMap);
Object resultObj = posMethodCall(service, cmd, reqMap);
String msg = "";
Object data = null;
String err = "";
//커스텀 한 값이 들어올 경우 해당 값으로 대체 이외 초기화 값으로 리턴
if(resultObj instanceof Map<?,?>) {
Map<String, Object> resultMap = (Map<String, Object>) resultObj;
if(resultMap.containsKey("msg")){
msg = String.valueOf(resultMap.get("msg"));
}
if(resultMap.containsKey("data")){
data = resultMap.get("data");
}
if(resultMap.containsKey("err")){
err = String.valueOf(resultMap.get("err"));
}
}else{
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
PosResponse response = new PosResponse("Y", msg, data, err);
return ApiResponse.of(response).ifPresentOrElse(HttpStatus.OK, HttpStatus.NOT_FOUND);
}
/**
* 서비스 메소드를 호출하는 메소드
* @param instance 서비스 object
* @param cmd 작업 명령
* @param reqMap 요청값
*/
public static Object posMethodCall(Object instance, String cmd, Map<String, Object> reqMap) {
Object result = null;
try{
//서비스의 클래스 가져오기
Class<?> service = instance.getClass();
//cmd에 해당하는 서비스 메소드 정보 가져오기 + param 클래스 입력
Method serviceMethod = service.getMethod(cmd, Map.class);
//해당 메솓 - 호출 + 파라미터 전달
result = serviceMethod.invoke(instance, reqMap);
}catch (NoSuchMethodException nme){
log.error(nme.getMessage());
throw new WnbtPosRestException("N", "작업 명령이 올바르지 않습니다"+"("+cmd+")", null, "bad cmd");
} catch (InvocationTargetException ex){
Throwable cause = ex.getTargetException();
log.error(cause.getMessage());
//WnbtPosRestException 일 경우 throw
if (cause instanceof WnbtPosRestException) {
throw (WnbtPosRestException) cause;
}
//WnbtPosRestException 이외 예외일 경우 WnbtPosRestException 처리
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
} catch (Exception e){
log.error(e.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
return result;
}
/**
* 포스정보 검색
* @param reqMap
* @return
*/
@Policy(AuthPolicy.PUBLIC)
@RequestMapping(value = "/selectBOPosMbrOrdrSearch")
public ResponseEntity<?> selectBOPosMbrOrdrSearch(@RequestBody Map<String, Object> reqMap) {
Map<String, Object> content = new HashMap<>();
log.debug("reqMap {}", reqMap);
//시크릿 키 set (공통)
String secretKey = boCommonService.selectSecretkey();
reqMap.put("secretKey",secretKey);
content = orderService.ext_order_search(reqMap);
return ApiResponse.of(content).ifPresentOrElse(HttpStatus.OK, HttpStatus.NOT_FOUND);
}
/**
* 포스 주문 누락건 처리 ( 배치 )
* @param reqMap
* @return
*/
@Policy(AuthPolicy.PUBLIC)
@RequestMapping(value = "/insertPosSyncOrderRegist")
public ResponseEntity<?> insertPosSyncOrderRegist(@RequestBody List<Map<String, Object>> reqMapList) throws ParseException, JsonProcessingException {
Map<String, Object> content = new HashMap<>();
log.debug("주문 싱크 파라미터 : {}", reqMapList);
for (Map<String, Object> reqMap : reqMapList) {
//시크릿 키 set (공통)
String secretKey = boCommonService.selectSecretkey();
reqMap.put("secretKey",secretKey);
try {
log.debug("주문 싱크 데이터 reqMap {}", reqMap);
orderService.order_insert(reqMap);
} catch (WnbtPosRestException we) {
log.error(we.getMessage());
continue;
} catch (Exception e) {
log.error(e.getMessage());
continue;
}
}
return ApiResponse.of(content).ifPresentOrElse(HttpStatus.OK, HttpStatus.NOT_FOUND);
}
/**
* 포스 반품 누락건 처리 ( 배치 )
* @param reqMap
* @return
*/
@Policy(AuthPolicy.PUBLIC)
@RequestMapping(value = "/insertPosSyncdRefundRegist")
public ResponseEntity<?> insertPosSyncdRefundRegist(@RequestBody List<Map<String, Object>> reqMapList) {
Map<String, Object> content = new HashMap<>();
for (Map<String, Object> reqMap : reqMapList) {
//시크릿 키 set (공통)
String secretKey = boCommonService.selectSecretkey();
reqMap.put("secretKey",secretKey);
try {
log.debug("반품 싱크 데이터 reqMap {}", reqMap);
orderService.refund_insert(reqMap);
} catch (WnbtPosRestException we) {
log.error(we.getMessage());
continue;
} catch (Exception e) {
log.error(e.getMessage());
continue;
}
}
return ApiResponse.of(content).ifPresentOrElse(HttpStatus.OK, HttpStatus.NOT_FOUND);
}
}

View File

@@ -0,0 +1,73 @@
package com.wb.domainserver.domain.gcone.pos.pos.mapper;
import com.wb.domainserver.domain.gcone.ordr.rtngudrefnd.vo.BORtngudrefndVO;
import com.wb.domainserver.util.dataaccess.DataMap;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Mapper
@Repository
public interface PosCouponMapper {
/**
* 쿠폰 검사
* @param reqMap
* @return
*/
public DataMap selectPosCouponInqire(Map<String, Object> reqMap);
/**
* 쿠폰 검사
* @param reqMap
* @return
*/
public Map<String, Object> selectPosOflneCouponInqire(DataMap reqMap);
/**
* 다운로드 쿠폰 사용처리 상태 업데이트
* @param dwldCouponData
*/
public void updatePosDwldCouponSttusCdUpdt(LinkedHashMap dwldCouponData);
/**
* 다운로드 쿠폰 사용처리 상태 업데이트
* @param dwldCouponData
*/
public void insertPosDwldCouponUsedLogRegist(LinkedHashMap dwldCouponData);
/**
* 복원 쿠폰 조회
* @param cancelVO
*/
public List<DataMap> selectPosUseCouponListInqire(BORtngudrefndVO cancelVO);
/**
* 다운로드 쿠폰 복원처리 상태 업데이트
* @param cancelVO
*/
public void updatePosDwldCouponRecvryUpdt(DataMap cancelVO);
/**
* 다운로드 쿠폰 사용내역 취소처리 상태 업데이트
* @param cancelVO
*/
public void updatePosOrderCouponCancelUpdt(DataMap cancelVO);
/**
* 오프라인 쿠폰 다운로드 insert
* @param dwldCouponData
*/
public void insertPosDwldCouponRegist(LinkedHashMap dwldCouponData);
}

View File

@@ -0,0 +1,55 @@
package com.wb.domainserver.domain.gcone.pos.pos.mapper;
import com.wb.domainserver.util.dataaccess.DataMap;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Map;
@Mapper
@Repository
public interface PosMapper {
//포스 - 매장 정보 조회
DataMap selectBOPosStrSrch(Map<String, Object> reqMap);
//포스 - 매장 방문기록 수정
void updateMbrStrVisit(Map<String, Object> reqMap);
//매출검색
List<DataMap> selectBOPosOrderSrchList(Map<String, Object> reqMap);
//포스 - 주문조회
DataMap selectOrderPosInfo(Map<String, Object> reqMap);
//포스 - 주문조회
DataMap selectOrderGPosInfo(String gPoscode);
//포스 - 주문조회
DataMap selectOrder(Map<String, Object> reqMap);
//포스 - 주문item조회
List<DataMap> selectOrderItem(Map<String, Object> reqMap);
//포스 - 상품조회
public DataMap selectGoods(DataMap reqMap);
//포스 - 상품item조회
DataMap selectGoodsItem(DataMap reqMap);
//포스 주문 결제 등록
public int insertPosOrder(Map<String, Object> reqMap);
//포스주문 날짜 업데이트
void updateSetPosDay(Map<String, Object> reqMap);
//포스 - 회원 건수 조회
int selectPosMbrCnt(Map<String, Object> reqMap);
//포스 - 회원 리스트 조회
List<DataMap> selectBOPosMbrList(Map<String, Object> reqMap);
//포스 - 회원 블랙리스트 조회
int selectPosMbrAppn(Map<String, Object> reqMap);
}

View File

@@ -0,0 +1,142 @@
package com.wb.domainserver.domain.gcone.pos.pos.mapper;
import com.wb.domainserver.domain.gcone.goods.purchs.vo.BOOrderItemOptnVO;
import com.wb.domainserver.domain.gcone.goods.purchs.vo.BOOrderVO;
import com.wb.domainserver.domain.gcone.ordr.ordr.vo.BOOrdrRefundItemVO;
import com.wb.domainserver.domain.gcone.ordr.ordr.vo.BOOrdrRefundVO;
import com.wb.domainserver.util.dataaccess.DataMap;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.math.BigInteger;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@Mapper
@Repository
public interface PosOrderMapper {
/**
* 매출 검색 목록 조회
* @param reqMap
* @return
*/
public List<LinkedHashMap> selectPosOrderSrchListInqire(Map<String, Object> reqMap);
/**
* 매출 등록 포스 주문 상품 조회
* @param detailArr
* @return
*/
public LinkedHashMap selectPosOrderGoodsInfoInqire(DataMap detailArr);
/**
* 포스 상품 고유번호 조회
* @param gPoscode
* @return
*/
public DataMap selectGoodsPosInfo(DataMap gPoscode);
/**
* 포스 주문 상품 옵션 등록
* @param gPoscode
* @return
*/
public void insertPosOrdrGoodsOption(BOOrderItemOptnVO orderItemOptnVO);
/**
* 포스 로그 상태 업데이트
* @param posLogVO
*/
public void updatePosLogStatusUpdt(DataMap posLogVO);
/**
* 반품시 원주문 정보 조회
* @param ordrParam
* @return
*/
public DataMap selectPosOrderReturnInfo(DataMap ordrParam);
/**
* 반품시 원주문 상품 정보 조회
* @param ordrParam
* @return
*/
public List<LinkedHashMap> selectPosOrderReturnItemListInqire(DataMap ordrParam);
/**
* 환불 정보 등록
* @param refundVO
*/
public void insertOrderRefund(BOOrdrRefundVO refundVO);
/**
* 환불 상품옵션 등록
* @param refundItemVO
*/
public void insertOrderRefundItem(BOOrdrRefundItemVO refundItemVO);
/**
* 포스 회원 사이트 정보 업데이트
* @param reqMap
*/
public void updateMbrSitePosInfoUpdt(DataMap reqMap);
/**
* 포스 주문 등록
* @param vo
*/
public void insertOrdr(BOOrderVO vo);
/**
* 매장기준
* @param vo
* @return
*/
public DataMap selectPosMlgValidInqire(DataMap vo);
/**
* 포스 첫구매여부 조회
* @param vo
* @return
*/
public String selectFrstPurchsAt(BOOrderVO vo);
/**
* 고객 매출정보 조회
* @param reqMap
* @return
*/
public List<LinkedHashMap> selectPosMbrOrdrListInqire(Map<String, Object> reqMap);
/**
* 포스 고객 정보 조회
* @param reqMap
* @return
*/
public LinkedHashMap selectPosMbrInfoInqire(Map<String, Object> reqMap);
/**
* 포스 주문 반품 체크
* @param orgOrdrInfo
* @return
*/
public DataMap selectRefundCheck(DataMap orgOrdrInfo);
}

View File

@@ -0,0 +1,25 @@
package com.wb.domainserver.domain.gcone.pos.pos.response;
import lombok.*;
@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode(callSuper=false)
@Builder
public class PosResponse {
private String status;
private String msg;
private Object data;
private String err;
public PosResponse(String status, String msg, Object data) {
this.status = status;
this.msg = msg;
this.data = data;
}
}

View File

@@ -0,0 +1,266 @@
package com.wb.domainserver.domain.gcone.pos.pos.service;
import com.wb.domainserver.domain.gcone.goods.purchs.mapper.BOPurchsMapper;
import com.wb.domainserver.domain.gcone.ordr.ordr.mapper.BOOrdrMapper;
import com.wb.domainserver.domain.gcone.ordr.rtngudrefnd.vo.BORtngudrefndVO;
import com.wb.domainserver.domain.gcone.pos.pos.mapper.PosCouponMapper;
import com.wb.domainserver.domain.gcone.pos.pos.mapper.PosMapper;
import com.wb.domainserver.domain.gcone.promtn.coupon.mapper.BOCouponMapper;
import com.wb.domainserver.exception.WnbtPosRestException;
import com.wb.domainserver.exception.code.PosCode;
import com.wb.domainserver.util.dataaccess.DataMap;
import com.wb.domainserver.util.string.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.util.*;
@Slf4j
@Service
@RequiredArgsConstructor
public class PosCouponService {
@Autowired
private BOCouponMapper couponMapper;
@Autowired
private PosCouponMapper mapper;
@Autowired
private BOOrdrMapper ordrMapper;
/**
* 쿠폰 검사
*
* @param cmd : coupon_check
* @param reqMap 요청값
* @param reqMap 요청값
* @param reqMap 요청값
* @param reqMap 요청값
* @param reqMap 요청값
* @param reqMap 요청값
* @return map
*/
@Transactional
public Map<String, Object> coupon_check(Map<String, Object> reqMap) throws WnbtPosRestException {
Map<String, Object> oflineCoupon = new HashMap<>();
log.info("포스 쿠폰 검사 : {}", reqMap);
try {
String couponCode = StringUtil.isNullToString(reqMap.get("COUPON_CODE"));
String authNo = StringUtil.isNullToString(reqMap.get("AUTH_NO"));
if (StringUtil.isEmpty(couponCode)) { // 쿠폰 번호 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 이벤트 코드를 지정해 주세요.", "NO_COUPON_CODE");
}
if (StringUtil.isEmpty(authNo)) { // 인증번호 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 번호를 지정해 주세요.", "NO_AUTH_NO");
}
if (authNo.length() != 17 && authNo.length() != 16 && authNo.length() != 14) { // old 인증번호때문에 14 포함
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 번호가 올바르지 않습니다.", "BAD_AUTH_NO");
}
DataMap posCoupon = new DataMap();
posCoupon = mapper.selectPosCouponInqire(reqMap);
log.debug("포스 쿠폰 확인 : {}", posCoupon);
if (ObjectUtils.isEmpty(posCoupon)) { // 포스 연결 쿠폰인지 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 코드가 일치하지 않습니다.", "BAD_COUPON_CODE");
}
oflineCoupon = mapper.selectPosOflneCouponInqire(posCoupon);
log.debug("인증번호 쿠폰 확인 : {}", oflineCoupon);
if (ObjectUtils.isEmpty(oflineCoupon)) { // 인증번호 쿠폰 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 이벤트 정보를 확인할 수 없습니다.", "BAD_COUPON");
}
if ("N".equals(oflineCoupon.get("issue_stop"))) { // 쿠폰 운영 여부 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 이벤트 사용이 중지되었습니다.", "STOP", oflineCoupon);
}
if ("N".equals(oflineCoupon.get("START_DATE"))) { // 시작일시 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 이벤트 사용기간이 시작되지 않았습니다.", "STARTDATE", oflineCoupon);
}
if ("N".equals(oflineCoupon.get("END_DATE"))) { // 종료일시 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 이벤트 사용기간이 종료되었습니다.", "ENDDATE", oflineCoupon);
}
if (ObjectUtils.isEmpty(oflineCoupon.get("offline_seq"))) { // 인증번호 쿠폰 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "등록된 쿠폰 번호가 아닙니다.", "8002", oflineCoupon);
}
if ("03".equals(oflineCoupon.get("use_status"))) { // 쿠폰 사용 여부 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "이미 사용된 쿠폰 번호입니다.", "8003", oflineCoupon);
}
oflineCoupon.put("coupon_num", authNo);
log.debug("사용가능 쿠폰 정보 : {}", oflineCoupon);
// resMap.put("data", oflineCoupon); // 쿠폰 객체 반환
} catch(WnbtPosRestException wpe) {
log.error(wpe.getMsg());
throw wpe;
}
return oflineCoupon;
}
/**
* 쿠폰 사용처리
*
*
* @param cmd : coupon_use
* @param reqMap 요청값
* @param reqMap 요청값
* @param reqMap 요청값
* @param reqMap 요청값
* @param reqMap 요청값
* @param reqMap 요청값
* @return map
*/
@Transactional
public Map<String, Object> coupon_use(Map<String, Object> reqMap) throws WnbtPosRestException {
Map<String, Object> resMap = new HashMap<String, Object>();
log.info("포스 쿠폰 사용처리 : {}", reqMap);
if (CollectionUtils.isEmpty((List<DataMap>) reqMap.get("coupon_arr"))) { // 사용 쿠폰 목록 확인
throw new WnbtPosRestException(PosCode.CUSTOM_MSG, "쿠폰 목록이 지정되지 않았습니다.", "NO_COUPON_ARR");
}
List<LinkedHashMap> oflineCouponList = new ArrayList<LinkedHashMap >();
DataMap oflineCoupon = new DataMap();
oflineCouponList = (List<LinkedHashMap >) reqMap.get("coupon_arr");
log.debug("포스 쿠폰 사용처리3 : {}", oflineCouponList);
DataMap memInfo = (DataMap) reqMap.get("memInfo"); //회원정보
log.debug("포스 쿠폰 사용처리 memInfo : {}", memInfo);
List<LinkedHashMap> downloadArrList = new ArrayList<LinkedHashMap >();
Integer coupon_sale = 0;
// 사용 쿠폰 목록 반복
for (LinkedHashMap coupon : oflineCouponList) {
Map<String, Object> couponData = new HashMap<>();
try {
couponData = coupon_check(coupon);
} catch (WnbtPosRestException wpe) {
if (!"Y".equals(wpe.getStatus()) || !"0000".equals(wpe.getErr())) {
if ("NO_AUTH_NO".equals(wpe.getErr())) {
log.debug("쿠폰 인증번호 없어서 통과");
continue;
}
}
log.error(wpe.getMessage());
}
log.debug("쿠폰 사용에서 검사 통과후 객체 확인 :{}", couponData);
LinkedHashMap dwldCouponData = new LinkedHashMap(couponData);
dwldCouponData.put("useq", memInfo.get("useq"));
dwldCouponData.put("mbr_dv_cd", memInfo.get("mbrDvCd"));
dwldCouponData.put("ordrInnb", reqMap.get("ordrInnb"));
dwldCouponData.put("sopmalCd", reqMap.get("sopmalCd"));
log.debug("dwldCouponData DataMap 으로 전환 후 :: {}", dwldCouponData);
if (dwldCouponData.get("download_seq") != null && !"0".equals(dwldCouponData.get("download_seq"))) { // 다운로드에 쿠폰있을 경우
// 쿠폰 사용처리 업데이트
mapper.updatePosDwldCouponSttusCdUpdt(dwldCouponData);
// 쿠폰 사용처리 내역 등록
mapper.insertPosDwldCouponUsedLogRegist(dwldCouponData);
} else if (dwldCouponData.get("download_seq") != null && "0".equals(dwldCouponData.get("download_seq"))) { // 다운로드에 쿠폰 없을 경우
mapper.insertPosDwldCouponRegist(dwldCouponData);
// 쿠폰 사용처리 내역 등록
mapper.insertPosDwldCouponUsedLogRegist(dwldCouponData);
}
LinkedHashMap download_arr = new LinkedHashMap();
download_arr.put("download_seq", dwldCouponData.get("download_seq"));
download_arr.put("coupon_site", dwldCouponData.get("coupon_site"));
download_arr.put("coupon_num", dwldCouponData.get("coupon_num"));
log.debug("@@@@@@@@@@@@@@@@11 download_arr 으로 전환 후 :: {}", download_arr);
if (!ObjectUtils.isEmpty(coupon.get("COUPON_SALE"))) {
String couponSaleStr = coupon.get("COUPON_SALE") == null || coupon.get("COUPON_SALE") == "" ? "0" : String.valueOf(coupon.get("COUPON_SALE"));
double couponSaleDouble = Double.parseDouble(couponSaleStr);
int couponSale = (int) couponSaleDouble;
download_arr.put("coupon_sale", couponSale);
coupon_sale += couponSale;
}
log.debug("@@@@@@@@@@@@@@@@22 download_arr 으로 전환 후 :: {}", download_arr);
// coupon_sale += Integer.parseInt(String.valueOf(coupon.get("COUPON_SALE")));
downloadArrList.add(download_arr);
log.debug("@@@@@@@@@@@@@@@@ downloadArrList 으로 전환 후 :: {}", downloadArrList);
}
resMap.put("download_arr", downloadArrList);
resMap.put("coupon_sale", coupon_sale);
log.debug("쿠폰사용 결과 : {}", resMap);
return resMap;
}
/**
* 쿠폰 복원처리
* @param cmd : coupon_cancel
* @return map
*/
@Transactional
public Map<String, Object> coupon_cancel(BORtngudrefndVO cancelVO) throws WnbtPosRestException {
Map<String, Object> resMap = new HashMap<String, Object>();
log.info("포스 쿠폰 복원처리 : {}", cancelVO);
List<DataMap> cancelList = mapper.selectPosUseCouponListInqire(cancelVO);
for (DataMap cancel : cancelList) {
cancel.put("mbrInnb", cancelVO.getMbrInnb());
cancel.put("mbrDvCd", cancelVO.getMbrDvCd());
mapper.updatePosDwldCouponRecvryUpdt(cancel);
mapper.updatePosOrderCouponCancelUpdt(cancel);
}
return resMap;
}
}

View File

@@ -0,0 +1,444 @@
package com.wb.domainserver.domain.gcone.pos.pos.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wb.domainserver.domain.gcone.mbr.mlg.service.BOPosMlgService;
import com.wb.domainserver.domain.gcone.pos.easywell.service.EasyWellService;
import com.wb.domainserver.domain.gcone.pos.pos.mapper.PosMapper;
import com.wb.domainserver.exception.WnbtPosRestException;
import com.wb.domainserver.exception.code.PosCode;
import com.wb.domainserver.util.dataaccess.DataMap;
import com.wb.domainserver.util.string.StringUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
@Service
@RequiredArgsConstructor
public class PosService {
@Autowired
private PosMapper mapper;
@Autowired
private PosOrderService posOrderService;
@Autowired
private EasyWellService easyWellService;
@Autowired
private BOPosMlgService boPosMlgService;
@Autowired
private PosCouponService posCouponService;
private final ObjectMapper objectMapper;
/**
* 포스 공통 체크
* 매장정보
* Uid 인증
* 매출코드 변환
*
* @param reqMap 요청값
*/
@Transactional
public void selectBOPosCommChk(Map<String, Object> reqMap) {
/*
D 예시=>
{cmd=member_search,
poscode=01,
search_item=cp,
search_key=01066431580,
storecode=E7T000036,
pgubun=E7T,
pcode=000036}
**/
if(reqMap.containsKey("provider_status")){
String providerStatus = String.valueOf(reqMap.get("provider_status"));
if(providerStatus.equals("Y")){ //개점
reqMap.put("provider_status", "02");
}else if (providerStatus.equals("N")){ //폐점
reqMap.put("provider_status", "03");
}else{ // 준비중
reqMap.put("provider_status", "01");
}
}
// 매장 정보
DataMap strInfo = mapper.selectBOPosStrSrch(reqMap);
//매장정보 없을 경우
if(ObjectUtils.isEmpty(strInfo)){
throw new WnbtPosRestException(PosCode.NO_STORE_INFO);
}
DataMap memInfo = new DataMap();
// uid 인증
if(reqMap.containsKey("uid") && !ObjectUtils.isEmpty(reqMap.get("uid")) && !"member_regist".equals(reqMap.get("cmd"))){
//회원 정보 검색
Map<String, Object> mbrList = new HashMap<>();
mbrList.put("search_key", reqMap.get("uid"));
mbrList.put("storecode", reqMap.get("storecode"));
mbrList.put("secretKey", reqMap.get("secretKey"));
mbrList.put("search_item", "uid");
List<DataMap> memberList = mapper.selectBOPosMbrList(mbrList);
log.debug("memberList :: {}", memberList);
Map<String, Object> mbrStrVisitMap = new HashMap<>();
try{
if(!CollectionUtils.isEmpty(memberList)){
memInfo = memberList.get(0);
//회원정보 검색 완료 후 오픈 어느 매장에 방문했는지 기록
mbrStrVisitMap.put("posStrInnb", strInfo.get("strInnb"));
mbrStrVisitMap.put("useq", memInfo.get("useq"));
mbrStrVisitMap.put("sopmalCd", reqMap.get("sopmalCd"));
mapper.updateMbrStrVisit(mbrStrVisitMap);
}else{
//회원 없을 경우
memInfo = new DataMap();
memInfo.put("useq", "0");
memInfo.put("mbrDvCd", "");
}
}catch (RuntimeException re){
log.error(re.getMessage());
}
}else{
//회원 없을 경우
memInfo = new DataMap();
memInfo.put("useq", "0");
memInfo.put("mbrDvCd", "");
}
// 매출코드 변환 (ocode)
// - 포스전표코드 : 년월일(8)+매출번호(6) = 14자리 (20160511000012)
// - 매출코드 : 매장구분(1)+매장번호(5)+'-'+포스번호(2)+'-'+포스전표코드(14) = 24자리 (J00002-01-20160511000027)
if (!ObjectUtils.isEmpty(reqMap.get("ocode"))) {
String ocode = String.valueOf(reqMap.get("ocode"));
String orderDate1 =ocode.substring(0, 8);
reqMap.put("order_date1", orderDate1);
int orderNumb = Integer.parseInt(ocode.substring(8));
reqMap.put("order_numb", orderNumb);
String pnumb = String.format("%06d", orderNumb);
reqMap.put("pnumb", pnumb);
}
reqMap.put("strInfo", strInfo);
reqMap.put("memInfo", memInfo);
}
/**
* 회원정보 검색
*
* @param reqMap 요청값
* @return map
*/
@Transactional
public Map<String, Object> member_search(Map<String, Object> reqMap){
Map<String, Object> resultMap = new HashMap<String, Object>();
Map<String, Object> data = new HashMap<>();
try {
//검색항목 없으면
if (StringUtil.isEmpty((String) reqMap.get("search_item"))) {
throw new WnbtPosRestException(PosCode.NO_SEARCH_ITEM);
}
//검색어없으면
if (StringUtil.isEmpty((String) reqMap.get("search_key"))) {
throw new WnbtPosRestException(PosCode.INPUT_CHECK);
}else{
//뒷 번호 4자리 검색
if("cp".equals(reqMap.get("search_item"))){
String mbtlnb = (String) reqMap.get("search_key");
mbtlnb = mbtlnb.replace("-","");
int mbtlnbLen = mbtlnb.length();
if(mbtlnbLen < 11){//휴대폰번호 전체 아닐 시
throw new WnbtPosRestException(PosCode.BAD_SEARCH_KEY);
}else{
//핸드폰 번호 검색조건 정합성 체크
if(mbtlnbLen != 10 && mbtlnbLen != 11){
throw new WnbtPosRestException(PosCode.BAD_SEARCH_KEY);
}else{
reqMap.put("accrateSc","Y");
}
//핸드폰 번호 블랙리스트 체크
int appnCnt = mapper.selectPosMbrAppn(reqMap);
if(appnCnt > 0){
String cp = "판매금지 고객입니다.("+(String) reqMap.get("search_key")+")";
throw new WnbtPosRestException(PosCode.CUSTOM_MSG,cp,"bad_consumer");
}
}
}
}
//회원 건수 조회
int cnt = mapper.selectPosMbrCnt(reqMap);
data.put("cnt", cnt);
List<DataMap> memberList = new ArrayList<>();
if (cnt > 0) {//회원있는 경우
if(cnt > 30){
throw new WnbtPosRestException(PosCode.TOO_MANY_RESULT);
}else{
memberList = mapper.selectBOPosMbrList(reqMap);
data.put("member_list", memberList);
}
}else{//없는 경우
String noMbr = "사용자 정보를 읽을 수 없습니다.("+(String) reqMap.get("search_key")+")";
throw new WnbtPosRestException(PosCode.CUSTOM_MSG,noMbr,"no_member_data");
}
}catch (WnbtPosRestException wpe){
throw wpe;
} catch (RuntimeException re) {
log.error(re.getMessage());
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
resultMap.put("data", data);
return resultMap;
}
/**
* 마일리지 적립
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> point_add(Map<String, Object> reqMap){
Map<String, Object> resultMap = new HashMap<>();
Map<String, Object> data = new HashMap<>();
data = boPosMlgService.insertBOPosMlgAdd(reqMap);
resultMap.put("data", data);
return resultMap;
}
/**
* 마일리지 적립 취소
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> point_add_cancel(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
Map<String, Object> data = new HashMap<>();
data = boPosMlgService.insertBOPosMlgAddCancl(reqMap);
resultMap.put("data", data);
return resultMap;
}
/**
* 마일리지 사용
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> point_use(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
Map<String, Object> data = new HashMap<>();
data = boPosMlgService.insertBOPosMlgUse(reqMap);
resultMap.put("data", data);
return resultMap;
}
/**
* 마일리지 사용 취소
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> point_use_cancel(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
Map<String, Object> data = new HashMap<>();
data = boPosMlgService.insertBOPosMlgUseCancl(reqMap);
resultMap.put("data", data);
return resultMap;
}
/**
* 매출 검색
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> order_search(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
try {
resultMap = posOrderService.order_search(reqMap);
} catch(WnbtPosRestException wpe) {
log.debug("주문 검색 실패");
log.error(wpe.getMsg());
throw wpe;
}
log.info("주문 검색 성공 : {}", resultMap);
return resultMap;
}
/**
* 매출 등록
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> order_add(Map<String, Object> reqMap) throws Exception {
Map<String, Object> resultMap = new HashMap<>();
//받는 정보
//data - master
//data - datail_arr[] : 상품정보
//data - promdt_arr[] : 프로모션정보
//data - coupon_arr[] : 쿠폰정보
log.debug("dat :::::: {}", reqMap.get("data"));
// LinkedHashMap data = (LinkedHashMap) reqMap.get("data");
//
// LinkedHashMap dataMaster = (LinkedHashMap) data.get("master");
LinkedHashMap data = new LinkedHashMap();
if(reqMap.containsKey("data")) {
String dataJson = String.valueOf(reqMap.get("data"));
data = objectMapper.readValue(dataJson, LinkedHashMap.class);
} else {
throw new WnbtPosRestException(PosCode.INTERNAL_SERVER_ERROR);
}
LinkedHashMap dataMaster = (LinkedHashMap) data.get("master");
log.debug("dataMaster: {}", dataMaster);
if(ObjectUtils.isEmpty(dataMaster)){
throw new WnbtPosRestException(PosCode.NO_MASTER);
}
List<LinkedHashMap> dataDatilArr = (List<LinkedHashMap>) data.get("detail_arr");
if (ObjectUtils.isEmpty(dataDatilArr)) {
throw new WnbtPosRestException(PosCode.NO_DETAIL_ARR);
}
if (dataMaster.get("BANGBN").equals("1")) { // 반품 여부 (1) : 취소된 원거래 영수증의 정보가 수정되어 재 전송된 것 -> 별도 처리 없이 패스
resultMap.put("status", "Y");
resultMap.put("msg", "");
return resultMap;
}
Date pDate = new SimpleDateFormat("yyyyMMdd").parse(dataMaster.get("ILJA").toString());
String formattedPDate = new SimpleDateFormat("yyyy-MM-dd").format(pDate);
reqMap.put("pdate", formattedPDate);
if (dataMaster.get("PANGBN").equals("00")) { //00:판매, 10:반품
resultMap = posOrderService.order_insert(reqMap);
} else {
resultMap = posOrderService.refund_insert(reqMap);
}
return resultMap;
}
/**
* 쿠폰검사
*
* @param reqMap 요청값
* @return map
*/
@Transactional
public Map<String, Object> coupon_check(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
try {
resultMap = posCouponService.coupon_check(reqMap);
} catch(WnbtPosRestException wpe) {
log.debug("쿠폰 검사 실패");
log.error(wpe.getMsg());
throw wpe;
}
resultMap.put("data", resultMap.get("data"));
resultMap.put("err", "0000");
log.info("쿠폰 검사 성공 : {}", resultMap);
return resultMap;
}
/**
* 쿠폰 사용처리
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> coupon_use(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
try {
resultMap = posCouponService.coupon_use(reqMap);
} catch(WnbtPosRestException wpe) {
log.debug("쿠폰 사용처리 실패");
log.error(wpe.getMsg());
throw wpe;
}
log.info("쿠폰 사용처리 성공 : {}", resultMap);
return resultMap;
}
/**
* 이지웰페이 조회
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> ew_check(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("data", easyWellService.ew_check(reqMap));
return resultMap;
}
/**
* 이지웰페이 사용
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> ew_use(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("data", easyWellService.ew_use(reqMap));
return resultMap;
}
/**
* 이지웰페이 사용취소
*
* @param reqMap 요청값
* @return map
*/
public Map<String, Object> ew_cancel(Map<String, Object> reqMap) {
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("data", easyWellService.ew_cancel(reqMap));
return resultMap;
}
}

View File

@@ -0,0 +1,103 @@
package com.wb.domainserver.domain.gcone.pos.pos.vo;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class BOPosVO {
private static final Map<String, Map<String, String>> posBrandCode = new HashMap<>();
static {
// 초기화: 동적으로 값을 추가
posBrandCode.put("E07", Map.ofEntries( // GC 직가맹
Map.entry("001", "CH"),
Map.entry("002", "TZ"),
Map.entry("003", "NC"),
Map.entry("004", "PL"),
Map.entry("005", "NB"),
Map.entry("006", "JM"),
Map.entry("007", "OY"),
Map.entry("008", "AF"),
Map.entry("009", "VN"),
Map.entry("010", "DL"),
Map.entry("011", "CO"),
Map.entry("012", "NC2"), // 증정품 차액 공급가
Map.entry("013", "PL2"), // 증정품 차액 공급가
Map.entry("014", "CN"),
Map.entry("015", "DT"),
Map.entry("016", "BD"),
Map.entry("017", "LF"),
Map.entry("018", "SC") // 실버케어
));
posBrandCode.put("EX2", Map.ofEntries( // GC 유통
Map.entry("001", "NC"),
Map.entry("002", "PL"),
Map.entry("003", "NB"),
Map.entry("004", "CH"),
Map.entry("005", "TZ"),
Map.entry("006", "WF"),
Map.entry("007", "OY"),
Map.entry("008", "CO"),
Map.entry("009", "VN"),
Map.entry("010", "AF"),
Map.entry("011", "BD"),
Map.entry("012", "DT")
));
posBrandCode.put("E7T", Map.ofEntries( // SL 직가맹
Map.entry("001", "NC"),
Map.entry("002", "PL"),
Map.entry("003", "TZ"),
Map.entry("004", "CH"),
Map.entry("005", "NB"),
Map.entry("006", "AF"),
Map.entry("007", "VN"),
Map.entry("008", "JM"),
Map.entry("009", "CO"),
Map.entry("010", "DT"),
Map.entry("011", "DL")
));
posBrandCode.put("EX3", Map.ofEntries( // SL 유통
Map.entry("001", "NC"),
Map.entry("002", "PL"),
Map.entry("003", "NB"),
Map.entry("004", "CH"),
Map.entry("005", "TZ"),
Map.entry("006", "ETC"), // 유료 쇼핑백
Map.entry("007", "CO"),
Map.entry("008", "BD"),
Map.entry("009", "VN"),
Map.entry("010", "AF"),
Map.entry("011", "OY"),
Map.entry("012", "BD"),
Map.entry("013", "DT"),
Map.entry("014", "CO"),
Map.entry("015", "DL")
));
}
public static Map<String, String> getValues(String key) {
return posBrandCode.getOrDefault(key, Collections.emptyMap());
}
public static String getValue(String key, String subKey) {
return posBrandCode.getOrDefault(key, Collections.emptyMap()).get(subKey);
}
public static void main(String[] args) {
// A의 데이터 출력
System.out.println("E07: " + getValues("E07"));
// 특정 키의 값 출력
String specificValue = getValue("EX3", "011");
System.out.println("EX3 - 011: " + specificValue);
// 전체 데이터 순회
for (Map.Entry<String, Map<String, String>> entry : posBrandCode.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}