<?php


class konto
{

    public $userId = 0;
    public $kontoBewegungen = array();
    public $anzahlBewegungen;
    private $_pdf;
    public $Verfalllabel = ' Healthmiles verfallen zum ';


    function __construct($userId, $unsorted = false)
    {
        $this->userId = $userId;
        $this->anzahlBewegungen = 0;
        $this->readKontoauszug($unsorted);
        return $this;
    }


    /**
     * Reads account lines and stores them in $this->kontoBewegungen
     * Called in constructor
     */
    function readKontoauszug($unsorted = false)
    {
        $query = "SELECT * FROM kontobewegungen WHERE userId = '" . $this->userId . "'  AND geloescht != 1";
        if (!$unsorted) {
            $query .= " ORDER BY datum DESC";
        }
        $result = dbQuery($query) or
        error("Konnte Konto nicht lesen: " . dbError());
        $numRows = dbNumRows($result);
        while ($row = dbFetchRow($result)) {
            if (isset($row['pkey'])) {
                $bewegung = new kontoBewegung($row);
                array_push($this->kontoBewegungen, $bewegung);
            }
        }
        $this->anzahlBewegungen = count($this->kontoBewegungen);
        dbFreeResult($result);
        return $numRows;
    }


    function readKontoauszugFiltered($startDate = '', $endDate = '')
    {
        $this->kontoBewegungen = array();
        if ($startDate != '') {
            list($year, $month, $day) = explode('-', $startDate);
            $startTimestamp = mktime(0, 0, 0, $month, $day, $year);
        }
        if ($endDate != '') {
            list($year, $month, $day) = explode('-', $endDate);
            $endTimestamp = mktime(0, 0, 0, $month, $day, $year);
        }

        $query = "SELECT * FROM kontobewegungen WHERE userId = " . $this->userId .
            " AND wert != 0 AND geloescht != 1";
        if (isset($startTimestamp)) {
            $query .= " AND datum >= $startTimestamp";
        }
        if (isset($endTimestamp)) {
            $query .= " AND datum <= $endTimestamp";
        }

        $query .= " ORDER BY datum ASC";
        $result = dbQuery($query) or
        error("Konnte Konto nicht lesen: " . dbError());
        $numRows = dbNumRows($result);
        while ($row = dbFetchRow($result)) {
            if (isset($row['pkey'])) {
                $bewegung = new kontoBewegung($row);
                array_push($this->kontoBewegungen, $bewegung);
            }
        }
        dbFreeResult($result);
        return $numRows;
    }


    /**
     * filters kontoauszug, so that "0" lines get thrown out
     *
     * */
    function filterKontoauszug($startDate = '', $endDate = '')
    {
        $i = 0;
        if ($startDate != '') {
            list($year, $month, $day) = explode('-', $startDate);
            $startTimestamp = mktime(0, 0, 0, $month, $day, $year);
        }
        if ($endDate != '') {
            list($year, $month, $day) = explode('-', $endDate);
            $endTimestamp = mktime(0, 0, 0, $month, $day, $year);
        }

        while ($i < sizeof($this->kontoBewebungen)) {
            if ($this->kontoBewebungen[$i]->wert == 0) {
                $this->kontoBewegungen[$i] = 0;
                sort($this->kontoBewegungen);
            }
            if (isset($startTimestamp) && $this->kontoBewegungen[$i]->datum <= $startTimestamp) {
                $this->kontoBewegungen[$i] = 0;
                sort($this->kontoBewegungen);
            }
            if (isset($endTimestamp) && $this->kontoBewegungen[$i]->datum >= $endTimestamp) {
                $this->kontoBewegungen[$i] = 0;
                sort($this->kontoBewegungen);
            }
        }
    }


