초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
This commit is contained in:
20
account_juil/PS_summarytable.php
Normal file
20
account_juil/PS_summarytable.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
|
||||
// HTML 헤더 로드
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
|
||||
?>
|
||||
|
||||
<script>
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
if(loader) loader.style.display = 'none';
|
||||
|
||||
$(document).ready(function () {
|
||||
// showShiningText('프로그램 개발 중입니다...', '80px');
|
||||
showShiningText();
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
744
account_juil/S_transaction.php
Normal file
744
account_juil/S_transaction.php
Normal file
@@ -0,0 +1,744 @@
|
||||
<?php
|
||||
// 거래명세표 보여주는 코드 s_transaction.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;
|
||||
}
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
// 첫 화면 표시 문구
|
||||
$title_message = '거래처 원장(VAT 포함)';
|
||||
?>
|
||||
<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;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php'); ?>
|
||||
<?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");
|
||||
// // fromdate를 이전 달의 1일로 설정
|
||||
// $fromdate = date("Y-m-01", strtotime("first day of -1 month"));
|
||||
$todate = $currentDate;
|
||||
$Transtodate = $todate;
|
||||
} else {
|
||||
$Transtodate = $todate;
|
||||
}
|
||||
|
||||
// 시작일과 종료일을 "8월1일~9월1일" 형태로 포맷팅
|
||||
$formatted_date_range = date("n월j일", strtotime($fromdate)) . '~' . date("n월j일", strtotime($todate));
|
||||
|
||||
function checkNull($strtmp) {
|
||||
return $strtmp !== null && trim($strtmp) !== '';
|
||||
}
|
||||
|
||||
$tablenamephonebook = 'phonebook';
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
// 이월잔액 계산을 위한 로직 (매출 - 수금)
|
||||
$initialBalances = [];
|
||||
|
||||
// 이월 잔액을 계산할 기준 날짜
|
||||
$lastMonthEnd = date("Y-m-d", strtotime($fromdate . " -1 day"));
|
||||
|
||||
// echo '<pre>';
|
||||
// echo '이월잔액 기간 lastMonthEnd: ';
|
||||
// print_r($lastMonthEnd);
|
||||
// echo '</pre>';
|
||||
|
||||
$searchsecondordnum = '';
|
||||
if(!empty($search))
|
||||
{
|
||||
$sql = "SELECT secondordnum FROM ".$DB.".".$tablenamephonebook."
|
||||
WHERE (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND represent='대표코드' AND (vendor_name LIKE '%$search%')";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$searchsecondordnum = $row['secondordnum'];
|
||||
}
|
||||
|
||||
// 거래처별 매출 및 수금 데이터 계산 (이월잔액)
|
||||
// 주일 work 테이블의 컬럼을 추가해야 함.
|
||||
$salesBeforeSql = "
|
||||
SELECT o.secondordnum, SUM(COALESCE(e.ET_total, 0)) AS total_sales
|
||||
FROM {$DB}.work o
|
||||
LEFT JOIN {$DB}.output_extra e ON o.num = e.parent_num
|
||||
WHERE o.outdate <= :lastMonthEnd AND (o.is_deleted IS NULL or o.is_deleted=0 or o.is_deleted ='')
|
||||
GROUP BY o.secondordnum
|
||||
";
|
||||
$paymentBeforeSql = "
|
||||
SELECT secondordnum, SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
|
||||
FROM {$DB}.account_juil
|
||||
WHERE registDate <= :lastMonthEnd AND (is_deleted IS NULL or is_deleted=0 or is_deleted ='' ) AND content = '거래처 수금'
|
||||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')
|
||||
GROUP BY secondordnum
|
||||
";
|
||||
$salesBeforeStmt = $pdo->prepare($salesBeforeSql);
|
||||
$salesBeforeStmt->execute([':lastMonthEnd' => $lastMonthEnd]);
|
||||
$salesBeforeData = $salesBeforeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$paymentBeforeStmt = $pdo->prepare($paymentBeforeSql);
|
||||
$paymentBeforeStmt->execute([':lastMonthEnd' => $lastMonthEnd]);
|
||||
$paymentBeforeData = $paymentBeforeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 거래처별로 매출과 수금을 비교해 이월 잔액을 계산
|
||||
foreach ($salesBeforeData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_sales = (float)$row['total_sales'];
|
||||
if (!isset($initialBalances[$secondordnum])) {
|
||||
$initialBalances[$secondordnum] = 0;
|
||||
}
|
||||
$initialBalances[$secondordnum] += $total_sales;
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($initialBalances);
|
||||
// echo '</pre>';
|
||||
|
||||
// 수금 데이터를 이용해 이월 잔액에서 수금을 차감
|
||||
foreach ($paymentBeforeData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_payment = (float)$row['total_payment'];
|
||||
if (!isset($initialBalances[$secondordnum])) {
|
||||
$initialBalances[$secondordnum] = 0;
|
||||
}
|
||||
$initialBalances[$secondordnum] -= $total_payment;
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($initialBalances);
|
||||
// echo '</pre>';
|
||||
|
||||
// 매출이 발생한 거래처 필터링 및 매출액 계산
|
||||
$salesSql = "
|
||||
SELECT o.secondordnum, COALESCE(e.ET_total, 0) as ET_total
|
||||
FROM {$DB}.work o
|
||||
LEFT JOIN {$DB}.output_extra e ON o.num = e.parent_num
|
||||
WHERE (o.outdate BETWEEN date('$fromdate') AND date('$Transtodate'))
|
||||
AND (o.is_deleted IS NULL OR o.is_deleted = 0 or o.is_deleted ='')
|
||||
";
|
||||
$salesStmt = $pdo->prepare($salesSql);
|
||||
$salesStmt->execute();
|
||||
$salesData = $salesStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$salesResults = [];
|
||||
foreach ($salesData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_sales = (float)$row['ET_total'];
|
||||
if (!isset($salesResults[$secondordnum])) {
|
||||
$salesResults[$secondordnum] = 0;
|
||||
}
|
||||
$salesResults[$secondordnum] += $total_sales;
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// echo '매출발생 시작 fromdate: ';
|
||||
// print_r($fromdate);
|
||||
// echo '</pre>';
|
||||
|
||||
// echo '<pre>';
|
||||
// echo '매출발생 종료 Transtodate: ';
|
||||
// print_r($Transtodate);
|
||||
// echo '</pre>';
|
||||
|
||||
// echo '<pre>';
|
||||
// echo '이월잔액배열 디오이엔시 추적 initialBalances: ';
|
||||
// print_r($initialBalances['56']);
|
||||
// echo '</pre>';
|
||||
|
||||
|
||||
// 모든 거래처 목록을 처리하기 전에 거래처 이름을 저장하는 배열 초기화
|
||||
$vendorNames = [];
|
||||
// 모든 거래처 목록을 생성 (매출, 기초채권)
|
||||
$allResults = array_unique(array_merge(array_keys($salesResults), array_keys($initialBalances)));
|
||||
|
||||
// 매출 금액 기준으로 역순으로 정렬
|
||||
usort($allResults, function($a, $b) use ($salesResults) {
|
||||
$salesA = isset($salesResults[$a]) ? $salesResults[$a] : 0;
|
||||
$salesB = isset($salesResults[$b]) ? $salesResults[$b] : 0;
|
||||
return round($salesA - $salesB);
|
||||
});
|
||||
|
||||
// 합계를 저장할 변수들
|
||||
$totalInitialReceivable = 0;
|
||||
$totalSalesAmount = 0;
|
||||
$totalPaymentAmount = 0;
|
||||
$totalBalanceDue = 0;
|
||||
|
||||
try {
|
||||
$start_num = 1;
|
||||
foreach ($allResults as $ordnum) {
|
||||
// 이월 잔액 설정
|
||||
$initialReceivable = isset($initialBalances[$ordnum]) ? $initialBalances[$ordnum] : 0;
|
||||
|
||||
// 수금 내역 가져오기
|
||||
$paymentSql = "SELECT SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) as total_payment
|
||||
FROM ".$DB.".account_juil
|
||||
WHERE secondordnum = '$ordnum'
|
||||
AND registDate BETWEEN '1970-01-01' AND date('$Transtodate')
|
||||
AND (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND content = '거래처 수금'
|
||||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||||
|
||||
$paymentStmt = $pdo->prepare($paymentSql);
|
||||
$paymentStmt->execute();
|
||||
$paymentData = $paymentStmt->fetch(PDO::FETCH_ASSOC);
|
||||
$total_payment = isset($paymentData['total_payment']) ? (int)str_replace(',', '', $paymentData['total_payment']) : 0;
|
||||
|
||||
$total_sales = isset($salesResults[$ordnum]) ? $salesResults[$ordnum] : 0;
|
||||
|
||||
// 조건: 기초채권이 있거나 매출이 있는 경우만 표시
|
||||
if ($initialReceivable != 0 || $total_sales != 0 ) { // 매출이 있는 것을 추출
|
||||
$sql = "SELECT * FROM $DB.$tablenamephonebook
|
||||
WHERE secondordnum = '$ordnum'
|
||||
AND (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND represent='대표코드'";
|
||||
|
||||
$stmh = $pdo->query($sql);
|
||||
while ($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/phonebook/_row.php';
|
||||
|
||||
if (intval($ordnum) > 0)
|
||||
{
|
||||
$savenum = $ordnum;
|
||||
// 거래처 이름 저장
|
||||
$vendorNames[$ordnum] =$vendor_name ;
|
||||
}
|
||||
else
|
||||
$savenum = $num;
|
||||
|
||||
$total_amount = round($total_sales ) ;
|
||||
|
||||
// 잔액 계산
|
||||
$balance_due = round($initialReceivable) + $total_amount - round($total_payment);
|
||||
|
||||
$totalInitialReceivable += $initialReceivable;
|
||||
$totalSalesAmount += $total_amount;
|
||||
$totalPaymentAmount += $total_payment;
|
||||
$totalBalanceDue += $balance_due;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (PDOException $Exception) {
|
||||
print "오류: ".$Exception->getMessage();
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($vendorNames);
|
||||
// echo '</pre>';
|
||||
|
||||
// 거래처 이름으로 정렬
|
||||
usort($allResults, function($a, $b) use ($vendorNames) {
|
||||
// 거래처 이름이 없는 경우 빈 문자열로 처리
|
||||
$nameA = $vendorNames[$a] ?? '';
|
||||
$nameB = $vendorNames[$b] ?? '';
|
||||
return strcmp($nameA, $nameB);
|
||||
});
|
||||
|
||||
// echo $sql;
|
||||
// echo '<pre>';
|
||||
// print_r($allResults);
|
||||
// echo '</pre>';
|
||||
|
||||
// $search값이 있다면 // 특정 숫자 67만 남기고 필터링
|
||||
// echo 'searchsecondordnum : ' . $searchsecondordnum;
|
||||
if (!empty($search)) {
|
||||
$allResults = array_filter($allResults, function ($value) use ($searchsecondordnum) {
|
||||
return $value === intval($searchsecondordnum);
|
||||
});
|
||||
|
||||
// array_values로 인덱스 재정렬
|
||||
$allResults = array_values($allResults);
|
||||
}
|
||||
|
||||
// 중복 제거
|
||||
$allResults = array_unique($allResults);
|
||||
|
||||
|
||||
// 중복 제거
|
||||
$allResults = array_unique($allResults);
|
||||
|
||||
// 빈 값 제거
|
||||
$allResults = array_filter($allResults, function ($value) {
|
||||
return $value !== null && $value !== '';
|
||||
});
|
||||
|
||||
// 배열 키 재정렬
|
||||
$allResults = array_values($allResults);
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($allResults);
|
||||
// echo '</pre>';
|
||||
|
||||
?>
|
||||
|
||||
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
|
||||
<div class="container mb-5">
|
||||
<input type="hidden" id="mode" name="mode" value="<?=$mode?>">
|
||||
<input type="hidden" id="num" name="num">
|
||||
<input type="hidden" id="tablename" name="tablename" value="<?=$tablenamephonebook?>">
|
||||
<input type="hidden" id="header" name="header" value="<?=$header?>">
|
||||
<input type="hidden" id="secondordnum" name="secondordnum" value="<?=$secondordnum?>">
|
||||
|
||||
<div class="card justify-content-center text-center mt-5">
|
||||
<div class="card-header">
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="text-center fs-5 me-4"><?=$title_message?></span>
|
||||
<span class="text-center ">* 출고완료일 기준 </span>
|
||||
<button type="button" class="btn btn-dark btn-sm mx-3" onclick='location.reload();' title="새로고침"> <i class="bi bi-arrow-clockwise"></i> </button>
|
||||
<!-- <span class="badge bg-primary"> (한빛에스티) 매월25일 마감 </span> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
▷ <span id="total"> </span>
|
||||
|
||||
<!-- 기간부터 검색까지 연결 묶음 start -->
|
||||
<button type="button" class="btn btn-outline-dark btn-sm me-1 change_dateRange" onclick='alldatesearch()'>전체</button>
|
||||
<span id="showdate" class="btn btn-dark btn-sm">기간</span>
|
||||
|
||||
<div id="showframe" class="card" style="width:300px;">
|
||||
<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-dark btn-sm me-1 change_dateRange" onclick='prepre_month()'>전전월</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='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:100px;" value="<?=$fromdate?>"> ~
|
||||
<input type="date" id="todate" name="todate" class="form-control me-1" style="width:100px;" value="<?=$todate?>"> </span>
|
||||
|
||||
<div class="inputWrap">
|
||||
<input type="text" id="search" name="search" value="<?=$search?>" onkeydown="if(event.key === 'Enter') submitForm();" autocomplete="off" class="form-control" style="width:150px;">
|
||||
<button class="btnClear"></button>
|
||||
</div>
|
||||
|
||||
<div id="autocomplete-list">
|
||||
</div>
|
||||
|
||||
<button id="searchBtn" type="button" class="btn btn-dark btn-sm me-2" onclick="submitForm()"> <i class="bi bi-search"></i> </button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-2" onclick="location.href='../getmoney/list.php?header=header'"><i class="bi bi-journal-x"></i> 수금 </button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick="location.href='../account_juil/month_sales.php?header=header'"> <i class="bi bi-file-earmark-ruled"></i> 판매일괄회계</button>
|
||||
<button type="button" class="btn btn-primary btn-sm me-1" onclick="saveBalance();"> <i class="bi bi-floppy"></i> 차기월 이월금확정</button>
|
||||
<button type="button" class="btn btn-danger btn-sm me-2" onclick="location.href='../account_juil/receivable.php?header=header'"> <i class="bi bi-journal-x"></i> 미수금 </button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-2" onclick="generateExcel();" > <i class="bi bi-file-earmark-spreadsheet"></i> </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card justify-content-center text-center mt-5">
|
||||
<div class="card-body">
|
||||
<div class="d-flex p-1 m-1 mb-1 justify-content-center align-items-center">
|
||||
<table class="table table-hover" id="myTable">
|
||||
<thead class="table-info">
|
||||
<th class="text-center w80px">번호</th>
|
||||
<th class="text-center w200px">거래처명</th>
|
||||
<th class="text-center w140px">이월잔액</th>
|
||||
<th class="text-center w140px"> 매출</th>
|
||||
<th class="text-center w140px">수금</th>
|
||||
<th class="text-center w140px">잔액</th>
|
||||
<th class="text-center w60px">결제일</th>
|
||||
<th class="text-center w140px">적요</th>
|
||||
<?php if($user_id == 'pro')
|
||||
print '<th class="text-center w50px">거래처 Code</th>';
|
||||
?>
|
||||
<th style="display:none;" ></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
try {
|
||||
$start_num = 1;
|
||||
|
||||
foreach ($allResults as $initnum) {
|
||||
|
||||
// echo 'second ord num '. $initnum . '<br>';
|
||||
// 이월잔액 설정
|
||||
$initialReceivable = isset($initialBalances[$initnum]) ? intval($initialBalances[$initnum]) : 0;
|
||||
// 마지막 자릿수가 1인지 확인
|
||||
if (floatval($initialReceivable) % 10 === 1) {
|
||||
// 마지막 자릿수를 제거 (정수로 처리)
|
||||
$initialReceivable = floor($initialReceivable / 10);
|
||||
}
|
||||
|
||||
// echo '거래처 $initnum' . $initnum . ' : ', $initialReceivable . ' <br> ' ;
|
||||
|
||||
// 수금 내역 가져오기
|
||||
$paymentSql = "SELECT SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) as total_payment
|
||||
FROM $DB.account_juil
|
||||
WHERE secondordnum = '$initnum'
|
||||
AND registDate BETWEEN date('$fromdate') AND date('$Transtodate')
|
||||
AND (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND content = '거래처 수금'
|
||||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||||
|
||||
$paymentStmt = $pdo->prepare($paymentSql);
|
||||
$paymentStmt->execute();
|
||||
$paymentData = $paymentStmt->fetch(PDO::FETCH_ASSOC);
|
||||
$total_payment = isset($paymentData['total_payment']) ? (int)str_replace(',', '', $paymentData['total_payment']) : 0;
|
||||
|
||||
$total_sales = isset($salesResults[$initnum]) ? $salesResults[$initnum] : 0;
|
||||
// print $total_sales;
|
||||
// 조건: 이월잔액이 있거나 매출이 있는 경우만 표시
|
||||
// 검색어가 있는 경우 검색어 있는 것만 나오게 함
|
||||
// echo 'searchsecondordnum : ' . $searchsecondordnum;
|
||||
|
||||
if ( ($initialReceivable != 0 or $total_sales != 0) and intval($initnum) > 1 ) {
|
||||
|
||||
$sql = "SELECT * FROM $DB.$tablenamephonebook
|
||||
WHERE secondordnum = '$initnum'
|
||||
AND (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND represent='대표코드'";
|
||||
|
||||
$total_amount = round($total_sales,2);
|
||||
|
||||
// 잔액 계산
|
||||
$balance_due = $initialReceivable + $total_amount - $total_payment;
|
||||
$memo = '';
|
||||
// if($balance_due>0 && $initialReceivable>0 )
|
||||
|
||||
// (주)한빛에스티는 25일 마감 예외처리해야함.
|
||||
// if($vendor_name === '㈜ 한빛에스티')
|
||||
// $vendor_name = '㈜ 한빛에스티(월마감25일)';
|
||||
|
||||
// 마지막 단위 원단위 중 1은 제거하는 로직
|
||||
// 당월매출 마지막 1원 삭제
|
||||
// 마지막 자리가 1로 끝나는 경우, 0으로 변경
|
||||
// print_r($total_payment);
|
||||
// $totalSalesAmount -= 5;
|
||||
if (round($total_amount,2) % 10 === 1) {
|
||||
$total_amount -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
|
||||
if ($balance_due % 10 === 1) {
|
||||
$balance_due -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
// print_r($balance_due);
|
||||
|
||||
if (intval($balance_due) !== 0 || $total_sales > 0 ) {
|
||||
?>
|
||||
<tr onclick="redirectToView('<?= $initnum ?>')">
|
||||
<td class="text-center"><?= $start_num ?></td>
|
||||
<td class="text-start text-primary"><?= $vendorNames[$initnum] ?></td>
|
||||
<td class="text-end text-primary fw-bold"><?= number_format($initialReceivable) ?></td>
|
||||
<td class="text-end text-secondary fw-bold"><?= number_format($total_amount) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($total_payment) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($balance_due) ?></td>
|
||||
<td class="text-end text-primary fw-bold">
|
||||
<?php if (!empty($paydate)) : ?>
|
||||
<?= htmlspecialchars($paydate) ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-end"><?= $memo ?></td>
|
||||
<?php if($user_id == 'pro')
|
||||
echo '<td class="text-center w50px"> ' . $initnum . ' </td>';
|
||||
?>
|
||||
<td style="display:none;"><?= $initnum ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$start_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot class="table-secondary">
|
||||
<tr>
|
||||
<th class="text-end w80px" colspan="2"> 합계 </th>
|
||||
<th class="text-end"><?= number_format($totalInitialReceivable) ?></th>
|
||||
<th class="text-end"><?= number_format($totalSalesAmount) ?></th>
|
||||
<th class="text-end"><?= number_format($totalPaymentAmount) ?></th>
|
||||
<th class="text-end"><?= number_format($totalBalanceDue) ?></th>
|
||||
<th class="text-end"> </th>
|
||||
<th class="text-end w150px"> </th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
} catch (PDOException $Exception) {
|
||||
print "오류: ".$Exception->getMessage();
|
||||
}
|
||||
?>
|
||||
<!-- 페이지로딩 -->
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
loader.style.display = 'none';
|
||||
});
|
||||
|
||||
function submitForm() {
|
||||
$('#board_form').submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var dataTable; // DataTables 인스턴스 전역 변수
|
||||
var bookpageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
|
||||
|
||||
$(document).ready(function() {
|
||||
// DataTables 초기 설정
|
||||
dataTable = $('#myTable').DataTable({
|
||||
"paging": true,
|
||||
"ordering": true,
|
||||
"searching": true,
|
||||
"pageLength": 100,
|
||||
"lengthMenu": [100, 200, 500, 1000],
|
||||
"language": {
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"search": "Live Search:"
|
||||
},
|
||||
// "order": [[8, 'desc']], // 잔액기준 내림차순 정렬
|
||||
"dom": 't<"bottom"ip>', // search 창과 lengthMenu 숨기기
|
||||
"footerCallback": function ( row, data, start, end, display ) {
|
||||
var api = this.api(), data;
|
||||
|
||||
// 합계를 계산하는 함수
|
||||
var intVal = function (i) {
|
||||
return typeof i === 'string' ?
|
||||
i.replace(/[\$,]/g, '')*1 :
|
||||
typeof i === 'number' ?
|
||||
i : 0;
|
||||
};
|
||||
|
||||
// 합계 계산
|
||||
totalInitialReceivable = api.column(2).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalSalesAmount = api.column(3).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalPaymentAmount = api.column(4).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalBalanceDue = api.column(5).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
|
||||
// 합계 출력
|
||||
$(api.column(2).footer()).html(numberWithCommas(totalInitialReceivable));
|
||||
$(api.column(3).footer()).html(numberWithCommas(totalSalesAmount));
|
||||
$(api.column(4).footer()).html(numberWithCommas(totalPaymentAmount));
|
||||
$(api.column(5).footer()).html(numberWithCommas(totalBalanceDue));
|
||||
}
|
||||
});
|
||||
|
||||
// 페이지 번호 복원 (초기 로드 시)
|
||||
var savedPageNumber = getCookie('bookpageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
|
||||
// 페이지 변경 이벤트 리스너
|
||||
dataTable.on('page.dt', function() {
|
||||
var bookpageNumber = dataTable.page.info().page + 1;
|
||||
setCookie('bookpageNumber', bookpageNumber, 10); // 쿠키에 페이지 번호 저장
|
||||
});
|
||||
|
||||
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
|
||||
$('#myTable_length select').on('change', function() {
|
||||
var selectedValue = $(this).val();
|
||||
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
|
||||
|
||||
// 변경 후 현재 페이지 번호 복원
|
||||
savedPageNumber = getCookie('bookpageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
});
|
||||
|
||||
var total = '<?php echo $start_num; ?>';
|
||||
$("#total").text(Number(total)-1);
|
||||
|
||||
});
|
||||
|
||||
function redirectToView(num) {
|
||||
var fromdate = document.getElementById('fromdate').value;
|
||||
var todate = document.getElementById('todate').value;
|
||||
var url = "../account_juil/S_transaction_sheet.php?num=" + num + "&fromdate=" + fromdate + "&todate=" + todate;
|
||||
customPopup(url, '거래원장', 1000, 850);
|
||||
}
|
||||
|
||||
function numberWithCommas(x) {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
}
|
||||
|
||||
function saveBalance() {
|
||||
// 테이블 데이터를 수집
|
||||
let data = [];
|
||||
let closure_date = $('#todate').val();
|
||||
let year = closure_date.split('-')[0];
|
||||
let month = closure_date.split('-')[1];
|
||||
let dayOfMonth = parseInt(closure_date.split('-')[2]);
|
||||
|
||||
// 해당 월의 마지막 날 계산
|
||||
let lastDayOfMonth = new Date(year, month, 0).getDate();
|
||||
|
||||
// 날짜가 말일 또는 25일이 아닌 경우 경고 메시지 출력
|
||||
if (dayOfMonth !== lastDayOfMonth && dayOfMonth !== 25) {
|
||||
alert('해당일자로 이월 마감할 수 없습니다.');
|
||||
return; // 함수 종료
|
||||
}
|
||||
|
||||
$('#myTable tbody tr').each(function() {
|
||||
let row = $(this);
|
||||
let balance = parseFloat(row.find('td:nth-child(6)').text().replace(/,/g, ''));
|
||||
let secondordnum = row.find('td:nth-child(9)').text().trim();
|
||||
|
||||
// 매월 말일인 경우
|
||||
if (dayOfMonth === lastDayOfMonth) {
|
||||
// '66'이 아닌 데이터만 처리
|
||||
if (secondordnum !== '66' && balance !== 0) {
|
||||
data.push({
|
||||
mode: row.attr('data-mode') || 'insert', // insert or update mode
|
||||
num: row.attr('data-num'),
|
||||
secondordnum: secondordnum,
|
||||
customer_name: row.find('td:nth-child(2)').text().trim(),
|
||||
balance: balance,
|
||||
closure_date: closure_date,
|
||||
memo: row.find('td:nth-child(8)').text().trim()
|
||||
});
|
||||
}
|
||||
}
|
||||
// 25일인 경우
|
||||
else if (dayOfMonth === 25) {
|
||||
// '66' 데이터만 처리
|
||||
if (secondordnum === '66' && balance !== 0) {
|
||||
data.push({
|
||||
mode: row.attr('data-mode') || 'insert', // insert or update mode
|
||||
num: row.attr('data-num'),
|
||||
secondordnum: secondordnum,
|
||||
customer_name: row.find('td:nth-child(2)').text().trim(),
|
||||
balance: balance,
|
||||
closure_date: closure_date,
|
||||
memo: row.find('td:nth-child(8)').text().trim()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Ajax로 데이터 전송
|
||||
if (data.length > 0) {
|
||||
$.ajax({
|
||||
url: 'insert_monthly_balance.php',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function(response) {
|
||||
let result = JSON.parse(response);
|
||||
if (result.status === 'success') {
|
||||
alert('이월금액이 성공적으로 저장되었습니다.');
|
||||
} else {
|
||||
alert('오류 발생: ' + result.message);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
alert('오류 발생: ' + error);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('저장할 데이터가 없습니다.');
|
||||
}
|
||||
}
|
||||
|
||||
function detail() {
|
||||
// 년도, 시작 월, 종료 월 값을 가져옴
|
||||
const year = document.getElementById('year').value;
|
||||
const startMonth = document.getElementById('startMonth').value;
|
||||
const endMonth = document.getElementById('endMonth').value;
|
||||
|
||||
// detail.php로 이동할 URL 생성
|
||||
const url = `detail.php?year=${year}&startMonth=${startMonth}&endMonth=${endMonth}`;
|
||||
|
||||
// customPopup을 사용하여 detail.php를 팝업으로 열기
|
||||
customPopup(url, '상세 내역', 900, 700);
|
||||
}
|
||||
|
||||
|
||||
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['secondord'] = cells[1]?.innerText || '';
|
||||
rowData['lastbalance'] = cells[2]?.innerText || '';
|
||||
rowData['monthsales'] = cells[3]?.innerText || '';
|
||||
rowData['income'] = cells[4]?.innerText || '';
|
||||
rowData['balances'] = cells[5]?.innerText || '';
|
||||
rowData['payday'] = cells[6]?.innerText || '';
|
||||
rowData['memo'] = cells[7]?.innerText || '';
|
||||
rowData['secondordnum'] = cells[8]?.innerText || '';
|
||||
|
||||
data.push(rowData);
|
||||
}
|
||||
|
||||
// saveExcel.php에 데이터 전송
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "customer_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 = 'downloadExcel.php?filename=' + encodeURIComponent(response.filename.split('/').pop());
|
||||
} 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));
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
saveLogData('거래처 원장');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
598
account_juil/S_transaction_sheet.php
Normal file
598
account_juil/S_transaction_sheet.php
Normal file
@@ -0,0 +1,598 @@
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
|
||||
// 첫 화면 표시 문구
|
||||
$title_message = '거래처 원장';
|
||||
$tablename = 'motor';
|
||||
|
||||
// 견적서, 거래명세서, 총거래원장등 설정 $item으로 설정하면 됨.
|
||||
$item_title ='거래처 원장';
|
||||
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
?>
|
||||
<title> <?= $title_message ?> </title>
|
||||
<style>
|
||||
table, th, td {
|
||||
border: 1px solid black !important; /* Bold border */
|
||||
font-size: 12px !important;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Add background color for date rows */
|
||||
.date-row {
|
||||
background-color: #f0f0f0!important; /* Light gray background */
|
||||
}
|
||||
.date-row-date {
|
||||
background-color: #f0f0f0!important; /* Light gray background */
|
||||
color: blue !important;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
width: 210mm; /* A4 width */
|
||||
height: 297mm; /* A4 height */
|
||||
margin: 0; /* Remove default margin */
|
||||
font-size: 10pt; /* Font size for printing */
|
||||
}
|
||||
.table {
|
||||
width: 100%; /* Full width tables */
|
||||
table-layout: fixed; /* Uniform column sizing */
|
||||
border-collapse: collapse; /* Ensure borders collapse */
|
||||
}
|
||||
.table th, .table td {
|
||||
padding: 1px; /* Reduce padding */
|
||||
border: 1px solid #ddd; /* Ensure borders are visible */
|
||||
}
|
||||
.text-center {
|
||||
text-align: center; /* Maintain center alignment */
|
||||
}
|
||||
|
||||
/* Prevent table row splitting */
|
||||
.table tr {
|
||||
page-break-inside: avoid; /* Prevent breaking inside rows */
|
||||
page-break-after: avoid; /* Allow breaking after rows */
|
||||
}
|
||||
.table thead {
|
||||
display: table-header-group; /* Ensure table headers are repeated */
|
||||
}
|
||||
.table tbody {
|
||||
display: table-row-group; /* Ensure table rows are grouped */
|
||||
}
|
||||
.table tfoot {
|
||||
display: table-footer-group; /* Ensure table footers are repeated */
|
||||
}
|
||||
|
||||
/* Add top and bottom margins to each page */
|
||||
.table tbody:before,
|
||||
.table tbody:after {
|
||||
content: "";
|
||||
display: table-row;
|
||||
height: 5mm; /* Adjust as needed for top and bottom margins */
|
||||
}
|
||||
|
||||
/* Remove border from the before and after elements */
|
||||
.table tbody:before td,
|
||||
.table tbody:after td {
|
||||
border: none; /* Remove borders */
|
||||
}
|
||||
|
||||
/* Adjust the border of the last row on the page */
|
||||
.table tbody tr:last-child td {
|
||||
border-bottom: none; /* Remove the bottom border */
|
||||
border-left: none; /* Remove the bottom border */
|
||||
border-right: none; /* Remove the bottom border */
|
||||
border-top: none; /* Remove the bottom border */
|
||||
}
|
||||
|
||||
/* Prevent border at the connection of two pages */
|
||||
.table tbody tr:last-child td:first-child {
|
||||
border-bottom: none; /* Remove the bottom border */
|
||||
border-left: none; /* Remove the bottom border */
|
||||
border-right: none; /* Remove the bottom border */
|
||||
border-top: none; /* Remove the bottom border */
|
||||
}
|
||||
.table tbody tr:last-child td:last-child {
|
||||
border-bottom: none; /* Remove the bottom border */
|
||||
border-left: none; /* Remove the bottom border */
|
||||
border-right: none; /* Remove the bottom border */
|
||||
border-top: none; /* Remove the bottom border */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php
|
||||
|
||||
$num = isset($_REQUEST['num']) ? $_REQUEST['num'] : '';
|
||||
$fromdate = isset($_REQUEST['fromdate']) ? $_REQUEST['fromdate'] : '';
|
||||
$todate = isset($_REQUEST['todate']) ? $_REQUEST['todate'] : '';
|
||||
$secondordnum = $num;
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
try {
|
||||
// Fetch customer details from phonebook
|
||||
$sql = "SELECT * FROM " . $DB . ".phonebook WHERE secondordnum = ?";
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->bindValue(1, $num, PDO::PARAM_STR);
|
||||
$stmh->execute();
|
||||
$customer = $stmh->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$customer) {
|
||||
throw new Exception("거래처 정보를 찾을 수 없습니다.");
|
||||
}
|
||||
|
||||
// Fetch sales details from output + output_extra
|
||||
$sql = "SELECT o.*, e.ET_total, e.estimateList, e.estimateSlatList, e.etcList, e.screen_unapprovedList, e.slat_unapprovedList, e.motorList, e.bendList, e.controllerList, e.accountList, e.ET_unapproved
|
||||
FROM " . $DB . ".output o
|
||||
LEFT JOIN " . $DB . ".output_extra e ON o.num = e.parent_num
|
||||
WHERE o.secondordnum = ? AND o.outdate BETWEEN ? AND ? AND (o.is_deleted IS NULL OR o.is_deleted = 0)
|
||||
ORDER BY o.outdate ASC";
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->bindValue(1, $num, PDO::PARAM_STR);
|
||||
$stmh->bindValue(2, $fromdate, PDO::PARAM_STR);
|
||||
$stmh->bindValue(3, $todate, PDO::PARAM_STR);
|
||||
$stmh->execute();
|
||||
$rows = $stmh->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// Fetch payments from account table
|
||||
$sql = "SELECT registDate, amount FROM " . $DB . ".account
|
||||
WHERE secondordnum = ?
|
||||
AND registDate BETWEEN ? AND ?
|
||||
AND (is_deleted IS NULL OR is_deleted = 0)
|
||||
AND content = '거래처 수금'
|
||||
ORDER BY registDate ASC";
|
||||
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->bindValue(1, $num, PDO::PARAM_STR);
|
||||
$stmh->bindValue(2, $fromdate, PDO::PARAM_STR);
|
||||
$stmh->bindValue(3, $todate, PDO::PARAM_STR);
|
||||
$stmh->execute();
|
||||
$payments = $stmh->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 다른 거래처는 기본적으로 마감 기준일 -1일
|
||||
$lastMonthEnd = date("Y-m-t", strtotime($fromdate . " -1 days"));
|
||||
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($lastMonthEnd);
|
||||
// echo '</pre>';
|
||||
|
||||
// 이월잔액 계산
|
||||
$salesBeforeSql = "
|
||||
SELECT SUM(COALESCE(e.ET_total, 0)) AS total_sales
|
||||
FROM " . $DB . ".output o
|
||||
LEFT JOIN " . $DB . ".output_extra e ON o.num = e.parent_num
|
||||
WHERE o.secondordnum = :secondordnum AND o.outdate <= :lastMonthEnd AND (o.is_deleted IS NULL OR o.is_deleted = 0)
|
||||
";
|
||||
$paymentBeforeSql = "
|
||||
SELECT SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
|
||||
FROM " . $DB . ".account
|
||||
WHERE secondordnum = :secondordnum AND registDate <= :lastMonthEnd AND (is_deleted IS NULL OR is_deleted = 0) AND content = '거래처 수금'
|
||||
";
|
||||
|
||||
$salesBeforeStmt = $pdo->prepare($salesBeforeSql);
|
||||
$salesBeforeStmt->execute([':secondordnum' => $secondordnum, ':lastMonthEnd' => $lastMonthEnd]);
|
||||
$salesBeforeData = $salesBeforeStmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$paymentBeforeStmt = $pdo->prepare($paymentBeforeSql);
|
||||
$paymentBeforeStmt->execute([':secondordnum' => $secondordnum, ':lastMonthEnd' => $lastMonthEnd]);
|
||||
$paymentBeforeData = $paymentBeforeStmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$initialSales = isset($salesBeforeData['total_sales']) ? (float)$salesBeforeData['total_sales'] : 0;
|
||||
$initialPayments = isset($paymentBeforeData['total_payment']) ? (float)$paymentBeforeData['total_payment'] : 0;
|
||||
|
||||
// Calculate the initial balance
|
||||
$initialBalance = intval(round($initialSales, 2) - round($initialPayments));
|
||||
|
||||
// 마지막 자릿수가 1인지 확인
|
||||
if (floatval($initialBalance) % 10 === 1) {
|
||||
// 마지막 자릿수를 제거 (정수로 처리)
|
||||
$initialBalance = floor($initialBalance / 10);
|
||||
}
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo "오류: " . $e->getMessage();
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-2">
|
||||
<div class="d-flex align-items-center justify-content-end mt-1 m-2">
|
||||
<i class="bi bi-info-circle-fill"></i> <?=$secondordnum?>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick="location.reload();"> <i class="bi bi-arrow-clockwise"></i> </button>
|
||||
<button class="btn btn-dark btn-sm me-1" onclick="generatePDF()"> PDF 저장 </button>
|
||||
<button class="btn btn-dark btn-sm me-1" onclick="sendmail();"> <i class="bi bi-envelope-arrow-up"></i> 전송 </button>
|
||||
<button class="btn btn-secondary btn-sm" onclick="self.close();"> <i class="bi bi-x-lg"></i> 닫기 </button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content-to-print">
|
||||
<div class="container" >
|
||||
<div class="d-flex align-items-center justify-content-center mb-3">
|
||||
<h2><?= $customer['vendor_name'] ?> 관리대장</h2>
|
||||
<h5>(거래명세서별)</h5>
|
||||
</div>
|
||||
<div class="row align-items-center justify-content-center mb-1 mt-2">
|
||||
<div class="col-sm-6 text-start">
|
||||
회사명 : (주) 경동기업 / 담당 : 정미영 차장
|
||||
</div>
|
||||
<div class="col-sm-6 text-end">
|
||||
<?= $fromdate ?> ~ <?= $todate ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center justify-content-center ">
|
||||
<table class="table" style="border-collapse: collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="text-start fw-bold" style="width:20%;">사업자등록번호</th>
|
||||
<th class="text-start fw-bold text-primary" style="width:30%;"><?= $customer['vendor_code'] ?></th>
|
||||
<th class="text-start fw-bold">대표자</th>
|
||||
<th class="text-start"><?= $customer['representative_name'] ?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-start fw-bold">여신한도</th>
|
||||
<th class="text-start">0</th>
|
||||
<th class="text-start fw-bold">전화</th>
|
||||
<th class="text-start"><?= $customer['phone'] ?> (모바일: <?= $customer['mobile'] ?>)</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-start fw-bold">Email</th>
|
||||
<th class="text-start"><?= $customer['email'] ?></th>
|
||||
<th class="text-start fw-bold">Fax</th>
|
||||
<th class="text-start"><?= $customer['fax'] ?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-start fw-bold">주소</th>
|
||||
<th colspan="3" class="text-start"><?= $customer['address'] ?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-start fw-bold">적요</th>
|
||||
<th colspan="3" class="text-start"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="d-flex align-items-center justify-content-center ">
|
||||
<table class="table" style="border-collapse: collapse;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="5" class="text-center">판매/수금내역</th>
|
||||
</tr>
|
||||
<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>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td colspan="2" class="text-center fw-bold text-primary">이월잔액</td>
|
||||
<td class="text-center"></td>
|
||||
<td class="text-center"></td>
|
||||
<td class="text-end fw-bold text-primary"><?= number_format($initialBalance) ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$total_balance = $initialBalance; // 초기 잔액 설정
|
||||
$monthly_sales = [];
|
||||
$current_month = '';
|
||||
$grand_total = 0;
|
||||
$sale_count = 0;
|
||||
$total_payment_sum = 0; // 수금 합계 초기화
|
||||
|
||||
// Merge sales and payments into one array
|
||||
$events = [];
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$events[] = [
|
||||
'date' => $row['outdate'],
|
||||
'type' => 'sale',
|
||||
'data' => $row
|
||||
];
|
||||
}
|
||||
// 수금부분
|
||||
foreach ($payments as $payment) {
|
||||
$events[] = [
|
||||
'date' => $payment['registDate'], // 올바른 키 이름 사용
|
||||
'type' => 'payment',
|
||||
'data' => [
|
||||
'amount' => $payment['amount'] // 올바른 키 이름 사용
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// Sort events by date
|
||||
usort($events, function($a, $b) {
|
||||
return strcmp($a['date'], $b['date']);
|
||||
});
|
||||
|
||||
// 출고예정일 첫번째 요소 저장변수
|
||||
$Last_deadline = '';
|
||||
foreach ($events as $event) {
|
||||
$event_date = $event['date'];
|
||||
$event_type = $event['type'];
|
||||
$month = date('Y/m', strtotime($event_date));
|
||||
|
||||
if ($event_type == 'payment') {
|
||||
$payment = $event['data'];
|
||||
$payment_date = $event_date; // 날짜는 이벤트의 날짜를 사용
|
||||
$payment_amount = (float)str_replace(',', '', $payment['amount']); // payment 대신 amount 키 사용
|
||||
$total_balance -= $payment_amount;
|
||||
$total_payment_sum += $payment_amount; // 수금 합계에 추가
|
||||
|
||||
if (!isset($monthly_sales[$month])) {
|
||||
$monthly_sales[$month] = 0;
|
||||
}
|
||||
|
||||
echo "<tr class='date-row'>
|
||||
<td class='date-row-date text-start'>{$payment_date}</td>
|
||||
<td class='date-row text-start'>입금</td>
|
||||
<td class='date-row text-end'></td>
|
||||
<td class='date-row text-end'>" . number_format($payment_amount) . "</td>
|
||||
<td class='date-row text-end'>" . number_format($total_balance) . "</td>
|
||||
</tr>";
|
||||
}
|
||||
|
||||
if ($current_month !== $month) {
|
||||
if ($current_month !== '') {
|
||||
echo "<tr>
|
||||
<td colspan='2' class='text-center fw-bold'>{$current_month} 계</td>
|
||||
<td class='text-end'>" . number_format($monthly_sales[$current_month]) . "</td>
|
||||
<td class='text-start'></td>
|
||||
<td class='text-start'></td>
|
||||
</tr>";
|
||||
}
|
||||
$current_month = $month;
|
||||
}
|
||||
|
||||
if ($event_type == 'sale') {
|
||||
$row = $event['data'];
|
||||
$outdate = $row['outdate'];
|
||||
$workplacename = isset($row['workplacename']) ? $row['workplacename'] : '';
|
||||
$amount = (float)$row['ET_total'];
|
||||
$total_balance += round($amount);
|
||||
$sale_count++;
|
||||
if (!isset($monthly_sales[$month])) {
|
||||
$monthly_sales[$month] = 0;
|
||||
}
|
||||
$monthly_sales[$month] += $amount;
|
||||
$grand_total += $amount;
|
||||
echo "<tr class='date-row' onclick=\"redirectToView('{$row['num']}', '{$tablename}')\">
|
||||
<td class='date-row-date text-start'>{$outdate}</td>
|
||||
<td class='date-row text-start'>{$workplacename}</td>
|
||||
<td class='date-row text-end'>" . number_format($amount) . "</td>
|
||||
<td class='date-row text-start'></td>
|
||||
<td class='date-row text-end'>" . number_format($total_balance) . "</td>
|
||||
</tr>";
|
||||
|
||||
// 상세내역: estimateList, estimateSlatList, etcList, screen_unapprovedList, slat_unapprovedList, motorList, bendList, controllerList, accountList
|
||||
$detailColumns = [
|
||||
'estimateList', 'estimateSlatList', 'etcList', 'screen_unapprovedList', 'slat_unapprovedList', 'motorList', 'bendList', 'controllerList', 'accountList'
|
||||
];
|
||||
foreach ($detailColumns as $col) {
|
||||
$list = isset($row[$col]) ? json_decode($row[$col], true) : [];
|
||||
if (is_array($list)) {
|
||||
foreach ($list as $item) {
|
||||
// 품목명, 수량, 단가, 금액 등 컬럼명은 데이터 구조에 따라 다를 수 있음
|
||||
$itemName = isset($item['col1']) ? $item['col1'] : '';
|
||||
$spec = isset($item['col2']) ? $item['col2'] : '';
|
||||
$qty = isset($item['col4']) ? $item['col4'] : (isset($item['col2']) ? $item['col2'] : 1);
|
||||
$unit = isset($item['col5']) ? str_replace(',', '', $item['col5']) : 0;
|
||||
$amountDetail = floatval($qty) * floatval($unit);
|
||||
if ($itemName && $amountDetail > 0) {
|
||||
echo "<tr>
|
||||
<td class='text-start'></td>
|
||||
<td class='text-start'>{$itemName} {$spec}</td>
|
||||
<td class='text-end'>" . number_format($amountDetail) . "</td>
|
||||
<td class='text-start'></td>
|
||||
<td class='text-start'></td>
|
||||
</tr>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 비인정 금액(ET_unapproved) 표시
|
||||
if (isset($row['ET_unapproved']) && floatval($row['ET_unapproved']) > 0) {
|
||||
echo "<tr>
|
||||
<td class='text-start'></td>
|
||||
<td class='text-start text-danger'>비인정 금액</td>
|
||||
<td class='text-end text-danger'>-" . number_format($row['ET_unapproved']) . "</td>
|
||||
<td class='text-start'></td>
|
||||
<td class='text-start'></td>
|
||||
</tr>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($current_month !== '') {
|
||||
|
||||
// 마지막 1원 정리
|
||||
if (round($monthly_sales[$current_month]) % 10 === 1) {
|
||||
$monthly_sales[$current_month] -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
|
||||
echo "<tr>
|
||||
<td colspan='2' class='text-center fw-bold date-row'>{$current_month} 계 <span style='font-size:9px;'> (VAT 포함) </span></td>
|
||||
<td class='text-end date-row fw-bold'>" . number_format($monthly_sales[$current_month]) . "</td>
|
||||
<td class='text-start date-row'></td>
|
||||
<td class='text-start date-row'></td>
|
||||
</tr>";
|
||||
}
|
||||
|
||||
|
||||
if (round($grand_total) % 10 === 1) {
|
||||
$grand_total -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
|
||||
if (round($total_balance) % 10 === 1) {
|
||||
$total_balance -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
|
||||
?>
|
||||
<tr class="date-row" >
|
||||
<td colspan="2" class="text-center fw-bold date-row" >총 <?= $sale_count ?>건 누계 <span style='font-size:11px;'> (VAT 포함) </span></td>
|
||||
<td class="text-end date-row fw-bold"><?= number_format($grand_total) ?></td>
|
||||
<td class="text-end date-row fw-bold"><?= number_format($total_payment_sum) ?></td> <!-- 수금 합계 표시 -->
|
||||
<td class="text-end date-row fw-bold"><?= number_format($total_balance) ?></td> <!-- 잔액 합계 표시 -->
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 페이지로딩 -->
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
loader.style.display = 'none';
|
||||
});
|
||||
|
||||
function generatePDF() {
|
||||
var workplace = '<?= $customer['vendor_name'] ?>';
|
||||
var deadline = '<?php echo $Last_deadline; ?>';
|
||||
var deadlineDate = new Date(deadline);
|
||||
var formattedDate = "(" + String(deadlineDate.getFullYear()).slice(-2) + "." + ("0" + (deadlineDate.getMonth() + 1)).slice(-2) + "." + ("0" + deadlineDate.getDate()).slice(-2) + ")";
|
||||
var result = '경동기업_거래원장(' + workplace + ')' + formattedDate + '.pdf';
|
||||
|
||||
var element = document.getElementById('content-to-print');
|
||||
var opt = {
|
||||
margin: [15, 8, 17, 8], // Top, right, bottom, left margins
|
||||
filename: result,
|
||||
image: { type: 'jpeg', quality: 0.98 },
|
||||
html2canvas: { scale: 2 },
|
||||
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
|
||||
pagebreak: { mode: [''] }
|
||||
};
|
||||
html2pdf().from(element).set(opt).save();
|
||||
}
|
||||
|
||||
|
||||
function redirectToView(num, tablename) {
|
||||
var url = "/output/write_form.php?mode=view&num=" + num + "&tablename=" + tablename;
|
||||
customPopup(url, '수주내역', 1850, 900);
|
||||
}
|
||||
|
||||
|
||||
ajaxRequest = null;
|
||||
|
||||
|
||||
function generatePDF_server(callback) {
|
||||
var workplace = '<?= $customer['vendor_name'] ?>';
|
||||
var item = '<?php echo $item_title; ?>';
|
||||
var deadline = '<?php echo $Last_deadline; ?>';
|
||||
var deadlineDate = new Date(deadline);
|
||||
var formattedDate = "(" + String(deadlineDate.getFullYear()).slice(-2) + "." + ("0" + (deadlineDate.getMonth() + 1)).slice(-2) + "." + ("0" + deadlineDate.getDate()).slice(-2) + ")";
|
||||
var result = 'DH ' + item +'(' + workplace + ')' + formattedDate + '.pdf';
|
||||
|
||||
var element = document.getElementById('content-to-print');
|
||||
var opt = {
|
||||
margin: [15, 8, 17, 8], // Top, right, bottom, left margins
|
||||
filename: result,
|
||||
image: { type: 'jpeg', quality: 0.98 },
|
||||
html2canvas: { scale: 2 },
|
||||
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
|
||||
pagebreak: { mode: [''] }
|
||||
};
|
||||
|
||||
html2pdf().from(element).set(opt).output('datauristring').then(function (pdfDataUri) {
|
||||
var pdfBase64 = pdfDataUri.split(',')[1]; // Base64 인코딩된 PDF 데이터 추출
|
||||
var formData = new FormData();
|
||||
formData.append('pdf', pdfBase64);
|
||||
formData.append('filename', result);
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'save_pdf.php', // PDF 파일을 저장하는 PHP 파일
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
success: function (response) {
|
||||
var res = JSON.parse(response);
|
||||
if (callback) {
|
||||
callback(res.filename); // 서버에 저장된 파일 경로를 콜백으로 전달
|
||||
}
|
||||
},
|
||||
error: function (xhr, status, error) {
|
||||
Swal.fire('Error', 'PDF 저장에 실패했습니다.', 'error');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function sendmail() {
|
||||
var secondordnum = '<?php echo $secondordnum; ?>'; // 서버에서 가져온 값
|
||||
var item = '<?php echo $item_title; ?>';
|
||||
console.log('secondordnum', secondordnum);
|
||||
|
||||
if (typeof ajaxRequest !== 'undefined' && ajaxRequest !== null) {
|
||||
ajaxRequest.abort();
|
||||
}
|
||||
|
||||
ajaxRequest = $.ajax({
|
||||
type: 'POST',
|
||||
url: 'get_companyCode.php', // 파일 이름 수정
|
||||
data: { secondordnum: secondordnum },
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
console.log('response : ', response);
|
||||
if (response.error) {
|
||||
Swal.fire('Error', response.error, 'error');
|
||||
} else {
|
||||
var email = response.email;
|
||||
var vendorName = response.vendor_name;
|
||||
|
||||
Swal.fire({
|
||||
title: '이메일 보내기',
|
||||
text: '거래처(' + vendorName + ') Email : (' + email + ') 이메일 전송 하시겠습니까?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '보내기',
|
||||
cancelButtonText: '취소',
|
||||
reverseButtons: true
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
generatePDF_server(function(filename) {
|
||||
sendEmail(email, vendorName, item, filename);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
Swal.fire('Error', '전송중 오류가 발생했습니다.', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function sendEmail(recipientEmail,vendorName, item, filename) {
|
||||
// 이메일 전송 코드 작성 (예: PHP를 호출하여 이메일 전송)
|
||||
if (typeof ajaxRequest !== 'undefined' && ajaxRequest !== null) {
|
||||
ajaxRequest.abort();
|
||||
}
|
||||
var deadline = '<?php echo $Last_deadline; ?>';
|
||||
var deadlineDate = new Date(deadline);
|
||||
var formattedDate = "(" + String(deadlineDate.getFullYear()).slice(-2) + "." + ("0" + (deadlineDate.getMonth() + 1)).slice(-2) + "." + ("0" + deadlineDate.getDate()).slice(-2) + ")";
|
||||
|
||||
ajaxRequest = $.ajax({
|
||||
type: 'POST',
|
||||
url: 'send_email.php', // 이메일 전송을 처리하는 PHP 파일
|
||||
data: { email: recipientEmail, vendorName : vendorName, filename: filename, item : item, formattedDate :formattedDate },
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
Swal.fire('Success', '정상적으로 전송되었습니다.', 'success');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
Swal.fire('Error', '전송에 실패했습니다. 확인바랍니다.', 'error');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
18
account_juil/_request.php
Normal file
18
account_juil/_request.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
$num = isset($_REQUEST['num']) ? $_REQUEST['num'] : '';
|
||||
$is_deleted = isset($_REQUEST['is_deleted']) ? $_REQUEST['is_deleted'] : 0;
|
||||
$searchtag = isset($_REQUEST['searchtag']) ? $_REQUEST['searchtag'] : '';
|
||||
$registDate = isset($_REQUEST['registDate']) ? $_REQUEST['registDate'] : '';
|
||||
$inoutsep = isset($_REQUEST['inoutsep']) ? $_REQUEST['inoutsep'] : '';
|
||||
$content = isset($_REQUEST['content']) ? $_REQUEST['content'] : '';
|
||||
$contentSub = isset($_REQUEST['contentSub']) ? $_REQUEST['contentSub'] : '';
|
||||
$amount = isset($_REQUEST['amount']) ? $_REQUEST['amount'] : '';
|
||||
$dueDate = isset($_REQUEST['dueDate']) ? $_REQUEST['dueDate'] : '';
|
||||
$first_writer = isset($_REQUEST['first_writer']) ? $_REQUEST['first_writer'] : '';
|
||||
$update_log = isset($_REQUEST['update_log']) ? $_REQUEST['update_log'] : '';
|
||||
$content_detail = isset($_REQUEST['content_detail']) ? $_REQUEST['content_detail'] : '';
|
||||
$bankbook = isset($_REQUEST['bankbook']) ? $_REQUEST['bankbook'] : '';
|
||||
$secondordnum = isset($_REQUEST['secondordnum']) ? $_REQUEST['secondordnum'] : '';
|
||||
$endorsementDate = isset($_REQUEST['endorsementDate']) ? $_REQUEST['endorsementDate'] : date('Y-m-d');
|
||||
$parentEBNum = isset($_REQUEST['parentEBNum']) ? $_REQUEST['parentEBNum'] : '';
|
||||
?>
|
||||
18
account_juil/_row.php
Normal file
18
account_juil/_row.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
$num = isset($row['num']) ? $row['num'] : '';
|
||||
$is_deleted = isset($row['is_deleted']) ? $row['is_deleted'] : 0;
|
||||
$searchtag = isset($row['searchtag']) ? $row['searchtag'] : '';
|
||||
$registDate = isset($row['registDate']) ? $row['registDate'] : '';
|
||||
$inoutsep = isset($row['inoutsep']) ? $row['inoutsep'] : '';
|
||||
$content = isset($row['content']) ? $row['content'] : '';
|
||||
$contentSub = isset($row['contentSub']) ? $row['contentSub'] : '';
|
||||
$amount = isset($row['amount']) ? $row['amount'] : '';
|
||||
$dueDate = isset($row['dueDate']) ? $row['dueDate'] : '';
|
||||
$first_writer = isset($row['first_writer']) ? $row['first_writer'] : '';
|
||||
$update_log = isset($row['update_log']) ? $row['update_log'] : '';
|
||||
$content_detail = isset($row['content_detail']) ? $row['content_detail'] : '';
|
||||
$bankbook = isset($row['bankbook']) ? $row['bankbook'] : '';
|
||||
$secondordnum = isset($row['secondordnum']) ? $row['secondordnum'] : '';
|
||||
$endorsementDate = isset($row['endorsementDate']) ? $row['endorsementDate'] : '';
|
||||
$parentEBNum = isset($row['parentEBNum']) ? $row['parentEBNum'] : '';
|
||||
?>
|
||||
1
account_juil/accountContents.json
Normal file
1
account_juil/accountContents.json
Normal file
File diff suppressed because one or more lines are too long
32
account_juil/accountlist.json
Normal file
32
account_juil/accountlist.json
Normal file
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"company": "국민",
|
||||
"number": "796801-00-039630",
|
||||
"memo": "주거래통장"
|
||||
},
|
||||
{
|
||||
"company": "국민",
|
||||
"number": "006090-18-199685",
|
||||
"memo": "미래에셋주식계좌"
|
||||
},
|
||||
{
|
||||
"company": "국민",
|
||||
"number": "796868-00-003858",
|
||||
"memo": "외국환거래통장"
|
||||
},
|
||||
{
|
||||
"company": "기업",
|
||||
"number": "339-086768-01-011",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "기업",
|
||||
"number": "339-086768-01-028",
|
||||
"memo": "보증부대출전용"
|
||||
},
|
||||
{
|
||||
"company": "국민",
|
||||
"number": "796816-00-062898",
|
||||
"memo": "산재예방시설자금(대출)"
|
||||
}
|
||||
]
|
||||
92
account_juil/accoutlist.json
Normal file
92
account_juil/accoutlist.json
Normal file
@@ -0,0 +1,92 @@
|
||||
[
|
||||
{
|
||||
"company": "국민은행★",
|
||||
"number": "231401-04-180862",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "국민은행",
|
||||
"number": "796801-00-006119",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "국민은행(롯데건설)",
|
||||
"number": "796837-00-001193",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "국민은행(영신)",
|
||||
"number": "433437-01-005318",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "국민은행(현대건설)",
|
||||
"number": "433437-01-005363",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "기업은행",
|
||||
"number": "149-074461-01-018",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "기업은행(동성빌딩)",
|
||||
"number": "461-044317-04-021",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "하나은행",
|
||||
"number": "337-890050-08504",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "하나은행(요진건설)",
|
||||
"number": "176-910045-85504",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "하나은행(이수건설)",
|
||||
"number": "176-910043-21004",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "하나은행(현대엔지니어링)",
|
||||
"number": "176-910039-25104",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "하나은행(한화)",
|
||||
"number": "176-910038-64504",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "신한은행(GS건설)",
|
||||
"number": "100-033-404566",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "신한은행(신세계건설)",
|
||||
"number": "100-033-032265",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "신한은행(케이알산업)",
|
||||
"number": "100-037-328297",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "우리은행(대림건설)",
|
||||
"number": "1005-203-967961",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "하나은행(하도급지킴이3)",
|
||||
"number": "176-910042-260004",
|
||||
"memo": ""
|
||||
},
|
||||
{
|
||||
"company": "기업은행(기보대출통장)",
|
||||
"number": "170-175366-01-011",
|
||||
"memo": ""
|
||||
}
|
||||
]
|
||||
168
account_juil/accoutlist.php
Normal file
168
account_juil/accoutlist.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
// accoutlist.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;
|
||||
}
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
$title_message = '법인계좌 목록 관리';
|
||||
?>
|
||||
<title><?= $title_message ?></title>
|
||||
<?php if($chkMobile==true) { ?>
|
||||
<style>
|
||||
@media (max-width: 1000px) {
|
||||
body { font-size: 25px; }
|
||||
.form-control, .fw-bold, .table td, .table th { font-size: 25px; }
|
||||
button { font-size: 30px; }
|
||||
.modal-body, .modal-title { font-size: 30px; }
|
||||
}
|
||||
</style>
|
||||
<?php } ?>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?php
|
||||
// 메뉴를 표현할지 판단하는 header
|
||||
$header = $_REQUEST['header'] ?? '';
|
||||
|
||||
if($user_id === '0266771300' ) {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader_accountant1.php'); // 경리
|
||||
} else {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php');
|
||||
}
|
||||
|
||||
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . '/account_juil/accoutlist.json';
|
||||
$cards = [];
|
||||
|
||||
if (file_exists($jsonFile)) {
|
||||
$jsonContent = file_get_contents($jsonFile);
|
||||
$cards = json_decode($jsonContent, true);
|
||||
if (!is_array($cards)) {
|
||||
$cards = [];
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
$index = isset($_POST['index']) ? intval($_POST['index']) : -1;
|
||||
$company = trim($_POST['company'] ?? '');
|
||||
$number = trim($_POST['number'] ?? '');
|
||||
$memo = trim($_POST['memo'] ?? '');
|
||||
|
||||
if ($action === 'insert' && $company !== '' && $number !== '') {
|
||||
$cards[] = [
|
||||
"company" => $company,
|
||||
"number" => $number,
|
||||
"memo" => $memo
|
||||
];
|
||||
} elseif ($action === 'update' && $index >= 0 && $index < count($cards)) {
|
||||
$cards[$index]["company"] = $company;
|
||||
$cards[$index]["number"] = $number;
|
||||
$cards[$index]["memo"] = $memo;
|
||||
} elseif ($action === 'delete' && $index >= 0 && $index < count($cards)) {
|
||||
array_splice($cards, $index, 1);
|
||||
}
|
||||
|
||||
file_put_contents($jsonFile, json_encode($cards, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="container mt-3">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-center align-items-center text-center">
|
||||
<h3 class="mb-0"><?= $title_message ?></h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="addCardForm" method="post" action="accoutlist.php" class="row g-3 mb-3">
|
||||
<input type="hidden" name="action" id="action" value="insert">
|
||||
<input type="hidden" name="index" id="index" value="-1">
|
||||
<div class="d-flex justify-content-center align-items-center text-center">
|
||||
<input type="text" name="company" id="company" class="form-control mx-1" placeholder="은행명" autocomplete="off" style="width:150px;">
|
||||
<input type="text" name="number" id="number" class="form-control mx-1" placeholder="계좌 번호" autocomplete="off" style="width:200px;">
|
||||
<input type="text" name="memo" id="memo" class="form-control mx-1" placeholder="비고" autocomplete="off" style="width:120px;">
|
||||
<button type="submit" class="btn btn-primary btn-sm mx-1" id="submitBtn">등록</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover text-center">
|
||||
<thead class="table-secondary">
|
||||
<tr>
|
||||
<th>순번</th>
|
||||
<th>은행명</th>
|
||||
<th>계좌 번호</th>
|
||||
<th>비고</th>
|
||||
<th>수정/삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($cards)): ?>
|
||||
<?php foreach ($cards as $i => $card): ?>
|
||||
<tr>
|
||||
<td><?= $i + 1 ?></td>
|
||||
<td><?= htmlspecialchars($card["company"], ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><?= htmlspecialchars($card["number"], ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><?= htmlspecialchars($card["memo"], ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary editBtn" data-index="<?= $i ?>">수정</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger deleteBtn" data-index="<?= $i ?>">삭제</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="5">등록된 계좌가 없습니다.</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
// 로딩 오버레이 제거
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
if(loader) loader.style.display = 'none';
|
||||
|
||||
$('.editBtn').on('click', function(){
|
||||
var row = $(this).closest('tr');
|
||||
var index = $(this).data('index');
|
||||
var company = row.find('td:eq(1)').text().trim();
|
||||
var number = row.find('td:eq(2)').text().trim();
|
||||
var memo = row.find('td:eq(3)').text().trim();
|
||||
$('#company').val(company);
|
||||
$('#number').val(number);
|
||||
$('#memo').val(memo);
|
||||
$('#index').val(index);
|
||||
$('#action').val('update');
|
||||
$('#submitBtn').text('수정');
|
||||
});
|
||||
|
||||
$('.deleteBtn').on('click', function(){
|
||||
var index = $(this).data('index');
|
||||
Swal.fire({
|
||||
title: '계좌 삭제',
|
||||
text: "정말 삭제하시겠습니까?",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '삭제',
|
||||
cancelButtonText: '취소'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$('#index').val(index);
|
||||
$('#action').val('delete');
|
||||
$('#addCardForm').submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include $_SERVER['DOCUMENT_ROOT'] . '/common/modal.php'; ?>
|
||||
</body>
|
||||
</html>
|
||||
737
account_juil/baddebt.php
Normal file
737
account_juil/baddebt.php
Normal file
@@ -0,0 +1,737 @@
|
||||
<?php
|
||||
// 거래명세표 보여주는 코드 s_transaction.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;
|
||||
}
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
// 첫 화면 표시 문구
|
||||
$title_message = '악성 채권추심';
|
||||
?>
|
||||
<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;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php'); ?>
|
||||
<?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");
|
||||
// // fromdate를 이전 달의 1일로 설정
|
||||
// $fromdate = date("Y-m-01", strtotime("first day of -1 month"));
|
||||
$todate = $currentDate;
|
||||
$Transtodate = $todate;
|
||||
} else {
|
||||
$Transtodate = $todate;
|
||||
}
|
||||
|
||||
// 시작일과 종료일을 "8월1일~9월1일" 형태로 포맷팅
|
||||
$formatted_date_range = date("n월j일", strtotime($fromdate)) . '~' . date("n월j일", strtotime($todate));
|
||||
|
||||
function checkNull($strtmp) {
|
||||
return $strtmp !== null && trim($strtmp) !== '';
|
||||
}
|
||||
|
||||
$tablenamephonebook = 'phonebook';
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
// 이월잔액 계산을 위한 로직 (매출 - 수금)
|
||||
$initialBalances = [];
|
||||
|
||||
// 이월 잔액을 계산할 기준 날짜
|
||||
$lastMonthEnd = date("Y-m-d", strtotime($fromdate . " -1 day"));
|
||||
|
||||
// echo '<pre>';
|
||||
// echo '이월잔액 기간 lastMonthEnd: ';
|
||||
// print_r($lastMonthEnd);
|
||||
// echo '</pre>';
|
||||
|
||||
$searchsecondordnum = '';
|
||||
if(!empty($search))
|
||||
{
|
||||
$sql = "SELECT secondordnum FROM ".$DB.".".$tablenamephonebook."
|
||||
WHERE (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND represent='대표코드' AND (vendor_name LIKE '%$search%')";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
$searchsecondordnum = $row['secondordnum'];
|
||||
}
|
||||
|
||||
// 거래처별 매출 및 수금 데이터 계산 (이월잔액)
|
||||
$salesBeforeSql = "
|
||||
SELECT o.secondordnum, SUM(COALESCE(e.ET_total, 0)) AS total_sales
|
||||
FROM {$DB}.output o
|
||||
LEFT JOIN {$DB}.output_extra e ON o.num = e.parent_num
|
||||
WHERE o.outdate <= :lastMonthEnd AND (o.is_deleted IS NULL or o.is_deleted=0 or o.is_deleted ='')
|
||||
GROUP BY o.secondordnum
|
||||
";
|
||||
$paymentBeforeSql = "
|
||||
SELECT secondordnum, SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
|
||||
FROM {$DB}.account_juil
|
||||
WHERE registDate <= :lastMonthEnd AND (is_deleted IS NULL or is_deleted=0 or is_deleted ='' ) AND content = '거래처 수금'
|
||||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')
|
||||
GROUP BY secondordnum
|
||||
";
|
||||
$salesBeforeStmt = $pdo->prepare($salesBeforeSql);
|
||||
$salesBeforeStmt->execute([':lastMonthEnd' => $lastMonthEnd]);
|
||||
$salesBeforeData = $salesBeforeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$paymentBeforeStmt = $pdo->prepare($paymentBeforeSql);
|
||||
$paymentBeforeStmt->execute([':lastMonthEnd' => $lastMonthEnd]);
|
||||
$paymentBeforeData = $paymentBeforeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 거래처별로 매출과 수금을 비교해 이월 잔액을 계산
|
||||
foreach ($salesBeforeData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_sales = (float)$row['total_sales'];
|
||||
if (!isset($initialBalances[$secondordnum])) {
|
||||
$initialBalances[$secondordnum] = 0;
|
||||
}
|
||||
$initialBalances[$secondordnum] += $total_sales;
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($initialBalances);
|
||||
// echo '</pre>';
|
||||
|
||||
// 수금 데이터를 이용해 이월 잔액에서 수금을 차감
|
||||
foreach ($paymentBeforeData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_payment = (float)$row['total_payment'];
|
||||
if (!isset($initialBalances[$secondordnum])) {
|
||||
$initialBalances[$secondordnum] = 0;
|
||||
}
|
||||
$initialBalances[$secondordnum] -= $total_payment;
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($initialBalances);
|
||||
// echo '</pre>';
|
||||
|
||||
// 매출이 발생한 거래처 필터링 및 매출액 계산
|
||||
$salesSql = "
|
||||
SELECT o.secondordnum, COALESCE(e.ET_total, 0) as ET_total
|
||||
FROM {$DB}.output o
|
||||
LEFT JOIN {$DB}.output_extra e ON o.num = e.parent_num
|
||||
WHERE (o.outdate BETWEEN date('$fromdate') AND date('$Transtodate'))
|
||||
AND (o.is_deleted IS NULL OR o.is_deleted = 0 or o.is_deleted ='')
|
||||
";
|
||||
$salesStmt = $pdo->prepare($salesSql);
|
||||
$salesStmt->execute();
|
||||
$salesData = $salesStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$salesResults = [];
|
||||
foreach ($salesData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_sales = (float)$row['ET_total'];
|
||||
if (!isset($salesResults[$secondordnum])) {
|
||||
$salesResults[$secondordnum] = 0;
|
||||
}
|
||||
$salesResults[$secondordnum] += $total_sales;
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// echo '매출발생 시작 fromdate: ';
|
||||
// print_r($fromdate);
|
||||
// echo '</pre>';
|
||||
|
||||
// echo '<pre>';
|
||||
// echo '매출발생 종료 Transtodate: ';
|
||||
// print_r($Transtodate);
|
||||
// echo '</pre>';
|
||||
|
||||
// echo '<pre>';
|
||||
// echo '이월잔액배열 디오이엔시 추적 initialBalances: ';
|
||||
// print_r($initialBalances['56']);
|
||||
// echo '</pre>';
|
||||
|
||||
|
||||
// 모든 거래처 목록을 처리하기 전에 거래처 이름을 저장하는 배열 초기화
|
||||
$vendorNames = [];
|
||||
// 모든 거래처 목록을 생성 (매출, 기초채권)
|
||||
$allResults = array_unique(array_merge(array_keys($salesResults), array_keys($initialBalances)));
|
||||
|
||||
// 매출 금액 기준으로 역순으로 정렬
|
||||
usort($allResults, function($a, $b) use ($salesResults) {
|
||||
$salesA = isset($salesResults[$a]) ? $salesResults[$a] : 0;
|
||||
$salesB = isset($salesResults[$b]) ? $salesResults[$b] : 0;
|
||||
return round($salesA - $salesB);
|
||||
});
|
||||
|
||||
// 합계를 저장할 변수들
|
||||
$totalInitialReceivable = 0;
|
||||
$totalSalesAmount = 0;
|
||||
$totalPaymentAmount = 0;
|
||||
$totalBalanceDue = 0;
|
||||
|
||||
try {
|
||||
$start_num = 1;
|
||||
foreach ($allResults as $ordnum) {
|
||||
// 이월 잔액 설정
|
||||
$initialReceivable = isset($initialBalances[$ordnum]) ? $initialBalances[$ordnum] : 0;
|
||||
|
||||
// 수금 내역 가져오기
|
||||
$paymentSql = "SELECT SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) as total_payment
|
||||
FROM ".$DB.".account_juil
|
||||
WHERE secondordnum = '$ordnum'
|
||||
AND registDate BETWEEN '1970-01-01' AND date('$Transtodate')
|
||||
AND (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND content = '거래처 수금'
|
||||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||||
|
||||
$paymentStmt = $pdo->prepare($paymentSql);
|
||||
$paymentStmt->execute();
|
||||
$paymentData = $paymentStmt->fetch(PDO::FETCH_ASSOC);
|
||||
$total_payment = isset($paymentData['total_payment']) ? (int)str_replace(',', '', $paymentData['total_payment']) : 0;
|
||||
|
||||
$total_sales = isset($salesResults[$ordnum]) ? $salesResults[$ordnum] : 0;
|
||||
|
||||
// 조건: 기초채권이 있거나 매출이 있는 경우만 표시
|
||||
if ($initialReceivable != 0 || $total_sales != 0 ) { // 매출이 있는 것을 추출
|
||||
$sql = "SELECT * FROM $DB.$tablenamephonebook
|
||||
WHERE secondordnum = '$ordnum'
|
||||
AND (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND represent='대표코드'";
|
||||
|
||||
$stmh = $pdo->query($sql);
|
||||
while ($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/phonebook/_row.php';
|
||||
|
||||
if (intval($ordnum) > 0)
|
||||
{
|
||||
$savenum = $ordnum;
|
||||
// 거래처 이름 저장
|
||||
$vendorNames[$ordnum] =$vendor_name ;
|
||||
}
|
||||
else
|
||||
$savenum = $num;
|
||||
|
||||
$total_amount = round($total_sales ) ;
|
||||
|
||||
// 잔액 계산
|
||||
$balance_due = round($initialReceivable) + $total_amount - round($total_payment);
|
||||
|
||||
$totalInitialReceivable += $initialReceivable;
|
||||
$totalSalesAmount += $total_amount;
|
||||
$totalPaymentAmount += $total_payment;
|
||||
$totalBalanceDue += $balance_due;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (PDOException $Exception) {
|
||||
print "오류: ".$Exception->getMessage();
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($vendorNames);
|
||||
// echo '</pre>';
|
||||
|
||||
// 거래처 이름으로 정렬
|
||||
usort($allResults, function($a, $b) use ($vendorNames) {
|
||||
// 거래처 이름이 없는 경우 빈 문자열로 처리
|
||||
$nameA = $vendorNames[$a] ?? '';
|
||||
$nameB = $vendorNames[$b] ?? '';
|
||||
return strcmp($nameA, $nameB);
|
||||
});
|
||||
|
||||
// echo $sql;
|
||||
// echo '<pre>';
|
||||
// print_r($allResults);
|
||||
// echo '</pre>';
|
||||
|
||||
// $search값이 있다면 // 특정 숫자 67만 남기고 필터링
|
||||
// echo 'searchsecondordnum : ' . $searchsecondordnum;
|
||||
if (!empty($search)) {
|
||||
$allResults = array_filter($allResults, function ($value) use ($searchsecondordnum) {
|
||||
return $value === intval($searchsecondordnum);
|
||||
});
|
||||
|
||||
// array_values로 인덱스 재정렬
|
||||
$allResults = array_values($allResults);
|
||||
}
|
||||
|
||||
// 중복 제거
|
||||
$allResults = array_unique($allResults);
|
||||
|
||||
|
||||
// 중복 제거
|
||||
$allResults = array_unique($allResults);
|
||||
|
||||
// 빈 값 제거
|
||||
$allResults = array_filter($allResults, function ($value) {
|
||||
return $value !== null && $value !== '';
|
||||
});
|
||||
|
||||
// 배열 키 재정렬
|
||||
$allResults = array_values($allResults);
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($allResults);
|
||||
// echo '</pre>';
|
||||
|
||||
?>
|
||||
|
||||
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
|
||||
<div class="container mb-5">
|
||||
<input type="hidden" id="mode" name="mode" value="<?=$mode?>">
|
||||
<input type="hidden" id="num" name="num">
|
||||
<input type="hidden" id="tablename" name="tablename" value="<?=$tablenamephonebook?>">
|
||||
<input type="hidden" id="header" name="header" value="<?=$header?>">
|
||||
<input type="hidden" id="secondordnum" name="secondordnum" value="<?=$secondordnum?>">
|
||||
|
||||
<div class="card justify-content-center text-center mt-5">
|
||||
<div class="card-header">
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="text-center text-danger fs-5 me-4"> <i class="bi bi-exclamation-octagon-fill text-danger"></i> <?=$title_message?></span>
|
||||
<button type="button" class="btn btn-dark btn-sm mx-3" onclick='location.reload();' title="새로고침"> <i class="bi bi-arrow-clockwise"></i> </button>
|
||||
<!-- <span class="badge bg-primary"> (한빛에스티) 매월25일 마감 </span> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
▷ <span id="total"> </span>
|
||||
|
||||
<!-- 기간부터 검색까지 연결 묶음 start -->
|
||||
<button type="button" class="btn btn-outline-dark btn-sm me-1 change_dateRange" onclick='alldatesearch()'>전체</button>
|
||||
<span id="showdate" class="btn btn-dark btn-sm">기간</span>
|
||||
|
||||
<div id="showframe" class="card" style="width:300px;">
|
||||
<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-dark btn-sm me-1 change_dateRange" onclick='prepre_month()'>전전월</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='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:100px;" value="<?=$fromdate?>"> ~
|
||||
<input type="date" id="todate" name="todate" class="form-control me-1" style="width:100px;" value="<?=$todate?>"> </span>
|
||||
|
||||
<div class="inputWrap">
|
||||
<input type="text" id="search" name="search" value="<?=$search?>" onkeydown="if(event.key === 'Enter') submitForm();" autocomplete="off" class="form-control" style="width:150px;">
|
||||
<button class="btnClear"></button>
|
||||
</div>
|
||||
|
||||
<div id="autocomplete-list">
|
||||
</div>
|
||||
|
||||
<button id="searchBtn" type="button" class="btn btn-dark btn-sm me-2" onclick="submitForm()"> <i class="bi bi-search"></i> </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card justify-content-center text-center mt-5">
|
||||
<div class="card-body">
|
||||
<div class="d-flex p-1 m-1 mb-1 justify-content-center align-items-center">
|
||||
<table class="table table-hover" id="myTable">
|
||||
<thead class="table-info">
|
||||
<th class="text-center w80px">번호</th>
|
||||
<th class="text-center w200px">거래처명</th>
|
||||
<th class="text-center w140px">이월잔액</th>
|
||||
<th class="text-center w140px"> 매출</th>
|
||||
<th class="text-center w140px">수금</th>
|
||||
<th class="text-center w140px">잔액</th>
|
||||
<th class="text-center w60px">결제일</th>
|
||||
<th class="text-center w140px">적요</th>
|
||||
<?php if($user_id == 'pro')
|
||||
print '<th class="text-center w50px">거래처 Code</th>';
|
||||
?>
|
||||
<th style="display:none;" ></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
try {
|
||||
$start_num = 1;
|
||||
|
||||
foreach ($allResults as $initnum) {
|
||||
|
||||
// echo 'second ord num '. $initnum . '<br>';
|
||||
// 이월잔액 설정
|
||||
$initialReceivable = isset($initialBalances[$initnum]) ? intval($initialBalances[$initnum]) : 0;
|
||||
// 마지막 자릿수가 1인지 확인
|
||||
if (floatval($initialReceivable) % 10 === 1) {
|
||||
// 마지막 자릿수를 제거 (정수로 처리)
|
||||
$initialReceivable = floor($initialReceivable / 10);
|
||||
}
|
||||
|
||||
// echo '거래처 $initnum' . $initnum . ' : ', $initialReceivable . ' <br> ' ;
|
||||
|
||||
// 수금 내역 가져오기
|
||||
$paymentSql = "SELECT SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) as total_payment
|
||||
FROM $DB.account_juil
|
||||
WHERE secondordnum = '$initnum'
|
||||
AND registDate BETWEEN date('$fromdate') AND date('$Transtodate')
|
||||
AND (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND content = '거래처 수금'
|
||||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||||
|
||||
$paymentStmt = $pdo->prepare($paymentSql);
|
||||
$paymentStmt->execute();
|
||||
$paymentData = $paymentStmt->fetch(PDO::FETCH_ASSOC);
|
||||
$total_payment = isset($paymentData['total_payment']) ? (int)str_replace(',', '', $paymentData['total_payment']) : 0;
|
||||
|
||||
$total_sales = isset($salesResults[$initnum]) ? $salesResults[$initnum] : 0;
|
||||
// print $total_sales;
|
||||
// 조건: 이월잔액이 있거나 매출이 있는 경우만 표시
|
||||
// 검색어가 있는 경우 검색어 있는 것만 나오게 함
|
||||
// echo 'searchsecondordnum : ' . $searchsecondordnum;
|
||||
|
||||
if ( ($initialReceivable != 0 or $total_sales != 0) and intval($initnum) > 1 ) {
|
||||
|
||||
$sql = "SELECT * FROM $DB.$tablenamephonebook
|
||||
WHERE secondordnum = '$initnum'
|
||||
AND (is_deleted IS NULL OR is_deleted = 0 or is_deleted ='' )
|
||||
AND represent='대표코드'";
|
||||
|
||||
$total_amount = round($total_sales,2);
|
||||
|
||||
// 잔액 계산
|
||||
$balance_due = $initialReceivable + $total_amount - $total_payment;
|
||||
$memo = '';
|
||||
// if($balance_due>0 && $initialReceivable>0 )
|
||||
|
||||
// (주)한빛에스티는 25일 마감 예외처리해야함.
|
||||
// if($vendor_name === '㈜ 한빛에스티')
|
||||
// $vendor_name = '㈜ 한빛에스티(월마감25일)';
|
||||
|
||||
// 마지막 단위 원단위 중 1은 제거하는 로직
|
||||
// 당월매출 마지막 1원 삭제
|
||||
// 마지막 자리가 1로 끝나는 경우, 0으로 변경
|
||||
// print_r($total_payment);
|
||||
// $totalSalesAmount -= 5;
|
||||
if (round($total_amount,2) % 10 === 1) {
|
||||
$total_amount -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
|
||||
if ($balance_due % 10 === 1) {
|
||||
$balance_due -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
// print_r($balance_due);
|
||||
|
||||
if (intval($balance_due) !== 0 || $total_sales > 0 ) {
|
||||
?>
|
||||
<tr onclick="redirectToView('<?= $initnum ?>')">
|
||||
<td class="text-center"><?= $start_num ?></td>
|
||||
<td class="text-start text-primary"><?= $vendorNames[$initnum] ?></td>
|
||||
<td class="text-end text-primary fw-bold"><?= number_format($initialReceivable) ?></td>
|
||||
<td class="text-end text-secondary fw-bold"><?= number_format($total_amount) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($total_payment) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($balance_due) ?></td>
|
||||
<td class="text-end text-primary fw-bold">
|
||||
<?php if (!empty($paydate)) : ?>
|
||||
<?= htmlspecialchars($paydate) ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-end"><?= $memo ?></td>
|
||||
<?php if($user_id == 'pro')
|
||||
echo '<td class="text-center w50px"> ' . $initnum . ' </td>';
|
||||
?>
|
||||
<td style="display:none;"><?= $initnum ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$start_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot class="table-secondary">
|
||||
<tr>
|
||||
<th class="text-end w80px" colspan="2"> 합계 </th>
|
||||
<th class="text-end"><?= number_format($totalInitialReceivable) ?></th>
|
||||
<th class="text-end"><?= number_format($totalSalesAmount) ?></th>
|
||||
<th class="text-end"><?= number_format($totalPaymentAmount) ?></th>
|
||||
<th class="text-end"><?= number_format($totalBalanceDue) ?></th>
|
||||
<th class="text-end"> </th>
|
||||
<th class="text-end w150px"> </th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
} catch (PDOException $Exception) {
|
||||
print "오류: ".$Exception->getMessage();
|
||||
}
|
||||
?>
|
||||
<!-- 페이지로딩 -->
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
loader.style.display = 'none';
|
||||
});
|
||||
|
||||
function submitForm() {
|
||||
$('#board_form').submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var dataTable; // DataTables 인스턴스 전역 변수
|
||||
var bookpageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
|
||||
|
||||
$(document).ready(function() {
|
||||
// DataTables 초기 설정
|
||||
dataTable = $('#myTable').DataTable({
|
||||
"paging": true,
|
||||
"ordering": true,
|
||||
"searching": true,
|
||||
"pageLength": 100,
|
||||
"lengthMenu": [100, 200, 500, 1000],
|
||||
"language": {
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"search": "Live Search:"
|
||||
},
|
||||
// "order": [[8, 'desc']], // 잔액기준 내림차순 정렬
|
||||
"dom": 't<"bottom"ip>', // search 창과 lengthMenu 숨기기
|
||||
"footerCallback": function ( row, data, start, end, display ) {
|
||||
var api = this.api(), data;
|
||||
|
||||
// 합계를 계산하는 함수
|
||||
var intVal = function (i) {
|
||||
return typeof i === 'string' ?
|
||||
i.replace(/[\$,]/g, '')*1 :
|
||||
typeof i === 'number' ?
|
||||
i : 0;
|
||||
};
|
||||
|
||||
// 합계 계산
|
||||
totalInitialReceivable = api.column(2).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalSalesAmount = api.column(3).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalPaymentAmount = api.column(4).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalBalanceDue = api.column(5).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
|
||||
// 합계 출력
|
||||
$(api.column(2).footer()).html(numberWithCommas(totalInitialReceivable));
|
||||
$(api.column(3).footer()).html(numberWithCommas(totalSalesAmount));
|
||||
$(api.column(4).footer()).html(numberWithCommas(totalPaymentAmount));
|
||||
$(api.column(5).footer()).html(numberWithCommas(totalBalanceDue));
|
||||
}
|
||||
});
|
||||
|
||||
// 페이지 번호 복원 (초기 로드 시)
|
||||
var savedPageNumber = getCookie('bookpageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
|
||||
// 페이지 변경 이벤트 리스너
|
||||
dataTable.on('page.dt', function() {
|
||||
var bookpageNumber = dataTable.page.info().page + 1;
|
||||
setCookie('bookpageNumber', bookpageNumber, 10); // 쿠키에 페이지 번호 저장
|
||||
});
|
||||
|
||||
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
|
||||
$('#myTable_length select').on('change', function() {
|
||||
var selectedValue = $(this).val();
|
||||
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
|
||||
|
||||
// 변경 후 현재 페이지 번호 복원
|
||||
savedPageNumber = getCookie('bookpageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
});
|
||||
|
||||
var total = '<?php echo $start_num; ?>';
|
||||
$("#total").text(Number(total)-1);
|
||||
|
||||
});
|
||||
|
||||
function redirectToView(num) {
|
||||
var fromdate = document.getElementById('fromdate').value;
|
||||
var todate = document.getElementById('todate').value;
|
||||
var url = "../account_juil/S_transaction_sheet.php?num=" + num + "&fromdate=" + fromdate + "&todate=" + todate;
|
||||
customPopup(url, '거래원장', 1000, 850);
|
||||
}
|
||||
|
||||
function numberWithCommas(x) {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
}
|
||||
|
||||
function saveBalance() {
|
||||
// 테이블 데이터를 수집
|
||||
let data = [];
|
||||
let closure_date = $('#todate').val();
|
||||
let year = closure_date.split('-')[0];
|
||||
let month = closure_date.split('-')[1];
|
||||
let dayOfMonth = parseInt(closure_date.split('-')[2]);
|
||||
|
||||
// 해당 월의 마지막 날 계산
|
||||
let lastDayOfMonth = new Date(year, month, 0).getDate();
|
||||
|
||||
// 날짜가 말일 또는 25일이 아닌 경우 경고 메시지 출력
|
||||
if (dayOfMonth !== lastDayOfMonth && dayOfMonth !== 25) {
|
||||
alert('해당일자로 이월 마감할 수 없습니다.');
|
||||
return; // 함수 종료
|
||||
}
|
||||
|
||||
$('#myTable tbody tr').each(function() {
|
||||
let row = $(this);
|
||||
let balance = parseFloat(row.find('td:nth-child(6)').text().replace(/,/g, ''));
|
||||
let secondordnum = row.find('td:nth-child(9)').text().trim();
|
||||
|
||||
// 매월 말일인 경우
|
||||
if (dayOfMonth === lastDayOfMonth) {
|
||||
// '66'이 아닌 데이터만 처리
|
||||
if (secondordnum !== '66' && balance !== 0) {
|
||||
data.push({
|
||||
mode: row.attr('data-mode') || 'insert', // insert or update mode
|
||||
num: row.attr('data-num'),
|
||||
secondordnum: secondordnum,
|
||||
customer_name: row.find('td:nth-child(2)').text().trim(),
|
||||
balance: balance,
|
||||
closure_date: closure_date,
|
||||
memo: row.find('td:nth-child(8)').text().trim()
|
||||
});
|
||||
}
|
||||
}
|
||||
// 25일인 경우
|
||||
else if (dayOfMonth === 25) {
|
||||
// '66' 데이터만 처리
|
||||
if (secondordnum === '66' && balance !== 0) {
|
||||
data.push({
|
||||
mode: row.attr('data-mode') || 'insert', // insert or update mode
|
||||
num: row.attr('data-num'),
|
||||
secondordnum: secondordnum,
|
||||
customer_name: row.find('td:nth-child(2)').text().trim(),
|
||||
balance: balance,
|
||||
closure_date: closure_date,
|
||||
memo: row.find('td:nth-child(8)').text().trim()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Ajax로 데이터 전송
|
||||
if (data.length > 0) {
|
||||
$.ajax({
|
||||
url: 'insert_monthly_balance.php',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function(response) {
|
||||
let result = JSON.parse(response);
|
||||
if (result.status === 'success') {
|
||||
alert('이월금액이 성공적으로 저장되었습니다.');
|
||||
} else {
|
||||
alert('오류 발생: ' + result.message);
|
||||
}
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
alert('오류 발생: ' + error);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
alert('저장할 데이터가 없습니다.');
|
||||
}
|
||||
}
|
||||
|
||||
function detail() {
|
||||
// 년도, 시작 월, 종료 월 값을 가져옴
|
||||
const year = document.getElementById('year').value;
|
||||
const startMonth = document.getElementById('startMonth').value;
|
||||
const endMonth = document.getElementById('endMonth').value;
|
||||
|
||||
// detail.php로 이동할 URL 생성
|
||||
const url = `detail.php?year=${year}&startMonth=${startMonth}&endMonth=${endMonth}`;
|
||||
|
||||
// customPopup을 사용하여 detail.php를 팝업으로 열기
|
||||
customPopup(url, '상세 내역', 900, 700);
|
||||
}
|
||||
|
||||
|
||||
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['secondord'] = cells[1]?.innerText || '';
|
||||
rowData['lastbalance'] = cells[2]?.innerText || '';
|
||||
rowData['monthsales'] = cells[3]?.innerText || '';
|
||||
rowData['income'] = cells[4]?.innerText || '';
|
||||
rowData['balances'] = cells[5]?.innerText || '';
|
||||
rowData['payday'] = cells[6]?.innerText || '';
|
||||
rowData['memo'] = cells[7]?.innerText || '';
|
||||
rowData['secondordnum'] = cells[8]?.innerText || '';
|
||||
|
||||
data.push(rowData);
|
||||
}
|
||||
|
||||
// saveExcel.php에 데이터 전송
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "customer_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 = 'downloadExcel.php?filename=' + encodeURIComponent(response.filename.split('/').pop());
|
||||
} 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));
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
saveLogData('경동기업 악성채권');
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
47
account_juil/cardlist.json
Normal file
47
account_juil/cardlist.json
Normal file
@@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"company": "국민카드",
|
||||
"number": "5585-2697-8607-8835",
|
||||
"user": "윤희재"
|
||||
},
|
||||
{
|
||||
"company": "국민카드",
|
||||
"number": "5585-2694-1183-1830",
|
||||
"user": "유민수"
|
||||
},
|
||||
{
|
||||
"company": "국민카드",
|
||||
"number": "5585-2694-6309-9823",
|
||||
"user": "계도건"
|
||||
},
|
||||
{
|
||||
"company": "국민카드",
|
||||
"number": "5585-2694-3595-6811",
|
||||
"user": "신승표"
|
||||
},
|
||||
{
|
||||
"company": "신한카드",
|
||||
"number": "9410-6441-0601-4244",
|
||||
"user": "사무실"
|
||||
},
|
||||
{
|
||||
"company": "신한카드",
|
||||
"number": "4902-9841-1316-7973",
|
||||
"user": "김영민"
|
||||
},
|
||||
{
|
||||
"company": "신한카드",
|
||||
"number": "3779-8508-1047-026",
|
||||
"user": "쿠팡"
|
||||
},
|
||||
{
|
||||
"company": "국민카드",
|
||||
"number": "5585-2694-1183-1830",
|
||||
"user": "이성제"
|
||||
},
|
||||
{
|
||||
"company": "국민카드",
|
||||
"number": "5585-2694-6309-9823",
|
||||
"user": "이성제"
|
||||
}
|
||||
]
|
||||
170
account_juil/cardlist.php
Normal file
170
account_juil/cardlist.php
Normal file
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
// cardlist.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;
|
||||
}
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
$title_message = '법인카드 관리';
|
||||
?>
|
||||
<title><?= $title_message ?></title>
|
||||
<?php if($chkMobile==true) { ?>
|
||||
<style>
|
||||
@media (max-width: 1000px) {
|
||||
body { font-size: 25px; }
|
||||
.form-control, .fw-bold, .table td, .table th { font-size: 25px; }
|
||||
button { font-size: 30px; }
|
||||
.modal-body, .modal-title { font-size: 30px; }
|
||||
}
|
||||
</style>
|
||||
<?php } ?>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?php
|
||||
// 메뉴를 표현할지 판단하는 header
|
||||
$header = $_REQUEST['header'] ?? '';
|
||||
|
||||
if($user_id === '0266771300' ) {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader_accountant1.php'); // 경리
|
||||
} else {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php');
|
||||
}
|
||||
|
||||
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . '/account_juil/cardlist.json';
|
||||
$cards = [];
|
||||
|
||||
if (file_exists($jsonFile)) {
|
||||
$jsonContent = file_get_contents($jsonFile);
|
||||
$cards = json_decode($jsonContent, true);
|
||||
if (!is_array($cards)) {
|
||||
$cards = [];
|
||||
}
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$action = $_POST['action'] ?? '';
|
||||
$index = isset($_POST['index']) ? intval($_POST['index']) : -1;
|
||||
$company = trim($_POST['company'] ?? '');
|
||||
$number = trim($_POST['number'] ?? '');
|
||||
$user = trim($_POST['user'] ?? '');
|
||||
|
||||
if ($action === 'insert' && $company !== '' && $number !== '') {
|
||||
$cards[] = [
|
||||
"company" => $company,
|
||||
"number" => $number,
|
||||
"user" => $user
|
||||
];
|
||||
} elseif ($action === 'update' && $index >= 0 && $index < count($cards)) {
|
||||
$cards[$index]["company"] = $company;
|
||||
$cards[$index]["number"] = $number;
|
||||
$cards[$index]["user"] = $user;
|
||||
} elseif ($action === 'delete' && $index >= 0 && $index < count($cards)) {
|
||||
array_splice($cards, $index, 1);
|
||||
}
|
||||
|
||||
file_put_contents($jsonFile, json_encode($cards, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="container mt-3">
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-center align-items-center text-center">
|
||||
<h3 class="mb-0"><?= $title_message ?></h3> <br>
|
||||
<small class="ms-5 text-muted">카드회사, 카드번호, 사용자 정보를 넣고 등록 버튼을 누르시면 등록됩니다.</small>
|
||||
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form id="addCardForm" method="post" action="cardlist.php" class="row g-3 mb-3">
|
||||
<input type="hidden" name="action" id="action" value="insert">
|
||||
<input type="hidden" name="index" id="index" value="-1">
|
||||
<div class="d-flex justify-content-center align-items-center text-center">
|
||||
<input type="text" name="company" id="company" class="form-control mx-1" placeholder="카드 회사" autocomplete="off" style="width:150px;">
|
||||
<input type="text" name="number" id="number" class="form-control mx-1" placeholder="카드 번호" autocomplete="off" style="width:200px;">
|
||||
<input type="text" name="user" id="user" class="form-control mx-1" placeholder="사용자" autocomplete="off" style="width:120px;">
|
||||
<button type="submit" class="btn btn-primary btn-sm mx-1" id="submitBtn">등록</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover text-center">
|
||||
<thead class="table-secondary">
|
||||
<tr>
|
||||
<th>순번</th>
|
||||
<th>카드 회사</th>
|
||||
<th>카드 번호</th>
|
||||
<th>사용자</th>
|
||||
<th>수정/삭제</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (!empty($cards)): ?>
|
||||
<?php foreach ($cards as $i => $card): ?>
|
||||
<tr>
|
||||
<td><?= $i + 1 ?></td>
|
||||
<td><?= htmlspecialchars($card["company"], ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><?= htmlspecialchars($card["number"], ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td><?= htmlspecialchars($card["user"], ENT_QUOTES, 'UTF-8') ?></td>
|
||||
<td>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary editBtn" data-index="<?= $i ?>">수정</button>
|
||||
<button type="button" class="btn btn-sm btn-outline-danger deleteBtn" data-index="<?= $i ?>">삭제</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php else: ?>
|
||||
<tr><td colspan="5">등록된 카드가 없습니다.</td></tr>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
// 로딩 오버레이 제거
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
if(loader) loader.style.display = 'none';
|
||||
|
||||
$('.editBtn').on('click', function(){
|
||||
var row = $(this).closest('tr');
|
||||
var index = $(this).data('index');
|
||||
var company = row.find('td:eq(1)').text().trim();
|
||||
var number = row.find('td:eq(2)').text().trim();
|
||||
var user = row.find('td:eq(3)').text().trim();
|
||||
$('#company').val(company);
|
||||
$('#number').val(number);
|
||||
$('#user').val(user);
|
||||
$('#index').val(index);
|
||||
$('#action').val('update');
|
||||
$('#submitBtn').text('수정');
|
||||
});
|
||||
|
||||
$('.deleteBtn').on('click', function(){
|
||||
var index = $(this).data('index');
|
||||
Swal.fire({
|
||||
title: '카드 삭제',
|
||||
text: "정말 삭제하시겠습니까?",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonColor: '#3085d6',
|
||||
cancelButtonColor: '#d33',
|
||||
confirmButtonText: '삭제',
|
||||
cancelButtonText: '취소'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
$('#index').val(index);
|
||||
$('#action').val('delete');
|
||||
$('#addCardForm').submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php include $_SERVER['DOCUMENT_ROOT'] . '/common/modal.php'; ?>
|
||||
</body>
|
||||
</html>
|
||||
135
account_juil/css/style.css
Normal file
135
account_juil/css/style.css
Normal file
@@ -0,0 +1,135 @@
|
||||
#openModalBtn {
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden; /* Changed from 'auto' to 'hidden' to prevent closing on outside click */
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
background-color: #fefefe;
|
||||
margin: auto;
|
||||
border-radius: 10px;
|
||||
width: 95%;
|
||||
max-width: 1200px;
|
||||
animation: fadeIn 0.5s;
|
||||
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
background-color: #1f48d4;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border-top-left-radius: 10px;
|
||||
border-top-right-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.close {
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.close:hover,
|
||||
.close:focus {
|
||||
color: #bbb;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.custom-card {
|
||||
background-color: #f9f9f9;
|
||||
padding: 15px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
|
||||
.tooltip-inner {
|
||||
background-color: black !important; /* 배경색 */
|
||||
color: white !important; /* 글자색 */
|
||||
}
|
||||
.tooltip-arrow {
|
||||
color: black !important; /* 화살표 색상 */
|
||||
}
|
||||
|
||||
/* 입력창에 대한 설계 */
|
||||
.ui-autocomplete {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.specialinputWrap {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.specialbtnClear {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.specialbtnClear:before {
|
||||
content: 'X';
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.specialbtnClear:hover {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.btnClear_lot {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: transparent;
|
||||
border: none;
|
||||
color: black;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btnClear_lot:before {
|
||||
content: 'X';
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.btnClear_lot:hover {
|
||||
color: black;
|
||||
}
|
||||
124
account_juil/customer_saveExcel.php
Normal file
124
account_juil/customer_saveExcel.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
// 에러 표시 설정
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
header('Content-Type: application/json'); // JSON 응답 설정
|
||||
|
||||
$response = ['success' => false, 'message' => 'Unknown error'];
|
||||
|
||||
try {
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
|
||||
// 요청에서 JSON 데이터 가져오기
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
// JSON 오류 확인
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
throw new Exception('Invalid JSON input: ' . json_last_error_msg());
|
||||
}
|
||||
|
||||
// 데이터가 비어있는지 확인
|
||||
if (empty($data)) {
|
||||
throw new Exception('No data received');
|
||||
}
|
||||
|
||||
// PHPExcel 라이브러리 포함
|
||||
require '../PHPExcel_1.8.0/Classes/PHPExcel.php';
|
||||
|
||||
// 새로운 PHPExcel 객체 생성
|
||||
$objPHPExcel = new PHPExcel();
|
||||
$objPHPExcel->setActiveSheetIndex(0);
|
||||
$sheet = $objPHPExcel->getActiveSheet();
|
||||
|
||||
// 헤더 설정
|
||||
|
||||
$headers = [
|
||||
'number' => '번호',
|
||||
'secondord' => '거래처명',
|
||||
'lastbalance' => '이월잔액',
|
||||
'monthsales' => '당월매출',
|
||||
'income' => '수금합계',
|
||||
'balances' => '잔액',
|
||||
'payday' => '결제일',
|
||||
'memo' => '적요',
|
||||
'secondordnum' => '거래처코드'
|
||||
];
|
||||
|
||||
// 헤더를 엑셀에 추가
|
||||
$col = 'A';
|
||||
foreach ($headers as $header) {
|
||||
$sheet->setCellValue($col . '1', $header);
|
||||
// 셀의 글씨를 굵게 하고 음영을 추가
|
||||
$sheet->getStyle($col . '1')->getFont()->setBold(true);
|
||||
$sheet->getStyle($col . '1')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
|
||||
$sheet->getStyle($col . '1')->getFill()->getStartColor()->setRGB('D9D9D9');
|
||||
$col++;
|
||||
}
|
||||
|
||||
// 데이터 채우기
|
||||
$rowNumber = 2;
|
||||
foreach ($data as $row) {
|
||||
$col = 'A';
|
||||
foreach ($headers as $key => $header) {
|
||||
$value = isset($row[$key]) ? $row[$key] : ''; // 데이터가 있으면 채우고 없으면 공백
|
||||
$sheet->setCellValue($col . $rowNumber, $value);
|
||||
$col++;
|
||||
}
|
||||
$rowNumber++;
|
||||
}
|
||||
|
||||
// 특정 열의 기본 폭 설정
|
||||
$sheet->getColumnDimension('B')->setWidth(40);
|
||||
|
||||
// 나머지 열의 폭을 글씨에 맞추기
|
||||
foreach (range('A', 'I') as $columnID) {
|
||||
if (!in_array($columnID, ['B'])) {
|
||||
$sheet->getColumnDimension($columnID)->setWidth(25);
|
||||
}
|
||||
}
|
||||
|
||||
// 테두리 설정
|
||||
$styleArray = [
|
||||
'borders' => [
|
||||
'allborders' => [
|
||||
'style' => PHPExcel_Style_Border::BORDER_THIN,
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$sheet->getStyle('A1:I' . ($rowNumber - 1))->applyFromArray($styleArray);
|
||||
|
||||
// 열별 정렬 설정
|
||||
$sheet->getStyle('E2:E' . ($rowNumber - 1))
|
||||
->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
|
||||
$sheet->getStyle('F2:F' . ($rowNumber - 1))
|
||||
->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
|
||||
$sheet->getStyle('G2:G' . ($rowNumber - 1))
|
||||
->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);
|
||||
$sheet->getStyle('H2:H' . ($rowNumber - 1))
|
||||
->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);
|
||||
|
||||
// 파일 저장
|
||||
$filename = 'DH모터(거래처원장)_' . date('YmdHis') . '.xlsx';
|
||||
$filePath = '../excelsave/' . $filename; // 파일 경로 확인 필요
|
||||
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
|
||||
$objWriter->save($filePath);
|
||||
|
||||
// 파일이 생성되었는지 확인
|
||||
if (file_exists($filePath)) {
|
||||
$response = ['success' => true, 'filename' => $filePath];
|
||||
} else {
|
||||
throw new Exception('Failed to save the Excel file');
|
||||
}
|
||||
} else {
|
||||
throw new Exception('Invalid request method');
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
error_log($e->getMessage()); // 오류 로그 기록
|
||||
$response = ['success' => false, 'message' => $e->getMessage()];
|
||||
}
|
||||
|
||||
// JSON 응답 반환
|
||||
echo json_encode($response);
|
||||
?>
|
||||
195
account_juil/detail.php
Normal file
195
account_juil/detail.php
Normal file
@@ -0,0 +1,195 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
$title_message = '상세 내역 조회';
|
||||
?>
|
||||
|
||||
<link href="css/style.css" rel="stylesheet">
|
||||
<title> <?=$title_message?> </title>
|
||||
<style>
|
||||
/* 테이블에 테두리 추가 */
|
||||
#detailTable, #detailTable th, #detailTable td {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* 테이블 셀 패딩 조정 */
|
||||
#detailTable th, #detailTable td {
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?php
|
||||
|
||||
$year = isset($_REQUEST['year']) ? $_REQUEST['year'] : date('Y');
|
||||
$startMonth = isset($_REQUEST['startMonth']) ? $_REQUEST['startMonth'] : 1;
|
||||
$endMonth = isset($_REQUEST['endMonth']) ? $_REQUEST['endMonth'] : date('m');
|
||||
|
||||
$startDate = "$year-$startMonth-01";
|
||||
$endDate = date("Y-m-t", strtotime("$year-$endMonth-01"));
|
||||
|
||||
$tablename = 'account_juil';
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
// 수입 내역 조회
|
||||
$incomeSql = "
|
||||
SELECT content, SUM(amount) as totalAmount
|
||||
FROM $tablename
|
||||
WHERE inoutsep = '수입'
|
||||
AND registDate BETWEEN :startDate AND :endDate
|
||||
AND is_deleted = '0'
|
||||
GROUP BY content
|
||||
";
|
||||
$incomeStmt = $pdo->prepare($incomeSql);
|
||||
$incomeStmt->bindParam(':startDate', $startDate);
|
||||
$incomeStmt->bindParam(':endDate', $endDate);
|
||||
$incomeStmt->execute();
|
||||
$incomeData = $incomeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 지출 내역 조회
|
||||
$expenseSql = "
|
||||
SELECT content, SUM(amount) as totalAmount
|
||||
FROM $tablename
|
||||
WHERE inoutsep = '지출'
|
||||
AND registDate BETWEEN :startDate AND :endDate
|
||||
AND is_deleted = '0'
|
||||
GROUP BY content
|
||||
";
|
||||
$expenseStmt = $pdo->prepare($expenseSql);
|
||||
$expenseStmt->bindParam(':startDate', $startDate);
|
||||
$expenseStmt->bindParam(':endDate', $endDate);
|
||||
$expenseStmt->execute();
|
||||
$expenseData = $expenseStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 월수익 계산
|
||||
$totalIncome = array_sum(array_column($incomeData, 'totalAmount'));
|
||||
$totalExpense = array_sum(array_column($expenseData, 'totalAmount'));
|
||||
$netIncome = $totalIncome - $totalExpense;
|
||||
|
||||
?>
|
||||
|
||||
<div class="container mt-5">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5 class="text-center"><?=$title_message?></h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row mb-3">
|
||||
<div class="d-flex justify-content-center align-items-center">
|
||||
<select id="year" name="year" class="form-select w-auto me-2" onchange="loadDetails()">
|
||||
<?php for ($i = date('Y'); $i >= 2024; $i--): ?>
|
||||
<option value="<?=$i?>" <?=($year == $i) ? 'selected' : ''?>><?=$i?>년</option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
|
||||
<select id="startMonth" name="startMonth" class="form-select w-auto me-1" onchange="loadDetails()">
|
||||
<?php for ($i = 1; $i <= 12; $i++): ?>
|
||||
<option value="<?=$i?>" <?=($startMonth == $i) ? 'selected' : ''?>><?=$i?>월</option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
~
|
||||
<select id="endMonth" name="endMonth" class="form-select w-auto me-5 " onchange="loadDetails()">
|
||||
<?php for ($i = 1; $i <= 12; $i++): ?>
|
||||
<option value="<?=$i?>" <?=($endMonth == $i) ? 'selected' : ''?>><?=$i?>월</option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="d-flex justify-content-center">
|
||||
<?php for ($i = 1; $i <= 12; $i++): ?>
|
||||
<button class="btn btn-outline-primary btn-sm me-1" onclick="loadSpecificMonth('<?=$i?>')">
|
||||
<?=$i?>월
|
||||
</button>
|
||||
<?php endfor; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-hover" id="detailTable">
|
||||
<thead class="table-info">
|
||||
<tr>
|
||||
<th colspan="2" class="text-center">수입</th>
|
||||
<th colspan="2" class="text-center">지출</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-center">항목</th>
|
||||
<th class="text-center">금액</th>
|
||||
<th class="text-center">항목</th>
|
||||
<th class="text-center">금액</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$maxRows = max(count($incomeData), count($expenseData));
|
||||
for ($i = 0; $i < $maxRows; $i++):
|
||||
$incomeContent = isset($incomeData[$i]) ? $incomeData[$i]['content'] : '';
|
||||
$incomeAmount = isset($incomeData[$i]) ? number_format($incomeData[$i]['totalAmount']) : '';
|
||||
|
||||
$expenseContent = isset($expenseData[$i]) ? $expenseData[$i]['content'] : '';
|
||||
$expenseAmount = isset($expenseData[$i]) ? number_format($expenseData[$i]['totalAmount']) : '';
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-center"><?=$incomeContent?></td>
|
||||
<td class="text-end text-primary"><?=$incomeAmount?></td>
|
||||
<td class="text-center"><?=$expenseContent?></td>
|
||||
<td class="text-end text-danger"><?=$expenseAmount?></td>
|
||||
</tr>
|
||||
<?php endfor; ?>
|
||||
</tbody>
|
||||
<tfoot class="table-secondary">
|
||||
<tr>
|
||||
<th class="text-end" > 수입 합계 </th>
|
||||
<th class="text-end text-primary"><?=number_format($totalIncome)?></th>
|
||||
<th class="text-end"> 지출 합계 </th>
|
||||
<th class="text-end text-danger"><?=number_format($totalExpense)?></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="text-end" colspan="3"> 월수익 </th>
|
||||
<th class="text-end"><?=number_format($netIncome)?></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
// 페이지 로딩
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
loader.style.display = 'none';
|
||||
});
|
||||
|
||||
// 기존 loadDetails 함수 유지
|
||||
function loadDetails() {
|
||||
const year = document.getElementById('year').value;
|
||||
const startMonth = document.getElementById('startMonth').value;
|
||||
const endMonth = document.getElementById('endMonth').value;
|
||||
|
||||
window.location.href = `detail.php?year=${year}&startMonth=${startMonth}&endMonth=${endMonth}`;
|
||||
}
|
||||
|
||||
// 새로운 함수 추가: 특정 월 선택 시 호출
|
||||
function loadSpecificMonth(month) {
|
||||
const year = document.getElementById('year').value;
|
||||
window.location.href = `detail.php?year=${year}&startMonth=${month}&endMonth=${month}`;
|
||||
}
|
||||
</script>
|
||||
25
account_juil/downloadExcel.php
Normal file
25
account_juil/downloadExcel.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
// 파일 이름이 제공되었는지 확인
|
||||
if (!isset($_GET['filename']) || empty($_GET['filename'])) {
|
||||
die('Filename not specified.');
|
||||
}
|
||||
|
||||
$filename = basename($_GET['filename']);
|
||||
$filePath = '../excelsave/' . $filename;
|
||||
|
||||
// 파일이 존재하는지 확인
|
||||
if (!file_exists($filePath)) {
|
||||
die('File not found.');
|
||||
}
|
||||
|
||||
// 파일을 다운로드하도록 설정
|
||||
header('Content-Description: File Transfer');
|
||||
header('Content-Type: application/octet-stream');
|
||||
header('Content-Disposition: attachment; filename=' . $filename);
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . filesize($filePath));
|
||||
readfile($filePath);
|
||||
exit;
|
||||
?>
|
||||
134
account_juil/fetch_balance.php
Normal file
134
account_juil/fetch_balance.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
// fetch_balance.php
|
||||
function fetch_balances($DB, $fromdate, $todate) {
|
||||
|
||||
return [];
|
||||
// require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
// $pdo = db_connect();
|
||||
|
||||
// // 현재 날짜
|
||||
// $currentDate = date("Y-m-d");
|
||||
|
||||
// // fromdate 또는 todate가 빈 문자열이거나 null인 경우 처리
|
||||
// if ($fromdate === "" || $fromdate === null || $todate === "" || $todate === null) {
|
||||
// $fromdate = date("Y-m-01");
|
||||
// $todate = $currentDate;
|
||||
// }
|
||||
|
||||
// $initialBalances = [];
|
||||
|
||||
// // 이월 잔액을 직접 계산하는 로직
|
||||
// $lastMonthEnd = date("Y-m-t", strtotime($fromdate . " -1 month"));
|
||||
|
||||
// // 미수금 내역 조회 (work + output_extra, outdate, ET_total)
|
||||
// $salesBeforeSql = "
|
||||
// SELECT o.secondordnum, SUM(COALESCE(e.ET_total, 0)) AS total_sales
|
||||
// FROM {$DB}.work o
|
||||
// LEFT JOIN {$DB}.output_extra e ON o.num = e.parent_num
|
||||
// WHERE o.outdate <= :lastMonthEnd AND (o.is_deleted IS NULL or o.is_deleted = 0)
|
||||
// GROUP BY o.secondordnum
|
||||
// ";
|
||||
// $paymentBeforeSql = "
|
||||
// SELECT secondordnum, SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
|
||||
// FROM {$DB}.account_juil
|
||||
// WHERE registDate <= :lastMonthEnd AND (is_deleted IS NULL or is_deleted = 0) AND content = '거래처 수금'
|
||||
// AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')
|
||||
// GROUP BY secondordnum
|
||||
// ";
|
||||
|
||||
// // 전월까지의 매출과 수금 데이터 가져오기
|
||||
// $salesBeforeStmt = $pdo->prepare($salesBeforeSql);
|
||||
// $salesBeforeStmt->execute([':lastMonthEnd' => $lastMonthEnd]);
|
||||
// $salesBeforeData = $salesBeforeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// $paymentBeforeStmt = $pdo->prepare($paymentBeforeSql);
|
||||
// $paymentBeforeStmt->execute([':lastMonthEnd' => $lastMonthEnd]);
|
||||
// $paymentBeforeData = $paymentBeforeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// // 이월 잔액 계산
|
||||
// foreach ($salesBeforeData as $row) {
|
||||
// $secondordnum = $row['secondordnum'];
|
||||
// $total_sales_before = round((float)$row['total_sales'],2); // 부가세 포함(이미 ET_total은 부가세 포함)
|
||||
|
||||
// if (!isset($initialBalances[$secondordnum])) {
|
||||
// $initialBalances[$secondordnum] = 0;
|
||||
// }
|
||||
|
||||
// $initialBalances[$secondordnum] += $total_sales_before;
|
||||
// }
|
||||
|
||||
// foreach ($paymentBeforeData as $row) {
|
||||
// $secondordnum = $row['secondordnum'];
|
||||
// $total_payment_before = (float)$row['total_payment'];
|
||||
|
||||
// if (!isset($initialBalances[$secondordnum])) {
|
||||
// $initialBalances[$secondordnum] = 0;
|
||||
// }
|
||||
|
||||
// $initialBalances[$secondordnum] -= $total_payment_before;
|
||||
// }
|
||||
|
||||
// // 당월 매출 내역 가져오기 (work + output_extra, outdate, ET_total)
|
||||
// $salesSql = "
|
||||
// SELECT o.secondordnum, COALESCE(e.ET_total, 0) AS ET_total
|
||||
// FROM {$DB}.work o
|
||||
// LEFT JOIN {$DB}.output_extra e ON o.num = e.parent_num
|
||||
// WHERE (o.outdate BETWEEN date('$fromdate') AND date('$todate')) AND (o.is_deleted IS NULL or o.is_deleted = 0)
|
||||
// ";
|
||||
|
||||
// $salesStmt = $pdo->prepare($salesSql);
|
||||
// $salesStmt->execute();
|
||||
// $salesData = $salesStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// $salesResults = [];
|
||||
// foreach ($salesData as $row) {
|
||||
// $secondordnum = $row['secondordnum'];
|
||||
// $total_sales = (float)$row['ET_total']; // ET_total은 부가세 포함
|
||||
|
||||
// if (!isset($salesResults[$secondordnum])) {
|
||||
// $salesResults[$secondordnum] = 0;
|
||||
// }
|
||||
// $salesResults[$secondordnum] += round($total_sales,2);
|
||||
// }
|
||||
|
||||
// // 당월 수금 내역 가져오기 (account_juil 테이블)
|
||||
// $paymentSql = "
|
||||
// SELECT secondordnum, SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
|
||||
// FROM {$DB}.account_juil
|
||||
// WHERE registDate BETWEEN date('$fromdate') AND date('$todate')
|
||||
// AND (is_deleted IS NULL or is_deleted = 0) AND content = '거래처 수금'
|
||||
// AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')
|
||||
// GROUP BY secondordnum
|
||||
// ";
|
||||
|
||||
// $paymentStmt = $pdo->prepare($paymentSql);
|
||||
// $paymentStmt->execute();
|
||||
// $paymentData = $paymentStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// $paymentResults = [];
|
||||
// foreach ($paymentData as $row) {
|
||||
// $secondordnum = $row['secondordnum'];
|
||||
// $total_payment = (float)$row['total_payment'];
|
||||
|
||||
// if (!isset($paymentResults[$secondordnum])) {
|
||||
// $paymentResults[$secondordnum] = 0;
|
||||
// }
|
||||
// $paymentResults[$secondordnum] += $total_payment;
|
||||
// }
|
||||
|
||||
// // 모든 거래처 목록을 생성 (매출, 기초채권)
|
||||
// $allResults = array_unique(array_merge(array_keys($salesResults), array_keys($initialBalances)));
|
||||
|
||||
// // 최종 잔액 계산
|
||||
// $balances = [];
|
||||
// foreach ($allResults as $secondordnum) {
|
||||
// $initialReceivable = isset($initialBalances[$secondordnum]) ? $initialBalances[$secondordnum] : 0;
|
||||
// $total_sales = isset($salesResults[$secondordnum]) ? $salesResults[$secondordnum] : 0; // 부가세 포함
|
||||
// $total_payment = isset($paymentResults[$secondordnum]) ? $paymentResults[$secondordnum] : 0;
|
||||
|
||||
// // 최종 잔액
|
||||
// $balances[$secondordnum] = $initialReceivable + $total_sales - $total_payment;
|
||||
// }
|
||||
// return $balances;
|
||||
}
|
||||
?>
|
||||
413
account_juil/fetch_modal.php
Normal file
413
account_juil/fetch_modal.php
Normal file
@@ -0,0 +1,413 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
$mode = isset($_POST['mode']) ? $_POST['mode'] : '';
|
||||
$num = isset($_POST['num']) ? $_POST['num'] : '';
|
||||
|
||||
$tablename = 'account_juil';
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
if ($mode === 'update' && $num) {
|
||||
try {
|
||||
$sql = "SELECT * FROM " . $tablename . " WHERE num=?";
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->bindValue(1, $num, PDO::PARAM_INT);
|
||||
$stmh->execute();
|
||||
$row = $stmh->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$content = $row['content']; // 저장된 content 값을 가져옴
|
||||
include '_row.php';
|
||||
// 콤마 제거 후 숫자로 변환
|
||||
$amount = floatval(str_replace(',', '', $row['amount']));
|
||||
} catch (PDOException $Exception) {
|
||||
echo "오류: " . $Exception->getMessage();
|
||||
exit;
|
||||
}
|
||||
} else if ($mode === 'copy' && $num) {
|
||||
try {
|
||||
$sql = "SELECT * FROM " . $tablename . " WHERE num=?";
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->bindValue(1, $num, PDO::PARAM_INT);
|
||||
$stmh->execute();
|
||||
$row = $stmh->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
$content = $row['content'];
|
||||
include '_row.php';
|
||||
$amount = floatval(str_replace(',', '', $row['amount']));
|
||||
$mode = 'insert'; // 복사 모드에서는 새로운 항목으로 등록
|
||||
$registDate = date('Y-m-d'); // 현재 날짜로 설정
|
||||
} catch (PDOException $Exception) {
|
||||
echo "오류: " . $Exception->getMessage();
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
include '_request.php';
|
||||
$mode = 'insert';
|
||||
$registDate = date('Y-m-d');
|
||||
$inoutsep = '지출';
|
||||
$amount = 0;
|
||||
$content = ''; // 기본값 설정
|
||||
}
|
||||
|
||||
$title_message = ($mode === 'update') ? '금전출납부 수정 #' . $num : '금전출납부 신규 등록' ;
|
||||
|
||||
// Bankbook options
|
||||
$bankbookOptions = [];
|
||||
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . "/account_juil/accoutlist.json";
|
||||
$accounts = [];
|
||||
$selectedAccount = null;
|
||||
|
||||
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];
|
||||
|
||||
// bankbookOptions 배열에 계좌 정보 추가
|
||||
foreach ($accounts as $account) {
|
||||
$displayText = $account['company'] . ' ' . $account['number'];
|
||||
if (!empty($account['memo'])) {
|
||||
$displayText .= ' (' . $account['memo'] . ')';
|
||||
}
|
||||
$bankbookOptions[] = $displayText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 전자어음은 별도로 처리하므로 JSON 배열에는 추가하지 않음
|
||||
|
||||
// 수입/지출 계정 정보 가져오기
|
||||
include 'fetch_options.php';
|
||||
|
||||
if($inoutsep == '수입')
|
||||
$options = $incomeOptions;
|
||||
elseif($inoutsep == '최초전월이월')
|
||||
$options = $incomeOptions;
|
||||
else
|
||||
$options = $expenseOptions;
|
||||
|
||||
// 선택된 항목의 세부항목 가져오기
|
||||
$selectedKey = $content ?? null; // URL의 'key' 매개변수로 전달
|
||||
$details = null;
|
||||
|
||||
if ($selectedKey) {
|
||||
// 수입에서 검색
|
||||
if (isset($jsonData['수입'][$selectedKey])) {
|
||||
$details = $jsonData['수입'][$selectedKey]['하위계정'];
|
||||
}
|
||||
// 지출에서 검색
|
||||
if (isset($jsonData['지출'][$selectedKey])) {
|
||||
$details = $jsonData['지출'][$selectedKey]['하위계정'];
|
||||
}
|
||||
}
|
||||
|
||||
// '개인대출'과 '주일기업' 등 키만 추출
|
||||
$Suboptions = [];
|
||||
if ($details) {
|
||||
foreach ($details as $detail) {
|
||||
foreach ($detail as $key => $value) {
|
||||
$Suboptions[] = $key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 항목의 세부항목 수정시 처리하는 구문
|
||||
if (isset($_POST['action']) && $_POST['action'] === 'getSubOptions') {
|
||||
$selectedKey = $_POST['selectedKey'] ?? null;
|
||||
|
||||
$subOptions = [];
|
||||
if ($selectedKey) {
|
||||
if (isset($incomeOptions[$selectedKey]) && isset($jsonData['수입'][$selectedKey]['하위계정'])) {
|
||||
$subOptions = $jsonData['수입'][$selectedKey]['하위계정'];
|
||||
} elseif (isset($expenseOptions[$selectedKey]) && isset($jsonData['지출'][$selectedKey]['하위계정'])) {
|
||||
$subOptions = $jsonData['지출'][$selectedKey]['하위계정'];
|
||||
} elseif (isset($incomeOptions[$selectedKey]) && isset($jsonData['최초전월이월'][$selectedKey]['하위계정'])) {
|
||||
$subOptions = $jsonData['최초전월이월'][$selectedKey]['하위계정'];
|
||||
}
|
||||
}
|
||||
|
||||
// $Suboptions 배열을 키를 기준으로 오름차순 정렬
|
||||
ksort($Suboptions);
|
||||
|
||||
echo json_encode(['subOptions' => $subOptions], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($Suboptions);
|
||||
// echo '</pre>';
|
||||
// echo '<pre>';
|
||||
// print_r($contentSub);
|
||||
// echo '</pre>';
|
||||
|
||||
//print_r($details[);
|
||||
// $options = array_merge($incomeOptions, $expenseOptions);
|
||||
|
||||
// $options 배열을 키를 기준으로 오름차순 정렬
|
||||
ksort($options);
|
||||
|
||||
// $Suboptions 배열을 키를 기준으로 오름차순 정렬
|
||||
ksort($Suboptions);
|
||||
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/load_GoogleDriveSecond.php'; // attached, image에 대한 정보 불러오기
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($savefilename_arr);
|
||||
// echo '</pre>';
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($$bankbookOptions );
|
||||
// echo '</pre>';
|
||||
?>
|
||||
|
||||
|
||||
<input type="hidden" id="update_log" name="update_log" value="<?=$update_log?>">
|
||||
<input type="hidden" id="first_writer" name="first_writer" value="<?=$first_writer?>">
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<div class="card justify-content-center w-100">
|
||||
<div class="card-header text-center">
|
||||
<span class="text-center fs-5"><?=$title_message?></span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-center text-center">
|
||||
<div class="d-flex align-items-center justify-content-center ">
|
||||
<table class="table table-bordered ">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-center fw-bold" style="width:13%">등록일자</td>
|
||||
<td class="text-center" colspan="3" style="width:37%">
|
||||
<input type="date" class="form-control noborder-input w110px" id="registDate" name="registDate" value="<?=$registDate?>">
|
||||
</td>
|
||||
<td class="text-center fw-bold" style="width:13%">구분</td>
|
||||
<td class="text-center" colspan="3" style="width:37%">
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<input type="radio" class="form-check-input mx-2" id="premonthly" name="inoutsep" value="최초전월이월" <?= $inoutsep === '최초전월이월' ? 'checked' : '' ?>>
|
||||
<label for="premonthly" class="form-check-label ">최초전월이월</label>
|
||||
|
||||
<input type="radio" class="form-check-input mx-2" id="income" name="inoutsep" value="수입" <?= $inoutsep === '수입' ? 'checked' : '' ?>>
|
||||
<label for="income" class="form-check-label ">수입</label>
|
||||
|
||||
<input type="radio" class="form-check-input mx-2" id="expense" name="inoutsep" value="지출" <?= $inoutsep === '지출' ? 'checked' : '' ?>>
|
||||
<label for="expense" class="form-check-label ">지출</label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center fw-bold">계좌</td>
|
||||
<td class="text-center" colspan="7">
|
||||
<div class="d-flex align-items-center align-items-center">
|
||||
<select class="form-select w-auto" style="font-size: 0.8rem;height: 32px;" id="bankbook" name="bankbook">
|
||||
<?php
|
||||
// _row.php에서 설정된 $bankbook 변수 사용
|
||||
$currentBankbook = isset($bankbook) ? $bankbook : '';
|
||||
|
||||
// JSON 계좌 옵션들 추가
|
||||
foreach ($bankbookOptions as $option):
|
||||
$isSelected = ($currentBankbook === $option);
|
||||
?>
|
||||
<option value="<?= htmlspecialchars($option) ?>" <?= $isSelected ? 'selected' : '' ?>><?= htmlspecialchars($option) ?></option>
|
||||
<?php endforeach; ?>
|
||||
|
||||
<!-- 전자어음 옵션 추가 (JSON에 없어도 항상 표시) -->
|
||||
<option value="전자어음" <?= $currentBankbook === '전자어음' ? 'selected' : '' ?>>전자어음</option>
|
||||
</select>
|
||||
<div id="endorsementDateContainer" class="ms-2" style="display: <?= $currentBankbook === '전자어음' ? 'inline-block' : 'none' ?>">
|
||||
<span class="form-label mx-5 fw-bold text-primary" style="font-size: 0.8rem; margin: 0;">배서일자</span>
|
||||
<input type="date" class="ms-5 form-control noborder-input" id="endorsementDate" name="endorsementDate" value="<?= $endorsementDate ?>" style="width: 110px; font-size: 0.8rem; height: 32px;">
|
||||
</div>
|
||||
<button type="button" id="selectElectronicBillBtn" class="btn btn-outline-primary btn-sm ms-2" style="display: <?= $currentBankbook === '전자어음' ? 'inline-block' : 'none' ?>">
|
||||
<i class="bi bi-search"></i> 전자어음 선택
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center fw-bold" >항목</td>
|
||||
<td class="text-center" colspan="3">
|
||||
<div class="row d-flex align-items-center justify-content-start">
|
||||
<select class="form-select w200px p-2" style="margin-left:15px; font-size: 0.8rem;height: 35px;" id="content" name="content">
|
||||
<?php foreach ($options as $key => $value): ?>
|
||||
<option value="<?= htmlspecialchars($key) ?>" <?= $content === $key ? 'selected' : '' ?>><?= htmlspecialchars($key) ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<span class="text-start" style="margin-left:15px; font-size: 0.8rem;" id="content_description">
|
||||
<?= $options[$content] ?? '' ?>
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center fw-bold" >세부항목</td>
|
||||
<td colspan="3" class="text-center">
|
||||
<select class="form-select w-auto" style="font-size: 0.8rem;height: 32px;" id="contentSub" name="contentSub">
|
||||
<?php foreach ($Suboptions as $value): // 키를 사용하지 않고 값만 사용 ?>
|
||||
<option value="<?= htmlspecialchars($value) ?>" <?= $contentSub === $value ? 'selected' : '' ?>>
|
||||
<?= htmlspecialchars($value) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</td>
|
||||
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center fw-bold">상세 내역</td>
|
||||
<td class="text-start" colspan="7">
|
||||
<input type="text" class="form-control text-start noborder-input" id="content_detail" name="content_detail" value="<?=$content_detail?>" autocomplete="off">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center fw-bold" >금액</td>
|
||||
<td class="text-center w200px">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control text-end fw-bold noborder-input "
|
||||
id="amount"
|
||||
name="amount"
|
||||
value="<?= (isset($amount) && $amount != 0) ? number_format($amount) : '' ?>"
|
||||
autocomplete="off"
|
||||
onkeyup="inputNumberFormat(this)"
|
||||
>
|
||||
</td>
|
||||
<td class="text-center text-end text-secondary w60px" >PNum</td>
|
||||
<td class="text-center w100px">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control text-end noborder-input "
|
||||
id="parentEBNum"
|
||||
name="parentEBNum"
|
||||
value="<?= (isset($parentEBNum)) ?$parentEBNum : '' ?>"
|
||||
autocomplete="off"
|
||||
>
|
||||
</td>
|
||||
<td class="text-center fw-bold" style="width:100px;">거래처코드</td>
|
||||
<td class="text-start">
|
||||
<input type="text" class="form-control text-start noborder-input w120px" id="secondordnum" name="secondordnum" value="<?= isset($secondordnum) ? $secondordnum : '' ?>" autocomplete="off" >
|
||||
</td>
|
||||
<td class="text-center fw-bold" style="width:100px;">만기일자</td>
|
||||
<td class="text-start">
|
||||
<input type="date" class="form-control text-start noborder-input w120px" id="dueDate" name="dueDate" value="<?= isset($dueDate) ? $dueDate : '' ?>" autocomplete="off" >
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
// 삽입 위치: form 하단, </div></div> 직전
|
||||
// try {
|
||||
// $imgSt = $pdo->prepare(
|
||||
// "SELECT picname
|
||||
// FROM picuploads
|
||||
// WHERE tablename = ?
|
||||
// AND parentnum = ?
|
||||
// AND item = 'image'"
|
||||
// );
|
||||
// $imgSt->execute([$tablename, $num]);
|
||||
// $files = $imgSt->fetchAll(PDO::FETCH_COLUMN);
|
||||
// if ($files) {
|
||||
// echo '<div class="mt-3"><strong>첨부 이미지</strong></div>';
|
||||
// echo '<div id="displayImage" class="d-flex flex-wrap gap-2">';
|
||||
// echo '</div>';
|
||||
// }
|
||||
// } catch (Exception $e) {
|
||||
// // 이미지 섹션 로드 실패 시 무시
|
||||
// }
|
||||
// // 삽입 위치: form 하단, </div></div> 직전
|
||||
try {
|
||||
$imgSt = $pdo->prepare(
|
||||
"SELECT picname
|
||||
FROM picuploads
|
||||
WHERE tablename = ?
|
||||
AND parentnum = ?
|
||||
AND item = 'image'"
|
||||
);
|
||||
$imgSt->execute([$tablename, $num]);
|
||||
$files = $imgSt->fetchAll(PDO::FETCH_COLUMN);
|
||||
if ($files) {
|
||||
echo '<div class="mt-3"><strong>첨부 이미지</strong></div>';
|
||||
echo '<div class="d-flex flex-wrap gap-2">';
|
||||
foreach ($files as $fileId) {
|
||||
$thumb = getThumbnail($fileId, $service)
|
||||
?: "https://drive.google.com/uc?id={$fileId}";
|
||||
$imageId = $fileId; // 고유한 이미지 ID 생성
|
||||
// $link ="https://drive.google.com/uc?id={$fileId}";
|
||||
$link ="https://drive.google.com/file/d/{$fileId}/view?usp=drivesdk";
|
||||
echo '<div>';
|
||||
echo " <a href=\"#\" onclick=\"openTmpImagePopup('{$link}', '{$imageId}'); return false;\">";
|
||||
echo " <img id=\"{$imageId}\" src=\"{$thumb}\" style=\"width:100px; height:auto;\" class=\"img-thumbnail\" />";
|
||||
echo ' </a>';
|
||||
echo '</div>';
|
||||
}
|
||||
echo '</div>';
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
// 이미지 섹션 로드 실패 시 무시
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<div class="d-flex justify-content-center">
|
||||
<button type="button" id="saveBtn" class="btn btn-dark btn-sm me-3">
|
||||
<i class="bi bi-floppy-fill"></i> 저장
|
||||
</button>
|
||||
<?php if($mode != 'insert') { ?>
|
||||
<button type="button" id="copyBtn" class="btn btn-primary btn-sm me-3">
|
||||
<i class="bi bi-files"></i> 복사
|
||||
</button>
|
||||
<button type="button" id="deleteBtn" class="btn btn-danger btn-sm me-3">
|
||||
<i class="bi bi-trash"></i> 삭제
|
||||
</button>
|
||||
<?php } ?>
|
||||
<button type="button" id="closeBtn" class="btn btn-outline-dark btn-sm me-2">
|
||||
× 닫기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 전자어음 선택 모달 -->
|
||||
<div id="electronicBillModal" class="modal fade" tabindex="-1" aria-labelledby="electronicBillModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-fullscreen">
|
||||
<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" id="electronicBillTable">
|
||||
<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>
|
||||
36
account_juil/fetch_options.php
Normal file
36
account_juil/fetch_options.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
// JSON 파일 경로
|
||||
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . '/account_juil/accountContents.json';
|
||||
|
||||
// JSON 파일 읽기
|
||||
if (file_exists($jsonFile)) {
|
||||
$jsonData = json_decode(file_get_contents($jsonFile), true);
|
||||
|
||||
// 수입 옵션 생성
|
||||
$incomeOptions = [];
|
||||
if (isset($jsonData['수입'])) {
|
||||
foreach ($jsonData['수입'] as $key => $value) {
|
||||
$incomeOptions[$key] = $value['description'];
|
||||
}
|
||||
}
|
||||
|
||||
// 지출 옵션 생성
|
||||
$expenseOptions = [];
|
||||
if (isset($jsonData['지출'])) {
|
||||
foreach ($jsonData['지출'] as $key => $value) {
|
||||
$expenseOptions[$key] = $value['description'];
|
||||
}
|
||||
}
|
||||
|
||||
// 결과 출력
|
||||
// echo json_encode([
|
||||
// 'incomeOptions' => $incomeOptions,
|
||||
// 'expenseOptions' => $expenseOptions,
|
||||
// 'selectedDetails' => $details
|
||||
// ], JSON_UNESCAPED_UNICODE);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'error' => 'JSON 파일을 찾을 수 없습니다.'
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
?>
|
||||
174
account_juil/fetch_todoMonthly.php
Normal file
174
account_juil/fetch_todoMonthly.php
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
|
||||
$mode = isset($_POST['mode']) ? $_POST['mode'] : '';
|
||||
$num = isset($_POST['num']) ? $_POST['num'] : '';
|
||||
|
||||
$tablename = 'todos_monthly';
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
try {
|
||||
if ($mode === 'modify' && $num) {
|
||||
$sql = "SELECT * FROM " . $tablename . " WHERE num=?";
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->bindValue(1, $num, PDO::PARAM_INT);
|
||||
$stmh->execute();
|
||||
$row = $stmh->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if ($row) {
|
||||
$title = isset($row['title']) ? $row['title'] : '';
|
||||
$registdate = isset($row['registdate']) ? $row['registdate'] : '';
|
||||
$itemsep = isset($row['itemsep']) ? $row['itemsep'] : '';
|
||||
$specialday = isset($row['specialday']) ? $row['specialday'] : '';
|
||||
$yearlyspecialday = isset($row['yearlyspecialday']) ? $row['yearlyspecialday'] : '';
|
||||
|
||||
// Determine which period type to show based on saved data
|
||||
$isYearly = !empty($yearlyspecialday); // 매년 값이 있는지 판단
|
||||
if ($isYearly) {
|
||||
// Split yearlyspecialday if available
|
||||
list($month, $day) = explode('/', $yearlyspecialday);
|
||||
} else {
|
||||
$month = 1;
|
||||
$day = 1;
|
||||
}
|
||||
|
||||
$first_writer = isset($row['first_writer']) ? $row['first_writer'] : '';
|
||||
$update_log = isset($row['update_log']) ? $row['update_log'] : '';
|
||||
$searchtag = isset($row['searchtag']) ? $row['searchtag'] : '';
|
||||
} else {
|
||||
echo "Record not found.";
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
$title = '';
|
||||
$registdate = date('Y-m-d');
|
||||
$itemsep = '';
|
||||
$specialday = '';
|
||||
$month = 1; // Default month for yearlyspecialday
|
||||
$day = 1; // Default day for yearlyspecialday
|
||||
$first_writer = $user_name;
|
||||
$update_log = '';
|
||||
$searchtag = '';
|
||||
$isYearly = false; // Default to monthly if no data
|
||||
}
|
||||
} catch (PDOException $Exception) {
|
||||
echo "오류: " . $Exception->getMessage();
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
|
||||
<input type="hidden" id="update_log" name="update_log" value="<?= isset($update_log) ? $update_log : '' ?>">
|
||||
<input type="hidden" id="num" name="num" value="<?= isset($num) ? $num : '' ?>">
|
||||
<input type="hidden" id="searchtag" name="searchtag" value="<?= isset($searchtag) ? $searchtag : '' ?>">
|
||||
<input type="hidden" id="user_name" name="user_name" value="<?= isset($user_name) ? $user_name : '' ?>">
|
||||
<input type="hidden" id="first_writer" name="first_writer" value="<?= isset($first_writer) ? $first_writer : '' ?>">
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<div class="card justify-content-center">
|
||||
<div class="card-header text-center">
|
||||
<span class="text-center fs-5"><?= $mode === 'update' ? '회계 월별 할일 수정' : '회계 월별 할일 신규 등록' ?></span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row justify-content-center text-center">
|
||||
<div class="d-flex align-items-center justify-content-center m-2">
|
||||
<table class="table table-bordered">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="text-center fs-6 fw-bold" style="width:150px;">등록일자</td>
|
||||
<td class="text-center" style="width:200px;">
|
||||
<input type="date" class="form-control fs-6" id="registdate" name="registdate" style="width:130px;" value="<?= htmlspecialchars($registdate) ?>">
|
||||
</td>
|
||||
<td class="text-center fs-6 fw-bold" style="width:150px;">작성자</td>
|
||||
<td class="text-center" colspan="1">
|
||||
<input type="text" class="form-control fs-6" id="first_writer" name="first_writer" value="<?= htmlspecialchars($first_writer) ?>" readonly>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="text-center fs-6 fw-bold" style="width:150px;">주기</td>
|
||||
<td class="text-center" colspan="3">
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<input type="radio" id="yearly" name="period" value="yearly" style="transform: scale(1.5);" <?= $isYearly ? 'checked' : '' ?> onchange="toggleDateFields()"> <span class="fs-6 ms-2 me-2">매년</span>
|
||||
<input type="radio" id="monthly" name="period" value="monthly" style="transform: scale(1.5);" <?= !$isYearly ? 'checked' : '' ?> onchange="toggleDateFields()"> <span class="fs-6 ms-2 me-2">매월</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="monthlyRow" style="<?= !$isYearly ? '' : 'display:none;' ?>">
|
||||
<td class="text-center fs-6 fw-bold" style="width:150px;">매월</td>
|
||||
<td class="text-center" colspan="3">
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<select class="form-control fs-6" style="width:60px;" id="specialday" name="specialday">
|
||||
<?php for ($day = 1; $day <= 31; $day++): ?>
|
||||
<option value="<?= $day ?>" <?= $specialday == $day ? 'selected' : '' ?>>
|
||||
<?= $day ?>
|
||||
</option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
<span class="fs-6">일</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="yearlyRow" style="<?= $isYearly ? '' : 'display:none;' ?>">
|
||||
<td class="text-center fs-6 fw-bold" style="width:150px;">매년</td>
|
||||
<td class="text-center" colspan="3">
|
||||
<div class="d-flex align-items-center justify-content-center">
|
||||
<select class="form-control fs-6" style="width:60px;" id="month" name="month">
|
||||
<?php for ($m = 1; $m <= 12; $m++): ?>
|
||||
<option value="<?= $m ?>" <?= $m == $month ? 'selected' : '' ?>><?= $m ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
<span class="fs-6">월</span>
|
||||
<select class="form-control fs-6 ms-2" style="width:60px;" id="day" name="day">
|
||||
<?php for ($d = 1; $d <= 31; $d++): ?>
|
||||
<option value="<?= $d ?>" <?= $d == $day ? 'selected' : '' ?>><?= $d ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
<span class="fs-6">일</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td class="text-center fs-6 fw-bold" style="width:150px;">내용</td>
|
||||
<td class="text-center" colspan="3" >
|
||||
<input type="text" class="form-control fs-6" id="title" name="title" value="<?= htmlspecialchars($title) ?>" autocomplete="off">
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-center">
|
||||
<button type="button" id="saveBtn_month" class="btn btn-dark btn-sm me-3">
|
||||
<i class="bi bi-floppy-fill"></i> 저장
|
||||
</button>
|
||||
<?php if ($mode === 'modify') { ?>
|
||||
<button type="button" id="deleteBtn_month" class="btn btn-danger btn-sm me-3">
|
||||
<i class="bi bi-trash"></i> 삭제
|
||||
</button>
|
||||
<?php } ?>
|
||||
<button type="button" id="closeBtn_month" class="btn btn-outline-dark btn-sm me-2">
|
||||
× 닫기
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleDateFields() {
|
||||
const yearlyRow = document.getElementById('yearlyRow');
|
||||
const monthlyRow = document.getElementById('monthlyRow');
|
||||
const yearlyRadio = document.getElementById('yearly').checked;
|
||||
|
||||
if (yearlyRadio) {
|
||||
yearlyRow.style.display = '';
|
||||
monthlyRow.style.display = 'none';
|
||||
} else {
|
||||
yearlyRow.style.display = 'none';
|
||||
monthlyRow.style.display = '';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
34
account_juil/get_electronic_bills.php
Normal file
34
account_juil/get_electronic_bills.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/load_GoogleDrive.php';
|
||||
|
||||
if (!isset($_SESSION["level"]) || $_SESSION["level"] > 5) {
|
||||
header("Content-Type: application/json");
|
||||
echo json_encode(['error' => '권한이 없습니다.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
try {
|
||||
// 배서일자가 없는 전자어음 데이터 조회
|
||||
$sql = "SELECT num, registDate, content, contentSub, content_detail, amount, dueDate
|
||||
FROM account_juil
|
||||
WHERE bankbook = '전자어음'
|
||||
AND (endorsementDate IS NULL OR endorsementDate = '' OR endorsementDate = '0000-00-00')
|
||||
AND (parentEBNum IS NULL OR parentEBNum = '' )
|
||||
AND (is_deleted = 0 OR is_deleted IS NULL)
|
||||
ORDER BY registDate DESC, num DESC";
|
||||
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->execute();
|
||||
$results = $stmh->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode(['success' => true, 'data' => $results], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
echo json_encode(['error' => '데이터 조회 중 오류가 발생했습니다: ' . $e->getMessage()], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
?>
|
||||
112
account_juil/insert.php
Normal file
112
account_juil/insert.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
$tablename = isset($_REQUEST['tablename']) ? $_REQUEST['tablename'] : 'account_juil';
|
||||
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : '';
|
||||
|
||||
header("Content-Type: application/json"); // Use JSON content type
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
include "_request.php";
|
||||
|
||||
// Construct the searchtag value
|
||||
$searchtag = $registDate . ' ' . $inoutsep . ' ' . $content . ' ' . $contentSub . ' ' . $amount . $content_detail ;
|
||||
|
||||
if ($mode == "update") {
|
||||
$update_log = date("Y-m-d H:i:s") . " - " . $_SESSION["name"] . " " . $update_log . "
";
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
// Prepare the SQL query for updating the account_juil information
|
||||
$sql = "UPDATE " . $tablename . " SET ";
|
||||
$sql .= "registDate = ?, inoutsep = ?, content = ?, content_detail = ?, amount = ?, dueDate = ?, searchtag = ?, update_log = ?, first_writer = ?, bankbook = ?, secondordnum = ?, contentSub=?, endorsementDate=?, parentEBNum=? ";
|
||||
$sql .= "WHERE num = ? LIMIT 1"; // Update only one record matching the 'num'
|
||||
|
||||
$stmh = $pdo->prepare($sql);
|
||||
|
||||
// Bind the variables to the prepared statement as parameters
|
||||
$stmh->bindValue(1, $registDate, PDO::PARAM_STR);
|
||||
$stmh->bindValue(2, $inoutsep, PDO::PARAM_STR);
|
||||
$stmh->bindValue(3, $content, PDO::PARAM_STR);
|
||||
$stmh->bindValue(4, $content_detail, PDO::PARAM_STR);
|
||||
$stmh->bindValue(5, str_replace(',', '', $amount), PDO::PARAM_STR); // 숫자안에 콤마제거후 저장
|
||||
$stmh->bindValue(6, $dueDate, PDO::PARAM_STR);
|
||||
$stmh->bindValue(7, $searchtag, PDO::PARAM_STR);
|
||||
$stmh->bindValue(8, $update_log, PDO::PARAM_STR);
|
||||
$stmh->bindValue(9, $first_writer, PDO::PARAM_STR);
|
||||
$stmh->bindValue(10, $bankbook, PDO::PARAM_STR);
|
||||
$stmh->bindValue(11, $secondordnum, PDO::PARAM_STR);
|
||||
$stmh->bindValue(12, $contentSub, PDO::PARAM_STR);
|
||||
$stmh->bindValue(13, $endorsementDate, PDO::PARAM_STR);
|
||||
$stmh->bindValue(14, $parentEBNum, PDO::PARAM_STR);
|
||||
$stmh->bindValue(15, $num, PDO::PARAM_INT);
|
||||
|
||||
// Execute the statement
|
||||
$stmh->execute();
|
||||
$pdo->commit();
|
||||
} catch (PDOException $Exception) {
|
||||
$pdo->rollBack();
|
||||
print "오류: " . $Exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == "insert" || $mode == '' || $mode == null) {
|
||||
$first_writer = date("Y-m-d H:i:s") . " - " . $_SESSION["name"] ;
|
||||
$update_log = date("Y-m-d H:i:s") . " - " . $_SESSION["name"] . " " . $update_log . "
";
|
||||
// Data insertion
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
|
||||
// Updated columns and values to be inserted
|
||||
$sql = "INSERT INTO " . $tablename . " (";
|
||||
$sql .= "registDate, inoutsep, content, content_detail, amount, dueDate, searchtag, update_log, first_writer, bankbook, secondordnum, contentSub, endorsementDate, parentEBNum ";
|
||||
$sql .= ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
$stmh = $pdo->prepare($sql);
|
||||
|
||||
$stmh->bindValue(1, $registDate, PDO::PARAM_STR);
|
||||
$stmh->bindValue(2, $inoutsep, PDO::PARAM_STR);
|
||||
$stmh->bindValue(3, $content, PDO::PARAM_STR);
|
||||
$stmh->bindValue(4, $content_detail, PDO::PARAM_STR);
|
||||
$stmh->bindValue(5, str_replace(',', '', $amount), PDO::PARAM_STR);
|
||||
$stmh->bindValue(6, $dueDate, PDO::PARAM_STR);
|
||||
$stmh->bindValue(7, $searchtag, PDO::PARAM_STR);
|
||||
$stmh->bindValue(8, $update_log, PDO::PARAM_STR);
|
||||
$stmh->bindValue(9, $first_writer, PDO::PARAM_STR);
|
||||
$stmh->bindValue(10, $bankbook, PDO::PARAM_STR);
|
||||
$stmh->bindValue(11, $secondordnum, PDO::PARAM_STR);
|
||||
$stmh->bindValue(12, $contentSub, PDO::PARAM_STR);
|
||||
$stmh->bindValue(13, $endorsementDate, PDO::PARAM_STR);
|
||||
$stmh->bindValue(14, $parentEBNum, PDO::PARAM_STR);
|
||||
|
||||
// Execute the statement
|
||||
$stmh->execute();
|
||||
$pdo->commit();
|
||||
} catch (PDOException $Exception) {
|
||||
$pdo->rollBack();
|
||||
print "오류: " . $Exception->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if ($mode == "delete") { // Data deletion
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
$sql = "UPDATE " . $tablename . " SET is_deleted=1 WHERE num = ?";
|
||||
$stmh = $pdo->prepare($sql);
|
||||
$stmh->bindValue(1, $num, PDO::PARAM_INT);
|
||||
$stmh->execute();
|
||||
$pdo->commit();
|
||||
} catch (PDOException $ex) {
|
||||
$pdo->rollBack();
|
||||
print "오류: " . $ex->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'num' => $num,
|
||||
'mode' => $mode
|
||||
];
|
||||
|
||||
echo json_encode($data, JSON_UNESCAPED_UNICODE);
|
||||
|
||||
?>
|
||||
75
account_juil/insert_bulk.php
Normal file
75
account_juil/insert_bulk.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
// insert_bulk.php
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/session.php';
|
||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/lib/mydb.php';
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
$pdo = db_connect();
|
||||
|
||||
// 1) 클라이언트에서 JSON 문자열로 넘어온 entries
|
||||
$payload = $_POST['entries'] ?? '';
|
||||
$entries = json_decode($payload, true);
|
||||
|
||||
if (!is_array($entries) || count($entries) === 0) {
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'message' => '저장할 데이터가 없습니다.'
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
exit;
|
||||
}
|
||||
|
||||
$nums = [];
|
||||
|
||||
try {
|
||||
$pdo->beginTransaction();
|
||||
|
||||
// 2) account_juil 테이블에 대량 INSERT
|
||||
$sql = "INSERT INTO account_juil (
|
||||
registDate,
|
||||
inoutsep,
|
||||
bankbook,
|
||||
content,
|
||||
contentSub,
|
||||
content_detail,
|
||||
amount,
|
||||
secondordnum,
|
||||
dueDate,
|
||||
endorsementDate
|
||||
) VALUES (
|
||||
?,?,?,?,?,?,?,?,?,?
|
||||
)";
|
||||
$stmt = $pdo->prepare($sql);
|
||||
|
||||
foreach ($entries as $row) {
|
||||
$stmt->execute([
|
||||
$row['registDate'], // 등록일자
|
||||
$row['inoutsep'], // 구분
|
||||
$row['bankbook'], // 계좌
|
||||
$row['content'], // 항목
|
||||
$row['contentSub'], // 세부항목
|
||||
$row['content_detail'], // 상세내용
|
||||
$row['amount'], // 금액 (콤마 제거된 숫자)
|
||||
$row['secondordnum'], // 거래처코드
|
||||
$row['dueDate'], // 만기일자
|
||||
$row['endorsementDate'], // 배서일자
|
||||
]);
|
||||
// 3) 새로 생성된 AUTO_INCREMENT PK (num) 수집
|
||||
$nums[] = $pdo->lastInsertId();
|
||||
}
|
||||
|
||||
$pdo->commit();
|
||||
|
||||
// 4) 성공 응답: nums 배열을 돌며 클라이언트가 이미지 업로드에 사용할 수 있음
|
||||
echo json_encode([
|
||||
'status' => 'success',
|
||||
'nums' => $nums
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
|
||||
} catch (PDOException $e) {
|
||||
$pdo->rollBack();
|
||||
echo json_encode([
|
||||
'status' => 'error',
|
||||
'message' => $e->getMessage()
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
1
account_juil/json/20250704_094103_backup.json
Normal file
1
account_juil/json/20250704_094103_backup.json
Normal file
File diff suppressed because one or more lines are too long
1
account_juil/json/20250704_105151_backup.json
Normal file
1
account_juil/json/20250704_105151_backup.json
Normal file
File diff suppressed because one or more lines are too long
1
account_juil/json/20250711_102912_backup.json
Normal file
1
account_juil/json/20250711_102912_backup.json
Normal file
File diff suppressed because one or more lines are too long
1
account_juil/json/20250716_095850_backup.json
Normal file
1
account_juil/json/20250716_095850_backup.json
Normal file
File diff suppressed because one or more lines are too long
1
account_juil/json/20250723_095857_backup.json
Normal file
1
account_juil/json/20250723_095857_backup.json
Normal file
File diff suppressed because one or more lines are too long
1
account_juil/json/20250728_095916_backup.json
Normal file
1
account_juil/json/20250728_095916_backup.json
Normal file
File diff suppressed because one or more lines are too long
1
account_juil/json/20250801_102040_backup.json
Normal file
1
account_juil/json/20250801_102040_backup.json
Normal file
File diff suppressed because one or more lines are too long
1
account_juil/json/20250825_101743_backup.json
Normal file
1
account_juil/json/20250825_101743_backup.json
Normal file
File diff suppressed because one or more lines are too long
2216
account_juil/list.php
Normal file
2216
account_juil/list.php
Normal file
File diff suppressed because it is too large
Load Diff
476
account_juil/list_daily.php
Normal file
476
account_juil/list_daily.php
Normal file
@@ -0,0 +1,476 @@
|
||||
<?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;
|
||||
}
|
||||
// 에러 표시 설정
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
$title_message = '일일 일보';
|
||||
?>
|
||||
|
||||
<link href="css/style.css" rel="stylesheet">
|
||||
<title> <?=$title_message?> </title>
|
||||
<style>
|
||||
/* 테이블에 테두리 추가 */
|
||||
.detail-table th, .detail-table td {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
/* 테이블 셀 패딩 조정 */
|
||||
.detail-table th, .detail-table td {
|
||||
padding: 4px;
|
||||
text-align: center;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?php
|
||||
|
||||
if($user_id === '0266771300' ) {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader_accountant1.php'); // 경리
|
||||
} else {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php');
|
||||
}
|
||||
|
||||
$fromdate = isset($_REQUEST['fromdate']) ? $_REQUEST['fromdate'] : '';
|
||||
$todate = isset($_REQUEST['todate']) ? $_REQUEST['todate'] : '';
|
||||
|
||||
// 날짜 기본값 설정: 당월 1일 ~ 오늘
|
||||
if (empty($fromdate) || empty($todate)) {
|
||||
$fromdate = date("2025-06-01");
|
||||
$todate = date("Y-m-d");
|
||||
}
|
||||
|
||||
$tablename = 'account_juil';
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
// 1. 계좌 목록 로드
|
||||
$jsonFile = $_SERVER['DOCUMENT_ROOT'] . "/account_juil/accoutlist.json";
|
||||
$accounts = file_exists($jsonFile) ? json_decode(file_get_contents($jsonFile), true) : [];
|
||||
$accountNames = [];
|
||||
if (is_array($accounts)) {
|
||||
foreach ($accounts as $acc) {
|
||||
$accountNames[] = $acc['company'] . ' ' . $acc['number'] . ($acc['memo'] ? ' (' . $acc['memo'] . ')' : '');
|
||||
}
|
||||
}
|
||||
// '전자어음' 계좌를 항상 추가
|
||||
if (!in_array('전자어음', $accountNames)) {
|
||||
$accountNames[] = '전자어음';
|
||||
}
|
||||
|
||||
// $accountNames[] = '전자어음';
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($accountNames);
|
||||
// echo '</pre>';
|
||||
|
||||
// 2. 검색 시작일 이전의 계좌별 기초 잔액 계산 (전일이월의 기초값)
|
||||
$runningBalances = [];
|
||||
foreach ($accountNames as $bankbookName) {
|
||||
$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' OR is_deleted IS NULL) AND registDate < :fromdate AND bankbook = :bankbook ";
|
||||
|
||||
//AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')";
|
||||
$initialStmh = $pdo->prepare($initialBalanceSql);
|
||||
$initialStmh->execute([':fromdate' => $fromdate, ':bankbook' => $bankbookName]);
|
||||
$result = $initialStmh->fetch(PDO::FETCH_ASSOC);
|
||||
$runningBalances[$bankbookName] = $result['balance'] ?? 0;
|
||||
}
|
||||
|
||||
// 3. 기간 내 모든 현금성 거래내역 한번에 조회 후 날짜별로 그룹화
|
||||
$allTransactionsSql = "SELECT * FROM $tablename WHERE registDate BETWEEN :fromdate AND :todate AND (is_deleted = 0 OR is_deleted IS NULL)
|
||||
ORDER BY registDate ASC, num ASC";
|
||||
|
||||
// AND content != '외상매출채권(전자어음)'
|
||||
// AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')
|
||||
$allTransactionsStmh = $pdo->prepare($allTransactionsSql);
|
||||
$allTransactionsStmh->execute([':fromdate' => $fromdate, ':todate' => $todate]);
|
||||
$allTransactions = $allTransactionsStmh->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$dataByDate = [];
|
||||
foreach ($allTransactions as $tx) {
|
||||
$dataByDate[$tx['registDate']][] = $tx;
|
||||
}
|
||||
|
||||
// 4. 외상매출채권(전자어음) 잔액 계산 - 배서일자 기준으로 수입/지출 구분
|
||||
$notesReceivableSql = "SELECT
|
||||
SUBSTRING(
|
||||
content_detail,
|
||||
LOCATE('(', content_detail) + 1,
|
||||
LOCATE(')', content_detail) - LOCATE('(', content_detail) - 1
|
||||
) AS bill_no,
|
||||
MIN(content_detail) as content_detail,
|
||||
MIN(registDate) as issue_date,
|
||||
MIN(dueDate) as due_date,
|
||||
SUM(
|
||||
CASE
|
||||
WHEN (endorsementDate IS NULL OR endorsementDate = '0000-00-00' OR endorsementDate = '')
|
||||
THEN REPLACE(amount, ',', '')
|
||||
ELSE -REPLACE(amount, ',', '')
|
||||
END
|
||||
) as outstanding_balance
|
||||
FROM $tablename
|
||||
WHERE (dueDate != '0000-00-00' AND dueDate IS NOT NULL AND dueDate != '')
|
||||
AND (is_deleted IS NULL OR is_deleted = 0)
|
||||
AND bankbook = '전자어음'
|
||||
GROUP BY bill_no
|
||||
HAVING outstanding_balance > 0
|
||||
ORDER BY due_date ASC";
|
||||
$notesStmh = $pdo->query($notesReceivableSql);
|
||||
$notesReceivable = $notesStmh->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// // 디버그: 전자어음 수입/지출 상세 데이터 확인
|
||||
// $debugDetailSql = "SELECT
|
||||
// content_detail,
|
||||
// registDate,
|
||||
// dueDate,
|
||||
// endorsementDate,
|
||||
// amount,
|
||||
// inoutsep,
|
||||
// bankbook,
|
||||
// CASE
|
||||
// WHEN (endorsementDate IS NULL OR endorsementDate = '0000-00-00' OR endorsementDate = '') THEN '수입'
|
||||
// ELSE '지출'
|
||||
// END as calculated_type,
|
||||
// CASE
|
||||
// WHEN (endorsementDate IS NULL OR endorsementDate = '0000-00-00' OR endorsementDate = '') THEN REPLACE(amount, ',', '')
|
||||
// ELSE -REPLACE(amount, ',', '')
|
||||
// END as calculated_amount
|
||||
// FROM $tablename
|
||||
// WHERE bankbook = '전자어음'
|
||||
// AND (dueDate != '0000-00-00' AND dueDate IS NOT NULL AND dueDate != '')
|
||||
// AND (is_deleted IS NULL OR is_deleted = 0)
|
||||
// ORDER BY content_detail, registDate";
|
||||
|
||||
// $debugDetailStmh = $pdo->query($debugDetailSql);
|
||||
// $debugDetailData = $debugDetailStmh->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// echo '<div style="background: #f0f0f0; padding: 15px; margin: 10px; border: 1px solid #ccc;">';
|
||||
// echo '<h4>디버그: 전자어음 상세 데이터</h4>';
|
||||
// echo '<table border="1" style="border-collapse: collapse; width: 100%;">';
|
||||
// echo '<tr style="background: #e0e0e0;">';
|
||||
// echo '<th>내용</th><th>등록일</th><th>만기일</th><th>배서일자</th><th>금액</th><th>수입/지출</th><th>계산타입</th><th>계산금액</th>';
|
||||
// echo '</tr>';
|
||||
|
||||
// foreach($debugDetailData as $row) {
|
||||
// echo '<tr>';
|
||||
// echo '<td>' . htmlspecialchars($row['content_detail']) . '</td>';
|
||||
// echo '<td>' . $row['registDate'] . '</td>';
|
||||
// echo '<td>' . $row['dueDate'] . '</td>';
|
||||
// echo '<td>' . $row['endorsementDate'] . '</td>';
|
||||
// echo '<td>' . $row['amount'] . '</td>';
|
||||
// echo '<td>' . $row['inoutsep'] . '</td>';
|
||||
// echo '<td>' . $row['calculated_type'] . '</td>';
|
||||
// echo '<td>' . $row['calculated_amount'] . '</td>';
|
||||
// echo '</tr>';
|
||||
// }
|
||||
// echo '</table>';
|
||||
// echo '</div>';
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($notesReceivable);
|
||||
// echo '</pre>';
|
||||
|
||||
// 5. 날짜별로 모든 데이터 계산 후 배열에 저장 (메모리에서 처리)
|
||||
$reportData = [];
|
||||
$current = strtotime($fromdate);
|
||||
$end = strtotime($todate);
|
||||
while ($current <= $end) {
|
||||
$currentDateStr = date('Y-m-d', $current);
|
||||
$dailyTransactions = $dataByDate[$currentDateStr] ?? [];
|
||||
|
||||
// 거래가 있는 날만 리포트 데이터 생성
|
||||
if (!empty($dailyTransactions)) {
|
||||
$dailySummaries = [];
|
||||
foreach ($accountNames as $bankbookName) {
|
||||
$prevBalance = $runningBalances[$bankbookName];
|
||||
|
||||
$dailyIncome = 0;
|
||||
$dailyExpense = 0;
|
||||
foreach ($dailyTransactions as $tx) {
|
||||
if ($tx['bankbook'] === $bankbookName) {
|
||||
$amount = floatval(str_replace(',', '', $tx['amount']));
|
||||
if ($tx['inoutsep'] === '지출') {
|
||||
$dailyExpense += $amount;
|
||||
} else {
|
||||
$dailyIncome += $amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$endOfDayBalance = $prevBalance + $dailyIncome - $dailyExpense;
|
||||
|
||||
$dailySummaries[$bankbookName] = [
|
||||
'prev' => $prevBalance,
|
||||
'income' => $dailyIncome,
|
||||
'expense' => $dailyExpense,
|
||||
'balance' => $endOfDayBalance
|
||||
];
|
||||
}
|
||||
$reportData[$currentDateStr] = [
|
||||
'summaries' => $dailySummaries,
|
||||
'transactions' => $dailyTransactions
|
||||
];
|
||||
}
|
||||
|
||||
// 전일이월액 업데이트는 거래가 없는 날도 매일 수행해야 함
|
||||
foreach ($accountNames as $bankbookName) {
|
||||
$dailyIncome = 0; $dailyExpense = 0;
|
||||
$currentDayTx = $dataByDate[$currentDateStr] ?? [];
|
||||
foreach ($currentDayTx as $tx) {
|
||||
if ($tx['bankbook'] === $bankbookName) {
|
||||
$amount = floatval(str_replace(',', '', $tx['amount']));
|
||||
if ($tx['inoutsep'] === '지출') $dailyExpense += $amount; else $dailyIncome += $amount;
|
||||
}
|
||||
}
|
||||
$runningBalances[$bankbookName] += ($dailyIncome - $dailyExpense);
|
||||
}
|
||||
|
||||
$current = strtotime('+1 day', $current);
|
||||
}
|
||||
|
||||
// 날짜 역순으로 출력하기 위해 배열 뒤집기
|
||||
$reportData = array_reverse($reportData, true);
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($reportData);
|
||||
// echo '</pre>';
|
||||
|
||||
?>
|
||||
|
||||
<form id="board_form" name="board_form" method="post">
|
||||
<div class="container">
|
||||
<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">
|
||||
<input type="date" id="fromdate" name="fromdate" class="form-control" style="width:130px;" value="<?=$fromdate?>">
|
||||
<span class="mx-2">~</span>
|
||||
<input type="date" id="todate" name="todate" class="form-control" style="width:130px;" value="<?=$todate?>">
|
||||
<button class="btn btn-outline-dark btn-sm ms-2" type="submit"><i class="bi bi-search"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 justify-content-center">
|
||||
<h4 class="text-center alert alert-warning p-2" >어음 및 외상매출채권 현황</h4>
|
||||
<div class="d-flex justify-content-center mt-2">
|
||||
<table class="table table-hover table-bordered table-sm w-75">
|
||||
<thead class="table-warning">
|
||||
<tr>
|
||||
<th style="width:55%;">내용</th>
|
||||
<th style="width:15%;">현재잔액</th>
|
||||
<th style="width:15%;">최초발행일</th>
|
||||
<th style="width:15%;">만기일자</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$totalOutstandingBalance = 0; // 합계 변수 초기화
|
||||
if (empty($notesReceivable)): ?>
|
||||
<tr><td colspan="4">해당 내역이 없습니다.</td></tr>
|
||||
<?php else: ?>
|
||||
<?php foreach ($notesReceivable as $note):
|
||||
$totalOutstandingBalance += $note['outstanding_balance']; // 합계 계산
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-start"><?= htmlspecialchars($note['content_detail']) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($note['outstanding_balance']) ?></td>
|
||||
<td><?= htmlspecialchars($note['issue_date']) ?></td>
|
||||
<td class="text-danger fw-bold"><?= htmlspecialchars($note['due_date']) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
<tfoot class="table-warning">
|
||||
<tr class="fw-bold">
|
||||
<td class="text-center">합계</td>
|
||||
<td class="text-end text-primary"><?= number_format($totalOutstandingBalance) ?></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (empty($reportData)): ?>
|
||||
<div class="alert alert-warning text-center mt-4" role="alert">
|
||||
해당 기간에 거래 내역이 없습니다.
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<?php foreach ($reportData as $date => $dayData): ?>
|
||||
<div class="card mt-4 mb-4">
|
||||
<div class="card-body">
|
||||
<div class="row d-flex justify-content-center m-1 mb-2">
|
||||
<?php
|
||||
$formatter = new IntlDateFormatter('ko_KR', IntlDateFormatter::FULL, IntlDateFormatter::NONE, null, null, 'Y년 M월 d일 EEEE');
|
||||
$formattedDate = $formatter->format(strtotime($date));
|
||||
?>
|
||||
<div class="alert alert-primary fs-4 text-center">
|
||||
일자: <?=$formattedDate?> / 작성자 : 우지영
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive d-flex justify-content-center">
|
||||
<table class="table table-hover table-bordered table-sm w-75">
|
||||
<thead class="table-secondary">
|
||||
<tr>
|
||||
<th class="text-center" style="width:10%;">은행</th>
|
||||
<th class="text-center" style="width:10%;">별칭</th>
|
||||
<th class="text-center" style="width:20;">계좌번호</th>
|
||||
<th class="text-center" style="width:15%;">전일이월</th>
|
||||
<th class="text-center" style="width:15%;">수입</th>
|
||||
<th class="text-center" style="width:15%;">지출</th>
|
||||
<th class="text-center" style="width:15%;">잔액</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$grandTotal_prev = 0; $grandTotal_income = 0; $grandTotal_expense = 0; $grandTotal_balance = 0;
|
||||
foreach (array_filter($accountNames, function($name) { return $name !== '전자어음'; }) as $bankbookName):
|
||||
$summary = $dayData['summaries'][$bankbookName];
|
||||
$grandTotal_prev += $summary['prev'];
|
||||
$grandTotal_income += $summary['income'];
|
||||
$grandTotal_expense += $summary['expense'];
|
||||
$grandTotal_balance += $summary['balance'];
|
||||
$bankTitleName = preg_match('/(.+?)은행/', $bankbookName, $matches) ? $matches[0] : $bankbookName;
|
||||
$bankAliasName = preg_match('/은행\((.*?)\)/', $bankbookName, $matches) ? (!empty($matches[1]) ? $matches[1] : '') : preg_replace('/은행.*?(?=\s*$)/', '', $bankbookName);
|
||||
// $bankAliasName이 $bankTitleName에 포함되어 있으면 빈 문자열로 설정
|
||||
$bankAliasName = (strpos($bankTitleName, $bankAliasName) !== false) ? '' : $bankAliasName;
|
||||
$bankAccountNumber = preg_replace('/[^0-9-]/', '', $bankbookName);
|
||||
?>
|
||||
<tr>
|
||||
<td class="text-start"><?= htmlspecialchars($bankTitleName) ?></td>
|
||||
<td class="text-start"><?= htmlspecialchars($bankAliasName) ?></td>
|
||||
<td class="text-start"><?= htmlspecialchars($bankAccountNumber) ?></td>
|
||||
<td class="text-end"><?= number_format($summary['prev']) ?></td>
|
||||
<td class="text-end"><?= number_format($summary['income']) ?></td>
|
||||
<td class="text-end"><?= number_format($summary['expense']) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($summary['balance']) ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr class="table-group-divider">
|
||||
<td class="text-center fw-bold" colspan="3">현금성 자산 합계</td>
|
||||
<td class="text-end fw-bold"><?= number_format($grandTotal_prev) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($grandTotal_income) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($grandTotal_expense) ?></td>
|
||||
<td class="text-end fw-bold"><?= number_format($grandTotal_balance) ?></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<h4 class="text-center alert alert-success p-2"><예금 입출금 내역></h4>
|
||||
<?php
|
||||
$transactionsByAccount = [];
|
||||
foreach ($dayData['transactions'] as $row) {
|
||||
$isNormalAccount = true;
|
||||
$isElectronicBill = ($row['bankbook'] === '전자어음' || strpos($row['content'], '전자어음') !== false || strpos($row['content_detail'], '전자어음') !== false);
|
||||
// 기존 계좌별 분류 + 전자어음 관련 내역도 별도 그룹으로 분류
|
||||
if ($isElectronicBill) {
|
||||
$transactionsByAccount['전자어음'][] = $row;
|
||||
} else {
|
||||
$transactionsByAccount[$row['bankbook']][] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($transactionsByAccount as $bankbookName => $transactions):
|
||||
?>
|
||||
<h5 class="mt-3 text-primary-emphasis"><?= htmlspecialchars($bankbookName) ?></h5>
|
||||
<div class="table-responsive d-flex justify-content-center">
|
||||
<table class="table table-bordered detail-table w-75">
|
||||
<thead class="table-group-divider">
|
||||
<tr>
|
||||
<th style="width:35%;">입금내역</th>
|
||||
<th style="width:15%;">금액</th>
|
||||
<th style="width:35%;">출금내역</th>
|
||||
<th style="width:15%;">금액</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$incomeRows = array_filter($transactions, function($tx) { return $tx['inoutsep'] !== '지출'; });
|
||||
$expenseRows = array_filter($transactions, function($tx) { return $tx['inoutsep'] === '지출'; });
|
||||
$maxRows = max(count($incomeRows), count($expenseRows));
|
||||
$dailyIncomeTotal = 0; $dailyExpenseTotal = 0;
|
||||
$incomeRows = array_values($incomeRows); $expenseRows = array_values($expenseRows);
|
||||
|
||||
for ($i = 0; $i < $maxRows; $i++):
|
||||
?>
|
||||
<tr>
|
||||
<?php if (isset($incomeRows[$i])):
|
||||
$item = $incomeRows[$i];
|
||||
$amount = floatval(str_replace(',', '', $item['amount']));
|
||||
$dailyIncomeTotal += $amount;
|
||||
?>
|
||||
<td class="text-start"><?= htmlspecialchars($item['content_detail'] ? $item['content_detail'] : "") ?></td>
|
||||
<td class="text-end"><?= number_format($amount) ?></td>
|
||||
<?php else: ?>
|
||||
<td></td><td></td>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (isset($expenseRows[$i])):
|
||||
$item = $expenseRows[$i];
|
||||
$amount = floatval(str_replace(',', '', $item['amount']));
|
||||
$dailyExpenseTotal += $amount;
|
||||
?>
|
||||
<td class="text-start"><?= htmlspecialchars($item['content_detail'] ? $item['content_detail'] : "") ?></td>
|
||||
<td class="text-end"><?= number_format($amount) ?></td>
|
||||
<?php else: ?>
|
||||
<td></td><td></td>
|
||||
<?php endif; ?>
|
||||
</tr>
|
||||
<?php endfor; ?>
|
||||
</tbody>
|
||||
<tfoot class="table-group-divider">
|
||||
<tr class="fw-bold">
|
||||
<td>입금 합계</td>
|
||||
<td class="text-end text-primary"><?= number_format($dailyIncomeTotal) ?></td>
|
||||
<td>출금 합계</td>
|
||||
<td class="text-end text-danger"><?= number_format($dailyExpenseTotal) ?></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
if(loader) {
|
||||
loader.style.display = 'none';
|
||||
}
|
||||
|
||||
if (typeof saveLogData === 'function') {
|
||||
saveLogData('주일기업 일일 일보');
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
75
account_juil/modal.php
Normal file
75
account_juil/modal.php
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
<!-- 이월자료 Modal -->
|
||||
<div class="container-fluid justify-content-center align-items-center">
|
||||
<div id="monthlyBalanceModal" class="modal fade" tabindex="-1">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title">이월자료 수정</h2>
|
||||
<span class="close">×</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table table-hover">
|
||||
<thead class="table-info">
|
||||
<tr>
|
||||
<th class="text-center" style="width:20%;">기준일자</th>
|
||||
<th class="text-center" style="width:30%;">거래처명</th>
|
||||
<th class="text-center" style="width:20%;">이월잔액</th>
|
||||
<th class="text-center" style="width:30%;">적요</th>
|
||||
<th style="display:none;">고유번호</th>
|
||||
<th style="display:none;">secondordnum</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="monthlyBalanceModalBody">
|
||||
<!-- 데이터를 여기에 동적으로 추가 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark btn-sm" onclick="saveMonthlyBalanceData()"> <i class="bi bi-floppy2-fill"></i> 저장</button>
|
||||
<span class="badge bg-dark close">×</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 판매일괄회계반영 Modal -->
|
||||
<div class="container-fluid justify-content-center align-items-center">
|
||||
<div id="monthlysaleModal" class="modal fade" tabindex="-1">
|
||||
<div class="modal-dialog modal-xl" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2 class="modal-title"> 판매일괄회계반영(계산서발행) </h2>
|
||||
<span class="close">×</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table table-hover">
|
||||
<thead class="table-info">
|
||||
<tr>
|
||||
<th class="text-center" >기준일자</th>
|
||||
<th class="text-center" >거래처명</th>
|
||||
<th class="text-center" >당월 발생금액</th>
|
||||
<th class="text-center" style="width:140px;" >계산서 발행</th>
|
||||
<th class="text-center" >적요</th>
|
||||
<th class="text-center" style="width:80px;" >고유번호</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="monthlysaleModalBody">
|
||||
<!-- 데이터를 여기에 동적으로 추가 -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-dark btn-sm" onclick="saveMonthlyBalanceData()"> <i class="bi bi-floppy2-fill"></i> 저장</button>
|
||||
<button type="button" class="btn btn-danger btn-sm" onclick="saveMonthlyDelete()"> <i class="bi bi-trash3-fill"></i> 삭제 </button>
|
||||
<span class="badge bg-dark close">×</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
676
account_juil/month_sales.php
Normal file
676
account_juil/month_sales.php
Normal file
@@ -0,0 +1,676 @@
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
session_start();
|
||||
if (!isset($_SESSION["level"]) || $_SESSION["level"] > 5) {
|
||||
sleep(1);
|
||||
header("Location: /login/login_form.php");
|
||||
exit;
|
||||
}
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
// 첫 화면 표시 문구
|
||||
$title_message = '판매일괄회계반영';
|
||||
?>
|
||||
<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;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<?php require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader.php'); ?>
|
||||
<?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) {
|
||||
$fromdate = date("Y-m-01", strtotime($currentDate)); // 월의 첫날 설정
|
||||
$todate = date("Y-m-t", strtotime($currentDate)); // 현재 달의 마지막 날 설정
|
||||
} else {
|
||||
$fromdate = date("Y-m-01", strtotime($fromdate)); // 선택한 달의 첫날 설정
|
||||
$todate = date("Y-m-t", strtotime($todate)); // 선택한 달의 마지막 날 설정
|
||||
}
|
||||
|
||||
function checkNull($strtmp) {
|
||||
return $strtmp !== null && trim($strtmp) !== '';
|
||||
}
|
||||
|
||||
$tablename = 'phonebook';
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
// 매출이 발생한 거래처 필터링 및 매출액 계산
|
||||
$salesSql = "
|
||||
SELECT o.secondordnum, COALESCE(e.ET_total, 0) AS ET_total
|
||||
FROM output o
|
||||
LEFT JOIN output_extra e ON o.num = e.parent_num
|
||||
WHERE (o.outdate BETWEEN :fromdate AND :todate) AND o.is_deleted IS NULL
|
||||
";
|
||||
$salesStmt = $pdo->prepare($salesSql);
|
||||
$salesStmt->bindParam(':fromdate', $fromdate, PDO::PARAM_STR);
|
||||
$salesStmt->bindParam(':todate', $todate, PDO::PARAM_STR);
|
||||
$salesStmt->execute();
|
||||
$salesData = $salesStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$salesResults = [];
|
||||
foreach ($salesData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$et_total = (float)$row['ET_total'];
|
||||
if (!isset($salesResults[$secondordnum])) {
|
||||
$salesResults[$secondordnum] = 0;
|
||||
}
|
||||
$salesResults[$secondordnum] += round($et_total, 2);
|
||||
}
|
||||
|
||||
arsort($salesResults); // 공급가액 내림차순으로 정렬
|
||||
|
||||
// 전월 마지막 날짜 계산
|
||||
$lastMonthDate = date("Y-m-t", strtotime($fromdate . " -1 month"));
|
||||
|
||||
// 전월 잔액 조회
|
||||
$balanceSql = "
|
||||
SELECT secondordnum, balance, num, invoice_issued, memo
|
||||
FROM monthly_balances
|
||||
WHERE closure_date = :lastMonthDate
|
||||
";
|
||||
|
||||
$balanceStmt = $pdo->prepare($balanceSql);
|
||||
$balanceStmt->execute([':lastMonthDate' => $lastMonthDate]);
|
||||
$previousBalances = $balanceStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 전월 잔액을 저장할 배열
|
||||
$previousBalanceMap = [];
|
||||
foreach ($previousBalances as $balanceRow) {
|
||||
$previousBalanceMap[$balanceRow['secondordnum']] = [
|
||||
'balance' => $balanceRow['balance'],
|
||||
'invoice_issued' => $balanceRow['invoice_issued'],
|
||||
'memo' => $balanceRow['memo'],
|
||||
'num' => $balanceRow['num']
|
||||
];
|
||||
}
|
||||
|
||||
// 현재월 잔액 조회
|
||||
$current_saleSql = "
|
||||
SELECT secondordnum, sales, num, invoice_issued, memo
|
||||
FROM monthly_sales
|
||||
WHERE closure_date BETWEEN :fromdate AND :todate AND is_deleted IS NULL
|
||||
";
|
||||
|
||||
$balanceStmt = $pdo->prepare($current_saleSql);
|
||||
$balanceStmt->bindParam(':fromdate', $fromdate, PDO::PARAM_STR);
|
||||
$balanceStmt->bindParam(':todate', $todate, PDO::PARAM_STR);
|
||||
$balanceStmt->execute();
|
||||
$currentBalances = $balanceStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 이번달 잔액을 저장할 배열
|
||||
$currentBalanceMap = [];
|
||||
foreach ($currentBalances as $balanceRow) {
|
||||
$currentBalanceMap[$balanceRow['secondordnum']] = [
|
||||
'sales' => $balanceRow['sales'],
|
||||
'invoice_issued' => $balanceRow['invoice_issued'],
|
||||
'memo' => $balanceRow['memo'],
|
||||
'num' => $balanceRow['num']
|
||||
];
|
||||
}
|
||||
|
||||
// 수금 내역 가져오기
|
||||
$paymentSql = "SELECT secondordnum, SUM(CAST(REPLACE(payment, ',', '') AS UNSIGNED)) as total_payment
|
||||
FROM getmoney
|
||||
WHERE registedate BETWEEN :fromdate AND :todate AND is_deleted IS NULL
|
||||
GROUP BY secondordnum";
|
||||
$paymentStmt = $pdo->prepare($paymentSql);
|
||||
$paymentStmt->bindParam(':fromdate', $fromdate, PDO::PARAM_STR);
|
||||
$paymentStmt->bindParam(':todate', $todate, PDO::PARAM_STR);
|
||||
$paymentStmt->execute();
|
||||
$paymentData = $paymentStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// 수금 내역을 저장할 배열
|
||||
$paymentMap = [];
|
||||
foreach ($paymentData as $paymentRow) {
|
||||
$paymentMap[$paymentRow['secondordnum']] = (int)str_replace(',', '', $paymentRow['total_payment']);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
|
||||
|
||||
<input type="hidden" id="mode" name="mode" value="<?=$mode?>">
|
||||
<input type="hidden" id="num" name="num">
|
||||
<input type="hidden" id="tablename" name="tablename" value="<?=$tablename?>">
|
||||
<input type="hidden" id="header" name="header" value="<?=$header?>">
|
||||
<input type="hidden" id="secondordnum" name="secondordnum" value="<?=$secondordnum?>">
|
||||
|
||||
<!-- 모달창 가져오기 -->
|
||||
<?php include 'modal.php'; ?>
|
||||
|
||||
<div class="container">
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="text-center fs-5 me-4"><?=$title_message?></span>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick='location.href="month_sales.php"'>
|
||||
<i class="bi bi-arrow-clockwise"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="text-center fs-6 text-danger"> * 세금계산서 발행일은 매월 말일 기준으로 입력해 주세요! 현재날짜로 입력하면 화면에 안나올수 있습니다. </span>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
▷ <?= count($salesResults) ?>
|
||||
<!-- 기간부터 검색까지 연결 묶음 start -->
|
||||
<button type="button" class="btn btn-secondary btn-sm me-1 change_dateRange" onclick='prepre_month()'>전전월</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm me-1 change_dateRange" onclick='pre_month()'>전월</button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='this_month()'>당월</button>
|
||||
|
||||
<input type="date" id="fromdate" name="fromdate" class="form-control" style="width:100px;" value="<?=$fromdate?>"> ~
|
||||
<input type="date" id="todate" name="todate" class="form-control me-1" style="width:100px;" value="<?=$todate?>"> </span>
|
||||
|
||||
<div class="inputWrap">
|
||||
<input type="text" id="search" name="search" value="<?=$search?>" onkeydown="if(event.key === 'Enter') submitForm();" autocomplete="off" class="form-control" style="width:150px;">
|
||||
<button class="btnClear"></button>
|
||||
</div>
|
||||
|
||||
<div id="autocomplete-list">
|
||||
</div>
|
||||
|
||||
<button id="searchBtn" type="button" class="btn btn-outline-dark btn-sm me-2" onclick="submitForm()"><i class="bi bi-search"></i> 검색</button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-2" onclick="location.href='../getmoney/list.php?header=header'"><i class="bi bi-journal-x"></i> 수금 </button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick="location.href='../account_juil/S_transaction.php?header=header'"> <i class="bi bi-file-earmark-ruled"></i> 거래원장</button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick="openMonthlyBalancePopup()"> <i class="bi bi-file-earmark-ruled"></i> 이월잔액</button>
|
||||
<button type="button" class="btn btn-danger btn-sm me-2" onclick="location.href='../account_juil/receivable.php?header=header'"> <i class="bi bi-journal-x"></i> 미수금 </button>
|
||||
</div>
|
||||
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<table class="table table-hover" id="myTable">
|
||||
<thead class="table-info">
|
||||
<th class="text-center w50px">번호</th>
|
||||
<th class="text-center w200px">회사명</th>
|
||||
<th class="text-center w100px">공급가</th>
|
||||
<th class="text-center w100px">부가세</th>
|
||||
<th class="text-center w100px">당월금액</th>
|
||||
<th class="text-center w50px">상세</th>
|
||||
<th class="text-center w100px">발행금액</th>
|
||||
<th class="text-center w100px">세금계산서</th>
|
||||
<th class="text-center w200px">적요</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
try {
|
||||
$start_num = 1;
|
||||
$processedSecondOrdnums = []; // 처리된 secondordnum을 추적하는 배열
|
||||
foreach ($salesResults as $secondordnum => $total_sales) {
|
||||
if((int)$total_sales!==0 && intval($secondordnum) > 0 )
|
||||
{
|
||||
$processedSecondOrdnums[] = $secondordnum;
|
||||
|
||||
$sql = "SELECT * FROM ".$DB.".".$tablename."
|
||||
WHERE secondordnum = '$secondordnum'
|
||||
AND is_deleted IS NULL
|
||||
AND represent='대표코드'";
|
||||
if (checkNull($search)) {
|
||||
$sql .= " AND (vendor_name LIKE '%$search%' OR representative_name LIKE '%$search%' OR manager_name LIKE '%$search%')";
|
||||
}
|
||||
$stmh = $pdo->query($sql);
|
||||
while ($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/phonebook/_row.php';
|
||||
if (empty($contact_info))
|
||||
$contact_info = $phone;
|
||||
|
||||
if (intval($secondordnum) > 0)
|
||||
$savenum = $secondordnum;
|
||||
else
|
||||
$savenum = $num;
|
||||
}
|
||||
|
||||
// 수금 내역 가져오기
|
||||
$payment_collection = 0;
|
||||
if (isset($paymentMap[$secondordnum])) {
|
||||
$payment_collection = $paymentMap[$secondordnum];
|
||||
}
|
||||
|
||||
// 전월 잔액 조회
|
||||
$previous_balance = 0;
|
||||
$previous_balance_num = '';
|
||||
if (isset($previousBalanceMap[$secondordnum])) {
|
||||
$previous_balance = $previousBalanceMap[$secondordnum]['balance'];
|
||||
$previous_balance_num = $previousBalanceMap[$secondordnum]['num'];
|
||||
}
|
||||
|
||||
$vat = round(round($total_sales) * 0.1);
|
||||
$total_amount = $total_sales + $vat;
|
||||
$balance_due = $total_amount - $payment_collection;
|
||||
|
||||
// 현재달 잔액 조회
|
||||
$current_sale = 0;
|
||||
$current_sale_num = '';
|
||||
$invoice_issued = '';
|
||||
$memo = '';
|
||||
|
||||
// 기존데이터가 존재할때
|
||||
if (isset($currentBalanceMap[$secondordnum])) {
|
||||
$current_sales = $currentBalanceMap[$secondordnum]['sales'];
|
||||
$current_sale_num = $currentBalanceMap[$secondordnum]['num'];
|
||||
$invoice_issued = isset($currentBalanceMap[$secondordnum]['invoice_issued']) ? $currentBalanceMap[$secondordnum]['invoice_issued'] : ''; // 기본값을 제공
|
||||
$memo = isset($currentBalanceMap[$secondordnum]['memo']) ? $currentBalanceMap[$secondordnum]['memo'] : ''; // 기본값을 제공
|
||||
}
|
||||
else{
|
||||
// 기존데이터가 없을때 신규
|
||||
$current_sales = 0;
|
||||
$current_sale_num = '';
|
||||
$invoice_issued = '';
|
||||
$memo = '';
|
||||
}
|
||||
|
||||
// 마지막 단위 원단위 중 1은 제거하는 로직
|
||||
// 당월매출 마지막 1원 삭제
|
||||
// 마지막 자리가 1로 끝나는 경우, 0으로 변경
|
||||
// print_r($total_payment);
|
||||
// $totalSalesAmount -= 5;
|
||||
if (round($total_amount) % 10 === 1) {
|
||||
$vat -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
$total_amount -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
|
||||
if (round($balance_due) % 10 === 1) {
|
||||
$balance_due -= 1; // 1을 빼서 마지막 자리를 0으로 만듭니다.
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<tr data-num="<?= $current_sale_num ?>" data-secondordnum="<?= $secondordnum ?>" data-vendorname="<?= $vendor_name ?>" data-totalamount="<?= $total_amount ?>">
|
||||
<td class="text-center"><?= $start_num ?></td>
|
||||
<td class="text-start text-primary" onclick="fetchMonthlyBalanceData('<?= $current_sale_num ?>', '<?= $secondordnum ?>', '<?= $vendor_name ?>', '<?= $total_amount ?>')"><?= $vendor_name ?></td>
|
||||
<td class="text-end " onclick="fetchMonthlyBalanceData('<?= $current_sale_num ?>', '<?= $secondordnum ?>', '<?= $vendor_name ?>', '<?= $total_amount ?>')"><?= number_format($total_sales) ?></td>
|
||||
<td class="text-end " onclick="fetchMonthlyBalanceData('<?= $current_sale_num ?>', '<?= $secondordnum ?>', '<?= $vendor_name ?>', '<?= $total_amount ?>')"><?= number_format($vat) ?></td>
|
||||
<td class="text-end fw-bold text-primary" onclick="fetchMonthlyBalanceData('<?= $current_sale_num ?>', '<?= $secondordnum ?>', '<?= $vendor_name ?>', '<?= $total_amount ?>')"><?= number_format($total_amount) ?></td>
|
||||
<td class="text-center" onclick="redirectToView('<?= $savenum ?>')"><span class="badge bg-secondary"> 상세 </span></td>
|
||||
<td class="text-end fw-bold" onclick="fetchMonthlyBalanceData('<?= $current_sale_num ?>', '<?= $secondordnum ?>', '<?= $vendor_name ?>', '<?= $total_amount ?>')"><?= number_format($current_sales) ?></td>
|
||||
<td class="text-center" onclick="fetchMonthlyBalanceData('<?= $current_sale_num ?>', '<?= $secondordnum ?>', '<?= $vendor_name ?>', '<?= $total_amount ?>')">
|
||||
<?php if ($invoice_issued): ?>
|
||||
<span class="badge bg-warning"><?= $invoice_issued ?></span>
|
||||
<?php else: ?>
|
||||
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="text-start" onclick="fetchMonthlyBalanceData('<?= $current_sale_num ?>', '<?= $secondordnum ?>', '<?= $vendor_name ?>', '<?= $total_amount ?>')"><?= $memo ?></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<?php
|
||||
$start_num++;
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot class="table-secondary">
|
||||
<tr>
|
||||
<th class="text-end" colspan="2"> 합계 </th>
|
||||
<th class="text-end"></th>
|
||||
<th class="text-end"></th>
|
||||
<th class="text-end"></th>
|
||||
<th class="text-end"></th>
|
||||
<th class="text-end"></th>
|
||||
<th class="text-end"></th>
|
||||
<th class="text-end"></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</form>
|
||||
<?php
|
||||
} catch (PDOException $Exception) {
|
||||
print "오류: ".$Exception->getMessage();
|
||||
}
|
||||
?>
|
||||
<!-- 페이지로딩 -->
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
loader.style.display = 'none';
|
||||
// 모달창 닫기
|
||||
$(document).on('click', '.close', function(e) {
|
||||
$("#monthlysaleModal").modal("hide");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
function submitForm() {
|
||||
$('#board_form').submit();
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var dataTable; // DataTables 인스턴스 전역 변수
|
||||
var monthsalepageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
|
||||
|
||||
$(document).ready(function() {
|
||||
// DataTables 초기 설정
|
||||
dataTable = $('#myTable').DataTable({
|
||||
"paging": true,
|
||||
"ordering": true,
|
||||
"searching": true,
|
||||
"pageLength": 50,
|
||||
"lengthMenu": [50, 100, 200, 500, 1000],
|
||||
"language": {
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"search": "Live Search:"
|
||||
},
|
||||
"order": [[2, 'desc']], // 금액 기준 내림차순 정렬
|
||||
"dom": 't<"bottom"ip>', // search 창과 lengthMenu 숨기기
|
||||
"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;
|
||||
};
|
||||
|
||||
var totalInitialReceivable = api
|
||||
.column(2)
|
||||
.data()
|
||||
.reduce(function (a, b) {
|
||||
return intVal(a) + intVal(b);
|
||||
}, 0);
|
||||
|
||||
var totalSalesAmount = api
|
||||
.column(3)
|
||||
.data()
|
||||
.reduce(function (a, b) {
|
||||
return intVal(a) + intVal(b);
|
||||
}, 0);
|
||||
|
||||
var totalissued = api
|
||||
.column(4)
|
||||
.data()
|
||||
.reduce(function (a, b) {
|
||||
return intVal(a) + intVal(b);
|
||||
}, 0);
|
||||
|
||||
|
||||
$(api.column(2).footer()).html(numberWithCommas(totalInitialReceivable));
|
||||
$(api.column(3).footer()).html(numberWithCommas(totalSalesAmount));
|
||||
$(api.column(4).footer()).html(numberWithCommas(totalissued));
|
||||
}
|
||||
});
|
||||
|
||||
// 페이지 번호 복원 (초기 로드 시)
|
||||
var savedPageNumber = getCookie('monthsalepageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
|
||||
// 페이지 변경 이벤트 리스너
|
||||
dataTable.on('page.dt', function() {
|
||||
var monthsalepageNumber = dataTable.page.info().page + 1;
|
||||
setCookie('monthsalepageNumber', monthsalepageNumber, 10); // 쿠키에 페이지 번호 저장
|
||||
});
|
||||
|
||||
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
|
||||
$('#myTable_length select').on('change', function() {
|
||||
var selectedValue = $(this).val();
|
||||
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
|
||||
|
||||
// 변경 후 현재 페이지 번호 복원
|
||||
savedPageNumber = getCookie('monthsalepageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function redirectToView(num) {
|
||||
var fromdate = document.getElementById('fromdate').value;
|
||||
var todate = document.getElementById('todate').value;
|
||||
var url = "customer_sheet.php?num=" + num + "&fromdate=" + fromdate + "&todate=" + todate;
|
||||
customPopup(url, '거래원장', 1000, 850);
|
||||
}
|
||||
function openMonthlyBalancePopup() {
|
||||
var url = "monthly_balance_popup.php";
|
||||
customPopup(url, '거래원장', 1000, 850);
|
||||
}
|
||||
|
||||
function fetchMonthlyBalanceData(current_sale_num, secondordnum, vendor_name, total_amount) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'fetch_closure_sale.php',
|
||||
data: { num: current_sale_num },
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
console.log(response); // 디버깅을 위해 response를 출력
|
||||
|
||||
var tableBody = $('#monthlysaleModalBody');
|
||||
tableBody.empty();
|
||||
|
||||
var currentDate = new Date().toISOString().slice(0, 10);
|
||||
var selectedRow = $('#myTable tr[data-num="' + current_sale_num + '"]'); // 현재 선택한 행
|
||||
|
||||
// 선택된 행이 없는 경우 처리
|
||||
if (selectedRow.length === 0) {
|
||||
console.error('Selected row not found.');
|
||||
return;
|
||||
}
|
||||
|
||||
var customer_name = vendor_name; // vendor_name을 직접 사용
|
||||
var formattedSales = parseFloat(total_amount).toLocaleString(); // total_amount를 3자리마다 콤마를 추가하여 포맷팅
|
||||
|
||||
console.log('Selected Row:', selectedRow);
|
||||
console.log('Customer Name:', customer_name);
|
||||
console.log('Formatted Sales:', formattedSales);
|
||||
|
||||
if (Array.isArray(response) && response.length !== 1) {
|
||||
// 여러 개의 배열이 반환된 경우 또는 데이터가 없는 경우
|
||||
var row = '<tr>' +
|
||||
'<td class="text-center"><input type="date" class="form-control text-center" value="' + currentDate + '"></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control customer_name text-start " value="' + customer_name + '"></td>' +
|
||||
'<td class="text-end"><input type="text" class="form-control text-end sales w-75" onkeyup="inputNumberFormat(this)" value="'+ formattedSales +'"></td>' +
|
||||
'<td class="text-center"><input type="checkbox" class="form-check-input invoice_issued"></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control memo" value=""></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control w80px text-start num" readonly value="' + current_sale_num + '"></td>' +
|
||||
'<td style="display:none;"><input type="hidden" class="text-start secondordnum" value="' + secondordnum + '"></td>' +
|
||||
'</tr>';
|
||||
tableBody.append(row);
|
||||
} else if (Array.isArray(response) && response.length === 1) {
|
||||
// 단일 데이터가 반환된 경우
|
||||
response.forEach(function(item) {
|
||||
var formattedsales = parseFloat(item.sales).toLocaleString();
|
||||
var row = '<tr>' +
|
||||
'<td class="text-center"><input type="date" class="form-control text-center" value="' + item.closure_date + '"></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control customer_name text-start " value="' + (item.customer_name !== null ? item.customer_name : '') + '"></td>' +
|
||||
'<td class="text-end"><input type="text" class="form-control text-end w120px sales w-75" onkeyup="inputNumberFormat(this)" value="' + formattedsales + '"></td>' +
|
||||
'<td class="text-center"><input type="checkbox" class="form-check-input invoice_issued" ' + (item.invoice_issued === '발행' ? 'checked' : '') + '></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control memo" value="' + (item.memo !== null ? item.memo : '') + '"></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control w80px text-start num" readonly value="' + current_sale_num + '"></td>' +
|
||||
'<td style="display:none;"><input type="hidden" class="text-start secondordnum" value="' + secondordnum + '"></td>' +
|
||||
'</tr>';
|
||||
tableBody.append(row);
|
||||
});
|
||||
} else {
|
||||
// 빈 배열이 반환된 경우 (예외 처리)
|
||||
var row = '<tr>' +
|
||||
'<td class="text-center"><input type="date" class="form-control text-center" value="' + currentDate + '"></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control customer_name text-start" value="' + customer_name + '"></td>' +
|
||||
'<td class="text-end"><input type="text" class="form-control text-end sales w-75" onkeyup="inputNumberFormat(this)" value="'+ formattedSales +'"></td>' +
|
||||
'<td class="text-center"><input type="checkbox" class="form-check-input invoice_issued"></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control memo" value=""></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control w80px text-start num" readonly value="' + current_sale_num + '"></td>' +
|
||||
'<td style="display:none;"><input type="hidden" class="text-start secondordnum" value="' + secondordnum + '"></td>' +
|
||||
'</tr>';
|
||||
tableBody.append(row);
|
||||
}
|
||||
|
||||
console.log('current_sale_num ',current_sale_num);
|
||||
$('#monthlysaleModal').modal('show');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("AJAX error: ", status, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function saveMonthlyBalanceData() {
|
||||
var data = [];
|
||||
$('#monthlysaleModalBody tr').each(function() {
|
||||
var num = $(this).find('.num').val();
|
||||
var closure_date = $(this).find('input[type="date"]').val();
|
||||
var customer_name = $(this).find('.customer_name').val();
|
||||
var sales = $(this).find('.sales').val().replace(/,/g, ''); // 콤마 제거
|
||||
var invoice_issued = $(this).find('input[type="checkbox"]').is(':checked');
|
||||
var memo = $(this).find('.memo').val();
|
||||
var secondordnum = $(this).find('.secondordnum').val();
|
||||
var mode = num ? 'update' : 'insert'; // num이 있는 경우 업데이트, 없는 경우 삽입
|
||||
data.push({
|
||||
mode: mode,
|
||||
num: num,
|
||||
closure_date: closure_date,
|
||||
customer_name: customer_name,
|
||||
sales: sales,
|
||||
invoice_issued: invoice_issued,
|
||||
secondordnum: secondordnum,
|
||||
memo: memo
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
console.log('data',data);
|
||||
|
||||
// 버튼 비활성화
|
||||
var saveButton = $('button[onclick="saveMonthlyBalanceData()"]');
|
||||
saveButton.prop('disabled', true);
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'insert_monthly_sale.php',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
toastAlert('파일저장');
|
||||
// 1.5초 후에 모달창 닫고 화면 새로고침
|
||||
setTimeout(function(){
|
||||
$('#monthlysaleModal').modal('hide');
|
||||
location.reload(); // 화면 새로고침
|
||||
}, 1500);
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("AJAX error: ", status, error);
|
||||
// 에러 발생 시 버튼 다시 활성화
|
||||
saveButton.prop('disabled', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 삭제처리
|
||||
function saveMonthlyDelete() {
|
||||
Swal.fire({
|
||||
title: '계산서 발행 삭제',
|
||||
text: "이 작업을 진행하시겠습니까?",
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '예',
|
||||
cancelButtonText: '아니오'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
var data = [];
|
||||
$('#monthlysaleModalBody tr').each(function() {
|
||||
var num = $(this).find('.num').val();
|
||||
var mode = 'delete';
|
||||
|
||||
data.push({
|
||||
mode: mode,
|
||||
num: num
|
||||
});
|
||||
});
|
||||
|
||||
// 버튼 비활성화
|
||||
var saveButton = $('button[onclick="saveMonthlyDelete()"]');
|
||||
saveButton.prop('disabled', true);
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'insert_monthly_sale.php',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function(response) {
|
||||
toastAlert('파일삭제');
|
||||
// 1.5초 후에 모달창 닫고 화면 새로고침
|
||||
setTimeout(function(){
|
||||
$('#monthlysaleModal').modal('hide');
|
||||
location.reload(); // 화면 새로고침
|
||||
}, 1500);
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("AJAX error: ", status, error);
|
||||
// 에러 발생 시 버튼 다시 활성화
|
||||
saveButton.prop('disabled', false);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// 사용자가 '아니오'를 누른 경우
|
||||
Swal.fire('취소되었습니다.', '', 'info');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 모달창 닫힐 때 버튼 다시 활성화
|
||||
$('#monthlysaleModal').on('hidden.bs.modal', function () {
|
||||
var saveButton = $('button[onclick="saveMonthlyBalanceData()"]');
|
||||
saveButton.prop('disabled', false);
|
||||
var saveButton_delete = $('button[onclick="saveMonthlyDelete()"]');
|
||||
saveButton_delete.prop('disabled', false);
|
||||
});
|
||||
|
||||
// 화면에 toastAlert() 표시
|
||||
function toastAlert(Str){
|
||||
// 오버레이 활성화
|
||||
document.getElementById("overlay").style.display = "block";
|
||||
|
||||
Toastify({
|
||||
text: Str,
|
||||
duration: 3000,
|
||||
close: true,
|
||||
gravity: "top",
|
||||
position: 'center',
|
||||
}).showToast();
|
||||
|
||||
// 1초 후에 오버레이 비활성화
|
||||
setTimeout(function(){
|
||||
document.getElementById("overlay").style.display = "none";
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function numberWithCommas(x) {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
335
account_juil/monthly_balance_popup.php
Normal file
335
account_juil/monthly_balance_popup.php
Normal file
@@ -0,0 +1,335 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
|
||||
// 첫 화면 표시 문구
|
||||
$title_message = '이월잔액 자료';
|
||||
?>
|
||||
|
||||
<title> <?=$title_message?> </title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?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) {
|
||||
// 전월의 첫날과 말일을 계산하여 설정
|
||||
$fromdate = date("Y-m-01", strtotime("first day of previous month")); // 전월의 첫날 설정
|
||||
$todate = date("Y-m-t", strtotime("last day of previous month")); // 전월의 마지막 날 설정
|
||||
$Transtodate = $todate;
|
||||
} else {
|
||||
// 지정된 fromdate와 todate의 월의 첫날과 마지막 날을 계산하여 설정
|
||||
$fromdate = date("Y-m-01", strtotime($fromdate)); // 선택한 달의 첫날 설정
|
||||
$todate = date("Y-m-t", strtotime($todate)); // 선택한 달의 마지막 날 설정
|
||||
$Transtodate = $todate;
|
||||
}
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
// 전월 마지막 날짜 계산
|
||||
// $lastMonthDate = date("Y-m-t", strtotime("last month"));
|
||||
$lastMonthDate = $Transtodate ;
|
||||
|
||||
// print $lastMonthDate;
|
||||
|
||||
// 전월 잔액 조회 (output + output_extra, outdate, ET_total)
|
||||
$balanceSql = "
|
||||
SELECT o.num, o.secondordnum, SUM(COALESCE(e.ET_total, 0)) AS balance, o.secondord AS secondord, '' AS memo, o.outdate AS closure_date
|
||||
FROM output o
|
||||
LEFT JOIN output_extra e ON o.num = e.parent_num
|
||||
WHERE o.outdate = :lastMonthDate AND o.outdate BETWEEN :fromdate AND :todate AND ( o.is_deleted IS NULL or o.is_deleted = 0 )
|
||||
GROUP BY o.secondordnum, o.outdate
|
||||
";
|
||||
|
||||
if (!empty($search)) {
|
||||
$balanceSql .= " AND o.secondordnum LIKE :search";
|
||||
}
|
||||
|
||||
$balanceStmt = $pdo->prepare($balanceSql);
|
||||
$balanceStmt->bindValue(':lastMonthDate', $lastMonthDate, PDO::PARAM_STR);
|
||||
$balanceStmt->bindValue(':fromdate', $fromdate, PDO::PARAM_STR);
|
||||
$balanceStmt->bindValue(':todate', $todate, PDO::PARAM_STR);
|
||||
|
||||
if (!empty($search)) {
|
||||
$balanceStmt->bindValue(':search', '%' . $search . '%', PDO::PARAM_STR);
|
||||
}
|
||||
|
||||
$balanceStmt->execute();
|
||||
$previousBalances = $balanceStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
?>
|
||||
|
||||
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
|
||||
|
||||
<input type="hidden" id="mode" name="mode" value="<?=$mode?>">
|
||||
<input type="hidden" id="num" name="num">
|
||||
<input type="hidden" id="tablename" name="tablename" value="<?=$tablename?>">
|
||||
<input type="hidden" id="header" name="header" value="<?=$header?>">
|
||||
<input type="hidden" id="secondordnum" name="secondordnum" value="<?=$secondordnum?>">
|
||||
|
||||
<?php include 'modal.php'; ?>
|
||||
|
||||
<div class="container">
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="text-center fs-5 me-4"><?=$title_message?></span>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick='location.reload();'>
|
||||
<i class="bi bi-arrow-clockwise"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<ion-icon name="caret-forward-outline"></ion-icon> <?= count($previousBalances) ?>
|
||||
|
||||
<button type="button" class="btn btn-secondary btn-sm me-1 change_dateRange" onclick='prepre_month()'>전전월</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm me-1 change_dateRange" onclick='pre_month()'>전월</button>
|
||||
|
||||
|
||||
<input type="date" id="fromdate" name="fromdate" class="form-control" style="width:100px;" value="<?=$fromdate?>"> ~
|
||||
<input type="date" id="todate" name="todate" class="form-control me-1" style="width:100px;" value="<?=$todate?>"> </span>
|
||||
|
||||
<div class="inputWrap">
|
||||
<input type="text" id="search" name="search" value="<?=$search?>" onkeydown="if(event.key === 'Enter') submitForm();" autocomplete="off" class="form-control me-1" style="width:150px;">
|
||||
<button class="btnClear"></button>
|
||||
</div>
|
||||
<button id="searchBtn" type="button" class="btn btn-dark btn-sm me-2" onclick="submitForm()"> <i class="bi bi-search"></i> </button>
|
||||
<button id="closeBtn" type="button" class="btn btn-secondary btn-sm ms-2" onclick="window.close();"> 창닫기 </button>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<table class="table table-hover" id="balanceTable">
|
||||
<thead class="table-info">
|
||||
<th class="text-center w50px">번호</th>
|
||||
<th class="text-center w100px">기준일자</th>
|
||||
<th class="text-center w130px">거래처명</th>
|
||||
<th class="text-end w100px">이월잔액</th>
|
||||
<th class="text-center w150px">적요</th>
|
||||
<th class="text-center w100px">거래처코드</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
try {
|
||||
$start_num = 1;
|
||||
foreach ($previousBalances as $row) {
|
||||
$num = $row['num'];
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$secondord = $row['secondord'];
|
||||
$balance = $row['balance'];
|
||||
$memo = isset($row['memo']) ? $row['memo'] : ''; // 기본값을 제공
|
||||
|
||||
?>
|
||||
<tr data-toggle="modal" data-target="#monthlyBalanceModal" onclick="fetchMonthlyBalanceData(<?= $num ?>)">
|
||||
<td class="text-center"><?= $start_num ?></td>
|
||||
<td class="text-center"><?= $lastMonthDate ?></td>
|
||||
<td class="text-start text-primary"><?= $secondord ?></td>
|
||||
<td class="text-end"><?= $balance != 0 ? number_format($balance) : '' ?></td>
|
||||
<td class="text-center"><?= $memo ?> </td>
|
||||
<td class="text-center text-info"><?= $secondordnum ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$start_num++;
|
||||
}
|
||||
} catch (PDOException $Exception) {
|
||||
print "오류: ".$Exception->getMessage();
|
||||
}
|
||||
?>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
// 페이지 로딩
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
loader.style.display = 'none';
|
||||
// 모달창 닫기
|
||||
$(document).on('click', '.close', function(e) {
|
||||
$("#monthlyBalanceModal").modal("hide");
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
var dataTable; // DataTables 인스턴스 전역 변수
|
||||
var bookpageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
|
||||
|
||||
function inputNumberFormat(input) {
|
||||
var value = input.value.replace(/,/g, ''); // 콤마 제거
|
||||
if (!isNaN(value) && value !== '') {
|
||||
input.value = parseFloat(value).toLocaleString();
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
// DataTables 초기 설정
|
||||
dataTable = $('#myTable').DataTable({
|
||||
"paging": true,
|
||||
"ordering": true,
|
||||
"searching": true,
|
||||
"pageLength": 50,
|
||||
"lengthMenu": [50, 100, 200, 500, 1000],
|
||||
"language": {
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"search": "Live Search:"
|
||||
},
|
||||
"order": [[2, 'desc']], // 공급가액 기준 내림차순 정렬
|
||||
"dom": 't<"bottom"ip>' // search 창과 lengthMenu 숨기기
|
||||
});
|
||||
|
||||
// 페이지 번호 복원 (초기 로드 시)
|
||||
var savedPageNumber = getCookie('bookpageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
|
||||
// 페이지 변경 이벤트 리스너
|
||||
dataTable.on('page.dt', function() {
|
||||
var bookpageNumber = dataTable.page.info().page + 1;
|
||||
setCookie('bookpageNumber', bookpageNumber, 10); // 쿠키에 페이지 번호 저장
|
||||
});
|
||||
|
||||
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
|
||||
$('#myTable_length select').on('change', function() {
|
||||
var selectedValue = $(this).val();
|
||||
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
|
||||
|
||||
// 변경 후 현재 페이지 번호 복원
|
||||
savedPageNumber = getCookie('bookpageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function submitForm() {
|
||||
$('#board_form').submit();
|
||||
}
|
||||
|
||||
function fetchMonthlyBalanceData(num) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'fetch_closure.php',
|
||||
data: { num: num },
|
||||
dataType: 'json',
|
||||
success: function(response) {
|
||||
console.log(response);
|
||||
if (!Array.isArray(response)) {
|
||||
console.error("Response is not an array:", response);
|
||||
return;
|
||||
}
|
||||
var tableBody = $('#monthlyBalanceModalBody');
|
||||
tableBody.empty();
|
||||
|
||||
response.forEach(function(item) {
|
||||
var formattedBalance = parseFloat(item.balance).toLocaleString();
|
||||
var row = '<tr>' +
|
||||
'<td class="text-center"><input type="date" class="form-control text-center" value="' + item.closure_date + '"></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control secondord" value="' + (item.secondord !== null ? item.secondord : '') + '"></td>' +
|
||||
'<td class="text-end"><input type="text" class="form-control text-end w120px balance" onkeyup="inputNumberFormat(this)" value="' + formattedBalance + '"></td>' +
|
||||
'<td class="text-center"><input type="text" class="form-control memo" value="' + (item.memo !== null ? item.memo : '') + '"></td>' +
|
||||
'<td style="display:none;" ><input type="hidden" class="num" value="' + item.num + '"></td>' +
|
||||
'</tr>';
|
||||
tableBody.append(row);
|
||||
});
|
||||
$('#monthlyBalanceModal').modal('show');
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("AJAX error: ", status, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
function saveMonthlyBalanceData() {
|
||||
var data = [];
|
||||
$('#monthlyBalanceModalBody tr').each(function() {
|
||||
var num = $(this).find('.num').val();
|
||||
var closure_date = $(this).find('input[type="date"]').val();
|
||||
var secondord = $(this).find('.secondord').val();
|
||||
var balance = $(this).find('.balance').val().replace(/,/g, ''); // 콤마 제거
|
||||
var memo = $(this).find('.memo').val();
|
||||
|
||||
data.push({
|
||||
num: num,
|
||||
closure_date: closure_date,
|
||||
secondord: secondord,
|
||||
balance: balance,
|
||||
memo: memo
|
||||
});
|
||||
});
|
||||
|
||||
// 버튼 비활성화
|
||||
var saveButton = $('button[onclick="saveMonthlyBalanceData()"]');
|
||||
saveButton.prop('disabled', true);
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: 'insert_monthly.php',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
success: function(response) {
|
||||
toastAlert('파일저장');
|
||||
// 1.5초 후에 모달창 닫고 화면 새로고침
|
||||
setTimeout(function(){
|
||||
$('#monthlyBalanceModal').modal('hide');
|
||||
location.reload(); // 화면 새로고침
|
||||
}, 1500);
|
||||
},
|
||||
error: function(xhr, status, error) {
|
||||
console.error("AJAX error: ", status, error);
|
||||
// 에러 발생 시 버튼 다시 활성화
|
||||
saveButton.prop('disabled', false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 모달창 닫힐 때 버튼 다시 활성화
|
||||
$('#monthlyBalanceModal').on('hidden.bs.modal', function () {
|
||||
var saveButton = $('button[onclick="saveMonthlyBalanceData()"]');
|
||||
saveButton.prop('disabled', false);
|
||||
});
|
||||
|
||||
// 화면에 toastAlert() 표시
|
||||
function toastAlert(Str){
|
||||
// 오버레이 활성화
|
||||
document.getElementById("overlay").style.display = "block";
|
||||
|
||||
Toastify({
|
||||
text: Str,
|
||||
duration: 3000,
|
||||
close: true,
|
||||
gravity: "top",
|
||||
position: 'center',
|
||||
}).showToast();
|
||||
|
||||
// 1초 후에 오버레이 비활성화
|
||||
setTimeout(function(){
|
||||
document.getElementById("overlay").style.display = "none";
|
||||
}, 1000);
|
||||
}
|
||||
</script>
|
||||
910
account_juil/receivable.php
Normal file
910
account_juil/receivable.php
Normal file
@@ -0,0 +1,910 @@
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
if (!isset($_SESSION["level"]) || $_SESSION["level"] > 5) {
|
||||
sleep(1);
|
||||
header("Location:" . $WebSite . "login/login_form.php");
|
||||
exit;
|
||||
}
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
// 첫 화면 표시 문구
|
||||
$title_message = '미수금 현황';
|
||||
?>
|
||||
|
||||
<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;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<?php
|
||||
if($user_id === '0266771300' ) {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader_accountant1.php'); // 경리
|
||||
} else {
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader1.php');
|
||||
}
|
||||
?>
|
||||
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/account_juil/fetch_balance.php");
|
||||
|
||||
$search = isset($_REQUEST['search']) ? $_REQUEST['search'] : '';
|
||||
$selectedYearMonth = isset($_REQUEST['yearMonth']) ? $_REQUEST['yearMonth'] : date("Ym");
|
||||
|
||||
// 현재 날짜가 속한 연월 계산
|
||||
$currentYearMonth = date("Ym");
|
||||
|
||||
// 선택된 연월의 이전 달을 계산
|
||||
$previousMonth = date("Ym", strtotime($selectedYearMonth . '01 -1 month'));
|
||||
$previousMonthDisplay = date("m", strtotime($previousMonth . '01')) . "월";
|
||||
|
||||
// 기준년월에 따른 fromdate, todate 설정
|
||||
$fromdate = $selectedYearMonth . '01';
|
||||
$todate = date("Y-m-t", strtotime($fromdate));
|
||||
|
||||
// 검색 기간 표시를 위해 fromdate와 todate를 Y-m-d 형식으로 변환
|
||||
$fromdate = date("Y-m-d", strtotime($fromdate));
|
||||
$todate = date("Y-m-d", strtotime($todate));
|
||||
|
||||
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : '';
|
||||
|
||||
function checkNull($strtmp) {
|
||||
return $strtmp !== null && trim($strtmp) !== '';
|
||||
}
|
||||
|
||||
$tablename = 'phonebook';
|
||||
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||||
$pdo = db_connect();
|
||||
|
||||
// 약속코멘트와 약속일을 가져온다.
|
||||
$promisedate = [];
|
||||
$memo = [];
|
||||
|
||||
$recordSql = "
|
||||
SELECT secondordnum, primisedate, comment
|
||||
FROM recordlist
|
||||
WHERE (is_deleted IS NULL or is_deleted = 0)
|
||||
ORDER BY num DESC
|
||||
";
|
||||
|
||||
$recordStmt = $pdo->prepare($recordSql);
|
||||
$recordStmt->execute();
|
||||
$recordData = $recordStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($recordData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$primisedate = $row['primisedate'];
|
||||
$comment = $row['comment'];
|
||||
|
||||
// 가장 최신의 약속일과 메모만 저장
|
||||
if (!isset($promisedate[$secondordnum])) {
|
||||
$promisedate[$secondordnum] = $primisedate;
|
||||
$memo[$secondordnum] = $comment;
|
||||
}
|
||||
}
|
||||
|
||||
// 이월 잔액을 동적으로 계산하기 위한 로직
|
||||
$previousMonthFromDate = date("Y-m-01", strtotime($previousMonth . '01'));
|
||||
$previousMonthToDate = date("Y-m-t", strtotime($previousMonth . '01'));
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($previousMonthFromDate);
|
||||
// echo ', ';
|
||||
// print_r($previousMonthToDate);
|
||||
// echo '</pre>';
|
||||
|
||||
// 전월 매출 및 수금 데이터 가져오기
|
||||
$previousMonthSalesSql = "
|
||||
SELECT o.secondordnum, COALESCE(e.ET_total, 0) AS ET_total
|
||||
FROM output o
|
||||
LEFT JOIN output_extra e ON o.num = e.parent_num
|
||||
WHERE (o.outdate BETWEEN date('$previousMonthFromDate') AND date('$previousMonthToDate')) AND (o.is_deleted IS NULL or o.is_deleted = 0)
|
||||
";
|
||||
$previousMonthSalesStmt = $pdo->prepare($previousMonthSalesSql);
|
||||
$previousMonthSalesStmt->execute();
|
||||
$previousMonthSalesData = $previousMonthSalesStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$previousMonthSales = [];
|
||||
foreach ($previousMonthSalesData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_sales_prev = (float)$row['ET_total'];
|
||||
if (!isset($previousMonthSales[$secondordnum])) {
|
||||
$previousMonthSales[$secondordnum] = 0;
|
||||
}
|
||||
$previousMonthSales[$secondordnum] += round($total_sales_prev, 2); // ET_total은 부가세 포함
|
||||
}
|
||||
|
||||
// 당월 매출 데이터 가져오기
|
||||
$salesSql = "
|
||||
SELECT o.secondordnum, COALESCE(e.ET_total, 0) AS ET_total
|
||||
FROM output o
|
||||
LEFT JOIN output_extra e ON o.num = e.parent_num
|
||||
WHERE (o.outdate BETWEEN date('$fromdate') AND date('$todate')) AND (o.is_deleted IS NULL or o.is_deleted = 0)
|
||||
";
|
||||
|
||||
$salesStmt = $pdo->prepare($salesSql);
|
||||
$salesStmt->execute();
|
||||
$salesData = $salesStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
$currentMonthSales = [];
|
||||
foreach ($salesData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_sales = (float)$row['ET_total'];
|
||||
if (!isset($currentMonthSales[$secondordnum])) {
|
||||
$currentMonthSales[$secondordnum] = 0;
|
||||
}
|
||||
$currentMonthSales[$secondordnum] += round($total_sales, 2);
|
||||
}
|
||||
|
||||
// 전월까지의 매출 및 수금 데이터를 기반으로 이월 잔액을 계산
|
||||
$initialBalances = [];
|
||||
$lastMonthEnd = date("Y-m-t", strtotime($fromdate . " -1 month"));
|
||||
|
||||
$salesBeforeSql = "
|
||||
SELECT o.secondordnum, SUM(COALESCE(e.ET_total, 0)) AS total_sales
|
||||
FROM output o
|
||||
LEFT JOIN output_extra e ON o.num = e.parent_num
|
||||
WHERE o.outdate <= :lastMonthEnd AND (o.is_deleted IS NULL or o.is_deleted = 0)
|
||||
GROUP BY o.secondordnum
|
||||
";
|
||||
|
||||
$paymentBeforeSql = "
|
||||
SELECT secondordnum, SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
|
||||
FROM account_juil
|
||||
WHERE registDate <= :lastMonthEnd AND (is_deleted IS NULL or is_deleted = 0) AND content = '거래처 수금'
|
||||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')
|
||||
GROUP BY secondordnum
|
||||
";
|
||||
|
||||
$salesBeforeStmt = $pdo->prepare($salesBeforeSql);
|
||||
$salesBeforeStmt->execute([':lastMonthEnd' => $lastMonthEnd]);
|
||||
$salesBeforeData = $salesBeforeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($lastMonthEnd);
|
||||
// echo '</pre>';
|
||||
|
||||
$paymentEnddate = date("Y-m-t", strtotime($todate));
|
||||
|
||||
$paymentBeforeStmt = $pdo->prepare($paymentBeforeSql);
|
||||
$paymentBeforeStmt->execute([':lastMonthEnd' => $paymentEnddate]);
|
||||
$paymentBeforeData = $paymentBeforeStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($salesBeforeData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_sales_before = round((float)$row['total_sales'], 2);
|
||||
if (!isset($initialBalances[$secondordnum])) {
|
||||
$initialBalances[$secondordnum] = 0;
|
||||
}
|
||||
$initialBalances[$secondordnum] += $total_sales_before;
|
||||
}
|
||||
|
||||
foreach ($paymentBeforeData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_payment_before = (float)$row['total_payment'];
|
||||
if (!isset($initialBalances[$secondordnum])) {
|
||||
$initialBalances[$secondordnum] = 0;
|
||||
}
|
||||
$initialBalances[$secondordnum] -= $total_payment_before;
|
||||
}
|
||||
|
||||
// 거래처별 잔액을 계산
|
||||
$balances = fetch_balances($DB, $fromdate, $todate);
|
||||
|
||||
// 모든 거래처 목록을 생성 (이월 잔액, 전월 매출, 당월 매출, 잔고)
|
||||
$allResults = array_unique(array_merge(array_keys($initialBalances), array_keys($currentMonthSales), array_keys($previousMonthSales), array_keys($balances)));
|
||||
|
||||
// ksort($allResults);
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($allResults[23]);
|
||||
// echo '</pre>';
|
||||
|
||||
|
||||
// 이번달 수금 금액 계산
|
||||
$currentMonthPayments = [];
|
||||
$currentMonthStart = date("Y-m-01", strtotime($todate));
|
||||
$currentMonthEnd = date("Y-m-t", strtotime($todate));
|
||||
|
||||
$currentPaymentSql = "
|
||||
SELECT secondordnum, SUM(CAST(REPLACE(amount, ',', '') AS SIGNED)) AS total_payment
|
||||
FROM account_juil
|
||||
WHERE registDate BETWEEN :currentMonthStart AND :currentMonthEnd
|
||||
AND (is_deleted IS NULL or is_deleted = 0) AND content = '거래처 수금'
|
||||
AND (dueDate = '0000-00-00' OR dueDate IS NULL OR dueDate = '')
|
||||
GROUP BY secondordnum
|
||||
";
|
||||
|
||||
$currentPaymentStmt = $pdo->prepare($currentPaymentSql);
|
||||
$currentPaymentStmt->execute([
|
||||
':currentMonthStart' => $currentMonthStart,
|
||||
':currentMonthEnd' => $currentMonthEnd
|
||||
]);
|
||||
$currentPaymentData = $currentPaymentStmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
|
||||
foreach ($currentPaymentData as $row) {
|
||||
$secondordnum = $row['secondordnum'];
|
||||
$total_payment_current = (float)$row['total_payment'];
|
||||
|
||||
if (!isset($currentMonthPayments[$secondordnum])) {
|
||||
$currentMonthPayments[$secondordnum] = 0;
|
||||
}
|
||||
|
||||
$currentMonthPayments[$secondordnum] += $total_payment_current;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 미수금 계산
|
||||
$receivables = []; // 미수금을 저장할 배열
|
||||
$vendorNames = []; // 거래처 이름을 저장할 배열
|
||||
$paydates = []; // 결제일을 저장할 배열
|
||||
|
||||
// 거래처 이름을 저장하는 배열 초기화
|
||||
$vendorNames = [];
|
||||
$paydates = [];
|
||||
foreach ($allResults as $secondordnum) {
|
||||
// 잔고, 전월매출, 당월매출, 이월 잔액 및 미수금을 계산
|
||||
$previousMonthSale = isset($previousMonthSales[$secondordnum]) ? $previousMonthSales[$secondordnum] : 0;
|
||||
$currentMonthSale = isset($currentMonthSales[$secondordnum]) ? $currentMonthSales[$secondordnum] : 0;
|
||||
$balance = isset($balances[$secondordnum]) ? $balances[$secondordnum] : 0;
|
||||
$currentMonthPayment = isset($currentMonthPayments[$secondordnum]) ? $currentMonthPayments[$secondordnum] : 0;
|
||||
|
||||
// 최종 잔고 계산 (이번달 수금액을 차감)
|
||||
// $finalBalance = $balance - $currentMonthPayment; // 이코드 보류함 250414 수정 이중으로 차감됨
|
||||
$finalBalance = $balance ;
|
||||
|
||||
if ($finalBalance > 0) {
|
||||
$receivableAmount = $finalBalance - $currentMonthSale - $previousMonthSale;
|
||||
if($receivableAmount > 0)
|
||||
$receivables[$secondordnum] = $receivableAmount;
|
||||
else
|
||||
$receivables[$secondordnum] = 0;
|
||||
} else {
|
||||
$receivables[$secondordnum] = 0;
|
||||
}
|
||||
|
||||
// 거래처 정보 가져오기
|
||||
$dueDateSql = "SELECT paydate, vendor_name, note FROM {$DB}.phonebook
|
||||
WHERE secondordnum = '$secondordnum' AND (is_deleted IS NULL or is_deleted = 0)";
|
||||
$dueDateStmt = $pdo->prepare($dueDateSql);
|
||||
$dueDateStmt->execute();
|
||||
$dueDateRow = $dueDateStmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
// 거래처 이름과 결제일을 저장
|
||||
$vendorNames[$secondordnum] = $dueDateRow['vendor_name'] ?? '';
|
||||
$paydates[$secondordnum] = $dueDateRow['paydate'] ?? '';
|
||||
}
|
||||
|
||||
|
||||
// 거래처 이름으로 정렬
|
||||
usort($allResults, function($a, $b) use ($vendorNames) {
|
||||
return strcmp($vendorNames[$a], $vendorNames[$b]);
|
||||
});
|
||||
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($receivables);
|
||||
// echo '</pre>';
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<!-- 리스트 모달 창 -->
|
||||
<div class="modal fade" id="recordListModal" tabindex="-1" aria-labelledby="recordListModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="recordListModalLabel">약속일 및 통화내역</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<ul id="recordList" class="list-group" style="max-height: 400px; overflow-y: auto;">
|
||||
<!-- 여기에서 기록 리스트가 동적으로 추가됩니다. -->
|
||||
</ul>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" id="newRecordButton">신규등록</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 수정/신규등록 모달 창 -->
|
||||
<div class="modal fade" id="recordEditModal" tabindex="-1" aria-labelledby="recordEditModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="recordEditModalLabel">결재 약속일 및 통화내역 수정</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form id="recordForm">
|
||||
<input type="hidden" id="recordNum" name="recordNum">
|
||||
<div class="mb-3">
|
||||
<label for="record" class="form-label">기록일시</label>
|
||||
<input type="datetime-local" class="form-control" style="width:200px;" id="recordTime" name="recordTime">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="comment" class="form-label">통화내용</label>
|
||||
<textarea class="form-control" id="comment" name="comment" style="height:150px;" ></textarea>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="primisedate" class="form-label">결재 약속일</label>
|
||||
<input type="date" class="form-control" style="width:110px;" id="primisedate" name="primisedate" >
|
||||
<input type="hidden" id="secondordID" name="secondordID" >
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">저장</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
|
||||
|
||||
<div class="container mb-5">
|
||||
<input type="hidden" id="mode" name="mode" value="<?=$mode?>">
|
||||
<input type="hidden" id="num" name="num">
|
||||
<input type="hidden" id="tablename" name="tablename" value="<?=$tablename?>">
|
||||
<input type="hidden" id="header" name="header" value="<?=$header?>">
|
||||
<input type="hidden" id="secondordnum" name="secondordnum" value="<?=$secondordnum?>">
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="text-center fs-5 me-4"><?=$title_message?></span>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick='location.reload();'>
|
||||
<i class="bi bi-arrow-clockwise"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- <div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="badge bg-danger fs-6 me-4"> 미수금 현황은 <거래처원장> '차기월 이월금확정' 처리 완료 후 계산됩니다. </span>
|
||||
</div>
|
||||
-->
|
||||
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<button type="button" class="btn btn-dark btn-sm me-2" onclick="location.href='../getmoney/list.php?header=header'"><i class="bi bi-journal-x"></i> 수금 </button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick="location.href='../account_juil/S_transaction.php?header=header'"> <i class="bi bi-file-earmark-ruled"></i> 거래원장</button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick="openMonthlyBalancePopup()"> <i class="bi bi-file-earmark-ruled"></i> 이월잔액</button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-1" onclick="location.href='../account_juil/month_sales.php?header=header'"> <i class="bi bi-file-earmark-ruled"></i> 판매일괄회계</button>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="badge bg-danger fs-3 me-3"> 현재개발중입니다. (미완성) </span>
|
||||
</div>
|
||||
-->
|
||||
<div class="d-flex p-1 m-1 mt-1 mb-1 justify-content-center align-items-center">
|
||||
<span class="text-primary fw-bold ms-2 me-3"> * 잔고(거래원장 잔액) - 당월매출 - 전월매출 = 미수금 (계산서 발행 후 결재일 넘기면 미수금)</span>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover" id="myTable">
|
||||
<thead class="table-danger">
|
||||
<th class="text-center ">번호</th>
|
||||
<th class="text-center w150px">거래처명</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 ">원장</th>
|
||||
<?php if($user_id == 'pro')
|
||||
print '<th class="text-center w40px">Code</th>';
|
||||
?>
|
||||
<th style="display:none;" ></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
try {
|
||||
$start_num = 1;
|
||||
foreach ($allResults as $secondordnum) {
|
||||
if (isset($receivables[$secondordnum]) && intval($receivables[$secondordnum]) > 0 ) {
|
||||
?>
|
||||
|
||||
<tr data-secondordnum="<?=$secondordnum ?>" data-secondord="<?= htmlspecialchars($vendorNames[$secondordnum])?>"
|
||||
data-promisedate="<?= htmlspecialchars($promisedate[$secondordnum] ?? '') ?>" data-memo="<?= htmlspecialchars($memo[$secondordnum] ?? '') ?>">
|
||||
|
||||
<td class="text-center choice"><?= $start_num ?></td>
|
||||
|
||||
<td class="text-start text-primary choice"
|
||||
data-secondord="<?= htmlspecialchars($vendorNames[$secondordnum])?>"
|
||||
onclick="redirectToView(this, '<?= $secondordnum ?>')">
|
||||
<?= htmlspecialchars($vendorNames[$secondordnum]) ?>
|
||||
</td>
|
||||
|
||||
<td class="text-center text-primary fw-bold choice"
|
||||
onclick="redirectToView(this, '<?= $secondordnum ?>')">
|
||||
<?= htmlspecialchars($paydates[$secondordnum]) ?>
|
||||
</td>
|
||||
|
||||
<td class="text-end text-danger fw-bold choice"
|
||||
onclick="redirectToView(this, '<?= $secondordnum ?>')">
|
||||
<?= number_format($receivables[$secondordnum]) ?>
|
||||
</td>
|
||||
|
||||
<td class="text-end text-secondary fw-bold choice"
|
||||
onclick="redirectToView(this, '<?= $secondordnum ?>')">
|
||||
<?= number_format(isset($previousMonthSales[$secondordnum]) ? $previousMonthSales[$secondordnum] : 0) ?>
|
||||
</td>
|
||||
|
||||
<td class="text-end fw-bold choice"
|
||||
onclick="redirectToView(this, '<?= $secondordnum ?>')">
|
||||
<?= number_format(isset($currentMonthSales[$secondordnum]) ? $currentMonthSales[$secondordnum] : 0) ?>
|
||||
</td>
|
||||
|
||||
<td class="text-end fw-bold choice" onclick="redirectToView(this, '<?= $secondordnum ?>')">
|
||||
<?= number_format(isset($balances[$secondordnum]) ? $balances[$secondordnum] : 0) ?>
|
||||
</td>
|
||||
|
||||
<td class="text-center choice" data-promisedate onclick="redirectToView(this, '<?= $secondordnum ?>')" >
|
||||
<?= (isset($promisedate[$secondordnum]) && $promisedate[$secondordnum] !== "0000-00-00") ? htmlspecialchars($promisedate[$secondordnum]) : '' ?>
|
||||
</td>
|
||||
|
||||
<td class="text-start choice" onclick="redirectToView(this, '<?= $secondordnum ?>')" data-memo title="<?= htmlspecialchars($memo[$secondordnum] ?? '') ?>">
|
||||
<?php
|
||||
if (isset($memo[$secondordnum])) {
|
||||
$memoText = htmlspecialchars($memo[$secondordnum]);
|
||||
// 한글 처리를 위해 mb_strlen과 mb_substr 사용
|
||||
if (mb_strlen($memoText, 'UTF-8') > 40) {
|
||||
echo mb_substr($memoText, 0, 40, 'UTF-8') . '...';
|
||||
} else {
|
||||
echo $memoText;
|
||||
}
|
||||
} else {
|
||||
echo '';
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
|
||||
<td class="text-center" onclick="ViewtoCustomerSheet('<?= $secondordnum ?>')">
|
||||
<span class="badge bg-secondary"> 보기 </span>
|
||||
</td>
|
||||
|
||||
<?php if($user_id == 'pro')
|
||||
echo '<td class="text-center w50px"> ' . $secondordnum . ' </td>';
|
||||
?>
|
||||
|
||||
<td style="display:none;"><?= $secondordnum ?></td>
|
||||
</tr>
|
||||
|
||||
<?php
|
||||
$start_num++;
|
||||
}
|
||||
}
|
||||
} catch (PDOException $Exception) {
|
||||
print "오류: ".$Exception->getMessage();
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot class="table-secondary">
|
||||
<tr>
|
||||
<th class="text-end w80px" colspan="3"> 합계 </th>
|
||||
<th class="text-end">
|
||||
<?= number_format(array_sum(array_map(function($value) {
|
||||
return floatval(str_replace(',', '', $value));
|
||||
}, $receivables))) ?>
|
||||
</th>
|
||||
|
||||
<th class="text-end"><?= number_format(array_sum($previousMonthSales)) ?></th>
|
||||
<th class="text-end"><?= number_format(array_sum($currentMonthSales)) ?></th>
|
||||
<th class="text-end"><?= number_format(array_sum($balances)) ?></th>
|
||||
<th class="text-end "> </th>
|
||||
<th class="text-end "> </th>
|
||||
<th class="text-end "> </th>
|
||||
<?php if($user_id == 'pro')
|
||||
echo '<th class="text-center w50px"> </th>';
|
||||
?>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- 페이지로딩 -->
|
||||
<script>
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
if(loader)
|
||||
loader.style.display = 'none';
|
||||
});
|
||||
|
||||
function submitForm() {
|
||||
$('#board_form').submit();
|
||||
}
|
||||
|
||||
|
||||
var dataTable; // DataTables 인스턴스 전역 변수
|
||||
var bookpageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
|
||||
|
||||
$(document).ready(function() {
|
||||
dataTable = $('#myTable').DataTable({
|
||||
"paging": true,
|
||||
"ordering": true,
|
||||
"searching": true,
|
||||
"pageLength": 100,
|
||||
"lengthMenu": [100, 200, 500, 1000],
|
||||
"language": {
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"search": "Live Search:"
|
||||
},
|
||||
// "order": [[3, 'desc']], // 잔액기준 내림차순 정렬
|
||||
"dom": 't<"bottom"ip>', // search 창과 lengthMenu 숨기기
|
||||
"footerCallback": function ( row, data, start, end, display ) {
|
||||
var api = this.api(), data;
|
||||
|
||||
var intVal = function (i) {
|
||||
return typeof i === 'string' ?
|
||||
i.replace(/[\$,]/g, '')*1 :
|
||||
typeof i === 'number' ?
|
||||
i : 0;
|
||||
};
|
||||
|
||||
totalInitialReceivable = api.column(4).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalSalesAmount = api.column(5).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalBalanceDue = api.column(6).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
|
||||
$(api.column(4).footer()).html(numberWithCommas(totalInitialReceivable));
|
||||
$(api.column(5).footer()).html(numberWithCommas(totalSalesAmount));
|
||||
$(api.column(6).footer()).html(numberWithCommas(totalBalanceDue));
|
||||
}
|
||||
});
|
||||
|
||||
var savedPageNumber = getCookie('bookpageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
|
||||
dataTable.on('page.dt', function() {
|
||||
var bookpageNumber = dataTable.page.info().page + 1;
|
||||
setCookie('bookpageNumber', bookpageNumber, 10);
|
||||
});
|
||||
|
||||
$('#myTable_length select').on('change', function() {
|
||||
var selectedValue = $(this).val();
|
||||
dataTable.page.len(selectedValue).draw();
|
||||
|
||||
savedPageNumber = getCookie('bookpageNumber');
|
||||
if (savedPageNumber) {
|
||||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function numberWithCommas(x) {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
}
|
||||
|
||||
var selectedSecondordnum = null;
|
||||
var selectedVendorName = null;
|
||||
|
||||
$(document).ready(function() {
|
||||
// 특정 열(td)에서만 클릭 이벤트를 설정합니다.
|
||||
$('#myTable').on('click', '.choice', function() {
|
||||
var trElement = $(this).closest('tr');
|
||||
|
||||
// .attr()을 사용하여 속성 값을 가져옵니다.
|
||||
selectedSecondordnum = trElement.attr('data-secondordnum');
|
||||
selectedVendorName = trElement.attr('data-secondord');
|
||||
|
||||
// 데이터가 잘 가져와지는지 콘솔에 출력해봅니다.
|
||||
console.log("Selected Vendor Name:", selectedVendorName);
|
||||
console.log("Selected Secondordnum:", selectedSecondordnum);
|
||||
|
||||
if (!selectedSecondordnum || !selectedVendorName) {
|
||||
console.error("secondordnum 또는 vendorName이 제대로 설정되지 않았습니다.");
|
||||
}
|
||||
});
|
||||
|
||||
// "새 기록" 버튼이 클릭되면 저장된 데이터를 사용합니다.
|
||||
$('#newRecordButton').on('click', function() {
|
||||
console.log("Selected Vendor Name:", selectedVendorName);
|
||||
console.log("Selected Secondordnum:", selectedSecondordnum);
|
||||
if (selectedVendorName && selectedSecondordnum) {
|
||||
openNewRecordModal(selectedVendorName, selectedSecondordnum);
|
||||
} else {
|
||||
alert('먼저 거래처를 선택하세요.');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function redirectToView(element, secondordnum) {
|
||||
var selectedSecondordnum = secondordnum;
|
||||
// 클릭된 <td> 요소의 부모 <tr>에서 data-secondord 속성을 가져옵니다.
|
||||
var vendorName = $(element).closest('tr').data('secondord');
|
||||
|
||||
// 기존에 같은 div가 있다면 제거
|
||||
$('#recordListModal .modal-header').empty();
|
||||
$('#recordListModal .vendor-name').empty();
|
||||
|
||||
// 거래처명을 표시할 div 요소 생성
|
||||
var companyNameDiv = $('<div>', {
|
||||
class: 'd-flex p-1 fs-4 m-1 mb-1 justify-content-center align-items-center vendor-name',
|
||||
text: vendorName
|
||||
});
|
||||
|
||||
selectedVendorName= vendorName;
|
||||
|
||||
// modal header에 거래처명 추가 (기존 h5 태그 위에)
|
||||
$('#recordListModal .modal-header').prepend('(' + selectedSecondordnum + ')');
|
||||
$('#recordListModal .modal-header').prepend(companyNameDiv);
|
||||
|
||||
$.ajax({
|
||||
url: 'get_records.php',
|
||||
type: 'GET',
|
||||
data: { secondordnum: selectedSecondordnum },
|
||||
success: function(data) {
|
||||
try {
|
||||
// JSON.parse 제거, data는 이미 JSON 객체임
|
||||
var records = Array.isArray(data) ? data : [];
|
||||
|
||||
var recordList = $('#recordList');
|
||||
recordList.empty();
|
||||
|
||||
if (records.length > 0) {
|
||||
records.forEach(function(record) {
|
||||
if (!record.primisedate || record.primisedate === '0000-00-00') {
|
||||
record.primisedate = '';
|
||||
}
|
||||
|
||||
// comment에 줄바꿈이나 특수 문자가 있을 경우 안전하게 변환
|
||||
let safeComment = JSON.stringify(record.comment)
|
||||
.replace(/\n/g, '\\n')
|
||||
.replace(/\r/g, '\\r')
|
||||
.replace(/"/g, '"') // 큰따옴표 이스케이프
|
||||
.replace(/'/g, '''); // 작은따옴표 이스케이프
|
||||
|
||||
recordList.append(
|
||||
'<li class="list-group-item d-flex justify-content-between align-items-center">' +
|
||||
record.recordTime + ' - ' + safeComment + ' - ' + record.primisedate +
|
||||
'<button type="button" class="btn btn-danger btn-sm" onclick="deleteRecord(' + record.num + ')">삭제</button>' +
|
||||
'<button type="button" class="btn btn-secondary btn-sm ms-2" onclick="editRecord(' + record.num + ')">수정</button>' +
|
||||
'</li>'
|
||||
);
|
||||
|
||||
});
|
||||
} else {
|
||||
recordList.append(
|
||||
'<li class="list-group-item text-center">' +
|
||||
'기록이 없습니다.' +
|
||||
'</li>'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
$('#recordListModal').modal('show');
|
||||
} catch (e) {
|
||||
console.error("Error processing data: ", e);
|
||||
}
|
||||
},
|
||||
error: function(error) {
|
||||
alert('오류 발생: ' + error.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function openNewRecordModal(vendorName, secondordNumber) {
|
||||
var today = new Date();
|
||||
|
||||
// UTC 시간을 기반으로 한국 시간을 계산합니다.
|
||||
var year = today.getUTCFullYear();
|
||||
var month = String(today.getUTCMonth() + 1).padStart(2, '0'); // 월은 0부터 시작하므로 1을 더합니다.
|
||||
var day = String(today.getUTCDate()).padStart(2, '0');
|
||||
var hours = String(today.getUTCHours() + 9).padStart(2, '0'); // UTC 시간을 기준으로 9시간을 더합니다.
|
||||
var minutes = String(today.getUTCMinutes()).padStart(2, '0');
|
||||
|
||||
if (hours >= 24) {
|
||||
hours = String(hours - 24).padStart(2, '0');
|
||||
day = String(parseInt(day) + 1).padStart(2, '0');
|
||||
}
|
||||
|
||||
var formattedDateTime = `${year}-${month}-${day}T${hours}:${minutes}`;
|
||||
|
||||
// 기존에 같은 div가 있다면 제거
|
||||
$('#recordEditModal .modal-header').empty();
|
||||
$('#recordEditModal .vendor-name').empty();
|
||||
|
||||
// 거래처명을 표시할 div 요소 생성
|
||||
var companyNameDiv = $('<div>', {
|
||||
class: 'd-flex p-1 fs-4 m-1 mb-1 justify-content-center align-items-center vendor-name',
|
||||
text: vendorName // 전달된 거래처 이름을 사용
|
||||
});
|
||||
|
||||
// modal header에 거래처명 추가
|
||||
$('#recordEditModal .modal-header').prepend('(' + secondordNumber + ') ');
|
||||
$('#recordEditModal .modal-header').prepend(companyNameDiv);
|
||||
|
||||
// Set form values
|
||||
$('#recordNum').val(0);
|
||||
// $('#primisedate').val(formattedDateTime.substring(0, 10)); // 오늘 날짜를 기본값으로 설정
|
||||
$('#primisedate').val(null); // 오늘 날짜를 기본값으로 설정
|
||||
$('#recordTime').val(formattedDateTime); // 현재 시간을 기본값으로 설정
|
||||
$('#comment').val('');
|
||||
$('#secondordID').val(secondordNumber);
|
||||
|
||||
// Show the modal
|
||||
$('#recordEditModal').modal('show');
|
||||
}
|
||||
|
||||
function editRecord(num) {
|
||||
// Ajax 요청으로 고유번호를 이용해 해당 레코드 데이터를 서버에서 가져온다.
|
||||
$.ajax({
|
||||
url: 'get_record_by_id.php', // 레코드 데이터를 가져오는 서버측 PHP 파일
|
||||
type: 'POST',
|
||||
data: { recordNum: num }, // 고유번호 전달
|
||||
success: function(response) {
|
||||
// JSON 데이터를 파싱하여 record 객체로 변환
|
||||
let record;
|
||||
try {
|
||||
record = JSON.parse(response); // response가 JSON 문자열이면 파싱
|
||||
} catch (e) {
|
||||
record = response; // 이미 객체일 경우 그대로 사용
|
||||
}
|
||||
|
||||
// 폼 초기화
|
||||
$('#recordForm')[0].reset();
|
||||
console.log(record);
|
||||
|
||||
if (!record) {
|
||||
alert('레코드 데이터를 불러오는 데 실패했습니다.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 기존에 같은 div가 있다면 제거
|
||||
$('#recordNum').val(record.num);
|
||||
$('#comment').val(decodeURIComponent(record.comment)); // 한글 인코딩 처리
|
||||
$('#secondordID').val(record.secondordnum);
|
||||
|
||||
// primisedate가 '0000-00-00'일 경우 공백으로 설정
|
||||
if (record.primisedate === '0000-00-00') {
|
||||
$('#primisedate').val('');
|
||||
} else {
|
||||
$('#primisedate').val(record.primisedate);
|
||||
}
|
||||
|
||||
// 거래처명을 표시할 div 요소 생성
|
||||
var companyNameDiv = $('<div>', {
|
||||
class: 'd-flex p-1 fs-4 m-1 mb-1 justify-content-center align-items-center vendor-name',
|
||||
text: record.secondordnum
|
||||
});
|
||||
|
||||
// modal header에 거래처명 추가
|
||||
$('#recordEditModal .modal-header').prepend('(' + record.secondordnum + ') ');
|
||||
$('#recordEditModal .modal-header').prepend(companyNameDiv);
|
||||
|
||||
// recordTime이 없을 경우 현재 시간으로 설정
|
||||
if (!record.recordTime) {
|
||||
var today = new Date();
|
||||
today.setHours(today.getHours() + 9); // UTC+9 시간 설정
|
||||
var formattedDateTime = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}-${String(today.getDate()).padStart(2, '0')}T${String(today.getHours()).padStart(2, '0')}:${String(today.getMinutes()).padStart(2, '0')}`;
|
||||
$('#recordTime').val(formattedDateTime);
|
||||
} else {
|
||||
$('#recordTime').val(record.recordTime);
|
||||
}
|
||||
|
||||
// 모달 창을 열어 수정 폼을 표시
|
||||
$('#recordEditModal').modal('show');
|
||||
},
|
||||
|
||||
error: function() {
|
||||
alert('레코드 데이터를 불러오는 데 오류가 발생했습니다.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('#recordForm').submit(function(event) {
|
||||
event.preventDefault();
|
||||
var formData = $(this).serialize();
|
||||
$.ajax({
|
||||
url: 'save_record.php',
|
||||
type: 'POST',
|
||||
data: formData,
|
||||
success: function(data) {
|
||||
|
||||
console.log(data);
|
||||
$('#recordEditModal').modal('hide');
|
||||
|
||||
// 테이블에서 해당 행을 찾고 약속일과 메모를 업데이트
|
||||
var row = $('tr[data-secondordnum="' + data.secondordnum + '"]');
|
||||
if (row.length > 0) {
|
||||
row.find('td[data-promisedate]').text(data.primisedate);
|
||||
row.find('td[data-memo]').text(data.comment);
|
||||
row.find('td[data-recordTime]').text(data.recordTime);
|
||||
}
|
||||
|
||||
// 모달 닫은 후 리로드
|
||||
$('#recordListModal').modal('hide');
|
||||
},
|
||||
error: function(error) {
|
||||
alert('오류 발생: ' + error.responseText);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function deleteRecord(num) {
|
||||
if (confirm('정말로 삭제하시겠습니까?')) {
|
||||
$.ajax({
|
||||
url: 'delete_record.php',
|
||||
type: 'POST',
|
||||
data: { num: num },
|
||||
success: function(data) {
|
||||
// 삭제된 기록의 정보가 반환됩니다.
|
||||
if (data && data.secondordnum) {
|
||||
// 테이블에서 해당 행을 찾아서 갱신합니다.
|
||||
var row = $('tr[data-secondordnum="' + data.secondordnum + '"]');
|
||||
if (row.length > 0) {
|
||||
// 약속일과 메모를 비워줍니다.
|
||||
row.find('td[data-promisedate]').text('');
|
||||
row.find('td[data-memo]').text('');
|
||||
row.find('td[data-recordTime]').text('');
|
||||
}
|
||||
}
|
||||
|
||||
// 폼 초기화
|
||||
$('#recordForm')[0].reset();
|
||||
|
||||
// 모달의 리스트를 다시 로드합니다.
|
||||
redirectToView(this, data.secondordnum);
|
||||
},
|
||||
error: function(error) {
|
||||
alert('오류 발생: ' + error.responseText);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function openMonthlyBalancePopup() {
|
||||
var url = "monthly_balance_popup.php";
|
||||
customPopup(url, '거래원장', 1000, 850);
|
||||
}
|
||||
|
||||
|
||||
function ViewtoCustomerSheet(num) {
|
||||
var fromdate = '2024-03-01'; // 고정된 시작 날짜
|
||||
var today = new Date();
|
||||
var year = today.getFullYear();
|
||||
var month = String(today.getMonth() + 1).padStart(2, '0');
|
||||
var day = String(today.getDate()).padStart(2, '0');
|
||||
var todate = year + '-' + month + '-' + day; // 현재 날짜
|
||||
|
||||
var url = "customer_sheet.php?num=" + num + "&fromdate=" + fromdate + "&todate=" + todate;
|
||||
customPopup(url, '거래원장', 1000, 850);
|
||||
}
|
||||
|
||||
|
||||
$(document).ready(function(){
|
||||
saveLogData('미수금 현황');
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
668
account_juil/receivablelist.php
Normal file
668
account_juil/receivablelist.php
Normal file
@@ -0,0 +1,668 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
// 에러 표시 설정
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
$title_message = '금전 출납부';
|
||||
?>
|
||||
|
||||
<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;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/myheader.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");
|
||||
$todate = $currentDate;
|
||||
$Transtodate = $todate;
|
||||
} else {
|
||||
$Transtodate = $todate;
|
||||
}
|
||||
|
||||
function checkNull($strtmp) {
|
||||
return $strtmp !== null && trim($strtmp) !== '';
|
||||
}
|
||||
|
||||
$tablename = 'account_juil';
|
||||
|
||||
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 amount ELSE 0 END) -
|
||||
SUM(CASE WHEN inoutsep = '지출' THEN amount ELSE 0 END) AS balance
|
||||
FROM $tablename WHERE is_deleted = '0' AND registDate < :fromdate";
|
||||
$initialBalanceStmh = $pdo->prepare($initialBalanceSql);
|
||||
$initialBalanceStmh->bindParam(':fromdate', $fromdate);
|
||||
$initialBalanceStmh->execute();
|
||||
$initialBalance = $initialBalanceStmh->fetch(PDO::FETCH_ASSOC)['balance'];
|
||||
|
||||
$totalIncomeSql = "SELECT SUM(amount) AS totalIncome FROM $tablename WHERE is_deleted = '0' AND inoutsep = '수입' AND registDate BETWEEN :fromdate AND :todate";
|
||||
$totalIncomeStmh = $pdo->prepare($totalIncomeSql);
|
||||
$totalIncomeStmh->bindParam(':fromdate', $fromdate);
|
||||
$totalIncomeStmh->bindParam(':todate', $todate);
|
||||
$totalIncomeStmh->execute();
|
||||
$totalIncome = $totalIncomeStmh->fetch(PDO::FETCH_ASSOC)['totalIncome'];
|
||||
|
||||
$totalExpenseSql = "SELECT SUM(amount) AS totalExpense FROM $tablename WHERE is_deleted = '0' AND inoutsep = '지출' AND registDate BETWEEN :fromdate AND :todate";
|
||||
$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 = [];
|
||||
$bankbookFilePath = $_SERVER['DOCUMENT_ROOT'] . "/account_juil/bankbook.txt";
|
||||
if (file_exists($bankbookFilePath)) {
|
||||
$bankbookOptions = file($bankbookFilePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
|
||||
<input type="hidden" id="mode" name="mode" value="<?=$mode?>">
|
||||
<input type="hidden" id="num" name="num">
|
||||
<input type="hidden" id="tablename" name="tablename" value="<?=$tablename?>">
|
||||
|
||||
<div class="container-fluid">
|
||||
<!-- Modal -->
|
||||
<div id="myModal" class="modal">
|
||||
<div class="modal-content" style="width:800px;">
|
||||
<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">
|
||||
<div class="card justify-content-center text-center mt-5">
|
||||
<div class="card-header">
|
||||
<span class="text-center fs-5"> <?=$title_message?> </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">
|
||||
<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-control me-1" style="width:50px;">
|
||||
<option value="">전체</option>
|
||||
<option value="수입" <?= $inoutsep_select === '수입' ? 'selected' : '' ?>>수입</option>
|
||||
<option value="지출" <?= $inoutsep_select === '지출' ? 'selected' : '' ?>>지출</option>
|
||||
</select>
|
||||
|
||||
<!-- 두 번째 select 문: 항목 선택 -->
|
||||
<select id="content_select" name="content_select" class="form-control me-1" style="width:100px;">
|
||||
<option value="">전체</option>
|
||||
<?php
|
||||
$incomeOptions = [
|
||||
'거래처 수금' => '거래처에서 입금한 금액',
|
||||
'최초 현금 입력' => '금전출납부 시작'
|
||||
];
|
||||
|
||||
$expenseOptions = [
|
||||
'급여(인건비)' => '직원 급여',
|
||||
'접대비' => '경조사비용',
|
||||
'통신비' => '전화요금, 인터넷요금',
|
||||
'세금과공과금' => '등록면허세, 취득세, 재산세등 각종세금',
|
||||
'차량유지비' => '유류대, 통행료',
|
||||
'보험료' => '차량보험료, 화재보험료등',
|
||||
'운반비' => '택배운반비외 각종운반비',
|
||||
'소모품비' => '각종 소모품 비용',
|
||||
'수수료비용' => '이체수수료, 등기수수료등',
|
||||
'복리후생비' => '직원 식대외 직원 작업복등',
|
||||
'개발비' => '프로그램 개발비용',
|
||||
'이자비용' => '이자비용',
|
||||
'카드대금' => '카드대금',
|
||||
'통관비' => '통관비',
|
||||
'자재비' => '자재비'
|
||||
];
|
||||
$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 id="newBtn" type="button" class="btn btn-dark btn-sm me-2"> <i class="bi bi-pencil-square"></i> 신규 </button>
|
||||
<button type="button" class="btn btn-secondary btn-sm me-1" onclick='location.reload();'> <i class="bi bi-arrow-clockwise"></i> 새로고침 </button>
|
||||
<button type="button" class="btn btn-dark btn-sm me-2" onclick="generateExcel();" > <i class="bi bi-file-earmark-spreadsheet"></i> 엑셀다운로드 </button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row w400px m-1 mt-2">
|
||||
<table class="table table-bordered">
|
||||
<thead class="table-secondary">
|
||||
<tr>
|
||||
<?php
|
||||
$tmp = ' ' . $bankbookOptions[0] . ' (계좌 잔액) : ';
|
||||
if (isset($finalBalance)) {
|
||||
$tmp_balance = number_format($finalBalance);
|
||||
}
|
||||
?>
|
||||
<th class="text-center" style="width:200px;"> <?=$tmp?> </th>
|
||||
<th class="text-end text-primary fw-bold" style="width:100px;"> <?=$tmp_balance?> </th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover" id="myTable">
|
||||
<thead class="table-info">
|
||||
<tr>
|
||||
<th class="text-center" style="width:60px;">번호</th>
|
||||
<th class="text-center" style="width:100px;">등록일자</th>
|
||||
<th class="text-center" style="width:100px;">항목</th>
|
||||
<th class="text-center" style="width:150px;">상세내용</th>
|
||||
<th class="text-center" style="width:100px;">수입</th>
|
||||
<th class="text-center" style="width:100px;">지출</th>
|
||||
<th class="text-center" style="width:100px;">잔액</th>
|
||||
<th class="text-center" style="width:200px;">적요</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$start_num = $total_row;
|
||||
$counter = 1;
|
||||
$balance = $initialBalance; // 초기 잔액 설정
|
||||
while($row = $stmh->fetch(PDO::FETCH_ASSOC)) {
|
||||
include '_row.php';
|
||||
if ($inoutsep === '수입') {
|
||||
$balance += $amount;
|
||||
} else {
|
||||
$balance -= $amount;
|
||||
}
|
||||
?>
|
||||
<tr onclick="loadForm('update', '<?=$num?>');">
|
||||
<td class="text-center"><?= $counter ?></td>
|
||||
<td class="text-center"><?= $registDate ?></td>
|
||||
<td class="text-center fw-bold "> <?= $content ?> </td>
|
||||
|
||||
<td class="text-start"><?= $content_detail ?></td>
|
||||
<?php if ($inoutsep === '수입') : ?>
|
||||
<td class="text-end fw-bold text-primary">
|
||||
<?= 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">
|
||||
<?= is_numeric($amount) ? number_format($amount) : htmlspecialchars($amount) ?>
|
||||
</td>
|
||||
<?php endif; ?>
|
||||
<td class="text-end fw-bold"><?= number_format($balance) ?></td>
|
||||
<td class="text-start"><?= $dueDate ?></td>
|
||||
</tr>
|
||||
<?php
|
||||
$start_num--;
|
||||
$counter++;
|
||||
}
|
||||
} catch (PDOException $Exception) {
|
||||
print "오류: ".$Exception->getMessage();
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot class="table-secondary">
|
||||
<tr>
|
||||
<th class="text-end" colspan="4"> 합계 </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"></th>
|
||||
|
||||
</tr>
|
||||
</tfoot>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<script>
|
||||
// 페이지 로딩
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
loader.style.display = 'none';
|
||||
});
|
||||
|
||||
|
||||
function numberWithCommas(x) {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const initialBalance = <?= json_encode($initialBalance) ?>;
|
||||
const finalBalance = <?= json_encode($finalBalance) ?>;
|
||||
|
||||
$(document).ready(function() {
|
||||
dataTable = $('#myTable').DataTable({
|
||||
"paging": true,
|
||||
"ordering": true,
|
||||
"searching": true,
|
||||
"pageLength": 2000,
|
||||
"lengthMenu": [2000],
|
||||
"language": {
|
||||
"lengthMenu": "Show _MENU_ entries",
|
||||
"search": "Live Search:"
|
||||
},
|
||||
// "order": [[0, 'desc']],
|
||||
"dom": 't<"bottom"ip>',
|
||||
"footerCallback": function (row, data, start, end, display) {
|
||||
var api = this.api(), data;
|
||||
|
||||
var intVal = function (i) {
|
||||
return typeof i === 'string' ?
|
||||
i.replace(/[\$,]/g, '')*1 :
|
||||
typeof i === 'number' ?
|
||||
i : 0;
|
||||
};
|
||||
|
||||
totalIncomeAmount = api.column(4, { page: 'current' }).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
totalExpenseAmount = api.column(5, { page: 'current' }).data().reduce(function (a, b) { return intVal(a) + intVal(b); }, 0);
|
||||
|
||||
$(api.column(4).footer()).html(numberWithCommas(totalIncomeAmount));
|
||||
$(api.column(5).footer()).html(numberWithCommas(totalExpenseAmount));
|
||||
$(api.column(6).footer()).html(numberWithCommas(finalBalance));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
|
||||
let isSaving = false;
|
||||
var ajaxRequest = null;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
$("#newBtn").on("click", function() {
|
||||
loadForm('insert');
|
||||
});
|
||||
|
||||
$("#searchBtn").on("click", function() {
|
||||
$("#board_form").submit();
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
function loadForm(mode, num = null) {
|
||||
if (num == null) {
|
||||
$("#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();
|
||||
|
||||
const expenseOptions = {
|
||||
'급여(인건비)': '직원 급여',
|
||||
'접대비': '경조사비용',
|
||||
'통신비': '전화요금, 인터넷요금',
|
||||
'세금과공과금': '등록면허세, 취득세, 재산세등 각종세금',
|
||||
'차량유지비': '유류대, 통행료',
|
||||
'보험료': '차량보험료, 화재보험료등',
|
||||
'운반비': '택배운반비외 각종운반비',
|
||||
'소모품비': '각종 소모품 비용',
|
||||
'수수료비용': '이체수수료, 등기수수료등',
|
||||
'복리후생비': '직원 식대외 직원 작업복등',
|
||||
'개발비': '프로그램 개발비용',
|
||||
'이자비용': '이자비용',
|
||||
'카드대금': '카드대금',
|
||||
'통관비': '통관비',
|
||||
'자재비': '자재비',
|
||||
'기계장치' : '기계구입'
|
||||
};
|
||||
|
||||
const incomeOptions = {
|
||||
'거래처 수금': '거래처에서 입금한 금액',
|
||||
'최초 현금 입력': '금전출납부 시작'
|
||||
};
|
||||
|
||||
function updateDescription() {
|
||||
const contentSelect = document.getElementById('content');
|
||||
const descriptionDiv = document.getElementById('content_description');
|
||||
if (contentSelect && descriptionDiv) {
|
||||
const selectedValue = contentSelect.value;
|
||||
const descriptions = document.querySelector('input[name="inoutsep"]:checked').value === '수입' ? incomeOptions : expenseOptions;
|
||||
descriptionDiv.innerText = descriptions[selectedValue] || '';
|
||||
}
|
||||
}
|
||||
|
||||
function updateContentOptions() {
|
||||
const contentSelect = document.getElementById('content');
|
||||
if (contentSelect) {
|
||||
contentSelect.innerHTML = '';
|
||||
|
||||
const options = document.querySelector('input[name="inoutsep"]:checked').value === '수입' ? incomeOptions : expenseOptions;
|
||||
|
||||
for (const [value, text] of Object.entries(options)) {
|
||||
const option = document.createElement('option');
|
||||
option.value = value;
|
||||
option.text = value;
|
||||
contentSelect.appendChild(option);
|
||||
}
|
||||
|
||||
updateDescription();
|
||||
}
|
||||
}
|
||||
|
||||
// 추가된 스크립트를 실행하도록 보장
|
||||
// updateContentOptions();
|
||||
|
||||
$(document).on("click", "#closeBtn", function() {
|
||||
$("#myModal").hide();
|
||||
});
|
||||
|
||||
|
||||
$(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(),
|
||||
bankbook: $("#bankbook").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);
|
||||
|
||||
},
|
||||
error: function(jqxhr, status, error) {
|
||||
console.log("AJAX error in loadForm:", status, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 페이지 로딩
|
||||
$(document).ready(function(){
|
||||
var loader = document.getElementById('loadingOverlay');
|
||||
loader.style.display = 'none';
|
||||
});
|
||||
</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['contentDetail'] = cells[3]?.innerText || '';
|
||||
rowData['income'] = cells[4]?.innerText || '';
|
||||
rowData['expense'] = cells[5]?.innerText || '';
|
||||
rowData['balance'] = cells[6]?.innerText || '';
|
||||
rowData['dueDate'] = cells[7]?.innerText || '';
|
||||
|
||||
data.push(rowData);
|
||||
}
|
||||
|
||||
// saveExcel.php에 데이터 전송
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "order_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 = 'downloadExcel.php?filename=' + encodeURIComponent(response.filename.split('/').pop());
|
||||
} 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));
|
||||
}
|
||||
</script>
|
||||
|
||||
26
account_juil/saveAccountContents.php
Normal file
26
account_juil/saveAccountContents.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
$fileName = $_POST['fileName'] ?? 'accountContents.json';
|
||||
$backupFileName = $_POST['backupFileName'] ?? '';
|
||||
$data = $_POST['data'] ?? '';
|
||||
|
||||
// JSON 폴더 경로 확인 및 생성
|
||||
$jsonFolder = $_SERVER['DOCUMENT_ROOT'] . '/account_juil/json/'; //################### 폴더 위치 주의 //
|
||||
if (!is_dir($jsonFolder)) {
|
||||
mkdir($jsonFolder, 0755, true); // 폴더 생성
|
||||
}
|
||||
|
||||
// 데이터 저장
|
||||
if (!empty($backupFileName)) {
|
||||
$backupFilePath = $jsonFolder . basename($backupFileName);
|
||||
file_put_contents($backupFilePath, $data); // 백업 파일 저장
|
||||
}
|
||||
|
||||
$filePath = basename($fileName);
|
||||
file_put_contents($filePath, $data); // 원본 파일 저장
|
||||
|
||||
echo json_encode(['message' => '데이터가 저장되었습니다.']);
|
||||
} else {
|
||||
http_response_code(405);
|
||||
echo json_encode(['message' => 'Invalid request method.']);
|
||||
}
|
||||
90
account_juil/saveExcel.php
Normal file
90
account_juil/saveExcel.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||
// JSON 데이터 받기
|
||||
$jsonData = file_get_contents('php://input');
|
||||
$data = json_decode($jsonData, true);
|
||||
|
||||
if (!$data) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid JSON data']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// PHPExcel 라이브러리 포함
|
||||
require_once($_SERVER['DOCUMENT_ROOT'] . '/PHPExcel_1.8.0/Classes/PHPExcel.php');
|
||||
|
||||
// 새로운 PHPExcel 객체 생성
|
||||
$objPHPExcel = new PHPExcel();
|
||||
$objPHPExcel->setActiveSheetIndex(0);
|
||||
$sheet = $objPHPExcel->getActiveSheet();
|
||||
|
||||
// 헤더 설정
|
||||
$headers = ['번호', '등록일자', '항목', '세부항목', '상세내용', '수입', '지출', '잔액', '적요'];
|
||||
$col = 'A';
|
||||
foreach ($headers as $header) {
|
||||
$sheet->setCellValue($col . '1', $header);
|
||||
// 헤더 스타일 설정
|
||||
$sheet->getStyle($col . '1')->getFont()->setBold(true);
|
||||
$sheet->getStyle($col . '1')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);
|
||||
$sheet->getStyle($col . '1')->getFill()->getStartColor()->setRGB('D9D9D9');
|
||||
$col++;
|
||||
}
|
||||
|
||||
// 데이터 입력
|
||||
$row = 2;
|
||||
foreach ($data as $item) {
|
||||
$sheet->setCellValue('A' . $row, $item['number']);
|
||||
$sheet->setCellValue('B' . $row, $item['registDate']);
|
||||
$sheet->setCellValue('C' . $row, $item['content']);
|
||||
$sheet->setCellValue('D' . $row, $item['contentSub']);
|
||||
$sheet->setCellValue('E' . $row, $item['contentDetail']);
|
||||
$sheet->setCellValue('F' . $row, $item['income']);
|
||||
$sheet->setCellValue('G' . $row, $item['expense']);
|
||||
$sheet->setCellValue('H' . $row, $item['balance']);
|
||||
$sheet->setCellValue('I' . $row, $item['dueDate']);
|
||||
$row++;
|
||||
}
|
||||
|
||||
// 열 너비 자동 조정
|
||||
foreach(range('A','I') as $columnID) {
|
||||
$sheet->getColumnDimension($columnID)->setAutoSize(true);
|
||||
}
|
||||
|
||||
// 파일 저장
|
||||
$filename = 'account_' . date('Ymd_His') . '.xlsx';
|
||||
$filepath = $_SERVER['DOCUMENT_ROOT'] . '/account_juil/excel/' . $filename;
|
||||
|
||||
// 디렉토리가 없으면 생성
|
||||
if (!file_exists($_SERVER['DOCUMENT_ROOT'] . '/account_juil/excel')) {
|
||||
mkdir($_SERVER['DOCUMENT_ROOT'] . '/account_juil/excel', 0777, true);
|
||||
}
|
||||
|
||||
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
|
||||
$objWriter->save($filepath);
|
||||
|
||||
echo json_encode(['success' => true, 'filename' => $filename]);
|
||||
exit;
|
||||
}
|
||||
else if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['download'])) {
|
||||
// 파일 다운로드 처리
|
||||
$filename = $_GET['download'];
|
||||
$filepath = $_SERVER['DOCUMENT_ROOT'] . '/account_juil/excel/' . $filename;
|
||||
|
||||
if (file_exists($filepath)) {
|
||||
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||
header('Cache-Control: max-age=0');
|
||||
readfile($filepath);
|
||||
|
||||
// 파일 삭제
|
||||
unlink($filepath);
|
||||
exit;
|
||||
} else {
|
||||
echo "File not found";
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid request method']);
|
||||
exit;
|
||||
}
|
||||
394
account_juil/settings.php
Normal file
394
account_juil/settings.php
Normal file
@@ -0,0 +1,394 @@
|
||||
<?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;
|
||||
}
|
||||
// 에러 표시 설정
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
||||
$title_message = '계정관리(수입,지출)';
|
||||
?>
|
||||
|
||||
<title> <?=$title_message?> </title>
|
||||
|
||||
<style>
|
||||
.editable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* +, - 버튼 패딩 2px 4px로 */
|
||||
.add-main-account, .add-sub-account, .delete-account {
|
||||
padding: 2px 4px !important;
|
||||
}
|
||||
|
||||
/* 각 list 아이템의 padding을 절반으로 */
|
||||
.list-group-item {
|
||||
padding-top: 0.5rem !important;
|
||||
padding-bottom: 0.5rem !important;
|
||||
padding-left: 0.75rem !important;
|
||||
padding-right: 0.75rem !important;
|
||||
}
|
||||
|
||||
/* card 요소의 여백(패딩/마진) 절반으로 줄이기 */
|
||||
.card {
|
||||
padding: 0.5rem !important;
|
||||
margin-bottom: 0.5rem !important;
|
||||
}
|
||||
.card-body, .card-header, .card-footer {
|
||||
padding: 0.5rem !important;
|
||||
}
|
||||
|
||||
/* 1단계 트리 노드(최상위 계정) 폰트 크기 크게 */
|
||||
.editable[data-level="0"] {
|
||||
font-size: 1.15rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<div class="d-flex justify-content-start mb-1">
|
||||
<h3>수입/지출 계정 관리</h3> <button type="button" class="btn btn-dark btn-sm ms-3 me-2" onclick='location.reload()'> <i class="bi bi-arrow-clockwise"></i> </button>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end mb-3">
|
||||
<button class="btn btn-dark btn-sm me-1 ms-1 saveData">
|
||||
<i class="bi bi-floppy2-fill"></i> 저장
|
||||
</button>
|
||||
<button class="btn btn-secondary btn-sm" onclick="self.close();">
|
||||
<i class="bi bi-x-lg"></i> 닫기
|
||||
</button>
|
||||
</div>
|
||||
<ul id="accountList" class="list-group"></ul>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
// 로딩 오버레이 제거
|
||||
var loader = $('#loadingOverlay');
|
||||
if (loader.length) {
|
||||
loader.hide();
|
||||
}
|
||||
|
||||
const fileName = '/account_juil/accountContents.json';
|
||||
let accountData = {}; // 데이터를 전역 변수로 관리
|
||||
|
||||
/*캐시 문제
|
||||
$.getJSON(fileName, ...)로 JSON 파일을 불러올 때, 브라우저가 파일을 캐시하고 있을 가능성이 있습니다. 이 경우 파일을 저장한 후에도 이전 캐시된 데이터가 불러와져 최신 수정 내용이 반영되지 않을 수 있습니다.
|
||||
해결 방법으로는 AJAX 요청 시 캐시 방지 파라미터(예: 타임스탬프)를 추가하거나, jQuery의 AJAX 설정에서 cache: false 옵션을 사용하는 방법이 있습니다.
|
||||
*/
|
||||
|
||||
function loadAccounts() {
|
||||
$.getJSON(fileName + '?_=' + new Date().getTime(), function (data) {
|
||||
// console.log('Loaded Account Data:', data);
|
||||
accountData = data;
|
||||
renderAccounts(data);
|
||||
}).fail(function () {
|
||||
alert('JSON 파일을 로드할 수 없습니다.');
|
||||
});
|
||||
}
|
||||
|
||||
// JSON 데이터 저장
|
||||
function saveAccounts() {
|
||||
const now = new Date();
|
||||
const formattedDate = now.toISOString().slice(0, 10).replace(/-/g, '');
|
||||
const formattedTime = now.toTimeString().slice(0, 8).replace(/:/g, '');
|
||||
const backupFileName = `${formattedDate}_${formattedTime}_backup.json`;
|
||||
|
||||
$.post('/account_juil/saveAccountContents.php', {
|
||||
fileName,
|
||||
backupFileName,
|
||||
data: JSON.stringify(accountData)
|
||||
}, function (response) {
|
||||
const result = JSON.parse(response);
|
||||
Swal.fire('저장 완료', `데이터가 서버에 저장되었습니다.\n백업 파일: ${backupFileName}`, 'success');
|
||||
|
||||
setTimeout(function() {
|
||||
// 부모 창 리로드
|
||||
if (window.opener && !window.opener.closed) {
|
||||
window.opener.location.reload();
|
||||
}
|
||||
|
||||
// 자신을 1.5초 후 리로드
|
||||
setTimeout(function() {
|
||||
window.location.reload();
|
||||
}, 2000);
|
||||
}, 1500);
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// 계정 렌더링
|
||||
function renderAccounts(data) {
|
||||
$('#accountList').empty();
|
||||
$.each(data, function (category, accounts) {
|
||||
const categoryItem = $(`<li class="list-group-item">
|
||||
<span class="editable" data-category="${category}" data-level="0">${category}</span>
|
||||
<button class="btn btn-sm btn-outline-primary ms-2 add-main-account" data-category="${category}">+</button>
|
||||
<ul class="list-group mt-2 ms-3"></ul>
|
||||
</li>`);
|
||||
const subAccountList = categoryItem.find('ul');
|
||||
$.each(accounts, function (accountName, accountDetails) {
|
||||
appendAccountItem(subAccountList, category, accountName, accountDetails, category);
|
||||
});
|
||||
$('#accountList').append(categoryItem);
|
||||
});
|
||||
}
|
||||
|
||||
// 하위 계정 추가
|
||||
function appendAccountItem(parentList, category, accountName, accountDetails, parentName) {
|
||||
// 디버깅용 로그 추가
|
||||
// console.log('Appending Account:', {
|
||||
// category,
|
||||
// accountName,
|
||||
// accountDetails,
|
||||
// parentName,
|
||||
// });
|
||||
|
||||
// 추가 버튼 여부 결정
|
||||
const addButton = accountDetails.level < 2 ? `
|
||||
<button class="btn btn-sm btn-outline-primary ms-2 add-sub-account"
|
||||
data-category="${category}"
|
||||
data-account="${accountName}">
|
||||
+
|
||||
</button>
|
||||
` : ''; // level 3에서는 추가 버튼이 나오지 않음
|
||||
|
||||
const accountItem = $(`<li class="list-group-item">
|
||||
<span class="editable"
|
||||
data-category="${category}"
|
||||
data-account="${accountName}"
|
||||
data-level="${accountDetails.level}"
|
||||
data-description="${accountDetails.description}"
|
||||
data-parent="${parentName}">
|
||||
${accountName}
|
||||
</span>
|
||||
${addButton}
|
||||
<button class="btn btn-sm btn-outline-danger ms-2 delete-account"
|
||||
data-category="${category}"
|
||||
data-account="${accountName}">
|
||||
-
|
||||
</button>
|
||||
<ul class="list-group mt-2 ms-3"></ul>
|
||||
</li>`);
|
||||
|
||||
const subAccountList = accountItem.find('ul');
|
||||
|
||||
// 하위 계정이 있을 경우 처리
|
||||
if (accountDetails.하위계정 && accountDetails.하위계정.length > 0) {
|
||||
accountDetails.하위계정.forEach(subAccount => {
|
||||
const subAccountName = Object.keys(subAccount)[0];
|
||||
const subAccountDetails = subAccount[subAccountName];
|
||||
|
||||
// 디버깅용 로그 추가
|
||||
// console.log('Appending Sub Account:', {
|
||||
// subAccountName,
|
||||
// subAccountDetails,
|
||||
// });
|
||||
|
||||
appendAccountItem(subAccountList, category, subAccountName, subAccountDetails, accountName);
|
||||
});
|
||||
} else {
|
||||
console.log(`No Sub Accounts for: ${accountName}`);
|
||||
}
|
||||
|
||||
parentList.append(accountItem);
|
||||
}
|
||||
|
||||
|
||||
// 계정 추가
|
||||
function addAccount(category, parentAccount, name, description, isMain) {
|
||||
if (isMain) {
|
||||
accountData[category][name] = {
|
||||
level: 1,
|
||||
description,
|
||||
parent: category,
|
||||
하위계정: []
|
||||
};
|
||||
} else {
|
||||
const parent = accountData[category][parentAccount];
|
||||
if (!parent.하위계정) parent.하위계정 = [];
|
||||
parent.하위계정.push({
|
||||
[name]: {
|
||||
level: (parent.level || 1) + 1,
|
||||
description,
|
||||
parent: parentAccount,
|
||||
하위계정: []
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 계정 삭제
|
||||
function deleteAccount(category, account) {
|
||||
const parentAccount = accountData[category];
|
||||
if (parentAccount[account]) {
|
||||
delete parentAccount[account];
|
||||
} else {
|
||||
// Find and delete in subaccounts
|
||||
$.each(parentAccount, function (key, value) {
|
||||
if (value.하위계정) {
|
||||
const index = value.하위계정.findIndex(sub => Object.keys(sub)[0] === account);
|
||||
if (index !== -1) {
|
||||
value.하위계정.splice(index, 1);
|
||||
return false; // Exit loop
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 계정 수정
|
||||
$('#accountList').on('click', '.editable', function () {
|
||||
const currentName = $(this).text().trim(); // 현재 계정 이름
|
||||
const currentDescription = $(this).data('description') || ''; // 현재 설명
|
||||
const parentCategory = $(this).closest('ul').closest('li').find('> .editable').data('category'); // 최상위 카테고리
|
||||
const level = $(this).data('level'); // 계정 레벨 정보
|
||||
|
||||
// 디버깅 정보 출력
|
||||
// console.log('DEBUG: currentName =', currentName);
|
||||
// console.log('DEBUG: currentDescription =', currentDescription);
|
||||
// console.log('DEBUG: parentCategory =', parentCategory);
|
||||
// console.log('DEBUG: level =', level);
|
||||
|
||||
// 최상위 레벨은 수정 불가
|
||||
if (level !== 1 && level !== 2 ) {
|
||||
Swal.fire('알림', '최상위 계정은 수정할 수 없습니다.', 'info');
|
||||
return;
|
||||
}
|
||||
|
||||
Swal.fire({
|
||||
title: '계정 수정',
|
||||
html: `
|
||||
<input type="text" id="accountName" class="swal2-input" placeholder="새 계정 이름" value="${currentName}" autocomplete="off">
|
||||
<input type="text" id="accountDescription" class="swal2-input" placeholder="새 계정 설명" value="${currentDescription}" autocomplete="off">
|
||||
`,
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '수정',
|
||||
cancelButtonText: '취소',
|
||||
preConfirm: () => {
|
||||
const newName = $('#accountName').val().trim();
|
||||
const newDescription = $('#accountDescription').val().trim();
|
||||
|
||||
if (!newName || !newDescription) {
|
||||
Swal.showValidationMessage('모든 입력란을 채워주세요.');
|
||||
}
|
||||
return { newName, newDescription };
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
const { newName, newDescription } = result.value;
|
||||
|
||||
try {
|
||||
let found = false;
|
||||
|
||||
// 최상위 카테고리 탐색
|
||||
if (accountData[parentCategory]) {
|
||||
$.each(accountData[parentCategory], function (key, value) {
|
||||
if (key === currentName) {
|
||||
// 최상위 계정 수정
|
||||
accountData[parentCategory][newName] = value;
|
||||
delete accountData[parentCategory][currentName];
|
||||
accountData[parentCategory][newName].description = newDescription;
|
||||
found = true;
|
||||
return false; // 루프 종료
|
||||
}
|
||||
|
||||
// 하위 계정 탐색
|
||||
if (value.하위계정) {
|
||||
value.하위계정.forEach((subAccount, index) => {
|
||||
const subAccountName = Object.keys(subAccount)[0];
|
||||
if (subAccountName === currentName) {
|
||||
// 하위 계정 수정
|
||||
value.하위계정[index] = {
|
||||
[newName]: {
|
||||
...subAccount[subAccountName],
|
||||
description: newDescription
|
||||
}
|
||||
};
|
||||
found = true;
|
||||
return false; // 루프 종료
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
throw new Error(`계정을 찾을 수 없습니다. currentName: ${currentName}, parentCategory: ${parentCategory}`);
|
||||
}
|
||||
|
||||
renderAccounts(accountData); // UI 업데이트
|
||||
} catch (error) {
|
||||
console.error('Error updating account:', error);
|
||||
Swal.fire('오류', `계정을 수정하는 중 문제가 발생했습니다.\n${error.message}`, 'error');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// 버튼 핸들러
|
||||
$('#accountList').on('click', '.add-main-account, .add-sub-account, .delete-account', function () {
|
||||
const isMain = $(this).hasClass('add-main-account');
|
||||
const isDelete = $(this).hasClass('delete-account');
|
||||
const category = $(this).data('category');
|
||||
const account = $(this).data('account');
|
||||
|
||||
if (isDelete) {
|
||||
Swal.fire({
|
||||
title: '삭제 확인',
|
||||
text: '해당 계정을 삭제하시겠습니까?',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '삭제',
|
||||
cancelButtonText: '취소'
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
deleteAccount(category, account);
|
||||
renderAccounts(accountData);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
title: isMain ? `${category}의 하위 계정 추가` : `${account}의 하위 계정 추가`,
|
||||
html: `
|
||||
<input type="text" id="accountName" class="swal2-input" placeholder="계정 이름" autocomplete="off">
|
||||
<input type="text" id="accountDescription" class="swal2-input" placeholder="계정 설명" autocomplete="off">
|
||||
`,
|
||||
focusConfirm: false,
|
||||
showCancelButton: true,
|
||||
preConfirm: () => {
|
||||
const name = $('#accountName').val().trim();
|
||||
const description = $('#accountDescription').val().trim();
|
||||
if (!name || !description) {
|
||||
Swal.showValidationMessage('모든 입력란을 채워주세요.');
|
||||
}
|
||||
return { name, description };
|
||||
}
|
||||
}).then(result => {
|
||||
if (result.isConfirmed) {
|
||||
const { name, description } = result.value;
|
||||
addAccount(category, account, name, description, isMain);
|
||||
renderAccounts(accountData);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 저장 버튼 클릭
|
||||
$('.saveData').on('click', saveAccounts);
|
||||
|
||||
loadAccounts();
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user