퍼스트가든에서 사용하는 사용자 함수 및 관련파일 추가

This commit is contained in:
2025-07-02 14:14:02 +09:00
parent 68797db562
commit ec949b682d
265 changed files with 27086 additions and 0 deletions

View File

@ -0,0 +1,4 @@
<?php
include_once '../../common.php';
include_once '../config.php';
include_once '../lib/lib.php';

View File

@ -0,0 +1,65 @@
<?php
include_once "_common.php";
// 테이블 존재 유무 확인 쿼리
$query_check_table = "SHOW TABLES LIKE '{$fg['bakery_product_table']}'";
$result_check_table = sql_query($query_check_table);
echo "테이블 존재 확인 쿼리 실행 결과...................." . json_encode($result_check_table) . "<br>";
if (sql_num_rows($result_check_table) == 0) {
$query_create_table = "CREATE TABLE {$fg['bakery_product_table']} (
idx INT AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(255) NOT NULL,
barcode INT NOT NULL UNIQUE,
used TINYINT(1) DEFAULT 1
)";
$result_create_table = sql_query($query_create_table);
echo "테이블 생성 쿼리 실행 결과...................." . json_encode($result_create_table) . "<br>";
} else {
echo "테이블이 이미 존재합니다.<br>";
}
// 중복을 제외하고 업데이트하는 쿼리 이전에 존재하는 데이터의 카운트를 가져옴
$query_count_inventory = "SELECT COUNT(*) as total FROM {$fg['bakery_inventory_table']}";
$result_count_inventory = sql_query($query_count_inventory);
$row_count_inventory = sql_fetch_array($result_count_inventory);
echo "{$fg['bakery_inventory_table']}에서 존재하는 데이터의 총 수...................." . $row_count_inventory['total'] . "<br>";
// 중복을 제외하고 업데이트하는 쿼리를 실행
$query_update = "INSERT IGNORE INTO fg_manager_bakery_product_info (product_name, barcode, used)
SELECT DISTINCT product_name, barcode, 1
FROM fg_manager_bakery_inventory AS inv
WHERE NOT EXISTS (
SELECT 1
FROM fg_manager_bakery_product_info AS prod
WHERE prod.barcode = inv.barcode
)";
$result_update = sql_query($query_update);
if ($result_update) {
echo "중복을 제외하고 업데이트 쿼리 실행 성공" . "<br>";
// 필드명을 변경하는 쿼리 추가
$query_alter_table = "ALTER TABLE {$fg['bakery_inventory_table']} CHANGE product_name product_name_old VARCHAR(255) NOT NULL";
$result_alter_table = sql_query($query_alter_table);
echo "'{$fg['bakery_inventory_table']}'의 'product_name' 필드명이 'product_name_old'로 변경되었습니다.<br>";
// INSERT된 데이터의 수를 가져옴
$query_count_inserted = "SELECT COUNT(*) as total FROM {$fg['bakery_product_table']} WHERE used = 1";
$result_count_inserted = sql_query($query_count_inserted);
$row_count_inserted = sql_fetch_array($result_count_inserted);
echo "{$fg['bakery_product_table']}에 삽입된 데이터의 수...................." . $row_count_inserted['total'] . "<br>";
// 중복 데이터를 제거한 데이터의 수
$inserted_rows = $row_count_inserted['total'] - $row_count_inventory['total'];
echo "중복을 제거한 후 기록된 데이터의 수...................." . max($inserted_rows, 0) . "<br>";
} else {
echo "업데이트에 실패했습니다. 종료합니다.<br>";
// 업데이트가 실패했다면 디버깅을 위해 쿼리를 출력함함
print_r($query_update);
echo "<br>";
}

View File

@ -0,0 +1,21 @@
<?php
include_once "_common.php";
if(!$_SESSION['user_id']) exit; // 로그인되어있지 않으면 확인 불가
$product_name = isset($_POST['product_name']) ? trim($_POST['product_name']) : exit;
$barcode = isset($_POST['barcode']) ? trim($_POST['barcode']) : exit;
$used = isset($_POST['used']) ? trim($_POST['used']) : exit;
// 데이터베이스에 입력하는 쿼리
$query = "INSERT INTO {$fg['bakery_product_table']} (product_name, barcode, used)
VALUES ('{$product_name}', '{$barcode}', '{$used}')";
$result = sql_query($query);
header("Content-Type: application/json");
if ($result) {
echo json_encode(["isSuccess" => true]);
} else {
echo json_encode(["isSuccess" => false, "message" => "추가에 실패하였습니다."]);
}
?>

View File

@ -0,0 +1,18 @@
<?php
include_once "_common.php";
if(!$_SESSION['user_id']) exit; // 로그인 되어있지 않으면 확인 불가
// 기본적인 보안 조치로 모든 데이터는 필터링하여 보관됩니다.
$idx = isset($_POST['idx']) ? intval($_POST['idx']) : exit;
// 데이터 행 삭제 쿼리
$query = "DELETE FROM {$fg['bakery_product_table']} WHERE idx = $idx";
// 쿼리 실행
$result = sql_query($query);
header("Content-Type: application/json");
if ($result) {
echo json_encode(["isSuccess" => true]);
} else {
echo json_encode(["isSuccess" => false]);
}

View File

@ -0,0 +1,34 @@
<?php
include_once "_common.php";
if(!$_SESSION['user_id']) exit; // 로그인되어있지 않으면 확인 불가
$product_name = isset($_POST['product_name']) ? trim($_POST['product_name']) : exit;
$barcode = isset($_POST['barcode']) ? trim($_POST['barcode']) : exit;
$used = isset($_POST['used']) ? trim($_POST['used']) : exit;
// bakery_stock.php에서는 idx가 넘어오지 않음.
if (isset($_POST['idx'])) {
$idx = intval($_POST['idx']);
} else {
$searchQuery = "SELECT idx FROM {$fg['bakery_product_table']} WHERE barcode = '{$barcode}'";
$searchResult = sql_fetch($searchQuery);
$idx = $searchResult['idx'];
}
// 업데이트 쿼리
$query = "UPDATE {$fg['bakery_product_table']}
SET product_name = '$product_name', barcode = '$barcode', used = $used
WHERE idx = $idx";
$result = sql_query($query);
header("Content-Type: application/json");
if ($result) {
echo json_encode(["isSuccess" => true]);
} else {
echo json_encode(["isSuccess" => false, "message" => "수정에 실패하였습니다."]);
}
?>

