티스토리 뷰

반응형

몇시간째 고생해서.. 만든코드입니다.

소계,합계

산출내역서... 가지고 만들어봅니다.


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 formatNumber(value) {
    return new Intl.NumberFormat().format(value);
}

// 숫자에서 콤마를 제거하는 함수
function cleanNumber(value) {
    return parseFloat(value.replace(/,/g, '')) || 0;
}

function calculateRowTotal(row) {
    const suInput = row.querySelector('.su-input');
    const areaLengthInput = row.querySelector('.area-length-input');
    const areaPriceInput = row.querySelector('.area-price-input');    
    const unitPriceInput = row.querySelector('.unit-price-input');

// 요소가 존재하는지 확인 후 값 읽기
const su = suInput ? cleanNumber(suInput.value) : 1;
const areaLength = areaLengthInput ? cleanNumber(areaLengthInput.value) : 1; // 없으면 1로 처리
const areaPrice = areaPriceInput ? cleanNumber(areaPriceInput.value) : 1;
let unitPrice = unitPriceInput ? cleanNumber(unitPriceInput.value)  : 1;

let totalPrice = 0;

// areaPrice 소수점 둘째 자리까지 반올림
const roundedAreaPrice = parseFloat(areaPrice.toFixed(2)); 

// 콘솔에 현재 값을 출력해보기
console.log('수량(su):', su);
console.log('면적 길이(areaLength):', areaLength);
console.log('면적 단가(roundedAreaPrice):', roundedAreaPrice);
console.log('단가(unitPrice):', unitPrice);

if (roundedAreaPrice) {
   unitPrice = areaLength * roundedAreaPrice; // 기본 수량 * 단가
   totalPrice = Math.ceil(su * parseFloat(unitPrice.toFixed(0))); // 기본 수량 * 단가
   console.log('계산된 단가 (unitPrice):', unitPrice);
   console.log('계산된 총합(totalPrice):', totalPrice);
}
else if (areaLength) {
   totalPrice = Math.ceil( su * areaLength *  parseFloat(unitPrice.toFixed(0)) ) ; // 기본 수량 * 단가
   console.log('계산된 총합(totalPrice) (면적이 있을 경우):', totalPrice);
}
else {
   totalPrice = Math.ceil(su *  parseFloat(unitPrice.toFixed(0)) ); // 기본 수량 * 단가   
   console.log('계산된 총합(totalPrice) (면적이 없을 경우):', totalPrice);
}
    // 총 합계를 표시
    const totalCell = row.querySelector('.total-price');
    if (totalCell) {
        totalCell.textContent = formatNumber(totalPrice);
    }

    return Math.ceil(totalPrice);
}

function calculateSubtotalBySerial(serialNumber) {
    let subtotal = 0;

    // 해당 일련번호에 해당하는 행들만 선택
    const rows = document.querySelectorAll(`.calculation-row[data-serial="${serialNumber}"]`);
    rows.forEach(row => {
        subtotal += calculateRowTotal(row); // 각 행의 총 합계 계산
    });

    // 해당 일련번호의 소계 셀 업데이트
    const subtotalCell = document.querySelector(`.subtotal-cell[data-serial="${serialNumber}"]`);
    if (subtotalCell) {
        subtotalCell.textContent = formatNumber(subtotal);
    } else {
        console.error(`소계 셀을 찾을 수 없습니다. 일련번호: ${serialNumber}`);
    }

    return subtotal;
}

function calculateAllSubtotals() {
    let grandTotal = 0;

    // 모든 일련번호에 대한 소계를 계산
    const uniqueSerials = new Set();
    document.querySelectorAll('.calculation-row').forEach(row => {
        uniqueSerials.add(row.dataset.serial); // 중복되지 않는 일련번호 수집
    });

    uniqueSerials.forEach(serialNumber => {
        grandTotal += calculateSubtotalBySerial(serialNumber); // 각 일련번호의 소계를 계산
    });

    return grandTotal;
}

function calculateGrandTotal() {
    const grandTotal = calculateAllSubtotals();
    const grandTotalCell = document.querySelector('.grand-total'); // 전체 합계 셀 클래스 접근

    if (grandTotalCell) {
        grandTotalCell.textContent = formatNumber(grandTotal);
    } else {
        console.error("전체 합계 셀을 찾을 수 없습니다. '.grand-total'이라는 클래스가 올바르게 설정되었는지 확인해주세요.");
    }
}

// 이벤트 리스너 설정
document.querySelectorAll('input').forEach(input => {
    input.addEventListener('input', function() {
        const row = input.closest('tr'); // 해당 input이 속한 행을 찾음
        calculateRowTotal(row); // 해당 행의 총합 계산
        calculateAllSubtotals(); // 소계 계산
        calculateGrandTotal(); // 전체 합계 계산
    });
});

// 페이지 로드 시 초기 계산
window.onload = function() {
    calculateAllSubtotals();
    calculateGrandTotal();
};

반응형
댓글