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

12 KiB
Raw Blame History

compare_price_edit_table.php 개발자 가이드

📋 개요

compare_price_edit_table.php는 방화셔터 견적 시스템의 단가 수정 기능을 담당하는 핵심 PHP 컴포넌트입니다. 이 파일은 스크린 원단과 절곡판의 단가를 실시간으로 수정하고 적용할 수 있는 인터페이스를 제공하며, 데이터베이스에서 최신 단가 정보를 조회하여 표시합니다.

🏗️ 파일 구조

📁 파일 위치

/estimate/common/compare_price_edit_table.php

📊 파일 정보

  • 파일 크기: 3.2KB (103 lines)
  • 주요 언어: PHP + HTML + JavaScript
  • 의존성: Bootstrap, jQuery, MySQL/PDO
  • 주요 기능: 단가 조회, 단가 수정, 실시간 적용

🔧 핵심 기능

1. 데이터베이스 연결 및 의존성

require_once($_SERVER['DOCUMENT_ROOT'] . "/session.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/lib/mydb.php");
require_once($_SERVER['DOCUMENT_ROOT'] . "/estimate/fetch_unitprice.php");
$pdo = db_connect();

2. 단가 변수 초기화

// 스크린 원단 가격
$price_screen = 0;

// 절곡판 단가 4종
$price_egi_1_2t = 0;  // EGI 1.15T, 1.2T
$price_egi_1_6t = 0;  // EGI 1.55T, 1.6T
$price_sus_1_2t = 0;
$price_sus_1_5t = 0;

📊 데이터베이스 조회 시스템

🗄️ 스크린 원단 가격 조회

// price_raw_materials 테이블에서 스크린 실리카 가격
$query = "SELECT itemList FROM {$DB}.price_raw_materials WHERE is_deleted IS NULL OR is_deleted = 0 ORDER BY num DESC LIMIT 1";
$stmt = $pdo->prepare($query);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
    $itemList = json_decode($row['itemList'], true);
    $price_screen = slatPrice($itemList, '스크린', '실리카');
}

🗄️ 절곡판 단가 조회

// BDmodels 테이블에서 절곡판 단가 4종 로딩
$query = "SELECT * FROM {$DB}.BDmodels WHERE seconditem = '절곡판' AND is_deleted IS NULL ORDER BY num DESC";
$stmt = $pdo->prepare($query);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $spec = $row['spec'] ?? '';
    $finishing = $row['finishing_type'] ?? '';
    $unitprice = intval(str_replace(',', '', $row['unitprice'] ?? 0));

    if (in_array($spec, ['1.15T', '1.2T']) && $finishing === 'EGI') $price_egi_1_2t = $unitprice;
    if (in_array($spec, ['1.55T', '1.6T']) && $finishing === 'EGI') $price_egi_1_6t = $unitprice;
    if ($spec === '1.2T' && $finishing === 'SUS') $price_sus_1_2t = $unitprice;
    if ($spec === '1.5T' && $finishing === 'SUS') $price_sus_1_5t = $unitprice;
}

🎨 UI 구조

📋 테이블 구조

<div class="container mt-2">
    <h5 class="text-center mb-2">단가 수정 테이블 (스크린 / 절곡판)</h5>
    <div class="table-responsive">
        <table class="table table-bordered text-center align-middle table-sm">
            <thead class="table-secondary">
                <tr>
                    <th>항목명</th>
                    <th>단가 (원)</th>
                    <th>단가 적용</th>
                </tr>
            </thead>
            <tbody>
                <!-- 단가 항목들 -->
            </tbody>
        </table>
    </div>
</div>

📊 단가 항목 구조

<tr>
    <td>스크린 원단 (㎡)</td>
    <td><input type="text" class="form-control text-end price-input" id="price_screen" value="<?= number_format($price_screen) ?>"></td>
    <td><button type="button" class="btn btn-outline-primary btn-sm apply-price" data-target="price_screen">적용</button></td>
</tr>
<tr>
    <td>EGI 1.15T / 1.2T</td>
    <td><input type="text" class="form-control text-end price-input" id="price_egi_1_2t" value="<?= number_format($price_egi_1_2t) ?>"></td>
    <td><button type="button" class="btn btn-outline-primary btn-sm apply-price" data-target="price_egi_1_2t">적용</button></td>