View File

@ -0,0 +1,155 @@
<?php
// 베이커리 제품목록록
include_once "_common.php";
if (!isset($_SESSION['user_id'])) header( 'Location: FG_MANAGER_URL' ); // 로그인 되어있지 않으면 로그인 페이지로 보냄
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"] : "ASC";
// 제품 목록 불러오기
$productList = getBakeryProductList($ord_by);
$totalCountQuery = "SELECT COUNT(*) as cnt FROM {$fg['bakery_product_table']}";
$totalCountResult = sql_query($totalCountQuery);
$totalCount = sql_fetch_array($totalCountResult)['cnt'];
$usedCountQuery = "SELECT COUNT(*) as cnt FROM {$fg['bakery_product_table']} WHERE used = 1";
$usedCountResult = sql_query($usedCountQuery);
$usedCount = sql_fetch_array($usedCountResult)['cnt'];
?>
<style>
.bakery tfoot {
font-weight: 600;
}
.sort-icon {
margin-left: 5px;
font-size: 12px;
vertical-align: middle;
}
</style>
<h2 class="mb-3">베이커리 제품목록</h2>
<div class="d-flex justify-content-between my-1 mb-3">
<div>
<p>전체 품목 수 : <?=$totalCount?> | 활성 품목 수 : <?=$usedCount?></p>
</div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#add_modal">추가</button>
<!-- 추가 버튼을 누르면 출력한다. -->
<div id="add_modal" class="modal fade">
<div class="modal-dialog modal-dialog-centered" style="width:800px;">
<div class="modal-content">
<?php //class="signup" ?>
<form class="add" action="bakery_product_list.add.php" method="POST" enctype="multipart/form-data" > <!-- 폼 이름을 알려줌 -->
<div class="modal-header">
<h4 class="modal-title">추가</h4>
</div>
<div class="modal-body text-start">
<div class="input-group mb-1">
<span class="input-group-text col-md-2" id="product_name">품명</span>
<input type="text" class="form-control" id="product_name" name="product_name" value="">
<input type="radio" class="btn-check" name="used" id="used_1" value="1" checked required>
<label class="btn btn-outline-primary" for="used_1">사용</label>
<input type="radio" class="btn-check" name="used" id="used_0" value="0" required>
<label class="btn btn-outline-primary" for="used_0">미사용</label>
</div>
<div class="input-group mb-1">
<span class="input-group-text col-md-2" id="barcode">바코드</span>
<input type="text" class="form-control" id="barcode" name="barcode" value="" required>
</div>
</div>
<div class="modal-footer">
<button type="submit" id="add_submit" class="btn btn-primary">추가</button>
<button type="button" class="btn btn-default" data-bs-dismiss="modal">닫기</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
</div>
<table class="table table-striped align-middle table-hover bakery" id="bakeryTable">
<colgroup>
<col width="30px">
<col width="150px">
<col width="70px">
<col width="70px">
<col width="50px">
</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" data-column="product_name"></span></th>
<th class="text-center" data-column="barcode" data-order="asc">바코드 <span class="sort-icon" data-column="barcode"></span></th>
<th class="text-center" data-column="current_stock" data-order="asc">사용 <span class="sort-icon" data-column="current_stock"></span></th>
<th class="text-center no-click">관리</th>
</tr>
</thead>
<!-- 테이블 데이터 -->
<tbody class="table-group-divider" id="bakeryTableBody">
<?php
// 제품목록 반복문
$i = 1;
foreach ($productList as $row) {
?>
<tr id="row-<?=$row['barcode']?>">
<td class="text-center"><?=$i?></td>
<td class="text-center"><?=$row['product_name']?></td>
<td class="text-center"><?=$row['barcode']?></td>
<td class="text-center"><?=($row['used'] == 1) ? '활성' : '비활성' ?></td>
<td class="text-center">
<button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modify_modal_<?=$row['idx']?>"><i class="fa-solid fa-pen-to-square"></i></button>
<a class="btn btn-danger" href="javascript:void(0);" role="button" onclick="confirmDelete('<?=$row['idx']?>')"><i class="fa-solid fa-trash-can"></i></a>
</td>
</tr>
<!-- 수정 모달 -->
<div id="modify_modal_<?=$row['idx']?>" class="modal fade" tabindex="-1" aria-labelledby="modify_modal_<?=$row['idx']?>" aria-hidden="true">
<div class="modal-dialog modal modal-dialog-centered">
<div class="modal-content">
<form class="modify" id="modify_<?=$row['idx']?>" name="modify_<?=$row['idx']?>">
<input type="hidden" name="idx" id="idx_<?=$row['idx']?>" value="<?=$row['idx']?>">
<div class="modal-header">
<h5 class="modal-title">정보 보기/수정</h5>
</div>
<div class="modal-body text-start">
<div class="input-group mb-1">
<span class="input-group-text col-md-2" id="product_name_<?=$row['idx']?>">품명</span>
<input type="text" class="form-control" id="product_name_<?=$row['idx']?>" name="product_name" value="<?=$row['product_name'] ?>">
<input type="radio" class="btn-check" name="used" id="used_<?=$row['idx']?>_1" value="1" <?=$row['used'] == "1" ? "checked": "" ?> required>
<label class="btn btn-outline-primary" for="used_<?=$row['idx']?>_1">사용</label>
<input type="radio" class="btn-check" name="used" id="used_<?=$row['idx']?>_0" value="0" <?=$row['used'] =="0" ? "checked" : "" ?> required>
<label class="btn btn-outline-primary" for="used_<?=$row['idx']?>_0">미사용</label>
</div>
<div class="input-group mb-1">
<span class="input-group-text col-md-2" id="barcode_<?=$row['idx']?>">바코드</span>
<input type="text" class="form-control" id="barcode_<?=$row['idx']?>" name="barcode" value="<?=$row['barcode']?>" required>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" >수정</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Close" data-bs-target="#modify_modal_<?=$row['idx']?>">닫기</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
<!-- 수정 모달 끝 -->
<?php $i++; } ?>
</tbody>
</table>
<?php
include_once "tail.sub.php";
include_once FG_MANAGER_PATH."/tail.php";

View File

