<?php
namespace factory;
class Projects
{
  static public function projects_list()
  {
    global $mdb;

    return $mdb -> select( 'project', '*', [ 'ORDER' => [ 'name' => 'ASC' ] ] );
  }

  static public function count_open_subtasks( $task_id ) {
    global $mdb;

    return $mdb -> count( 'task_action', [ 'AND' => [ 'task_id' => $task_id, 'status' => null ] ] );
  }

  static public function task_text_new( $task_id, $text )
  {
    global $mdb;

    return $mdb -> insert( 'tasks_text_history', [
      'task_id' => $task_id,
      'text' => htmlspecialchars( $text ),
      'date_add' => date( 'Y-m-d H:i:s' )
    ] );
  }

  static public function task_text_update( $history_id, $text )
  {
    global $mdb;

    return $mdb -> update( 'tasks_text_history', [
      'text' => htmlspecialchars( $text )
    ], [
      'id' => $history_id
    ] );
  }

  static public function task_total_time( $task_id, $month = '' )
  {
    global $mdb;

    $seconds = 0;

    if ( $month )
    {
      $results = $mdb -> select( 'tasks_work', [ 'date_start', 'date_end' ], [ 'AND' => [ 'task_id' => $task_id, 'date_end[>=]' => $month . '-01 00:00:00', 'date_end[<=]' => $month . '-' . date( 't', strtotime( $month ) ) . ' 23:59:59' ], 'ORDER' => [ 'id' => 'ASC' ] ] );
    }
    else
      $results = $mdb -> select( 'tasks_work', [ 'date_start', 'date_end' ], [ 'AND' => [ 'task_id' => $task_id ], 'ORDER' => [ 'id' => 'ASC' ] ] );

    if ( is_array( $results ) and count( $results ) ) foreach ( $results as $row )
    {
      if ( !$row['date_end'] )
        $row['date_end'] = date( 'Y-m-d H:i:s' );

      $seconds += strtotime( $row['date_end'] ) - strtotime( $row['date_start'] );
    }
    return $seconds;
  }

  static public function send_email_task_change_status( $task_id )
  {
    $task = \factory\Projects::task_details( $task_id );

    switch( $task['status'] )
    {
      case 0:
        $status = 'nowe';
      break;
      case 1:
        $status = 'do sprawdzenia';
      break;
      case 2:
        $status = 'zamknięte';
      break;
    }

    if ( $task['status_change_mail'] )
      \S::send_email(
        'jacek.pyziak@project-pro.pl',
        'crmPRO - zmieniono status zadania',
        '<p>Witaj<br/>zmieniono status zadania <b>' . $task['name'] . ' - ' . \factory\Crm::get_client_name( (int)$task['client_id'] ) . '</b> na <b>' . $status . '</b>.</p>'
        . '<hr>'
        . html_entity_decode( $task['text'] )
      );
  }

  static public function task_order_save( $order )
  {
    global $mdb;

    $order = explode( ',', $order );

    foreach ( $order as $task )
    {
      $task = explode( ':', $task );
      $mdb -> update( 'tasks', [ 'o' => $task[1] ], [ 'id' => $task[0] ] );
    }
    return true;
  }

  public static function action_mark_as_done( $action_id )
  {
    $action = \R::load( 'task_action', $action_id );
    $action['status'] = 1;
    $action['date_complete'] = date( 'Y-m-d H:i:s' );
    return \R::store( $action );
  }

  public static function action_name( $action_id )
  {
    $action = \R::load( 'task_action', $action_id );
    return $action['name'];
  }

  public static function send_email_notification( $task_id, $user_id )
  {
    \S::send_email(
          \factory\Users::get_user_email( $user_id ),
          'crmPRO - nowe zadanie',
          '<p>Witaj<br/>przypisano Ci nowe zadanie <b>' . \factory\Projects::get_task_name( $task_id ) . '</b></p>'
        );
  }

  public static function get_task_name( $task_id )
  {
    global $mdb;
    return $mdb -> get( 'tasks', 'name', [ 'id' => $task_id ] );
  }

  public static function set_project_as_default( $user_id, $project_id )
  {
    global $mdb;
    return $mdb -> update( 'users', [ 'default_project' => $project_id ], [ 'id' => $user_id ] );
  }