</tr>
<tr>
    <td>EGI 1.55T / 1.6T</td>
    <td><input type="text" class="form-control text-end price-input" id="price_egi_1_6t" value="<?= number_format($price_egi_1_6t) ?>"></td>
    <td><button type="button" class="btn btn-outline-primary btn-sm apply-price" data-target="price_egi_1_6t">적용</button></td>
</tr>
<tr>
    <td>SUS 1.2T</td>
    <td><input type="text" class="form-control text-end price-input" id="price_sus_1_2t" value="<?= number_format($price_sus_1_2t) ?>"></td>
    <td><button type="button" class="btn btn-outline-primary btn-sm apply-price" data-target="price_sus_1_2t">적용</button></td>
</tr>
<tr>
    <td>SUS 1.5T</td>
    <td><input type="text" class="form-control text-end price-input" id="price_sus_1_5t" value="<?= number_format($price_sus_1_5t) ?>"></td>
    <td><button type="button" class="btn btn-outline-primary btn-sm apply-price" data-target="price_sus_1_5t">적용</button></td>
</tr>

🔧 JavaScript 기능

🎯 단가 적용 기능

$(document).ready(function () {
    $('.apply-price').on('click', function () {
        const targetId = $(this).data('target');
        const price = parseFloat($('#' + targetId).val().replace(/,/g, '')) || 0;

        $('.unit-price-input').each(function () {
            const $this = $(this);
            if ($this.data('target') === targetId) {
                const row = $this.closest('tr');
                const su = parseFloat(row.find('.su-input').val().replace(/,/g, '')) || 0;
                const total = price * su;
                $this.val(price.toLocaleString());
                row.find('.total-price').text(total.toLocaleString());
            }
        });
    });
});

📊 단가 항목 분류

🎯 단가 항목별 상세

1. 스크린 원단

  • ID: price_screen
  • 단위: ㎡ (제곱미터)
  • 데이터 소스: price_raw_materials 테이블
  • 조건: 스크린, 실리카

2. EGI 절곡판 1.15T/1.2T

  • ID: price_egi_1_2t
  • 규격: 1.15T, 1.2T
  • 마감: EGI
  • 데이터 소스: BDmodels 테이블

3. EGI 절곡판 1.55T/1.6T

  • ID: price_egi_1_6t
  • 규격: 1.55T, 1.6T
  • 마감: EGI
  • 데이터 소스: BDmodels 테이블

4. SUS 절곡판 1.2T

  • ID: price_sus_1_2t
  • 규격: 1.2T
  • 마감: SUS
  • 데이터 소스: BDmodels 테이블

5. SUS 절곡판 1.5T

  • ID: price_sus_1_5t
  • 규격: 1.5T
  • 마감: SUS
  • 데이터 소스: BDmodels 테이블

🗄️ 데이터베이스 스키마

📋 price_raw_materials 테이블

-- 스크린 원단 가격 조회
SELECT itemList 
FROM price_raw_materials 
WHERE is_deleted IS NULL OR is_deleted = 0 
ORDER BY num DESC 
LIMIT 1

📋 BDmodels 테이블

-- 절곡판 단가 조회
SELECT * 
FROM BDmodels 
WHERE seconditem = '절곡판' 
  AND is_deleted IS NULL 
ORDER BY num DESC

📊 필드 구조

  • spec: 규격 (1.15T, 1.2T, 1.55T, 1.6T, 1.5T)
  • finishing_type: 마감 타입 (EGI, SUS)
  • unitprice: 단가 (콤마 포함 문자열)
  • is_deleted: 삭제 여부

🔧 개발자 사용법

📝 기본 사용법

// 파일 포함
include_once('/estimate/common/compare_price_edit_table.php');

// 단가 변수 사용
echo "스크린 단가: " . number_format($price_screen);
echo "EGI 1.2T 단가: " . number_format($price_egi_1_2t);

🎯 단가 적용 로직

// 특정 단가 적용
function applySpecificPrice(targetId, newPrice) {
    const price = parseFloat(newPrice.replace(/,/g, '')) || 0;
    
    $('.unit-price-input').each(function () {
        const $this = $(this);
        if ($this.data('target') === targetId) {
            const row = $this.closest('tr');
            const su = parseFloat(row.find('.su-input').val().replace(/,/g, '')) || 0;
            const total = price * su;
            $this.val(price.toLocaleString());
            row.find('.total-price').text(total.toLocaleString());
        }
    });
}

🔄 데이터베이스 업데이트