@ -0,0 +1,26 @@
<?php
include_once '_common.php';
if(!$_SESSION['user_id']) exit; // 로그인 되어있지 않으면 확인 불가
if ($_SERVER["REQUEST_METHOD"] == "POST") { // POST로 넘어온 값이 있다면
// 변수 선언
$date = trim($_POST["searchDate"]);
$worker = trim($_POST['worker']);
$author = trim($_POST['author']);
// update query
$query = "INSERT INTO {$fg['bakery_author_table']} (date, worker, author) ";
$query .= "VALUES('{$date}', '{$worker}', '{$author}') ";
// 이미 값이 있는 경우 업데이트함
$query .= "ON DUPLICATE KEY UPDATE worker = '{$worker}', author = '{$author}' ";
$result = sql_query($query);
if ($result) {
echo json_encode(array('success' => true));
} else {
echo json_encode(array('success' => false, 'message' => 'Database error'));
}
} else {
echo json_encode(array('success' => false, 'message' => 'Invalid request method'));
}

View File

@ -0,0 +1,46 @@
<?php
include_once '_common.php';
if(!$_SESSION['user_id']) exit; // 로그인 되어있지 않으면 확인 불가
if ($_SERVER["REQUEST_METHOD"] == "POST") { // POST로 넘어온 값을 처리
$searchDate = $_POST['searchDate'];
// 임시 배열 생성
$updates = [];
// POST 데이터 처리
foreach ($_POST as $key => $value) {
if (preg_match('/^(.*)-(\d+)$/', $key, $matches)) {
$name = $matches[1];
$barcode = $matches[2];
// 중복된 barcode에 대한 값들을 배열에 저장
if (!isset($updates[$barcode])) {
$updates[$barcode] = [];
}
$updates[$barcode][$name] = $value;
}
}
// 쿼리 생성
foreach ($updates as $barcode => $fields) {
$setClauses = [];
foreach ($fields as $name => $value) {
$setClauses[] = "{$name} = '{$value}'";
}
$setClause = implode(', ', $setClauses);
$query = "UPDATE {$fg['bakery_inventory_table']} SET {$setClause} WHERE date = '{$searchDate}' AND barcode = '{$barcode}'";
// 쿼리 실행
$result = sql_query($query);
}
if ($result) {
echo json_encode(array('status' => 'success'));
} else {
echo json_encode(array('status' => 'error', 'message' => 'Database error'));
}
} else {
echo json_encode(array('status' => 'error', 'message' => 'Invalid request method'));
}

View File

@ -0,0 +1,18 @@
<?php
include_once "_common.php";
if(!$_SESSION['user_id']) exit; // 로그인 되어있지 않으면 확인 불가
// 기본적인 보안 조치로 모든 데이터는 필터링하여 보관됩니다.
$idx = isset($_POST['idx']) ? intval($_POST['idx']) : 0;
// 데이터 행 삭제 쿼리
$query = "DELETE FROM {$fg['bakery_inventory_table']} WHERE idx = $idx";
// 쿼리 실행
$result = sql_query($query);
header("Content-Type: application/json");
if ($result) {
echo json_encode(["isSuccess" => true]);
} else {
echo json_encode(["isSuccess" => false]);
}

View File

@ -0,0 +1,45 @@
<?php
include_once "_common.php";
if(!$_SESSION['user_id']) exit; // 로그인 되어있지 않으면 확인 불가
// POST 데이터 받아오기
$searchDate = isset($_POST['searchDate']) ? $_POST['searchDate'] : '';
$ord_by = isset($_POST['ord_by']) ? $_POST['ord_by'] : 'product_name ASC';
// getBakeryInvenData 함수 호출
$results = getBakeryInvenData($searchDate, $ord_by);
// 데이터 출력
$output = '';
$i = 1;
foreach ($results as $row) {
// 재고 점검 후 일치하지 않으면 업데이트
// 전날 재고
$previous_stock = intval(getPrevStock($searchDate, $row['barcode']));
// 현재고
$current_stock = $previous_stock + $row['production'] - $row['inhouse_use'] - $row['recycling'] - $row['disposal'] - $row['sales'];
$output .= '<tr>';
$output .= '<td class="text-center">' . htmlspecialchars($i) . '</td>';
$output .= '<td class="text-center">' . htmlspecialchars($row['product_name']) . '</td>';
$output .= '<td class="text-center">' . htmlspecialchars($row['barcode']) . '</td>';
$output .= '<td class="text-end">' . number_format($previous_stock) . '</td>';
$output .= '<td class="text-end"><span class="value">' . htmlspecialchars($row['production']) . '</span>';
$output .= '<input class="form-control text-end d-none" type="text" value="' . htmlspecialchars($row['production']) . '" id="production-' . htmlspecialchars($row['barcode']) . '" product_name="' . htmlspecialchars($row['product_name']) . '" aria-label="production" readonly></td>';
$output .= '<td class="text-end"><span class="value">' . htmlspecialchars($row['inhouse_use']) . '</span>';
$output .= '<input class="form-control text-end d-none" type="text" value="' . htmlspecialchars($row['inhouse_use']) . '" id="inhouse_use-' . htmlspecialchars($row['barcode']) . '" product_name="' . htmlspecialchars($row['product_name']) . '" aria-label="inhouse_use" readonly></td>';
$output .= '<td class="text-end"><span class="value">' . htmlspecialchars($row['recycling']) . '</span>';
$output .= '<input class="form-control text-end d-none" type="text" value="' . htmlspecialchars($row['recycling']) . '" id="recycling-' . htmlspecialchars($row['barcode']) . '" product_name="' . htmlspecialchars($row['product_name']) . '" aria-label="recycling" readonly></td>';
$output .= '<td class="text-end"><span class="value">' . htmlspecialchars($row['disposal']) . '</span>';
$output .= '<input class="form-control text-end d-none" type="text" value="' . htmlspecialchars($row['disposal']) . '" id="disposal-' . htmlspecialchars($row['barcode']) . '" product_name="' . htmlspecialchars($row['product_name']) . '" aria-label="disposal" readonly></td>';
$output .= '<td class="text-end">' . number_format($row['sales']) . '</td>';
$output .= '<td class="text-end">' . number_format($row['sales_amount']) . '</td>';
$output .= '<td class="text-end">' . number_format($row['menu_discount']) . '</td>';
$output .= '<td class="text-end">' . number_format($row['payment_amount']) . '</td>';
$output .= '<td class="text-end">' . number_format($current_stock) . '</td>';
$output .= '</tr>';
$i++;
}
echo $output;

