재무팀엔 많은 기능이 있는데 내가 맡은 기능은 총 3가지로
1. 계좌현황 및 관리
2. 자금관리
3. 예산관리
이다.
우선 계좌현황 및 관리에서 구현한 기능을 소개하려면 테이블 구조를 알아야 한다.
계좌현황/관리 | 사용 카테고리 | ||||||||
테이블명 | erp_account | ||||||||
Column | Description | Data Type | Length | Null | Initial Value | Primary Key | Foreign Key | Constraint | Remark |
칼럼명 | 설명 | 데이터 타입 | 길이 | 널(null)값 | 초기값 | 기본키 | 외래키 | 제약조건 | 비고 |
account_no | sequence | INT | O | ||||||
company_no | 회사 테이블 seq | INT | O | 계좌 소유: 회사명/회사코드 | |||||
account_bank | 은행 | VARCHAR | 50 | NOT NULL | |||||
account_type | 계좌종류 | VARCHAR | 30 | ||||||
account_num | 계좌번호 | VARCHAR | 50 | NOT NULL | UNIQUE | ||||
account_swift | SWIFT CODE | VARCHAR | 30 | NOT NULL | |||||
currency_no | 통화 테이블 seq | INT | O | KRW, USD, EUR, JYP | |||||
account_balance | 잔액 | INT | |||||||
account_exchange | 원화환산금액 | INT | |||||||
account_date | 가입일 | DATE | |||||||
team_nos | 팀명 나열 | VARCHAR |
팀 테이블의 name을 , 로 여러 개 불러옴
|
||||||
comcode_no | 회사코드(고객사) 테이블 seq | INT | O | 회사코드 부여 |
계좌 - 통화 테이블 | 사용 카테고리 | ||||||||
테이블명 | erp_currency | ||||||||
Column | Description | Data Type | Length | Null | Initial Value | Primary Key | Foreign Key | Constraint | Remark |
칼럼명 | 설명 | 데이터 타입 | 길이 | 널(null)값 | 초기값 | 기본키 | 외래키 | 제약조건 | 비고 |
currency_no | sequence | INT | O | ||||||
country_no | 국가 테이블 seq | INT | O | 국가명 | |||||
currency_name | 통화 | VARCHAR | 30 | KRW, USD, EUR, JYP | |||||
currency_rate | 적용환율 | DECIMAL(M,D) | api | ||||||
currency_date | 기준일자 | DATE | api |
이렇게 서로 참조를 하고 있는 테이블 구조이다.
해외거래처까지 다루는 ERP를 기획했다보니 원화뿐만 아니라 외화까지 다뤄야 하기에 통화테이블까지 만들었는데 이 환율과 적용일자는 관세청 공공 데이터 API를 이용하기로 했다.
https://www.data.go.kr/data/15101230/openapi.do
관세청_관세환율정보(GW)
관세법 제18조(과세환율)에 따른 과세환율입니다. 적용개시일자, 주간환율구분코드를 이용하여 관세환율정보서비스의 국가부호, 화폐단위명, 환율, 통화부호, 적용개시일자, 수출입구분 등을
www.data.go.kr
관세환율정보 API를 이용해 내가 구현하고 싶었던 기능은 계좌관리 페이지에 들어오게 되면 API가 실행이 되고 API내부에 있는 환율과 적용개시일자 정보를 통화테이블에 자동으로 INSERT를 시키며 INSERT를 할 때의 조건은 이미 입력된 적용개시일자에 따른 환율정보가 있다면 INSERT를 하지 않고 적용개시일자가 다를 때에만 INSERT를 시키도록 한다.
이때, UPDATE가 아닌 INSERT를 하는 이유는 재무상태표나 월말결산 등과 같이 보고를 할 때 해당일자에 대한 환율을 통해 계산된 원화환산금액이 필요하기 때문이다.
window.onload = function() {
// 환율 데이터 업데이트 함수 실행
updateExchangeRate();
// 주기적으로 업데이트 함수 호출 (예: 1시간마다)
setInterval(updateExchangeRate, 3600000); // 1시간마다 호출 (1시간 = 3600000 밀리초)
// 환율 데이터 업데이트 함수
function updateExchangeRate() {
// 오늘 날짜를 문자열로 변환
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return year + month + day;
}
// 오늘 날짜를 가져오기
const today = new Date();
const getDate = formatDate(today);
console.log(getDate);
// 환율 API 호출
var xhr = new XMLHttpRequest();
var url = 'http://apis.data.go.kr/1220000/retrieveTrifFxrtInfo/getRetrieveTrifFxrtInfo';
var queryParams = '?' + encodeURIComponent('serviceKey') + '=' + 'WjGespN29wux4Xj7jLxhXiLVM5JxvOfZUbZy7BVs%2B0JsYWmmqa8DgBDtuM50dvHb%2BQU3jR5Wa1UAB6%2F50Scuiw%3D%3D';
queryParams += '&' + encodeURIComponent('aplyBgnDt') + '=' + encodeURIComponent(getDate);
queryParams += '&' + encodeURIComponent('weekFxrtTpcd') + '=' + encodeURIComponent('1');
xhr.open('GET', url + queryParams);
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// API 호출 성공 시 데이터 처리
var responseXML = this.responseXML;
var items = responseXML.getElementsByTagName("item");
var jsonData = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
var itemData = {
fxrt: item.getElementsByTagName("fxrt")[0].textContent,
aplyBgnDt: item.getElementsByTagName("aplyBgnDt")[0].textContent,
cntySgn: item.getElementsByTagName("cntySgn")[0].textContent,
currSgn: item.getElementsByTagName("currSgn")[0].textContent,
// 기타 필요한 데이터 필드 추가
};
jsonData.push(itemData);
}
// 데이터를 컨트롤러로 전송
var formData = new FormData();
formData.append('jsonData', JSON.stringify(jsonData)); // JSON 데이터를 문자열로 변환하여 FormData에 추가
var com = document.getElementById("com").value;
var updateXhr = new XMLHttpRequest();
updateXhr.open('POST', "${pageContext.request.contextPath}/account/autoUpdate?comcode_code=" + com, true);
updateXhr.send(formData);
}
};
xhr.send('');
}
}
우선 해당 JavaScript의 전체 코드이다.
먼저 window.onload에 모든 js코드를 넣어 페이지가 LOAD되면 실행되도록 한다.
function updateExchangeRate() {
// 오늘 날짜를 문자열로 변환
function formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return year + month + day;
}
이 함수의 동작은
하나의 매개변수 date를 받고 이 매개변수는 형식화하려는 날짜를 나타낸다. 그리고 date.getFullYear()를 사용하여 주어진 date 객체에서 연도를 추출하고 이 값을 year 변수에 저장한다.
date.getMonth()를 호출하여 월을 가져온다. JavaScript의 월은 0부터 시작하므로, 1을 더해서 월을 실제 월로 변환한다. 그런 다음 String 함수를 사용하여 이 값을 문자열로 변환하고 padStart(2, '0') 메소드를 사용해서 월을 두 자리로 만든다.
예를 들어 1월은 '01'로, 10월은 '10'으로 변환되며 이 값을 month 변수에 저장한다.
date.getDate()를 호출하여 날짜를 가져온다. 그리고 padStart(2, '0') 메소드를 사용해서 날짜를 두 자리로 만들고 이 값을 day 변수에 저장한다.
마지막으로, year, month, day를 연결하여 YYYYMMDD 형식의 문자열을 생성한다.
const today = new Date();
const getDate = formatDate(today);
다음은 오늘 날짜를 getDate에 저장시킨다.
// 환율 API 호출
var xhr = new XMLHttpRequest();
var url = 'http://apis.data.go.kr/1220000/retrieveTrifFxrtInfo/getRetrieveTrifFxrtInfo';
var queryParams = '?' + encodeURIComponent('serviceKey') + '=' + 'WjGespN29wux4Xj7jLxhXiLVM5JxvOfZUbZy7BVs%2B0JsYWmmqa8DgBDtuM50dvHb%2BQU3jR5Wa1UAB6%2F50Scuiw%3D%3D';
queryParams += '&' + encodeURIComponent('aplyBgnDt') + '=' + encodeURIComponent(getDate);
queryParams += '&' + encodeURIComponent('weekFxrtTpcd') + '=' + encodeURIComponent('1');
xhr.open('GET', url + queryParams);
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// API 호출 성공 시 데이터 처리
var responseXML = this.responseXML;
var items = responseXML.getElementsByTagName("item");
var jsonData = [];
for (var i = 0; i < items.length; i++) {
var item = items[i];
var itemData = {
fxrt: item.getElementsByTagName("fxrt")[0].textContent,
aplyBgnDt: item.getElementsByTagName("aplyBgnDt")[0].textContent,
cntySgn: item.getElementsByTagName("cntySgn")[0].textContent,
currSgn: item.getElementsByTagName("currSgn")[0].textContent,
// 기타 필요한 데이터 필드 추가
};
jsonData.push(itemData);
}
다음은 환율데이터를 호출하는 것으로
xhr.onreadystatechange 이벤트 핸들러는 XMLHttpRequest 객체의 상태가 변할 때마다 호출된다.
readyState가 4이고 status가 200이면 API 호출이 성공한 것으로 간주하고, responseXML을 사용하여 XML 응답을 파싱한다.
그런 다음 getElementsByTagName를 사용하여 XML에서 필요한 데이터를 추출하고 이를 JSON 형태로 가공하여 jsonData 배열에 저장한다.
후에 컨트롤러로 전송을 하게 되면
@RequestMapping(value = "/account/autoUpdate", method = RequestMethod.POST)
public String autoUpdate(@RequestParam("jsonData") String jsonData, Erp_AccountVO avo, Erp_CurrencyVO vo, String comcode_code) {
// 받은 JSON 데이터를 다시 객체로 변환
List<Map<String, String>> dataList = new ArrayList<>();
try {
ObjectMapper objectMapper = new ObjectMapper();
dataList = objectMapper.readValue(jsonData, new TypeReference<List<Map<String, String>>>() {});
} catch (Exception e) {
e.printStackTrace();
}
이같은 형태로
@RequestParam("jsonData") String jsonData는 HTTP 요청에서 jsonData라는 이름의 파라미터를 받아서 이를 문자열 형태의 jsonData 매개변수로 저장한다.
후에
for (Map<String, String> item : dataList) {
System.out.println("fxrt: " + item.get("fxrt"));
System.out.println("aplyBgnDt: " + item.get("aplyBgnDt"));
System.out.println("currSgn: " + item.get("currSgn"));
String country_code = item.get("cntySgn");
int country_no = b2.selectCountryno(country_code);
List<Erp_CurrencyVO> list = b2.currencyDate(country_no);
List<String> currencyDates = list.stream()
.map(Erp_CurrencyVO::getCurrency_date)
.collect(Collectors.toList());
String fxrtString = item.get("fxrt"); // "fxrt"에 해당하는 문자열 값을 가져온다.
double fxrtDouble = Double.parseDouble(fxrtString); // 문자열을 double로 변환한다.
를 통해 해당 데이터들이 컨트롤러에 잘 넘어오는 것을 확인할 수 있다.
따라서 해당 데이터를 통해 페이지가 열릴 때마다 통화 테이블에 INSERT가 되는 것을 확인 할 수 있었다.
'ERP Project' 카테고리의 다른 글
물류팀 기능구현(1) (2) | 2023.10.10 |
---|---|
재무팀 기능구현(2) (0) | 2023.10.10 |
인사팀 기능구현(2) (0) | 2023.09.20 |
인사팀 기능구현(1) (0) | 2023.09.20 |
역할 분담 (0) | 2023.09.20 |