  public static function task_update( $user_id, $task_id, $text ) {
    global $mdb;

    return $mdb -> update( 'tasks', [
                      'text' => htmlspecialchars( $text )
                    ], [
                      'AND' => [
                        'id' => $task_id
                      ]
                    ] );
  }

  public static function project_delete( $project_id )
  {
    global $mdb;
    return $mdb -> delete( 'project', [ 'id' => $project_id ] );
  }

  public static function project_name( $project_id )
  {
    global $mdb;
    return $mdb -> get( 'project', 'name', [ 'id' => $project_id ] );
  }

  public static function open_task( $user_id )
  {
    global $mdb;

    $task_id = $mdb -> get( 'tasks_work', 'task_id', [ 'AND' => [ 'user_id' => $user_id, 'date_end' => null ] ] );
    if ( $task_id )
    {
      return \factory\Projects::task_details( $task_id );
    }

    return false;
  }

  static public function task_change_status( $task_id, $status, $user_id )
  {
    global $mdb;

    \factory\Projects::task_end( $task_id, $user_id );

    $current_status = $mdb -> get( 'tasks', 'status', [ 'id' => $task_id ] );

    if ( $current_status == 0 and $status == 1 )
    {
      if ( $mdb -> update( 'tasks', [ 'status' => 1 ], [ 'id' => $task_id ] ) )
      {
        if ( !$mdb -> count( 'task_user', [ 'AND' => [ 'task_id' => $task_id, 'user_id' => 1 ] ] ) )
          $mdb -> insert( 'task_user', [
            'task_id' => $task_id,
            'user_id' => 1
          ] );

        \factory\Projects::send_email_task_change_status( $task_id );
        return [ 'result' => 'ok' ];
      }
    }

    if ( ( $current_status == 1 or $current_status == 0 ) and $status == 2 )
    {
      if ( $mdb -> update( 'tasks', [ 'status' => 2, 'date_complete' => date( 'Y-m-d H:i:s' ) ], [ 'id' => $task_id ] ) )
      {
        if ( !$mdb -> count( 'task_user', [ 'AND' => [ 'task_id' => $task_id, 'user_id' => 1 ] ] ) )
          $mdb -> insert( 'task_user', [
            'task_id' => $task_id,
            'user_id' => 1
          ] );

        \factory\Projects::send_email_task_change_status( $task_id );
        return [ 'result' => 'ok' ];
      }
    }

    if ( $current_status == 2 and $status == 1 )
    {
      if ( $mdb -> update( 'tasks', [ 'status' => 1, 'date_complete' => null ], [ 'id' => $task_id ] ) )
      {
        if ( !$mdb -> count( 'task_user', [ 'AND' => [ 'task_id' => $task_id, 'user_id' => 1 ] ] ) )
          $mdb -> insert( 'task_user', [
            'task_id' => $task_id,
            'user_id' => 1
          ] );

        \factory\Projects::send_email_task_change_status( $task_id );
        return [ 'result' => 'ok' ];
      }
    }

    if ( ( $current_status == 1 or $current_status == 2 ) and $status == 0 )
    {
      if ( $mdb -> update( 'tasks', [ 'status' => 0, 'date_complete' => null ], [ 'id' => $task_id ] ) )
      {
        if ( $mdb -> count( 'task_user', [ 'AND' => [ 'task_id' => $task_id, 'user_id[!]' => 1 ] ] ) )
          $mdb -> delete( 'task_user', [
            'task_id' => $task_id,
            'user_id' => 1
          ] );

        \factory\Projects::send_email_task_change_status( $task_id );
        return [ 'result' => 'ok' ];
      }
    }

    return [ 'result' => 'error' ];
  }

  public static function task_delete( $task_id )
  {
    global $mdb;

    $attachments_repository = new \Domain\Tasks\TaskAttachmentRepository( $mdb );
    $attachments_repository -> purgeByTaskId( (int)$task_id );

    return $mdb -> update( 'tasks', [ 'deleted' => 1 ], [ 'id' => $task_id ] );
  }