    /**
     * Adds a line to the account
     * The db id of the line is stored
     * in the returned object
     *
     * @param object kontobewegung
     * @returns object kontobewegung
     * */
    function addKontobewegung($kontobewegung, $kindId = 0)
    {
        $userId = $kontobewegung->userId;
        $kategorie = $kontobewegung->kategorie;
        $unterkategorie = $kontobewegung->unterkategorie;
        $praemienid = $kontobewegung->praemienid;
        $praemienhmid = $kontobewegung->praemienhmid;
        $kommentar = dbEscapeString($kontobewegung->kommentar);
        $datum = $kontobewegung->datum;
        $datumerwerb = convertdate($kontobewegung->datumerwerb);
        if ($datumerwerb == '') {
            $datumerwerb = '0000-01-01';
        }
        $datumbescheinigung = convertdate($kontobewegung->datumbescheinigung);
        if ($datumbescheinigung == '') {
            $datumbescheinigung = '0000-01-01';
        }
        $beschreibung = dbEscapeString($kontobewegung->beschreibung);
        $wert = $kontobewegung->wert;
        if (trim($wert) === '')
            $wert = 0;
        $zeitstempel = $kontobewegung->zeitstempel;
        if (!$zeitstempel)
            $zeitstempel = time();
        if (!isset($kontobewegung->gueltig) || ($kontobewegung->gueltig === '')) {
            $gueltig = 1;
        } else {
            $gueltig = 0;
        }

        $query = "INSERT INTO kontobewegungen SET " .
            "userId = '$userId', " .
            "kategorie = '$kategorie', " .
            "unterkategorie = '$unterkategorie', " .
            "praemienid = '$praemienid', " .
            "praemienhmid = '$praemienhmid', " .
            "kommentar = '$kommentar', " .
            "datum = $datum, " .
            "datumerwerb = '$datumerwerb', " .
            "datumbescheinigung = '$datumbescheinigung', " .
            "beschreibung = '$beschreibung', " .
            "wert = $wert, " .
            "zeitstempel = $zeitstempel, " .
            "gueltig = $gueltig";

        $result = dbQuery($query) or
        error("Konnte Kontobewebung nicht in Datenbank eintragen: " . dbError());
        $kontobewegung->id = dbInsertId();
        array_push($this->kontoBewegungen, $kontobewegung);
        dbFreeResult($result);
        if ($kindId > 0) {
            $query = "INSERT INTO kindermassnahmen
              SET kontobewegungsId = " . $kontobewegung->id . ",
              childId = $kindId";
            $result = dbQuery($query) or
            error("Konnte Kontobewegung nicht in Datenbank eintragen: " . dbError());
        }
        return $kontobewegung;
    }


    /**
     * Returns total of account
     * */
    function getSaldo($endDate = '')
    {
        if ($endDate == '') {
            $endTimestamp = time();
        } else if (is_numeric($endDate)) {
            $endTimestamp = $endDate;
        } else {
            list($year, $month, $day) = explode('-', $endDate);
            if ($year < 2000) {
                list($day, $month, $year) = explode('.', $endDate);
            }
            if ($year > 2000) {
                $endTimestamp = mktime(23, 59, 59, $month, $day, $year);
            } else {
                $endTimestamp = time();
                $endDate = '';
            }
        }

        $saldo = 0;
        foreach ($this->kontoBewegungen as $kontobewegung) {
            if (($kontobewegung->datum <= $endTimestamp)) {
                $saldo += $kontobewegung->wert;
            }
        }
        /* There's no negative saldo: level it to 0 if negative */
        if ($saldo < 0 && $endDate == '') {
            $saldo = 0;
        }
        return $saldo;
    }

    /* Gets latest timestamp of a valid positive entry into the account
     *
     * @returns timestamp of last positive and valid entry, 0 if none found
     */


    function getLastEntryDate($timefence)
    {
        $query = "SELECT max(datum) AS timestamp FROM kontobewegungen WHERE wert > 0 and gueltig = 1
                    AND userId = '" . $this->userId . "' AND datum <= $timefence  AND geloescht != 1";
        $result = dbQuery($query) or
        error("Konnte letzten Eintrag nicht aus der Datenbank lesen: " . dbError());
        if (dbNumRows($result) > 0) {
            $row = dbFetchRow($result);
            return ($row['timestamp']);
        }
        return 0;
    }

    /* Gets first timestamp of entires
     *
     * @returns timestamp of first entry
     */


    function getFirstEntryDate()
    {
        $query = "SELECT min(datum) AS timestamp FROM kontobewegungen WHERE
                    userId = '" . $this->userId . "' AND geloescht != 1";
        $result = dbQuery($query) or
        error("Konnte letzten Eintrag nicht aus der Datenbank lesen: " . dbError());
        if (dbNumRows($result) > 0) {
            $row = dbFetchRow($result);
            return ($row['timestamp']);
        }
        return 0;
    }

    /* Calcs the number of points that expire next month
     * and the month after the next month
     *
     * @returns array(Expire_month+1, Expire_month+2);
     *
      function calcinvalidatenext($date = '', $twomonths = true) {
     * 120229: GEM now @returns array(Expire_month+1, Expire_month+2, Expire_month+3);
     */


