Итак, есть xlsx файл со списком задач. Из него можно узнать
- TITLE
- DESCRIPTION
- RESPONSIBLE_ID
- CREATED_BY
- START_DATE_PLAN
- END_DATE_PLAN
Сегодня:
- загружаем файл без перезагрузки страницы
- обрабатываем xlsx файл с помощью
- добавляем свои свойства к задачам
- добавляем задачи в базу КП по конкретным группам
FormData
Я уже где-то упоминала что не помню как работать с обычными формами, поэтому всё делаю на аджаксе. У меня так быстрее получается. Самой большой проблемой тут виделось скачивание файла и отправка его серверу без перезагрузки страницы. Недолгое гугление выдало мне FormData, что и было использовано.
Да, это не поддерживается "неновыми" браузерами, но у меня не стояло задачи написать универсальный инструмент для всех.
Итак, пишем обработчик клика по кнопочке, который и будет запускать всё действо.
$(document).ready(function() { $('#btn_send_form').click(function(event) { //b_PS - это айдишка поля для показа статуса $("#b_PS").empty().append('<img src="loading.gif">'); //это "чтобы крутилось" пока скрипт выполняется var fd = new FormData(); //то что нам надо! //PS - это айдишка инпута типа файл, от которого и берём инфу fd.append('file', $('#PS')[0].files[0]); //добавляем туда нужные поля - файл fd.append('action', 'import_tasks'); //и поле для указания аджакс скрипту что делать то ) $.ajax({ url : 'ajax_import.php', type: 'POST', data : fd, processData: false, //вот это облизательно! contentType: false, success:function(data, textStatus, jqXHR){ $("#b_PS").empty().append(data); //чистим крутилку и добавляем ответ от обработчика } }); event.preventDefault(); //на всякий случай }); }); //ну и добавляем строчечку для неандертальцев if(!window.FormData) { document.write("<span style="color:red">Ваш браузер не поддерживается этим скриптом</span>"); |
XLSXReader
Эта замечательная библиотечка позволяет нам считывать содержимое xlsx файла. Даже со всех содержащихся там листов. Так как всяких извращений типа графиков и формул задачи не содержат, то спокойно используем этого клопа для нашей работы.
Для дальнейшего использования была накарябана функция, которая на вход получает путь к файлу и возвращает нам массив с построчными данными, содержащимися в импортируемом файле. Так как первая строка содержит названия столбцов, то было решено привести массив в ассоциативный вид, где индексами будут названия столбцов, а значениями - соответственно построчное содержимое.
Замечание: даты в xlsx содержатся в каком-то своём формате, соответственно надо их переработать в человеческий вид. Библиотека XLSXReader предоставляет для этого метод, который и используется.
* string $filename - полный путь к файлу
* array $date_indexes - массив с индексами столбцов, где содержится дата (см. код)
function read_xlsx($filename, $date_indexes = array()) { //начинаем обработку икселя $xlsx = new XLSXReader($filename); //имена листов (мы юзаем например первый) $sheetNames = $xlsx->getSheetNames(); //полная инфа с листа $sheetData = $xlsx->getSheetData($sheetNames[1]); //перерабатываем инфу в нужный вид $arData = array(); $first_row = array(); foreach($sheetData as $key=>$row) { //запоминаем первую строку и будем использовать её как индексы if (!count($first_row)) { $first_row = $row; continue; } //формируем нужную строку-массив $arrow = array(); foreach($row as $rowkey=>$value) { $index = $first_row[$rowkey]; //если заданы индексы для дат, то преобразовываем их из формата // экселя в формат человеческой даты if (in_array($rowkey, $date_indexes) && is_numeric($value)) $value = date('d.m.Y', XLSXReader::toUnixTimeStamp($value)); $arrow[$index] = $value; } $arData[$key] = $arrow; } return $arData; } |
Собственно, в скрипте обработчике фукнция вызывается вот так:
$file_array = read_xlsx($_FILES['file']['tmp_name']); |
Пользовательские свойства задач
Идём Настройки -- Настройки продукта -- Пользовательские поля
Добавляем новое свойство. Для того, чтобы оно принадлежало задаче надо задать поле Объект в TASKS_TASK, например вот так
Таким образом это поле будет принадлежать задаче и спрашиваться при её добавлении и, если заполнено, то отображаться при просмотре.
Группа задачи
Для того, чтобы в списке задач была сортировка по группам, к задаче надо добавлять группу. Это делается при добавлении задачи указанием поля GROUP_ID
Но у нас в документе были указаны только названия групп, без айдишек. Дабы не добавлять работы операторам по поиску нужных айдишек групп сделаем это сами. А если группа по имени не найдена, пропускаем эту строку и записываем в отчёт как ошибку.
Для этого сначала считываем все группы, которые существуют в портале. А затем по имени находим айдишку. Собственно всё =)
//собираем группы if (!CModule::IncludeModule("socialnetwork")) die('<b style="color:red">module socialnetwork problem</b>'); $arGroups = array(); $hGroups = CSocNetGroup::GetList( array("ID" => "DESC"), array('ACTIVE'=>'Y'), false, false, array('ID', 'NAME') ); while($row = $hGroups->Fetch()) $arGroups[$row['NAME']] = $row['ID']; |
Добавление задачи
Использую старый класс CTasks, ибо новый у меня так и не взлетел. Может, у меня руки кривые, а может я слишком ленивая чтобы разбираться.
Собираем поля, нужные для создания задачи:
- RESPONSIBLE_ID - айдишка ответственного
- CREATED_BY - айдишка постановщика задачи
- UF_TASK_TP_ADRES - наше пользовательское поле. у нас тут адрес.
- GROUP_ID - айдишка соц.группы
- TITLE - название задачи
- DESCRIPTION - описание задачи
- START_DATE_PLAN - дата начала
- END_DATE_PLAN - дата окончания
if (!CModule::IncludeModule("tasks")) die('<b style="color:red">module tasks problem</b>'); $ctio = new CTasks; //создаём задачу $task_ID = $ctio->Add($arTaskFields); |
Добавляем немного кода с обработками ошибок и - готово!