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

6123 lines
255 KiB
PHP

<script>
// 이 파일에서 불러오는 코드는 아래와 같음
// include $_SERVER['DOCUMENT_ROOT'] . '/common/output.php'; // 후반부에 들어갈 자바스크립트 코드 모음
// include $_SERVER['DOCUMENT_ROOT'] . '/common/fileImage.php'; // 파일과 이미지 불러오고 저장하는 서브모듈
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 getScreenJpg(exititem, direction, printside) {
if (exititem == '1') {
if (isZeroOrEmpty(direction) && isZeroOrEmpty(printside)) return '1';
if (direction == '1' && isZeroOrEmpty(printside)) return '2';
if (isZeroOrEmpty(direction) && printside == '1') return '3';
if (direction == '1' && printside == '1') return '4';
} else if (exititem == '2') {
if (isZeroOrEmpty(direction) && isZeroOrEmpty(printside)) return '5';
if (direction == '1' && isZeroOrEmpty(printside)) return '6';
if (isZeroOrEmpty(direction) && printside == '1') return '7';
if (direction == '1' && printside == '1') return '8';
} else if (exititem == '3') {
if (isZeroOrEmpty(direction) && isZeroOrEmpty(printside)) return '9';
if (direction == '1' && isZeroOrEmpty(printside)) return '10';
if (isZeroOrEmpty(direction) && printside == '1') return '11';
if (direction == '1' && printside == '1') return '12';
} else if (exititem == '4') {
if (isZeroOrEmpty(direction) && isZeroOrEmpty(printside)) return '13';
if (direction == '1' && isZeroOrEmpty(printside)) return '14';
if (isZeroOrEmpty(direction) && printside == '1') return '15';
if (direction == '1' && printside == '1') return '16';
} else if (exititem == '5') {
if (isZeroOrEmpty(direction)) return '17';
if (direction == '1') return '18';
}
return null; // 기본값 또는 오류 처리
}
function calculateRow(element) {
const row = element.closest('tr');
if (!row || (!row.closest('#screenTable') && !row.closest('#screen_unapprovedTable'))) return;
const cutwidthElement = row.querySelector('[name="cutwidth[]"]');
const cutheightElement = row.querySelector('[name="cutheight[]"]');
const numberElement = row.querySelector('[name="number[]"]');
const exititemElement = row.querySelector('[name="exititem[]"]');
const printsideElement = row.querySelector('[name="printside[]"]');
const directionElement = row.querySelector('[name="direction[]"]');
const intervalnumElement = row.querySelector('[name="intervalnum[]"]');
const intervalnumsecondElement = row.querySelector('[name="intervalnumsecond[]"]');
const exitintervalElement = row.querySelector('[name="exitinterval[]"]');
const coverElement = row.querySelector('[name="cover[]"]');
const memoElement = row.querySelector('[name="memo[]"]');
const width = cutwidthElement ? parseFloat(cutwidthElement.value.replace(/,/g, '')) || 0 : 0;
const height = cutheightElement ? parseFloat(cutheightElement.value.replace(/,/g, '')) || 0 : 0;
const number = numberElement ? parseFloat(numberElement.value.replace(/,/g, '')) || 0 : 0;
const exititem = exititemElement ? exititemElement.value : '0';
const printside = printsideElement ? printsideElement.value : '';
const direction = directionElement ? directionElement.value : '';
const intervalnum = intervalnumElement ? intervalnumElement.value : '';
const intervalnumsecond = intervalnumsecondElement ? intervalnumsecondElement.value : '';
const exitinterval = exitintervalElement ? parseFloat(exitintervalElement.value) || 900 : 900;
const cover = coverElement ? parseFloat(coverElement.value) || 1200 : 1200;
const memo = memoElement ? memoElement.value : '';
if (exititem === '0') {
if (printsideElement) printsideElement.value = '';
if (directionElement) directionElement.value = '';
if (intervalnumElement) intervalnumElement.value = '';
if (intervalnumsecondElement) intervalnumsecondElement.value = '';
if (exitintervalElement) exitintervalElement.value = '';
if (coverElement) coverElement.value = '';
} else {
if (printsideElement && printside === '') printsideElement.value = '0';
if (directionElement && direction === '') directionElement.value = '0';
if (coverElement && coverElement.value === '') coverElement.value = '1200';
if (exitintervalElement && exitintervalElement.value === '') exitintervalElement.value = '900';
}
let comment = '';
if (exititem === '0') {
comment = "(문X)";
}
// console.log('exititem :',exititem)
// console.log('printside :',printside)
// console.log('direction :',direction)
let screenjpg = getScreenJpg(exititem, direction, printside);
// console.log(screenjpg); // '1'이 출력됩니다.
let remainleft, remainright, numcenter;
if (exititem == '0') {
remainleft = ' ';
remainright = ' ';
} else if (exititem == '1') {
remainleft = width / 2 - (exitinterval / 2);
remainright = remainleft;
} else if (exititem == '2') {
remainleft = '좌 ' + intervalnum + ' ';
remainright = width - intervalnum - exitinterval;
} else if (exititem == '3') {
remainleft = width - intervalnumsecond - exitinterval;
remainright = '우 ' + intervalnumsecond + ' 띄고';
} else if (exititem == '4' || exititem == '5') {
remainleft = '좌 ' + intervalnum + ' 띄고,';
remainright = '우 ' + intervalnumsecond + ' 띄고';
numcenter = width - exitinterval * 2 - intervalnum - intervalnumsecond;
}
if (row.querySelector('[name="drawbottom1[]"]')) row.querySelector('[name="drawbottom1[]"]').value = remainleft;
if (row.querySelector('[name="drawbottom2[]"]')) row.querySelector('[name="drawbottom2[]"]').value = remainright;
if (row.querySelector('[name="drawbottom3[]"]')) row.querySelector('[name="drawbottom3[]"]').value = numcenter || ' ';
const text2Input = row.querySelector('.text2');
if (text2Input) {
let text = `${width} x ${height} , ${number} EA, ${comment}`;
// 문자열 끝에 남아있는 쉼표와 공백을 지운다
text = text.replace(/,\s*$/, '');
text2Input.value = text;
}
const imgElement = row.querySelector('.draw img');
if (imgElement) {
imgElement.src = `../img/screen/screen${screenjpg}.jpg`;
// console.log('screenjpg : ' + screenjpg);
// console.log('imgElement.src' + imgElement.src);
if(screenjpg !== 'null' )
imgElement.style.display = 'block';
}
const drawElement = row.querySelector('[name="draw[]"]');
if (drawElement && screenjpg !== 'null') {
drawElement.value = `screen${screenjpg}.jpg`;
}
screen_updateTotals();
}
function screen_updateTotals() {
const rows = document.querySelectorAll('#screenTable tr');
let totalScreen = 0;
let totalScreenM2 = 0;
rows.forEach(row => {
const numberElement = row.querySelector('[name="number[]"]');
const cutwidthElement = row.querySelector('[name="cutwidth[]"]');
const cutheightElement = row.querySelector('[name="cutheight[]"]');
const number = numberElement ? parseFloat(numberElement.value.replace(/,/g, '')) || 0 : 0;
const cutwidth = cutwidthElement ? parseFloat(cutwidthElement.value.replace(/,/g, '')) || 0 : 0;
const cutheight = cutheightElement ? parseFloat(cutheightElement.value.replace(/,/g, '')) || 0 : 0;
totalScreen += number;
totalScreenM2 += (cutwidth * cutheight * number) / 1000000;
});
document.getElementById('total_screen').textContent = `총 수량: ${totalScreen}`;
document.getElementById('total_screen_m2').textContent = `총 면적: ${totalScreenM2.toFixed(1)} m²`;
}
document.querySelectorAll('input, select').forEach(input => {
input.addEventListener('input', function() { calculateRow(this); });
if (input.tagName.toLowerCase() === 'select') {
input.addEventListener('change', function() { calculateRow(this); });
}
});
screen_updateTotals();
// 스크린작업지시서 작성
/**
* addRow(null, estimateData)를 호출하면,
* estimateData의 속성(col2, col3, col4, col7, col10, col11, exititem, printside, direction, intervalnum, intervalnumsecond,
* exitinterval, cover, drawbottom1, drawbottom3, drawbottom2, draw, text2)
* 을 각각 올바른 <input>이나 <select>의 value/selected 속성으로 설정해 줍니다.
*/
function addRow(button, estimateData = {}) {
const table = document.getElementById('screenTable');
const newRow = document.createElement('tr');
// PHP에서 넘어온 사용자 이름, 모드 값 (필요에 따라 사용)
const username = '<?php echo $user_name; ?>';
const mode = '<?php echo $mode; ?>';
if (!authorities.includes(username) || mode === 'view') return;
// estimateData 기본값 설정
// col2 → floors, col3 → text1, col4 → memo, col7 → number, col10 → cutwidth, col11 → cutheight
const floors = estimateData.col2 || '';
const text1 = estimateData.col3 || '';
const memo = estimateData.col5 || ''; // 실리카 등 추가메모
const cutwidth = estimateData.col10 || '';
const cutheight = estimateData.col11 || '';
// const numberVal = estimateData.col14 || '1'; // 수량은 무조건 1로 세팅
const numberVal = '1'; // 수량은 무조건 1로 세팅
// 나머지 필드(옵션)들도 estimateData에서 가져오기
const exititem = estimateData.exititem || '0';
const printside = estimateData.printside || '';
const direction = estimateData.direction || '';
const intervalnum = estimateData.intervalnum || '';
const intervalnumsecond = estimateData.intervalnumsecond || '';
const exitinterval = estimateData.exitinterval || '';
const cover = estimateData.cover || '';
const drawbottom1 = estimateData.drawbottom1 || '';
const drawbottom3 = estimateData.drawbottom3 || '';
const drawbottom2 = estimateData.drawbottom2 || '';
const drawHidden = estimateData.draw || ''; // 예: "screen5.jpg"
const text2Val = estimateData.text2 || '';
const done_check = estimateData.done_check || '';
const remain_check = estimateData.remain_check || '';
const mid_check = estimateData.mid_check || '';
const left_check = estimateData.left_check || '';
const right_check = estimateData.right_check || '';
// 새 행 innerHTML 생성
newRow.innerHTML =
'<td class="text-center">' + (table.rows.length + 1) + '</td>' +
// floors (col2) → "층"
'<td><input type="text" class="form-control" name="floors[]" value="' + floors + '" placeholder="층" oninput="calculateRow(this)" autocomplete="off"></td>' +
// text1 (col3) → "부호"
'<td><input type="text" class="form-control" name="text1[]" value="' + text1 + '" placeholder="부호" oninput="calculateRow(this)" autocomplete="off"></td>' +
// memo (col4) → "추가메모"
'<td><input type="text" class="form-control" name="memo[]" value="' + memo + '" placeholder="추가메모" oninput="calculateRow(this)" autocomplete="off"></td>' +
// cutwidth (col10) → "가로(W)"
'<td><input type="text" class="form-control" name="cutwidth[]" value="' + cutwidth + '" placeholder="가로(W)" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>' +
// cutheight (col11) → "세로(H)"
'<td><input type="text" class="form-control" name="cutheight[]" value="' + cutheight + '" placeholder="세로(H)" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>' +
// number (col7) → "수량(EA)"
'<td><input type="text" class="form-control" name="number[]" value="' + numberVal + '" placeholder="수량(EA)" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>' +
// exititem → "없음/중앙/좌측/우측/문2개/문2개지그재그"
'<td><select class="form-control exititem text-center" name="exititem[]" onchange="calculateRow(this)" style="font-size:10px;">' +
'<option value="0"' + (exititem === '0' ? ' selected' : '') + '>없음</option>' +
'<option value="1"' + (exititem === '1' ? ' selected' : '') + '>중앙</option>' +
'<option value="2"' + (exititem === '2' ? ' selected' : '') + '>좌측</option>' +
'<option value="3"' + (exititem === '3' ? ' selected' : '') + '>우측</option>' +
'<option value="4"' + (exititem === '4' ? ' selected' : '') + '>문2개</option>' +
'<option value="5"' + (exititem === '5' ? ' selected' : '') + '>문2개 지그재그</option>' +
'</select></td>' +
// printside → "양면/한면"
'<td><select class="form-control printside text-center" name="printside[]" onchange="calculateRow(this)" style="font-size:10px;">' +
'<option value=""' + (printside === '' ? ' selected' : '') + '></option>' +
'<option value="0"' + (printside === '0' ? ' selected' : '') + '>양면</option>' +
'<option value="1"' + (printside === '1' ? ' selected' : '') + '>한면</option>' +
'</select></td>' +
// direction → "정방향/역방향"
'<td><select class="form-control direction text-center" name="direction[]" onchange="calculateRow(this)" style="font-size:10px;">' +
'<option value=""' + (direction === '' ? ' selected' : '') + '></option>' +
'<option value="0"' + (direction === '0' ? ' selected' : '') + '>정방향</option>' +
'<option value="1"' + (direction === '1' ? ' selected' : '') + '>역방향</option>' +
'</select></td>' +
// intervalnum → "좌간격"
'<td><input type="text" class="form-control intervalnum" name="intervalnum[]" value="' + intervalnum + '" placeholder="좌간격" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>' +
// intervalnumsecond → "우간격"
'<td><input type="text" class="form-control intervalnumsecond" name="intervalnumsecond[]" value="' + intervalnumsecond + '" placeholder="우간격" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>' +
// exitinterval → "개구부"
'<td><input type="text" class="form-control exitinterval" name="exitinterval[]" value="' + exitinterval + '" placeholder="개구부" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>' +
// cover → "덮개"
'<td><input type="text" class="form-control cover" name="cover[]" value="' + cover + '" placeholder="덮개" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>' +
// drawbottom1 → "좌문구"
'<td><input type="text" class="form-control drawbottom1" name="drawbottom1[]" value="' + drawbottom1 + '" placeholder="좌" oninput="calculateRow(this)" autocomplete="off"></td>' +
// drawbottom3 → "중앙문구"
'<td><input type="text" class="form-control drawbottom3" name="drawbottom3[]" value="' + drawbottom3 + '" placeholder="중앙" oninput="calculateRow(this)" autocomplete="off"></td>' +
// drawbottom2 → "우문구"
'<td><input type="text" class="form-control drawbottom2" name="drawbottom2[]" value="' + drawbottom2 + '" placeholder="우" oninput="calculateRow(this)" autocomplete="off"></td>' +
// drawHidden + <img> → 도면(Hidden + 썸네일)
'<td class="draw">' +
// img 태그: src가 있으면 보여주기, 없으면 display:none
'<img src="' + (drawHidden ? ('../img/screen/' + drawHidden) : '') + '" ' +
'style="width:150px; height:auto; ' + (drawHidden ? '' : 'display:none;') + '" ' +
'onclick="showLargeImage(this)">' +
// 실제 파일명 숨김
'<input type="hidden" name="draw[]" value="' + drawHidden + '">' +
'</td>' +
// text2 → "텍스트2"
'<td><input type="text" class="form-control text2" name="text2[]" value="' + text2Val + '" readonly></td>' +
// 복사 / 행추가 / 삭제 버튼
'<td>' +
'<span class="text-primary fs-6 hover-pointer ms-1 me-2" onclick="copyRow(this)">' +
'<i class="bi bi-copy"></i>' +
'</span>' +
'<span class="text-success fs-6 hover-pointer ms-1 me-2" onclick="addRow(this)">+</span>' +
'<span class="text-danger fs-6 hover-pointer ms-1" onclick="removeRow(this)">-</span>' +
'</td>' +
// 화면에 표시하지 않지만 내부 연산에 필요한 hidden 체크박스들
'<td style="display:none;">' +
'<input type="text" class="form-control done_check" name="done_check[]" style="display:none;" value="' + done_check + '">' +
'<input type="text" class="form-control remain_check" name="remain_check[]" style="display:none;" value="' + remain_check + '">' +
'<input type="text" class="form-control mid_check" name="mid_check[]" style="display:none;" value="' + mid_check + '">' +
'<input type="text" class="form-control left_check" name="left_check[]" style="display:none;" value="' + left_check + '">' +
'<input type="text" class="form-control right_check" name="right_check[]" style="display:none;" value="' + right_check + '">' +
'</td>';
// 생성된 <tr>을 삽입
if (button) {
table.insertBefore(newRow, button.closest('tr').nextSibling);
} else {
table.appendChild(newRow);
}
// 새로 추가된 행에 대해 한 번 calculateRow() 호출
calculateRow(newRow);
}
// 데이터를 전달하여 행을 추가하는 함수
function addRowsFromEstimate(estimateList) {
const slatcheck = $("#slatcheck").prop('checked'); // 주자재(스크린,철재) 체크여부
console.log('스크린 slatcheck : ', slatcheck);
// 견적 데이터를 사용하여 발주서를 초기화
const orderTableBody = document.getElementById('screenTable');
orderTableBody.innerHTML = ''; // 기존 발주서 내용 초기화
// 제품코드 및 인증번호 불러오기
estimateList.forEach((estimateData) => {
prodCode = estimateData.col4;
console.log('견적서 prodCode :', prodCode);
});
// 스크린 작업지시서 추가
if (slatcheck === true) {
estimateList.forEach((estimateData) => {
// 수량이 1보다 큰 경우, 해당 수량만큼 행을 반복 생성
const quantity = parseInt(estimateData.col14) || 1;
for (let i = 0; i < quantity; i++) {
addRow(null, estimateData);
}
});
}
else
{
// 스크린 견적서 체크 안되어 있으면 작업지시서 추가 안함
console.log('slatcheck is false');
// 스크린 작업지시서 숨기기
$("#screen_order").hide();
}
}
function copyRow(button) {
const row = button.closest('tr');
const newRow = row.cloneNode(true);
const table = document.getElementById('screenTable');
const username = '<?php echo $user_name; ?>';
const mode = '<?php echo $mode; ?>';
if (!authorities.includes(username) || mode == 'view')
return;
newRow.querySelectorAll('input, select').forEach(input => {
if (input.name === "done_check[]") {
input.value = row.querySelector(`[name="${input.name}"]`).value;
} else if (input.type === 'checkbox') {
input.checked = row.querySelector(`[name="${input.name}"]`).checked;
} else {
input.value = row.querySelector(`[name="${input.name}"]`).value;
}
});
const imgElement = newRow.querySelector('.draw img');
if (imgElement) {
imgElement.src = row.querySelector('.draw img').src;
}
const drawElement = newRow.querySelector('[name="draw[]"]');
if (drawElement) {
drawElement.value = row.querySelector('[name="draw[]"]').value;
}
// Update row number
newRow.querySelector('td').innerText = table.rows.length + 1;
if (button) {
table.insertBefore(newRow, row.nextSibling);
} else {
table.appendChild(newRow);
}
newRow.querySelectorAll('input, select').forEach(input => {
input.addEventListener('input', function() { calculateRow(this); });
if (input.tagName.toLowerCase() === 'select') {
input.addEventListener('change', function() { calculateRow(this); });
}
});
// Ensure totals are updated after row is copied
screen_updateTotals();
}
function removeRow(button) {
const username = '<?php echo $user_name; ?>';
const mode = '<?php echo $mode; ?>';
if (!authorities.includes(username) || mode == 'view')
return;
const row = button.closest('tr');
row.remove();
// Update row numbers
const rows = document.querySelectorAll('#screenTable tr');
rows.forEach((row, index) => {
row.cells[0].innerText = index + 1;
});
screen_updateTotals();
}
function showLargeImage(img) {
const largeImage = document.createElement('img');
largeImage.src = img.src;
largeImage.style.position = 'fixed';
largeImage.style.top = '50%';
largeImage.style.left = '50%';
largeImage.style.transform = 'translate(-50%, -50%)';
largeImage.style.zIndex = '1000';
largeImage.style.maxWidth = '90%';
largeImage.style.maxHeight = '90%';
largeImage.style.border = '2px solid #fff';
largeImage.style.boxShadow = '0 0 10px rgba(0, 0, 0, 0.5)';
largeImage.onclick = function() {
document.body.removeChild(largeImage);
};
document.body.appendChild(largeImage);
}
function screen_updateTotals() {
const rows = document.querySelectorAll('#screenTable tr');
let totalScreen = 0;
let totalScreenM2 = 0;
rows.forEach(row => {
const number = parseFloat(row.querySelector('[name="number[]"]').value.replace(/,/g, '')) || 0;
const cutwidth = parseFloat(row.querySelector('[name="cutwidth[]"]').value.replace(/,/g, '')) || 0;
const cutheight = parseFloat(row.querySelector('[name="cutheight[]"]').value.replace(/,/g, '')) || 0;
totalScreen += number;
totalScreenM2 += (cutwidth * cutheight * number) / 1000000;
});
document.getElementById('total_screen').textContent = `총 수량: ${totalScreen}`;
document.getElementById('total_screen_m2').textContent = `총 면적: ${totalScreenM2.toFixed(1)} m²`;
}
document.querySelectorAll('#screenTable input, #screenTable select').forEach(input => {
input.addEventListener('input', function() { calculateRow(this); });
if (input.tagName.toLowerCase() === 'select') {
input.addEventListener('change', function() { calculateRow(this); });
}
});
screen_updateTotals();
</script>
<script>
function calculateAndSetValues() {
const rows = document.querySelectorAll('#screenTable tr');
let screen_su = 0;
let screen_m2 = 0;
let screen = '0';
let allDone = true;
let hasInProgress = false;
rows.forEach(row => {
const number = parseFloat(row.querySelector('[name="number[]"]').value.replace(/,/g, '')) || 0;
const cutwidth = parseFloat(row.querySelector('[name="cutwidth[]"]').value.replace(/,/g, '')) || 0;
const cutheight = parseFloat(row.querySelector('[name="cutheight[]"]').value.replace(/,/g, '')) || 0;
const done_check = row.querySelector('[name="done_check[]"]').value;
if (number > 0) {
screen = '1';
}
screen_su += number;
screen_m2 += (cutwidth * cutheight * number) / 1000000;
if (done_check === '1') {
hasInProgress = true;
} else {
allDone = false;
}
});
document.getElementById('screen_su').value = screen_su;
document.getElementById('screen_m2').value = screen_m2.toFixed(1);
document.getElementById('screen').value = screen;
}
document.querySelector('form').addEventListener('submit', function(event) {
calculateAndSetValues();
});
function slat_calculateAndSetValues() {
const rows = document.querySelectorAll('#slatTable tr');
let slat_su = 0;
let slat_m2 = 0;
let slat = '0';
let allDone = true;
let hasInProgress = false;
rows.forEach(row => {
const number = parseFloat(row.querySelector('[name="number[]"]').value.replace(/,/g, '')) || 0;
const cutwidth = parseFloat(row.querySelector('[name="cutwidth[]"]').value.replace(/,/g, '')) || 0;
const cutheight = parseFloat(row.querySelector('[name="cutheight[]"]').value.replace(/,/g, '')) || 0;
const done_check = row.querySelector('[name="done_check[]"]').value;
if (number > 0) {
slat = '1';
}
slat_su += number;
slat_m2 += (cutwidth * cutheight * number) / 1000000;
if (done_check === '1') {
hasInProgress = true;
} else {
allDone = false;
}
});
document.getElementById('slat_su').value = slat_su;
document.getElementById('slat_m2').value = slat_m2.toFixed(1);
document.getElementById('slat').value = slat;
// if (rows.length > 0) {
// if (allDone) {
// document.getElementById('slat_state').value = '제작완료';
// } else if (hasInProgress) {
// document.getElementById('slat_state').value = '제작중';
// }
// }
}
document.querySelector('form').addEventListener('submit', function(event) {
slat_calculateAndSetValues();
});
</script>
<script>
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();
}
});
$(document).on('click', '.fetch_outworkplaceBtn', function() {
call_outworkplace();
});
$('#outworkplace').on('keypress', function(event) {
if (event.keyCode === 13) { // 엔터키의 코드는 13입니다.
call_outworkplace();
}
});
});
ajaxRequest_write = null;
// 현장명 검색 처리
function call_outworkplace() {
var search = $('#outworkplace').val(); // 검색어를 가져옴
// console.log("Search term:", search); // 전달되는 값 확인
// AJAX 요청을 통해 데이터 가져오기
if (ajaxRequest_write !== null) {
ajaxRequest_write.abort();
}
ajaxRequest_write = $.ajax({
url: 'fetch_outworkplace.php',
type: 'POST',
data: { search: search },
dataType: 'json',
success: function(data) {
// console.log("Response data:", data); // 서버로부터의 응답을 콘솔에 출력
var tbody = $('.ModalBody');
tbody.empty(); // 기존 데이터를 지움
if (Array.isArray(data) && data.length > 0) {
data.forEach(function(row, index) {
var tr = $('<tr onclick="fetchoutworkplace(\'' + row.outworkplace + '\',\'' + row.receiver + '\',\'' + row.outputplace + '\', \'' + row.phone + '\');">').append(
$('<td>').addClass('text-center').text(index + 1),
$('<td>').addClass('text-start').html( row.outworkplace ),
$('<td>').addClass('text-start').html( row.receiver ),
$('<td>').addClass('text-start').html( row.outputplace ),
$('<td>').addClass('text-start').html( row.phone )
);
tbody.append(tr);
});
} else if (data.length === 0) {
var tr = $('<tr>').append(
$('<td>').attr('colspan', '5').addClass('text-center').text('No data available')
);
tbody.append(tr);
} else {
console.error('Unexpected data format:', data);
var tr = $('<tr>').append(
$('<td>').attr('colspan', '5').addClass('text-center').text('Error loading data')
);
tbody.append(tr);
}
$('#outworkplaceModal').modal('show'); // 모달 띄우기
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('AJAX request failed:', textStatus, errorThrown);
var tbody = $('#ModalBody');
var tr = $('<tr>').append(
$('<td>').attr('colspan', '5').addClass('text-center').text('Error loading data')
);
tbody.append(tr);
}
});
}
function intovaltel(phone, receiver)
// 수신처 전화번호, 주소 화면에 넣어주기
{
$("#phone").val(phone);
$("#receiver").val(receiver);
$("#telModal").modal("hide");
}
function fetchoutworkplace(outworkplace, receiver, outputplace, phone )
// 현장명, 수신처, 수신처 주소, 전화번호 화면에 넣어주기
{
$("#phone").val(phone);
$("#receiver").val(receiver);
$("#outworkplace").val(outworkplace);
$("#outputplace").val(outputplace);
$("#outworkplaceModal").modal("hide");
}
// 수신(반장/업체) 정보가져오기
function callreceiver() {
var search = $('#receiver').val(); // 검색어를 가져옴
// console.log("Search term:", search); // 전달되는 값 확인
// AJAX 요청을 통해 데이터 가져오기
if (ajaxRequest_write !== null) {
ajaxRequest_write.abort();
}
ajaxRequest_write = $.ajax({
url: 'fetch_receiver.php',
type: 'POST',
data: { search: search },
dataType: 'json',
success: function(data) {
// console.log("Response data:", data); // 서버로부터의 응답을 콘솔에 출력
var tbody = $('#ModalBody');
tbody.empty(); // 기존 데이터를 지움
if (Array.isArray(data) && data.length > 0) {
data.forEach(function(row, index) {
var tr = $('<tr onclick="intovaltel(\'' + row.phone + '\', \'' + row.receiver + '\');">').append(
$('<td>').addClass('text-center').text(index + 1),
$('<td>').addClass('text-start').html( row.receiver ),
$('<td>').addClass('text-start').html( row.phone ),
$('<td>').addClass('text-start').html( row.outputplace ),
);
tbody.append(tr);
});
} else if (data.length === 0) {
var tr = $('<tr>').append(
$('<td>').attr('colspan', '4').addClass('text-center').text('No data available')
);
tbody.append(tr);
} else {
console.error('Unexpected data format:', data);
var tr = $('<tr>').append(
$('<td>').attr('colspan', '4').addClass('text-center').text('Error loading data')
);
tbody.append(tr);
}
$('#telModal').modal('show'); // 모달 띄우기
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('AJAX request failed:', textStatus, errorThrown);
var tbody = $('#ModalBody');
var tr = $('<tr>').append(
$('<td>').attr('colspan', '4').addClass('text-center').text('Error loading data')
);
tbody.append(tr);
}
});
}
function intovaltel(phone, receiver)
// 수신처 전화번호, 주소 화면에 넣어주기
{
$("#phone").val(phone);
$("#receiver").val(receiver);
$("#telModal").modal("hide");
}
</script>
<script>
// 페이지 로딩
$(document).ready(function(){
var loader = document.getElementById('loadingOverlay');
if(loader) {
loader.style.display = 'none';
}
});
</script>
<script>
var mode = '<?php echo $mode; ?>';
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": [25, 50, 100, 200, 500, 1000],
"language": {
"lengthMenu": "Show _MENU_ entries",
"search": "Live Search:"
},
"order": [[0, 'asc']]
});
// 페이지 번호 복원 (초기 로드 시)
var savedPageNumber = getCookie('outputpageNumber');
if (savedPageNumber) {
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
}
// 페이지 변경 이벤트 리스너
dataTable.on('page.dt', function() {
var outputpageNumber = dataTable.page.info().page + 1;
setCookie('outputpageNumber', outputpageNumber, 10); // 쿠키에 페이지 번호 저장
});
// 페이지 길이 셀렉트 박스 변경 이벤트 처리
$('#myTable_length select').on('change', function() {
var selectedValue = $(this).val();
dataTable.page.len(selectedValue).draw(); // 페이지 길이 변경 (DataTable 파괴 및 재초기화 없이)
// 변경 후 현재 페이지 번호 복원
savedPageNumber = getCookie('outputpageNumber');
if (savedPageNumber) {
dataTable.page(parseInt(savedPageNumber) - 1).draw(false);
}
});
});
function restorePageNumber() {
var savedPageNumber = getCookie('outputpageNumber');
// if (savedPageNumber) {
// dataTable.page(parseInt(savedPageNumber) - 1).draw('page');
// }
location.reload(true);
}
$(document).ready(function(){
$("#copyBtn").click(function(){
//개발자전용 수정위치
location.href = 'write_form1.php?mode=copy&num=' + $("#num").val() + "&tablename=" + $("#tablename").val() ;
}); // end of function
$("#viewscreenBtn").click(function(){
var url = '/make/write_form.php?mode=view&num=' + $("#num").val() + "&tablename=" + $("#tablename").val() ;
customPopup(url, '스크린 작업지시서', 1850, 900);
}); // end of function
$("#viewslatBtn").click(function(){
var url = '/egimake/write_form.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 );
}
});
}
});
}
});
$("#saveBtn").click(function(e) { // "DATA 저장" 버튼 클릭 이벤트
var num = $("#num").val(); // 번호 값 가져오기
// 복사일때는 insert로 처리함
if($("#mode").val() !=='copy')
{
if (Number(num) < 1) {
$("#mode").val('insert');
} else {
$("#mode").val('modify');
}
}
else
{
$("#mode").val('insert');
}
// 모든 필수 입력 필드 확인
var empty = false;
$('input[name="cutwidth[]"], input[name="cutheight[]"], input[name="number[]"]').each(function() {
if ($(this).val().trim() === '') {
empty = true;
}
});
// 비어 있는 필드가 있으면 경고창 표시하고 함수 실행 중지
// if (empty) {
// Swal.fire({
// icon: 'error',
// title: '입력 오류',
// text: '입력창의 가로, 세로, 수량은 필수입니다!',
// confirmButtonText: '확인'
// });
// return; // 함수 실행 중지
// }
// 자료 삽입/수정하는 모듈 (로트번호 체크하고 저장하기)
savelotNum();
});
// 화면이 시작된 후
hideOverlay();
});
// 공통저장을 위한 함수 json형식으로 변환하는 로직
function saveTableToHiddenField(tbodySelector, hiddenInputSelector) {
const formData = [];
$(tbodySelector).find('tr').each(function () {
const rowData = {};
$(this).find('input, select').each(function () {
const name = $(this).attr('name')?.replace('[]', '');
if (name) {
rowData[name] = $(this).val();
}
});
formData.push(rowData);
});
const jsonString = JSON.stringify(formData);
$(hiddenInputSelector).val(jsonString);
}
function saveAllJSONTables() {
const targets = [
{ body: '#deliveryfeeTableBody', field: '#deliveryfeeList' }, // 배송비
{ body: '#screen_unapprovedListBody', field: '#screen_unapprovedList' }, // 스크린 비인정제품
{ body: '#slat_unapprovedListBody', field: '#slat_unapprovedList' }, // 철재-슬랫 비인정제품
{ body: '#motor_listBody', field: '#motorList' }, // 모터
{ body: '#bend_listBody', field: '#bendList' }, // 절곡품
{ body: '#controller_listBody', field: '#controllerList' }, // 컨트롤러
{ body: '#etc_listBody', field: '#etcList' }, // 기타
{ body: '#account_listBody', field: '#accountList' } // 회계
];
targets.forEach(t => saveTableToHiddenField(t.body, t.field));
}
// 삽입/수정하는 모듈
function saveData() {
// json 형태로 form문에 저장하기
let formData = [];
// 스크린작업지시서
$('#screenTable 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);
});
// JSON 문자열로 변환
let jsonString = JSON.stringify(formData);
// console.log('screenlist json : ', jsonString);
// 숨겨진 필드에 JSON 데이터 설정
$('#screenlist').val(jsonString);
// 스크린수 및 기타 연산을 수행함.
calculateAndSetValues();
// 철재작업지시서
formData = [];
$('#slatTable 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);
});
// JSON 문자열로 변환
jsonString = JSON.stringify(formData);
// console.log('slatlist json : ', jsonString);
// 숨겨진 필드에 JSON 데이터 설정
$('#slatlist').val(jsonString);
// 스라트 연산수행
slat_calculateAndSetValues();
// estimateList 저장 로직
const screenData = collectEstimateListData('#estimateListTable');
// JSON 변환 후 hidden field에 대입
jsonString = JSON.stringify(screenData);
// console.log('save 버튼 클릭시 estimateList json : ', jsonString);
$('#estimateList').val(jsonString);
// 철재작업지시서
const slatData = collectEstimateListData_Slat(); // 철재슬라트용 자료 저장하기
// JSON 변환 후 hidden field에 대입
jsonString = JSON.stringify(slatData);
// console.log('save 버튼 클릭시 slatlist json : ', jsonString);
$('#estimateSlatList').val(jsonString);
// json형태로 저장하기
saveAllJSONTables();
showMsgModal(2); // 파일저장중
// console.log('전송전 prodCode' + $("#prodCode").val());
// 폼데이터 전송시 사용함 Get form
var form = $('#board_form')[0];
var datasource = new FormData(form);
// // Iterate over the FormData entries and log them
// for (var pair of datasource.entries()) {
// console.log(pair[0] + ': ' + pair[1]);
// }
$.ajax({
enctype: 'multipart/form-data', // file을 서버에 전송하려면 이렇게 해야 함 주의
processData: false,
contentType: false,
cache: false,
timeout: 600000,
url: "insert.php",
type: "post",
data: datasource,
dataType: "json",
success: function(data){
// console.log(data);
// console.log(data.num);
// console.log(data.prodCode);
if (window.opener && !window.opener.closed) {
if (typeof window.opener.restorePageNumber === 'function') {
window.opener.restorePageNumber(); // 함수가 있으면 실행
}
}
setTimeout(function() {
if (data && data.num)
// 저장된 데이터 번호를 사용하여 새로운 페이지로 이동
hideMsgModal();
Toastify({
text: "저장완료",
duration: 1500,
close:true,
gravity:"top",
position: "center",
style: {
background: "linear-gradient(to right, #00b09b, #96c93d)"
},
}).showToast();
setTimeout(function() {
hideOverlay();
//개발자전용 수정위치
window.location.href = 'write_form1.php?mode=view&tablename=' + $('#tablename').val() + '&num=' + data.num;
}, 1500);
}, 1000);
},
error: function(jqxhr, status, error) {
console.log(jqxhr, status, error);
alert("An error occurred: " + error); // Display error message
}
});
}
/**
* estimateList 데이터를 수집하는 함수
* @param {string} tableSelector - jQuery 셀렉터 (예: '#estimateListTable')
* @returns {Array<Object>} formData 배열
* 스크린 견적서에 대한 처리 save_josn.php에 저장하기 위한 형태를 만듭니다.
* 발주서 수정 버튼을 누르면 함수가 실행되는 것입니다. 스크린, 철재 별도로 로직 개발
*/
function collectEstimateListData(tableSelector = '#estimateListTable') {
const formData = [];
$(`${tableSelector} tbody tr`).each(function() {
const rowData = {};
$(this).find('td').each(function(idx) {
const $td = $(this);
// console.log('idx : ', idx); // 인덱스 0부터 시작함
if(idx == 9) {
// col10_SW 클래스를 가진 요소가 있는지 확인
const col10Element = $td.find('.col10_SW');
if(col10Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col10_SW'] = col10Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col10_SW'] = $td.text().trim() || '';
}
}
else if(idx == 10) {
// col11_SH 클래스를 가진 요소가 있는지 확인
const col11Element = $td.find('.col11_SH');
if(col11Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col11_SH'] = col11Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col11_SH'] = $td.text().trim() || '';
}
}
else if(idx == 11) {
// col10 클래스를 가진 요소가 있는지 확인
const col12Element = $td.find('.col10');
if(col12Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col10'] = col12Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col10'] = $td.text().trim() || '';
}
}
else if(idx == 12) {
// col11 클래스를 가진 요소가 있는지 확인
const col13Element = $td.find('.col11');
if(col13Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col11'] = col13Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col11'] = $td.text().trim() || '';
}
// col12 클래스를 가진 요소가 있는지 확인
const col12Element = $td.find('.col12');
if(col12Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col12'] = col12Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col12'] = $td.text().trim() || '';
}
}
else if (idx < 9) { // 1~9번째 컬럼
const colName = 'col' + (idx + 1);
let val = $td.find('input, select').val();
if (val === undefined || val === null) {
val = $td.text().trim();
}
rowData[colName] = (val === 0 || val === '0') ? '' : val;
}
else if (idx > 12 && idx < 19) { // 13~19번째 컬럼
const colName = 'col' + (idx - 1); // 마이너스되서 -1 적용 (최초 + 1)
let val = $td.find('input, select').val();
if (val === undefined || val === null) {
val = $td.text().trim();
}
rowData[colName] = (val === 0 || val === '0') ? '' : val;
}
// 18번 브랜드
else if (idx === 19) {
rowData['col18_brand'] = $td.text().trim() || '';
}
// 19번 모델명
else if (idx === 20) {
rowData['col18'] = $td.text().trim() || '';
}
// 20번 유/무선 화면에 보이는 숫자는 21인데 -1 해서 본다. 0부터 시작하니까
else if (idx === 21) {
rowData['col18_wireless'] = $td.text().trim() || '';
}
// 22~38번
else if (idx > 21 && idx < 39) {
const colName = 'col' + (idx - 3);
let val = $td.find('input, select').val();
if (val === undefined || val === null) {
val = $td.text().trim();
}
rowData[colName] = (val === 0 || val === '0') ? '' : val;
}
// 39번 custom/standard + frontbottom, railwidth, boxdirection (화면에는 col36이
else if (idx === 39) {
const parts = $td.text().trim().split(',').map(p => p.trim());
const standardSizes = ['500*350', '500*380'];
const sizeValue = parts[0] || '';
const isCustom = !standardSizes.includes(sizeValue);
rowData['col36'] = isCustom ? 'custom' : sizeValue;
rowData['col36_custom'] = isCustom ? sizeValue : '';
rowData['col36_frontbottom'] = parts[1] || '50';
rowData['col36_railwidth'] = parts[2] || '70';
rowData['col36_boxdirection'] = parts[3] || '양면';
}
// 40~48번
else if (idx > 39 && idx < 49) {
const colName = 'col' + (idx - 3);
let val = $td.find('input, select').val();
if (val === undefined || val === null) {
val = $td.text().trim();
}
rowData[colName] = (val === 0 || val === '0') ? '' : val;
}
// 49번 wing
else if (idx === 49) {
rowData['col45_wing'] = $td.text().trim() || '';
}
// 50~62번
else if (idx > 49 && idx < 63) {
const colName = 'col' + (idx - 4);
let val = $td.find('input, select').val();
if (val === undefined || val === null) {
val = $td.text().trim();
}
rowData[colName] = (val === 0 || val === '0') ? '' : val;
}
// 63번 inch/length/qty
else if (idx === 63) {
rowData['col59_inch'] = $td.find('select').val() || '';
rowData['col59_length'] = $td.find('input.col59-length-input').val() || '';
rowData['col59'] = $td.find('input.col59-input').val() || '';
}
// 64~75번
else if (idx > 63 && idx < 76) {
const colName = 'col' + (idx - 4);
let val = $td.find('input, select').val();
if (val === undefined || val === null) {
val = $td.text().trim();
}
rowData[colName] = (val === 0 || val === '0') ? '' : val;
}
});
formData.push(rowData);
});
return formData;
}
/**
* estimateSlatList 데이터를 수집하는 함수
* @param {string} tableSelector - jQuery 셀렉 * 터 (기본값: '#estimateSlatListTable')
* @returns {Array<Object>} formData 배열
* 철재 견적서에 대한 save_json.php 저장을 위한 형태
* 발주서 수정 버튼을 누르면 함수가 실행되는 것입니다.
*/
function collectEstimateListData_Slat(tableSelector = '#estimateSlatListTable') {
const formData = [];
$(`${tableSelector} tbody tr`).each(function() {
const rowData = {};
$(this).find('td').each(function(idx) {
// console.log('idx : ', idx); // 인덱스 0부터 시작함
const $td = $(this);
let colName;
// 1~5번째 컬럼 (col1 ~ col5)
if (idx < 4) {
colName = 'col' + (idx + 1);
}
else if (idx == 4) {
colName = 'col4_quartz';
}
else if (idx >= 5 && idx <= 9) {
colName = 'col' + idx;
}
else if(idx == 10) {
// col10_SW 클래스를 가진 요소가 있는지 확인
const col10Element = $td.find('.col10_SW');
if(col10Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col10_SW'] = col10Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col10_SW'] = $td.text().trim() || '';
}
return;
}
else if(idx == 11) {
// col11_SH 클래스를 가진 요소가 있는지 확인
const col11Element = $td.find('.col11_SH');
if(col11Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col11_SH'] = col11Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col11_SH'] = $td.text().trim() || '';
}
return;
}
else if(idx == 12) {
// col10 클래스를 가진 요소가 있는지 확인
const col12Element = $td.find('.col10');
if(col12Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col10'] = col12Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col10'] = $td.text().trim() || '';
}
return;
}
else if(idx == 13) {
// col11 클래스를 가진 요소가 있는지 확인
const col13Element = $td.find('.col11');
if(col13Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col11'] = col13Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col11'] = $td.text().trim() || '';
}
return;
}
else if(idx == 14) {
// col12 클래스를 가진 요소가 있는지 확인
const col12Element = $td.find('.col12');
if(col12Element.length > 0) {
// 요소가 있으면 text 값을 가져옴
rowData['col12'] = col12Element.text().trim() || '';
} else {
// 요소가 없으면 td의 text 값을 직접 가져옴
rowData['col12'] = $td.text().trim() || '';
}
return;
}
else if (idx > 14 && idx < 21) {
colName = 'col' + (idx - 2 );
}
// 20번째 컬럼 (모터 유/무선)
else if (idx === 21) {
colName = 'col19_brand';
}
else if (idx === 22) {
colName = 'col19';
}
else if (idx === 23) {
colName = 'col19_wireless';
}
else if (idx > 23 && idx < 41) {
colName = 'col' + (idx - 4);
}
else if (idx === 41) {
const parts = $td.text().trim().split(',').map(part => part.trim());
const standardSizes = ['650*550', '700*600', '780*650'];
const sizeValue = parts[0] || '';
const isCustom = !standardSizes.includes(sizeValue);
rowData['col37'] = isCustom ? 'custom' : sizeValue;
rowData['col37_custom'] = isCustom ? sizeValue : '';
rowData['col37_frontbottom'] = parts[1] || '50';
rowData['col37_railwidth'] = parts[2] || '70';
rowData['col37_boxdirection'] = parts[3] || '양면';
return;
}
else if (idx>41 && idx < 51) {
colName = 'col' + (idx - 4 );
}
else if (idx === 51) {
colName = 'col46_wing';
}
else
{
colName = 'col' + (idx - 5 );
}
// Default value processing for non-special columns
let value = $td.find('input, select').val();
if (value === undefined || value === null) {
value = $td.text().trim();
}
rowData[colName] = (value === 0 || value === '0') ? '' : value;
});
formData.push(rowData);
});
return formData;
}
// 서버에 데이터를 저장할 때 호출되는 함수
function savelotNum() {
var prodCode = $('#prodCode').val(); // 선택된 제품코드
var pairCode = $('#prodCode').find(':selected').data('pair'); // 대응하는 인정제품 코드
var outworkplace = $('#outworkplace').val(); // 현장명
var user_name = $('#user_name').val(); // 작성자 이름
// console.log('savelotNum 전송전 prodCode' + $("#prodCode").val());
if (prodCode && pairCode) {
// 로트번호 자동생성 체크박스가 체크되어 있는지 확인
if ($('#createAutoCode').is(':checked')) {
$.ajax({
url: 'lotnum_generator.php',
method: 'POST', // POST 방식으로 전달
data: {
prodCode: prodCode,
pairCode: pairCode,
outworkplace: outworkplace,
user_name: user_name
},
dataType: 'json',
success: function(response) {
// 서버에서 받아온 데이터 (예: lotNum)
// console.log(response);
$('#lotNum').val(response.lotNum); // lotNum 필드 업데이트
saveData(); // 저장버튼 실행
},
error: function(jqxhr, status, error) {
// console.log("Error:", error); // 에러 로그 출력
alert("로트번호 생성 중 오류가 발생했습니다.");
}
});
} else {
var lotNum = 'KD-' + pairCode + '-';
if( $('#lotNum').val() == null || $('#lotNum').val() == '')
$('#lotNum').val(lotNum); // 축약된 형태로만 표시
saveData(); // 자동생성 체크가 안되었을 때도 저장 수행
}
} else {
saveData(); // 제품코드나 인정제품 코드가 없을 경우에도 저장 수행
}
}
</script>
<script>
function inputNumberFormat(input) {
input.value = input.value.replace(/\D/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function adjustTextareaHeight(textarea) {
textarea.style.height = 'auto';
textarea.style.height = (textarea.scrollHeight) + 'px';
}
$(document).ready(function() {
var $comment = $('#comment');
if ($comment.length) {
adjustTextareaHeight($comment[0]); // 초기 높이 조정
$comment.on('input', function() {
adjustTextareaHeight(this);
});
}
var $updatecomment = $('#updatecomment');
if ($updatecomment.length) {
adjustTextareaHeight($updatecomment[0]); // 초기 높이 조정
$updatecomment.on('input', function() {
adjustTextareaHeight(this);
});
}
});
$(document).ready(function() {
// Log 파일보기
$("#showlogBtn").click( function() {
var num = '<?php echo $num; ?>'
// table 이름을 넣어야 함
var workitem = 'output' ;
// 버튼 비활성화
var btn = $(this);
popupCenter("../Showlog.php?num=" + num + "&workitem=" + workitem , '로그기록', 500, 500);
btn.prop('disabled', false);
});
});
// 모달창 닫기
$(document).on('click', '.Modalclose', function(e) {
$("#telModal").modal("hide");
$("#outworkplaceModal").modal("hide");
$("#loadEstimateModal").modal("hide");
$("#loadEstimateModal_slat").modal("hide");
});
$(document).ready(function(){
$('#screenBtn').click(function() {
var num = $('#num').val();
window.location.href = "../make/write_form.php?mode=view&num=" + num;
});
$('#steelBtn').click(function() {
var num = $('#num').val();
var outdate = $('#outdate').val();
var indate = $('#indate').val();
var outworkplace = $('#outworkplace').val();
var receiver = $('#receiver').val();
var phone = $('#phone').val();
var outputplace = $('#outputplace').val();
var comment = $('#comment').val();
var orderman = $('#orderman').val();
window.location.href = "../egimake/write_form.php?mode=take&outputnum=" + num + "&outdate=" + outdate + "&indate=" + indate + "&outworkplace=" + outworkplace + "&receiver=" + receiver + "&phone=" + phone + "&outputplace=" + outputplace + "&comment=" + comment + "&orderman=" + orderman;
});
});
$(document).ready(function() {
var modeValue = $('#mode').val();
var screenSuValue = $('#screen_su').val();
var slatSuValue = $('#slat_su').val();
if (modeValue === 'view' && (!screenSuValue || parseInt(screenSuValue) <= 0)) {
$('#screen_order').hide();
}
if (modeValue === 'view' && (!slatSuValue || parseInt(slatSuValue) <= 0)) {
$('#slat_order').hide();
}
});
function slat_calculateRow(element) {
const row = element.closest('tr');
if (!row || (!row.closest('#slatTable') && !row.closest('#slat_unapprovedTable'))) return;
const cutwidthElement = row.querySelector('[name="cutwidth[]"]');
const cutheightElement = row.querySelector('[name="cutheight[]"]');
const numberElement = row.querySelector('[name="number[]"]');
const exititemElement = row.querySelector('[name="exititem[]"]');
const intervalnumElement = row.querySelector('[name="intervalnum[]"]');
const hingenumElement = row.querySelector('[name="hingenum[]"]');
const hingeElement = row.querySelector('[name="hinge[]"]');
const hingeDirectionElement = row.querySelector('[name="hinge_direction[]"]');
const memoElement = row.querySelector('[name="memo[]"]');
const width = cutwidthElement ? parseFloat(cutwidthElement.value.replace(/,/g,'')) || 0 : 0;
const height = cutheightElement ? parseFloat(cutheightElement.value.replace(/,/g,'')) || 0 : 0;
const number = numberElement ? parseFloat(numberElement.value.replace(/,/g,'')) || 0 : 0;
const exititem = exititemElement ? exititemElement.value : '0';
const intervalnum = intervalnumElement ? parseFloat(intervalnumElement.value.replace(/,/g,''))|| 0 : 0;
const hingenum = hingenumElement ? parseFloat(hingenumElement.value.replace(/,/g,'')) || 0 : 0;
const hinge = hingeElement ? hingeElement.value : '';
const hingeDirection= hingeDirectionElement ? hingeDirectionElement.value : '';
const memo = memoElement ? memoElement.value : '';
let comment = '';
if (exititem === '0') {
intervalnumElement.value = '';
hingenumElement.value = '';
comment = `${memo} 절단: ${width}x총H${height}x${Math.round(height/72+1)}(매), 수량: ${number}틀`;
}
else if (exititem === '1') {
comment = `${memo} 상바: ${width}x총H${height}x${Math.round(height/72+1)-29}(매), `+
`쪽바: ${Math.floor((width - (900 + hingenum))/2)}x${29*2*number}(매), `+
`비상문바: 900x29(매), 수량: ${number}틀 ${hinge}:${hingenum}`;
}
else if (exititem === '2' || exititem === '3') {
const i = width - hingenum - intervalnum - 900;
comment = `${memo} 상바: ${width}x총H${height}x${Math.round(height/72+1)-29}(매), `+
`1번 쪽바: ${intervalnum}x29(매), 2번 쪽바: ${i}x29(매), `+
`비상문바: 900x29(매), 수량: ${number}틀 ${hinge}:${hingenum}`;
}
// hinge 값이 있을 때만 마지막에 (hingeDirection) 추가
if (hinge) {
comment += ` (${hingeDirection})`;
}
// text2 업데이트
const text2Input = row.querySelector('.text2');
if (text2Input) {
text2Input.value = comment;
}
slat_updateTotals();
}
function slat_updateTotals() {
let totalslat = 0;
let totalslatM2 = 0;
$('#slatTable tr').each(function() {
const number = parseFloat($(this).find('[name="number[]"]').val()?.replace(/,/g, '') || 0) || 0;
const cutwidth = parseFloat($(this).find('[name="cutwidth[]"]').val()?.replace(/,/g, '') || 0) || 0;
const cutheight = parseFloat($(this).find('[name="cutheight[]"]').val()?.replace(/,/g, '') || 0) || 0;
totalslat += number;
totalslatM2 += (cutwidth * cutheight * number) / 1000000;
});
$('#total_slat').text(`총 수량: ${totalslat}`);
$('#total_slat_m2').text(`총 면적: ${totalslatM2.toFixed(1)} m²`);
}
$('#slatTable').on('input', 'input, select', function() {
slat_calculateRow(this);
}).on('change', 'select', function() {
slat_calculateRow(this);
});
slat_updateTotals();
// 철재작업지시서 추가
function addRow_slat(button, estimateData = {}) {
const table = document.getElementById('slatTable');
const newRow = document.createElement('tr');
const username = '<?php echo $user_name; ?>';
const mode = '<?php echo $mode; ?>';
if (!authorities.includes(username) || mode === 'view') return;
// estimateData 키명에 맞춰서
const floors = estimateData.col2 || '';
const text1 = estimateData.col3 || '';
const memo = estimateData.col4 || 'EGI 1.6T';
// 견적서에서 불러오는 위치와 비인정 철재에서 불러오는 위치가 다르다. 비인정은 5,6번이 제작치수임
var cutwidth, cutheight;
if (!Number(estimateData.col10) || !Number(estimateData.col11)) {
cutwidth = estimateData.col5 || '';
cutheight = estimateData.col6 || '';
} else {
cutwidth = estimateData.col10 || '';
cutheight = estimateData.col11 || '';
}
// // 견적서에서 불러오는 위치와 비인정 철재에서 불러오는 위치가 다르다.
// if(Number(estimateData.col5) && Number(estimateData.col6)) {
// const cutwidth = estimateData.col5 || '';
// const cutheight = estimateData.col6 || '';
// }
// else {
// const cutwidth = estimateData.col10 || '';
// const cutheight = estimateData.col11 || '';
// }
// const number = estimateData.col7 || '1';
const number = '1'; // 수량은 무조건 1로 세팅
const exititem = estimateData.exititem || '0';
const interval = estimateData.intervalnum || '';
const hinge = estimateData.hinge || '';
const hingenum = estimateData.hingenum || '';
const hingeDir = estimateData.hinge_direction || '(없음)';
const text2 = estimateData.text2 || '';
newRow.innerHTML = `
<td>${table.rows.length+1}</td>
<td><input type="text" class="form-control col2" name="floors[]" value="${floors}" placeholder="층" oninput="slat_calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control col3" name="text1[]" value="${text1}" placeholder="부호" oninput="slat_calculateRow(this)" autocomplete="off"></td>
<td>
<select class="form-control col4" name="memo[]" onchange="slat_calculateRow(this)">
<option ${memo==='EGI 1.6T'?'selected':''}>EGI 1.6T</option>
<option ${memo==='EGI 1.2T'?'selected':''}>EGI 1.2T</option>
</select>
</td>
<td><input type="text" class="form-control col5" name="cutwidth[]" value="${cutwidth}" placeholder="가로(W)" oninput="inputNumbers(this); slat_calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control col6" name="cutheight[]" value="${cutheight}" placeholder="세로(H)" oninput="inputNumbers(this); slat_calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control col7" name="number[]" value="${number}" placeholder="수량" oninput="inputNumbers(this); slat_calculateRow(this)" autocomplete="off"></td>
<td>
<select class="form-control exititem text-center" name="exititem[]" onchange="slat_calculateRow(this)">
<option value="0" ${exititem==='0'?'selected':''}>없음</option>
<option value="1" ${exititem==='1'?'selected':''}>중앙</option>
<option value="2" ${exititem==='2'?'selected':''}>좌측</option>
<option value="3" ${exititem==='3'?'selected':''}>우측</option>
</select>
</td>
<td><input type="text" class="form-control intervalnum" name="intervalnum[]" value="${interval}" placeholder="띄울치수" oninput="inputNumbers(this); slat_calculateRow(this)" autocomplete="off"></td>
<td>
<select class="form-control hinge" name="hinge[]" onchange="slat_calculateRow(this)">
<option value=""></option>
<option ${hinge==='승리'?'selected':''}>승리</option>
<option ${hinge==='태영'?'selected':''}>태영</option>
<option ${hinge==='굴비'?'selected':''}>굴비</option>
<option ${hinge==='대신'?'selected':''}>대신</option>
</select>
</td>
<td><input type="text" class="form-control hingenum" name="hingenum[]" value="${hingenum}" placeholder="힌지치수" readonly></td>
<td>
<select class="form-control hinge_direction" name="hinge_direction[]" onchange="slat_calculateRow(this)">
<option ${hingeDir==='(없음)'?'selected':''}>(없음)</option>
<option ${hingeDir==='정방향'?'selected':''}>정방향</option>
<option ${hingeDir==='역방향'?'selected':''}>역방향</option>
</select>
</td>
<td><input type="text" class="form-control text2" name="text2[]" style="font-size:11px!important;" value="${text2}" title="${text2}" readonly></td>
<td>
<span class="text-primary hover-pointer me-2" onclick="slat_copyRow(this)"><i class="bi bi-copy"></i></span>
<span class="text-success hover-pointer me-2" onclick="addRow_slat(this)">+</span>
<span class="text-danger hover-pointer" onclick="slat_removeRow(this)">-</span>
</td>
<td style="display:none;">
<input type="hidden" name="done_check[]" value="${estimateData.done_check||''}">
</td>
`;
if (button) table.insertBefore(newRow, button.closest('tr').nextSibling);
else table.appendChild(newRow);
slat_calculateRow(newRow);
slat_updateTotals();
}
function slat_copyRow(button) {
const row = button.closest('tr');
const newRow = row.cloneNode(true);
const table = document.getElementById('slatTable');
const username = '<?php echo $user_name; ?>';
const mode = '<?php echo $mode; ?>';
if (!authorities.includes(username) || mode == 'view')
return;
newRow.querySelectorAll('input, select').forEach(input => {
if (input.name === "done_check[]") {
input.value = row.querySelector(`[name="${input.name}"]`).value;
} else if (input.type === 'checkbox') {
input.checked = row.querySelector(`[name="${input.name}"]`).checked;
} else {
input.value = row.querySelector(`[name="${input.name}"]`).value;
}
});
// Update row number
newRow.querySelector('td').innerText = table.rows.length + 1;
if (button) {
table.insertBefore(newRow, row.nextSibling);
} else {
table.appendChild(newRow);
}
newRow.querySelectorAll('input, select').forEach(input => {
input.addEventListener('input', function() { slat_calculateRow(this); });
if (input.tagName.toLowerCase() === 'select') {
input.addEventListener('change', function() { slat_calculateRow(this); });
}
});
// Ensure totals are updated after row is copied
screen_updateTotals();
}
// 숫자만 입력 가능하도록 inputNumber 함수
$(document).on('input', '.inputNumber', function() {
this.value = this.value.replace(/[^0-9]/g, '');
});
// 비인정제품에 대한 처리
// 공통 유틸리티 함수
function toggleTableHeaderVisibility(tableBody) {
const table = tableBody.closest('table');
const thead = table.find('thead');
if (tableBody.find('tr').length === 0) {
thead.hide();
} else {
thead.show();
}
// console.log(tableBody.find('tr').length);
}
function updateSerialNumbers(tableBody) {
tableBody.find('tr').each(function(index) {
$(this).find('.serial-number').text(index + 1);
});
}
// 추가/삭제/복사 등 이벤트 바인딩
$(document).ready(function () {
// 각 + 버튼 클릭 시 해당 함수 실행
$('.add-row-screen-unapproved').on('click', function () {
alertToast('행추가');
addRowUA_screen($('#screen_unapprovedListBody'));
});
$('.add-row-slat-unapproved').on('click', function () {
addRowUA_slat($('#slat_unapprovedListBody'));
alertToast('행추가');
});
$('.add-row-motor').on('click', function () {
addRowUA_motor($('#motor_listBody'));
alertToast('행추가');
});
$('.add-row-bend').on('click', function () {
addRowUA_bend($('#bend_listBody'));
alertToast('행추가');
});
$('.add-row-controller').on('click', function () {
addRowUA_controller($('#controller_listBody'));
alertToast('행추가');
});
$('.add-row-etc').on('click', function () {
addRowUA_etc($('#etc_listBody'));
alertToast('행추가');
});
});
// 추가 이벤트 바인딩
$(document).on('click', '.add-row-generic', function() {
const tableBody = $(this).closest('tbody');
const currentRow = $(this).closest('tr');
const tableId = tableBody.attr('id');
if (tableId.includes('screen')) addRowUA_screen(tableBody, currentRow);
else if (tableId.includes('slat')) addRowUA_slat(tableBody, currentRow);
else if (tableId.includes('motor')) addRowUA_motor(tableBody, currentRow);
else if (tableId.includes('bend')) addRowUA_bend(tableBody, currentRow);
else if (tableId.includes('controller')) addRowUA_controller(tableBody, currentRow);
else if (tableId.includes('etc')) addRowUA_etc(tableBody, currentRow);
else if (tableId.includes('account')) addRow_Account(tableBody, currentRow);
alertToast('행추가');
});
// 삭제 이벤트 바인딩
$(document).on('click', '.remove-row-generic', function() {
const tableBody = $(this).closest('tbody');
$(this).closest('tr').remove();
updateSerialNumbers(tableBody);
toggleTableHeaderVisibility(tableBody);
alertToast('행삭제');
});
// 복사 이벤트 바인딩
$(document).on('click', '.copy-row-generic', function () {
const tableBody = $(this).closest('tbody');
const currentRow = $(this).closest('tr');
const newRow = currentRow.clone();
// select 값 복원
newRow.find('select').each(function (i) {
$(this).val( currentRow.find('select').eq(i).val() );
});
// 현재 행 바로 아래에 삽입
currentRow.after(newRow);
updateSerialNumbers(tableBody);
toggleTableHeaderVisibility(tableBody);
alertToast('행복사');
});
// 테이블 thead 표시 여부 조절
$(document).ready(function () {
toggleTableHeaderVisibility($('#screen_unapprovedListBody'));
toggleTableHeaderVisibility($('#slat_unapprovedListBody'));
toggleTableHeaderVisibility($('#motor_listBody'));
toggleTableHeaderVisibility($('#bend_listBody'));
toggleTableHeaderVisibility($('#controller_listBody'));
toggleTableHeaderVisibility($('#etc_listBody'));
});
// 배송관련 동적행 추가
function addRow_deliveryfee(tableBody, rowData = {}) {
// rowData.col1 ~ col11에 담긴 값이 있으면 사용, 없으면 빈 문자열
var col10Val = rowData.col10 || ''; // 하차업체명
var col9Val = rowData.col9 || ''; // 상차지
var col1Val = rowData.col1 || ''; // 물류업체명
var col2Val = rowData.col2 || ''; // 차량톤수
var col3Val = rowData.col3 || ''; // 금액
var col4Val = rowData.col4 || ''; // 부가세
var col5Val = rowData.col5 || ''; // 합계
var col6Val = rowData.col6 || ''; // 착불/선불
var col7Val = rowData.col7 || ''; // 차량번호
var col8Val = rowData.col8 || ''; // 기사연락처
var col11Val = rowData.col11 || ''; // 비고
// 물류업체명 select 옵션
var deliveryCompanyOptions = ['25시물류','조운물류'];
// 차량톤수 select 옵션
var tonOptions = ['1','1.4','0.5','2.5','3.5','5','오토바이'];
// 착불/선불 select 옵션
var payTypeOptions = ['착불','선불'];
// 3자리 콤마 찍는 헬퍼 함수
function formatNumber(num) {
if (isNaN(num) || num === null) return '';
// 소수점 이하 처리 여부는 필요에 따라 수정(현재 정수·소수 모두 콤마 가능)
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// 새 행 생성
var newRow = $('<tr>');
// (1) 첫 번째 열: + / - 버튼
newRow.append(
'<td class="text-center" style="width:5%;">' +
'<div class="d-flex justify-content-center align-items-center">' +
'<button type="button" class="btn btn-outline-dark btn-sm viewNoBtn add-row-deliveryfee me-1" style="border:0px;" ' +
'data-table="' + tableBody.closest("table").attr("id") + '">+</button>' +
'<button type="button" class="btn btn-outline-danger btn-sm viewNoBtn remove-row-deliveryfee" style="border:0px;">-</button>' +
'</div>' +
'</td>'
);
// (11) 하차업체명 (col10) - 문자 입력
newRow.append(
'<td class="text-center" style="width:12%;">' +
'<input type="text" name="col10[]" class="form-control text-center" '
+ 'value="' + col10Val + '" autocomplete="off">' +
'</td>'
);
// (10) 상차지 (col9) - 문자 입력
newRow.append(
'<td class="text-center" style="width:12%;">' +
'<input type="text" name="col9[]" class="form-control text-center" '
+ 'value="' + col9Val + '" autocomplete="off">' +
'</td>'
);
// (2) 물류업체명 (col1) - select
var col1Html = '<select name="col1[]" class="form-select w-auto viewNoBtn text-center" style="font-size:0.8rem;" autocomplete="off">';
col1Html += '<option value="">선택</option>';
$.each(deliveryCompanyOptions, function(index, item) {
var selected = (item === col1Val) ? ' selected' : '';
col1Html += '<option value="'+ item + '"' + selected + '>' + item + '</option>';
});
col1Html += '</select>';
newRow.append('<td class="text-center" style="width:6%;">' + col1Html + '</td>');
// // (3) 차량톤수 (col2) - select
// var col2Html = '<select name="col2[]" class="form-control viewNoBtn text-center" autocomplete="off">';
// col2Html += '<option value="">선택</option>';
// $.each(tonOptions, function(index, item) {
// var selected = (item === col2Val) ? ' selected' : '';
// col2Html += '<option value="'+ item + '"' + selected + '>' + item + '</option>';
// });
// col2Html += '</select>';
// newRow.append('<td class="text-center" style="width:6%;">' + col2Html + '</td>');
// (3) 차량톤수 (col2) - input 요소로 변경
newRow.append(
'<td class="text-center" style="width:6%;">' +
'<input type="text" name="col2[]" class="form-control text-center" ' +
'value="' + col2Val + '" autocomplete="off">' +
'</td>'
);
// (4) 금액 (col3) - input, 숫자만 입력하도록 inputNumber 클래스 사용
newRow.append(
'<td class="text-center" style="width:5%;">' +
'<input type="text" name="col3[]" class="form-control text-center " '
+ 'value="' + col3Val + '" autocomplete="off">' +
'</td>'
);
// (5) 부가세 (col4) - input(자동계산), 금액 * 10%, 읽기 전용
newRow.append(
'<td class="text-center" style="width:5%;">' +
'<input type="text" name="col4[]" class="form-control text-center inputNumber" '
+ 'value="' + col4Val + '" autocomplete="off" readonly>' +
'</td>'
);
// (6) 합계 (col5) - input(자동계산), 금액 + 부가세, 읽기 전용
newRow.append(
'<td class="text-center" style="width:5%;">' +
'<input type="text" name="col5[]" class="form-control text-center inputNumber" '
+ 'value="' + col5Val + '" autocomplete="off" readonly>' +
'</td>'
);
// (7) 착불/선불 (col6) - select
var col6Html = '<select name="col6[]" class="form-select w-auto viewNoBtn text-center" style="font-size:0.8rem;" autocomplete="off">';
col6Html += '<option value="">선택</option>';
$.each(payTypeOptions, function(index, item) {
var selected = (item === col6Val) ? ' selected' : '';
col6Html += '<option value="'+ item + '"' + selected + '>' + item + '</option>';
});
col6Html += '</select>';
newRow.append('<td class="text-center" style="width:6%;">' + col6Html + '</td>');
// (8) 차량번호 (col7) - 문자 입력
newRow.append(
'<td class="text-center" style="width:10%;">' +
'<input type="text" name="col7[]" class="form-control text-center" '
+ 'value="' + col7Val + '" autocomplete="off">' +
'</td>'
);
// (9) 기사 연락처 (col8) - 예) 010-5555-4444 형태
newRow.append(
'<td class="text-center" style="width:12%;">' +
'<input type="text" name="col8[]" class="form-control text-center" '
+ 'value="' + col8Val + '" autocomplete="off">' +
'</td>'
);
// (12) 비고 (col11) - 문자 입력
newRow.append(
'<td class="text-center" style="width:15%;">' +
'<input type="text" name="col11[]" class="form-control text-start" '
+ 'value="' + col11Val + '" autocomplete="off">' +
'</td>'
);
// 행을 테이블에 추가
tableBody.append(newRow);
// 금액(col3) 입력 시 => 부가세(col4), 합계(col5) 자동 계산, 3자리 콤마 처리
newRow.find('input[name="col3[]"]').on('input', function() {
var $input = $(this);
var $row = $input.closest('tr');
// 1) 사용자가 입력한 금액에서 쉼표 제거 후 숫자 파싱
var rawAmount = $input.val().replace(/,/g, '');
var amount = parseFloat(rawAmount) || 0;
// 2) 부가세 10% 계산 및 합계
var vat = Math.round(amount * 0.1);
var total = amount + vat;
// 3) 금액 자체에도 3자리 콤마 적용 (사용자 입력창에 실시간 표시)
$input.val(formatNumber(amount));
// 4) 부가세(col4), 합계(col5)도 콤마 적용
$row.find('input[name="col4[]"]').val(formatNumber(vat));
$row.find('input[name="col5[]"]').val(formatNumber(total));
});
// 만약 rowData.col3에 기존 값이 있었다면, 초기 상태에서도 부가세/합계가 계산되도록 트리거
if (col3Val) {
newRow.find('input[name="col3[]"]').trigger('input');
}
toggleTableHeaderVisibility(tableBody);
// 모드가 'view'인 경우 disable 처리 (기존 코드 유지)
var mode = '<?php echo $mode; ?>';
if (mode === 'view') {
disableView();
}
}
// 배송관련 이벤트 및 각종 처리
$(document).ready(function() {
var encodedVal = $('#deliveryfeeList').val(); // 인코딩된 JSON 문자열
// console.log('encodedVal : ', encodedVal);
// encodedVal이 존재하고, 공백이 아니라면 시도
if (encodedVal && encodedVal.trim() !== '') {
try {
// 1) decodeURIComponent()로 원래 문자열 복원
var decodedVal = decodeURIComponent(encodedVal);
// 2) 한 번 parse
var temp = JSON.parse(decodedVal);
// 3) 이중 인코딩 경우 => 다시 parse
if (typeof temp === 'string') {
temp = JSON.parse(temp);
}
// 4) 배열이면 forEach로 addRow
if (Array.isArray(temp)) {
temp.forEach(function(rowData) {
addRow_deliveryfee($('#deliveryfeeTableBody'), rowData);
});
}
} catch (e) {
// 여기서 에러 처리: 로그 찍거나, 경고 메시지 표시 등
console.error('Invalid or empty JSON in #deliveryfeeList:', e);
}
}
// 이후 +, - 버튼 이벤트 등 기존 로직
$('#deliveryfeeTableBody').on('click', '.remove-row-deliveryfee', function() {
$(this).closest('tr').remove();
});
// 이후 +, - 버튼 이벤트 등 기존 로직
$('#deliveryfeeTableBody').on('click', '.add-row-deliveryfee', function() {
addRow_deliveryfee($('#deliveryfeeTableBody'));
});
$('.add-row-deliveryfee').on('click', function() {
addRow_deliveryfee($('#deliveryfeeTableBody'));
});
});
function slat_removeRow(button) {
const username = '<?php echo $user_name; ?>';
const mode = '<?php echo $mode; ?>';
if (!authorities.includes(username) || mode == 'view')
return;
const row = button.closest('tr');
row.remove();
// Update row numbers
const rows = document.querySelectorAll('#slatTable tr');
rows.forEach((row, index) => {
row.cells[0].innerText = index + 1;
});
slat_updateTotals();
}
function slat_updateTotals() {
const rows = document.querySelectorAll('#slatTable tr');
let totalslat = 0;
let totalslatM2 = 0;
rows.forEach(row => {
const number = parseFloat(row.querySelector('[name="number[]"]').value.replace(/,/g, '')) || 0;
const cutwidth = parseFloat(row.querySelector('[name="cutwidth[]"]').value.replace(/,/g, '')) || 0;
const cutheight = parseFloat(row.querySelector('[name="cutheight[]"]').value.replace(/,/g, '')) || 0;
totalslat += number;
totalslatM2 += (cutwidth * cutheight * number) / 1000000;
});
document.getElementById('total_slat').textContent = `총 수량: ${totalslat}`;
document.getElementById('total_slat_m2').textContent = `총 면적: ${totalslatM2.toFixed(1)} m²`;
}
document.querySelectorAll('input, select').forEach(input => {
input.addEventListener('input', function() { slat_calculateRow(this); });
if (input.tagName.toLowerCase() === 'select') {
input.addEventListener('change', function() { slat_calculateRow(this); });
}
});
slat_updateTotals();
$(document).ready(function() {
$(document).on('change', 'select[name="hinge[]"]', function() {
var selectedHinge = $(this).val();
var hingenumValue = 0;
switch (selectedHinge) {
case '승리':
hingenumValue = "85";
break;
case '태영':
hingenumValue = "70";
break;
case '굴비':
hingenumValue = "60";
break;
case '대신':
hingenumValue = "50";
break;
}
$(this).closest('tr').find('input.hingenum').val(hingenumValue);
// Delay the calculation to ensure the hinge number is updated
setTimeout(() => {
slat_calculateRow(this);
}, 500);
});
// Trigger change event to set the value on page load if a hinge is already selected
$('select[name="hinge[]"]').trigger('change');
});
function phonebookBtn(searchfield)
{
var search = $("#" + searchfield).val();
href = '../phonebook/list.php?search=' + search ;
popupCenter(href, '전화번호 검색', 1600, 800);
}
function acigroupBtn()
{
var num = $("#num" ).val();
var search = $("#outworkplace").val();
href = '../acigroup/list.php?searchItem=group&search=' + search ;
popupCenter(href, '', 1600, 800);
}
</script>
<!-- mode == 'view' 조회 화면일때 사용금지 시키는 구문 -->
<script>
$(document).ready(function() {
// 견적서 불러오기 버튼 클릭 시
$(document).on('click', '#loadEstimateBtn', function() {
$("#loadEstimateModal").modal("show"); // 모달창 띄우기
var search = $('#secondord').val(); // #secondord 발주처 입력값을 검색어로 사용
// 약간의 시간차를 두고 검색 버튼 클릭을 자동으로 트리거
$('#searchEstimate').val(search);
setTimeout(function() {
estimate_search(search,'스크린');
}, 800); // 0.5초 후에 트리거 (필요에 따라 시간을 조정할 수 있습니다)
});
// 스크린 발주서 등록/수정 버튼 클릭 시
$(document).on('click', '#editOrderBtn', function() {
var num = $("#num").val(); // num 값만 전달
// 스크린 발주서(견적서의 내용 적용)
// estimateList 저장 로직
const screenData = collectEstimateListData('#estimateListTable');
// JSON 변환 후 hidden field에 대입
jsonString = JSON.stringify(screenData);
//console.log('jsonString : ' + jsonString);
// 현재 날짜와 시간으로 임시 키 생성
let tempKey = 'screen_' + new Date().toISOString().replace(/[-:.]/g, '');
// AJAX로 서버에 JSON 저장 요청
$.ajax({
url: 'save_json.php', // JSON 파일을 저장할 서버측 PHP 파일
type: 'POST',
data: {
jsonData: jsonString,
tempKey: tempKey
},
dataType: 'json',
success: function(response) {
if (response.success) {
// 1) 각 input 요소에서 값 읽어오기
const estimateSurang = $('#estimateSurang').val();
const EstimateFirstSum = $('#EstimateFirstSum').val();
const EstimateUpdatetSum = $('#EstimateUpdatetSum').val();
const EstimateDiffer = $('#EstimateDiffer').val();
const estimateTotal = $('#estimateTotal').val();
const EstimateDiscountRate = $('#EstimateDiscountRate').val();
const EstimateDiscount = $('#EstimateDiscount').val();
const EstimateFinalSum = $('#EstimateFinalSum').val();
const makeWidth = $('#makeWidth').val();
const makeHeight = $('#makeHeight').val();
const maguriWing = $('#maguriWing').val();
const inspectionFee = $('#inspectionFee').val();
// 체크박스 상태 전달
const steelChecked = ($("#steel").prop('checked')) ? 'checked' : '' ; // 절곡체크가 steel 임.
const motorChecked = ($("#motor").prop('checked')) ? 'checked' : ''; // 모터가 들어가는지 체크
const warrantyChecked = ($("#warranty").prop('checked')) ? 'checked' : ''; // 인정제품인지 체크
const slatChecked = ($("#slatcheck").prop('checked')) ? 'checked' : ''; // 주자재(스크린,철재) 체크
const partsChecked = ($("#partscheck").prop('checked')) ? 'checked' : ''; // 부자재 체크
// 2) 쿼리 스트링 객체로 만들기
const params = {
num: num,
tempKey: tempKey,
mode: 'edit',
itemoption:'screen',
estimateSurang,
EstimateFirstSum,
EstimateUpdatetSum,
EstimateDiffer,
estimateTotal,
EstimateDiscountRate,
EstimateDiscount,
EstimateFinalSum,
makeWidth,
makeHeight,
maguriWing,
inspectionFee,
steelChecked, // 체크박스 상태 전달
motorChecked,
warrantyChecked,
slatChecked,
partsChecked
};
// 3) $.param 으로 직렬화한 뒤 URL 생성
const url = '/estimate/write_form.php?' + $.param(params);
// 4) 팝업 열기
customPopup(url, '발주서 등록/수정', 1900, 900);
} else {
alert('JSON 저장에 실패했습니다. 다시 시도해 주세요.');
}
},
error: function(jqXHR, textStatus, errorThrown) {
// 오류를 콘솔에 출력
console.log('AJAX 요청 실패');
console.log('상태 코드:', jqXHR.status); // HTTP 상태 코드 (e.g., 404, 500)
console.log('응답 텍스트:', jqXHR.responseText); // 서버에서 반환된 오류 메시지
console.log('오류 상태:', textStatus); // 오류 상태 (e.g., "timeout", "error")
console.log('오류 메시지:', errorThrown); // 오류 메시지 (e.g., "Internal Server Error")
alert('서버와의 통신에 실패했습니다.');
}
});
});
// 스크린 견적서 보기 버튼 클릭 시
$(document).on('click', '#ViewEstimateBtn', function() {
var num = $("#estimate_num").val();
if (!num || num === '0') {
Swal.fire({
icon: 'warning',
title: '알림',
text: '견적을 불러온 기록이 없습니다.'
});
return;
}
var tablename = "estimate";
// URL에 변수를 추가
var url = '/estimate/write_form.php?mode=view' + '&num=' + num + "&tablename=" + tablename;
customPopup(url, '견적서', 1850, 900);
});
// 스크린 발주서 보기 버튼 클릭 시
$(document).on('click', '#loadOrderBtn', function() {
var num = $("#num").val();
var url = '/output/viewOrder.php?num=' + num ;
customPopup(url, '발주서', 800, 900);
});
// 스크린작업일지 버튼 클릭 시
$(document).on('click', '#loadScreenWorkBtn', function() {
var num = $("#num").val();
var url = '/output/viewScreenWork.php?num=' + num ;
customPopup(url, '스크린작업일지', 800, 900);
});
// 스크린 절곡 작업일지 버튼 클릭 시
$(document).on('click', '#loadBendingWorkBtn', function() {
var num = $("#num").val();
var url = '/output/viewBendingWork.php?num=' + num ;
customPopup(url, '절곡작업일지', 800, 900);
});
// 스크린 출고증 버튼 클릭 시
$(document).on('click', '#loadOutputWorkBtn', function() {
var num = $("#num").val();
var url = '/output/viewOutput.php?num=' + num ;
customPopup(url, '출고증', 800, 900);
});
// 스크린 납품확인서 버튼 클릭 시
$(document).on('click', '#loadConfirmBtn', function() {
var num = $("#num").val();
var url = '/output/viewConfirm.php?num=' + num ;
customPopup(url, '납품확인서', 800, 900);
});
// 스크린-중간검사 버튼 클릭 시
$(document).on('click', '#loadmidInspectScreenBtn', function() {
var num = $("#num").val();
var url = '/output/viewMidInspectScreen.php?num=' + num ;
customPopup(url, '스크린-중간검사', 800, 900);
});
// 스크린 절곡-중간검사 버튼 클릭 시
$(document).on('click', '#loadmidInspectBendingBtn', function() {
var num = $("#num").val();
var url = '/output/viewMidInspectBending.php?num=' + num ;
customPopup(url, '절곡-중간검사', 800, 900);
});
// 비인정 관련 버튼 이벤트 처리
// 비인정 발주서 보기 버튼 클릭 시
$(document).on('click', '#loadOrderBtn_UA', function() {
var num = $("#num").val();
var url = '/output/viewOrder_UA.php?num=' + num ;
customPopup(url, '발주서', 800, 900);
});
// 비인정 스크린작업일지 버튼 클릭 시
$(document).on('click', '#loadScreenWorkBtn_UA', function() {
var num = $("#num").val();
var url = '/output/viewScreenWork_UA.php?num=' + num ;
customPopup(url, '스크린작업일지', 800, 900);
});
// 비인정 철재작업일지 버튼 클릭 시
$(document).on('click', '#loadSlatWorkBtn_UA', function() {
var num = $("#num").val();
var url = '/output/viewSlatWork_UA.php?num=' + num ;
customPopup(url, '철재작업일지', 800, 900);
});
// 비인정 절곡 작업일지 버튼 클릭 시
$(document).on('click', '#loadBendingWorkBtn_UA', function() {
var num = $("#num").val();
var url = '/output/viewBendingWork_UA.php?num=' + num ;
customPopup(url, '절곡작업일지', 800, 900);
});
// 비인정 출고증 버튼 클릭 시
$(document).on('click', '#loadOutputWorkBtn_UA', function() {
var num = $("#num").val();
var url = '/output/viewOutput_UA.php?num=' + num ;
customPopup(url, '출고증', 800, 900);
});
// 비인정 납품확인서 버튼 클릭 시
$(document).on('click', '#loadConfirmBtn_UA', function() {
var num = $("#num").val();
var url = '/output/viewConfirm_UA.php?num=' + num ;
customPopup(url, '납품확인서', 800, 900);
});
// // 비인정 스크린-철재스라트 중간검사 버튼 클릭 시
// $(document).on('click', '#loadmidInspectScreenBtn_UA', function() {
// var num = $("#num").val();
// var url = '/output/viewMidInspectScreen.php?num=' + num ;
// customPopup(url, '스크린-중간검사', 800, 900);
// });
// // 비인정 절곡-중간검사 버튼 클릭 시
// $(document).on('click', '#loadmidInspectBendingBtn_UA', function() {
// var num = $("#num").val();
// var url = '/output/viewMidInspectBending.php?num=' + num ;
// customPopup(url, '절곡-중간검사', 800, 900);
// });
// 검색 버튼 클릭 시 (전역 바인딩, 중복 호출 방지)
$(document).off('click', '#searchEstimateBtn').on('click', '#searchEstimateBtn', function() {
var search = $('#searchEstimate').val();
// 스크린 검색
setTimeout(function() {
estimate_search(search, '스크린');
}, 800); // 0.5초 후에 트리거 (필요에 따라 시간을 조정할 수 있습니다)
});
// 모달창에서 스크린 견적서 검색
function estimate_search(search, whichItem) {
// 특정 모달의 ModalBody를 선택
var modalId = '#loadEstimateModal'; // 모달 ID 지정
var tbody = $(modalId).find('.ModalBody');
$.ajax({
url: 'fetch_estimate.php',
type: 'POST',
data: { search: search , whichItem: whichItem },
dataType: 'json',
success: function(data) {
// console.log("Response data:", data); // 서버로부터의 응답을 콘솔에 출력
tbody.empty(); // 기존 데이터를 지움
if (Array.isArray(data) && data.length > 0) {
data.forEach(function(row, index) {
var tr = $('<tr onclick="fetchEstimateDetails(\'' + row.num + '\');">').append(
$('<td>').addClass('text-center').text(index + 1),
$('<td>').addClass('text-center').text(row.indate), // 접수일
$('<td>').addClass('text-center').text(row.pjnum), // 견적번호
$('<td>').addClass('text-center').text(row.major_category), // 스크린/철재 구분
$('<td>').addClass('text-center').text(row.model_name), // 제품모델
$('<td>').addClass('text-center').text(row.secondord), // 발주처
$('<td>').addClass('text-start').text(row.outworkplace), // 현장명
$('<td>').addClass('text-end').text(row.estimateTotal ? Number(row.estimateTotal).toLocaleString() : ''), // 금액
$('<td>').addClass('text-center').text(row.estimateSurang ? Number(row.estimateSurang).toLocaleString() : ''), // 수량
$('<td>').addClass('text-center').text(row.orderman) // 담당자
);
tbody.append(tr);
});
} else if (data.length === 0) {
var tr = $('<tr>').append(
$('<td>').attr('colspan', '7').addClass('text-center').text('검색된 데이터가 없습니다.')
);
tbody.append(tr);
} else {
console.error('Unexpected data format:', data);
var tr = $('<tr>').append(
$('<td>').attr('colspan', '7').addClass('text-center').text('데이터를 불러오는 중 오류가 발생했습니다.')
);
tbody.append(tr);
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('AJAX request failed:', textStatus, errorThrown);
var tr = $('<tr>').append(
$('<td>').attr('colspan', '7').addClass('text-center').text('데이터를 불러오는 중 오류가 발생했습니다.')
);
tbody.append(tr);
}
});
}
});
function EstimateSearchEnter(event) {
if (event.key === "Enter") {
// 검색 버튼 클릭을 트리거
const searchButton = document.getElementById('searchEstimateBtn');
if (searchButton) {
searchButton.click();
} else {
console.error('searchEstimateBtn element not found');
}
}
}
// 스크린 견적 상세 정보를 가져오는 AJAX 함수
function fetchEstimateDetails(estimateId) {
// console.log('estimateId' + estimateId);
$("#loadEstimateModal").modal("hide"); // 모달창 닫기
$("#estimate_screenDiv").show(); // 스크린탭 보이게 하기
$.ajax({
url: 'fetch_estimate_details.php', // 서버에서 데이터를 가져오는 경로
method: 'POST',
data: { estimateId: estimateId }, // 실제 전달된 estimateId 사용
dataType: 'json',
success: function(response) {
// Check if response is valid and contains necessary data
if (response && Array.isArray(response) && response.length > 0) {
const estimateData = response[0];
// console.log('estimateData' + estimateData);
// major_category 값을 확인하여 처리
if (estimateData.major_category === '스크린') {
// 스크린일 경우 estimateList 데이터를 숨겨진 필드에 넣음
document.getElementById('estimateList').value = estimateData.estimateList;
document.getElementById('estimateList_auto').value = estimateData.estimateList_auto;
} else if (estimateData.major_category === '철재') {
// 철재스라트일 경우 estimateSlatList 데이터를 숨겨진 필드에 넣음
document.getElementById('estimateSlatList').value = estimateData.estimateSlatList;
document.getElementById('estimateSlatList_auto').value = estimateData.estimateSlatList_auto;
}
// 견적서 외 주요 hidden input 값도 반영
$('#pjnum').val(estimateData.pjnum || '');
$('#major_category').val(estimateData.major_category || '');
$('#position').val(estimateData.position || '');
$('#makeWidth').val(estimateData.makeWidth || '');
$('#makeHeight').val(estimateData.makeHeight || '');
$('#secondord').val(estimateData.secondord || ''); // 발주처
$('#secondordman').val(estimateData.secondordman || ''); // 발주처
$('#secondordmantel').val(estimateData.secondordmantel || ''); // 발주처
$('#secondordnum').val(estimateData.secondordnum || ''); // 발주처 코드
$('#outworkplace').val(estimateData.outworkplace || ''); // 견적서 현장명
$('#estimate_num').val(estimateData.num || ''); // 견적서 코드
// 로트번호 생성 자동체크
$('#createAutoCode').prop('checked', true);
function formatNumber(value) {
return value && !isNaN(value) ? Number(value).toLocaleString() : '';
}
// 1) 수치(VAT 포함) 계산
const supplyPrice = Number(estimateData.estimateTotal) || 0;
const FirstSum = Number(estimateData.EstimateFirstSum) || 0;
const updateSum = Number(estimateData.EstimateUpdatetSum) || 0; // 수정금액
const withVAT = Math.round(supplyPrice * 1.1); // 소수점 없이 반올림
const withVAT_FirstSum = Math.round(FirstSum * 1.1); // 소수점 없이 반올림
const withVAT_updateSum = Math.round(updateSum * 1.1); // 소수점 없이 반올림
const differSum = withVAT_FirstSum - withVAT_updateSum;
$('#estimateTotal').val(formatNumber(withVAT));// VAT 포함으로 저장하기 견적은 공급가액임 최초저장금액도 적용함
$('#EstimateFirstSum').val(formatNumber(withVAT_FirstSum));
$('#EstimateUpdatetSum').val(formatNumber(withVAT_updateSum));
$('#EstimateDiffer').val(formatNumber(differSum));
$('#EstimateDiscountRate').val(estimateData.EstimateDiscountRate || '');
$('#EstimateDiscount').val(estimateData.EstimateDiscount || '');
$('#EstimateFinalSum').val(formatNumber(estimateData.EstimateFinalSum));
$('#maguriWing').val(estimateData.maguriWing || '');
// detailJson은 JSON 객체이므로 다시 문자열화해서 전달
$('#detailJson').val(estimateData.detailJson || '');
// 5가지 체크박스 상태 설정
$('#steel').prop('checked', estimateData.steel === '1');
$('#motor').prop('checked', estimateData.motor === '1');
$('#warranty').prop('checked', estimateData.warranty === '인정');
$('#slatcheck').prop('checked', estimateData.slatcheck === '1');
$('#partscheck').prop('checked', estimateData.partscheck === '1');
if (estimateData.warranty === '인정') {
$('#warranty').trigger('change');
}
// console.log('steel checkbox', estimateData.steel);
// console.log('motor checkbox', estimateData.motor);
// console.log('warranty checkbox', estimateData.warranty);
// console.log('slatcheck checkbox', estimateData.slatcheck);
// console.log('partscheck checkbox', estimateData.partscheck);
// estimateList를 모달창에서 보여주기 위해 추가
loadEstimateList(estimateData.estimateList, estimateData.estimateList_auto);
// 닫기 버튼
$(document).on('click', '.closeModal_Estimate', function() {
$("#selectEstimateModal").modal("hide"); // 모달창 띄우기
});
// 데이터를 렌더링하는 함수 호출
// renderEstimateData(estimateData);
} else {
console.error('Received invalid response data');
}
},
error: function(err) {
console.error('Error fetching data', err);
}
});
}
var fullEstimateList = []; // 전역 변수로 전체 estimateList 저장
// 스크린견적불러오기 estimateList 데이터를 모달창에 로드하고 선택한 항목을 처리하는 함수
function loadEstimateList(estimateList, estimateList_auto) {
// estimateList가 문자열로 전달된 경우 JSON 파싱
if (typeof estimateList === 'string' && estimateList !== '' && estimateList !== null && estimateList !== undefined && estimateList !== '[]' && estimateList !== '{}') {
try {
estimateList = JSON.parse(estimateList); // 문자열이면 JSON 배열로 변환
estimateList_auto = JSON.parse(estimateList_auto); // 문자열이면 JSON 배열로 변환
} catch (e) {
console.error('estimateList를 JSON으로 파싱하는 중 오류 발생:', e);
return;
}
}
// estimateList가 배열인지 확인
if (!Array.isArray(estimateList)) {
console.error('estimateList는 배열이어야 합니다. 받은 값:', estimateList);
return; // 배열이 아니면 함수 종료
}
fullEstimateList = estimateList; // 전역 변수에 전체 데이터를 저장
// console.log('estimateList 견적서 불러오기', estimateList);
var tbody = $('#estimateListBody');
tbody.empty(); // 기존 데이터를 지움
// 데이터를 반복하면서 각 행을 생성
estimateList.forEach(function(estimate, index) {
var tr = $('<tr>').append(
$('<td>').append(
// checkbox를 기본 checked 상태로 생성
$('<input type="checkbox" class="estimate-checkbox">')
.val(estimate.col1 ?? '')
.prop('checked', true)
),
$('<td>').text(estimate.col2 ?? ''), // col2
$('<td>').text(estimate.col3 ?? ''), // col3
$('<td>').text(estimate.col4 ?? ''), // col4
$('<td>').text(estimate.col5 ?? ''), // col5
$('<td>').text(estimate.col10 ?? ''), // col10
$('<td>').text(estimate.col11 ?? ''), // col11
$('<td>').text(estimate.col14 ?? '') // col14
);
tbody.append(tr);
});
// 모달창 띄우기
$('#selectEstimateModal').modal('show');
// 전체 선택 체크박스 체크
$('.selectAllEstimates').prop('checked', true);
// 전체 선택 체크박스 change 이벤트 추가
$('.selectAllEstimates').off('change').on('change', function() {
// 체크된 상태에 맞춰 하위 체크박스 일괄 토글
$('.estimate-checkbox').prop('checked', $(this).prop('checked'));
});
// 적용 버튼 클릭 시 선택된 항목 처리
$('#applySelectedEstimates').off('click').on('click', function() {
var selectedEstimateIds = [];
// 선택된 체크박스의 값을 배열로 수집
$('.estimate-checkbox:checked').each(function() {
selectedEstimateIds.push($(this).val());
});
if (selectedEstimateIds.length > 0) {
// 선택된 항목을 처리하는 함수 호출
processSelectedEstimates(selectedEstimateIds);
// 모달창 닫기
$('#selectEstimateModal').modal('hide');
} else {
alert('적용할 항목을 선택해주세요.');
}
});
}
// 스크린 견적서 선택된 항목을 처리하는 함수
function processSelectedEstimates(selectedEstimateIds) {
// 선택된 ID들에 해당하는 데이터를 전체 목록에서 필터링
const filteredEstimates = fullEstimateList.filter(function(estimate) {
return selectedEstimateIds.includes(estimate.col1); // col1이 고유번호
});
// console.log('필터링된 데이터:', filteredEstimates); // 필터링된 데이터 출력
// 선택된 자료의 col1을 1부터 시작하는 일렬번호로 재설정
filteredEstimates.forEach((estimate, index) => {
estimate.col1 = (index + 1).toString(); // 일렬번호를 1부터 설정
});
// console.log('forEach 후 데이터:', filteredEstimates); // 일렬번호 설정 후 출력
// 필터링된 데이터를 함수로 전달하여 화면에 표시
renderEstimateData({ estimateList: filteredEstimates }, 'adapt'); // 기록함
}
// 스크린 견적서 불러온 데이터 표시화면 write_form.php의 발주서 및 스크린작업지시서 적용 두가지 적용하는 함수
// adapt 적용시 이것을 부모창에서 실행함.
function renderEstimateData(data, reload = null) {
// Check if the data and estimateList exist and are valid JSON
if (data && data.estimateList) {
try {
// 이미 파싱된 JSON인지 확인하려면 try-catch 사용
if (typeof data.estimateList === 'string') {
estimateList = JSON.parse(data.estimateList); // 문자열이면 JSON 파싱
} else {
estimateList = data.estimateList; // 이미 파싱된 JSON일 경우 그대로 사용
}
const estimateDiv = document.getElementById('estimate_screenDiv');
estimateDiv.innerHTML = ''; // Clear previous content
const table = document.createElement('table');
table.className = 'table table-bordered';
table.id = 'estimateListTable';
// Create the table header (this can be expanded with your desired header structure)
const thead = document.createElement('thead');
let headerRow =
"<tr>" +
"<th rowspan='6' style='width: 150px ;'>일련<br>번호</th>" +
"<th rowspan='6' style='width: 150px ;'>층수</th>" +
"<th rowspan='6' style='width: 150px ;'>부호</th>" +
"<th rowspan='6' style='width: 200px ;'>제품명</th>" +
"<th rowspan='6' style='width: 150px ;'>종류</th>" +
"<th rowspan='4' colspan='2' style='width: 300px ;'>가이드레일</th>" +
"<th rowspan='4' colspan='2' style='width: 300px ;'>①오픈사이즈</th>" +
"<th rowspan='4' colspan='2'>②-1제작사이즈 <br> <span class='text-primary'> (스크린)</span></th>" +
"<th rowspan='4' colspan='2'>②-2제작사이즈 <br> <span class='text-danger'> (부자재)</span></th>" +
"<th rowspan='6' style='width: 150px ;'>③면적</th>" +
"<th rowspan='6' style='width: 150px ;'>④중량</th>" +
"<th rowspan='6' style='width: 150px ;'>셔터<br>수량</th>" +
"<th rowspan='4' colspan='3' >연동제어기</th>" +
"<th rowspan='2' colspan='7' >⑤모터</th>" +
"<th rowspan='1' colspan='36' >절곡</th>" +
"<th rowspan='1' colspan='14' style='width: 500px ;' >부자재</th>" +
"</tr>" +
"<tr>" +
"<th rowspan='2' colspan='13' >⑥가이드레일(한쌍)</th>" +
"<th rowspan='2' colspan='13' >⑦케이스(셔터박스)</th>" +
"<th rowspan='2' colspan='10' >⑧하단마감재</th>" +
"<th rowspan='2' colspan='8' >⑨감기샤프트</th>" +
"<th rowspan='2' colspan='4' >⑩각파이프</th>" +
"<th rowspan='4' >⑪환봉</th>" +
"<th rowspan='4' >⑫앵글</th>" +
"</tr>" +
"<tr>" +
"<th rowspan='4' > <span class='text-primary'> 모터 견적가 포함</span> </th>" +
"<th rowspan='4' >전원</th>" +
"<th rowspan='4' >유/무선</th>" +
"<th rowspan='4' >용량</th>" +
"<th rowspan='2' colspan='3'>브라케트</th>" +
"</tr>" +
"<tr>" +
"<th rowspan='1' colspan='6' >마감/보강재</th>" +
"<th rowspan='3' >하부base1</th>" +
"<th rowspan='3' >하부base2</th>" +
"<th colspan='5' >레일용 연기차단재</th>" +
"<th colspan='12' >케이스</th>" +
"<th >케이스용<br>연기차단재</th>" +
"<th colspan='3' >하장바</th>" +
"<th colspan='3' >엘바</th>" +
"<th colspan='3' >보강평철</th>" +
"<th >무게평철</th>" +
"<th rowspan='3' >인치</th>" +
"<th colspan='7' >원형파이프</th>" +
"<th rowspan='2' colspan='4' >50*30*1.4T</th>" +
"</tr>" +
"<tr>" +
"<th rowspan='2' >설치유형</th>" +
"<th rowspan='2' >마감유형</th>" +
"<th rowspan='2' >가로</th>" +
"<th rowspan='2' >높이</th>" +
"<th rowspan='2' >가로</th>" +
"<th rowspan='2' >높이</th>" +
"<th rowspan='2' >가로</th>" +
"<th rowspan='2' >높이</th>" +
"<th rowspan='2' >매립</th>" +
"<th rowspan='2' >노출</th>" +
"<th rowspan='2' >매립형<br>뒷박스</th>" +
"<th rowspan='2' >가로*세로</th>" +
"<th rowspan='2' >사이즈</th>" +
"<th rowspan='2' >받침용<br>앵글</th>" +
"<th rowspan='2' >size</th>" +
"<th rowspan='2' >2438</th>" +
"<th rowspan='2' >3000</th>" +
"<th rowspan='2' >3500</th>" +
"<th rowspan='2' >4000</th>" +
"<th rowspan='2' >4300</th>" +
"<th colspan='5' >W50</th>" +
"<th colspan='8' >셔터박스</th>" +
"<th rowspan='1' >상부덮개</th>" +
"<th colspan='3' >마구리</th>" +
"<th rowspan='2' >W80</th>" +
"<th colspan='3' >60*40</th>" +
"<th colspan='3' >60*17</th>" +
"<th colspan='3' >50</th>" +
"<th >12T</th>" +
"<th style='width: 300px ;'> 연결 샤프트 </th>" +
"<th colspan='3' >4</th>" +
"<th colspan='3' >5</th>" +
"</tr>" +
"<tr>" +
"<th >2438</th>" +
"<th >3000</th>" +
"<th >3500</th>" +
"<th >4000</th>" +
"<th >4300</th>" +
"<th >규격 <br> (사이즈,전면밑,레일폭,점검구방향)</th>" +
"<th >size</th>" +
"<th >1219</th>" +
"<th >2438</th>" +
"<th >3000</th>" +
"<th >3500</th>" +
"<th >4000</th>" +
"<th >4150</th>" +
"<th >1219*389</th>" +
"<th >size</th>" +
"<th >날개</th>" +
"<th >수량</th>" +
"<th >size</th>" +
"<th >3000</th>" +
"<th >4000</th>" +
"<th >size</th>" +
"<th >3000</th>" +
"<th >4000</th>" +
"<th >size</th>" +
"<th >3000</th>" +
"<th >4000</th>" +
"<th >2000</th>" +
"<th >인치 &nbsp;&nbsp;&nbsp; / &nbsp;&nbsp; 길이 &nbsp;&nbsp; / &nbsp;&nbsp; 수량 </th>" +
"<th >3000</th>" +
"<th >4500</th>" +
"<th >6000</th>" +
"<th >6000</th>" +
"<th >7000</th>" +
"<th >8200</th>" +
"<th >보강</th>" +
"<th >size</th>" +
"<th >3000</th>" +
"<th >6000</th>" +
"<th >3000</th>" +
"<th >2500</th>" +
"</tr>";
const user_id = $("#user_id").val();
// console.log('user_id : ', user_id);
// 개발자 모드일 경우
if (user_id === 'pro') {
// ① 첫 번째 행: 컬럼명 라벨(col1 ~ col71), 특별 처리 포함
headerRow += "<tr>";
for (let i = 1; i <= 71; i++) {
if(i==10) {
headerRow += "<th class='text-primary'>col10_SW</th>";
headerRow += "<th class='text-primary'>col11_SH</th>";
headerRow += "<th class='text-primary'>col" + i + "</th>";
}
else if (i === 18) {
// 18번일 때는 brand, col18, wireless 3개
headerRow += "<th class='text-primary'>col18_brand</th>";
headerRow += "<th class='text-primary'>col18</th>";
headerRow += "<th class='text-primary'>col18_wireless</th>";
}
else if (i > 18) {
// 19~71번은 colN
headerRow += `<th class='text-primary'>col${i}</th>`;
// 45번일 때 wing 추가
if (i === 45) {
headerRow += "<th class='text-primary'>col45_wing</th>";
}
}
else {
// 1~17번
headerRow += `<th class='text-primary'>col${i}</th>`;
}
}
headerRow += "</tr>";
// ② 두 번째 행: 열 번호(1~74)
headerRow += "<tr>";
for (let i = 1; i <= 76; i++) {
headerRow += `<th class='text-success'>${i}</th>`;
}
headerRow += "</tr>";
}
thead.innerHTML = headerRow;
table.appendChild(thead);
const tbody = document.createElement('tbody');
// console.log(estimateList);
// Loop through estimateList rows and create table rows
// 스크린견적서 발주서로 변환 수량은 1이상일때 다중행을 만들어야 합니다. 수량은 1로 고정하고,
let surangArray = [15,16,17,24,25,26,27,28,31,32,33,34,35,38,39,40,41,42,43,44,46,47,49,50,52,53,55,56,57,60,61,62,63,64,65,68,69,70,71];
let rowCounter = 0; // 행 번호 초기화
estimateList.forEach((row) => {
// console.log('rowCounter : ', rowCounter);
// 수량이 1보다 큰 경우, 해당 수량만큼 행을 반복 생성
const quantity = parseInt(row['col14']) || 1;
// console.log('quantity : ', quantity);
for (let lpcounter = 0; lpcounter < quantity; lpcounter++) {
rowCounter++; // 행 번호 증가
const tr = document.createElement('tr');
for (let i = 1; i <= 71; i++) {
var td = document.createElement('td');
if(i ===10) {
td.className = 'w150px text-primary fw-bold col10_SW';
td.textContent = row['col10_SW'] || row['col10'] || '';
tr.appendChild(td);
td = document.createElement('td');
td.className = 'w150px text-primary fw-bold col11_SH';
td.textContent = row['col11_SH'] || row['col11'] || ''; // 우선순위가 있다
tr.appendChild(td);
td = document.createElement('td');
td.className = 'w150px col10';
td.textContent = row['col10'] || '';
tr.appendChild(td);
}
else if (i === 36 && row['col36'] !== 'custom') {
console.log('row[col36] : ', row['col36']);
console.log('row[col36_frontbottom] : ', row['col36_frontbottom']);
console.log('row[col36_railwidth] : ', row['col36_railwidth']);
console.log('row[col36_boxdirection] : ', row['col36_boxdirection']);
const colNameCustom = 'col36' ; // 정상적인 컬럼
const colNameFrontBottom = 'col36_frontbottom';
const colNameRailWidth = 'col36_railwidth';
const colNameBoxDirection = 'col36_boxdirection';
td.className = 'w300px';
// Combine all relevant values into a single string
const customValue = row[colNameCustom] || ''; // Custom value for col36
const frontBottomValue = row[colNameFrontBottom] || '50'; // Default to 50
const railWidthValue = row[colNameRailWidth] || '70'; // Default to 70
const boxDirectionValue = row[colNameBoxDirection] || ''; // Default is empty
// Display all values
td.textContent = `${customValue}, ${frontBottomValue}, ${railWidthValue}, ${boxDirectionValue}`;
}
else if (i === 36 && row['col36'] === 'custom') {
console.log('row[col36_custom] : ', row['col36_custom']);
console.log('row[col36_frontbottom] : ', row['col36_frontbottom']);
console.log('row[col36_railwidth] : ', row['col36_railwidth']);
console.log('row[col36_boxdirection] : ', row['col36_boxdirection']);
const colNameCustom = 'col36_custom' ;
const colNameFrontBottom = 'col36_frontbottom';
const colNameRailWidth = 'col36_railwidth';
const colNameBoxDirection = 'col36_boxdirection';
td.className = 'w300px';
// Combine all relevant values into a single string
const customValue = row[colNameCustom] || ''; // Custom value for col36
const frontBottomValue = row[colNameFrontBottom] || '50'; // Default to 50
const railWidthValue = row[colNameRailWidth] || '70'; // Default to 70
const boxDirectionValue = row[colNameBoxDirection] || ''; // Default is empty
// Display all values
td.textContent = `${customValue}, ${frontBottomValue}, ${railWidthValue}, ${boxDirectionValue}`;
}
else if (i === 18) {
var colName = 'col' + i + '_brand';
td.className = 'w150px';
td.textContent = row[colName] || ''; // Check if the column exists
tr.appendChild(td);
td = document.createElement('td');
colName = 'col' + i;
td.className = 'w100px';
td.textContent = row[colName] || ''; // Check if the column exists
tr.appendChild(td);
td = document.createElement('td');
colName = 'col' + i + '_wireless';
td.textContent = row[colName] || ''; // Check if the column exists
}
else if (i === 45) {
colName = 'col' + i ;
td.className = 'w100px';
td.textContent = row[colName] || ''; // Check if the column exists
tr.appendChild(td);
td = document.createElement('td');
colName = 'col' + i + '_wing'; // 마구리 날개 컬럼 추가
td.className = 'w100px';
td.textContent = row[colName] || ''; // Check if the column exists
tr.appendChild(td);
}
else if (i === 59) {
const col59Value = row['col59']/quantity || '1'; // 수량
const col59Inch = row['col59_inch'] || '2인치';
const col59Length = row['col59_length'] || '300';
const selectHtml = '<select name="col' + i + '_inch[]" style="font-size:0.7rem; height:30px;" disabled class="form-select w-auto text-center viewmode me-2 col-select col' + i + '-inch-select">' +
'<option value="2인치"' + (col59Inch === '2인치' ? ' selected' : '') + '>2인치</option>' +
'<option value="3인치"' + (col59Inch === '3인치' ? ' selected' : '') + '>3인치</option>' +
'</select>';
const inputHtmlLength = '<input type="text" name="col' + i + '_length[]" class="form-control readonly text-center col' + i + '-length-input me-2" style="width:60px;" ' +
'value="' + col59Length + '" placeholder="길이">';
const inputHtmlQty = '<input type="text" name="col' + i + '[]" class="form-control text-center readonly col59 col59-input col' + i + '-qty-input" style="width:60px;" ' +
'value="' + col59Value + '" placeholder="수량">';
td.className = 'text-center w300px';
td.innerHTML = '<div class="d-flex justify-content-center align-items-center">' +
selectHtml + inputHtmlLength + inputHtmlQty +
'</div>';
}
else
{
const colName = 'col' + i;
td.className = 'w100px ' + colName + ' ';
let value = row[colName];
if(i === 1 ) {
value = rowCounter;
}
if(i === 14) {
value = 1; // 수량 1로 고정
}
if(surangArray.includes(i)) {
value = value/quantity;
td.textContent = (value === 0 || value === '0') ? '': (value || '');
}
else {
td.textContent = (value === 0 || value === '0') ? '': (value || '');
}
}
// console.log('rowCounter : ', rowCounter);
$("#prodCode").val(row['col4']); // 제품코드 적용하기
$("#warrantyNum").val(searchWarrantyNumber(row['col4']));
tr.appendChild(td);
} // end of for
tbody.appendChild(tr);
} // end of for
});
table.appendChild(tbody);
// Sum columns that need to be summed
// col14, col15 의미함
const sumColumns = [14, 15, 16, 17, 24,25,26,27,28, 31, 32, 33, , 34, 35,38,39, 40, 41, 42, 43, 44, 46, 47, 49,50, 52, 53, 55, 56, 57, 59, 60,61,62, 63, 64, 65, 66, 68,69,70, 71 ];
const columnSums = calculateColumnSums(estimateList, sumColumns);
// Generate tfoot for sum
const tfoot = document.createElement('tfoot');
tfoot.className = 'table-secondary';
const footerRow = document.createElement('tr');
const footerTh = document.createElement('th');
footerTh.className = 'text-end';
footerTh.setAttribute('colspan', '15');
footerTh.textContent = '합계';
footerRow.appendChild(footerTh);
// Add empty cells or total cells based on sumColumns
for (let i = 14; i <= 71; i++) {
var td = document.createElement('th');
if (sumColumns.includes(i)) {
td.className = 'text-center';
const sumValue = columnSums[i];
// 0이면 빈 문자열, 정수면 그대로, 아니면 소수점 두자리까지 표시
td.textContent = (sumValue === 0) ? '' : (Number.isInteger(sumValue) ? sumValue : sumValue.toFixed(2));
} else {
td.className = 'text-center';
}
footerRow.appendChild(td);
if(i==20) {
td = document.createElement('th');
td.textContent = '';
footerRow.appendChild(td);
td = document.createElement('th');
td.textContent = '';
footerRow.appendChild(td);
}
if(i==45) {
td = document.createElement('th');
td.textContent = '';
footerRow.appendChild(td);
}
}
tfoot.appendChild(footerRow);
table.appendChild(tfoot);
estimateDiv.appendChild(table);
// 스크린 작업지시서 적용
if (reload !== null) {
addRowsFromEstimate(estimateList);
}
} catch (error) {
console.error("Error parsing JSON data: ", error);
alert("데이터를 처리하는 중 오류가 발생했습니다.");
}
} else {
console.error("Invalid or missing data.");
alert("유효한 데이터가 없습니다.");
}
}
// Function to calculate sum for specified columns
function calculateColumnSums(estimateList, sumColumns) {
const columnSums = {};
// Initialize the sums for each column in sumColumns
sumColumns.forEach((col) => {
columnSums[col] = 0;
});
// Loop through the rows in estimateList and calculate the sum for each column
estimateList.forEach((row) => {
sumColumns.forEach((col) => {
const colName = `col${col}`;
const value = parseFloat(row[colName]) || 0; // Parse value or default to 0
columnSums[col] += value;
});
});
return columnSums;
}
</script>
<script>
// 철재 견적불러오기 등 버튼에 대한 처리부분
// 검색 버튼 클릭 시 (전역 바인딩)
$(document).on('click', '#searchEstimateBtn_slat', function() {
var search = $('#searchEstimate_slat').val();
setTimeout(function() {
estimate_search_slat(search, '철재');
}, 500); // 0.5초 후에 트리거 (필요에 따라 시간을 조정할 수 있습니다)
});
function estimate_search_slat(search, whichItem) {
// 특정 모달의 ModalBody를 선택
var modalId = '#loadEstimateModal_slat'; // 모달 ID 지정
var tbody = $(modalId).find('.ModalBody');
console.log("search data:", search);
console.log("whichItem data:", whichItem);
$.ajax({
url: 'fetch_estimate.php',
type: 'POST',
data: { search: search , whichItem: whichItem },
dataType: 'json',
success: function(data) {
console.log("Response fetch_estimate.php data:", data); // 서버로부터의 응답을 콘솔에 출력
tbody.empty(); // 기존 데이터를 지움
if (Array.isArray(data) && data.length > 0) {
data.forEach(function(row, index) {
var tr = $('<tr onclick="fetchEstimateDetails_slat(\'' + row.num + '\');">').append(
$('<td>').addClass('text-center').text(index + 1),
$('<td>').addClass('text-center').text(row.indate), // 접수일
$('<td>').addClass('text-center').text(row.pjnum), // 견적번호
$('<td>').addClass('text-center').text(row.major_category), // 스크린/철재 구분
$('<td>').addClass('text-center').text(row.model_name), // 제품모델
$('<td>').addClass('text-center').text(row.secondord), // 발주처
$('<td>').addClass('text-start').text(row.outworkplace), // 현장명
$('<td>').addClass('text-end').text(row.estimateTotal ? Number(row.estimateTotal).toLocaleString() : ''), // 금액
$('<td>').addClass('text-center').text(row.estimateSurang ? Number(row.estimateSurang).toLocaleString() : ''), // 수량
$('<td>').addClass('text-center').text(row.orderman) // 담당자
);
tbody.append(tr);
});
} else if (data.length === 0) {
var tr = $('<tr>').append(
$('<td>').attr('colspan', '7').addClass('text-center').text('검색된 데이터가 없습니다.')
);
tbody.append(tr);
} else {
console.error('Unexpected data format:', data);
var tr = $('<tr>').append(
$('<td>').attr('colspan', '7').addClass('text-center').text('데이터를 불러오는 중 오류가 발생했습니다.')
);
tbody.append(tr);
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.error('AJAX request failed:', textStatus, errorThrown);
var tr = $('<tr>').append(
$('<td>').attr('colspan', '7').addClass('text-center').text('데이터를 불러오는 중 오류가 발생했습니다.')
);
tbody.append(tr);
}
});
}
function EstimateSearchEnter_slat(event) {
if (event.key === "Enter") {
// 검색 버튼 클릭을 트리거
const searchButton = $('#searchEstimateBtn_slat'); // 클래스 사용
if (searchButton.length) {
searchButton.trigger('click'); // 버튼 클릭 트리거
} else {
console.error('.searchEstimateBtn element not found');
}
}
}
$(document).ready(function() {
// // 모달 열기 시 포커스 설정 및 aria-hidden 제거
// $('#loadEstimateModal').on('show.bs.modal', function () {
// $(this).removeAttr('aria-hidden'); // aria-hidden 제거
// });
// // 모달 닫기 시 aria-hidden 추가 및 포커스 복구
// $('#loadEstimateModal').on('hide.bs.modal', function () {
// $(this).attr('aria-hidden', 'true'); // aria-hidden 추가
// });
// // 모달 열기 시 포커스 설정 및 aria-hidden 제거
// $('#loadEstimateModal_slat').on('show.bs.modal', function () {
// $(this).removeAttr('aria-hidden'); // aria-hidden 제거
// });
// // 모달 닫기 시 aria-hidden 추가 및 포커스 복구
// $('#loadEstimateModal_slat').on('hide.bs.modal', function () {
// $(this).attr('aria-hidden', 'true'); // aria-hidden 추가
// });
// // 모달 열기 시 포커스 설정 및 aria-hidden 제거
// $('#selectEstimateModal').on('show.bs.modal', function () {
// $(this).removeAttr('aria-hidden'); // aria-hidden 제거
// });
// // 모달 닫기 시 aria-hidden 추가 및 포커스 복구
// $('#selectEstimateModal').on('hide.bs.modal', function () {
// $(this).attr('aria-hidden', 'true'); // aria-hidden 추가
// });
// 견적서 불러오기 버튼 클릭 시
$(document).on('click', '#loadEstimateBtn_slat', function() {
$("#loadEstimateModal_slat").modal("show"); // 모달창 띄우기
var search = $('#secondord').val(); // #secondord 발주처 입력값을 검색어로 사용
// 약간의 시간차를 두고 검색 버튼 클릭을 자동으로 트리거
$('#searchEstimate_slat').val(search);
setTimeout(function() {
estimate_search_slat(search,'철재');
}, 500); // 0.5초 후에 트리거 (필요에 따라 시간을 조정할 수 있습니다)
});
// 철재 발주서 등록/수정 버튼 클릭 시
$(document).on('click', '#editOrderBtn_slat', function() {
const num = $("#num").val();
// 철재 발주서 데이터 수집
const slatData = collectEstimateListData_Slat('#estimateSlatListTable');
const jsonString = JSON.stringify(slatData);
// 현재 날짜와 시간으로 임시 키 생성
const tempKey = 'slat_' + new Date().toISOString().replace(/[-:.]/g, '');
// AJAX로 서버에 JSON 저장 요청
$.ajax({
url: 'save_json.php',
type: 'POST',
data: {
jsonData: jsonString,
tempKey: tempKey
},
dataType: 'json',
success: function(response) {
if (response.success) {
// 1) 각 input 요소에서 값 읽어오기
const estimateSurang = $('#estimateSurang').val();
const EstimateFirstSum = $('#EstimateFirstSum').val();
const EstimateUpdatetSum = $('#EstimateUpdatetSum').val();
const EstimateDiffer = $('#EstimateDiffer').val();
const EstimateDiscountRate = $('#EstimateDiscountRate').val();
const EstimateDiscount = $('#EstimateDiscount').val();
const EstimateFinalSum = $('#EstimateFinalSum').val();
const estimateTotal = $('#estimateTotal').val();
const makeWidth = $('#makeWidth').val();
const makeHeight = $('#makeHeight').val();
const maguriWing = $('#maguriWing').val();
const inspectionFee = $('#inspectionFee').val();
// 체크박스 상태 전달
const steelChecked = ($("#steel").prop('checked')) ? 'checked' : '' ; // 절곡체크가 steel 임.
const motorChecked = ($("#motor").prop('checked')) ? 'checked' : ''; // 모터가 들어가는지 체크
const warrantyChecked = ($("#warranty").prop('checked')) ? 'checked' : ''; // 인정제품인지 체크
const slatChecked = ($("#slatcheck").prop('checked')) ? 'checked' : ''; // 주자재(스크린,철재) 체크
const partsChecked = ($("#partscheck").prop('checked')) ? 'checked' : ''; // 부자재 체크
// 2) 쿼리 스트링 객체로 만들기
const params = {
num: num,
tempKey: tempKey,
mode: 'edit',
itemoption: 'slat', // Changed from 'screen' to 'slat'
estimateSurang,
EstimateFirstSum,
EstimateUpdatetSum,
EstimateDiffer,
estimateTotal,
EstimateDiscountRate,
EstimateDiscount,
EstimateFinalSum,
makeWidth,
makeHeight,
maguriWing,
inspectionFee,
steelChecked, // 체크박스 상태 전달
motorChecked,
warrantyChecked,
slatChecked,
partsChecked
};
// 3) $.param 으로 직렬화한 뒤 URL 생성
const url = '/estimate/write_form.php?' + $.param(params);
// 4) 팝업 열기
customPopup(url, '발주서 등록/수정', 1890, 900);
} else {
alert('JSON 저장에 실패했습니다. 다시 시도해 주세요.');
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('AJAX 요청 실패');
console.log('상태 코드:', jqXHR.status);
console.log('응답 텍스트:', jqXHR.responseText);
console.log('오류 상태:', textStatus);
console.log('오류 메시지:', errorThrown);
alert('일시적으로 서버와의 통신 실패. 죄송하지만, 버튼 실행을 다시해 주세요. 문제가 지속되면 관리자에게 문의해 주세요.');
}
});
});
// 철재 견적서 보기 버튼 클릭 시
$(document).on('click', '#ViewEstimateBtn_slat', function() {
var num = $("#estimate_num").val();
if (!num || num === '0') {
Swal.fire({
icon: 'warning',
title: '알림',
text: '견적을 불러온 기록이 없습니다.'
});
return;
}
var tablename = "estimate";
// URL에 변수를 추가
var url = '/estimate/write_form.php?mode=view' + '&num=' + num + "&tablename=" + tablename;
customPopup(url, '견적서', 1850, 900);
});
// 철재 발주서 보기 버튼 클릭 시
$(document).on('click', '#loadOrderBtn_slat', function() {
var num = $("#num").val();
var url = '/output/viewOrder_slat.php?num=' + num ;
customPopup(url, '철재 발주서', 800, 900);
});
// 철재스라트작업일지 버튼 클릭 시
$(document).on('click', '#loadSlatWorkBtn', function() {
var num = $("#num").val();
var url = '/output/viewSlatWork.php?num=' + num ;
customPopup(url, '철재 작업일지', 800, 900);
});
// 철재 절곡 작업일지 버튼 클릭 시
$(document).on('click', '#loadBendingWorkBtn_slat', function() {
var num = $("#num").val();
var url = '/output/viewBendingWork_slat.php?num=' + num ;
customPopup(url, '철재 절곡작업일지', 800, 900);
});
// 철재 출고증 버튼 클릭 시
$(document).on('click', '#loadOutputWorkBtn_slat', function() {
var num = $("#num").val();
var url = '/output/viewOutput_slat.php?num=' + num ;
customPopup(url, '철재 출고증', 800, 900);
});
// 철재 납품확인서 버튼 클릭 시
$(document).on('click', '#loadConfirmBtn_slat', function() {
var num = $("#num").val();
var url = '/output/viewConfirm_slat.php?num=' + num ;
customPopup(url, '철재 납품확인서', 800, 900);
});
// 철재-중간검사 버튼 클릭 시
$(document).on('click', '#loadmidInspectSlatBtn', function() {
var num = $("#num").val();
var url = '/output/viewMidInspectSlat.php?num=' + num ;
customPopup(url, '철재-중간검사', 800, 900);
});
// 조인트바-중간검사 버튼 클릭 시
$(document).on('click', '#loadmidInspectJointbarBtn', function() {
var num = $("#num").val();
var url = '/output/viewinspectionJointbar.php?num=' + num ;
customPopup(url, '조인트바-중간검사', 800, 900);
});
// 철재 절곡-중간검사 버튼 클릭 시
$(document).on('click', '#loadmidInspectBendingBtn_slat', function() {
var num = $("#num").val();
var url = '/output/viewMidInspectBending_slat.php?num=' + num ;
customPopup(url, '철재 절곡-중간검사', 800, 900);
});
// 검색 버튼 클릭 시
$('.searchEstimateBtn_slat').on('click', function() {
var search = $('#searchEstimate_slat').val();
// 철재 검색
setTimeout(function() {
estimate_search_slat(search,'철재');
}, 500); // 0.5초 후에 트리거 (필요에 따라 시간을 조정할 수 있습니다)
});
});
// 견적 상세 정보를 가져오는 AJAX 함수
function fetchEstimateDetails_slat(estimateId) {
// console.log('estimateId' + estimateId);
$("#loadEstimateModal_slat").modal("hide"); // 모달창 닫기
$("#estimate_slatDiv").show(); // 철재스라트탭 보이게 하기
$.ajax({
url: 'fetch_estimate_details.php', // 서버에서 데이터를 가져오는 경로 (스크린, 철재 구분없다. 아이디로 가져옴)
method: 'POST',
data: { estimateId: estimateId }, // 실제 전달된 estimateId 사용
dataType: 'json',
success: function(response) {
console.log(response);
// Check if response is valid and contains necessary data
if (response && Array.isArray(response) && response.length > 0) {
const estimateData = response[0];
// major_category 값을 확인하여 처리
if (estimateData.major_category === '스크린') {
// 철재스라트일 경우 estimateList 데이터를 숨겨진 필드에 넣음
document.getElementById('estimateList').value = estimateData.estimateList;
document.getElementById('estimateList_auto').value = estimateData.estimateList_auto;
} else if (estimateData.major_category === '철재') {
// 철재스라트일 경우 estimateSlatList 데이터를 숨겨진 필드에 넣음
document.getElementById('estimateSlatList').value = estimateData.estimateSlatList;
document.getElementById('estimateSlatList_auto').value = estimateData.estimateSlatList_auto;
}
// 견적서 외 주요 hidden input 값도 반영
$('#pjnum').val(estimateData.pjnum || '');
$('#major_category').val(estimateData.major_category || '');
$('#position').val(estimateData.position || '');
$('#makeWidth').val(estimateData.makeWidth || '');
$('#makeHeight').val(estimateData.makeHeight || '');
$('#secondord').val(estimateData.secondord || ''); // 발주처
$('#secondordman').val(estimateData.secondordman || ''); // 발주처
$('#secondordmantel').val(estimateData.secondordmantel || ''); // 발주처
$('#secondordnum').val(estimateData.secondordnum || ''); // 발주처 코드
$('#outworkplace').val(estimateData.outworkplace || ''); // 견적서 현장명
$('#estimate_num').val(estimateData.num || ''); // 견적서 코드
// 로트번호 생성 자동체크
$('#createAutoCode').prop('checked', true);
function formatNumber(value) {
return value && !isNaN(value) ? Number(value).toLocaleString() : '';
}
// 1) 수치(VAT 포함) 계산
const supplyPrice = Number(estimateData.estimateTotal) || 0;
const FirstSum = Number(estimateData.EstimateFirstSum) || 0;
const updateSum = Number(estimateData.EstimateUpdatetSum) || 0; // 수정금액
const withVAT = Math.round(supplyPrice * 1.1); // 소수점 없이 반올림
const withVAT_FirstSum = Math.round(FirstSum * 1.1); // 소수점 없이 반올림
const withVAT_updateSum = Math.round(updateSum * 1.1); // 소수점 없이 반올림
const differSum = withVAT_FirstSum - withVAT_updateSum;
$('#estimateTotal').val(formatNumber(withVAT));// VAT 포함으로 저장하기 견적은 공급가액임 최초저장금액도 적용함
$('#EstimateFirstSum').val(formatNumber(withVAT_FirstSum));
$('#EstimateUpdatetSum').val(formatNumber(withVAT_updateSum));
$('#EstimateDiffer').val(formatNumber(differSum));
$('#EstimateDiscountRate').val(estimateData.EstimateDiscountRate || '');
$('#EstimateDiscount').val(estimateData.EstimateDiscount || '');
$('#EstimateFinalSum').val(formatNumber(estimateData.EstimateFinalSum));
$('#maguriWing').val(estimateData.maguriWing || '');
// detailJson은 JSON 객체이므로 다시 문자열화해서 전달
$('#detailJson').val(estimateData.detailJson || '');
// 5가지 체크박스 상태 설정
$('#steel').prop('checked', estimateData.steel === '1');
$('#motor').prop('checked', estimateData.motor === '1');
$('#warranty').prop('checked', estimateData.warranty === '인정');
$('#slatcheck').prop('checked', estimateData.slatcheck === '1');
$('#partscheck').prop('checked', estimateData.partscheck === '1');
if (estimateData.warranty === '인정') {
$('#warranty').trigger('change');
}
// estimateList를 모달창에서 보여주기 위해 추가
loadEstimateList_slat(estimateData.estimateSlatList, estimateData.estimateSlatList_auto); // 철재 정보를 넘겨준다.
// 닫기 버튼
$(document).on('click', '.closeModal_Estimate', function() {
$("#selectEstimateModal").modal("hide"); // 모달창 띄우기
});
} else {
console.error('Received invalid response data');
}
},
error: function(err) {
console.error('Error fetching data', err);
}
});
}
var fullEstimateList_slat = []; // 전역 변수로 전체 estimateList 저장
function loadEstimateList_slat(estimateList_slat, estimateList_auto_slat) {
// estimateList가 문자열로 전달된 경우 JSON 파싱
if (typeof estimateList_slat === 'string' && estimateList_slat !== '' && estimateList_slat !== null && estimateList_slat !== undefined && estimateList_slat !== '[]' && estimateList_slat !== '{}') {
try {
estimateList_slat = JSON.parse(estimateList_slat); // 문자열이면 JSON 배열로 변환
estimateList_auto_slat = JSON.parse(estimateList_auto_slat); // 문자열이면 JSON 배열로 변환
} catch (e) {
console.error('estimateList를 JSON으로 파싱하는 중 오류 발생:', e);
return;
}
}
// estimateList가 배열인지 확인
if (!Array.isArray(estimateList_slat)) {
console.error('estimateList_slat는 배열이어야 합니다. 받은 값:', estimateList_slat);
return; // 배열이 아니면 함수 종료
}
fullEstimateList_slat = estimateList_slat; // 전역 변수에 전체 데이터를 저장
var tbody = $('#estimateListBody'); // 견적항목 선택
tbody.empty(); // 기존 데이터를 지움
// 데이터를 반복하면서 각 행을 생성
estimateList_slat.forEach(function(estimate, index) {
var tr = $('<tr>').append(
$('<td>').append(
$('<input type="checkbox" class="estimate-checkbox">')
.val(estimate.col1 ?? '')
.prop('checked', true) // 기본 체크 상태
),
$('<td>').text(estimate.col2 ?? ''), // col2
$('<td>').text(estimate.col3 ?? ''), // col3
$('<td>').text(estimate.col4 ?? ''), // col4
$('<td>').text(estimate.col5 ?? ''), // col5
$('<td>').text(estimate.col10 ?? ''), // col10
$('<td>').text(estimate.col11 ?? ''), // col11
$('<td>').text(estimate.col15 ?? '') // col15 철재슬랫 수량
);
tbody.append(tr);
});
// 모달창 띄우기
$('#selectEstimateModal').modal('show');
// 전체 선택 체크박스 change 이벤트 추가
$('.selectAllEstimates').off('change').on('change', function() {
// 체크된 상태에 맞춰 하위 체크박스 일괄 토글
$('.estimate-checkbox').prop('checked', $(this).prop('checked'));
});
// 적용 버튼 클릭 시 선택된 항목 처리
$('#applySelectedEstimates').off('click').on('click', function() {
var selectedEstimateIds = [];
// 선택된 체크박스의 값을 배열로 수집
$('.estimate-checkbox:checked').each(function() {
selectedEstimateIds.push($(this).val());
});
if (selectedEstimateIds.length > 0) {
// 선택된 항목을 처리하는 함수 호출
// 철재 슬랫
processSelectedEstimates_slat(selectedEstimateIds);
// 모달창 닫기
$('#selectEstimateModal').modal('hide');
} else {
alert('적용할 항목을 선택해주세요.');
}
});
}
// 철재 견적서 선택된 항목을 처리하는 함수
function processSelectedEstimates_slat(selectedEstimateIds) {
// 선택된 ID들에 해당하는 데이터를 전체 목록에서 필터링
const filteredEstimates = fullEstimateList_slat.filter(function(estimate) {
return selectedEstimateIds.includes(estimate.col1); // col1이 고유번호
});
// console.log('필터링된 데이터:', filteredEstimates); // 필터링된 데이터 출력
// 선택된 자료의 col1을 1부터 시작하는 일렬번호로 재설정
filteredEstimates.forEach((estimate, index) => {
estimate.col1 = (index + 1).toString(); // 일렬번호를 1부터 설정
});
// console.log('forEach 후 데이터:', filteredEstimates); // 일렬번호 설정 후 출력
// 필터링된 데이터를 함수로 전달하여 화면에 표시
renderEstimateData_slat({ estimateSlatList: filteredEstimates }, 'adapt'); // 기록함
}
// 철재 슬랫 견적서 화면 표시
function renderEstimateData_slat(data, reload = null) {
// Check if the data and estimateSlatList exist and are valid JSON
if (data && data.estimateSlatList) {
try {
// 이미 파싱된 JSON인지 확인하려면 try-catch 사용
if (typeof data.estimateSlatList === 'string') {
estimateSlatList = JSON.parse(data.estimateSlatList); // 문자열이면 JSON 파싱
} else {
estimateSlatList = data.estimateSlatList; // 이미 파싱된 JSON일 경우 그대로 사용
}
const estimateDiv = document.getElementById('estimate_slatDiv');
estimateDiv.innerHTML = ''; // Clear previous content
const table = document.createElement('table');
table.className = 'table table-bordered';
table.id = 'estimateSlatListTable';
// Create the table header (this can be expanded with your desired header structure)
const thead = document.createElement('thead');
let headerRow =
"<tr>" +
"<th rowspan='6' style='width: 150px !important;'>일련<br>번호</th>" +
"<th rowspan='6' style='width: 150px !important;'>층수</th>" +
"<th rowspan='6' style='width: 150px !important;'>부호</th>" +
"<th rowspan='6' style='width: 200px !important;'>제품명</th>" +
"<th rowspan='6' style='width: 200px !important;'>투시창선택</th>" +
"<th rowspan='6' style='width: 150px !important;'>종류</th>" +
"<th rowspan='4' colspan='2' style='width: 300px !important;'>가이드레일</th>" +
"<th rowspan='4' colspan='2' style='width: 300px !important;'>①오픈사이즈</th>" +
"<th rowspan='4' colspan='2'>②-1제작사이즈 <br> <span class='text-primary'> (철재)</span></th>" +
"<th rowspan='4' colspan='2'>②-2제작사이즈 <br> <span class='text-danger'> (부자재)</span></th>" +
"<th rowspan='6' style='width: 150px !important;'>③면적</th>" +
"<th rowspan='6' style='width: 150px !important;'>④중량</th>" +
"<th rowspan='6' style='width: 150px !important;'>투시창 <br> 수량</th>" +
"<th rowspan='6' style='width: 150px !important;'>셔터<br>수량</th>" +
"<th rowspan='4' colspan='3' style='width: 300px !important;'>연동제어기</th>" +
"<th rowspan='2' colspan='7' style='width: 400px !important;'>⑤모터</th>" +
"<th rowspan='1' colspan='36' style='width: 1200px !important;'>절곡</th>" +
"<th rowspan='1' colspan='21' style='width: 600px !important;'>부자재</th>" +
"</tr>" +
"<tr>" +
"<th rowspan='2' colspan='8' style='width: 600px;'>⑥가이드레일(한쌍)</th>" +
"<th rowspan='2' colspan='18' style='width: 900px;'>⑦케이스(셔터박스)</th>" +
"<th rowspan='2' colspan='10' style='width: 750px;'>⑧하단마감재</th>" +
"<th rowspan='2' colspan='13' style='width: 600px;'>⑨감기샤프트</th>" +
"<th rowspan='2' colspan='4' style='width: 300px;'>⑩각파이프</th>" +
"<th rowspan='4' style='width: 150px;'>⑪조인트바</th>" +
"<th rowspan='4' style='width: 150px;'>⑫앵글</th>" +
"</tr>" +
"<tr>" +
"<th rowspan='4'> <span class='text-primary'> 모터 견적가 포함</span> </th> " +
"<th rowspan='4' style='width: 150px;'>전원</th>" +
"<th rowspan='4' style='width: 150px;'>유/무선</th>" +
"<th rowspan='4' style='width: 150px;'>용량</th>" +
"<th rowspan='2' colspan='3' style='width: 300px;'>브라케트</th>" +
"</tr>" +
"<tr>" +
"<th rowspan='1' colspan='6' style='width: 600px;'>가이드레일 마감/보강재</th>" +
"<th rowspan='3' style='width: 150px;'>하부base1</th>" +
"<th rowspan='3' style='width: 150px;'>하부base2</th>" +
"<th colspan='5' style='width: 500px;'>레일용 연기차단재 <br> (W50)</th>" +
"<th colspan='12' style='width: 900px;'>케이스</th>" +
"<th style='width: 150px;'>케이스용<br>연기차단재</th>" +
"<th colspan='3' style='width: 300px;'>하장바</th>" +
"<th colspan='7'> x </th>" +
"<th rowspan='3' style='width: 150px;'>인치</th>" +
"<th colspan='12' style='width: 700px;'>원형파이프</th>" +
"<th rowspan='2' colspan='4' style='width: 300px;'>50*30*1.4T</th>" +
"</tr>" +
"<tr>" +
"<th rowspan='2' style='width: 150px;'>설치유형</th>" +
"<th rowspan='2' style='width: 150px;'>마감유형</th>" +
"<th rowspan='2' style='width: 150px;'>가로</th>" +
"<th rowspan='2' style='width: 150px;'>높이</th>" +
"<th rowspan='2' style='width: 150px;'>가로</th>" +
"<th rowspan='2' style='width: 150px;'>높이</th>" +
"<th rowspan='2' style='width: 150px;'>가로</th>" +
"<th rowspan='2' style='width: 150px;'>높이</th>" +
"<th rowspan='2' style='width: 150px;'>매립</th>" +
"<th rowspan='2' style='width: 150px;'>노출</th>" +
"<th rowspan='2' style='width: 150px;'>매립형<br>뒷박스</th>" +
"<th rowspan='2' style='width: 200px;'>가로*세로</th>" +
"<th rowspan='2' style='width: 150px;'>사이즈</th>" +
"<th rowspan='2' style='width: 150px;'>받침용<br>앵글</th>" +
"<th rowspan='2' style='width: 150px;'>size</th>" +
"<th rowspan='2'>2438</th>" +
"<th rowspan='2'>3000</th>" +
"<th rowspan='2'>3500</th>" +
"<th rowspan='2'>4000</th>" +
"<th rowspan='2'>4300</th>" +
"<th rowspan='2' style='width: 150px;'>2438</th>" +
"<th rowspan='2' style='width: 150px;'>3000</th>" +
"<th rowspan='2' style='width: 150px;'>3500</th>" +
"<th rowspan='2' style='width: 150px;'>4000</th>" +
"<th rowspan='2' style='width: 150px;'>4300</th>" +
"<th colspan='8' style='width: 800px;'>셔터박스</th>" +
"<th rowspan='1' style='width: 150px;'>상부덮개</th>" +
"<th colspan='3' style='width: 300px;'>마구리</th>" +
"<th rowspan='1' style='width: 150px;'>W80</th>" +
"<th colspan='3' style='width: 300px;'>60*40</th>" +
"<th colspan='7'> x </th>" +
"<th colspan='1'> x </th>" +
"<th colspan='3' style='width: 300px;'>4</th>" +
"<th colspan='3' style='width: 300px;'>5</th>" +
"<th colspan='4' style='width: 400px;'>6</th>" +
"<th colspan='1' style='width: 100px;'>8</th>" +
"</tr>" +
"<tr>" +
"<th >규격 <br> (사이즈,전면밑,레일폭,점검구방향)</th>" +
"<th style='width: 150px;'>size</th>" +
"<th style='width: 150px;'>1219</th>" +
"<th style='width: 150px;'>2438</th>" +
"<th style='width: 150px;'>3000</th>" +
"<th style='width: 150px;'>3500</th>" +
"<th style='width: 150px;'>4000</th>" +
"<th style='width: 150px;'>4150</th>" +
"<th style='width: 150px;'>1219*@</th>" +
"<th style='width: 150px;'>size</th>" +
"<th style='width: 150px;'>날개</th>" +
"<th style='width: 150px;'>수량</th>" +
"<th style='width: 150px;'>3000</th>" +
"<th style='width: 150px;'>size</th>" +
"<th style='width: 150px;'>3000</th>" +
"<th style='width: 150px;'>4000</th>" +
"<th colspan='7'> x </th>" +
"<th style='width: 150px;'>철재X </th>" +
"<th style='width: 150px;'>3000</th>" +
"<th style='width: 150px;'>4500</th>" +
"<th style='width: 150px;'>6000</th>" +
"<th style='width: 150px;'>6000</th>" +
"<th style='width: 150px;'>7000</th>" +
"<th style='width: 150px;'>8200</th>" +
"<th style='width: 150px;'>3000</th>" +
"<th style='width: 150px;'>6000</th>" +
"<th style='width: 150px;'>7000</th>" +
"<th style='width: 150px;'>8000</th>" +
"<th style='width: 150px;'>8200</th>" +
"<th style='width: 150px;'>보강개수환산</th>" +
"<th style='width: 150px;'>size</th>" +
"<th style='width: 150px;'>3000</th>" +
"<th style='width: 150px;'>6000</th>" +
"<th style='width: 150px;'>300</th>" +
"<th style='width: 150px;'>2500</th>" +
"</tr>";
const user_id = $("#user_id").val();
// console.log('user_id :', user_id);
// 개발자 모드일 경우 열 번호 행 추가
if (user_id && user_id === 'pro') {
headerRow += "<tr>";
// 1) col2~col4
for (let i = 1; i <= 4; i++) {
headerRow += `<th class='text-primary'>col${i}</th>`;
}
// 2) col4 다음에 col4_quartz
headerRow += "<th class='text-primary'>col4_quartz</th>";
// 3) col5~col18
for (let i = 5; i <= 18; i++) {
if(i==10) {
headerRow += "<th class='text-primary'>col10_SW</th>";
headerRow += "<th class='text-primary'>col11_SH</th>";
headerRow += "<th class='text-primary'>col" + i + "</th>";
}
else{
headerRow += `<th class='text-primary'>col${i}</th>`;
}
}
// 4) col19 이전에 추가할 3개
headerRow += "<th class='text-primary'>col19_brand</th>";
headerRow += "<th class='text-primary'>col19</th>";
headerRow += "<th class='text-primary'>col19_wireless</th>";
// 5) col20~col46
for (let i = 20; i <= 46; i++) {
headerRow += `<th class='text-primary'>col${i}</th>`;
}
// 6) col46_wing
headerRow += "<th class='text-primary'>col46_wing</th>";
// 7) col47~col77
for (let i = 47; i <= 77; i++) {
headerRow += `<th class='text-primary'>col${i}</th>`;
}
headerRow += "</tr>";
// 두 번째 행: 숫자 1~81 출력
headerRow += "<tr>";
for (let i = 1; i <= 83; i++) {
headerRow += `<th class='text-success'>${i}</th>`;
}
headerRow += "</tr>";
// 결과 문자열 사용 (예: DOM에 삽입하거나 콘솔 출력)
console.log(headerRow);
}
thead.innerHTML = headerRow;
table.appendChild(thead);
const tbody = document.createElement('tbody');
// console.log(estimateSlatList);
// estimateSlatList.forEach((row) => {
// console.log(row);
// });
// col1 형태 읽어오기
let surangArray = [16, 17, 18, 27, 28, 28, 29, 30, 31, 34, 35, 36, 37, 38, 41, 42, 43, 44, 45, 46, 47, 49, 50, 52, 53, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 76, 77, 78, 79];
let rowCounter = 0; // 행 번호 초기화
estimateSlatList.forEach((row) => {
// console.log('rowCounter : ', rowCounter);
// 수량이 1보다 큰 경우, 해당 수량만큼 행을 반복 생성 철재 수량
const quantity = parseInt(row['col15']) || 1;
// console.log('quantity : ', quantity);
for (let lpcounter = 0; lpcounter < quantity; lpcounter++) {
rowCounter++; // 행 번호 증가
const tr = document.createElement('tr');
for (let i = 1; i <= 77; i++) {
var td = document.createElement('td');
if(i === 4 ) { // 셔터박스 크기 유동적
let colName = 'col' + i;
td.className = 'w100px' + ' ' + colName;
td.textContent = row[colName] || ''; // Check if the column exists
tr.appendChild(td);
td = document.createElement('td');
colName = 'col' + i + '_quartz';
td.className = 'w150px' + ' ' + colName;
td.textContent = row[colName] || ''; // Check if the column exists
}
else if(i ===10) {
td.className = 'w150px text-primary fw-bold col10_SW';
td.textContent = row['col10_SW'] || row['col10'] || '';
tr.appendChild(td);
td = document.createElement('td');
td.className = 'w150px text-primary fw-bold col11_SH';
td.textContent = row['col11_SH'] || row['col11'] || ''; // 우선순위가 있다
tr.appendChild(td);
td = document.createElement('td');
td.className = 'w150px col10';
td.textContent = row['col10'] || '';
tr.appendChild(td);
}
else if (i === 37 && row['col37'] !== 'custom') {
console.log('row[col37] : ', row['col37']);
console.log('row[col37_frontbottom] : ', row['col37_frontbottom']);
console.log('row[col37_railwidth] : ', row['col37_railwidth']);
console.log('row[col37_boxdirection] : ', row['col37_boxdirection']);
const colNameCustom = 'col' + i ;
const colNameFrontBottom = 'col' + i + '_frontbottom';
const colNameRailWidth = 'col' + i + '_railwidth';
const colNameBoxDirection = 'col' + i + '_boxdirection';
td.className = 'w300px';
// Combine all relevant values into a single string
const customValue = row[colNameCustom] || ''; // Custom value for col38
const frontBottomValue = row[colNameFrontBottom] || '50'; // Default to 50
const railWidthValue = row[colNameRailWidth] || '70'; // Default to 70
const boxDirectionValue = row[colNameBoxDirection] || '양면'; // Default is empty
// Display all values
td.textContent = `${customValue}, ${frontBottomValue}, ${railWidthValue}, ${boxDirectionValue}`;
} else if (i === 37 && row['col37'] === 'custom') { // custom일때는 다르게 처리함
console.log('row[col37_custom] : ', row['col37_custom']);
console.log('row[col37_frontbottom] : ', row['col37_frontbottom']);
console.log('row[col37_railwidth] : ', row['col37_railwidth']);
console.log('row[col37_boxdirection] : ', row['col37_boxdirection']);
const colNameCustom = 'col37_custom' ;
const colNameFrontBottom = 'col37_frontbottom';
const colNameRailWidth = 'col37_railwidth';
const colNameBoxDirection = 'col37_boxdirection';
td.className = 'w300px';
// Combine all relevant values into a single string
const customValue = row[colNameCustom] || ''; // Custom value for col38
const frontBottomValue = row[colNameFrontBottom] || '50'; // Default to 50
const railWidthValue = row[colNameRailWidth] || '70'; // Default to 70
const boxDirectionValue = row[colNameBoxDirection] || '양면'; // Default is empty
// Display all values
td.textContent = `${customValue}, ${frontBottomValue}, ${railWidthValue}, ${boxDirectionValue}`;
} else if (i === 19) { // 모터 유무선여부
var colName = 'col19_brand';
td.className = 'w150px' + ' ' + colName;
td.textContent = row[colName] || '';
tr.appendChild(td);
td = document.createElement('td');
colName = 'col19';
td.className = 'w100px' + ' ' + colName;
td.textContent = row[colName] || ''; // Check if the column exists
tr.appendChild(td);
td = document.createElement('td');
colName = 'col19_wireless';
td.className = 'w100px' + ' ' + colName;
td.textContent = row[colName] || ''; // Check if the column exists
} else if (i === 46) { // 마구리 날개부분 추가
var colName = 'col46';
td.className = 'w100px' + ' ' + colName;
td.textContent = row[colName] || '';
tr.appendChild(td);
td = document.createElement('td');
colName = 'col46_wing';
td.className = 'w100px' + ' ' + colName;
td.textContent = row[colName] || ''; // Check if the column exists
}
else
{
const colName = 'col' + i;
td.className = 'w100px ' + colName + ' ' ;
let value = row[colName];
if(i === 1 ) {
value = rowCounter;
}
if(i === 15) { // 수량 컬럼
value = 1; // 수량 1로 고정
}
if(surangArray.includes(i)) {
value = value/quantity;
td.textContent = (value === 0 || value === '0') ? '': (value || '');
}
else {
td.textContent = (value === 0 || value === '0') ? '': (value || '');
}
}
$("#prodCode").val(row['col4']); // 제품코드 적용하기
$("#warrantyNum").val(searchWarrantyNumber(row['col4']));
tr.appendChild(td);
}
tbody.appendChild(tr);
} // end of for
});
table.appendChild(tbody);
// Sum columns that need to be summed
// 합계를 낼 col다음 숫자임
const sumColumns = [14,15,16,17,18,25,26,27,28,29,33,34,35,36,39,40,41,42,43,44,47,48,50,51,61,62,63,64,65,66,67,68,69,70,71,74,75,76,77];
const columnSums = calculateColumnSums_slat(estimateSlatList, 14, 77);
// Generate tfoot for sum
const tfoot = document.createElement('tfoot');
tfoot.className = 'table-secondary';
const footerRow = document.createElement('tr');
const footerTh = document.createElement('th');
footerTh.className = 'text-end';
footerTh.setAttribute('colspan', '16');
footerTh.textContent = '합계';
footerRow.appendChild(footerTh);
// Add empty cells or total cells based on sumColumns
// col77까지 해당됨
for (let i = 14; i <= 77; i++) {
var td = document.createElement('th');
if (sumColumns.includes(i)) {
td.className = 'text-center';
const sumValue = columnSums[i];
// 0이면 빈 문자열, 정수면 그대로, 아니면 소수점 둘째자리까지
td.textContent = (sumValue === 0) ? '' : (Number.isInteger(sumValue) ? sumValue : sumValue.toFixed(2));
} else {
td.className = 'text-center';
td.textContent = ''; // 비합산 열도 공백으로 초기화
}
footerRow.appendChild(td);
if (i === 19) {
var td = document.createElement('th');
td.textContent = '';
footerRow.appendChild(td);
var td = document.createElement('th');
td.textContent = '';
footerRow.appendChild(td);
}
else if (i === 46) {
var td = document.createElement('th');
td.textContent = '';
footerRow.appendChild(td);
}
}
tfoot.appendChild(footerRow);
table.appendChild(tfoot);
estimateDiv.appendChild(table);
// reload 옵션이 있으면 스크린발주서에 적용하기
if (reload !== null) {
addRowsFromEstimate_Slat(estimateSlatList); // 견적 데이터를 발주서에 추가
}
} catch (error) {
console.error("Error parsing JSON data: ", error);
alert("데이터를 처리하는 중 오류가 발생했습니다.");
}
} else {
console.error("Invalid or missing data.");
alert("유효한 데이터가 없습니다.");
}
}
function calculateColumnSums_slat(estimateSlatList, startCol, endCol) {
const columnSums = {};
// Initialize sums for the specified range of columns
for (let col = startCol; col <= endCol; col++) {
columnSums[col] = 0;
}
// Loop through rows and calculate sums for the specified columns
estimateSlatList.forEach((row) => {
for (let col = startCol; col <= endCol; col++) {
let colName = `col${col}`;
const value = parseFloat(row[colName]) || 0; // Parse value or default to 0
columnSums[col] += value;
}
});
return columnSums;
}
// 발주서, 견적데이터에서 전달하여 철재 작업지시서 행을 추가하는 함수
function addRowsFromEstimate_Slat(estimateSlatList) {
const slatcheck = $("#slatcheck").prop('checked'); // 주자재(스크린,철재) 체크여부
console.log('slatcheck : ', slatcheck);
// 견적 데이터를 사용하여 철재 발주서를 초기화
const orderTableBody = document.getElementById('slatTable');
orderTableBody.innerHTML = ''; // 기존 발주서 내용 초기화
// 철재 슬랫 견적서 체크시 작업지시서 추가
if (slatcheck === true) {
estimateSlatList.forEach((estimateData) => {
// 수량이 1보다 큰 경우, 해당 수량만큼 행을 반복 생성
const quantity = parseInt(estimateData.col15) || 1;
for (let i = 0; i < quantity; i++) {
addRow_slat(null, estimateData);
}
});
}
else
{
// 철재 슬랫 견적서 체크 안되어 있으면 작업지시서 추가 안함
console.log('slatcheck is false');
// 철재 작업지시서 숨기기
$("#slat_order").hide();
}
}
</script>
<!-- 부트스트랩 툴팁 -->
<script>
document.addEventListener('DOMContentLoaded', function () {
var tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
var tooltipList = tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
// $("#order_form_write").modal("show");
});
$(document).on('click', '#viewEstimateDetail', function() {
var estimateList = $("#estimateList").val();
var estimateSlatList = $("#estimateSlatList").val();
var num = $("#num").val();
// 가로폭, 세로폭, 마구리날개, 검사비설정 정보 전달하는 함수
var makeWidth = $("#makeWidth").val();
var makeHeight = $("#makeHeight").val();
var maguriWing = $("#maguriWing").val();
var inspectionFee = $("#inspectionFee").val();
if(estimateList !== '[]') { // 스크린견적서가 있다면
var url = '/estimate/output_EsDetail_screen.php?num=' + num + '&makeWidth=' + makeWidth + '&makeHeight=' + makeHeight + '&maguriWing=' + maguriWing + '&inspectionFee=' + inspectionFee;
}
else if(estimateSlatList !== '[]') // 철재견적서가 있다면
{
var url = '/estimate/output_EsDetail_slat.php?num=' + num + '&makeWidth=' + makeWidth + '&makeHeight=' + makeHeight + '&maguriWing=' + maguriWing + '&inspectionFee=' + inspectionFee;
}
customPopup(url, '견적 산출내역서', 1200, 900);
});
</script>
<script>
// searchWarrantyNumber 함수 정의
function searchWarrantyNumber(searchCode) {
// 제품명과 인정번호 데이터를 객체로 정의합니다.
const productData = {
"KD-SL60": "NVS22-0902-1",
"KTE01": "FDS-NVS23-0117-1",
"KSS01": "FDS-OTS23-0117-2",
"KSS02": "FDS-OTS25-0318-2",
"KSE01": "FDS-OTS23-0117-3",
"KWE01": "FDS-OTS23-0117-4",
"KQTS01": "FDS-NVS23-1226-3",
"KDSS01": "FDS-OTS25-0318-1"
};
// 입력된 제품명에 해당하는 인정번호를 반환
return productData[searchCode] || "해당 제품명이 없습니다.";
}
$(document).ready(function() {
// 뷰 ID와 쿠키 이름 매핑 (output-list 제거)
var views = [
{ id: "estimate_screenDiv", cookie: "showEsimateView", button: "#estimate_view" , iconId: "#estimate_viewIcon" },
{ id: "estimate_slatDiv", cookie: "showEsimateView_slat", button: "#estimate_slat_view" , iconId: "#estimate_slat_viewIcon" },
{ id: "showGroupViewDiv", cookie: "showGroupView", button: "#showGroupViewBtn" , iconId: "#showGroupViewIcon" }
];
views.forEach(function (view) {
$(view.button).on("click", function () {
toggleView(view.id, view.cookie, view.iconId);
});
initializeView(view.id, view.cookie, view.iconId);
});
// output-list는 항상 보이게 설정
$("#output-list").css("display", "block");
});
// prodCode변경
$(document).ready(function(){
$('#prodCode').on('change', function() {
var prodCode = $(this).val(); // 선택된 제품코드
var pairCode = $(this).find(':selected').data('pair'); // 대응하는 인정제품 코드
if (prodCode && pairCode) {
// 로트번호 자동생성 체크박스가 체크되어 있는지 확인
var lotNum = 'KD-' + pairCode ;
$('#lotNum').val(lotNum); // lotNum 필드 업데이트
$("#warrantyNum").val(searchWarrantyNumber(prodCode));
} else {
$('#lotNum').val(''); // 제품코드가 선택되지 않은 경우 필드 초기화
}
// console.log('호출 prodCode' + $("#prodCode").val());
});
});
$(document).ready(function() {
// 견적선택에서 전체 선택 또는 해제 동작 구현
$('#selectAllEstimates').on('change', function() {
var isChecked = $(this).is(':checked');
// 전체 체크박스 선택 또는 해제
$('.estimate-checkbox').prop('checked', isChecked);
});
// 모달창이 열릴 때 이미 선택된 상태 유지
$('#selectEstimateModal').on('show.bs.modal', function() {
$('#selectAllEstimates').prop('checked', false); // 모달이 열릴 때 전체 선택을 초기화
});
// 다른 필요한 초기화 코드
});
<!-- mode == 'view' 조회 화면일때 사용금지 시키는 구문 -->
$(document).ready(function() {
var mode = '<?php echo isset($mode) ? $mode : ''; ?>';
// 마지막에 넣어줘야 전체를 적용할 수 있다.
if (mode === 'view')
disableView();
});
function disableView() {
$('input:not(.ViewMode), textarea:not(.ViewMode)').prop('readonly', true);
// select는 disabled 적용, ViewMode 제외
$('select:not(.ViewMode)').prop('disabled', true);
$('input[type=hidden]').prop('readonly', false);
// checkbox와 radio는 클릭 불가능하게 하고 시각적 강조
$('input[type="checkbox"], input[type="radio"]').each(function() {
$(this).addClass('readonly-checkbox readonly-radio');
});
// 파일 입력 비활성화
$('input[type=file]').prop('disabled', true);
$('.fetch_receiverBtn').prop('disabled', true); // 수신자 버튼 비활성화
$('.viewNoBtn').prop('disabled', true); //버튼 비활성화
$('.searchplace').prop('disabled', true); // 수신자 버튼 비활성화
$('.searchsecondord').prop('disabled', true); // 수신자 버튼 비활성화
$('.fetch_loadgroupBtn').prop('disabled', true); // 품질인증 그룹명 버튼 비활성화
// 레이블 텍스트 크게 설정
$('label').css('font-size', '1.1em');
// select 속성 readonly 효과 내기
$('select[data-readonly="true"]').on('mousedown', function(event) {
event.preventDefault();
});
// checkbox 속성 readonly 효과 내기
$('input[type="checkbox"]').on('click', function(event) {
if($(this).data('readonly') === true) {
event.preventDefault();
return false;
}
});
}
// =======================================================
// "비인정 스크린" 전용 뷰 테이블 렌더링 함수
// - 앞 4개 칼럼(col1~col4)은 실제 저장된 rowData로 채움
// - 나머지 fullHeaders 길이만큼 col5~col16이 있으면 그 값을, 없으면 빈 칸 출력
// =======================================================
function renderUnapprovedScreenView(containerSelector, title, tbodyId, dataList) {
console.log('renderUnapprovedScreenView 함수 호출');
if (!Array.isArray(dataList) || dataList.length === 0) {
// 데이터가 없으면 아무것도 추가하지 않음
return;
}
// console.log('renderUnapprovedScreenView 내부 호출');
// 1) 스크린 작업지시서 전체 헤더 목록
// "부호, 가로(W), 세로(H), 수량(EA)"를 포함하여
// addRow()가 실제 생성하는 th 순서 그대로 나열해야 합니다.
const fullHeaders = [
'부호', // → rowData.col1
'가로(W)', // → rowData.col2
'세로(H)', // → rowData.col3
'수량(EA)', // → rowData.col4
// 아래부터는 col5 ~ col16 순서와 매핑됩니다.
'비상문', // → rowData.col5 (if exists)
'인쇄면', // → rowData.col6
'인쇄방향', // → rowData.col7
'좌간격', // → rowData.col8
'우간격', // → rowData.col9
'개구부', // → rowData.col10
'덮개폭', // → rowData.col11
'좌문구', // → rowData.col12
'중앙문구', // → rowData.col13
'우문구', // → rowData.col14
'도면', // → rowData.col15
'발주서 기록' // → rowData.col16
];
// 2) <thead> 생성
let html = `<h6 class="fw-bold text-primary mt-3">${title}</h6>`;
html += `<table class="table table-bordered table-sm text-center">`;
html += `<thead class="table-light"><tr>`;
// 첫 번째 열: "번호"
html += `<th style="width: 50px;">번호</th>`;
// fullHeaders 배열에 들어있는 항목만큼 <th> 출력
fullHeaders.forEach(headerText => {
html += `<th>${headerText}</th>`;
});
html += `</tr></thead>`;
// 3) <tbody> 생성 (tbodyId 부여)
html += `<tbody id="${tbodyId}">`;
dataList.forEach((rowData, rowIndex) => {
html += `<tr>`;
// 3-1) 1열: 번호
html += `<td>${rowIndex + 1}</td>`;
// 3-2) 2~5열: col1~col4 (실제 데이터)
html += `<td>${rowData.col1 || ''}</td>`;
html += `<td>${rowData.col2 || ''}</td>`;
html += `<td>${rowData.col3 || ''}</td>`;
html += `<td>${rowData.col4 || ''}</td>`;
// 3-3) 6열 이후: fullHeaders.length - 4 개의 칼럼
// col5 ~ col16 순서대로, 만약 rowData에 해당 키가 있으면 표시, 없으면 빈칸
for (let headerIndex = 4; headerIndex < fullHeaders.length; headerIndex++) {
const colName = `col${headerIndex + 1}`; // headerIndex=4 → col5, …, headerIndex=15 → col16
html += `<td>${rowData[colName] || ''}</td>`;
}
html += `</tr>`;
});
html += `</tbody></table>`;
// 4) 지정된 컨테이너에 append
$(containerSelector).append(html);
}
// 수주내역의 후반부 자바스크립트
$(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);
// 화면 로딩 시 데이터가 있을 경우 해당 테이블에 행을 추가
// window.screen_unapprovedList.forEach(rowData => {
// addRowUA_screen($('#screen_unapprovedListBody'), null, rowData);
// });
// "비인정 스크린" 뷰를 출력
window.screen_unapprovedList.forEach(rowData => {
addRowUA_screen($('#screen_unapprovedListBody'), null, rowData);
});
window.slat_unapprovedList.forEach(rowData => {
addRowUA_slat($('#slat_unapprovedListBody'), null, rowData);
});
window.motorList.forEach(rowData => {
addRowUA_motor($('#motor_listBody'), null, rowData);
});
window.bendList.forEach(rowData => {
addRowUA_bend($('#bend_listBody'), null, rowData);
});
window.controllerList.forEach(rowData => {
addRowUA_controller($('#controller_listBody'), null, rowData);
});
window.etcList.forEach(rowData => {
addRowUA_etc($('#etc_listBody'), null, rowData);
});
// 최초 비인정 거래명세에 값이 없으면 자동으로 거래명세표를 만든다.
if (window.accountList && window.accountList.length > 0) {
window.accountList.forEach(rowData => {
addRow_Account($('#account_listBody'), null, rowData);
});
} else {
recalculateAccountTable();
}
/*************************************************
* 거래명세표 비인정 데이터 렌더링(모달창) 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: null // null 이면 col1, col2.. 직접 사용
};
const keys = fieldMap[tableId];
// 1) 제목
let html = `<h6 class="fw-bold text-primary mt-3">${title}</h6>`;
// 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') {
// 절곡품 (5번째 컬럼에만 이미지)
columns.forEach((_, i) => {
const col = `col${i+1}`;
if (i === 5) {
html += `<td><img src="${row[col]||''}" style="max-width:50px;"></td>`;
} else {
html += `<td>${row[col]||''}</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 = '.col-5'; // 테이블을 렌더링할 부모 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)', '검색', '폭합(mm)','이미지','수량', '비고'], window.bendList);
renderViewUATable(container, '부자재', 'etc_list_view', 'etc_listBody_view',
['품명', '규격', '길이', '수량', '비고'], window.etcList);
// estimateList이 객체나 배열 형태라면 바로 사용
if (typeof estimateList === 'object' && estimateList !== null) {
console.log('estimateList 객체로 전달됨');
} else if (typeof estimateList === 'string') {
// 문자열로 전달된 경우만 JSON.parse로 파싱
try {
estimateList = JSON.parse(estimateList);
document.getElementById('estimateList').value = JSON.stringify(estimateList);
} catch (e) {
console.error('JSON 파싱 오류:', e);
estimateList = [];
}
}
// estimateList이 객체나 배열 형태라면 바로 사용
if (typeof estimateList_auto === 'object' && estimateList_auto !== null) {
console.log('estimateList_auto 객체로 전달됨');
} else if (typeof estimateList_auto === 'string') {
// 문자열로 전달된 경우만 JSON.parse로 파싱
try {
estimateList_auto = JSON.parse(estimateList_auto);
document.getElementById('estimateList_auto').value = JSON.stringify(estimateList_auto);
} catch (e) {
console.error('JSON 파싱 오류:', e);
estimateList_auto = [];
}
}
// 데이터가 배열이 아니거나 비어있을 경우를 처리
if (!Array.isArray(estimateList) || estimateList.length === 0) {
console.log('estimateList 유효한 데이터가 없습니다.');
if (mode === 'view')
$("#screenWindow").hide(); // 스크린 견적서 불러오기 등 작업일지 등등 감추기
} else {
// 데이터가 있을 경우 테이블을 생성하여 표시
renderEstimateData({ estimateList: JSON.stringify(estimateList) });
}
// estimateSlatList이 객체나 배열 형태라면 바로 사용
if (typeof estimateSlatList === 'object' && estimateSlatList !== null) {
console.log('estimateSlatList 객체로 전달됨');
} else if (typeof estimateSlatList === 'string') {
// 문자열로 전달된 경우만 JSON.parse로 파싱
try {
estimateSlatList = JSON.parse(estimateSlatList);
document.getElementById('estimateSlatList').value = JSON.stringify(estimateSlatList);
} catch (e) {
console.error('JSON 파싱 오류:', e);
estimateSlatList = [];
}
}
// estimateSlatList이 객체나 배열 형태라면 바로 사용
if (typeof estimateSlatList_auto === 'object' && estimateSlatList_auto !== null) {
console.log('estimateSlatList_auto 객체로 전달됨');
} else if (typeof estimateSlatList_auto === 'string') {
// 문자열로 전달된 경우만 JSON.parse로 파싱
try {
estimateSlatList_auto = JSON.parse(estimateSlatList_auto);
document.getElementById('estimateSlatList_auto').value = JSON.stringify(estimateSlatList_auto);
} catch (e) {
console.error('JSON 파싱 오류:', e);
estimateSlatList_auto = [];
}
}
// 데이터가 배열이 아니거나 비어있을 경우를 처리
if (!Array.isArray(estimateSlatList) || estimateSlatList.length === 0) {
console.log('estimateSlatList 유효한 데이터가 없습니다.');
if (mode === 'view')
$("#slatWindow").hide(); // 스라트 견적서 불러오기 등 작업일지 등등 감추기
} else {
// 데이터가 있을 경우 테이블을 생성하여 표시
renderEstimateData_slat({ estimateSlatList: JSON.stringify(estimateSlatList) });
}
});
// 쿠키 값 가져오는 함수
function getCookie(name) {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.startsWith(name + '=')) {
return cookie.substring(name.length + 1);
}
}
return null;
}
// 쿠키 저장 함수
function setCookie(name, value, days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
var expires = "expires=" + date.toUTCString();
document.cookie = name + "=" + value + ";" + expires + ";path=/";
}
function toggleView(viewId, cookieName, iconId = null) {
const view = getCookie(cookieName);
const listContainer = $("#" + viewId);
const icon = iconId ? $(iconId) : null;
if (view === "show") {
listContainer.hide();
setCookie(cookieName, "hide", 10);
if (icon) icon.removeClass("bi-chevron-down").addClass("bi-chevron-right");
} else {
listContainer.show();
setCookie(cookieName, "show", 10);
if (icon) icon.removeClass("bi-chevron-right").addClass("bi-chevron-down");
}
}
function initializeView(viewId, cookieName, iconId = null) {
const view = getCookie(cookieName);
const listContainer = $("#" + viewId);
const icon = iconId ? $(iconId) : null;
if (view === "show") {
listContainer.show();
if (icon) icon.removeClass("bi-chevron-right").addClass("bi-chevron-down");
} else {
listContainer.hide();
if (icon) icon.removeClass("bi-chevron-down").addClass("bi-chevron-right");
}
}
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();
}
/* =================================================================================
비인정스크린행추가 함수
================================================================================= */
// 1. '종류' 선택을 위한 옵션 배열
const unapprovedScreenOptions = [
'실리카', '화이바', '와이어', '제연커튼',
'신설비상문', '실리카원단', '화이바원단', '와이어원단', '(직접입력)'
];
/**
* 비인정 스크린 테이블에 새로운 행을 추가하는 함수
* @param {jQuery} tableBody - 행을 추가할 tbody의 jQuery 객체
* @param {jQuery|null} afterRow - 이 행 다음에 새 행을 추가하고 싶을 때의 기준 행
* @param {Object} rowData - 행에 채워넣을 초기 데이터
*/
function addRowUA_screen(tableBody, afterRow = null, rowData = {}) {
const newRow = $('<tr>');
const mode = $('#mode').val();
// rowData 기본값 설정
const data = {
item_type: rowData.item_type || '', // 종류
floors: rowData.floors || '',
text1: rowData.text1 || '',
memo: rowData.memo || '',
cutwidth: rowData.cutwidth || '',
cutheight: rowData.cutheight || '',
number: rowData.number || '1',
exititem: rowData.exititem || '0',
printside: rowData.printside || '',
direction: rowData.direction || '',
intervalnum: rowData.intervalnum || '',
intervalnumsecond: rowData.intervalnumsecond || '',
exitinterval: rowData.exitinterval || '',
cover: rowData.cover || '',
drawbottom1: rowData.drawbottom1 || '',
drawbottom3: rowData.drawbottom3 || '',
drawbottom2: rowData.drawbottom2 || '',
draw: rowData.draw || '',
text2: rowData.text2 || '',
done_check: rowData.done_check || '',
remain_check: rowData.remain_check || '',
mid_check: rowData.mid_check || '',
left_check: rowData.left_check || '',
right_check: rowData.right_check || ''
};
// '종류' 선택을 위한 createSelect_unapproved 함수 사용
const itemTypeSelect = createSelect_unapproved('item_type[]', unapprovedScreenOptions, data.item_type);
// console.log('item_type : ', data.item_type);
// ① mode 값 읽기
const isView = $('#mode').val() === 'view';
// ② 첫 번째 셀(버튼) 생성
let cellsHtml = '<td class="text-center"><div class="d-flex justify-content-center align-items-center">' +
'<span class="serial-number me-2"></span>';
// ③ view 모드가 아닐 때만 버튼 추가
if (!isView) {
cellsHtml += `
<button type="button" class="btn btn-outline-dark btn-sm viewNoBtn me-1 add-row-generic" style="border:0;">+</button>
<button type="button" class="btn btn-outline-danger btn-sm viewNoBtn me-1 remove-row-generic" style="border:0;">-</button>
<button type="button" class="btn btn-outline-secondary btn-sm viewNoBtn copy-row-generic me-1" style="border:0;"><i class="bi bi-files"></i></button>
`;
}
// ④ 셀 닫기
cellsHtml += '</div></td>';
// First column with buttons
cellsHtml += `
<td>${itemTypeSelect}</td>
<td><input type="text" class="form-control calc_col1" name="floors[]" value="${data.floors}" placeholder="층" oninput="calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col2" name="text1[]" value="${data.text1}" placeholder="부호" oninput="calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col3" name="memo[]" value="${data.memo}" placeholder="추가메모" oninput="calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col4" name="cutwidth[]" value="${data.cutwidth}" placeholder="가로(W)" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col5" name="cutheight[]" value="${data.cutheight}" placeholder="세로(H)" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col6" name="number[]" value="${data.number}" placeholder="수량(EA)" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>
<td>
<select class="form-control calc_col7 exititem text-center" name='exititem[]' style="font-size:10px;" onchange='calculateRow(this)'>
<option value='0' ${data.exititem == '0' ? 'selected' : ''}>없음</option>
<option value='1' ${data.exititem == '1' ? 'selected' : ''}>중앙</option>
<option value='2' ${data.exititem == '2' ? 'selected' : ''}>좌측</option>
<option value='3' ${data.exititem == '3' ? 'selected' : ''}>우측</option>
<option value='4' ${data.exititem == '4' ? 'selected' : ''}>문2개</option>
<option value='5' ${data.exititem == '5' ? 'selected' : ''}>문2개 지그재그</option>
</select>
</td>
<td>
<select class="form-control calc_col8 printside text-center" name='printside[]' style="font-size:10px;" onchange='calculateRow(this)'>
<option value='' ${data.exititem == '0' ? 'selected' : ''}></option>
<option value='0' ${data.printside == '0' && data.exititem != '0' ? 'selected' : ''}>양면</option>
<option value='1' ${data.printside == '1' && data.exititem != '0' ? 'selected' : ''}>한면</option>
</select>
</td>
<td>
<select class="form-control calc_col9 direction text-center" style="font-size:10px;" name='direction[]' onchange='calculateRow(this)'>
<option value='' ${data.exititem == '0' ? 'selected' : ''}></option>
<option value='0' ${data.direction == '0' && data.exititem != '0' ? 'selected' : ''}>정방향</option>
<option value='1' ${data.direction == '1' && data.exititem != '0' ? 'selected' : ''}>역방향</option>
</select>
</td>
<td><input type="text" class="form-control calc_col10 intervalnum" name="intervalnum[]" value="${data.intervalnum}" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col11 intervalnumsecond" name="intervalnumsecond[]" value="${data.intervalnumsecond}" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col12 exitinterval" name="exitinterval[]" value="${data.exitinterval}" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col13 cover" name="cover[]" value="${data.cover}" placeholder="덮개" oninput="inputNumbers(this); calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col14 drawbottom1" name="drawbottom1[]" value="${data.drawbottom1}" placeholder="좌" oninput="calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col15 drawbottom3" name="drawbottom3[]" value="${data.drawbottom3}" placeholder="중앙" oninput="calculateRow(this)" autocomplete="off"></td>
<td><input type="text" class="form-control calc_col16 drawbottom2" name="drawbottom2[]" value="${data.drawbottom2}" placeholder="우" oninput="calculateRow(this)" autocomplete="off"></td>
<td class="draw">
<img src="${data.draw ? '../img/screen/' + data.draw : ''}"
style="width: 120px; height: auto; ${data.draw ? 'display: inline-block;' : 'display: none;'}"
onclick="showLargeImage(this)">
<input type="hidden" name="draw[]" value="${data.draw}">
</td>
<td><input type="text" class="form-control calc_col17 text2" name="text2[]" style="font-size:10px;" value="${data.text2}" readonly></td>
`;
cellsHtml += `
<td style="display:none;">
<input type="hidden" class="form-control" name="done_check[]" value="${data.done_check}">
<input type="hidden" class="form-control" name="remain_check[]" value="${data.remain_check}">
<input type="hidden" class="form-control" name="mid_check[]" value="${data.mid_check}">
<input type="hidden" class="form-control" name="left_check[]" value="${data.left_check}">
<input type="hidden" class="form-control" name="right_check[]" value="${data.right_check}">
</td>`;
newRow.html(cellsHtml);
// 행 삽입
if (afterRow && afterRow.length) {
afterRow.after(newRow);
} else {
tableBody.append(newRow);
}
// .serial-number 클래스 있어야 함
updateSerialNumbers(tableBody);
// 헤더 표시 여부 조절
toggleTableHeaderVisibility(tableBody);
if ($("#mode").val() == 'view') {
disableView();
}
}
const motorOption1 = ['전동개폐기_단상 220V', '전동개폐기_삼상 380V', '베어링부(브라켓트)', '컨트롤러', '전동축링(복주머니)', '링', '플랜지', '환봉', '체인', '무기둥 브라켓트_90도', '무기둥 브라켓트_180도', '고정용 볼트&넛트','(직접입력)'];
const motorOption2 = ['150kg', '300kg', '400kg', '철재300kg','철재400kg','500kg', '600kg', '800kg', '1000kg', '1500kg', '2000kg'];
const motorOption3 = ['(없음)', '380*180', '450*225', '530*320', '600*350', '690*390', '910*600'];
const motorOption4 = ['2~4인치','2~5인치','2~6인치','3~4인치', '3~5인치', '3~6인치', '4~5인치', '4~6인치', '5~6인치', '6~8인치', '2인치','3인치','4인치', '5인치', '6인치', '8인치','10인치','12인치'];
const motorOption5 = ['구형', '신형'];
const motorOption6 = ['●'];
const defaultMotorOption2 = [ '(없음)', '380*180', '450*225', '530*320', '600*350', '690*390', '910*600' ];
const motorOption2Map = {
'(없음)': ['(없음)'],
'150kg': ['380*180'],
'300kg': ['380*180'],
'400kg': ['380*180'],
'철재300kg': ['530*320'],
'철재400kg': ['530*320'],
'500kg': ['600*350'],
'600kg': ['600*350'],
'800kg': ['690*390'],
'1000kg': ['690*390'],
'1500kg': ['690*390'],
'2000kg': ['690*390']
};
const motorOption3Map = {
'(없음)': ['(없음)'],
'380*180': ['2~4인치', '2~5인치', '2~6인치', '3~4인치', '3~5인치', '3~6인치', '4~5인치', '4~6인치', '5~6인치', '6~8인치', '2인치','3인치','4인치', '5인치','6인치'],
'450*225': ['2~4인치', '2~5인치', '2~6인치', '3~4인치', '3~5인치', '3~6인치', '4~5인치', '4~6인치', '5~6인치', '6~8인치', '2인치','3인치', '4인치', '5인치', '6인치', '8인치', '10인치', '12인치'],
'530*320': ['2~4인치', '2~5인치', '2~6인치', '3~4인치', '3~5인치', '3~6인치', '4~5인치', '4~6인치', '5~6인치', '6~8인치', '2인치','3인치', '4인치', '5인치', '6인치', '8인치', '10인치', '12인치'],
'600*350': ['2~4인치', '2~5인치', '2~6인치', '3~4인치', '3~5인치', '3~6인치', '4~5인치', '4~6인치', '5~6인치', '6~8인치', '2인치','3인치', '4인치', '5인치', '6인치', '8인치', '10인치', '12인치'],
'690*390': ['2~4인치', '2~5인치', '2~6인치', '3~4인치', '3~5인치', '3~6인치', '4~5인치', '4~6인치', '5~6인치', '6~8인치', '2인치','3인치', '4인치', '5인치', '6인치', '8인치', '10인치', '12인치']
};
// 2) change 이벤트 핸들러: col2가 바뀔 때마다 col3 옵션 재구성
$('#motor_listBody').on('change', 'select.col2', function() {
const selectedCapacity = $(this).val();
const $row = $(this).closest('tr');
const $col3 = $row.find('select.col3');
// 매핑된 옵션 또는 기본 전체 목록
// const newOpts = motorOption2Map[selectedCapacity] || motorOption3;
const newOpts = motorOption3;
// console.log('motorOption2Map[selectedCapacity]', motorOption2Map[selectedCapacity]);
// 옵션 재생성
$col3.empty();
newOpts.forEach(opt => {
$col3.append($('<option>').val(opt).text(opt));
});
// 자동으로 첫 번째 옵션 선택
// $col3.val(newOpts[0]);
$col3.val(motorOption2Map[selectedCapacity] );
});
// 3) addRowUA_motor 수정: 초기 로드 시에도 rowData.col2 값에 맞춰 col3 옵션 지정
function addRowUA_motor(
tableBody = $('#motor_listBody'),
afterRow = null,
rowData = {}
) {
// 기본값 보충
rowData = Object.assign({ col5: '1' }, rowData);
// rowData.col2(용량)에 매핑된 col3 옵션
const initialCol3 = motorOption2Map[rowData.col2] || motorOption3;
const fields = [
{ name: 'col1', type: 'select' }, // 품명
{ name: 'col2', type: 'select' }, // 모터용량
{ name: 'col3', type: 'select' }, // 브라켓크기
{ name: 'col4', type: 'select' }, // 샤프트
{ name: 'col5' }, // 수량
{ name: 'col6', type: 'select' }, // 구형/신형
{ name: 'col7', type: 'select' }, // 안전리미트
{ name: 'col8' } // 비고
];
const options = {
col1: motorOption1,
col2: motorOption2,
col3: initialCol3, // 여기에 동적 리스트 전달
col4: motorOption4,
col6: motorOption5,
col7: motorOption6
};
createCommonRow(tableBody, fields, options, rowData, afterRow);
}
const bendOption1 = ['가이드레일(보강재)', '가이드레일(마감재)', '가이드레일(하부BACE)', '삼각쫄대', '연기차단재(레일용)', '연기차단재(케이스용)', '하단마감재', 'L-BAR', '보강평철', '케이스_셔터박스', '케이스(전면부)', '케이스(린텔부)', '케이스(후면부)', '케이스(후면상부)', '케이스(후면하부)', '케이스(상면부)', '케이스(상부점검구)', '케이스(하부점검구)', '케이스(측면점검구)', '케이스(마구리)', '케이스(EGI 앵글)', '상부마감재(린텔)', 'R몰딩', 'R케이스', '절단판','(직접입력)'];
const bendOption2 = ['EGI 1.6T', 'EGI 1.2T', 'EGI 0.8T', 'GI 0.45T', 'SUS 1.5T', 'SUS 1.2T'];
function addRowUA_bend(
tableBody = $('#bend_listBody'),
afterRow = null,
rowData = {}
) {
searchOption = true;
// rowData에 기본 수량 설정
rowData = Object.assign({ col7: '1' }, rowData);
const fields = [
{ name: 'col1', type: 'select' }, // 품명
{ name: 'col2', type: 'select' }, // 두께
{ name: 'col3' }, // 길이
{ name: 'col4', type: 'button' }, // 검색 버튼
{ name: 'col5' }, // 폭합
{ name: 'col6', type: 'image' }, // 이미지
{ name: 'col7' }, // 수량
{ name: 'col8' } // 비고
];
const options = {
col1: bendOption1,
col2: bendOption2
};
// Create the row with search button
let newRow = $('<tr>');
// First column with buttons
newRow.append('<td class="text-center">' +
'<div class="d-flex justify-content-center align-items-center">' +
'<span class="serial-number me-2"></span>' +
'<button type="button" class="btn btn-outline-dark btn-sm viewNoBtn me-1 add-row-generic" style="border:0px;">+</button>' +
'<button type="button" class="btn btn-outline-danger btn-sm viewNoBtn me-1 remove-row-generic" style="border:0px;">-</button>' +
'<button type="button" class="btn btn-outline-secondary btn-sm viewNoBtn copy-row-generic me-1" style="border:0px;"><i class="bi bi-files"></i></button>' +
'</div></td>');
// Add other columns
fields.forEach(field => {
if (field.type === 'select') {
newRow.append(`<td class="text-center">${createSelect(field.name, options[field.name] || [], rowData[field.name] || '')}</td>`);
} else if (field.type === 'button') {
newRow.append(`<td class="text-center"><button type="button" class="btn btn-primary btn-sm search-bend-btn"><i class="bi bi-search"></i> </button></td>`);
} else if (field.type === 'image') {
// 이미지 컨테이너와 함께 hidden input 추가
const imgSrc = rowData[field.name] || '';
newRow.append(`
<td class="text-center">
<div class="image-container" style="max-width:100px; max-height:50px; height:auto; width:auto;">
${imgSrc ? `<img src="${imgSrc}" alt="형상 이미지" style="max-width:100px; max-height:50px; height:auto; width:auto;">` : '<span class="text-secondary">이미지 없음</span>'}
</div>
<input type="hidden" class="${field.name}" name="${field.name}[]" value="${imgSrc}">
</td>
`);
} else {
newRow.append(`<td class="text-center">${createInput(field.name, rowData[field.name] || '')}</td>`);
}
});
// Add hidden columns for bending data
newRow.append('<td class="d-none bending-data"></td>');
newRow.append('<td class="d-none image-url"></td>');
// Insert the row
if (afterRow && afterRow.length) {
afterRow.after(newRow);
} else {
tableBody.append(newRow);
}
// Add click handler for search button
newRow.find('.search-bend-btn').on('click', function(e) {
e.preventDefault();
const $row = $(this).closest('tr');
let itemName = $row.find('select.col1').val();
let material = $row.find('select.col2').val();
itemName = '';
material = '';
let searchString = $row.find('select.col1').val().substring(0, 2) ?? ''; // 앞의 두글자만 전달함
// Store current button reference for use in modal
window.currentSearchButton = this;
// Show modal with search results
$.ajax({
url: '/bending/searchbending.php',
type: 'GET',
data: {
search: searchString
},
success: function(response) {
console.log('response', response);
// Remove existing modal if it exists
if ($('#bendingSearchModal').length) {
$('#bendingSearchModal').remove();
}
// Create and show modal
$('body').append(`
<div class="modal fade" id="bendingSearchModal" tabindex="-1" aria-labelledby="bendingSearchModalLabel" aria-hidden="true">
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="bendingSearchModalLabel">절곡 정보 검색</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row mb-3">
<div class="col-md-6">
<div class="input-group">
<input type="text" class="form-control" id="bendingSearchInput" placeholder="검색어를 입력하세요" value="${searchString}">
<button class="btn btn-outline-secondary" type="button" id="bendingSearchBtn">
<i class="bi bi-search"></i> 검색
</button>
</div>
</div>
</div>
<div class="table-responsive">
<table class="table table-hover table-bordered">
<thead class="table-secondary">
<tr>
<th>대분류</th>
<th>중분류</th>
<th>품명</th>
<th>재질</th>
<th>규격(가로*세로)</th>
<th>이미지(형상)</th>
<th>폭합(mm)</th>
<th>절곡회수</th>
<th>비고</th>
<th>선택</th>
</tr>
</thead>
<tbody id="bendingSearchResults">
${response}
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
</div>
</div>
</div>
</div>
`);
// Add click handler for search results
$(document).on('click', '.select-bending-item, #bendingSearchResults tr', function(e) {
const $selectedRow = $(this).closest('tr');
const $targetRow = $(window.currentSearchButton).closest('tr');
// Update the target row with selected data
$targetRow.find('input.col5').val($selectedRow.find('td:eq(6)').text()); // 폭합
// Update image data
const $imgCell = $selectedRow.find('td:eq(5)');
const $img = $imgCell.find('img');
if ($img.length) {
const imgSrc = $img.attr('src');
// 이미지 URL을 hidden input에 저장
$targetRow.find('input.col6').val(imgSrc);
// 이미지 표시
$targetRow.find('.image-container').html(`<img src="${imgSrc}" alt="형상 이미지" style="max-width:100px; max-height:50px; height:auto; width:auto;">`);
} else {
$targetRow.find('input.col6').val('');
$targetRow.find('.image-container').html('<span class="text-secondary">이미지 없음</span>');
}
// Close the modal
$('#bendingSearchModal').modal('hide');
});
// Add search functionality
$('#bendingSearchBtn').on('click', function() {
console.log('searchBtn clicked');
const searchTerm = $('#bendingSearchInput').val();
// AJAX 요청으로 서버에서 검색 수행
$.ajax({
url: 'bending/searchbending.php',
type: 'POST',
data: {
search: searchTerm
},
success: function(response) {
try {
const data = JSON.parse(response);
let html = '';
if (data.length > 0) {
data.forEach(function(row) {
html += '<tr>';
html += '<td>' + (row.major_category || '') + '</td>';
html += '<td>' + (row.sub_category || '') + '</td>';
html += '<td>' + (row.item_name || '') + '</td>';
html += '<td>' + (row.material || '') + '</td>';
html += '<td>' + (row.specifications || '') + '</td>';
html += '<td>' + (row.image_url ? '<img src="' + row.image_url + '" alt="형상 이미지" style="max-width:100px; max-height:50px;">' : '<span class="text-secondary">이미지 없음</span>') + '</td>';
html += '<td>' + (row.width_sum || '') + '</td>';
html += '<td>' + (row.bending_count || '') + '</td>';
html += '<td>' + (row.notes || '') + '</td>';
html += '<td><button class="btn btn-sm btn-primary select-bending-item">선택</button></td>';
html += '</tr>';
});
} else {
html = '<tr><td colspan="10" class="text-center">검색 결과가 없습니다.</td></tr>';
}
$('#bendingSearchResults').html(html);
} catch (e) {
console.error('Error parsing response:', e);
$('#bendingSearchResults').html('<tr><td colspan="10" class="text-center">데이터 처리 중 오류가 발생했습니다.</td></tr>');
}
},
error: function(xhr, status, error) {
console.error('Search request failed:', error);
$('#bendingSearchResults').html('<tr><td colspan="10" class="text-center">검색 중 오류가 발생했습니다.</td></tr>');
}
});
});
// Add enter key support for search
$('#bendingSearchInput').on('keypress', function(e) {
if (e.which === 13) {
$('#bendingSearchBtn').click();
}
});
// Add modal hidden event handler
$('#bendingSearchModal').on('hidden.bs.modal', function () {
// Clear search input
$('#bendingSearchInput').val('');
// Remove modal from DOM
$(this).remove();
});
// Show the modal
const modal = new bootstrap.Modal(document.getElementById('bendingSearchModal'));
modal.show();
},
error: function(xhr, status, error) {
console.error('Error loading search modal:', error);
Swal.fire('오류', '검색 결과를 불러오는데 실패했습니다.', 'error');
}
});
});
updateSerialNumbers(tableBody);
toggleTableHeaderVisibility(tableBody);
}
const controllerOption1 = ['제어기_노출형', '제어기_매립형', '뒷박스', '방범스위치', '방범리모콘', '방범케이스', '키뭉치', '열찰(key)', '제어기기판', '컨트롤기판','(직접입력)'];
const controllerOption2 = ['구형', '신형'];
function addRowUA_controller(
tableBody = $('#controller_listBody'),
afterRow = null,
rowData = {}
) {
// rowData에 기본 수량 설정
rowData = Object.assign({ col2: '1' }, rowData);
const fields = [
{ name: 'col1', type: 'select' }, // 품명
{ name: 'col2' }, // 수량
{ name: 'col3', type: 'select' }, // 신형/구형
{ name: 'col4' } // 비고
];
const options = {
col1: controllerOption1,
col3: controllerOption2
};
createCommonRow(tableBody, fields, options, rowData, afterRow);
}
// 1) 매핑 정보
const etcOption1 = [
'감기샤프트', '각파이프', '앵글', '무게평철',
'마환봉', '조인트바', '봉제가스켓', '롤가스켓',
'락카스프레이', '힌지', '비상문평철', '미미',
'텐텐지', '덧대기원단', '처짐방지로라',
'내화실', '버미글라스','(직접입력)'
];
const defaultEtcOption2 = [
'2인치(60.5*2.9T)',
'3인치(89.1*2T)','4인치(114.3*2T)',
'5인치(139.8*2.9T)','6인치(165.2*2.9T)',
'8인치(216.3*4.2T)','10인치(267.4*6T)',
'12인치(318.5*6T)'
];
const etcOption2Map = {
'(없음)': ['(없음)'],
'감기샤프트': defaultEtcOption2,
'각파이프': ['50*30*1.4T', '30*30*1.4T', '100*50*2T', '100*100*2T'],
'앵글': ['40*40*3T', '50*50*4T'],
'무게평철': ['50*9T', '50*12T'],
'마환봉': ['6파이'],
'조인트바': ['(없음)'],
'봉제가스켓': ['(없음)'],
'롤가스켓': ['(없음)'],
'락카스프레이': ['은색', '적갈색', '연회색'],
'힌지': ['정방향(태영)', '역방향(태영)', '정방향(승리)', '역방향(승리)'],
'비상문평철': ['(없음)'],
'미미': ['(없음)'],
'텐텐지': ['(없음)'],
'덧대기원단': ['(없음)'],
'처짐방지로라': ['(없음)'],
'내화실': ['(없음)'],
'버미글라스': ['(없음)']
};
// 2) 의존 이벤트 등록
$('#etc_listBody').on('change', 'select.col1', function() {
const selected = $(this).val();
const $row = $(this).closest('tr');
const $col2 = $row.find('select.col2');
const opts = etcOption2Map[selected] || ['(없음)'];
$col2.empty();
if (!opts || opts.length === 0) {
// 값이 없으면 '(없음)' 추가
$col2.append($('<option>').val('(없음)').text('(없음)'));
} else {
// 값이 있을 경우 해당 옵션들 추가
opts.forEach(opt => {
$col2.append($('<option>').val(opt).text(opt));
});
}
});
// 3) addRow 함수 (기존 그대로)
function addRowUA_etc(
tableBody = $('#etc_listBody'),
afterRow = null,
rowData = {}
) {
// 1) 기본값 보충
rowData = Object.assign({ col4: '1' }, rowData);
// 2) col1 값에 따라 col2 옵션을 결정
// 매핑이 없으면 defaultEtcOption2 사용
const initialCol2 = etcOption2Map[rowData.col1] || defaultEtcOption2;
// 3) 필드 정의
const fields = [
{ name: 'col1', type: 'select' }, // 품명
{ name: 'col2', type: 'select' }, // 규격 (의존 셀)
{ name: 'col3' }, // 길이 mm
{ name: 'col4' }, // 수량
{ name: 'col5' } // 비고
];
// 4) selectOptions 에 col2 만 동적으로 교체
const options = {
col1: etcOption1,
col2: initialCol2
};
// 5) 행 생성
createCommonRow(tableBody, fields, options, rowData, afterRow);
// (createCommonRow 내부에서 createSelect 에 rowData[col2]를 넘기므로
// 자동으로 selected 처리됩니다.)
// 6) 추가된 행의 뷰 모드 처리나 기타 후속 작업이 필요하면 여기서!
if ($("#mode").val() === 'view') {
disableView();
}
}
function createCommonRow(tableBody, fields, selectOptions = {}, rowData = {}, afterRow = null, searchOption = null) {
let newRow = $('<tr>');
// 첫 열: 일련번호 + 버튼들
newRow.append('<td class="text-center">' +
'<div class="d-flex justify-content-center align-items-center">' +
'<span class="serial-number me-2"></span>' +
'<button type="button" class="btn btn-outline-dark btn-sm viewNoBtn me-1 add-row-generic" style="border:0px;">+</button>' +
'<button type="button" class="btn btn-outline-danger btn-sm viewNoBtn me-1 remove-row-generic" style="border:0px;">-</button>' +
'<button type="button" class="btn btn-outline-secondary btn-sm viewNoBtn copy-row-generic" style="border:0px;"><i class="bi bi-files"></i></button>' +
'</div></td>');
// 나머지 셀 생성
fields.forEach(field => {
if (field.type === 'select') {
newRow.append(`<td class="text-center">${createSelect(field.name, selectOptions[field.name] || [], rowData[field.name] || '')}</td>`);
} else if (field.type === 'button') {
newRow.append(`<td class="text-center">${createButton(field.name, '<i class="bi bi-search"></i>')}</td>`);
} else {
newRow.append(`<td class="text-center">${createInput(field.name, rowData[field.name] || '')}</td>`);
}
});
// 행 삽입
if (afterRow && afterRow.length) {
afterRow.after(newRow);
} else {
tableBody.append(newRow);
}
updateSerialNumbers(tableBody);
// 헤더 표시 여부 조절
toggleTableHeaderVisibility(tableBody);
if ($("#mode").val() == 'view') {
disableView();
}
}
// 직접입력함수 직접입력한 select 옵션 추가
function createSelect(name, options, selectedValue = '') {
let html = `<select name="${name}[]" class="form-select form-select-sm viewNoBtn text-center ${name}" style="height:30px; font-size:0.75rem;">`;
// 기본 "(없음)" 옵션
html += `<option value="(없음)"${selectedValue === '(없음)' ? ' selected' : ''}>(없음)</option>`;
// selectedValue가 비어있지 않고 options 에 없으면, 먼저 추가
if (selectedValue && !options.includes(selectedValue) && selectedValue !== '(없음)') {
html += `<option value="${selectedValue}" selected>${selectedValue}</option>`;
}
// 기존 옵션들 출력
options.forEach(opt => {
html += `<option value="${opt}"${opt === selectedValue ? ' selected' : ''}>${opt}</option>`;
});
html += '</select>';
return html;
}
function createInput(name, value = '', type = 'text') {
return `<input type="${type}" name="${name}[]" class="form-control form-control-sm text-center viewNoBtn ${name}" autocomplete="off" value="${value}" style="height:30px; font-size:0.75rem;">`;
}
function createButton(name, value = '', type = 'button') {
return `<button type="${type}" name="${name}[]" class="btn btn-outline-secondary btn-sm viewNoBtn ${name}" style="height:30px; font-size:0.75rem;"> ${value}</button>`;
}
function initDirectInputOnSelect(selectSelector) {
const modalId = 'directInputModal';
// 1) 모달 엘리먼트가 없으면 body에 추가 (transform 제거)
if (!document.getElementById(modalId)) {
$('body').append(`
<div id="${modalId}-backdrop" style="
display:none;
position:fixed; top:0; left:0;
width:100%; height:100%;
background:rgba(0,0,0,0.3);
z-index:9998;
"></div>
<div id="${modalId}" style="
display:none;
position:absolute; /* fixed → absolute */
background:#fff;
padding:1rem;
border:1px solid #ccc;
border-radius:4px;
box-shadow:0 2px 8px rgba(0,0,0,0.2);
z-index:9999;
white-space:nowrap; /* 크기 자동 조절 */
">
<div style="margin-bottom:.5rem;">
<input type="text" id="${modalId}-input" class="form-control form-control-sm" placeholder="추가항목을 입력하세요">
</div>
<div class="text-end">
<button type="button" id="${modalId}-cancel" class="btn btn-sm btn-secondary me-1">취소</button>
<button type="button" id="${modalId}-confirm" class="btn btn-sm btn-primary">입력</button>
</div>
</div>
`);
}
let $currentSelect = null;
// 2) select 변경 감지
$('body').on('change', selectSelector, function() {
if ($(this).val() === '(직접입력)') {
$currentSelect = $(this);
const $modal = $(`#${modalId}`);
const $backdrop = $(`#${modalId}-backdrop`);
// 2-1) select 위치 계산
const off = $currentSelect.offset();
const h = $currentSelect.outerHeight();
// 2-2) 모달 위치를 select 바로 아래로 설정
$modal.css({
top: off.top + h + 4, // select 바로 아래(+여백 4px)
left: off.left,
display: 'block'
});
// 2-3) 배경 보이기
$backdrop.show();
// 2-4) 입력창에 포커스
$(`#${modalId}-input`).val('').focus();
}
});
// 3) 취소 버튼
$('body').on('click', `#${modalId}-cancel`, function() {
$(`#${modalId}-backdrop, #${modalId}`).hide();
if ($currentSelect) {
$currentSelect.val($currentSelect.find('option:first').val());
}
});
// 4) 입력 확인
$('body').on('click', `#${modalId}-confirm`, function() {
const val = $(`#${modalId}-input`).val().trim();
if (!val) {
alert('값을 입력해주세요.');
return;
}
if ($currentSelect) {
$currentSelect
.append($('<option>').val(val).text(val))
.val(val)
.trigger('change');
}
$(`#${modalId}-backdrop, #${modalId}`).hide();
});
// 5) Enter 키로도 확인 동작
$('body').on('keydown', `#${modalId}-input`, function(e) {
if (e.key === 'Enter') {
e.preventDefault(); // 폼 제출 방지
$(`#${modalId}-confirm`).click(); // 확인 버튼 클릭 트리거
}
});
// 6) ESC 키로도 취소 동작
$('body').on('keydown', `#${modalId}-input`, function(e) {
if (e.key === 'Escape') {
e.preventDefault(); // 폼 제출 방지
$(`#${modalId}-cancel`).click();
}
});
}
// 사용 예: 문서 로드 후 원하는 select 에 적용
$(function() {
initDirectInputOnSelect('#etc_listBody select.col1');
initDirectInputOnSelect('#screen_unapprovedListBody select.col1');
initDirectInputOnSelect('#slat_unapprovedListBody select.col1');
initDirectInputOnSelect('#motor_listBody select.col1');
initDirectInputOnSelect('#bend_listBody select.col1');
initDirectInputOnSelect('#controller_listBody select.col1');
// ...다른 카테고리도 동일하게 호출
});
// ─────────────────────────────────────────────
// 3) 5개 버튼 처리: "행전체 삭제" + 4가지 자동 로드
// ─────────────────────────────────────────────
// 3-1) 스크린 노출형 데이터
const screenOutData = [
{ col1: '가이드레일(보강재)', col2: 'EGI 1.6T' },
{ col1: '가이드레일(마감재)', col2: 'SUS 1.2T' },
{ col1: '가이드레일(하부BACE)', col2: 'EGI 1.2T' },
{ col1: '삼각쫄대', col2: 'EGI 1.2T' },
{ col1: '연기차단재(케이스용)', col2: 'EGI 0.8T' },
{ col1: '하단마감재', col2: 'SUS 1.5T' },
{ col1: 'L-BAR', col2: 'EGI 1.6T' },
{ col1: '보강평철', col2: 'EGI 1.2T' },
{ col1: '케이스_셔터박스', col2: 'EGI 1.6T' }
];
// "스크린 매립형" 데이터
const screenInData = [
{ col1: '가이드레일(보강재)', col2: 'EGI 1.6T' },
{ col1: '가이드레일(마감재)', col2: 'SUS 1.2T' },
{ col1: '가이드레일(하부BACE)', col2: 'EGI 1.2T' },
{ col1: '삼각쫄대', col2: 'EGI 1.2T' },
{ col1: '연기차단재(케이스용)', col2: 'EGI 0.8T' },
{ col1: '하단마감재', col2: 'SUS 1.5T' },
{ col1: 'L-BAR', col2: 'EGI 1.6T' },
{ col1: '보강평철', col2: 'EGI 1.2T' },
{ col1: '상부마감재(린텔)', col2: 'SUS 1.5T' },
{ col1: 'R몰딩', col2: 'EGI 1.2T' },
{ col1: 'R케이스', col2: 'GI 0.45T' }
];
// "철재스라트 노출형" 데이터
const slatOutData = [
{ col1: '가이드레일(보강재)', col2: 'EGI 1.6T' },
{ col1: '가이드레일(마감재)', col2: 'SUS 1.2T' },
{ col1: '가이드레일(하부BACE)', col2: 'EGI 1.2T' },
{ col1: '연기차단재(레일용)', col2: 'EGI 0.8T' },
{ col1: '연기차단재(케이스용)', col2: 'EGI 0.8T' },
{ col1: '하단마감재', col2: 'SUS 1.5T' },
{ col1: '케이스_셔터박스', col2: 'EGI 1.6T' }
];
// "철재스라트 매립형" 데이터
const slatInData = [
{ col1: '가이드레일(보강재)', col2: 'EGI 1.6T' },
{ col1: '가이드레일(마감재)', col2: 'SUS 1.2T' },
{ col1: '가이드레일(하부BACE)', col2: 'EGI 1.2T' },
{ col1: '연기차단재(레일용)', col2: 'EGI 0.8T' },
{ col1: '연기차단재(케이스용)', col2: 'EGI 0.8T' },
{ col1: '하단마감재', col2: 'SUS 1.5T' },
{ col1: '상부마감재(린텔)', col2: 'SUS 1.5T' },
{ col1: 'R몰딩', col2: 'EGI 1.2T' },
{ col1: 'R케이스', col2: 'GI 0.45T' }
];
// 비인정 스크린 "행전체 삭제"
$('#screen_unapprovedTableRemoveAllBtn').on('click', function () {
Swal.fire({
title: '정말 삭제하시겠습니까?',
text: '비인정 스크린의 모든 행이 삭제됩니다.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '삭제',
cancelButtonText: '취소',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
$('#screen_unapprovedListBody').empty();
toggleTableHeaderVisibility($('#screen_unapprovedListBody'));
Swal.fire('삭제 완료', '모든 행이 삭제되었습니다.', 'success');
}
});
});
// 비인정 철재 "행전체 삭제"
$('#slat_unapprovedTableRemoveAllBtn').on('click', function () {
Swal.fire({
title: '정말 삭제하시겠습니까?',
text: '비인정 철재스라트의 모든 행이 삭제됩니다.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '삭제',
cancelButtonText: '취소',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
$('#slat_unapprovedListBody').empty();
toggleTableHeaderVisibility($('#slat_unapprovedListBody'));
Swal.fire('삭제 완료', '모든 행이 삭제되었습니다.', 'success');
}
});
});
// 비인정 전동 "행전체 삭제"
$('#motor_tableRemoveAllBtn').on('click', function () {
Swal.fire({
title: '정말 삭제하시겠습니까?',
text: '비인정 전동 개폐기 & 베어링부(브라켓트)의 모든 행이 삭제됩니다.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '삭제',
cancelButtonText: '취소',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
$('#motor_listBody').empty();
toggleTableHeaderVisibility($('#motor_listBody'));
Swal.fire('삭제 완료', '모든 행이 삭제되었습니다.', 'success');
}
});
});
// 비인정 제어기 "행전체 삭제"
$('#controller_tableRemoveAllBtn').on('click', function () {
Swal.fire({
title: '정말 삭제하시겠습니까?',
text: '비인정 제어기의 모든 행이 삭제됩니다.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '삭제',
cancelButtonText: '취소',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
$('#controller_listBody').empty();
toggleTableHeaderVisibility($('#controller_listBody'));
Swal.fire('삭제 완료', '모든 행이 삭제되었습니다.', 'success');
}
});
});
// "행전체 삭제"
$('#bendRowRemoveAllBtn').on('click', function () {
Swal.fire({
title: '정말 삭제하시겠습니까?',
text: '모든 절곡품 행이 삭제됩니다.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '삭제',
cancelButtonText: '취소',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
$('#bend_listBody').empty();
toggleTableHeaderVisibility($('#bend_listBody'));
Swal.fire('삭제 완료', '모든 행이 삭제되었습니다.', 'success');
}
});
});
// 부자재 행전체 삭제
$('#etc_tableRemoveAllBtn').on('click', function () {
Swal.fire({
title: '정말 삭제하시겠습니까?',
text: '모든 부자재 행이 삭제됩니다.',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '삭제',
cancelButtonText: '취소',
reverseButtons: true
}).then((result) => {
if (result.isConfirmed) {
$('#etc_listBody').empty();
toggleTableHeaderVisibility($('#etc_listBody'));
Swal.fire('삭제 완료', '모든 행이 삭제되었습니다.', 'success');
}
});
});
// "스크린 노출형"
$('#loadScreenOutBtn').on('click', function() {
screenOutData.forEach(r => addRowUA_bend($('#bend_listBody'), null, r));
});
// "스크린 매립형"
$('#loadScreenInBtn').on('click', function() {
screenInData.forEach(r => addRowUA_bend($('#bend_listBody'), null, r));
});
// "철재스라트 노출형"
$('#loadSlatOutBtn').on('click', function() {
slatOutData.forEach(r => addRowUA_bend($('#bend_listBody'), null, r));
});
// "철재스라트 매립형"
$('#loadSlatInBtn').on('click', function() {
slatInData.forEach(r => addRowUA_bend($('#bend_listBody'), null, r));
});
/**
* 철판 가격 계산 함수
* @param {string} material 재질 문자열 (예: "EGI 1.2T", "SUS 1.6T")
* @param {string|number} thickness 두께만 숫자로 (예: "1.2" 또는 1.2)
* @param {number} length 길이(mm)
* @param {number} width 폭(mm)
* @param {number} qty 수량
* @returns {number} 총 가격 (원 단위, 소수점 이하 버림)
*/
function getSteelPrice(material, thickness, length, width, qty) {
console.log('item_bend',item_bend);
// 1) 재질 대문자 통일 및 EGI/SUS 추출
var mat = (material || '').toString().trim().toUpperCase();
var rawMat = mat.includes("EGI") ? "EGI" :
mat.includes("SUS") ? "SUS" : "";
// 2) 두께에서 숫자만 꺼내 문자열로 통일
var th = thickness.toString().replace(/[^0-9.]/g, "");
// 3) EGI 용 특수 두께 매핑 (1.15→1.2, 1.55→1.6)
if (rawMat === "EGI") {
if (th === "1.15") th = "1.2";
if (th === "1.55") th = "1.6";
}
// 4) 단가표에서 찾기 (item_bend 배열에 { col1: 재질, col5: 두께, col17: 면적당단가 } 구조 가정)
var matched = item_bend.find(function(item) {
return (item.col1 || "").toString().toUpperCase() === rawMat
&& item.col5 === th;
});
var unitPricePerM2 = matched
? parseFloat(matched.col17.toString().replace(/,/g, ""))
: 0;
// 5) 면적 계산 (mm → m 변환: mm² / 1,000,000)
// length, width가 ''이거나 0일 때는 0, 그 외에는 mm² → m² 계산
const l = parseFloat(length);
const w = parseFloat(width);
const areaM2 = (l > 0 && w > 0)
? (l * w) / 1e6
: 0;
// 6) 총 가격 계산
var total = unitPricePerM2 * areaM2 * qty;
// 7) 소수점 이하 버림 후 반환
return Math.floor(total);
}
// 사용 예시
// var price = getSteelPrice("EGI 1.55T", "1.55", 2000, 1000, 3);
// console.log("총 가격:", price.toLocaleString(), "원");
</script>
<script>
// ─────────────────────────────────────────────────────────────
// 1.4) 숫자만 입력받도록 하는 함수
function inputNumbers(input) {
input.value = input.value.replace(/[^0-9.]/g, '');
}
// ─────────────────────────────────────────────────────────────
// ─────────────────────────────────────────────────────────────
// 1.6) "screenTable"(스크린 작업지시서) 의 총 <th> 개수를 알아오는 함수
// → 비인정테이블을 만들 때, 동일한 개수의 <td>를 만들어주기 위해 사용
function getScreenTableThCount() {
return $('#screenTable thead tr:first-child th').length;
}
// ─────────────────────────────────────────────────────────────
// 1.7) 비인정스크린 각 행을 순회하며 첫 열에 일련번호를 매겨주는 함수
function updateSerialNumbers(tableBody) {
tableBody.find('tr').each(function(index) {
$(this).find('.serial-number').text(index + 1);
});
}
// ─────────────────────────────────────────────────────────────
// 1.8) 비인정스크린 테이블의 헤더 표시/숨김 토글
function toggleTableHeaderVisibility(tableBody) {
const table = tableBody.closest('table');
const thead = table.find('thead');
if (tableBody.find('tr').length === 0) {
thead.hide();
} else {
thead.show();
}
}
// ─────────────────────────────────────────────────────────────
// 1.9) 부호(셀렉트), 직접입력 옵션까지 처리하는 <select> 생성 함수
function createSelect_unapproved(name, opts, selectedVal = '') {
name = name.replace('[]', '');
let html = `<select name="${name}[]" class="form-select form-select-sm text-center col1 ${name}"
style="height:30px; font-size:0.75rem;">`;
// 1) 기본 ("없음") 옵션
// html += `<option value="(없음)" ${selectedVal === '(없음)' ? 'selected' : ''}>(없음)</option>`;
// 2) 기존에 선택된 임의 값 (opts에 없는 경우)
if (selectedVal && !opts.includes(selectedVal) && selectedVal !== '(없음)' && selectedVal !== '(직접입력)') {
html += `<option value="${selectedVal}" selected>${selectedVal}</option>`;
}
// 3) 실제 옵션들
opts.forEach(o => {
html += `<option value="${o}" ${o === selectedVal ? 'selected' : ''}>${o}</option>`;
});
html += `</select>`;
return html;
}
// 비인정철재-슬랫 작업
// 슬랫용 품목 옵션
const slatOptions1 = [
'방화용 1.6T', '방범용 1.2T', '방범용 1.6T',
'이중파이프', '단열셔터', '조인트바', '(직접입력)'
];
const materialOpts = ['(없음)','EGI 1.6T','EGI 1.2T'];
const hingeOpts = ['(없음)','승리','태영','굴비','대신'];
const hingeDirectionOpts = ['(없음)','정방향','역방향'];
// 비인정 철재-슬랫 행 추가 함수 (전역)
function addRowUA_slat(tableBody, afterRow = null, data = {}) {
// memo는 재질을 의미한다. 중요!
data = Object.assign({
item_type:'', floors:'', text1:'', memo:'EGI 1.6T', cutwidth:'', cutheight:'',
number:'1', exititem:'0', intervalnum:'', hinge:'', hingenum:'', hinge_direction:'(없음)', text2:''
}, data);
// ① 품목 셀렉트 생성
const itemTypeSelect = createSelect_unapproved(
'item_type[]',
slatOptions1,
data.item_type
);
// console.log('item_type : ', data.item_type);
// ① mode 값 읽기
const isView = $('#mode').val() === 'view';
// ② 첫 번째 셀(버튼) 생성
let cellsHtml = '<tr><td class="text-center"><div class="d-flex justify-content-center align-items-center">' +
'<span class="serial-number me-2"></span>';
// ③ view 모드가 아닐 때만 버튼 추가
if (!isView) {
cellsHtml += `
<button type="button" class="btn btn-outline-dark btn-sm viewNoBtn me-1 add-row-generic" style="border:0;">+</button>
<button type="button" class="btn btn-outline-danger btn-sm viewNoBtn me-1 remove-row-generic" style="border:0;">-</button>
<button type="button" class="btn btn-outline-secondary btn-sm viewNoBtn copy-row-generic me-1" style="border:0;"><i class="bi bi-files"></i></button>
`;
}
// ④ 셀 닫기
cellsHtml += '</div></td>';
// First column with buttons
cellsHtml += `
<td>${itemTypeSelect}</td>
<td><input type="text" name="floors[]" class="form-control col2 viewNoBtn" value="${data.floors}" placeholder="층" oninput="slat_calculateRow(this)"></td>
<td><input type="text" name="text1[]" class="form-control col3 viewNoBtn" value="${data.text1}" placeholder="부호" oninput="slat_calculateRow(this)"></td>
<td>
<select name="memo[]" class="form-control viewNoBtn" onchange="slat_calculateRow(this)">
${materialOpts.map(o=>`<option ${o===data.memo?'selected':''}>${o}</option>`).join('')}
</select>
</td>
<td><input type="text" name="cutwidth[]" class="form-control col2 viewNoBtn" value="${data.cutwidth}" placeholder="가로(W)" oninput="slat_calculateRow(this)"></td>
<td><input type="text" name="cutheight[]" class="form-control col3 viewNoBtn" value="${data.cutheight}" placeholder="세로(H)" oninput="slat_calculateRow(this)"></td>
<td><input type="text" name="number[]" class="form-control col4 viewNoBtn" value="${data.number}" placeholder="수량(EA)" oninput="slat_calculateRow(this)"></td>
<td>
<select name="exititem[]" class="form-control viewNoBtn" onchange="slat_calculateRow(this)">
<option value="0">(없음)</option>
<option value="1" ${data.exititem==='1'?'selected':''}>중앙</option>
<option value="2" ${data.exititem==='2'?'selected':''}>좌측</option>
<option value="3" ${data.exititem==='3'?'selected':''}>우측</option>
</select>
</td>
<td><input type="text" name="intervalnum[]" class="form-control intervalnum viewNoBtn" value="${data.intervalnum}" placeholder="띄울치수" oninput="slat_calculateRow(this)"></td>
<td>
<select name="hinge[]" class="form-control viewNoBtn" onchange="slat_calculateRow(this)">
${hingeOpts.map(o=>`<option ${o===data.hinge?'selected':''}>${o}</option>`).join('')}
</select>
</td>
<td><input type="text" name="hingenum[]" class="form-control hingenum viewNoBtn" value="${data.hingenum}" placeholder="힌지치수" readonly></td>
<td>
<select class="form-control hinge_direction text-center" name="hinge_direction[]">
${hingeDirectionOpts.map(o=>`<option ${o===data.hinge_direction?'selected':''}>${o}</option>`).join('')}
</select>
</td>
<td>
<input
type="text" class="form-control text2 text-start" name="text2[]" value="<?=$text2?>" style="font-size: 11px!important;" title="<?=$text2?>" readonly >
</td>
`;
// 4) 숨김 필드
cellsHtml += `<td style="display:none;"><input type="hidden" name="done_check[]" value="${data.done_check||''}"></td></tr>`;
// 행 삽입
if (afterRow && afterRow.length) {
afterRow.after(cellsHtml);
} else {
tableBody.append(cellsHtml);
}
// .serial-number 클래스 있어야 함
updateSerialNumbers(tableBody);
// 헤더 표시 여부 조절
toggleTableHeaderVisibility(tableBody);
// 1.6T, 1.2T 선택에 따라 재질선택하는 동적코드
$(document).on('change', 'select[name="item_type[]"]', function() {
const val = $(this).val() || '';
const $memo = $(this).closest('tr').find('select[name="memo[]"]');
if (val.includes('1.6')) {
$memo.val('EGI 1.6T').trigger('change');
}
else if (val.includes('1.2')) {
$memo.val('EGI 1.2T').trigger('change');
}
else {
$memo.val('(없음)').trigger('change');
}
});
// 비상문 선택에 따른 처리
$(document).on('change', 'select[name="exititem[]"]', function() {
const val = $(this).val() || '';
const intervalnum = $(this).closest('tr').find('input[name="intervalnum[]"]');
const hinge = $(this).closest('tr').find('select[name="hinge[]"]');
const hingeDirection = $(this).closest('tr').find('select[name="hinge_direction[]"]');
const hingenum = $(this).closest('tr').find('input[name="hingenum[]"]');
console.log('비상문 변경 클릭', val);
if (val.includes('0')) { // 0은 없음
intervalnum.val('');
hinge.val('(없음)');
hingeDirection.val('(없음)');
hingenum.val('');
}
else if (val.includes('1') || val.includes('2') || val.includes('3')) { // 1,2,3은 중앙, 좌측, 우측
hinge.val('(없음)');
hingeDirection.val('(없음)');
intervalnum.val('');
hingenum.val('');
}
});
if ($("#mode").val() == 'view') {
disableView();
}
slat_updateTotals();
// console.log('slat_unapprovedListBody : ', slat_unapprovedListBody);
}
$('#slat_unapprovedTable').on('input', 'input, select', function() {
slat_calculateRow(this);
}).on('change', 'select', function() {
slat_calculateRow(this);
slat_updateTotals();
});
// 변환버튼 이벤트 바인딩
$(document).ready(function() {
$('#convertUnapprovedBtn').on('click', function() {
Swal.fire({
title: '스크린 작업지시서 덮어쓰기 확인',
text: '기존자료에 덮어씁니다. 정말 적용하시겠습니까?',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '확인',
cancelButtonText: '취소'
}).then((result) => {
if (result.isConfirmed) {
$('#screenTable').empty();
$('#screen_unapprovedTable tbody tr').each(function() {
const $uRow = $(this);
const convertData = {
// addRow 이 기대하는 key 이름으로 맞춰서
col2: $uRow.find('input[name="floors[]"]').val() || '',
col3: $uRow.find('input[name="text1[]"]').val() || '',
col5: $uRow.find('select[name="item_type[]"]').val() || '', // select 주의 실리카,.... 등 표시
col10: $uRow.find('input[name="cutwidth[]"]').val() || '',
col11: $uRow.find('input[name="cutheight[]"]').val() || '',
col14: $uRow.find('input[name="number[]"]').val() || '1',
exititem: $uRow.find('select[name="exititem[]"]').val() || '0',
printside: $uRow.find('select[name="printside[]"]').val() || '',
direction: $uRow.find('select[name="direction[]"]').val() || '',
intervalnum: $uRow.find('input[name="intervalnum[]"]').val() || '',
intervalnumsecond:$uRow.find('input[name="intervalnumsecond[]"]').val()|| '',
exitinterval: $uRow.find('input[name="exitinterval[]"]').val() || '',
cover: $uRow.find('input[name="cover[]"]').val() || '',
drawbottom1: $uRow.find('input[name="drawbottom1[]"]').val() || '',
drawbottom3: $uRow.find('input[name="drawbottom3[]"]').val() || '',
drawbottom2: $uRow.find('input[name="drawbottom2[]"]').val() || '',
draw: $uRow.find('input[name="draw[]"]').val() || '',
text2: $uRow.find('input[name="text2[]"]').val() || '',
done_check: $uRow.find('input[name="done_check[]"]').val() || '',
remain_check: $uRow.find('input[name="remain_check[]"]').val() || '',
mid_check: $uRow.find('input[name="mid_check[]"]').val() || '',
left_check: $uRow.find('input[name="left_check[]"]').val() || '',
right_check: $uRow.find('input[name="right_check[]"]').val() || ''
};
console.log('비인정스크린 convertData : ', convertData);
// ② addRow를 호출하면, 내부에서 estimateData를 보고 모든 <input> / <select>를 한 번에 세팅한다
addRow(null, convertData);
alertToast('비인정스크린 변환 완료');
});
}
});
});
});
</script>
<script>
$(document).ready(function() {
$('#convertUnapproved_slatBtn').on('click', function() {
Swal.fire({
title: '철재-슬랫 작업지시서 덮어쓰기 확인',
text: '기존자료에 덮어씁니다. 정말 적용하시겠습니까?',
icon: 'warning',
showCancelButton: true,
confirmButtonText: '확인',
cancelButtonText: '취소'
}).then((result) => {
if (result.isConfirmed) {
// 기존 발주서 비우기
$('#slatTable').empty();
// 비인정테이블의 각 행을 순회하며 변환
$('#slat_unapprovedTable tbody tr').each(function() {
const $uRow = $(this);
const convertData = {
// addRow_slat 이 기대하는 key 이름으로 맞춰서
col2: $uRow.find('input[name="floors[]"]').val() || '',
col3: $uRow.find('input[name="text1[]"]').val() || '',
col4: $uRow.find('select[name="item_type[]"]').val() || '', // select 주의
col5: $uRow.find('input[name="cutwidth[]"]').val() || '',
col6: $uRow.find('input[name="cutheight[]"]').val() || '',
col7: $uRow.find('input[name="number[]"]').val() || '1',
exititem: $uRow.find('select[name="exititem[]"]').val() || '0',
intervalnum: $uRow.find('input[name="intervalnum[]"]').val() || '',
hinge: $uRow.find('select[name="hinge[]"]').val() || '',
hingenum: $uRow.find('input[name="hingenum[]"]').val() || '',
hinge_direction: $uRow.find('select[name="hinge_direction[]"]').val() || '',
text2: $uRow.find('input[name="text2[]"]').val() || '',
done_check: $uRow.find('input[name="done_check[]"]').val() || ''
};
// addRow_slat 호출 (첫 번째 인자 null: 맨 끝에 추가)
addRow_slat(null, convertData);
});
// 완료 토스트
alertToast('비인정 철재-슬랫 변환 완료');
}
});
});
});
</script>
<?php include $_SERVER['DOCUMENT_ROOT'] . '/common/fileImage.php'; // 파일과 이미지 불러오고 저장하는 서브모듈 ?>
<script>
// 인정 체크박스 이벤트 리스너
$(document).ready(function() {
$('#warranty').on('change', function() {
const commentTextarea = $('#comment');
const currentComment = commentTextarea.val();
const warrantyText = '★인정제품★';
if (this.checked) {
// 체크되었을 때: 비고란 맨 앞에 '★인정제품★' 문구 추가
if (!currentComment.includes(warrantyText)) {
commentTextarea.val(warrantyText + (currentComment ? ' ' : '') + currentComment);
}
} else {
// 체크 해제되었을 때: 비고란에서 '★인정제품★' 문구 제거
const newComment = currentComment.replace(new RegExp(warrantyText + '\\s*\\n?', 'g'), '');
commentTextarea.val(newComment);
}
});
});
</script>