<?php
#- Gesamtteilnehmerzahl
#- Teilnehmerzahl, die Healthmiles gesammelt, also Nachweise zur Prävention eingereicht haben
#- Teilnehmerzahl, die eine Prämie erhalten haben.

class statistics {
  # - Gesamtteilnehmerzahl
  var $datum;
  var $timestamp;
  var $year;
  var $month;
  var $day;
  var $punkte_gesamt;
  var $punkte_ultimoverfallen;
  var $punkte_eingeloest;
  var $punkte_einloesbar;
  var $neuanmeldungen_O18;
  var $neuanmeldungen_U18;
  var $teilnehmer;
  var $teilnehmer_U18;

  function __construct($datum = false) {
    if ($datum == false) {
        # default = yesterday
        $this->datum = date("Y-m-d", (time() - 86400));
    } else {
        $this->datum = $datum;
    }

    List($year,$month,$day) = explode('-',$this->datum);
    # Convert strings to numbers
    $this->year = $year+0;
    $this->month = $month+0;
    $this->day = $day+0;
    $this->timestamp = mktime(0,0,0,$this->month, $this->day, $this->year);

    return $this;
  }

  public function insert()
  {
      /**
      $this->punkte_gesamt += 351400;
      $this->punkte_einloesbar += 220000;
      $this->teilnehmer_O18 += 14343;
      $this->teilnehmer_U18 += 4064;
      */
      $query = "REPLACE INTO statistik
          SET datum = '" . $this->datum . "', 
              punkte_gesamt = " . $this->punkte_gesamt . ",
              punkte_ultimoverfallen = " . $this->punkte_ultimoverfallen . ",
              punkte_eingeloest = " . ($this->punkte_eingeloest?$this->punkte_eingeloest:0) . ",
              punkte_einloesbar = " . $this->punkte_einloesbar . ",
              neuanmeldungen_O18 = " . $this->neuanmeldungen_O18 . ",
              neuanmeldungen_U18 = " . $this->neuanmeldungen_U18 . ",
              teilnehmer_O18 = " . $this->teilnehmer_O18 . ",
              teilnehmer_U18 = " . $this->teilnehmer_U18 ;

    $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
    return true;
  }

  function readEntries() {
    $stats = Array();
    $query = "SELECT * FROM statistik 
              ORDER BY datum ASC";
    $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());

