- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
2426 lines
101 KiB
PHP
2426 lines
101 KiB
PHP
<?php
|
||
// 2025/05/23 데이터 복사시 견적번호 마지막의 뒤 -00형태 제거하기
|
||
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';
|
||
|
||
$mode = isset($_REQUEST['mode']) ? $_REQUEST['mode'] : '';
|
||
$num = isset($_REQUEST["num"]) ? $_REQUEST["num"] : "";
|
||
$tablename = isset($_REQUEST["tablename"]) ? $_REQUEST["tablename"] : "";
|
||
$header = isset($_REQUEST["header"]) ? $_REQUEST["header"] : ""; // 수주창에서 호출하는 경우 사용
|
||
$itemoption = isset($_REQUEST["itemoption"]) ? $_REQUEST["itemoption"] : ""; // option = screen , slat 선택 전달 (수주내역에서 호출)
|
||
$tempKey = isset($_REQUEST["tempKey"]) ? $_REQUEST["tempKey"] : "";
|
||
|
||
$estimateSurang = $_REQUEST['estimateSurang'] ?? '';
|
||
$EstimateFirstSum = $_REQUEST['EstimateFirstSum'] ?? '';
|
||
$EstimateUpdatetSum = $_REQUEST['EstimateUpdatetSum'] ?? '';
|
||
$EstimateDiffer = $_REQUEST['EstimateDiffer'] ?? '';
|
||
$estimateTotal = $_REQUEST['estimateTotal'] ?? '';
|
||
$makeWidth = $_REQUEST['makeWidth'] ?? '';
|
||
$makeHeight = $_REQUEST['makeHeight'] ?? '';
|
||
$maguriWing = $_REQUEST['maguriWing'] ?? '';
|
||
$inspectionFee = $_REQUEST['inspectionFee'] ?? '';
|
||
|
||
|
||
// print '$makeWidth ' . $makeWidth . '<br>';
|
||
// print '$makeHeight ' . $makeHeight . '<br>';
|
||
// print '$maguriWing ' . $maguriWing . '<br>';
|
||
// print '$inspectionFee ' . $inspectionFee . '<br>';
|
||
|
||
if($header == 'header')
|
||
{
|
||
$title_message = "견적서에서 발주 산출";
|
||
}
|
||
else
|
||
{
|
||
if($mode === 'copy')
|
||
$title_message = "(데이터복사) 견적 산출";
|
||
else
|
||
$title_message = "견적 산출" ;
|
||
}
|
||
|
||
if($itemoption == 'screen')
|
||
{
|
||
$title_message = "스크린 발주서 수정";
|
||
$tablename = 'output';
|
||
$major_category = '스크린';
|
||
}
|
||
else if($itemoption == 'slat')
|
||
{
|
||
$title_message = "철재스라트 발주서 수정";
|
||
$tablename = 'output';
|
||
$major_category = '철재';
|
||
}
|
||
|
||
$authorities = ["개발자","전진","노완호","이세희","함신옥","손금주","이은진","이경호"];
|
||
// print $position;
|
||
?>
|
||
<title> <?=$title_message?> </title>
|
||
|
||
<style>
|
||
textarea {
|
||
overflow: hidden;
|
||
resize: none; /* 사용자 크기 조절을 방지 */
|
||
}
|
||
/* 기본 스타일 설정 */
|
||
input[type="checkbox"],
|
||
input[type="radio"] {
|
||
transform: scale(1.3); /* 크기 확대 */
|
||
margin: 3px; /* 여백 추가 */
|
||
}
|
||
|
||
/* "readonly" 상태일 때 스타일 설정 */
|
||
.readonly-checkbox,
|
||
.readonly-radio {
|
||
pointer-events: none; /* 사용자 상호작용 비활성화 */
|
||
opacity: 1; /* 불투명도 설정 */
|
||
color: red;
|
||
}
|
||
|
||
/* 레이블 텍스트 크게 설정 */
|
||
label {
|
||
font-size: 1.2em; /* 글꼴 크기 확대 */
|
||
display: inline-block;
|
||
margin: 3px 0;
|
||
}
|
||
.w-40{
|
||
width: 40%!important;
|
||
}
|
||
.w-50{
|
||
width: 50%!important;
|
||
}
|
||
.w-60{
|
||
width: 60%!important;
|
||
}
|
||
|
||
.w-85{
|
||
width: 85%!important;
|
||
}
|
||
|
||
.viewNoBtn {
|
||
cursor : pointer;
|
||
}
|
||
|
||
/* CSS: 수동편집된 요소의 배경색 */
|
||
.manually-edited {
|
||
background-color: #f8d7da !important;
|
||
}
|
||
</style>
|
||
|
||
</head>
|
||
|
||
<?
|
||
include $_SERVER['DOCUMENT_ROOT'] . '/mymodal.php';
|
||
|
||
// 첨부 이미지에 대한 부분
|
||
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
|
||
$pdo = db_connect();
|
||
|
||
$today = date("Y-m-d"); // 현재일자 변수지정
|
||
|
||
if(!empty($itemoption) && $itemoption == 'screen')
|
||
{
|
||
|
||
$today = date("Y-m-d"); // 현재일자 변수지정
|
||
|
||
$num = $_GET['num'] ?? '';
|
||
$tempKey = $_GET['tempKey'] ?? '';
|
||
|
||
if ($tempKey) {
|
||
$jsonFilePath = $_SERVER['DOCUMENT_ROOT'] . '/output/json/' . $tempKey . '.json';
|
||
|
||
// JSON 파일이 존재하면 읽어옴
|
||
if (file_exists($jsonFilePath)) {
|
||
$jsonData = file_get_contents($jsonFilePath);
|
||
$estimateList = json_decode($jsonData, true);
|
||
$estimateList_auto = json_decode($jsonData, true); // auto는 기존자료 복사
|
||
} else {
|
||
echo "JSON 파일을 찾을 수 없습니다.";
|
||
exit;
|
||
}
|
||
} else {
|
||
echo "유효하지 않은 접근입니다.";
|
||
exit;
|
||
}
|
||
|
||
if (empty($makeWidth) || !is_numeric($makeWidth)) $makeWidth = '160';
|
||
if (empty($makeHeight) || !is_numeric($makeHeight)) $makeHeight = '350';
|
||
if (empty($maguriWing) || !is_numeric($maguriWing)) $maguriWing = '50';
|
||
|
||
// echo '<pre>';
|
||
// print_r($estimateList);
|
||
// echo '</pre>';
|
||
}
|
||
else if(!empty($itemoption) && $itemoption == 'slat')
|
||
{
|
||
|
||
$today = date("Y-m-d"); // 현재일자 변수지정
|
||
|
||
$num = $_GET['num'] ?? '';
|
||
$tempKey = $_GET['tempKey'] ?? '';
|
||
|
||
if ($tempKey) {
|
||
$jsonFilePath = $_SERVER['DOCUMENT_ROOT'] . '/output/json/' . $tempKey . '.json';
|
||
|
||
// JSON 파일이 존재하면 읽어옴
|
||
if (file_exists($jsonFilePath)) {
|
||
$jsonData = file_get_contents($jsonFilePath);
|
||
$estimateSlatList = json_decode($jsonData, true);
|
||
$estimateSlatList_auto = json_decode($jsonData, true); // auto는 기존자료 복사
|
||
} else {
|
||
echo "JSON 파일을 찾을 수 없습니다.";
|
||
exit;
|
||
}
|
||
} else {
|
||
echo "유효하지 않은 접근입니다.";
|
||
exit;
|
||
}
|
||
|
||
if (empty($makeWidth) || !is_numeric($makeWidth)) $makeWidth = '110';
|
||
if (empty($makeHeight) || !is_numeric($makeHeight)) $makeHeight = '350';
|
||
if (empty($maguriWing) || !is_numeric($maguriWing)) $maguriWing = '50';
|
||
|
||
// echo '<pre>';
|
||
// print_r($estimateSlatList);
|
||
// echo '</pre>';
|
||
|
||
}
|
||
else
|
||
{
|
||
// 수주리스트에서 호출이 아닌 경우 이것 실행
|
||
if ($mode=="modify" || !empty($num) )
|
||
{
|
||
try{
|
||
$sql = "select * from $DB.$tablename where num = ? ";
|
||
$stmh = $pdo->prepare($sql);
|
||
|
||
$stmh->bindValue(1,$num,PDO::PARAM_STR);
|
||
$stmh->execute();
|
||
$count = $stmh->rowCount();
|
||
$row = $stmh->fetch(PDO::FETCH_ASSOC); // $row 배열로 DB 정보를 불러온다.
|
||
if($count<1){
|
||
print "검색결과가 없습니다.<br>";
|
||
}else{
|
||
|
||
include '_row.php';
|
||
|
||
if($indate!="0000-00-00") $indate = date("Y-m-d", strtotime( $indate) );
|
||
else $indate="";
|
||
if($outdate!="0000-00-00") $outdate = date("Y-m-d", strtotime( $outdate) );
|
||
else $outdate="";
|
||
|
||
}
|
||
}catch (PDOException $Exception) {
|
||
print "오류: ".$Exception->getMessage();
|
||
}
|
||
}
|
||
|
||
else if ($mode!="modify" && $mode!="view"){ // 수정모드가 아닐때 신규 자료일때는 변수 초기화 한다.
|
||
include '_request.php';
|
||
$indate=date("Y-m-d");
|
||
$orderman=$_SESSION["name"];
|
||
$outworkplace=null;
|
||
$comment=null;
|
||
$secondord = '';
|
||
$secondordman = '';
|
||
$secondordmantel = '';
|
||
$inspectionFeeFormatted = '50,000'; // 검사비 설정
|
||
}
|
||
|
||
else if ($mode == "copy" || $mode == 'split') {
|
||
try {
|
||
$sql = "select * from " . $DB . ".{$tablename} where num = ? ";
|
||
$stmh = $pdo->prepare($sql);
|
||
$stmh->bindValue(1, $num, PDO::PARAM_STR);
|
||
$stmh->execute();
|
||
$count = $stmh->rowCount();
|
||
if($count<1){
|
||
print "검색결과가 없습니다.<br>";
|
||
} else {
|
||
$row = $stmh->fetch(PDO::FETCH_ASSOC);
|
||
}
|
||
include '_row.php';
|
||
} catch (PDOException $Exception) {
|
||
print "오류: ".$Exception->getMessage();
|
||
}
|
||
// 자료번호 초기화
|
||
$num = 0;
|
||
$indate=date("Y-m-d");
|
||
$orderman=$_SESSION["name"];
|
||
}
|
||
|
||
}
|
||
|
||
if ($mode == "copy") {
|
||
// 견적번호의 마지막 -00 제거하기
|
||
$pjnum = substr($pjnum, 0, -3);
|
||
}
|
||
|
||
|
||
if(!empty($itemoption) && ($itemoption == 'slat' || $itemoption == 'screen' ) )
|
||
{
|
||
// 전달받은 체크박스상태 값으로 수정함.
|
||
$steel = $_REQUEST['steelChecked'] == 'checked' ? '1' : '0';
|
||
$motor = $_REQUEST['motorChecked'] == 'checked' ? '1' : '0';
|
||
$warranty = $_REQUEST['warrantyChecked'] == 'checked' ? '인정' : '';
|
||
$slatcheck = $_REQUEST['slatChecked'] == 'checked' ? '1' : '0';
|
||
$partscheck = $_REQUEST['partsChecked'] == 'checked' ? '1' : '0';
|
||
|
||
// echo $itemoption . '<br>' ;
|
||
// echo $steel;
|
||
// echo $motor;
|
||
// echo $warranty;
|
||
// echo $slatcheck;
|
||
// echo $partscheck;
|
||
}
|
||
|
||
// echo '<pre>';
|
||
// print_r($row);
|
||
// echo '</pre>';
|
||
|
||
// echo '모델명 : ' . $model_name;
|
||
|
||
// 검사비가 0일때 신규일때는 만들어주고 수정일때는 무시함
|
||
if (!empty($inspectionFee)) {
|
||
$inspectionFee = (int)str_replace(',', '', $inspectionFee);
|
||
}
|
||
|
||
// 검사비 출력용으로 포맷 적용
|
||
$inspectionFeeFormatted = number_format($inspectionFee);
|
||
|
||
|
||
?>
|
||
|
||
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data" >
|
||
|
||
<input type="hidden" id="mode" name="mode" value="<?= isset($mode) ? $mode : '' ?>">
|
||
<input type="hidden" id="num" name="num" value="<?= isset($num) ? $num : '' ?>">
|
||
<input type="hidden" id="level" name="level" value="<?= isset($level) ? $level : '' ?>">
|
||
<input type="hidden" id="user_name" name="user_name" value="<?= isset($user_name) ? $user_name : '' ?>">
|
||
<input type="hidden" id="update_log" name="update_log" value="<?= isset($update_log) ? $update_log : null ?>">
|
||
<input type="hidden" id="tablename" name="tablename" value="<?= isset($tablename) ? $tablename : '' ?>">
|
||
<input type="hidden" id="header" name="header" value="<?= isset($header) ? $header : '' ?>">
|
||
<input type="hidden" id="is_deleted" name="is_deleted" value="<?= isset($is_deleted) ? $is_deleted : null ?>">
|
||
<input type="hidden" id="position" name="position" value="<?= isset($position) ? $position : null ?>">
|
||
<input type="hidden" id="secondordnum" name="secondordnum" value="<?= isset($secondordnum) ? $secondordnum : null ?>">
|
||
<input type="hidden" id="major_category" name="major_category" value="<?= isset($major_category) ? $major_category : null ?>">
|
||
<input type="hidden" id="estimateList" name="estimateList">
|
||
<input type="hidden" id="estimateSlatList" name="estimateSlatList">
|
||
<input type="hidden" id="estimateList_auto" name="estimateList_auto">
|
||
<input type="hidden" id="estimateSlatList_auto" name="estimateSlatList_auto">
|
||
|
||
<div class="container">
|
||
<div class="row justify-content-center align-items-center ">
|
||
<div class="card align-middle " style="width: 55rem;">
|
||
<div class="card-body text-center">
|
||
<div class="row d-flex justify-content-center align-items-center mb-3" >
|
||
<div class="col-sm-1" >
|
||
<div class="d-flex p-1 mb-1 justify-content-start align-items-center ">
|
||
<?=$mode?>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-9" >
|
||
<div class="d-flex p-1 mb-1 justify-content-center align-items-center ">
|
||
<h4> <?=$title_message?> </h4>
|
||
<?php if($mode =='view') { ?>
|
||
<button type="button" class="btn btn-dark btn-sm mx-1" onclick='location.reload();' > <i class="bi bi-arrow-clockwise"></i> </button>
|
||
<button type="button" class="btn btn-dark btn-sm mx-1" onclick="location.href='write_form.php?mode=modify&num=<?=$num?>&tablename=<?=$tablename?>';" > <i class="bi bi-pencil-square"></i> 수정 </button>
|
||
<button id="copyBtn" class="btn btn-primary btn-sm mx-1" type="button"><i class="bi bi-copy"></i> 복사</button>
|
||
<button id="deleteBtn" class="btn btn-danger btn-sm mx-1" type="button"><i class="bi bi-trash2"></i> 삭제</button>
|
||
<?php } ?>
|
||
<?php if($mode!=='view') { ?>
|
||
<?php if(!empty($itemoption)) : ?>
|
||
<button id="adaptParentBtn" class="btn btn-dark btn-sm me-1 " type="button"> <i class="bi bi-hdd-fill"></i> 발주서에 적용하기 </button>
|
||
<?php else : ?>
|
||
<button id="saveBtn" class="btn btn-dark btn-sm mx-1 " type="button"> <i class="bi bi-hdd-fill"></i> 저장 </button>
|
||
<?php endif; ?>
|
||
<? } ?>
|
||
<button type="button" class="btn btn-outline-dark btn-sm mx-2" id="showlogBtn"> H
|
||
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-2" >
|
||
<button type="button" class="btn btn-outline-dark btn-sm " onclick="self.close();" > <i class="bi bi-box-arrow-left"></i> 창닫기 </button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="container-fluid" >
|
||
<div class="row" >
|
||
<div class="col-lg-12 col-sm-12">
|
||
<div class="d-flex justify-content-center align-items-center">
|
||
<div class="card">
|
||
<div class="card-body text-center">
|
||
<div class="d-flex justify-content-center align-items-center" >
|
||
<table class="table table-bordered"
|
||
<?php if (!empty($itemoption)) echo 'style="display:none;"'; ?>>
|
||
<tbody
|
||
<?php if (!empty($itemoption)) echo 'style="display:none;"'; ?> >
|
||
<tr>
|
||
<td class="text-end" style="width:100px;"> 제품 대분류 </td>
|
||
<td style="width:220px;">
|
||
<span class="text-center text-danger mx-2">
|
||
<?php
|
||
$checkstep_options = ["스크린", "철재"];
|
||
$major_category_array = explode(", ", $major_category);
|
||
|
||
// 값이 비어있을 경우 '스크린'을 기본으로 선택
|
||
if (empty($major_category)) {
|
||
$major_category_array = ["스크린"];
|
||
}
|
||
foreach ($checkstep_options as $option) {
|
||
$checked = in_array($option, $major_category_array) ? 'checked' : '';
|
||
echo '<span class="fw-bold text-primary ms-2">' . $option . '</span>
|
||
<input type="radio" name="radio_item" value="' . $option . '" ' . $checked . '> ';
|
||
}
|
||
?>
|
||
</span>
|
||
</td>
|
||
<td class="text-end" style="width:60px;"> 모델명 </td>
|
||
<td>
|
||
<!-- 제품모델(KSS01 등) 선택 -->
|
||
<?php
|
||
$modelsList = [];
|
||
|
||
// $modelsList가 전역에서 아직 설정되지 않았거나, 배열이 아니거나 비어있으면 JSON 파일에서 로드합니다.
|
||
if (!isset($modelsList) || !is_array($modelsList) || empty($modelsList)) {
|
||
$jsonFile = $_SERVER['DOCUMENT_ROOT'].'/models/models.json';
|
||
if(file_exists($jsonFile)) {
|
||
$jsonContent = file_get_contents($jsonFile);
|
||
$modelsList = json_decode($jsonContent, true);
|
||
if(!is_array($modelsList)) {
|
||
$modelsList = [];
|
||
}
|
||
}
|
||
}
|
||
// (1) $model_name 공백 제거
|
||
$model_name = isset($model_name) ? trim($model_name) : '';
|
||
|
||
// 모델 리스트 로드 로직은 그대로…
|
||
|
||
echo '<select
|
||
id="model_name"
|
||
name="model_name"
|
||
class="form-select mx-1 d-block w-auto viewmode viewNoBtn"
|
||
style="font-size:0.8rem; height:32px;"
|
||
data-readonly="true"
|
||
>';
|
||
echo '<option value="">(모델 선택)</option>';
|
||
|
||
foreach ($modelsList as $model) {
|
||
// (2) 값 준비
|
||
$optValue = trim($model['model_name']);
|
||
$pairValue = trim($model['pair']);
|
||
|
||
$value = htmlspecialchars($optValue, ENT_QUOTES, 'UTF-8');
|
||
$pair = htmlspecialchars($pairValue, ENT_QUOTES, 'UTF-8');
|
||
|
||
// (3) selected 결정
|
||
$selected = ($model_name === $optValue) ? ' selected' : '';
|
||
|
||
echo "<option value=\"{$value}\" data-pair=\"{$pair}\"{$selected}>{$value}</option>";
|
||
}
|
||
|
||
echo '</select>';
|
||
?>
|
||
</td>
|
||
<td class="text-end" style="width:50px;"> 접수 </td>
|
||
<td style="width:100px;">
|
||
<input type="date" id="indate" name="indate" class="form-control" value="<?=$indate?>" >
|
||
</td>
|
||
<td class="text-end" style="width:80px;"> 견적번호 </td>
|
||
<td style="width:180px;">
|
||
<input type="text" id="pjnum" name="pjnum" class="form-control" value="<?=$pjnum?>" >
|
||
</td>
|
||
<td class="text-end" style="width:80px;">발주처</td>
|
||
<td style="width:300px;">
|
||
<div class="d-flex align-items-center justify-content-center">
|
||
<input type="text" id="secondord" name="secondord" value="<?=$secondord?>" class="form-control text-start" autocomplete="off" onkeydown="if(event.keyCode == 13) { phonebookBtn('secondord'); }">
|
||
<button type="button" class="btn btn-dark-outline btn-sm restrictbtn" onclick="phonebookBtn('secondord');"> <i class="bi bi-gear"></i> </button>
|
||
</div>
|
||
</td>
|
||
<td class="text-end" style="width:60px;"> 담당자</td>
|
||
<td style="width:130px;">
|
||
<input type="text" id="secondordman" name="secondordman" class="form-control text-start" autocomplete="off" value="<?=$secondordman?>" onkeydown="if(event.keyCode == 13) { phonebookBtn('secondordman'); }">
|
||
</td>
|
||
<td class="text-end" style="width:90px;"> 연락처 <i class="bi bi-telephone-forward-fill"></i></td>
|
||
<td style="width:130px;">
|
||
<div class="d-flex align-items-center justify-content-center">
|
||
<input type="text" id="secondordmantel" name="secondordmantel" value="<?=$secondordmantel?>" autocomplete="off" class="form-control text-start" onkeydown="if(event.keyCode == 13) { phonebookBtn('secondordmantel'); }">
|
||
</div>
|
||
</td>
|
||
<td class="text-center" style="width:100px;"> (경동)작성자 </td>
|
||
<td style="width:100px;">
|
||
<input type="text" id="orderman" name="orderman" value="<?=$orderman?>" class="form-control" placeholder="주일/경동 직원" >
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-sm-8">
|
||
<div class="d-flex justify-content-center align-items-center"
|
||
<?php if(!empty($itemoption)) echo 'style="display:none;"'; ?> >
|
||
<table class="table table-bordered">
|
||
<tbody>
|
||
<tr>
|
||
<td colspan="4" class="text-start" >
|
||
<?php
|
||
$steelChecked = ($steel == "1") ? 'checked' : '' ; // 절곡체크가 steel 임.
|
||
$motorChecked = ($motor == "1") ? 'checked' : ''; // 모터가 들어가는지 체크
|
||
$warrantyChecked = ($warranty == "인정") ? 'checked' : ''; // 인정제품인지 체크
|
||
$slatChecked = ($slatcheck == "1") ? 'checked' : ''; // 주자재(스크린,철재) 체크
|
||
$partsChecked = ($partscheck == "1") ? 'checked' : ''; // 부자재 체크
|
||
?>
|
||
<div class="d-flex align-items-center justify-content-center">
|
||
<h6>
|
||
<label for="warranty">
|
||
<input type="checkbox" id="warranty" data-readonly="true" name="warranty" value="인정" <?= $warrantyChecked ?> onchange="toggleOtherCheckboxes(this)">
|
||
<span class="badge bg-primary-subtle border border-primary-subtle text-primary-emphasis rounded-pill me-1"> 인정 </span>
|
||
</label>
|
||
<label for="slatcheck">
|
||
<input type="checkbox" id="slatcheck" data-readonly="true" name="slatcheck" value="1" <?= $slatChecked ?>>
|
||
<span class="badge bg-info-subtle border border-info-subtle text-info-emphasis rounded-pill me-1"> 주자재(스크린,철재) </span>
|
||
</label>
|
||
<label for="motor">
|
||
<input type="checkbox" id="motor" data-readonly="true" name="motor" value="1" <?= $motorChecked ?>>
|
||
<span class="badge bg-success-subtle border border-success-subtle text-success-emphasis rounded-pill me-1"> 모터 </span>
|
||
</label>
|
||
<label for="steel">
|
||
<input type="checkbox" data-readonly="true" id="steel" name="steel" value="1" <?= $steelChecked ?>>
|
||
<span class="badge bg-secondary-subtle border border-secondary-subtle text-secondary-emphasis rounded-pill me-1"> 절곡 </span>
|
||
</label>
|
||
<label for="partscheck">
|
||
<input type="checkbox" id="partscheck" data-readonly="true" name="partscheck" value="1" <?= $partsChecked ?>>
|
||
<span class="badge bg-danger-subtle border border-danger-subtle text-danger-emphasis rounded-pill me-1"> 부자재 </span>
|
||
</label>
|
||
<button type="button" id="applyToAllRowsBtn" class="btn btn-warning btn-sm ms-3" title="체크박스 설정을 모든 행에 적용">
|
||
<i class="bi bi-arrow-down-circle"></i> 체크 해제된 모든행의 값 제거하기
|
||
</button>
|
||
</h6>
|
||
</div>
|
||
|
||
<script>
|
||
function toggleOtherCheckboxes(warrantyCheckbox) {
|
||
// 나머지 4개 체크박스 ID들
|
||
const otherCheckboxes = ['slatcheck', 'motor', 'steel', 'partscheck'];
|
||
|
||
// 인정 체크박스가 체크되었는지 확인
|
||
const isChecked = warrantyCheckbox.checked;
|
||
|
||
// 나머지 체크박스들을 모두 동일한 상태로 설정
|
||
otherCheckboxes.forEach(function(checkboxId) {
|
||
const checkbox = document.getElementById(checkboxId);
|
||
if (checkbox) {
|
||
checkbox.checked = isChecked;
|
||
}
|
||
});
|
||
}
|
||
|
||
// 모든 행에 체크박스 설정 적용하는 함수
|
||
function applyCheckboxSettingsToAllRows() {
|
||
console.log('🔍 [DEBUG] applyCheckboxSettingsToAllRows 함수 시작');
|
||
|
||
// 중복 실행 방지를 위한 플래그
|
||
if (window.isApplyingCheckboxSettings) {
|
||
console.log('⚠️ [DEBUG] 이미 실행 중입니다. 중복 실행 방지');
|
||
return;
|
||
}
|
||
window.isApplyingCheckboxSettings = true;
|
||
|
||
try {
|
||
// 체크박스 상태 확인
|
||
const warrantyChecked = document.getElementById('warranty').checked;
|
||
const slatcheckChecked = document.getElementById('slatcheck').checked;
|
||
const motorChecked = document.getElementById('motor').checked;
|
||
const steelChecked = document.getElementById('steel').checked;
|
||
const partscheckChecked = document.getElementById('partscheck').checked;
|
||
|
||
console.log('📋 [DEBUG] 체크박스 상태:', {
|
||
warranty: warrantyChecked,
|
||
slatcheck: slatcheckChecked,
|
||
motor: motorChecked,
|
||
steel: steelChecked,
|
||
partscheck: partscheckChecked
|
||
});
|
||
|
||
// 현재 선택된 제품 타입 확인
|
||
const selectedType = $('input[name="radio_item"]:checked').val();
|
||
console.log('🎯 [DEBUG] 선택된 제품 타입:', selectedType);
|
||
|
||
let targetTable = '';
|
||
let uncheckedClasses = {};
|
||
|
||
if (selectedType === '스크린') {
|
||
targetTable = '#estimateTable';
|
||
console.log('📺 [DEBUG] 스크린 테이블 선택됨:', targetTable);
|
||
// 스크린 테이블용 클래스 매핑 name
|
||
uncheckedClasses = {
|
||
'slatcheck': ['col10_SW', 'col11_SH'], // 주자재 - 제품명, 종류, 가이드레일, 마감유형
|
||
'motor': ['col18_brand','col18', 'col18_wireless', 'col19', 'col20', 'col21', 'col22','col15','col16','col17'], // 연동제어기 매립, 노출, 뒷박스, 모터 - 브랜드, 전원, 유/무선, 용량
|
||
'steel': [ 'col6','col7', 'col36_custom','col36_frontbottom','col36_railwidth','col36_boxdirection','col23', 'col24', 'col25', 'col26', 'col27', 'col28', 'col29', 'col30', 'col31', 'col32', 'col33', 'col34', 'col35', 'col36', 'col37', 'col38', 'col39', 'col40', 'col41', 'col42', 'col43', 'col44', 'col45', 'col46', 'col47', 'col48', 'col49', 'col50', 'col51', 'col52', 'col53', 'col54', 'col55', 'col56', 'col57'], // 절곡 - 모든 절곡 관련 컬럼
|
||
'partscheck': ['col59_inch','col59_length','col59','col60','col61','col62', 'col63', 'col64', 'col65', 'col66', 'col67', 'col68', 'col69', 'col70', 'col71', 'col72', 'col73', 'col74', 'col75'] // 부자재 - 부자재 관련 컬럼
|
||
};
|
||
} else if (selectedType === '철재') {
|
||
targetTable = '#estimateSlatTable';
|
||
console.log('🔧 [DEBUG] 철재 테이블 선택됨:', targetTable);
|
||
// 철재 테이블용 클래스 매핑 name
|
||
// 마지막에 조인트바 col76 강제로 체크사항에 넣음
|
||
uncheckedClasses = {
|
||
'slatcheck': ['col10_SW', 'col11_SH', 'col76'], // 주자재 - 제품명, 종류, 가이드레일, 마감유형
|
||
'motor': ['col19_brand','col19', 'col19_wireless', 'col20', 'col21', 'col22', 'col23', 'col16','col17','col18', 'col76'], // 연동제어기 매립, 노출, 뒷박스, 모터 - 브랜드, 전원, 유/무선, 용량
|
||
'steel': ['col37', 'col37_custom','col37_frontbottom', 'col37_railwidth', 'col37_boxdirection', 'col25', 'col26', 'col27', 'col28', 'col29', 'col30', 'col31', 'col32', 'col33', 'col34', 'col35', 'col36', 'col37', 'col39', 'col40', 'col41', 'col42', 'col43', 'col44', 'col45', 'col46_wing', 'col47', 'col48', 'col50', 'col51', 'col52', 'col53', 'col54', 'col55', 'col56', 'col57', 'col58' ], // 절곡 - 모든 절곡 관련 컬럼
|
||
'partscheck': ['col61','col62', 'col63', 'col64', 'col65', 'col66', 'col67', 'col68', 'col69', 'col70', 'col71', 'col74', 'col75', 'col77'] // 부자재 - 부자재 관련 컬럼 조인트바는 주자재로 인식
|
||
};
|
||
} else {
|
||
console.error('❌ [DEBUG] 제품 타입이 선택되지 않음');
|
||
alert('제품 타입을 선택해주세요.');
|
||
return;
|
||
}
|
||
|
||
// 테이블 존재 여부 확인
|
||
const tableExists = $(targetTable).length > 0;
|
||
console.log('📊 [DEBUG] 테이블 존재 여부:', tableExists, '테이블:', targetTable);
|
||
|
||
if (!tableExists) {
|
||
console.error('❌ [DEBUG] 테이블을 찾을 수 없음:', targetTable);
|
||
alert('테이블을 찾을 수 없습니다: ' + targetTable);
|
||
return;
|
||
}
|
||
|
||
// 테이블 내 행 수 확인
|
||
const rowCount = $(targetTable + ' tbody tr').length;
|
||
console.log('📈 [DEBUG] 테이블 행 수:', rowCount);
|
||
|
||
// 처리된 요소들을 추적하기 위한 Set
|
||
const processedElements = new Set();
|
||
let totalProcessedElements = 0;
|
||
|
||
// 체크되지 않은 항목들의 값을 빈 값으로 설정
|
||
Object.keys(uncheckedClasses).forEach(function(checkboxName) {
|
||
const checkbox = document.getElementById(checkboxName);
|
||
console.log('🔍 [DEBUG] 체크박스 확인:', checkboxName, '존재:', !!checkbox, '체크됨:', checkbox ? checkbox.checked : 'N/A');
|
||
|
||
if (checkbox && !checkbox.checked) {
|
||
const classesToClear = uncheckedClasses[checkboxName];
|
||
console.log('🧹 [DEBUG] 클리어할 클래스들:', checkboxName, classesToClear);
|
||
|
||
classesToClear.forEach(function(className) {
|
||
const elements = $(targetTable + ' tbody tr').find('input[name*="' + className + '"], select[name*="' + className + '"]');
|
||
console.log('🔍 [DEBUG] 클래스', className, '에 해당하는 요소 수:', elements.length);
|
||
|
||
$(targetTable + ' tbody tr').each(function(rowIndex) {
|
||
const row = $(this);
|
||
const rowElements = row.find('input[name*="' + className + '"], select[name*="' + className + '"]');
|
||
|
||
rowElements.each(function(elementIndex) {
|
||
const element = $(this)[0];
|
||
|
||
// 이미 처리된 요소는 건너뛰기
|
||
if (processedElements.has(element)) {
|
||
console.log('⏭️ [DEBUG] 이미 처리된 요소 건너뛰기:', className, '행:', rowIndex, '요소:', elementIndex);
|
||
return;
|
||
}
|
||
processedElements.add(element);
|
||
totalProcessedElements++;
|
||
|
||
const oldValue = $(this).val();
|
||
let newValue = '';
|
||
|
||
if ($(this).is('select')) {
|
||
$(this).val('').trigger('change');
|
||
newValue = '';
|
||
console.log('🔄 [DEBUG] SELECT 요소 값 변경:', className, '행:', rowIndex, '요소:', elementIndex, '이전값:', oldValue, '새값:', newValue);
|
||
} else {
|
||
// col10_SW, col11_SH인 경우 'x' 입력, 그 외는 빈 값
|
||
if (className === 'col10_SW' || className === 'col11_SH' ) {
|
||
$(this).val('x');
|
||
newValue = 'x';
|
||
} else if (className === 'col76') {
|
||
$(this).val('');
|
||
newValue = '';
|
||
// 조인트바 강제생성함
|
||
Slat_updateCo76(row) ;
|
||
} else {
|
||
$(this).val('');
|
||
newValue = '';
|
||
}
|
||
console.log('🔄 [DEBUG] INPUT 요소 값 변경:', className, '행:', rowIndex, '요소:', elementIndex, '이전값:', oldValue, '새값:', newValue);
|
||
}
|
||
});
|
||
});
|
||
});
|
||
} else {
|
||
console.log('✅ [DEBUG] 체크박스가 체크되어 있거나 존재하지 않음:', checkboxName);
|
||
}
|
||
});
|
||
|
||
console.log('📊 [DEBUG] 총 처리된 요소 수:', totalProcessedElements);
|
||
|
||
// 성공 메시지 표시
|
||
Toastify({
|
||
text: "체크박스 설정이 모든 행에 적용되었습니다. (처리된 요소: " + totalProcessedElements + "개)",
|
||
duration: 3000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
style: {
|
||
background: "linear-gradient(to right, #00b09b, #96c93d)"
|
||
},
|
||
}).showToast();
|
||
|
||
// 계산 업데이트 (한 번만 실행)
|
||
if (typeof calculateAmounts === 'function') {
|
||
console.log('🧮 [DEBUG] calculateAmounts 함수 호출');
|
||
calculateAmounts();
|
||
} else {
|
||
console.warn('⚠️ [DEBUG] calculateAmounts 함수를 찾을 수 없음');
|
||
}
|
||
} catch (error) {
|
||
console.error('❌ [DEBUG] 오류 발생:', error);
|
||
alert('오류가 발생했습니다: ' + error.message);
|
||
} finally {
|
||
// 플래그 해제
|
||
window.isApplyingCheckboxSettings = false;
|
||
console.log('🏁 [DEBUG] applyCheckboxSettingsToAllRows 함수 종료');
|
||
}
|
||
}
|
||
</script>
|
||
</td>
|
||
</tr>
|
||
<tr <?php if(!empty($itemoption)) echo 'style="display:none;"'; ?> >
|
||
<td class="text-end" style="width:90px;"> 현 장 명 </td>
|
||
<td style="width:400px;">
|
||
<input type="text" id="outworkplace" name="outworkplace" value="<?=$outworkplace?>" class="form-control searchplace text-start me-1" >
|
||
</td>
|
||
<td class="text-end" style="width:60px;" > 비고 </td>
|
||
<td >
|
||
<div class="d-flex p-1 mb-1 justify-content-start align-items-center ">
|
||
<textarea id="comment" name="comment" class="form-control text-dark" style="height: 55px;" placeholder="기타 사항 기록" ><?=$comment?></textarea>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-4">
|
||
<div class="d-flex mb-1 justify-content-center align-items-center ">
|
||
<div class="d-flex align-items-center justify-content-end mt-0">
|
||
<table class="table table-bordered mt-0 text-end w-auto">
|
||
<thead >
|
||
<tr>
|
||
<th colspan="5" class="text-end">공급가액 기준, VAT별도</th>
|
||
</tr>
|
||
<tr class="table-secondary">
|
||
<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>
|
||
<input type="text" id="estimateSurang" name="estimateSurang" class="form-control text-center" readonly >
|
||
</td>
|
||
<td>
|
||
<input type="text" id="EstimateFirstSum" name="EstimateFirstSum" class="form-control text-end text-primary" readonly
|
||
value="<?= isset($EstimateFirstSum) && !empty($EstimateFirstSum) && is_numeric($EstimateFirstSum) ? number_format((float)$EstimateFirstSum) : '' ?>">
|
||
</td>
|
||
<td>
|
||
<input type="text" id="EstimateUpdatetSum" name="EstimateUpdatetSum" class="form-control text-end text-primary" readonly
|
||
value="<?= isset($EstimateUpdatetSum) && !empty($EstimateUpdatetSum) && is_numeric($EstimateUpdatetSum) ? number_format((float)$EstimateUpdatetSum) : '' ?>">
|
||
</td>
|
||
<td>
|
||
<input type="text" id="EstimateDiffer" name="EstimateDiffer" class="form-control text-end text-danger" readonly
|
||
value="<?= isset($EstimateDiffer) && !empty($EstimateDiffer) && is_numeric($EstimateDiffer) ? number_format((float)$EstimateDiffer) : '' ?>">
|
||
</td>
|
||
<td>
|
||
<input type="text" id="estimateTotal" name="estimateTotal" class="form-control text-end" readonly
|
||
value="<?= isset($estimateTotal) && $estimateTotal != 0 ? number_format($estimateTotal) : $estimateTotal ?>">
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="row">
|
||
<div class="col-sm-12">
|
||
<div class="d-flex justify-content-center align-items-center">
|
||
<span class="text-dark fs-6 me-4"> 공통 제작치수 적용 </span>
|
||
<span class="text-primary fs-6 mx-1"> 가로(폭) </span>
|
||
<input type="text" id="makeWidth" name="makeWidth" value="<?php echo htmlspecialchars($makeWidth); ?>" class="form-control text-primary fs-6 w60px me-2">
|
||
<span class="text-danger fs-6 mx-1"> 세로(높이) </span>
|
||
<input type="text" id="makeHeight" name="makeHeight" value="<?php echo htmlspecialchars($makeHeight); ?>" class="form-control text-danger fs-6 w60px">
|
||
<span class="text-success fs-6 ms-4 me-1"> 마구리 날개치수 </span>
|
||
<input type="text" id="maguriWing" name="maguriWing" value="<?php echo htmlspecialchars($maguriWing); ?>" class="form-control text-success fs-6 w60px">
|
||
<span class="text-dark fs-6 ms-4 me-1"> 검사비 설정 </span>
|
||
<input type="text"
|
||
id="inspectionFee"
|
||
name="inspectionFee"
|
||
value="<?php echo htmlspecialchars($inspectionFeeFormatted); ?>"
|
||
class="form-control text-dark text-end fs-6 w80px col-input"
|
||
onclick="this.select();"
|
||
oninput="NumberWithComma(this);">
|
||
<span class="text-secondary fs-6 ms-5 me-1"> ※ 값을 설정하고 행을 추가해 주세요. 이 값이 반영됩니다. </span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="ScreenSection" >
|
||
<div class="row">
|
||
<div class="col-sm-4">
|
||
<div class="d-flex justify-content-end mt-2">
|
||
<button type='button' id='view_screenguidebookBtn' class='btn btn-primary btn-sm ms-2 me-3 mt-1'> <i class='bi bi-chevron-down'></i> </button>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-8">
|
||
<div id="view_screenguidebook">
|
||
<div class="d-flex justify-content-start mt-2">
|
||
<table class="table table-bordered w-85">
|
||
<thead class="table-secondary">
|
||
<tr>
|
||
<th>상품명</th>
|
||
<th>제품명</th>
|
||
<th>제품명 설명</th>
|
||
<th>비고</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="text-start">국민방화 스크린 셔터</td>
|
||
<td class="text-start">KSS01</td>
|
||
<td class="text-start">K(경동:국민방화 브랜드명) S(실리카코팅직물 스크린) S(SUS마감)</td>
|
||
<td class="text-start"></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-start">국민방화 스크린 셔터</td>
|
||
<td class="text-start">KSS02</td>
|
||
<td class="text-start">K(경동:국민방화 브랜드명) S(실리카코팅직물 스크린) S(SUS마감)</td>
|
||
<td class="text-start"></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-start">국민방화 스크린 셔터</td>
|
||
<td class="text-start">KSE01</td>
|
||
<td class="text-start">K(경동:국민방화 브랜드명) S(실리카코팅직물 스크린) E(EGI마감)</td>
|
||
<td class="text-start"></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-start">국민방화 스크린 플러스 셔터</td>
|
||
<td class="text-start">KWE01</td>
|
||
<td class="text-start">K(경동:국민방화 브랜드명) W(와이어글라스코팅직물 스크린) E(EGI마감)</td>
|
||
<td class="text-start">SUS 마감일 경우 --- 기존 EGI 마감재에 SUS 마감재로 덧방 추가</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php include $_SERVER['DOCUMENT_ROOT'] . '/estimate/common/common_screen.php'; // 견적서에서 screen 화면 테이블 공통부분
|
||
// 스크린셔터
|
||
generateTableSection('estimate', '스크린셔터', $badgeClass = 'bg-primary', $user_id, '견적서', $mode);
|
||
?>
|
||
|
||
</div> <!-- end of ScreenSection -->
|
||
<div id="SlatSection">
|
||
<div class="row">
|
||
<div class="col-sm-4">
|
||
<div class="d-flex justify-content-end mt-2">
|
||
<button type='button' id='view_slatguidebookBtn' class='btn btn-success btn-sm ms-2 me-3 mt-1'> <i class='bi bi-chevron-down'></i> </button>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-8">
|
||
<div id="view_slatguidebook">
|
||
<div class="d-flex justify-content-start mt-2">
|
||
<table class="table table-bordered ">
|
||
<thead class="table-success">
|
||
<tr>
|
||
<th>상품명</th>
|
||
<th>제품명</th>
|
||
<th>제품명 설명</th>
|
||
<th>비고</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td class="text-start">국민방화 스틸 셔터</td>
|
||
<td class="text-start">KD-SL60</td>
|
||
<td class="text-start">KD(경동:국민방화 브랜드명) SL(철재 : SLAT) 60(비차열 60분)</td>
|
||
<td class="text-start">해당 성적서는 사용 안하고 있음 - KTE01 및 KQTS01로 대체 사용중</td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-start">국민방화 스틸 셔터</td>
|
||
<td class="text-start">KTE01</td>
|
||
<td class="text-start">K(경동:국민방화 브랜드명) T(철재 : Steel) E(EGI마감)</td>
|
||
<td class="text-start"></td>
|
||
</tr>
|
||
<tr>
|
||
<td class="text-start">국민방화 투시형 스틸 셔터</td>
|
||
<td class="text-start">KQTS01</td>
|
||
<td class="text-start">K(경동:국민방화 브랜드명) Q(투시형 : Quartz) T(철재 : Steel) S(SUS마감)</td>
|
||
<td class="text-start">투시창 생략하여 제작 설치 가능</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php include $_SERVER['DOCUMENT_ROOT'] . '/estimate/common/common_slat.php'; // 견적서에서 slat 화면 테이블 공통부분
|
||
generateTableSection_slat('estimateSlat', '철재(스라트)', $badgeClass = 'bg-success', $user_id, '견적서', $mode);
|
||
?>
|
||
</div>
|
||
</div> <!-- end of SlatSection -->
|
||
</div>
|
||
</div>
|
||
</form>
|
||
|
||
<script>
|
||
const authorities = <?php echo json_encode($authorities, JSON_UNESCAPED_UNICODE); ?>;
|
||
// console.log(authorities); // 배열 출력
|
||
|
||
function inputNumbers(input) {
|
||
input.value = input.value.replace(/[^0-9.]/g, '');
|
||
}
|
||
|
||
function isZeroOrEmpty(value) {
|
||
return value === '0' || value === '';
|
||
}
|
||
|
||
function captureReturnKey(e) {
|
||
if(e.keyCode==13 && e.srcElement.type != 'textarea')
|
||
return false;
|
||
}
|
||
|
||
$(document).ready(function() {
|
||
$(document).on('click', '.fetch_receiverBtn', function() {
|
||
callreceiver();
|
||
});
|
||
|
||
$('#receiver').on('keypress', function(event) {
|
||
if (event.keyCode === 13) { // 엔터키의 코드는 13입니다.
|
||
callreceiver();
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<script>
|
||
// 페이지 로딩
|
||
$(document).ready(function(){
|
||
var loader = document.getElementById('loadingOverlay');
|
||
if(loader)
|
||
loader.style.display = 'none';
|
||
});
|
||
</script>
|
||
|
||
<script>
|
||
var mode = $("#mode").val();
|
||
var ajaxRequest_write = null;
|
||
</script>
|
||
|
||
<script>
|
||
var dataTable; // DataTables 인스턴스 전역 변수
|
||
var outputpageNumber; // 현재 페이지 번호 저장을 위한 전역 변수
|
||
|
||
var ajaxRequest_write = null;
|
||
|
||
$(document).ready(function() {
|
||
// DataTables 초기 설정
|
||
dataTable = $('#myTable').DataTable({
|
||
"paging": true,
|
||
"ordering": true,
|
||
"searching": true,
|
||
"pageLength": 500,
|
||
"lengthMenu": [200, 500, 1000],
|
||
"language": {
|
||
"lengthMenu": "Show _MENU_ entries",
|
||
"search": "Live Search:"
|
||
},
|
||
"order": [[0, 'asc']]
|
||
});
|
||
|
||
// 페이지 번호 복원 (초기 로드 시)
|
||
var savedPageNumber = getCookie('estimatepageNumber');
|
||
if (savedPageNumber) {
|
||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||
}
|
||
|
||
// 페이지 변경 이벤트 리스너
|
||
dataTable.on('page.dt', function() {
|
||
var estimatepageNumber = dataTable.page.info().page + 1;
|
||
setCookie('estimatepageNumber', estimatepageNumber, 10); // 쿠키에 페이지 번호 저장
|
||
});
|
||
|
||
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
|
||
$('#myTable_length select').on('change', function() {
|
||
var selectedValue = $(this).val();
|
||
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
|
||
|
||
// 변경 후 현재 페이지 번호 복원
|
||
savedPageNumber = getCookie('estimatepageNumber');
|
||
if (savedPageNumber) {
|
||
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
|
||
}
|
||
});
|
||
});
|
||
|
||
function restorePageNumber() {
|
||
var savedPageNumber = getCookie('estimatepageNumber');
|
||
// if (savedPageNumber) {
|
||
// dataTable.page(parseInt(savedPageNumber) - 1).draw('page');
|
||
// }
|
||
location.reload(true);
|
||
}
|
||
|
||
$(document).ready(function(){
|
||
|
||
$("#copyBtn").click(function(){
|
||
|
||
location.href = 'write_form.php?mode=copy&num=' + $("#num").val() + "&tablename=" + $("#tablename").val() ;
|
||
|
||
}); // end of function
|
||
|
||
$("#viewscreenBtn").click(function(){
|
||
|
||
var url = '/make/write_form_new.php?mode=view&num=' + $("#num").val() + "&tablename=" + $("#tablename").val() ;
|
||
customPopup(url, '스크린 작업지시서', 1850, 900);
|
||
|
||
}); // end of function
|
||
|
||
$("#viewslatBtn").click(function(){
|
||
|
||
var url = '/egimake/write_form_new.php?mode=view&num=' + $("#num").val() + "&tablename=" + $("#tablename").val() ;
|
||
customPopup(url, '철재(스라트) 작업지시서', 1850, 900);
|
||
}); // end of function
|
||
|
||
|
||
|
||
// 삭제버튼
|
||
$("#deleteBtn").click( function() {
|
||
|
||
var update_log = $("#update_log").val();
|
||
var user_name = $("#user_name").val();
|
||
var level = $("#level").val();
|
||
|
||
if (!update_log.includes(user_name) && level !== '1')
|
||
{
|
||
Swal.fire({
|
||
title: '삭제불가',
|
||
text: "작성자와 관리자만 삭제가능합니다.",
|
||
icon: 'error',
|
||
confirmButtonText: '확인'
|
||
});
|
||
} else {
|
||
|
||
Swal.fire({
|
||
title: '자료 삭제',
|
||
text: "삭제는 신중! 정말 삭제하시겠습니까?",
|
||
icon: 'warning',
|
||
showCancelButton: true,
|
||
confirmButtonColor: '#3085d6',
|
||
cancelButtonColor: '#d33',
|
||
confirmButtonText: '삭제',
|
||
cancelButtonText: '취소'
|
||
}).then((result) => {
|
||
|
||
if (result.isConfirmed) {
|
||
|
||
$("#mode").val('delete'); // `mode` 값을 설정
|
||
var form = $('#board_form')[0];
|
||
var formData = new FormData(form); // `formData`를 여기에서 정의합니다.
|
||
|
||
// `formData`에 필요한 추가 데이터를 수동으로 설정
|
||
formData.set('mode', $("#mode").val());
|
||
formData.set('num', $("#num").val());
|
||
|
||
// console.log('mode', $("#mode").val());
|
||
// console.log('num', $("#num").val());
|
||
|
||
if ( (typeof ajaxRequest_write !== 'undefined' && ajaxRequest_write) || ajaxRequest_write!==null ) {
|
||
ajaxRequest_write.abort();
|
||
}
|
||
|
||
ajaxRequest_write = $.ajax({
|
||
enctype: 'multipart/form-data', // file을 서버에 전송하려면 이렇게 해야 함 주의
|
||
processData: false,
|
||
contentType: false,
|
||
cache: false,
|
||
timeout: 1000000,
|
||
url: "insert.php",
|
||
type: "post",
|
||
data: formData,
|
||
dataType: "json",
|
||
success : function( data ){
|
||
|
||
// console.log(data);
|
||
Toastify({
|
||
text: "파일 삭제완료 ",
|
||
duration: 2000,
|
||
close:true,
|
||
gravity:"top",
|
||
position: "center",
|
||
style: {
|
||
background: "linear-gradient(to right, #00b09b, #96c93d)"
|
||
},
|
||
}).showToast();
|
||
setTimeout(function(){
|
||
if (window.opener && !window.opener.closed) {
|
||
// 부모 창에 restorePageNumber 함수가 있는지 확인
|
||
if (typeof window.opener.restorePageNumber === 'function') {
|
||
window.opener.restorePageNumber(); // 함수가 있으면 실행
|
||
}
|
||
// window.opener.location.reload(); // 부모 창 새로고침
|
||
window.close();
|
||
}
|
||
|
||
}, 2000);
|
||
|
||
},
|
||
error : function( jqxhr , status , error ){
|
||
console.log( jqxhr , status , error );
|
||
}
|
||
});
|
||
|
||
|
||
}
|
||
});
|
||
}
|
||
|
||
});
|
||
|
||
// 화면이 시작된 후
|
||
hideOverlay();
|
||
});
|
||
|
||
function inputNumberFormat(input) {
|
||
input.value = input.value.replace(/\D/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||
}
|
||
|
||
function saveData() {
|
||
const myform = document.getElementById('board_form');
|
||
let allValid = true;
|
||
|
||
if (!allValid) return;
|
||
|
||
var num = $("#num").val();
|
||
|
||
showMsgModal(2); // 파일저장중
|
||
|
||
// 복사일때는 insert로 처리함
|
||
if($("#mode").val() !=='copy')
|
||
{
|
||
if (Number(num) < 1) {
|
||
$("#mode").val('insert');
|
||
} else {
|
||
$("#mode").val('modify');
|
||
}
|
||
}
|
||
else
|
||
{
|
||
$("#mode").val('insert');
|
||
}
|
||
|
||
// **계산이 끝난 뒤 이 내부 콜백이 실행됩니다**
|
||
calculateAmounts(function() {
|
||
// ① 계산 결과를 스냅샷에 저장
|
||
collectAndSave();
|
||
|
||
// 선택된 라디오 버튼 값을 수집
|
||
var selectedRadio = $("input[name='radio_item']:checked").val();
|
||
$("#major_category").val(selectedRadio);
|
||
|
||
var form = $('#board_form')[0];
|
||
var datasource = new FormData(form);
|
||
|
||
if (ajaxRequest_write !== null) {
|
||
ajaxRequest_write.abort();
|
||
}
|
||
|
||
ajaxRequest_write = $.ajax({
|
||
enctype: 'multipart/form-data',
|
||
processData: false,
|
||
contentType: false,
|
||
cache: false,
|
||
timeout: 600000,
|
||
url: "insert.php",
|
||
type: "post",
|
||
data: datasource,
|
||
dataType: "json",
|
||
success: function(data) {
|
||
console.log(data);
|
||
setTimeout(function() {
|
||
if (window.opener && !window.opener.closed) {
|
||
if (typeof window.opener.restorePageNumber === 'function') {
|
||
window.opener.restorePageNumber(); // 함수가 있으면 실행
|
||
}
|
||
}
|
||
setTimeout(function() {
|
||
hideMsgModal();
|
||
if (data && data.num)
|
||
// 저장된 데이터 번호를 사용하여 새로운 페이지로 이동
|
||
window.location.href = 'write_form.php?mode=view&tablename=' + $('#tablename').val() + '&num=' + data.num;
|
||
}, 1000);
|
||
|
||
}, 1500);
|
||
|
||
hideOverlay();
|
||
hideMsgModal();
|
||
},
|
||
error: function(jqxhr, status, error) {
|
||
console.log(jqxhr, status, error);
|
||
hideMsgModal();
|
||
}
|
||
});
|
||
});
|
||
}
|
||
|
||
// 저장 버튼 클릭 핸들러 등에서 실행
|
||
function collectAndSave() {
|
||
const actualList = []; // 사용자가 수정한 최종값
|
||
const autoList = []; // 자동산출 스냅샷
|
||
|
||
$('#estimateTable tbody tr').each(function() {
|
||
const rowActual = {};
|
||
const rowAuto = {};
|
||
|
||
$(this).find('input, select').each(function() {
|
||
const name = $(this).attr('name').replace('[]', '');
|
||
const curVal = $(this).val() || '';
|
||
const autoVal = $(this).attr('data-auto') || '';
|
||
|
||
rowActual[name] = curVal;
|
||
rowAuto[name] = autoVal;
|
||
});
|
||
|
||
actualList.push(rowActual);
|
||
autoList.push(rowAuto);
|
||
});
|
||
|
||
// 첫 번째 테이블 값 저장
|
||
$('#estimateList').val( JSON.stringify(actualList) );
|
||
$('#estimateList_auto').val( JSON.stringify(autoList) );
|
||
|
||
// 두 번째(슬랫) 테이블도 동일하게
|
||
const actualListSlat = [];
|
||
const autoListSlat = [];
|
||
|
||
$('#estimateSlatTable tbody tr').each(function() {
|
||
const rowActual = {};
|
||
const rowAuto = {};
|
||
|
||
$(this).find('input, select').each(function() {
|
||
const name = $(this).attr('name').replace('[]', '');
|
||
const curVal = $(this).val() || '';
|
||
const autoVal = $(this).attr('data-auto') || '';
|
||
|
||
rowActual[name] = curVal;
|
||
rowAuto[name] = autoVal;
|
||
});
|
||
|
||
actualListSlat.push(rowActual);
|
||
autoListSlat.push(rowAuto);
|
||
});
|
||
|
||
$('#estimateSlatList').val(JSON.stringify(actualListSlat) );
|
||
$('#estimateSlatList_auto').val(JSON.stringify(autoListSlat) );
|
||
|
||
}
|
||
|
||
function deleteData() {
|
||
var level = '<?php echo isset($level) ? $level : ''; ?>';
|
||
|
||
if (!first_writer.includes(first_writer) && level !== '1') {
|
||
Swal.fire({
|
||
title: '삭제불가',
|
||
text: "작성자와 관리자만 삭제가능합니다.",
|
||
icon: 'error',
|
||
confirmButtonText: '확인'
|
||
});
|
||
} else {
|
||
Swal.fire({
|
||
title: '자료 삭제',
|
||
text: "삭제는 신중! 정말 삭제하시겠습니까?",
|
||
icon: 'warning',
|
||
showCancelButton: true,
|
||
confirmButtonColor: '#3085d6',
|
||
cancelButtonColor: '#d33',
|
||
confirmButtonText: '삭제',
|
||
cancelButtonText: '취소'
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
$("#mode").val('delete');
|
||
var form = $('#board_form')[0];
|
||
var formData = new FormData(form);
|
||
|
||
formData.set('mode', $("#mode").val());
|
||
formData.set('num', $("#num").val());
|
||
|
||
if (ajaxRequest_write !== null) {
|
||
ajaxRequest_write.abort();
|
||
}
|
||
|
||
ajaxRequest_write = $.ajax({
|
||
enctype: 'multipart/form-data',
|
||
processData: false,
|
||
contentType: false,
|
||
cache: false,
|
||
timeout: 1000000,
|
||
url: "insert_estimate.php",
|
||
type: "post",
|
||
data: formData,
|
||
dataType: "json",
|
||
success: function(data) {
|
||
Toastify({
|
||
text: "파일 삭제완료 ",
|
||
duration: 2000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
style: {
|
||
background: "linear-gradient(to right, #00b09b, #96c93d)"
|
||
},
|
||
}).showToast();
|
||
setTimeout(function() {
|
||
if (window.opener && !window.opener.closed) {
|
||
if (typeof window.opener.restorePageNumber === 'function') {
|
||
window.opener.restorePageNumber();
|
||
}
|
||
window.opener.location.reload();
|
||
window.close();
|
||
}
|
||
}, 1000);
|
||
},
|
||
error: function(jqxhr, status, error) {
|
||
console.log(jqxhr, status, error);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
}
|
||
}
|
||
|
||
$(document).ready(function() {
|
||
// Log 파일보기
|
||
$("#showlogBtn").click( function() {
|
||
var num = '<?php echo $num; ?>'
|
||
// table 이름을 넣어야 함
|
||
var workitem = $("#tablename").val();
|
||
// 버튼 비활성화
|
||
var btn = $(this);
|
||
popupCenter("../Showlog.php?num=" + num + "&workitem=" + workitem , '로그기록', 500, 500);
|
||
btn.prop('disabled', false);
|
||
});
|
||
|
||
// 모든행에 적용하기 버튼 클릭 이벤트
|
||
$("#applyToAllRowsBtn").click(function() {
|
||
// 중복 클릭 방지
|
||
if (window.isApplyingCheckboxSettings) {
|
||
return;
|
||
}
|
||
|
||
// 확인 다이얼로그 표시
|
||
Swal.fire({
|
||
title: '설정 적용 확인',
|
||
text: '체크박스 설정을 모든 행에 적용하시겠습니까?',
|
||
icon: 'question',
|
||
showCancelButton: true,
|
||
confirmButtonText: '적용',
|
||
cancelButtonText: '취소'
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
applyCheckboxSettingsToAllRows();
|
||
}
|
||
});
|
||
});
|
||
});
|
||
|
||
function phonebookBtn(searchfield)
|
||
{
|
||
var search = $("#" + searchfield).val();
|
||
href = '../phonebook/list.php?search=' + search ;
|
||
popupCenter(href, '전화번호 검색', 1600, 800);
|
||
}
|
||
</script>
|
||
|
||
<script>
|
||
var ajaxRequest = null;
|
||
var ajaxRequest_write = null;
|
||
var hallDoorOptions = [] ;
|
||
var carDoorOptions = [];
|
||
var carWallOptions = [];
|
||
var etcOptions = [];
|
||
|
||
$(document).ready(function() {
|
||
initializePage();
|
||
bindEventHandlers();
|
||
|
||
$("#saveBtn").click(function() {
|
||
saveData();
|
||
});
|
||
|
||
// 발주서에 적용하기 버튼 클릭 이벤트 처리
|
||
$("#adaptParentBtn").click(function() {
|
||
// 팝업 창에서 데이터 저장 및 부모 창에 전달
|
||
const myform = document.getElementById('board_form');
|
||
let allValid = true;
|
||
|
||
// 유효성 검사 실패 시 리턴
|
||
if (!allValid) return;
|
||
|
||
var num = $("#num").val();
|
||
$("#overlay").show();
|
||
$("button").prop("disabled", true);
|
||
|
||
// 현재 창의 값을 부모창으로 전달
|
||
if (window.opener && !window.opener.closed) {
|
||
const currentMakeWidth = $("#makeWidth").val();
|
||
const currentMakeHeight = $("#makeHeight").val();
|
||
const currentMaguriWing = $("#maguriWing").val();
|
||
const currentInspectionFee = $("#inspectionFee").val();
|
||
|
||
// 부모창에 해당 필드가 있는 경우에만 값 설정
|
||
if (window.opener.$("#makeWidth").length) {
|
||
window.opener.$("#makeWidth").val(String(currentMakeWidth || ''));
|
||
}
|
||
if (window.opener.$("#makeHeight").length) {
|
||
window.opener.$("#makeHeight").val(String(currentMakeHeight || ''));
|
||
}
|
||
if (window.opener.$("#maguriWing").length) {
|
||
window.opener.$("#maguriWing").val(String(currentMaguriWing || ''));
|
||
}
|
||
if (window.opener.$("#inspectionFee").length) {
|
||
window.opener.$("#inspectionFee").val(String(currentInspectionFee || ''));
|
||
}
|
||
}
|
||
|
||
Toastify({
|
||
text: "발주서에 적용중...",
|
||
duration: 2000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
style: {
|
||
background: "linear-gradient(to right, #00b09b, #96c93d)"
|
||
},
|
||
}).showToast();
|
||
|
||
let formData = [];
|
||
let jsonString = '';
|
||
if($("#major_category").val() == '스크린')
|
||
{
|
||
// estimateTable의 데이터를 JSON으로 직렬화
|
||
$('#estimateTable tbody tr').each(function() {
|
||
let rowData = {};
|
||
$(this).find('input, select').each(function() {
|
||
let name = $(this).attr('name').replace('[]', '');
|
||
let value = $(this).val();
|
||
rowData[name] = value;
|
||
});
|
||
formData.push(rowData);
|
||
});
|
||
|
||
jsonString = JSON.stringify(formData);
|
||
$('#estimateList').val(jsonString);
|
||
}
|
||
else if($("#major_category").val() == '철재')
|
||
{
|
||
// estimateTable의 데이터를 JSON으로 직렬화
|
||
$('#estimateSlatTable tbody tr').each(function() {
|
||
let rowData = {};
|
||
$(this).find('input, select').each(function() {
|
||
let name = $(this).attr('name').replace('[]', '');
|
||
let value = $(this).val();
|
||
rowData[name] = value;
|
||
});
|
||
formData.push(rowData);
|
||
});
|
||
|
||
jsonString = JSON.stringify(formData);
|
||
$('#estimateSlatList').val(jsonString);
|
||
}
|
||
|
||
// 부모 창에 데이터를 전달
|
||
if (window.opener && !window.opener.closed) {
|
||
// 부모 창의 숨겨진 필드 estimateList에 데이터 저장
|
||
if($("#major_category").val() == '스크린')
|
||
{
|
||
window.opener.document.getElementById('estimateList').value = jsonString;
|
||
}
|
||
else if($("#major_category").val() == '철재')
|
||
{
|
||
window.opener.document.getElementById('estimateSlatList').value = jsonString;
|
||
}
|
||
const parsedData = JSON.parse(jsonString); // 파싱된 배열 전달
|
||
|
||
// 복사할 필드 ID 목록
|
||
const fields = [
|
||
'estimateSurang',
|
||
'EstimateFirstSum',
|
||
'EstimateUpdatetSum',
|
||
'EstimateDiffer',
|
||
'estimateTotal',
|
||
'makeWidth',
|
||
'makeHeight',
|
||
'maguriWing',
|
||
'inspectionFee'
|
||
];
|
||
|
||
// 하나라도 오류가 나오면 전체 전달이 안된다.
|
||
$.each(fields, function(_, id) {
|
||
// 팝업창 내 값 읽기
|
||
const val = $('#' + id).val() || '';
|
||
|
||
// 부모창 요소 찾기
|
||
const $parentInput = $(window.opener.document).find('#' + id);
|
||
if ($parentInput.length) {
|
||
// 존재하면 값 대입
|
||
$parentInput.val(val);
|
||
console.log(`[DEBUG] 부모창에 '${id}' 입력란이 있습니다. 값="${val}" 로 설정됨.`);
|
||
} else {
|
||
// 없으면 경고
|
||
console.warn(`[DEBUG] 부모창에 '${id}' 입력란을 찾을 수 없습니다!`);
|
||
}
|
||
});
|
||
|
||
// 체크박스에 대한 처리 부모창에 checkbox 그대로 체크해주기
|
||
const checkFields = [
|
||
'steel', // 체크5개 요소 전달
|
||
'motor',
|
||
'warranty',
|
||
'slatcheck',
|
||
'partscheck'
|
||
];
|
||
|
||
$.each(checkFields, function(_, id) {
|
||
const isChecked = $('#' + id).prop('checked');
|
||
const $parentInput = $(window.opener.document).find('#' + id);
|
||
if ($parentInput.length) {
|
||
$parentInput.prop('checked', isChecked);
|
||
}
|
||
});
|
||
|
||
if($("#major_category").val() == '스크린')
|
||
{
|
||
// Check if screenTable has existing rows
|
||
if(window.opener.document.getElementById('screenTable').getElementsByTagName('tr').length > 0) {
|
||
Swal.fire({
|
||
title: '스크린 발주서 기존데이터에 덮어쓰시겠습니까?',
|
||
icon: 'question',
|
||
showCancelButton: true,
|
||
confirmButtonText: '네',
|
||
cancelButtonText: '아니오'
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
window.opener.renderEstimateData({ estimateList: parsedData }, "reload");
|
||
// 일정 시간 후 창을 닫음
|
||
setTimeout(function() {
|
||
window.close();
|
||
}, 1000);
|
||
} else {
|
||
window.opener.renderEstimateData({ estimateList: parsedData }, null);
|
||
// 일정 시간 후 창을 닫음
|
||
setTimeout(function() {
|
||
window.close();
|
||
}, 1000);
|
||
}
|
||
});
|
||
} else {
|
||
window.opener.renderEstimateData({ estimateList: parsedData }, "reload");
|
||
// 일정 시간 후 창을 닫음
|
||
setTimeout(function() {
|
||
window.close();
|
||
}, 1000);
|
||
}
|
||
}
|
||
else if($("#major_category").val() == '철재')
|
||
{
|
||
// Check if slatTable has existing rows
|
||
if(window.opener.document.getElementById('slatTable').getElementsByTagName('tr').length > 0) {
|
||
Swal.fire({
|
||
title: '철재 슬랫 발주서 기존데이터에 덮어쓰시겠습니까?',
|
||
icon: 'question',
|
||
showCancelButton: true,
|
||
confirmButtonText: '네',
|
||
cancelButtonText: '아니오'
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
window.opener.renderEstimateData_slat({ estimateSlatList: parsedData }, "reload");
|
||
// 일정 시간 후 창을 닫음
|
||
setTimeout(function() {
|
||
window.close();
|
||
}, 1000);
|
||
} else {
|
||
window.opener.renderEstimateData_slat({ estimateSlatList: parsedData }, null);
|
||
// 일정 시간 후 창을 닫음
|
||
setTimeout(function() {
|
||
window.close();
|
||
}, 1000);
|
||
}
|
||
});
|
||
} else {
|
||
window.opener.renderEstimateData_slat({ estimateSlatList: parsedData }, "reload");
|
||
// 일정 시간 후 창을 닫음
|
||
setTimeout(function() {
|
||
window.close();
|
||
}, 1000);
|
||
}
|
||
}
|
||
|
||
} else {
|
||
alert('부모창을 찾을 수 없습니다.');
|
||
return;
|
||
// 일정 시간 후 창을 닫음
|
||
setTimeout(function() {
|
||
window.close();
|
||
}, 1000);
|
||
}
|
||
});
|
||
|
||
$("#viewEstimateUnit").click(function() {
|
||
// var url = '/output/estimateUnit.php';
|
||
var url = '/estimate/list_unit.php?header=no';
|
||
customPopup(url, '견적 단가 관리', 1850, 900);
|
||
});
|
||
$("#viewEstimate").click(function() {
|
||
var num = $("#num").val();
|
||
var url = '/estimate/EsDetail_screen.php?option=option&num=' + num;
|
||
customPopup(url, '견적서', 1200, 900);
|
||
});
|
||
$("#viewEstimateDetail").click(function() {
|
||
var num = $("#num").val();
|
||
var url = '/estimate/EsDetail_screen.php?num=' + num;
|
||
customPopup(url, '견적 산출내역서', 1200, 900);
|
||
});
|
||
|
||
$("#viewEstimateSlatUnit").click(function() {
|
||
// var url = '/output/estimateUnit.php';
|
||
var url = '/estimate/list_unit.php?header=no';
|
||
customPopup(url, '견적 단가 관리', 1850, 900);
|
||
});
|
||
$("#viewEstimateSlat").click(function() {
|
||
var num = $("#num").val();
|
||
// option이 있으면 산출내역 없음
|
||
var url = '/estimate/EsDetail_slat.php?option=option&num=' + num;
|
||
customPopup(url, '견적서', 1200, 900);
|
||
});
|
||
$("#viewEstimateSlatDetail").click(function() {
|
||
var num = $("#num").val();
|
||
var url = '/estimate/EsDetail_slat.php?num=' + num;
|
||
customPopup(url, '견적산출', 1200, 900);
|
||
});
|
||
|
||
$(".deleteBtn").click(function() {
|
||
deleteData();
|
||
});
|
||
|
||
});
|
||
// 초기 페이지 설정
|
||
function initializePage() {
|
||
var loader = document.getElementById('loadingOverlay');
|
||
if (loader) loader.style.display = 'none';
|
||
|
||
// 쿠키 기반 초기 뷰 상태
|
||
initializeView('estimate_screenDiv', 'showEsimateScreenView', "block");
|
||
initializeView('estimate_slatDiv', 'showEsimateslatView', "block");
|
||
|
||
// 실제값과 자동산출값 둘 다 PHP에서 JSON으로 가져오기
|
||
var estimate = <?php echo json_encode($estimateList ?? []); ?>;
|
||
var estimateAuto = <?php echo json_encode($estimateList_auto ?? []); ?>;
|
||
var estimateSlat = <?php echo json_encode($estimateSlatList ?? []); ?>;
|
||
var estimateSlatAuto = <?php echo json_encode($estimateSlatList_auto?? []); ?>;
|
||
|
||
// 데이터 유무에 따라 div 토글
|
||
if (estimate.length > 0) $("#estimate_screenDiv").show();
|
||
if (estimateSlat.length > 0) $("#estimate_slatDiv").show();
|
||
|
||
// 테이블 로드 (actual, auto 둘 다 넘김)
|
||
loadTableData('#estimateTable', estimate, estimateAuto,
|
||
'estimate');
|
||
loadTableData('#estimateSlatTable', estimateSlat, estimateSlatAuto,
|
||
'estimateSlat');
|
||
}
|
||
|
||
// loadTableData 함수 시그니처 변경
|
||
function loadTableData(tableId, dataList, autoList, typebutton) {
|
||
var tableBody = $(tableId).find('tbody');
|
||
var theadId = (tableId === '#estimateTable')
|
||
? '#thead_estimate'
|
||
: '#thead_estimateSlat';
|
||
|
||
// JSON 파싱 안전 처리
|
||
if (typeof dataList === 'string') {
|
||
try { dataList = JSON.parse(dataList); }
|
||
catch (e) { console.error(e); dataList = []; }
|
||
}
|
||
if (typeof autoList === 'string') {
|
||
try { autoList = JSON.parse(autoList); }
|
||
catch (e) { console.error(e); autoList = []; }
|
||
}
|
||
|
||
$(theadId).show();
|
||
|
||
if (!Array.isArray(dataList)) dataList = [];
|
||
if (!Array.isArray(autoList)) autoList = [];
|
||
|
||
if (dataList.length === 0) {
|
||
$(tableId === '#estimateTable'
|
||
? "#estimate_screenDiv"
|
||
: "#estimate_slatDiv"
|
||
).hide();
|
||
return;
|
||
}
|
||
|
||
// 실제값과 자동값을 인덱스로 매칭해서 addRow 호출
|
||
dataList.forEach(function(item, idx) {
|
||
var autoItem = autoList[idx] || {};
|
||
if (tableId === '#estimateTable') {
|
||
addRow(tableBody, item, typebutton, null, autoItem);
|
||
} else {
|
||
addRow_slat(tableBody, item, typebutton, null, autoItem);
|
||
}
|
||
});
|
||
|
||
$(tableId === '#estimateTable'
|
||
? "#estimate_screenDiv"
|
||
: "#estimate_slatDiv"
|
||
).show();
|
||
}
|
||
|
||
|
||
// 공통 함수: 페이지 로드 시 쿠키를 기반으로 각 요소의 표시 상태 설정
|
||
function initializeView(viewId, cookieName, status) {
|
||
var view = getCookie(cookieName);
|
||
var listContainer = $("#" + viewId);
|
||
if (view === "show") {
|
||
listContainer.css("display", status);
|
||
} else {
|
||
listContainer.css("display", status); // 항상열리게 하려면 여기서 조정한다.
|
||
// listContainer.css("display", "none");
|
||
}
|
||
}
|
||
|
||
// 이벤트 핸들러 바인딩
|
||
function bindEventHandlers() {
|
||
|
||
if (mode == 'view') {
|
||
disableView();
|
||
}
|
||
|
||
$(document).on('click', '.remove-row', function() {
|
||
if (mode !== 'view') {
|
||
var currentRow = $(this).closest('tr');
|
||
var tableBody = currentRow.closest('tbody');
|
||
|
||
// 현재 행 제거
|
||
currentRow.remove();
|
||
|
||
// 남아있는 행들의 col1 값을 다시 정렬
|
||
tableBody.children('tr').each(function(index) {
|
||
$(this).find('input[name="col1[]"]').val(index + 1);
|
||
});
|
||
alertToast('행 삭제');
|
||
Screen_updateTotals();
|
||
}
|
||
});
|
||
|
||
|
||
$(document).on('click', '.close-modal', function() {
|
||
$(this).closest('.modal').modal('hide');
|
||
});
|
||
|
||
// add-row는 두개로 나눠야 한다. 함수호출이 다르니... remove-row, copy-row는 한개로 가능하다.
|
||
$(document).on('click', '.add-row', function () {
|
||
if (mode !== 'view') {
|
||
// console.log('add-row 호출됨');
|
||
$("#estimate_screenDiv").show();
|
||
var tableId = $(this).data('table');
|
||
var tableBody = $('#' + tableId).find('tbody');
|
||
var currentRow = $(this).closest('tr');
|
||
|
||
addRow(tableBody, {}, tableId, currentRow); // ← 현재 행 다음에 삽입
|
||
alertToast('행 추가');
|
||
Screen_updateTotals();
|
||
}
|
||
});
|
||
$(document).on('click', '.add-row-slat', function () {
|
||
if (mode !== 'view') {
|
||
// console.log('add-row-slat 호출됨');
|
||
$("#estimate_slatDiv").show();
|
||
var tableId = $(this).data('table');
|
||
var tableBody = $('#' + tableId).find('tbody');
|
||
var currentRow = $(this).closest('tr');
|
||
|
||
addRow_slat(tableBody, {}, tableId, currentRow); // ← 현재 행 다음에 삽입
|
||
alertToast('행 추가');
|
||
Screen_updateTotals();
|
||
}
|
||
});
|
||
|
||
// 행 복사
|
||
$(document).on('click', '.copy-row', function() {
|
||
if (mode !== 'view') {
|
||
var currentRow = $(this).closest('tr');
|
||
var tableBody = currentRow.closest('tbody');
|
||
var clonedRow = currentRow.clone(true); // true로 이벤트와 데이터를 복사
|
||
|
||
// 전체 행 수를 기준으로 새로운 col1 값 설정
|
||
var newCol1Value = tableBody.children('tr').length + 1;
|
||
|
||
clonedRow.find('input, select').each(function(index) {
|
||
var currentInput = currentRow.find('input, select').eq(index);
|
||
|
||
// col1 값이 있는 필드인 경우, 새로 계산된 값 설정
|
||
if ($(this).attr('name') === 'col1[]') {
|
||
$(this).val(newCol1Value);
|
||
} else {
|
||
// 나머지 필드는 그대로 복사
|
||
$(this).val(currentInput.val());
|
||
}
|
||
});
|
||
// 현재 행 바로 아래에 추가
|
||
currentRow.after(clonedRow);
|
||
alertToast('행 복사');
|
||
updateSerialNumbers(tableBody);
|
||
Screen_updateTotals();
|
||
Slat_updateTotals();
|
||
}
|
||
});
|
||
|
||
// 철재 처리부분
|
||
$(document).on('click', '.remove-row', function() {
|
||
if (mode !== 'view') {
|
||
$(this).closest('tr').remove();
|
||
alertToast('행삭제');
|
||
Slat_updateTotals();
|
||
}
|
||
});
|
||
|
||
}
|
||
|
||
function alertToast(message) {
|
||
// 기본 배경 색상 (초록)
|
||
let backgroundColor = "linear-gradient(to right, #00b09b, #96c93d)";
|
||
|
||
// 조건에 따라 색상 변경
|
||
if (message.includes("추가")) {
|
||
backgroundColor = "linear-gradient(to right, #2196F3, #21CBF3)"; // 파란 계열
|
||
} else if (message.includes("삭제")) {
|
||
backgroundColor = "linear-gradient(to right, #f44336, #e57373)"; // 빨간 계열
|
||
} else if (message.includes("복사")) {
|
||
backgroundColor = "linear-gradient(to right, #4CAF50, #81C784)"; // 녹색 계열
|
||
}
|
||
|
||
Toastify({
|
||
text: message,
|
||
duration: 2000,
|
||
close: true,
|
||
gravity: "top",
|
||
position: "center",
|
||
style: {
|
||
background: backgroundColor
|
||
},
|
||
}).showToast();
|
||
}
|
||
|
||
|
||
function showModal(options, modalId, modalBodyId, input) {
|
||
targetInput = input;
|
||
$(modalBodyId).empty();
|
||
options.forEach(function(item) {
|
||
$(modalBodyId).append('<tr><td class="text-center">' + item + '</td></tr>');
|
||
});
|
||
$(modalId).modal('show');
|
||
}
|
||
|
||
function inputNumberFormat(input) {
|
||
// 콤마 제거 후 숫자만 남기기
|
||
let value = input.value.replace(/[^\d]/g, '');
|
||
|
||
// 3자리마다 콤마 추가
|
||
if (value) {
|
||
value = parseInt(value).toLocaleString();
|
||
}
|
||
|
||
input.value = value;
|
||
}
|
||
|
||
function NumberWithComma(input) {
|
||
// 콤마 제거 후 숫자만 남기기
|
||
let value = input.value.replace(/[^\d]/g, '');
|
||
|
||
// 3자리마다 콤마 추가
|
||
if (value) {
|
||
value = parseInt(value).toLocaleString();
|
||
}
|
||
|
||
input.value = value;
|
||
}
|
||
|
||
function disableView() {
|
||
// 수동 편집된 요소는 제외하고 나머지를 readonly 처리
|
||
$('input, textarea, select')
|
||
.not('.manually-edited')
|
||
.prop('readonly', true);
|
||
|
||
// 히든 필드와 수동 편집된 히든 필드는 건드리지 않기
|
||
$('input[type=hidden]')
|
||
.not('.manually-edited')
|
||
.prop('readonly', false);
|
||
|
||
// select와 버튼들 disabled 설정
|
||
$('select, .restrictbtn, .sub_add, .add').prop('disabled', true);
|
||
|
||
// 파일 input은 readonly 해제
|
||
$('input[type=file]').prop('readonly', false);
|
||
|
||
// 버튼들 disabled 설정
|
||
$('.viewNoBtn').prop('disabled', true);
|
||
$('.specialbtnClear').prop('disabled', true);
|
||
|
||
// 버튼 비활성화 (수동 편집 여부와 상관 없이)
|
||
$('button.add-row, button.remove-row, button.copy-row')
|
||
.prop('disabled', true);
|
||
|
||
// 모든행에 적용하기 버튼 비활성화
|
||
$('#applyToAllRowsBtn').prop('disabled', true);
|
||
|
||
// checkbox/radio 통합 처리 - disabled 대신 클릭 이벤트 차단
|
||
$('input[type="checkbox"], input[type="radio"]')
|
||
.each(function() {
|
||
if (!$(this).hasClass('manually-edited')) {
|
||
// disabled 속성 제거하고 스타일만 적용
|
||
$(this).removeProp('disabled')
|
||
.addClass('readonly-checkbox readonly-radio');
|
||
|
||
// 클릭 이벤트 차단
|
||
$(this).on('click', function(event) {
|
||
event.preventDefault();
|
||
return false;
|
||
});
|
||
}
|
||
});
|
||
|
||
// 파일 입력 비활성화
|
||
$('input[type=file]')
|
||
.not('.manually-edited')
|
||
.prop('disabled', true);
|
||
|
||
$('.fetch_receiverBtn, .viewmode')
|
||
.not('.manually-edited')
|
||
.prop('disabled', true);
|
||
|
||
// 레이블 텍스트 크게 설정
|
||
$('label').css('font-size', '1.2em');
|
||
|
||
// select 속성 readonly 효과 내기
|
||
$('select[data-readonly="true"]').on('mousedown', function(event) {
|
||
event.preventDefault();
|
||
});
|
||
|
||
// select[data-readonly] 에 마우스 다운 차단 (수동 편집된 건 제외)
|
||
document.querySelectorAll('select[data-readonly="true"]').forEach(function(select) {
|
||
if (!select.classList.contains('manually-edited')) {
|
||
select.addEventListener('mousedown', function(event) {
|
||
event.preventDefault();
|
||
});
|
||
}
|
||
});
|
||
|
||
console.log('disableView 함수 호출');
|
||
}
|
||
|
||
function captureReturnKey(e) {
|
||
if (e.keyCode == 13 && e.srcElement.type != 'textarea') {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function recaptureReturnKey(e) {
|
||
if (e.keyCode == 13 && e.srcElement.type != 'textarea') {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function closePopup() {
|
||
if (popupWindow && !popupWindow.closed) {
|
||
popupWindow.close();
|
||
isWindowOpen = false;
|
||
}
|
||
}
|
||
|
||
function showWarningModal() {
|
||
Swal.fire({
|
||
title: '등록 오류 알림',
|
||
text: '필수입력 요소를 확인바랍니다.',
|
||
icon: 'warning',
|
||
}).then(result => {
|
||
if (result.isConfirmed) {
|
||
return;
|
||
}
|
||
});
|
||
}
|
||
|
||
function showlotError() {
|
||
Swal.fire({
|
||
title: '등록 오류 알림',
|
||
text: '입력 항목들을 점검해주세요.',
|
||
icon: 'warning',
|
||
}).then(result => {
|
||
if (result.isConfirmed) {
|
||
return;
|
||
}
|
||
});
|
||
}
|
||
|
||
function inputNumber(input) {
|
||
// 현재 커서 위치를 저장
|
||
const cursorPosition = input.selectionStart;
|
||
// 입력값에서 숫자만 남기고 제거
|
||
const value = input.value.replace(/,/g, '');
|
||
// 천 단위 콤마 추가
|
||
const formattedValue = Number(value).toLocaleString();
|
||
// 포맷팅된 값으로 설정
|
||
input.value = formattedValue;
|
||
// 포맷팅 후에도 원래 커서 위치 유지
|
||
input.setSelectionRange(cursorPosition, cursorPosition);
|
||
}
|
||
</script>
|
||
|
||
<?php include $_SERVER['DOCUMENT_ROOT'] . '/estimate/common/common_addrowJS.php'; // 견적서에서 screen or slat JS코드 공통 ?>
|
||
|
||
<!-- mode == 'view' "view" 조회 화면일때 사용금지 시키는 구문 -->
|
||
<script>
|
||
$(document).ready(function() {
|
||
var mode = '<?php echo $mode; ?>' ;
|
||
|
||
if (mode === 'view') {
|
||
disableView();
|
||
}
|
||
|
||
|
||
//발주서에 적용하기
|
||
$('#adaptBtn').on('click', function() {
|
||
let formData = [];
|
||
$('#estimateTable tbody tr').each(function() {
|
||
let rowData = {};
|
||
$(this).find('input, select').each(function() {
|
||
let name = $(this).attr('name').replace('[]', '');
|
||
let value = $(this).val();
|
||
rowData[name] = value;
|
||
});
|
||
formData.push(rowData);
|
||
});
|
||
|
||
let jsonString = JSON.stringify(formData);
|
||
|
||
// 폼 생성 및 전송
|
||
let form = $('<form></form>').attr({
|
||
method: 'POST',
|
||
action: '/output/write_form.php' // 데이터를 전송할 URL
|
||
});
|
||
|
||
// 폼에 데이터를 숨겨진 필드로 추가
|
||
$('<input>').attr({
|
||
type: 'hidden',
|
||
name: 'estimateData',
|
||
value: jsonString
|
||
}).appendTo(form);
|
||
|
||
// 폼 전송
|
||
form.appendTo('body').submit();
|
||
});
|
||
});
|
||
|
||
$(document).ready(function() {
|
||
// 뷰 ID와 쿠키 이름 매핑 (output-list 제거)
|
||
var views = [
|
||
{ id: "estimate_screenDiv", cookie: "showEsimateScreenView", button: "#estimateScreen_view" , status : "block" },
|
||
{ id: "view_screenguidebook", cookie: "showEsimateScreenDetailView", button: "#view_screenguidebookBtn" , status : "none" },
|
||
{ id: "estimate_slatDiv", cookie: "showEsimateslatView", button: "#estimateslat_view", status : "block" },
|
||
{ id: "view_slatguidebook", cookie: "showEsimateslatDetailView", button: "#view_slatguidebookBtn", status : "none" }
|
||
|
||
];
|
||
|
||
// 각 뷰 버튼에 클릭 이벤트 할당 및 페이지 로드 시 초기화
|
||
views.forEach(function(view) {
|
||
// 버튼 클릭 시 View 토글
|
||
$(view.button).on("click", function() {
|
||
toggleView(view.id, view.cookie);
|
||
});
|
||
|
||
// 페이지 로드 시 View 초기화
|
||
initializeView(view.id, view.cookie, view.status); // 추가 초기상태도 전달한다.
|
||
});
|
||
|
||
});
|
||
|
||
// 공통 함수: View 토글 및 쿠키 설정
|
||
function toggleView(viewId, cookieName) {
|
||
var view = getCookie(cookieName);
|
||
var listContainer = $("#" + viewId);
|
||
if (view === "show") {
|
||
listContainer.css("display", "none");
|
||
setCookie(cookieName, "hide", 10);
|
||
} else {
|
||
listContainer.css("display", "block");
|
||
setCookie(cookieName, "show", 10);
|
||
}
|
||
}
|
||
|
||
$(document).ready(function() {
|
||
let previousOption = $('input[name="radio_item"]:checked').val(); // 이전 선택 상태 저장
|
||
|
||
// 선택된 라디오 버튼에 따라 섹션 표시 및 데이터 초기화
|
||
function toggleSections() {
|
||
const selectedOption = $('input[name="radio_item"]:checked').val();
|
||
const outworkplace = $('#outworkplace').val();
|
||
const num = $('#num').val(); // 신규인 경우는 스크린 행추가
|
||
|
||
// 섹션 토글
|
||
$("#ScreenSection").toggle(selectedOption === "스크린");
|
||
$("#SlatSection").toggle(selectedOption === "철재");
|
||
|
||
if (selectedOption === '스크린') {
|
||
// 철재견적서 tbody 비우기
|
||
$('#estimateSlatTable tbody').empty();
|
||
|
||
setTimeout(function () {
|
||
const tableId = 'estimateTable';
|
||
const tableBody = $('#' + tableId).find('tbody');
|
||
|
||
if (tableBody.find('tr').length === 0) { // 행이 없을 때만 추가
|
||
addRow(tableBody, {}, tableId, null);
|
||
alertToast('스크린 행 자동 추가');
|
||
Screen_updateTotals();
|
||
}
|
||
}, 800);
|
||
|
||
} else if (selectedOption === '철재') {
|
||
// 스크린견적서 tbody 비우기
|
||
$('#estimateTable tbody').empty();
|
||
|
||
setTimeout(function () {
|
||
const tableId = 'estimateSlatTable';
|
||
const tableBody = $('#' + tableId).find('tbody');
|
||
// console.log('tableBody.find length : ' + tableBody.find('tr').length);
|
||
if (tableBody.find('tr').length === 0) { // 행이 없을 때만 추가
|
||
addRow_slat(tableBody, {}, tableId, null);
|
||
alertToast('철재 행 자동 추가');
|
||
Screen_updateTotals();
|
||
}
|
||
}, 800);
|
||
}
|
||
}
|
||
|
||
|
||
// 페이지 로드 시 초기 상태 설정
|
||
toggleSections();
|
||
|
||
// 라디오 버튼 클릭 시 토글 기능 추가
|
||
$('input[name="radio_item"]').on('change', function() {
|
||
const selectedOption = $(this).val(); // 현재 선택된 옵션
|
||
if (selectedOption !== previousOption) {
|
||
swal.fire({
|
||
title: '변환 확인',
|
||
text: '스크린/철재 변환은 기존 자료가 초기화 됩니다. 진행하시겠습니까?',
|
||
icon: 'warning',
|
||
showCancelButton: true,
|
||
confirmButtonText: '네',
|
||
cancelButtonText: '아니오'
|
||
}).then((result) => {
|
||
if (result.isConfirmed) {
|
||
// 사용자가 '네'를 선택한 경우
|
||
previousOption = selectedOption; // 이전 상태 업데이트
|
||
toggleSections();
|
||
|
||
if(selectedOption === '철재')
|
||
{
|
||
$('#makeWidth').val('110');
|
||
$('#makeHeight').val('350');
|
||
}
|
||
else
|
||
{
|
||
$('#makeWidth').val('160');
|
||
$('#makeHeight').val('350');
|
||
}
|
||
|
||
} else {
|
||
// 사용자가 '아니오'를 선택한 경우
|
||
$('input[name="radio_item"][value="' + previousOption + '"]').prop('checked', true);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<script>
|
||
// simple debounce helper
|
||
function debounce(fn, delay) {
|
||
let timer = null;
|
||
return function(...args) {
|
||
clearTimeout(timer);
|
||
timer = setTimeout(() => fn.apply(this, args), delay);
|
||
};
|
||
}
|
||
|
||
// 콜백(done)을 인자로 받도록 수정
|
||
function calculateAmounts(done) {
|
||
// 중복 실행 방지를 위한 플래그
|
||
if (window.isCalculatingAmounts) {
|
||
// 이미 계산 중이면 콜백만 실행하고 리턴
|
||
if (typeof done === 'function') {
|
||
// 현재 진행 중인 계산이 완료될 때까지 대기
|
||
const checkInterval = setInterval(() => {
|
||
if (!window.isCalculatingAmounts) {
|
||
clearInterval(checkInterval);
|
||
done();
|
||
}
|
||
}, 500);
|
||
}
|
||
return;
|
||
}
|
||
|
||
window.isCalculatingAmounts = true;
|
||
|
||
try {
|
||
const selectedType = $('input[name="radio_item"]:checked').val();
|
||
if (!selectedType) {
|
||
// console.log('타입이 선택되지 않았습니다.');
|
||
return;
|
||
}
|
||
|
||
let estimateList = [];
|
||
let estimateSlatList = [];
|
||
|
||
// estimateList 수집 (스크린용)
|
||
$('#estimateTable tbody tr').each(function() {
|
||
let rowData = {};
|
||
$(this).find('input, select').each(function() {
|
||
const name = $(this).attr('name')?.replace('[]', '') || '';
|
||
const value = $(this).val() || '';
|
||
rowData[name] = value;
|
||
});
|
||
estimateList.push(rowData);
|
||
});
|
||
|
||
// estimateSlatList 수집 (철재 슬랫용)
|
||
$('#estimateSlatTable tbody tr').each(function() {
|
||
let rowData = {};
|
||
$(this).find('input, select').each(function() {
|
||
const name = $(this).attr('name')?.replace('[]', '') || '';
|
||
const value = $(this).val() || '';
|
||
rowData[name] = value;
|
||
});
|
||
estimateSlatList.push(rowData);
|
||
});
|
||
|
||
// FormData 준비
|
||
const formData = new FormData();
|
||
formData.append('type', selectedType);
|
||
const num = $('#num').val();
|
||
const inspectionFee = $('#inspectionFee').val().replace(/,/g, ''); // 콤마 제거
|
||
|
||
if (num) formData.append('num', num);
|
||
if (estimateList.length) {
|
||
try {
|
||
const jsonStr = JSON.stringify(estimateList);
|
||
// console.log('estimateList JSON:', jsonStr); // 디버깅용
|
||
formData.append('estimateList', jsonStr);
|
||
} catch (e) {
|
||
console.error('estimateList JSON 변환 실패:', e);
|
||
return;
|
||
}
|
||
}
|
||
if (estimateSlatList.length) {
|
||
try {
|
||
const jsonStr = JSON.stringify(estimateSlatList);
|
||
// console.log('estimateSlatList JSON:', jsonStr); // 디버깅용
|
||
formData.append('estimateSlatList', jsonStr);
|
||
} catch (e) {
|
||
console.error('estimateSlatList JSON 변환 실패:', e);
|
||
return;
|
||
}
|
||
}
|
||
if (inspectionFee) formData.append('inspectionFee', inspectionFee);
|
||
|
||
// checkbox 5개 상태 추가
|
||
const steel = $('#steel').prop('checked') ? '1' : '0';
|
||
const motor = $('#motor').prop('checked') ? '1' : '0';
|
||
const warranty = $('#warranty').prop('checked') ? '인정' : '';
|
||
const slatcheck = $('#slatcheck').prop('checked') ? '1' : '0';
|
||
const partscheck = $('#partscheck').prop('checked') ? '1' : '0';
|
||
|
||
formData.append('steel', steel);
|
||
formData.append('motor', motor);
|
||
formData.append('warranty', warranty);
|
||
formData.append('slatcheck', slatcheck);
|
||
formData.append('partscheck', partscheck);
|
||
|
||
// 중복 호출 방지
|
||
if (ajaxRequest !== null ) ajaxRequest.abort();
|
||
|
||
ajaxRequest = $.ajax({
|
||
url: '/estimate/get_estimate_amount.php',
|
||
type: 'POST',
|
||
data: formData,
|
||
processData: false,
|
||
contentType: false,
|
||
dataType: 'json', // 'text'에서 'json'으로 변경
|
||
success: function(resp) {
|
||
// console.log('resp: ' + resp);
|
||
if (!resp.success) {
|
||
console.error('계산 오류:', resp.error);
|
||
return;
|
||
}
|
||
|
||
// Check if resp.data exists and has the expected structure
|
||
if (!resp.data || !resp.data.details) {
|
||
console.error('Invalid response structure:', resp);
|
||
return;
|
||
}
|
||
|
||
const { details, itemDetails, surangSum } = resp.data;
|
||
console.log('details : ' + details);
|
||
itemDetails.forEach((item, index) => {
|
||
console.log(`Item ${index + 1}:`, item);
|
||
});
|
||
// 각 행별 합계 뿌리기
|
||
let calculatedTotal = 0;
|
||
|
||
if (Array.isArray(details)) {
|
||
details.forEach((sum, idx) => {
|
||
calculatedTotal += Math.round(sum);
|
||
// const subtotalCell = $(`.subtotal-cell[data-serial="${idx}"]`);
|
||
// if (subtotalCell.length) {
|
||
// // 항목별 금액 정보 표시
|
||
// const itemDetail = itemDetails[idx] || {};
|
||
// const detailText = Object.entries(itemDetail)
|
||
// .map(([key, value]) => `${key}: ${value.toLocaleString()}원`)
|
||
// .join(', ');
|
||
|
||
// subtotalCell.text(sum.toLocaleString() + '원');
|
||
// // 툴팁으로 항목별 금액 표시
|
||
// subtotalCell.attr('title', detailText);
|
||
// }
|
||
});
|
||
}
|
||
|
||
// const total_amount = Math.round(initialTotal);
|
||
// const vat = Math.round(total_amount * 0.1);
|
||
// const total = total_amount + vat;
|
||
|
||
$('#estimateTotal').val(calculatedTotal.toLocaleString()); // 자동계산금액
|
||
$('#estimateSurang').val(surangSum.toLocaleString());
|
||
|
||
// 비교용 로그 출력
|
||
// console.log('estimateSurang :', details.length.toLocaleString());
|
||
// console.log('🔍 행별 합계 누적(calculatedTotal):', calculatedTotal.toLocaleString());
|
||
// console.log('📦 전체 계산된 합(total_amount):', total_amount.toLocaleString());
|
||
// console.log('📋 항목별 금액:', itemDetails);
|
||
|
||
// const difference = Math.abs(calculatedTotal - total_amount);
|
||
// if (difference <= 10) {
|
||
// console.log('%c✅ 행별 합과 전체 합이 10원 이내로 일치합니다.', 'color: green; font-weight: bold;');
|
||
// } else {
|
||
// console.warn('%c⚠️ 행별 합과 전체 합이 10원 이상 차이가 납니다.', 'color: red; font-weight: bold;');
|
||
// }
|
||
ajaxRequest = null;
|
||
// **계산이 완전히 끝난 뒤** 콜백 실행**
|
||
if (typeof done === 'function') done();
|
||
|
||
},
|
||
error: function(xhr, status, err) {
|
||
console.error('AJAX 오류:', status, err);
|
||
console.error('응답:', xhr.responseText);
|
||
ajaxRequest = null;
|
||
if (typeof done === 'function') done();
|
||
}
|
||
});
|
||
} finally {
|
||
// 플래그 해제 (AJAX 완료 후)
|
||
setTimeout(() => {
|
||
window.isCalculatingAmounts = false;
|
||
}, 100);
|
||
}
|
||
}
|
||
|
||
var debouncedCalc = debounce(calculateAmounts, 500);
|
||
|
||
$(function() {
|
||
if (!$('input[name="radio_item"]:checked').length) {
|
||
$('input[name="radio_item"][value="스크린"]').prop('checked', true);
|
||
}
|
||
|
||
// 라디오 버튼 클릭 시 토글 기능 추가
|
||
$('input[name="radio_item"]').on('change', function() {
|
||
debouncedCalc();
|
||
});
|
||
|
||
// 이벤트 바인딩 시 중복 방지
|
||
$('input, select').off('input change.calc').on('input change.calc', debouncedCalc);
|
||
$('.add-row').off('click.calc').on('click.calc', debouncedCalc);
|
||
$('.remove-row').off('click.calc').on('click.calc', debouncedCalc);
|
||
$('.copy-row').off('click.calc').on('click.calc', debouncedCalc);
|
||
|
||
// 초기 실행 (한 번만)
|
||
if (!window.initialCalcDone) {
|
||
debouncedCalc();
|
||
window.initialCalcDone = true;
|
||
}
|
||
});
|
||
|
||
// 비고란의 textarea 크기 조절
|
||
$(document).ready(function() {
|
||
const $textarea = $('#comment');
|
||
|
||
// textarea 요소가 없으면 함수 종료
|
||
if (!$textarea.length) return;
|
||
|
||
// textarea 높이를 조절하는 함수
|
||
function adjustHeight($el) {
|
||
$el.css('height', 'auto'); // 먼저 높이를 초기화
|
||
$el.css('height', $el[0].scrollHeight + 'px'); // 내용에 맞춰 높이 재설정
|
||
}
|
||
|
||
// 입력 이벤트 발생 시 높이 조절
|
||
$textarea.on('input', function() {
|
||
adjustHeight($(this));
|
||
});
|
||
|
||
// 페이지 로드시, 이미 입력된 내용이 있다면 높이 조절
|
||
adjustHeight($textarea);
|
||
});
|
||
|
||
// 견적번호 생성
|
||
$(document).ready(function () {
|
||
if (!$('#pjnum').val()) {
|
||
$.ajax({
|
||
url: '/estimate/get_initial_pjnum.php',
|
||
type: 'GET',
|
||
success: function (data) {
|
||
if (data) $('#pjnum').val(data);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|