// 단가 업데이트 예시
function updatePrice($table, $spec, $finishing, $newPrice) {
    global $pdo, $DB;
    
    $query = "UPDATE {$DB}.BDmodels 
              SET unitprice = :price 
              WHERE spec = :spec 
                AND finishing_type = :finishing 
                AND is_deleted IS NULL";
    
    $stmt = $pdo->prepare($query);
    $stmt->bindParam(':price', $newPrice);
    $stmt->bindParam(':spec', $spec);
    $stmt->bindParam(':finishing', $finishing);
    
    return $stmt->execute();
}

🚨 주의사항

⚠️ 필수 의존성

  • PHP 7.4+
  • MySQL/PDO
  • jQuery 3.x
  • Bootstrap 5.x

🔒 보안 고려사항

  • SQL 인젝션 방지를 위한 prepared statements 사용
  • 입력값 검증 및 이스케이프 처리
  • 세션 기반 인증 확인

📱 성능 최적화

  • 데이터베이스 쿼리 최적화
  • 캐싱 전략 고려
  • 불필요한 데이터베이스 호출 최소화

🐛 디버깅 가이드

🔍 일반적인 문제 해결

1. 단가가 표시되지 않는 경우

// 데이터베이스 연결 확인
if (!$pdo) {
    echo "데이터베이스 연결 실패";
    exit;
}

// 쿼리 결과 확인
$stmt = $pdo->prepare($query);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
var_dump($row); // 결과 확인

2. 단가 적용이 안 되는 경우

// JavaScript 디버깅
$('.apply-price').on('click', function () {
    const targetId = $(this).data('target');
    const price = parseFloat($('#' + targetId).val().replace(/,/g, '')) || 0;
    
    console.log('Target ID:', targetId);
    console.log('Price:', price);
    
    // 대상 요소 확인
    const targetElements = $('.unit-price-input[data-target="' + targetId + '"]');
    console.log('Target elements found:', targetElements.length);
});

3. 데이터베이스 오류

// PDO 오류 처리
try {
    $stmt = $pdo->prepare($query);
    $stmt->execute();
} catch (PDOException $e) {
    echo "데이터베이스 오류: " . $e->getMessage();
    error_log("PDO Error: " . $e->getMessage());
}

📚 관련 파일

🔗 의존성 파일

  • session.php: 세션 관리
  • mydb.php: 데이터베이스 연결
  • fetch_unitprice.php: 단가 조회 함수

🔗 연관 파일

  • compare_lastJS.php: 견적 비교 JavaScript
  • common_screen.php: 스크린 테이블 생성
  • common_slat.php: 철재 테이블 생성

🔗 데이터베이스 테이블

  • price_raw_materials: 원자재 가격 정보
  • BDmodels: 제품 모델 및 단가 정보

🔗 JavaScript 연동

  • apply-price: 단가 적용 버튼
  • price-input: 단가 입력 필드
  • unit-price-input: 단가 표시 필드

🎯 향후 개선 방향

🔄 코드 리팩토링

  • 클래스 기반 구조로 변경
  • 설정 파일 분리
  • 의존성 주입 패턴 도입

🎨 UI/UX 개선

  • 실시간 단가 검증
  • 단가 변경 히스토리
  • 드래그 앤 드롭 단가 적용

성능 최적화

  • 단가 캐싱 시스템
  • 비동기 단가 업데이트
  • 데이터베이스 인덱스 최적화

🔧 기능 확장

  • 다중 통화 지원
  • 단가 버전 관리
  • 자동 단가 업데이트

📊 단가 관리 시스템

🎯 단가 업데이트 프로세스

  1. 데이터베이스 조회: 최신 단가 정보 조회
  2. 사용자 입력: 새로운 단가 입력
  3. 실시간 적용: 선택된 항목에 단가 적용
  4. 총액 재계산: 수량 × 단가로 총액 계산

📈 단가 변동 추적

  • 기존 단가와 신규 단가 비교
  • 단가 변동 비율 계산
  • 단가 변경 이력 관리

🔄 자동화 기능

  • 정기적인 단가 업데이트
  • 단가 변동 알림
  • 단가 유효성 검증

📅 문서 버전: 1.0
👨‍💻 작성자: 개발팀
📝 최종 수정일: 2024-12-24
🔗 관련 문서: 견적 시스템 전체 가이드, common_addrowJS 개발자 가이드, common_screen 개발자 가이드, common_slat 개발자 가이드, compare_lastJS 개발자 가이드