[Модуль] Simple Calendar (app_calendar)

Разработка дополнительных модулей, подключение различных приложений.

Модератор: immortal

Logrus
Сообщения: 2087
Зарегистрирован: Пт апр 07, 2017 12:20 pm
Благодарил (а): 313 раз
Поблагодарили: 458 раз

Re: Календарь/менеджер задач

Сообщение Logrus » Пн мар 26, 2018 5:05 am

он последнюю версию модуля правил по тому что ранее на страницах описано (это не нужно все уже в модуле на маркете), вот и ошибки
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
Аватара пользователя
webms
Сообщения: 498
Зарегистрирован: Чт дек 15, 2016 3:13 am
Благодарил (а): 221 раз
Поблагодарили: 88 раз

Re: Календарь/менеджер задач

Сообщение webms » Пн мар 26, 2018 11:49 am

Немного измененный код вызова озвучки задач. Все работает

Сценарий: sayDela

Код: Выделить всё

function dayss($day)
{
  $a = substr($day, strlen($day) - 1, 1);
  if ($a == 1) $str = "день";
  if ($a == 2 || $a == 3 || $a == 4) $str = "дня";
  if ($a == 5 || $a == 6 || $a == 7 || $a == 8 || $a == 9 || $a == 0) $str = "дней";
  return $str;
}

if (!empty($params['PropushhennyeDela'])) {
  $stateOff = $params['PropushhennyeDela'];
}
else {
  $stateOff = "";
}

if (file_exists('./modules/app_calendar/app_calendar.class.php'))
{
  include_once('./modules/app_calendar/app_calendar.class.php');
  $calendar = new app_calendar();
  $calendar -> usual($out);
  $events = $out['EVENTS_TODAY'];
  $say_phrase = '';
  if ($events)
  {
    $tasks = '';
    $cals = '';
    $i = 0;
    $j = 0;
    foreach($events as $ev)
    {
      if ($ev['IS_TASK'] == 1 and $ev['IS_DONE'] == 0)
      {
        $i++;
        $tasks.= $i.'. '.$ev['TITLE'].'. ';
      }
      else
      {
        $j++;
        $cals.= $j.'. '.$ev['TITLE'].'. ';
      }
    }
    if ($i != 0) $say_phrase.= "У вас на сегодня запланированы задачи, ".$tasks;
    if ($j != 0) $say_phrase.= "Сегодняшние события, ".$cals;
  }
  if ($stateOff != 'OFF') { //вызывается параметром, если ничего не пришло - будет говорить. 
    $events = $out['CALENDAR_CATEGORIES'];
    $i = 0;
    $tasks = '';
    if ($events)
    {
      foreach($events as $category)
      {
        $events_past = $category['EVENTS_PAST'];
        if ($events_past)
        {
          $tasks.= 'из категории: ' . $category['TITLE'] . '. '; //Если нужно перед пропущенными задачами указывать категорию   
          foreach($events_past as $ev)
          {
            $i++;
            $tasks.= $i.'. '.$ev['TITLE'].'. ';
          }
        }
      }
      if ($i != 0) $say_phrase.= " Напоминаю пропущенные задачи, ".$tasks;
    }
  }
  $events = $out['EVENTS_PASTPLAN'];
  if ($events[0]['TITLE'])
  {
    $say_phrase.= "Напоминаю что";
    $total_tasks = count($events);
    for ($i = 0; $i < $total_tasks; $i++)
    {
      $datetime1 = date_create($events[$i]['DUE']);
      $datetime2 = date_create(date('Y-m-d'));
      $timeRASCHET = date_diff($datetime1, $datetime2);
      $say_phrase.= " через ".$timeRASCHET -> days." ".dayss($timeRASCHET -> days)." ".$events[$i]['TITLE'].". ";
    }
  }
}
if ($say_phrase)
{
  sleep(2);
  echo $say_phrase;
  //rs('DemoSay', $say_phrase); //Алиса говорит, но в чат не пишет.
  //say($say_phrase,3);
}
 
Если НЕ нужно говорить пропущенные дела, то вызываем (я например утром не хочу слушать пропущенные, только сегодняшние ближайшие на три дня)

Код: Выделить всё

rs("sayDela",array("PropushhennyeDela"=>"OFF")); 
За это сообщение автора webms поблагодарил:
odinvolk (Пн мар 26, 2018 12:46 pm)
Рейтинг: 1.16%
fandaymon
Сообщения: 1555
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 39 раз
Поблагодарили: 574 раза