View File

@ -0,0 +1,140 @@
<?php
include_once '_common.php';
if (!isset($_SESSION['user_id'])) exit; // 로그인 되어있지 않으면 로그인 페이지로 보냄
// cafe24 절대경로
// /firstgarden/www/
$is_debug = false; // 디버깅 시 true로 변경
$is_test = false; // 상품별(분류별상품)으로 바코드 업데이트 시킬때
$is_dataForceInsert = false; // 강제로 데이터 맞출때 씀
// 추후 table 생성하여 대/중/소분류에 들어갈 값을 넣도록 수정해야 함
// 값을 추출할 소분류 설정
$chkMajCat = array('보스코');
$chkMidCat = array();
$chkSmallCat = array(
'보스코 베이커리'
);
// 제외항목
// $excludeBarcode = array('900014', '900015');
// 라이브러리 로드
require_once $_SERVER['DOCUMENT_ROOT'].'/vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
use Shuchkin\SimpleXLSX;
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file'])) {
if ($is_debug) var_dump($_FILES['file']);
// 변수 만들기
$date = trim($_POST['searchDate']);
$file = $_FILES['file'];
$datetime = date('Y-m-d H:i:s');
$uploadDir = 'uploads/';
$uploadFile = $uploadDir . basename($file['name']);
$newXlsxFile = $uploadDir . pathinfo($file['name'], PATHINFO_FILENAME) . '.xlsx';
// 디렉토리가 없는 경우 생성
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0777, true);
}
// 데이터 처리
if (move_uploaded_file($file['tmp_name'], $uploadFile)) {
if ($is_debug) echo "파일 업로드 성공: " . htmlspecialchars(basename($file['name'])) . "<br>" . PHP_EOL;
try {
// 파일 형식에 따라 변환
$fileType = pathinfo($uploadFile, PATHINFO_EXTENSION);
if ($fileType == 'xls') {
// PHPSpreadsheet로 .xls 파일을 .xlsx 파일로 변환
$spreadsheet = IOFactory::load($uploadFile);
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save($newXlsxFile);
// 업로드된 파일을 새로운 .xlsx 파일로 설정
$uploadFile = $newXlsxFile;
}
// SimpleXLSX로 파일 읽기
$xlsx = SimpleXLSX::parse($uploadFile);
if ($xlsx && !$is_test) {
$data = [];
foreach ($xlsx->rows() as $row) {
// 대분류 열이 보스코일 때
if (in_array($row[1], $chkMajCat)) {
// 소분류 체크
if (in_array($row[3], $chkSmallCat)) {
// 바코드 체크
if (!empty($row[4])) {
// 데이터 설정
$date = $date;
$product_name = $row[6] ?? ''; // 품명
$barcode = $row[4] ?? ''; // 바코드
$sales = $row[7] ?? ''; // 판매
$sales_amount = $row[8] ?? ''; // 판매금액
$menu_discount = $row[9] ?? ''; // 할인액
$payment_amount = $row[10] ?? ''; // 매출액
// `bakery_product_table`에 바코드가 있는지 확인
$checkQuery = "SELECT used FROM {$fg['bakery_product_table']} WHERE barcode = '{$barcode}'";
$checkResult = sql_query($checkQuery);
$rowCount = sql_num_rows($checkResult);
if ($rowCount > 0) {
$used = sql_fetch_array($checkResult)['used'];
// 바코드가 존재하지만 used 값이 0인 경우 continue
if ($used == 0) continue;
} else {
// 바코드가 없는 경우 추가
$insertQuery = "INSERT INTO {$fg['bakery_product_table']} (product_name, barcode, used) VALUES ('{$product_name}', '{$barcode}', 1)";
sql_query($insertQuery);
}
// 바코드가 신규로 들어간 경우에는 used값이 항상 1이고, 기존 0인 경우는 이미 continue 처리가 되어있음
// 데이터 삽입
$query = "INSERT INTO {$fg['bakery_inventory_table']} (date, barcode, sales, sales_amount, menu_discount, payment_amount, edit_datetime) ";
$query .= " VALUES ('{$date}', '{$barcode}', '{$sales}', '{$sales_amount}', '{$menu_discount}', '{$payment_amount}', '{$datetime}') ";
// 이미 값이 있는 경우 업데이트
$query .= " ON DUPLICATE KEY UPDATE
sales = '{$sales}',
sales_amount = '{$sales_amount}',
menu_discount = '{$menu_discount}',
payment_amount = '{$payment_amount}',
edit_datetime = '{$datetime}'
";
$result = sql_query($query);
// 점검용, Query Print
if ($is_debug) {
print_r($query);
echo "<br>" . PHP_EOL;
}
}
}
}
}
} else {
echo SimpleXLSX::parseError();
}
} catch (Exception $e) {
echo '엑셀 파일 읽기 오류: ', $e->getMessage();
}
// 파일 삭제
if (file_exists($uploadFile)) {
unlink($uploadFile);
if ($is_debug) echo "파일 삭제 완료." . PHP_EOL;
}
} else {
echo "파일 업로드 실패";
}
} else {
echo "잘못된 요청";
}

View File

