/** * Procurement Dashboard Handler * Обработчик для главной страницы модуля закупок */ export class ProcurementDashboardHandler { constructor(options = {}) { this.apiBase = options.apiBase || '/api/v1/procurement'; this.statsContainer = options.statsContainer || '#procDashboardStats'; this.recentRequestsContainer = options.recentRequestsContainer || '#recentRequests'; this.recentEquipmentContainer = options.recentEquipmentContainer || '#recentEquipment'; this.init(); } async init() { await Promise.all([ this.loadStats(), this.loadRecentRequests(), this.loadRecentEquipment() ]); } /** * Загрузка статистики */ async loadStats() { try { const [requestsResp, equipmentResp] = await Promise.all([ fetch(`${this.apiBase}/requests/?page_size=1000`), fetch(`${this.apiBase}/equipment/?page_size=1000`) ]); if (!requestsResp.ok || !equipmentResp.ok) return; const requestsData = await requestsResp.json(); const equipmentData = await equipmentResp.json(); const requests = requestsData.results || requestsData; const equipment = equipmentData.results || equipmentData; // Подсчёт статистики const stats = { totalRequests: requests.length, pendingRequests: requests.filter(r => r.status === 'pending_approval').length, approvedRequests: requests.filter(r => ['approved', 'ordered', 'delivered'].includes(r.status)).length, totalEquipment: equipment.length, inUseEquipment: equipment.filter(e => e.status === 'in_use').length, totalBudget: requests.reduce((sum, r) => sum + parseFloat(r.total_cost || 0), 0) }; this.updateStatsDisplay(stats); } catch (error) { console.error('Error loading dashboard stats:', error); } } /** * Обновление отображения статистики */ updateStatsDisplay(stats) { const container = document.querySelector(this.statsContainer); if (!container) return; const statsElements = { 'totalRequests': stats.totalRequests, 'pendingRequests': stats.pendingRequests, 'approvedRequests': stats.approvedRequests, 'totalEquipment': stats.totalEquipment, 'inUseEquipment': stats.inUseEquipment, 'totalBudget': this.formatCurrency(stats.totalBudget) }; Object.entries(statsElements).forEach(([id, value]) => { const el = container.querySelector(`[data-stat="${id}"]`); if (el) el.textContent = value; }); } /** * Загрузка последних заявок */ async loadRecentRequests() { const container = document.querySelector(this.recentRequestsContainer); if (!container) return; try { const resp = await fetch(`${this.apiBase}/requests/?ordering=-created_at&page_size=5`); if (!resp.ok) return; const data = await resp.json(); const requests = data.results || data; if (requests.length === 0) { container.innerHTML = `
Заявок пока нет
Оборудования пока нет
${eq.inventory_number} •
${eq.category_name || 'Без категории'}