  public static function project_save( $project_id, $name, $users, $client_id )
  {
    global $mdb;

    if ( !$project_id )
    {
      $mdb -> insert( 'project', [
        'name' => $name,
        'client_id' => $client_id ? (int)$client_id : null
      ] );
      $id = $mdb -> id();

      /* uczestnicy */
      if ( is_array( $users ) ) foreach ( $users as $user )
      {
        $mdb -> insert( 'project_user', [
          'project_id' => (int)$id,
          'user_id' => (int)$user
        ] );
      }
      else if ( $users )
      {
        $mdb -> insert( 'project_user', [
          'project_id' => (int)$id,
          'user_id' => (int)$users
        ] );
      }

      return $id;
    }
    else
    {
      $mdb -> update( 'project', [
        'name' => $name,
        'client_id' => $client_id ? (int)$client_id : null
      ], [
        'AND' => [
          'id'  => $project_id
        ]
      ] );

      /* uczestnicy */
      $not_in = [ 0 ];

      if ( is_array( $users ) ) foreach ( $users as $user )
        $not_in[] = $user;
      else if ( $users )
        $not_in[] = $users;

      $mdb -> delete( 'project_user', [ 'AND' => [ 'project_id' => (int)$project_id, 'user_id[!]' => $not_in ] ] );

      $users_tmp = $mdb -> select( 'project_user', 'user_id', [ 'project_id' => (int)$project_id ] );

      if ( !is_array( $users ) )
        $users = [ $users ];

      $users = array_diff( $users, $users_tmp );

      if ( is_array( $users ) and !empty( $users ) ) foreach ( $users as $user )
      {
        if ( $project_id and $user )
          $mdb -> insert( 'project_user', [
                    'project_id' => (int)$project_id,
                    'user_id' => (int)$user
                  ] );
      }

      return $project_id;
    }
    return false;
  }

  public static function project_user_id( $task_id )
  {
    global $mdb;
    return $mdb -> get( 'project', 'user_id', [ 'id' => $task_id ] );
  }

  public static function task_user_id( $task_id )
  {
    global $mdb;
    return $mdb -> get( 'tasks', 'user_id', [ 'id' => $task_id ] );
  }

  public static function project_details( $project_id )
  {
    global $mdb;

    $project = $mdb -> get( 'project', '*', [ 'id' => $project_id ] );
    $project['users'] = $mdb -> select( 'project_user', 'user_id', [ 'project_id' => $project_id ] );

    return $project;
  }

  public static function tasks_without_project( $user_id )
  {
    global $mdb;
    $count = $mdb -> query( 'SELECT '
                                . 'COUNT(0) AS c '
                              . 'FROM '
                                . 'tasks AS t '
                                . 'LEFT JOIN task_user AS tu ON tu.task_id = t.id '
                              . 'WHERE '
                                . '( user_id = ' . (int)$user_id . ' OR created_by = ' . (int)$user_id . ' ) AND project_id IS NULL AND status != 1' ) -> fetchAll( \PDO::FETCH_ASSOC );
    $row['total_tasks'] = $count[0]['c'];
    return $count[0]['c'];
  }

  static public function get_project_name( $project_id )
  {
    global $mdb;
    return $mdb -> get( 'project', 'name', [ 'id' => $project_id ] );
  }

