Files
2026-06-11 18:47:38 +09:00

670 lines
24 KiB
PHP

<?php
$sub_menu = "800760";
include_once('./_common.php');
auth_check($auth[$sub_menu], 'r');
$g5['title'] = '워크플로우 통합 테스트';
// 필요한 클래스들 로드
require_once G5_PATH . '/adm/order_manage/classes/EstimateManager.class.php';
require_once G5_PATH . '/adm/order_manage/classes/StatusManager.class.php';
require_once G5_PATH . '/adm/order_manage/classes/NotificationHelper.class.php';
$estimate_manager = new EstimateManager();
$status_manager = new StatusManager();
$notification_helper = new NotificationHelper();
// 테스트 액션 처리
$action = isset($_REQUEST['action']) ? clean_xss_tags($_REQUEST['action']) : '';
$test_results = [];
if ($action && $_SERVER['REQUEST_METHOD'] === 'POST') {
auth_check($auth[$sub_menu], 'w');
try {
switch ($action) {
case 'test_customer_workflow':
$test_results = runCustomerWorkflowTest();
break;
case 'test_dealer_workflow':
$test_results = runDealerWorkflowTest();
break;
case 'test_admin_workflow':
$test_results = runAdminWorkflowTest();
break;
case 'test_expert_visit_workflow':
$test_results = runExpertVisitWorkflowTest();
break;
case 'test_full_integration':
$test_results = runFullIntegrationTest();
break;
case 'cleanup_test_data':
$test_results = cleanupTestData();
break;
}
} catch (Exception $e) {
$test_results = [
'success' => false,
'message' => '테스트 실행 중 오류 발생: ' . $e->getMessage(),
'details' => []
];
}
}
// 테스트 함수들
function runCustomerWorkflowTest()
{
global $estimate_manager, $status_manager;
$results = [
'success' => true,
'message' => '고객 워크플로우 테스트',
'details' => []
];
try {
// 1. 테스트 견적 생성
$test_data = [
'wr_id' => 99999, // 테스트용 ID
'zip_code' => '12345',
'address1' => '서울시 강남구',
'address2' => '테스트동 123-45',
'house_type' => '아파트',
'house_size' => '84㎡',
'material' => '시스템창호',
'color' => '화이트',
'glass_thickness' => '24mm',
'install' => '전체교체',
'items' => [
[
'product' => '거실 창호',
'qty' => 2,
'price' => 500000,
'amount' => 1000000
]
]
];
// 견적 생성 테스트
$estimate_id = $estimate_manager->createEstimate($test_data);
if ($estimate_id) {
$results['details'][] = ['step' => '견적 생성', 'status' => 'PASS', 'message' => "견적 ID: {$estimate_id}"];
} else {
throw new Exception('견적 생성 실패');
}
// 2. 상태 변경 테스트 (견적신청중 → 작성완료)
$status_result = $estimate_manager->completeEstimate(99999, 'customer');
if ($status_result['success']) {
$results['details'][] = ['step' => '견적 완료', 'status' => 'PASS', 'message' => $status_result['message']];
} else {
throw new Exception('견적 완료 실패: ' . $status_result['message']);
}
// 3. 견적 선택 시뮬레이션 (가상의 입찰 생성 후 선택)
$bid_data = [
'total_amount' => 1200000,
'message' => '테스트 입찰입니다.'
];
$bid_result = $estimate_manager->createBiddingWithItems($estimate_id, $bid_data, []);
if ($bid_result['success']) {
$results['details'][] = ['step' => '입찰 생성', 'status' => 'PASS', 'message' => '테스트 입찰 생성됨'];
// 견적 선택
$select_result = $estimate_manager->selectBidWithStatus($estimate_id, $bid_result['data']['bidding_id'], 'customer');
if ($select_result['success']) {
$results['details'][] = ['step' => '견적 선택', 'status' => 'PASS', 'message' => $select_result['message']];
} else {
$results['details'][] = ['step' => '견적 선택', 'status' => 'FAIL', 'message' => $select_result['message']];
}
} else {
$results['details'][] = ['step' => '입찰 생성', 'status' => 'FAIL', 'message' => $bid_result['message']];
}
} catch (Exception $e) {
$results['success'] = false;
$results['details'][] = ['step' => '오류', 'status' => 'FAIL', 'message' => $e->getMessage()];
}
return $results;
}
function runDealerWorkflowTest()
{
global $estimate_manager;
$results = [
'success' => true,
'message' => '대리점 워크플로우 테스트',
'details' => []
];
try {
// 1. 기존 견적에 입찰 제출 테스트
$estimate = sql_fetch("SELECT * FROM estimate WHERE is_deleted = 0 AND status = '작성완료' LIMIT 1");
if (!$estimate) {
// 테스트용 견적이 없으면 생성
$results['details'][] = ['step' => '테스트 견적 확인', 'status' => 'INFO', 'message' => '테스트용 견적이 없어 고객 워크플로우를 먼저 실행하세요.'];
return $results;
}
$bid_data = [
'total_amount' => 1500000,
'message' => '대리점 테스트 입찰입니다.'
];
$items_data = [
[
'product' => '테스트 창호',
'qty' => 1,
'price' => 1500000,
'amount' => 1500000,
'brand' => '테스트브랜드'
]
];
$bid_result = $estimate_manager->createBiddingWithItems($estimate['id'], $bid_data, $items_data);
if ($bid_result['success']) {
$results['details'][] = ['step' => '입찰 제출', 'status' => 'PASS', 'message' => '입찰이 성공적으로 제출됨'];
} else {
throw new Exception('입찰 제출 실패: ' . $bid_result['message']);
}
// 2. 시공 일정 설정 테스트 (선택된 견적이 있는 경우)
if ($estimate['selected_bid_id']) {
$construction_date = date('Y-m-d', strtotime('+7 days'));
$schedule_result = $estimate_manager->setConstructionSchedule($estimate['wr_id'], $construction_date, 'agent');
if ($schedule_result['success']) {
$results['details'][] = ['step' => '시공 일정 설정', 'status' => 'PASS', 'message' => $schedule_result['message']];
} else {
$results['details'][] = ['step' => '시공 일정 설정', 'status' => 'FAIL', 'message' => $schedule_result['message']];
}
}
} catch (Exception $e) {
$results['success'] = false;
$results['details'][] = ['step' => '오류', 'status' => 'FAIL', 'message' => $e->getMessage()];
}
return $results;
}
function runAdminWorkflowTest()
{
global $estimate_manager, $status_manager;
$results = [
'success' => true,
'message' => '관리자 워크플로우 테스트',
'details' => []
];
try {
// 1. 상태 관리 테스트
$estimate = sql_fetch("SELECT * FROM estimate WHERE is_deleted = 0 LIMIT 1");
if ($estimate) {
$current_status = $status_manager->getCurrentStatus($estimate['wr_id']);
if ($current_status) {
$results['details'][] = ['step' => '상태 조회', 'status' => 'PASS', 'message' => "현재 상태: {$current_status['status']}"];
} else {
$results['details'][] = ['step' => '상태 조회', 'status' => 'FAIL', 'message' => '상태 조회 실패'];
}
// 2. 결제 상태 업데이트 테스트
if ($estimate['selected_bid_id']) {
$payment_result = $estimate_manager->updatePaymentStatus($estimate['wr_id'], 'deposit', 'admin');
if ($payment_result['success']) {
$results['details'][] = ['step' => '결제 상태 업데이트', 'status' => 'PASS', 'message' => $payment_result['message']];
} else {
$results['details'][] = ['step' => '결제 상태 업데이트', 'status' => 'FAIL', 'message' => $payment_result['message']];
}
}
}
// 3. 통계 데이터 조회 테스트
$stats = $estimate_manager->getEstimateStatistics();
if (!empty($stats['total_statistics'])) {
$results['details'][] = ['step' => '통계 조회', 'status' => 'PASS', 'message' => "총 견적: {$stats['total_statistics']['total_estimates']}"];
} else {
$results['details'][] = ['step' => '통계 조회', 'status' => 'FAIL', 'message' => '통계 데이터 조회 실패'];
}
} catch (Exception $e) {
$results['success'] = false;
$results['details'][] = ['step' => '오류', 'status' => 'FAIL', 'message' => $e->getMessage()];
}
return $results;
}
function runExpertVisitWorkflowTest()
{
global $estimate_manager;
$results = [
'success' => true,
'message' => '전문가 방문 워크플로우 테스트',
'details' => []
];
try {
// 1. 전문가 방문 요청 테스트
$estimate = sql_fetch("SELECT * FROM estimate WHERE is_deleted = 0 AND temp_1 != 'Y' LIMIT 1");
if ($estimate) {
$visit_result = $estimate_manager->requestExpertVisit($estimate['wr_id'], 'customer');
if ($visit_result['success']) {
$results['details'][] = ['step' => '전문가 방문 요청', 'status' => 'PASS', 'message' => $visit_result['message']];
// 2. 결제 확인 테스트
$payment_result = $estimate_manager->confirmExpertVisitPayment($estimate['wr_id'], 'admin');
if ($payment_result['success']) {
$results['details'][] = ['step' => '방문 비용 결제 확인', 'status' => 'PASS', 'message' => $payment_result['message']];
// 3. 일정 설정 테스트
$visit_datetime = date('Y-m-d H:i', strtotime('+3 days 14:00'));
$schedule_result = $estimate_manager->scheduleExpertVisit($estimate['wr_id'], $visit_datetime, 'admin', 'admin');
if ($schedule_result['success']) {
$results['details'][] = ['step' => '방문 일정 설정', 'status' => 'PASS', 'message' => $schedule_result['message']];
// 4. 방문 완료 테스트
$complete_result = $estimate_manager->completeExpertVisit($estimate['wr_id'], '테스트 방문 완료', 'admin');
if ($complete_result['success']) {
$results['details'][] = ['step' => '방문 완료 처리', 'status' => 'PASS', 'message' => $complete_result['message']];
} else {
$results['details'][] = ['step' => '방문 완료 처리', 'status' => 'FAIL', 'message' => $complete_result['message']];
}
} else {
$results['details'][] = ['step' => '방문 일정 설정', 'status' => 'FAIL', 'message' => $schedule_result['message']];
}
} else {
$results['details'][] = ['step' => '방문 비용 결제 확인', 'status' => 'FAIL', 'message' => $payment_result['message']];
}
} else {
$results['details'][] = ['step' => '전문가 방문 요청', 'status' => 'FAIL', 'message' => $visit_result['message']];
}
} else {
$results['details'][] = ['step' => '테스트 견적 확인', 'status' => 'INFO', 'message' => '전문가 방문 테스트용 견적이 없습니다.'];
}
} catch (Exception $e) {
$results['success'] = false;
$results['details'][] = ['step' => '오류', 'status' => 'FAIL', 'message' => $e->getMessage()];
}
return $results;
}
function runFullIntegrationTest()
{
$results = [
'success' => true,
'message' => '전체 통합 테스트',
'details' => []
];
try {
// 1. 고객 워크플로우 테스트
$customer_test = runCustomerWorkflowTest();
$results['details'][] = ['step' => '고객 워크플로우', 'status' => $customer_test['success'] ? 'PASS' : 'FAIL', 'message' => $customer_test['message']];
// 2. 대리점 워크플로우 테스트
$dealer_test = runDealerWorkflowTest();
$results['details'][] = ['step' => '대리점 워크플로우', 'status' => $dealer_test['success'] ? 'PASS' : 'FAIL', 'message' => $dealer_test['message']];
// 3. 관리자 워크플로우 테스트
$admin_test = runAdminWorkflowTest();
$results['details'][] = ['step' => '관리자 워크플로우', 'status' => $admin_test['success'] ? 'PASS' : 'FAIL', 'message' => $admin_test['message']];
// 4. 전문가 방문 워크플로우 테스트
$expert_test = runExpertVisitWorkflowTest();
$results['details'][] = ['step' => '전문가 방문 워크플로우', 'status' => $expert_test['success'] ? 'PASS' : 'FAIL', 'message' => $expert_test['message']];
// 전체 성공 여부 판단
$all_passed = $customer_test['success'] && $dealer_test['success'] && $admin_test['success'] && $expert_test['success'];
$results['success'] = $all_passed;
if ($all_passed) {
$results['message'] = '모든 워크플로우 테스트가 성공적으로 완료되었습니다.';
} else {
$results['message'] = '일부 워크플로우 테스트에서 오류가 발생했습니다.';
}
} catch (Exception $e) {
$results['success'] = false;
$results['details'][] = ['step' => '통합 테스트 오류', 'status' => 'FAIL', 'message' => $e->getMessage()];
}
return $results;
}
function cleanupTestData()
{
$results = [
'success' => true,
'message' => '테스트 데이터 정리',
'details' => []
];
try {
// 테스트용 데이터 삭제
$cleanup_queries = [
"DELETE FROM estimate WHERE wr_id = 99999",
"DELETE FROM estimate_item WHERE estimate_id IN (SELECT id FROM estimate WHERE wr_id = 99999)",
"DELETE FROM estimate_bidding WHERE estimate_id IN (SELECT id FROM estimate WHERE wr_id = 99999)",
"DELETE FROM estimate_history WHERE estimate_id IN (SELECT id FROM estimate WHERE wr_id = 99999)"
];
foreach ($cleanup_queries as $query) {
sql_query($query);
}
$results['details'][] = ['step' => '테스트 데이터 삭제', 'status' => 'PASS', 'message' => '테스트 데이터가 정리되었습니다.'];
} catch (Exception $e) {
$results['success'] = false;
$results['details'][] = ['step' => '정리 오류', 'status' => 'FAIL', 'message' => $e->getMessage()];
}
return $results;
}
include_once(G5_ADMIN_PATH . '/admin.head.php');
?>
<div class="local_desc01 local_desc">
<p>
전체 주문 관리 시스템의 워크플로우를 통합 테스트합니다.<br>
고객, 대리점, 관리자, 전문가 방문의 각 시나리오를 자동으로 검증합니다.
</p>
</div>
<!-- 테스트 실행 버튼들 -->
<div class="test-controls">
<div class="btn-group">
<form method="post" style="display: inline;">
<input type="hidden" name="action" value="test_customer_workflow">
<button type="submit" class="btn btn-primary">고객 워크플로우 테스트</button>
</form>
<form method="post" style="display: inline;">
<input type="hidden" name="action" value="test_dealer_workflow">
<button type="submit" class="btn btn-info">대리점 워크플로우 테스트</button>
</form>
<form method="post" style="display: inline;">
<input type="hidden" name="action" value="test_admin_workflow">
<button type="submit" class="btn btn-warning">관리자 워크플로우 테스트</button>
</form>
<form method="post" style="display: inline;">
<input type="hidden" name="action" value="test_expert_visit_workflow">
<button type="submit" class="btn btn-success">전문가 방문 워크플로우 테스트</button>
</form>
</div>
<div class="btn-group" style="margin-top: 10px;">
<form method="post" style="display: inline;">
<input type="hidden" name="action" value="test_full_integration">
<button type="submit" class="btn btn-danger">전체 통합 테스트</button>
</form>
<form method="post" style="display: inline;">
<input type="hidden" name="action" value="cleanup_test_data">
<button type="submit" class="btn btn-secondary" onclick="return confirm('테스트 데이터를 정리하시겠습니까?')">테스트 데이터
정리</button>
</form>
</div>
</div>
<!-- 테스트 결과 표시 -->
<?php if (!empty($test_results)): ?>
<div class="test-results">
<h3>테스트 결과: <?php echo get_text($test_results['message']); ?></h3>
<div class="result-summary <?php echo $test_results['success'] ? 'success' : 'failure'; ?>">
<strong><?php echo $test_results['success'] ? '✅ 성공' : '❌ 실패'; ?></strong>
<p><?php echo get_text($test_results['message']); ?></p>
</div>
<?php if (!empty($test_results['details'])): ?>
<div class="tbl_head01 tbl_wrap">
<table>
<caption>상세 테스트 결과</caption>
<thead>
<tr>
<th scope="col">단계</th>
<th scope="col">상태</th>
<th scope="col">메시지</th>
</tr>
</thead>
<tbody>
<?php foreach ($test_results['details'] as $detail): ?>
<tr class="<?php echo strtolower($detail['status']); ?>">
<td class="td_left"><?php echo get_text($detail['step']); ?></td>
<td class="td_center">
<span class="status-badge <?php echo strtolower($detail['status']); ?>">
<?php echo $detail['status']; ?>
</span>
</td>
<td class="td_left"><?php echo get_text($detail['message']); ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<!-- 시스템 상태 체크 -->
<div class="system-status">
<h3>시스템 상태 체크</h3>
<div class="tbl_head01 tbl_wrap">
<table>
<caption>시스템 구성 요소 상태</caption>
<thead>
<tr>
<th scope="col">구성 요소</th>
<th scope="col">상태</th>
<th scope="col">설명</th>
</tr>
</thead>
<tbody>
<?php
// 시스템 상태 체크
$system_checks = [
[
'component' => 'EstimateManager',
'status' => class_exists('EstimateManager') ? 'OK' : 'ERROR',
'description' => class_exists('EstimateManager') ? '견적 관리 클래스 로드됨' : '견적 관리 클래스 로드 실패'
],
[
'component' => 'StatusManager',
'status' => class_exists('StatusManager') ? 'OK' : 'ERROR',
'description' => class_exists('StatusManager') ? '상태 관리 클래스 로드됨' : '상태 관리 클래스 로드 실패'
],
[
'component' => 'NotificationHelper',
'status' => class_exists('NotificationHelper') ? 'OK' : 'ERROR',
'description' => class_exists('NotificationHelper') ? '알림 헬퍼 클래스 로드됨' : '알림 헬퍼 클래스 로드 실패'
],
[
'component' => 'Database Tables',
'status' => sql_fetch("SHOW TABLES LIKE 'estimate'") ? 'OK' : 'ERROR',
'description' => sql_fetch("SHOW TABLES LIKE 'estimate'") ? '필수 테이블 존재' : '필수 테이블 누락'
],
[
'component' => 'Mail Templates',
'status' => sql_fetch("SHOW TABLES LIKE 'order_mail_templates'") ? 'OK' : 'ERROR',
'description' => sql_fetch("SHOW TABLES LIKE 'order_mail_templates'") ? '메일 템플릿 테이블 존재' : '메일 템플릿 테이블 누락'
],
[
'component' => 'SMS Templates',
'status' => sql_fetch("SHOW TABLES LIKE 'order_sms_templates'") ? 'OK' : 'ERROR',
'description' => sql_fetch("SHOW TABLES LIKE 'order_sms_templates'") ? 'SMS 템플릿 테이블 존재' : 'SMS 템플릿 테이블 누락'
]
];
foreach ($system_checks as $check):
?>
<tr class="<?php echo strtolower($check['status']); ?>">
<td class="td_left"><?php echo $check['component']; ?></td>
<td class="td_center">
<span class="status-badge <?php echo strtolower($check['status']); ?>">
<?php echo $check['status']; ?>
</span>
</td>
<td class="td_left"><?php echo $check['description']; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<style>
.test-controls {
margin: 20px 0;
padding: 20px;
background: #f8f9fa;
border-radius: 5px;
}
.btn-group {
margin-bottom: 10px;
}
.btn-group form {
margin-right: 10px;
}
.btn {
padding: 8px 16px;
border: none;
border-radius: 4px;
cursor: pointer;
text-decoration: none;
display: inline-block;
}
.btn-primary {
background: #007cba;
color: white;
}
.btn-info {
background: #17a2b8;
color: white;
}
.btn-warning {
background: #ffc107;
color: black;
}
.btn-success {
background: #28a745;
color: white;
}
.btn-danger {
background: #dc3545;
color: white;
}
.btn-secondary {
background: #6c757d;
color: white;
}
.test-results {
margin: 30px 0;
padding: 20px;
border-radius: 5px;
}
.result-summary {
padding: 15px;
border-radius: 5px;
margin-bottom: 20px;
}
.result-summary.success {
background: #d4edda;
border: 1px solid #c3e6cb;
color: #155724;
}
.result-summary.failure {
background: #f8d7da;
border: 1px solid #f5c6cb;
color: #721c24;
}
.status-badge {
padding: 3px 8px;
border-radius: 3px;
font-size: 11px;
font-weight: bold;
}
.status-badge.pass {
background: #28a745;
color: white;
}
.status-badge.fail {
background: #dc3545;
color: white;
}
.status-badge.info {
background: #17a2b8;
color: white;
}
.status-badge.ok {
background: #28a745;
color: white;
}
.status-badge.error {
background: #dc3545;
color: white;
}
tr.pass {
background-color: #d4edda;
}
tr.fail {
background-color: #f8d7da;
}
tr.info {
background-color: #d1ecf1;
}
tr.ok {
background-color: #d4edda;
}
tr.error {
background-color: #f8d7da;
}
.system-status {
margin-top: 30px;
}
</style>
<?php
include_once(G5_ADMIN_PATH . '/admin.tail.php');
?>