우리가 많이 사용하는 거래명세표...
Ecount ERP의 화면은 아래와 같지요.
위의 거래명세표를 php와 자바스크립트를 이용해서 구현해 보는 것입니다.
기존의 인정제품의 거래명세표 양식이 있어서 이를 수정해서 위의 형태 테이블로 만들어야 할 것 같군요.
그래도 폼이 이전에 만든것이 있어서 활용한다는 것은 시간절약에 도움이 되겠네요.
인정제품의 거래명세표에서 '제품명'은 제거해야겠네요. 비인정제품이니...
완성된 코드는 아래와 같습니다.
<?php
// EsDetail_screen.php 견적파일을 output 수주에서 사용하게 개선한 코드임.
require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
// output_head.php에서 사용할 변수 선언
$title_message = '거래명세서 ';
$title_message_sub = '거래명세서';
$tablename = 'output'; // 수주 테이블
$item = '거래명세서 ';
$emailTitle = '거래명세서';
$subTitle = '비인정제품';
// 필요한 함수가 있다면 공통 유틸 파일 포함
if (!function_exists('number_to_korean')) {
@include_once($_SERVER['DOCUMENT_ROOT'] . '/lib/common.php'); // 예: 함수 정의 파일
}
?>
<?php include $_SERVER['DOCUMENT_ROOT'] . '/load_header.php';
// 수주내역에서 거래명세표 표시
$selectWork = '거래명세표';
?>
<title> <?=$title_message?> </title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<?php
$num = isset($_REQUEST['num']) ? $_REQUEST['num'] : '';
// echo 'num: ' . $num . '<br>';
// echo 'DB: ' . $DB . '<br>';
// echo 'tablename: ' . $tablename . '<br>';
$option = isset($_REQUEST['option']) ? $_REQUEST['option'] : ''; // 견적서와 산출서의 다른점을 표현하는 것
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/estimate/fetch_unitprice.php");
$pdo = db_connect();
try {
$sql = "select * from {$DB}.{$tablename} where num = ? ";
$stmh = $pdo->prepare($sql);
$stmh->bindValue(1, $num, PDO::PARAM_STR);
$stmh->execute();
$count = $stmh->rowCount();
if ($count < 1) {
print "검색결과가 없습니다.<br>";
} else {
$row = $stmh->fetch(PDO::FETCH_ASSOC);
include $_SERVER['DOCUMENT_ROOT'] . "/output/_row.php";
// output_extra 불러오기
$sql_extra = "SELECT * FROM {$DB}.output_extra WHERE parent_num = ?";
$stmh_extra = $pdo->prepare($sql_extra);
$stmh_extra->bindValue(1, $num, PDO::PARAM_STR);
$stmh_extra->execute();
$row_extra = $stmh_extra->fetch(PDO::FETCH_ASSOC);
if ($row_extra) {
include $_SERVER['DOCUMENT_ROOT'] . "/output/_row_extra.php";
}
// echo '<pre> ';
// print_r($estimateSlatList);
// echo '</pre>';
}
} catch (PDOException $Exception) {
print "오류: " . $Exception->getMessage();
}
// 회계 데이터를 row_extra에서 불러옵니다
$accountList = isset($row_extra['accountList']) ? $row_extra['accountList'] : '';
// 디버그: 원본 데이터 확인
echo '<div style="display:none;" id="debug-original">';
echo 'Original accountList: ';
var_dump($accountList);
echo '</div>';
// 디버그: JSON 디코딩 전 데이터 타입 확인
echo '<div style="display:none;" id="debug-type">';
echo 'Type of accountList: ';
var_dump(gettype($accountList));
echo '</div>';
$decodedAccountList = json_decode($accountList, true);
// 디버그: JSON 디코딩 결과 확인
echo '<div style="display:none;" id="debug-decode">';
echo 'Decoded accountList: ';
var_dump($decodedAccountList);
echo '</div>';
// 디버그: JSON 디코딩 오류 확인
echo '<div style="display:none;" id="debug-json-error">';
echo 'JSON decode error: ';
var_dump(json_last_error());
echo 'JSON decode error message: ';
var_dump(json_last_error_msg());
echo '</div>';
// 디코딩된 데이터가 배열인지 확인합니다.
if (!is_array($decodedAccountList)) {
echo '<div class="alert alert-danger">';
echo '데이터가 정상적이지 않습니다. 확인바랍니다.<br>';
echo 'Error Type: ' . gettype($decodedAccountList) . '<br>';
echo 'JSON Error: ' . json_last_error_msg() . '<br>';
echo '</div>';
exit;
}
// 디버그: 배열 구조 확인
echo '<div style="display:none;" id="debug-structure">';
echo 'Array structure: ';
print_r($decodedAccountList);
echo '</div>';
// 디코딩된 데이터를 JavaScript 변수로 전달
echo '<script>';
echo 'var accountListData = ' . json_encode($decodedAccountList) . ';';
echo 'console.log("accountListData:", accountListData);'; // JavaScript 콘솔에 데이터 출력
echo '</script>';
$shutterboxMsg = '';
// 테이블 데이터 처리
$totalSupply = 0;
$totalVat = 0;
$totalAmount = 0;
$rowCount = 0;
foreach ($decodedAccountList as $item) {
$supplyAmount = floatval(str_replace(',', '', $item['col6']));
$vatAmount = floatval(str_replace(',', '', $item['col7']));
$total = $supplyAmount + $vatAmount;
$totalSupply += $supplyAmount;
$totalVat += $vatAmount;
$totalAmount += $total;
$rowCount++;
}
// ET_unapproved와 ET_total 설정
$ET_unapproved = $totalAmount;
$ET_total = $ET_unapproved + (isset($estimateTotal) ? floatval(str_replace(',', '', $estimateTotal)) : 0);
?>
<form id="board_form" name="board_form" method="post" enctype="multipart/form-data">
<input type="hidden" id="mode" name="mode" value="<?= isset($mode) ? $mode : '' ?>">
<input type="hidden" id="num" name="num" value="<?= isset($num) ? $num : '' ?>">
<input type="hidden" id="user_name" name="user_name" value="<?= isset($user_name) ? $user_name : '' ?>">
<input type="hidden" id="update_log" name="update_log" value="<?= isset($update_log) ? $update_log : null ?>">
<input type="hidden" id="tablename" name="tablename" value="<?= isset($tablename) ? $tablename : '' ?>">
<input type="hidden" id="header" name="header" value="<?= isset($header) ? $header : '' ?>">
<div class="container mt-2">
<div class="d-flex align-items-center justify-content-end mt-3 m-1 mb-4">
<button type="button" class="btn btn-dark btn-sm ms-1 me-1" onclick="generatePDF()"> PDF 저장 </button>
<button type="button" class="btn btn-dark btn-sm me-1" onclick="sendmail();"> <i class="bi bi-envelope-arrow-up"></i> 전송 </button>
<button type="button" class="btn btn-secondary btn-sm ms-5" onclick="self.close();"> × 닫기 </button>
</div>
<br>
</div>
</form>
<div id="content-to-print">
<br>
<div class="container mt-1">
<div class="d-flex align-items-center justify-content-center ">
<table class="table table-sm" style="border-collapse: collapse;">
<tbody>
<tr>
<td class="text-center align-middle fw-bold fs-4" style="border-top:none; border-bottom:none;" >
<?php
if($option!=='option')
echo '<span class="text-dark"> ' . $title_message . ' </span> </td>'; // <span id="updateText" class="text-danger"> </span>
else
echo '<span class="text-dark"> ' . $title_message_sub . ' </span> </td>';
?>
</tr>
</tbody>
</table>
</div>
<div class="d-flex align-items-center justify-content-center ">
<table class="table" style="border-collapse: collapse;">
<tbody>
<tr>
<td class="text-center fw-bold yellowBold " style="width:10%;">업체명</td>
<td class="text-center yellowBold " style="width:40%;"> <?=$secondord?> (귀하) </td>
<td rowspan="5" class="text-center align-middle fw-bold" style="width:5%; border-top:none; border-bottom:none;" >공 급 자</td>
<td class="text-center fw-bold lightgray " > 상호 </td>
<td class="text-center fw-bold" colspan="3" >㈜ 경동기업 </td>
</tr>
<tr>
<td class="text-center fw-bold">제품명</td>
<td class="text-center" > <?=$subTitle?> </td>
<td class="text-center fw-bold lightgray " style="width:10%;" >등록번호</td>
<td class="text-center" style="width:10%;"> 139-87-00333 </td>
<td class="text-center fw-bold lightgray " >대표자</td>
<td class="text-center fw-bold">
<div class="d-flex align-items-center justify-content-center ">
이 경 호
<!-- <img src="../img/daehanstamp.png" alt="도장" style="width:45px; height:45px;"> -->
</div>
</td>
<tr>
<td class="text-center fw-bold">현장명</td>
<td class="text-center fw-bold" > <?=$outworkplace?></td>
<td class="text-center fw-bold lightgray " > 사업장주소 </td>
<td colspan="3" class="text-center"> 경기도 김포시 통진읍 옹정로 45-22</td>
</tr>
<tr>
<td class="text-center fw-bold">담당자</td>
<td class="text-center"><?=$secondordman?></td>
<td class="text-center fw-bold lightgray " > 업 태 </td>
<td class="text-center" > 제조업 </td>
<td class="text-center fw-bold lightgray " >종목</td>
<td class="text-center" > 방화셔터, 금속창호 </td>
</tr>
<tr>
<td class="text-center fw-bold">연락처</td>
<td class="text-center"><?=$secondordmantel?></td>
<td class="text-center fw-bold lightgray " > TEL. </td>
<td class="text-center" > 031-983-5130</td>
<td class="text-center fw-bold lightgray " > FAX </td>
<td class="text-center" > 02-6911-6315 </td>
</tr>
</tbody>
</table>
</div>
<div class="d-flex align-items-center justify-content-center ">
<table class="table" style="border-collapse: collapse;">
<tbody>
<tr>
<td class="text-center fw-bold" style="width:250px;" >
합계 금액(VAT포함) <br>
아래와 같이 계산합니다.
</td>
<td class="text-center align-middle fs-6 fw-bold" style="width:50px;"> 금 </td>
<td rowspan="5" class="text-end align-middle fw-bold fs-6" style="width:500px;" > <span id="koreantotalsum"> </span> </td>
<td class="text-center fw-bold align-middle fs-6" style="width:50px;" > 원 </td>
<td class="align-middle text-end fs-6 fw-bold" style="width:250px;"> ( ₩ <span id="totalsum"> </span> )</td>
</tr>
</tbody>
</table>
</div>
<?php
// 전체 SET 내역 표시 일련번호, 종류, 부호, 제품명, 오픈사이즈 등 전체금액 나오는 부분
// 2025/05/23 모터 견적가 포함 검색 추가
// 견적서, 거래명세표는 테이블형태가 다름, 거래명세표는 부가세 부분 표시하고 합계를 나타냄
if(True) {
$data = [];
$counter = 0;
$index = 0;
$sums = []; // 각 행의 합을 저장할 배열
$col7_sum = 0; // col7 수량 합계
$col89_sum = 0; // col8 + col9 합계
$col10_sum = 0;
$row_count = 0;
echo '<div class="d-flex align-items-center justify-content-center ">';
echo '<table id="tableDetail" class="table table-bordered">';
echo '<thead>';
echo '<tr>';
echo '<th>월/일</th>';
echo '<th>품명 및 규격</th>';
echo '<th>수량</th>';
echo '<th>단가</th>';
echo '<th>공급가액</th>';
echo '<th>부가세</th>';
echo '<th>합계</th>';
echo '<th>비고</th>';
echo '</tr>';
echo '</thead>';
echo '<tbody>';
// 전체 반복 찾기
foreach ($decodedAccountList as $item) {
// 품목명과 규격 정보 가져오기
$itemTitle = $item['col2'] ;
$specifications = '';
if (isset($item['col2']) && isset($item['col3'])) {
$specifications = $item['col2'] . '[' . $item['col3'] . ']';
}
// 수량과 단가 정보
$quantity = floatval(str_replace(',', '', $item['col4']));
$unitPrice = floatval(str_replace(',', '', $item['col5']));
// 금액 계산
$supplyAmount = $quantity * $unitPrice;
$vat = round($supplyAmount * 0.1);
$total = $supplyAmount + $vat;
// 비고
$remarks = '';
echo '<tr class="calculation-row calculation-firstrow" data-row="' . $row_count . '" data-serial="' . $row_count . '">';
echo '<td class="text-center">' . date('m/d') . '</td>';
echo '<td class="text-start ">' . htmlspecialchars($itemTitle) . ' ' . htmlspecialchars($specifications) . '</td>';
echo '<td class="text-end total-su-input" data-serial="' . $row_count . '">' . $quantity . '</td>';
echo '<td class="text-end text-dark total-unit-price" data-serial="' . $row_count . '">' . number_format($unitPrice) . '</td>';
echo '<td class="text-end subtotal-cell" data-serial="' . $row_count . '">' . number_format($supplyAmount) . '</td>';
echo '<td class="text-end vat-cell" data-serial="' . $row_count . '">' . number_format($vat) . '</td>';
echo '<td class="text-end fw-bold subtotalamount-cell" data-serial="' . $row_count . '">' . number_format($total) . '</td>';
echo '<td class="text-center w150px">' . htmlspecialchars($remarks) . '</td>';
echo '</tr>';
$col7_sum += $quantity;
$supply_sum += $supplyAmount;
$vat_sum += $vat;
$total_sum += $total;
$row_count++;
}
// 소계 행 추가
echo '<tr class="subtotal">';
echo '<td class="text-center" colspan="2"><strong>소계</strong></td>';
echo '<td class="text-end fw-bold ">' . number_format($col7_sum) . '</td>';
echo '<td class="text-end fw-bold "></td>';
echo '<td class="text-end fw-bold ">' . number_format($supply_sum) . '</td>';
echo '<td class="text-end fw-bold ">' . number_format($vat_sum) . '</td>';
echo '<td class="text-end fw-bold grand-sum">' . number_format($total_sum) . '</td>';
echo '</tr>';
echo '</tbody>';
echo '</table>';
echo '</div>';
}
// 비고
echo '<div class="d-flex align-items-center justify-content-center mt-5 mb-5 ">';
echo '<table class="table mt-3" style="border-collapse: collapse;">';
echo '<thead>';
echo '<tr>'; // 2행
echo '<th colspan="1" class="text-center">계좌정보</th>';
echo '<th colspan="1" class="text-start">국민은행 796801-00-039630 예금주 : (주)경동기업 </th>';
echo '<th colspan="1" class="text-center">E-mail</th>';
echo '<th colspan="1" class="text-center"> <span class="text-primary" > kd5130@naver.com </span> </th>';
echo '</tr>';
echo '</thead>';
echo '</table>';
echo '</div>';
?>
</div> <!-- end of container -->
<div class="container mb-5 mt-2">
<div class="d-flex align-items-center justify-content-center mb-5">
</div>
</div>
<script>
// 견적서의 lastJS를 변형해서 수주내역에서 인정제품의 거래명세표를 저장하기 위함이다.
var ajaxRequest_write = null;
$(document).ready(function() {
$('#loadingOverlay').hide(); // 로딩 오버레이 숨기기
});
function inputNumber(input) {
const value = input.value.replace(/,/g, ''); // 콤마 제거
input.value = parseInt(value, 10).toLocaleString(); // 다시 콤마 추가
calculateRowTotal($(input).closest('tr')); // 행의 합계 다시 계산
}
function generatePDF() {
var title_message = '<?php echo $title_message; ?>';
var workplace = '<?php echo $outworkplace; ?>';
var deadline = '<?php echo $indate; ?>';
var deadlineDate = new Date(deadline);
var formattedDate = "(" + String(deadlineDate.getFullYear()).slice(-2) + "." + ("0" + (deadlineDate.getMonth() + 1)).slice(-2) + "." + ("0" + deadlineDate.getDate()).slice(-2) + ")";
var result = 'KD' + title_message + '(' + workplace +')' + formattedDate + '.pdf';
var element = document.getElementById('content-to-print');
// 강제로 input 요소의 폰트 크기 변경
var inputs = element.querySelectorAll('input');
inputs.forEach(function(input) {
input.style.fontSize = '6px'; // 모든 input 요소에 10px 폰트 크기 적용
});
var opt = {
margin: [15, 8, 17, 8], // Top, right, bottom, left margins
filename: result,
image: { type: 'jpeg', quality: 0.70 },
html2canvas: { scale: 4 },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
pagebreak: { mode: [''] }
};
html2pdf().from(element).set(opt).save();
}
$(document).ready(function () {
var rowArray = <?= isset($row_array_json) ? $row_array_json : '[]' ?>;
if (Array.isArray(rowArray) && rowArray.length > 0) {
rowArray.forEach(function (rowspanValue, index) {
var cell = document.getElementById('dynamicRowspan-' + index);
console.log('index', index);
if (cell && rowspanValue > 0) {
cell.setAttribute('rowspan', rowspanValue);
}
});
}
});
// 숫자 포맷팅 함수 (콤마 추가 및 소수점 둘째자리에서 반올림)
function formatNumber(value) {
// 소수점 둘째 자리에서 반올림
const roundedValue = Math.round(value);
// 콤마 추가 포맷팅
return new Intl.NumberFormat().format(roundedValue);
}
// 숫자에서 콤마를 제거하는 함수
function cleanNumber(value) {
// value가 null 또는 undefined인 경우 0을 반환하도록 처리
if (!value) return 0;
return parseFloat(value.replace(/,/g, '')) || 0;
}
// 입력 필드에서 숫자를 포맷팅하는 함수
function inputNumber(input) {
const cursorPosition = input.selectionStart; // 현재 커서 위치를 저장
const value = input.value.replace(/,/g, ''); // 입력값에서 숫자만 남기고 제거
const formattedValue = Number(value).toLocaleString(); // 천 단위 콤마 추가
input.value = formattedValue; // 포맷팅된 값으로 설정
input.setSelectionRange(cursorPosition, cursorPosition); // 커서 위치 유지
}
// 숫자만 남기는 헬퍼
function cleanNumber(str) {
return Number(String(str).replace(/[^0-9.-]/g, '')) || 0;
}
// 3자리마다 콤마 찍되, 먼저 소수점 이하는 반올림 처리
function formatNumber(num) {
// 1) 문자열이면 콤마 없애고 숫자로 변환
const value = typeof num === 'string'
? parseFloat(num.replace(/,/g, ''))
: num;
// 2) 소수점 이하 반올림
const rounded = Math.round(value || 0);
// 3) 천 단위 구분자 추가
return rounded.toLocaleString();
}
// 한글 숫자 변환 함수
function KoreanNumber(number) {
const koreanNumbers = ['', '일', '이', '삼', '사', '오', '육', '칠', '팔', '구'];
const koreanUnits = ['', '십', '백', '천'];
const bigUnits = ['', '만', '억', '조'];
let result = '';
let unitIndex = 0;
let numberStr = String(number);
// 숫자가 0인 경우 '영원'을 반환
if (number == 0) return '영원';
// 뒤에서부터 4자리씩 끊어서 처리
while (numberStr.length > 0) {
let chunk = numberStr.slice(-4); // 마지막 4자리
numberStr = numberStr.slice(0, -4); // 나머지 숫자
let chunkResult = '';
for (let i = 0; i < chunk.length; i++) {
const digit = parseInt(chunk[i]);
if (digit > 0) {
chunkResult += koreanNumbers[digit] + koreanUnits[chunk.length - i - 1];
}
}
if (chunkResult) {
result = chunkResult + bigUnits[unitIndex] + result;
}
unitIndex++;
}
// 불필요한 '일십', '일백', '일천' 등의 단위를 제거하고 '원'을 붙여 반환
result = result.replace(/일(?=십|백|천)/g, '').trim();
return result + '원';
}
function removeAllButLastOccurrence(string, target) {
// 마지막 '만'의 위치를 찾습니다
const lastPos = string.lastIndexOf(target);
// 마지막 '만'이 없으면 원래 문자열을 반환합니다
if (lastPos === -1) {
return string;
}
// 마지막 '만'을 제외한 모든 '만'을 제거합니다
const beforeLastPos = string.slice(0, lastPos);
const afterLastPos = string.slice(lastPos);
// '만'을 빈 문자열로 대체합니다
const result = beforeLastPos.replace(new RegExp(target, 'g'), '') + afterLastPos;
return result;
}
function generatePDF_server(callback) {
var workplace = '<?php echo $title_message; ?>';
var item = '<?php echo $emailTitle; ?>';
var today = new Date();
var formattedDate = "(" + String(today.getFullYear()).slice(-2) + "." + ("0" + (today.getMonth() + 1)).slice(-2) + "." + ("0" + today.getDate()).slice(-2) + ")";
var result = 'KD' + item +'(' + workplace + ')' + formattedDate + '.pdf';
var element = document.getElementById('content-to-print');
var opt = {
margin: [10, 3, 12, 3], // Top, right, bottom, left margins
filename: result,
image: { type: 'jpeg', quality: 0.70 },
html2canvas: { scale: 4 },
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
pagebreak: { mode: [''] }
};
html2pdf().from(element).set(opt).output('datauristring').then(function (pdfDataUri) {
var pdfBase64 = pdfDataUri.split(',')[1]; // Base64 인코딩된 PDF 데이터 추출
var formData = new FormData();
formData.append('pdf', pdfBase64);
formData.append('filename', result);
$.ajax({
type: 'POST',
url: '/email/save_pdf.php', // PDF 파일을 저장하는 PHP 파일
data: formData,
processData: false,
contentType: false,
success: function (response) {
var res = JSON.parse(response);
if (callback) {
callback(res.filename); // 서버에 저장된 파일 경로를 콜백으로 전달
}
},
error: function (xhr, status, error) {
Swal.fire('Error', 'PDF 저장에 실패했습니다.', 'error');
}
});
});
}
var ajaxRequest = null;
function sendmail() {
var secondordnum = '<?php echo $secondordnum; ?>'; // 서버에서 가져온 값
var item = '<?php echo $emailTitle; ?>';
if (!secondordnum) {
Swal.fire({
icon: 'warning',
title: '오류 알림',
text: '발주처 코드가 없습니다.'
});
return; // 함수 종료
}
if (typeof ajaxRequest !== 'undefined' && ajaxRequest !== null) {
ajaxRequest.abort();
}
ajaxRequest = $.ajax({
type: 'POST',
url: '/email/get_companyCode.php',
data: { secondordnum: secondordnum },
dataType: 'json',
success: function(response) {
console.log('response : ', response);
if (response.error) {
Swal.fire('Error', response.error, 'error');
} else {
var email = response.email;
var vendorName = response.vendor_name;
Swal.fire({
title: 'E메일 보내기',
text: vendorName + ' Email 주소확인',
icon: 'warning',
input: 'text', // input 창을 텍스트 필드로 설정
inputLabel: 'Email 주소 수정 가능',
inputValue: email, // 기존 이메일 주소를 기본값으로 설정
showCancelButton: true,
confirmButtonText: '보내기',
cancelButtonText: '취소',
reverseButtons: true,
inputValidator: (value) => {
if (!value) {
return '이메일 주소를 입력해주세요!';
}
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailPattern.test(value)) {
return '올바른 이메일 형식을 입력해주세요!';
}
}
}).then((result) => {
if (result.isConfirmed) {
const updatedEmail = result.value; // 입력된 이메일 주소 가져오기
generatePDF_server(function(filename) {
sendEmail(updatedEmail, vendorName, item, filename);
});
}
});
}
},
error: function(xhr, status, error) {
Swal.fire('Error', '전송중 오류가 발생했습니다.', 'error');
}
});
}
function sendEmail(recipientEmail, vendorName, item, filename) {
if (typeof ajaxRequest !== 'undefined' && ajaxRequest !== null) {
ajaxRequest.abort();
}
var today = new Date();
var formattedDate = "(" + String(today.getFullYear()).slice(-2) + "." + ("0" + (today.getMonth() + 1)).slice(-2) + "." + ("0" + today.getDate()).slice(-2) + ")";
ajaxRequest = $.ajax({
type: 'POST',
url: '/email/send_email.php', // 이메일 전송을 처리하는 PHP 파일
data: { email: recipientEmail, vendorName: vendorName, filename: filename, item: item, formattedDate: formattedDate },
success: function(response) {
console.log(response);
Swal.fire('Success', '정상적으로 전송되었습니다.', 'success');
},
error: function(xhr, status, error) {
Swal.fire('Error', '전송에 실패했습니다. 확인바랍니다.', 'error');
}
});
}
// 페이지 로드 완료 후 실행
document.addEventListener('DOMContentLoaded', function() {
// 총액 계산
let totalAmount = 0;
const rows = document.querySelectorAll('#tableDetail tbody tr:not(.subtotal)');
rows.forEach(row => {
const amountCell = row.querySelector('.subtotalamount-cell');
if (amountCell) {
const amount = parseFloat(amountCell.textContent.replace(/,/g, '')) || 0;
totalAmount += amount;
}
});
// 숫자 형식으로 표시
const totalsumElement = document.getElementById('totalsum');
if (totalsumElement) {
totalsumElement.textContent = totalAmount.toLocaleString();
}
// 한글 형식으로 표시
const koreantotalsumElement = document.getElementById('koreantotalsum');
if (koreantotalsumElement) {
koreantotalsumElement.textContent = KoreanNumber(totalAmount);
}
// ET_unapproved와 ET_total 업데이트
const etUnapproved = document.getElementById('ET_unapproved');
const etTotal = document.getElementById('ET_total');
if (etUnapproved) {
etUnapproved.value = totalAmount;
}
if (etTotal) {
etTotal.value = totalAmount;
}
// 부모 창이 있는 경우 부모 창의 값도 업데이트
if (window.opener) {
const parentET_unapproved = window.opener.document.getElementById('ET_unapproved');
const parentET_total = window.opener.document.getElementById('ET_total');
if (parentET_unapproved) {
parentET_unapproved.value = totalAmount;
}
if (parentET_total) {
parentET_total.value = totalAmount;
}
}
});
</script>
</body>
</html>
약 700줄의 코드가 완성되었는데, 실제 실행하면 아래의 화면이 나옵니다.
2시간동안 연구끝에 성공... 휴...
반응형
'IT tech Coding > php' 카테고리의 다른 글
ob_start()란 무엇인가요? PHP에서 헤더 오류를 막는 필수 함수! (0) | 2025.06.10 |
---|---|
PHP select 태그에서 대소문자 구분 없이 selected 처리하는 방법 (0) | 2025.05.28 |
PHP 경고 메시지 "A non well formed numeric value encountered" 해결 방법 (0) | 2025.03.25 |
PHP에서 JSON 데이터를 활용해 각 항목의 상태를 자동으로 판정하는 방법 (0) | 2025.03.23 |
수입검사 품목에 대한 통계자료 작성 코드 (0) | 2025.03.13 |