<?php
/**
 * General Healthmiles functions glued into one main class
 *
 * @author Carsten Schaedlich <carstens@projektvier.de>
 * @package Healthmiles
 *
 */

class healthmiles {

    /** fetches all users currently present in the database 
     * 
     * @param bool $u18
     * @return array of user ids
    */
    public function getAllUsers($startDate,$endDate,$u18,$versand,$agechange) {
        $users = Array();

        $startTimestamp = isodatetotimestamp($startDate);
        $endTimestamp = isodatetotimestamp($endDate);

        $starttimestamp18yearsago = strtotime("18 years ago", $startTimestamp);
        $endtimestamp18yearsago = strtotime("18 years ago", $endTimestamp);

        $timestamp18yearsago = strtotime("18 years ago", strtotime("today"));
        $date18yearsago = date("Y-m-d", $timestamp18yearsago);

        $startdate18yearsago = date("Y-m-d", $starttimestamp18yearsago);
        $enddate18yearsago = date("Y-m-d", $endtimestamp18yearsago);

        $timestamp5yearsago = strtotime("5 years ago", strtotime("today"));
        $date5yearsago = date("Y-m-d", $timestamp5yearsago);

        $query = "SELECT DISTINCT(u.userId), email FROM users AS u 
            WHERE u.auszugperemail = $versand";
        # Select between U18, O18 and those that changed age to 18
        if (!$agechange) {
            if ($u18) {
                $query .= " AND u.geburtsdatum > '$enddate18yearsago'";
                $query .= " AND u.geburtsdatum < '$date5yearsago'";
            } else {
                $query .= " AND u.geburtsdatum < '$startdate18yearsago'";
            }
        } else {
                $query .= " AND u.geburtsdatum >= '$startdate18yearsago'";
                $query .= " AND u.geburtsdatum <= '$enddate18yearsago'";
        }
        $query .= ' ORDER BY land, plz';

#        print "<pre>$query</pre>\n";
        $result = dbQuery($query) or error("Kontoaenderungen koennen nicht gelesen werden: $query");

        while($row = dbFetchRow($result)) {
            if ($row['email'] == '') {
                $users[] = $row['userId'];
            }
        }

        return $users;
    }

    /**
     * Filter out those userIds that do not have been missing
     * from the data imported from the CRM system
     */
    public function filterActiveUsers($userIds)
    {
        $date = date('Y-m-d', strtotime('2 days ago'));
        $newUserIds = array();
        foreach ($userIds as $userId)
        {
            $user = new user(0,$userId);
            // Attribute crmkv holds the latest date when
            // a user appeared in the CRM data file
            if ($user->crmkv >= $date) {
                $newUserIds[] = $userId;
            }
        }
        return $newUserIds;
    }

    /** Function fetches all users that have changes in their account in a given
     *  time frame
     *
     * @param date startDate  (yyyy-mm-dd) day will be ignored
     * @param date endDate    (yyyy-mm-dd) day will be ignored
     * @param bool u18        if true, fetch users less than 18 years old 
     * @param int  email      0 = no letter, 1 = postal, 2 = email
     * @return array of user ids
     */
    public function getUsersWithAccountChanges($startDate, $endDate, $u18, $email, $agechange = false, $plusnurverfaller = false) {

        $startTimestamp = isodatetotimestamp($startDate);
        $endTimestamp = isodatetotimestamp($endDate);

        # required for calculation of those who became 18 years old
        # during the interval defined by startDate and endDate:
        $starttimestamp18yearsago = strtotime("18 years ago", $startTimestamp);
        $endtimestamp18yearsago = strtotime("18 years ago", $endTimestamp);
        $timestamp18yearsago = strtotime("18 years ago", strtotime("today"));
        $date18yearsago = date("Y-m-d", $timestamp18yearsago);
        $startdate18yearsago = date("Y-m-d", $starttimestamp18yearsago);
        $enddate18yearsago = date("Y-m-d", $endtimestamp18yearsago);

        $timestamp5yearsago = strtotime("5 years ago", strtotime("today"));
        $date5yearsago = date("Y-m-d", $timestamp5yearsago);

        /* Select all that have account changes in the given time range */
        $query = "SELECT DISTINCT(u.userId), email FROM users AS u, kontobewegungen AS k 
            WHERE u.userId = k.userId
            AND k.datum >= $startTimestamp
            AND k.datum <= $endTimestamp
            AND wert <> 0 
            AND beschreibung != ''
            AND u.auszugperemail = $email";
        if ($agechange) {
            $query = "SELECT DISTINCT(u.userId) FROM users AS u
                WHERE u.auszugperemail = $email";
        }

        # Select between U18, O18 and those that changed age to 18
        if (!$agechange) {
            if ($u18) {
                $query .= " AND u.geburtsdatum > '$enddate18yearsago'";
                $query .= " AND u.geburtsdatum < '$date5yearsago'";
            } else {
                $query .= " AND u.geburtsdatum < '$startdate18yearsago'";
            }
        } else {
                $query .= " AND u.geburtsdatum >= '$startdate18yearsago'";
                $query .= " AND u.geburtsdatum <= '$enddate18yearsago'";
        }

        # print "Query: $query<br/>\n";
        $result = dbQuery($query) or error("Kontoaenderungen koennen nicht gelesen werden: $query");
        $users = Array();
        while($row=dbFetchRow($result)) {
            if ($row['email'] == '') {
                $users[] = $row['userId'];
            }
        }
        dbFreeResult($result);
        if ($plusnurverfaller) {
            $users2 = $this->getUsersWithInvalidations($startDate,$endDate,$u18,$email,$agechange);
            $users = array_merge($users,array_diff($users2,$users));
            unset($users2);
        }
        /** Sortiere nach Land und PLZ 
           Ein wenig teuer, weil jedes Benutzer-Objekt einzeln aus der 
           Datenbank geholt wird...
           Bei ca 20.000 Einträgen sind das 2,2 Sekunden...
         */
        $tosort = array();
        foreach ($users as $userid) {
            $myUser = new user(0,$userid);
            $plz = $myUser->plz;
            $country = $myUser->land;
            unset($myUser);
            $val = $country.$plz;
            $tosort[$userid] = $val;
        }
        unset($users);
        asort($tosort);
        $users = array_keys($tosort);
        unset($tosort);

        return $users;
    }