    function calcinvalidatenext($date = '', $twomonths = true, $threemonths = true, $fourmonths = true)
    {
        /* If date not given, month = this month */
        if ($date != '') {
            list($year, $month, $day) = explode('-', $date);
        } else {
            $now = time();
            $year = date('Y', $now);
            $month = date('m', $now);
        }
        # Punkte verfallen immer zum letzten des Vormonats
        # = 1. des jetzigen Monats 00:00:00 Uhr
        $day = 1;

        # Berechne nächsten Monatsanfang
        # Year-Wrapping
        $month++;
        if ($month > 12) {
            $month = 1;
            $year++;
        }
        $reference = mktime(0, 0, 0, $month, $day, $year);
        $timefence = mktime(0, 0, 0, $month, $day, $year - 2);

        $verfallen0 = $this->calcinvalidatenotrefreshed($timefence, $reference);
        /* wenn punkte verfallen, weil zwei Jahre lang keine neuen Punkte
          hinzukommen, dann beinhaltet der Verfall bereits die Vier-Jahres-Regelung
         */
        #print "Verfallen weil nicht innerhalb von zwei Jahren refreshed: $verfallen0\n";
        if ($verfallen0 == 0) {
            $timefence = mktime(0, 0, 0, $month, $day, $year - 4);
            $verfallen0 = $this->calcinvalidatedpoints($timefence, $reference);
            #print "Verfallen weil vier Jahre alt: $verfallen0\n";
        }

        $verfallen1 = 0;
        if ($twomonths) {
            $month++;
            if ($month > 12) {
                $month = 1;
                $year++;
            }
            $timefence = mktime(0, 0, 0, $month, $day, $year - 2);
            $verfallen1 = $this->calcinvalidatenotrefreshed($timefence,
                $reference);


            if ($verfallen1 == 0) {
                $timefence = mktime(0, 0, 0, $month, $day, $year - 4);
                $verfallen1 = $this->calcinvalidatedpoints($timefence,
                    $reference);
            }
        }
        if ($threemonths) {
            $month++;
            if ($month > 12) {
                $month = 1;
                $year++;
            }
            $timefence = mktime(0, 0, 0, $month, $day, $year - 2);
            $verfallen2 = $this->calcinvalidatenotrefreshed($timefence,
                $reference);

            if ($verfallen2 == 0) {
                $timefence = mktime(0, 0, 0, $month, $day, $year - 4);
                $verfallen2 = $this->calcinvalidatedpoints($timefence,
                    $reference);
            }
        }

        if ($fourmonths) {
            $month++;
            if ($month > 12) {
                $month = 1;
                $year++;
            }
            $timefence = mktime(0, 0, 0, $month, $day, $year - 2);
            $verfallen3 = $this->calcinvalidatenotrefreshed($timefence,
                $reference);

            if ($verfallen3 == 0) {
                $timefence = mktime(0, 0, 0, $month, $day, $year - 4);
                $verfallen3 = $this->calcinvalidatedpoints($timefence,
                    $reference);
            }
        }

        /* Return next month and the month after minus the points that already
          expire next month, etc.
         */
        $verfallen = array($verfallen0,
            $verfallen1 - $verfallen0,
            $verfallen2 - $verfallen1,
            $verfallen3 - $verfallen2);
        return $verfallen;
    }


    /**
     * Invalidates points if no new points are added
     * during the last two years
     * */
    function invalidateifnotrefreshed($year, $month)
    {
        $verfallen = 0;
#          $now = time();
#          $year = date('Y', $endtime);
#          $month = date('m', $endtime);
        $day = 1;
        $twoyearsago = $year - 2;
        $twoyearsold = mktime(0, 0, 0, $month, $day, $twoyearsago);
        $reference = mktime(0, 0, 0, $month, $day, $year);

        # Berechne Verfall, durch Nichtauffrischen
        $verfallen = $this->calcinvalidatenotrefreshed($twoyearsold, $reference);

        if ($verfallen > 0) {
            # Buche Punkteverfall
            $abzug = new kontoBewegung();
            $abzug->userId = $this->userId;
            $abzug->kategorie = 0;
            $abzug->unterkategorie = 0;
            $abzug->praemienid = 0;
            $abzug->praemienhmid = 0;
            $abzug->kommentar = 'Punkteverfall, da 2 Jahre keine Punkte aufgefrischt wurden';
            $abzug->datum = time();
            $abzug->beschreibung = 'Punkteverfall, da 2 Jahre keine Punkte aufgefrischt wurden';
            $abzug->wert = -$verfallen;
            $abzug->gueltig = 0;
            $this->addKontobewegung($abzug);

            # Kennzeichne Punkte als verfallen
            #$query = "UPDATE kontobewegungen SET gueltig = 0
            #    WHERE (wert > 0)
            #    AND gueltig = 1
            #    AND userId = '" . $this->userId . "'";
            #$result = dbQuery($query) or
            #    error("Konnte letzten Eintrag nicht aus der Datenbank lesen: " .  dbError());
        }
        return $verfallen;
    }


