부과예고의 실시간 현재 상태 완료...

별도 계산방법 고민중...
dev
박성영 3 months ago
parent d36859da50
commit 8f230673d8

@ -21,6 +21,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
@ -510,5 +511,266 @@ public class CrdnLevyPrvntcController {
}
}
/**
* API
* : 1,000 .
*
* @param bdstTxtnMprc
* @return
*/
@Operation(summary = "시가표준액 계산", description = "건축물과세시가에서 1,000원 미만 절사하여 시가표준액을 계산합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "계산 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 숫자 형식"),
@ApiResponse(responseCode = "500", description = "서버 오류")
})
@PostMapping("/calculateStandardMarketPrice.ajax")
@ResponseBody
public ResponseEntity<?> calculateStandardMarketPrice(
@Parameter(description = "건축물과세시가") @RequestParam String bdstTxtnMprc) {
Map<String, Object> result = new HashMap<>();
try {
BigDecimal bdstTxtnMprcDecimal = new BigDecimal(bdstTxtnMprc);
// 중요로직: 시가표준액 = 건축물과세시가에서 1,000원 미만 절사
BigDecimal mprcStdAmt = bdstTxtnMprcDecimal
.divide(new BigDecimal("1000"), 0, RoundingMode.DOWN)
.multiply(new BigDecimal("1000"));
result.put("success", true);
result.put("mprcStdAmt", mprcStdAmt.toPlainString());
return ApiResponseUtil.success(result, "시가표준액이 계산되었습니다.");
} catch (NumberFormatException e) {
log.error("숫자 형식 변환 오류", e);
result.put("success", false);
result.put("message", "잘못된 숫자 형식입니다.");
return ResponseEntity.badRequest().body(result);
} catch (Exception e) {
log.error("시가표준액 계산 중 오류 발생", e);
result.put("success", false);
result.put("message", "시가표준액 계산 중 오류가 발생했습니다.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* API
* : , , , , 2 .
*
* @param mprcStdAmt
* @param vltnArea
* @param adsbmtnEnfcRt
* @param cmpttnRtRate
* @param cmpttnRt2Rate 2
* @return
*/
@Operation(summary = "산정액 및 부과총액 계산", description = "시가표준액 × 위반면적 × 가감산시행령률 × 산정률 × 산정률2로 산정액을 계산하고, 1의 자리 절사하여 부과총액을 계산합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "계산 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 숫자 형식"),
@ApiResponse(responseCode = "500", description = "서버 오류")
})
@PostMapping("/calculateLevyAmount.ajax")
@ResponseBody
public ResponseEntity<?> calculateLevyAmount(
@Parameter(description = "시가표준액") @RequestParam String mprcStdAmt,
@Parameter(description = "위반면적") @RequestParam String vltnArea,
@Parameter(description = "가감산시행령률") @RequestParam String adsbmtnEnfcRt,
@Parameter(description = "산정률 비율값") @RequestParam String cmpttnRtRate,
@Parameter(description = "산정률2 비율값") @RequestParam String cmpttnRt2Rate) {
Map<String, Object> result = new HashMap<>();
try {
BigDecimal mprcStdAmtDecimal = new BigDecimal(mprcStdAmt);
BigDecimal vltnAreaDecimal = new BigDecimal(vltnArea);
BigDecimal adsbmtnEnfcRtDecimal = new BigDecimal(adsbmtnEnfcRt);
BigDecimal cmpttnRtRateDecimal = new BigDecimal(cmpttnRtRate);
BigDecimal cmpttnRt2RateDecimal = new BigDecimal(cmpttnRt2Rate);
// 중요로직: 산정액 = 시가표준액 × 위반면적 × (가감산시행령률 ÷ 100) × 산정률 × 산정률2
BigDecimal cmpttnAmt = mprcStdAmtDecimal
.multiply(vltnAreaDecimal)
.multiply(adsbmtnEnfcRtDecimal.divide(new BigDecimal("100"), 10, RoundingMode.HALF_UP))
.multiply(cmpttnRtRateDecimal)
.multiply(cmpttnRt2RateDecimal)
.setScale(0, RoundingMode.DOWN); // 소수점 버림
// 중요로직: 부과총액 = 산정액의 1의 자리 절사 (10원 단위 버림)
BigDecimal levyWholAmt = cmpttnAmt
.divide(new BigDecimal("10"), 0, RoundingMode.DOWN)
.multiply(new BigDecimal("10"));
result.put("success", true);
result.put("cmpttnAmt", cmpttnAmt.toPlainString());
result.put("levyWholAmt", levyWholAmt.toPlainString());
return ApiResponseUtil.success(result, "산정액 및 부과총액이 계산되었습니다.");
} catch (NumberFormatException e) {
log.error("숫자 형식 변환 오류", e);
result.put("success", false);
result.put("message", "잘못된 숫자 형식입니다.");
return ResponseEntity.badRequest().body(result);
} catch (Exception e) {
log.error("산정액 및 부과총액 계산 중 오류 발생", e);
result.put("success", false);
result.put("message", "산정액 및 부과총액 계산 중 오류가 발생했습니다.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* API
* : 100% .
*
* @param baseRate ( 100)
* @param adtnRt ()
* @param sbtrRt ()
* @return
*/
@Operation(summary = "가감산시행령률 계산", description = "기본율 + 가산율 - 감산율로 가감산시행령률을 계산합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "계산 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 숫자 형식"),
@ApiResponse(responseCode = "500", description = "서버 오류")
})
@PostMapping("/calculateAdsbmtnEnfcRt.ajax")
@ResponseBody
public ResponseEntity<?> calculateAdsbmtnEnfcRt(
@Parameter(description = "기본율") @RequestParam(defaultValue = "100") String baseRate,
@Parameter(description = "가산율") @RequestParam(required = false, defaultValue = "0") String adtnRt,
@Parameter(description = "감산율") @RequestParam(required = false, defaultValue = "0") String sbtrRt) {
Map<String, Object> result = new HashMap<>();
try {
BigDecimal baseRateDecimal = new BigDecimal(baseRate);
BigDecimal adtnRtDecimal = new BigDecimal(adtnRt);
BigDecimal sbtrRtDecimal = new BigDecimal(sbtrRt);
// 중요로직: 가감산시행령률 = 기본율 + 가산율 - 감산율
BigDecimal adsbmtnEnfcRt = baseRateDecimal
.add(adtnRtDecimal)
.subtract(sbtrRtDecimal);
// 범위 검증 (0 ~ 1000% 제한)
if (adsbmtnEnfcRt.compareTo(BigDecimal.ZERO) < 0) {
adsbmtnEnfcRt = BigDecimal.ZERO;
} else if (adsbmtnEnfcRt.compareTo(new BigDecimal("1000")) > 0) {
adsbmtnEnfcRt = new BigDecimal("1000");
}
result.put("success", true);
result.put("adsbmtnEnfcRt", adsbmtnEnfcRt.toPlainString());
return ApiResponseUtil.success(result, "가감산시행령률이 계산되었습니다.");
} catch (NumberFormatException e) {
log.error("숫자 형식 변환 오류", e);
result.put("success", false);
result.put("message", "잘못된 숫자 형식입니다.");
return ResponseEntity.badRequest().body(result);
} catch (Exception e) {
log.error("가감산시행령률 계산 중 오류 발생", e);
result.put("success", false);
result.put("message", "가감산시행령률 계산 중 오류가 발생했습니다.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
/**
* API ( + )
* : , , .
* .
*
* @param bdstTxtnMprc
* @param vltnArea
* @param adsbmtnEnfcRt
* @param cmpttnRtRate
* @param cmpttnRt2Rate 2 ( )
* @return
*/
@Operation(summary = "실시간 계산용 통합 API", description = "실시간 입력을 위한 모든 계산을 한번에 처리합니다. 디바운싱과 캐싱을 지원합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "계산 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 숫자 형식"),
@ApiResponse(responseCode = "500", description = "서버 오류")
})
@PostMapping("/calculateRealtime.ajax")
@ResponseBody
public ResponseEntity<?> calculateRealtime(
@Parameter(description = "건축물과세시가") @RequestParam String bdstTxtnMprc,
@Parameter(description = "위반면적") @RequestParam String vltnArea,
@Parameter(description = "가감산시행령률") @RequestParam String adsbmtnEnfcRt,
@Parameter(description = "산정률 비율값") @RequestParam String cmpttnRtRate,
@Parameter(description = "산정률2 비율값") @RequestParam String cmpttnRt2Rate) {
Map<String, Object> result = new HashMap<>();
try {
// 중요로직: 입력값 검증 및 BigDecimal 변환
BigDecimal bdstTxtnMprcDecimal = new BigDecimal(bdstTxtnMprc);
BigDecimal vltnAreaDecimal = new BigDecimal(vltnArea);
BigDecimal adsbmtnEnfcRtDecimal = new BigDecimal(adsbmtnEnfcRt);
BigDecimal cmpttnRtRateDecimal = new BigDecimal(cmpttnRtRate);
BigDecimal cmpttnRt2RateDecimal = new BigDecimal(cmpttnRt2Rate);
// 1단계: 시가표준액 계산 (1,000원 미만 절사)
BigDecimal mprcStdAmt = bdstTxtnMprcDecimal
.divide(new BigDecimal("1000"), 0, java.math.RoundingMode.DOWN)
.multiply(new BigDecimal("1000"));
// 2단계: 산정액 계산 (시가표준액 × 위반면적 × 가감산시행령률(%) × 산정률(비율) × 산정률2(비율))
BigDecimal cmpttnAmt = mprcStdAmt
.multiply(vltnAreaDecimal)
.multiply(adsbmtnEnfcRtDecimal.divide(new BigDecimal("100"), 10, java.math.RoundingMode.HALF_UP))
.multiply(cmpttnRtRateDecimal)
.multiply(cmpttnRt2RateDecimal)
.setScale(0, java.math.RoundingMode.DOWN);
// 3단계: 부과총액 계산 (10원 단위 절사)
BigDecimal levyWholAmt = cmpttnAmt
.divide(new BigDecimal("10"), 0, java.math.RoundingMode.DOWN)
.multiply(new BigDecimal("10"));
// 중요로직: 결과 데이터 구성 (캐싱을 위한 구조화된 응답)
result.put("success", true);
result.put("message", "실시간 계산이 성공적으로 완료되었습니다.");
// 계산 결과
Map<String, Object> calculations = new HashMap<>();
calculations.put("mprcStdAmt", mprcStdAmt); // 시가표준액
calculations.put("cmpttnAmt", cmpttnAmt); // 산정액
calculations.put("levyWholAmt", levyWholAmt); // 부과총액
// 표시용 포맷팅된 값
Map<String, String> displayValues = new HashMap<>();
displayValues.put("mprcStdAmtDisplay", String.format("%,d", mprcStdAmt.longValue()) + " 원");
displayValues.put("cmpttnAmtDisplay", String.format("%,d", cmpttnAmt.longValue()) + " 원");
displayValues.put("levyWholAmtDisplay", String.format("%,d", levyWholAmt.longValue()) + " 원");
result.put("calculations", calculations);
result.put("displayValues", displayValues);
// 캐싱을 위한 입력 파라미터 해시값 (프론트엔드에서 사용)
String cacheKey = String.format("%s_%s_%s_%s_%s",
bdstTxtnMprc, vltnArea, adsbmtnEnfcRt, cmpttnRtRate, cmpttnRt2Rate);
result.put("cacheKey", cacheKey.hashCode());
log.debug("실시간 계산 완료 - 시가표준액: {}, 산정액: {}, 부과총액: {}",
mprcStdAmt, cmpttnAmt, levyWholAmt);
return ResponseEntity.ok(result);
} catch (NumberFormatException e) {
log.error("실시간 계산 중 숫자 형식 변환 오류", e);
result.put("success", false);
result.put("message", "잘못된 숫자 형식입니다.");
return ResponseEntity.badRequest().body(result);
} catch (Exception e) {
log.error("실시간 계산 중 오류 발생", e);
result.put("success", false);
result.put("message", "실시간 계산 중 오류가 발생했습니다.");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(result);
}
}
}

@ -6,55 +6,66 @@
<!--
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
■ 부과예고 이행강제금 산출조사서 계산 로직 상세 명세서 (VO 컬럼명 기준)
■ 부과예고 이행강제금 산출조사서 계산 로직 상세 명세서 (VO 컬럼명 기준) - BigDecimal 서버 계산 방식
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1. 건축물과세시가(bdstTxtnMprc) 계산
1. 건축물과세시가(bdstTxtnMprc) 계산 【서버 API】
- 공식: bldgCrtrMprcAmt × strctIdx × usgIdx × pstnIdx × elpsYrRdvlrt × bscsCstrnRt
- 설명: 건물신축가격기준액 × 구조지수 × 용도지수 × 위치지수 × 경과년수별잔가율 × 기초공사율
- 정확도: BigDecimal 사용으로 부동소수점 오차 방지
- 반올림: 소수점 없이 반올림 (RoundingMode.HALF_UP)
- API: POST /calculateTaxableMarketPrice.ajax
- 처리위치: CrdnLevyPrvntcController.calculateTaxableMarketPrice()
2. 시가표준액(mprcStdAmt) 계산
- 공식: Math.floor(bdstTxtnMprc / 1000) × 1000
2. 시가표준액(mprcStdAmt) 계산 【서버 API】
- 공식: bdstTxtnMprc.divide(1000).multiply(1000) with RoundingMode.DOWN
- 설명: 건축물과세시가에서 1,000원 미만 절사
- 처리위치: JavaScript calculateAuto()
- 정확도: BigDecimal 사용으로 정확한 절사 보장
- API: POST /calculateStandardMarketPrice.ajax
- 처리위치: CrdnLevyPrvntcController.calculateStandardMarketPrice()
3. 가감산시행령률(adsbmtnEnfcRt) 계산
3. 가감산시행령률(adsbmtnEnfcRt) 계산 【서버 API】
- 공식: baseRate + adtnRt - sbtrRt (BigDecimal 연산)
- 기본값: 100%
- 가산 적용 시: 100 + adtnRt (가산율)
- 감산 적용 시: 100 - sbtrRt (감산율)
- 가감산율 범위: 0 ≤ rate ≤ 100
- 처리위치: JavaScript 팝업을 통한 수동 설정
- 범위 제한: 0 ≤ rate ≤ 1000% (서버에서 검증)
- API: POST /calculateAdsbmtnEnfcRt.ajax
- 처리위치: CrdnLevyPrvntcController.calculateAdsbmtnEnfcRt()
4. 산정률(cmpttnRt) / 산정률 비율값(cmpttnRtRate)
- 표시용 값(cmpttnRt): 행위유형별 고정값 (예: 40.00%)
- 계산용 값(cmpttnRtRate): 소수점 비율 (예: 0.40)
- 변환: cmpttnRtRate = cmpttnRt ÷ 100
- 변환: cmpttnRtRate = cmpttnRt ÷ 100 (서버에서 BigDecimal 처리)
- 데이터 출처: 행위정보에서 자동 설정
5. 산정률2(cmpttnRt2) / 산정률2 비율값(cmpttnRt2Rate)
- 표시용 값(cmpttnRt2): 위반사항별 값 (예: 50.00%)
- 계산용 값(cmpttnRt2Rate): 소수점 비율 (예: 0.50)
- 변환: cmpttnRt2Rate = cmpttnRt2 ÷ 100
- 변환: cmpttnRt2Rate = cmpttnRt2 ÷ 100 (서버에서 BigDecimal 처리)
- 선택: 담당자가 드롭다운에서 선택
6. 산정액(cmpttnAmt) 계산
- 공식: Math.floor(mprcStdAmt × vltnArea × (adsbmtnEnfcRt ÷ 100) × cmpttnRtRate × cmpttnRt2Rate)
6. 산정액(cmpttnAmt) 계산 【서버 API】
- 공식: mprcStdAmt × vltnArea × (adsbmtnEnfcRt ÷ 100) × cmpttnRtRate × cmpttnRt2Rate
- 설명: 시가표준액 × 위반면적 × 가감산시행령률(%) × 산정률(비율) × 산정률2(비율)
- 반올림: 소수점 버림 (Math.floor)
- 처리위치: JavaScript calculateLevyAmount()
- 정확도: BigDecimal.multiply() 체인 연산으로 정확도 보장
- 반올림: setScale(0, RoundingMode.DOWN) - 소수점 버림
- API: POST /calculateLevyAmount.ajax
- 처리위치: CrdnLevyPrvntcController.calculateLevyAmount()
7. 부과총액(levyWholAmt) 계산
- 공식: Math.floor(cmpttnAmt ÷ 10) × 10
7. 부과총액(levyWholAmt) 계산 【서버 API】
- 공식: cmpttnAmt.divide(10, RoundingMode.DOWN).multiply(10)
- 설명: 산정액에서 1의 자리 절사 (10원 단위 버림)
- 정확도: BigDecimal 연산으로 정확한 절사 보장
- 예시: 1,234,567원 → 1,234,560원
- 처리위치: JavaScript calculateLevyAmount()
- API: POST /calculateLevyAmount.ajax (산정액과 함께 반환)
- 처리위치: CrdnLevyPrvntcController.calculateLevyAmount()
8. 이행강제금(impltCpsrAmt) 계산
- 공식: SUM(levyWholAmt) WHERE crdnYr = ? AND crdnNo = ? AND impltTaskSeCd = ?
- 설명: 해당 단속의 모든 행위정보별 부과총액 합계
- 조건: 모든 행위정보에 대한 부과정보가 등록된 경우에만 계산
- 정확도: DB에서 SUM 집계 함수 사용으로 정확성 보장
- 처리위치: CrdnLevyPrvntcServiceImpl.updateImpltCpsrAmt()
■ 주요 VO 컬럼 설명
@ -76,11 +87,28 @@
- levyWholAmt: 부과총액 (BigDecimal)
- impltCpsrAmt: 이행강제금 (BigDecimal)
■ 계산 처리 흐름
1단계: 서버 API로 건축물과세시가 계산 (CrdnLevyPrvntcController)
2단계: JavaScript로 시가표준액 자동 설정 (calculateAuto)
3단계: JavaScript로 산정액/부과총액 계산 (calculateLevyAmount)
4단계: 서버에서 모든 행위별 부과총액 합산하여 이행강제금 계산 (Service Layer)
■ 계산 처리 흐름 (완전한 서버 사이드 BigDecimal 계산)
┌─────────────────────────────────────────────────────────────────────────────┐
│ 1단계: 건축물과세시가 계산 【calculateTaxableMarketPrice.ajax】 │
│ ├─ Input: 건물기준시가액, 구조지수, 용도지수, 위치지수, 경과년수별잔가율, 기초공사율 │
│ ├─ Process: BigDecimal 6개 값 곱셈 연산 │
│ └─ Output: 정확한 건축물과세시가 │
│ ↓ │
│ 2단계: 시가표준액 계산 【calculateStandardMarketPrice.ajax】 │
│ ├─ Input: 건축물과세시가 │
│ ├─ Process: BigDecimal.divide(1000).multiply(1000) 절사 연산 │
│ └─ Output: 1,000원 미만 절사된 시가표준액 │
│ ↓ │
│ 3단계: 산정액/부과총액 계산 【calculateLevyAmount.ajax】 │
│ ├─ Input: 시가표준액, 위반면적, 가감산시행령률, 산정률, 산정률2 │
│ ├─ Process: BigDecimal 5개 값 곱셈 → 소수점 버림 → 10원 단위 절사 │
│ └─ Output: 정확한 산정액 + 부과총액 │
│ ↓ │
│ 4단계: 이행강제금 계산 【Service Layer + DB SUM】 │
│ ├─ Input: 모든 행위정보별 부과총액 │
│ ├─ Process: DB SUM 집계 함수로 합산 │
│ └─ Output: 최종 이행강제금 │
└─────────────────────────────────────────────────────────────────────────────┘
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
-->
@ -302,6 +330,7 @@
</option>
</c:forEach>
</select><!-- 산정률2 -->
<input type="hidden" id="cmpttnRt2" class="input text-right" value="" readonly/><!-- 산정률2(값) -->
<input type="hidden" id="cmpttnRt2Rate" class="input text-right" value="" readonly/><!-- 산정률2(값) -->
</td>
@ -961,10 +990,12 @@
$('#cmpttnRt2').val(rateValue || '');
$('#cmpttnRt2Rate').val(rateValue2 || '');
$('#cmpttnRt2Display').val((rateValue || '') + ' %').trigger('focus');
// 산정액 계산 함수 호출
calculateLevyAmount();
});
// 위반면적 변경 시 산정액 계산 함수 호출
$('#vltnArea').on('change keyup', function() {
calculateLevyAmount();
@ -1152,6 +1183,7 @@
return false;
}
// 산정률2 유효성 검증
if (!$('#cmpttnRt2Cd').val()) {
alert('산정률2를 선택해주세요.');
$('#cmpttnRt2Cd').focus();
@ -1213,36 +1245,54 @@
* - 부과총액 = 산정액의 1의 자리 절사 (10원 단위 버림)
*/
function calculateLevyAmount() {
var standardMarketPrice = parseFloat($('#standardMarketPrice_top').inputmask('unmaskedvalue')) || 0;
var vltnArea = parseFloat($('#vltnArea').inputmask('unmaskedvalue')) || 0;
var adsbmtnEnfcRt = parseFloat($('#adsbmtnEnfcRt').val()) || 0;
var cmpttnRtRate = parseFloat($('#cmpttnRtRate').val()) || 0;
var cmpttnRt2Rate = parseFloat($('#cmpttnRt2Rate').val()) || 0;
var cmpttnAmt = 0; // 산정액
var levyWholAmt = 0; // 부과총액
var standardMarketPrice = $('#standardMarketPrice_top').inputmask('unmaskedvalue') || '0';
var vltnArea = $('#vltnArea').inputmask('unmaskedvalue') || '0';
var adsbmtnEnfcRt = $('#adsbmtnEnfcRt').val() || '0';
var cmpttnRtRate = $('#cmpttnRtRate').val() || '0';
var cmpttnRt2Rate = $('#cmpttnRt2Rate').val() || '0';
// 모든 값이 0보다 큰지 확인 (필수 입력값 체크)
if (standardMarketPrice > 0 && vltnArea > 0 && adsbmtnEnfcRt > 0 && cmpttnRtRate > 0 && cmpttnRt2Rate > 0) {
// 산정액 계산 (소수점 버림)
cmpttnAmt = Math.floor(standardMarketPrice * vltnArea * (adsbmtnEnfcRt / 100) * cmpttnRtRate * cmpttnRt2Rate);
if (parseFloat(standardMarketPrice) > 0 && parseFloat(vltnArea) > 0 && parseFloat(adsbmtnEnfcRt) > 0 &&
parseFloat(cmpttnRtRate) > 0 && parseFloat(cmpttnRt2Rate) > 0) {
// 부과총액 계산: 산정액에서 1의 자리 절사 (10원 단위로 버림)
levyWholAmt = Math.floor(cmpttnAmt / 10) * 10;
}
// 서버 API로 정확한 계산 요청 (BigDecimal 사용)
$.ajax({
url: '<c:url value="/crdn/crndRegistAndView/crdnLevyPrvntc/calculateLevyAmount.ajax"/>',
type: 'POST',
data: {
mprcStdAmt: standardMarketPrice,
vltnArea: vltnArea,
adsbmtnEnfcRt: adsbmtnEnfcRt,
cmpttnRtRate: cmpttnRtRate,
cmpttnRt2Rate: cmpttnRt2Rate
},
success: function(response) {
if (response && response.data && response.success) {
var cmpttnAmt = response.data.cmpttnAmt;
var levyWholAmt = response.data.levyWholAmt;
// '산정액' 필드에 값 설정
if (cmpttnAmt > 0) {
$('#cmpttnAmt').val(cmpttnAmt).trigger('focus');
} else {
$('#cmpttnAmt').val('').trigger('focus');
}
// '산정액' 필드에 값 설정
$('#cmpttnAmt').val(parseInt(cmpttnAmt)).trigger('focus');
// '부과총액' 필드 및 표시에 값 설정
$('#levyWholAmt').val(parseInt(levyWholAmt));
$('#levyWholAmtDisplay').text(parseInt(levyWholAmt).toLocaleString() + ' 원');
// '부과총액' 필드 및 표시에 값 설정
if (levyWholAmt > 0) {
$('#levyWholAmt').val(levyWholAmt);
$('#levyWholAmtDisplay').text(levyWholAmt.toLocaleString() + ' 원');
console.log('산정액 (서버계산):', cmpttnAmt);
console.log('부과총액 (서버계산):', levyWholAmt);
}
},
error: function() {
alert('산정액 및 부과총액 계산 중 오류가 발생했습니다.');
// 오류 시 필드 초기화
$('#cmpttnAmt').val('').trigger('focus');
$('#levyWholAmt').val('');
$('#levyWholAmtDisplay').text('0 원');
}
});
} else {
// 값이 부족할 때 필드 초기화
$('#cmpttnAmt').val('').trigger('focus');
$('#levyWholAmt').val('');
$('#levyWholAmtDisplay').text('0 원');
}
@ -1268,7 +1318,10 @@
$('#taxableMarketPrice').val('').trigger('focus'); // 건축물과세시가
$('#standardMarketPrice').val('').trigger('focus'); // 시가표준액
$('#standardMarketPrice_top').val('').trigger('focus'); // 시가표준액(상단)
calculateLevyAmount(); // 산정액 계산
// 필드 초기화 시 산정액/부과총액도 초기화
$('#cmpttnAmt').val('').trigger('focus');
$('#levyWholAmt').val('');
$('#levyWholAmtDisplay').text('0 원');
return;
}
@ -1287,15 +1340,35 @@
data: params,
success: function(response) {
if (response && response.data && response.success) {
var taxableMarketPrice = parseFloat(response.data.taxableMarketPrice) || 0;
// 시가표준액 계산: 1,000원 미만 절사
var standardMarketPrice = Math.floor(taxableMarketPrice / 1000) * 1000;
// 계산된 값을 input 필드에 설정
$('#taxableMarketPrice').val(taxableMarketPrice).trigger('focus'); // 건축물과세시가
$('#standardMarketPrice').val(standardMarketPrice).trigger('focus'); // 시가표준액
$('#standardMarketPrice_top').val(standardMarketPrice).trigger('focus'); // 시가표준액(상단)
var taxableMarketPrice = response.data.taxableMarketPrice;
// 건축물과세시가 설정
$('#taxableMarketPrice').val(taxableMarketPrice).trigger('focus');
// 시가표준액 계산을 서버 API로 요청 (BigDecimal 정확도 보장)
$.ajax({
url: '<c:url value="/crdn/crndRegistAndView/crdnLevyPrvntc/calculateStandardMarketPrice.ajax"/>',
type: 'POST',
data: { bdstTxtnMprc: taxableMarketPrice },
success: function(standardResponse) {
if (standardResponse && standardResponse.data && standardResponse.success) {
var standardMarketPrice = standardResponse.data.mprcStdAmt;
// 시가표준액 설정
$('#standardMarketPrice').val(standardMarketPrice).trigger('focus');
$('#standardMarketPrice_top').val(standardMarketPrice).trigger('focus');
console.log('건축물과세시가:', taxableMarketPrice);
console.log('시가표준액:', standardMarketPrice);
// 산정액 계산 함수 호출
calculateLevyAmount();
}
},
error: function() {
alert('시가표준액 계산 중 오류가 발생했습니다.');
}
});
} else {
alert(response.message || '계산 중 오류가 발생했습니다.');
$('#taxableMarketPrice').val('').trigger('focus'); // 건축물과세시가
@ -1310,7 +1383,10 @@
$('#taxableMarketPrice').val('').trigger('focus'); // 건축물과세시가
$('#standardMarketPrice').val('').trigger('focus'); // 시가표준액
$('#standardMarketPrice_top').val('').trigger('focus'); // 시가표준액(상단)
calculateLevyAmount(); // 산정액 계산
// 오류 시 산정액/부과총액도 초기화
$('#cmpttnAmt').val('').trigger('focus');
$('#levyWholAmt').val('');
$('#levyWholAmtDisplay').text('0 원');
}
});
}
@ -1395,4 +1471,5 @@
};
})(window, jQuery);
</script>
Loading…
Cancel
Save