- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
1072 lines
40 KiB
PHP
1072 lines
40 KiB
PHP
<?php
|
|
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
|
|
$title_message = '스크린 출고증';
|
|
$tablename = 'output';
|
|
$item ='출고증';
|
|
$emailTitle ='출고증';
|
|
include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
|
|
// 출고담당자관리자 명단
|
|
$QCadmin = false ;
|
|
if($user_name=='이세희' || $user_name=='개발자' || $user_name=='함신옥' || $user_name=='이경호' || $user_name=='노완호' )
|
|
$QCadmin = true ;
|
|
?>
|
|
<title> <?=$title_message?> </title>
|
|
<link rel="stylesheet" href="css/style.css">
|
|
</head>
|
|
<body>
|
|
|
|
<?php
|
|
// JavaScript에서 전달된 변수들 받기
|
|
$num = isset($_REQUEST['num']) ? $_REQUEST['num'] : '';
|
|
|
|
require_once($_SERVER['DOCUMENT_ROOT'] . "/estimate/fetch_unitprice.php");
|
|
|
|
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";
|
|
|
|
// output_extra 테이블에서 데이터 불러오기
|
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/output/load_output_extraTable.php';
|
|
}
|
|
} catch (PDOException $Exception) {
|
|
print "오류: " . $Exception->getMessage();
|
|
}
|
|
|
|
// JSON 문자열을 PHP 배열로 디코딩합니다.
|
|
//스크린발주서 읽기
|
|
$eList = json_decode($estimateList, true);
|
|
|
|
// 행의 수는 배열의 크기와 동일하므로, count() 함수를 사용하여 구합니다.
|
|
$surang = count($eList);
|
|
|
|
// COD 출고증 certificate of delivery
|
|
$COD = isset($COD) ? json_decode($COD, true) : [];
|
|
|
|
// print_r($COD);
|
|
|
|
// JSON 데이터를 JavaScript 변수로 변환
|
|
echo "<script>";
|
|
echo "var CODData = " . json_encode($COD) . ";";
|
|
echo "</script>";
|
|
|
|
// echo '<pre>';
|
|
// print_r($eList);
|
|
// echo '</pre>';
|
|
|
|
// 행의 수는 배열의 크기와 동일하므로, count() 함수를 사용하여 구합니다.
|
|
$surang = count($eList);
|
|
|
|
// 행의 수를 출력하거나 활용할 수 있습니다.
|
|
// echo "행의 수: " . $surang . "<br>";
|
|
|
|
$THscreenSu = $surang + 2 ;
|
|
|
|
$indateStr = date("m/d", strtotime($indate));
|
|
$todayStr = date("m/d");
|
|
|
|
?>
|
|
|
|
<div class="container mt-2">
|
|
<div class="d-flex align-items-center justify-content-end mt-1 m-2">
|
|
<button type="button" class="btn btn-dark btn-sm mx-3" onclick='location.reload();' title="새로고침"> <i class="bi bi-arrow-clockwise"></i> </button>
|
|
<button type="button" class="btn btn-dark btn-sm me-1 ms-1 saveData" > <i class="bi bi-floppy2-fill"></i> 서버 저장 </button>
|
|
<button type="button" class="btn btn-dark btn-sm me-1" onclick="generatePDF()"> PDF 저장 </button>
|
|
<button type="button" class="btn btn-dark btn-sm me-1" onclick="sendmail();"> <i class="bi bi-envelope-arrow-up"></i> 전송 </button>
|
|
<button type="button" class="btn btn-secondary btn-sm ms-5" onclick="self.close();"> <i class="bi bi-x-lg"></i> 닫기 </button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="lotModal" tabindex="-1" aria-labelledby="lotModalLabel" aria-hidden="true">
|
|
<div class="modal-dialog modal-full">
|
|
<div class="modal-content" style="width:750px;">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="lotModalLabel">출고증 로트번호 선택</h5>
|
|
<button type="button" class="btn-close cancelBtn" aria-label="Close"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<ul class="nav nav-tabs" id="lotTabs" role="tablist">
|
|
<li class="nav-item" role="presentation">
|
|
<button class="nav-link" id="material-tab" data-bs-toggle="tab" data-bs-target="#material" type="button" role="tab" aria-controls="material" aria-selected="false">로트 찾기</button>
|
|
</li>
|
|
</ul>
|
|
<div class="tab-content" id="lotTabContent">
|
|
<div class="tab-pane fade show active" id="material" role="tabpanel" aria-labelledby="material-tab">
|
|
<!-- 원자재 로트번호 목록 -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary btn-sm nullBtn_bending">공백 삽입</button>
|
|
<button type="button" class="btn btn-secondary btn-sm cancelBtn">취소</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data" onkeydown="return captureReturnKey(event)" >
|
|
|
|
<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="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="item_name" name="item_name" value="<?= isset($item_name) ? $item_name : '' ?>">
|
|
<input type="hidden" id="COD" name="COD"> <!-- COD는 출고증 로트번호 기록위한 변수임 -->
|
|
|
|
<div id="content-to-print">
|
|
<br>
|
|
<div class="container mt-3">
|
|
<div class="row mt-2">
|
|
<div class="d-flex align-items-center justify-content-start">
|
|
<table class="table " style="border-collapse: collapse;">
|
|
<thead>
|
|
<tr>
|
|
<th colspan="5" rowspan="4" class="text-center" style="width:70%;">
|
|
<div class="row">
|
|
<div class="col-sm-2">
|
|
<img src="../img/kdlogo.png" alt="경동기업" class="me-1" style="width:100%; height:auto;">
|
|
</div>
|
|
<div class="col-sm-10">
|
|
<div class="d-flex align-items-center justify-content-center m-1">
|
|
<span class="text-dark ms-2 me-2 fs-1" > 출 </span>
|
|
<span class="text-dark ms-2 me-2 fs-1" > 고 </span>
|
|
<span class="text-dark ms-2 fs-1" > 증 </span>
|
|
</div>
|
|
<br>
|
|
<div class="d-flex align-items-center justify-content-center mt-2">
|
|
<span class="text-dark ms-2 " style="font-size:10px;" > 전화 : 031-983-5130 | 팩스 : 02-6911-6315 | 이메일 : kd5130@naver.com </span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</th>
|
|
<th class="text-center " style="width:5%;">로트번호</th>
|
|
<th colspan="3" class="text-center text-primary fw-bold" style="width:30%; "> <?=$lotNum?> </th>
|
|
</tr>
|
|
<tr>
|
|
<th rowspan="3" class="text-center fw-bold" style="height:100px;">결 재</th>
|
|
<th class="text-center p-1 clickable" style="width : 70px; height:22px; padding:2px; cursor:pointer;" id="writer">작성</th>
|
|
<th class="text-center p-1 clickable" style="width : 70px; height:22px; padding:2px; cursor:pointer;" id="reviewer">검토</th>
|
|
<th class="text-center p-1 clickable approval-only" style="width : 90px; height:22px; padding:2px; cursor:pointer;" id="approver">승인</th>
|
|
</tr>
|
|
<tr style="height:40px;">
|
|
<th class="text-center" id="writerDisplay"></th>
|
|
<th class="text-center" id="reviewerDisplay"></th>
|
|
<th class="text-center" id="approvalDisplay"></th>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-center" style="height:22px; padding:2px;">판매/<?=$orderman?></th>
|
|
<th class="text-center" style="height:22px; padding:2px;"><span class="text-primary"> 출하 </span></th>
|
|
<th class="text-center" style="height:22px; padding:2px;">생산관리</th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mt-2">
|
|
<div class="d-flex align-items-center justify-content-start">
|
|
<table class="table table-bordered" style="border-collapse: collapse;">
|
|
<thead>
|
|
<tr>
|
|
<th colspan="2" class="text-center align-middle lightgray" style="width:33%;">신 청 업 체</th>
|
|
<th colspan="2" class="text-center align-middle lightgray" style="width:33%;">신 청 내 용</th>
|
|
<th colspan="2" class="text-center align-middle lightgray" style="width:33%;">납 품 정 보</th>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th class="text-center align-middle lightgray">발주일</th>
|
|
<th class="text-center"><?=specialDate($orderdate)?></th>
|
|
<th class="text-center align-middle lightgray">현 장 명</th>
|
|
<th colspan="3" class="text-center text-primary fw-bold"><?=$outworkplace?> </th>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-center align-middle lightgray">발주처</th>
|
|
<th class="text-center"><?=$secondord?> </th>
|
|
<th class="text-center align-middle lightgray">납기요청일</th>
|
|
<th colspan="1" class="text-center text-primary fw-bold"><?=specialDate($outdateplusone)?> </th>
|
|
<th class="text-center align-middle lightgray">인수담당자</th>
|
|
<th colspan="1" class="text-center text-primary fw-bold"><?=$receiver?> </th>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-center align-middle lightgray">발주 담당자</th>
|
|
<th class="text-center"><?=$receiver?></th>
|
|
<th class="text-center align-middle lightgray">출고일</th>
|
|
<th colspan="1" class="text-center text-primary fw-bold"><?=specialDate($outdate)?> </th>
|
|
<th class="text-center align-middle lightgray">인수자연락처</th>
|
|
<th class="text-center text-primary fw-bold"><?=$phone?> </th>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-center align-middle lightgray">담당자 연락처</th>
|
|
<th class="text-center text-dark fw-bold"><?=$phone?> </th>
|
|
<th class="text-center align-middle lightgray">셔터총수량</th>
|
|
<th class="text-center"> <?=$surang ?> (개소) </th>
|
|
<th class="text-center align-middle lightgray">배 송 방 법</th>
|
|
<th class="text-center"> <?=$delivery ?> </th>
|
|
</tr>
|
|
<tr>
|
|
<th class="text-center align-middle lightgray">배송지 주소</th>
|
|
<th colspan="5" class="text-center"><?=$outputplace?></th>
|
|
</tr>
|
|
</thead>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="d-flex align-items-center justify-content-start ">
|
|
<table class="table" style="border-collapse: collapse; padding:5;">
|
|
<tbody>
|
|
<tr>
|
|
<td class="text-center fw-bold w120px" >
|
|
* 별도 추가사항
|
|
</td>
|
|
<td class="text-center fw-bold fs-6" style="background-color:yellow; padding:15!important;" >
|
|
<?=$displayText?>
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-2 ">
|
|
<div class="orderlist_UA">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- 페이지로딩 -->
|
|
<script>
|
|
$(document).ready(function(){
|
|
var loader = document.getElementById('loadingOverlay');
|
|
loader.style.display = 'none';
|
|
});
|
|
|
|
function generatePDF() {
|
|
var workplace = '<?php echo $title_message; ?>';
|
|
var today = new Date();
|
|
var formattedDate = "(" + String(today.getFullYear()).slice(-2) + "." + ("0" + (today.getMonth() + 1)).slice(-2) + "." + ("0" + today.getDate()).slice(-2) + ")";
|
|
var result = 'KD출고증(' + workplace +')' + formattedDate + '.pdf';
|
|
|
|
var element = document.getElementById('content-to-print');
|
|
var opt = {
|
|
margin: [10, 3, 12, 3], // Top, right, bottom, left margins
|
|
filename: result,
|
|
image: { type: 'jpeg', quality: 0.98 },
|
|
html2canvas: { scale: 1 },
|
|
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
|
|
pagebreak: { mode: [''] }
|
|
};
|
|
html2pdf().from(element).set(opt).save();
|
|
}
|
|
|
|
function generatePDF_server(callback) {
|
|
var workplace = '<?php echo $title_message; ?>';
|
|
var item = '<?php echo $emailTitle; ?>';
|
|
var today = new Date();
|
|
var formattedDate = "(" + String(today.getFullYear()).slice(-2) + "." + ("0" + (today.getMonth() + 1)).slice(-2) + "." + ("0" + today.getDate()).slice(-2) + ")";
|
|
var result = 'KD' + item +'(' + workplace + ')' + formattedDate + '.pdf';
|
|
|
|
var element = document.getElementById('content-to-print');
|
|
var opt = {
|
|
margin: [10, 3, 12, 3], // Top, right, bottom, left margins
|
|
filename: result,
|
|
image: { type: 'jpeg', quality: 0.98 },
|
|
html2canvas: { scale: 2 },
|
|
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
|
|
pagebreak: { mode: [''] }
|
|
};
|
|
|
|
html2pdf().from(element).set(opt).output('datauristring').then(function (pdfDataUri) {
|
|
var pdfBase64 = pdfDataUri.split(',')[1]; // Base64 인코딩된 PDF 데이터 추출
|
|
var formData = new FormData();
|
|
formData.append('pdf', pdfBase64);
|
|
formData.append('filename', result);
|
|
|
|
$.ajax({
|
|
type: 'POST',
|
|
url: '/email/save_pdf.php', // PDF 파일을 저장하는 PHP 파일
|
|
data: formData,
|
|
processData: false,
|
|
contentType: false,
|
|
success: function (response) {
|
|
var res = JSON.parse(response);
|
|
if (callback) {
|
|
callback(res.filename); // 서버에 저장된 파일 경로를 콜백으로 전달
|
|
}
|
|
},
|
|
error: function (xhr, status, error) {
|
|
Swal.fire('Error', 'PDF 저장에 실패했습니다.', 'error');
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
var ajaxRequest = null;
|
|
|
|
function sendmail() {
|
|
var secondordnum = '<?php echo $secondordnum; ?>'; // 서버에서 가져온 값
|
|
var item = '<?php echo $emailTitle; ?>';
|
|
|
|
if (!secondordnum) {
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: '오류 알림',
|
|
text: '발주처 코드가 없습니다.'
|
|
});
|
|
return; // 함수 종료
|
|
}
|
|
|
|
if (typeof ajaxRequest !== 'undefined' && ajaxRequest !== null) {
|
|
ajaxRequest.abort();
|
|
}
|
|
|
|
ajaxRequest = $.ajax({
|
|
type: 'POST',
|
|
url: '/email/get_companyCode.php',
|
|
data: { secondordnum: secondordnum },
|
|
dataType: 'json',
|
|
success: function(response) {
|
|
console.log('response : ', response);
|
|
if (response.error) {
|
|
Swal.fire('Error', response.error, 'error');
|
|
} else {
|
|
var email = response.email;
|
|
var vendorName = response.vendor_name;
|
|
|
|
Swal.fire({
|
|
title: 'E메일 보내기',
|
|
text: vendorName + ' Email 주소확인',
|
|
icon: 'warning',
|
|
input: 'text', // input 창을 텍스트 필드로 설정
|
|
inputLabel: 'Email 주소 수정 가능',
|
|
inputValue: email, // 기존 이메일 주소를 기본값으로 설정
|
|
showCancelButton: true,
|
|
confirmButtonText: '보내기',
|
|
cancelButtonText: '취소',
|
|
reverseButtons: true,
|
|
inputValidator: (value) => {
|
|
if (!value) {
|
|
return '이메일 주소를 입력해주세요!';
|
|
}
|
|
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
if (!emailPattern.test(value)) {
|
|
return '올바른 이메일 형식을 입력해주세요!';
|
|
}
|
|
}
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
const updatedEmail = result.value; // 입력된 이메일 주소 가져오기
|
|
generatePDF_server(function(filename) {
|
|
sendEmail(updatedEmail, vendorName, item, filename);
|
|
});
|
|
}
|
|
});
|
|
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
Swal.fire('Error', '전송중 오류가 발생했습니다.', 'error');
|
|
}
|
|
});
|
|
}
|
|
|
|
function sendEmail(recipientEmail, vendorName, item, filename) {
|
|
if (typeof ajaxRequest !== 'undefined' && ajaxRequest !== null) {
|
|
ajaxRequest.abort();
|
|
}
|
|
var today = new Date();
|
|
var formattedDate = "(" + String(today.getFullYear()).slice(-2) + "." + ("0" + (today.getMonth() + 1)).slice(-2) + "." + ("0" + today.getDate()).slice(-2) + ")";
|
|
|
|
ajaxRequest = $.ajax({
|
|
type: 'POST',
|
|
url: '/email/send_email.php', // 이메일 전송을 처리하는 PHP 파일
|
|
data: { email: recipientEmail, vendorName: vendorName, filename: filename, item: item, formattedDate: formattedDate },
|
|
success: function(response) {
|
|
console.log(response);
|
|
Swal.fire('Success', '정상적으로 전송되었습니다.', 'success');
|
|
},
|
|
error: function(xhr, status, error) {
|
|
Swal.fire('Error', '전송에 실패했습니다. 확인바랍니다.', 'error');
|
|
}
|
|
});
|
|
}
|
|
|
|
|
|
|
|
$(document).ready(function() {
|
|
var selectedItemName = ''; // itemName을 저장할 변수
|
|
var selectedusesurang = ''; // itemName을 저장할 변수
|
|
|
|
// lotnumInput 클릭 시 itemName을 저장
|
|
$(document).on('click', '.lotnumInput', function() {
|
|
var row = $(this).closest('tr');
|
|
selectedRow = row; // tr 요소 저장
|
|
|
|
selectedItemName = $(this).data('itemname'); // itemName 저장
|
|
selectedusesurang = $(this).data('usesurang'); // usesurang 저장
|
|
|
|
console.log(selectedItemName);
|
|
if (selectedItemName) {
|
|
loadLotData('material', selectedItemName, selectedusesurang);
|
|
|
|
setTimeout(function() {
|
|
$('#lotModal').modal('show');
|
|
}, 1000);
|
|
} else {
|
|
alert('품목명을 입력해주세요.');
|
|
}
|
|
});
|
|
|
|
$('#material-tab').on('shown.bs.tab', function() {
|
|
if (selectedItemName) {
|
|
loadLotData('material', selectedItemName, selectedusesurang);
|
|
}
|
|
});
|
|
|
|
$('#lotModal').on('shown.bs.modal', function() {
|
|
if (selectedItemName) {
|
|
loadLotData('material', selectedItemName, selectedusesurang);
|
|
}
|
|
});
|
|
|
|
});
|
|
|
|
// 로트번호 데이터를 불러오는 함수
|
|
function loadLotData(type, itemName, usesurang) {
|
|
$.post('fetch_lot_COD.php', { lot_type: type, item_name: itemName, usesurang : usesurang })
|
|
.done(function(data) {
|
|
if (type === 'material') {
|
|
$('#material').html(data);
|
|
}
|
|
|
|
})
|
|
.fail(function(xhr, status, error) {
|
|
console.error("AJAX Request Failed:", status, error);
|
|
alert("로트 데이터를 불러오는 중 오류가 발생했습니다.");
|
|
});
|
|
}
|
|
|
|
// 선택한 로트 번호를 적용하는 함수
|
|
function selectLotNumber_prod(lotNumber) {
|
|
selectedRow.find('input.lotnumInput').val(lotNumber);
|
|
$('#lotModal').modal('hide');
|
|
}
|
|
// 절곡로트번호 공백 삽입
|
|
$(document).on('click', '.nullBtn_bending', function() {
|
|
selectLotNumber_prod('');
|
|
});
|
|
|
|
function selectLotNumber(lotNumber) {
|
|
// motor-lot 필드가 선택되었는지 확인
|
|
console.log('selectLotNumber 호출됨, lotNumber:', lotNumber);
|
|
|
|
// 선택된 로트 번호를 motor-lot 및 lotnumInput 필드에 설정
|
|
selectedRow.find('input.motor-lot').val(lotNumber).trigger('input'); // input 이벤트 트리거
|
|
selectedRow.find('input.lotnumInput').val(lotNumber);
|
|
selectedRow.find('.info-btn').attr('data-lotnum', lotNumber); // 내부의 .info-btn 선택
|
|
|
|
// 모달 닫기
|
|
$('#lotModal').modal('hide');
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
// 모든 모터 lotnumInput 필드에 대해 변경 이벤트 리스너 추가
|
|
$('.motor-lot').on('input', function() {
|
|
// input 이벤트가 발생했음을 확인
|
|
console.log('motor-lot input 이벤트 발생');
|
|
|
|
// 현재 모터 입력 필드의 인덱스를 가져옴
|
|
const index = $(this).data('index');
|
|
const lotValue = $(this).val();
|
|
console.log('motor lot 선택됨', lotValue, 'index:', index);
|
|
|
|
// 해당 인덱스를 가진 브라켓 lotnumInput 필드를 찾아 값을 설정
|
|
const $bracketInput = $('.bracket-lot[data-index="' + index + '"]');
|
|
if ($bracketInput.length) {
|
|
$bracketInput.val(lotValue);
|
|
console.log('bracket-lot 설정됨:', lotValue, 'index:', index);
|
|
} else {
|
|
console.log('해당 인덱스의 bracket-lot을 찾을 수 없음:', index);
|
|
}
|
|
});
|
|
});
|
|
|
|
|
|
$(document).on('click', '.nullBtn', function() {
|
|
selectLotNumber('');
|
|
});
|
|
|
|
$(document).on('click', '.cancelBtn', function() {
|
|
$('#lotModal').modal('hide');
|
|
});
|
|
|
|
$(document).on('click', '.saveData', function() {
|
|
saveData();
|
|
});
|
|
|
|
$(document).on('click', '.lot-done-btn', function() {
|
|
const num = $(this).data('num');
|
|
const tablename = $(this).data('tablename');
|
|
const rawitemname = $(this).data('rawitemname');
|
|
const lottype = $(this).data('lottype');
|
|
const usesurang = $(this).closest('tr').find('.usesurang').text(); // 사용 수량을 가져옴
|
|
const currentRow = $(this).closest('tr'); // 현재 tr 요소 저장
|
|
|
|
// console.log('num:', num);
|
|
// console.log('tablename:', tablename);
|
|
// console.log('lottype:', lottype);
|
|
// console.log('usesurang:', usesurang);
|
|
// console.log('rawitemname:', rawitemname);
|
|
|
|
Swal.fire({
|
|
title: '로트 소진 처리',
|
|
text: '해당 로트를 소진 처리하시겠습니까?',
|
|
icon: 'warning',
|
|
showCancelButton: true,
|
|
confirmButtonColor: '#3085d6',
|
|
cancelButtonColor: '#d33',
|
|
confirmButtonText: '예, 처리합니다',
|
|
cancelButtonText: '취소'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
$.ajax({
|
|
url: 'update_lotdone.php',
|
|
type: 'POST',
|
|
data: {
|
|
num: num,
|
|
tablename: tablename,
|
|
mode: 'update',
|
|
lotDone: '소진'
|
|
},
|
|
dataType: 'json',
|
|
success: function(response) {
|
|
console.log(response);
|
|
if (response && response.success) {
|
|
Swal.fire({
|
|
title: '처리 완료',
|
|
text: '소진 처리되었습니다.',
|
|
icon: 'success',
|
|
confirmButtonText: '확인'
|
|
}).then(() => {
|
|
// 해당 tr 요소 제거
|
|
currentRow.remove();
|
|
});
|
|
} else {
|
|
Swal.fire({
|
|
title: '오류',
|
|
text: '소진 처리 중 오류가 발생했습니다.',
|
|
icon: 'error',
|
|
confirmButtonText: '확인'
|
|
});
|
|
}
|
|
},
|
|
error: function(xhr, status, error) {
|
|
Swal.fire({
|
|
title: 'AJAX 오류',
|
|
text: '요청 중 오류가 발생했습니다.',
|
|
icon: 'error',
|
|
confirmButtonText: '확인'
|
|
});
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
// 결재 취소 기능
|
|
$(document).on('click', '.remove-approval', function() {
|
|
// 승인자 정보를 지우고 화면에서 숨김
|
|
$('#approvalDisplay').html('').hide();
|
|
|
|
// JSON 데이터에서 승인자의 정보 제거
|
|
let formData = JSON.parse($('#COD').val() || '[]');
|
|
const approvalIndex = formData.findIndex(item => item.approval);
|
|
|
|
if (approvalIndex !== -1) {
|
|
formData[approvalIndex].approval.approver.name = '';
|
|
formData[approvalIndex].approval.approver.date = '';
|
|
}
|
|
|
|
// JSON 문자열로 다시 저장
|
|
$('#COD').val(JSON.stringify(formData));
|
|
|
|
Toastify({
|
|
text: "승인 정보가 삭제되었습니다.",
|
|
duration: 2000,
|
|
close: true,
|
|
gravity: "top",
|
|
position: "center",
|
|
style: {
|
|
background: "linear-gradient(to right, #ff5f6d, #ffc371)"
|
|
},
|
|
}).showToast();
|
|
|
|
saveData();
|
|
});
|
|
|
|
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 saveData() {
|
|
// 결재 부분 정보 저장
|
|
let approvalData = {
|
|
writer: {
|
|
name: $('#writerDisplay').html().split('<br>')[0] || '',
|
|
date: $('#writerDisplay').html().split('<br>')[1] || ''
|
|
},
|
|
reviewer: {
|
|
name: $('#reviewerDisplay').html().split('<br>')[0] || '',
|
|
date: $('#reviewerDisplay').html().split('<br>')[1] || ''
|
|
},
|
|
approver: {
|
|
name: $('#approvalDisplay').clone().children('i').remove().end().html().split('<br>')[0] || '',
|
|
date: $('#approvalDisplay').clone().children('i').remove().end().html().split('<br>')[1] || ''
|
|
}
|
|
};
|
|
|
|
let formData = [];
|
|
formData.push({ approval: approvalData });
|
|
|
|
// 입고 LOT NO 정보 저장 (행별)
|
|
let lotNums = [];
|
|
$('.lotnumInput').each(function() {
|
|
lotNums.push($(this).val());
|
|
});
|
|
formData.push({ lotNumbers: lotNums });
|
|
|
|
// 추가 정보 저장
|
|
formData.push({ num: $('#num').val() });
|
|
formData.push({ tablename: $('#tablename').val() });
|
|
formData.push({ update_log: $('#update_log').val() });
|
|
|
|
// JSON 문자열로 변환
|
|
let jsonString = JSON.stringify(formData);
|
|
|
|
// 숨겨진 필드에 JSON 데이터 설정
|
|
$('#COD').val(jsonString);
|
|
|
|
$("#overlay").show(); // 오버레이 표시
|
|
$("button").prop("disabled", true); // 모든 버튼 비활성화
|
|
|
|
// 폼데이터 전송시 사용함 Get form
|
|
var form = $('#board_form')[0];
|
|
var datasource = new FormData(form);
|
|
|
|
showMsgModal(2); // 파일저장중
|
|
|
|
$.ajax({
|
|
enctype: 'multipart/form-data',
|
|
processData: false,
|
|
contentType: false,
|
|
cache: false,
|
|
timeout: 600000,
|
|
url: "insert_COD.php",
|
|
type: "post",
|
|
data: datasource,
|
|
dataType: "json",
|
|
success: function(data) {
|
|
// console.log(data);
|
|
setTimeout(function() {
|
|
$("button").prop("disabled", false); // 모든 버튼 활성화
|
|
hideMsgModal();
|
|
$("#overlay").hide(); // 오버레이 숨김
|
|
|
|
Toastify({
|
|
text: "저장완료",
|
|
duration: 3000,
|
|
close: true,
|
|
gravity: "top",
|
|
position: "center",
|
|
style: {
|
|
background: "linear-gradient(to right, #00b09b, #96c93d)"
|
|
},
|
|
}).showToast();
|
|
|
|
}, 1000);
|
|
},
|
|
error: function(jqxhr, status, error) {
|
|
console.log(jqxhr, status, error);
|
|
alert("An error occurred: " + error);
|
|
}
|
|
});
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
if (CODData.length > 0) {
|
|
console.log(CODData);
|
|
|
|
// 결재 부분 정보
|
|
const approval = CODData.find(item => item.approval);
|
|
if (approval) {
|
|
// 작성자 정보 표시
|
|
$('#writerDisplay').html(
|
|
(approval.approval.writer.name || '') + '<br>' + (approval.approval.writer.date || '')
|
|
);
|
|
|
|
// 검토자 정보 표시
|
|
$('#reviewerDisplay').html(
|
|
(approval.approval.reviewer.name || '') + '<br>' + (approval.approval.reviewer.date || '')
|
|
);
|
|
|
|
// 승인자 정보 표시
|
|
if (approval.approval.approver.name && approval.approval.approver.date) {
|
|
$('#approvalDisplay').show();
|
|
$('#approvalDisplay').html(
|
|
approval.approval.approver.name + '<br>' + approval.approval.approver.date +
|
|
' <i class="bi bi-x-circle remove-approval" style="cursor: pointer;"></i>'
|
|
);
|
|
} else {
|
|
// 승인 정보가 없을 때는 공백으로 처리
|
|
$('#approvalDisplay').hide().html('');
|
|
}
|
|
}
|
|
|
|
// 입고 LOT NO 정보
|
|
const lotNumbers = CODData.find(item => item.lotNumbers);
|
|
if (lotNumbers) {
|
|
$('.lotnumInput').each(function(index) {
|
|
$(this).val(lotNumbers.lotNumbers[index] || '');
|
|
});
|
|
$('.info-btn').each(function(index) {
|
|
$(this).attr('data-lotnum', lotNumbers.lotNumbers[index] || '');
|
|
});
|
|
}
|
|
|
|
// 업데이트 로그가 있을 경우 표시
|
|
const updateLog = CODData.find(item => item.update_log);
|
|
if (updateLog) {
|
|
$('#update_log').val(updateLog.update_log || '');
|
|
}
|
|
}
|
|
});
|
|
|
|
|
|
// 부트스트랩 툴팁
|
|
$(document).ready(function() {
|
|
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
|
|
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
|
|
return new bootstrap.Tooltip(tooltipTriggerEl);
|
|
});
|
|
});
|
|
// 결재부분 클릭처리
|
|
$(document).on('click', '.clickable', function() {
|
|
const isQCadmin = <?= json_encode($QCadmin); ?>; // 관리자인 경우 true
|
|
const userName = <?= json_encode($user_name); ?>; // 현재 사용자 이름
|
|
const todayStr = <?= json_encode($todayStr); ?>; // 오늘 날짜
|
|
|
|
let targetId = $(this).attr('id') + 'Display';
|
|
|
|
// 작성과 검토는 누구나 가능
|
|
if ($(this).attr('id') === 'writer' || $(this).attr('id') === 'reviewer') {
|
|
$('#' + targetId).html(userName + '<br>' + todayStr);
|
|
}
|
|
// 승인 버튼은 관리자만 가능
|
|
else if ($(this).attr('id') === 'approver') {
|
|
if (!isQCadmin) {
|
|
alert('승인 권한이 없습니다.');
|
|
return;
|
|
}
|
|
|
|
// 승인자의 이름과 오늘 날짜 표시
|
|
$('#approvalDisplay').html(
|
|
userName + '<br>' + todayStr +
|
|
' <i class="bi bi-x-circle remove-approval" style="cursor: pointer;"></i>'
|
|
);
|
|
$('#approvalDisplay').show();
|
|
|
|
// 결재 정보를 업데이트하여 저장 로직에 반영
|
|
updateApprovalData(userName, todayStr);
|
|
saveData(); // 저장까지 실행하기
|
|
}
|
|
});
|
|
|
|
// 결재 정보 업데이트 함수
|
|
function updateApprovalData(userName, date) {
|
|
let approvalData = {
|
|
writer: {
|
|
name: $('#writerDisplay').text().split('<br>')[0] || '',
|
|
date: $('#writerDisplay').text().split('<br>')[1] || ''
|
|
},
|
|
reviewer: {
|
|
name: $('#reviewerDisplay').text().split('<br>')[0] || '',
|
|
date: $('#reviewerDisplay').text().split('<br>')[1] || ''
|
|
},
|
|
approver: {
|
|
name: $('#approvalDisplay').text().split('<br>')[0] || '',
|
|
date: $('#approvalDisplay').text().split('<br>')[1] || ''
|
|
}
|
|
};
|
|
|
|
let formData = JSON.parse($('#COD').val() || '[]');
|
|
const approvalIndex = formData.findIndex(item => item.approval);
|
|
|
|
if (approvalIndex !== -1) {
|
|
formData[approvalIndex].approval = approvalData;
|
|
} else {
|
|
formData.push({ approval: approvalData });
|
|
}
|
|
|
|
$('#COD').val(JSON.stringify(formData));
|
|
|
|
}
|
|
|
|
ajaxRequest1 = null;
|
|
|
|
$(document).on('click', '.info-btn, .info-wire-btn', function () {
|
|
var lotnum = $(this).data('lotnum');
|
|
console.log('lotnum :', lotnum);
|
|
if (!lotnum) {
|
|
Swal.fire('알림', '로트번호를 입력하세요.', 'warning');
|
|
return;
|
|
}
|
|
|
|
if (ajaxRequest1 !== null) {
|
|
ajaxRequest1.abort();
|
|
}
|
|
ajaxRequest1 = $.ajax({
|
|
url: 'fetch_certificate.php',
|
|
type: 'POST',
|
|
data: { lotnum: lotnum },
|
|
dataType: 'json',
|
|
success: function (response) {
|
|
console.log('response :',response);
|
|
if (response.success) {
|
|
if (response.item === "offering") {
|
|
// 제공품 성적서
|
|
var url = "/lot/write_sheet.php?num=" + response.num;
|
|
customPopup(url, '제공품 성적서', 800, 900);
|
|
} else if (response.item === "regular") {
|
|
// 일반 성적서 데이터 처리
|
|
viewBoardInstock(
|
|
response.num,
|
|
response.itemname,
|
|
response.specification,
|
|
response.remarks
|
|
);
|
|
}
|
|
} else {
|
|
Swal.fire('오류', response.message, 'error');
|
|
}
|
|
},
|
|
error: function (jqXHR, textStatus, errorThrown) {
|
|
console.error('AJAX Error:', textStatus, errorThrown);
|
|
console.error('Response Text:', jqXHR.responseText);
|
|
Swal.fire('오류', '서버 요청에 실패했습니다. <br> ' + textStatus + ': ' + errorThrown, 'error');
|
|
},
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
// 수주내역의 후반부 자바스크립트
|
|
$(document).ready(function() {
|
|
// 서버에서 전달된 estimateList 데이터
|
|
var mode = '<?php echo $mode; ?>' ;
|
|
let estimateList = <?php echo json_encode($estimateList ?? []); ?>; // 스크린견적서에서 불러온 발주내용
|
|
let estimateList_auto = <?php echo json_encode($estimateList_auto ?? []); ?>;
|
|
let estimateSlatList = <?php echo json_encode($estimateSlatList ?? []); ?>; // 철재견적서에서 불러온 발주내용
|
|
let estimateSlatList_auto = <?php echo json_encode($estimateSlatList_auto ?? []); ?>;
|
|
var etcList = <?php echo json_encode($etcList ?? []); ?>;
|
|
let screen_unapprovedList = <?php echo json_encode($screen_unapprovedList ?? []); ?>;
|
|
let slat_unapprovedList = <?php echo json_encode($slat_unapprovedList ?? []); ?>;
|
|
let motorList = <?php echo json_encode($motorList ?? []); ?>;
|
|
let bendList = <?php echo json_encode($bendList ?? []); ?>;
|
|
let controllerList = <?php echo json_encode($controllerList ?? []); ?>;
|
|
let accountList = <?php echo json_encode($accountList ?? []); ?>;
|
|
|
|
/**
|
|
* 입력값(raw)을 안전하게 배열로 변환합니다.
|
|
* - raw가 문자열이면 JSON.parse
|
|
* - raw가 객체/배열이면 JSON.stringify → JSON.parse
|
|
* - 파싱 실패하거나 최종 결과가 배열이 아니면 빈 배열 반환
|
|
*/
|
|
function parseJsonList(raw) {
|
|
let str;
|
|
|
|
// 1) raw를 JSON 문자열로 확보
|
|
if (typeof raw === 'string') {
|
|
str = raw;
|
|
} else {
|
|
try {
|
|
str = JSON.stringify(raw);
|
|
} catch (e) {
|
|
console.error('parseJsonList: 데이터를 문자열로 변환 실패', e);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// 2) 문자열을 JSON으로 파싱
|
|
try {
|
|
const parsed = JSON.parse(str);
|
|
if (!Array.isArray(parsed)) {
|
|
console.warn('parseJsonList: 파싱 결과가 배열이 아님, 빈 배열로 초기화');
|
|
return [];
|
|
}
|
|
return parsed;
|
|
} catch (e) {
|
|
console.error('parseJsonList: JSON 파싱 오류', e);
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// 각각 리스트 파싱하고 전역 변수로 설정
|
|
window.screen_unapprovedList = parseJsonList(screen_unapprovedList);
|
|
window.slat_unapprovedList = parseJsonList(slat_unapprovedList);
|
|
window.motorList = parseJsonList(motorList);
|
|
window.bendList = parseJsonList(bendList);
|
|
window.controllerList = parseJsonList(controllerList);
|
|
window.etcList = parseJsonList(etcList);
|
|
window.accountList = parseJsonList(accountList);
|
|
|
|
/*************************************************
|
|
* 거래명세표 비인정 데이터 렌더링(모달창) UA는 비인정약자임 unapproved 의미
|
|
*/
|
|
function renderViewUATable(containerSelector, title, tableId, tbodyId, columns, dataList) {
|
|
if (!Array.isArray(dataList) || dataList.length === 0) return;
|
|
|
|
// tableId 별로 꺼낼 프로퍼티명 매핑
|
|
const fieldMap = {
|
|
// 비인정 스크린
|
|
screen_unapprovedList_view: [
|
|
'item_type', // 품명
|
|
'floors', // 층
|
|
'text1', // 부호
|
|
'cutwidth', // 가로
|
|
'cutheight', // 세로
|
|
'number' // 수량
|
|
],
|
|
// 비인정 철재-슬랫
|
|
slat_unapprovedList_view: [
|
|
'item_type', // 품목
|
|
'floors', // 층
|
|
'text1', // 부호
|
|
'memo', // 재질
|
|
'cutwidth', // 가로
|
|
'cutheight', // 세로
|
|
'number', // 수량
|
|
'exititem', // 비상문
|
|
'hinge', // 힌지종류
|
|
'hinge_direction' // 힌지방향
|
|
],
|
|
// 절곡품
|
|
bend_list_view:[
|
|
'col1', // 품목
|
|
'col2', // 두께
|
|
'col3', // 길이(mm)
|
|
'col7', // 수량
|
|
'col8', // 비고
|
|
],
|
|
};
|
|
|
|
const keys = fieldMap[tableId];
|
|
|
|
// 1) 제목
|
|
let html = `<div class="fw-bold mt-3">${title}</div>`;
|
|
|
|
// 2) thead
|
|
html += `<table class="table table-bordered table-sm text-center" id="${tableId}">`;
|
|
html += `<thead class="table-light"><tr><th>번호</th>`;
|
|
columns.forEach(h => html += `<th>${h}</th>`);
|
|
html += `</tr></thead>`;
|
|
|
|
// 3) tbody
|
|
html += `<tbody id="${tbodyId}">`;
|
|
|
|
dataList.forEach((row, idx) => {
|
|
html += `<tr><td>${idx+1}</td>`;
|
|
|
|
if (tableId === 'screen_unapprovedList_view') {
|
|
// 스크린 비인정: [품명, 층+부호, 가로, 세로, 수량]
|
|
const vals = [
|
|
row.item_type || '',
|
|
`${row.floors||''} ${row.text1||''}`,
|
|
row.cutwidth || '',
|
|
row.cutheight|| '',
|
|
row.number || ''
|
|
];
|
|
vals.forEach(v => html += `<td>${v}</td>`);
|
|
|
|
} else if (tableId === 'slat_unapprovedList_view') {
|
|
// 비인정 철재-슬랫 [품명, 층+부호, 가로, 세로, 수량]
|
|
const vals = [
|
|
row.item_type || '',
|
|
`${row.floors||''} ${row.text1||''}`,
|
|
row.cutwidth || '',
|
|
row.cutheight|| '',
|
|
row.number || '',
|
|
row.exititem === '0' ? '(없음)' : '(있음)',
|
|
row.hinge || '',
|
|
row.hinge_direction || '',
|
|
];
|
|
vals.forEach(v => html += `<td>${v}</td>`);
|
|
|
|
} else if (tableId === 'bend_list_view') {
|
|
const vals = [
|
|
row.col1 || '',
|
|
row.col2 || '',
|
|
row.col3 || '',
|
|
row.col7 || '',
|
|
row.col8 || '',
|
|
];
|
|
vals.forEach(v => html += `<td>${v}</td>`);
|
|
|
|
} else {
|
|
// 그 외: col1, col2, …
|
|
columns.forEach((_, i) => {
|
|
const col = `col${i+1}`;
|
|
html += `<td>${row[col]||''}</td>`;
|
|
});
|
|
}
|
|
|
|
html += `</tr>`;
|
|
});
|
|
|
|
html += `</tbody></table>`;
|
|
$(containerSelector).append(html);
|
|
}
|
|
|
|
const container = '.orderlist_UA'; // 테이블을 렌더링할 부모 div 선택자
|
|
|
|
renderViewUATable(container, '스크린', 'screen_unapprovedList_view', 'screen_unapprovedListBody_view',
|
|
['품명', '층부호','가로', '세로', '수량'], window.screen_unapprovedList);
|
|
|
|
renderViewUATable(container, '철재-슬랫', 'slat_unapprovedList_view', 'slat_unapprovedListBody_view',
|
|
['품명', '층부호','가로', '세로', '수량', '비상문', '힌지종류', '힌지방향'], window.slat_unapprovedList);
|
|
|
|
renderViewUATable(container, '전동 개폐기 & 베어링부(브라켓트)', 'motor_list_view', 'motor_listBody_view',
|
|
['품명', '용량', '브라켓', '샤프트', '수량', '형태', '리미트', '비고'], window.motorList);
|
|
|
|
renderViewUATable(container, '연동 폐쇄기구(제어기) & 방범스위치', 'controller_list_view', 'controller_listBody_view',
|
|
['품명', '수량', '형태', '비고'], window.controllerList);
|
|
|
|
renderViewUATable(container, '절곡품 (규격 및 타입은 도면 참조)', 'bend_list_view', 'bend_listBody_view',
|
|
['품명', '두께', '길이(mm)', '수량', '비고'], window.bendList);
|
|
|
|
renderViewUATable(container, '부자재', 'etc_list_view', 'etc_listBody_view',
|
|
['품명', '규격', '길이', '수량', '비고'], window.etcList);
|
|
|
|
});
|
|
</script>
|
|
|
|
<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/instock/common/viewJS.php'; ?> <!--공통 JS 여기에 viewBoardInstock() 함수 들어있음 -->
|
|
</body>
|
|
</html>
|