- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
2217 lines
86 KiB
PHP
2217 lines
86 KiB
PHP
<?php
|
||
require_once $_SERVER['DOCUMENT_ROOT'] . '/load_GoogleDrive.php'; // 세션 등 여러가지 포함됨 파일 포함
|
||
|
||
if (!isset($_SESSION["level"]) || $_SESSION["level"] > 5) {
|
||
sleep(1);
|
||
header("Location:" . $WebSite . "login/login_form.php");
|
||
exit;
|
||
}
|
||
|
||
// 에러 표시 설정
|
||
ini_set('display_errors', 1);
|
||
ini_set('display_startup_errors', 1);
|
||
error_reporting(E_ALL);
|
||
|
||
// **대량 등록용 임시 key 발급**
|
||
$bulkTimeKey = bin2hex(random_bytes(16));
|
||
|
||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||
$title_message = '금전 출납부';
|
||
$tablename = 'account_juil';
|
||
require_once $_SERVER['DOCUMENT_ROOT'] . '/load_GoogleDriveSecond.php'; // attached, image에 대한 정보 불러오기
|
||
|
||
?>
|
||
|
||
<link href="css/style.css" rel="stylesheet">
|
||
<title> <?=$title_message?> </title>
|
||
|
||
<style>
|
||
/* 테이블에 테두리 추가 */
|
||
#myTable, #myTable th, #myTable td {
|
||
border: 1px solid black;
|
||
border-collapse: collapse;
|
||
}
|
||
|
||
/* 테이블 셀 패딩 조정 */
|
||
#myTable th, #myTable td {
|
||
padding: 8px;
|
||
text-align: center;
|
||
}
|
||
|
||
|
||
/* 전체 모달 폰트 기본값 12px 유지 */
|
||
#bulkEntryModal * {
|
||
font-size: 12px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
/* 모달 배경 오버레이 */
|
||
#bulkEntryModal {
|
||
display: none;
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: rgba(0, 0, 0, 0.6);
|
||
z-index: 1050;
|
||
}
|
||
|
||
/* 모달 내용 영역 (가운데 정렬) */
|
||
#bulkEntryModal > div {
|
||
background: white;
|
||
width: 1920px;
|
||
margin: 40px auto;
|
||
padding: 20px;
|
||
border-radius: 8px;
|
||
position: relative;
|
||
}
|
||
|
||
/* 버튼 스타일 */
|
||
#bulkEntryModal .btn {
|
||
padding: 2px 8px;
|
||
font-size: 12px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* 테이블 관련 */
|
||
#bulkEntryModal table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
#bulkEntryModal table th,
|
||
#bulkEntryModal table td {
|
||
padding: 4px;
|
||
vertical-align: middle;
|
||
font-size: 12px;
|
||
border: 1px solid #dee2e6;
|
||
}
|
||
#bulkEntryModal table thead {
|
||
background-color: #f8f9fa;
|
||
}
|
||
|
||
/* 모달 열릴 때 바디 스크롤 방지 */
|
||
body.modal-open {
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 계좌잔액 토글 버튼 스타일 */
|
||
.account-balance-toggle {
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.account-balance-toggle:hover {
|
||
color: #007bff;
|
||
transform: scale(1.1);
|
||
}
|
||
|
||
#accountBalanceContainer {
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
/* 계좌잔액 텍스트 클릭 가능하게 */
|
||
strong.me-2.account-balance-label {
|
||
cursor: pointer;
|
||
user-select: none;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<!-- 로딩 오버레이 -->
|
||
<div id="loadingOverlay" style="
|
||
display: none;
|
||
position: fixed;
|
||
top: 0; left: 0;
|
||
width: 100%; height: 100%;
|
||
background: rgba(0,0,0,0.6);
|
||
z-index: 2000;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
color: #fff;
|
||
font-size: 1.5em;
|
||
display: none;
|
||
">
|
||
<div>
|
||
<i class="bi bi-arrow-clockwise rotate" style="font-size:2em; animation: spin 1s linear infinite;"></i>
|
||
<div>잠시만 기다려주세요…</div>
|
||
</div>
|
||
</div>
|
||
|
||
<style>
|
||
@keyframes spin {
|
||
from { transform: rotate(0deg); }
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
</style>
|
||
|
||
<?php
|
||
|
||
if($user_id === '0266771300' ) {
|
||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader_accountant1.php'); // 경리
|
||
} else {
|
||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php');
|
||
}
|
||
|
||
$search = isset($_REQUEST['search']) ? $_REQUEST['search'] : '';
|
||
$fromdate = isset($_REQUEST['fromdate']) ? $_REQUEST['fromdate'] : '';
|
||
$todate = isset($_REQUEST['todate']) ? $_REQUEST['todate'] : '';
|
||
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : '';
|
||
|
||
// 현재 날짜
|
||
$currentDate = date("Y-m-d");
|
||
|
||
// fromdate 또는 todate가 빈 문자열이거나 null인 경우
|
||
if ($fromdate === "" || $fromdate === null || $todate === "" || $todate === null) {
|
||
// 현재 월의 1일을 fromdate로 설정
|
||
// $fromdate = date("Y-m-01");
|
||
// 전달(이전 달)의 1일을 fromdate로 설정
|
||
$fromdate = date("Y-m-01", strtotime("-1 month"));
|
||
$todate = $currentDate;
|
||
$Transtodate = $todate;
|
||
} else {
|
||
$Transtodate = $todate;
|
||
}
|
||
|
||
function checkNull($strtmp) {
|
||
return $strtmp !== null && trim($strtmp) !== '';
|
||
}
|
||
|
||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||
$pdo = db_connect();
|
||
|
||
$inoutsep_select = isset($_REQUEST['inoutsep_select']) ? $_REQUEST['inoutsep_select'] : '';
|
||
$content_select = isset($_REQUEST['content_select']) ? $_REQUEST['content_select'] : '';
|
||
|
||
$order = " ORDER BY registDate ASC, num ASC ";
|
||
|
||
$sql_conditions = [];
|
||
$sql_params = [];
|
||
|
||
if (checkNull($search)) {
|
||
$sql_conditions[] = "searchtag LIKE :search";
|
||
$sql_params[':search'] = "%$search%";
|
||
}
|
||
|
||
$sql_conditions[] = "registDate BETWEEN :fromdate AND :todate";
|
||
$sql_params[':fromdate'] = $fromdate;
|
||
$sql_params[':todate'] = $todate;
|
||
|
||
$sql_conditions[] = "is_deleted = 0";
|
||
|
||
if (checkNull($inoutsep_select)) {
|
||
$sql_conditions[] = "inoutsep = :inoutsep";
|
||
$sql_params[':inoutsep'] = $inoutsep_select;
|
||
}
|
||
|
||
if (checkNull($content_select)) {
|
||
$sql_conditions[] = "content = :content";
|
||
$sql_params[':content'] = $content_select;
|
||
}
|
||
|
||
$sql = "SELECT * FROM " . $tablename . " WHERE " . implode(' AND ', $sql_conditions) . $order;
|
||
|
||
try {
|
||
$stmh = $pdo->prepare($sql);
|
||
foreach ($sql_params as $param => $value) {
|
||
$stmh->bindValue($param, $value);
|
||
}
|
||
$stmh->execute();
|
||
$total_row = $stmh->rowCount();
|
||
|
||
// 수입, 지출을 기반으로 초기 잔액 계산
|
||
$initialBalanceSql = "SELECT
|
||
SUM(CASE WHEN inoutsep = '수입' THEN REPLACE(amount, ',', '') ELSE 0 END) +
|
||
SUM(CASE WHEN inoutsep = '최초전월이월' THEN REPLACE(amount, ',', '') ELSE 0 END) -
|
||
SUM(CASE WHEN inoutsep = '지출' THEN REPLACE(amount, ',', '') ELSE 0 END) AS balance
|
||
FROM $tablename
|
||
WHERE is_deleted = '0' AND registDate < :fromdate
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
$initialBalanceStmh = $pdo->prepare($initialBalanceSql);
|
||
$initialBalanceStmh->bindParam(':fromdate', $fromdate);
|
||
$initialBalanceStmh->execute();
|
||
$initialBalance = $initialBalanceStmh->fetch(PDO::FETCH_ASSOC)['balance'];
|
||
|
||
$totalIncomeSql = "SELECT SUM(REPLACE(amount, ',', '')) AS totalIncome
|
||
FROM $tablename
|
||
WHERE is_deleted = '0' AND (inoutsep = '수입' OR inoutsep = '최초전월이월')
|
||
AND registDate BETWEEN :fromdate AND :todate
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
$totalIncomeStmh = $pdo->prepare($totalIncomeSql);
|
||
$totalIncomeStmh->bindParam(':fromdate', $fromdate);
|
||
$totalIncomeStmh->bindParam(':todate', $todate);
|
||
$totalIncomeStmh->execute();
|
||
$totalIncome = $totalIncomeStmh->fetch(PDO::FETCH_ASSOC)['totalIncome'];
|
||
|
||
$totalExpenseSql = "SELECT SUM(REPLACE(amount, ',', '')) AS totalExpense
|
||
FROM $tablename
|
||
WHERE is_deleted = '0' AND inoutsep = '지출'
|
||
AND registDate BETWEEN :fromdate AND :todate
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
$totalExpenseStmh = $pdo->prepare($totalExpenseSql);
|
||
$totalExpenseStmh->bindParam(':fromdate', $fromdate);
|
||
$totalExpenseStmh->bindParam(':todate', $todate);
|
||
$totalExpenseStmh->execute();
|
||
$totalExpense = $totalExpenseStmh->fetch(PDO::FETCH_ASSOC)['totalExpense'];
|
||
|
||
$finalBalance = $initialBalance + $totalIncome - $totalExpense;
|
||
|
||
// Bankbook options
|
||
$bankbookOptions = [];
|
||
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . "/account_juil/accoutlist.json";
|
||
$accounts = [];
|
||
$selectedAccount = null;
|
||
$accountBalances = [];
|
||
|
||
if (file_exists($jsonFile)) {
|
||
$jsonContent = file_get_contents($jsonFile);
|
||
$accounts = json_decode($jsonContent, true);
|
||
if (is_array($accounts) && !empty($accounts)) {
|
||
// 선택된 계좌 또는 기본 계좌(첫 번째) 설정
|
||
$selectedAccountIndex = isset($_REQUEST['selected_account']) ? intval($_REQUEST['selected_account']) : 0;
|
||
$selectedAccount = $accounts[$selectedAccountIndex] ?? $accounts[0];
|
||
|
||
// 각 계좌별 잔액 계산
|
||
foreach ($accounts as $index => $account) {
|
||
$accountDisplay = $account['company'] . ' ' . $account['number'];
|
||
if (!empty($account['memo'])) {
|
||
$accountDisplay .= ' (' . $account['memo'] . ')';
|
||
}
|
||
|
||
// 해당 계좌의 잔액 계산
|
||
$accountBalanceSql = "SELECT
|
||
SUM(CASE WHEN inoutsep = '수입' AND bankbook = ? THEN REPLACE(amount, ',', '') ELSE 0 END) +
|
||
SUM(CASE WHEN inoutsep = '최초전월이월' AND bankbook = ? THEN REPLACE(amount, ',', '') ELSE 0 END) -
|
||
SUM(CASE WHEN inoutsep = '지출' AND bankbook = ? THEN REPLACE(amount, ',', '') ELSE 0 END) AS balance
|
||
FROM $tablename
|
||
WHERE is_deleted = '0'
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
$accountBalanceStmh = $pdo->prepare($accountBalanceSql);
|
||
$accountBalanceStmh->bindValue(1, $accountDisplay, PDO::PARAM_STR);
|
||
$accountBalanceStmh->bindValue(2, $accountDisplay, PDO::PARAM_STR);
|
||
$accountBalanceStmh->bindValue(3, $accountDisplay, PDO::PARAM_STR);
|
||
$accountBalanceStmh->execute();
|
||
$accountBalances[$index] = $accountBalanceStmh->fetch(PDO::FETCH_ASSOC)['balance'] ?? 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// 각 계좌별 요약 정보를 담을 배열 초기화
|
||
$accountSummaries = [];
|
||
if (is_array($accounts)) {
|
||
foreach ($accounts as $index => $account) {
|
||
$accountDisplay = $account['company'] . ' ' . $account['number'];
|
||
if (!empty($account['memo'])) {
|
||
$accountDisplay .= ' (' . $account['memo'] . ')';
|
||
}
|
||
|
||
// 1. 계좌별 기초 잔액 (기간 이전)
|
||
$initialSql = "SELECT
|
||
(SUM(CASE WHEN inoutsep = '수입' OR inoutsep = '최초전월이월' THEN REPLACE(amount, ',', '') ELSE 0 END) -
|
||
SUM(CASE WHEN inoutsep = '지출' THEN REPLACE(amount, ',', '') ELSE 0 END)) AS balance
|
||
FROM $tablename
|
||
WHERE is_deleted = '0' AND registDate < :fromdate AND bankbook = :bankbook
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
$initialStmh = $pdo->prepare($initialSql);
|
||
$initialStmh->bindParam(':fromdate', $fromdate);
|
||
$initialStmh->bindParam(':bankbook', $accountDisplay);
|
||
$initialStmh->execute();
|
||
$initialBalanceAccount = $initialStmh->fetch(PDO::FETCH_ASSOC)['balance'] ?? 0;
|
||
|
||
// 2. 기간 내 수입
|
||
$incomeSql = "SELECT SUM(REPLACE(amount, ',', '')) AS totalIncome
|
||
FROM $tablename
|
||
WHERE is_deleted = '0' AND (inoutsep = '수입' OR inoutsep = '최초전월이월')
|
||
AND registDate BETWEEN :fromdate AND :todate AND bankbook = :bankbook
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
$incomeStmh = $pdo->prepare($incomeSql);
|
||
$incomeStmh->bindParam(':fromdate', $fromdate);
|
||
$incomeStmh->bindParam(':todate', $todate);
|
||
$incomeStmh->bindParam(':bankbook', $accountDisplay);
|
||
$incomeStmh->execute();
|
||
$totalIncomeAccount = $incomeStmh->fetch(PDO::FETCH_ASSOC)['totalIncome'] ?? 0;
|
||
|
||
// 3. 기간 내 지출
|
||
$expenseSql = "SELECT SUM(REPLACE(amount, ',', '')) AS totalExpense
|
||
FROM $tablename
|
||
WHERE is_deleted = '0' AND inoutsep = '지출'
|
||
AND registDate BETWEEN :fromdate AND :todate AND bankbook = :bankbook
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
$expenseStmh = $pdo->prepare($expenseSql);
|
||
$expenseStmh->bindParam(':fromdate', $fromdate);
|
||
$expenseStmh->bindParam(':todate', $todate);
|
||
$expenseStmh->bindParam(':bankbook', $accountDisplay);
|
||
$expenseStmh->execute();
|
||
$totalExpenseAccount = $expenseStmh->fetch(PDO::FETCH_ASSOC)['totalExpense'] ?? 0;
|
||
|
||
// 4. 최종 잔액
|
||
$finalBalanceAccount = $initialBalanceAccount + $totalIncomeAccount - $totalExpenseAccount;
|
||
|
||
// 계산된 정보를 배열에 저장
|
||
$accountSummaries[$index] = [
|
||
'name' => $accountDisplay,
|
||
'income' => $totalIncomeAccount,
|
||
'expense' => $totalExpenseAccount,
|
||
'balance' => $finalBalanceAccount
|
||
];
|
||
}
|
||
}
|
||
|
||
|
||
// 각 계좌별 최종 잔액 정보를 담을 배열 초기화
|
||
$accountFinalBalances = [];
|
||
if (is_array($accounts)) {
|
||
foreach ($accounts as $index => $account) {
|
||
$accountDisplay = $account['company'] . ' ' . $account['number'];
|
||
if (!empty($account['memo'])) {
|
||
$accountDisplay .= ' (' . $account['memo'] . ')';
|
||
}
|
||
|
||
// 계좌별 전체 기간의 최종 잔액 계산
|
||
$balanceSql = "SELECT
|
||
(SUM(CASE WHEN inoutsep = '수입' OR inoutsep = '최초전월이월' THEN REPLACE(amount, ',', '') ELSE 0 END) -
|
||
SUM(CASE WHEN inoutsep = '지출' THEN REPLACE(amount, ',', '') ELSE 0 END)) AS balance
|
||
FROM $tablename
|
||
WHERE is_deleted = '0' AND bankbook = :bankbook
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
|
||
$balanceStmh = $pdo->prepare($balanceSql);
|
||
$balanceStmh->bindParam(':bankbook', $accountDisplay);
|
||
$balanceStmh->execute();
|
||
$balanceResult = $balanceStmh->fetch(PDO::FETCH_ASSOC);
|
||
|
||
// 계산된 정보를 배열에 저장
|
||
$accountFinalBalances[$index] = [
|
||
'name' => $accountDisplay,
|
||
'balance' => $balanceResult['balance'] ?? 0
|
||
];
|
||
}
|
||
}
|
||
|
||
// print $sql;
|
||
|
||
?>
|
||
|
||
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
|
||
|
||
<input type="hidden" id="mode" name="mode" value="<?= isset($mode) ? $mode : '' ?>">
|
||
<input type="hidden" id="num" name="num" value="<?= isset($num) ? $num : '' ?>">
|
||
<input type="hidden" id="tablename" name="tablename" value="<?= isset($tablename) ? $tablename : '' ?>">
|
||
<input type="hidden" id="savetitle" name="savetitle" value="<?=isset($savetitle) ? $savetitle : '' ?>" >
|
||
<input type="hidden" id="pInput" name="pInput" value="<?=isset($pInput) ? $pInput : '' ?>" >
|
||
|
||
<div id="bulkEntryModal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.6); z-index:1050;">
|
||
<div style="background:white; width:1880px; height:950px; margin:40px auto; padding:20px; border-radius:8px; position:relative;">
|
||
<div class="d-flex justify-content-between bg-dark text-white" >
|
||
<h3 class="p-2">금전출납부 대량 등록</h3>
|
||
<button type="button" id="closeAccountModal" style="background:none; border:none; color:white; font-size:24px;">×</button>
|
||
</div>
|
||
|
||
<div class="custom-modal-body">
|
||
<div class="table-responsive">
|
||
<table class="table table-bordered" id="bulkEntryTable">
|
||
<thead>
|
||
<tr>
|
||
<th style="width:6%;">+/-/Copy</th>
|
||
<th style="width:6%;">등록일자</th>
|
||
<th style="width:7%;">구분</th>
|
||
<th style="width:15%;">계좌</th>
|
||
<th style="width:8%;">항목</th>
|
||
<th style="width:8%;">세부항목</th>
|
||
<th style="width:5%;">거래처 <i class="bi bi-search"></i></th>
|
||
<th style="width:5%;">거래처코드</th>
|
||
<th style="width:6%;">만기일자</th>
|
||
<th style="width:6%;">배서일자</th>
|
||
<th style="width:14%;">상세내용</th>
|
||
<th style="width:6%;">금액</th>
|
||
<th style="width:8%;">이미지첨부</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="d-flex justify-content-end">
|
||
<button type="button" id="saveBulkBtn" class="btn btn-dark btn-sm me-2">
|
||
<i class="bi bi-floppy-fill"></i> 전체 저장
|
||
</button>
|
||
<button type="button" class="btn btn-dark btn-sm me-2" id="closeAccountModal2">
|
||
× 닫기
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 전자어음 검색 모달 -->
|
||
<div class="modal fade" id="electronicBillModal" tabindex="-1" aria-labelledby="electronicBillModalLabel" aria-hidden="true" style="z-index:1060;">
|
||
<div class="modal-dialog modal-xl">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="electronicBillModalLabel">전자어음 검색</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover">
|
||
<thead class="table-secondary">
|
||
<tr>
|
||
<th>번호</th>
|
||
<th>등록일자</th>
|
||
<th>항목</th>
|
||
<th>세부항목</th>
|
||
<th>상세내용</th>
|
||
<th>금액</th>
|
||
<th>만기일자</th>
|
||
<th>선택</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="electronicBillTableBody">
|
||
<!-- 전자어음 데이터가 여기에 동적으로 추가됩니다 -->
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="container-fluid">
|
||
<!-- Modal -->
|
||
<div id="myModal" class="modal">
|
||
<div class="modal-content" style="width:1000px;">
|
||
<div class="modal-header">
|
||
<span class="modal-title"> <?=$title_message?> </span>
|
||
<span class="close">×</span>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="custom-card"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="container-fluid">
|
||
<div class="card justify-content-center text-center mt-5">
|
||
<div class="card-header">
|
||
<span class="text-center fs-5"> <?=$title_message?>
|
||
<button type="button" class="btn btn-dark btn-sm me-1" onclick='location.reload()'>
|
||
<i class="bi bi-arrow-clockwise" ></i> </button>
|
||
</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="d-flex justify-content-center align-items-center mt-2">
|
||
<span>
|
||
▷ <?= $total_row ?>
|
||
</span>
|
||
|
||
<!-- 기간부터 검색까지 연결 묶음 start -->
|
||
<span id="showdate" class="btn btn-dark btn-sm">기간</span>
|
||
|
||
<div id="showframe" class="card" style="width:500px;">
|
||
<div class="card-header" style="padding:2px;">
|
||
<div class="d-flex justify-content-center align-items-center">
|
||
기간 설정
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="d-flex justify-content-center align-items-center">
|
||
<button type="button" class="btn btn-outline-success btn-sm me-1 change_dateRange" onclick='alldatesearch()'>전체</button>
|
||
<button type="button" class="btn btn-outline-primary btn-sm me-1 change_dateRange" onclick='pre_year()'>전년도</button>
|
||
<button type="button" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='pre_month()'>전월</button>
|
||
<button type="button" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='dayBeforeYesterday()'>전전일</button>
|
||
<button type="button" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='yesterday()'>전일</button>
|
||
<button type="button" class="btn btn-outline-danger btn-sm me-1 change_dateRange" onclick='this_today()'>오늘</button>
|
||
<button type="button" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='this_month()'>당월</button>
|
||
<button type="button" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='this_year()'>당해년도</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<input type="date" id="fromdate" name="fromdate" class="form-control" style="width:110px;" value="<?=$fromdate?>"> ~
|
||
<input type="date" id="todate" name="todate" class="form-control me-1" style="width:110px;" value="<?=$todate?>">
|
||
|
||
<!-- 첫 번째 select 문: 수입/지출 구분 -->
|
||
<select id="inoutsep_select" name="inoutsep_select" class="form-select form-select-sm mx-1 d-block w-auto mx-1" >
|
||
<option value="">구분</option>
|
||
<option value="수입" <?= $inoutsep_select === '수입' ? 'selected' : '' ?>>수입</option>
|
||
<option value="지출" <?= $inoutsep_select === '지출' ? 'selected' : '' ?>>지출</option>
|
||
<option value="최초전월이월" <?= $inoutsep_select === '최초전월이월' ? 'selected' : '' ?>>최초전월이월</option>
|
||
</select>
|
||
|
||
<!-- 두 번째 select 문: 항목 선택 -->
|
||
<select id="content_select" name="content_select" class="form-select form-select-sm mx-1 d-block w-auto mx-1" >
|
||
<option value="">전체항목</option>
|
||
<?php
|
||
include 'fetch_options.php';
|
||
$options = array_merge(array_keys($incomeOptions), array_keys($expenseOptions));
|
||
foreach ($options as $option) {
|
||
$selected = ($content_select === $option) ? 'selected' : '';
|
||
echo "<option value=\"$option\" $selected>$option</option>";
|
||
}
|
||
?>
|
||
</select>
|
||
|
||
<div class="inputWrap30">
|
||
<input type="text" id="search" class="form-control" style="width:150px;" name="search" value="<?=$search?>" onKeyPress="if (event.keyCode==13){ enter(); }">
|
||
<button class="btnClear"></button>
|
||
</div>
|
||
|
||
<button class="btn btn-outline-dark btn-sm" type="button" id="searchBtn"> <i class="bi bi-search"></i> </button>
|
||
<button type="button" class="btn btn-secondary btn-sm ms-2 me-2" onclick="settings();" data-bs-toggle="tooltip" data-bs-placement="bottom" title="계정 관리(추가/수정/삭제)" > <i class="bi bi-gear-fill"></i> </button>
|
||
<button id="newBtn" type="button" class="btn btn-dark btn-sm me-2"> <i class="bi bi-pencil-square"></i> 신규 </button>
|
||
<button id="bulkNewBtn" type="button" class="btn btn-info btn-sm me-2"> <i class="bi bi-plus-square"></i> 대량등록 </button>
|
||
<button type="button" class="btn btn-dark btn-sm me-2" onclick="generateExcel();" > <i class="bi bi-file-earmark-spreadsheet"></i> 엑셀다운로드 </button>
|
||
<button type="button" class="btn btn-primary btn-sm me-2" onclick="detail();" > <i class="bi bi-ticket-detailed"></i> 상세내역 </button>
|
||
</div>
|
||
</div>
|
||
<div class="d-flex flex-wrap justify-content-start align-items-center mt-2 p-2 border rounded" style="gap: 10px;">
|
||
<strong id="accountBalanceToggleLabel" class="me-2" style="cursor:pointer;user-select:none;">
|
||
계좌 잔액
|
||
<i id="accountBalanceToggleIcon" class="bi bi-chevron-down" style="cursor:pointer;font-size:0.8em;" title="계좌잔액 보기/숨기기"></i>
|
||
</strong>
|
||
<div id="accountBalanceContainer" style="gap:10px;">
|
||
<?php foreach ($accountFinalBalances as $summary): ?>
|
||
<?php if ($summary['balance'] > 0): ?>
|
||
<div class="border rounded p-1" style="font-size: 0.9em;">
|
||
<span class="text-secondary"><?= htmlspecialchars($summary['name']) ?>:</span>
|
||
<span class="fw-bold ms-1"><?= number_format($summary['balance']) ?></span>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="table-responsive">
|
||
<table class="table table-hover" id="myTable">
|
||
<thead class="table-secondary">
|
||
<tr>
|
||
<th class="text-center" style="width:40px;">번호</th>
|
||
<th class="text-center" style="width:60px;">등록</th>
|
||
<th class="text-center" style="width:60px;">구분</th>
|
||
<th class="text-center" style="width:80px;">항목</th>
|
||
<th class="text-center" style="width:80px;">세부항목</th>
|
||
<th class="text-center" style="width:250px;">상세내용</th>
|
||
<th class="text-center" style="width:80px;">수입</th>
|
||
<th class="text-center" style="width:80px;">지출</th>
|
||
<th class="text-center" style="width:100px;">잔액</th>
|
||
<th class="text-center" style="width:220px;">계좌</th>
|
||
<th class="text-center" style="width:80px;">만기일자</th>
|
||
<th class="text-center" style="width:80px;">배서일자</th>
|
||
<th class="text-center" style="width:60px;">✅ 첨부서류</th>
|
||
</tr>
|
||
<tr style="background-color: #808080!important;">
|
||
<th class="text-end" colspan="6"> 합계 </th>
|
||
<th class="text-end" id="totalIncomeAmount"></th>
|
||
<th class="text-end" id="totalExpenseAmount"></th>
|
||
<th class="text-end" id="totalBalanceAmount"></th>
|
||
<th class="text-end" colspan="4"></th>
|
||
</tr>
|
||
</thead>
|
||
<?php
|
||
// 1. 계좌별 기초 잔액을 계산하여 배열로 관리 (기간 시작일 이전)
|
||
$runningBalances = [];
|
||
if (is_array($accounts)) {
|
||
foreach ($accounts as $account) {
|
||
$accountDisplay = $account['company'] . ' ' . $account['number'];
|
||
if (!empty($account['memo'])) {
|
||
$accountDisplay .= ' (' . $account['memo'] . ')';
|
||
}
|
||
|
||
$initialBalanceSql = "SELECT
|
||
(SUM(CASE WHEN inoutsep = '수입' OR inoutsep = '최초전월이월' THEN REPLACE(amount, ',', '') ELSE 0 END) -
|
||
SUM(CASE WHEN inoutsep = '지출' THEN REPLACE(amount, ',', '') ELSE 0 END)) AS balance
|
||
FROM $tablename
|
||
WHERE is_deleted = '0' AND registDate < :fromdate AND bankbook = :bankbook
|
||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||
$initialBalanceStmh = $pdo->prepare($initialBalanceSql);
|
||
$initialBalanceStmh->bindParam(':fromdate', $fromdate);
|
||
$initialBalanceStmh->bindParam(':bankbook', $accountDisplay);
|
||
$initialBalanceStmh->execute();
|
||
$result = $initialBalanceStmh->fetch(PDO::FETCH_ASSOC);
|
||
$runningBalances[$accountDisplay] = $result['balance'] ?? 0;
|
||
}
|
||
}
|
||
|
||
$start_num = $total_row;
|
||
$counter = 1;
|
||
|
||
// 2. 루프를 돌며 각 거래에 대한 계좌별 잔액을 계산하고 출력
|
||
// 이 while 루프는 페이지 상단에서 시작된 try 블록 안에서 실행됩니다.
|
||
while($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
|
||
|
||
include '_row.php'; // $num, $registDate, $bankbook 등의 변수 할당
|
||
|
||
$amount = floatval(str_replace(',', '', $row['amount']));
|
||
|
||
// json에 없는 계좌의 거래가 있을 경우를 대비해 초기화
|
||
if (!isset($runningBalances[$bankbook])) {
|
||
$runningBalances[$bankbook] = 0;
|
||
}
|
||
|
||
// 해당 계좌의 잔액을 업데이트 (어음이 아닌 경우만)
|
||
if ($dueDate === '0000-00-00' || !$dueDate || $dueDate === '' || $bankbook === '전자어음') {
|
||
if ($row['inoutsep'] === '수입' || $row['inoutsep'] === '최초전월이월') {
|
||
$runningBalances[$bankbook] += $amount;
|
||
} else { // 지출
|
||
$runningBalances[$bankbook] -= $amount;
|
||
}
|
||
}
|
||
?>
|
||
<tr>
|
||
<td class="text-center" onclick="loadForm('update', '<?=$num?>');"><?= $counter ?></td>
|
||
<td class="text-center" onclick="loadForm('update', '<?=$num?>');"><?= $registDate ?></td>
|
||
<td class="text-center <?= ($inoutsep === '수입' || $inoutsep === '최초전월이월') ? 'text-primary' : 'text-danger' ?>" onclick="loadForm('update', '<?=$num?>');"><?= $inoutsep ?></td>
|
||
<td class="text-center fw-bold <?= ($inoutsep === '수입' || $inoutsep === '최초전월이월') ? 'text-primary' : 'text-danger' ?>" onclick="loadForm('update', '<?=$num?>');"> <?= $content ?> </td>
|
||
<td class="text-center fw-bold <?= ($inoutsep === '수입' || $inoutsep === '최초전월이월') ? 'text-primary' : 'text-danger' ?>" onclick="loadForm('update', '<?=$num?>');"> <?= $contentSub ?> </td>
|
||
<td class="text-start <?= ($inoutsep === '수입' || $inoutsep === '최초전월이월') ? 'text-primary' : 'text-danger' ?>" onclick="loadForm('update', '<?=$num?>');"><?= $content_detail ?></td>
|
||
<?php if ($inoutsep === '수입' || $inoutsep === '최초전월이월') : ?>
|
||
<td class="text-end fw-bold text-primary" onclick="loadForm('update', '<?=$num?>');">
|
||
<?= is_numeric($amount) ? number_format($amount) : htmlspecialchars($amount) ?>
|
||
</td>
|
||
<td class="text-end"></td>
|
||
<?php else : ?>
|
||
<td class="text-end"></td>
|
||
<td class="text-end fw-bold text-danger" onclick="loadForm('update', '<?=$num?>');">
|
||
<?= is_numeric($amount) ? number_format($amount) : htmlspecialchars($amount) ?>
|
||
</td>
|
||
<?php endif; ?>
|
||
<td class="text-end fw-bold" onclick="loadForm('update', '<?=$num?>');"><?= number_format($runningBalances[$bankbook]) ?></td>
|
||
<td class="text-start" onclick="loadForm('update', '<?=$num?>');"><?= $bankbook ?></td>
|
||
<td class="text-start" onclick="loadForm('update', '<?=$num?>');">
|
||
<?= ($dueDate === '0000-00-00' || !$dueDate) ? '' : '(어음)'. $dueDate ?>
|
||
</td>
|
||
<td class="text-start" onclick="loadForm('update', '<?=$num?>');">
|
||
<?= ($bankbook === '전자어음' && $endorsementDate && $endorsementDate !== '0000-00-00') ? $endorsementDate : '' ?>
|
||
</td>
|
||
<td class="text-center">
|
||
<?php
|
||
// picuploads 테이블에서 이미지 검색
|
||
$imageSql = "SELECT picname FROM {$DB}.picuploads WHERE tablename = 'account_juil' AND parentnum = :num AND item = 'image' ";
|
||
$imageStmh = $pdo->prepare($imageSql);
|
||
$imageStmh->bindParam(':num', $num);
|
||
$imageStmh->execute();
|
||
$images = $imageStmh->fetchAll(PDO::FETCH_COLUMN); // 모든 결과를 배열로 가져옴
|
||
|
||
if (!empty($images)) {
|
||
foreach ($images as $fileId) {
|
||
if ($fileId) {
|
||
$imageId = 'account_image_' . $num . '_' . array_search($fileId, $images); // 고유 ID 생성
|
||
$link = "https://drive.google.com/file/d/{$fileId}/view?usp=drivesdk";
|
||
?>
|
||
<i class="bi bi-check2-square text-success" style="cursor: pointer;"
|
||
onclick="openTmpImagePopup('<?= $link ?>', '<?= $imageId ?>');"></i>
|
||
<?php
|
||
}
|
||
}
|
||
} else {
|
||
echo ' ';
|
||
}
|
||
?>
|
||
</td>
|
||
</tr>
|
||
<?php
|
||
$start_num--;
|
||
$counter++;
|
||
} // while 루프의 닫는 괄호
|
||
|
||
// ▼▼▼ 페이지 상단의 try 구문을 닫는 필수 catch 구문 ▼▼▼
|
||
} catch (PDOException $Exception) {
|
||
print "오류: ".$Exception->getMessage();
|
||
}
|
||
?>
|
||
|
||
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
|
||
<!-- 이미지 로딩 모달 -->
|
||
<div class="modal fade" id="loadingImageModal" tabindex="-1" aria-labelledby="loadingImageModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
|
||
<div class="modal-dialog modal-dialog-centered modal-sm">
|
||
<div class="modal-content">
|
||
<div class="modal-body text-center">
|
||
<div class="spinner-border text-primary" role="status">
|
||
<span class="visually-hidden">Loading...</span>
|
||
</div>
|
||
<p class="mt-2 mb-0">이미지를 불러오는 중...</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 페이지 로딩
|
||
$(document).ready(function(){
|
||
var loader = document.getElementById('loadingOverlay');
|
||
if (loader) {
|
||
loader.style.display = 'none';
|
||
}
|
||
$("#loadingOverlay").hide();
|
||
});
|
||
|
||
function numberWithCommas(x) {
|
||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||
}
|
||
|
||
|
||
$(document).ready(function() {
|
||
|
||
const initialBalance = <?= json_encode($initialBalance) ?>;
|
||
const finalBalance = <?= json_encode($finalBalance) ?>;
|
||
|
||
dataTable = $('#myTable').DataTable({
|
||
"paging": true,
|
||
"ordering": true,
|
||
"searching": true,
|
||
"pageLength": 1000,
|
||
"lengthMenu": [1000],
|
||
"language": {
|
||
"lengthMenu": "Show _MENU_ entries",
|
||
"search": "Live Search:"
|
||
},
|
||
"order": [[0, 'desc']],
|
||
"dom": 't<"bottom"ip>',
|
||
"columnDefs": [
|
||
{
|
||
"orderable": true, // 정렬 활성화
|
||
"targets": [0, 1, 2, 3, 4, 5, 6, 7, 8] // 정렬 가능하도록 설정할 열 인덱스
|
||
},
|
||
{
|
||
"orderable": false, // 정렬 비활성화
|
||
"targets": [9, 10, 11, 12] // 나머지 열 (계좌, 만기일자, 배서일자) 비활성화
|
||
}
|
||
],
|
||
"footerCallback": function (row, data, start, end, display) {
|
||
var api = this.api();
|
||
|
||
var intVal = function (i) {
|
||
return typeof i === 'string' ?
|
||
i.replace(/[\$,]/g, '')*1 :
|
||
typeof i === 'number' ?
|
||
i : 0;
|
||
};
|
||
|
||
// Calculate the totals for Income, Expense, and Balance
|
||
// 컬럼숫자 입력
|
||
var totalIncomeAmount = api.column(6, { page: 'current' }).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||
var totalExpenseAmount = api.column(7, { page: 'current' }).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||
|
||
// Update the header with the calculated totals
|
||
$('#totalIncomeAmount').html(numberWithCommas(totalIncomeAmount));
|
||
$('#totalExpenseAmount').html(numberWithCommas(totalExpenseAmount));
|
||
$('#totalBalanceAmount').html(numberWithCommas(finalBalance));
|
||
}
|
||
});
|
||
});
|
||
|
||
</script>
|
||
|
||
<script>
|
||
|
||
let isSaving = false;
|
||
var ajaxRequest = null;
|
||
var ajaxRequest_SubOption = null;
|
||
|
||
// PHP 변수를 JS 에 전달
|
||
const bulkTimeKey = "<?= $bulkTimeKey ?>";
|
||
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
|
||
$("#newBtn").on("click", function() {
|
||
loadForm('insert');
|
||
});
|
||
|
||
$("#searchBtn").on("click", function() {
|
||
$("#board_form").submit();
|
||
});
|
||
|
||
// 복사 버튼 클릭 이벤트
|
||
$(document).on("click", "#copyBtn", function() {
|
||
document.querySelector(".modal-body .custom-card").innerHTML = '';
|
||
$("#myModal").hide();
|
||
var num = $("#num").val();
|
||
loadForm('copy', num);
|
||
});
|
||
|
||
// 전자어음 선택 버튼 클릭 이벤트
|
||
$(document).on("click", "#selectElectronicBillBtn", function() {
|
||
// 거래처가 먼저 선택되어 있는지 확인
|
||
const secondordnum = document.getElementById('secondordnum').value;
|
||
if (!secondordnum || secondordnum.trim() === '') {
|
||
alert('전자어음을 선택하기 전에 먼저 거래처를 검색하여 선택해주세요.');
|
||
return;
|
||
}
|
||
loadElectronicBills();
|
||
});
|
||
|
||
});
|
||
|
||
|
||
// 모달창에 내용을 넣는 구조임 모달을 부르고 내용을 동적으로 넣는다.
|
||
function loadForm(mode, num = null) {
|
||
// 로딩 오버레이 보여주기
|
||
$("#loadingOverlay").show();
|
||
|
||
if (num == null || mode == 'copy') {
|
||
$("#mode").val('insert');
|
||
} else {
|
||
$("#mode").val('update');
|
||
$("#num").val(num);
|
||
}
|
||
|
||
if (ajaxRequest !== null) {
|
||
ajaxRequest.abort();
|
||
}
|
||
ajaxRequest = $.ajax({
|
||
type: "POST",
|
||
url: "fetch_modal.php",
|
||
data: { mode: mode, num: num },
|
||
dataType: "html",
|
||
success: function(response) {
|
||
document.querySelector(".modal-body .custom-card").innerHTML = response;
|
||
|
||
$("#myModal").show();
|
||
|
||
// PHP 데이터를 JSON으로 인코딩
|
||
const incomeOptions = <?php echo json_encode($incomeOptions, JSON_UNESCAPED_UNICODE); ?>;
|
||
const expenseOptions = <?php echo json_encode($expenseOptions, JSON_UNESCAPED_UNICODE); ?>;
|
||
|
||
console.log('Income Options:', incomeOptions);
|
||
console.log('Expense Options:', expenseOptions);
|
||
|
||
function updateDescription() {
|
||
const contentSelect = document.getElementById('content');
|
||
const descriptionDiv = document.getElementById('content_description');
|
||
const selectedValue = contentSelect.value;
|
||
|
||
// 수입인지 지출인지에 따라 설명 변경
|
||
const descriptions = document.querySelector('input[name="inoutsep"]:checked').value === '수입' ? incomeOptions : expenseOptions;
|
||
descriptionDiv.innerText = descriptions[selectedValue] || '';
|
||
|
||
// '거래처 수금' 또는 계좌가 '전자어음'일 때 검색 버튼 추가
|
||
const bankbookSelect = document.getElementById('bankbook');
|
||
const isElectronicBill = bankbookSelect && bankbookSelect.value === '전자어음';
|
||
if (selectedValue === '거래처 수금' || isElectronicBill) {
|
||
// contentSub를 '외상매출금'으로 설정 (거래처 수금일 때만)
|
||
if (selectedValue === '거래처 수금') {
|
||
const contentSubSelect = document.getElementById('contentSub');
|
||
if (contentSubSelect) {
|
||
contentSubSelect.innerHTML = '<option value="외상매출금">외상매출금</option>';
|
||
contentSubSelect.value = '외상매출금';
|
||
}
|
||
}
|
||
// 검색 버튼이 이미 있는지 확인
|
||
let searchBtn = document.getElementById('phonebookSearchBtn');
|
||
if (!searchBtn) {
|
||
searchBtn = document.createElement('button');
|
||
searchBtn.id = 'phonebookSearchBtn';
|
||
searchBtn.type = 'button';
|
||
searchBtn.className = 'btn btn-primary btn-sm ms-2 w120px';
|
||
searchBtn.innerHTML = '거래처 <i class="bi bi-search"></i> ';
|
||
descriptionDiv.parentNode.insertBefore(searchBtn, descriptionDiv.nextSibling);
|
||
// 검색 버튼 클릭 이벤트
|
||
searchBtn.addEventListener('click', function() {
|
||
phonebookBtn('');
|
||
});
|
||
}
|
||
} else {
|
||
// '거래처 수금'이 아닌 경우 검색 버튼 제거
|
||
const searchBtn = document.getElementById('phonebookSearchBtn');
|
||
if (searchBtn) {
|
||
searchBtn.remove();
|
||
}
|
||
}
|
||
}
|
||
|
||
function updateContentOptions() {
|
||
console.log('updateContentOptions');
|
||
const contentSelect = document.getElementById('content');
|
||
if (contentSelect) {
|
||
contentSelect.innerHTML = '';
|
||
|
||
const selectedType = document.querySelector('input[name="inoutsep"]:checked').value;
|
||
let options;
|
||
|
||
if (selectedType === '최초전월이월') {
|
||
options = {'최초전월이월': '최초전월이월'};
|
||
} else {
|
||
options = selectedType === '수입' ? incomeOptions : expenseOptions;
|
||
}
|
||
|
||
for (const [value, text] of Object.entries(options)) {
|
||
const option = document.createElement('option');
|
||
option.value = value;
|
||
option.text = value;
|
||
contentSelect.appendChild(option);
|
||
}
|
||
|
||
// 수입 선택 시 자동으로 '거래처 수금' 선택
|
||
if (selectedType === '수입') {
|
||
contentSelect.value = '거래처 수금';
|
||
}
|
||
|
||
updateDescription();
|
||
}
|
||
}
|
||
|
||
function phonebookBtn(search)
|
||
{
|
||
returnID = '수금등록';
|
||
href = '/pb_juil/list.php?search=' + search + '&returnID=' + returnID;
|
||
popupCenter(href, '전화번호 검색', 1800, 800);
|
||
|
||
}
|
||
|
||
|
||
$(document).on("click", "#closeBtn", function() {
|
||
$("#myModal").hide();
|
||
});
|
||
|
||
|
||
// loadForm() 성공 콜백 안에서
|
||
// 1) 기존에 붙어 있던 saveBtn 클릭 핸들러 제거
|
||
$(document).off("click", "#saveBtn");
|
||
// 2) 새로 핸들러 바인딩
|
||
$(document).on("click", "#saveBtn", function() {
|
||
// if (isSaving) return;
|
||
// isSaving = true;
|
||
|
||
// AJAX 요청을 보냄
|
||
if (ajaxRequest !== null) {
|
||
ajaxRequest.abort();
|
||
}
|
||
ajaxRequest = $.ajax({
|
||
url: "/account_juil/insert.php",
|
||
type: "post",
|
||
data: {
|
||
mode: $("#mode").val(),
|
||
num: $("#num").val(),
|
||
update_log: $("#update_log").val(),
|
||
registDate: $("#registDate").val(),
|
||
inoutsep: $("input[name='inoutsep']:checked").val(),
|
||
content: $("#content").val(),
|
||
amount: $("#amount").val(),
|
||
dueDate: $("#dueDate").val(),
|
||
first_writer: $("#first_writer").val(),
|
||
content_detail: $("#content_detail").val(),
|
||
contentSub: $("#contentSub").val(),
|
||
bankbook: $("#bankbook").val(),
|
||
secondordnum: $("#secondordnum").val(),
|
||
endorsementDate: $("#endorsementDate").val(),
|
||
parentEBNum: $("#parentEBNum").val()
|
||
},
|
||
dataType: "json",
|
||
success: function(response) {
|
||
Toastify({
|
||
text: "저장 완료",
|
||
duration: 3000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
backgroundColor: "#4fbe87",
|
||
}).showToast();
|
||
|
||
setTimeout(function() {
|
||
$("#myModal").hide();
|
||
location.reload();
|
||
}, 1500); // 1.5초 후 실행
|
||
|
||
},
|
||
error: function(jqxhr, status, error) {
|
||
console.log("AJAX Error: ", status, error);
|
||
// isSaving = false;
|
||
}
|
||
});
|
||
});
|
||
|
||
$(document).on("click", "#deleteBtn", function() {
|
||
var level = '<?= $_SESSION["level"] ?>';
|
||
|
||
if (level !== '1') {
|
||
Swal.fire({
|
||
title: '삭제불가',
|
||
text: "관리자만 삭제 가능합니다.",
|
||
icon: 'error',
|
||
confirmButtonText: '확인'
|
||
});
|
||
return;
|
||
}
|
||
|
||
Swal.fire({
|
||
title: '자료 삭제',
|
||
text: "삭제는 신중! 정말 삭제하시겠습니까?",
|
||
icon: 'warning',
|
||
showCancelButton: true,
|
||
confirmButtonColor: '#3085d6',
|
||
cancelButtonColor: '#d33',
|
||
confirmButtonText: '삭제',
|
||
cancelButtonText: '취소'
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
$("#mode").val('delete');
|
||
var formData = $("#board_form").serialize();
|
||
|
||
$.ajax({
|
||
url: "/account_juil/insert.php",
|
||
type: "post",
|
||
data: formData,
|
||
success: function(response) {
|
||
Toastify({
|
||
text: "파일 삭제완료",
|
||
duration: 2000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
backgroundColor: "#4fbe87",
|
||
}).showToast();
|
||
|
||
$("#myModal").hide();
|
||
location.reload();
|
||
},
|
||
error: function(jqxhr, status, error) {
|
||
console.log(jqxhr, status, error);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
});
|
||
|
||
|
||
|
||
$(".close").on("click", function() {
|
||
$("#myModal").hide();
|
||
});
|
||
|
||
// 항목 선택 변경 시 설명 업데이트
|
||
$(document).on("change", "#content", updateDescription);
|
||
|
||
$(document).on("change", "input[name='inoutsep']", updateContentOptions);
|
||
|
||
// 계좌 선택 변경 시 배서일자 필드 표시/숨김 처리
|
||
$(document).on("change", "#bankbook", function() {
|
||
const endorsementDateContainer = document.getElementById('endorsementDateContainer');
|
||
const selectElectronicBillBtn = document.getElementById('selectElectronicBillBtn');
|
||
|
||
if (endorsementDateContainer) {
|
||
endorsementDateContainer.style.display = this.value === '전자어음' ? 'inline-block' : 'none';
|
||
}
|
||
if (selectElectronicBillBtn) {
|
||
selectElectronicBillBtn.style.display = this.value === '전자어음' ? 'inline-block' : 'none';
|
||
}
|
||
// 계좌가 바뀌면 거래처 검색 버튼 표시/숨김도 갱신
|
||
if (typeof updateDescription === 'function') updateDescription();
|
||
});
|
||
|
||
// 전자어음 선택 버튼 클릭 이벤트
|
||
$(document).on("click", "#selectElectronicBillBtn", function() {
|
||
loadElectronicBills();
|
||
});
|
||
|
||
// 기존 이미지 불러오기 (Google Drive에서 가져오기)
|
||
function displayImageLoad() {
|
||
$('#displayImage').show();
|
||
var data = <?php echo json_encode($saveimagename_arr); ?>;
|
||
$("#displayImage").html('');
|
||
if (Array.isArray(data) && data.length > 0) {
|
||
data.forEach(function (fileData, i) {
|
||
const realName = fileData.realname || '다운로드 파일';
|
||
const thumbnail = fileData.thumbnail || '/assets/default-thumbnail.png';
|
||
const link = fileData.link || '#';
|
||
const fileId = fileData.fileId || null;
|
||
const rotation = fileData.rotation || 0;
|
||
const mode = '<?php echo $mode; ?>';
|
||
|
||
if (!fileId) {
|
||
console.error("fileId가 누락되었습니다. index: " + i, fileData);
|
||
return;
|
||
}
|
||
|
||
// 구글 드라이브 이미지 팝업 링크 생성
|
||
let deleteButton = '';
|
||
if (mode !== 'view') {
|
||
deleteButton = `<button type="button" class="btn btn-danger btn-sm mx-3" id="delImage${i}" onclick="delImageFn('${i}', '${fileId}')">
|
||
<i class="bi bi-trash"></i>
|
||
</button>`;
|
||
}
|
||
|
||
$("#displayImage").append(
|
||
"<div class='row mb-3'>" +
|
||
"<div class='col d-flex align-items-center justify-content-center'>" +
|
||
"<div class='position-relative'>" +
|
||
"<a href='#' onclick=\"openTmpImagePopup('" + link + "', 'image" + i + "'); return false;\">" +
|
||
"<img id='image" + i + "' src='" + thumbnail + "' style='width:100px; height:auto; transform: rotate(" + rotation + "deg);'>" +
|
||
"</a>" +
|
||
(mode !== 'view' ?
|
||
"<div class='position-absolute top-0 end-0 mt-1 me-1'>" +
|
||
"<button type='button' class='btn btn-primary btn-sm rotate-btn' onclick=\"rotateImage('" + fileId + "', 'image" + i + "')\">" +
|
||
"<i class='bi bi-arrow-clockwise'></i>" +
|
||
"</button>" +
|
||
"</div>" : "") +
|
||
"</div>" +
|
||
deleteButton +
|
||
"</div>" +
|
||
"</div>"
|
||
);
|
||
});
|
||
} else {
|
||
$("#displayImage").append(
|
||
"<div class='text-center text-muted'>No files</div>"
|
||
);
|
||
}
|
||
}
|
||
|
||
displayImageLoad(); // 기존이미지 업로드 보이기
|
||
|
||
// 모달 로드 완료 후 초기 상태 설정
|
||
if (typeof updateDescription === 'function') {
|
||
updateDescription();
|
||
}
|
||
},
|
||
error: function(jqxhr, status, error) {
|
||
console.log("AJAX error in loadForm:", status, error);
|
||
},
|
||
complete: function() {
|
||
// 성공이든 실패든 로딩 오버레이 숨기기
|
||
$("#loadingOverlay").hide();
|
||
}
|
||
});
|
||
}
|
||
|
||
function updateSubOptions() {
|
||
const contentSelect = document.getElementById('content');
|
||
const contentSubSelect = document.getElementById('contentSub');
|
||
const selectedValue = contentSelect.value;
|
||
|
||
if (ajaxRequest !== null) {
|
||
ajaxRequest.abort();
|
||
}
|
||
|
||
// AJAX 요청으로 세부항목 가져오기
|
||
ajaxRequest = $.ajax({
|
||
url: 'fetch_modal.php',
|
||
type: 'POST',
|
||
data: { action: 'getSubOptions', selectedKey: selectedValue },
|
||
dataType: 'json',
|
||
success: function(response) {
|
||
// 기존 옵션 초기화
|
||
contentSubSelect.innerHTML = '';
|
||
|
||
if (response.subOptions && response.subOptions.length > 0) {
|
||
// 새로운 옵션 추가
|
||
response.subOptions.forEach(item => {
|
||
for (const key in item) {
|
||
const option = document.createElement('option');
|
||
option.value = key;
|
||
option.text = key;
|
||
contentSubSelect.appendChild(option);
|
||
}
|
||
});
|
||
} else {
|
||
// 세부항목이 없는 경우 기본값 처리
|
||
const option = document.createElement('option');
|
||
option.value = '';
|
||
option.text = '세부항목 없음';
|
||
contentSubSelect.appendChild(option);
|
||
}
|
||
},
|
||
error: function(jqxhr, status, error) {
|
||
console.log("AJAX Error:", status, error);
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
// content 선택 변경 이벤트
|
||
$(document).on('change', '#content', updateSubOptions);
|
||
|
||
</script>
|
||
|
||
<script>
|
||
function generateExcel() {
|
||
var table = document.getElementById('myTable');
|
||
var rows = table.getElementsByTagName('tr');
|
||
var data = [];
|
||
|
||
// 각 행을 반복하여 데이터 수집
|
||
for (var i = 1; i < rows.length; i++) { // 헤더 행을 건너뜀
|
||
var cells = rows[i].getElementsByTagName('td');
|
||
var rowData = {};
|
||
rowData['number'] = cells[0]?.innerText || '';
|
||
rowData['registDate'] = cells[1]?.innerText || '';
|
||
rowData['content'] = cells[2]?.innerText || '';
|
||
rowData['contentSub'] = cells[3]?.innerText || '';
|
||
rowData['contentDetail'] = cells[4]?.innerText || '';
|
||
rowData['income'] = cells[5]?.innerText || '';
|
||
rowData['expense'] = cells[6]?.innerText || '';
|
||
rowData['balance'] = cells[7]?.innerText || '';
|
||
rowData['dueDate'] = cells[8]?.innerText || '';
|
||
|
||
data.push(rowData);
|
||
}
|
||
|
||
// saveExcel.php에 데이터 전송
|
||
var xhr = new XMLHttpRequest();
|
||
xhr.open("POST", "saveExcel.php", true);
|
||
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
||
xhr.onreadystatechange = function () {
|
||
if (xhr.readyState == 4) {
|
||
if (xhr.status == 200) {
|
||
try {
|
||
var response = JSON.parse(xhr.responseText);
|
||
if (response.success) {
|
||
console.log('Excel file generated successfully.');
|
||
// 다운로드 스크립트로 리디렉션
|
||
window.location.href = 'saveExcel.php?download=' + encodeURIComponent(response.filename);
|
||
} else {
|
||
console.log('Failed to generate Excel file: ' + response.message);
|
||
}
|
||
} catch (e) {
|
||
console.log('Error parsing response: ' + e.message + '\nResponse text: ' + xhr.responseText);
|
||
}
|
||
} else {
|
||
console.log('Failed to generate Excel file: Server returned status ' + xhr.status);
|
||
}
|
||
}
|
||
};
|
||
xhr.send(JSON.stringify(data));
|
||
}
|
||
|
||
function settings() {
|
||
// 계정설정
|
||
const url = `settings.php`;
|
||
customPopup(url, '계정 관리', 600, 850);
|
||
}
|
||
|
||
function detail() {
|
||
// detail.php로 이동할 URL 생성
|
||
const url = `detail.php`;
|
||
|
||
// customPopup을 사용하여 detail.php를 팝업으로 열기
|
||
customPopup(url, '상세 내역', 800, 900);
|
||
}
|
||
|
||
|
||
function openPopup(url, title, width, height) {
|
||
// 화면 중앙에 팝업을 띄우도록 좌표 계산
|
||
const left = (window.screen.width / 2) - (width / 2);
|
||
const top = (window.screen.height / 2) - (height / 2);
|
||
|
||
// 팝업 창 생성
|
||
const popupWindow = window.open(
|
||
url,
|
||
title,
|
||
`width=${width},height=${height},top=${top},left=${left},scrollbars=yes,resizable=yes`
|
||
);
|
||
|
||
// 오버레이 생성
|
||
const overlay = document.createElement('div');
|
||
overlay.id = 'overlay';
|
||
overlay.style.position = 'fixed';
|
||
overlay.style.top = 0;
|
||
overlay.style.left = 0;
|
||
overlay.style.width = '100%';
|
||
overlay.style.height = '100%';
|
||
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'; // 반투명 검은색
|
||
overlay.style.zIndex = 10000; // 최상위 레이어
|
||
overlay.style.cursor = 'not-allowed'; // 사용자가 클릭하지 못하도록 마우스 커서를 변경
|
||
document.body.appendChild(overlay);
|
||
|
||
// 팝업이 닫히면 오버레이 제거
|
||
const interval = setInterval(() => {
|
||
if (popupWindow.closed) {
|
||
clearInterval(interval);
|
||
document.body.removeChild(overlay);
|
||
}
|
||
}, 500);
|
||
|
||
// 팝업 창에 포커스 이동
|
||
if (window.focus) {
|
||
popupWindow.focus();
|
||
}
|
||
}
|
||
|
||
|
||
function enter() {
|
||
$("#board_form").submit();
|
||
}
|
||
|
||
</script>
|
||
|
||
<!-- 부트스트랩 툴팁 -->
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
||
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
||
return new bootstrap.Tooltip(tooltipTriggerEl);
|
||
});
|
||
// $("#order_form_write").modal("show");
|
||
});
|
||
|
||
</script>
|
||
|
||
<script>
|
||
// PHP 데이터를 JavaScript 변수로 변환
|
||
const incomeOptions = <?php echo json_encode($incomeOptions, JSON_UNESCAPED_UNICODE); ?>;
|
||
const expenseOptions = <?php echo json_encode($expenseOptions, JSON_UNESCAPED_UNICODE); ?>;
|
||
|
||
// 수입/지출 선택에 따른 계정과목 업데이트
|
||
document.getElementById('inoutsep_select').addEventListener('change', function() {
|
||
const contentSelect = document.getElementById('content_select');
|
||
const selectedType = this.value;
|
||
|
||
// 기존 옵션 제거 (전체항목 제외)
|
||
while (contentSelect.options.length > 1) {
|
||
contentSelect.remove(1);
|
||
}
|
||
|
||
// 선택된 타입에 따라 옵션 추가
|
||
const options = selectedType === '수입' ? incomeOptions : expenseOptions;
|
||
|
||
// 옵션 추가
|
||
Object.keys(options).forEach(key => {
|
||
const option = document.createElement('option');
|
||
option.value = key;
|
||
option.textContent = key;
|
||
contentSelect.appendChild(option);
|
||
});
|
||
|
||
// 전체항목으로 초기화
|
||
contentSelect.value = '';
|
||
});
|
||
|
||
$(document).ready(function(){
|
||
// 방문기록 남김
|
||
var title = '<?php echo $title_message; ?>';
|
||
saveMenuLog(title);
|
||
|
||
// 계좌잔액 토글 기능 초기화
|
||
initAccountBalanceToggle();
|
||
});
|
||
|
||
// account_juil/list.php 파일의 기존 <script> 태그 안에 추가
|
||
|
||
// --- 대량등록 관련 스크립트 시작 ---
|
||
$(document).ready(function() {
|
||
// '대량등록' 버튼 클릭 시 모달 열기
|
||
$("#bulkNewBtn").on("click", function() {
|
||
// 테이블 내용 초기화
|
||
$("#bulkEntryTable tbody").empty();
|
||
// 첫 행 추가
|
||
addRow_BulkEntry();
|
||
// 모달 표시
|
||
$("#bulkEntryModal").show();
|
||
});
|
||
|
||
// 모달 닫기 버튼
|
||
$("#bulkEntryModal .close").on("click", function() {
|
||
$("#bulkEntryModal").hide();
|
||
});
|
||
|
||
// 행 추가 버튼 (+)
|
||
$(document).on('click', '#bulkEntryTable .add-row', function() {
|
||
addRow_BulkEntry();
|
||
});
|
||
|
||
// 행 삭제 버튼 (-)
|
||
$(document).on('click', '#bulkEntryTable .remove-row', function() {
|
||
if ($("#bulkEntryTable tbody tr").length > 1) { // 최소 1개의 행은 유지
|
||
$(this).closest('tr').remove();
|
||
}
|
||
});
|
||
|
||
// '전체 저장' 버튼 클릭 이벤트
|
||
$("#saveBulkBtn").on("click", function() {
|
||
saveBulkData();
|
||
});
|
||
|
||
// '구분' 변경 시 '항목' 드롭다운 업데이트
|
||
$(document).on('change', '.bulk-inoutsep', function() {
|
||
updateBulkContentOptions($(this));
|
||
});
|
||
|
||
// '항목' 변경 시 '세부항목' 드롭다운 업데이트
|
||
$(document).on('change', '.bulk-content', function() {
|
||
updateBulkSubOptions($(this));
|
||
});
|
||
|
||
// '계좌' 변경 시 배서일자 필드 표시/숨김
|
||
$(document).on('change', '.bulk-bankbook', function() {
|
||
const $row = $(this).closest('tr');
|
||
const $endorsementDateField = $row.find('.bulk-endorsementDate');
|
||
const $selectElectronicBillBtn = $row.find('.bulk-select-electronic-bill-btn');
|
||
|
||
if (this.value === '전자어음') {
|
||
$endorsementDateField.show();
|
||
$selectElectronicBillBtn.show();
|
||
// 전자어음 선택 시 오늘날짜로 설정
|
||
if (!$endorsementDateField.val()) {
|
||
$endorsementDateField.val(new Date().toISOString().slice(0, 10));
|
||
}
|
||
} else {
|
||
$endorsementDateField.hide();
|
||
$selectElectronicBillBtn.hide();
|
||
}
|
||
});
|
||
|
||
// 대량등록에서 전자어음 선택 버튼 클릭 이벤트
|
||
$(document).on('click', '.bulk-select-electronic-bill-btn', function() {
|
||
const $row = $(this).closest('tr');
|
||
const secondordnum = $row.find('.bulk-secondordnum').val();
|
||
|
||
// 거래처가 먼저 선택되어 있는지 확인
|
||
if (!secondordnum || secondordnum.trim() === '') {
|
||
alert('전자어음을 선택하기 전에 먼저 거래처를 검색하여 선택해주세요.');
|
||
return;
|
||
}
|
||
|
||
loadElectronicBillsForBulk($row);
|
||
});
|
||
});
|
||
/**
|
||
* 대량등록 테이블에 새로운 행을 추가하는 함수
|
||
*/
|
||
function addRow_BulkEntry() {
|
||
// 현재 행의 등록일자 가져오기
|
||
const currentRow = $(event.target).closest('tr');
|
||
const currentDate = currentRow ? currentRow.find('.bulk-registDate').val() : new Date().toISOString().slice(0, 10);
|
||
|
||
const bankbookOptions = `<?php
|
||
$optionsHtml = "";
|
||
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . "/account_juil/accoutlist.json";
|
||
if (file_exists($jsonFile)) {
|
||
$accounts = json_decode(file_get_contents($jsonFile), true);
|
||
if (is_array($accounts)) {
|
||
foreach ($accounts as $account) {
|
||
$displayText = htmlspecialchars($account['company'] . ' ' . $account['number'] . (!empty($account['memo']) ? ' (' . $account['memo'] . ')' : ''), ENT_QUOTES);
|
||
$optionsHtml .= "<option value='" . $displayText . "'>" . $displayText . "</option>";
|
||
}
|
||
}
|
||
}
|
||
echo $optionsHtml;
|
||
?><option value="전자어음">전자어음</option>`;
|
||
|
||
const newRow = `
|
||
<tr>
|
||
<td class="text-center">
|
||
<button type="button" class="btn btn-sm btn-outline-primary add-row" style="padding: 2px 5px;">+</button>
|
||
<button type="button" class="btn btn-sm btn-outline-danger remove-row" style="padding: 2px 6px;">-</button>
|
||
<button type="button" class="btn btn-sm btn-outline-secondary copy-row" style="padding: 2px 6px;">
|
||
<i class="bi bi-files"></i>
|
||
</button>
|
||
</td>
|
||
<td><input type="date" class="form-control form-control-sm bulk-registDate noborder-input" value="${currentDate}"></td>
|
||
<td>
|
||
<select class="form-select form-select-sm bulk-inoutsep">
|
||
<option value="지출" selected>지출</option>
|
||
<option value="수입">수입</option>
|
||
<option value="최초전월이월">최초전월이월</option>
|
||
</select>
|
||
</td>
|
||
<td><select class="form-select form-select-sm bulk-bankbook">${bankbookOptions}</select></td>
|
||
<td><select class="form-select form-select-sm bulk-content"></select></td>
|
||
<td><select class="form-select form-select-sm bulk-contentSub"></select></td>
|
||
<td>
|
||
<button type="button" class="btn btn-sm btn-outline-primary bulk-search-company">
|
||
<i class="bi bi-search"></i>
|
||
</button>
|
||
</td>
|
||
<td><input type="text" class="form-control form-control-sm bulk-secondordnum noborder-input" autocomplete="off"></td>
|
||
<td><input type="date" class="form-control form-control-sm bulk-dueDate noborder-input"></td>
|
||
<td>
|
||
<input type="date" class="form-control form-control-sm bulk-endorsementDate noborder-input" value="${new Date().toISOString().slice(0, 10)}" style="display: none;">
|
||
<button type="button" class="btn btn-outline-primary btn-sm bulk-select-electronic-bill-btn" style="display: none;">
|
||
<i class="bi bi-search"></i>
|
||
</button>
|
||
</td>
|
||
<td><input type="text" class="form-control form-control-sm bulk-content_detail noborder-input text-start" autocomplete="off"></td>
|
||
<td><input type="text" class="form-control form-control-sm bulk-amount text-end noborder-input" onkeyup="inputNumberFormat(this)" autocomplete="off"></td>
|
||
<td>
|
||
<input type="file"
|
||
class="form-control form-control-sm bulk-image-input"
|
||
multiple
|
||
accept="image/*">
|
||
</td>
|
||
</tr>
|
||
`;
|
||
|
||
if (currentRow && currentRow.length) {
|
||
// 현재 행이 있는 경우 해당 행 다음에 추가
|
||
currentRow.after(newRow);
|
||
currentRow.next().find('.bulk-inoutsep').trigger('change');
|
||
} else {
|
||
// 현재 행이 없는 경우(첫 행 추가) 테이블에 추가
|
||
$('#bulkEntryTable tbody').append(newRow);
|
||
$('#bulkEntryTable tbody tr:last .bulk-inoutsep').trigger('change');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* '구분' (수입/지출/최초전월이월) 선택에 따라 '항목' 드롭다운 메뉴를 업데이트하는 함수
|
||
*/
|
||
function updateBulkContentOptions($selectElement) {
|
||
const selectedType = $selectElement.val();
|
||
const contentSelect = $selectElement.closest('tr').find('.bulk-content');
|
||
let options;
|
||
|
||
contentSelect.empty();
|
||
if(selectedType == '최초전월이월') {
|
||
contentSelect.append(`<option value="최초전월이월">최초전월이월</option>`);
|
||
options = incomeOptions;
|
||
} else {
|
||
options = (selectedType === '수입') ? incomeOptions : expenseOptions;
|
||
}
|
||
|
||
// 나머지 옵션들 추가
|
||
for (const key in options) {
|
||
if (key !== '전월이월') { // 전월이월은 이미 추가했으므로 건너뜀
|
||
contentSelect.append(`<option value="${key}">${key}</option>`);
|
||
}
|
||
}
|
||
contentSelect.trigger('change'); // 항목이 변경되었으므로 세부항목도 업데이트
|
||
}
|
||
|
||
/**
|
||
* '항목' 선택에 따라 '세부항목' 드롭다운 메뉴를 업데이트하는 함수
|
||
*/
|
||
function updateBulkSubOptions($selectElement) {
|
||
const selectedKey = $selectElement.val();
|
||
console.log('updateBulkSubOptions 함수 호출 후 selectedKey : ', selectedKey);
|
||
const contentSubSelect = $selectElement.closest('tr').find('.bulk-contentSub');
|
||
|
||
$.ajax({
|
||
url: 'fetch_modal.php',
|
||
type: 'POST',
|
||
data: { action: 'getSubOptions', selectedKey: selectedKey },
|
||
dataType: 'json',
|
||
success: function(response) {
|
||
contentSubSelect.empty();
|
||
console.log(response);
|
||
if (response.subOptions && response.subOptions.length > 0) {
|
||
response.subOptions.forEach(item => {
|
||
for (const key in item) {
|
||
contentSubSelect.append(`<option value="${key}">${key}</option>`);
|
||
}
|
||
});
|
||
} else {
|
||
contentSubSelect.append(`<option value="">없음</option>`);
|
||
}
|
||
},
|
||
error: function() {
|
||
contentSubSelect.empty().append('<option value="">없음</option>');
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 대량 등록 모달의 모든 데이터를 서버로 전송하여 저장하는 함수
|
||
*/
|
||
function saveBulkData() {
|
||
// 1) 행 데이터 수집 (entries 배열)
|
||
let entries = [];
|
||
$("#bulkEntryTable tbody tr").each(function() {
|
||
const $r = $(this);
|
||
const amt = $r.find(".bulk-amount").val().replace(/,/g,'');
|
||
const registDate = $r.find(".bulk-registDate").val();
|
||
|
||
if (!amt || !registDate || registDate === '0000-00-00') {
|
||
Swal.fire({
|
||
title: '등록일과 금액은 필수입니다.',
|
||
icon: 'warning',
|
||
confirmButtonText: '확인'
|
||
});
|
||
return;
|
||
}
|
||
if (!amt) return; // 금액 없으면 건너뜀
|
||
entries.push({
|
||
registDate: $r.find(".bulk-registDate").val(),
|
||
inoutsep: $r.find(".bulk-inoutsep").val(),
|
||
bankbook: $r.find(".bulk-bankbook").val(),
|
||
content: $r.find(".bulk-content").val() || '',
|
||
contentSub: $r.find(".bulk-contentSub").val() || '',
|
||
content_detail: $r.find(".bulk-content_detail").val() || '',
|
||
amount: amt,
|
||
secondordnum:$r.find(".bulk-secondordnum").val()|| '',
|
||
dueDate: $r.find(".bulk-dueDate").val() || '',
|
||
endorsementDate: $r.find(".bulk-endorsementDate").val() || '',
|
||
|
||
// **여기에 timekey 추가**
|
||
timekey: bulkTimeKey
|
||
});
|
||
});
|
||
|
||
if (entries.length === 0) {
|
||
return Swal.fire('입력 없음','저장할 데이터가 없습니다.','info');
|
||
}
|
||
|
||
// 2) 서버에 bulk insert
|
||
$.ajax({
|
||
url: "/account_juil/insert_bulk.php",
|
||
method: "POST",
|
||
data: { entries: JSON.stringify(entries) },
|
||
dataType: "json"
|
||
}).done(function(resp) {
|
||
if (resp.status !== 'success') {
|
||
return Swal.fire('저장 실패', resp.message || 'Bulk insert 오류','error');
|
||
}
|
||
|
||
// resp.nums 는 [num1, num2, …] 형태로, entries 순서와 같은 인덱스 매칭
|
||
const nums = resp.nums;
|
||
let uploads = []; // Promise 배열
|
||
|
||
nums.forEach((num, idx) => {
|
||
const input = $("#bulkEntryTable tbody tr").eq(idx).find(".bulk-image-input")[0];
|
||
if (input && input.files.length > 0) {
|
||
// FormData 로 이미지만 전송
|
||
const fd = new FormData();
|
||
fd.append("tablename", "account_juil");
|
||
fd.append("item", "image");
|
||
fd.append("upfilename","bulkImage");
|
||
fd.append("folderPath","경동기업/uploads");
|
||
fd.append("DBtable", "picuploads");
|
||
// **여기도 timekey 사용**
|
||
fd.append("timekey", bulkTimeKey);
|
||
fd.append("num", num); // 실제 num 업뎃 후에도 num 포함해 두면 안전합니다
|
||
|
||
Array.from(input.files).forEach(file => {
|
||
fd.append("bulkImage[]", file);
|
||
});
|
||
|
||
uploads.push(
|
||
$.ajax({
|
||
url: "/filedrive/fileprocess.php",
|
||
method: "POST",
|
||
data: fd,
|
||
processData: false,
|
||
contentType: false
|
||
})
|
||
);
|
||
}
|
||
});
|
||
|
||
// 3) 모든 이미지 업로드가 끝나면 리로드
|
||
Promise.all(uploads)
|
||
.then(() => {
|
||
Toastify({
|
||
text: `${entries.length}건 저장 완료`,
|
||
duration: 2000,
|
||
close: true,
|
||
gravity: "top", position: "center",
|
||
backgroundColor: "#4fbe87"
|
||
}).showToast();
|
||
})
|
||
.catch(err => {
|
||
console.error("이미지 업로드 중 오류:", err);
|
||
Toastify({
|
||
text: "일부 이미지 업로드에 실패했습니다.",
|
||
duration: 3000,
|
||
close: true,
|
||
gravity: "top", position: "center",
|
||
backgroundColor: "#f44336"
|
||
}).showToast();
|
||
})
|
||
.finally(() => {
|
||
setTimeout(()=> {
|
||
$("#bulkEntryModal").hide();
|
||
location.reload();
|
||
}, 1500);
|
||
});
|
||
|
||
}).fail((jq,status,err) => {
|
||
Swal.fire('서버 오류','대량 저장 중 오류가 발생했습니다.','error');
|
||
console.error(status, err);
|
||
});
|
||
}
|
||
// --- 대량등록 관련 스크립트 끝 ---
|
||
|
||
$(function() {
|
||
var $modal = $('#bulkEntryModal');
|
||
var $openBtn = $('#openAccountModal');
|
||
var $closeBtns = $('#closeAccountModal, #closeAccountModal2');
|
||
var $dateInput = $('#accountDate');
|
||
var $accountCompany = $('#accountCompany');
|
||
var $secondord = $('#secondord');
|
||
var $saveBtn = $('#saveAccountBtn');
|
||
var $body = $('body');
|
||
|
||
// 모달 열기
|
||
$openBtn.on('click', function() {
|
||
$modal.show();
|
||
|
||
// 날짜 초기화
|
||
if (!$dateInput.val()) {
|
||
var today = new Date();
|
||
var yyyy = today.getFullYear();
|
||
var mm = String(today.getMonth() + 1).padStart(2, '0');
|
||
var dd = String(today.getDate()).padStart(2, '0');
|
||
$dateInput.val(yyyy + '-' + mm + '-' + dd);
|
||
}
|
||
|
||
// 거래처 초기화
|
||
if ($secondord.val()) {
|
||
$accountCompany.val($secondord.val());
|
||
}
|
||
|
||
$body.addClass('modal-open'); // 스크롤 방지
|
||
});
|
||
|
||
// 모달 닫기 (× 버튼들)
|
||
$closeBtns.on('click', function() {
|
||
$modal.hide();
|
||
$body.removeClass('modal-open');
|
||
});
|
||
|
||
// 저장 버튼 클릭
|
||
$saveBtn.on('click', function() {
|
||
saveData_account(); // 사용자가 정의한 함수 호출
|
||
$modal.hide();
|
||
$body.removeClass('modal-open');
|
||
});
|
||
|
||
// 바깥 영역 클릭 시 닫기
|
||
$modal.on('click', function(e) {
|
||
if (e.target === this) {
|
||
$modal.hide();
|
||
$body.removeClass('modal-open');
|
||
}
|
||
});
|
||
});
|
||
|
||
// 거래처 검색 버튼 클릭 이벤트
|
||
$(document).on('click', '.bulk-search-company', function() {
|
||
const $row = $(this).closest('tr');
|
||
const $secondordnum = $row.find('.bulk-secondordnum');
|
||
const $contentDetail = $row.find('.bulk-content_detail');
|
||
|
||
returnID = '수금등록';
|
||
href = '/pb_juil/list.php?search=&returnID=' + returnID;
|
||
popupCenter(href, '전화번호 검색', 1800, 800);
|
||
});
|
||
|
||
// 거래처 선택 시 처리
|
||
function setCompanyInfo(companyCode, companyName) {
|
||
const $activeRow = $('#bulkEntryTable tbody tr:last');
|
||
$activeRow.find('.bulk-secondordnum').val(companyCode);
|
||
$activeRow.find('.bulk-content_detail').val(companyName);
|
||
}
|
||
|
||
// 팝업 중앙 정렬 함수
|
||
function popupCenter(url, title, w, h) {
|
||
var left = (screen.width/2)-(w/2);
|
||
var top = (screen.height/2)-(h/2);
|
||
return window.open(url, title, 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
|
||
}
|
||
|
||
// 행 복사 이벤트
|
||
$(document).on('click', '.copy-row', function() {
|
||
const $currentRow = $(this).closest('tr');
|
||
const $newRow = $currentRow.clone();
|
||
|
||
// 현재 행의 값들 저장
|
||
const currentInoutsep = $currentRow.find('.bulk-inoutsep').val();
|
||
const currentBankbook = $currentRow.find('.bulk-bankbook').val();
|
||
const currentContent = $currentRow.find('.bulk-content').val();
|
||
const currentContentSub = $currentRow.find('.bulk-contentSub').val();
|
||
const currentSecondordnum = $currentRow.find('.bulk-secondordnum').val();
|
||
const currentContentDetail = $currentRow.find('.bulk-content_detail').val();
|
||
const currentAmount = $currentRow.find('.bulk-amount').val();
|
||
const currentDueDate = $currentRow.find('.bulk-dueDate').val();
|
||
const currentEndorsementDate = $currentRow.find('.bulk-endorsementDate').val();
|
||
const currentRegistDate = $currentRow.find('.bulk-registDate').val();
|
||
|
||
// 현재 행 바로 아래에 삽입
|
||
$currentRow.after($newRow);
|
||
|
||
// 모든 값들을 새 행에 설정
|
||
$newRow.find('.bulk-registDate').val(currentRegistDate);
|
||
$newRow.find('.bulk-inoutsep').val(currentInoutsep);
|
||
$newRow.find('.bulk-bankbook').val(currentBankbook);
|
||
$newRow.find('.bulk-secondordnum').val(currentSecondordnum);
|
||
$newRow.find('.bulk-content_detail').val(currentContentDetail);
|
||
$newRow.find('.bulk-amount').val(currentAmount);
|
||
$newRow.find('.bulk-dueDate').val(currentDueDate);
|
||
$newRow.find('.bulk-endorsementDate').val(currentEndorsementDate);
|
||
|
||
// 구분 변경 이벤트 트리거
|
||
$newRow.find('.bulk-inoutsep').trigger('change');
|
||
|
||
// 항목과 세부항목 설정을 위한 지연 처리
|
||
setTimeout(function() {
|
||
$newRow.find('.bulk-content').val(currentContent);
|
||
$newRow.find('.bulk-content').trigger('change');
|
||
|
||
// 세부항목 설정을 위한 추가 지연
|
||
setTimeout(function() {
|
||
$newRow.find('.bulk-contentSub').val(currentContentSub);
|
||
}, 100);
|
||
}, 100);
|
||
|
||
// 토스트 메시지 표시
|
||
Toastify({
|
||
text: "행이 복사되었습니다",
|
||
duration: 2000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
backgroundColor: "#4fbe87",
|
||
}).showToast();
|
||
});
|
||
|
||
// 항목 선택 변경 이벤트 핸들러 수정
|
||
$(document).on('change', '.bulk-content', function() {
|
||
const $row = $(this).closest('tr');
|
||
const selectedKey = $(this).val();
|
||
const $contentSubSelect = $row.find('.bulk-contentSub');
|
||
|
||
// 현재 선택된 세부항목 값 저장
|
||
const currentSubValue = $contentSubSelect.val();
|
||
|
||
$.ajax({
|
||
url: 'fetch_modal.php',
|
||
type: 'POST',
|
||
data: { action: 'getSubOptions', selectedKey: selectedKey },
|
||
dataType: 'json',
|
||
success: function(response) {
|
||
$contentSubSelect.empty();
|
||
if (response.subOptions && response.subOptions.length > 0) {
|
||
response.subOptions.forEach(item => {
|
||
for (const key in item) {
|
||
const option = document.createElement('option');
|
||
option.value = key;
|
||
option.text = key;
|
||
$contentSubSelect.append(option);
|
||
}
|
||
});
|
||
// 이전에 선택된 값이 있으면 다시 선택
|
||
if (currentSubValue) {
|
||
$contentSubSelect.val(currentSubValue);
|
||
}
|
||
} else {
|
||
$contentSubSelect.append(`<option value="">없음</option>`);
|
||
}
|
||
},
|
||
error: function() {
|
||
$contentSubSelect.empty().append('<option value="">없음</option>');
|
||
}
|
||
});
|
||
});
|
||
|
||
|
||
function getGoogleDriveFileId(link) {
|
||
// 구글드라이브 파일ID 추출
|
||
var match = link.match(/\/d\/([a-zA-Z0-9_-]+)/);
|
||
return match ? match[1] : '';
|
||
}
|
||
|
||
// --- 여기부터 수정 및 추가된 함수 ---
|
||
// 로딩 모달을 보여주는 함수 (새로 추가)
|
||
function showImageLoadingModal() {
|
||
$('#loadingImageModal').modal('show');
|
||
}
|
||
|
||
// 로딩 모달을 숨기는 함수 (새로 추가)
|
||
function hideImageLoadingModal() {
|
||
$('#loadingImageModal').modal('hide');
|
||
}
|
||
|
||
|
||
// 이미지 팝업을 여는 함수 (보완됨)
|
||
function openTmpImagePopup(link, imageId) {
|
||
showImageLoadingModal(); // 이미지 클릭 즉시 로딩 모달 표시
|
||
|
||
console.log('link : ', link);
|
||
console.log('imageId : ', imageId);
|
||
|
||
var fileId = getGoogleDriveFileId(link);
|
||
if (!fileId) {
|
||
alert('구글드라이브 파일ID 추출 실패');
|
||
hideImageLoadingModal(); // 오류 발생 시 모달 숨김
|
||
return;
|
||
}
|
||
|
||
const imgElement = document.getElementById(imageId);
|
||
let currentRotation = 0;
|
||
|
||
if (imgElement) {
|
||
const transformStyle = imgElement.style.transform;
|
||
currentRotation = transformStyle
|
||
? parseInt(transformStyle.replace('rotate(', '').replace('deg)', '')) || 0
|
||
: 0;
|
||
} else {
|
||
console.warn('이미지 요소가 존재하지 않습니다:', imageId);
|
||
}
|
||
|
||
$.post('/filedrive/download_and_rotate.php', { fileId: fileId, rotation: currentRotation }, function(res) {
|
||
if (res.success) {
|
||
// 팝업 창 열기. 팝업 창이 로딩 모달을 닫는 역할을 함.
|
||
var popupWindow = popupCenter(
|
||
'/filedrive/view_tmpimg.php?img=' + encodeURIComponent(res.imgUrl) + '&rotation=' + res.rotation,
|
||
'imagePopup', 800, 600
|
||
);
|
||
if (!popupWindow) {
|
||
alert('팝업 창을 여는 데 실패했습니다. 브라우저의 팝업 차단 설정을 확인해주세요.');
|
||
hideImageLoadingModal();
|
||
}
|
||
} else {
|
||
alert(res.msg || '이미지 처리 실패');
|
||
hideImageLoadingModal();
|
||
}
|
||
}, 'json').fail(function() {
|
||
alert('서버와 통신 중 오류가 발생했습니다.');
|
||
hideImageLoadingModal();
|
||
});
|
||
}
|
||
|
||
// 전자어음 데이터 로드 함수
|
||
function loadElectronicBills() {
|
||
$.ajax({
|
||
url: 'get_electronic_bills.php',
|
||
type: 'GET',
|
||
dataType: 'json',
|
||
success: function(response) {
|
||
if (response.success) {
|
||
displayElectronicBills(response.data);
|
||
$('#electronicBillModal').modal('show');
|
||
} else {
|
||
alert('전자어음 데이터를 불러오는데 실패했습니다.');
|
||
}
|
||
},
|
||
error: function() {
|
||
alert('서버와 통신 중 오류가 발생했습니다.');
|
||
}
|
||
});
|
||
}
|
||
|
||
// 전자어음 목록 표시 함수
|
||
function displayElectronicBills(data) {
|
||
const tbody = $('#electronicBillTableBody');
|
||
tbody.empty();
|
||
|
||
if (data.length === 0) {
|
||
tbody.append('<tr><td colspan="8" class="text-center">배서일자가 없는 전자어음이 없습니다.</td></tr>');
|
||
return;
|
||
}
|
||
|
||
data.forEach(function(item) {
|
||
const row = `
|
||
<tr>
|
||
<td>${item.num}</td>
|
||
<td>${item.registDate}</td>
|
||
<td>${item.content || ''}</td>
|
||
<td>${item.contentSub || ''}</td>
|
||
<td>${item.content_detail || ''}</td>
|
||
<td class="text-end">${numberWithCommas(item.amount)}</td>
|
||
<td>${item.dueDate || ''}</td>
|
||
<td>
|
||
<button type="button" class="btn btn-primary btn-sm" onclick="selectElectronicBill('${item.num}', '${item.content}', '${item.contentSub}', '${item.content_detail}', '${item.amount}', '${item.dueDate}')">
|
||
선택
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
tbody.append(row);
|
||
});
|
||
}
|
||
|
||
// 전자어음 선택 함수
|
||
function selectElectronicBill(num, content, contentSub, contentDetail, amount, dueDate) {
|
||
// 모달 닫기
|
||
$('#electronicBillModal').modal('hide');
|
||
|
||
// 구분이 '지출'인 경우 항목을 '외상매출채권(전자어음)'으로 설정
|
||
const inoutsep = document.getElementById('inoutsep') ? document.getElementById('inoutsep').value : '';
|
||
if (inoutsep === '지출') {
|
||
$('#content').val('외상매출채권(전자어음)');
|
||
$('#contentSub').val('없음');
|
||
} else {
|
||
$('#content').val(content);
|
||
$('#contentSub').val(contentSub);
|
||
}
|
||
|
||
$('#content_detail').val(contentDetail);
|
||
$('#amount').val(numberWithCommas(amount));
|
||
$('#dueDate').val(dueDate);
|
||
$('#parentEBNum').val(num);
|
||
|
||
// 항목 변경 이벤트 트리거
|
||
$('#content').trigger('change');
|
||
|
||
// 토스트 메시지 표시
|
||
Toastify({
|
||
text: "전자어음 데이터가 적용되었습니다",
|
||
duration: 2000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
backgroundColor: "#4fbe87",
|
||
}).showToast();
|
||
}
|
||
|
||
// 대량등록용 전자어음 데이터 로드 함수
|
||
function loadElectronicBillsForBulk($row) {
|
||
$.ajax({
|
||
url: 'get_electronic_bills.php',
|
||
type: 'GET',
|
||
dataType: 'json',
|
||
success: function(response) {
|
||
if (response.success) {
|
||
displayElectronicBillsForBulk(response.data, $row);
|
||
$('#electronicBillModal').modal('show');
|
||
} else {
|
||
alert('전자어음 데이터를 불러오는데 실패했습니다.');
|
||
}
|
||
},
|
||
error: function() {
|
||
alert('서버와 통신 중 오류가 발생했습니다.');
|
||
}
|
||
});
|
||
}
|
||
|
||
// 대량등록용 전자어음 목록 표시 함수
|
||
function displayElectronicBillsForBulk(data, $row) {
|
||
const tbody = $('#electronicBillTableBody');
|
||
tbody.empty();
|
||
|
||
if (data.length === 0) {
|
||
tbody.append('<tr><td colspan="8" class="text-center">배서일자가 없는 전자어음이 없습니다.</td></tr>');
|
||
return;
|
||
}
|
||
|
||
data.forEach(function(item) {
|
||
const rowIndex = $row.index();
|
||
const row = `
|
||
<tr>
|
||
<td>${item.num}</td>
|
||
<td>${item.registDate}</td>
|
||
<td>${item.content || ''}</td>
|
||
<td>${item.contentSub || ''}</td>
|
||
<td>${item.content_detail || ''}</td>
|
||
<td class="text-end">${numberWithCommas(item.amount)}</td>
|
||
<td>${item.dueDate || ''}</td>
|
||
<td>
|
||
<button type="button" class="btn btn-primary btn-sm" onclick="selectElectronicBillForBulk('${item.num}', '${item.content || ''}', '${item.contentSub || ''}', '${item.content_detail || ''}', '${item.amount}', '${item.dueDate || ''}', ${rowIndex})">
|
||
선택
|
||
</button>
|
||
</td>
|
||
</tr>
|
||
`;
|
||
tbody.append(row);
|
||
});
|
||
}
|
||
|
||
// 대량등록용 전자어음 선택 함수
|
||
function selectElectronicBillForBulk(num, content, contentSub, contentDetail, amount, dueDate, rowIndex) {
|
||
// 모달 닫기
|
||
$('#electronicBillModal').modal('hide');
|
||
|
||
// 해당 행의 필드에 데이터 적용
|
||
const $row = $('#bulkEntryTable tbody tr').eq(rowIndex);
|
||
|
||
// 구분이 '지출'인 경우 항목을 '외상매출채권(전자어음)'으로 설정
|
||
const inoutsep = $row.find('.bulk-inoutsep').val();
|
||
if (inoutsep === '지출') {
|
||
$row.find('.bulk-content').val('외상매출채권(전자어음)');
|
||
$row.find('.bulk-contentSub').val('없음');
|
||
} else {
|
||
$row.find('.bulk-content').val(content);
|
||
$row.find('.bulk-contentSub').val(contentSub);
|
||
}
|
||
|
||
$row.find('.bulk-content_detail').val(contentDetail);
|
||
$row.find('.bulk-amount').val(numberWithCommas(amount));
|
||
$row.find('.bulk-dueDate').val(dueDate);
|
||
|
||
// 항목 변경 이벤트 트리거
|
||
$row.find('.bulk-content').trigger('change');
|
||
|
||
// 토스트 메시지 표시
|
||
Toastify({
|
||
text: "전자어음 데이터가 적용되었습니다",
|
||
duration: 2000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
backgroundColor: "#4fbe87",
|
||
}).showToast();
|
||
}
|
||
|
||
|
||
|
||
// 전자어음 목록 불러오기
|
||
|
||
// 계좌잔액 토글 기능
|
||
function initAccountBalanceToggle() {
|
||
const toggleBtn = document.getElementById('accountBalanceToggleIcon');
|
||
const label = document.getElementById('accountBalanceToggleLabel');
|
||
const container = document.getElementById('accountBalanceContainer');
|
||
if (!toggleBtn || !container || !label) return;
|
||
|
||
// 쿠키에서 저장된 상태 확인
|
||
const isVisible = getCookie('accountBalanceVisible') !== 'false';
|
||
|
||
// 초기 상태 설정
|
||
if (!isVisible) {
|
||
container.style.display = 'none';
|
||
toggleBtn.classList.remove('bi-chevron-down');
|
||
toggleBtn.classList.add('bi-chevron-right');
|
||
} else {
|
||
container.style.display = 'flex';
|
||
toggleBtn.classList.remove('bi-chevron-right');
|
||
toggleBtn.classList.add('bi-chevron-down');
|
||
}
|
||
|
||
function toggleBalance(e) {
|
||
e.stopPropagation();
|
||
const isCurrentlyVisible = container.style.display !== 'none';
|
||
if (isCurrentlyVisible) {
|
||
container.style.display = 'none';
|
||
toggleBtn.classList.remove('bi-chevron-down');
|
||
toggleBtn.classList.add('bi-chevron-right');
|
||
setCookie('accountBalanceVisible', 'false', 365);
|
||
} else {
|
||
container.style.display = 'flex';
|
||
toggleBtn.classList.remove('bi-chevron-right');
|
||
toggleBtn.classList.add('bi-chevron-down');
|
||
setCookie('accountBalanceVisible', 'true', 365);
|
||
}
|
||
}
|
||
|
||
toggleBtn.addEventListener('click', toggleBalance);
|
||
label.addEventListener('click', toggleBalance);
|
||
}
|
||
|
||
// 쿠키 설정 함수
|
||
function setCookie(name, value, days) {
|
||
let expires = "";
|
||
if (days) {
|
||
const date = new Date();
|
||
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
|
||
expires = "; expires=" + date.toUTCString();
|
||
}
|
||
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
||
}
|
||
|
||
// 쿠키 읽기 함수
|
||
function getCookie(name) {
|
||
const nameEQ = name + "=";
|
||
const ca = document.cookie.split(';');
|
||
for (let i = 0; i < ca.length; i++) {
|
||
let c = ca[i];
|
||
while (c.charAt(0) === ' ') c = c.substring(1, c.length);
|
||
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
|
||
}
|
||
return null;
|
||
}
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|