Files
sam-kd/annualleave/process.php
hskwon aca1767eb9 초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경
- DB 연결 하드코딩 → .env 기반으로 변경
- MySQL strict mode DATE 오류 수정
2025-12-10 20:14:31 +09:00

456 lines
14 KiB
PHP

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
$title_message = '연차 신청';
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
$tablename = "eworks";
isset($_REQUEST["num"]) ? $num=$_REQUEST["num"] : $num='';
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
$pdo = db_connect();
try{
$sql = "select * from " . $DB . "." . $tablename . " where num = ? ";
$stmh = $pdo->prepare($sql);
$stmh->bindValue(1,$num,PDO::PARAM_STR);
$stmh->execute();
$count = $stmh->rowCount();
$row = $stmh->fetch(PDO::FETCH_ASSOC); // $row 배열로 DB 정보를 불러온다.
include 'rowDBask.php';
}catch (PDOException $Exception) {
print "오류: ".$Exception->getMessage();
}
// end of if
// 배열로 기본정보 불러옴
include "load_DB.php";
// holiday 테이블에서 휴일 목록 불러오기
$holidayDates = [];
try {
$holidaySql = "SELECT startdate, enddate FROM " . $DB . ".holiday WHERE is_deleted IS NULL";
$holidayStmt = $pdo->query($holidaySql);
$holidayRows = $holidayStmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($holidayRows as $holidayRow) {
$startdate = $holidayRow['startdate'];
$enddate = $holidayRow['enddate'];
// enddate가 '0000-00-00'이거나 비어있으면 startdate만 휴일
if (empty($enddate) || $enddate === '0000-00-00' || $enddate === null) {
$holidayDates[] = $startdate;
} else {
// 기간 내의 모든 날짜를 배열에 추가
$start = new DateTime($startdate);
$end = new DateTime($enddate);
$end->modify('+1 day'); // 종료일 포함
$period = new DatePeriod($start, new DateInterval('P1D'), $end);
foreach ($period as $date) {
$holidayDates[] = $date->format('Y-m-d');
}
}
}
} catch (PDOException $e) {
// 오류 발생 시 빈 배열 유지
error_log("Holiday 데이터 로드 오류: " . $e->getMessage());
}
// print $totalremainday;
// 잔여일수 개인별 산출 루틴
try{
// 연차 잔여일수 산출
$totalusedday = 0;
$totalremainday = 0;
for($i=0;$i<count($totalname_arr);$i++)
if($author== $totalname_arr[$i])
{
$availableday = $availableday_arr[$i];
}
// 연차 사용일수 계산
for($i=0;$i<count($totalname_arr);$i++)
if($author== $totalname_arr[$i])
{
$totalusedday = $totalused_arr[$i];
$totalremainday = $availableday - $totalusedday;
}
} catch (PDOException $Exception) {
print "오류: ".$Exception->getMessage();
}
?>
<body>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog modal-lg modal-center" >
<!-- Modal content-->
<div class="modal-content modal-lg">
<div class="modal-header">
<h4 class="modal-title">알림</h4>
</div>
<div class="modal-body">
<div id=alertmsg class="fs-1 mb-5 justify-content-center" >
결재가 완료되었습니다. <br>
<br>
수고하셨습니다.
</div>
</div>
<div class="modal-footer">
<button type="button" id="closeModalBtn" class="btn btn-default" data-dismiss="modal">닫기</button>
</div>
</div>
</div>
</div>
<div class="container h-60">
<div class="row d-flex justify-content-center align-items-center h-50">
<div class="col-12 text-center">
<div class="card align-middle" style="width:24rem; border-radius:20px;">
<div class="card" style="padding:10px;margin:10px;">
<h3 class="card-title text-center" style="color:#113366;"> (연차) 승인</h3>
</div>
<div class="card-body text-center">
<form id="board_form" class="form-signin" method="post" >
<input type="hidden" id="mode" name="mode">
<input type="hidden" id="num" name="num" value="<?=$num?>" >
<input type="hidden" id="registdate" name="registdate" value="<?=$today?>" >
<input type="hidden" id="al_part" name="al_part" value="<?=$al_part?>" >
<input type="hidden" id="author_id" name="author_id" value="<?=$author_id?>" >
<input type="hidden" id="admin_name" name="admin_name" value="<?=$admin_name?>" >
<span class="form-control">
성 명 <input type="text" id="author" name="author" size=8 class="text-center" readonly value="<?=$author?>" >
</span>
<span class="form-control">
선택 &nbsp;&nbsp;
<?php
// 연차종류 4종류로 만듬
$item_arr = array('연차','오전반차','오전반반차','오후반차','오후반반차');
for($i=0;$i<count($item_arr);$i++) {
if($al_item==$item_arr[$i])
print "<input type='radio' name='al_item' checked='checked' value='" . $item_arr[$i] . "'> " . $item_arr[$i] . " &nbsp ";
else
print "<input type='radio' name='al_item' value='" . $item_arr[$i] . "'> " . $item_arr[$i] . " &nbsp ";
}
?>
</span>
<span class="form-control">
신청시작일 <input type="date" id="al_askdatefrom" name="al_askdatefrom" readonly required autofocus value="<?=$al_askdatefrom?>" >
</span>
<span class="form-control">
신청종료일
<input type="date" id="askdateto" name="askdateto" readonly required value="<?=$al_askdateto?>" >
</span>
<span class="form-control">
<span style="color:blue">신청 기간 산출</span>
<input type="text" id="al_usedday" size=2 name="al_usedday" readonly class="text-center" value="<?=$al_usedday?>" >
</span>
<span class="form-control">
<span style="color:red">연차 잔여일수</span>
<input type="text" id="totalremainday" name="totalremainday" size=2 class="text-center" readonly value="<?=$totalremainday?>" >
</span>
<br>
<h6 class="form-signin-heading">신청 사유</h6>
<select name="al_content" id="al_content" readonly class="form-control text-center" >
<?php
$content_arr= array();
array_push($content_arr,"개인사정","휴가","여행", "병원진료등", "모두 함께 쉬는 연차휴가", "기타");
for($i=0;$i<count($content_arr);$i++) {
if($al_content==$content_arr[$i])
print "<option selected readonly value='" . $content_arr[$i] . "'> " . $content_arr[$i] . "</option>";
else
print "<option readonly value='" . $content_arr[$i] . "'> " . $content_arr[$i] . "</option>";
}
?>
</select>
<?php
switch($status) {
case 'send':
$statusstr = '결재요청';
break;
case 'ing':
$statusstr = '결재중';
break;
case 'end':
$statusstr = '결재완료';
break;
default:
$statusstr = '';
break;
}
?>
<h6 class="form-signin-heading">결재 상태</h6>
<input type="hidden" id="status" name="status" value="<?=$status?>" >
<input type="text" id="statusstr" name="statusstr" class="form-control text-center" readonly value="<?=$statusstr?>" >
<br>
<button id="saveBtn" class="btn btn-lg btn-secondary btn-block" type="button">
<? if((int)$num>0) print '승인'; else print '결재요청(등록)'; ?></button>
<? if((int)$num>0) { ?>
<button id="delBtn" class="btn btn-lg btn-danger btn-block" type="button">삭제</button>
<? } ?>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function(){
// 파트 가져옴 (제조파트, 지원파트)
var al_part = '<?php echo $al_part; ?>';
// 신청일 변경시 종료일도 변경함
$("#al_askdatefrom").change(function(){
var radioVal = $('input[name="al_item"]:checked').val();
console.log(radioVal);
$('#al_askdateto').val($("#al_askdatefrom").val());
const result = getDateDiff($("#al_askdatefrom").val(), $("#al_askdateto").val());
switch(radioVal)
{
case '연차' :
$('#al_usedday').val(result);
break;
case '오전반차' :
case '오후반차' :
$('#al_usedday').val(result/2);
break;
case '오전반반차' :
case '오후반반차' :
$('#al_usedday').val(result/4);
break;
}
});
$('input[name="al_item"]').change(function(){
var radioVal = $('input[name="al_item"]:checked').val();
console.log(radioVal);
// $('#al_askdateto').val($("#al_askdatefrom").val());
const result = getDateDiff($("#al_askdatefrom").val(), $("#al_askdateto").val());
switch(radioVal)
{
case '연차' :
$('#al_usedday').val(result);
break;
case '오전반차' :
case '오후반차' :
$('#al_usedday').val(result/2);
break;
case '오전반반차' :
case '오후반반차' :
$('#al_usedday').val(result/4);
break;
}
});
// 종료일을 변경해도 자동계산해 주기
$("#al_askdateto").change(function(){
var radioVal = $('input[name="al_item"]:checked').val();
console.log(radioVal);
// $('#al_askdateto').val($("#al_askdatefrom").val());
const result = getDateDiff($("#al_askdatefrom").val(), $("#al_askdateto").val());
switch(radioVal)
{
case '연차' :
$('#al_usedday').val(result);
break;
case '오전반차' :
case '오후반차' :
$('#al_usedday').val(result/2);
break;
}
});
$("#closeBtn").click(function(){ // 저장하고 창닫기
});
$("#copyBtn").click(function(){ // 데이터복사버튼
var num = $("#num").val();
location.href='copy_data.php?num=' + num;
});
$("#saveBtn").click(function(){ // DATA 저장버튼 누름
var num = $("#num").val();
var status = $("#status").val();
$("#mode").val('modify');
var admin_name = $("#admin_name").val();
var resultOK = 0;
console.log(status);
console.log(admin_name);
if((admin_name == '소현철' || admin_name =='김보곤') && status =='ing') {
$("#status").val('end');
resultOK = 1;
} // end of if
// 지원파트 1차 결재
if((admin_name=='최장중' || admin_name=='김보곤') && status=='send' && al_part=='지원파트') {
$("#status").val('ing');
resultOK = 1;
} // end of if
// 제조파트 1차 결재
if((admin_name=='이경묵' || admin_name=='김보곤') && status=='send' && al_part=='제조파트') {
$("#status").val('ing');
resultOK = 1;
} // end of if
console.log('변경후 status ' + status);
if(resultOK == 1) { // 결과가 성공하면
$.ajax({
url: "insert_ask.php",
type: "post",
data: $("#board_form").serialize(),
dataType:"json",
success : function( data ){
console.log( data);
$('#myModal').modal('show');
//1초 지연후 실행
setTimeout(function() {
opener.location.reload();
window.close();
}, 2000);
},
error : function( jqxhr , status , error ){
console.log( jqxhr , status , error );
}
});
}
else // 오류가 있으면 오류창 띄움
{
tmp='결재권자가 틀립니다. 확인바랍니다.';
$('#alertmsg').html(tmp);
$('#myModal').modal('show');
//1초 지연후 실행
setTimeout(function() {
opener.location.reload();
window.close();
}, 2000);
}
});
$("#delBtn").click(function(){ // del
var num = $("#num").val();
var status = $("#status").val();
// 결재요청이 아닌경우 수정안됨
if(confirm("데이터 삭제.\n\n정말 지우시겠습니까?")) {
$("#mode").val('delete');
$.ajax({
url: "insert_ask.php",
type: "post",
data: $("#board_form").serialize(),
dataType:"json",
success : function( data ){
console.log( data);
opener.location.reload();
window.close();
},
error : function( jqxhr , status , error ){
console.log( jqxhr , status , error );
}
});
} // end of if
});
}); // end of ready document
// PHP에서 전달된 휴일 목록을 JavaScript 변수로 변환
var holidayDates = <?= json_encode($holidayDates, JSON_UNESCAPED_UNICODE) ?>;
// 휴일 날짜를 Set으로 변환하여 빠른 검색 가능하도록 함
var holidaySet = new Set(holidayDates);
// 날짜를 YYYY-MM-DD 형식으로 변환하는 함수
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 getDateDiff = (d1, d2) => {
if (!d1 || !d2) return 0;
const date1 = new Date(d1);
const date2 = new Date(d2);
// 날짜 유효성 검사
if (isNaN(date1.getTime()) || isNaN(date2.getTime())) {
console.warn('getDateDiff: 유효하지 않은 날짜', d1, d2);
return 0;
}
// holidaySet이 없으면 빈 Set 사용 (방어 코드)
const holidays = (typeof holidaySet !== 'undefined' && holidaySet instanceof Set)
? holidaySet
: (typeof window.holidaySet !== 'undefined' && window.holidaySet instanceof Set)
? window.holidaySet
: new Set();
let count = 0;
const oneDay = 24 * 60 * 60 * 1000; // 하루의 밀리세컨드 수
// 시작일과 종료일을 포함하여 계산하기 위해 date1의 복사본 생성
let startDate = new Date(date1);
let endDate = new Date(date2);
// 시작일이 종료일보다 큰 경우 교환
if (startDate > endDate) {
const temp = startDate;
startDate = endDate;
endDate = temp;
}
// 시작일부터 종료일까지 반복 (포함)
const currentDate = new Date(startDate);
while (currentDate <= endDate) {
const dayOfWeek = currentDate.getDay(); // 요일 (0:일, 1:월, ..., 6:토)
const dateString = formatDate(currentDate); // YYYY-MM-DD 형식으로 변환
// 주말이 아니고 휴일도 아닌 경우에만 count 증가
if (dayOfWeek !== 0 && dayOfWeek !== 6 && !holidays.has(dateString)) {
count++;
}
currentDate.setTime(currentDate.getTime() + oneDay); // 다음 날짜로 이동
}
return count;
}
</script>
</body>
</html>