#!/usr/local/bin/perl -w

# (C) 2001 Christian Jacobi
# (C) 2001 Christoph Berg
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

use lib '/home/tante/tet-nt';
use tante_db;
use tet_window;
use Tk;
use POSIX qw(strftime);

$VERSION = '$Id: tet,v 1.14 2002/07/29 12:49:04 tesh Exp $';
$NAME = "Tante Emma Tool";


## Hilfsfunktionen ##

# Umrechnungen
my $dmeuro = 1.95583;
sub euro2dm {
	my $euro = shift;
	return $euro * $dmeuro;
}
sub dm2euro {
	my $dm = shift;
	return $dm / $dmeuro;
}

# betrag (integer = cents) -> string
sub betrag2string_euro {
	my $betrag = shift;
	return sprintf "%.2f EUR", $betrag/100.0;
}
sub betrag2string_dm {
	my $betrag = shift;
	return sprintf "%.2f DM", euro2dm($betrag)/100.0;
}

# string -> betrag (integer = cents)
sub string2betrag {
	my $betrag = shift;
	$betrag =~ s/,/./;
	my $b = 0;

	if ($betrag =~ /^-/) {
		$output = "Betrag darf nicht negativ sein.";
		return 0;
	}

	if ($betrag =~ /^(\d+)\.(\d\d) *EUR$/i) { # 1.23 EUR
		$b = 100 * $1 + $2;
		$output = "Betrag darf nicht Null sein." if $b == 0;
		return $b;
	}
	if ($betrag =~ /^(\d+) *EUR$/i) { # 1 EUR
		$b = 100 * $1;
		$output = "Betrag darf nicht Null sein." if $b == 0;
		return $b;
	}
	if ($betrag =~ /^(\d+)\.(\d\d)? *DM$/i) { # 1.23 DM
		$b = 100 * $1 + $2;
		$b = int(sprintf "%.0f", dm2euro($b));  # Runden in Perl macht keinen Spaß
		$output = "Betrag darf nicht Null sein." if $b == 0;
		return $b;
	}
	if ($betrag =~ /^(\d+) *DM$/i) { # 1 DM
		$b = 100 * $1;
		$b = int(sprintf "%.0f", dm2euro($b));  # Runden in Perl macht keinen Spaß
		$output = "Betrag darf nicht Null sein." if $b == 0;
		return $b;
	}
	$output = "Ungültiger Betrag: `$betrag' (DM/EUR muß angegeben werden)";
	return 0;
}

# logging
sub writelog {
	my $msg = shift;
	my $logfilename = "/home/tante/log/tesh-nt.log";

	open L, ">> $logfilename" or die "$logfilename: $!";
	print L strftime("%d/%m/%Y %T", localtime);
	print L " $0\[$$\]: $msg\n";
	close L;
}

# Felder für Überweisungs-Empfänger ausfüllen
sub info2 {
	return 0 if $inp_an_nickname eq "";
	my $result = do_query("SELECT vorname, nachname, kid, guthaben FROM kunden WHERE nickname = '$inp_an_nickname'");

	my ($an_vorname, $an_nachname);
	if($result->ntuples() == 1) {
		($an_vorname, $an_nachname, $an_kid, $an_kunde_guthaben) = $result->fetchrow();
		$inp_an_name = "$an_vorname $an_nachname";
		$inp_an_guthaben_euro = betrag2string_euro($an_kunde_guthaben);
		$inp_an_guthaben_dm = betrag2string_dm($an_kunde_guthaben);
		return 1;
	}
	$output = "Keinen Benutzer `$inp_an_nickname' gefunden.";
	return 0;
}


## TET-Funktionen (Tk-Callback-Handler) ##

sub create_user {
	if($inp_nickname eq "") {
		$output = "Kein Benutzername angegeben!";
		return;
	}

	my $check = do_query("SELECT * FROM kunden WHERE nickname = '$inp_nickname'");
	if($check->ntuples() != 0) {
		$output = "Nickname existiert schon!";
		return;
	}

	my $new_kid;
	my $result = do_query("SELECT kid FROM kunden ORDER BY kid DESC LIMIT 1");
	($new_kid) = $result->fetchrow;

	++$new_kid;
	do_query("INSERT INTO kunden (vorname, nachname, nickname, kid, email, pw, guthaben, created, last_contact) ".
		 "VALUES ('$inp_vorname', '$inp_nachname', '$inp_nickname', $new_kid, '$inp_email', '*', 0, 'now', 'now')");
	$output = "Kunde angelegt.";
}

sub delete_user {
	if($inp_nickname eq "") {
		$output = "Kein Benutzername angegeben!";
		return;
	}

	$output = "Noch nicht implementiert.";
}