Re: Календарь/менеджер задач

Сообщение fandaymon » Пн мар 26, 2018 2:24 pm

Кстати - $timeRASCHET не нужен, селект же возвращает AGE, где как раз и хранится сколько дней осталось до задачи
Можно написать просто так:

Код: Выделить всё

 if ($events)
  {
    $say_phrase.= "Напоминаю что";
    foreach ($events as $tasks) 
    {
      $say_phrase.= " через ".  $tasks['AGE'] ." ".dayss($tasks['AGE'])." ".$tasks['TITLE'].". ";
    }
  } 
И повторюсь - если интересны только задачи, то в calendar.class надо вписать так

Код: Выделить всё

 $events_pastplan=SQLSelect("SELECT *, (TO_DAYS(DUE)-TO_DAYS(NOW())) as AGE FROM calendar_events WHERE (TO_DAYS(DUE)>TO_DAYS(NOW()) AND (TO_DAYS(DUE)-TO_DAYS(NOW())<=3) AND IS_DONE=0 AND IS_TASK=1) ORDER BY AGE");
  if ($events_pastplan) {
   $out['EVENTS_PASTPLAN']=$events_pastplan;
  }  
если же интересует ещё и категория задач, то

Код: Выделить всё

 $events_pastplan=SQLSelect("SELECT *, (TO_DAYS(DUE)-TO_DAYS(NOW())) as AGE,calendar_categories.TITLE as CATEGORY FROM calendar_events LEFT JOIN calendar_categories ON calendar_events.CALENDAR_CATEGORY_ID=calendar_categories.ID WHERE (TO_DAYS(DUE)>TO_DAYS(NOW()) AND (TO_DAYS(DUE)-TO_DAYS(NOW())<=3) AND IS_DONE=0 AND IS_TASK=1) ORDER BY calendar_categories.TITLE,AGE");
  if ($events_pastplan) {
   $out['EVENTS_PASTPLAN']=$events_pastplan;
  }  
Тогда можно добавить вывод категорий

Код: Выделить всё

 if ($events)
  {
    $say_phrase.= "Напоминаю что";
    $category='';
    foreach ($events as $tasks) 
    {
      if ($category!=$tasks['CATEGORY']) {
       $category=$tasks['CATEGORY'];
       $say_phrase.=" в категории " . $category;
      }
      $say_phrase.= " через ".  $tasks['AGE'] ." ".dayss($tasks['AGE'])." ".$tasks['TITLE'].". ";
    }
  } 
За это сообщение автора fandaymon поблагодарил:
webms (Пн мар 26, 2018 3:27 pm)
Рейтинг: 1.16%
Аватара пользователя
webms
Сообщения: 498
Зарегистрирован: Чт дек 15, 2016 3:13 am
Благодарил (а): 221 раз
Поблагодарили: 88 раз

Re: Календарь/менеджер задач

Сообщение webms » Пн мар 26, 2018 3:41 pm

fandaymon, очередное спасибо)
Pull requests отправил Сергею, но только убрал условие произносить только будущие задачи, не понимаю зачем это нужно (ведь события тоже нужно озвучивать :), например из категории ДР)
fandaymon
Сообщения: 1555
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 39 раз
Поблагодарили: 574 раза

Re: Календарь/менеджер задач

Сообщение fandaymon » Пн мар 26, 2018 4:41 pm

webms писал(а):fandaymon, очередное спасибо)
Pull requests отправил Сергею, но только убрал условие произносить только будущие задачи, не понимаю зачем это нужно (ведь события тоже нужно озвучивать :), например из категории ДР)
ДР в PAST_PLAN не попадёт, так как это повторяющееся событие и DUE там может быть любого года. Если мы, например вносили Новый Год в прошлом году, то в таблице будет запись с DUE='2017-01-01',IS_REPEATING=1,REPEAT_TYPE=1.

Если стоит задача озвучивать и то и другое, то есть же EVENTS_SOON. Туда попадают все будущие задачи и события, в диапазоне который задаётся в Настройках модуля. Работать с ними так же, как с EVENTS_PAST. И функция dayss тогда не нужна, потому что в массиве уже есть поле DAYS.

