Files
sam-kd/annualleave/admin.php

471 lines
17 KiB
PHP
Raw Normal View History

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
if (!isset($_SESSION["level"]) || $_SESSION["level"] > 5) {
sleep(1);
header("Location:" . $WebSite . "login/login_form.php");
exit;
}
$title_message = '연차 관리자모드';
$tablename = 'almember';
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
?>
<title><?= $title_message ?></title>
<body>
<?php if($mycompany ==='경동')
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader.php');
else
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php');
?>
</head>
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/common.php");
// 테스트 예제
// $fiscalYearEnd = "2024-12-31"; // 현재 기준 회계년도말
// 현재 연도를 가져온 후, 이전 연도의 마지막 날을 생성
// $fiscalYearEnd = (date('Y') - 1) . "-12-31";
// // 입사일 배열
// $hireDates = [
// "2024-12-2", "2024-12-5", "2024-11-21", "2024-6-17", "2022-6-8",
// "2022-10-11", "2022-10-17", "2020-3-6", "2020-8-1", "2021-1-7",
// "2021-1-25", "2021-3-22", "2021-6-24", "2021-9-13", "2021-10-1",
// "2020-5-1", "2019-4-1", "2019-12-9", "2023-3-6", "2017-11-1",
// "2023-4-3", "2016-11-14", "2015-7-14", "2024-4-9", "2023-7-3",
// "2023-7-24", "2023-8-1", "2023-8-1", "2024-3-4", "2023-9-1",
// "2024-2-5"
// ];
// foreach ($hireDates as $hireDate) {
// $result = calculateAnnualLeave($hireDate, $fiscalYearEnd);
// echo "입사일: $hireDate, 근속연수: {$result['G']}, &nbsp;&nbsp;&nbsp;&nbsp; 최초1,2년미만 가산: {$result['H']}, &nbsp;&nbsp;&nbsp;&nbsp; 년도별 연차일수: {$result['I']}, &nbsp;&nbsp;&nbsp;&nbsp; 총발생일수: {$result['J']}<br>";
// }
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
$pdo = db_connect();
// 검색 조건 변수 추가
$mode = isset($_REQUEST["mode"]) ? $_REQUEST["mode"] : "";
$search = isset($_REQUEST["search"]) ? $_REQUEST["search"] : "";
$corpSearch = isset($_REQUEST["corpSearch"]) ? $_REQUEST["corpSearch"] : $mycompany ;
$partSearch = isset($_REQUEST["partSearch"]) ? $_REQUEST["partSearch"] : "";
$year = isset($_REQUEST["year"]) ? $_REQUEST["year"] : date("Y");
$showRetired = isset($_POST['showRetired']) ? $_POST['showRetired'] : 0;
// JSON 파일에서 소속 및 부서 데이터 로드
$corpFile = $_SERVER['DOCUMENT_ROOT'] . '/member/corp.json';
$corpData = file_exists($corpFile) ? json_decode(file_get_contents($corpFile), true) : [];
if (!is_array($corpData)) $corpData = [];
$partFile = $_SERVER['DOCUMENT_ROOT'] . '/member/part.json';
$partData = file_exists($partFile) ? json_decode(file_get_contents($partFile), true) : [];
if (!is_array($partData)) $partData = [];
// 기본 SQL 조건
$conditions = ["referencedate = :year", "is_deleted IS NULL"];
$bindParams = [':year' => $year];
if (!$showRetired) {
$conditions[] = "(comment IS NULL OR comment = '')";
} else {
$conditions[] = "comment = '퇴사'";
}
// 검색 조건 추가
if ($mode == "search") {
if (!empty($search)) {
$columns = [];
$stmt = $pdo->query("SHOW COLUMNS FROM " . $DB . "." . $tablename);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$columns[] = $row['Field'];
}
$searchConditions = [];
foreach ($columns as $index => $col) {
$paramName = ":search{$index}";
$searchConditions[] = "$col LIKE $paramName";
$bindParams[$paramName] = "%$search%";
}
$conditions[] = "(" . implode(" OR ", $searchConditions) . ")";
}
if (!empty($corpSearch)) {
$conditions[] = "company LIKE :corpSearch";
$bindParams[":corpSearch"] = "%$corpSearch%";
}
if (!empty($partSearch)) {
$conditions[] = "part LIKE :partSearch";
$bindParams[":partSearch"] = "%$partSearch%";
}
}
// almember의 기본정보 배열을 불러옴 (예, $basic_name_arr, $basic_part_arr 등)
require_once($_SERVER['DOCUMENT_ROOT'] . "/almember/load_DB.php");
// echo '<pre>';
// print_r($previous_year_usage_arr);
// echo '</pre>';
$sql = "SELECT * FROM {$DB}.almember WHERE " . implode(" AND ", $conditions) . " ORDER BY referencedate DESC, dateofentry ASC, num DESC";
$stmh = $pdo->prepare($sql);
$stmh->execute($bindParams);
$total_row = $stmh->rowCount();
// print $admin;
?>
<form name="board_form" id="board_form" method="post" action="admin.php?mode=search">
<input type="hidden" id="ALadmin" name="ALadmin" value="<?=$ALadmin?>">
<div class="container">
<div class="card mt-2 mb-4">
<div class="card-body">
<div class="d-flex mt-3 mb-3 justify-content-center align-items-center">
<span class="text-dark fs-5" > <?=$title_message?> &nbsp;&nbsp; </span>
<button type="button" class="btn btn-dark btn-sm mx-2" onclick='location.reload()'> <i class="bi bi-arrow-clockwise"></i> </button>
<button type="button" id="backBtn" class="btn btn-outline-primary btn-sm mx-2" > <ion-icon name="caret-back-circle-outline"></ion-icon> 이전화면 </button> &nbsp;&nbsp;&nbsp;
</div>
<div class="d-flex mt-3 mb-3 justify-content-center align-items-center">
<span class="text-secondary fs-6" > 주일/경동 연차는 (회계년도말) 기준으로 산정한다. </span>
</div>
<div class="d-flex mt-3 justify-content-center align-items-center">
<i class="bi bi-caret-right"></i> <?= $total_row ?>개 &nbsp;&nbsp;&nbsp;
<!-- 퇴사자 체크박스 -->
<div class="form-check">
<input class="form-check-input" type="checkbox" id="showRetired" name="showRetired" value=1 onchange="filterRetired()" <?php echo isset($_POST['showRetired']) && $_POST['showRetired'] == 1 ? 'checked' : ''; ?>>
<label class="form-check-label mx-2" for="showRetired">퇴사자 보기</label>
</div>
&nbsp;&nbsp;&nbsp;
<span class="mx-1"> 선택년도</span>
<select name="year" id="year" class="form-select w80px mx-1" style="font-size: 0.8rem; height: 32px;">
<?php
$current_year = date("Y"); // 현재 년도를 얻습니다.
$year_arr = array(); // 빈 배열을 생성합니다.
for ($i = 0; $i < 3; $i++) {
$year_arr[] = $current_year - $i;
}
for($i=0;$i<count($year_arr);$i++) {
if($year==$year_arr[$i])
print "<option selected value='" . $year_arr[$i] . "'> " . $year_arr[$i] . "</option>";
else
print "<option value='" . $year_arr[$i] . "'> " . $year_arr[$i] . "</option>";
}
?>
</select>
<!-- 소속 검색 select 추가 -->
<div class="inputWrap30 mx-1">
<select name="corpSearch" id="corpSearch" class="form-select w-auto mx-1" style="font-size: 0.8rem; height: 32px;">
<option value=""><?= "(소속)" ?></option>
<?php foreach($corpData as $corp): ?>
<option value="<?= htmlspecialchars($corp, ENT_QUOTES, 'UTF-8') ?>" <?= ($corpSearch === $corp) ? 'selected' : '' ?>>
<?= htmlspecialchars($corp, ENT_QUOTES, 'UTF-8') ?>
</option>
<?php endforeach; ?>
</select>
</div>
<!-- 부서 검색 select 추가 -->
<div class="inputWrap30 mx-1">
<select name="partSearch" id="partSearch" class="form-select w-auto mx-1" style="font-size: 0.8rem; height: 32px;">
<option value=""><?= "(부서)" ?></option>
<!-- 옵션은 JS에서 동적으로 채워짐 -->
</select>
</div>
<input type="text" name="search" id="search" class="form-control mx-1" style="width:150px; height: 32px;" value="<?=$search?>" onkeydown="JavaScript:SearchEnter();" placeholder="검색어" autocomplete="off" >
&nbsp;
<button type="button" id="searchBtn" class="btn btn-dark btn-sm mx-1" > <i class="bi bi-search"></i> 검색 </button>
<?php if (intval($ALadmin) == 1 ) { ?>
<button type="button" class="btn btn-dark btn-sm mx-1" onclick="popupCenter('write_form.php', '신규', 600, 400);return false;" > <i class="bi bi-pencil"></i> 신규 </button>
<button type="button" class="btn btn-dark btn-sm mx-1" id="csvDownload" > <i class="bi bi-floppy-fill"></i> CSV </button>
<button type="button" id="massBtn" class="btn btn-sm btn-primary mx-1"> <i class="bi bi-cloud-arrow-up"></i> 대량등록</button>
<?php } ?>
</div>
<div class="row d-flex mt-3 mb-1 justify-content-center align-items-center">
<table class="table table-hover" id="myTable">
<thead class="table-primary">
<tr>
<th class="text-center">번호</th>
<th class="text-center">구분</th>
<th class="text-center">성명</th>
<th class="text-center">회사</th>
<th class="text-center">파트</th>
<th class="text-center">입사일</th>
<th class="text-center">해당연도</th>
<th class="text-center">근속년</th>
<th class="text-center">1~2년미만 가산</th>
<th class="text-center">근속년수별</th>
<th class="text-center">발생일합</th>
<th class="text-center">전년도 선사용</th>
<th class="text-center">사용일 합계</th>
<th class="text-center">잔여일</th>
</tr>
</thead>
<tbody>
<?php
$start_num = $total_row;
while ($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
include "_row.php";
// 년도를 추출하여 -1을 적용
// 문자열 연결 연산자 `.` 추가
$fiscalYearEnd = ($referencedate - 1) . "-12-31";
// echo '참고년도 : ' . $referencedate ;
// echo '전년도 : ' . $fiscalYearEnd ;
$result = calculateAnnualLeave($dateofentry, $fiscalYearEnd);
$continueYear = $result['G'];
$initial_less_than_one_year = $result['H'];
$service_based = $result['I'];
$availableday = $result['J'];
$totalusedday = 0;
$totalremainday = isset($availableday) ? $availableday : 0;
if (isset($totalname_arr) && is_array($totalname_arr) && count($totalname_arr) > 0) {
for ($i = 0; $i < count($totalname_arr); $i++) {
if (trim($name) == trim($totalname_arr[$i]) && $referencedate == $totalusedYear_arr[$i]) {
$totalusedday = $totalused_arr[$i];
$previous_year_usage = $previous_year_usage_arr[$i];
$totalremainday = $availableday - $totalusedday - $previous_year_usage;
}
}
}
?>
<tr onclick="redirectToView('<?= $row['num'] ?>', '<?= $tablename ?>')">
<td class="text-center"><?=$start_num?> </td>
<td class="text-center"><?=$comment?> </td>
<td class="text-center"><?=$name?> </td>
<td class="text-center"><?=$company?> </td>
<td class="text-center"><?=$part?> </td>
<td class="text-center"><?=$dateofentry?> </td>
<td class="text-center"><?=$referencedate?> </td>
<td class="text-center"><?= $continueYear ? $continueYear : '' ?> </td>
<td class="text-center text-dark"><?= $initial_less_than_one_year ? $initial_less_than_one_year : '' ?> </td>
<td class="text-center text-secondary"><b><?= $service_based ? $service_based : '' ?></b> </td>
<td class="text-center text-primary"><b><?= $availableday ? $availableday : '' ?></b> </td>
<td class="text-center "> <?= $previous_year_usage ? '<h6> <span class="badge bg-primary"> ' . $previous_year_usage . ' </span> </h6> ' : '' ?> </td>
<td class="text-center text-success"><b><?= $totalusedday ? $totalusedday : '' ?></b> </td>
<td class="text-center <?= ($totalremainday < 0) ? 'text-danger' : 'text-dark' ?>">
<b><?= $totalremainday ?: '' ?></b>
</td>
</tr>
<?php
$start_num--;
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</form>
<br>
<br>
<div class="container">
<? include '../footer.php'; ?>
</div>
<!-- 페이지로딩 -->
<script>
$(document).ready(function(){
var loader = document.getElementById('loadingOverlay');
loader.style.display = 'none';
});
</script>
<script>
var dataTable; // DataTables 인스턴스 전역 변수
var aladminpageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
$(document).ready(function() {
// DataTables 초기 설정
dataTable = $('#myTable').DataTable({
"paging": true,
"ordering": true,
"searching": false,
"pageLength": 50,
"lengthMenu": [25, 50, 100, 200, 500, 1000],
"language": {
"lengthMenu": "Show _MENU_ entries",
"search": "Live Search:"
},
"order": [[0, 'desc']]
});
// 페이지 번호 복원 (초기 로드 시)
var savedPageNumber = getCookie('aladminpageNumber');
if (savedPageNumber) {
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
}
// 페이지 변경 이벤트 리스너
dataTable.on('page.dt', function() {
var aladminpageNumber = dataTable.page.info().page + 1;
setCookie('aladminpageNumber', aladminpageNumber, 10); // 쿠키에 페이지 번호 저장
});
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
$('#myTable_length select').on('change', function() {
var selectedValue = $(this).val();
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
// 변경 후 현재 페이지 번호 복원
savedPageNumber = getCookie('aladminpageNumber');
if (savedPageNumber) {
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
}
});
});
function restorePageNumber() {
var savedPageNumber = getCookie('aladminpageNumber');
if (savedPageNumber) {
dataTable.page(parseInt(savedPageNumber) - 1).draw('page');
}
}
function SearchEnter(){
if(event.keyCode == 13){
document.getElementById('board_form').submit();
}
}
$(document).ready(function(){
$('select[name="year"]').change(function(){
var val = $('input[name="year"]:checked').val();
document.getElementById('board_form').submit();
});
$("#closeModalBtn").click(function(){
$('#myModal').modal('hide');
});
$("#searchBtn").click(function(){
document.getElementById('board_form').submit();
});
$("#backBtn").click(function(){
location.href='/annualleave/index.php';
});
$("#massBtn").click(function(){
popupCenter('write_form_init.php', '연초 대량등록', 420, 800);
});
});
function redirectToView(num, tablename) {
var ALadmin = document.getElementById("ALadmin").value; // hidden input의 값 가져오기
if (ALadmin != "1") {
Swal.fire({
title: '접근 제한',
text: '관리자만 수정이 가능합니다.',
icon: 'warning',
confirmButtonText: '확인'
});
return; // 함수 실행 중지
}
var url = "write_form.php?mode=modify&num=" + num + "&tablename=" + tablename;
customPopup(url, '연차 수정', 600, 400);
}
document.getElementById("csvDownload").addEventListener("click", function() {
const table = document.getElementById("myTable");
const theadRow = table.querySelector("thead tr");
const rows = table.querySelectorAll("tbody tr");
const csvRows = [];
// Include the header row
const headerData = [];
theadRow.querySelectorAll("th").forEach(function(cell) {
headerData.push(cell.textContent);
});
csvRows.push(headerData.join(","));
// Include the data rows
rows.forEach(function(row) {
const rowData = [];
row.querySelectorAll("td").forEach(function(cell) {
rowData.push(cell.textContent);
});
csvRows.push(rowData.join(","));
});
const csvContent = csvRows.join("\n");
// 한글깨짐문제 '\ufeff' + data 이것 참조
const blob = new Blob(['\ufeff' + csvContent], { type: "text/csv;charset=utf-8;" });
const link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.setAttribute("download", "직원연차.csv");
document.body.appendChild(link);
link.click();
});
function filterRetired() {
// 퇴사자 체크박스 상태 확인
// const showRetired = document.getElementById('showRetired').checked;
document.getElementById('board_form').submit();
}
$(document).ready(function(){
var title = '<?=$title_message;?>';
saveMenuLog(title);
});
</script>
<script>
$(document).ready(function(){
// PHP의 부서 JSON 데이터를 JS 변수로 저장 (각 항목은 ['corp'=> ..., 'part'=> ...] 형식)
var partData = <?= json_encode($partData) ?>;
// PHP에서 전달된 부서 검색 값 (기존에 선택된 값)
var initialPart = "<?= htmlspecialchars($partSearch, ENT_QUOTES, 'UTF-8') ?>";
// 부서 select 업데이트 함수
function updatePartSelect(selectedCorp) {
var $partSelect = $('#partSearch');
$partSelect.empty();
$partSelect.append('<option value=""><?= "(부서)" ?></option>');
// 선택된 소속과 일치하는 부서 옵션만 추가
$.each(partData, function(index, dept) {
if(dept.corp === selectedCorp) {
$partSelect.append('<option value="'+ dept.part +'">'+ dept.part +'</option>');
}
});
// 만약 초기 부서값이 있다면 선택
if(initialPart !== "") {
$partSelect.val(initialPart);
}
}
// 페이지 로드 시, 이미 소속이 선택되어 있다면 부서 옵션 업데이트
var initialCorp = $('#corpSearch').val();
updatePartSelect(initialCorp);
// 소속 select 변경 시 부서 select 업데이트
$('#corpSearch').on('change', function(){
var selectedCorp = $(this).val();
updatePartSelect(selectedCorp);
});
});
</script>
</body>
</html>