연차변경원 진행중
This commit is contained in:
parent
e8e10c48c0
commit
05dc5b5d76
@ -5,6 +5,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@ -18,6 +19,8 @@ public class LeaveChangeRequestVO {
|
||||
private String userName;
|
||||
private LocalDate originalLeaveDate;
|
||||
private LocalDate requestedLeaveDate;
|
||||
private BigDecimal originalLeaveDays; // 추가
|
||||
private BigDecimal requestedLeaveDays; // 추가
|
||||
private String requestReason;
|
||||
private String requestStatus;
|
||||
private String requestStatusName; // 추가
|
||||
|
||||
@ -32,4 +32,6 @@ public class LeavePlanVO {
|
||||
private String requestStatus; // 변경 상태
|
||||
private String requestStatusName; // 변경 상태 코드 name
|
||||
private String changeCount; // 변경 카운트
|
||||
private BigDecimal originalLeaveDays; // 변경 전 일수
|
||||
private BigDecimal requestedLeaveDays; // 변경 후 일수
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ public interface ItnLeaveService {
|
||||
|
||||
boolean rejectLeavePlan(Long planId, String approverId, String rejectReason);
|
||||
|
||||
boolean requestLeaveChange(LeaveChangeRequestVO leaveChangeRequestVO);
|
||||
RestResponse requestLeaveChange(LeaveChangeRequestVO leaveChangeRequestVO);
|
||||
|
||||
LeaveChangeRequestVO getLeaveChangeRequestDetail(Long changeRequestId);
|
||||
|
||||
|
||||
@ -71,6 +71,8 @@ public class ItnLeaveServiceImpl implements ItnLeaveService {
|
||||
LeaveChangeRequestVO leaveChangeRequestVO = itnLeaveMapper.selectItnLeaveChangeRequestById(changeRequestId);
|
||||
if (leaveChangeRequestVO != null) {
|
||||
leaveChangeRequestVO.setUserName(tCodeUtils.getUserName(leaveChangeRequestVO.getUniqId()));
|
||||
log.info("originalLeaveDays: {}", leaveChangeRequestVO.getOriginalLeaveDays());
|
||||
log.info("requestedLeaveDays: {}", leaveChangeRequestVO.getRequestedLeaveDays());
|
||||
}
|
||||
return leaveChangeRequestVO;
|
||||
}
|
||||
@ -79,6 +81,30 @@ public class ItnLeaveServiceImpl implements ItnLeaveService {
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean saveLeavePlan(LeavePlanVO leavePlanVO) {
|
||||
// ==================== [검증 로직 시작] ====================
|
||||
|
||||
// 1. 사용자의 촉진 연차 목표치 조회 (itn_leave_status.promoted_leave)
|
||||
LeaveStatusVO leaveStatus = itnLeaveMapper.selectLeaveStatusByUserIdAndYear(leavePlanVO.getUniqId(), leavePlanVO.getYear());
|
||||
BigDecimal promotedLeaveGoal = leaveStatus.getPromotedLeave();
|
||||
|
||||
// 2. 현재 DB에 저장된 '승인' 및 '대기' 상태의 모든 연차 계획 총합을 계산
|
||||
List<LeavePlanVO> existingPlans = itnLeaveMapper.selectLeavePlansByUserIdAndYear(leavePlanVO.getUniqId(), leavePlanVO.getYear());
|
||||
BigDecimal currentPledgedDays = existingPlans.stream()
|
||||
.filter(p -> "10".equals(p.getStatus()) || "20".equals(p.getStatus())) // 10: 대기, 20: 승인
|
||||
.map(LeavePlanVO::getLeaveDays)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
// 3. 이번에 새로 신청한 연차 일수
|
||||
BigDecimal newRequestDays = leavePlanVO.getLeaveDays();
|
||||
|
||||
// 4. 예상 총합(기존 총합 + 신규 신청)이 목표치를 초과하는지 검증
|
||||
if (currentPledgedDays.add(newRequestDays).compareTo(promotedLeaveGoal) > 0) {
|
||||
// 초과할 경우, 예외를 발생시켜 저장을 막고 사용자에게 에러 메시지 전달
|
||||
throw new IllegalArgumentException("신청 가능한 촉진 연차 일수를 초과했습니다.");
|
||||
}
|
||||
|
||||
// ==================== [검증 로직 종료] ====================
|
||||
|
||||
if (leavePlanVO.getPlanId() == null) {
|
||||
// 신규 신청
|
||||
leavePlanVO.setStatus(LEAVE_STATUS_PENDING); // 초기 상태는 PENDING
|
||||
@ -173,18 +199,37 @@ public class ItnLeaveServiceImpl implements ItnLeaveService {
|
||||
// 연차 변경 요청
|
||||
@Override
|
||||
@Transactional
|
||||
public boolean requestLeaveChange(LeaveChangeRequestVO leaveChangeRequestVO) {
|
||||
// 기존 연차 계획의 변경 요청 상태를 10으로 업데이트
|
||||
// LeavePlanVO originalLeavePlan = itnLeaveMapper.selectLeavePlanById(leaveChangeRequestVO.getPlanId());
|
||||
// if (originalLeavePlan == null) {
|
||||
// return false; // 원본 연차 계획이 없음
|
||||
// }
|
||||
// leaveChangeRequestVO.setUniqId(originalLeavePlan.getUniqId());
|
||||
public RestResponse requestLeaveChange(LeaveChangeRequestVO leaveChangeRequestVO) {
|
||||
// ==================== [검증 로직 시작] ====================
|
||||
|
||||
// 1. 사용자의 촉진 연차 목표치 조회 (itn_leave_status.promoted_leave)
|
||||
LeaveStatusVO leaveStatus = itnLeaveMapper.selectLeaveStatusByUserIdAndYear(leaveChangeRequestVO.getUniqId(), String.valueOf(leaveChangeRequestVO.getOriginalLeaveDate().getYear()));
|
||||
BigDecimal promotedLeaveGoal = leaveStatus.getPromotedLeave();
|
||||
|
||||
// 연차 변경 요청 이력 저장
|
||||
// 2. 현재 DB에 저장된 '승인' 및 '대기' 상태의 모든 연차 계획 총합을 계산
|
||||
List<LeavePlanVO> existingPlans = itnLeaveMapper.selectLeavePlansByUserIdAndYear(leaveChangeRequestVO.getUniqId(), String.valueOf(leaveChangeRequestVO.getOriginalLeaveDate().getYear()));
|
||||
BigDecimal currentPledgedDays = existingPlans.stream()
|
||||
.filter(p -> "10".equals(p.getStatus()) || "20".equals(p.getStatus())) // 10: 대기, 20: 승인
|
||||
.map(LeavePlanVO::getLeaveDays)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
|
||||
// 3. 이번 '변경'으로 인해 발생하는 연차 변동량 계산
|
||||
// (예: 1.0일 -> 0.5일 변경 시 -0.5 / 0.5일 -> 1.0일 변경 시 +0.5)
|
||||
BigDecimal changeInDays = leaveChangeRequestVO.getRequestedLeaveDays().subtract(leaveChangeRequestVO.getOriginalLeaveDays());
|
||||
|
||||
// 4. 예상 총합(기존 총합 + 변동량)이 목표치를 초과하는지 검증
|
||||
if (currentPledgedDays.add(changeInDays).compareTo(promotedLeaveGoal) > 0) {
|
||||
// 초과할 경우, 예외를 발생시켜 저장을 막음
|
||||
return new RestResponse(HttpStatus.BAD_REQUEST, "변경 후 총 연차 일수가 촉진 연차 한도를 초과합니다.");
|
||||
}
|
||||
|
||||
// ==================== [검증 로직 종료] ====================
|
||||
|
||||
// 5. 검증 통과 시, 기존 로직 수행
|
||||
leaveChangeRequestVO.setRequestStatus(LEAVE_CHANGE_REQUEST_STATUS_PENDING);
|
||||
return itnLeaveMapper.insertLeaveChangeRequest(leaveChangeRequestVO) > 0;
|
||||
itnLeaveMapper.insertLeaveChangeRequest(leaveChangeRequestVO);
|
||||
|
||||
return new RestResponse(HttpStatus.OK, "연차 변경 요청이 성공적으로 제출되었습니다.");
|
||||
}
|
||||
|
||||
|
||||
@ -202,11 +247,21 @@ public class ItnLeaveServiceImpl implements ItnLeaveService {
|
||||
changeRequest.setApproverId(approverId);
|
||||
itnLeaveMapper.updateLeaveChangeRequestStatus(changeRequest);
|
||||
|
||||
// 원본 연차 계획 업데이트 (날짜 변경)
|
||||
// 원본 연차 계획 업데이트 (날짜 및 일수 변경)
|
||||
LeavePlanVO originalLeavePlan = itnLeaveMapper.selectLeavePlanById(changeRequest.getPlanId());
|
||||
if (originalLeavePlan != null) {
|
||||
originalLeavePlan.setLeaveDate(changeRequest.getRequestedLeaveDate());
|
||||
originalLeavePlan.setLeaveDays(changeRequest.getRequestedLeaveDays()); // 일수 변경 반영
|
||||
itnLeaveMapper.updateLeavePlan(originalLeavePlan); // 기존 updateLeavePlan 사용
|
||||
|
||||
// 사용된 연차 재계산 및 업데이트 (used_leave는 고정값이므로 수정하지 않음)
|
||||
// LeaveStatusVO leaveStatus = itnLeaveMapper.selectLeaveStatusByUserIdAndYear(originalLeavePlan.getUniqId(), originalLeavePlan.getYear());
|
||||
// if (leaveStatus != null) {
|
||||
// BigDecimal oldUsedLeave = leaveStatus.getUsedLeave();
|
||||
// BigDecimal changedAmount = changeRequest.getOriginalLeaveDays().subtract(changeRequest.getRequestedLeaveDays());
|
||||
// leaveStatus.setUsedLeave(oldUsedLeave.subtract(changedAmount));
|
||||
// itnLeaveMapper.updateLeaveStatus(leaveStatus);
|
||||
// }
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@ -89,12 +89,16 @@ public class ItnLeaveRestController {
|
||||
public ResponseEntity<RestResponse> submitLeaveChangeRequest(@RequestBody LeaveChangeRequestVO leaveChangeRequestVO
|
||||
, @AuthenticationPrincipal CustomUserDetails loginUser) {
|
||||
leaveChangeRequestVO.setUniqId(loginUser.getUser().getUniqId());
|
||||
boolean result = itnLeaveService.requestLeaveChange(leaveChangeRequestVO);
|
||||
if (result) {
|
||||
return ResponseEntity.ok().body(new RestResponse(HttpStatus.OK, "연차 변경 요청이 성공적으로 제출되었습니다."));
|
||||
} else {
|
||||
return ResponseEntity.badRequest().body(new RestResponse(HttpStatus.BAD_REQUEST, "연차 변경 요청 제출에 실패했습니다."));
|
||||
}
|
||||
// boolean result = itnLeaveService.requestLeaveChange(leaveChangeRequestVO);
|
||||
|
||||
|
||||
|
||||
return ResponseEntity.ok().body(itnLeaveService.requestLeaveChange(leaveChangeRequestVO));
|
||||
// if (result) {
|
||||
// return ResponseEntity.ok().body(new RestResponse(HttpStatus.OK, "연차 변경 요청이 성공적으로 제출되었습니다."));
|
||||
// } else {
|
||||
// return ResponseEntity.badRequest().body(new RestResponse(HttpStatus.BAD_REQUEST, "연차 변경 요청 제출에 실패했습니다."));
|
||||
// }
|
||||
}
|
||||
|
||||
// 연차 변경 요청 상세 조회
|
||||
|
||||
@ -53,6 +53,8 @@
|
||||
c.change_request_id,
|
||||
c.original_leave_date,
|
||||
c.requested_leave_date,
|
||||
c.original_leave_days,
|
||||
c.requested_leave_days,
|
||||
c.request_reason,
|
||||
c.request_status,
|
||||
c.request_dt,
|
||||
@ -143,6 +145,8 @@
|
||||
UNIQ_ID,
|
||||
ORIGINAL_LEAVE_DATE,
|
||||
REQUESTED_LEAVE_DATE,
|
||||
ORIGINAL_LEAVE_DAYS,
|
||||
REQUESTED_LEAVE_DAYS,
|
||||
REQUEST_REASON,
|
||||
REQUEST_STATUS,
|
||||
REQUEST_DT
|
||||
@ -151,6 +155,8 @@
|
||||
#{uniqId},
|
||||
#{originalLeaveDate},
|
||||
#{requestedLeaveDate},
|
||||
#{originalLeaveDays},
|
||||
#{requestedLeaveDays},
|
||||
#{requestReason},
|
||||
#{requestStatus},
|
||||
NOW()
|
||||
@ -167,6 +173,8 @@
|
||||
T1.UNIQ_ID,
|
||||
T1.ORIGINAL_LEAVE_DATE,
|
||||
T1.REQUESTED_LEAVE_DATE,
|
||||
T1.ORIGINAL_LEAVE_DAYS,
|
||||
T1.REQUESTED_LEAVE_DAYS,
|
||||
T1.REQUEST_REASON,
|
||||
T1.REQUEST_STATUS,
|
||||
(SELECT CODE_NAME FROM COMMON_CODE_DETAIL WHERE CODE_GROUP_ID = 'CHANGE_REQUEST_STATUS' AND CODE_ID = T1.REQUEST_STATUS) AS requestStatusName,
|
||||
@ -195,6 +203,8 @@
|
||||
T1.UNIQ_ID,
|
||||
T1.ORIGINAL_LEAVE_DATE,
|
||||
T1.REQUESTED_LEAVE_DATE,
|
||||
T1.ORIGINAL_LEAVE_DAYS,
|
||||
T1.REQUESTED_LEAVE_DAYS,
|
||||
T1.REQUEST_REASON,
|
||||
T1.REQUEST_STATUS,
|
||||
(SELECT CODE_NAME FROM COMMON_CODE_DETAIL WHERE CODE_GROUP_ID = 'CHANGE_REQUEST_STATUS' AND CODE_ID = T1.REQUEST_STATUS) AS requestStatusName,
|
||||
@ -211,11 +221,11 @@
|
||||
SELECT
|
||||
T1.CHANGE_REQUEST_ID,
|
||||
T1.PLAN_ID,
|
||||
ilp.YEAR ,
|
||||
ilp.LEAVE_DAYS ,
|
||||
T1.UNIQ_ID,
|
||||
T1.ORIGINAL_LEAVE_DATE,
|
||||
T1.REQUESTED_LEAVE_DATE,
|
||||
T1.ORIGINAL_LEAVE_DAYS,
|
||||
T1.REQUESTED_LEAVE_DAYS,
|
||||
T1.REQUEST_REASON,
|
||||
T1.REQUEST_STATUS,
|
||||
(SELECT CODE_NAME FROM COMMON_CODE_DETAIL WHERE CODE_GROUP_ID = 'CHANGE_REQUEST_STATUS' AND CODE_ID = T1.REQUEST_STATUS) AS requestStatusName,
|
||||
@ -224,8 +234,6 @@
|
||||
T1.REQUEST_DT,
|
||||
T1.APPROVAL_DT
|
||||
FROM ITN_LEAVE_CHANGE_REQUEST T1
|
||||
left join itn_leave_plan ilp
|
||||
on T1.plan_id = ilp.PLAN_ID
|
||||
WHERE T1.CHANGE_REQUEST_ID = #{changeRequestId}
|
||||
</select>
|
||||
|
||||
@ -238,6 +246,8 @@
|
||||
T1.UNIQ_ID,
|
||||
T1.ORIGINAL_LEAVE_DATE,
|
||||
T1.REQUESTED_LEAVE_DATE,
|
||||
T1.ORIGINAL_LEAVE_DAYS,
|
||||
T1.REQUESTED_LEAVE_DAYS,
|
||||
T1.REQUEST_REASON,
|
||||
T1.REQUEST_STATUS,
|
||||
(SELECT CODE_NAME FROM COMMON_CODE_DETAIL WHERE CODE_GROUP_ID = 'CHANGE_REQUEST_STATUS' AND CODE_ID = T1.REQUEST_STATUS) AS requestStatusName,
|
||||
|
||||
@ -53,6 +53,7 @@
|
||||
<th>신청자</th>
|
||||
<th>기존 연차 일자</th>
|
||||
<th>요청 변경 일자</th>
|
||||
<th>변경일수</th>
|
||||
<th>요청 사유</th>
|
||||
<th>요청 일시</th>
|
||||
<th>상태</th>
|
||||
@ -64,6 +65,10 @@
|
||||
<td th:text="${@TCodeUtils.getUserName(changeRequest.uniqId)}"></td>
|
||||
<td th:text="${changeRequest.originalLeaveDate}"></td>
|
||||
<td th:text="${changeRequest.requestedLeaveDate}"></td>
|
||||
<td>
|
||||
<span th:if="${changeRequest.originalLeaveDays != null and changeRequest.requestedLeaveDays != null}"
|
||||
th:text="|${changeRequest.originalLeaveDays} → ${changeRequest.requestedLeaveDays}|"></span>
|
||||
</td>
|
||||
<td th:text="${changeRequest.requestReason}"></td>
|
||||
<td th:text="${#temporals.format(changeRequest.requestDt, 'yyyy-MM-dd HH:mm')}"></td>
|
||||
<td th:text="${changeRequest.requestStatusName}"></td>
|
||||
@ -179,6 +184,11 @@
|
||||
$('#leaveChangeRequestDetailModal #detailChangeRequestUserId').val(data.userName);
|
||||
$('#leaveChangeRequestDetailModal #detailOriginalLeaveDate').val(data.originalLeaveDate);
|
||||
$('#leaveChangeRequestDetailModal #detailRequestedLeaveDate').val(data.requestedLeaveDate);
|
||||
if (data.originalLeaveDays != null && data.requestedLeaveDays != null) {
|
||||
$('#leaveChangeRequestDetailModal #detailLeaveDaysChange').val(`${data.originalLeaveDays} → ${data.requestedLeaveDays}`);
|
||||
} else {
|
||||
$('#leaveChangeRequestDetailModal #detailLeaveDaysChange').val('-');
|
||||
}
|
||||
$('#leaveChangeRequestDetailModal #detailRequestReason').val(data.requestReason);
|
||||
$('#leaveChangeRequestDetailModal #detailChangeRequestRequestDt').val(data.requestDt);
|
||||
$('#leaveChangeRequestDetailModal #changeRequestApprovalStatus').val('20'); // 기본값 설정 : 승인
|
||||
@ -237,6 +247,10 @@
|
||||
<label>요청 변경 일자</label>
|
||||
<input type="text" class="form-control" id="detailRequestedLeaveDate" readonly>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>변경 일수</label>
|
||||
<input type="text" class="form-control" id="detailLeaveDaysChange" readonly>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>요청 사유</label>
|
||||
<textarea class="form-control" id="detailRequestReason" rows="3" readonly></textarea>
|
||||
|
||||
@ -112,6 +112,56 @@
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 촉진 연차 현황 요약 섹션 추가 -->
|
||||
<div class="mb-4" th:with="
|
||||
promotedLeaveVal=${leaveStatus != null ? leaveStatus.promotedLeave : T(java.math.BigDecimal).ZERO},
|
||||
filteredLeavePlans=${leavePlans != null ? leavePlans.?[status == '10' or status == '20'] : T(java.util.Collections).emptyList()},
|
||||
plannedTotal=${#aggregates.sum(filteredLeavePlans.![leaveDays != null ? leaveDays : T(java.math.BigDecimal).ZERO])},
|
||||
remainingPlanDays=${T(java.util.Optional).ofNullable(promotedLeaveVal).orElse(T(java.math.BigDecimal).ZERO).subtract(T(java.util.Optional).ofNullable(plannedTotal).orElse(T(java.math.BigDecimal).ZERO))}">
|
||||
<h5 class="mb-3"><i class="fas fa-chart-pie text-info mr-1"></i> 촉진 연차 현황</h5>
|
||||
<table class="table table-bordered table-hover align-middle" style="width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th style="width: 200px; background-color: #f8f9fa;">촉진 연차 목표</th>
|
||||
<td th:text="${leaveStatus.promotedLeave} + '일'">10.0일</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="background-color: #f8f9fa;">현재 계획된 연차 총합</th>
|
||||
<td th:text="${plannedTotal} + '일'">8.0일</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th style="background-color: #f8f9fa;">추가 계획 가능 연차</th>
|
||||
<td th:text="${remainingPlanDays} + '일'">2.0일</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- 디버깅 정보 (임시) -->
|
||||
<div style="background-color: #f0f0f0; padding: 10px; margin-top: 20px; border-radius: 5px;">
|
||||
<p><strong>디버깅 정보:</strong></p>
|
||||
<p>촉진 연차 목표 (promotedLeave): <span th:text="${leaveStatus.promotedLeave}"></span></p>
|
||||
<p>현재 계획된 연차 총합 (plannedTotal): <span th:text="${plannedTotal}"></span></p>
|
||||
<p>추가 계획 가능 연차 (remainingPlanDays): <span th:text="${remainingPlanDays}"></span></p>
|
||||
</div>
|
||||
|
||||
<!-- 사용자 안내 메시지 -->
|
||||
<div>
|
||||
<div th:if="${remainingPlanDays.compareTo(T(java.math.BigDecimal).ZERO) > 0}" class="alert alert-info mt-3" role="alert">
|
||||
<i class="fas fa-info-circle mr-1"></i> 촉진 연차를 모두 사용하려면 <strong th:text="${remainingPlanDays}">2.0</strong>일의 연차를 더 신청해야 합니다.
|
||||
</div>
|
||||
<div th:if="${remainingPlanDays.compareTo(T(java.math.BigDecimal).ZERO) <= 0}" class="alert alert-success mt-3" role="alert">
|
||||
<i class="fas fa-check-circle mr-1"></i> 촉진 연차 목표를 달성했거나 초과했습니다.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 추가된 버튼 -->
|
||||
<div th:if="${remainingPlanDays.compareTo(T(java.math.BigDecimal).ZERO) > 0}" class="text-center mt-3">
|
||||
<a th:href="@{/itn/leave/request}" class="btn btn-primary btn-lg">
|
||||
<i class="fas fa-plus-circle mr-2"></i> 연차 사용 계획 신청하기
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 연차 사용 계획 -->
|
||||
<div>
|
||||
<h5>📅 연차 사용 계획</h5>
|
||||
@ -122,6 +172,7 @@
|
||||
<th style="width: 200px;">일자</th>
|
||||
<th style="width: 200px;">일수</th>
|
||||
<th style="width: 200px;">변경 횟수</th>
|
||||
<th style="width: 200px;">변경일수</th>
|
||||
<th style="width: 200px;">요청 상태</th>
|
||||
<th>반려 사유</th>
|
||||
<th style="width: 100px;" class="text-center">관리</th>
|
||||
@ -141,6 +192,10 @@
|
||||
style="cursor: pointer;">
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<span th:if="${plan.originalLeaveDays != null and plan.requestedLeaveDays != null}"
|
||||
th:text="|${plan.originalLeaveDays} → ${plan.requestedLeaveDays}|"></span>
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
@ -158,7 +213,7 @@
|
||||
<td th:text="${plan.rejectionReason}"></td>
|
||||
<td>
|
||||
<a href="#"
|
||||
th:onclick="openLeaveChangeRequestModal([[${plan.planId}]], [[${plan.leaveDate}]])"
|
||||
th:onclick="openLeaveChangeRequestModal([[${plan.planId}]], [[${plan.leaveDate}]], [[${plan.leaveDays}]])"
|
||||
th:if="${plan.requestStatus != '10'} and ${plan.leaveDate > T(java.time.LocalDate).now()}"
|
||||
class="btn btn-info btn-sm">
|
||||
변경 요청
|
||||
@ -172,6 +227,14 @@
|
||||
</tr>
|
||||
</th:block>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="table-active font-weight-bold text-center">
|
||||
<td>합계</td>
|
||||
<td th:text="${#aggregates.sum(leavePlans.![leaveDays])}"></td>
|
||||
<td th:text="${#aggregates.sum(leavePlans.![T(java.lang.Integer).parseInt(changeCount)])}"></td>
|
||||
<td colspan="3"></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -220,7 +283,7 @@
|
||||
$body.empty(); // 기존 내용 제거
|
||||
|
||||
if (historyList.length === 0) {
|
||||
$body.append('<tr><td colspan="5">변경 이력이 없습니다.</td></tr>');
|
||||
$body.append('<tr><td colspan="6">변경 이력이 없습니다.</td></tr>');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -230,6 +293,9 @@
|
||||
: item.requestStatus === '40' ? 'badge-success'
|
||||
: 'badge-light';
|
||||
|
||||
const leaveDaysChangeHtml = (item.originalLeaveDays != null && item.requestedLeaveDays != null) ?
|
||||
`<td>${item.originalLeaveDays} → ${item.requestedLeaveDays}</td>` : '<td>-</td>';
|
||||
|
||||
const row = `
|
||||
<tr>
|
||||
<td class="bg-secondary text-white font-monospace rounded px-2 py-1">
|
||||
@ -237,6 +303,7 @@
|
||||
</td>
|
||||
<td>${item.originalLeaveDate}</td>
|
||||
<td>${item.requestedLeaveDate}</td>
|
||||
${leaveDaysChangeHtml}
|
||||
<td>${item.requestReason}</td>
|
||||
<td>
|
||||
<span class="badge ${badgeClass} px-3 py-2">${item.requestStatusName}</span>
|
||||
@ -254,11 +321,13 @@
|
||||
});
|
||||
}
|
||||
|
||||
window.openLeaveChangeRequestModal = function (planId, originalLeaveDate) {
|
||||
window.openLeaveChangeRequestModal = function (planId, originalLeaveDate, originalLeaveDays) {
|
||||
console.log(' openLeaveChangeRequestModal ');
|
||||
$('#leaveChangeRequestModal #planId').val(planId);
|
||||
$('#leaveChangeRequestModal #originalLeaveDate').val(originalLeaveDate);
|
||||
$('#leaveChangeRequestModal #originalLeaveDays').val(originalLeaveDays);
|
||||
$('#leaveChangeRequestModal #requestedLeaveDate').val('');
|
||||
$('#leaveChangeRequestModal #requestedLeaveDays').val('1.0');
|
||||
$('#leaveChangeRequestModal #requestReason').val('');
|
||||
$('#leaveChangeRequestModal').modal('show');
|
||||
}
|
||||
@ -266,7 +335,9 @@
|
||||
function submitLeaveChangeRequest() {
|
||||
const planId = $('#leaveChangeRequestModal #planId').val();
|
||||
const originalLeaveDate = $('#leaveChangeRequestModal #originalLeaveDate').val();
|
||||
const originalLeaveDays = $('#leaveChangeRequestModal #originalLeaveDays').val();
|
||||
const requestedLeaveDate = $('#leaveChangeRequestModal #requestedLeaveDate').val();
|
||||
const requestedLeaveDays = $('#leaveChangeRequestModal #requestedLeaveDays').val();
|
||||
const requestReason = $('#leaveChangeRequestModal #requestReason').val();
|
||||
|
||||
if (!requestedLeaveDate) {
|
||||
@ -283,7 +354,9 @@
|
||||
const data = {
|
||||
planId: planId,
|
||||
originalLeaveDate: originalLeaveDate,
|
||||
originalLeaveDays: originalLeaveDays,
|
||||
requestedLeaveDate: requestedLeaveDate,
|
||||
requestedLeaveDays: requestedLeaveDays,
|
||||
requestReason: requestReason
|
||||
};
|
||||
|
||||
@ -295,9 +368,15 @@
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function (response) {
|
||||
fn_successAlert(response.msg);
|
||||
$('#leaveChangeRequestModal').modal('hide');
|
||||
location.reload();
|
||||
if(response.status == 'BAD_REQUEST'){
|
||||
|
||||
fn_failedAlert(response.msg);
|
||||
}else{
|
||||
|
||||
fn_successAlert(response.msg);
|
||||
$('#leaveChangeRequestModal').modal('hide');
|
||||
location.reload();
|
||||
}
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
const errorResponse = JSON.parse(xhr.responseText);
|
||||
@ -321,6 +400,7 @@
|
||||
<div class="modal-body">
|
||||
<form id="leaveChangeRequestForm">
|
||||
<input type="hidden" id="planId" name="planId">
|
||||
<input type="hidden" id="originalLeaveDays" name="originalLeaveDays">
|
||||
<div class="form-group">
|
||||
<label for="originalLeaveDate">기존 연차 일자</label>
|
||||
<input type="text" class="form-control" id="originalLeaveDate" readonly>
|
||||
@ -334,6 +414,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="requestedLeaveDays">변경 요청 일수</label>
|
||||
<select class="form-control" id="requestedLeaveDays" name="requestedLeaveDays">
|
||||
<option value="1.0">연차 (1.0일)</option>
|
||||
<option value="0.5">반차 (0.5일)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="requestReason">변경 요청 사유</label>
|
||||
<textarea class="form-control" id="requestReason" name="requestReason" rows="3" required></textarea>
|
||||
@ -351,7 +438,7 @@
|
||||
<!-- 변경 이력 모달 -->
|
||||
<!-- 변경 이력 모달 -->
|
||||
<div class="modal fade" id="changeHistoryModal" tabindex="-1" role="dialog" aria-labelledby="changeHistoryModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg" role="document">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="changeHistoryModalLabel">변경 이력</h5>
|
||||
@ -367,23 +454,40 @@
|
||||
<th style="width: 20%;">변경 일시</th>
|
||||
<th style="width: 15%;">기존 날짜</th>
|
||||
<th style="width: 15%;">요청 날짜</th>
|
||||
<th style="width: 10%;">변경일수</th>
|
||||
<th style="width: 30%;">요청 사유</th>
|
||||
<th style="width: 20%;">처리 상태</th>
|
||||
<th style="width: 30%;">처리 상태</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="changeHistoryBody">
|
||||
<tr>
|
||||
<td class="bg-secondary text-white font-monospace rounded px-2 py-1">
|
||||
2025-07-15 09:32
|
||||
</td>
|
||||
<td>2025-07-22</td>
|
||||
<td>2025-07-24</td>
|
||||
<td>개인 일정 조정</td>
|
||||
<td>
|
||||
<span class="badge badge-secondary px-3 py-2">대기</span>
|
||||
</td>
|
||||
</tr>
|
||||
<!-- 추가 row 가능 -->
|
||||
<th:block th:if="${not #lists.isEmpty(historyList)}">
|
||||
<tr th:each="item : ${historyList}">
|
||||
<td class="bg-secondary text-white font-monospace rounded px-2 py-1">
|
||||
<span th:text="${#temporals.format(item.requestDt, 'yyyy-MM-dd HH:mm')}"></span>
|
||||
</td>
|
||||
<td th:text="${item.originalLeaveDate}"></td>
|
||||
<td th:text="${item.requestedLeaveDate}"></td>
|
||||
<td>
|
||||
<span th:if="${item.originalLeaveDays != null and item.requestedLeaveDays != null}"
|
||||
th:text="|${item.originalLeaveDays} → ${item.requestedLeaveDays}|"></span>
|
||||
<span th:unless="${item.originalLeaveDays != null and item.requestedLeaveDays != null}">-</span>
|
||||
</td>
|
||||
<td th:text="${item.requestReason}"></td>
|
||||
<td>
|
||||
<span th:class="'badge px-3 py-2 fs-6 ' +
|
||||
(${item.requestStatus} == '20' ? 'badge-secondary' :
|
||||
(${item.requestStatus} == '30' ? 'badge-warning' :
|
||||
(${item.requestStatus} == '40' ? 'badge-success' : 'badge-light')))"
|
||||
th:text="${item.requestStatusName}">
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</th:block>
|
||||
<th:block th:if="${#lists.isEmpty(historyList)}">
|
||||
<tr>
|
||||
<td colspan="6">변경 이력이 없습니다.</td>
|
||||
</tr>
|
||||
</th:block>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user