@ -0,0 +1,281 @@
<?php
// 베이커리 재고관리
include_once "_common.php";
if (!isset($_SESSION['user_id'])) header( 'Location: FG_MANAGER_URL' ); // 로그인 되어있지 않으면 로그인 페이지로 보냄
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";
// 날짜로 검색한 경우 해당 날짜를 사용하고, 아닌 경우 오늘 날짜를 사용함
$searchDate = isset($_REQUEST["searchDate"]) ? $_REQUEST["searchDate"] : date("Y-m-d"); // 검색일
$prevDate = date("Y-m-d", strtotime("-1 day", strtotime($searchDate))); // 검색 전일
$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;
// 합계 변수 선언
$t_prev_stock = $t_production = $t_inhouse_use = $t_recycling = $t_disposal = $t_sales = $t_sales_amount = $t_menu_discount = $t_payment_amount = $t_current_stock = 0;
/*
$chkQuery = "SELECT * FROM {$fg['bakery_product_table']} WHERE used = 1 ";
$cheQueryResult = sql_query($chkQuery);
$a=1;
while ($row = sql_fetch_array($cheQueryResult)) {
echo $a;
print_r($row);
echo "<br>";
$a++;
}
echo "여기까지 테스트";
*/
bakeryPreUpdate($searchDate, $edit_datetime);
$authInfo = getAuthorInfo($searchDate);
if (!$authInfo) {
$authInfo = ['worker' => '', 'author' => ''];
}
?>
<style>
/* 베이커리용 CSS */
.bakery tfoot {
font-weight: 600;
}
.sort-icon {
margin-left: 5px;
font-size: 12px;
vertical-align: middle;
}
/* 틀 고정
.tableWrapper {
overflow: auto;
height: 700px;
width: 100%;
}
#bakeryTable th {
position: sticky;
top: 0px;
}
*/
</style>
<h2 class="mb-3">베이커리 일일현황</h2>
<div class="d-flex justify-content-between">
<div class="row align-items-start flex-nowrap">
<div class="col-auto input-group">
<span class="input-group-text">날짜선택</span>
<input type="date" class="form-control" id="searchDateInput" name="searchDate" max="9999-12-31" value="<?= $searchDate ?>">
</div>
<div class="col-auto">
<form>
<input type="hidden" id="hiddenSearchDate" name="searchDate" value="<?= date("Y-m-d") ?>">
<button type="submit" class="btn btn-primary mb-3">오늘</button>
</form>
</div>
</div>
<div>
<input type="file" id="inventoryFileInput" style="display:none;" accept=".xls,.xlsx" />
<div class="btn-group" role="group" aria-label="bakery-button">
<?php if(!bakeryChkDate($searchDate, $_SESSION['user_id'])) {?>
<button type="button" class="btn btn-primary" id="editButton" onclick="toggleEditMode()" >수정</button>
<button type="button" class="btn btn-primary d-none" id="confirmButton" onclick="confirmEditMode()">확인</button>
<?php } ?>
<button type="button" class="btn btn-secondary" id="uploadInventoryButton">파일첨부</button>
<button type="button" class="btn btn-success" id="exportExcelButton">엑셀변환</button>
<?php if ($is_bakery || $is_admin) { ?>
<button type="button" class="btn btn-success" id="print">양식출력</button>
<?php } ?>
</div>
</div>
</div>
<div class="mb-3" style="max-width:600px;">
<form class="form-group" id="author" name="author" >
<input type="hidden" name="searchDate" id="searchDate" value="<?=$searchDate?>">
<div class="input-group">
<span class="input-group-text" id="worker">근무자</span>
<input style="width: 250px;" type="text" class="form-control" name="worker" id="worker" value="<?=$authInfo['worker']?>" required>
<span class="input-group-text" id="author">작성자</span>
<input style="width: 100px;" type="text" class="form-control" name="author" id="author" value="<?=$authInfo['author']?>" required>
</div>
</form>
</div>
<div class="tableWrapper">
<table class="table table-striped align-middle table-hover 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">
<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" data-column="product_name"></span></th>
<th class="text-center" data-column="barcode" data-order="asc">바코드 <span class="sort-icon" data-column="barcode"></span></th>
<th class="text-center" data-column="previous_stock" data-order="asc">전일재고 <span class="sort-icon" data-column="previous_stock"></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="unit_price" data-order="asc">단가 <span class="sort-icon" data-column="unit_price"></span></th>
<th class="text-center" data-column="sales_amount" data-order="asc">판매금액 <span class="sort-icon" data-column="sales_amount"></span></th>
<th class="text-center" data-column="menu_discount" data-order="asc">메뉴별할인 <span class="sort-icon" data-column="menu_discount"></span></th>
<th class="text-center" data-column="payment_amount" data-order="asc">결제금액 <span class="sort-icon" data-column="payment_amount"></span></th>
<th class="text-center" data-column="current_stock" data-order="asc">현재고 <span class="sort-icon" data-column="current_stock"></span></th>
</tr>
</thead>
<!-- 테이블 데이터 -->
<tbody class="table-group-divider" id="bakeryTableBody">
<?php
// 데이터 가져와서 뿌리기
$i = 1; // number 표시를 위한 변수
foreach (getBakeryInvenData($searchDate, $ord_by) as $row) {
// 전일자 현재고 가져오기, 없으면 0을 반환함
$previous_stock = getPrevStock($searchDate, $row['barcode']) ;
// 현재고
$current_stock = $previous_stock + $row['production'] - $row['inhouse_use'] - $row['recycling'] - $row['disposal'] - $row['sales'];
// 계산된 값과 DB에 저장된 값이 일치하지 않으면 업데이트
if ( $row['current_stock'] != $current_stock ) bakeryCurrentStockUpdate($searchDate, $row['barcode'], $current_stock);
// 단가 만들기
$unit_price = 0;
if ( $row['sales_amount'] != 0 || $row['sales'] != 0 ) {
$unit_price = $row['sales_amount'] / $row['sales'];
}
// 합계값 만들기, 전일재고와 현재고는 DB의 값을 사용하지 않음
$t_prev_stock += $previous_stock;
$t_production += $row['production'];
$t_inhouse_use += $row['inhouse_use'];
$t_recycling += $row['recycling'];
$t_disposal += $row['disposal'];
$t_sales += $row['sales'];
$t_sales_amount += $row['sales_amount'];
$t_menu_discount += $row['menu_discount'];
$t_payment_amount += $row['payment_amount'];
$t_current_stock += $current_stock;
?>
<tr id="row-<?=$row['barcode']?>">
<td class="text-center"><?=$i?></td>
<td class="text-center">
<a data-bs-toggle="modal" data-bs-target="#modify_modal_<?=$row['idx']?>">
<?=htmlspecialchars($row['product_name'])?>
</a>
</td>
<td class="text-center"><?=$row['barcode']?></td>
<td class="text-end"><?=number_format($previous_stock)?></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($unit_price)?></td>
<td class="text-end"><?=number_format($row['sales_amount'])?></td>
<td class="text-end"><?=number_format($row['menu_discount'])?></td>
<td class="text-end"><?=number_format($row['payment_amount'])?></td>
<td class="text-end"><?=number_format($current_stock)?></td>
</tr>
<!-- 수정 모달 -->
<div id="modify_modal_<?=$row['idx']?>" class="modal fade" tabindex="-1" aria-labelledby="modify_modal_<?=$row['idx']?>" aria-hidden="true">
<div class="modal-dialog modal modal-dialog-centered">
<div class="modal-content">
<form class="modify" id="modify_<?=$row['idx']?>" name="modify_<?=$row['idx']?>">
<div class="modal-header">
<h5 class="modal-title">정보 보기/수정</h5>
</div>
<div class="modal-body text-start">
<div class="input-group mb-1">
<span class="input-group-text col-md-2" id="product_name_<?=$row['idx']?>">품명</span>
<input type="text" class="form-control" id="product_name_<?=$row['idx']?>" name="product_name" value="<?=$row['product_name'] ?>">
<input type="radio" class="btn-check" name="used" id="used_<?=$row['idx']?>_1" value="1" <?=$row['used'] == "1" ? "checked": "" ?> required>
<label class="btn btn-outline-primary" for="used_<?=$row['idx']?>_1">사용</label>
<input type="radio" class="btn-check" name="used" id="used_<?=$row['idx']?>_0" value="0" <?=$row['used'] =="0" ? "checked" : "" ?> required>
<label class="btn btn-outline-primary" for="used_<?=$row['idx']?>_0">미사용</label>
</div>
<div class="input-group mb-1">
<span class="input-group-text col-md-2" id="barcode_<?=$row['idx']?>">바코드</span>
<input type="text" class="form-control" id="barcode_<?=$row['idx']?>" name="barcode" value="<?=$row['barcode']?>" required>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" >수정</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal" aria-label="Close" data-bs-target="#modify_modal_<?=$row['idx']?>">닫기</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
<!-- 수정 모달 끝 -->
<?php $i++;
} // endforeach
?>
</tbody>
<!-- 합계 데이터 출력 -->
<tfoot>
<tr>
<td colspan="3" class="text-center">합계</th>
<td class="text-end" id="total_prev_stock"><?=number_format($t_prev_stock)?></th>
<td class="text-end" id="total_production"><?=number_format($t_production)?></th>
<td class="text-end" id="total_inhouse_use"><?=number_format($t_inhouse_use)?></th>
<td class="text-end" id="total_recycling"><?=number_format($t_recycling)?></th>
<td class="text-end" id="total_disposal"><?=number_format($t_disposal)?></th>
<td class="text-end" id="total_sales"><?=number_format($t_sales)?></th>
<td class="text-end" id="total_unit_price"></th>
<td class="text-end" id="total_sales_amount"><?=number_format($t_sales_amount)?></th>
<td class="text-end" id="total_menu_discount"><?=number_format($t_menu_discount)?></th>
<td class="text-end" id="total_payment_amount"><?=number_format($t_payment_amount)?></th>
<td class="text-end" id="total_current_stock"><?=number_format($t_current_stock)?></th>
</tr>
</tfoot>
</table>
</div>
<?php
include_once "tail.sub.php";
include_once FG_MANAGER_PATH."/tail.php";