  public static function user_projects( $user_id )
  {
    global $mdb;

    $results = $mdb -> query( 'SELECT '
                                  . 'p.id, p.name, client_id '
                                . 'FROM '
                                  . 'project AS p '
                                  . 'LEFT JOIN project_user AS pu ON pu.project_id = p.id '
                                . 'WHERE '
                                  . 'user_id = ' . (int)$user_id . ' '
                                . 'ORDER BY '
                                  . 'name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
    {
      $count = $mdb -> query( 'SELECT '
                                  . 't.id '
                                . 'FROM '
                                  . 'tasks AS t '
                                  . 'LEFT JOIN task_user AS tu ON tu.task_id = t.id '
                                . 'WHERE '
                                    . '( user_id = ' . (int)$user_id . ' OR created_by = ' . (int)$user_id . ' ) AND project_id = ' . $row['id'] . ' AND ( status = 0 OR status = 5 ) AND deleted = 0 AND ( date_complete IS NULL OR date_complete > \'' . date( 'Y-m-d', strtotime( "-21 days") ) . '\' ) '
                                . 'GROUP BY t.id'
                              ) -> fetchAll( \PDO::FETCH_ASSOC );
      $row['total_tasks'] = count( $count );
      $project[] = $row;
    }
    return $project;
  }

  // nieprzypisane zadania
  static public function get_unassigned_tasks( $user_id, $project_id )
  {
    global $mdb;

    if ( $project_id === 'all' )
      $search = '';
    else if ( (int)$project_id !== 0 and $project_id )
      $search = ' AND project_id = ' . (int)$project_id;
    else
      $search = ' AND project_id IS NULL';

    $results = $mdb -> query( 'SELECT '
                                    . 't.* '
                                  . 'FROM '
                                    . 'tasks AS t  '
                                  . 'WHERE '
                                    . 'created_by = ' . (int)$user_id . ' ' . $search . ' AND t.id NOT IN ( SELECT task_id FROM task_user GROUP BY task_id ) AND deleted = 0 AND ( date_complete IS NULL OR date_complete > \'' . date( 'Y-m-d', strtotime( "-21 days") ) . '\' ) '
                                  . 'ORDER BY '
                                    . 'status ASC, o ASC, date_start IS NOT NULL DESC, date_start ASC, date_end IS NOT NULL DESC, date_end ASC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
    {
      $row['total_time'] = \factory\Projects::task_total_time( $row['id'] );
      $tasks[] = $row;
    }

    return $tasks;
  }

  // zamknięte zadania
  static public function get_closed_tasks( $user_id, $project_id )
  {
    global $mdb;

    if ( $project_id === 'all' )
      $search = '';
    else if ( (int)$project_id !== 0 and $project_id )
      $search = ' AND project_id = ' . (int)$project_id;
    else
      $search = ' AND project_id IS NULL';

    $results = $mdb -> query( 'SELECT '
                                    . 't.* '
                                  . 'FROM '
                                    . 'tasks AS t '
                                    . 'LEFT JOIN task_user  AS tu ON tu.task_id = t.id '
                                  . 'WHERE '
                                    . '(
                                          (
                                              user_id = ' . (int)$user_id . '
                                            OR
                                              created_by = ' . (int)$user_id . ' ) ' . $search . '
                                          )
                                        AND
                                          (
                                              status = 2
                                            AND
                                              date_complete > \'' . date( 'Y-m-d', strtotime( "-2 months") ) . '\'
                                          ) '
                                    . 'AND '
                                      . '( parent_id IS NULL OR parent_id IS NOT NULL AND ( SELECT status FROM tasks WHERE id = t.parent_id ) = 1 ) AND deleted = 0 '
                                  . 'GROUP BY '
                                      . 't.id '
                                  . 'ORDER BY '
                                    . 'date_complete DESC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
    {
      $row['total_time'] = \factory\Projects::task_total_time( $row['id'] );
      $row['users'] = $mdb -> select( 'task_user', 'user_id', [ 'task_id' => $row['id'] ] );
      $tasks[] = $row;
    }
    return $tasks;
  }

  // zadania do oceny
  static public function get_toreview_tasks( $user_id, $project_id )
  {
    global $mdb;

    if ( $project_id === 'all' )
      $search = '';
    else if ( (int)$project_id !== 0 and $project_id )
      $search = ' AND project_id = ' . (int)$project_id;
    else
      $search = ' AND project_id IS NULL';

    $results = $mdb -> query( 'SELECT '
                                    . 't.* '
                                  . 'FROM '
                                    . 'tasks AS t  '
                                    . 'LEFT JOIN task_user  AS tu ON tu.task_id = t.id '
                                  . 'WHERE '
                                    . '( user_id = ' . (int)$user_id . ' OR created_by = ' . (int)$user_id . ' ) ' . $search . ' AND status = 1 AND t.id IN ( SELECT task_id FROM task_user GROUP BY task_id ) AND deleted = 0 AND ( date_complete IS NULL OR date_complete > \'' . date( 'Y-m-d', strtotime( "-21 days") ) . '\' ) '
                                  . 'GROUP BY '
                                      . 't.id '
                                  . 'ORDER BY '
                                    . 'status ASC, o ASC, date_start IS NOT NULL DESC, date_start ASC, date_end IS NOT NULL DESC, date_end ASC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
    {
      $row['total_time'] = \factory\Projects::task_total_time( $row['id'] );
      $row['users'] = $mdb -> select( 'task_user', 'user_id', [ 'task_id' => $row['id'] ] );
      $tasks[] = $row;
    }

    return $tasks;
  }

  // zadania przypisane w trakcie
  static public function get_inprogress_tasks( $user_id, $project_id )
  {
    global $mdb;

    if ( $project_id === 'all' )
      $search = '';
    else if ( (int)$project_id !== 0 and $project_id )
      $search = ' AND project_id = ' . (int)$project_id;
    else
      $search = ' AND project_id IS NULL';

    if ( $user_id == 1 )
      $results = $mdb -> query( 'SELECT '
                                      . 't.* '
                                    . 'FROM '
                                      . 'tasks AS t  '
                                      . 'LEFT JOIN task_user AS tu ON tu.task_id = t.id '
                                    . 'WHERE '
                                      . '( user_id = ' . (int)$user_id . ' ) ' . $search . ' AND status = 0 AND t.id IN ( SELECT task_id FROM task_user GROUP BY task_id ) AND deleted = 0 AND ( date_complete IS NULL OR date_complete > \'' . date( 'Y-m-d', strtotime( "-21 days") ) . '\' ) '
                                    . 'GROUP BY '
                                        . 't.id '
                                    . 'ORDER BY '
                                      . 'status ASC, o ASC, date_start IS NOT NULL DESC, date_start ASC, date_end IS NOT NULL DESC, date_end ASC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    else {
      $results = $mdb -> query( 'SELECT '
                                      . 't.* '
                                    . 'FROM '
                                      . 'tasks AS t  '
                                      . 'LEFT JOIN task_user AS tu ON tu.task_id = t.id '
                                    . 'WHERE '
                                      . '( user_id = ' . (int)$user_id . ' OR created_by = ' . (int)$user_id . ' ) ' . $search . ' AND status = 0 AND t.id IN ( SELECT task_id FROM task_user GROUP BY task_id ) AND deleted = 0 AND ( date_complete IS NULL OR date_complete > \'' . date( 'Y-m-d', strtotime( "-21 days") ) . '\' ) '
                                    . 'GROUP BY '
                                        . 't.id '
                                    . 'ORDER BY '
                                      . 'status ASC, o ASC, date_start IS NOT NULL DESC, date_start ASC, date_end IS NOT NULL DESC, date_end ASC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    }
    if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
    {
      $row['total_time'] = \factory\Projects::task_total_time( $row['id'] );
      $row['users'] = $mdb -> select( 'task_user', 'user_id', [ 'task_id' => $row['id'] ] );
      $tasks[] = $row;
    }

    return $tasks;
  }

  public static function user_tasks( $user_id, $project_id = '' )
  {
    global $mdb;

    if ( $project_id === 'all' )
      $search = '';
    else if ( (int)$project_id !== 0 and $project_id )
      $search = ' AND project_id = ' . (int)$project_id;
    else
      $search = ' AND project_id IS NULL';

    if ( $project_id == 21 )
      $results = $mdb -> query( 'SELECT '
                                    . 't.* '
                                  . 'FROM '
                                    . 'tasks AS t '
                                    . 'LEFT JOIN task_user  AS tu ON tu.task_id = t.id '
                                  . 'WHERE '
                                    . '( user_id = ' . (int)$user_id . ' OR created_by = ' . (int)$user_id . ' ) ' . $search . ' AND status = 0 '
                                    . 'AND '
                                      . '( parent_id IS NULL OR parent_id IS NOT NULL AND ( SELECT status FROM tasks WHERE id = t.parent_id ) = 1 ) '
                                    . 'AND '
                                      . 'open = 1 '
                                  . 'GROUP BY '
                                      . 't.id '
                                  . 'ORDER BY '
                                    . 'status ASC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    else
      $results = $mdb -> query( 'SELECT '
                                    . 't.* '
                                  . 'FROM '
                                    . 'tasks AS t '
                                    . 'LEFT JOIN task_user  AS tu ON tu.task_id = t.id '
                                  . 'WHERE '
                                    . '( user_id = ' . (int)$user_id . ' OR created_by = ' . (int)$user_id . ' ) ' . $search . ' AND status = 0 '
                                    . 'AND '
                                      . '( parent_id IS NULL OR parent_id IS NOT NULL AND ( SELECT status FROM tasks WHERE id = t.parent_id ) = 1 ) '
                                    . 'AND '
                                      . 'open = 1 '
                                  . 'GROUP BY '
                                      . 't.id '
                                  . 'ORDER BY '
                                    . 'open DESC, status ASC, date_start IS NOT NULL DESC, date_start ASC, date_end IS NOT NULL DESC, date_end ASC, o ASC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
    {
      $row['total_time'] = \factory\Projects::task_total_time( $row['id'], $user_id );
      $row['users'] = $mdb -> select( 'task_user', 'user_id', [ 'task_id' => $row['id'] ] );
      $row['actions'] = $mdb -> select( 'task_action', '*', [ 'AND' => [ 'task_id' => $row['id'], 'OR' => [ 'date_complete' => null, 'date_complete[>=]' => date( 'Y-m-d H:i:s', strtotime( "-21 days") ) ] ], 'ORDER' => [ 'status' => 'ASC', 'id' => 'ASC' ] ] );

      $tasks[] = $row;
    }

    if ( $project_id == 21 )
      $results = $mdb -> query( 'SELECT '
                                    . 't.* '
                                  . 'FROM '
                                    . 'tasks AS t '
                                    . 'LEFT JOIN task_user  AS tu ON tu.task_id = t.id '
                                  . 'WHERE '
                                    . '(
                                          (
                                              user_id = ' . (int)$user_id . '
                                            OR
                                              created_by = ' . (int)$user_id . ' ) ' . $search . '
                                          )
                                        AND
                                          (
                                              status = 0
                                            OR
                                                status = 1
                                            AND
                                              date_complete > \'' . date( 'Y-m-d', strtotime( "-60 days") ) . '\'
                                          ) '
                                    . 'AND '
                                      . '( parent_id IS NULL OR parent_id IS NOT NULL AND ( SELECT status FROM tasks WHERE id = t.parent_id ) = 1 ) '
                                    . 'AND '
                                      . 'open = 0 '
                                  . 'GROUP BY '
                                      . 't.id '
                                  . 'ORDER BY '
                                    . 'status ASC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    else
      $results = $mdb -> query( 'SELECT '
                                    . 't.* '
                                  . 'FROM '
                                    . 'tasks AS t '
                                    . 'LEFT JOIN task_user  AS tu ON tu.task_id = t.id '
                                  . 'WHERE '
                                    . '(
                                          (
                                              user_id = ' . (int)$user_id . '
                                            OR
                                              created_by = ' . (int)$user_id . ' ) ' . $search . '
                                          )
                                        AND
                                          (
                                              status = 0
                                            OR
                                                status = 1
                                            AND
                                              date_complete > \'' . date( 'Y-m-d', strtotime( "-60 days") ) . '\'
                                          ) '
                                    . 'AND '
                                      . '( parent_id IS NULL OR parent_id IS NOT NULL AND ( SELECT status FROM tasks WHERE id = t.parent_id ) = 1 ) '
                                    . 'AND '
                                      . 'open = 0 '
                                  . 'GROUP BY '
                                      . 't.id '
                                  . 'ORDER BY '
                                    . 'open DESC, status ASC, date_start IS NOT NULL DESC, date_start ASC, date_end IS NOT NULL DESC, date_end ASC, o ASC, name ASC' ) -> fetchAll( \PDO::FETCH_ASSOC );
    if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
    {
      $row['total_time'] = \factory\Projects::task_total_time( $row['id'], $user_id );
      $row['users'] = $mdb -> select( 'task_user', 'user_id', [ 'task_id' => $row['id'] ] );
      $row['actions'] = $mdb -> select( 'task_action', '*', [ 'AND' => [ 'task_id' => $row['id'], 'OR' => [ 'date_complete' => null, 'date_complete[>=]' => date( 'Y-m-d H:i:s', strtotime( "-21 days") ) ] ], 'ORDER' => [ 'status' => 'ASC', 'id' => 'ASC' ] ] );
      $tasks[] = $row;
    }
    return $tasks;
  }
}