sub change_pw {
	if($inp_nickname eq "") {
		$output = "Kein Benutzername angegeben!";
		return;
	}
	return unless info();

	if ($inp_pw1 ne $inp_pw2) {
		$output = "Die Paßwörter sind verschieden.";
		return;
	}
	if (length $inp_pw1 < 5) {
		$output = "Das Paßwort muß mindestens 5 Zeichen haben.";
		return;
	}

	my $pw = crypt $inp_pw1, $inp_nickname;
	do_query("UPDATE kunden SET pw = '$pw' where kid = $inp_kid");
	$output = "Paßwort geändert.";
	writelog("$inp_nickname ($inp_kid) hat neues Passwort `$pw'");
}

# Felder ausfüllen, 0: Fehler, 1: Ok
sub info {
	return 0 if $inp_nickname eq "";
	my $result = do_query("select * from kunden where nickname = '$inp_nickname'");
	$output = "";

	if($result->ntuples() == 1) {
		$output = "";
		($inp_vorname, $inp_nachname, $inp_nickname, $inp_kid,
			$inp_email, $inp_pw, $inp_created, $inp_last_contact,
			$inp_locked, $kunde_guthaben, $inp_bemerkung) =
			$result->fetchrow();
		$inp_name = "$inp_vorname $inp_nachname";
		$inp_guthaben_euro = betrag2string_euro($kunde_guthaben);
		$inp_guthaben_dm = betrag2string_dm($kunde_guthaben);
		return 1;
	}
	$output = "Keinen Benutzer `$inp_nickname' gefunden.";
	return 0;
}

sub info_change_commit {
	if($inp_nickname eq "") {
		$output = "Kein Benutzername angegeben!";
		return;
	}

	do_query("UPDATE kunden SET vorname = '$inp_vorname', nachname = '$inp_nachname', email = '$inp_email', locked = '$inp_locked', bemerkung = '$inp_bemerkung' where kid = $inp_kid");
	$output = "Daten geändert.";
	writelog("$inp_nickname ($inp_kid) hat neue Daten `$inp_vorname $inp_nachname, $inp_email, locked: $inp_locked, bemerkung: $inp_bemerkung'");
}

sub einzahlen {
	$output = "";
	return if $inp_nickname eq "";
	return unless info();

	my $b = string2betrag($inp_betrag);
	return if($b == 0);

	my $zeit = localtime;
	my $result = do_query(
	"INSERT INTO buchungen (kid,aid,zeit,betrag,guthaben_neu,bemerkung,zahlung) VALUES ($inp_kid, 0, '$zeit', $b, ". ($kunde_guthaben+$b) .", '$inp_betreff', 't');" .
	"UPDATE kunden SET guthaben = guthaben+$b WHERE nickname = '$inp_nickname'");
	#if($result->ntuples != 1) {
	#	$output = "Fehler beim Eintragen.";
	#	return;
	#}
	info();  # hier wird $kunde_guthaben geändert!
	$output = betrag2string_euro($b) . " eingezahlt.";
	writelog("$inp_nickname ($inp_kid) Einzahlung `$inp_betreff' Betrag `". betrag2string_euro($b) ."' Neues Guthaben `$kunde_guthaben'");
}

sub abbuchen {
	$output = "";
	return if $inp_nickname eq "";
	return unless info();

	my $b = - string2betrag($inp_betrag); # minus: abbuchen
	return if($b == 0);

	my $zeit = localtime;
	my $result = do_query(
	"INSERT INTO buchungen (kid,aid,zeit,betrag,guthaben_neu,bemerkung,zahlung) VALUES ($inp_kid, 0, '$zeit', $b, ". ($kunde_guthaben+$b) .", '$inp_betreff', 't');" .
	"UPDATE kunden SET guthaben = guthaben+$b WHERE nickname = '$inp_nickname'");
	#if($result->ntuples != 1) {
	#	$output = "Fehler beim Eintragen.";
	#	return;
	#}
	info();  # hier wird $kunde_guthaben geändert!
	$output = betrag2string_euro(-$b) . " abgebucht.";
	writelog("$inp_nickname ($inp_kid) Einzahlung `$inp_betreff' Betrag `". betrag2string_euro($b) ."' Neues Guthaben `$kunde_guthaben'");
}

