기간별 수량 조회 페이지 신설

This commit is contained in:
2025-07-23 16:55:58 +09:00
parent 95fbca87ab
commit fcc95c6c0a
2 changed files with 355 additions and 1 deletions

View File

@ -0,0 +1,269 @@
<?php
// 베이커리 재고관리
include_once "_common.php";
if (!isset($_SESSION['user_id'])) header( 'Location: FG_MANAGER_URL' ); // 로그인 되어있지 않으면 로그인 페이지로 보냄
include_once 'head.sub.php';
include_once FG_MANAGER_PATH."/head.php";
// 검색 변수 초기화
!isset($search) ?? "";
!isset($where) ?? "";
!isset($search_count) ?? "";
$is_debug = false; // 디버깅 시 true로 변경
// ord_by 로 넘어온 값이 있으면 반영
$ord_by = isset($_REQUEST["ord_by"]) ? $_REQUEST["ord_by"] : "product_name ASC";
// 검색어 반영
$searchWord = $_GET["searchWord"] ?? "";
// 날짜 가져오기
$today = new DateTime();
$startDate = $_REQUEST["startDate"] ?? (clone $today)->modify('-7 days')->format('Y-m-d');
$endDate = $_REQUEST["endDate"] ?? (clone $today)->modify('-1 day')->format('Y-m-d');
// 최종 수정시간
$edit_datetime = date('Y-m-d H:i:s'); // 최종 수정 시간 업데이트
// 베이커리 계정인지 확인하고, 오늘 이후 날짜인 경우 생산-매출액란을 공란으로 출력하기 위한 변수
$is_bakery = ( $_SESSION['user_id'] == "bakery" ) ? true : false;
$is_bakery_input = ( strtotime($searchDate) >= strtotime(date("Y-m-d")) ) ? true : false;
// 합계 구하기
$totalBakeryInvenData = getBakeryInvenSumPeriod($startDate, $endDate, $searchWord);
// barcode별 그룹화된 상세 데이터를 구하기
$bakeryInvenData = getBakeryInvenDataPeriod($startDate, $endDate, $searchWord);
?>
<style>
/* 틀 고정
.tableWrapper {
overflow: auto;
height: 700px;
width: 100%;
}
#bakeryTable th {
position: sticky;
top: 0px;
}
*/
</style>
<div class="d-flex justify-content-between mb-3 ">
<div class="row align-items-start">
<h2>베이커리 기간별 현황</h2>
</div>
<div class="row align-items-end align-self-end only-print">
<p>조회일자 : <?=$startDate?> ~ <?=$endDate?></p>
</div>
</div>
<div class="d-flex justify-content-between mb-3 no-print">
<div class="row align-items-start flex-nowrap">
<div class="input-group">
<span class="input-group-text">시작일</span>
<input type="date" class="form-control" id="startDateInput" name="startDate" max="9999-12-31" value="<?= $startDate ?>">
<span class="input-group-text">종료일</span>
<input type="date" class="form-control" id="endDateInput" name="endDate" max="9999-12-31" value="<?= $endDate ?>">
</div>
</div>
<div class="row align-items-end">
<div class="input-group">
<input class="form-control" type="text" name="searchWord" id="searchWord" placeholder="상품명 검색" value="<?= htmlspecialchars($_GET['searchWord'] ?? '') ?>" />
<button class="btn btn-success" id="searchBtn" type="button">검색</button>
<button class="btn btn-primary" type="button" id="resetSearch">초기화</button>
</div>
</div>
<!--
<div class="row align-items-end">
<input type="file" id="inventoryFileInput" style="display:none;" accept=".xls,.xlsx" />
<div class="btn-group" role="group" aria-label="bakery-button">
<button type="button" class="btn btn-success" id="exportExcelButton">엑셀변환</button>
</div>
</div>
-->
</div>
<div class="table">
<h3>개요</h3>
<table class="table align-middle" id="bakeryTotalTable">
<thead class="table-light">
<tr class="align-middle">
<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>
</tr>
</thead>
<tbody>
<tr class="align-middle">
<th class="text-center"><?=number_format(cntUsedBakeryItems())?></th>
<th class="text-center"><?=number_format($totalBakeryInvenData['t_production'])?></th>
<th class="text-center"><?=number_format($totalBakeryInvenData['t_inhouse_use'])?></th>
<th class="text-center"><?=number_format($totalBakeryInvenData['t_recycling'])?></th>
<th class="text-center"><?=number_format($totalBakeryInvenData['t_disposal'])?></th>
<th class="text-center"><?=number_format($totalBakeryInvenData['t_sales'])?></th>
<th class="text-center"><?=number_format($totalBakeryInvenData['t_payment_amount'])?></th>
</tr>
</tbody>
</table>
</div>
<div class="tableWrapper">
<h3>상세</h3>
<table class="table align-middle table-hover <?php if( $bakeryInvenData) echo 'table-striped'?> bakery" id="bakeryTable">
<colgroup>
<col width="30px">
<col width="150px">
<col width="70px">
<col width="70px">
<col width="70px">
<col width="70px">
<col width="70px">
<col width="70px">
</colgroup>
<!-- 테이블 제목 -->
<thead class="table-light">
<tr class="align-middle">
<th class="text-center no-click">No.</th>
<th class="text-center" data-column="product_name" data-order="asc">품목 <span class="sort-icon fa fa-sort-up" data-column="product_name"></span></th>
<th class="text-center" data-column="production" data-order="asc">생산 <span class="sort-icon" data-column="production"></span></th>
<th class="text-center" data-column="inhouse_use" data-order="asc">업장사용 <span class="sort-icon" data-column="inhouse_use"></span></th>
<th class="text-center" data-column="recycling" data-order="asc">재활용 <span class="sort-icon" data-column="recycling"></span></th>
<th class="text-center" data-column="disposal" data-order="asc">폐기 <span class="sort-icon" data-column="disposal"></span></th>
<th class="text-center" data-column="sales" data-order="asc">판매 <span class="sort-icon" data-column="sales"></span></th>
<th class="text-center" data-column="payment_amount" data-order="asc">매출액 <span class="sort-icon" data-column="payment_amount"></span></th>
</tr>
</thead>
<!-- 테이블 데이터 -->
<tbody class="table-group-divider" id="bakeryTableBody">
<?php
if ( $bakeryInvenData ) {
// 데이터 가져와서 뿌리기
$i = 1; // number 표시를 위한 변수
foreach ($bakeryInvenData as $row) {
?>
<tr id="row-<?=$row['barcode']?>">
<td class="text-center"><?=$i?></td>
<td class="text-left"><?=htmlspecialchars($row['product_name'])?></td>
<td class="text-end"><span class="value"><?=number_format($row['production'])?></span>
<input class="form-control text-end d-none" type="text" value="<?=$row['production']?>" id="production-<?=$row['barcode']?>" product_name="<?=$row['product_name']?>" aria-label="production" readonly>
</td>
<td class="text-end"><span class="value"><?=number_format($row['inhouse_use'])?></span>
<input class="form-control text-end d-none" type="text" value="<?=$row['inhouse_use']?>" id="inhouse_use-<?=$row['barcode']?>" product_name="<?=$row['product_name']?>" aria-label="inhouse_use" readonly>
</td>
<td class="text-end"><span class="value"><?=number_format($row['recycling'])?></span>
<input class="form-control text-end d-none" type="text" value="<?=$row['recycling']?>" id="recycling-<?=$row['barcode']?>" product_name="<?=$row['product_name']?>" aria-label="recycling" readonly>
</td>
<td class="text-end"><span class="value"><?=number_format($row['disposal'])?></span>
<input class="form-control text-end d-none" type="text" value="<?=$row['disposal']?>" id="disposal-<?=$row['barcode']?>" product_name="<?=$row['product_name']?>" aria-label="disposal" readonly>
</td>
<td class="text-end"><?=number_format($row['sales'])?></td>
<td class="text-end"><?=number_format($row['payment_amount'])?></td>
</tr>
<?php
$i++;
} // endforeach
?>
</tbody>
<!-- 합계 데이터 출력 -->
<tfoot class="no-print">
<tr>
<td colspan="2" class="text-center">합계</th>
<td class="text-end" id="total_production"><?=number_format($totalBakeryInvenData['t_production'])?></td>
<td class="text-end" id="total_inhouse_use"><?=number_format($totalBakeryInvenData['t_inhouse_use'])?></td>
<td class="text-end" id="total_recycling"><?=number_format($totalBakeryInvenData['t_recycling'])?></td>
<td class="text-end" id="total_disposal"><?=number_format($totalBakeryInvenData['t_disposal'])?></td>
<td class="text-end" id="total_sales"><?=number_format($totalBakeryInvenData['t_sales'])?></td>
<td class="text-end" id="total_payment_amount"><?=number_format($totalBakeryInvenData['t_payment_amount'])?></td>
</tr>
</tfoot>
<?php
} else {
// 데이터가 없을 경우 출력
echo "<tr class='align-middle'>";
echo "<td class='text-center' colspan='9'> 자료가 존재하지 않습니다 </td>";
echo "</tr></tbody>";
} // endif
?>
</table>
</div>
<script>
const startDateInput = document.getElementById('startDateInput');
const endDateInput = document.getElementById('endDateInput');
const searchInput = document.getElementById('searchWord');
const searchBtn = document.getElementById('searchBtn');
const resetBtn = document.getElementById('resetSearch');
// URL 쿼리 갱신 함수
function getUrlWithParams(paramsToUpdate = {}, paramsToDelete = []) {
const url = new URL(window.location.href);
// 업데이트
for (const key in paramsToUpdate) {
url.searchParams.set(key, paramsToUpdate[key]);
}
// 삭제
for (const key of paramsToDelete) {
url.searchParams.delete(key);
}
return url.toString();
}
// 날짜 변경 시
function onDateChange() {
const url = getUrlWithParams({
startDate: startDateInput.value,
endDate: endDateInput.value,
});
window.location.href = url;
}
// 검색 버튼 클릭 시
function onSearchClick() {
const url = getUrlWithParams({
startDate: startDateInput.value,
endDate: endDateInput.value,
searchWord: searchInput.value,
});
window.location.href = url;
}
// 검색어 입력창에서 엔터 입력 시 검색 실행
searchInput.addEventListener('keydown', function (e) {
if (e.key === 'Enter') {
e.preventDefault(); // 폼 제출 방지
onSearchClick(); // 검색 함수 호출
}
});
// 초기화 버튼 클릭 시
function onResetClick() {
const url = getUrlWithParams({}, ['searchWord']);
window.location.href = url;
}
// 이벤트 바인딩
startDateInput.addEventListener('change', onDateChange);
endDateInput.addEventListener('change', onDateChange);
searchBtn.addEventListener('click', onSearchClick);
resetBtn.addEventListener('click', onResetClick);
</script>
<?php
include_once "tail.sub.php";
include_once FG_MANAGER_PATH."/tail.php";

