diff --git a/mysql_preview_server.py b/mysql_preview_server.py
index 20b0e9b..d62dbbb 100644
--- a/mysql_preview_server.py
+++ b/mysql_preview_server.py
@@ -787,13 +787,22 @@ def get_erp_project_code_cache(conn, source_page='const'):
{
'projectCode': row[0],
'projectName': row[1],
- 'contractType': row[2] or '',
- 'applicationType': row[3] or '',
+ 'businessCode': row[2] or '',
+ 'siteLocation': row[3] or '',
+ 'clientName': row[4] or '',
+ 'finalContractAmountText': row[5] or '',
+ 'contractType': row[6] or '',
+ 'applicationType': row[7] or '',
+ 'syncedAt': row[8] or '',
}
for row in conn.execute(
'''
SELECT p.projectCode,
p.projectName,
+ COALESCE(d.businessCode, '') AS businessCode,
+ COALESCE(d.siteLocation, '') AS siteLocation,
+ COALESCE(d.clientName, '') AS clientName,
+ COALESCE(d.finalContractAmountText, '') AS finalContractAmountText,
COALESCE(d.contractType, '') AS contractType,
COALESCE((
SELECT GROUP_CONCAT(applicationType, '||')
@@ -805,7 +814,8 @@ def get_erp_project_code_cache(conn, source_page='const'):
AND IFNULL(b.applicationType, '') <> ''
ORDER BY b.applicationType
)
- ), '') AS applicationType
+ ), '') AS applicationType,
+ COALESCE(d.syncedAt, '') AS detailSyncedAt
FROM erp_project_code_cache p
LEFT JOIN erp_contract_detail_cache d
ON d.sourcePage = p.sourcePage
diff --git a/project-codes.html b/project-codes.html
index 1199145..57c3d0e 100644
--- a/project-codes.html
+++ b/project-codes.html
@@ -833,7 +833,11 @@
detailTitle.textContent = `${detail.projectName || '-'} [${detail.projectCode}]`;
detailMeta.textContent = `사업코드 ${detail.businessCode || '-'} · 마지막 동기화 ${detail.syncedAt || '-'}`;
+ renderDetailRows(detail);
+ renderMergedBridgeRows(detail.scaleRows || [], state.bridgeOverviews || [], state.budgetPlan);
+ }
+ function renderDetailRows(detail) {
const rows = [
['사업코드', detail.businessCode],
['약칭', detail.projectName],
@@ -856,8 +860,6 @@
${typeof value === 'string' && value.includes('
`).join('');
-
- renderMergedBridgeRows(detail.scaleRows || [], state.bridgeOverviews || [], state.budgetPlan);
}
function normalizeBridgeName(value) {
@@ -1168,12 +1170,45 @@
if (!detailResponse.ok) {
if (!refresh && detailResponse.status === 404) {
- state.detail = null;
state.bridgeOverviews = overviewResponse.ok ? (Array.isArray(overviewData.overviews) ? overviewData.overviews : []) : [];
state.budgetPlan = budgetPlanResponse.ok ? (budgetPlanData.plan || null) : null;
detailTitle.textContent = `${projectName || '-'} [${projectCode}]`;
- detailMeta.textContent = 'DB 캐시에 계약정보가 없습니다. 새 정보 다시 가져오기를 누르면 ERP에서 수집합니다.';
- detailBody.innerHTML = '| 저장된 계약정보가 없습니다. 최신 정보가 필요하면 오른쪽 상단 버튼을 눌러주세요. | ';
+ detailMeta.textContent = 'DB 캐시에 계약정보가 없어 ERP에서 기본 계약정보를 가져오는 중입니다.';
+ try {
+ const freshDetailResponse = await fetch(
+ `/api/erp-contract-detail?page=const&projectCode=${encodeURIComponent(projectCode)}&projectName=${encodeURIComponent(projectName || '')}&refresh=1`,
+ { cache: 'no-store' }
+ );
+ const freshDetailData = await freshDetailResponse.json();
+ if (freshDetailResponse.ok) {
+ state.detail = freshDetailData.detail || null;
+ if (state.selectedRow && state.detail) {
+ state.selectedRow.businessCode = state.detail.businessCode || state.selectedRow.businessCode || '';
+ state.selectedRow.siteLocation = state.detail.siteLocation || state.selectedRow.siteLocation || '';
+ state.selectedRow.clientName = state.detail.clientName || state.selectedRow.clientName || '';
+ state.selectedRow.finalContractAmountText = state.detail.finalContractAmountText || state.selectedRow.finalContractAmountText || '';
+ state.selectedRow.contractType = state.detail.contractType || state.selectedRow.contractType || '';
+ state.selectedRow.syncedAt = state.detail.syncedAt || state.selectedRow.syncedAt || '';
+ }
+ renderDetail(state.detail);
+ return;
+ }
+ } catch (error) {
+ }
+
+ state.detail = null;
+ const selectedSummary = state.selectedRow || {};
+ detailMeta.textContent = '기본 계약정보를 아직 가져오지 않았습니다. 새 정보 다시 가져오기를 누르면 ERP에서 수집합니다.';
+ renderDetailRows({
+ businessCode: selectedSummary.businessCode || '',
+ projectName: projectName || selectedSummary.projectName || '',
+ projectCode,
+ siteLocation: selectedSummary.siteLocation || '',
+ clientName: selectedSummary.clientName || '',
+ finalContractAmountText: selectedSummary.finalContractAmountText || '',
+ contractType: selectedSummary.contractType || '',
+ syncedAt: selectedSummary.syncedAt || '',
+ });
renderMergedBridgeRows([], state.bridgeOverviews || [], state.budgetPlan);
return;
}
@@ -1184,7 +1219,12 @@
state.bridgeOverviews = Array.isArray(overviewData.overviews) ? overviewData.overviews : [];
state.budgetPlan = budgetPlanResponse.ok ? (budgetPlanData.plan || null) : null;
if (state.selectedRow && state.detail) {
+ state.selectedRow.businessCode = state.detail.businessCode || state.selectedRow.businessCode || '';
+ state.selectedRow.siteLocation = state.detail.siteLocation || state.selectedRow.siteLocation || '';
+ state.selectedRow.clientName = state.detail.clientName || state.selectedRow.clientName || '';
+ state.selectedRow.finalContractAmountText = state.detail.finalContractAmountText || state.selectedRow.finalContractAmountText || '';
state.selectedRow.contractType = state.detail.contractType || state.selectedRow.contractType || '';
+ state.selectedRow.syncedAt = state.detail.syncedAt || state.selectedRow.syncedAt || '';
state.selectedRow.applicationType = Array.from(new Set(
state.bridgeOverviews.map((item) => String(item.applicationType || '').trim()).filter(Boolean)
)).sort((a, b) => a.localeCompare(b, 'ko')).join('||') || state.selectedRow.applicationType || '';
|