Код: Выделить всё

    $events = $out['CALENDAR_CATEGORIES'];
    $tasks = '';
    if ($events)
    {
      foreach($events as $category)
      {
        $say_phrase.= "Напоминаю что";
        $events_soon= $category['EVENTS_SOON'];
        if ($events_soon)
        {
          $say_phrase.= 'в категории: ' . $category['TITLE'] . '. '; //Если нужно перед пропущенными задачами указывать категорию   
          foreach($events_soon as $ev)
          {
            $say_phrase.= " через ".  $ev['AGE'] ." ". $ev['DAYS'] ." ".$ev['TITLE'].". ";
          }
        }
      }
fandaymon
Сообщения: 1555
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 39 раз
Поблагодарили: 574 раза

Re: Календарь/менеджер задач

Сообщение fandaymon » Пн мар 26, 2018 6:31 pm

Наверное стоило всё-таки расписать как в этом модуле хранятся данные и что именно выдаёт функция usual

Все записи в календаре делятся на задачи (IS_TASK=1) и события (IS_TASK=0). Отличие задачи от события в том, что она может быть сделана.
И события и задачи бывают одноразовыми (IS_REPEATING=0) и повторяющимися (IS_REPEATING=1)
Одноразовое событие просто наступает в дату, указанную в поле DUE. Одноразовая задача может быть выполнена - IS_DONE становится равным 1 и в DONE_WHEN заносится дата, когда она выполнилась.
С повторяющимися событиями и задачами сложнее. В зависимости от REPEAT_TYPE событие повторяется ежегодно (1), ежемесячно (2) или еженедельно (3). В DUE заносится дата первого наступления события, а дальше при проверках (например мы отбираем сегодняшние события EVENTS_TODAY для того, чтобы вывести их в календарик) проверяются

REPEAT_TYPE=1 день и месяц DUE
REPEAT_TYPE=2 день DUE
REPEAT_TYPE=3 день недели DUE

С многоразовыми задачами ещё сложнее - у них IS_DONE всегда будет равен 0 (т.е. задача не выполнена). Просто когда мы нажимаем на крестик выполнить, в поле DONE_WHEN пишется текущая дата, в LOG добавляется что задача была выполнена такого-то числа и к текущему DUE добавляется

REPEAT_TYPE=1 год
REPEAT_TYPE=2 31 день и в полученной дате день меняется на тот же день что и был в DUE
REPEAT_TYPE=3 7 дней

Ежемесячные задачи забитые например на 31 будут изменятся неочевидным образом - после 31 января будет 31 марта...

Далее - что же делает функция usual? Она подготавливает 4 блока для вывода календаря

EVENTS_TODAY - здесь события и невыполненные задачи на сегодня, как одноразовые, так и повторяющиеся.
EVENTS_TODAY['TITLE'] - название задачи/события
EVENTS_TODAY['IS_TASK'] - это задача (1) или событие (0)
EVENTS_TODAY['IS_REPEATING'] - оно повторяющееся (1) или одноразовое (0)
EVENTS_TODAY['CALENDAR_CATEGORY'_ID] - id (число) категории. Если оно равно 0, значит у события/задачи нет категории
EVENTS_TODAY['ICON'] - название файла с иконкой категории
EVENTS_TODAY['USER_ID'] - это событие/задача для всех (0) или для конкретного пользователя (>0)


RECENTLY_DONE - если в настройках модуля стоит Показывать недавно выполненные задачи, то в этом блоке будут они. Недавно выполненные это значит в DONE_WHEN вчерашняя или сегодняшняя дата.
Поля тут будут те же самые что и выше, кроме ICON

И наконец блок CALENDAR_CATEGORIES в котором все категории событий и задач. У каждой категории свой блок EVENTS_PAST и EVENTS_SOON. Поэтому для того чтобы вывести все случившиеся недавно события нам нужны 2 цикла. Один переберает все категории, а второй, внутри первого, перебирает все задачи из блока EVENTS_PAST

Код: Выделить всё

   $events = $out['CALENDAR_CATEGORIES']; // в массиве $events у нас все категории

    if ($events) {  // проверяем есть ли у нас какие-нибудь категории
      foreach($events as $category) { // если есть, то открываем цикл и заносим в массив $category все что относится к текущей категории
        // в $category у нас будет (ID=>1,TITLE=>'1 категория'..., EVENTS_PAST=>array(задачи относящиеся к 1 категории))
        $events_past= $category['EVENTS_PAST']; // в массив $event_past заносим блок EVENTS_PAST относящийся к текущей категории
        if ($events_past) { //проверяем есть ли там что-нибудь
         foreach($events_past as $ev) { // если есть, то открываем цикл и заносим в массив $ev одну запись из блока EVENTS_PAST
            //$ev['AGE'] - количество дней от DUE до текущей даты
            //$ev['DAYS'] - слово дней, согласованное с AGE
           //$ev['TITLE'] - название задачи
           //$ev['DUE'] - когда она должна была быть сделана
           //$category['TITLE'] - название категории
           //$category['ICON'] - иконка категории
          }
        }
      }
В EVENTS_PAST попадаю несделанные просроченные задачи, т.е. IS_TASK=1 and IS_DONE=0 and DUE<текущей даты

В EVENTS_SOON не сделанные задачи и события DUE которых больше текущей даты, но меньше чем текущая дата + кол-во дней указанное в настройках модуля
За это сообщение автора fandaymon поблагодарили (всего 2):
Logrus (Пн мар 26, 2018 6:38 pm) • webms (Пн мар 26, 2018 9:49 pm)
Рейтинг: 2.33%
Logrus
Сообщения: 2087
Зарегистрирован: Пт апр 07, 2017 12:20 pm
Благодарил (а): 313 раз
Поблагодарили: 458 раз

Re: Календарь/менеджер задач

Сообщение Logrus » Вс апр 01, 2018 1:13 am

OperationalModes - TaskExistMode
https://connect.smartliving.ru/profile/57/objects.html
(автор, хз, вроде , видел в ветке про камень и что-то с Гарри Поттером)
с озвучкой совместить (у Багира вроде б тырил в modeChanged свич касе и туда озвучку?)
Последний раз редактировалось Logrus Вс апр 01, 2018 1:50 am, всего редактировалось 1 раз.
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
Jilber
Сообщения: 686
Зарегистрирован: Ср май 03, 2017 7:41 pm
Благодарил (а): 113 раз
Поблагодарили: 107 раз

Re: Календарь/менеджер задач

Сообщение Jilber » Вс апр 01, 2018 1:25 am

Не этот Гарри Поттер (на скрине) ?
Logrus
Сообщения: 2087
Зарегистрирован: Пт апр 07, 2017 12:20 pm
Благодарил (а): 313 раз
Поблагодарили: 458 раз

Re: Календарь/менеджер задач

Сообщение Logrus » Вс апр 01, 2018 1:47 am

viewtopic.php?f=5&t=34#p7324 ага, автор нашелся, aka msh555 )))
не-е, но не суть как индикацию обозвать (сама идея и реализация, ну дальнейшее применение/использование интересны)
Telegram | Блог
Raspberry Pi3, с образа от Сергея 3.31, PHP 7, флешка 16 Гб работает с 10.09.2017
Почти всё время уходит на исправление ошибок, оставшееся - на их повторение. (с) ))) Спасибо
fandaymon
Сообщения: 1555
Зарегистрирован: Сб янв 13, 2018 5:00 pm
Благодарил (а): 39 раз
Поблагодарили: 574 раза