View File

@ -315,7 +315,77 @@ function get_total_count($db_name) {
return $R;
}
function getBakeryInvenDataPeriod($start_date, $end_date, $searchWord = "", $ord_by = "a.date ASC, b.product_name ASC") {
global $fg;
// 검색 조건
$search_sql = "";
if ($searchWord !== "") {
$searchWord = sql_real_escape_string($searchWord);
$search_sql = "AND b.product_name LIKE '%{$searchWord}%'";
}
$query = "SELECT
b.product_name,
SUM(a.production) AS production,
SUM(a.inhouse_use) AS inhouse_use,
SUM(a.recycling) AS recycling,
SUM(a.disposal) AS disposal,
SUM(a.sales) AS sales,
SUM(a.payment_amount) AS payment_amount
FROM {$fg['bakery_inventory_table']} AS a
LEFT JOIN {$fg['bakery_product_table']} AS b
ON a.barcode = b.barcode
WHERE b.used = 1
AND a.date BETWEEN '{$start_date}' AND '{$end_date}'
{$search_sql}
GROUP BY a.barcode
ORDER BY {$ord_by}";
error_log($query);
$result = sql_query($query);
$R = array();
while ($row = sql_fetch_array($result)) {
$R[] = $row;
}
return $R;
}
// 기간별 합계 수량 구하기
function getBakeryInvenSumPeriod($start_date, $end_date, $searchWord = "") {
global $fg;
$search_sql = "";
if ($searchWord !== "") {
$searchWord = sql_real_escape_string($searchWord);
$search_sql = "AND b.product_name LIKE '%{$searchWord}%'";
}
$query = "SELECT
SUM(a.production) AS t_production,
SUM(a.inhouse_use) AS t_inhouse_use,
SUM(a.recycling) AS t_recycling,
SUM(a.disposal) AS t_disposal,
SUM(a.sales) AS t_sales,
SUM(a.payment_amount) AS t_payment_amount
FROM {$fg['bakery_inventory_table']} AS a
LEFT JOIN {$fg['bakery_product_table']} AS b
ON a.barcode = b.barcode
WHERE b.used = 1
AND a.date BETWEEN '{$start_date}' AND '{$end_date}'
{$search_sql}";
error_log($query);
return sql_fetch($query); // 결과 없으면 false 반환
}
// 전체 품명 불러오기
function getBakeryProductList($ord_by = "ASC") {
global $fg;
@ -329,6 +399,21 @@ function get_total_count($db_name) {
return $R;
}
// 사용 중인(used=1) 품목 수 구하기
function cntUsedBakeryItems() {
global $fg;
$query = "SELECT COUNT(*) AS cnt FROM {$fg['bakery_product_table']} WHERE used = 1";
error_log($query);
$result = sql_fetch($query);
$result = $result['cnt'];
return $result;
}
// 어제자 최종재고 불러오기
function getPrevStock($date, $barcode) {
global $fg;