- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
391 lines
15 KiB
PHP
391 lines
15 KiB
PHP
<?php include $_SERVER['DOCUMENT_ROOT'] . '/session.php'; ?>
|
|
<?php include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php' ?>
|
|
|
|
<style>
|
|
.table-bordered,
|
|
.table-bordered td,
|
|
.table-bordered th {
|
|
border-color: #000000 !important; /* 더 진한 테두리 색상 */
|
|
}
|
|
</style>
|
|
|
|
<body>
|
|
<?php
|
|
require_once($_SERVER['DOCUMENT_ROOT'] . "/common.php");
|
|
$num = $_REQUEST["num"] ?? '';
|
|
|
|
// 새로 추가: 소속 검색값 (corpSearch)
|
|
$corpSearch = isset($_REQUEST["corpSearch"]) ? $_REQUEST["corpSearch"] : "";
|
|
$partSearch = isset($_REQUEST["partSearch"]) ? $_REQUEST["partSearch"] : "";
|
|
|
|
// corp.json 파일에서 소속 목록 불러오기
|
|
$corpFile = $_SERVER['DOCUMENT_ROOT'] . '/member/corp.json';
|
|
$corpData = [];
|
|
if (file_exists($corpFile)) {
|
|
$corpJson = file_get_contents($corpFile);
|
|
$corpData = json_decode($corpJson, true);
|
|
if (!is_array($corpData)) { $corpData = []; }
|
|
}
|
|
|
|
// part.json 파일에서 부서 목록 불러오기
|
|
$partFile = $_SERVER['DOCUMENT_ROOT'] . '/member/part.json';
|
|
$partData = [];
|
|
if (file_exists($partFile)) {
|
|
$partJson = file_get_contents($partFile);
|
|
$partData = json_decode($partJson, true);
|
|
if (!is_array($partData)) {
|
|
$partData = [];
|
|
}
|
|
}
|
|
|
|
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
|
$pdo = db_connect();
|
|
|
|
// almember의 기본정보 배열을 불러옴 (예, $basic_name_arr, $basic_part_arr 등)
|
|
require_once($_SERVER['DOCUMENT_ROOT'] . "/almember/load_DB.php");
|
|
|
|
$currentYear = date("Y"); // 현재 년도 가져오기
|
|
|
|
// echo '<pre>';
|
|
// print_r($dateofentry_arr);
|
|
// echo '</pre>';
|
|
|
|
?>
|
|
<form id="board_form" name="board_form" class="form-signin" method="post" >
|
|
<div class="container-fluid" style="width:380px;">
|
|
<div class="row d-flex justify-al_content-center align-items-center h-50">
|
|
<div class="col-12 text-center">
|
|
<div class="card align-middle" style="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">
|
|
<input type="hidden" id="mode" name="mode">
|
|
<input type="hidden" id="num" name="num" value="<?=$num?>" >
|
|
<input type="hidden" id="registdate" name="registdate" value="<?=$registdate?>" >
|
|
<input type="hidden" id="user_name" name="user_name" value="<?=$user_name?>" >
|
|
<input type="hidden" id="author_id" name="author_id" value="<?=$author_id?>" >
|
|
<input type="hidden" id="htmltext" name="htmltext" >
|
|
<div id="savetext">
|
|
<div class="d-flex justify-content-center align-items-center mb-3">
|
|
<!-- 해당년도 및 현재년도 input 추가 -->
|
|
<div class="mt-1">
|
|
<label for="current-year" class="form-label">해당년도</label>
|
|
<input type="text" id="current-year" name="current_year" class="form-control fs-6 text-center" value="<?= $currentYear ?>" readonly>
|
|
</div>
|
|
</div>
|
|
<div class="d-flex justify-content-center align-items-center mb-3">
|
|
<!-- 소속 검색 select 추가 -->
|
|
<div class="inputWrap30 mx-1">
|
|
<select name="corpSearch" id="corpSearch" class="form-select w100px mx-1" style="font-size: 0.9rem; 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 w120px mx-1" style="font-size: 0.9rem; height: 32px;">
|
|
<option value=""><?= "(부서)" ?></option>
|
|
<!-- 옵션은 JS에서 동적으로 채워짐 -->
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-center align-items-center mb-3">
|
|
<input type="checkbox" id="select-all" class="d-flex align-items-center me-2 mb-2" >
|
|
<label for="select-all" class="d-flex align-items-center me-2 mb-2" >
|
|
전체 선택
|
|
</label>
|
|
</div>
|
|
<div class="d-flex justify-content-center align-items-center mb-3">
|
|
<div id="author-list" class="d-flex flex-wrap mt-2">
|
|
<?php
|
|
for ($i = 0; $i < count($employee_name_arr); $i++) {
|
|
// $author 변수가 미리 설정되어 있다면 해당 직원과 비교하여 checked 처리 (없다면 생략)
|
|
$checked = (isset($author) && $author == $employee_name_arr[$i]) ? "checked" : "";
|
|
$dateofentry = $employee_dateofentry_arr[$i] ?? '';
|
|
$company = $employee_company_arr[$i] ?? '';
|
|
$part = $employee_part_arr[$i] ?? '';
|
|
|
|
// $fiscalYearEnd = ($referencedate - 1) . "-12-31";
|
|
// 현재 연도를 가져온 후, 이전 연도의 마지막 날을 생성
|
|
$fiscalYearEnd = (date('Y') - 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'];
|
|
|
|
echo "<div class='d-flex align-items-start text-start mb-1' style='width: 33.33%;'>";
|
|
echo " <label class='w-100'>";
|
|
echo " <input type='checkbox' class='author-checkbox ms-3' name='author[]' value='" . htmlspecialchars($employee_name_arr[$i], ENT_QUOTES, 'UTF-8') . "' ";
|
|
echo " data-author-id='" . htmlspecialchars($employee_id_arr[$i], ENT_QUOTES, 'UTF-8') . "' ";
|
|
echo " data-company='" . htmlspecialchars($company, ENT_QUOTES, 'UTF-8') . "' ";
|
|
echo " data-availableday='" . htmlspecialchars($availableday, ENT_QUOTES, 'UTF-8') . "' ";
|
|
echo " data-initial_less_than_one_year='" . htmlspecialchars($initial_less_than_one_year, ENT_QUOTES, 'UTF-8') . "' ";
|
|
echo " data-service_based='" . htmlspecialchars($service_based, ENT_QUOTES, 'UTF-8') . "' ";
|
|
echo " data-part='" . htmlspecialchars($part, ENT_QUOTES, 'UTF-8') . "' ";
|
|
echo " data-dateofentry='" . htmlspecialchars($dateofentry, ENT_QUOTES, 'UTF-8') . "' $checked>";
|
|
echo " <span class='ms-2'>" . htmlspecialchars($employee_name_arr[$i], ENT_QUOTES, 'UTF-8') . "</span>";
|
|
echo " </label>";
|
|
echo "</div>";
|
|
}
|
|
?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
// "전체 선택" 체크박스 동작
|
|
$('#select-all').on('change', function () {
|
|
var isChecked = $(this).is(':checked');
|
|
$('.author-checkbox').prop('checked', isChecked);
|
|
});
|
|
|
|
// 개별 체크박스 동작 시 "전체 선택" 체크박스 상태 업데이트
|
|
$('.author-checkbox').on('change', function () {
|
|
var allChecked = $('.author-checkbox:checked').length === $('.author-checkbox').length;
|
|
$('#select-all').prop('checked', allChecked);
|
|
});
|
|
</script>
|
|
<div class="d-flex justify-content-center align-items-center mb-3">
|
|
<button id="saveBtn" class="btn btn-sm btn-dark mx-1" type="button"> <i class="bi bi-floppy-fill"></i> (주의) 대량등록 실행 </button>
|
|
<button class="btn btn-dark btn-sm ms-3" id="closeBtn" > × 닫기 </button>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
<script>
|
|
var ajaxRequest = null;
|
|
|
|
$(document).ready(function(){
|
|
var loader = document.getElementById('loadingOverlay');
|
|
if(loader)
|
|
loader.style.display = 'none';
|
|
});
|
|
|
|
$(document).ready(function(){
|
|
|
|
var status = $('#status').val();
|
|
// 처리완료인 경우는 수정하기 못하게 한다.
|
|
|
|
$("#closeBtn").click(function(){ // 저장하고 창닫기
|
|
window.close(); // 현재 창 닫기
|
|
setTimeout(function(){
|
|
if (window.opener && !window.opener.closed) {
|
|
window.opener.location.reload(); // 부모 창 새로고침
|
|
}
|
|
}, 1000);
|
|
});
|
|
|
|
$("#saveBtn").click(function () {
|
|
var authorList = [];
|
|
var basicNameArr = <?= json_encode($employee_name_arr); ?>;
|
|
|
|
// 선택된 직원 정보를 배열에 추가
|
|
$(".author-checkbox:checked").each(function () {
|
|
var authorName = $(this).val();
|
|
|
|
// 기준연도: 해당연도 입력값이 있으면 해당연도 12월 31일, 없으면 오늘 날짜를 기준으로 함
|
|
var now = new Date();
|
|
refDateStr = now.getFullYear() + "-" + ("0" + (now.getMonth()+1)).slice(-2) + "-" + ("0" + now.getDate()).slice(-2);
|
|
|
|
// 연차일수 계산 후 업데이트
|
|
console.log('성명 : ',authorName);
|
|
|
|
authorList.push({
|
|
name: authorName,
|
|
company: $(this).data("company"),
|
|
part: $(this).data("part"),
|
|
author_id: $(this).data("author-id"),
|
|
availableday: $(this).data("availableday") , // 총 연차일수
|
|
initial_less_than_one_year: $(this).data("initial_less_than_one_year") , // 1,2년 미만 연차 계산
|
|
service_based: $(this).data("service_based") , // 기본연차
|
|
dateofentry: $(this).data("dateofentry")
|
|
});
|
|
});
|
|
|
|
if (authorList.length === 0) {
|
|
alert("직원을 선택하세요.");
|
|
return;
|
|
}
|
|
|
|
// 추가 데이터를 hidden 필드로 가져오기
|
|
var registdate = $("#registdate").val();
|
|
var currentYear = $("#current-year").val();
|
|
var alUsedDay = '';
|
|
|
|
// 요청 데이터 생성
|
|
var requestData = {
|
|
author_list: JSON.stringify(authorList),
|
|
current_year: currentYear
|
|
};
|
|
|
|
console.log("Request Data:", requestData);
|
|
|
|
$.ajax({
|
|
url: "insert_init.php",
|
|
type: "POST",
|
|
data: requestData,
|
|
dataType: "json",
|
|
success: function (response) {
|
|
console.log(response);
|
|
|
|
if (response.status === "success") {
|
|
Swal.fire({
|
|
icon: "success",
|
|
title: "등록 완료",
|
|
text: "대량 등록이 성공적으로 완료되었습니다.",
|
|
confirmButtonText: "확인"
|
|
}).then(() => {
|
|
// window.opener.location.reload(); // 부모 창 새로고침
|
|
});
|
|
} else {
|
|
Swal.fire({
|
|
icon: "error",
|
|
title: "오류 발생",
|
|
text: response.message,
|
|
confirmButtonText: "확인"
|
|
});
|
|
}
|
|
},
|
|
error: function (jqXHR, textStatus, errorThrown) {
|
|
console.error("AJAX 에러:", textStatus, errorThrown);
|
|
Swal.fire({
|
|
icon: "error",
|
|
title: "저장 실패",
|
|
text: "저장 중 오류가 발생했습니다. 다시 시도해주세요.",
|
|
confirmButtonText: "확인"
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
}); // end of ready document
|
|
|
|
</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);
|
|
}
|
|
renderEmployeeList() ;
|
|
}
|
|
|
|
// 페이지 로드 시, 이미 소속이 선택되어 있다면 부서 옵션 업데이트
|
|
var initialCorp = $('#corpSearch').val();
|
|
updatePartSelect(initialCorp);
|
|
|
|
// 소속 select 변경 시 부서 select 업데이트
|
|
$('#corpSearch').on('change', function(){
|
|
var selectedCorp = $(this).val();
|
|
updatePartSelect(selectedCorp);
|
|
renderEmployeeList() ;
|
|
});
|
|
|
|
// 페이지 로드 시 초기 직원 목록 렌더링
|
|
renderEmployeeList();
|
|
|
|
// 부서 select 변경 시 직원 목록 재렌더링
|
|
$('#partSearch').on('change', function(){
|
|
renderEmployeeList();
|
|
});
|
|
|
|
});
|
|
</script>
|
|
|
|
<!-- PHP 배열들을 JS 객체 배열로 생성 (각 직원의 정보) -->
|
|
<script>
|
|
var employeeData = <?= json_encode(array_map(function($name, $id, $company, $part, $dateofentry) {
|
|
return [
|
|
'name' => $name,
|
|
'id' => $id,
|
|
'company' => $company,
|
|
'part' => $part,
|
|
'dateofentry' => $dateofentry
|
|
];
|
|
}, $employee_name_arr, $employee_id_arr, $employee_company_arr, $employee_part_arr, $employee_dateofentry_arr)) ?>;
|
|
|
|
// 동적으로 직원 목록을 생성하는 함수 (개선된 버전)
|
|
function renderEmployeeList() {
|
|
var selectedCorp = $('#corpSearch').val();
|
|
var selectedPart = $('#partSearch').val();
|
|
var $authorList = $('#author-list');
|
|
$authorList.empty();
|
|
|
|
// 먼저 필터링된 직원 데이터를 배열에 저장
|
|
var filteredEmployees = [];
|
|
$.each(employeeData, function(index, emp) {
|
|
// 소속 필터: 소속이 선택되어 있고 일치하지 않으면 건너뜀
|
|
if (selectedCorp && emp.company !== selectedCorp) {
|
|
return; // continue each
|
|
}
|
|
// 부서 필터: 부서가 선택되어 있고 일치하지 않으면 건너뜀
|
|
if (selectedPart && emp.part !== selectedPart) {
|
|
return;
|
|
}
|
|
filteredEmployees.push(emp);
|
|
});
|
|
|
|
// 필터링된 직원 수에 따라 각 항목의 너비 결정 (3개 이상이면 33%, 2개 이하이면 각각 50% 혹은 100%)
|
|
var itemWidth = "33.33%";
|
|
if (filteredEmployees.length <= 3) {
|
|
itemWidth = (100 / (filteredEmployees.length || 1)) + "%";
|
|
}
|
|
|
|
// 필터링된 직원 배열을 순회하며 체크박스와 이름을 생성
|
|
$.each(filteredEmployees, function(index, emp) {
|
|
// 기본 체크 상태 (필요에 따라 수정)
|
|
var checked = "";
|
|
var employeeHTML = "<div class='d-flex align-items-center text-start mb-1' style='width:" + itemWidth + ";' data-company='" +
|
|
emp.company + "' data-part='" + emp.part + "'>";
|
|
employeeHTML += " <input type='checkbox' class='author-checkbox mx-1' name='author[]' value='" +
|
|
emp.name + "' ";
|
|
employeeHTML += " data-author-id='" + emp.id + "' ";
|
|
employeeHTML += " data-company='" + emp.company + "' ";
|
|
employeeHTML += " data-part='" + emp.part + "' ";
|
|
employeeHTML += " data-dateofentry='" + emp.dateofentry + "' " + checked + ">";
|
|
employeeHTML += " <span class='mx-1'>" + emp.name + "</span>";
|
|
employeeHTML += "</div>";
|
|
$authorList.append(employeeHTML);
|
|
});
|
|
}
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|