Не могу создать одинаковые слоты в mod_scheduler

Не могу создать одинаковые слоты в mod_scheduler

от Mikhail Apakin -
Количество ответов: 10

Добрый день.

Есть плагин mod_scheduler сиречь Расписание.

Есть преподаватель, который одновременно хочет еженедельно проводить консультации в двух разных курсах.

Заходит он в один курс, создаёт элемент Расписание и пишет, что, мол, хочу каждую субботу проводить встречу. Параметры расписания см. в аттаче. Всё хорошо, создаются встречи каждую субботу с 12 до 14. 

Идёт преподаватель в другой свой курс, создаёт элемент Расписание и пишет, что, мол, хочу каждую субботу проводить встречу. Параметры расписания см. в аттаче. А ему в ответ — «Can not find data record in database table scheduler_slots». Причём это именно если создавать повторяющиеся интервалы. Если делать по одному — всё в порядке. 

Кто-нибудь сталкивался? Куды бечь? Я попробую написать автору плагина, конечно, но не уверен в результате.

Спасибо.

Приложение shedule.jpg
В ответ на Mikhail Apakin

Re: Не могу создать одинаковые слоты в mod_scheduler

от Vadim Tabunshchik -
Изображение пользователя Developers
Заходит он в один курс, создаёт элемент Расписание и пишет, что, мол, хочу каждую субботу проводить встречу.
Идёт преподаватель в другой свой курс, создаёт элемент Расписание и пишет, что, мол, хочу каждую субботу проводить встречу.

И что, в обоих курсах встречи с 12.00 до 14.00? А смысл? «Фигаро здесь, Фигаро там...»©

Модуль в такой ситуации предупреждение выводит, что есть «Пересекающиеся промежутки времени». Пр отсутствующую запись в БД ничего не слышал. А версию модуля какую используете?

В ответ на Vadim Tabunshchik

Re: Не могу создать одинаковые слоты в mod_scheduler

от Mikhail Apakin -

Да, смысл именно в этом. Там два похожих курса и ему проще проводить встречу вместе.

Moodle 2.7.9 (умоляю, ничего не говорите про обновление!), шедулер 2.7.2 (2014090104).

Если руками создавать встречи, всё в порядке. Делает и не ругается.

В ответ на Mikhail Apakin

Re: Не могу создать одинаковые слоты в mod_scheduler

от Vadim Tabunshchik -
Изображение пользователя Developers
Moodle 2.7.9 (умоляю, ничего не говорите про обновление!)

Молчу улыбаюсь

Есть 2.7.10, установил шедулер 2.7.2 (2014090104), всё работает как положено. Ошибок «Can not find data record in database table scheduler_slots» не встречал.

  1. обновите перевод, у вас половина на английском, а модуль уже весь переведен на русский.
  2. на скрине Teacher - Администратор Пользователь. Вы под админом создаете расписание или Админ назначен преподавателем в курс? Если нет препода в курсе, модуль предупреждение выводит и интервалы не создает.
  3. Если руками создавать встречи, всё в порядке - А как «не руками» можно создавать встречи? Я импорта расписания не нашел, только выгрузить можно.
В ответ на Vadim Tabunshchik

Re: Не могу создать одинаковые слоты в mod_scheduler

от Mikhail Apakin -
обновите перевод, у вас половина на английском, а модуль уже весь переведен на русский.

Это просто интерфейс системы английский, мне так привычнее.

на скрине Teacher - Администратор Пользователь. Вы под админом создаете расписание или Админ назначен преподавателем в курс?
Если нет препода в курсе, модуль предупреждение выводит и интервалы не создает.

Да, Администратор Пользователь записан на этот курс как преподаватель.

А как «не руками» можно создавать встречи? Я импорта расписания не нашел, только выгрузить можно.

Можно сделать один слот, а можно повторяющийся. Если делать по одному, всё норм. Если делать повторяющийся, вылезает вот это.

Я в песочнице включил отладку и отображение ошибок, в общем, в развёрнутом виде ошибка выглядит вот так:

Не удается найти данную запись в таблице scheduler_slots базы данных.
Подробнее об этой ошибке
Debug info: SELECT * FROM {scheduler_slots} WHERE id = ? AND schedulerid = ?
[array (
0 => '44',
1 => '2',
)]
Error code: invalidrecord
Stack trace:
line 1451 of /lib/dml/moodle_database.php: dml_missing_record_exception thrown
line 1427 of /lib/dml/moodle_database.php: call to moodle_database->get_record_select()
line 287 of /mod/scheduler/model/scheduler_instance.php: call to moodle_database->get_record()
line 93 of /mod/scheduler/teacherview.controller.php: call to scheduler_instance->get_slot()
line 217 of /mod/scheduler/teacherview.php: call to scheduler_action_doaddsession()
line 87 of /mod/scheduler/view.php: call to include()

