diff --git a/src/com/pms/api/SalesSlipApiClient.java b/src/com/pms/api/SalesSlipApiClient.java
new file mode 100644
index 0000000..3e25515
--- /dev/null
+++ b/src/com/pms/api/SalesSlipApiClient.java
@@ -0,0 +1,500 @@
+package com.pms.api;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.security.cert.X509Certificate;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import org.apache.commons.codec.binary.Base64;
+import java.util.Random;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 아마란스10 자동전표데이터등록 API 클라이언트
+ * 매출마감 시 회계전표를 ERP에 자동 등록한다.
+ * API: /apiproxy/api11A10
+ */
+public class SalesSlipApiClient {
+
+ private static final String API_URL = "~/apiproxy/api11A10";
+ private static final String CALLER_NAME = "API_gcmsAmaranth40578";
+ private static final String ACCESS_TOKEN = "MN5KzKBWRAa92BPxDlRLl3GcsxeZXc";
+ private static final String HASH_KEY = "22519103205540290721741689643674301018832465";
+ private static final String GROUP_SEQ = "gcmsAmaranth40578";
+
+ // 회사코드 / 회계단위
+ public static final String CO_CD = "1000";
+ public static final String DIV_CD = "1000";
+
+ // 김하얀 사원코드 (전표 작성자)
+ public static final String INSERT_ID = "2024010";
+
+ // 영업팀 부서코드
+ public static final String SALES_DEPT_CD = "004";
+
+ // 계정과목 코드 (기본값, DB erp_acct_code에서 조회하여 덮어쓸 수 있음)
+ public static final String DEFAULT_ACCT_ACCOUNTS_RECEIVABLE = "1080000"; // 외상매출금
+ public static final String DEFAULT_ACCT_VAT_COLLECTED = "2550000"; // 부가세예수금
+ public static final String DEFAULT_ACCT_PRODUCT_SALES = "4040000"; // 제품매출
+
+ // 실제 사용할 계정코드 (Service에서 DB 조회 후 설정)
+ private String acctAccountsReceivable = DEFAULT_ACCT_ACCOUNTS_RECEIVABLE;
+ private String acctVatCollected = DEFAULT_ACCT_VAT_COLLECTED;
+ private String acctProductSales = DEFAULT_ACCT_PRODUCT_SALES;
+
+ /**
+ * DB에서 조회한 계정과목 코드를 설정한다.
+ * erp_acct_code 테이블에서 api11A02로 동기화된 값을 사용.
+ */
+ public void setAccountCodes(String accountsReceivable, String vatCollected, String productSales) {
+ if (accountsReceivable != null && !accountsReceivable.isEmpty()) {
+ this.acctAccountsReceivable = accountsReceivable;
+ }
+ if (vatCollected != null && !vatCollected.isEmpty()) {
+ this.acctVatCollected = vatCollected;
+ }
+ if (productSales != null && !productSales.isEmpty()) {
+ this.acctProductSales = productSales;
+ }
+ System.out.println("[SalesSlipApi] 계정과목 설정 - 외상매출금: " + this.acctAccountsReceivable
+ + ", 부가세예수금: " + this.acctVatCollected
+ + ", 제품매출: " + this.acctProductSales);
+ }
+
+ // 증빙코드
+ public static final String ATTR_TAX_INVOICE = "1"; // 세금계산서
+ public static final String ATTR_ETC = "9"; // 기타
+
+ // 세무구분
+ public static final String TAX_FG_DOMESTIC = "11"; // 과세-세금계산서
+ public static final String TAX_FG_EXPORT = "12"; // 영세-수출
+
+ // 전표유형
+ public static final String DOCU_TY_SALES = "3"; // 매출
+
+ // 차대구분
+ public static final String DRCR_DEBIT = "3"; // 차변
+ public static final String DRCR_CREDIT = "4"; // 대변
+
+ /**
+ * 자동전표 데이터를 아마란스에 등록한다.
+ *
+ * @param baseUrl API 서버 기본 URL (https://erp.rps-korea.com)
+ * @param requestBody 전표 데이터 JSON 문자열
+ * @return API 응답 JSON 문자열
+ * @throws Exception API 호출 실패
+ */
+ public String registerSalesSlip(String baseUrl, String requestBody) throws Exception {
+ if (requestBody == null || requestBody.trim().isEmpty()) {
+ throw new IllegalArgumentException("전표 데이터(requestBody)는 필수입니다.");
+ }
+
+ System.setProperty("https.protocols", "TLSv1.2");
+
+ TrustManager[] trustAllCerts = new TrustManager[] {
+ new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() { return null; }
+ public void checkClientTrusted(X509Certificate[] certs, String authType) {}
+ public void checkServerTrusted(X509Certificate[] certs, String authType) {}
+ }
+ };
+
+ SSLContext sc = SSLContext.getInstance("TLS");
+ sc.init(null, trustAllCerts, new java.security.SecureRandom());
+ HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+ HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
+ public boolean verify(String hostname, javax.net.ssl.SSLSession session) {
+ return true;
+ }
+ });
+
+ String urlPath = API_URL.replace("~", "");
+ String cleanBaseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
+ String fullUrl = cleanBaseUrl + urlPath;
+
+ System.out.println("[SalesSlipApi] 요청 URL: " + fullUrl);
+ System.out.println("[SalesSlipApi] 요청 Body: " + requestBody);
+
+ URL url = new URL(fullUrl);
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+
+ connection.setConnectTimeout(30000);
+ connection.setReadTimeout(30000);
+ connection.setInstanceFollowRedirects(false);
+
+ try {
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
+ connection.setRequestProperty("Accept", "application/json");
+
+ connection.setRequestProperty("callerName", CALLER_NAME);
+ connection.setRequestProperty("Authorization", "Bearer " + ACCESS_TOKEN);
+
+ String transactionId = generateTransactionId();
+ connection.setRequestProperty("transaction-id", transactionId);
+
+ String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
+ connection.setRequestProperty("timestamp", timestamp);
+
+ connection.setRequestProperty("groupSeq", GROUP_SEQ);
+
+ String wehagoSign = generateWehagoSign(ACCESS_TOKEN, transactionId, timestamp, urlPath);
+ connection.setRequestProperty("wehago-sign", wehagoSign);
+
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+
+ OutputStreamWriter writer = new OutputStreamWriter(
+ connection.getOutputStream(), StandardCharsets.UTF_8);
+ writer.write(requestBody);
+ writer.flush();
+ writer.close();
+
+ int responseCode = connection.getResponseCode();
+
+ // 리다이렉트 처리
+ if (responseCode == 301 || responseCode == 302 || responseCode == 303 ||
+ responseCode == 307 || responseCode == 308) {
+ String location = connection.getHeaderField("Location");
+ connection.disconnect();
+
+ if (location != null) {
+ URL redirectUrl = new URL(location);
+ connection = (HttpURLConnection) redirectUrl.openConnection();
+ connection.setConnectTimeout(30000);
+ connection.setReadTimeout(30000);
+ connection.setInstanceFollowRedirects(false);
+ connection.setRequestMethod("POST");
+ connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
+ connection.setRequestProperty("Accept", "application/json");
+ connection.setRequestProperty("callerName", CALLER_NAME);
+ connection.setRequestProperty("Authorization", "Bearer " + ACCESS_TOKEN);
+ connection.setRequestProperty("transaction-id", transactionId);
+ connection.setRequestProperty("timestamp", timestamp);
+ connection.setRequestProperty("groupSeq", GROUP_SEQ);
+ connection.setRequestProperty("wehago-sign", wehagoSign);
+
+ connection.setDoOutput(true);
+ connection.setDoInput(true);
+
+ OutputStreamWriter redirectWriter = new OutputStreamWriter(
+ connection.getOutputStream(), StandardCharsets.UTF_8);
+ redirectWriter.write(requestBody);
+ redirectWriter.flush();
+ redirectWriter.close();
+
+ responseCode = connection.getResponseCode();
+ }
+ }
+
+ BufferedReader reader = null;
+ StringBuilder response = new StringBuilder();
+
+ try {
+ if (responseCode >= 200 && responseCode < 300) {
+ reader = new BufferedReader(new InputStreamReader(
+ connection.getInputStream(), StandardCharsets.UTF_8));
+ } else {
+ java.io.InputStream errorStream = connection.getErrorStream();
+ if (errorStream != null) {
+ reader = new BufferedReader(new InputStreamReader(
+ errorStream, StandardCharsets.UTF_8));
+ } else {
+ throw new Exception("전표등록 API 호출 실패: HTTP " + responseCode);
+ }
+ }
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ response.append(line);
+ }
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+
+ String responseStr = response.toString();
+ System.out.println("[SalesSlipApi] 응답 코드: " + responseCode);
+ System.out.println("[SalesSlipApi] 응답 Body: " + responseStr);
+
+ if (responseCode >= 200 && responseCode < 300) {
+ return responseStr;
+ } else {
+ throw new Exception("전표등록 API 호출 실패: HTTP " + responseCode + " - " + responseStr);
+ }
+
+ } finally {
+ connection.disconnect();
+ }
+ }
+
+ /**
+ * 국내 매출전표 JSON 생성 (세금계산서)
+ *
+ * @param menuDt 작성일자 (yyyyMMdd, 세금계산서발행일)
+ * @param menuSq 작성번호 (동일 일자 내 고유)
+ * @param slipTitle 전표제목 (거래처명_품명)
+ * @param trCd 거래처코드 (client_mng.client_cd)
+ * @param trNm 거래처명
+ * @param totalAmount 총액 (공급가액 + 부가세)
+ * @param vatAmount 부가세
+ * @param supplyAmount 공급가액
+ * @param itemSummary 적요 (품명)
+ * @param taxFg 세무구분코드 (convertTaxType으로 변환한 값)
+ * @return 전표 JSON 문자열
+ */
+ public String buildDomesticSlipJson(String menuDt, int menuSq, String slipTitle,
+ String trCd, String trNm,
+ long totalAmount, long vatAmount, long supplyAmount,
+ String itemSummary, String taxFg) {
+ StringBuilder json = new StringBuilder();
+ json.append("{");
+ json.append("\"coCd\":\"").append(CO_CD).append("\"");
+ json.append(",\"groupSeq\":\"").append(GROUP_SEQ).append("\"");
+ json.append(",\"data\":[");
+
+ // Line 1: 차변 외상매출금 (총액)
+ json.append("{");
+ json.append("\"inDivCd\":\"").append(DIV_CD).append("\"");
+ json.append(",\"menuDt\":\"").append(escapeJson(menuDt)).append("\"");
+ json.append(",\"menuSq\":").append(menuSq);
+ json.append(",\"menuLnSq\":1");
+ json.append(",\"isuDoc\":\"").append(escapeJson(slipTitle)).append("\"");
+ json.append(",\"docuTy\":\"").append(DOCU_TY_SALES).append("\"");
+ json.append(",\"drcrFg\":\"").append(DRCR_DEBIT).append("\"");
+ json.append(",\"acctCd\":\"").append(acctAccountsReceivable).append("\"");
+ json.append(",\"trCd\":\"").append(escapeJson(trCd)).append("\"");
+ json.append(",\"trNm\":\"").append(escapeJson(trNm)).append("\"");
+ json.append(",\"acctAm\":").append(totalAmount);
+ json.append(",\"attrCd\":\"").append(ATTR_TAX_INVOICE).append("\"");
+ json.append(",\"rmkDc\":\"").append(escapeJson(itemSummary)).append("\"");
+ json.append(",\"ctDept\":\"").append(SALES_DEPT_CD).append("\"");
+ json.append(",\"insertId\":\"").append(INSERT_ID).append("\"");
+ json.append(",\"exFg\":\"1\"");
+ json.append("}");
+
+ // Line 2: 대변 부가세예수금 (부가세)
+ json.append(",{");
+ json.append("\"inDivCd\":\"").append(DIV_CD).append("\"");
+ json.append(",\"menuDt\":\"").append(escapeJson(menuDt)).append("\"");
+ json.append(",\"menuSq\":").append(menuSq);
+ json.append(",\"menuLnSq\":2");
+ json.append(",\"isuDoc\":\"").append(escapeJson(slipTitle)).append("\"");
+ json.append(",\"docuTy\":\"").append(DOCU_TY_SALES).append("\"");
+ json.append(",\"drcrFg\":\"").append(DRCR_CREDIT).append("\"");
+ json.append(",\"acctCd\":\"").append(acctVatCollected).append("\"");
+ json.append(",\"trCd\":\"").append(escapeJson(trCd)).append("\"");
+ json.append(",\"trNm\":\"").append(escapeJson(trNm)).append("\"");
+ json.append(",\"acctAm\":").append(vatAmount);
+ json.append(",\"attrCd\":\"").append(ATTR_TAX_INVOICE).append("\"");
+ json.append(",\"rmkDc\":\"").append(escapeJson(itemSummary)).append("\"");
+ json.append(",\"taxFg\":\"").append(escapeJson(taxFg)).append("\"");
+ json.append(",\"jeonjaYn\":\"1\"");
+ json.append(",\"supAm\":").append(supplyAmount);
+ json.append(",\"ctDept\":\"").append(SALES_DEPT_CD).append("\"");
+ json.append(",\"insertId\":\"").append(INSERT_ID).append("\"");
+ json.append(",\"exFg\":\"1\"");
+ json.append("}");
+
+ // Line 3: 대변 제품매출 (공급가액)
+ json.append(",{");
+ json.append("\"inDivCd\":\"").append(DIV_CD).append("\"");
+ json.append(",\"menuDt\":\"").append(escapeJson(menuDt)).append("\"");
+ json.append(",\"menuSq\":").append(menuSq);
+ json.append(",\"menuLnSq\":3");
+ json.append(",\"isuDoc\":\"").append(escapeJson(slipTitle)).append("\"");
+ json.append(",\"docuTy\":\"").append(DOCU_TY_SALES).append("\"");
+ json.append(",\"drcrFg\":\"").append(DRCR_CREDIT).append("\"");
+ json.append(",\"acctCd\":\"").append(acctProductSales).append("\"");
+ json.append(",\"trCd\":\"").append(escapeJson(trCd)).append("\"");
+ json.append(",\"trNm\":\"").append(escapeJson(trNm)).append("\"");
+ json.append(",\"acctAm\":").append(supplyAmount);
+ json.append(",\"attrCd\":\"").append(ATTR_TAX_INVOICE).append("\"");
+ json.append(",\"rmkDc\":\"").append(escapeJson(itemSummary)).append("\"");
+ json.append(",\"ctDept\":\"").append(SALES_DEPT_CD).append("\"");
+ json.append(",\"insertId\":\"").append(INSERT_ID).append("\"");
+ json.append(",\"exFg\":\"1\"");
+ json.append("}");
+
+ json.append("]}");
+ return json.toString();
+ }
+
+ /**
+ * 해외 매출전표 JSON 생성 (수출)
+ *
+ * @param menuDt 작성일자 (yyyyMMdd, 선적일자)
+ * @param menuSq 작성번호
+ * @param slipTitle 전표제목 (거래처명_품명_외화총액_환율)
+ * @param trCd 거래처코드
+ * @param trNm 거래처명
+ * @param krwTotalAmount 원화총액
+ * @param exchCd 환종코드 (USD, JPY 등)
+ * @param exchangeRate 환율
+ * @param foreignAmount 외화금액
+ * @param exportDeclNo 수출신고필증 신고번호
+ * @param loadingDate 선적일자 (yyyyMMdd)
+ * @param itemSummary 적요
+ * @return 전표 JSON 문자열
+ */
+ public String buildOverseasSlipJson(String menuDt, int menuSq, String slipTitle,
+ String trCd, String trNm,
+ long krwTotalAmount,
+ String exchCd, double exchangeRate, double foreignAmount,
+ String exportDeclNo, String loadingDate,
+ String itemSummary, String taxFg) {
+ StringBuilder json = new StringBuilder();
+ json.append("{");
+ json.append("\"coCd\":\"").append(CO_CD).append("\"");
+ json.append(",\"groupSeq\":\"").append(GROUP_SEQ).append("\"");
+ json.append(",\"data\":[");
+
+ // Line 1: 차변 외상매출금 (원화총액)
+ json.append("{");
+ json.append("\"inDivCd\":\"").append(DIV_CD).append("\"");
+ json.append(",\"menuDt\":\"").append(escapeJson(menuDt)).append("\"");
+ json.append(",\"menuSq\":").append(menuSq);
+ json.append(",\"menuLnSq\":1");
+ json.append(",\"isuDoc\":\"").append(escapeJson(slipTitle)).append("\"");
+ json.append(",\"docuTy\":\"").append(DOCU_TY_SALES).append("\"");
+ json.append(",\"drcrFg\":\"").append(DRCR_DEBIT).append("\"");
+ json.append(",\"acctCd\":\"").append(acctAccountsReceivable).append("\"");
+ json.append(",\"trCd\":\"").append(escapeJson(trCd)).append("\"");
+ json.append(",\"trNm\":\"").append(escapeJson(trNm)).append("\"");
+ json.append(",\"acctAm\":").append(krwTotalAmount);
+ json.append(",\"attrCd\":\"").append(ATTR_ETC).append("\"");
+ json.append(",\"rmkDc\":\"").append(escapeJson(itemSummary)).append("\"");
+ json.append(",\"ctDept\":\"").append(SALES_DEPT_CD).append("\"");
+ json.append(",\"insertId\":\"").append(INSERT_ID).append("\"");
+ json.append(",\"exFg\":\"1\"");
+ json.append("}");
+
+ // Line 2: 대변 제품매출 (원화총액) — 해외는 제품매출이 2번
+ json.append(",{");
+ json.append("\"inDivCd\":\"").append(DIV_CD).append("\"");
+ json.append(",\"menuDt\":\"").append(escapeJson(menuDt)).append("\"");
+ json.append(",\"menuSq\":").append(menuSq);
+ json.append(",\"menuLnSq\":2");
+ json.append(",\"isuDoc\":\"").append(escapeJson(slipTitle)).append("\"");
+ json.append(",\"docuTy\":\"").append(DOCU_TY_SALES).append("\"");
+ json.append(",\"drcrFg\":\"").append(DRCR_CREDIT).append("\"");
+ json.append(",\"acctCd\":\"").append(acctProductSales).append("\"");
+ json.append(",\"trCd\":\"").append(escapeJson(trCd)).append("\"");
+ json.append(",\"trNm\":\"").append(escapeJson(trNm)).append("\"");
+ json.append(",\"acctAm\":").append(krwTotalAmount);
+ json.append(",\"attrCd\":\"").append(ATTR_ETC).append("\"");
+ json.append(",\"rmkDc\":\"").append(escapeJson(itemSummary)).append("\"");
+ json.append(",\"ctDept\":\"").append(SALES_DEPT_CD).append("\"");
+ json.append(",\"insertId\":\"").append(INSERT_ID).append("\"");
+ json.append(",\"exFg\":\"1\"");
+ json.append("}");
+
+ // Line 3: 대변 부가세예수금 (0원) + 수출 부가세 정보
+ json.append(",{");
+ json.append("\"inDivCd\":\"").append(DIV_CD).append("\"");
+ json.append(",\"menuDt\":\"").append(escapeJson(menuDt)).append("\"");
+ json.append(",\"menuSq\":").append(menuSq);
+ json.append(",\"menuLnSq\":3");
+ json.append(",\"isuDoc\":\"").append(escapeJson(slipTitle)).append("\"");
+ json.append(",\"docuTy\":\"").append(DOCU_TY_SALES).append("\"");
+ json.append(",\"drcrFg\":\"").append(DRCR_CREDIT).append("\"");
+ json.append(",\"acctCd\":\"").append(acctVatCollected).append("\"");
+ json.append(",\"trCd\":\"").append(escapeJson(trCd)).append("\"");
+ json.append(",\"trNm\":\"").append(escapeJson(trNm)).append("\"");
+ json.append(",\"acctAm\":0");
+ json.append(",\"attrCd\":\"").append(ATTR_ETC).append("\"");
+ json.append(",\"rmkDc\":\"").append(escapeJson(itemSummary)).append("\"");
+ // 부가세 수출 관련 필드
+ json.append(",\"taxFg\":\"").append(escapeJson(taxFg)).append("\"");
+ json.append(",\"issDt\":\"").append(escapeJson(loadingDate)).append("\"");
+ json.append(",\"dummy1\":\"").append(escapeJson(exchCd)).append("\"");
+ json.append(",\"billAm\":").append(exchangeRate);
+ json.append(",\"cashAm\":").append(foreignAmount);
+ json.append(",\"supAm\":").append(krwTotalAmount);
+ json.append(",\"ctNb\":\"").append(escapeJson(exportDeclNo)).append("\"");
+ json.append(",\"ctDept\":\"").append(SALES_DEPT_CD).append("\"");
+ json.append(",\"insertId\":\"").append(INSERT_ID).append("\"");
+ json.append(",\"exFg\":\"1\"");
+ json.append("}");
+
+ json.append("]}");
+ return json.toString();
+ }
+
+ /**
+ * PLM 환종 code_id → 아마란스 ISO 환종코드 변환
+ */
+ /**
+ * PLM 과세구분 code_id → 아마란스 세무구분(taxFg) 변환
+ * 부가세 라인에만 세무구분이 들어감
+ */
+ public static String convertTaxType(String plmTaxTypeCodeId) {
+ if (plmTaxTypeCodeId == null) return "";
+ switch (plmTaxTypeCodeId) {
+ case "0900216": return "11"; // 과세매출 → 과세-세금계산서
+ case "0900217": return "12"; // 수출 → 영세-수출
+ case "0900218": return "51"; // 과세매입 → 과세-세금계산서(매입)
+ case "0900219": return "52"; // 영세매입 → 영세-수출(매입)
+ case "0900220": return "54"; // 수입
+ default: return "";
+ }
+ }
+
+ public static String convertCurrencyCode(String plmCurrencyCodeId) {
+ if (plmCurrencyCodeId == null) return "KRW";
+ switch (plmCurrencyCodeId) {
+ case "0001566": return "KRW";
+ case "0001534": return "USD";
+ case "0001537": return "JPY";
+ case "0001536": return "CNY";
+ case "0001535": return "EUR";
+ default: return "KRW";
+ }
+ }
+
+ private String escapeJson(String value) {
+ if (value == null) return "";
+ return value.replace("\\", "\\\\")
+ .replace("\"", "\\\"")
+ .replace("\n", "\\n")
+ .replace("\r", "\\r")
+ .replace("\t", "\\t");
+ }
+
+ private String generateTransactionId() {
+ String chars = "0123456789abcdef";
+ Random random = new Random();
+ StringBuilder sb = new StringBuilder(32);
+ for (int i = 0; i < 32; i++) {
+ sb.append(chars.charAt(random.nextInt(chars.length())));
+ }
+ return sb.toString();
+ }
+
+ private String generateWehagoSign(String accessToken, String transactionId,
+ String timestamp, String urlPath) throws Exception {
+ try {
+ String value = accessToken + transactionId + timestamp + urlPath;
+ SecretKeySpec keySpec = new SecretKeySpec(
+ HASH_KEY.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
+ Mac mac = Mac.getInstance("HmacSHA256");
+ mac.init(keySpec);
+ byte[] encrypted = mac.doFinal(value.getBytes(StandardCharsets.UTF_8));
+ return Base64.encodeBase64String(encrypted);
+ } catch (Exception e) {
+ System.err.println("[SalesSlipApi] Wehago-sign 생성 오류: " + e.getMessage());
+ e.printStackTrace();
+ throw e;
+ }
+ }
+}
diff --git a/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml b/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml
index 5c83660..1fb1c24 100644
--- a/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml
+++ b/src/com/pms/salesmgmt/mapper/salesNcollectMgmt.xml
@@ -2142,6 +2142,102 @@ ORDER BY T.REGDATE DESC, T.PROJECT_NO DESC
LOADING_DATE = #{loadingDate}
WHERE OBJID::VARCHAR = #{OBJID}
-
+
+
+
+
+
+
+
+
+
+
+
@@ -983,74 +984,341 @@ public MapsaveSaleRegistration(HttpServletRequest request, Map< * @param paramMap * @return */ - public Map salesDeadlineConfirm(HttpServletRequest request,Map paramMap){ + public Map salesDeadlineConfirm(HttpServletRequest request, Map paramMap) { Map resultMap = new HashMap(); - SqlSession sqlSession = SqlMapConfig.getInstance().getSqlSession(false); - try{ - System.out.println("===== 매출마감 처리 시작 ====="); - System.out.println("paramMap: " + paramMap); - + SqlSession sqlSession = null; + try { + System.out.println("===== 매출마감 + 아마란스 전표연동 시작 ====="); + String objIdListStr = CommonUtils.checkNull(paramMap.get("objIdList")); String deadlineDate = CommonUtils.checkNull(paramMap.get("deadlineDate")); - - System.out.println("objIdListStr: " + objIdListStr); - System.out.println("deadlineDate: " + deadlineDate); - - if(objIdListStr == null || objIdListStr.isEmpty()){ + + if (objIdListStr == null || objIdListStr.isEmpty()) { resultMap.put("result", false); resultMap.put("msg", "선택된 항목이 없습니다."); - System.out.println("에러: 선택된 항목 없음"); return resultMap; } - - if(deadlineDate == null || deadlineDate.isEmpty()){ + if (deadlineDate == null || deadlineDate.isEmpty()) { resultMap.put("result", false); resultMap.put("msg", "매출마감일을 입력해주세요."); - System.out.println("에러: 매출마감일 없음"); return resultMap; } - + String[] targetObjIdList = objIdListStr.split(","); - System.out.println("targetObjIdList 길이: " + targetObjIdList.length); - - if(null != targetObjIdList && 0 < targetObjIdList.length){ - HttpSession session = request.getSession(); - sqlSession = SqlMapConfig.getInstance().getSqlSession(); - PersonBean person = (PersonBean)session.getAttribute(Constants.PERSON_BEAN); - - String userId = person.getUserId(); - System.out.println("userId: " + userId); - - for(int i=0; i > slipDataList = new ArrayList