    function calcinvalidatenotrefreshed($timefence, $reference)
    {
        $verfallen = 0;
        /* Alle Kontobewegungen bis "$reference" werden beruecksichtigt
          Wenn zwischen dem Datum "$timefence" und "$reference" keine Punkte
          hinzugekommen sind, dann verfallen die noch bestehenden Punkte
          nach Abzug der eingeloesten Praemien
         */
        $latestentrydate = $this->getLastEntryDate($reference);
        /* Wenn innerhalb der letzten zwei Jahre keine positiven Buchungen
          vorhanden sind, berechne Anzahl der Punkte, die innerhalb der letzten
          zwei Jahre verfallen sind.
         */
        // if (($latestentrydate > 0) && ($latestentrydate < $timefence)) {
        /* var_dump(date('d.m.Y',$reference),$reference);
         var_dump(date('d.m.Y',$latestentrydate),$latestentrydate);
         var_dump(date('d.m.Y',$timefence),$timefence);*/
        if (($latestentrydate > 0) && ($latestentrydate < $timefence)) {
            $verfallen = $this->calcinvalidatedpoints($timefence, $reference);
        }
        return $verfallen;
    }

    /*
     *
     */


    function invalidatePoints($date = '')
    {
        $abzug = null;
        if ($date != '') {
            list($year, $month, $day) = explode('-', $date);
        } else {
            $now = time();
            $year = date('Y', $now);
            $month = date('m', $now);
        }
        # Punkte verfallen immer zum letzten des Vormonats
        # = 1. des jetzigen Monats 00:00:00 Uhr
        $day = 1;
        #print "Konto::invalidatePoints - Year: $year, Month: $month, Day: $day\n";
        # Berechne nächsten Monatsanfang
        # Year-Wrapping
        $timefence = mktime(0, 0, 0, $month, $day, $year - 2);
        $reference = mktime(0, 0, 0, $month, $day, $year);
        #print "Timefence: $timefence\n";
        $verfallen = $this->calcinvalidatenotrefreshed($timefence, $reference);
        /* Jetziger Saldo darf nicht kleiner als null verden */
        list($nowyear, $nowmonth, $nowday) = explode('-', date('Y-m-d', time()));
        $saldo = $this->getSaldo("$nowyear-$nowmonth-$nowday");
        if ($saldo < $verfallen) {
            $verfallen = $saldo;
        }
        # wenn punkte verfallen, weil zwei Jahre lang keine neuen Punkte
        # hinzukommen, dann beinhaltet der Verfall bereits die Vier-Jahres-Regelung
        if ($verfallen == 0) {
            $timefence = mktime(0, 0, 0, $month, $day, $year - 4);
            $verfallen = $this->calcinvalidatedpoints($timefence, $reference);
            if ($saldo < $verfallen) {
                $verfallen = $saldo;
            }

            if ($verfallen > 0) {
                $user = new user(0, $this->userId);
                print $this->userId . ", " . $user->versnummer . ": Ziehe $verfallen Punkte ab (4 Jahre). Saldo: $saldo\n";
                $abzug = new kontoBewegung();
                $abzug->userId = $this->userId;
                $abzug->kategorie = 0;
                $abzug->unterkategorie = 0;
                $abzug->praemienid = 0;
                $abzug->praemienhmid = 0;
                $abzug->kommentar = 'Punkteverfall nach 4 Jahren.';
                $abzug->datum = $reference;
                $abzug->datumerwerb = "$year-$month-$day";
                $abzug->beschreibung = 'Punkteverfall nach 4 Jahren.';
                $abzug->wert = -$verfallen;
                $abzug->gueltig = 0;
                $this->addKontobewegung($abzug);
            }
        } else {
            $user = new user(0, $this->userId);
            print $this->userId . ", " . $user->versnummer . ": Ziehe $verfallen Punkte ab (2 Jahre). Saldo: $saldo\n";
            $abzug = new kontoBewegung();
            $abzug->userId = $this->userId;
            $abzug->kategorie = 0;
            $abzug->unterkategorie = 0;
            $abzug->praemienid = 0;
            $abzug->praemienhmid = 0;
            $abzug->kommentar = 'Punkteverfall nach zwei Jahren Inaktivitaet';
            #$abzug->datum = mktime(0,0,0,$month,$day,$year);
            $abzug->datum = $reference;
            $abzug->datumerwerb = "$year-$month-$day";
            $abzug->beschreibung = 'Punkteverfall nach zwei Jahren Inaktivitaet';
            $abzug->wert = -$verfallen;
            $abzug->gueltig = 0;
            $this->addKontobewegung($abzug);
        }
        return $abzug;
    }