    public function getUsersWithInvalidations($startDate,$endDate,$u18,$email,$agechange=false) {

        $timestamp18yearsago = strtotime("18 years ago", strtotime("today"));
        $date18yearsago = date("Y-m-d", $timestamp18yearsago);
        $startTimestamp = isodatetotimestamp($startDate);
        $endTimestamp = isodatetotimestamp($endDate);

        $starttimestamp18yearsago = strtotime("18 years ago", $startTimestamp);
        $endtimestamp18yearsago = strtotime("18 years ago", $endTimestamp);
        $startdate18yearsago = date("Y-m-d", $starttimestamp18yearsago);
        $enddate18yearsago = date("Y-m-d", $endtimestamp18yearsago);

        $timestamp5yearsago = strtotime("5 years ago", strtotime("today"));
        $date5yearsago = date("Y-m-d", $timestamp5yearsago);

        $query = "SELECT userId FROM users WHERE 
            auszugperemail = $email";
        if (!$agechange) {
            if ($u18) {
                $query .= " AND geburtsdatum > '$enddate18yearsago'";
                $query .= " AND geburtsdatum < '$date5yearsago'";
            } elseif (! $agechange) {
                $query .= " AND geburtsdatum < '$startdate18yearsago'";
            }
        } else {
                $query .= " AND geburtsdatum >= '$startdate18yearsago'";
                $query .= " AND geburtsdatum <= '$enddate18yearsago'";
        }

#        print $query . "\n";
        $result = dbQuery($query) or error("Kontoaenderungen koennen nicht gelesen werden");
        print "Anzahl: " . dbNumRows($result) . "\n";
        $users = Array();
        $i=0;
        while($row=dbFetchRow($result)) {
            if ($i/100 == round($i/100)) {
                print "$i\n";
            }
            $i++;
          $userId = $row['userId'];
          $konto = new konto($userId);
          #$invalidpoints = $konto->calcinvalidatenext($endDate);
          $invalidpoints = $konto->calcinvalidatenext(date('Y-m-d'));
          if ($invalidpoints[0] > 0 || $invalidpoints[1] > 0 ) {
              $users[] = $userId;
          }
        }
        return $users;
    }


    # Selektiert alle Teilnehmer, die einem angegebenen Zeitraum eingetragen wurden
    #
    # @param $startDate Anfang des Zeitraumes
    # @param $endDate Anfang des Zeitraumes
    # @param $u18 false = Erwachsene, true = Kinder und Jugendliche
    # @param $self false = Durch Bearbeiter angelegt, true = selbst eingetragen über Frontend
    public function getRegistrations($startDate, $endDate, $u18, $self) {
        $timestamp18yearsago = strtotime("18 years ago", strtotime("today"));
        $date18yearsago = date("Y-m-d", $timestamp18yearsago);
        $startTimestamp = isodatetotimestamp($startDate);
        $endTimestamp = isodatetotimestamp($endDate);
        print "StartDate: $startDate, EndDate: $endDate\n";
        $query = "SELECT DISTINCT(u.userId) FROM users AS u, userlogs AS l 
            WHERE u.userId = l.object
            AND erstellungsdatum >= $startTimestamp
            AND erstellungsdatum <= $endTimestamp";
        if ($self) {
            $query .= " AND l.type = 'client' AND l.aktion = 'Angelegt'";
        } else {
            $query .= " AND l.type = 'admin' AND l.aktion = 'Angelegt'";
        }
        if ($u18) {
            $query .= " AND u.geburtsdatum > '$date18yearsago'";
        } else {
            $query .= " AND u.geburtsdatum <= '$date18yearsago'";
        }
#        print "Query: $query<br/>\n";
        $result = dbQuery($query) or error("Kontoaenderungen koennen nicht gelesen werden. Query: '$query'\n" . dbError());
        $users = Array();
        while($row=dbFetchRow($result)) {
          $users[] = $row['userId'];
        }
        dbFreeResult($result);
        return $users;
    }

