Добавление HTTP-сервиса для ввода табелей и регистрация в конфигурации
1) Изменение в 101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/Configuration/Configuration.mdo: - добавлена ссылка на новый HTTP-сервис ПС_ВебСервисТабелей 2) Новая функциональность в 101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/HTTPServices/ПС_ВебСервисТабелей/Module.bsl: - реализован серверный модуль веб-сервиса с обработчиками маршрутов - GET /index — возвращает HTML-форму ввода табеля - GET /me — возвращает JSON с данными текущего пользователя - GET /departments — возвращает JSON со списком доступных подразделений - GET /employees — возвращает JSON со списком сотрудников подразделения - GET /kinds — возвращает список видов использования рабочего времени - GET /funds — возвращает список источников финансирования 3) Новая функциональность в 101_ЦМСЧ_ЗиКГУ.ЗагрузкаДанныхИзExcel/src/HTTPServices/ПС_ВебСервисТабелей/ПС_ВебСервисТабелей.mdo: - создан метаданный объект HTTP-сервиса "ПС_ВебСервисТабелей" - настроены корневой URL /tabel и маршруты для всех обработчиков
This commit is contained in:
@@ -78,6 +78,7 @@
|
|||||||
<commonModules>CommonModule.ПС_ЗагрузкаДанныхИзExcel_Описание</commonModules>
|
<commonModules>CommonModule.ПС_ЗагрузкаДанныхИзExcel_Описание</commonModules>
|
||||||
<commonModules>CommonModule.ПС_КартаДанных</commonModules>
|
<commonModules>CommonModule.ПС_КартаДанных</commonModules>
|
||||||
<commonModules>CommonModule.ПС_ТабелиСервер</commonModules>
|
<commonModules>CommonModule.ПС_ТабелиСервер</commonModules>
|
||||||
|
<httpServices>HTTPService.ПС_ВебСервисТабелей</httpServices>
|
||||||
<catalogs>Catalog.Организации</catalogs>
|
<catalogs>Catalog.Организации</catalogs>
|
||||||
<catalogs>Catalog.ПодразделенияОрганизаций</catalogs>
|
<catalogs>Catalog.ПодразделенияОрганизаций</catalogs>
|
||||||
<catalogs>Catalog.Пользователи</catalogs>
|
<catalogs>Catalog.Пользователи</catalogs>
|
||||||
|
|||||||
@@ -0,0 +1,385 @@
|
|||||||
|
// HTTP-сервис "Веб-сервис табелей".
|
||||||
|
// Маршруты:
|
||||||
|
// GET /index — HTML-форма ввода табеля
|
||||||
|
// GET /me — JSON с данными текущего пользователя
|
||||||
|
// GET /departments — JSON со списком доступных подразделений
|
||||||
|
// GET /employees — JSON со списком действующих сотрудников подразделения
|
||||||
|
|
||||||
|
#Область ОбработчикиСобытий
|
||||||
|
|
||||||
|
Функция ОбработкаГлавной(Запрос)
|
||||||
|
Возврат ГлавнаяHtml();
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
Функция ОбработкаТекущегоПользователя(Запрос)
|
||||||
|
Данные = ДанныеТекущегоПользователя();
|
||||||
|
Объект = Новый Соответствие;
|
||||||
|
Объект.Вставить("name", Данные.Имя);
|
||||||
|
Объект.Вставить("user", Данные.ИмяПользователя);
|
||||||
|
Возврат JsonОтвет(200, Объект);
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
Функция ОбработкаСпискаПодразделений(Запрос)
|
||||||
|
Массив = Новый Массив;
|
||||||
|
Подразделения = ДоступныеПодразделения();
|
||||||
|
Для Каждого КлючЗначение Из Подразделения Цикл
|
||||||
|
П = КлючЗначение.Значение;
|
||||||
|
Элемент = Новый Соответствие;
|
||||||
|
Элемент.Вставить("ref", XMLСтрока(П.Ссылка));
|
||||||
|
Элемент.Вставить("name", П.Имя);
|
||||||
|
Массив.Добавить(Элемент);
|
||||||
|
КонецЦикла;
|
||||||
|
Объект = Новый Соответствие;
|
||||||
|
Объект.Вставить("items", Массив);
|
||||||
|
Возврат JsonОтвет(200, Объект);
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
Функция ОбработкаСпискаСотрудников(Запрос)
|
||||||
|
СтрокаПодразделения = Запрос.ПараметрыЗапроса.Получить("dep");
|
||||||
|
Если СтрокаПодразделения = Неопределено Тогда
|
||||||
|
СтрокаПодразделения = Запрос.ПараметрыURL.Получить("dep");
|
||||||
|
КонецЕсли;
|
||||||
|
Если СтрокаПодразделения = Неопределено ИЛИ ПустаяСтрока(СтрокаПодразделения) Тогда
|
||||||
|
Ошибка = Новый Соответствие;
|
||||||
|
Ошибка.Вставить("error", "Не передано подразделение (dep)");
|
||||||
|
Возврат JsonОтвет(400, Ошибка);
|
||||||
|
КонецЕсли;
|
||||||
|
|
||||||
|
Массив = Новый Массив;
|
||||||
|
СотрудникиСписок = СотрудникиПодразделения(СтрокаПодразделения);
|
||||||
|
Для Каждого Строка Из СотрудникиСписок Цикл
|
||||||
|
Элемент = Новый Соответствие;
|
||||||
|
Элемент.Вставить("ref", XMLСтрока(Строка.Ссылка));
|
||||||
|
Элемент.Вставить("name", Строка.Имя);
|
||||||
|
Элемент.Вставить("position", Строка.Должность);
|
||||||
|
Массив.Добавить(Элемент);
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Объект = Новый Соответствие;
|
||||||
|
Объект.Вставить("items", Массив);
|
||||||
|
Возврат JsonОтвет(200, Объект);
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
Функция ОбработкаСпискаВидовВремени(Запрос)
|
||||||
|
Массив = Новый Массив;
|
||||||
|
ВидыСписок = ВидыВремениСписок();
|
||||||
|
Для Каждого Строка Из ВидыСписок Цикл
|
||||||
|
Элемент = Новый Соответствие;
|
||||||
|
Элемент.Вставить("ref", XMLСтрока(Строка.Ссылка));
|
||||||
|
Элемент.Вставить("letter", Строка.Буква);
|
||||||
|
Элемент.Вставить("name", Строка.Наименование);
|
||||||
|
Массив.Добавить(Элемент);
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Объект = Новый Соответствие;
|
||||||
|
Объект.Вставить("items", Массив);
|
||||||
|
Возврат JsonОтвет(200, Объект);
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
Функция ОбработкаСпискаИсточниковФинансирования(Запрос)
|
||||||
|
Массив = Новый Массив;
|
||||||
|
Для Каждого Строка Из ИсточникиФинансированияСписок() Цикл
|
||||||
|
Элемент = Новый Соответствие;
|
||||||
|
Элемент.Вставить("ref", Строка.Код);
|
||||||
|
Элемент.Вставить("name", Строка.Наименование);
|
||||||
|
Массив.Добавить(Элемент);
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Объект = Новый Соответствие;
|
||||||
|
Объект.Вставить("items", Массив);
|
||||||
|
Возврат JsonОтвет(200, Объект);
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
|
#Область СлужебныеПроцедурыИФункции
|
||||||
|
|
||||||
|
// HTML-страница.
|
||||||
|
|
||||||
|
Функция ГлавнаяHtml()
|
||||||
|
ДанныеПользователя = ДанныеТекущегоПользователя();
|
||||||
|
Подразделения = ДоступныеПодразделения();
|
||||||
|
|
||||||
|
Части = Новый Массив;
|
||||||
|
Части.Добавить("<!DOCTYPE html>");
|
||||||
|
Части.Добавить("<html lang=""ru"">");
|
||||||
|
Части.Добавить("<head>");
|
||||||
|
Части.Добавить("<meta charset=""utf-8"">");
|
||||||
|
Части.Добавить("<title>Ввод табеля — MVP</title>");
|
||||||
|
Части.Добавить("<style>");
|
||||||
|
Части.Добавить("body { font-family: -apple-system, Segoe UI, sans-serif; margin: 24px; color: #1f2933; background: #f7f9fb; }");
|
||||||
|
Части.Добавить("h1 { margin: 0 0 4px; font-size: 22px; }");
|
||||||
|
Части.Добавить(".muted { color: #6b7280; font-size: 13px; }");
|
||||||
|
Части.Добавить(".card { background: white; border: 1px solid #e1e5eb; border-radius: 6px; padding: 16px; margin-top: 12px; }");
|
||||||
|
Части.Добавить(".filters { display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-end; }");
|
||||||
|
Части.Добавить(".filter-cell { display: flex; flex-direction: column; min-width: 180px; }");
|
||||||
|
Части.Добавить("label { margin-top: 8px; font-size: 13px; }");
|
||||||
|
Части.Добавить("select, input, button { padding: 6px 10px; font-size: 14px; border: 1px solid #cbd2d9; border-radius: 4px; }");
|
||||||
|
Части.Добавить("button { background: #2c7be5; color: white; border: 0; cursor: pointer; padding: 8px 16px; }");
|
||||||
|
Части.Добавить("button:disabled { background: #9aa5b1; cursor: not-allowed; }");
|
||||||
|
Части.Добавить("table.t { border-collapse: collapse; margin-top: 12px; font-size: 12px; }");
|
||||||
|
Части.Добавить("table.t th, table.t td { border: 1px solid #e1e5eb; padding: 2px; text-align: center; min-width: 32px; }");
|
||||||
|
Части.Добавить("table.t th { background: #f0f4f8; }");
|
||||||
|
Части.Добавить("table.t td.name, table.t th.name { text-align: left; padding-left: 8px; min-width: 220px; background: #fafbfc; position: sticky; left: 0; }");
|
||||||
|
Части.Добавить("table.t select { width: 100%; border: 0; padding: 2px 4px; font-size: 12px; background: transparent; }");
|
||||||
|
Части.Добавить(".scroll { overflow-x: auto; max-width: 100%; }");
|
||||||
|
Части.Добавить("</style>");
|
||||||
|
Части.Добавить("</head>");
|
||||||
|
Части.Добавить("<body>");
|
||||||
|
Части.Добавить("<h1>Ввод табеля учёта рабочего времени</h1>");
|
||||||
|
Части.Добавить("<div class=""muted"">MVP — проверка концепции.</div>");
|
||||||
|
Части.Добавить("<div class=""card"">");
|
||||||
|
Части.Добавить("<div><b>Пользователь:</b> " + ДанныеПользователя.Имя + "</div>");
|
||||||
|
Части.Добавить("<div><b>Подразделений доступно:</b> " + Формат(Подразделения.Количество(), "ЧГ=0") + "</div>");
|
||||||
|
Части.Добавить("</div>");
|
||||||
|
Части.Добавить("<div class=""card"">");
|
||||||
|
Части.Добавить("<div class=""filters"">");
|
||||||
|
Части.Добавить("<div class=""filter-cell""><label>Подразделение</label>");
|
||||||
|
Части.Добавить("<select id=""depSelect""><option value="""">— выберите —</option>" + ОпцииПодразделений(Подразделения) + "</select></div>");
|
||||||
|
Части.Добавить("<div class=""filter-cell""><label>Период (месяц)</label>");
|
||||||
|
Части.Добавить("<input type=""month"" id=""period"" value=""" + Формат(ТекущаяДатаСеанса(), "ДФ=yyyy-MM") + """></div>");
|
||||||
|
Части.Добавить("<div class=""filter-cell""><label>Источник финансирования</label>");
|
||||||
|
Части.Добавить("<select id=""fundSelect""><option value="""">— выберите —</option></select></div>");
|
||||||
|
Части.Добавить("<div class=""filter-cell""><label> </label><button id=""load"" disabled>Загрузить табель</button></div>");
|
||||||
|
Части.Добавить("</div>");
|
||||||
|
Части.Добавить("<div style=""margin-top: 8px;""><span id=""status"" class=""muted""></span></div>");
|
||||||
|
Части.Добавить("</div>");
|
||||||
|
Части.Добавить("<div class=""card"">");
|
||||||
|
Части.Добавить("<div id=""tableArea""><div class=""muted"">Сотрудники появятся после загрузки.</div></div>");
|
||||||
|
Части.Добавить("</div>");
|
||||||
|
Части.Добавить("<script>");
|
||||||
|
Части.Добавить("var sel = document.getElementById('depSelect');");
|
||||||
|
Части.Добавить("var period = document.getElementById('period');");
|
||||||
|
Части.Добавить("var fundSel = document.getElementById('fundSelect');");
|
||||||
|
Части.Добавить("var btn = document.getElementById('load');");
|
||||||
|
Части.Добавить("var status = document.getElementById('status');");
|
||||||
|
Части.Добавить("var tableArea = document.getElementById('tableArea');");
|
||||||
|
Части.Добавить("var kinds = [];");
|
||||||
|
Части.Добавить("function ready() { btn.disabled = !(sel.value && period.value && fundSel.value); }");
|
||||||
|
Части.Добавить("sel.onchange = ready; period.onchange = ready; fundSel.onchange = ready;");
|
||||||
|
Части.Добавить("function loadKinds(cb) {");
|
||||||
|
Части.Добавить(" var xhr = new XMLHttpRequest();");
|
||||||
|
Части.Добавить(" xhr.open('GET', '/8ZikBudg/hs/tabel/kinds', true);");
|
||||||
|
Части.Добавить(" xhr.onload = function() {");
|
||||||
|
Части.Добавить(" if (xhr.status === 200) { try { var d = JSON.parse(xhr.responseText); kinds = d.items || []; cb && cb(); }");
|
||||||
|
Части.Добавить(" catch (e) { status.textContent = 'Ошибка /kinds: ' + e.message; } }");
|
||||||
|
Части.Добавить(" else { status.textContent = 'Ошибка /kinds: HTTP ' + xhr.status; } };");
|
||||||
|
Части.Добавить(" xhr.onerror = function() { status.textContent = 'Сбой запроса /kinds.'; };");
|
||||||
|
Части.Добавить(" xhr.send();");
|
||||||
|
Части.Добавить("}");
|
||||||
|
Части.Добавить("function loadFunds() {");
|
||||||
|
Части.Добавить(" var xhr = new XMLHttpRequest();");
|
||||||
|
Части.Добавить(" xhr.open('GET', '/8ZikBudg/hs/tabel/funds', true);");
|
||||||
|
Части.Добавить(" xhr.onload = function() {");
|
||||||
|
Части.Добавить(" if (xhr.status === 200) { try { var d = JSON.parse(xhr.responseText);");
|
||||||
|
Части.Добавить(" for (var i = 0; i < d.items.length; i++) {");
|
||||||
|
Части.Добавить(" var o = document.createElement('option'); o.value = d.items[i].ref; o.textContent = d.items[i].name; fundSel.appendChild(o);");
|
||||||
|
Части.Добавить(" } ready(); }");
|
||||||
|
Части.Добавить(" catch (e) { status.textContent = 'Ошибка /funds: ' + e.message; } }");
|
||||||
|
Части.Добавить(" else { status.textContent = 'Ошибка /funds: HTTP ' + xhr.status; } };");
|
||||||
|
Части.Добавить(" xhr.onerror = function() { status.textContent = 'Сбой запроса /funds.'; };");
|
||||||
|
Части.Добавить(" xhr.send();");
|
||||||
|
Части.Добавить("}");
|
||||||
|
Части.Добавить("function daysInPeriod(p) {");
|
||||||
|
Части.Добавить(" var a = p.split('-'); var y = parseInt(a[0], 10); var m = parseInt(a[1], 10);");
|
||||||
|
Части.Добавить(" return new Date(y, m, 0).getDate();");
|
||||||
|
Части.Добавить("}");
|
||||||
|
Части.Добавить("btn.onclick = function() {");
|
||||||
|
Части.Добавить(" status.textContent = 'Загрузка…'; btn.disabled = true; tableArea.innerHTML = '';");
|
||||||
|
Части.Добавить(" var days = daysInPeriod(period.value);");
|
||||||
|
Части.Добавить(" var xhr = new XMLHttpRequest();");
|
||||||
|
Части.Добавить(" xhr.open('GET', '/8ZikBudg/hs/tabel/employees?dep=' + encodeURIComponent(sel.value), true);");
|
||||||
|
Части.Добавить(" xhr.onload = function() {");
|
||||||
|
Части.Добавить(" if (xhr.status === 200) { try {");
|
||||||
|
Части.Добавить(" var data = JSON.parse(xhr.responseText); renderTable(data.items || [], days);");
|
||||||
|
Части.Добавить(" status.textContent = 'Готово. Сотрудников: ' + (data.items || []).length + ', дней: ' + days + '.';");
|
||||||
|
Части.Добавить(" } catch (e) { status.textContent = 'Ошибка разбора: ' + e.message; } }");
|
||||||
|
Части.Добавить(" else { status.textContent = 'Ошибка /employees: HTTP ' + xhr.status; }");
|
||||||
|
Части.Добавить(" ready();");
|
||||||
|
Части.Добавить(" };");
|
||||||
|
Части.Добавить(" xhr.onerror = function() { status.textContent = 'Сбой запроса /employees.'; ready(); };");
|
||||||
|
Части.Добавить(" xhr.send();");
|
||||||
|
Части.Добавить("};");
|
||||||
|
Части.Добавить("function renderTable(items, days) {");
|
||||||
|
Части.Добавить(" if (!items.length) { tableArea.innerHTML = '<div class=""muted"">В подразделении нет действующих сотрудников.</div>'; return; }");
|
||||||
|
Части.Добавить(" var opts = '';");
|
||||||
|
Части.Добавить(" for (var k = 0; k < kinds.length; k++) { opts += '<option value=""' + kinds[k].letter + '"">' + kinds[k].letter + '</option>'; }");
|
||||||
|
Части.Добавить(" var html = '<div class=""scroll""><table class=""t""><thead><tr>';");
|
||||||
|
Части.Добавить(" html += '<th class=""name"">№</th><th class=""name"">Сотрудник</th>';");
|
||||||
|
Части.Добавить(" for (var d = 1; d <= days; d++) { html += '<th>' + d + '</th>'; }");
|
||||||
|
Части.Добавить(" html += '</tr></thead><tbody>';");
|
||||||
|
Части.Добавить(" for (var i = 0; i < items.length; i++) {");
|
||||||
|
Части.Добавить(" html += '<tr><td class=""name"">' + (i + 1) + '</td><td class=""name"">' + items[i].name + '</td>';");
|
||||||
|
Части.Добавить(" for (var d = 1; d <= days; d++) { html += '<td><select data-row=""' + i + '"" data-day=""' + d + '""><option value=""""></option>' + opts + '</select></td>'; }");
|
||||||
|
Части.Добавить(" html += '</tr>';");
|
||||||
|
Части.Добавить(" }");
|
||||||
|
Части.Добавить(" html += '</tbody></table></div>';");
|
||||||
|
Части.Добавить(" tableArea.innerHTML = html;");
|
||||||
|
Части.Добавить("}");
|
||||||
|
Части.Добавить("loadFunds(); loadKinds();");
|
||||||
|
Части.Добавить("</script>");
|
||||||
|
Части.Добавить("</body></html>");
|
||||||
|
|
||||||
|
ТелоHtml = СтрСоединить(Части, Символы.ПС);
|
||||||
|
|
||||||
|
Ответ = Новый HTTPСервисОтвет(200);
|
||||||
|
Ответ.Заголовки.Вставить("Content-Type", "text/html; charset=utf-8");
|
||||||
|
Ответ.УстановитьТелоИзСтроки(ТелоHtml, КодировкаТекста.UTF8);
|
||||||
|
Возврат Ответ;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
Функция ОпцииПодразделений(Подразделения)
|
||||||
|
Части = Новый Массив;
|
||||||
|
Для Каждого КлючЗначение Из Подразделения Цикл
|
||||||
|
Ссылка = XMLСтрока(КлючЗначение.Значение.Ссылка);
|
||||||
|
Имя = КлючЗначение.Значение.Имя;
|
||||||
|
Части.Добавить("<option value=""" + Ссылка + """>" + Имя + "</option>");
|
||||||
|
КонецЦикла;
|
||||||
|
Возврат СтрСоединить(Части, "");
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Backend.
|
||||||
|
|
||||||
|
Функция ДанныеТекущегоПользователя()
|
||||||
|
ИмяПользователя = "";
|
||||||
|
Попытка
|
||||||
|
ИмяПользователя = ИмяПользователя();
|
||||||
|
Исключение
|
||||||
|
ИмяПользователя = "Не определён";
|
||||||
|
КонецПопытки;
|
||||||
|
Возврат Новый Структура("ИмяПользователя, Имя", ИмяПользователя, ИмяПользователя);
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Возвращает Соответствие: Ключ = XMLСтрока(ссылки), Значение = Структура{Ссылка, Имя}.
|
||||||
|
Функция ДоступныеПодразделения()
|
||||||
|
Результат = Новый Соответствие;
|
||||||
|
Запрос = Новый Запрос(
|
||||||
|
"ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка, Наименование КАК Имя
|
||||||
|
|ИЗ Справочник.ПодразделенияОрганизаций
|
||||||
|
|ГДЕ НЕ ПометкаУдаления
|
||||||
|
|УПОРЯДОЧИТЬ ПО Наименование");
|
||||||
|
Выборка = Запрос.Выполнить().Выбрать();
|
||||||
|
Пока Выборка.Следующий() Цикл
|
||||||
|
Данные = Новый Структура("Ссылка, Имя", Выборка.Ссылка, СокрЛП(Выборка.Имя));
|
||||||
|
Результат.Вставить(XMLСтрока(Выборка.Ссылка), Данные);
|
||||||
|
КонецЦикла;
|
||||||
|
Возврат Результат;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Фиксированный набор источников финансирования для учреждений здравоохранения.
|
||||||
|
Функция ИсточникиФинансированияСписок()
|
||||||
|
Результат = Новый Массив;
|
||||||
|
Результат.Добавить(Новый Структура("Код, Наименование", "СГЗ",
|
||||||
|
"Субсидии на выполнение государственного задания"));
|
||||||
|
Результат.Добавить(Новый Структура("Код, Наименование", "ПД",
|
||||||
|
"Приносящая доход деятельность"));
|
||||||
|
Результат.Добавить(Новый Структура("Код, Наименование", "ОМС",
|
||||||
|
"Обязательное медицинское страхование"));
|
||||||
|
Возврат Результат;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Возвращает массив структур {Ссылка, Имя, Должность} — сотрудники, действующие в подразделении.
|
||||||
|
Функция СотрудникиПодразделения(Знач СтрокаПодразделения)
|
||||||
|
Результат = Новый Массив;
|
||||||
|
|
||||||
|
ПодразделениеСсылка = XMLЗначение(Тип("СправочникСсылка.ПодразделенияОрганизаций"),
|
||||||
|
СтрокаПодразделения);
|
||||||
|
|
||||||
|
Запрос = Новый Запрос(
|
||||||
|
"ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
|
||||||
|
| КадроваяИстория.Сотрудник КАК Сотрудник
|
||||||
|
|ИЗ
|
||||||
|
| РегистрСведений.КадроваяИсторияСотрудниковИнтервальный КАК КадроваяИстория
|
||||||
|
|ГДЕ
|
||||||
|
| КадроваяИстория.Подразделение = &Подразделение
|
||||||
|
| И КадроваяИстория.ВидСобытия <> ЗНАЧЕНИЕ(Перечисление.ВидыКадровыхСобытий.Увольнение)
|
||||||
|
| И КадроваяИстория.ДатаНачала <= &ТекущаяДата
|
||||||
|
| И (КадроваяИстория.ДатаОкончания = ДАТАВРЕМЯ(1, 1, 1)
|
||||||
|
| ИЛИ КадроваяИстория.ДатаОкончания >= &ТекущаяДата)
|
||||||
|
|УПОРЯДОЧИТЬ ПО
|
||||||
|
| КадроваяИстория.Сотрудник.Наименование");
|
||||||
|
Запрос.УстановитьПараметр("Подразделение", ПодразделениеСсылка);
|
||||||
|
Запрос.УстановитьПараметр("ТекущаяДата", ТекущаяДатаСеанса());
|
||||||
|
|
||||||
|
Выборка = Запрос.Выполнить().Выбрать();
|
||||||
|
Пока Выборка.Следующий() Цикл
|
||||||
|
Сотрудник = Выборка.Сотрудник;
|
||||||
|
Результат.Добавить(Новый Структура(
|
||||||
|
"Ссылка, Имя, Должность",
|
||||||
|
Сотрудник,
|
||||||
|
СокрЛП(Сотрудник.Наименование),
|
||||||
|
""));
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Возврат Результат;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Возвращает массив структур {Ссылка, Буква, Наименование} — предопределённые виды использования рабочего времени.
|
||||||
|
Функция ВидыВремениСписок()
|
||||||
|
Результат = Новый Массив;
|
||||||
|
|
||||||
|
Запрос = Новый Запрос(
|
||||||
|
"ВЫБРАТЬ
|
||||||
|
| ВидыВремени.Ссылка КАК Ссылка,
|
||||||
|
| ВидыВремени.БуквенныйКод КАК Буква,
|
||||||
|
| ВидыВремени.Наименование КАК Наименование
|
||||||
|
|ИЗ
|
||||||
|
| Справочник.ВидыИспользованияРабочегоВремени КАК ВидыВремени
|
||||||
|
|ГДЕ
|
||||||
|
| НЕ ВидыВремени.ПометкаУдаления
|
||||||
|
| И ВидыВремени.НеИспользуется = ЛОЖЬ
|
||||||
|
|УПОРЯДОЧИТЬ ПО
|
||||||
|
| ВидыВремени.Наименование");
|
||||||
|
|
||||||
|
УстановитьПривилегированныйРежим(Истина);
|
||||||
|
Выборка = Запрос.Выполнить().Выбрать();
|
||||||
|
УстановитьПривилегированныйРежим(Ложь);
|
||||||
|
|
||||||
|
Пока Выборка.Следующий() Цикл
|
||||||
|
Результат.Добавить(Новый Структура(
|
||||||
|
"Ссылка, Буква, Наименование",
|
||||||
|
Выборка.Ссылка,
|
||||||
|
СокрЛП(Выборка.Буква),
|
||||||
|
СокрЛП(Выборка.Наименование)));
|
||||||
|
КонецЦикла;
|
||||||
|
|
||||||
|
Возврат Результат;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
// Сериализация в JSON.
|
||||||
|
|
||||||
|
Функция JsonОтвет(КодСостояния, Объект)
|
||||||
|
ЗаписьJSON = Новый ЗаписьJSON;
|
||||||
|
ЗаписьJSON.УстановитьСтроку();
|
||||||
|
ЗаписатьJsonЗначение(ЗаписьJSON, Объект);
|
||||||
|
Тело = ЗаписьJSON.Закрыть();
|
||||||
|
|
||||||
|
Ответ = Новый HTTPСервисОтвет(КодСостояния);
|
||||||
|
Ответ.Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");
|
||||||
|
Ответ.УстановитьТелоИзСтроки(Тело, КодировкаТекста.UTF8);
|
||||||
|
Возврат Ответ;
|
||||||
|
КонецФункции
|
||||||
|
|
||||||
|
Процедура ЗаписатьJsonЗначение(ЗаписьJSON, Значение)
|
||||||
|
Если Значение = Неопределено Тогда
|
||||||
|
ЗаписьJSON.ЗаписатьЗначение(Null);
|
||||||
|
ИначеЕсли ТипЗнч(Значение) = Тип("Соответствие") ИЛИ ТипЗнч(Значение) = Тип("Структура") Тогда
|
||||||
|
ЗаписьJSON.ЗаписатьНачалоОбъекта();
|
||||||
|
Для Каждого КлючЗначение Из Значение Цикл
|
||||||
|
ЗаписьJSON.ЗаписатьИмяСвойства(КлючЗначение.Ключ);
|
||||||
|
ЗаписатьJsonЗначение(ЗаписьJSON, КлючЗначение.Значение);
|
||||||
|
КонецЦикла;
|
||||||
|
ЗаписьJSON.ЗаписатьКонецОбъекта();
|
||||||
|
ИначеЕсли ТипЗнч(Значение) = Тип("Массив") Тогда
|
||||||
|
ЗаписьJSON.ЗаписатьНачалоМассива();
|
||||||
|
Для Каждого Элемент Из Значение Цикл
|
||||||
|
ЗаписатьJsonЗначение(ЗаписьJSON, Элемент);
|
||||||
|
КонецЦикла;
|
||||||
|
ЗаписьJSON.ЗаписатьКонецМассива();
|
||||||
|
Иначе
|
||||||
|
ЗаписьJSON.ЗаписатьЗначение(Значение);
|
||||||
|
КонецЕсли;
|
||||||
|
КонецПроцедуры
|
||||||
|
|
||||||
|
#КонецОбласти
|
||||||
|
|
||||||
+103
@@ -0,0 +1,103 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<mdclass:HTTPService xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="8fcbeb90-fb46-4f8a-9d9a-da3a1005ea23">
|
||||||
|
<name>ПС_ВебСервисТабелей</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Веб-сервис табелей</value>
|
||||||
|
</synonym>
|
||||||
|
<rootURL>tabel</rootURL>
|
||||||
|
<reuseSessions>AutoUse</reuseSessions>
|
||||||
|
<sessionMaxAge>20</sessionMaxAge>
|
||||||
|
<urlTemplates uuid="67247dad-9453-41aa-8e88-2b895a5ca48a">
|
||||||
|
<name>Корневой</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Корневой URL</value>
|
||||||
|
</synonym>
|
||||||
|
<template>/index</template>
|
||||||
|
<methods uuid="dcd0c0b4-ded3-4462-a1d9-84a6a723e0fb">
|
||||||
|
<name>Главная</name>
|
||||||
|
<handler>ОбработкаГлавной</handler>
|
||||||
|
</methods>
|
||||||
|
</urlTemplates>
|
||||||
|
<urlTemplates uuid="d1885db9-af3d-4cb3-b90a-e74096076566">
|
||||||
|
<name>ТекущийПользователь</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Текущий пользователь</value>
|
||||||
|
</synonym>
|
||||||
|
<template>/me</template>
|
||||||
|
<methods uuid="692d8ffd-af43-47e0-bf4e-68ca93635e64">
|
||||||
|
<name>Получить</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>GET /me</value>
|
||||||
|
</synonym>
|
||||||
|
<handler>ОбработкаТекущегоПользователя</handler>
|
||||||
|
</methods>
|
||||||
|
</urlTemplates>
|
||||||
|
<urlTemplates uuid="779b1022-0604-4aa4-85ad-d7c59cdf9146">
|
||||||
|
<name>Подразделения</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Список подразделений</value>
|
||||||
|
</synonym>
|
||||||
|
<template>/departments</template>
|
||||||
|
<methods uuid="f4de8672-285a-416b-8936-c030453f8c3b">
|
||||||
|
<name>Получить</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>GET /departments</value>
|
||||||
|
</synonym>
|
||||||
|
<handler>ОбработкаСпискаПодразделений</handler>
|
||||||
|
</methods>
|
||||||
|
</urlTemplates>
|
||||||
|
<urlTemplates uuid="a2c66a9e-06b5-4636-bfce-f021e1b348b7">
|
||||||
|
<name>СотрудникиПодразделения</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Сотрудники подразделения</value>
|
||||||
|
</synonym>
|
||||||
|
<template>/employees</template>
|
||||||
|
<methods uuid="d784cad9-e739-4c7e-972f-96466b37c27f">
|
||||||
|
<name>Получить</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>GET /employees?dep=...</value>
|
||||||
|
</synonym>
|
||||||
|
<handler>ОбработкаСпискаСотрудников</handler>
|
||||||
|
</methods>
|
||||||
|
</urlTemplates>
|
||||||
|
<urlTemplates uuid="7bdbf8ab-d00d-4a52-8f4e-8137aab4e1cd">
|
||||||
|
<name>ВидыВремени</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Виды использования рабочего времени</value>
|
||||||
|
</synonym>
|
||||||
|
<template>/kinds</template>
|
||||||
|
<methods uuid="bb592643-a5c4-4a7c-a2cd-28a91eca8ee9">
|
||||||
|
<name>Получить</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>GET /kinds</value>
|
||||||
|
</synonym>
|
||||||
|
<handler>ОбработкаСпискаВидовВремени</handler>
|
||||||
|
</methods>
|
||||||
|
</urlTemplates>
|
||||||
|
<urlTemplates uuid="a5ceeefc-14ef-4a89-aa52-21835d58618f">
|
||||||
|
<name>ИсточникиФинансирования</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>Источники финансирования</value>
|
||||||
|
</synonym>
|
||||||
|
<template>/funds</template>
|
||||||
|
<methods uuid="8f2dfa7c-1cfe-4a3f-932e-831a52e79a42">
|
||||||
|
<name>Получить</name>
|
||||||
|
<synonym>
|
||||||
|
<key>ru</key>
|
||||||
|
<value>GET /funds</value>
|
||||||
|
</synonym>
|
||||||
|
<handler>ОбработкаСпискаИсточниковФинансирования</handler>
|
||||||
|
</methods>
|
||||||
|
</urlTemplates>
|
||||||
|
</mdclass:HTTPService>
|
||||||
Submodule
+1
Submodule Учет родительской платы added at d21b4cc635
Reference in New Issue
Block a user