/* tkpurchase-partner-portal.js - Partner portal logic */ let portalSchedules = []; let portalCheckins = {}; let partnerCompanyId = null; let companyWorkersCache = null; // 작업자 목록 캐시 let editingReportId = null; // 수정 모드일 때 보고 ID async function loadMySchedules() { try { const r = await api('/schedules/my'); portalSchedules = r.data || []; } catch(e) { console.warn('Load schedules error:', e); portalSchedules = []; } } async function loadMyCheckins() { try { const r = await api('/checkins/my'); const list = r.data || []; portalCheckins = {}; list.forEach(c => { if (c.schedule_id) portalCheckins[c.schedule_id] = c; }); } catch(e) { console.warn('Load checkins error:', e); portalCheckins = {}; } } async function loadCompanyWorkers() { if (companyWorkersCache) return companyWorkersCache; try { const r = await api('/partners/' + partnerCompanyId + '/workers'); companyWorkersCache = (r.data || []).filter(w => w.is_active !== 0); return companyWorkersCache; } catch(e) { console.warn('Load workers error:', e); companyWorkersCache = []; return []; } } async function renderScheduleCards() { await Promise.all([loadMySchedules(), loadMyCheckins()]); const container = document.getElementById('scheduleCards'); const noMsg = document.getElementById('noScheduleMessage'); if (!portalSchedules.length) { container.innerHTML = ''; noMsg.classList.remove('hidden'); return; } noMsg.classList.add('hidden'); container.innerHTML = portalSchedules.map(s => { const checkin = portalCheckins[s.id]; const isCheckedIn = checkin && !checkin.check_out_time; const isCheckedOut = checkin && checkin.check_out_time; const reportCount = checkin ? (parseInt(checkin.work_report_count) || 0) : 0; // Step indicators const step1Class = checkin ? 'text-emerald-600' : 'text-gray-400'; const step2Class = isCheckedIn || isCheckedOut ? 'text-emerald-600' : 'text-gray-400'; const step3Class = isCheckedOut ? 'text-emerald-600' : 'text-gray-400'; return `

${escapeHtml(s.workplace_name || '작업장 미지정')}

${formatDate(s.start_date) === formatDate(s.end_date) ? formatDate(s.start_date) : formatDate(s.start_date) + ' ~ ' + formatDate(s.end_date)}
${s.work_description ? `

${escapeHtml(s.work_description)}

` : ''}
예상 ${s.expected_workers || 0}명 ${s.notes ? `${escapeHtml(s.notes)}` : ''}
1. 작업 시작
2. 업무현황${reportCount > 0 ? ' (' + reportCount + '건)' : ''}
3. 작업 종료
${!checkin ? `

작업 시작

` : `
체크인 완료 (${formatTime(checkin.check_in_time)}) · ${checkin.actual_worker_count || 0}명
`}
${isCheckedIn ? `

업무현황

업무현황을 먼저 저장한 후 작업을 종료하세요.

` : ''} ${isCheckedOut ? `
작업 종료 완료 (${formatTime(checkin.check_out_time)})
${reportCount > 0 ? '
업무현황 ' + reportCount + '건 제출 완료
' : ''}
` : ''}
`; }).join(''); // 체크인된 카드의 보고 목록 로드 + 보고 0건이면 폼 자동 표시 for (const s of portalSchedules) { const checkin = portalCheckins[s.id]; if (checkin && !checkin.check_out_time) { const reportCount = parseInt(checkin.work_report_count) || 0; loadReportsList(checkin.id, s.id); if (reportCount === 0) { showReportForm(checkin.id, s.id); } } } } async function loadReportsList(checkinId, scheduleId) { const container = document.getElementById('reportsList_' + checkinId); if (!container) return; try { const r = await api('/work-reports?checkin_id=' + checkinId + '&limit=50'); const reports = (r.data || []).filter(rr => rr.checkin_id === checkinId); renderReportsList(checkinId, scheduleId, reports); } catch(e) { container.innerHTML = ''; } } function renderReportsList(checkinId, scheduleId, reports) { const container = document.getElementById('reportsList_' + checkinId); if (!container) return; if (!reports.length) { container.innerHTML = '

아직 등록된 업무현황이 없습니다.

'; return; } container.innerHTML = reports.map(r => { const workerCount = r.workers ? r.workers.length : 0; const totalHours = r.workers ? r.workers.reduce((sum, w) => sum + Number(w.hours_worked || 0), 0) : 0; const isConfirmed = !!r.confirmed_by; const isRejected = !!r.rejected_by; const statusBadge = isConfirmed ? ' 확인완료' : isRejected ? ' 반려' : '미확인'; const canEdit = !isConfirmed; return `
보고 #${r.report_seq || 1} ${statusBadge}
${escapeHtml((r.work_content || '').substring(0, 50))}${(r.work_content || '').length > 50 ? '...' : ''}
${workerCount}명 · ${totalHours}h · 진행률 ${r.progress_rate || 0}%
${isRejected && r.rejection_reason ? `
${escapeHtml(r.rejection_reason)}
` : ''}
${canEdit ? `` : ''}
`; }).join(''); } async function showReportForm(checkinId, scheduleId, editReport) { editingReportId = editReport ? editReport.id : null; const formContainer = document.getElementById('reportForm_' + checkinId); const toggleBtn = document.getElementById('reportFormToggle_' + checkinId); if (!formContainer) return; // 작업자 목록 로드 const workers = await loadCompanyWorkers(); const datalistHtml = workers.map(w => `