В ответ на Mikhail Apakin

Re: Не могу создать одинаковые слоты в mod_scheduler

от Vadim Tabunshchik -
Изображение пользователя Developers

По первым трем пунктам всё понятно. улыбаюсь

По ошибке тоже понятно, не может найти запись в базе данных, хотя она существует, если во втором курсе создан модуль. Но на этапе добавления повторяющихся промежутков времени выскакивает ошибка Debug info

У меня, наконец-то, получилось воспроизвести эту ошибку. Ковыряние в коде привело вот к этому фрагменту в файле teacherview.controller.php:

            while ($slot->starttime <= $data->timeend - $slot->duration * 60) {
                $conflicts = scheduler_get_conflicts($scheduler->id, $data->timestart, $data->timestart + $slot->duration * 60, $data->teacherid, 0, SCHEDULER_ALL, false);
                if ($conflicts) {
                    if (!$data->forcewhenoverlap) {
                        print_string('conflictingslots', 'scheduler');
                        echo '<ul>';
                        foreach ($conflicts as $aconflict) {
                            $sql = 'SELECT c.fullname, c.shortname, s.name as schedname, sl.starttime '
                                    .'FROM {course} c, {scheduler} s, {scheduler_slots} sl '
                                    .'WHERE s.course = c.id AND sl.schedulerid = s.id AND sl.id = :conflictid';
                            $conflictinfo = $DB->get_record_sql($sql, array('conflictid' => $aconflict->id));
                            $msg = $output->userdate($conflictinfo->starttime) . ', ' . $output->usertime($conflictinfo->starttime) . ': ';
                            $msg .= s($conflictinfo->schedname). ' '.get_string('incourse', 'scheduler') . ' ';
                            $msg .= $conflictinfo->shortname . ' - ' . $conflictinfo->fullname;
                            echo html_writer::tag('li', $msg);
                        }
                        echo '</ul><br/>';
                    } else { // we force, so delete all conflicting before inserting
                        foreach ($conflicts as $conflict) {
                            $cslot = $scheduler->get_slot($conflict->id);
                            $cslot->delete();
                        }
                    }
                }
                if (!$conflicts || $data->forcewhenoverlap) {
                    $DB->insert_record('scheduler_slots', $slot, false, true);
                    $countslots++;
                }
                $slot->starttime += ($slot->duration + $data->break) * 60;
                $data->timestart += ($slot->duration + $data->break) * 60;

scheduler_get_conflicts выводит все конфликты - совпадающие по времени промежутки. Дальше, если есть конфликты if ($conflicts), проверяем включено ли принудительное добавление if (!$data->forcewhenoverlap) и выводим список конфликтов print_string и echo, после чего } else {// we force, so delete all conflicting before inserting удаляем слоты $cslot->delete() и только после этих манипуляций при условии, что нет конфликтов или включено принудительное добавление if (!$conflicts || $data->forcewhenoverlap) добавляем слоты $DB->insert_record.

Имхо, тут логика нарушена. Ну, вывели, что есть конфликты, но принудиловка то отключена !$data->forcewhenoverlap, и что мы будем удалять? Слоты то не добавлены.

Я думаю должно быть так: если нет конфликтов или включено прнудительное добавление, то слоты добавляем принудительно. Во всех остальных случаях выводим список конфликтов, удаляем (если есть что удалять), выводим сообщение и т. д.

Попробуйте это кусок кода заменить на нижеследующий и поэкспериментировать. Потом «доложите» улыбаюсь

            while ($slot->starttime <= $data->timeend - $slot->duration * 60) {
                $conflicts = scheduler_get_conflicts($scheduler->id, $data->timestart, $data->timestart + $slot->duration * 60, $data->teacherid, 0, SCHEDULER_ALL, false);
                if (!$conflicts || $data->forcewhenoverlap) {
                    $DB->insert_record('scheduler_slots', $slot, false, true);
                    $countslots++;
                } else {
                    if (!$data->forcewhenoverlap) {
                        print_string('conflictingslots', 'scheduler');
                        echo '<ul>';
                        foreach ($conflicts as $aconflict) {
                            $sql = 'SELECT c.fullname, c.shortname, s.name as schedname, sl.starttime '
                                    .'FROM {course} c, {scheduler} s, {scheduler_slots} sl '
                                    .'WHERE s.course = c.id AND sl.schedulerid = s.id AND sl.id = :conflictid';
                            $conflictinfo = $DB->get_record_sql($sql, array('conflictid' => $aconflict->id));
                            $msg = $output->userdate($conflictinfo->starttime) . ', ' . $output->usertime($conflictinfo->starttime) . ': ';
                            $msg .= s($conflictinfo->schedname). ' '.get_string('incourse', 'scheduler') . ' ';
                            $msg .= $conflictinfo->shortname . ' - ' . $conflictinfo->fullname;
                            echo html_writer::tag('li', $msg);
                        }
                        echo '</ul><br/>';
                    } else { // we force, so delete all conflicting before inserting
                        foreach ($conflicts as $conflict) {
                            $cslot = $scheduler->get_slot($conflict->id);
                            $cslot->delete();
                        }
                    }
                }
                $slot->starttime += ($slot->duration + $data->break) * 60;
                $data->timestart += ($slot->duration + $data->break) * 60;

С таким кодом у меня ошибки не было (может потом будет улыбаюсь)

Вот без включения принудительного добавления (forcewhenoverlap установлен в NO):
002

А это при включении forcewhenoverlap:
site

ЗЫ: это баг и нужно писать разработчику плагина.

В ответ на Vadim Tabunshchik

Re: Не могу создать одинаковые слоты в mod_scheduler

от Mikhail Apakin -

Отлично, спасибо большое, теперь всё правильно.

При отключенном Force when overlap теперь создаётся 0 слотов

Force when overlap off

При включённом слоты создаются без проблем.

Force when overlap on

Ещё раз спасибо за помощь.

В ответ на Mikhail Apakin

Re: Не могу создать одинаковые слоты в mod_scheduler

от Vadim Tabunshchik -
Изображение пользователя Developers

Михаил, не торопитесь, я косяк нашел в своих исправлениях. Если добавлять одиночные записи, совпадающие с уже существующими, то они без времени начала и окончания в таблице при просмотре.

Проглядел, нужно строки

                $slot->starttime += ($slot->duration + $data->break) * 60;
                $data->timestart += ($slot->duration + $data->break) * 60;

поднять выше в кейс if (!$conflicts || $data->forcewhenoverlap), т. е. верхняя часть кода будет такая:

while ($slot->starttime <= $data->timeend - $slot->duration * 60) {
                $conflicts = scheduler_get_conflicts($scheduler->id, $data->timestart, $data->timestart + $slot->duration * 60, $data->teacherid, 0, SCHEDULER_ALL, false);
                if (!$conflicts || $data->forcewhenoverlap) {
                    $DB->insert_record('scheduler_slots', $slot, false, true);
                    $countslots++;
                $slot->starttime += ($slot->duration + $data->break) * 60;
                $data->timestart += ($slot->duration + $data->break) * 60;
                } else {
                    if (!$data->forcewhenoverlap) {

Насколько я понял, проблема в запросе SQL, идет выборка записей из таблицы {scheduler_slots} записей, конфликтующих с уже добавленным расписанием из другого курса, но всё дело в том, что записи для текущего курса ещё не добавлены, записи с sl.schedulerid, соответствующие встрече этого курса отсутствуют.

В ответ на Vadim Tabunshchik

Re: Не могу создать одинаковые слоты в mod_scheduler

от Mikhail Apakin -

Хм, странно. У меня ничего не изменилось по сравнению с первой версией вашего кода.

http://apakin.net/shots5/2017-06-06_13-30-55.jpg

Более того, я попробовал эти строчки поставить даже перед проверкой на конфликт, пофиг. Почему-то он не показывает при повторе. В какой момент это происходит, я не понял пока.

В ответ на Mikhail Apakin

Re: Не могу создать одинаковые слоты в mod_scheduler

от Vadim Tabunshchik -
Изображение пользователя Developers

Да я уже вчера весь мосх себе вынес, разбираясь с этим фрагментом. Можно оставить мой первоначальный вариант. Всё равно все глюки не побороть. Я глянул версию модуля для 3.3, вот там уже сделано по человечески, добавлен контроллер для отслеживания совпадающих записей, удаление (с предупреждением) повторяющихся, чтобы не было пустых строк, о кот. я говорил, и их видно на вашем скрине.

И, думаю, повторяющиеся одинаковые записи не будут создаваться в БД, ка на вашем последнем скрине. В модуле для 2.8 есть такой глюк - при создании абсолютно одиноковой записи в БД остаются обе (старая и новая), а на страницу выводится только новая.

И писать в баг-трекер бесполезно, старые версии никто «ремонтировать» не будет, все силы брошены на 3.3 улыбаюсь