sub ueberweisen {
	$output = "";
	return if $inp_nickname eq "";

	return unless info();
	if(!info2()) {
		$output = "Empfänger muß eingegeben werden.";
		return;
	}
	if($inp_kid == $an_kid) {
		$output = "Empfänger und Empfänger sind gleich.";
		return;
	}

	my $b = string2betrag($inp_betrag);
	return if($b == 0);

	my $zeit = localtime;
	my $result = do_query(
	"INSERT INTO buchungen (kid,aid,zeit,betrag,guthaben_neu,bemerkung,zahlung) VALUES ($inp_kid, 0, '$zeit', -$b, ". ($kunde_guthaben-$b) .", 'Ueberweisung an $inp_an_nickname: $inp_betreff', 't');" .
	"INSERT INTO buchungen (kid,aid,zeit,betrag,guthaben_neu,bemerkung,zahlung) VALUES ($an_kid, 0, '$zeit', $b, ". ($an_kunde_guthaben+$b) .", 'Ueberweisung von $inp_nickname: $inp_betreff', 't'); " .
	"UPDATE kunden SET guthaben=guthaben-$b WHERE kid=$inp_kid; " .
	"UPDATE kunden SET guthaben=guthaben+$b WHERE kid=$an_kid;");
	#if($result->ntuples != 3) {
	#	$output = "Fehler beim Eintragen.";
	#	return;
	#}
	info();  # hier wird $kunde_guthaben geändert!
	info2(); # hier wird $an_kunde_guthaben geändert!
	$output = betrag2string_euro($b) ." überwiesen.";
	writelog("$inp_nickname ($inp_kid) `Ueberweisung an $inp_an_nickname: $inp_betreff' Betrag `". betrag2string_euro(-$b) ."' Neues Guthaben `". betrag2string_euro($kunde_guthaben) ."'");
	writelog("$inp_an_nickname ($an_kid) `Ueberweisung von $inp_nickname: $inp_betreff' Betrag `". betrag2string_euro( $b) ."' Neues Guthaben `". betrag2string_euro($an_kunde_guthaben) ."'");
}

sub ueberweisung_info {
	info();
	info2();
}

sub tauschen {
	my $tmp_nickname;
	$tmp_nickname = $inp_nickname;
	$inp_nickname = $inp_an_nickname;
	$inp_an_nickname = $tmp_nickname;
	ueberweisung_info();
}

sub buchungen {
	$output = "";
	my ($b, $result);

	if ($inp_nickname eq "") {
		$result = do_query("SELECT nickname, a.name, zeit, b.bemerkung, betrag, guthaben_neu FROM kunden k, artikel a, buchungen b WHERE k.kid = b.kid and a.aid = b.aid ORDER BY zeit DESC LIMIT $inp_limit");
	} else {
		$result = do_query("SELECT nickname, a.name, zeit, b.bemerkung, betrag, guthaben_neu FROM kunden k, artikel a, buchungen b WHERE nickname = '$inp_nickname' and k.kid = b.kid and a.aid = b.aid ORDER BY zeit DESC LIMIT $inp_limit");
	}
	$buchungen_output = "";
	#while (@l = ($kid, $aid, $zeit, $bemerkung, $zahlung, $betrag, $guthaben_neu) = $result->fetchrow()) {
	while (@l = $result->fetchrow()) {
		@l = map { s/^(-?\d+)$/sprintf "%+.2f EUR", $1\/100.0/e; $_; } @l;
		$buchungen_output = (join "\t", @l) . "\n$buchungen_output"; # rückwärts anzeigen
	}
}

sub summe {
	$output = "";
	my ($b, $result, $sum);

	$result = do_query("SELECT nickname, zeit, b.bemerkung, betrag FROM kunden k, buchungen b WHERE k.kid = b.kid and b.aid = 0 and zeit > current_timestamp - interval '$inp_timeinterval' ORDER BY zeit DESC limit 100");
	$summe_output = ""; $sum = 0;
	while (@l = $result->fetchrow()) {
		$sum += $l[3];
		@l = map { s/^(-?\d+)$/sprintf "%+.2f EUR", $1\/100.0/e; $_; } @l;
		$summe_output = (join "\t", @l) . "\n$summe_output"; # rückwärts anzeigen
	}
	$sum =~ s/^(-?\d+)$/sprintf "%+.2f EUR", $1\/100.0/e;
	$summe_output .= "-----------\nSumme: $sum";
}

sub schuldner {
	$output = "";
	my ($b, $result, $sum);

	my $gr = string2betrag($inp_grenze);
	return if $gr == 0;

	$result = do_query("SELECT nickname, vorname, nachname, guthaben, last_contact FROM kunden k WHERE guthaben < -$gr ORDER BY guthaben LIMIT 100");

	$schuldner_output = ""; $sum = 0;
	while (@l = $result->fetchrow()) {
		$sum += $l[3];
		@l = map { s/^(-?\d+)$/sprintf "%+.2f EUR", $1\/100.0/e; $_; } @l;
		$schuldner_output = "$schuldner_output\n" . (join "\t", @l);
	}
	$sum =~ s/^(-?\d+)$/sprintf "%+.2f EUR", $1\/100.0/e;
	$schuldner_output .= "\n-----------\nSumme: $sum";
}

sub exit_tet {
	$output = "Auf Wiedersehen.";
	exit 0;
}

sub restart_tet {
	exec $0;
}


## Init-Kram ##

$output = "$NAME $VERSION";
$inp_betrag = "5 EUR";
$inp_betreff = "Einzahlung";
$inp_nickname = "";
$inp_an_nickname = "";
$inp_limit = 10;
$inp_timeinterval = "1h";
$inp_grenze = "5 EUR";

open_db();
init_window();

MainLoop();