    while ($row = dbFetchRow($result)) {
      $tmpstats = new statistics($row['datum']);
      $tmpstats->punkte_gesamt = $row['punkte_gesamt'];
      $tmpstats->punkte_ultimoverfallen = $row['punkte_ultimoverfallen'];
      $tmpstats->punkte_eingeloest = $row['punkte_eingeloest'];
      $tmpstats->punkte_einloesbar = $row['punkte_einloesbar'];
      $tmpstats->neuanmeldungen_O18 = $row['neuanmeldungen_O18'];
      $tmpstats->neuanmeldungen_U18 = $row['neuanmeldungen_U18'];
      $tmpstats->teilnehmer_O18 = $row['teilnehmer_O18'];
      $tmpstats->teilnehmer_U18 = $row['teilnehmer_U18'];
      $stats[] = $tmpstats;
    }
    return $stats;
  }

  function getLastEntry() {
    $query = "SELECT * FROM statistik 
              ORDER BY datum DESC";

    $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());

    if (dbNumRows($result) < 1) {
        return '';
    }
    $row = dbFetchRow($result);
    $datum = $row['datum'];
    $time = strtotime($datum);
    return date('Y-m-d',$time);
  }

  function getNumbers() {
    $eintraege = Array();
    $start = $this->getEarliestEntry();
    $startyear = date("Y", $start);
    $thisyear = date("Y", time());
    print "Erwachsene:\n";
    print "Jahr;Neueintraege;Teilnehmer mit Gutschriften;Teilnehmer mit Praemien;Teilnehmerbestand\n";
    while($startyear <= $thisyear) {
      $startstamp = mktime(0,0,0,1,1,$startyear);
      $endstamp = mktime(23,59,59,12,31,$startyear);
      $anzahl = $this->getNeueintraege($startstamp, $endstamp);
      print "$startyear;$anzahl;";
      $anzahl = $this->getGutschriftenTeilnehmer($startstamp, $endstamp);
      print "$anzahl;";
      $anzahl = $this->getPraemienTeilnehmer($startstamp, $endstamp);
      print "$anzahl;";
      $anzahl = $this->getTeilnehmer($endstamp);
      print "$anzahl";
      print "\n";
      $startyear++;
    }

    $startstamp = mktime(0,0,0,1,1,2009);
    $endstamp = mktime(23,59,59,06,31,2009);
    $anzahl = $this->getNeueintraege($startstamp, $endstamp);
    print "31.06.2009;$anzahl;";
    $anzahl = $this->getGutschriftenTeilnehmer($startstamp, $endstamp);
    print "$anzahl;";
    $anzahl = $this->getPraemienTeilnehmer($startstamp, $endstamp);
    print "$anzahl;";
    $anzahl = $this->getTeilnehmer($endstamp);
    print "$anzahl";
    print "\n";


    $startyear = date("Y", $start);
    print "U18:\n";
    print "Jahr;Neueintraege;Teilnehmer mit Gutschriften;Teilnehmer mit Praemien;Teilnehmerbestand\n";
    while($startyear <= $thisyear) {
      $startstamp = mktime(0,0,0,1,1,$startyear);
      $endstamp = mktime(23,59,59,12,31,$startyear);
      $anzahl = $this->getNeueintraege($startstamp, $endstamp,true);
      print "$startyear;$anzahl;";
      $anzahl = $this->getGutschriftenTeilnehmer($startstamp, $endstamp, true);
      print "$anzahl;";
      $anzahl = $this->getPraemienTeilnehmer($startstamp, $endstamp, true);
      print "$anzahl;";
      $anzahl = $this->getTeilnehmer($endstamp, true);
      print "$anzahl";
      print "\n";
      $startyear++;
    }
    $startstamp = mktime(0,0,0,1,1,2009);
    $endstamp = mktime(23,59,59,06,31,2009);
    $anzahl = $this->getNeueintraege($startstamp, $endstamp,true);
    print "31.06.2009;$anzahl;";
    $anzahl = $this->getGutschriftenTeilnehmer($startstamp, $endstamp,true);
    print "$anzahl;";
    $anzahl = $this->getPraemienTeilnehmer($startstamp, $endstamp,true);
    print "$anzahl;";
    $anzahl = $this->getTeilnehmer($endstamp,true);
    print "$anzahl";
    print "\n";
  }


  # Regemaessige Statistik....
  #
  function getAllPoints() {
    $endtimestamp = $this->timestamp + 86400;
    $enddate = date("Y-m-d",$endtimestamp);

    $query = "SELECT userId FROM users WHERE erstellungsdatum < " . $endtimestamp;
    $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
    $gesamt = 0;
    while( $row = dbFetchRow($result)) {
      $userId = $row['userId'];
      $konto = new konto($userId,true); # read kontoauszug unsorted
      $saldo = $konto->getSaldo($enddate);
      $gesamt += $saldo;
    }
    $this->punkte_gesamt = $gesamt;
    return $gesamt;
  }

  function getAllInvalidates() {
    if ($this->month == 1) {
      $month = 12;
      $year = $this->year -1;
    } else {
      $month = $this->month -1;
      $year = $this->year;
    }
    $enddate = "$year-$month-1";
    $query = "SELECT userId FROM users WHERE 1";
    $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());

    $gesamt = 0;
    while( $row = dbFetchRow($result)) {
      $userId = $row['userId'];
      $konto = new konto($userId,true); # read kontoauszug unsorted
      $invalidate = $konto->calcinvalidatenext($enddate, false);
      $gesamt += $invalidate[0];
    }
    $this->punkte_ultimoverfallen = $gesamt;
    return $gesamt;
  }

  function getTeilnehmer($u18 = false) {
      $query = "SELECT userId FROM users
          WHERE erstellungsdatum <= " . $this->timestamp;
      if ($u18) {
        $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) < geburtsdatum ";
      } else {
        $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) >= geburtsdatum ";
      }
      $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
      $anzahl = dbNumRows($result);
      if ($u18) {
        $this->teilnehmer_U18 = $anzahl;
      } else {
        $this->teilnehmer_O18 = $anzahl;
      }
      return($anzahl);
  }


  function getNeueintraege($start, $end, $u18 = false) {
      $query = "SELECT userId FROM users
          WHERE erstellungsdatum >= $start
          AND erstellungsdatum <= $end";
      if ($u18) {
        $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) < geburtsdatum ";
      } else {
        $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) >= geburtsdatum ";
      }
      $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());

      $anzahl = dbNumRows($result);
      if($u18) {
        $this->neuanmeldungen_U18 = $anzahl;
      } else {
        $this->neuanmeldungen_O18 = $anzahl;
      }
      return($anzahl);
  }

  # - Teilnehmerzahl, die Healthmiles gesammelt, also Nachweise zur Prävention eingereicht haben
  function getGutschriftenTeilnehmer($start, $end, $u18 = false) {
      $query = "SELECT kontobewegungen.userId FROM kontobewegungen, users
          WHERE users.userId = kontobewegungen.userId
          AND datum >= $start
          AND datum <= $end";
      if ($u18) {
          $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) < geburtsdatum ";
      } else {
          $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) >= geburtsdatum ";
      }
      $query .="AND wert > 0
          GROUP by userId";
      $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
      $anzahl = dbNumRows($result);
      return($anzahl);

  }

  function getPraemienTeilnehmer($start, $end,$u18 = false) {
      $query = "SELECT kontobewegungen.userId FROM kontobewegungen, users
          WHERE users.userId = kontobewegungen.userId
          AND datum >= $start
          AND datum <= $end"
          AND geloescht !=1;
      if ($u18) {
          $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) < geburtsdatum ";
      } else {
          $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) >= geburtsdatum ";
      }
      $query .= "AND wert < 0
          AND beschreibung LIKE 'Bestellung der %'
          GROUP by userId";
      $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
      $anzahl = dbNumRows($result);
      return($anzahl);
  }


  # Berechnet alle Punkte, die im Monat des angegebenen Timestamps
  # eingeloest wurden
  function getEingeloestePunkte() {
    # Start with 1st of month
    $starttimestamp = mktime(0,0,0,$this->month,1,$this->year);
    $daysinmonth = date("t", $starttimestamp);
    # End with day of this statistic
    $endtimestamp = mktime(23,59,59,$this->month,$this->day,$this->year);
    $query = "SELECT sum(-wert) AS punkte
              FROM kontobewegungen
              WHERE datum >= $starttimestamp
              AND datum <= $endtimestamp
              AND (beschreibung LIKE 'Spende%'
              OR beschreibung LIKE 'Bestellung%')
              AND geloescht !=1";
    $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
    $row = dbFetchRow($result);
    $gesamt = $row['punkte'];
    $this->punkte_eingeloest = $gesamt;
    return $gesamt;
  }

  /* New entries */
  function neueTeilnehmer($u18=false) {
    list($year, $month, $day) = explode('-', date("Y-m-d", $this->timestamp));
    $startDate = mktime(0,0,0,$this->month, $this->day, $this->year);
    $endDate = mktime(23,59,59,$this->month, $this->day, $this->year);
    $query = "SELECT count(userId) AS anzahl FROM users
              WHERE erstellungsdatum >= $startDate
              AND   erstellungsdatum <= $endDate";
    if ($u18) {
        $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) < geburtsdatum ";
    } else {
        $query .= " AND DATE_SUB( FROM_UNIXTIME(erstellungsdatum), INTERVAL 18 YEAR ) >= geburtsdatum ";
    }
    $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
    $row = dbFetchRow($result);
    $anzahl = $row['anzahl'];
    if($u18) {
        $this->neuanmeldungen_U18 = $anzahl;
    } else {
        $this->neuanmeldungen_O18 = $anzahl;
    }
    return $anzahl;
  }


  function getEinloesbarePunkte() {
    # Alle Teilnehmer suchen, die bereits Punkte haben
    $query = "SELECT distinct(users.userId) AS userId
        FROM users, kontobewegungen
        WHERE users.userId = kontobewegungen.userId
        AND kontobewegungen.wert > 0
        AND kontobewegungen.geloescht !=1
        AND datum <= " . ($this->timestamp + 86400);
    $result = dbQuery($query) or
        error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
    $count = 0;
    $einloesbarepunkte = 0;
    while ($row = dbFetchRow($result)) {
       # 1. Hat der Teilnehmer bereits Punkte eingelöst?
       $userId = $row['userId'];
       $konto = new konto($userId);
       # Hole Kontostand zum Datum der Statistikerstellung
       $punkte = $konto->getSaldo($this->datum);
       $subquery = "SELECT userId FROM kontobewegungen
                 WHERE userId = $userId
                 AND wert < 0
                 AND datum <= " . ($this->timestamp + 86400) . "
                 AND (beschreibung LIKE 'Bestellung%'
                 OR beschreibung LIKE 'Spende an%')
                 AND kontobewegungen.geloescht !=1";
       $subresult = dbQuery($subquery) or
           error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());

       # Wenn Spende oder Praemienbestellung erfolgt
       if (dbNumRows($subresult) > 0) {
           # Hat bereits Punkte eingeloest
           if ($punkte >= 250) {
               $einloesbarepunkte += $punkte;
           }
       } else {
          # Andernfalls müssen wenigstens 500 Punkte auf dem
          # Konto liegen
          if ($punkte >= 500) {
               $einloesbarepunkte += $punkte;
          }
      }
    }
    $this->punkte_einloesbar = $einloesbarepunkte;
    return $einloesbarepunkte;
  }

  function getEarliestEntry() {
      $query = "SELECT min(erstellungsdatum) AS erstellungsdatum
          FROM users";
      $result = dbQuery($query) or
           error("Cannot commit query " . __CLASS__ . ":" . __FUNCTION__ . " '$query': " . dbError());
      $row = dbFetchRow($result);
      $erstellungsdatum = $row['erstellungsdatum'];
      return $erstellungsdatum;
  }

  function gesammeltePunkte($from, $to, $type = 'O18')
  {
      list($yearfrom, $monthfrom,  $dayfrom) = explode('-',$from);
      list($yearto , $monthto, $dayto) = explode('-',$to);
      #print "$yearfrom-$monthfrom-$dayfrom - $yearto-$monthto-$dayto\n";
      #exit;
      $gesamt = 0;

      for($year = $yearfrom; $year <= $yearto; $year++)
      {
          for ($month = (($year == $yearfrom)?$monthfrom:1); $month <= (($year == $yearto)?$monthto:12); $month++)
          {

              $timestart = mktime(0,0,0,$month,1,$year);
              $daysinmonth = date('t',$timestart);
              for ($day = 1; $day <= $daysinmonth; $day++)
              {
                  print "$year-$month-$day\n";
                  $timestart = mktime(0,0,0,$month,$day,$year);
                  $timeend = mktime(23,59,59,$month,$day,$year);
                  $timestamp18yearsago = strtotime("18 years ago", $timestart);
                  $birthdate = date('Y-m-d',$timestamp18yearsago);
                  $query = "SELECT SUM(wert) AS punkte FROM users, kontobewegungen 
                      WHERE datum >= $timestart 
                      AND datum <= $timeend
                      AND users.userId = kontobewegungen.userId
                      AND wert > 0
                      AND kontobewegungen.geloescht != 1";
                  if ($type=='O18') $query .= " AND geburtsdatum < '$birthdate'";
                  else $query .= " AND geburtsdatum >= '$birthdate'";
                  $result = dbQuery($query) or die(dbError() . "\n".$query. "\n");
                  $row = dbFetchRow($result);
                  $gesamt += $row['punkte'];
              }
          }
      }
      return $gesamt;
  }
}