    # Gibt alle aktuell eingetragenen Punkte an
    #
    # @return int Anzahl
    public function getPoints() {
      $query = "SELECT userId from users\n";
#      print "Query: $query<br/>\n";
      $result = dbQuery($query) or error("Users koennen nicht gelesen werden. Query: '$query'\n" . dbError());
      $userIds = Array();
      while($row=dbFetchRow($result)) {
          $userIds[] = $row['userId'];
      }
      $points = 0;
      $progress = new progress(sizeof($userIds));
      $i = 0;
      foreach ($userIds as $userId) {
        $progress->show($i++);
        $konto = new konto($userId);
        $points += $konto->getSaldo();
      }
      return $points;
    }

    public function logauszug($auszugname, $startDate, $endDate, $u18, $versand, $plusnurverfaller) {
        $query = "INSERT INTO auszugversandlog 
                  SET auszugname = '$auszugname', 
                      startdate = '$startdate',
                      enddate = '$enddate', 
                      u18 = 'u18',
                      versand = '$versand',
                      plusnurverfaller = '$plusnurverfaller')";
        dbQuery($query) or error("Can't insert: $query" . dbError());
    }

    /**
     * Gibt die UserIds von allen Neuanmeldungen im Zeitraum
     * $starttimestamp -> $endtimestamp zurück
     *
     * @param $starttimestamp int Startzeitpunkt
     * @param $endtimestamp int Endzeitpunkt 
     * @return array (int) userids Liste der Userids
     */
    public function getNewUsers($starttimestamp = 0, $endtimestamp = 0) {
        if (!$starttimestamp) {
          /* yesterday */
            $starttimestamp = strtotime("yesterday 00:00:00", time());
            $endtimestamp= $starttimestamp + 86400; // 24h
        }
        if (!$endtimestamp) {
            $endtimestamp = time();
        }
        $query = "SELECT userId FROM users
            WHERE erstellungsdatum > $starttimestamp
            AND erstellungsdatum <= $endtimestamp";
        $result = dbQuery($query) or error("Cannot select: $query" . dbError());
        $userids = array();
        while ($row = dbFetchRow($result)) {
            array_push($userids,$row['userId']);
        } 
        return $userids;
    }

    public function getExportTeilnehmer()
    {
        $query = "SELECT * FROM userlogs WHERE aktion='Teilnehmer Kassenexport' ORDER BY timestamp DESC";
        $result = dbQuery($query)
            or error("Konnte log nicht aus der Datenbank lesen: " . dbError());
        $row = dbFetchRow($result);
        $userids=array();
        $start = 631148401;
        if ($row) {
            $start = $row['timestamp'];
        }
        $userids = $this->getNewUsers($start);
        return $userids;
    }


    public function exportTeilnehmer($userids)
    {
        global $exportpath, $zipbin;
        $filename = '';
        if (count($userids) > 0) {
            $exportdirname = date("Ymd-His");
            if (!is_dir($exportpath . "/" . $exportdirname)) {
                $oldumask = umask(0);
                if (!mkdir($exportpath . "/" . $exportdirname, 0775)) {
                    umask($oldumask);
                    die('Erstellung des Verzeichnisses ' .
                            $exportpath . "/" . $exportdirname . ' schlug fehl!');
                }
                umask($oldumask);
            }
            $exportfilenames = array();
            $number = count($userids);
            $id = 1;
            foreach ($userids as $userid)
            {
                $myUser = new user(0, $userid);
                $exportfilename = $exportpath . "/" . $exportdirname . "/";

                $exportfilename .= 'healthmiles_teilnehmer_' . $myUser->versnummerneu . '.xml';
                $xml = $myUser->toXML($id);
                if ($xml == '') {
                    continue;
                }
                $id++;
                if ($exportfilehandle = fopen($exportfilename, "w")) {
                    fwrite($exportfilehandle, $xml);
                    fclose($exportfilehandle);
                    $exportfilenames[] = $exportfilename;
                } else {
                    print "Writing of " . $exportfilename . " FAILED!<br />\n";
                }
            }
            $filename = $exportpath . '/TeilnehmerExport-' . $exportdirname . '.zip';
            echo system($zipbin . ' -q -j -r ' . $exportpath . '/TeilnehmerExport-' . $exportdirname . ' ' . $exportpath . '/' . $exportdirname);
//            echo system($zipbin . ' -e -q -j -P secu09 -r ' . $exportpath . '/TeilnehmerExport-' . $exportdirname . ' ' . $exportpath . '/' . $exportdirname);
            $this->rrmdir($exportpath . '/' . $exportdirname);
        }
        return $filename;
    }

    private function rrmdir($dir)
    {
        if (is_dir($dir)) {
            $objects = scandir($dir);
            foreach ($objects as $object)
            {
                if ($object != "." && $object != "..") {
                    if (filetype($dir . "/" . $object) == "dir")
                        rrmdir($dir . "/" . $object);
                    else
                        unlink($dir . "/" . $object);
                }
            }
            reset($objects);
            rmdir($dir);
        }
    }

}
