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

472 lines
27 KiB
PHP

<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
$title_message = '매출 통계';
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><?= $title_message ?></title>
</head>
<body>
<?php
$header = isset($_REQUEST['header']) ? $_REQUEST['header'] : '';
$active_tab = isset($_REQUEST['active_tab']) ? $_REQUEST['active_tab'] : 'sales';
// 세무사아이디면 다른 메뉴 연결
if($_SESSION["userid"] == '0266771300') {
include $_SERVER['DOCUMENT_ROOT'] . '/myheader_accountant.php';
}
else {
include $_SERVER['DOCUMENT_ROOT'] . '/myheader.php';
}
$tablename = 'output';
$tablename_sub = 'output_extra';
// 매년 1월1일부터 현재일까지 계산
$fromdate = isset($_REQUEST['fromdate']) && $_REQUEST['fromdate'] ? $_REQUEST['fromdate'] : date("Y-m-01"); // 이번 달 1일
$todate = isset($_REQUEST['todate']) && $_REQUEST['todate'] ? $_REQUEST['todate'] : date("Y-m-d"); // 오늘 날짜
$transtodate = date("Y-m-d", strtotime($todate . '+1 day')); // todate의 다음 날
$orderby = "ORDER BY outdate DESC";
$sql = "SELECT o.*, e.ET_total, o.secondordnum
FROM {$DB}.{$tablename} o
LEFT JOIN {$DB}.{$tablename_sub} 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') " . $orderby;
try {
$stmh = $pdo->prepare($sql);
$stmh->execute();
$rows = $stmh->fetchAll(PDO::FETCH_ASSOC);
$chartData = [];
$itemData = [];
foreach ($rows as $row) {
$month = date("Y-m", strtotime($row['outdate']));
if (!isset($chartData[$month])) {
$chartData[$month] = 0;
$itemData[$month] = [
'total' => 0
];
}
// ET_total이 null이 아닌 경우에만 더하기
if (isset($row['ET_total']) && is_numeric($row['ET_total'])) {
$chartData[$month] += $row['ET_total'];
$itemData[$month]['total'] += $row['ET_total'];
}
}
$jsonChartData = json_encode($chartData);
$jsonItemData = json_encode($itemData);
} catch (PDOException $Exception) {
print "오류: " . $Exception->getMessage();
}
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
const salesData = <?= $jsonChartData ?>;
const itemData = <?= $jsonItemData ?>;
const sortedLabels = Object.keys(salesData).sort((a, b) => new Date(a) - new Date(b));
const sortedData = sortedLabels.map(label => parseFloat(salesData[label]));
const sortedItemData = sortedLabels.map(label => itemData[label]);
Highcharts.chart('salesChart', {
chart: {
type: 'column'
},
title: {
text: '월별 매출'
},
xAxis: {
categories: sortedLabels,
crosshair: true
},
yAxis: {
min: 0,
title: {
text: '매출액 (원)'
}
},
tooltip: {
headerFormat: '<span style="font-size:10px">{point.key}</span><table>',
pointFormatter: function() {
return '<tr><td style="color:' + this.series.color + ';padding:0">' + this.series.name + ': </td>' +
'<td style="padding:0"><b>' + Highcharts.numberFormat(this.y, 0, '.', ',') + ' 원</b></td></tr>';
},
footerFormat: '</table>',
shared: true,
useHTML: true,
style: {
padding: '10px',
minWidth: '200px'
}
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: '매출액',
data: sortedData
}]
});
// 전체합계 table tbody 내용 계산
const tableBody = document.getElementById('myTable').getElementsByTagName('tbody')[0];
let totalSum = 0;
sortedLabels.forEach((label, index) => {
let row = tableBody.insertRow();
let cell1 = row.insertCell(0);
let cell2 = row.insertCell(1);
cell1.innerHTML = label;
cell1.className = 'text-center fw-bold';
// Formatting numbers with commas
const formattedAmount = new Intl.NumberFormat('ko-KR', { style: 'currency', currency: 'KRW' }).format(sortedData[index]);
cell2.innerHTML = formattedAmount;
cell2.className = 'text-end';
totalSum += sortedData[index];
});
let totalRow = tableBody.insertRow();
let totalCell1 = totalRow.insertCell(0);
let totalCell2 = totalRow.insertCell(1);
totalCell1.innerHTML = '합계';
totalCell1.className = 'text-center fw-bold';
// Formatting numbers with commas
const formattedTotalSum = new Intl.NumberFormat('ko-KR', { style: 'currency', currency: 'KRW' }).format(totalSum);
totalCell2.innerHTML = formattedTotalSum;
totalCell2.className = 'text-end fw-bold';
});
</script>
<form id="board_form" name="board_form" method="post" >
<input type="hidden" id="active_tab" name="active_tab" value="<?= $active_tab ?>">
<div class="container mt-3 mb-5">
<div class="card mb-2 mt-2">
<div class="card-body">
<div class="d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<h5><?=$title_message?></h5>
<button type="button" class="btn btn-dark btn-sm mx-3" onclick='location.reload();' title="새로고침">
<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 id="showdate" class="btn btn-dark btn-sm">기간</span> &nbsp;
<div id="showframe" class="card" style=" width:400px; padding:4px;">
<div class="card-header" style=" padding:4px;">
<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" id="preyear" class="btn btn-outline-primary btn-sm me-1 change_dateRange" onclick='pre_year()'>전년도</button>
<button type="button" id="three_month" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='three_month_ago()'>M-3월</button>
<button type="button" id="prepremonth" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='prepre_month()'>전전월</button>
<button type="button" id="premonth" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='pre_month()'>전월</button>
<button type="button" id="thismonth" class="btn btn-dark btn-sm me-1 change_dateRange" onclick='this_month()'>당월</button>
<button type="button" id="thisyear" 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?>"> &nbsp; ~ &nbsp;
<input type="date" id="todate" name="todate" class="form-control me-1" style="width:100px;" value="<?=$todate?>"> &nbsp;
<button id="searchBtn" type="button" class="btn btn-dark btn-sm">
<i class="bi bi-search"></i> 검색
</button>
</div>
<div class="card mb-2 mt-2">
<div class="card-body">
<!-- Nav tabs -->
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link <?= $active_tab == 'sales' ? 'active' : '' ?>" id="sales-tab" data-bs-toggle="tab" data-bs-target="#sales" type="button" role="tab" aria-controls="sales" aria-selected="<?= $active_tab == 'sales' ? 'true' : 'false' ?>">전체 매출</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link <?= $active_tab == 'details' ? 'active' : '' ?>" id="details-tab" data-bs-toggle="tab" data-bs-target="#details" type="button" role="tab" aria-controls="details" aria-selected="<?= $active_tab == 'details' ? 'true' : 'false' ?>">매출 세부내역</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link <?= $active_tab == 'contractors' ? 'active' : '' ?>" id="contractors-tab" data-bs-toggle="tab" data-bs-target="#contractors" type="button" role="tab" aria-controls="contractors" aria-selected="<?= $active_tab == 'contractors' ? 'true' : 'false' ?>">거래처별 매출현황</button>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<!-- 전체 매출 탭 -->
<div class="tab-pane fade show <?= $active_tab == 'sales' ? 'active' : '' ?>" id="sales" role="tabpanel" aria-labelledby="sales-tab">
<div class="row d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<div class="col-sm-6">
<div class="card mb-2 mt-2">
<div class="card-body">
<div class="d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<div id="salesChart" style="width: 100%; height: 400px;"></div>
</div>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="card mb-2 mt-2">
<div class="card-body">
<div class="d-flex p-1 m-1 mt-1 justify-content-end align-items-center">
(금액: 원)
</div>
<div class="d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<table class="table table-hover" id="myTable">
<thead class="table-primary">
<tr>
<th class="text-center">해당 월</th>
<th class="text-end">매출금액</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 매출 세부내역 탭 -->
<div class="tab-pane fade <?= $active_tab == 'details' ? 'show active' : '' ?>" id="details" role="tabpanel" aria-labelledby="details-tab">
<div class="row d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<div class="col-sm-12">
<div class="card mb-2 mt-2">
<div class="card-body">
<div class="d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<table class="table table-hover" id="detailsTable">
<thead class="table-primary">
<tr>
<th class="text-center">거래처코드</th>
<th class="text-center">거래처명</th>
<th class="text-end">누적매출금액</th>
</tr>
</thead>
<tbody>
<?php
$contractorTotals = [];
$totalSales = 0;
// 거래처별 누적 매출 계산
foreach ($rows as $row) {
if (isset($row['ET_total']) && is_numeric($row['ET_total']) && $row['ET_total'] > 0) {
$contractorCode = $row['secondordnum'];
$contractorName = $row['secondord'];
if (!isset($contractorTotals[$contractorCode])) {
$contractorTotals[$contractorCode] = [
'name' => $contractorName,
'total' => 0
];
}
$contractorTotals[$contractorCode]['total'] += $row['ET_total'];
}
}
// 누적 매출액 기준으로 내림차순 정렬
uasort($contractorTotals, function($a, $b) {
return $b['total'] - $a['total'];
});
// 정렬된 결과 출력
foreach ($contractorTotals as $code => $data) {
echo '<tr>';
echo '<td class="text-center">' . htmlspecialchars($code) . '</td>';
echo '<td class="text-center">' . htmlspecialchars($data['name']) . '</td>';
echo '<td class="text-end">' . number_format($data['total']) . '</td>';
echo '</tr>';
$totalSales += $data['total'];
}
?>
<tr class="table-primary">
<td colspan="2" class="text-center fw-bold">합계</td>
<td class="text-end fw-bold"><?= number_format($totalSales) ?></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 거래처별 매출현황 탭 -->
<div class="tab-pane fade <?= $active_tab == 'contractors' ? 'show active' : '' ?>" id="contractors" role="tabpanel" aria-labelledby="contractors-tab">
<?php
$contractorChartData = [];
$totalSalesByContractor = [];
foreach ($rows as $row) {
if (isset($row['ET_total']) && is_numeric($row['ET_total']) && $row['ET_total'] > 0) {
$contractor = $row['secondord'];
$month = date('Y-m', strtotime($row['outdate']));
if (!isset($contractorChartData[$contractor][$month])) {
$contractorChartData[$contractor][$month] = 0;
}
$contractorChartData[$contractor][$month] += $row['ET_total'];
if (!isset($totalSalesByContractor[$contractor])) {
$totalSalesByContractor[$contractor] = 0;
}
$totalSalesByContractor[$contractor] += $row['ET_total'];
}
}
// 매출액 기준으로 내림차순 정렬
arsort($totalSalesByContractor);
$counter = 1;
?>
<div class="container">
<?php foreach ($totalSalesByContractor as $contractor => $totalSales): ?>
<?php if ($totalSales > 0): ?>
<div class="row">
<div class="card mb-2 mt-2">
<div class="card-body">
<div class="col-sm-12">
<div class="d-flex p-1 mt-4 mb-4 justify-content-center align-items-center">
<h4 class="mt-3"><?= $counter ?>위 <?= htmlspecialchars($contractor) ?></h4>
</div>
</div>
<div class="row d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<div class="col-sm-5">
<div class="card mb-2 mt-2">
<div class="card-body">
<div class="d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<div id="chart-<?= htmlspecialchars($contractor) ?>" style="height: 400px;"></div>
</div>
</div>
</div>
</div>
<div class="col-sm-7">
<div class="card mb-2 mt-2">
<div class="card-body">
<div class="d-flex p-1 m-1 mt-1 justify-content-center align-items-center">
<table class="table table-hover">
<thead class="table-success">
<tr>
<th class="text-center">월</th>
<th class="text-end">매출금액</th>
</tr>
</thead>
<tbody>
<?php
$totalSum = 0;
foreach ($contractorChartData[$contractor] as $month => $total_sales):
$totalSum += $total_sales;
?>
<tr>
<td class="text-center fw-bold"><?= $month ?></td>
<td class="text-end">₩<?= number_format($total_sales) ?></td>
</tr>
<?php endforeach; ?>
<tr class="font-weight-bold">
<td class="text-center fw-bold">합계</td>
<td class="text-end fw-bold">₩<?= number_format($totalSum) ?></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
Highcharts.chart('chart-<?= htmlspecialchars($contractor) ?>', {
chart: {
type: 'column'
},
title: {
text: ''
},
xAxis: {
categories: <?= json_encode(array_keys($contractorChartData[$contractor])) ?>
},
yAxis: {
title: {
text: '매출액 (원)'
}
},
series: [{
name: '매출액',
data: <?= json_encode(array_values($contractorChartData[$contractor])) ?>
}]
});
</script>
<?php $counter++; ?>
<?php endif; ?>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</body>
</html>
<!-- 페이지 로딩 -->
<script>
$(document).ready(function(){
var loader = document.getElementById('loadingOverlay');
if(loader)
loader.style.display = 'none';
});
</script>
<!-- 기간설정 -->
<script>
$(document).ready(function() {
var savedDateRange = getCookie('dateRange');
if (savedDateRange) {
$('#dateRange').val(savedDateRange);
}
$('button[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) {
var tabId = $(e.target).attr('id');
$('#active_tab').val(tabId.split('-')[0]);
});
});
$(document).ready(function(){
var title = '매출 통계';
saveLogData(title);
});
</script>