    /**
     * Invalidates points after four years
     * @param time - a time stamp within the month of the calculation boundary
     * @return points - invalidated points
     * */
    function invalidateafterfouryears()
    {
        $now = time();
        $year = date('Y', $now);
        $month = date('m', $now);
        # Punkte verfallen immer zum letzten des Vormonats
        # = 1. des jetzigen Monats 00:00:00 Uhr
        $day = 1;

        $foryearsago = $year - 4;
        $fouryearsold = mktime(0, 0, 0, $month, $day, $foryearsago);
        $reference = mktime(0, 0, 0, $month, $day, $year);
        $verfallen = calcinvalidatedpoints($fouryearsold, $reference);

        if ($verfallen > 0) {
            $abzug = new kontoBewegung();
            $abzug->userId = $this->userId;
            $abzug->kategorie = 0;
            $abzug->unterkategorie = 0;
            $abzug->praemienid = 0;
            $abzug->praemienhmid = 0;
            $abzug->kommentar = 'Punkteverfall fuer Punkte, die 4 Jahre lang nicht eingeloest wurden';
            $abzug->datum = time();
            $abzug->beschreibung = 'Punkteverfall fuer Punkte, die 4 Jahre lang nicht eingeloest wurden';
            $abzug->wert = -$verfallen;
            $abzug->gueltig = 0;
            $this->addKontobewegung($abzug);

            # print "Verfallen: $verfallen, weil 4 Jahre nicht eingeloest\n";

            $query = "UPDATE kontobewegungen SET gueltig = 0 WHERE datum < $fouryearsold
                  AND userId = '" . $this->userId . "'
                  AND gueltig = 1 and wert > 0";
            $result = dbQuery($query) or
            error("Konnte letzten Eintrag nicht aus der Datenbank lesen: " . dbError());
        }
        return $verfallen;
    }