View File

@ -0,0 +1,34 @@
<?php
include_once '_common.php';
if(!$_SESSION['user_id']) exit; // 로그인 되어있지 않으면 확인 불가
if ($_SERVER["REQUEST_METHOD"] == "POST") { // POST로 넘어온 값이 있다면
// 변수 선언
$product_name = trim($_POST["product_name"]);
$barcode = trim($_POST['barcode']);
$date = trim($_POST['searchDate']);
$id = trim($_POST['id']);
$value = trim($_POST['value']);
$edit_datetime = date('Y-m-d H:i:s', strtotime($date)); // 최종 수정 시간 업데이트
// 리스트에서 product name을 가지고 와야 함, 사전에 post로 전달받거나 품목 테이블에서 가져와야함
// 기존에 동일한 date, barcode를 가진 값이 있는 경우 insert가 아닌 update 로 처리해야 함
// update query
$query = "INSERT INTO {$fg['bakery_inventory_table']} (date, barcode, {$id}, edit_datetime) ";
$query .= "VALUES('{$date}', '{$barcode}', '{$value}', '{$edit_datetime}') ";
$query .= "ON DUPLICATE KEY UPDATE
{$id} = '{$value}',
edit_datetime = '{$edit_datetime}'
"; // 이미 값이 있는 경우 업데이트함
$result = sql_query($query);
if ($result) {
echo json_encode(array('status' => 'success'));
} else {
echo json_encode(array('status' => 'error', 'message' => 'Database error'));
}
} else {
echo json_encode(array('status' => 'error', 'message' => 'Invalid request method'));
}

View File

