1821 lines
141 KiB
HTML
1821 lines
141 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="ru">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<title>QAZAQtelecom HSE — План ПБ 2026</title>
|
||
<style>
|
||
|
||
*{box-sizing:border-box;margin:0;padding:0}
|
||
body{font:14px/1.4 Arial,sans-serif;background:#F4F6F9;color:#1A1A2E;min-height:100vh}
|
||
input,select,textarea,button{font:inherit;outline:none}
|
||
.btn{background:#005BAA;color:#fff;padding:12px 24px;border-radius:8px;font-weight:600;font-size:14px;border:none;cursor:pointer;display:inline-block;text-align:center;transition:all 0.2s}.btn:hover{background:#004B8C;box-shadow:0 2px 8px rgba(0,91,170,0.3)}
|
||
.btn-sm{padding:7px 16px;font-size:12px}.btn-r{background:#E53935;color:#fff}.btn-g{background:#2E7D32;color:#fff}.btn-o{background:#F57C00;color:#fff}
|
||
#login{display:flex;align-items:center;justify-content:center;min-height:100vh;background:linear-gradient(135deg,#003D73,#005BAA,#0077CC)}
|
||
#login>div{background:#fff;border-radius:16px;padding:40px;width:400px;max-width:90vw;text-align:center;box-shadow:0 8px 32px rgba(0,0,0,0.15)}
|
||
#login h1{font-size:22px;font-weight:800;margin-bottom:4px}#login h1 span{color:#005BAA}
|
||
#login>div>p{color:#64748B;font-size:13px;margin-bottom:24px}
|
||
#login input{display:block;width:100%;padding:12px;border:2px solid #E2E8F0;border-radius:10px;font-size:14px;margin-bottom:12px;transition:border 0.2s}
|
||
#login input:focus{border-color:#005BAA}
|
||
#app{display:none;min-height:100vh}
|
||
#sidebar{position:fixed;left:0;top:0;bottom:0;width:220px;background:#0A1628;color:#fff;z-index:100;overflow-y:auto;box-shadow:2px 0 12px rgba(0,0,0,0.1)}
|
||
#sidebar .logo{padding:20px 16px 12px;font-size:16px;font-weight:800;border-bottom:1px solid rgba(255,255,255,.1);display:flex;align-items:center;gap:8px}
|
||
#sidebar .logo span{color:#005BAA}
|
||
#sidebar .user{font-size:11px;color:#94A3B8;padding:10px 16px;border-bottom:1px solid rgba(255,255,255,.05)}
|
||
#sidebar a{display:block;padding:12px 16px;color:#CBD5E1;text-decoration:none;font-size:13px;cursor:pointer;border-left:3px solid transparent;transition:all 0.15s}
|
||
#sidebar a:hover{background:rgba(0,91,170,.1);color:#fff}
|
||
#sidebar a.active{background:rgba(0,91,170,.2);color:#005BAA;border-left-color:#005BAA;font-weight:600}
|
||
#sidebar .logout{position:absolute;bottom:16px;left:16px;right:16px}
|
||
#main{margin-left:220px;padding:24px;min-height:100vh}
|
||
.top{display:flex;justify-content:space-between;align-items:center;padding:0 0 16px;border-bottom:2px solid #E2E8F0;margin-bottom:20px}
|
||
.top h2{font-size:20px;font-weight:700}
|
||
.card{background:#fff;border-radius:12px;padding:20px;margin-bottom:16px;border:1px solid #E8ECF1;overflow-x:auto;box-shadow:0 1px 4px rgba(0,0,0,0.04)}
|
||
.card h3{font-size:16px;font-weight:700;margin-bottom:12px}
|
||
table{width:100%;border-collapse:collapse}
|
||
th,td{padding:8px 10px;font-size:13px;text-align:left;border-bottom:1px solid #E2E8F0;vertical-align:top}
|
||
th{background:#F1F5F9;font-weight:600;font-size:11px;text-transform:uppercase;color:#64748B;white-space:nowrap}
|
||
tr:hover{background:#FAFBFC}
|
||
.badge{display:inline-block;padding:3px 8px;border-radius:100px;font-size:11px;font-weight:600;white-space:nowrap}
|
||
.badge.g{background:#E8F5E9;color:#2E7D32}.badge.a{background:#FFF3E0;color:#E65100}.badge.r{background:#FFEBEE;color:#C62828}.badge.b{background:#E3F2FD;color:#1565C0}.badge.w{background:#F5F5F5;color:#757575}
|
||
.fr{display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap;align-items:center}
|
||
.fr input,.fr select{padding:8px 12px;border:1px solid #E2E8F0;border-radius:8px;font-size:13px;background:#fff}.fr input{min-width:200px}
|
||
.tr-red{background:#FFF5F5}.tr-red td{border-bottom-color:#FECACA;color:#991B1B}
|
||
.tr-amber{background:#FFFBEB}.tr-amber td{border-bottom-color:#FDE68A;color:#92400E}
|
||
.tr-green{background:#F0FDF4}.tr-green td{border-bottom-color:#BBF7D0;color:#065F46}
|
||
.sec-h{background:#005BAA;color:#fff;padding:6px 12px;border-radius:6px;font-size:12px;font-weight:700;display:inline-block;margin:16px 0 8px}
|
||
.stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:20px}
|
||
.stat-card{background:#fff;border-radius:12px;padding:16px;border:1px solid #E2E8F0;text-align:center}
|
||
.stat-card .num{font-size:28px;font-weight:800;margin:4px 0}.stat-card .lb{font-size:12px;color:#64748B}
|
||
.stat-card.sg .num{color:#10B981}.stat-card.sr .num{color:#EF4444}.stat-card.sb .num{color:#00B4D8}.stat-card.sa .num{color:#F59E0B}
|
||
.chat-box{height:280px;overflow-y:auto;border:1px solid #E2E8F0;border-radius:10px;padding:12px;margin-bottom:12px;background:#FAFBFC}
|
||
.msg{padding:8px 12px;border-radius:10px;margin-bottom:8px;max-width:85%;font-size:13px;line-height:1.4}
|
||
.msg.u{margin-left:auto;background:#005BAA;color:#fff}.msg.b{background:#F1F5F9;color:#0B1A2E}
|
||
.msg .nm{font-size:10px;color:#94A3B8;margin-bottom:2px}
|
||
.chat-inp{display:flex;gap:8px}.chat-inp input{flex:1;padding:10px 14px;border:1px solid #E2E8F0;border-radius:8px;font-size:13px}
|
||
.chat-q{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:12px}
|
||
.chat-q button{padding:6px 12px;border:1px solid #E2E8F0;border-radius:100px;font-size:11px;background:#fff;cursor:pointer;color:#0B1A2E}
|
||
.chat-q button:hover{background:#00B4D8;color:#fff;border-color:#00B4D8}
|
||
.rank-bar{height:8px;border-radius:4px;background:#E2E8F0;overflow:hidden;margin-top:4px}
|
||
.rank-bar>div{height:100%;border-radius:4px;transition:width .3s}
|
||
.sub-row{font-size:12px;color:#64748B;cursor:pointer;user-select:none}
|
||
.sub-row:hover{color:#00B4D8}.sub-row .arr{display:inline-block;width:16px;text-align:center}
|
||
.sub-items{padding-left:24px}.sub-item{font-size:12px;padding:4px 0;border-bottom:1px solid #F1F5F9}.sub-item:last-child{border:none}
|
||
.mod-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.5);z-index:1000;display:none;align-items:center;justify-content:center}
|
||
.mod-box{background:#fff;border-radius:16px;padding:28px;max-width:750px;width:90vw;max-height:85vh;overflow-y:auto;position:relative}
|
||
.file-item{display:flex;align-items:center;gap:8px;padding:6px 8px;background:#F8FAFC;border-radius:6px;margin:4px 0;border:1px solid #E2E8F0;flex-wrap:wrap}
|
||
.file-item .fn{font-size:12px;flex:1;min-width:80px}.file-item .fs{font-size:10px;color:#64748B}.file-item a{font-size:11px;color:#00B4D8;cursor:pointer;text-decoration:underline}
|
||
.stor-bar{font-size:11px;color:#64748B;padding:4px 0}
|
||
@media(max-width:768px){#sidebar{width:56px}#sidebar .logo span,#sidebar a span,#sidebar .user{display:none}#main{margin-left:56px}.stat-grid{grid-template-columns:repeat(2,1fr)}}
|
||
</style>
|
||
|
||
#toast{position:fixed;top:20px;right:20px;z-index:9999;background:#2E7D32;color:#fff;padding:12px 24px;border-radius:8px;font-size:14px;font-weight:600;box-shadow:0 4px 12px rgba(0,0,0,0.2);display:none;transition:opacity 0.3s}
|
||
</head>
|
||
<body onload="init()" style="margin:0">
|
||
<div id="login"><div>
|
||
<h1><span>QAZAQtelecom</span> HSE</h1>
|
||
<p>План производственной безопасности 2026</p>
|
||
<input id="lem" placeholder="curator@telecom.kz">
|
||
<input id="lpw" type="password" placeholder="Пароль">
|
||
<p id="lerr" style="color:#EF4444;font-size:12px;display:none">Неверная почта</p>
|
||
<button class="btn" style="width:100%" onclick="doLogin()">Войти</button>
|
||
</div></div>
|
||
<div id="toast"></div>
|
||
<div id="app">
|
||
<div id="sidebar">
|
||
<div class="logo">QAZAQtelecom <span>HSE</span></div>
|
||
<div class="user" id="su_name"></div>
|
||
<a class=" active" id="snav_events" onclick="switchTab('events')"><span>Мероприятия</span></a>
|
||
<a class="" id="snav_analytics" onclick="switchTab('analytics')"><span>Аналитика</span></a>
|
||
<a class="" id="snav_reports" onclick="switchTab('reports')"><span>Отчётность</span></a>
|
||
<a class="" id="snav_ai" onclick="switchTab('ai')"><span>Джарвис</span></a>
|
||
<a class="" id="snav_hse" onclick="switchTab('hse')"><span>HSE.sk.kz</span></a>
|
||
<a class="" id="snav_users" onclick="switchTab('users')"><span>Учётные записи</span></a>
|
||
<div class="logout"><button class="btn btn-sm btn-r" style="width:100%" onclick="doLogout()">Выйти</button></div>
|
||
</div>
|
||
<div id="main">
|
||
<div class="top"><h2 id="page_title">Мероприятия</h2>
|
||
<div style="display:flex;gap:8px;align-items:center">
|
||
<span id="stor_ind" class="stor-bar"></span>
|
||
<button class="btn btn-sm btn-o" onclick="saveBackup()">Резерв</button>
|
||
<button class="btn btn-sm btn-g" onclick="document.getElementById('fu').click()">Восст.</button>
|
||
<input type="file" id="fu" accept=".json" style="display:none" onchange="loadBackup(this)">
|
||
</div></div>
|
||
<div id="tab_events">
|
||
<div class="fr">
|
||
<input id="sea" placeholder="Поиск..." oninput="renderEv()">
|
||
<select id="fs" onchange="renderEv()"><option value="">Все статусы</option><option value="warn">В процессе</option><option value="done">Исполнено</option><option value="late">Просрочено</option></select>
|
||
<select id="fb" onchange="renderEv()"><option value="">Все филиалы</option></select>
|
||
<span id="sc" style="font-size:12px;color:#64748B;margin-left:auto"></span>
|
||
</div>
|
||
<div class="card" id="ev_content"></div>
|
||
</div>
|
||
<div id="tab_analytics" style="display:none">
|
||
<div class="stat-grid" id="an_stats"></div>
|
||
<div class="card"><h3>TOP-10 проблемных мероприятий</h3><div id="an_top"></div></div>
|
||
<div class="card"><h3>Выполнение по разделам</h3><div id="an_sections"></div></div>
|
||
<div style="display:flex;gap:8px;margin-bottom:16px">
|
||
<button class="btn btn-sm btn-o" onclick="dlAnalyticsPPT()">Скачать PPT</button>
|
||
<button class="btn btn-sm btn-r" onclick="dlAnalyticsPDF()">Скачать PDF</button>
|
||
<button class="btn btn-sm" onclick="dlAnalyticsWord()">Скачать Word</button>
|
||
</div>
|
||
<div class="card" id="ltif_card"><h3>LTIF — Коэффициент частоты травм</h3>
|
||
<p style="font-size:12px;color:#64748B;margin-bottom:8px">LTIF = (A × 1 000 000) / Человеко-часы, где A — число пострадавших</p>
|
||
<div style="display:flex;gap:8px;flex-wrap:wrap;align-items:end;margin-bottom:10px">
|
||
<div><span style="font-size:11px;color:#64748B">Месяц</span>
|
||
<select id="ltif_month" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px">
|
||
<option value="0">Январь</option><option value="1">Февраль</option><option value="2">Март</option>
|
||
<option value="3">Апрель</option><option value="4">Май</option><option value="5">Июнь</option>
|
||
<option value="6">Июль</option><option value="7">Август</option><option value="8">Сентябрь</option>
|
||
<option value="9">Октябрь</option><option value="10">Ноябрь</option><option value="11">Декабрь</option>
|
||
</select></div>
|
||
<div><span style="font-size:11px;color:#64748B">Человеко-часы</span>
|
||
<input id="ltif_hours" type="number" placeholder="0" style="width:130px;padding:6px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px"></div>
|
||
<div><span style="font-size:11px;color:#64748B">Пострадавших (A)</span>
|
||
<input id="ltif_inj" type="number" placeholder="0" style="width:80px;padding:6px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px"></div>
|
||
<button class="btn btn-sm btn-g" onclick="saveLTIF()">Сохранить</button>
|
||
<button class="btn btn-sm" onclick="loadLTIF()">Загрузить</button>
|
||
</div>
|
||
<div id="ltif_result" style="font-size:14px;padding:8px 0"></div>
|
||
<div id="ltif_table"></div>
|
||
<div id="ltif_corr_div"></div>
|
||
</div>
|
||
</div>
|
||
<div id="tab_reports" style="display:none">
|
||
<div class="card"><h3>Выгрузка сводного отчёта</h3>
|
||
<p style="font-size:13px;color:#64748B;margin-bottom:12px">Выберите период и формат для скачивания отчёта.</p>
|
||
<div class="fr">
|
||
<span style="font-size:13px;color:#64748B">Период:</span>
|
||
<select id="rp_period" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px" onchange="rpPeriodChange()">
|
||
<option value="year">Год</option>
|
||
<option value="month">Месяц</option>
|
||
<option value="q1">Январь-Март (Q1)</option>
|
||
<option value="q2">Апрель-Июнь (Q2)</option>
|
||
<option value="q3">Июль-Сентябрь (Q3)</option>
|
||
<option value="q4">Октябрь-Декабрь (Q4)</option>
|
||
<option value="h1">1-е полугодие</option>
|
||
<option value="h2">2-е полугодие</option>
|
||
</select>
|
||
<span style="font-size:12px;color:#64748B">Период:</span> <select id="rp_month_dd" onchange="rpDropdownChange()" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px;min-width:160px"></select>
|
||
<span style="font-size:12px;color:#64748B;display:none">с</span> <select id="rp_month_from" style="display:none" onchange="renderReports()" style="padding:6px 8px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px">
|
||
<option value="0">Январь</option><option value="1">Февраль</option><option value="2">Март</option>
|
||
<option value="3">Апрель</option><option value="4">Май</option><option value="5">Июнь</option>
|
||
<option value="6">Июль</option><option value="7">Август</option><option value="8">Сентябрь</option>
|
||
<option value="9">Октябрь</option><option value="10">Ноябрь</option><option value="11">Декабрь</option>
|
||
</select>
|
||
<span style="font-size:12px;color:#64748B;display:none">по</span> <select id="rp_month_to" style="display:none" onchange="renderReports()" style="padding:6px 8px;border:1px solid #E2E8F0;border-radius:6px;font-size:12px">
|
||
<option value="0">Январь</option><option value="1">Февраль</option><option value="2">Март</option>
|
||
<option value="3">Апрель</option><option value="4">Май</option><option value="5">Июнь</option>
|
||
<option value="6">Июль</option><option value="7">Август</option><option value="8">Сентябрь</option>
|
||
<option value="9">Октябрь</option><option value="10">Ноябрь</option><option value="11" selected>Декабрь</option>
|
||
</select>
|
||
<select id="rp_year" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px">
|
||
<option>2026</option><option>2027</option>
|
||
</select>
|
||
<select id="rp_status" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px">
|
||
<option value="">Все статусы</option>
|
||
<option value="warn">В процессе</option>
|
||
<option value="done">Исполнено</option>
|
||
<option value="late">Просрочено</option>
|
||
</select>
|
||
</div>
|
||
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
||
<button class="btn btn-sm btn-g" onclick="dlCSV()">CSV</button>
|
||
<button class="btn btn-sm" onclick="dlHTML()">HTML</button>
|
||
<button class="btn btn-sm btn-o" onclick="dlWord()">Word</button>
|
||
<button class="btn btn-sm" style="background:#7C3AED;color:#fff" onclick="dlZip()">ZIP</button>
|
||
<button class="btn btn-sm btn-r" onclick="dlPdf()">PDF</button>
|
||
</div>
|
||
<p id="rp_count" style="font-size:12px;color:#64748B;margin-top:8px"></p>
|
||
</div>
|
||
<div class="card" id="rp_preview"></div>
|
||
</div>
|
||
<div id="tab_users" style="display:none">
|
||
<div class="card"><h3>Учётные записи</h3>
|
||
<p style="font-size:13px;color:#64748B;margin-bottom:8px">Управление ответственными лицами по филиалам</p>
|
||
<button class="btn btn-sm btn-g" onclick="showRegModal()">+ Зарегистрировать</button>
|
||
<div id="users_list" style="margin-top:14px"></div>
|
||
</div></div>
|
||
<div id="tab_hse" style="display:none">
|
||
<div class="card"><h3>Интеграция с HSE.sk.kz</h3>
|
||
<p style="font-size:13px;color:#64748B;margin-bottom:16px">Направление подписанного сводного отчёта по месяцам в систему hse.sk.kz</p>
|
||
<div style="margin-bottom:12px"><strong>Месяц:</strong>
|
||
<input type="month" id="hse_month" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;margin-left:8px">
|
||
</div>
|
||
<div style="margin-bottom:12px"><strong>Формат:</strong>
|
||
<select id="hse_fmt" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;margin-left:8px">
|
||
<option value="word">Word (.docx)</option>
|
||
<option value="pdf">PDF</option>
|
||
</select>
|
||
</div>
|
||
<div style="margin-bottom:12px"><strong>API Ключ:</strong>
|
||
<input id="hse_key" type="password" placeholder="Ключ API HSE.sk.kz" style="padding:6px 10px;border:1px solid #E2E8F0;border-radius:6px;margin-left:8px;width:300px">
|
||
</div>
|
||
<button class="btn btn-sm btn-g" onclick="hseSend()" id="hse_btn">Отправить отчёт в HSE.sk.kz</button>
|
||
<div id="hse_result" style="margin-top:12px;font-size:13px"></div>
|
||
</div></div>
|
||
<div id="tab_ai" style="display:none">
|
||
<div class="card">
|
||
<div class="chat-q">
|
||
<button onclick="aiAsk('сводка')">Сводка</button>
|
||
<button onclick="aiAsk('просроченные')">Просроченные</button>
|
||
<button onclick="aiAsk('риски')">Риски</button>
|
||
<button onclick="aiAsk('рейтинг')">Рейтинг</button>
|
||
<button onclick="aiAsk('прогноз')">Прогноз</button>
|
||
<button onclick="aiAsk('статус')">Статус</button>
|
||
<button onclick="aiAsk('план')">План действий</button>
|
||
</div>
|
||
<div class="chat-box" id="ai_chat"></div>
|
||
<div class="chat-inp"><input id="ai_inp" placeholder="Спроси про план ПБ..." onkeydown="if(event.key=='Enter')aiSend()">
|
||
<button class="btn btn-sm" onclick="aiSend()">Отправить</button></div>
|
||
</div></div>
|
||
</div></div>
|
||
<div id="modal" class="mod-overlay" onclick="if(event.target===this)closeModal()">
|
||
<div class="mod-box" id="modal_body"></div>
|
||
</div>
|
||
<div id="regModal" class="mod-overlay" onclick="if(event.target===this)closeRegModal()">
|
||
<div class="mod-box" style="max-width:500px">
|
||
<h3 style="margin-bottom:14px">Регистрация пользователя</h3>
|
||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Email (логин)</label>
|
||
<input id="reg_email" placeholder="ivanov@telecom.kz" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
|
||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">ФИО</label>
|
||
<input id="reg_name" placeholder="Иванов И.И." style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
|
||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Телефон</label>
|
||
<input id="reg_phone" placeholder="+77001234567" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
|
||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Роль</label>
|
||
<select id="reg_role" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></select></div>
|
||
<div style="margin-bottom:8px"><label style="font-size:12px;color:#64748B">Филиал</label>
|
||
<select id="reg_branch" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></select></div>
|
||
<div style="margin-bottom:14px"><label style="font-size:12px;color:#64748B">Пароль</label>
|
||
<input id="reg_pass" type="password" placeholder="****" style="width:100%;padding:8px;border:1px solid #E2E8F0;border-radius:6px;font-size:13px"></div>
|
||
<div style="display:flex;gap:8px;justify-content:flex-end">
|
||
<button class="btn btn-sm" style="background:#E2E8F0;color:#0B1A2E" onclick="closeRegModal()">Отмена</button>
|
||
<button class="btn btn-sm btn-g" onclick="addUser()">Зарегистрировать</button>
|
||
<p style="font-size:11px;color:#64748B;margin-top:8px">На корпоративную почту придёт уведомление о регистрации и напоминания о необходимости представления отчёта</p>
|
||
</div></div></div>
|
||
<script>
|
||
var ALL_EVENTS=[
|
||
{
|
||
"id": 1,
|
||
"sec": 0,
|
||
"b": 6,
|
||
"s": "warn",
|
||
"p": 45,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Сертификаты, протоколы, электронная ведомость обучения",
|
||
"r": "Генеральный директор КУ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Продолжить проведение обучения и повышения квалификации руководителей и работников компании в соответствии с лучшими международными практиками, ориентированными на специфику условий труда, работы повышенной опасности и требований промышленной безопасности, а также развитие культуры безопасности, включая обучение производственного персонала по курсу «Культура безопасного труда», в том числе с применением VR, AR – технологий и цифровых симуляторов аварийных ситуаций по различным направлениям производственной безопасности (с правом выдачи сертификатов).",
|
||
"ai": "Обучение ведётся по графику. Охвачено 45% персонала.",
|
||
"h": [
|
||
"15.01 — Создано",
|
||
"01.03 — Запущено"
|
||
]
|
||
},
|
||
{
|
||
"id": 2,
|
||
"sec": 0,
|
||
"b": 0,
|
||
"s": "done",
|
||
"p": 100,
|
||
"due": "31.03.2026",
|
||
"done": "28.03.2026",
|
||
"dname": "Отчёт о проведённом анализе, утверждённый ВНД",
|
||
"r": "Директор ДПБ\nГенеральный директор ДИТ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Провести анализ, в том числе с использованием аналитических платформ (Microsoft Teams, Power BI, Tableau, Qlik и др.), и в случае необходимости, осуществить пересмотр внутренних нормативных документов филиалов/ДАО Общества в соответствии со «Стратегией развития производственной безопасности АО «Самрук-Қазына» на 2024-2028 гг.», включая установку значений ключевых показателей производственной безопасности.",
|
||
"ai": "Анализ завершён в срок.",
|
||
"h": [
|
||
"10.01 — Создано",
|
||
"28.03 — Утверждён"
|
||
]
|
||
},
|
||
{
|
||
"id": 3,
|
||
"sec": 0,
|
||
"b": 0,
|
||
"s": "warn",
|
||
"p": 50,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Протоколы совещаний (a, b, c)",
|
||
"r": "а) Главный административный директор, Директор ДПБ\nГенеральные директора филиалов и ДАО\nb, c) Генеральные директора филиалов и ДАО",
|
||
"t": "Организовывать тематические совещания по вопросам производственной безопасности, в том числе с целью разъяснения внедряемых программ и инициатив:\na) руководство Общества с филиалами/ДАО Общества, не менее одного раза в квартал, в том числе с целью личного мониторинга показателей эффективности по производственной безопасности в рамках «Стратегии развития производственной безопасности АО «Самрук-Қазына» на 2024-2028 гг.» и статуса исполнения «Плана мероприятий по производственной безопасности АО «Самрук-Қазына» на 2026 год»;\nb) руководство филиалов/ДАО Общества со структурными подразделениями, не менее 1 раза в месяц;\nc) руководство региональных подразделений/филиалов/ДАО Общества с подрядными организациями, осуществляющими работы/предоставляющими услуги на объектах, не менее 1 раза в квартал.",
|
||
"ai": "Проведено 2 квартальных совещания.",
|
||
"h": [
|
||
"10.01 — Создано",
|
||
"15.02 — Q1",
|
||
"15.05 — Q2"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Руководство Общества с филиалами/ДАО Общества, не менее одного раза в квартал, с личным мониторингом показателей эффективности"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Руководство филиалов/ДАО Общества со структурными подразделениями, не менее 1 раза в месяц"
|
||
},
|
||
{
|
||
"l": "c",
|
||
"t": "Руководство региональных подразделений/филиалов/ДАО с подрядными организациями, не менее 1 раза в квартал"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 4,
|
||
"sec": 0,
|
||
"b": 6,
|
||
"s": "warn",
|
||
"p": 55,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Отчёт о проделанной работе, тесты",
|
||
"r": "Генеральные директора филиалов и ДАО",
|
||
"t": "Продолжить практику проверки знаний в формате тестирования после проведения инструктажей по охране труда в филиалах/ДАО Общества.",
|
||
"ai": "Тестирование внедрено в 6 филиалах. Средний результат — 82%.",
|
||
"h": [
|
||
"01.02 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 5,
|
||
"sec": 0,
|
||
"b": 0,
|
||
"s": "done",
|
||
"p": 100,
|
||
"due": "31.03.2026",
|
||
"done": "25.03.2026",
|
||
"dname": "Информация о нематериальном поощрении",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Рассмотреть возможность нематериального поощрения филиалов и ДАО Общества, демонстрирующих устойчивое снижение количества несчастных случаев, пожаров и аварий по итогам нескольких и более лет.",
|
||
"ai": "Положение утверждено.",
|
||
"h": [
|
||
"15.01 — Проект",
|
||
"25.03 — Утверждено"
|
||
]
|
||
},
|
||
{
|
||
"id": 6,
|
||
"sec": 0,
|
||
"b": 6,
|
||
"s": "warn",
|
||
"p": 60,
|
||
"due": "30.06.2026",
|
||
"done": "—",
|
||
"dname": "Утверждённый ВНД, перечень внутренних тренеров",
|
||
"r": "Генеральный директор КУ\nУправляющий директор по персоналу\nГенеральные директора филиалов и ДАО",
|
||
"t": "Разработать/внести изменения в случае необходимости и утвердить внутренний нормативный документ, регламентирующий процедуру работы внутренних тренеров, в том числе по производственной безопасности, включая порядок их отбора, подготовки и привлечения, а также установление условий доплаты к основной заработной плате за выполнение тренерских функций.",
|
||
"ai": "Проект ВНД на финальном согласовании.",
|
||
"h": [
|
||
"01.03 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 7,
|
||
"sec": 0,
|
||
"b": 1,
|
||
"s": "warn",
|
||
"p": 40,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Материалы, рассмотренные в рамках обмена опытом",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Проводить мероприятия по обмену опытом в области производственной безопасности:\na) Продолжить практику обмена передовым опытом на площадке Комитета HSE, в том числе путем выездов на производственные объекты ПК, с целью последующего тиражирования успешных практик в ПК.\nb) Рассмотреть возможность организации обмена опытом в области производственной безопасности для работников ПК с иностранными и казахстанскими компаниями, соответствующих деятельности ПК, в том числе путем проведения онлайн-семинаров.",
|
||
"ai": "Проведён 1 выезд на KEGOC.",
|
||
"h": [
|
||
"15.02 — Создано",
|
||
"01.04 — Выезд"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Продолжить практику обмена передовым опытом на площадке Комитета HSE, в том числе путем выездов на производственные объекты ПК"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Рассмотреть возможность организации обмена опытом с иностранными и казахстанскими компаниями, в том числе путем проведения онлайн-семинаров"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 8,
|
||
"sec": 0,
|
||
"b": 4,
|
||
"s": "wait",
|
||
"p": 15,
|
||
"due": "30.09.2026",
|
||
"done": "—",
|
||
"dname": "Заключительный Акт, программа Well-being, отчёт о скрининге, отчёт о микротравмах",
|
||
"r": "а) Директор ДПБ\nb) Генеральный директор КУ\nУправляющий директор по персоналу\nc) Управляющий директор по персоналу\nГенеральные директора филиалов и ДАО\nd) Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Провести анализ эффективности реализуемых мероприятий по охране здоровья:\na) организовать и обеспечить 100% прохождение обязательных периодических медицинских осмотров работниками, включая офисных работников;\nb) организовать ежегодную «Неделю благополучия» (Well-being Week) для работников всех уровней, предусматривая практические мероприятия по стресс-менеджменту, ментальному здоровью и физической активности;\nc) создать условия и обеспечить контроль за прохождением медицинского скрининга работников в соответствии с Приказом и.о. Министра Здравоохранения РК от 30 октября 2020 года №КР ДСМ-174/2020, в том числе в целях раннего диагностирования факторов риска сердечно-сосудистых заболеваний;\nd) внедрить алгоритм учета и расследования микротравм, а также фиксировать использование содержимого медицинских аптечек путем регистрации и расследования данных случаев.",
|
||
"ai": "Медосмотры — Q3. Well-being — сентябрь.",
|
||
"h": [
|
||
"01.04 — Создано"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Организовать и обеспечить 100% прохождение обязательных периодических медицинских осмотров работниками, включая офисных работников"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Организовать ежегодную «Неделю благополучия» (Well-being Week) для работников всех уровней"
|
||
},
|
||
{
|
||
"l": "c",
|
||
"t": "Создать условия и обеспечить контроль за прохождением медицинского скрининга работников"
|
||
},
|
||
{
|
||
"l": "d",
|
||
"t": "Внедрить алгоритм учета и расследования микротравм, фиксировать использование содержимого медицинских аптечек"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 9,
|
||
"sec": 0,
|
||
"b": 6,
|
||
"s": "wait",
|
||
"p": 20,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Результаты конкурсов, пакет материалов",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Рассмотреть возможность участия ДПБ/филиалов/ДАО Общества в международных/национальных конкурсах и отраслевых соревнованиях профессионального мастерства в области производственной безопасности.",
|
||
"ai": "Определены 2 конкурса.",
|
||
"h": [
|
||
"01.05 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 10,
|
||
"sec": 1,
|
||
"b": 1,
|
||
"s": "warn",
|
||
"p": 55,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Аналитическая справка в разбивке по филиалам/ДАО",
|
||
"r": "Генеральный директор ОДС\nГенеральный директор СФ\nГенеральный директор ДУП\nГенеральный директор ДИТ",
|
||
"t": "Проводить работы по техническому перевооружению морально и физически изношенного оборудования, зданий и сооружений, эксплуатация которых из-за их технического состояния сопровождается повышенными рисками возникновения аварий и несчастных случаев с тяжёлыми и летальными исходами, в соответствии с ранее утвержденными Планами на 2024-2027 годы.",
|
||
"ai": "По плану 2024-2027. Заменено 55%.",
|
||
"h": [
|
||
"01.01 — Переходящее"
|
||
]
|
||
},
|
||
{
|
||
"id": 11,
|
||
"sec": 1,
|
||
"b": 1,
|
||
"s": "warn",
|
||
"p": 70,
|
||
"due": "30.06.2026",
|
||
"done": "—",
|
||
"dname": "Переутверждённая процедура, фотоотчёт, протоколы обучения",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Пересмотреть и актуализировать внутренний порядок выдачи нарядно-допускной системы, усилив законодательные требования Республики Казахстан путем внедрения в пилотном режиме практики применения сертификатов безопасности для одного из видов работ повышенной опасности. Указанные сертификаты должны содержать исчерпывающую информацию о потенциальных рисках и мерах безопасности перед началом работ, предусматривать обязательный замер газовоздушной среды при работах в замкнутом пространстве, анализ плана участка и исполнительных чертежей, установку защитных барьеров при проведении земляных работ, выполнение электрической изоляции источников опасности с обязательной проверкой отсутствия напряжения, а также меры безопасности при проведении радиографических работ.",
|
||
"ai": "Процедура пересмотрена. Пилот запущен.",
|
||
"h": [
|
||
"01.02 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 12,
|
||
"sec": 1,
|
||
"b": 8,
|
||
"s": "wait",
|
||
"p": 8,
|
||
"due": "30.09.2026",
|
||
"done": "—",
|
||
"dname": "Справка о внедрении, фотоотчёт",
|
||
"r": "Генеральные директора филиалов и ДАО",
|
||
"t": "Рассмотреть возможность внедрения системы цифровой маркировки опасных технических устройств, предусматривающей присвоение каждому устройству QR-кода для обеспечения быстрого доступа к паспорту, инструкции по эксплуатации и информации о проведенных технических освидетельствованиях, с учетом возможности использования мобильных телефонов на опасных производственных объектах.",
|
||
"ai": "Проект на стадии ТЭО.",
|
||
"h": [
|
||
"01.05 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 13,
|
||
"sec": 1,
|
||
"b": 0,
|
||
"s": "warn",
|
||
"p": 50,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Акты проверок и график",
|
||
"r": "Директор ДПБ",
|
||
"t": "Филиалам/ДАО Общества не реже 1 раза в квартал проводить проверку согласно адаптированным проверочным листам, в области БиОТ, промышленной и пожарной безопасности в соответствии с требованиями законодательства Республики Казахстан.",
|
||
"ai": "Q1 завершены. Q2 — по графику.",
|
||
"h": [
|
||
"01.01 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 14,
|
||
"sec": 1,
|
||
"b": 0,
|
||
"s": "warn",
|
||
"p": 40,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Письмо о предоставлении кандидата",
|
||
"r": "Директор ДПБ",
|
||
"t": "Продолжить практику участия в перекрёстных аудитах ПК, в том числе в соответствии с Планом-графиком проведения аудитов.",
|
||
"ai": "Назначены 4 аудитора.",
|
||
"h": [
|
||
"15.01 — Назначены"
|
||
]
|
||
},
|
||
{
|
||
"id": 15,
|
||
"sec": 1,
|
||
"b": 0,
|
||
"s": "warn",
|
||
"p": 48,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Аналитическая справка, Журнал «Опережающие индикаторы»",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Усилить контроль за применением проактивных инструментов:\nа) Продолжить мониторинг применения проактивных инструментов предотвращения аварий и несчастных случаев (проведение поведенческих аудитов/наблюдений безопасности, регистрация и расследование опасных условий, опасных действий и потенциально опасных происшествий Near Miss; право приостановки работы) с целью выработки корректирующих мероприятий, исключения формализма и занесения достоверных данных в Журнал «Опережающие индикаторы» Системы управления отчетности АО «Самрук-Қазына» и потенциально опасных происшествий Near Miss.",
|
||
"ai": "147 Near Miss. Аудиты — 320 шт.",
|
||
"h": [
|
||
"01.01 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 16,
|
||
"sec": 1,
|
||
"b": 1,
|
||
"s": "done",
|
||
"p": 85,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "План-график аудитов, Акты, Протоколы совещаний",
|
||
"r": "Генеральные директора филиалов и ДАО",
|
||
"t": "Провести работу по повышению эффективности управления подрядными организациями, в том числе:\na) обеспечить проведение согласно типового чек-листа, разработанного Фондом, аудита подрядчиков внутри филиалов/ДАО Общества выборочных перекрёстных аудитов подрядных организаций, осуществляющих работы по договорам на оказание услуг сроком от 6 месяцев и более на объектах предприятий, преимущественно в которых произошли несчастные случаи со смертельным и тяжелым исходами, с участием специалистов службы производственной безопасности Общества и ДАО, не связанных с проверяемыми объектами;\nb) продолжить практику проведения стартовых/установочных совещаний с подрядными организациями перед допуском на территорию объекта филиалов/ДАО Общества с целью ознакомления с внутренними нормативными документами по производственной безопасности, а также информацией об опасных производственных объектах, оборудовании и (или) территории, создающих угрозу жизни и здоровью людей.",
|
||
"ai": "Q1 — 12 подрядчиков проверено.",
|
||
"h": [
|
||
"15.01 — План"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Обеспечить проведение аудита подрядчиков согласно типового чек-листа Фонда"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Продолжить практику проведения стартовых/установочных совещаний с подрядными организациями перед допуском на объект"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 17,
|
||
"sec": 1,
|
||
"b": 0,
|
||
"s": "warn",
|
||
"p": 35,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Отчёты, график проверок, фотоотчёт",
|
||
"r": "а) Главный административный директор, Директор ДПБ\nb) Генеральные директора филиалов и ДАО",
|
||
"t": "Обеспечить контроль за состоянием производственной безопасности на производственных объектах:\nа) руководителям Общества уровня СЕО-1, курирующим вопросы производственной безопасности в Обществе, не реже одного раза в квартал лично проверять одно из филиалов Общества/подрядных организаций или участок, в зависимости от структуры и специфики Общества с обязательным представлением актов по результатам проверок в Фонд;\nb) первым руководителям и руководителям линейных подразделений филиалов Общества лично принимать участие во внутреннем производственном контроле с посещением производственных площадок не реже одного раза в квартал.",
|
||
"ai": "CEO-1: 2 филиала.",
|
||
"h": [
|
||
"01.02 — Создано"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Руководителям уровня СЕО-1 не реже одного раза в квартал лично проверять филиал/подрядчика"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Первым руководителям филиалов лично принимать участие в контроле с посещением площадок"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 18,
|
||
"sec": 1,
|
||
"b": 1,
|
||
"s": "done",
|
||
"p": 90,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Ежемесячный сводный отчёт",
|
||
"r": "Генеральные директора филиалов и ДАО\nДиректор ДПБ",
|
||
"t": "Обеспечить контроль за состоянием транспортной безопасности, в том числе путем ежемесячного мониторинга нарушений требований транспортной безопасности со стороны штатных водителей и водителей подрядных организаций, оказывающих транспортные услуги по перевозке работников, с последующим применением предусмотренных договорами мер воздействия, включая штрафные санкции и ограничения на допуск к работам.",
|
||
"ai": "34 нарушения. Тренд — снижение.",
|
||
"h": [
|
||
"01.01 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 19,
|
||
"sec": 2,
|
||
"b": 1,
|
||
"s": "warn",
|
||
"p": 30,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Акты тренировок, пресс-релизы",
|
||
"r": "a) Управляющий директор по безопасности, Руководители ДАО\nb) Генеральный директор СФ, Руководители ДАО\nс) Управляющий директор по безопасности\nГенеральные директора филиалов и ДАО",
|
||
"t": "Обеспечить проведение:\nа) не менее одной учебной тревоги и/или противоаварийной тренировки по ликвидации крупной аварии, ЧС на опасном производственном объекте с привлечением Фонда и государственных органов;\nb) не менее двух тренировок по тушению пожара в административных зданиях (офисах) с привлечением государственных органов;\nc) не менее одного практического занятия по оказанию первой помощи с применением симуляционного оборудования в условиях ЧС техногенного и природного характера.",
|
||
"ai": "1 учение. Пожарные: 1 из 2.",
|
||
"h": [
|
||
"01.02 — Создано"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Не менее одной учебной тревоги/противоаварийной тренировки"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Не менее двух тренировок по тушению пожара"
|
||
},
|
||
{
|
||
"l": "c",
|
||
"t": "Не менее одного занятия по оказанию первой помощи"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 20,
|
||
"sec": 2,
|
||
"b": 0,
|
||
"s": "warn",
|
||
"p": 65,
|
||
"due": "30.06.2026",
|
||
"done": "—",
|
||
"dname": "Приказ о внедрении, материалы обучения, акты штабов",
|
||
"r": "Управляющий директор по безопасности\nГенеральные директора филиалов и ДАО",
|
||
"t": "Усилить работу по реагированию на ЧС:\nа) внедрить процедуру «Crisis Management System» (Система управления кризисными ситуациями) для обеспечения своевременной и согласованной реакции на всех уровнях управления на кризисные события, а также сокращение ущерба для работников, активов, окружающей среды и репутации компании;\nb) рассмотреть возможность проведения обучения для ответственных работников филиалов/ДАО Общества по действиям в условиях ЧС;\nc) провести не менее двух заседаний штабов с целью отработки действий на практике.",
|
||
"ai": "CMS внедрена. Обучение — 60%.",
|
||
"h": [
|
||
"01.03 — Создано"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Внедрить процедуру «Crisis Management System»"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Провести обучение ответственных работников по действиям в условиях ЧС"
|
||
},
|
||
{
|
||
"l": "c",
|
||
"t": "Провести не менее двух заседаний штабов"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 21,
|
||
"sec": 3,
|
||
"b": 0,
|
||
"s": "done",
|
||
"p": 100,
|
||
"due": "31.12.2026",
|
||
"done": "15.02.2026",
|
||
"dname": "Публикация на информационных порталах",
|
||
"r": "Директор ДПБ\nПресс-секретарь ЦА",
|
||
"t": "Обеспечить выпуск обращения от Председателя Правления ПК о важности соблюдения требований по производственной безопасности.",
|
||
"ai": "Опубликовано. Охват — 100%.",
|
||
"h": [
|
||
"15.02 — Публикация"
|
||
]
|
||
},
|
||
{
|
||
"id": 22,
|
||
"sec": 3,
|
||
"b": 0,
|
||
"s": "wait",
|
||
"p": 15,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Протоколы форумов, протоколы семинаров",
|
||
"r": "a) Директор ДПБ\nГенеральные директора филиалов и ДАО\nДепартамент по коммуникациям и продвижению бренда\nb) Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Проведение мероприятий по производственной безопасности:\na) в филиалах/ДАО Общества стратегических сессий/Форумов для первых руководителей филиалов/ДАО Общества;\nb) рассмотреть возможность проведения семинаров для подрядных организаций ПК на отдельных площадках филиалов/ДАО Общества.",
|
||
"ai": "Форум — октябрь.",
|
||
"h": [
|
||
"01.05 — Создано"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "В филиалах/ДАО стратегические сессии/Форумы для первых руководителей"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Семинары для подрядных организаций ПК на отдельных площадках"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 23,
|
||
"sec": 3,
|
||
"b": 6,
|
||
"s": "wait",
|
||
"p": 10,
|
||
"due": "30.09.2026",
|
||
"done": "—",
|
||
"dname": "Протокол итогов Олимпиады",
|
||
"r": "Директор ДПБ",
|
||
"t": "Проведение Олимпиады по производственной безопасности среди специалистов производственной безопасности Общества и подрядных организации на уровне Общества.",
|
||
"ai": "Положение на согласовании.",
|
||
"h": [
|
||
"01.05 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 24,
|
||
"sec": 3,
|
||
"b": 0,
|
||
"s": "done",
|
||
"p": 92,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Информационные бюллетени, листы ознакомления",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Обеспечить ознакомление всех работников филиалов/ДАО Общества с обстоятельствами несчастных случаев с тяжелым и летальным исходами, произошедших в ПК Фонда, и относящихся к специфике деятельности Общества, посредством направления информационных бюллетеней, в том числе с использованием цифровых решений либо в рамках внеплановых инструктажей.",
|
||
"ai": "3 бюллетеня, 92%.",
|
||
"h": [
|
||
"01.01 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 25,
|
||
"sec": 3,
|
||
"b": 6,
|
||
"s": "warn",
|
||
"p": 40,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Публикации в SK News, материалы мероприятий",
|
||
"r": "a) Управляющий директор по персоналу\nДепартамент по коммуникациям и продвижению бренда\nГенеральные директора филиалов и ДАО\nb) Директор ДПБ\nГенеральные директора филиалов и ДАО\nc) Директор ДПБ\nd) Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Проведение молодежных проектных инициатив в рамках работы Центра молодых работников по производственной безопасности группы компаний АО «Самрук-Қазына» с целью вовлечения молодых специалистов в вопросы производственной безопасности, в том числе:\na) публикация реальных историй из трудовой жизни работников в корпоративном журнале «SK News»;\nb) посещение рабочих мест, где в 2022-2025 годах произошли несчастные случаи с летальным или тяжелым исходом;\nc) привлечение молодых специалистов по производственной безопасности в перекрёстные аудиты состояния производственной безопасности ДЗО ПК АО «Самрук-Қазына»;\nd) онлайн-семинары/прямые эфиры на различные темы по вопросам производственной безопасности.",
|
||
"ai": "2 истории в SK News.",
|
||
"h": [
|
||
"01.02 — Создано"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Публикация реальных историй из трудовой жизни работников в журнале «SK News»"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Посещение рабочих мест, где в 2022-2025 годах произошли несчастные случаи"
|
||
},
|
||
{
|
||
"l": "c",
|
||
"t": "Привлечение молодых специалистов в перекрёстные аудиты"
|
||
},
|
||
{
|
||
"l": "d",
|
||
"t": "Онлайн-семинары/прямые эфиры на темы производственной безопасности"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 26,
|
||
"sec": 3,
|
||
"b": 2,
|
||
"s": "warn",
|
||
"p": 50,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Видеоролики, постеры, брошюры",
|
||
"r": "а) Генеральные директора филиалов и ДАО\nb) и с) Директор ДПБ\nДепартамент по коммуникациям и продвижению бренда\nГенеральные директора филиалов и ДАО\nd) Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Усилить наглядную агитацию по производственной безопасности:\nа) Продолжить работы по разработке и использованию видеороликов/презентаций по производственной безопасности, в том числе:\n- с участием работников, получивших травму, а также членов семей работников (с их согласия);\n- с участием нарушителей требований безопасности и охраны труда, включая разбор ошибок и разработку мер по предотвращению аналогичных случаев в будущем (с их согласия).\nb) Разработать серии специализированных видеороликов:\n- в формате «Безопасность будущего», направленный на демонстрацию внедряемых цифровых и ИИ-решений в сфере производственной безопасности в группе Фонда;\n- по профилактике производственного травматизма с акцентом на наиболее опасные риски (ДТП, падения с высоты, работа с движущимися механизмами и т.д.).\nc) Рассмотреть возможность выпуска подкаста с участием трудовых династий о переходе от ручного труда к автоматизации и цифровизации, способствующем повышению уровня производственной безопасности.\nd) Продолжить работы по разработке и распространению постеров, брошюр, информационных рассылок на различные темы по соблюдению производственной безопасности.",
|
||
"ai": "2 видеоролика снято.",
|
||
"h": [
|
||
"01.02 — Создано"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Разработка и использование видеороликов/презентаций по ПБ"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Серии видеороликов «Безопасность будущего» и по профилактике травматизма"
|
||
},
|
||
{
|
||
"l": "c",
|
||
"t": "Выпуск подкаста с участием трудовых династий"
|
||
},
|
||
{
|
||
"l": "d",
|
||
"t": "Разработка и распространение постеров, брошюр, рассылок"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 27,
|
||
"sec": 3,
|
||
"b": 3,
|
||
"s": "warn",
|
||
"p": 30,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Фотофиксация",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Рассмотрение возможности организации встреч коллектива с получившими производственные травмы работниками (с их согласия) с целью предупреждения аналогичных случаев травматизма.",
|
||
"ai": "1 встреча проведена.",
|
||
"h": [
|
||
"01.03 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 28,
|
||
"sec": 3,
|
||
"b": 0,
|
||
"s": "warn",
|
||
"p": 25,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Информационное письмо, пресс-релизы",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО\nДепартамент по коммуникациям и продвижению бренда",
|
||
"t": "Проведение мероприятий, направленных на пропаганду безопасного выполнения работ через семейные ценности:\nа) направление информационного письма членам семьи (супруг/а, родители) работника, положительно отличившегося в вопросах производственной безопасности;\nb) проведение Семейных дней охраны труда и дней открытых дверей для семей работников, в том числе на тему «Золотые правила безопасности для детей», с целью воспитания подрастающего поколения в традициях безопасности;\nc) проведение конкурса рисунков среди работников и их детей по безопасной работе и соблюдению правил на производстве на тему «Спецодежда будущего!».",
|
||
"ai": "5 писем семьям.",
|
||
"h": [
|
||
"01.04 — Создано"
|
||
],
|
||
"sub": [
|
||
{
|
||
"l": "a",
|
||
"t": "Направление письма членам семьи работника, отличившегося в вопросах ПБ"
|
||
},
|
||
{
|
||
"l": "b",
|
||
"t": "Проведение Семейных дней охраны труда и дней открытых дверей"
|
||
},
|
||
{
|
||
"l": "c",
|
||
"t": "Конкурс рисунков «Спецодежда будущего!»"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"id": 29,
|
||
"sec": 3,
|
||
"b": 6,
|
||
"s": "late",
|
||
"p": 40,
|
||
"due": "30.06.2026",
|
||
"done": "—",
|
||
"dname": "Корпоративный сборник лучших практик",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Разработать корпоративный сборник лучших практик по производственной безопасности в формате методического пособия или интерактивного PDF документа, отражающий меры по снижению производственного травматизма и управлению критическими рисками. В сборнике предусмотреть описание сути инициатив, перечень ключевых рисков (железнодорожные происшествия, ДТП, работы на высоте и др.), реализованные мероприятия, а также достигнутые результаты за последние пять лет.",
|
||
"ai": "Риск срыва Q2.",
|
||
"h": [
|
||
"01.03 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 30,
|
||
"sec": 3,
|
||
"b": 7,
|
||
"s": "warn",
|
||
"p": 60,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Предложения, план реализации",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Сбор предложений по совершенствованию системы управления производственной безопасности посредством применения цифровых решений с консолидацией в ДПБ.",
|
||
"ai": "18 предложений.",
|
||
"h": [
|
||
"01.01 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 31,
|
||
"sec": 3,
|
||
"b": 0,
|
||
"s": "warn",
|
||
"p": 75,
|
||
"due": "30.06.2026",
|
||
"done": "—",
|
||
"dname": "Видеообзор",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Разработка видеообзора кейсов происшествий в ПК с учетом специфики деятельности (из доступных на открытых медиа источниках) для наглядной демонстрации и разъяснения работникам о необходимости и важности соблюдения требований безопасности.",
|
||
"ai": "Монтаж 75%.",
|
||
"h": [
|
||
"01.03 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 32,
|
||
"sec": 4,
|
||
"b": 8,
|
||
"s": "warn",
|
||
"p": 70,
|
||
"due": "30.06.2026",
|
||
"done": "—",
|
||
"dname": "Справка, скриншоты чат-бота",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Обеспечить применение в филиалах/ДАО Общества чат-бот ИИ ассистент по производственной безопасности с целью упрощения доступа к нормативно-правовым актам Республики Казахстан и ВНД группы Фонда.",
|
||
"ai": "Чат-бот тестируется.",
|
||
"h": [
|
||
"01.02 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 33,
|
||
"sec": 4,
|
||
"b": 8,
|
||
"s": "wait",
|
||
"p": 15,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Справка, скриншоты системы",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Обеспечить применение в филиалах/ДАО Общества интегрированную систему анализа и предупреждения несчастных случаев и критических происшествий, а также платформу по идентификации и оценке рисков перед началом проведения работ на опасных производственных объектах.",
|
||
"ai": "ТЗ согласовывается.",
|
||
"h": [
|
||
"01.04 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 34,
|
||
"sec": 4,
|
||
"b": 8,
|
||
"s": "wait",
|
||
"p": 10,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Справка, скриншоты HSE паспорта",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Рассмотреть возможность запуска в филиалах/ДАО Общества электронного HSE паспорта на каждого работника с последующей интеграцией в корпоративную цифровую систему. Электронный HSE паспорт должен содержать сведения о прохождении инструктажей, обучения и проверок знаний, результаты медицинских осмотров, а также данные о выданных СИЗ, допусках к видам работ, стаже и квалификации.",
|
||
"ai": "Концепция утверждена.",
|
||
"h": [
|
||
"01.05 — Создано"
|
||
]
|
||
},
|
||
{
|
||
"id": 35,
|
||
"sec": 4,
|
||
"b": 5,
|
||
"s": "wait",
|
||
"p": 8,
|
||
"due": "31.12.2026",
|
||
"done": "—",
|
||
"dname": "Справка, скриншоты системы",
|
||
"r": "Директор ДПБ\nГенеральные директора филиалов и ДАО",
|
||
"t": "Рассмотреть возможность внедрения системы оформления нарядов-допусков на проведение работ повышенной опасности в электронном виде в филиалах/ДАО Общества.",
|
||
"ai": "Предпроект.",
|
||
"h": [
|
||
"01.05 — Создано"
|
||
]
|
||
}
|
||
];
|
||
|
||
var cu=null,evs=[],tab="events",curSub=null;
|
||
var secs=["Раздел I. Обучение, компетенции и культура безопасности","Раздел II. Техническая безопасность и надежность","Раздел III. Готовность к ЧС","Раздел IV. Коммуникации и вовлеченность","Раздел V. Цифровизация и инновации"];
|
||
var brs=["Дирекция производственной безопасности","Объединение «Дивизион «Сеть»","Дивизион по корпоративному бизнесу","Дивизион по розничному бизнесу","Сервисная фабрика","Дирекция «Телеком Комплект»","Корпоративный университет","Дирекция управления проектами","Дивизион цифрового бизнеса"];
|
||
var stn={warn:"В процессе",late:"Просрочено",done:"Исполнено"};
|
||
var stc={warn:"a",late:"r",done:"g"};
|
||
var USR={curator:{n:"Куратор ПБ",bg:0},admin:{n:"Администратор",bg:0},dpp:{n:"Директор ДПБ",bg:0},ivanov:{n:"Иванов Иван",bg:1},petrov:{n:"Петров Петр",bg:2},sidorov:{n:"Сидоров Сидор",bg:3},kozhin:{n:"Кожин А.М.",bg:4},ismailov:{n:"Исмаилов Р.К.",bg:1},nurpeisov:{n:"Нурпеисов Д.А.",bg:5},suleimenov:{n:"Сулейменов К.Т.",bg:6},kassenov:{n:"Касенов Б.Б.",bg:7},serikov:{n:"Сериков Е.С.",bg:8},zhunusov:{n:"Жунусов А.А.",bg:2},muratov:{n:"Муратов А.Т.",bg:3},bakirov:{n:"Бакиров Т.Н.",bg:4}};
|
||
|
||
function cleanTitle(e){
|
||
if(!e||!e.t)return"";
|
||
if(!e.sub||!e.sub.length)return e.t;
|
||
var t=e.t;var idx=t.indexOf("\na)");if(idx<0)idx=t.indexOf("\n\u0430)");if(idx<0)idx=t.indexOf("\na\u0029");if(idx<0)idx=t.indexOf(":"+String.fromCharCode(10)+"a");
|
||
return idx>0?t.substring(0,idx).trim():t
|
||
}
|
||
function esc(s){
|
||
return String(s).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")
|
||
}
|
||
function nl2c(s){
|
||
if(!s)return"";
|
||
return s.split(String.fromCharCode(10)).join(", ")
|
||
}
|
||
function subResp(r,letter){
|
||
if(!r)return"";
|
||
var parts=r.split(String.fromCharCode(10));
|
||
var cur="",found=false;
|
||
for(var i=0;i<parts.length;i++){
|
||
var p=parts[i].trim();
|
||
if(!p)continue;
|
||
var m=p.match(/^([a-z\u0430-\u044F]+)[\u0029\)]/);
|
||
if(m){
|
||
if(found)break;
|
||
var ids=m[1].split(",");
|
||
for(var j=0;j<ids.length;j++){
|
||
if(ids[j].trim()===letter){found=true;cur=p.replace(/^[a-z\u0430-\u044F,\s]+[\u0029\)]\s*/,"");break}
|
||
}
|
||
}else{
|
||
if(found)cur+=String.fromCharCode(10)+p
|
||
}
|
||
}
|
||
return cur||""
|
||
}
|
||
|
||
function init(){
|
||
try{
|
||
var su=localStorage.getItem("su");
|
||
if(su)cu=JSON.parse(su);
|
||
}catch(e){}
|
||
loadEv();
|
||
var fb=document.getElementById("fb");
|
||
if(fb){
|
||
for(var i=0;i<brs.length;i++){
|
||
var o=document.createElement("option");
|
||
o.value=i;o.textContent=brs[i];
|
||
fb.appendChild(o)
|
||
}
|
||
}
|
||
if(cu)showApp()
|
||
}
|
||
|
||
function doLogin(){
|
||
var e=document.getElementById("lem").value.trim().toLowerCase();
|
||
var k=e.split("@")[0];
|
||
var u=USR[k]||USR[e];
|
||
if(!u){var ex=localStorage.getItem("ext_users");if(ex){try{var eu=JSON.parse(ex);if(eu[k])u=eu[k];if(!u&&eu[e])u=eu[e]}catch(e){}}}
|
||
if(u){
|
||
cu={n:u.n,bg:u.bg,role:u.role!==undefined?u.role:(u.bg===0?0:1)};
|
||
localStorage.setItem("su",JSON.stringify(cu));
|
||
showApp()
|
||
}else{
|
||
document.getElementById("lerr").style.display="block"
|
||
}
|
||
}
|
||
function doLogout(){
|
||
localStorage.removeItem("su");
|
||
cu=null;
|
||
document.getElementById("login").style.display="flex";
|
||
document.getElementById("app").style.display="none"
|
||
}
|
||
function showApp(){
|
||
document.getElementById("login").style.display="none";
|
||
document.getElementById("app").style.display="block";
|
||
document.getElementById("su_name").textContent=cu?cu.n:"";
|
||
var unav=document.getElementById("snav_users");
|
||
if(unav)unav.style.display=cu&&cu.bg===0?"":"none";
|
||
var hsenav=document.getElementById("snav_hse");
|
||
if(hsenav)hsenav.style.display=cu&&cu.bg===0?"":"none";
|
||
if(cu&&cu.role===2){var anav=document.getElementById("snav_analytics");if(anav)anav.style.display="";var unav2=document.getElementById("snav_users");if(unav2)unav2.style.display="none"}
|
||
switchTab("events")
|
||
}
|
||
|
||
function loadEv(){
|
||
evs=[];
|
||
if(typeof ALL_EVENTS!=="undefined"&&ALL_EVENTS&&ALL_EVENTS.length){
|
||
var saved=localStorage.getItem("se5");
|
||
var smap={};
|
||
if(saved){
|
||
try{
|
||
var sd=JSON.parse(saved);
|
||
for(var i=0;i<sd.length;i++){
|
||
if(sd[i]&&sd[i].id)smap[sd[i].id]=sd[i]
|
||
}
|
||
}catch(e){}
|
||
}
|
||
for(var i=0;i<ALL_EVENTS.length;i++){
|
||
var e=ALL_EVENTS[i];
|
||
if(smap[e.id]){
|
||
e.s=smap[e.id].s||e.s;
|
||
if(smap[e.id].p!==undefined)e.p=smap[e.id].p;
|
||
if(smap[e.id].done)e.done=smap[e.id].done;
|
||
if(smap[e.id].h)e.h=smap[e.id].h;
|
||
if(smap[e.id].q!==undefined)e.q=smap[e.id].q;
|
||
if(smap[e.id].n!==undefined)e.n=smap[e.id].n
|
||
}
|
||
evs.push(e)
|
||
}
|
||
}
|
||
storCheck()
|
||
}
|
||
function saveEv(){
|
||
var out=[];
|
||
for(var i=0;i<evs.length;i++){
|
||
out.push({id:evs[i].id,s:evs[i].s,p:evs[i].p,done:evs[i].done,h:evs[i].h,q:evs[i].q,n:evs[i].n})
|
||
}
|
||
try{localStorage.setItem("se5",JSON.stringify(out))}catch(e){}
|
||
storCheck()
|
||
}
|
||
|
||
function switchTab(t){
|
||
tab=t;
|
||
var tabs=["events","analytics","reports","ai","users","hse"];
|
||
var tn={events:"Мероприятия",analytics:"Аналитика",reports:"Отчётность",ai:"Джарвис",users:"Учётные записи",hse:"HSE.sk.kz"};
|
||
for(var i=0;i<tabs.length;i++){
|
||
var el=document.getElementById("tab_"+tabs[i]);
|
||
if(el)el.style.display="none";
|
||
var nav=document.getElementById("snav_"+tabs[i]);
|
||
if(nav)nav.className=""
|
||
}
|
||
var sel=document.getElementById("tab_"+t);
|
||
if(sel)sel.style.display="block";
|
||
document.getElementById("page_title").textContent=tn[t];
|
||
if(t==="events")renderEv();
|
||
if(t==="analytics")renderAnalytics();
|
||
if(t==="reports")renderReports();
|
||
if(t==="ai")renderAI()
|
||
if(t==="hse"){var hm=document.getElementById("hse_month");if(hm&&!hm.value)hm.value=new Date().toISOString().slice(0,7)}
|
||
if(t==="users")renderUsers()
|
||
}
|
||
|
||
function daysRem(due){
|
||
if(!due||due==="\u2014")return 999;
|
||
var p=due.split(".");
|
||
if(p.length!==3)return 999;
|
||
var d=new Date(parseInt(p[2],10),parseInt(p[1],10)-1,parseInt(p[0],10));
|
||
var now=new Date();
|
||
now.setHours(0,0,0,0);
|
||
return Math.floor((d-now)/86400000)
|
||
}
|
||
|
||
function renderEv(){
|
||
var sea=document.getElementById("sea").value.toLowerCase().trim();
|
||
var fs=document.getElementById("fs").value;
|
||
var fb=document.getElementById("fb").value;
|
||
var fl=evs;
|
||
if(sea){
|
||
fl=fl.filter(function(e){
|
||
return e.t.toLowerCase().indexOf(sea)!==-1||
|
||
e.r.toLowerCase().indexOf(sea)!==-1||
|
||
e.dname.toLowerCase().indexOf(sea)!==-1||
|
||
String(e.id).indexOf(sea)!==-1
|
||
})
|
||
}
|
||
if(fs)fl=fl.filter(function(e){return e.s===fs});
|
||
if(fb!=="")fl=fl.filter(function(e){return String(e.b)===fb});
|
||
document.getElementById("sc").textContent="Показано: "+fl.length+" из "+evs.length;
|
||
var h="";
|
||
var lastSec=-1;
|
||
for(var i=0;i<fl.length;i++){
|
||
var e=fl[i];
|
||
if(e.sec!==lastSec){
|
||
if(lastSec!==-1)h+="<tr><td colspan='7' style='padding:4px;border:none'></td></tr>";
|
||
h+="<tr><td colspan='7' style='padding:0;border:none'><div class='sec-h'>"+esc(secs[e.sec])+"</div></td></tr>";
|
||
lastSec=e.sec
|
||
}
|
||
var dr=daysRem(e.due);
|
||
var rowCl=e.s==="done"?"tr-green":dr<=0&&e.s!=="done"?"tr-red":dr<=14?"tr-amber":"";
|
||
var cl=stc[e.s]||"w";
|
||
var drText=dr<=0&&e.s!=="done"?"Просрочено на "+Math.abs(dr)+" дн.":e.s==="done"?"Готово":dr===999?"\u2014":dr+" дн.";
|
||
var hasSub=e.sub&&e.sub.length>0;
|
||
h+="<tr class='"+rowCl+"'>";
|
||
h+="<td style='font-weight:700;font-size:12px'>"+e.id+"</td>";
|
||
h+="<td><div style='font-size:12px;line-height:1.3'>"+esc(e.t)+"</div><div style='font-size:10px;color:#64748B;margin-top:2px'>"+esc(e.dname)+"</div></td>";
|
||
h+="<td style='font-size:11px'>"+esc(nl2c(e.r))+"</td>";
|
||
h+="<td style='font-size:12px;white-space:nowrap'>"+e.due+" <span style='font-size:10px;color:#64748B'>("+drText+")</span></td>";
|
||
if(hasSub){h+="<td></td><td></td>"}
|
||
else{
|
||
h+="<td><span class='badge "+cl+"'>"+stn[e.s]+"</span></td>";
|
||
h+="<td><button class='btn btn-sm' style='padding:4px 12px;font-size:11px' onclick='openEv("+e.id+")'>Открыть</button></td>"
|
||
}
|
||
h+="</tr>";
|
||
if(hasSub){
|
||
for(var si=0;si<e.sub.length;si++){
|
||
var sr=subResp(e.r,e.sub[si].l)||nl2c(e.r);
|
||
var ss=e.s==="wait"?"warn":e.s;
|
||
var scl=stc[ss]||"a";
|
||
h+="<tr class='"+rowCl+" sub-item-row'><td style='padding-left:24px;font-size:11px;color:#64748B'>"+e.id+"."+esc(e.sub[si].l)+"</td>";
|
||
h+="<td style='font-size:11px'>"+esc(e.sub[si].t)+"</td>";
|
||
h+="<td style='font-size:11px'>"+esc(sr)+"</td>";
|
||
h+="<td style='font-size:11px'>"+e.due+"</td>";
|
||
h+="<td><span class='badge "+scl+"' style='font-size:10px'>"+stn[ss]+"</span></td>";
|
||
h+="<td><button class='btn btn-sm' style='padding:4px 10px;font-size:11px' onclick='openEv("+e.id+","+si+")'>Открыть</button></td></tr>"
|
||
}
|
||
}
|
||
}
|
||
if(!h)h="<p style='color:#64748B;padding:20px;text-align:center'>Нет мероприятий</p>";
|
||
document.getElementById("ev_content").innerHTML="<table><tr><th>N</th><th>Мероприятие</th><th>Ответственные</th><th>Срок</th><th>Статус</th><th></th></tr>"+h+"</table>"
|
||
}
|
||
|
||
function togSub(id){
|
||
var el=document.getElementById("sub_"+id);
|
||
if(!el)return;
|
||
var arr=document.getElementById("arr_"+id);
|
||
if(el.style.display==="none"){
|
||
el.style.display="block";
|
||
if(arr)arr.innerHTML="▼"
|
||
}else{
|
||
el.style.display="none";
|
||
if(arr)arr.innerHTML="▸"
|
||
}
|
||
}
|
||
function chkSub(id,idx,val){
|
||
var key="ss_"+id;
|
||
var ss=localStorage.getItem(key);
|
||
var arr=[];
|
||
if(ss){try{arr=JSON.parse(ss)}catch(e){}}
|
||
arr[idx]=val?true:false;
|
||
try{localStorage.setItem(key,JSON.stringify(arr))}catch(e){}
|
||
renderEv()
|
||
}
|
||
|
||
function openEv(id,subIdx){curSub=subIdx!==undefined?subIdx:null;var e=null;for(var i=0;i<evs.length;i++){if(evs[i].id===id){e=evs[i];break}}if(!e)return;var fk=subIdx!==undefined?"sf_"+id+"_s"+subIdx:"sf_"+id;var now=new Date();var curMonth=now.getMonth();var savedMonth=localStorage.getItem("evmonth_"+id);var selMonth=savedMonth!==null?parseInt(savedMonth,10):curMonth;var fkBase="sf_"+id+"_m"+selMonth+(subIdx!==undefined?"_s"+subIdx:"");var h="<div style='max-width:700px'>";var titlePre=subIdx!==undefined?"N"+id+"."+e.sub[subIdx].l+" ":"N"+id+". ";var titleText=subIdx!==undefined?e.sub[subIdx].t:e.t;h+="<h3 style='margin-bottom:8px;padding-right:30px'>"+titlePre+esc(titleText)+"</h3>";h+="<div style='font-size:12px;color:#64748B;margin-bottom:6px'><strong>\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439:</strong> "+esc(nl2c(e.r))+"</div>";h+="<div style='font-size:12px;color:#64748B;margin-bottom:6px'><strong>\u0424\u0438\u043B\u0438\u0430\u043B:</strong> "+brs[e.b]+" | <strong>\u0421\u0440\u043E\u043A:</strong> "+e.due;if(e.done&&e.done!="\u2014")h+=" | <strong>\u0418\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u043E:</strong> "+e.done;h+="</div>";h+="<div style='margin-bottom:12px'><strong>\u0421\u0442\u0430\u0442\u0443\u0441:</strong> <select id='evs_"+e.id+"' onchange='chgSt("+e.id+")'>";var sk=["warn","late","done"];for(var si=0;si<sk.length;si++){h+="<option value='"+sk[si]+"'";if(e.s===sk[si])h+=" selected";h+=">"+stn[sk[si]]+"</option>"}h+="</select></div>";if(e.h&&e.h.length){h+="<div style='margin-bottom:12px'><strong>\u0418\u0441\u0442\u043E\u0440\u0438\u044F:</strong><ul style='font-size:12px;margin:4px 0 0 16px'>";for(var hi=0;hi<e.h.length;hi++){h+="<li>"+esc(e.h[hi])+"</li>"}h+="</ul></div>"}h+="<div style='margin-bottom:12px'><strong>\u041E\u0442\u0447\u0451\u0442\u043D\u043E\u0441\u0442\u044C:</strong></div>";h+="<div style='margin-bottom:8px;display:flex;gap:3px;flex-wrap:wrap' id='evm_btns_"+e.id+"'>";var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];for(var mi=0;mi<12;mi++){h+="<button class='btn btn-sm' style='padding:5px 12px;font-size:12px;border-radius:6px;transition:all 0.15s;"+(mi===selMonth?"background:#005BAA;color:#fff;font-weight:700;border:2px solid #003D73;box-shadow:0 2px 6px rgba(0,91,170,0.4);transform:scale(1.05)":"")+"' onclick='switchEvMonthBtn("+e.id+","+mi+","+(subIdx!==undefined?subIdx:"null")+")'>"+mnames[mi]+"</button>"}h+="</div>";h+="<div style='margin-bottom:12px'><strong>\u0424\u0430\u0439\u043B\u044B \u0437\u0430 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439 \u043C\u0435\u0441\u044F\u0446:</strong><div id='fileList_"+e.id+"'>";if(cu&&cu.bg===0){for(var bi=0;bi<brs.length;bi++){var bk=fkBase+"_b"+bi;var fd=localStorage.getItem(bk);if(fd){try{var fa=JSON.parse(fd);if(fa.length)h+="<div style='font-size:11px;color:#64748B;margin-top:4px'><strong>"+esc(brs[bi])+":</strong></div>";for(var fi=0;fi<fa.length;fi++){var f=fa[fi];h+="<div class='file-item'><span class='fn'>"+esc(f.n)+"</span><span class='fs'>("+(f.s?Math.round(f.s/1024)+"KB":"")+", "+esc(f.u||"")+" "+esc(f.d||"")+")</span><a onclick='openFile("+e.id+","+fi+","+bi+")'>\u041E\u0442\u043A\u0440\u044B\u0442\u044C</a> <a onclick='dlFile("+e.id+","+fi+","+bi+")'>\u0421\u043A\u0430\u0447\u0430\u0442\u044C</a><a style='color:#EF4444;margin-left:4px' onclick='delFile("+e.id+","+fi+","+bi+")'>\u0423\u0434\u0430\u043B\u0438\u0442\u044C</a></div>"}}catch(ex){}}}}else{var bk=fkBase+"_b"+(cu?cu.bg:0);var fd=localStorage.getItem(bk);if(fd){try{var fa=JSON.parse(fd);for(var fi=0;fi<fa.length;fi++){var f=fa[fi];h+="<div class='file-item'><span class='fn'>"+esc(f.n)+"</span><span class='fs'>("+(f.s?Math.round(f.s/1024)+"KB":"")+", "+esc(f.u||"")+" "+esc(f.d||"")+")</span><a onclick='openFile("+e.id+","+fi+","+(cu?cu.bg:0)+")'>\u041E\u0442\u043A\u0440\u044B\u0442\u044C</a> <a onclick='dlFile("+e.id+","+fi+","+(cu?cu.bg:0)+")'>\u0421\u043A\u0430\u0447\u0430\u0442\u044C</a><a style='color:#EF4444;margin-left:4px' onclick='delFile("+e.id+","+fi+","+(cu?cu.bg:0)+")'>\u0423\u0434\u0430\u043B\u0438\u0442\u044C</a></div>"}}catch(ex){}}}h+="</div><div style='margin-top:6px'><input type='file' id='fu_"+e.id+"' style='font-size:12px' onchange='upFile("+e.id+(subIdx!==undefined?","+subIdx:"")+")'></div>";h+="<div style='margin-bottom:12px;margin-top:12px'><textarea id='evn_"+e.id+"' placeholder='\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435 / \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F...' style='width:100%;padding:12px;border:1px solid #E2E8F0;border-radius:8px;font-size:13px;line-height:1.6;resize:vertical;min-height:120px;white-space:pre-wrap;overflow-y:auto' oninput='autoSaveNote("+e.id+")'>"+esc(subIdx!==undefined?((localStorage.getItem("sn_"+e.id+"_s"+subIdx+"_m"+selMonth)||"")):(localStorage.getItem("sn_"+e.id+"_m"+selMonth)||e.n||""))+"</textarea></div>";h+="</div>";if(subIdx===undefined&&e.sub&&e.sub.length>0){h+="<div style='margin-bottom:12px'><strong>\u041F\u043E\u0434\u043F\u0443\u043D\u043A\u0442\u044B:</strong>";var ss=localStorage.getItem("ss_"+e.id);for(var si=0;si<e.sub.length;si++){var checked="";if(ss){try{var sp=JSON.parse(ss);if(sp[si])checked="checked"}catch(ex){}}h+="<div style='font-size:12px;padding:4px 0'><input type='checkbox' "+checked+" onchange='chkSub("+e.id+","+si+",this.checked)'> "+esc(e.sub[si].l)+") "+esc(e.sub[si].t)+"</div>"}h+="</div>"}h+="<div style='margin-top:16px;text-align:right;border-top:1px solid #E2E8F0;padding-top:12px'><button class='btn btn-sm btn-g' onclick='saveEvModal("+e.id+")'>\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C</button>";h+="<button class='btn btn-sm' style='margin-left:8px;background:#E2E8F0;color:#0B1A2E' onclick='closeModal()'>\u041E\u0442\u043C\u0435\u043D\u0430</button></div>";h+="</div>";showModal(h)}
|
||
|
||
function showModal(html){
|
||
var mb=document.getElementById("modal_body");
|
||
var m=document.getElementById("modal");
|
||
if(!mb||!m)return;
|
||
mb.innerHTML=html;
|
||
m.style.display="flex"
|
||
}
|
||
var _ats={};function autoSaveNote(id){clearTimeout(_ats[id]);_ats[id]=setTimeout(function(){var inn=document.getElementById("evn_"+id);if(!inn)return;var mv2=localStorage.getItem("evmonth_"+id)||"0";var ss=curSub!==null?"_s"+curSub:"";try{localStorage.setItem("sn_"+id+ss+"_m"+mv2,inn.value.trim())}catch(e){}showToast("\u0410\u0432\u0442\u043E\u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u043E")},3000)}function showToast(msg){var t=document.getElementById("toast");if(!t)return;t.textContent=msg;t.style.display="block";t.style.opacity="1";clearTimeout(t._tid);t._tid=setTimeout(function(){t.style.opacity="0";setTimeout(function(){t.style.display="none"},300)},2000)}function closeModal(){
|
||
document.getElementById("modal").style.display="none"
|
||
}
|
||
|
||
function switchEvMonthBtn(id,m,subIdx){var inn=document.getElementById("evn_"+id);var curM=localStorage.getItem("evmonth_"+id)||"0";var subSuffix=curSub!==null?"_s"+curSub:"";if(inn)try{localStorage.setItem("sn_"+id+subSuffix+"_m"+curM,inn.value.trim())}catch(e){}try{localStorage.setItem("evmonth_"+id,m.toString())}catch(e){}openEv(id,subIdx!==null?subIdx:undefined)}
|
||
function switchEvMonth(id,subIdx){var inm=document.getElementById("evm_"+id);if(!inm)return;var mv=inm.value;var inn=document.getElementById("evn_"+id);var subSuffix=curSub!==null?"_s"+curSub:"";if(inn)try{localStorage.setItem("sn_"+id+subSuffix+"_m"+mv,inn.value.trim())}catch(e){}try{localStorage.setItem("evmonth_"+id,mv)}catch(e){}openEv(id,subIdx!==null?subIdx:undefined)}
|
||
function saveEvModal(id){var sel=document.getElementById("evs_"+id);for(var i=0;i<evs.length;i++){if(evs[i].id===id){if(sel)evs[i].s=sel.value;if(sel&&sel.value==="done"&&(evs[i].done==="\u2014"||!evs[i].done)){var d=new Date();evs[i].done=d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear()}break}}var inm=document.getElementById("evm_"+id);var mv=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");if(mv!=null){try{localStorage.setItem("evmonth_"+id,mv)}catch(e){};var inn=document.getElementById("evn_"+id);var subSuffix2=curSub!==null?"_s"+curSub:"";if(inn)try{localStorage.setItem("sn_"+id+subSuffix2+"_m"+mv,inn.value.trim())}catch(e){}}saveEv();showToast("\u0414\u0430\u043D\u043D\u044B\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u044B");renderEv()}
|
||
function chgSt(id){
|
||
var sel=document.getElementById("evs_"+id);
|
||
if(!sel)return;
|
||
for(var i=0;i<evs.length;i++){
|
||
if(evs[i].id===id){
|
||
evs[i].s=sel.value;
|
||
if(sel.value==="done"&&(evs[i].done==="\u2014"||!evs[i].done)){
|
||
var d=new Date();
|
||
evs[i].done=d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear()
|
||
}
|
||
break
|
||
}
|
||
}
|
||
}
|
||
|
||
function refreshFiles(id){var inm=document.getElementById("evm_"+id);var mv=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");var prefix="sf_"+id+"_m"+mv;var fdiv=document.getElementById("fileList_"+id);if(!fdiv)return;var groups={};var keys=[];for(var k in localStorage){if(localStorage.hasOwnProperty(k)&&k.indexOf(prefix)===0)keys.push(k)}for(var i=0;i<keys.length;i++){var fd=localStorage.getItem(keys[i]);if(fd){try{var arr=JSON.parse(fd);for(var j=0;j<arr.length;j++){var f=arr[j];var parts=keys[i].split("_b");var bi=parseInt(parts[parts.length-1])||0;if(!groups[bi])groups[bi]=[];groups[bi].push({n:f.n,s:f.s,d:f.d,u:f.u,bi:bi,idx:j,key:keys[i]})}}catch(e){}}}var fh="";for(var bi=0;bi<brs.length;bi++){if(!groups[bi]||!groups[bi].length)continue;if(cu&&cu.bg===0)fh+="<div style=\'font-size:11px;color:#64748B;margin-top:4px\'><strong>"+esc(brs[bi])+":</strong></div>";for(var j=0;j<groups[bi].length;j++){var f=groups[bi][j];fh+="<div class=\'file-item\'><span class=\'fn\'>"+esc(f.n)+"</span><span class=\'fs\'>("+(f.s?Math.round(f.s/1024)+"KB":"")+", "+esc(f.u||"")+" "+esc(f.d||"")+")</span><a onclick=\'openFile("+id+","+f.idx+","+f.bi+")\' style=\'cursor:pointer\'>\u041E\u0442\u043A\u0440\u044B\u0442\u044C</a> <a onclick=\'dlFile("+id+","+f.idx+","+f.bi+")\' style=\'cursor:pointer\'>\u0421\u043A\u0430\u0447\u0430\u0442\u044C</a><a style=\'color:#EF4444;margin-left:4px;cursor:pointer\' onclick=\'delFileRefresh("+id+","+f.idx+","+f.bi+")\'>>\u0423\u0434\u0430\u043B\u0438\u0442\u044C</a></div>"}}fdiv.innerHTML=fh||"\u041D\u0435\u0442 \u0444\u0430\u0439\u043B\u043E\u0432"}function delFileRefresh(id,idx,br){if(!confirm("\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0444\u0430\u0439\u043B?"))return;var mk=(localStorage.getItem("evmonth_"+id)||"0");var bk="_b"+(br!==undefined?br:(cu?cu.bg:0));var key="sf_"+id+"_m"+mk+(curSub!==null?"_s"+curSub:"")+bk;var ex=localStorage.getItem(key);if(!ex)return;try{var arr=JSON.parse(ex);arr.splice(idx,1);if(arr.length)localStorage.setItem(key,JSON.stringify(arr));else localStorage.removeItem(key);refreshFiles(id)}catch(e){}}
|
||
function upFile(id){var inp=document.getElementById("fu_"+id);if(!inp||!inp.files||!inp.files[0])return;var f=inp.files[0];if(f.size>2097152){alert("\u0424\u0430\u0439\u043B \u0431\u043E\u043B\u044C\u0448\u0435 2MB");return}var fr=new FileReader();var subKey=curSub!==null?"_s"+curSub:"";var inm=document.getElementById("evm_"+id);var mv2=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");var monthKey="_m"+mv2;var brKey="_b"+(cu?cu.bg:0);var fname=f.name;var fsize=f.size;fr.onload=function(){var key="sf_"+id+monthKey+subKey+brKey;var arr=[];var ex=localStorage.getItem(key);if(ex){try{arr=JSON.parse(ex)}catch(e){}}var d=new Date();arr.push({n:fname,s:fsize,d:d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear(),u:cu?cu.n:"",data:fr.result});try{localStorage.setItem(key,JSON.stringify(arr))}catch(e){alert("\u041E\u0448\u0438\u0431\u043A\u0430 \u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F. \u041E\u0447\u0438\u0441\u0442\u0438\u0442\u0435 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435.");return}showToast("\u0424\u0430\u0439\u043B \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043D");refreshFiles(id)};fr.readAsDataURL(f)}
|
||
function openFile(id,idx,br){var inm=document.getElementById("evm_"+id);var mv3=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");var mk="_m"+mv3;var bk="_b"+(br!==undefined?br:(cu?cu.bg:0));var key="sf_"+id+mk+(curSub!==null?"_s"+curSub:"")+bk;var ex=localStorage.getItem(key);if(!ex)return;try{var arr=JSON.parse(ex);var f=arr[idx];if(f&&f.data){var w=window.open("","_blank");w.document.write("<iframe src='"+f.data+"' style='width:100%;height:100%;border:none'></iframe>")}}catch(e){}}
|
||
function dlFile(id,idx,br){
|
||
var inm=document.getElementById("evm_"+id);
|
||
var mv4=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");
|
||
var monthKey="_m"+mv4;
|
||
var key="sf_"+id+monthKey+(curSub!==null?"_s"+curSub:"")+"_b"+(cu?cu.bg:0);
|
||
var ex=localStorage.getItem(key);
|
||
if(!ex)return;
|
||
try{
|
||
var arr=JSON.parse(ex);
|
||
var f=arr[idx];
|
||
if(!f||!f.data)return;
|
||
var a=document.createElement("a");
|
||
a.href=f.data;
|
||
a.download=f.n;
|
||
document.body.appendChild(a);
|
||
a.click();
|
||
document.body.removeChild(a)
|
||
}catch(e){}
|
||
}
|
||
function delFile(id,idx,br){
|
||
if(!confirm("\u0423\u0434\u0430\u043B\u0438\u0442\u044C \u0444\u0430\u0439\u043B?"))return;
|
||
var inm=document.getElementById("evm_"+id);
|
||
var mv4=inm?inm.value:(localStorage.getItem("evmonth_"+id)||"0");
|
||
var monthKey="_m"+mv4;
|
||
var brKey="_b"+(br!==undefined?br:(cu?cu.bg:0));
|
||
var key="sf_"+id+monthKey+(curSub!==null?"_s"+curSub:"")+brKey;
|
||
var ex=localStorage.getItem(key);
|
||
if(!ex)return;
|
||
try{
|
||
var arr=JSON.parse(ex);
|
||
arr.splice(idx,1);
|
||
if(arr.length){localStorage.setItem(key,JSON.stringify(arr))}
|
||
else{localStorage.removeItem(key)}
|
||
openEv(id,curSub!==null?curSub:undefined)
|
||
}catch(e){}
|
||
}
|
||
|
||
function saveBackup(){saveEv();var backup={events:evs.map(function(e){return{id:e.id,s:e.s,p:e.p,done:e.done,h:e.h,q:e.q,n:e.n}}),files:{}};var fkeys=[];for(var k in localStorage){if(localStorage.hasOwnProperty(k)&&k.indexOf("sf_")===0)fkeys.push(k)}for(var i=0;i<fkeys.length;i++){backup.files[fkeys[i]]=localStorage.getItem(fkeys[i])}var blob=new Blob([JSON.stringify(backup,null,2)],{type:"application/json"});var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="backup_"+new Date().toISOString().slice(0,10)+".json";a.click()}
|
||
function loadBackup(inp){if(!inp.files||!inp.files[0])return;var fr=new FileReader();fr.onload=function(){try{var d=JSON.parse(fr.result);if(!d||!d.events){alert("\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442");return}var out=[];for(var i=0;i<d.events.length;i++){out.push({id:d.events[i].id,s:d.events[i].s||"warn",p:d.events[i].p||0,done:d.events[i].done||"\u2014",h:d.events[i].h||[]})}localStorage.setItem("se5",JSON.stringify(out));if(d.files){var fk=Object.keys(d.files);for(var i=0;i<fk.length;i++){try{localStorage.setItem(fk[i],d.files[fk[i]])}catch(e){}}}loadEv();renderEv();var fc=d.files?Object.keys(d.files).length:0;alert("\u0412\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u043E "+out.length+" \u0437\u0430\u043F\u0438\u0441\u0435\u0439, "+fc+" \u0444\u0430\u0439\u043B\u043E\u0432")}catch(e){alert("\u041E\u0448\u0438\u0431\u043A\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u043A\u0438")}};fr.readAsText(inp.files[0])}
|
||
|
||
function storCheck(){
|
||
var el=document.getElementById("stor_ind");
|
||
if(!el)return;
|
||
try{
|
||
var used=0;
|
||
for(var k in localStorage){
|
||
if(localStorage.hasOwnProperty(k)){
|
||
used+=((localStorage[k].length||0)*2)
|
||
}
|
||
}
|
||
var max=5242880;
|
||
var pct=Math.round(used/max*100);
|
||
el.textContent="\u0425\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435: "+pct+"% ("+Math.round(used/1024)+"KB)"
|
||
}catch(e){el.textContent=""}
|
||
}
|
||
|
||
function renderAnalytics(){
|
||
if(cu&&cu.bg===0)loadLTIF();
|
||
var total=evs.length;
|
||
var done=0,late=0,warn=0;
|
||
for(var i=0;i<evs.length;i++){
|
||
var s=evs[i].s;
|
||
if(s==="done")done++;
|
||
else if(s==="late")late++;
|
||
else if(s==="warn")warn++
|
||
}
|
||
var html="";
|
||
html+="<div class='stat-card sb'><div class='lb'>\u0412\u0441\u0435\u0433\u043E \u043C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0439</div><div class='num'>"+total+"</div></div>";
|
||
html+="<div class='stat-card sg'><div class='lb'>\u0418\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u043E</div><div class='num'>"+done+"</div><div class='lb'>"+Math.round(done/total*100)+"%</div></div>";
|
||
html+="<div class='stat-card sr'><div class='lb'>\u041F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E</div><div class='num'>"+late+"</div></div>";
|
||
html+="<div class='stat-card'><div class='lb'>В процессе</div><div class='num'>"+warn+"</div></div>";
|
||
document.getElementById("an_stats").innerHTML=html;
|
||
|
||
var problem=[];
|
||
for(var i=0;i<evs.length;i++){
|
||
if(evs[i].s==="late"||evs[i].s==="warn"){
|
||
var dr=daysRem(evs[i].due);
|
||
problem.push({id:evs[i].id,t:evs[i].t,b:evs[i].b,s:evs[i].s,dr:dr,dn:evs[i].dname})
|
||
}
|
||
}
|
||
problem.sort(function(a,b){return a.dr-b.dr});
|
||
var pt=problem.slice(0,5);
|
||
if(pt.length){
|
||
var ph="<table><tr><th>N</th><th>\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0421\u0442\u0430\u0442\u0443\u0441</th><th>\u0414\u043D\u0435\u0439</th></tr>";
|
||
for(var i=0;i<pt.length;i++){
|
||
var pc=pt[i].s==="late"?"r":"w";
|
||
ph+="<tr><td>"+pt[i].id+"</td><td style='font-size:12px'>"+esc(pt[i].t)+"</td><td>"+brs[pt[i].b]+"</td><td><span class='badge "+pc+"'>"+stn[pt[i].s]+"</span></td><td>"+(pt[i].dr<=0?"\u041F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E":pt[i].dr+" \u0434\u043D.")+"</td></tr>"
|
||
}
|
||
ph+="</table>";
|
||
document.getElementById("an_top").innerHTML=ph;
|
||
var secData=[];for(var si=0;si<secs.length;si++){secData.push({n:secs[si].split(".")[1]||secs[si],t:0,d:0})}for(var i=0;i<evs.length;i++){var e=evs[i];secData[e.sec].t++;if(e.s==="done")secData[e.sec].d++}var sh="<table>";for(var i=0;i<secData.length;i++){var sp=secData[i].t?Math.round(secData[i].d/secData[i].t*100):0;sh+="<tr><td>"+esc(secData[i].n)+"</td><td>"+secData[i].d+"/"+secData[i].t+"</td><td><div class=\"rank-bar\"><div style=\"width:"+sp+"%;background:"+(sp>=70?"#10B981":sp>=40?"#F59E0B":"#EF4444")+"\"></div></div></td><td>"+sp+"%</td></tr>"}sh+="</table>";document.getElementById("an_sections").innerHTML=sh
|
||
}else{
|
||
document.getElementById("an_top").innerHTML="<p style='color:#64748B'>\u041F\u0440\u043E\u0431\u043B\u0435\u043C \u043D\u0435\u0442</p>"
|
||
}
|
||
}
|
||
|
||
function getFilteredEvs(){var statusF=document.getElementById("rp_status").value;var year=parseInt(document.getElementById("rp_year").value,10)||2026;var months=getReportMonths();var r=[];for(var i=0;i<evs.length;i++){var e=evs[i];if(statusF&&e.s!==statusF)continue;var dp=e.due.split(".");if(dp.length===3){var em=parseInt(dp[1],10)-1;var ey=parseInt(dp[2],10);if(ey===year&&months.indexOf(em)!==-1)r.push(e)}}return r}
|
||
function getReportPeriod(){
|
||
var period=document.getElementById("rp_period").value;
|
||
var year=document.getElementById("rp_year").value;
|
||
var month=parseInt(document.getElementById("rp_month").value,10)||0;
|
||
var mnames=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];
|
||
if(period==="month")return mnames[month]+" "+year;
|
||
if(period==="q1")return "I \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
|
||
if(period==="q2")return "II \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
|
||
if(period==="q3")return "III \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
|
||
if(period==="q4")return "IV \u043A\u0432\u0430\u0440\u0442\u0430\u043B "+year;
|
||
if(period==="h1")return "1-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;
|
||
if(period==="h2")return "2-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;
|
||
return year+" \u0433\u043E\u0434"
|
||
}
|
||
function rpPeriodChange(){}
|
||
function getReportPeriod(){
|
||
var period=document.getElementById("rp_period").value;var year=document.getElementById("rp_year").value;
|
||
var mFrom=parseInt(document.getElementById("rp_month_from").value,10)||0;var mTo=parseInt(document.getElementById("rp_month_to").value,10)||11;
|
||
var mn=["\u044F\u043D\u0432\u0430\u0440\u044C","\u0444\u0435\u0432\u0440\u0430\u043B\u044C","\u043C\u0430\u0440\u0442","\u0430\u043F\u0440\u0435\u043B\u044C","\u043C\u0430\u0439","\u0438\u044E\u043D\u044C","\u0438\u044E\u043B\u044C","\u0430\u0432\u0433\u0443\u0441\u0442","\u0441\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u043E\u043A\u0442\u044F\u0431\u0440\u044C","\u043D\u043E\u044F\u0431\u0440\u044C","\u0434\u0435\u043A\u0430\u0431\u0440\u044C"];
|
||
if(period==="year")return year+" \u0433\u043E\u0434";if(period==="q1")return "I \u043A\u0432. "+year;if(period==="q2")return "II \u043A\u0432. "+year;
|
||
if(period==="q3")return "III \u043A\u0432. "+year;if(period==="q4")return "IV \u043A\u0432. "+year;
|
||
if(period==="h1")return "1-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;if(period==="h2")return "2-\u0435 \u043F\u043E\u043B\u0443\u0433\u043E\u0434\u0438\u0435 "+year;
|
||
if(period==="month")return mn[mFrom]+" "+year;return mn[mFrom]+" \u2014 "+mn[mTo]+" "+year
|
||
}
|
||
function getReportMonths(){
|
||
var period=document.getElementById("rp_period").value;var mFrom=parseInt(document.getElementById("rp_month_from").value,10)||0;var mTo=parseInt(document.getElementById("rp_month_to").value,10)||11;
|
||
var months=[];if(period==="year"){for(var i=0;i<12;i++)months.push(i)}else if(period==="q1")months=[0,1,2];else if(period==="q2")months=[3,4,5];else if(period==="q3")months=[6,7,8];else if(period==="q4")months=[9,10,11];else if(period==="h1")months=[0,1,2,3,4,5];else if(period==="h2")months=[6,7,8,9,10,11];else if(period==="month")months=[mFrom];else{for(var i=mFrom;i<=mTo;i++)months.push(i)}return months
|
||
}
|
||
function rpDropdownChange(){var dd=document.getElementById("rp_month_dd");if(!dd)return;var v=dd.value.split("-");document.getElementById("rp_period").value="month";document.getElementById("rp_month_from").value=parseInt(v[1])-1;document.getElementById("rp_month_to").value=parseInt(v[1])-1;document.getElementById("rp_year").value=v[0];renderReports()}
|
||
function renderReports(){
|
||
var dd=document.getElementById("rp_month_dd");if(dd&&!dd.options.length){var mn=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];var now=new Date();var cm=now.getMonth();var cy=now.getFullYear();var h="";var sv=cy+"-"+String(cm+1).padStart(2,"0");for(var y=2026;y<=2027;y++){for(var m=0;m<12;m++){var val=y+"-"+String(m+1).padStart(2,"0");h+="<option value=\""+val+"\""+(val===sv?" selected":"")+">"+mn[m]+" "+y+"</option>"}}dd.innerHTML=h}
|
||
var fl=getFilteredEvs();
|
||
var cnt=document.getElementById("rp_count");
|
||
if(cnt)cnt.textContent="Выбрано мероприятий: "+fl.length;
|
||
document.getElementById("rp_preview").innerHTML=""
|
||
}
|
||
function dlCSV(){
|
||
var fl=getFilteredEvs();
|
||
var csv="\uFEFFN;\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435;\u0424\u0438\u043B\u0438\u0430\u043B;\u0421\u0440\u043E\u043A;\u0421\u0442\u0430\u0442\u0443\u0441;\u041F\u0440\u043E\u0433\u0440\u0435\u0441\u0441;\u041A\u043E\u043B-\u0432\u043E;\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435;\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u044B\u0439\n";
|
||
for(var i=0;i<fl.length;i++){
|
||
var e=fl[i];
|
||
csv+=e.id+";\""+esc(e.t)+"\";\""+brs[e.b]+"\";"+e.due+";"+stn[e.s]+";"+(e.p||0)+"%;"+(e.q||"")+";\""+esc(e.n||"")+"\";\""+esc(nl2c(e.r))+"\"\n"
|
||
}
|
||
var blob=new Blob([csv],{type:"text/csv;charset=utf-8"});
|
||
var a=document.createElement("a");
|
||
a.href=URL.createObjectURL(blob);
|
||
a.download="report_"+document.getElementById("rp_year").value+"_"+getReportPeriod().replace(/\s/g,"_")+".csv";
|
||
a.click()
|
||
}
|
||
function dlHTML(){var fl=getFilteredEvs();var periodLabel=getReportPeriod();var months=getReportMonths();var mn=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];var hh="<!DOCTYPE html><html><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 "+periodLabel+"</title><style>body{font:14px Arial;padding:30px;color:#1A1A2E}h3{font-size:14px;color:#005BAA;border-bottom:1px solid #ddd;padding-bottom:6px}.meta{font-size:12px;color:#1A1A2E;background:#F0F4FF;padding:6px 10px;border-radius:4px;margin:2px 0 6px}.desc{font-size:12px;padding:10px;background:#F0F4FF;border-left:4px solid #005BAA;border-radius:4px;margin:6px 0}.files{font-size:11px;margin:6px 0}.files .fg{margin:4px 0 8px;padding:4px 8px;background:#f9f9f9;border-radius:4px}.files .fgl{font-weight:600;color:#005BAA;font-size:11px}.files a{color:#005BAA;display:block;margin:2px 0 2px 8px}@media print{body{padding:10mm}}</style></head><body><h2>\u041F\u043B\u0430\u043D \u041F\u0411</h2><p>QAZAQtelecom HSE \u0437\u0430 "+periodLabel+"</p><p style='font-size:11px;color:#64748B'>"+new Date().toLocaleDateString("ru-RU")+"</p><br>";for(var i=0;i<fl.length;i++){var e=fl[i];var sn=secs[e.sec].split(". ")[1]||secs[e.sec];hh+="<h3>N"+e.id+". "+esc(e.t)+"</h3>";hh+="<div class='meta'>\u0420\u0430\u0437\u0434\u0435\u043B | "+esc(sn)+" | \u0421\u0440\u043E\u043A: "+e.due+" | "+stn[e.s]+"</div>";var rn="";for(var mi=0;mi<months.length;mi++){var nk="sn_"+e.id+"_m"+months[mi];var sv=localStorage.getItem(nk);if(sv){rn=sv;break}}if(!rn&&e.n)rn=e.n;if(rn)hh+="<div class='desc'><strong>\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435:</strong><br>"+esc(rn)+"</div>";var fhtml="";var hasAny=false;for(var mi=0;mi<months.length;mi++){var fg="";var mk="_m"+months[mi];for(var si=-1;si<(e.sub?e.sub.length:0);si++){var sk=si>=0?"_s"+si:"";for(var bk=0;bk<brs.length;bk++){var key="sf_"+e.id+mk+sk+"_b"+bk;var fd=localStorage.getItem(key);if(fd){try{var arr=JSON.parse(fd);for(var fi=0;fi<arr.length;fi++){var f=arr[fi];if(f&&f.n&&f.data)fg+="<a href='"+f.data+"' download='"+esc(f.n)+"'>\uD83D\uDCC4 "+esc(f.n)+" ("+Math.round((f.s||0)/1024)+" KB)</a>"}}catch(ex){}}}}if(fg){fhtml+="<div class='fg'><div class='fgl'>"+mn[months[mi]]+":</div>"+fg+"</div>";hasAny=true}}if(hasAny)hh+="<div class='files'><strong>\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E\u0449\u0438\u0435 \u0444\u0430\u0439\u043B\u044B:</strong>"+fhtml+"</div>"}hh+="<p style='font-size:11px;color:#64748B'><em>"+new Date().toLocaleDateString("ru-RU")+"</em></p></body></html>";var blob=new Blob([hh],{type:"text/html"});var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="report_pb_"+periodLabel.replace(/\s/g,"_")+".html";a.click()}
|
||
function dlWord(){var fl=getFilteredEvs();var periodLabel=getReportPeriod();var months=getReportMonths();var mn=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];var hh="<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word'><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 "+periodLabel+"</title><style>@page{size:A4;margin:20mm}body{font:12pt 'Times New Roman'}h2{font-size:16pt;text-align:center}h3{font-size:12pt;color:#005BAA;border-bottom:1px solid #ccc}.meta{font-size:10pt;color:#555}.desc{font-size:10pt;padding:6pt;background:#f9f9f9}.files{font-size:9pt}.files a{color:#005BAA;display:block}</style></head><body><h2>\u041F\u043B\u0430\u043D \u041F\u0411</h2><p style='text-align:center'>AO \u00AB\u041A\u0430\u0437\u0430\u0445\u0442\u0435\u043B\u0435\u043A\u043E\u043C\u00BB \u0437\u0430 "+periodLabel+"</p><br>";for(var i=0;i<fl.length;i++){var e=fl[i];var sn=secs[e.sec].split(". ")[1]||secs[e.sec];hh+="<h3>N"+e.id+". "+esc(e.t)+"</h3>";hh+="<p class='meta'>\u0420\u0430\u0437\u0434\u0435\u043B | "+esc(sn)+" | \u0421\u0440\u043E\u043A: "+e.due+" | "+stn[e.s]+"</p>";var rn="";for(var mi=0;mi<months.length;mi++){var nk="sn_"+e.id+"_m"+months[mi];var sv=localStorage.getItem(nk);if(sv){rn=sv;break}}if(!rn&&e.n)rn=e.n;if(rn)hh+="<p class='desc'><strong>\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435:</strong> "+esc(rn)+"</p>";var fhtml="";for(var mi=0;mi<months.length;mi++){var fg="";var mk="_m"+months[mi];for(var si=-1;si<(e.sub?e.sub.length:0);si++){var sk=si>=0?"_s"+si:"";for(var bk=0;bk<brs.length;bk++){var key="sf_"+e.id+mk+sk+"_b"+bk;var fd=localStorage.getItem(key);if(fd){try{var arr=JSON.parse(fd);for(var fi=0;fi<arr.length;fi++){var f=arr[fi];if(f&&f.n)fg+="<a href='"+f.data+"'>"+esc(f.n)+" ("+Math.round((f.s||0)/1024)+" KB)</a>"}}catch(ex){}}}}if(fg)fhtml+="<p><strong>"+mn[months[mi]]+":</strong><br>"+fg+"</p>"}if(fhtml)hh+="<div class='files'><strong>\u041F\u043E\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u044E\u0449\u0438\u0435 \u0444\u0430\u0439\u043B\u044B:</strong><br>"+fhtml+"</div>"}hh+="<p style='font-size:9pt;color:#888'>"+new Date().toLocaleDateString("ru-RU")+"</p></body></html>";var blob=new Blob([hh],{type:"application/msword"});var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="report_pb_"+periodLabel.replace(/\s/g,"_")+".doc";a.click()}
|
||
function dlPdf(){var fl=getFilteredEvs();var periodLabel=getReportPeriod();var hh="<!DOCTYPE html><html><head><meta charset='utf-8'><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 "+periodLabel+"</title><style>body{font:14px Arial;padding:20px}table{border-collapse:collapse;width:100%}th,td{border:1px solid #ccc;padding:6px 10px;font-size:12px}th{background:#0A1628;color:#fff}@media print{body{padding:10mm}}</style></head><body><h2>\u041F\u043B\u0430\u043D \u041F\u0411</h2><p>QAZAQtelecom HSE \u0437\u0430 "+periodLabel+"</p><br><table><tr><th>N</th><th>\u041C\u0435\u0440\u043E\u043F\u0440\u0438\u044F\u0442\u0438\u0435</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0421\u0440\u043E\u043A</th><th>\u0421\u0442\u0430\u0442\u0443\u0441</th><th>%</th><th>\u041F\u0440\u0438\u043C\u0435\u0447\u0430\u043D\u0438\u0435</th></tr>";for(var i=0;i<fl.length;i++){var e=fl[i];hh+="<tr><td>"+e.id+"</td><td>"+esc(e.t)+"</td><td>"+brs[e.b]+"</td><td>"+e.due+"</td><td>"+stn[e.s]+"</td><td>"+(e.p||0)+"%</td><td>"+esc(e.n||"")+"</td></tr>"}hh+="</table><p><em>"+new Date().toLocaleDateString("ru-RU")+"</em></p><script>window.onload=function(){window.print()}<\/script></body></html>";var w=window.open("","_blank","width=900,height=700");w.document.write(hh);w.document.close()}
|
||
function dlZip(){
|
||
var fl=getFilteredEvs();var periodLabel=getReportPeriod();var months=getReportMonths();
|
||
var zipParts=[];var offsets=[];var centralDir=[];var offset=0;
|
||
var mn=["\u042F\u043D\u0432\u0430\u0440\u044C","\u0424\u0435\u0432\u0440\u0430\u043B\u044C","\u041C\u0430\u0440\u0442","\u0410\u043F\u0440\u0435\u043B\u044C","\u041C\u0430\u0439","\u0418\u044E\u043D\u044C","\u0418\u044E\u043B\u044C","\u0410\u0432\u0433\u0443\u0441\u0442","\u0421\u0435\u043D\u0442\u044F\u0431\u0440\u044C","\u041E\u043A\u0442\u044F\u0431\u0440\u044C","\u041D\u043E\u044F\u0431\u0440\u044C","\u0414\u0435\u043A\u0430\u0431\u0440\u044C"];
|
||
function addFile(name,bytes){
|
||
var encoder=new TextEncoder();var data=typeof bytes==="string"?encoder.encode(bytes):new Uint8Array(bytes);
|
||
var nameBytes=encoder.encode(name);var crc=crc32(data);
|
||
var lh=new Uint8Array(30+nameBytes.length);var v=new DataView(lh.buffer);
|
||
v.setUint32(0,0x04034b50,true);v.setUint16(8,0,true);v.setUint16(10,0,true);v.setUint16(26,nameBytes.length,true);
|
||
v.setUint32(14,crc,true);v.setUint32(18,data.length,true);v.setUint32(22,data.length,true);lh.set(nameBytes,30);
|
||
zipParts.push(lh);zipParts.push(data);
|
||
var cd=new Uint8Array(46+nameBytes.length);var cv=new DataView(cd.buffer);
|
||
cv.setUint32(0,0x02014b50,true);cv.setUint16(8,0,true);cv.setUint16(10,0,true);cv.setUint16(28,nameBytes.length,true);
|
||
cv.setUint32(16,crc,true);cv.setUint32(20,data.length,true);cv.setUint32(24,data.length,true);cv.setUint32(42,offset,true);cd.set(nameBytes,46);
|
||
centralDir.push(cd);offset+=30+nameBytes.length+data.length
|
||
}
|
||
function crc32(data){var c=0xffffffff;for(var i=0;i<data.length;i++){c^=data[i];for(var j=0;j<8;j++){if(c&1)c=(c>>>1)^0xedb88320;else c>>>=1}}return(c^0xffffffff)>>>0}
|
||
var html='<!DOCTYPE html><html><head><meta charset="utf-8"><title>\u041E\u0442\u0447\u0451\u0442 \u041F\u0411 \u0437\u0430 '+periodLabel+'</title><style>body{font:14px Arial;padding:20px}h2{font-size:20px}h3{font-size:14px;color:#005BAA;border-bottom:1px solid #ccc}.meta{font-size:12px;color:#555}.desc{font-size:12px;padding:8px;background:#f9f9f9;margin:6px 0}</style></head><body><h2>\u041F\u043B\u0430\u043D \u041F\u0411 \u2014 QAZAQtelecom HSE</h2><p>\u041F\u0435\u0440\u0438\u043E\u0434: '+periodLabel+'</p><p>\u0414\u0430\u0442\u0430: '+new Date().toLocaleDateString("ru-RU")+'</p><br>';
|
||
for(var i=0;i<fl.length;i++){var e=fl[i];var sn=secs[e.sec].split(". ")[1]||secs[e.sec];
|
||
html+='<h3>N'+e.id+'. '+esc(e.t)+'</h3><div class="meta">\u0420\u0430\u0437\u0434\u0435\u043B | '+esc(sn)+' | \u0421\u0440\u043E\u043A: '+e.due+' | '+stn[e.s]+'</div>';
|
||
var rn="";for(var mi=0;mi<months.length;mi++){var nk="sn_"+e.id+"_m"+months[mi];var sv=localStorage.getItem(nk);if(sv){rn=sv;break}}if(!rn&&e.n)rn=e.n;if(rn)html+='<div class="desc"><strong>\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435:</strong><br>'+esc(rn)+'</div>'
|
||
}
|
||
html+='<p><em>'+new Date().toLocaleDateString("ru-RU")+'</em></p></body></html>';
|
||
addFile("report.html",html);
|
||
for(var i=0;i<fl.length;i++){var e=fl[i];
|
||
for(var mi=0;mi<12;mi++){var mk="_m"+mi;
|
||
for(var si=-1;si<(e.sub?e.sub.length:0);si++){var sk=si>=0?"_s"+si:"";
|
||
for(var bk=0;bk<brs.length;bk++){var key="sf_"+e.id+mk+sk+"_b"+bk;var fd=localStorage.getItem(key);
|
||
if(fd){try{var arr=JSON.parse(fd);for(var fi=0;fi<arr.length;fi++){var f=arr[fi];if(f&&f.n&&f.data){var b64=f.data.split(",")[1];if(b64){var bin=Uint8Array.from(atob(b64),function(c){return c.charCodeAt(0)});addFile("event_"+e.id+"/"+esc(f.n),bin)}}}}catch(ex){}}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
var cdOff=offset;for(var i=0;i<centralDir.length;i++)zipParts.push(centralDir[i]);
|
||
var cdSz=zipParts.reduce(function(s,p){return s+p.length},0)-cdOff;
|
||
var eocd=new Uint8Array(22);var ev=new DataView(eocd.buffer);
|
||
ev.setUint32(0,0x06054b50,true);ev.setUint16(8,centralDir.length,true);ev.setUint16(10,centralDir.length,true);
|
||
ev.setUint32(12,cdSz,true);ev.setUint32(16,cdOff,true);zipParts.push(eocd);
|
||
var blob=new Blob(zipParts,{type:"application/zip"});var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="report_pb_"+periodLabel.replace(/\s/g,"_")+".zip";a.click()
|
||
}
|
||
function hseSend(){
|
||
var btn=document.getElementById("hse_btn");
|
||
var result=document.getElementById("hse_result");
|
||
btn.disabled=true;btn.textContent="Отправка...";result.innerHTML="";
|
||
var month=document.getElementById("hse_month").value;
|
||
var fmt=document.getElementById("hse_fmt").value;
|
||
var apiKey=document.getElementById("hse_key").value;
|
||
if(!month){result.innerHTML="<span style='color:#EF4444'>Выберите месяц</span>";btn.disabled=false;btn.textContent="Отправить отчёт в HSE.sk.kz";return}
|
||
if(!apiKey){result.innerHTML="<span style='color:#EF4444'>Введите API ключ</span>";btn.disabled=false;btn.textContent="Отправить отчёт в HSE.sk.kz";return}
|
||
var fl=getFilteredEvs();
|
||
var total=fl.length;
|
||
var done=0;for(var i=0;i<fl.length;i++){if(fl[i].s==="done")done++}
|
||
var pct=total?Math.round(done/total*100):0;
|
||
var payload={month:month,events:fl.map(function(e){return{id:e.id,title:e.t,branch:brs[e.b],deadline:e.due,status:e.s,progress:e.p||0,quantity:e.q||"",note:e.n||""}}),summary:{total:total,done:done,pct:pct}};
|
||
try{
|
||
fetch("http://localhost:5000/api/hse/send",{method:"POST",headers:{"Content-Type":"application/json","Authorization":"Bearer hse-integration"},body:JSON.stringify({month:month,api_key:apiKey,format:fmt,report:payload})}).then(function(r){return r.json()}).then(function(d){
|
||
if(d.ok){result.innerHTML="<span style='color:#10B981'>Отчёт за "+month+" отправлен в HSE.sk.kz</span>"}
|
||
else{result.innerHTML="<span style='color:#EF4444'>Ошибка: "+(d.error||"соединение")+"</span>"}
|
||
}).catch(function(e){result.innerHTML="<span style='color:#EF4444'>Сервер не запущен. Запустите <code>python3 server.py</code></span>"}).finally(function(){btn.disabled=false;btn.textContent="Отправить отчёт в HSE.sk.kz"})
|
||
}catch(e){}
|
||
}
|
||
|
||
var aiGreeted=false;
|
||
function renderAI(){
|
||
if(!aiGreeted){
|
||
aiGreeted=true;
|
||
var box=document.getElementById("ai_chat");
|
||
if(box){
|
||
box.innerHTML="";
|
||
addMsg("b","Джарвис к вашим услугам. Я анализирую 35 мероприятий ПБ по 9 филиалам. Спросите: сводка, просроченные, риски, рейтинг, аудит, прогноз, советник.","Джарвис")
|
||
}
|
||
}
|
||
}
|
||
function addMsg(role,text,name){
|
||
var box=document.getElementById("ai_chat");
|
||
if(!box)return;
|
||
var nm=role==="u"?"\u0412\u044B":(name||"\u0411\u043E\u0442");
|
||
box.innerHTML+="<div class='msg "+role+"'><div class='nm'>"+esc(nm)+"</div><div>"+esc(text)+"</div></div>";
|
||
box.scrollTop=box.scrollHeight
|
||
}
|
||
function aiAsk(q){
|
||
addMsg("u",q,"\u0412\u044B");
|
||
setTimeout(function(){aiResp(q)},300)
|
||
}
|
||
function aiSend(){
|
||
var inp=document.getElementById("ai_inp");
|
||
if(!inp||!inp.value.trim())return;
|
||
var q=inp.value.trim();
|
||
inp.value="";
|
||
aiAsk(q)
|
||
}
|
||
function aiResp(q){
|
||
var total=evs.length;
|
||
var done=0,late=0,warn=0;
|
||
for(var i=0;i<evs.length;i++){
|
||
var s=evs[i].s;
|
||
if(s==="done")done++;
|
||
else if(s==="late")late++;
|
||
else if(s==="warn")warn++
|
||
}
|
||
var ql=q.toLowerCase();
|
||
var ans="";
|
||
|
||
if(ql.indexOf("свод")!==-1||ql.indexOf("общ")!==-1||ql.indexOf("статус")!==-1||ql.indexOf("все")!==-1){
|
||
ans="Общая сводка по плану ПБ:";
|
||
ans+="\n- Всего: "+total+" мероприятий";
|
||
ans+="\n- Исполнено: "+done+" ("+Math.round(done/total*100)+"%)";
|
||
ans+="\n- В процессе: "+warn;
|
||
ans+="\n- Просрочено: "+late
|
||
|
||
}else if(ql.indexOf("просроч")!==-1||ql.indexOf("срочн")!==-1||ql.indexOf("критич")!==-1){
|
||
var lateList=[];
|
||
for(var i=0;i<evs.length;i++){if(evs[i].s==="late"){lateList.push(evs[i])}}
|
||
if(lateList.length){
|
||
ans="Просроченные мероприятия ("+lateList.length+"):";
|
||
for(var i=0;i<lateList.length;i++){
|
||
ans+="\nN"+lateList[i].id+" - "+lateList[i].t.slice(0,80)+"... ("+lateList[i].due+", "+brs[lateList[i].b]+")"
|
||
}
|
||
}else{ans="Просроченных нет"}
|
||
|
||
}else if(ql.indexOf("рик")!==-1||ql.indexOf("risk")!==-1||ql.indexOf("пробл")!==-1||ql.indexOf("срыв")!==-1){
|
||
var risk=[];
|
||
for(var i=0;i<evs.length;i++){
|
||
var dr=daysRem(evs[i].due);
|
||
if(evs[i].s!=="done"&&dr<=30&&dr>0){risk.push(evs[i])}
|
||
}
|
||
if(risk.length){
|
||
ans="Менее 30 дней до срока ("+risk.length+"):";
|
||
for(var i=0;i<risk.length;i++){
|
||
ans+="\nN"+risk[i].id+" - "+risk[i].t.slice(0,60)+"... ("+daysRem(risk[i].due)+" дн.)"
|
||
}
|
||
}else{ans="Рисков нет"}
|
||
|
||
}else if(ql.indexOf("рейт")!==-1||ql.indexOf("филиал")!==-1||ql.indexOf("лучш")!==-1||ql.indexOf("худш")!==-1){
|
||
var brd=[];
|
||
for(var i=0;i<brs.length;i++){brd.push({n:brs[i],t:0,d:0})}
|
||
for(var i=0;i<evs.length;i++){var e=evs[i];brd[e.b].t++;if(e.s==="done")brd[e.b].d++}
|
||
brd.sort(function(a,b){return(b.d/b.t||0)-(a.d/a.t||0)});
|
||
ans="Рейтинг филиалов:";
|
||
for(var i=0;i<brd.length;i++){
|
||
var pct=brd[i].t?Math.round(brd[i].d/brd[i].t*100):0;
|
||
ans+="\n"+(i+1)+". "+brd[i].n+": "+brd[i].d+"/"+brd[i].t+" ("+pct+"%)"
|
||
}
|
||
|
||
}else if(ql.indexOf("прогноз")!==-1||ql.indexOf("прогн")!==-1){
|
||
var atRisk=0,crit=0,onTrack=0;
|
||
for(var i=0;i<evs.length;i++){
|
||
var dr=daysRem(evs[i].due);
|
||
if(evs[i].s==="done")onTrack++;
|
||
else if(dr<=0)crit++;
|
||
else if(dr<=30)atRisk++;
|
||
else onTrack++
|
||
}
|
||
ans="Прогноз выполнения плана ПБ:\n- Выполнено: "+onTrack+"\n- В зоне риска (<30 дн): "+atRisk+"\n- Критические (просрочено): "+crit;
|
||
ans+="\n\nПрогнозируемый % выполнения к концу года: "+Math.round((onTrack+atRisk*0.5)/evs.length*100)+"%";
|
||
if(crit>3)ans+="\n\nРекомендация: срочный штаб по "+crit+" просроченным пунктам."
|
||
|
||
}else if(ql.indexOf("статус")!==-1||ql.indexOf("состоян")!==-1||ql.indexOf("обстан")!==-1){
|
||
var bySec=[];
|
||
for(var si=0;si<secs.length;si++){bySec.push({n:secs[si].split(".")[0],t:0,d:0,l:0})}
|
||
for(var i=0;i<evs.length;i++){
|
||
var e=evs[i];bySec[e.sec].t++;
|
||
if(e.s==="done")bySec[e.sec].d++;
|
||
else if(e.s==="late")bySec[e.sec].l++
|
||
}
|
||
ans="Состояние по разделам:";
|
||
for(var i=0;i<bySec.length;i++){
|
||
ans+="\n"+bySec[i].n+": "+bySec[i].d+"/"+bySec[i].t+" ("+Math.round(bySec[i].d/bySec[i].t*100)+"%)"+(bySec[i].l?" просрочено:"+bySec[i].l:"")
|
||
}
|
||
|
||
}else if(ql.indexOf("план")!==-1||ql.indexOf("действ")!==-1||ql.indexOf("рекоменд")!==-1||ql.indexOf("совет")!==-1){
|
||
var pct=Math.round(done/total*100);
|
||
if(pct<30)ans="Рекомендация: выполнено менее 30%. Рекомендуется усилить контроль за просроченными и провести штаб с ответственными лицами";
|
||
else if(pct<60)ans="Рекомендация: выполнено "+pct+"%. Обратить внимание на процент выполнения в филиалах с низким показателем";
|
||
else ans="Хороший прогресс: "+pct+"%. Рекомендуется продолжать работу в том же темпе"
|
||
|
||
}else if(ql.indexOf("аудит")!==-1||ql.indexOf("провер")!==-1||ql.indexOf("контрол")!==-1){
|
||
ans="Аудит плана ПБ:";
|
||
ans+="\n- выполнено: "+done+"/"+total+" ("+Math.round(done/total*100)+"%)";
|
||
ans+="\n- просрочено: "+late;
|
||
var riskCount=0;
|
||
for(var i=0;i<evs.length;i++){var dr=daysRem(evs[i].due);if(evs[i].s!=="done"&&dr<=30&&dr>0)riskCount++}
|
||
ans+="\n- в риске (<30 дней): "+riskCount;
|
||
if(done/total>0.7)ans+="\nОбщая оценка: хорошо";
|
||
else if(done/total>0.4)ans+="\nОбщая оценка: удовлетворительно";
|
||
else ans+="\nОбщая оценка: требует внимания"
|
||
|
||
}else if(ql.indexOf("пункт")!==-1||ql.indexOf("номер")!==-1){
|
||
var match=ql.match(/\d+/);
|
||
if(match){
|
||
var num=parseInt(match[0],10);
|
||
var found=null;
|
||
for(var i=0;i<evs.length;i++){if(evs[i].id===num){found=evs[i];break}}
|
||
if(found){
|
||
ans="N"+found.id+" "+found.t.slice(0,80)+"...";
|
||
ans+="\nСтатус: "+stn[found.s];
|
||
ans+="\nФилиал: "+brs[found.b];
|
||
ans+="\nСрок: "+found.due;
|
||
ans+="\nПрогресс: "+(found.p||0)+"%"
|
||
}else{ans="Пункт N"+num+" не найден"}
|
||
}else{ans="Напиши номер пункта, например: пункт 5"}
|
||
|
||
}else{
|
||
ans="Я — Джарвис, ваш аналитический ассистент. Могу ответить:\n\n• сводка — общая статистика\n• просроченные — список просрочек\n• риски — зона риска (<30 дней)\n• рейтинг — рейтинг филиалов\n• аудит — полный аудит\n• прогноз — прогноз исполнения\n• статус — состояние по разделам\n• план — план действий и рекомендации\n• пункт N — детали конкретного мероприятия"
|
||
}
|
||
|
||
addMsg("b",ans,"Джарвис")
|
||
}
|
||
function renderUsers(){
|
||
if(!cu||cu.bg!==0){document.getElementById("tab_users").innerHTML="<div class='card'><p style='color:#EF4444'>\u0414\u043E\u0441\u0442\u0443\u043F \u0437\u0430\u043F\u0440\u0435\u0449\u0451\u043D</p></div>";return}
|
||
var ex=localStorage.getItem("ext_users");
|
||
if(ex){try{var eu=JSON.parse(ex);for(var k in eu){if(eu.hasOwnProperty(k)&&!USR[k])USR[k]=eu[k]}}catch(e){}}
|
||
var rn={0:"\u041A\u0443\u0440\u0430\u0442\u043E\u0440",1:"\u041E\u0442\u0432. \u043B\u0438\u0446\u043E",2:"\u0420\u0443\u043A. \u0444\u0438\u043B\u0438\u0430\u043B\u0430"};
|
||
var h="<table><tr><th>\u041B\u043E\u0433\u0438\u043D</th><th>\u0424\u0418\u041E</th><th>\u0422\u0435\u043B\u0435\u0444\u043E\u043D</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0420\u043E\u043B\u044C</th><th></th></tr>";
|
||
for(var k in USR){
|
||
if(!USR.hasOwnProperty(k))continue;
|
||
var u=USR[k];
|
||
h+="<tr><td>"+esc(k)+(k.indexOf("@")===-1?"@telecom.kz":"")+"</td><td>"+esc(u.n)+"</td><td>"+esc(u.ph||"")+"</td><td>"+esc(brs[u.bg]||"")+"</td><td>"+esc(rn[u.role]||(u.bg===0?"\u041A\u0443\u0440\u0430\u0442\u043E\u0440":"\u041E\u0442\u0432. \u043B\u0438\u0446\u043E"))+"</td>";
|
||
h+="<td><button class='btn btn-sm btn-o' style='padding:3px 8px;margin-right:4px' onclick=\"resetPw('"+esc(k)+"')\">\u0421\u0431\u0440\u043E\u0441</button><button class='btn btn-sm btn-r' style='padding:3px 10px' onclick=\"delUser('"+esc(k)+"')\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button></td></tr>"
|
||
}
|
||
h+="</table>";
|
||
document.getElementById("users_list").innerHTML=h
|
||
}
|
||
function resetPw(k){
|
||
var np=prompt("Новый пароль для "+k+":","0000");
|
||
if(np&&USR[k]){USR[k].pw=np;saveUsers();renderUsers()}
|
||
}
|
||
function addUser(){
|
||
var em=document.getElementById("reg_email").value.trim().toLowerCase();
|
||
var k=em.split("@")[0];
|
||
var nm=document.getElementById("reg_name").value.trim();
|
||
var ph=document.getElementById("reg_phone").value.trim();
|
||
var bg=parseInt(document.getElementById("reg_branch").value,10);
|
||
var pw=document.getElementById("reg_pass").value.trim();
|
||
var rlSel=document.getElementById("reg_role");
|
||
var rl=rlSel?parseInt(rlSel.value,10):1;
|
||
if(!em||!nm){alert("\u0417\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u0435 \u043B\u043E\u0433\u0438\u043D \u0438 \u0424\u0418\u041E");return}
|
||
if(USR[k]){alert("\u041F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442");return}
|
||
USR[k]={n:nm,bg:bg,ph:ph,role:rl};
|
||
if(pw)USR[k].pw=pw;
|
||
saveUsers();
|
||
closeRegModal();
|
||
renderUsers()
|
||
}
|
||
function showRegModal(){
|
||
var rb=document.getElementById("reg_branch");
|
||
if(rb&&!rb.options.length){
|
||
for(var i=0;i<brs.length;i++){
|
||
var o=document.createElement("option");
|
||
o.value=i;o.textContent=brs[i];
|
||
rb.appendChild(o)
|
||
}
|
||
}
|
||
var rr=document.getElementById("reg_role");
|
||
if(rr&&!rr.options.length){
|
||
var roles=[{v:0,t:"\u041A\u0443\u0440\u0430\u0442\u043E\u0440 \u041F\u0411"},{v:1,t:"\u041E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043D\u043D\u043E\u0435 \u043B\u0438\u0446\u043E"},{v:2,t:"\u0420\u0443\u043A\u043E\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C \u0444\u0438\u043B\u0438\u0430\u043B\u0430"}];
|
||
for(var j=0;j<roles.length;j++){
|
||
var o2=document.createElement("option");
|
||
o2.value=roles[j].v;o2.textContent=roles[j].t;
|
||
rr.appendChild(o2)
|
||
}
|
||
}
|
||
document.getElementById("regModal").style.display="flex"
|
||
}
|
||
function closeRegModal(){
|
||
document.getElementById("regModal").style.display="none";
|
||
document.getElementById("reg_email").value="";
|
||
document.getElementById("reg_name").value="";
|
||
document.getElementById("reg_phone").value="";
|
||
document.getElementById("reg_pass").value=""
|
||
}
|
||
function delUser(k){
|
||
if(!confirm("Удалить "+k+"?"))return;
|
||
delete USR[k];
|
||
saveUsers();
|
||
renderUsers()
|
||
}
|
||
function saveLTIF(){
|
||
if(!cu||cu.bg!==0){alert("\u0422\u043E\u043B\u044C\u043A\u043E \u043A\u0443\u0440\u0430\u0442\u043E\u0440 \u043C\u043E\u0436\u0435\u0442 \u0432\u043D\u043E\u0441\u0438\u0442\u044C \u0434\u0430\u043D\u043D\u044B\u0435 LTIF");return}
|
||
var m=parseInt(document.getElementById("ltif_month").value,10);
|
||
var h=parseFloat(document.getElementById("ltif_hours").value)||0;
|
||
var a=parseInt(document.getElementById("ltif_inj").value)||0;
|
||
if(!h){alert("\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u043E-\u0447\u0430\u0441\u044B");return}
|
||
var data=localStorage.getItem("ltif_data");
|
||
var ltif=[];
|
||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||
if(ltif[m]&<if[m].h){
|
||
var co=localStorage.getItem("ltif_corrections");
|
||
var corr=[];
|
||
if(co){try{corr=JSON.parse(co)}catch(e){}}
|
||
var d=new Date();
|
||
corr.push({month:m,oldH:ltif[m].h,oldA:ltif[m].a,newH:h,newA:a,comment:"\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u0431\u0435\u0437 \u043A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u044F",date:d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear(),user:cu?cu.n:""});
|
||
try{localStorage.setItem("ltif_corrections",JSON.stringify(corr))}catch(e){}
|
||
}
|
||
ltif[m]={h:h,a:a};
|
||
try{localStorage.setItem("ltif_data",JSON.stringify(ltif))}catch(e){}
|
||
loadLTIF()
|
||
}
|
||
function saveLtifCorrection(m){
|
||
if(!cu||cu.bg!==0)return;
|
||
var nh=parseFloat(document.getElementById("ltifc_h_"+m).value)||0;
|
||
var na=parseInt(document.getElementById("ltifc_a_"+m).value)||0;
|
||
var nc=document.getElementById("ltifc_c_"+m).value.trim()||"\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430";
|
||
if(!nh){alert("\u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u0447\u0435\u043B\u043E\u0432\u0435\u043A\u043E-\u0447\u0430\u0441\u044B");return}
|
||
var data=localStorage.getItem("ltif_data");
|
||
var ltif=[];
|
||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||
var oh=ltif[m]?ltif[m].h:0;
|
||
var oa=ltif[m]?ltif[m].a:0;
|
||
var co=localStorage.getItem("ltif_corrections");
|
||
var corr=[];
|
||
if(co){try{corr=JSON.parse(co)}catch(e){}}
|
||
var d=new Date();
|
||
corr.push({month:m,oldH:oh,oldA:oa,newH:nh,newA:na,comment:nc,date:d.getDate()+"."+String(d.getMonth()+1).padStart(2,"0")+"."+d.getFullYear(),user:cu?cu.n:""});
|
||
try{localStorage.setItem("ltif_corrections",JSON.stringify(corr))}catch(e){}
|
||
ltif[m]={h:nh,a:na};
|
||
try{localStorage.setItem("ltif_data",JSON.stringify(ltif))}catch(e){}
|
||
loadLTIF()
|
||
}
|
||
function loadLTIF(){
|
||
var data=localStorage.getItem("ltif_data");
|
||
var ltif=[];
|
||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
|
||
var m=parseInt(document.getElementById("ltif_month").value,10);
|
||
var cur=ltif[m];
|
||
if(cur){document.getElementById("ltif_hours").value=cur.h;document.getElementById("ltif_inj").value=cur.a}
|
||
else{document.getElementById("ltif_hours").value="";document.getElementById("ltif_inj").value=""}
|
||
var res=document.getElementById("ltif_result");
|
||
var totalH=0,totalA=0;
|
||
var isCurator=cu&&cu.bg===0;
|
||
var tbl="<table><tr><th>\u041C\u0435\u0441\u044F\u0446</th><th>\u0427\u0435\u043B-\u0447\u0430\u0441\u044B</th><th>\u041F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0435</th><th>LTIF</th>"+(isCurator?"<th>\u041A\u043E\u0440\u0440.</th>":"")+"</tr>";
|
||
for(var i=0;i<12;i++){
|
||
if(ltif[i]&<if[i].h){
|
||
totalH+=ltif[i].h;totalA+=ltif[i].a;
|
||
var lt=ltif[i].a*1000000/ltif[i].h;
|
||
tbl+="<tr><td>"+mnames[i]+"</td><td>"+ltif[i].h.toLocaleString()+"</td><td>"+ltif[i].a+"</td><td>"+lt.toFixed(2)+"</td>";
|
||
if(isCurator)tbl+="<td><button class='btn btn-sm btn-o' style='padding:2px 6px;font-size:10px' onclick=\"showLtifCorr("+i+")\">\u041A\u043E\u0440\u0440.</button></td>";
|
||
tbl+="</tr>"
|
||
}
|
||
}
|
||
tbl+="</table>";
|
||
if(totalH>0){
|
||
var totalLT=totalA*1000000/totalH;
|
||
res.innerHTML="<strong>\u0413\u043E\u0434\u043E\u0432\u043E\u0439 LTIF: "+totalLT.toFixed(2)+"</strong> (\u043F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0445: "+totalA+", \u0447\u0435\u043B-\u0447\u0430\u0441\u043E\u0432: "+totalH.toLocaleString()+")"
|
||
}else{res.innerHTML=""}
|
||
document.getElementById("ltif_table").innerHTML=tbl;
|
||
document.getElementById("ltif_corr_div").innerHTML="";
|
||
document.getElementById("ltif_card").style.display=cu&&cu.bg===0?"":"none";
|
||
renderLtifCorrections()
|
||
}
|
||
function showLtifCorr(m){
|
||
if(!cu||cu.bg!==0)return;
|
||
var data=localStorage.getItem("ltif_data");
|
||
var ltif=[];
|
||
if(data){try{ltif=JSON.parse(data)}catch(e){}}
|
||
var cur=ltif[m];
|
||
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
|
||
var h="<div style='margin-top:8px;padding:8px;background:#FFF3E0;border-radius:6px;font-size:12px'>";
|
||
h+="<strong>\u041A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0430 \u0437\u0430 "+esc(mnames[m])+":</strong><br>";
|
||
h+="\u0427\u0435\u043B-\u0447\u0430\u0441\u044B: <input id='ltifc_h_"+m+"' type='number' value='"+(cur?cur.h:"")+"' style='width:120px;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'> ";
|
||
h+="\u041F\u043E\u0441\u0442\u0440\u0430\u0434\u0430\u0432\u0448\u0438\u0445: <input id='ltifc_a_"+m+"' type='number' value='"+(cur?cur.a:"0")+"' style='width:60px;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'><br>";
|
||
h+="\u041F\u0440\u0438\u0447\u0438\u043D\u0430: <input id='ltifc_c_"+m+"' placeholder='\u041F\u0440\u0438\u0447\u0438\u043D\u0430 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043A\u0438' style='width:100%;padding:4px;border:1px solid #E2E8F0;border-radius:4px;font-size:11px'><br>";
|
||
h+="<button class='btn btn-sm btn-g' style='margin-top:4px;padding:3px 10px;font-size:11px' onclick='saveLtifCorrection("+m+")'>\u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C</button> ";
|
||
h+="<button class='btn btn-sm' style='margin-top:4px;padding:3px 10px;font-size:11px;background:#E2E8F0;color:#0B1A2E' onclick='document.getElementById(\"ltif_corr_div\").innerHTML=\"\"'>\u041E\u0442\u043C\u0435\u043D\u0430</button></div>";
|
||
document.getElementById("ltif_corr_div").innerHTML=h
|
||
}
|
||
function renderLtifCorrections(){
|
||
var co=localStorage.getItem("ltif_corrections");
|
||
if(!co)return;
|
||
try{
|
||
var corr=JSON.parse(co);
|
||
if(!corr||!corr.length)return;
|
||
var mnames=["\u042F\u043D\u0432","\u0424\u0435\u0432","\u041C\u0430\u0440","\u0410\u043F\u0440","\u041C\u0430\u0439","\u0418\u044E\u043D","\u0418\u044E\u043B","\u0410\u0432\u0433","\u0421\u0435\u043D","\u041E\u043A\u0442","\u041D\u043E\u044F","\u0414\u0435\u043A"];
|
||
corr.sort(function(a,b){return b.month-a.month});
|
||
var h="<div style='margin-top:12px'><strong>\u0418\u0441\u0442\u043E\u0440\u0438\u044F \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u0438\u0440\u043E\u0432\u043E\u043A:</strong><table style='font-size:11px'><tr><th>\u041C\u0435\u0441\u044F\u0446</th><th>\u0411\u044B\u043B\u043E \u0447-\u0447/\u043F</th><th>\u0421\u0442\u0430\u043B\u043E \u0447-\u0447/\u043F</th><th>\u041F\u0440\u0438\u0447\u0438\u043D\u0430</th><th>\u0414\u0430\u0442\u0430</th><th>\u041A\u0442\u043E</th></tr>";
|
||
for(var i=0;i<corr.length;i++){
|
||
var c=corr[i];
|
||
h+="<tr><td>"+mnames[c.month]+"</td><td>"+(c.oldH||0)+"/"+(c.oldA||0)+"</td><td>"+c.newH+"/"+c.newA+"</td><td style='font-size:10px'>"+esc(c.comment||"")+"</td><td>"+esc(c.date||"")+"</td><td>"+esc(c.user||"")+"</td></tr>"
|
||
}
|
||
h+="</table></div>";
|
||
document.getElementById("ltif_corr_div").innerHTML+=h
|
||
}catch(e){}
|
||
}
|
||
function saveUsers(){
|
||
var ex={};
|
||
for(var k in USR){
|
||
if(!USR.hasOwnProperty(k))continue;
|
||
if(k!=="curator"&&k!=="admin"&&k!=="dpp")ex[k]=USR[k]
|
||
}
|
||
try{localStorage.setItem("ext_users",JSON.stringify(ex))}catch(e){}
|
||
}
|
||
function dlAnalyticsPPT(){
|
||
var total=evs.length;var done=0,late=0,warn=0;
|
||
for(var i=0;i<evs.length;i++){if(evs[i].s==="done")done++;else if(evs[i].s==="late")late++;else warn++}
|
||
var pct=total?Math.round(done/total*100):0;
|
||
var brd=[];for(var i=0;i<brs.length;i++){brd.push({n:brs[i],t:0,d:0})}
|
||
for(var i=0;i<evs.length;i++){var e=evs[i];brd[e.b].t++;if(e.s==="done")brd[e.b].d++}
|
||
brd.sort(function(a,b){return(b.d/b.t||0)-(a.d/a.t||0)});
|
||
var h="<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:p='urn:schemas-microsoft-com:office:powerpoint'><head><meta charset='utf-8'><title>\u0410\u043D\u0430\u043B\u0438\u0442\u0438\u043A\u0430 HSE</title><style>body{font:18px Arial;padding:30px}@page{size:A4 landscape;margin:15mm}h1{color:#005BAA;font-size:28px}.num{font-size:48px;font-weight:800;color:#005BAA}.pct{font-size:72px;font-weight:800;color:"+(pct>=70?"#10B981":pct>=40?"#F59E0B":"#EF4444")+"}.bar{height:28px;background:#005BAA;border-radius:6px;margin:8px 0}.slide{page-break-after:always;min-height:350px}table{border-collapse:collapse;width:100%}td{padding:12px 20px;border:1px solid #ddd;font-size:16px}th{background:#0A1628;color:#fff;padding:10px 14px;font-size:13px}</style></head><body><div class='slide'><h1>QAZAQtelecom HSE \u2014 \u0410\u043D\u0430\u043B\u0438\u0442\u0438\u043A\u0430 \u041F\u0411</h1><p>\u0414\u0430\u0442\u0430: "+new Date().toLocaleDateString("ru-RU")+"</p><br><div style='text-align:center'><div class='pct'>"+pct+"%</div><p style='font-size:20px;color:#64748B'>\u041E\u0431\u0449\u0438\u0439 \u043F\u0440\u043E\u0446\u0435\u043D\u0442 \u0438\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F</p></div><br><table><tr><td style='text-align:center'><div class='num'>"+total+"</div>\u0412\u0441\u0435\u0433\u043E</td><td style='text-align:center'><div class='num'>"+done+"</div>\u0418\u0441\u043F\u043E\u043B\u043D\u0435\u043D\u043E</td><td style='text-align:center'><div class='num'>"+warn+"</div>\u0412 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0435</td><td style='text-align:center'><div class='num' style='color:#EF4444'>"+late+"</div>\u041F\u0440\u043E\u0441\u0440\u043E\u0447\u0435\u043D\u043E</td></tr></table><div class='bar' style='width:"+Math.round(pct*5)+"px'></div></div><div class='slide'><h2>\u0420\u0435\u0439\u0442\u0438\u043D\u0433 \u0444\u0438\u043B\u0438\u0430\u043B\u043E\u0432</h2><table><tr><th>\u2116</th><th>\u0424\u0438\u043B\u0438\u0430\u043B</th><th>\u0412\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u043E</th><th>%</th></tr>";
|
||
for(var i=0;i<brd.length;i++){var bp=brd[i].t?Math.round(brd[i].d/brd[i].t*100):0;h+="<tr><td>"+(i+1)+"</td><td>"+esc(brd[i].n)+"</td><td>"+brd[i].d+"/"+brd[i].t+"</td><td><div class='bar' style='width:"+(bp*2)+"px'></div> "+bp+"%</td></tr>"}
|
||
h+="</table></div></body></html>";
|
||
var blob=new Blob([h],{type:"application/vnd.ms-powerpoint"});
|
||
var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="analytics_"+new Date().toISOString().slice(0,10)+".ppt";a.click()
|
||
}
|
||
function dlAnalyticsPDF(){
|
||
var h=document.getElementById("tab_analytics").innerHTML;
|
||
var w=window.open("","_blank","width=900,height=700");
|
||
w.document.write("<!DOCTYPE html><html><head><meta charset='utf-8'><title>Аналитика</title><style>body{font:14px Arial;padding:20px}@media print{body{padding:10mm}}.card{background:#fff;border:1px solid #E8ECF1;border-radius:12px;padding:16px;margin-bottom:12px}.num{font-size:28px;font-weight:800}</style></head><body><h2>QAZAQtelecom HSE — Аналитика</h2><p>"+new Date().toLocaleDateString("ru-RU")+"</p><br>"+h+"<script>window.onload=function(){window.print()}<\/script></body></html>");
|
||
w.document.close()
|
||
}
|
||
function dlAnalyticsWord(){
|
||
var total=evs.length;
|
||
var done=0,late=0,warn=0;
|
||
for(var i=0;i<evs.length;i++){
|
||
if(evs[i].s==="done")done++;else if(evs[i].s==="late")late++;else warn++
|
||
}
|
||
var h="<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:w='urn:schemas-microsoft-com:office:word'><head><meta charset='utf-8'><title>Аналитика HSE</title><style>@page{size:A4;margin:20mm}body{font:14pt 'Times New Roman'}h1{color:#005BAA}table{border-collapse:collapse}td{border:1px solid #000;padding:12px 20px;font-size:20pt;font-weight:700}</style></head><body><h1>QAZAQtelecom HSE — Аналитика</h1><p>Дата: "+new Date().toLocaleDateString("ru-RU")+"</p><br><table><tr><td>Всего<br><span style='font-size:28pt'>"+total+"</span></td><td>Исполнено<br><span style='font-size:28pt'>"+done+" ("+Math.round(done/total*100)+"%)</span></td><td>В процессе<br><span style='font-size:28pt'>"+warn+"</span></td><td>Просрочено<br><span style='font-size:28pt;color:red'>"+late+"</span></td></tr></table></body></html>";
|
||
var blob=new Blob([h],{type:"application/msword"});
|
||
var a=document.createElement("a");a.href=URL.createObjectURL(blob);a.download="analytics.doc";a.click()
|
||
}
|
||
|
||
</script></script></script></script></script></script></script></script></script>
|
||
</body>
|
||
</html>
|