    /**
     * Calcs points to be invalidated in a given timefence
     *
     * @param timefence - a time stamp within the month of the
     *                    calculation boundary (e.g. now - 2 years)
     * @param reference - end of period for which the invalidated points
     *                    are to be calculated (e.g. beginning of today's month)
     * @return points - invalidated points
     * */
    function calcinvalidatedpoints($timefence, $reference)
    {
        /* Errechne den Saldo zum Zeitpunkt $timefence: Ueberschuss, der Verfallen kann */
        $result = dbQuery("SELECT SUM(wert) AS saldo
                  FROM kontobewegungen WHERE userId = " . $this->userId . "
                  AND geloescht != 1
                  AND datum <= $timefence"); // datum = unix timestamp

        if (!$result)
            die("Konnte Kontostaende nicht lesen: " . dbError());
        $row = dbFetchRow($result);
        $ueberschuss = $row['saldo'];

        /* Wenn kein Ueberschuss vorhanden ist, kann nichts verfallen */
        if ($ueberschuss <= 0) {
            return 0;
        }

        /* Berechne Summe aller eingeloesten Punkte der Zeit nach dem Time Fence */
        $result = dbQuery('SELECT SUM(wert) AS eingeloestepunkte
              FROM kontobewegungen WHERE userId = ' . $this->userId . "
              AND datum > $timefence AND datum <= $reference
              AND wert < 0
              AND geloescht != 1");

        if (!$result)
            die("Konnte Kontostaende nicht lesen: " . dbError());
        $row = dbFetchRow($result);
        $eingeloestepunkte = abs($row['eingeloestepunkte']);

        /* Differenz zwischen dem Uerberschuss und eingeloesten Punkten */
        $verfall = $ueberschuss - $eingeloestepunkte;

        /* Wenn mehr Punkte eingelöst wurden, als Ueberschuss vorhanden war, ist dieser aufgebraucht worden, also 0  */
        if ($verfall < 0) {
            return 0;
        }

        /* Ansonsten ist ein ueberschuss uebrig geblieben, der nun als negativer Kontoeintrag gebucht werden muss */
        $saldo = $this->getSaldo(date('Y-m-d', $reference)); // Diese Funktin braucht leider ein ISO-Datum

        /* Das Folgende ist eventuell buggy. Hier müsste es wahrscheinlich heißen: verfall = min(saldo,verfall) */
        if (($saldo - $verfall) < 0) {
            $verfall = 0;
        } else {
            // Falls durch den Verfall der jetzige Saldo negativ würde,
            // darf ebenfalls nichts verfallen
            $saldo = $this->getSaldo();  // Ohne Parameter: aktueller Saldo
            if (($saldo - $verfall) < 0) {
                $verfall = 0;
            }
        }
        return $verfall;
    }


    /**
     * Delete an entry from the account
     * */
    function deleteKontobewegung($id)
    {
        foreach ($this->kontoBewegungen as $kontobewegung) {
            if ($kontobewegung->id == $id) {
                $kontobewegung->deleteEntry();
            }
        }
    }


    /**
     * get line by line id
     * */
    function getKontobewegungById($id)
    {
        foreach ($this->kontoBewegungen as $kontobewegung) {
            if ($kontobewegung->id == $id) {
                return ($kontobewegung);
            }
        }
        return false;
    }


    /**
     * Wurde bereits eine Praemie bestellt, die
     * nur einmal im Kalenderjahr bestellt werden darf?
     *
     * */
    function praemienlimit($praemienid)
    {
        $year = date('Y', time());
        $startofyear = mktime(0, 0, 0, 1, 1, $year);
        /* Durchsuche alle Praemienbestellungen ab Anfang des Jahres */
        foreach ($this->kontoBewegungen as $kontobewegung) {
            if ($kontobewegung->datum >= $startofyear && $kontobewegung->wert < 0) {
#          if ($kontobewegung->datumerwerb < $startofyear)
                #                       return false;
                $mypraemienid = $kontobewegung->praemienid;
                /* Wenn bereits bestellte Praemie der zu ueberpruefenden Praemie gleicht */
                if ($mypraemienid == $praemienid) {
                    $praemie = new praemie($mypraemienid);
                    if ($praemie->anzahlprojahr > 0) {
                        return true;
                    }
                }
            }
        }
        return false;
    }


    /**
     * Geldpraemienlimit
     *
     *
     * */
    function geldpraemienlimit($praemienid)
    {
        $praemie = new praemie($praemienid);
        if (!$praemie->geldpraemie) {
            return false;
        }
        $query = "SELECT id FROM praemien WHERE geldpraemie = 1";
        $result = dbQuery($query);
        while ($row = dbFetchRow($result)) {
            $praemienid = $row['id'];
            if ($this->praemienlimit($praemienid)) {
                return true;
            }
        }
        return false;
    }


    /**
     * Wurde bereits ein Bonus gebucht, der nur
     * nur alle x monate vergeben werden darf?
     * */
    function bonuslimit($id, $datumerwerb = '')
    {
        // Heute
        $year = date('Y', time());
        $month = date('m', time());
        $day = 1;
        $unterkategorie = unterkategorie::getUnterkategorieById($id);
        $vergabemonate = $unterkategorie->vergabemonate;
        $anzahlprojahr = $unterkategorie->anzahlprojahr;
        if ($vergabemonate == 0) {
            // Check Anzahlprojahr
            if ($anzahlprojahr == 0) {
                return false;
            }

            /* Kein Erwerbsdatum eingetragen - nehme aktuelles Jahr */
            if ($datumerwerb == '') {
                $year = date('Y');
                $datumerwerb = "$year-01-01";
            } else {
                list($year, $month, $day) = explode('-', $datumerwerb);
            }

            $start = mktime(0, 0, 0, 1, 1, $year);
            $end = mktime(23, 59, 59, 12, 31, $year);
            $startdate = date('Y-m-d', $start);
            $enddate = date('Y-m-d', $end);

            foreach ($this->kontoBewegungen as $kontobewegung) {
                if (($kontobewegung->unterkategorie == $id && $kontobewegung->wert > 0)) {
                    // Falls datumerwerb eingetragen ist, pruefe dieses Feld
                    if ($kontobewegung->datumerwerb >= '0001-01-01') {
                        if ($enddate >= $kontobewegung->datumerwerb && $startdate <= $kontobewegung->datumerwerb) {
                            $count++;
                        }
                    } else {
                        // print "Eintragungsdatum wird geprueft\n";
                        if ($kontobewegung->datum >= $start && $kontobewegung->datum <= $end) {
                            // sonst gilt eintragungsdatum (timestamp :[ )
                            $count++;
                        }
                    }
                }
            }
            if ($count >= $anzahlprojahr) {
                return true;
            }
            return false;
        }


        # alle 12 Monate: einmal im Kalenderjahr
        # Start: Januar
        if ($vergabemonate == 12) {
            $startmonth = '01';
        }
        # alle 6 Monate: einmal im Halbjahr
        # Start: Januar oder July
        if ($vergabemonate == 6) {
            $startmonth = ($month < 7)
                ? '01'
                : '07';
        }
        // print "Startmonat: $startmonth\n";
        $start = mktime(0, 0, 0, $startmonth, 1, $year);
        foreach ($this->kontoBewegungen as $kontobewegung) {
            if (($kontobewegung->unterkategorie == $id)) {
                # Falls datumerwerb eingetragen ist, pruefe dieses Feld
                if ($kontobewegung->datumerwerb >= '0001-01-01') {
                    if ("$year-$startmonth-01" <= $kontobewegung->datumerwerb) {
                        return true;
                    }
                } else {
                    // print "Eintragungsdatum wird geprueft\n";
                    if ($kontobewegung->datum >= $start) {
                        // sonst gilt eintragungsdatum (timestamp :[ )
                        return true;
                    }
                }
            }
        }
        return false;
    }

    /*
     * Ermittelt, ob Teilnehmer Mindestpunkteanzahl hat,
     * um Praemieeinzuloesen
     */


    function hasminbestellpunkte()
    {
        if (!$this->userId || $this->userId <= 0) {
            return false;
        }
        $mySaldo = $this->getSaldo();
        /* Wenn Teilnehmer 500 Punkte oder mehr hat,
          darf er eine Praemie einloesen */
        if ($mySaldo >= 500) {
            return true;
        }

        /* Wenn bereits Spende oder Praemienbestellung erfolgt ist,
          reichen 250 Punkte */
        $query = "SELECT userId FROM kontobewegungen
              WHERE userId = " . $this->userId . "
              AND geloescht != 1
              AND wert < 0
              AND (beschreibung LIKE 'Bestellung%'
                      OR beschreibung LIKE 'Spende an%')";
        $result = dbQuery($query) or
        error("Cannot commit query " .
            __CLASS__ . ":" . __FUNCTION__ . " '$query': " .
            dbError());
        if (dbNumRows($result) > 0) {
            /* Hat bereits Punkte eingeloest */
            if ($mySaldo >= 250) {
                return true;
            }
        }
        return false;
    }


    public function getPraemienbestellungen($start, $end)
    {
        $this->kontoBewegungen = array();
        $query = "SELECT * FROM kontobewegungen
              WHERE userId = " . $this->userId . "
              AND wert < 0
              AND geloescht != 1
              AND datum >= $start AND datum <= $end
              AND beschreibung NOT LIKE '%Punkteverfall%'";
        $result = dbQuery($query) or error("Cannot select praemienbestellungen");
        while ($row = dbFetchRow($result)) {
            $bewegung = new kontoBewegung($row);
            array_push($this->kontoBewegungen, $bewegung);
        }

        /*
          "userId, count(userId) AS anzahl, abs(sum(wert)) AS summe
          FROM kontobewegungen
          group by userId
          order by anzahl DESC";
         */
    }


    public function toPdf($from, $to)
    {
        ob_clean();
        // Verfall
        $today = date('Y-m-d', time());
        list($year, $month, $day) = explode('-', $today);
        $refDate = "$year-$month-15";
        $refTimestamp = strtotime('+1 months ago', strtotime($refDate));
        $daysinmonth = date("t", $refTimestamp);
        //$enddate = date('Y-m-' . $daysinmonth,$refTimestamp);
        $enddate = date('Y-m-15', $refTimestamp);


        /* Ersten des nächsten und übernächsten Monats berechnen */
        list($year, $month) = explode('-', $enddate);
        $refDate = "$year-$month-15";
        $VerfallDatum0 = date('01.m.Y',
            strtotime('+1 months', strtotime($refDate)));
        $VerfallDatum1 = date('01.m.Y',
            strtotime('+2 months', strtotime($refDate)));
        $VerfallDatum2 = date('01.m.Y',
            strtotime('+3 months', strtotime($refDate)));
        $VerfallDatum3 = date('01.m.Y',
            strtotime('+4 months', strtotime($refDate)));

        $startdate = date('Y-m-16', strtotime('+3 months ago', $refTimestamp));
        $invalidpoints = $this->calcinvalidatenext($enddate);

        $Verfall0 = $invalidpoints[0] + 0;
        $Verfall1 = $invalidpoints[1] + 0;
        $Verfall2 = $invalidpoints[2] + 0;
        $Verfall3 = $invalidpoints[3] + 0;


        $user = new User('', $this->userId);
        $subject = 'Kontoauszug für ' . $user->vorname . ' ' . $user->name;
        if ($user->versnummerneu != '') {
            $subject .= ' (' . $user->versnummerneu . ')';
        } else {
            $subject .= ' (' . $user->versnummer . ' ' . $user->rechtskreis . ')';
        }
        $subject = utf8_decode($subject);

        $this->_pdf = new FPDF('P', 'cm', 'A4');
        /* FALSE in Textparametern meint kein UTF8, aendern fuer UTF8 Ausgaben aus der DB? */
        $this->_pdf->SetAuthor(utf8_decode('SECURVITA Healthmiles'), FALSE);
        $this->_pdf->SetSubject($subject, FALSE);
        $this->_pdf->SetTitle($subject, FALSE);
        $this->_pdf->SetDisplayMode('fullwidth', 'continuous');

        $this->_pdf->SetMargins(2.2, 5, 2.5);
        $this->_pdf->SetAutoPageBreak(TRUE, 3);
        $this->_pdf->SetFont('Arial', '', 10);
        $this->_pdf->AddPage();

        $this->_pdf->SetFont('', 'B', 8);
        $this->_pdf->SetXY(2.3, 1);
        $this->_pdf->Cell(13, 0.5, $subject . ' vom ' . date('Y-m-d', time()),
            0, 1, 'L');
        $this->_pdf->SetLeftMargin(2.3);

        // keine Anzeige von Punkteverfall im Kontoauszug
        /*
        $this->_pdf->SetFont('', 'B');
        $this->_pdf->Write(0.4, "\n" . $Verfall0);
        $this->_pdf->SetFont('', '');
        $this->_pdf->Write(0.4, utf8_decode($this->Verfalllabel . $VerfallDatum1));

        $this->_pdf->SetFont('', 'B');
        $this->_pdf->Write(0.4, "\n" . $Verfall1);
        $this->_pdf->SetFont('', '');
        $this->_pdf->Write(0.4,
            utf8_decode($this->Verfalllabel . $VerfallDatum2));

        $this->_pdf->SetFont('', 'B');
        $this->_pdf->Write(0.4, "\n" . $Verfall2);
        $this->_pdf->SetFont('', '');
        $this->_pdf->Write(0.4,
            utf8_decode($this->Verfalllabel . $VerfallDatum3));
*/
        /* Verfall 3
        $this->_pdf->SetFont('', 'B');
        $this->_pdf->Write(0.4, "\n" . $Verfall3);
        $this->_pdf->SetFont('', '');
        $this->_pdf->Write(0.4,
            utf8_decode($this->Verfalllabel . $VerfallDatum3));
*/
        $this->_pdf->Write(0.4, "\n\n");
        /* Boxen mit Ueberschriften */
        $this->_pdf->SetFont('', 'B', 8);
        $this->_pdf->SetLeftMargin(2.3);
        $this->_pdf->Cell(1.7, 0.5, "Buchung", 1, 0, 'L');
        $this->_pdf->Cell(1.7, 0.5, "Erwerb", 1, 0, 'L');
        //$this->_pdf->Cell(10.8, 0.5, "Beschreibung", 1, 0, 'L');
        $this->_pdf->Cell(5.65, 0.5, "Beschreibung", 1, 0, 'L');
#          $this->_pdf->Cell(5.65, 0.5, "Kommentar", 1, 0, 'L');
        $this->_pdf->Cell(1.2, 0.5, "Punkte", 1, 1, 'R');
        $this->_pdf->SetFont('', '', 8);

        $this->_pdf->SetFillColor(230, 230, 230);

        $stopDate = strtotime('-10 years');
        $AnzahlZeilen = 1;
        foreach ($this->kontoBewegungen as $kontobewegung) {
            if ($kontobewegung->wert == 0 || $kontobewegung->datum < $stopDate)
                continue;
            $y = $this->_pdf->GetY();
            $x = 5.7;
            $this->_pdf->SetXY($x, $y);
            $beschreibung = trim($kontobewegung->beschreibung);
            $kommentar = trim($kontobewegung->kommentar);
            if (strlen($beschreibung) > 77) {
                $beschreibung = substr($beschreibung, 0, 77) . "...";
            }
            $this->_pdf->MultiCell(5.65, 0.5, utf8_decode($beschreibung), 1, 'L',
                ($AnzahlZeilen % 2 != 0));
#              $x += 5.65;
#              $height = $this->_pdf->GetY() - $y;
#              $this->_pdf->SetXY($x,$y);
#              $this->_pdf->MultiCell(5.65, $height, $kommentar, 1,  'L', ($AnzahlZeilen % 2 != 0));
            $x += 5.65;
            $height = $this->_pdf->GetY() - $y;
            $this->_pdf->SetXY($x, $y);
            $this->_pdf->Cell(1.2, $height, $kontobewegung->wert, 1, 0, 'R',
                ($AnzahlZeilen % 2 != 0));
            $this->_pdf->SetXY(2.3, $y);
            $this->_pdf->Cell(1.7, $height,
                date("d.m.Y", $kontobewegung->datum), 1, 0, 'L',
                ($AnzahlZeilen % 2 != 0));
            $this->_pdf->SetXY(4, $y);
            $this->_pdf->Cell(1.7, $height,
                convertdatefromsql($kontobewegung->datumerwerb),
                1, 1, 'L',
                ($AnzahlZeilen % 2 != 0));
            $AnzahlZeilen++;
            $y = $this->_pdf->GetY();
            if ($y > 25) {
                $this->_pdf->AddPage();
                $this->_pdf->SetXY(2.3, 4.6);
            }
        }
        $this->_pdf->SetFont('', 'B', 8);
        $this->_pdf->Cell(1.7, 0.5, "Saldo", 1, 0, 'L');
        $this->_pdf->Cell(1.7, 0.5, "", 1, 0, 'L');
        $this->_pdf->Cell(5.65, 0.5, "", 1, 0, 'L');
        $this->_pdf->Cell(1.2, 0.5, $this->getSaldo(), 1, 0, 'R');

        $this->_pdf->Close();
        $this->_pdf->Output('kontoauszug_' . utf8_decode($user->vorname) . '_' . utf8_decode($user->name) . '_' . date('Y-m-d',
                time()) . '.pdf',
            'I');
    }
}