@ -0,0 +1,96 @@
<?php
// 설정 파일 포함
include_once('_common.php');
if(!$_SESSION['user_id']) exit; // 로그인 되어있지 않으면 확인 불가
// 검색 날짜
$searchDate = $_POST['searchDate'];
$ord_by = $_POST['ordBy'];
$result = getBakeryInvenData($searchDate, $ord_by);
// UTF-8 BOM 추가
echo "\xEF\xBB\xBF";
// 헤더 설정
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-Description: PHP Generated Data");
?>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<style type="text/css">
.tit { background-color:#C0C0C0; height:30px; }
.no-text { mso-number-format:'\@'; text-align:center; }
</style>
<table cellspacing="0" cellpadding="0" border="1">
<thead>
<tr>
<th class="tit">품목</th>
<th class="tit">바코드</th>
<th class="tit">전일재고</th>
<th class="tit">생산</th>
<th class="tit">업장사용</th>
<th class="tit">재활용</th>
<th class="tit">폐기</th>
<th class="tit">판매수량</th>
<th class="tit">판매단가</th>
<th class="tit">판매금액</th>
<th class="tit">메뉴별할인</th>
<th class="tit">결제금액</th>
<th class="tit">현재고</th>
</tr>
</thead>
<tbody>
<?php
$t_prev_stock = $t_production = $t_inhouse_use = $t_recycling = $t_disposal = $t_sales = $t_sales_amount = $t_menu_discount = $t_payment_amount = $t_current_stock = 0;
// 데이터 출력
foreach ( $result as $row) {
?>
<tr>
<td><?=$row['product_name']?></td>
<td><?=$row['barcode']?></td>
<td><?=number_format(getPrevStock($searchDate, $row['barcode']))?></td>
<td><?=number_format($row['production'])?></td>
<td><?=number_format($row['inhouse_use'])?></td>
<td><?=number_format($row['recycling'])?></td>
<td><?=number_format($row['disposal'])?></td>
<td><?=number_format($row['sales'])?></td>
<td><?=($row['sales'] != 0 && $row['sales_amount'] != 0) ? number_format($row['sales_amount']/$row['sales']) : 0 ?></td>
<td><?=number_format($row['sales_amount'])?></td>
<td><?=number_format($row['menu_discount'])?></td>
<td><?=number_format($row['payment_amount'])?></td>
<td><?=number_format($row['current_stock'])?></td>
</tr>
<?php
// 합계 함수 처리
$t_prev_stock += $row['previous_stock'];
$t_production += $row['production'];
$t_inhouse_use += $row['inhouse_use'];
$t_recycling += $row['recycling'];
$t_disposal += $row['disposal'];
$t_sales += $row['sales'];
$t_sales_amount += $row['sales_amount'];
$t_menu_discount += $row['menu_discount'];
$t_payment_amount += $row['payment_amount'];
$t_current_stock += $row['current_stock'];
}
?>
</tbody>
<tfoot class="table-group-divider">
<tr class="bakery_total">
<td>합계</td>
<td></td>
<td><?=number_format($t_prev_stock) ?></td>
<td><?=number_format($t_production) ?></td>
<td><?=number_format($t_inhouse_use) ?></td>
<td><?=number_format($t_recycling) ?></td>
<td><?=number_format($t_disposal) ?></td>
<td><?=number_format($t_sales) ?></td>
<td></td>
<td><?=number_format($t_sales_amount) ?></td>
<td><?=number_format($t_menu_discount) ?></td>
<td><?=number_format($t_payment_amount) ?></td>
<td><?=number_format($t_current_stock) ?></td>
</tr>
</tfoot>
</table>

View File

@ -0,0 +1,102 @@
<?php
// 베이커리팀용 양식출력 파일
// 베이커리 재고관리
include_once "_common.php";
if(!$_SESSION['user_id']) exit;
// 검색 변수 초기화
!isset($search) ?? "";
!isset($where) ?? "";
!isset($search_count) ?? "";
$is_debug = false; // 디버깅 시 true로 변경
// 날짜로 검색한 경우 해당 날짜를 사용하고, 아닌 경우 오늘 날짜를 사용함
$searchDate = isset($_REQUEST["searchDate"]) ? $_REQUEST["searchDate"] : date("Y-m-d"); // 검색일
$prevDate = date("Y-m-d", strtotime("-1 day", strtotime($searchDate))); // 검색 전일
$edit_datetime = date('Y-m-d H:i:s'); // 최종 수정 시간 업데이트
bakeryPreUpdate($searchDate, $edit_datetime);
?>
<style>
@page {
margin-left: 2cm;
margin-right: 2cm;
}
.container { width: "100%"}
.bakery tfoot {
font-weight: 600;
}
.sort-icon {
margin-left: 5px;
font-size: 12px;
vertical-align: middle;
}
</style>
<html>
<head>
<title>베이커리 일일현황</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
</head>
<body>
<h2 class="mb-3 text-center">베이커리 일일현황</h2>
<div class="d-flex justify-content-end mb-3">
<div class="col-auto">
날짜 : <?= $searchDate ?>
</div>
</div>
<table class="table table-striped align-middle table-hover 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">품목</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 class="table-group-divider" id="bakeryTableBody">
<?php
// 데이터 가져와서 뿌리기
$i = 1; // number 표시를 위한 변수
foreach (getBakeryInvenData($searchDate) as $row) {
if($is_debug) var_dump($row);
// 전일자 현재고 가져오기, 없으면 0을 반환함
$previous_stock = getPrevStock($searchDate, $row['barcode']) ;
// 현재고
$current_stock = $previous_stock + $row['production'] - $row['inhouse_use'] - $row['recycling'] - $row['disposal'] - $row['sales'];
?>
<tr id="row-<?=$row['barcode']?>">
<td class="text-center"><?=$i?></td>
<td class="text-center"><?=htmlspecialchars($row['product_name'])?></td>
<td class="text-center"><?=$previous_stock?></td>
<td class="text-end"><input class="form-control text-end" type="text" value=""></td>
<td class="text-end"><input class="form-control text-end" type="text" value=""></td>
<td class="text-end"><input class="form-control text-end" type="text" value=""></td>
<td class="text-end"><input class="form-control text-end" type="text" value=""></td>
<td class="text-center"><?=$current_stock?></td>
</tr>
<?php $i++;
}
?>
</tbody>
</table>
</body>
</html>

264
manager/bakery/tail.sub.php Normal file
View File

@ -0,0 +1,264 @@
<script>
$(document).ready(function() {
var ordBy = <?php echo json_encode(isset($ord_by) ? $ord_by : ''); ?>;
var searchDate = <?php echo json_encode(isset($searchDate) ? $searchDate : ''); ?>;
// 삭제 확인 및 처리 함수
window.confirmDelete = function(idx) {
if (confirm('정말 삭제하시겠습니까? 삭제한 후 복원할 수 없습니다.')) {
var delete_url = 'bakery_product_list.ajax.delete.php';
var formData = {
idx: idx
};
$.post(delete_url, formData, function(json) {
if (json !== undefined && json.isSuccess) {
alert('처리가 완료되었습니다.');
location.reload();
} else {
alert('처리중 에러가 발생하였습니다: ' + (json || '알 수 없는 오류'));
}
});
}
};
// 수정 폼 전송 및 처리 함수 추가
$('.modify').on('submit', function(event) {
event.preventDefault(); // 기본 제출 동작 방지
var form = $(this);
var formData = form.serialize(); // 폼 데이터 직렬화
$.post('bakery_product_list.ajax.update.php', formData, function(json) {
console.log(json); // 반환된 데이터를 확인하기 위한 로그
if (json !== undefined && json.isSuccess) {
alert('수정이 완료되었습니다.');
location.reload();
} else if(json !== undefined && !json.isSuccess) {
alert('수정 중 에러가 발생하였습니다: ' + (json.message || '알 수 없는 오류'));
} else {
alert('수정 중 에러가 발생하였습니다. JSON 데이터가 정의되지 않았습니다.');
}
}).fail(function() {
alert('AJAX 요청 실패.');
});
});
// 추가 폼 전송 및 처리 함수 추가
$('.add').on('submit', function(event) {
event.preventDefault(); // 기본 제출 동작 방지
var form = $(this);
var formData = form.serialize(); // 폼 데이터 직렬화
$.post('bakery_product_list.ajax.add.php', formData, function(json) {
console.log(json); // 반환된 데이터를 확인하기 위한 로그
if (json !== undefined && json.isSuccess) {
alert('품목 추가가 완료되었습니다.');
location.reload();
} else if(json !== undefined && !json.isSuccess) {
alert('추가 중 에러가 발생하였습니다: ' + (json.message || '알 수 없는 오류'));
} else {
alert('추가 중 에러가 발생하였습니다. JSON 데이터가 정의되지 않았습니다.');
}
}).fail(function() {
alert('AJAX 요청 실패.');
});
});
function attachThClickEvent() {
$('table').off('click', 'th'); // 기존 이벤트 제거
$('table').on('click', 'th', function() {
if ($(this).hasClass('no-click')) {
return; // no-click 클래스를 가진 th 요소는 클릭 이벤트를 무시하고 이후 코드 실행 안함
}
console.log('th clicked:', $(this).data('column')); // 로그 추가
const column = $(this).data('column');
let order = $(this).data('order') || 'asc'; // 기본값 'asc'
order = order === 'asc' ? 'desc' : 'asc';
$(this).data('order', order);
sortTable(column, order); // 테이블 정렬 함수 호출
});
}
function sortTable(column, order) {
const tbody = $('#bakeryTable tbody');
const rows = tbody.find('tr').toArray();
rows.sort((a, b) => {
const aValue = $(a).find(`td:eq(${getColumnIndex(column)})`).text();
const bValue = $(b).find(`td:eq(${getColumnIndex(column)})`).text();
if (order === 'asc') {
return aValue.localeCompare(bValue, undefined, {numeric: true});
} else {
return bValue.localeCompare(aValue, undefined, {numeric: true});
}
});
$.each(rows, (index, row) => {
tbody.append(row);
// 정렬 후 No. 열의 값을 재설정
$(row).find('td').eq(0).text(index + 1);
});
}
function getColumnIndex(column) {
return $(`#bakeryTable th[data-column="${column}"]`).index();
}
attachThClickEvent();
// 날짜 입력값 변경 시 페이지 전체 갱신
$('#searchDateInput').on('change', function() {
const searchDate = $(this).val();
const url = new URL(window.location.href);
url.searchParams.set('searchDate', searchDate);
window.location.href = url.toString();
});
// 수정 버튼 클릭 시
window.toggleEditMode = function() {
document.querySelectorAll('tbody .value').forEach(span => {
span.classList.toggle('d-none');
});
document.querySelectorAll('tbody input.form-control').forEach(input => {
input.classList.toggle('d-none');
if (input.hasAttribute('readonly')) {
input.removeAttribute('readonly');
} else {
input.setAttribute('readonly', 'readonly');
}
});
document.getElementById('editButton').classList.toggle('d-none');
document.getElementById('confirmButton').classList.toggle('d-none');
}
// 확인 버튼 클릭 시 데이터 업데이트 및 합계 갱신
window.confirmEditMode = function() {
var formData = new FormData();
document.querySelectorAll('tbody input.form-control').forEach(input => {
formData.append(input.id, input.value);
});
formData.append('searchDate', $('#searchDate').val());
$.ajax({
url: 'bakery_stock.ajax.confirm.update.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(response) {
console.log('Data updated successfully'); // 로그 추가
toggleEditMode();
// updateTableBody({ ord_by: ordBy, searchDate: $('#searchDate').val() }); // 불필요한 호출 제거
updateTotal(); // 합계 갱신
// location.reload();
},
error: function(xhr, status, error) {
console.error('Error: ' + error);
}
});
}
// 파일 업로드 버튼 클릭 시 파일 선택 창 열기
$('#uploadInventoryButton').on('click', function() {
$('#inventoryFileInput').click();
});
// 파일 선택 시 AJAX로 파일 업로드
$('#inventoryFileInput').on('change', function() {
var file = $('#inventoryFileInput')[0].files[0];
if (isValidExcelFile(file)) {
var formData = new FormData();
formData.append('file', file);
formData.append('searchDate', $('#searchDate').val());
$.ajax({
url: 'bakery_stock.ajax.upload_inventory.php',
type: 'POST',
data: formData,
contentType: false,
processData: false,
success: function(response) {
alert('파일 업로드 완료');
location.reload(); // 파일 업로드 후 페이지 새로고침
},
error: function() {
alert('파일 업로드 실패');
}
});
} else {
alert('엑셀 파일만 업로드할 수 있습니다.');
}
});
function isValidExcelFile(file) {
const validExtensions = ['.xls', '.xlsx'];
const fileName = file.name.toLowerCase();
return validExtensions.some(ext => fileName.endsWith(ext));
}
// 엑셀변환 ajax
document.getElementById('exportExcelButton').addEventListener('click', function() {
$.ajax({
url: 'bakery_stock_excel.php',
type: 'POST',
data: { searchDate: $('#searchDate').val(), ordBy: ordBy },
xhrFields: {
responseType: 'blob'
},
success: function(data) {
var blob = new Blob([data], { type: 'application/vnd.ms-excel' });
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = 'bakery_data_' + $('#searchDate').val() + '.xls';
link.click();
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('엑셀 파일 다운로드 실패:', textStatus, errorThrown);
}
});
});
// author 업데이트
$('#author input').on('blur', function(event) {
var formData = new FormData(document.getElementById('author')); // 폼 데이터 직렬화
console.log("Form Data:", formData); // 직렬화된 데이터 로그 확인
$.ajax({
type: 'POST',
url: 'bakery_stock.ajax.author.update.php',
data: formData,
processData: false,
contentType: false,
success: function(response) {
if (response.success) {
console.log('데이터가 성공적으로 저장되었습니다.');
} else {
console.error('데이터 저장에 실패하였습니다: ' + response.message);
}
},
error: function(xhr, status, error) {
console.error('AJAX 호출 중 오류가 발생하였습니다: ' + error);
}
});
});
// 출력 버튼 클릭 이벤트 추가
$('#print').on('click', function() {
var searchDate = $('#searchDate').val(); // searchDate 값을 가져옴
var printWindow = window.open('bakery_stock_print.php?searchDate=' + searchDate, '_blank', 'width=800,height=600');
printWindow.onload = function() {
printWindow.print();
};
});
});
</script>