Re: Календарь/менеджер задач

Сообщение fandaymon » Вс апр 01, 2018 6:26 am

Logrus писал(а):viewtopic.php?f=5&t=34#p7324 ага, автор нашелся, aka msh555 )))
не-е, но не суть как индикацию обозвать (сама идея и реализация, ну дальнейшее применение/использование интересны)
А зачем такие сложности с подключением модуля календаря и кучей циклов для того чтобы выяснить есть ли не выполненные задачи?!

Код: Выделить всё

$rec=SQLSelectOne("select id from calendar_events where IS_TASK=1 and IS_DONE=0 and  TO_DAYS(DUE)<=TO_DAYS(NOW())");
if $rec {
 echo 'Есть не выполненные задания'; \\ включаем лампочку
} 
Если пользователей несколько то можно в select добавить проверку на пользователя или категорию. 4 строчки и делают тоже самое. Добавляем их в часовой цикл и проверяем в момент, когда меняется дата.

В модуль календаря в функцию task_done в конце добавляем эти же 4 строчки и в случае необходимости выключаем лампочку

И примерно тоже самое в функцию добавления таска - для включения лампы в случае добавления таска на сегодня или прошлое
И в функцию удаления таска

Нет смысла проверять что-то каждую минуту - с точки зрения расхода ресурсов лучше добавить проверки в местах изменения
Ответить