Out of memory

bapiede wrote on Mon Aug  7 13:41:03 MEST 2006:
Hi,
after upgrading to Eclipse 3.2 and EPIC 0.4 some Perl Skripts couldn't be
opened.

Only "large" file are affected (example: 2574 lines). Small files could
be opened as before.

Eclipse error:
java.lang.OutOfMemoryError: Java heap space

Thanks to everybody!

Regards, Christian
jploski wrote on Mon Aug  7 13:47:38 MEST 2006:
I also had OutOfMemory problems after upgrading to Eclipse 3.2, however,
unrelated to EPIC. Adding the following arguments to Eclipse's command line
helped:

-vmargs -XX:MaxPermSize=128m

You can also try with -Xmx256M which extends the memory available to the
Java VM to 256 MB.
jgangemi wrote on Mon Aug  7 14:41:36 MEST 2006:
this may also be related to a jvm bug, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=92250.

supposedly sun's jre 1.5.0_07 helps address part of this issue.
jgangemi wrote on Mon Aug  7 14:47:41 MEST 2006:
actually, is this error prompting a popup dialog asking you to restart eclipse,
or does the error appear in the editor window? 

it may that the perl file contains syntax the parser doesn't understand
(this was the case w/ perl format syntax not in the previous release). 

if you're getting the error in the editor window itself, would it be possible
for you to attach the file causing exhibitting the problem?
bapiede wrote on Mon Aug  7 15:24:12 MEST 2006:
The error message appears in the editor window

Here's the Perl Code:

#!/usr/bin/perl
#
# Kassen-Terminal
#

use strict;
use Gtk2 "-init";
use Gtk2::GladeXML;
use Gtk2::SimpleList;
use DBI;
use utf8;
use warnings;
use Date::Manip;

use lib "../lib";
use pos_common;
use pos_print;

my $version    = "0.2.0";
my $lastchange = "31.05.06";

# Konfig einlesen
our %config = pos_read_config("/srv/pos/etc/client.conf");

# Datenbank Verbindung
our $db = pos_db_connect();

#
#
# Datenbank Abfragen vorbereiten
#
#

my $get_funktion =
  $db->prepare("SELECT funktion FROM stamm_hotkeys WHERE gruppe=? AND pos=?;");
my $get_artikel =
  $db->prepare(
	"SELECT artbez, eigpreis, mwst, oem FROM stamm_artikel WHERE ttnr=?;");

#
#
# GUI initialisieren
#
#

my $gladexml = Gtk2::GladeXML->new("glade/terminal.glade");
$gladexml->signal_autoconnect_from_package("main");

sub gtk_main_quit {
	Gtk2->main_quit;
}

#
#
# globale Variablen
#
#

# Tooltipps
my $tooltip = Gtk2::Tooltips->new;

# Welches Zahlen wurden eingebenen
# erscheinen im Display
my @zahlen;

# der Hash speichert den Bon
my %bon;

# Die Gruppe der Hotkey-Tasten die zuerst angezeigt werden soll
my $gruppe = "start";

# wer ist der aktuelle Verkäufer
my $uid = 0;

# und sein Name
my $username = "";
my $longname = "";

# Bar Betrag
my %bar;

# Karten Betrag
my %karte;

# Kunden-Nummer
my %kunde;

# Rabatt
my %rabatt;

# mit Rechnung bezahlter Betrag
my %calculaterechnung;
my %rechnung;

# mit Gutschein bezahlter Betrag
my %gutschein;

# und die Gutschein-Nummer
my %gutscheinnr;

# wird eine Bonkopie erstellt, dann steht in diesem Hash die entsprechende
Bon-ID
my %bonid;

# Stückelung für Kassen-Ist
my %kassenist = (
	'1cent' => {
		'label' => 'Wie viele 1 Cent Münzen befinden sich in der Kasse',
		'value' => '0'
	},
	'2cent' => {
		'label' => 'Wie viele 2 Cent Münzen befinden sich in der Kasse',
		'value' => '0'
	},
	'5cent' => {
		'label' => 'Wie viele 5 Cent Münzen befinden sich in der Kasse',
		'value' => '0'
	},
	'10cent' => {
		'label' => 'Wie viele 10 Cent Münzen befinden sich in der Kasse',
		'value' => '0'
	},
	'20cent' => {
		'label' => 'Wie viele 20 Cent Münzen befinden sich in der Kasse',
		'value' => '0'
	},
	'50cent' => {
		'label' => 'Wie viele 50 Cent Münzen befinden sich in der Kasse',
		'value' => '0'
	},
	'1euro' => {
		'label' => 'Wie viele 1 Euro Münzen befinden sich in der Kasse',
		'value' => '0'
	},
	'2euro' => {
		'label' => 'Wie viele 2 Euro Münzen befinden sich in der Kasse',
		'value' => '0'
	},
	'5euro' => {
		'label' => 'Wie viele 5 Euro Scheine befinden sich in der Kasse',
		'value' => '0'
	},
	'10euro' => {
		'label' => 'Wie viele 10 Euro Scheine befinden sich in der Kasse',
		'value' => '0'
	},
	'20euro' => {
		'label' => 'Wie viele 20 Euro Scheine befinden sich in der Kasse',
		'value' => '0'
	},
	'50euro' => {
		'label' => 'Wie viele 50 Euro Scheine befinden sich in der Kasse',
		'value' => '0'
	},
	'100euro' => {
		'label' => 'Wie viele 100 Euro Scheine befinden sich in der Kasse',
		'value' => '0'
	},
	'200euro' => {
		'label' => 'Wie viele 200 Euro Scheine befinden sich in der Kasse',
		'value' => '0'
	},
	'500euro' => {
		'label' => 'Wie viele 500 Euro Scheine befinden sich in der Kasse',
		'value' => '0'
	}
);

# alle möglichen Stückelungen
#my @stueckelung = (
#	'1cent',   '2cent',   '5cent', '10cent', '20cent', '50cent',
#	'1euro',   '2euro',   '5euro', '10euro', '20euro', '50euro',
#	'100euro', '200euro', '500euro'
#);
# Reihenfolge geändert: 500 € -> 1 Cent
my @stueckelung = (
	'500euro', '200euro', '100euro', '50euro', '20euro', '10euro',
	'5euro',   '2euro',   '1euro',   '50cent', '20cent', '10cent',
	'5cent',   '2cent',   '1cent'
);

# wie oft wurde das Kassen-Ist korrigiert
my $kassenistkorrektur = 0;

# Welche Stückelung wird gerade abgefragt?
my $aktstueckelung = 0;

# Debug Code
##print $_ foreach (keys %kassenist);

#
#
# Glade Widgets
#
#

# Hauptfenster
my $terminal = $gladexml->get_widget("Terminal");

# Fehlermeldungen
my $dialogFehler = $gladexml->get_widget("dialogFehler");
my $labelFehler  = $gladexml->get_widget("labelFehler");

# Informationen
my $dialogInfo = $gladexml->get_widget("dialogInfo");
my $labelInfo  = $gladexml->get_widget("labelInfo");

# und andere:
my $dialogQuit         = $gladexml->get_widget("dialogQuit");
my $labelQuit          = $gladexml->get_widget("labelQuit");
my $aboutDialog        = $gladexml->get_widget("aboutdialog");
my $buttonOk           = $gladexml->get_widget("okbutton1");
my $buttonCancel       = $gladexml->get_widget("cancelbutton1");
my $window             = $gladexml->get_widget("Terminal");
my $button1            = $gladexml->get_widget("button1");
my $button2            = $gladexml->get_widget("button2");
my $button3            = $gladexml->get_widget("button3");
my $button4            = $gladexml->get_widget("button4");
my $button5            = $gladexml->get_widget("button5");
my $button6            = $gladexml->get_widget("button6");
my $button7            = $gladexml->get_widget("button7");
my $button8            = $gladexml->get_widget("button8");
my $button9            = $gladexml->get_widget("button9");
my $button0            = $gladexml->get_widget("button0");
my $buttonKomma        = $gladexml->get_widget("buttonKomma");
my $buttonEnter        = $gladexml->get_widget("buttonEnter");
my $buttonPlus         = $gladexml->get_widget("buttonPlus");
my $display            = $gladexml->get_widget("display");
my $beenden            = $gladexml->get_widget("buttonQuit");
my $listebestandwidget = $gladexml->get_widget("treeviewBestand");
my $listebestand;    # wird in Funktion artikel_fill definiert
my $listebonwidget = $gladexml->get_widget("treeviewBon");
my $listebon;        # wird in Funktion create_bon definiert
my $listezbon;       # wird in Funktion create_zbon definiert
my $listezbonwidget = $gladexml->get_widget("treeviewZBon");
my $displayNetto    = $gladexml->get_widget("displayNetto");
my $displayMwst     = $gladexml->get_widget("displayMwSt");
my $displaySumme    = $gladexml->get_widget("displaySumme");
my $labelZurueck    = $gladexml->get_widget("labelZurueck");
my $displayZurueck  = $gladexml->get_widget("displayZurueck");
my $displayGegeben  = $gladexml->get_widget("displayGegeben");
my $dialogSonstige  = $gladexml->get_widget("dialogSonstige");

# Dialog Z-Bon
my $labelverkaeufe = $gladexml->get_widget("labelverkaeufe");
my $labelUmsatz    = $gladexml->get_widget("labelUmsatz");
my $labelMaxUmsatz = $gladexml->get_widget("labelMaxUmsatz");
my $labelArtikel   = $gladexml->get_widget("labelArtikel");
my $labelBar       = $gladexml->get_widget("labelBar");
my $labelKarte     = $gladexml->get_widget("labelKarte");
my $labelRechnung  = $gladexml->get_widget("labelRechnung");
my $labelGutschein = $gladexml->get_widget("labelGutschein");
my $dialogZbon     = $gladexml->get_widget("dialogZbon");

# Dialog Stammkunde
my $dialogKunde         = $gladexml->get_widget("dialogKunde");
my $dialogKundeErgebnis = $gladexml->get_widget("dialogKundeErgebnis");
my $displayKunde        = $gladexml->get_widget("displayKunde");

# Dialog NeuerKunde
my $dialogNeuerKunde      = $gladexml->get_widget("dialogNeuerKunde");
my $labelNKPerson         = $gladexml->get_widget("labelNKPerson");
my $labelNKFirma          = $gladexml->get_widget("labelNKFirma");
my $labelNKAnschrift      = $gladexml->get_widget("labelNKAnschrift");
my $labelNKTelefon        = $gladexml->get_widget("labelNKTelefon");
my $labelNKDurchwahl      = $gladexml->get_widget("labelNKDurchwahl");
my $labelNKFax            = $gladexml->get_widget("labelNKFax");
my $labelNKeMail          = $gladexml->get_widget("labelNKeMail");
my $labelNKDrucker        = $gladexml->get_widget("labelNKDrucker");
my $labelNKDruckerDesc    = $gladexml->get_widget("labelNKDruckerDesc");
my $labelNKAnfragen       = $gladexml->get_widget("labelNKAnfragen");
my $labelNKAnfragenStatus = $gladexml->get_widget("labelNKAnfragenStatus");
my $labelNKBemerk         = $gladexml->get_widget("labelNKBemerk");

# Dialog Auftrag erstellen
my $dialogAuftragerstellen   = $gladexml->get_widget("dialogAuftragerstellen");
my $comboboxAuftragerstellen =
  $gladexml->get_widget("comboboxAuftragerstellen");
my $calendarAuftragerstellen =
  $gladexml->get_widget("calendarAuftragerstellen");
my $checkbuttonAuftragerstellen =
  $gladexml->get_widget("checkbuttonAuftragerstellen");
my $textviewAuftragerstellen =
  $gladexml->get_widget("textviewAuftragerstellen");

# Dialog GutscheinNr
my $dialogGutscheinNr = $gladexml->get_widget("dialogGutscheinNr");
my $entryGutscheinNr  = $gladexml->get_widget("entryGutscheinNr");

# Dialog Extras
my $dialogExtras = $gladexml->get_widget("dialogExtras");

# Dialog Kassen-Ist
my $dialogKassenIst     = $gladexml->get_widget("dialogKassenIst");
my $labelKassenIst      = $gladexml->get_widget("labelKassenIst");
my $spinbuttonKassenIst = $gladexml->get_widget("spinbuttonKassenIst");

# Dialog Bonkopie
my $dialogBonkopieNummer = $gladexml->get_widget("dialogBonkopieNummer");
my $entryBonkopie        = $gladexml->get_widget("entryBonkopie");
my $dialogBonkopieWarten = $gladexml->get_widget("dialogBonkopieWarten");
my $dialogBonkopieListe  = $gladexml->get_widget("dialogBonkopieListe");
my $listebonkopieliste   = $gladexml->get_widget("treeviewBonkopieListe");

# Labels für Kunden
my $labelKundennummer   = $gladexml->get_widget("labelKundenNummer");
my $labelPerson         = $gladexml->get_widget("labelPerson");
my $labelFirma          = $gladexml->get_widget("labelFirma");
my $labelAnschrift      = $gladexml->get_widget("labelAnschrift");
my $labelTelefon        = $gladexml->get_widget("labelTelefon");
my $labelDurchwahl      = $gladexml->get_widget("labelDurchwahl");
my $labelFax            = $gladexml->get_widget("labelFax");
my $labeleMail          = $gladexml->get_widget("labeleMail");
my $labelDrucker        = $gladexml->get_widget("labelDrucker");
my $labelDruckerDesc    = $gladexml->get_widget("labelDruckerDesc");
my $labelAnfragen       = $gladexml->get_widget("labelAnfragen");
my $labelAnfragenstatus = $gladexml->get_widget("labelAnfragenStatus");
my $labelBemerk         = $gladexml->get_widget("labelBemerk");
my $labelZahlungsart    = $gladexml->get_widget("labelZahlungsart");
my $labelRabatt         = $gladexml->get_widget("labelRabatt");
my $labelatime          = $gladexml->get_widget("labelatime");
my $labelauser          = $gladexml->get_widget("labelauser");
my $labelctime          = $gladexml->get_widget("labelctime");
my $labelcuser          = $gladexml->get_widget("labelcuser");

# Suche
my $entrySuche = $gladexml->get_widget("entrySuche");
my $listesuche;
my $listesuchergebnis        = $gladexml->get_widget("treeviewSuche");
my $dialogSuche              = $gladexml->get_widget("dialogSuche");
my $dialogSucheInformationen =
  $gladexml->get_widget("dialogSucheInformationen");

# Suche Informationen
my $labelwgruppe    = $gladexml->get_widget("labelwgruppe");
my $labelttnr       = $gladexml->get_widget("labelttnr");
my $labelmarke      = $gladexml->get_widget("labelmarke");
my $labeloem        = $gladexml->get_widget("labeloem");
my $labeldrucker    = $gladexml->get_widget("labeldrucker");
my $labelean        = $gladexml->get_widget("labelean");
my $labelkompatibel = $gladexml->get_widget("labelkompatibel");
my $labelemstar     = $gladexml->get_widget("labelemstar");
my $labelartbez     = $gladexml->get_widget("labelartbez");
my $labelartnr      = $gladexml->get_widget("labelartnr");
my $labelseiten     = $gladexml->get_widget("labelseiten");
my $labelgruppe     = $gladexml->get_widget("labelgruppe");
my $labelfarbe      = $gladexml->get_widget("labelfarbe");
my $labelspez       = $gladexml->get_widget("labelspez");
my $labelinhalt     = $gladexml->get_widget("labelinhalt");
my $labelbemerk     = $gladexml->get_widget("labelbemerk");
my $labelregal      = $gladexml->get_widget("labelregal");
my $labeleigpreis   = $gladexml->get_widget("labeleigpreis");
my $labelfremdpreis = $gladexml->get_widget("labelfremdpreis");
my $labelkomppreis  = $gladexml->get_widget("labelkomppreis");
my $labelverglpreis = $gladexml->get_widget("labelverglpreis");

# Verkaeufer Namen anzeigen
my $labelVerkaeufer = $gladexml->get_widget("labelClient");

# Widgets im About Dialog
my $windowAbout     = $gladexml->get_widget("windowAbout");
my $labelLastchange = $gladexml->get_widget("labelLastchange");
my $labelVersion    = $gladexml->get_widget("labelVersion");

# Widgets für Verkäufer Wechseln Dialog
my $dialogVerkaeufer      = $gladexml->get_widget("dialogVerkaeufer");
my $entryVerkaeuferNummer = $gladexml->get_widget("entryVerkaeuferNummer");

my $dialogVerkaeuferUndefiniert =
  $gladexml->get_widget("dialogVerkaeuferUndefiniert");

# Widgets für Gesamtstorno
my $dialogGesamtstorno = $gladexml->get_widget("dialogGesamtstorno");

# handler fuer Hotkeys
my $labelHotkey = $gladexml->get_widget("labelHotkey");
my @hotkey;
$hotkey[1]  = $gladexml->get_widget("hotkey1");
$hotkey[2]  = $gladexml->get_widget("hotkey2");
$hotkey[3]  = $gladexml->get_widget("hotkey3");
$hotkey[4]  = $gladexml->get_widget("hotkey4");
$hotkey[5]  = $gladexml->get_widget("hotkey5");
$hotkey[6]  = $gladexml->get_widget("hotkey6");
$hotkey[7]  = $gladexml->get_widget("hotkey7");
$hotkey[8]  = $gladexml->get_widget("hotkey8");
$hotkey[9]  = $gladexml->get_widget("hotkey9");
$hotkey[10] = $gladexml->get_widget("hotkey10");
$hotkey[11] = $gladexml->get_widget("hotkey11");
$hotkey[12] = $gladexml->get_widget("hotkey12");

sub float {
	my $float = shift;
	$float =~ s/,/./g;
	return $float;
}

sub on_buttonAbout_clicked {
	$labelVersion->set_text($version);
	$labelLastchange->set_text($lastchange);
	$windowAbout->show;
}

sub on_closebuttonAbout_clicked {
	$windowAbout->hide;
	return 1;
}

sub on_okbuttonQuit_clicked {
	Gtk2->main_quit;
}

sub on_cancelbuttonQuit_clicked {
	$dialogQuit->hide;
	return 1;
}

sub on_cancelbuttonSonstige_clicked {
	$dialogSonstige->hide;
	return 1;
}

sub beenden {
	my $pos = keys %{ $bon{$uid} };
	if ( ( $pos > 0 ) && ( $bonid{$uid} eq "" ) ) {
		$labelQuit->set_markup(
"Möchten Sie das Programm wirklich beenden?\nDer
aktuelle Bon geht dann verloren!"
		);
	}
	else {
		$labelQuit->set_text("Möchten Sie das Programm wirklich beenden?");
	}
	$dialogQuit->show;
	return 1;
}

sub on_buttonQuit_clicked {
	beenden();
}

sub on_button1_clicked {
	my $text = $display->get_text;
	$text = $text . "1";
	$display->set_text($text);
}

sub on_button2_clicked {
	my $text = $display->get_text;
	$text = $text . "2";
	$display->set_text($text);
}

sub on_button3_clicked {
	my $text = $display->get_text;
	$text = $text . "3";
	$display->set_text($text);
}

sub on_button4_clicked {
	my $text = $display->get_text;
	$text = $text . "4";
	$display->set_text($text);
}

sub on_button5_clicked {
	my $text = $display->get_text;
	$text = $text . "5";
	$display->set_text($text);
}

sub on_button6_clicked {
	my $text = $display->get_text;
	$text = $text . "6";
	$display->set_text($text);
}

sub on_button7_clicked {
	my $text = $display->get_text;
	$text = $text . "7";
	$display->set_text($text);
}

sub on_button8_clicked {
	my $text = $display->get_text;
	$text = $text . "8";
	$display->set_text($text);
}

sub on_button9_clicked {
	my $text = $display->get_text;
	$text = $text . "9";
	$display->set_text($text);
}

sub on_button0_clicked {
	my $text = $display->get_text;
	$text = $text . "0";
	$display->set_text($text);
}

sub on_buttonKomma_clicked {
	my $text = $display->get_text;

	# nur dann einen Punkt hinzufügen, wenn nicht bereits einer existiert.
	if ( $text !~ /,/ ) {
		$text = "$text.";
		$display->set_text($text);
	}
}

sub on_buttonNeuerKunde_clicked {
	$dialogKunde->hide;
	$dialogNeuerKunde->show;
}

sub on_buttonNeuerPreis_clicked {
	my @index = $listebon->get_selected_indices;
	if ( @index == 1 ) {
		if ( $display->get_text ne "" ) {

			# es war ein Betrag im Feld display
			my $neuerpreis = $display->get_text + 0;

			# wird brutto eingegeben
			$neuerpreis = $neuerpreis / 116 * 100;
			$bon{$uid}->{ ++$index[0] }->{"Stuckpreis"} = $neuerpreis;
			$display->set_text("");
			update_bon();
		}
		else {

			# kein Betrag im Feld display
			$labelFehler->set_text(
"Markieren Sie die gewünschte Position des Bons und geben Sie im Tastenfeld
den gewünschten neuen Preis ein.
Danach klicken Sie auf \"Neuer Preis\"."
			);
			$dialogFehler->reshow_with_initial_size;
		}
	}
	else {
		$labelFehler->set_text(
"Markieren Sie die gewünschte Position des Bons und geben Sie im Tastenfeld
den gewünschten neuen Preis ein.
Danach klicken Sie auf \"Neuer Preis\"."
		);
		$dialogFehler->reshow_with_initial_size;
	}
}

sub on_buttonCE_clicked {
	$display->set_text("");
	@zahlen = undef;
}

sub on_buttonExtras_clicked {
	$dialogExtras->show;
}

sub on_buttonSonstigeGutschein_clicked {

	# Button Gutschein, bei Zahlungsart Sonstige
	$dialogSonstige->hide;
	$dialogGutscheinNr->show;
}

sub on_buttonGutschein_clicked {
	return if commit() == 1;
	my $betrag = $display->get_text;
	$betrag += 0;
	if ( $betrag <= 0 ) {
		$labelFehler->set_text(
"Geben Sie den Gutschein-Betrag ein und klicken Sie danach auf die Schalftfläche
Gutschein."
		);
		$dialogFehler->reshow_with_initial_size;
	}
	else {    # wie viele Positionen hat der aktuelle Bon?
		my $pos = keys %{ $bon{$uid} };

		$pos++;
		$bon{$uid}->{$pos}->{"TTNr"}       = "00090002";
		$bon{$uid}->{$pos}->{"Bezeichn"}   = "Gutschein";
		$bon{$uid}->{$pos}->{"Anzahl"}     = "1";
		$bon{$uid}->{$pos}->{"Stuckpreis"} = $betrag;
		$bon{$uid}->{$pos}->{"MwSt"}       = "";
		$bon{$uid}->{$pos}->{"OEM"}        = "";
		update_bon();
		$display->set_text("");
	}
}

sub on_hotkey1_clicked {
	$get_funktion->execute( $gruppe, 1 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 1 );
}

sub on_hotkey2_clicked {
	$get_funktion->execute( $gruppe, 2 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 2 );

}

sub on_hotkey3_clicked {
	$get_funktion->execute( $gruppe, 3 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 3 );

}

sub on_hotkey4_clicked {

	$get_funktion->execute( $gruppe, 4 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 4 );
}

sub on_hotkey5_clicked {
	$get_funktion->execute( $gruppe, 5 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 5 );

}

sub on_hotkey6_clicked {
	$get_funktion->execute( $gruppe, 6 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 6 );

}

sub on_hotkey7_clicked {
	$get_funktion->execute( $gruppe, 7 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 7 );

}

sub on_hotkey8_clicked {
	$get_funktion->execute( $gruppe, 8 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 8 );

}

sub on_hotkey9_clicked {
	$get_funktion->execute( $gruppe, 9 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 9 );

}

sub on_hotkey10_clicked {
	$get_funktion->execute( $gruppe, 10 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 10 );

}

sub on_hotkey11_clicked {
	$get_funktion->execute( $gruppe, 11 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 11 );

}

sub on_hotkey12_clicked {
	$get_funktion->execute( $gruppe, 12 );
	my ($funktion) = $get_funktion->fetchrow_array;
	change_hotkeys( $funktion, 12 );

}

sub on_buttonArtikel_clicked {
	return if commit() == 1;

	# wie viele Positionen hat der aktuelle Bon?
	my $pos  = keys %{ $bon{$uid} };
	my $text = $display->get_text;
	my $temp = $text + 0;
	if ( $text ne "" ) {

		# der von Hand eingegebene Artikel ist immer inkl. 16 % MwSt.
		$temp = $temp / 116 * 100;
		$pos++;
		$bon{$uid}->{$pos}->{"TTNr"}       = "00090001";
		$bon{$uid}->{$pos}->{"Bezeichn"}   = "Bezeichnung";
		$bon{$uid}->{$pos}->{"Anzahl"}     = "1";
		$bon{$uid}->{$pos}->{"Stuckpreis"} = $temp;
		$bon{$uid}->{$pos}->{"MwSt"}       = "16";
		$bon{$uid}->{$pos}->{"OEM"}        = "";
		update_bon();
		$display->set_text("");
	}
	else {

	# wenn nichts im Display steht, erhöhen wir die Anzahl der letzten Artikels
		if ( $pos > 0 ) {
			my $anzahl = $bon{$uid}->{$pos}->{"Anzahl"};
			$anzahl++;
			$bon{$uid}->{$pos}->{"Anzahl"} = $anzahl;
			update_bon();
		}
	}
}

sub on_buttonAuftragerstellen_clicked {
	$dialogExtras->hide;
	my $pos = keys %{ $bon{$uid} };
	if ( $pos > 0 ) {

		# Abfrage um Kunden zu ermitteln
		my $getcustomer =
		  $db->prepare(
			"SELECT id, firma, person FROM stamm_kunden ORDER BY id;");
		$getcustomer->execute();
		my $modell = Gtk2::ListStore->new('Glib::String');
		while ( my ( $id, $firma, $person ) = $getcustomer->fetchrow_array ) {
			my $string = "$id - $firma - $person";
			my $iter   = $modell->append;
			$modell->set( $iter, 0, $string );
		}
		$comboboxAuftragerstellen->set_model($modell);
		$comboboxAuftragerstellen->set_text_column(0);
		$dialogAuftragerstellen->show;
	}
	else {
		$labelFehler->set_text(
"Fügen Sie alle gewünschten Artikel dem Kassen-Bon hinzu und klicken Sie
danach auf die Schaltfläche "Auftrag erstellen"."
		);
		$dialogFehler->reshow_with_initial_size;
	}
}

sub on_buttonGesamtstorno_clicked {
	if ( keys %{ $bon{$uid} } > 0 ) {
		$dialogGesamtstorno->show;
	}
}

sub on_okbuttonGesamtstorno_clicked {
	$dialogGesamtstorno->hide;
	reset_vars();
	update_bon();
}

sub on_okbuttonGutscheinNr_clicked {
	my $id           = $entryGutscheinNr->get_text;
	my $getgutschein =
	  $db->prepare("SELECT betrag, used FROM stamm_gutscheine WHERE id=?");
	$getgutschein->execute($id);
	my ( $betrag, $used ) = $getgutschein->fetchrow_array;
	if ( $betrag <= 0 ) {
		$labelFehler->set_text("Unbekannte Gutschein-Nummer.");
		$dialogFehler->reshow_with_initial_size;
		return;
	}
	if ( $used != 0 ) {
		$labelFehler->set_text("Der Gutschein wurde bereits eingelöst.");
		$dialogFehler->reshow_with_initial_size;
		return;
	}
	$dialogGutscheinNr->hide;
	$entryGutscheinNr->set_text("");
	$gutschein{$uid}   = $betrag;
	$gutscheinnr{$uid} = $id;
	update_bon();
}

sub on_okbuttonDialogInfo_clicked {
	$dialogInfo->hide;
	return 1;
}

sub on_cancelbuttonGutscheinNr_clicked {
	$dialogGutscheinNr->hide;
	return 1;
}

sub on_cancelbuttonGesamtstorno_clicked {
	$dialogGesamtstorno->hide;
	return 1;
}

sub on_buttonRechnung_clicked {
	$dialogSonstige->hide;
	$calculaterechnung{$uid} = 1;
	update_bon();
}

sub on_buttonSonstige_clicked {
	my $pos = keys %{ $bon{$uid} };

 # wenn noch keine Positionen im Bon sind, kann man keine Zahlungsart auswählen
	if ( $pos > 0 ) {
		$dialogSonstige->show;
	}
}

sub on_buttonStorno_clicked {
	my @index = $listebon->get_selected_indices;
	if ( @index > 0 ) {

		# Hash neu aufbauen (Löcher schließen)
		my %temp = %{ $bon{$uid} };
		%{ $bon{$uid} } = ();
		my $counter = 1;
		##debug print "Lösche Index: $_\n" foreach @index;

		# alle Hash-Einträge durch gehen
		foreach my $aktkey ( sort keys %temp ) {
			##debug print "Aktueller Hash Key: $aktkey\n";
			foreach my $aktindex (@index) {
				print "Aktueller Index $aktindex\n";

				# die Listenelemente beginnen bei 0, der Hash aber bei 1
				#$aktindex++;

				# steht der aktuelle key in der Liste?
				if ( $aktindex + 1 == $aktkey ) {
					##debug print "Überspringe Index $aktindex\n";

					# dann wird dieser Eintrag im neuen Array übersprungen
					next;
				}
				else {

# der Eintrag steht nicht in der Liste, d.h. die Werte werden in den neuen
Hash übernommen
					##debug print "Übernehme Index $aktindex\n";

					$bon{$uid}->{$counter}->{"TTNr"} = $temp{$aktkey}->{"TTNr"};
					$bon{$uid}->{$counter}->{"Bezeichn"} =
					  $temp{$aktkey}->{"Bezeichn"};
					$bon{$uid}->{$counter}->{"Anzahl"} =
					  $temp{$aktkey}->{"Anzahl"};
					$bon{$uid}->{$counter}->{"Stuckpreis"} =
					  $temp{$aktkey}->{"Stuckpreis"};
					$bon{$uid}->{$counter}->{"MwSt"} = $temp{$aktkey}->{"MwSt"};
					$counter++;
				}
			}
		}
		##debug print keys %bon, "\n", keys %temp, "\n\n";
		update_bon();
	}
	else {
		$labelFehler->set_text(
"Markieren Sie zuerst die Position des Bons, die Sie stornieren möchten."
		);
		$dialogFehler->reshow_with_initial_size;

	}
}

sub on_buttonBonkopie_clicked {

# da bei der Bonkopie der aktuelle Bon ersetzt wird, muss dieser zuerst
abgespeichert werden
	return if commit() == 1;
	$dialogExtras->hide;
	$dialogBonkopieNummer->show;
}

sub on_buttonBondrucken_clicked {

	# nur drucken, wenn bonid bekannt
	if ( $bonid{$uid} ne "" ) {
		pos_printbon( $bonid{$uid} );
		$dialogBonkopieWarten->show;
		my $rc = pos_printbon( $bonid{$uid} );
		if ( $rc == 1 ) {
			$labelFehler->set_text("Fehler beim Druck der Bonkopie.");
			$dialogFehler->reshow_with_initial_size;
		}
		if ( $rc == 2 ) {
			$labelFehler->set_text("Unbekannte Bon-Nummer.");
			$dialogFehler->reshow_with_initial_size;
		}
		if ( $rc == 3 ) {
			$labelFehler->set_text(
"Fehler beim Drucken des Bons. Bitte prüfen Sie den Standard-Drucker."
			);
			$dialogFehler->reshow_with_initial_size;
		}
		$dialogBonkopieWarten->hide;
	}
	else {
		$labelFehler->set_text(
"Sie können einen Bon erst drucken, wenn der Bezahlvorgang abgeschlossen
wurde oder mit der Funktion Bon Kopie im Menü Extras ein Bon ausgewählt
wurde."
		);
		$dialogFehler->reshow_with_initial_size;
	}
}

sub on_buttonBar_clicked {
	my $pos = keys %{ $bon{$uid} };

   # wenn noch keine Positionen im Bon sind, kann man keinen Bar Betrag
eingeben
	if ( $pos > 0 ) {
		$bar{$uid} = $display->get_text + 0;
		$display->set_text("");
		update_bon();
	}
}

sub on_buttonKassenIst_clicked {

# wenn bereits ein Kassen-Ist Bericht durchgeführt wurde, aber seit dem
nochmal was verkauft wurde
# dann darf man noch einen machen


my $kassenisttable = pos_hostname() . "_kassenist";
my $checkkassenist =
  $db->prepare("SELECT timestamp FROM $kassenisttable WHERE timestamp LIKE
?");
  

	# wurde heute schon ein Kassen-Ist gespeichert?
	my ($timestamp) = pos_time() =~ /(\d{8})\d{6}/;
	my $query=$timestamp."%";
	$checkkassenist->execute($query);
	my ($kassenisttimestamp)=$checkkassenist->fetchrow_array;
	if ( $kassenisttimestamp ne "" ) {

		# es wurde heute schon ein Kassen-Ist Bericht durchgeführt
		# prüfen ob DANACH noch ein neuer Bon dazukam
		my $bondb        = pos_hostname() . "_bon";
		my $gettimestamp =
		  $db->prepare(
			"SELECT timestamp FROM $bondb ORDER BY timestamp DESC LIMIT 1;");
		$gettimestamp->execute;
		my ($dbtimestamp) = $gettimestamp->fetchrow_array;
		print STDERR "Kassen-Ist: $kassenisttimestamp, Kassen-Bon: $dbtimestamp\n";
		if ( $dbtimestamp <= $kassenisttimestamp ) {
# ist die letzte Position im Kassen-Bon nicht neuer als der Kassen-Abschluss,
dann ist kein weiterer Kassen-Ist möglich
			$labelFehler->set_text(
				"Es wurde bereits ein Kassen-Abschluss durchgeführt." );
			$dialogFehler->reshow_with_initial_size;
			return;    
		}

	}

# für alle Scheine und Münzen einmal fragen
# 1cent, 2cent, 5cent, 10cent, 20cent, 50cent, 1euro, 2euro, 5euro, 10euro,
20euro, 50euro, 100euro, 200euro, 500euro

	my $temp  = $stueckelung[$aktstueckelung];
	my $temp2 = $kassenist{$temp}->{'label'};
	$labelKassenIst->set_text($temp2);
	$temp = $kassenist{$temp}->{"value"};
	$spinbuttonKassenIst->set_value($temp);
	$dialogKassenIst->show;
}

sub on_buttonKarte_clicked {
	my $pos = keys %{ $bon{$uid} };

   # wenn noch keine Positionen im Bon sind, kann man keinen Bar Betrag
eingeben
	if ( $pos > 0 ) {
		$karte{$uid} = $display->get_text + 0;
		$display->set_text("");
		update_bon();
	}
}

sub on_buttonKunde_clicked {
	$dialogKunde->show;
}

sub on_okbuttonAuftragerstellen_clicked {

	# neuen Auftrag erstellen
	my $index = $comboboxAuftragerstellen->get_active;
	my ( $jahr, $monat, $tag ) = $calendarAuftragerstellen->get_date;

	# Monat ist 0-11, Tag 1-31, deshalb:
	$monat++;

	##db print "Kalender: $tag.$monat.$jahr\n";

	my $keinliefertermin = $checkbuttonAuftragerstellen->get_active;
	##db print "Liefertermin: $keinliefertermin\n";
	my $heute    = ParseDate("today");
	my $kalender = ParseDate("$jahr/$monat/$tag");
	##db print "Heute: $heute, Kalender: $kalender\n";
	my $flag = Date_Cmp( $heute, $kalender );
	##db print "Flag: $flag\n";
# Wenn im Kalender heute oder ein vergangenes Datum gewählt wurde, und
nicht die Option "Kein Liefertermin"
# dann muss eine Fehlermeldung angezeigt werden
	if ( ( $flag > 0 ) && ( $keinliefertermin != 1 ) ) {
		$labelFehler->set_text(
			"Das Datum für den Liefertermin muss in der Zukunft liegen.");
		$dialogFehler->reshow_with_initial_size;
		return;
	}
	else {

		# Auftrag abspeichern
		my $buffer    = $textviewAuftragerstellen->get_buffer;
		my $startiter = $buffer->get_start_iter;
		my $enditer   = $buffer->get_end_iter;
		my $bemerk    = $buffer->get_text( $startiter, $enditer, 0 );
		##db print "$bemerk\n";

		# Kunde ermitteln
		my $getkunde = $db->prepare("SELECT id FROM stamm_kunden ORDER BY id;");
		$getkunde->execute;
		my $kunde;
		my $counter = 0;
		while ( ($kunde) = $getkunde->fetchrow_array ) {
			if ( $counter == $index ) {
				last;
			}
			$counter++;
		}

		# Termin ist 0 wenn kein Liefertermin ausgewählt wurde
		my $termin;
		if ( $keinliefertermin == 1 ) {
			$termin = 0;
		}
		else {
			($termin) = $kalender =~ /(\d{8})\d{2}:\d{2}:\d{2}/;
		}
		my $table       = pos_hostname() . "_auftraege";
		my $saveauftrag =
		  $db->prepare(
"INSERT INTO $table (timestamp, user, bemerk, ttnr, anzahl, kunde, termin)
VALUES (?,?,?,?,?,?,?)"
		  );
		my $timestamp = pos_time();

		foreach my $aktkey ( keys %{ $bon{$uid} } ) {
			my $ttnr   = $bon{$uid}->{$aktkey}->{"TTNr"};
			my $anzahl = $bon{$uid}->{$aktkey}->{"Anzahl"};
			my $rc     =
			  $saveauftrag->execute( $timestamp, $uid, $bemerk, $ttnr, $anzahl,
				$kunde, $termin );

			if ( $rc != 1 ) {
				$labelFehler->set_text(
"Ein kritischer Fehler beim Arbeiten mit der Datenbank ist aufgetreten.
Notieren Sie alle Positionen des aktuellen Bons und beenden Sie die Kasse
umgehend!\nBenachrichtigen Sie schnellstens einen Administrator!"
				);

				$dialogFehler->reshow_with_initial_size;
			}
		}
		$dialogAuftragerstellen->hide;
		reset_vars();
		update_bon();
	}
}

sub on_okbuttonBonkopieListe_clicked {

	# zwei häufig benötigte Abfragen
	my $getoem    = $db->prepare("SELECT oem FROM stamm_artikel WHERE ttnr=?;");
	my $getartbez =
	  $db->prepare("SELECT artbez FROM stamm_artikel WHERE ttnr=?;");

	my @index = $listebonkopieliste->get_selected_indices;
	if ( @index > 0 ) {

		# es wurde was ausgewählt
		if ( @index > 1 ) {
			$labelFehler->set_text(
				"Es können nicht mehrere Bons ausgewählt werden.");
			$dialogFehler->reshow_with_initial_size;
		}
		else {

			# Fenster gleich zumachen
			$dialogBonkopieListe->hide;

			my $aktindex = $index[0];
			my $datum    = ${ $listebonkopieliste->{data} }[$aktindex][0];
			my $uhrzeit  = ${ $listebonkopieliste->{data} }[$aktindex][1];
			my $table    = pos_hostname() . "_bon";
			my ( $tag, $monat, $jahr ) = $datum =~ /(\d{2})\.(\d{2})\.(\d{4})/;
			my ( $stunde, $minute, $sekunde ) =
			  $uhrzeit =~ /(\d{2}):(\d{2}):(\d{2})/;
			$bonid{$uid} =
			  pos_hostname() . "_" . $jahr . $monat . $tag . $stunde . $minute
			  . $sekunde;

			# diesen Bon auslesen
			my $getbon =
			  $db->prepare(
"SELECT pos, ttnr, preis, anzahl, user, kunde, mwst, gutschein FROM $table
WHERE bonid=? ORDER BY pos;"
			  );
			$getbon->execute( $bonid{$uid} );
			my $summe       = 0;
			my $mwst        = 0;
			my $karte       = 0;
			my $bar         = 0;
			my $rabatt      = 0;
			my $rechnung    = 0;
			my $gutschein   = 0;
			my $gutscheinnr = 0;

			while (
				my (
					$aktpos,  $aktttnr,  $aktpreis, $aktanzahl,
					$aktuser, $aktkunde, $aktmwst,  $aktgutschein
				)
				= $getbon->fetchrow_array
			  )
			{

				if ( $aktttnr eq "900000000" ) {
					$bar{$uid} = $aktpreis;
					next;
				}

				if ( $aktttnr eq "900000001" ) {
					$karte{$uid} = $aktpreis;
					next;
				}

				if ( $aktttnr eq "900000002" ) {
					$rabatt{$uid} = $aktpreis;
					next;
				}

				if ( $aktttnr eq "900000003" ) {
					$rechnung{$uid} = $aktpreis;
					next;
				}

				# ist es ein Gutschein?
				if ( $aktttnr eq "900000004" ) {
					$gutschein{$uid}   = $aktpreis;
					$gutscheinnr{$uid} = $aktgutschein;
					next;
				}

				# OEM-Nummer
				$getoem->execute($aktttnr);
				my ($oem) = $getoem->fetchrow_array;

				# Bezeichnung
				$getartbez->execute($aktttnr);
				my ($bez) = $getartbez->fetchrow_array;

				# in den aktuellen Bon speichern
				$bon{$uid}->{$aktpos}->{"TTNr"}       = $aktttnr;
				$bon{$uid}->{$aktpos}->{"Bezeichn"}   = $bez;
				$bon{$uid}->{$aktpos}->{"Anzahl"}     = $aktanzahl;
				$bon{$uid}->{$aktpos}->{"Stuckpreis"} = $aktpreis;
				$bon{$uid}->{$aktpos}->{"MwSt"}       = $aktmwst;
				$bon{$uid}->{$aktpos}->{"OEM"}        = $oem;
			}

			# und korrekt anzeigen
			update_bon();
		}
	}
	else {
		$labelFehler->set_text(
			"Wählen Sie einen Bon aus der Liste, um diesen zu drucken.");
		$dialogFehler->reshow_with_initial_size;
	}
}

sub on_okbuttonBonkopieNummer_clicked {
	my $bonid = $entryBonkopie->get_text;
	if ( $bonid eq "" ) {

# es wurde keine Bon-ID eingegeben, also muss die Auswahl-Liste angezeigt
werden
		$dialogBonkopieNummer->hide;

		my $table = pos_hostname() . "_bon";
		@{ $listebonkopieliste->{data} } = ();
		my $getbons =
		  $db->prepare(
			"SELECT DISTINCT bonid FROM $table ORDER BY bonid desc;");
		my $getumsatz =
		  $db->prepare(
"SELECT preis, mwst, anzahl FROM $table WHERE bonid=? AND ttnr NOT LIKE
\"90000000%\";"
		  );
		$getbons->execute;
		while ( my ($bonid) = $getbons->fetchrow_array ) {
			$getumsatz->execute($bonid);
			my $umsatz = 0;
			while ( my ( $preis, $mwst, $anzahl ) = $getumsatz->fetchrow_array )
			{
				$preis += $preis / 100 * $mwst;
				$preis = $preis * $anzahl;
				$umsatz += $preis;
			}
			$umsatz = sprintf( "%.2f", $umsatz );
			my ( $jahr, $monat, $tag, $stunde, $minute, $sekunde ) =
			  $bonid =~ /.*_(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;
			my $datum   = $tag . "." . $monat . "." . $jahr;
			my $uhrzeit = $stunde . ":" . $minute . ":" . $sekunde;
			push @{ $listebonkopieliste->{data} },
			  [ $datum, $uhrzeit, $umsatz ];
		}
		$dialogBonkopieListe->reshow_with_initial_size;
	}
	else {
		$dialogBonkopieWarten->show;
		$dialogBonkopieNummer->hide;
		my $rc = pos_printbon($bonid);
		if ( $rc == 1 ) {
			$labelFehler->set_text("Fehler beim Druck der Bonkopie.");
			$dialogFehler->reshow_with_initial_size;
		}
		if ( $rc == 2 ) {
			$labelFehler->set_text("Unbekannte Bon-Nummer.");
			$dialogFehler->reshow_with_initial_size;
		}
		if ( $rc == 3 ) {
			$labelFehler->set_text(
"Fehler beim Drucken des Bons. Bitte prüfen Sie den Standard-Drucker."
			);
			$dialogFehler->reshow_with_initial_size;
		}
		$dialogBonkopieWarten->hide;
	}
}

sub on_okbuttonDialogFehler_clicked {
	$dialogFehler->hide;
	return 1;
}

sub on_okbuttonDialogVerkaeufer_clicked {
	my $localuid = $entryVerkaeuferNummer->get_text;

	# gibt die Rückfrage 0 treffer, existiert der User nicht
	my $localusername = pos_get_username($localuid);
	if ( $localusername eq "" ) {
		$labelFehler->set_text(
			"Die angegebene Verkäufer-Nummer ist unbekannt.");
		$dialogFehler->reshow_with_initial_size;

	}
	else {
		$uid      = $localuid;
		$username = $localusername;
		$longname = pos_get_longname($username);
		$labelVerkaeufer->set_label("Aktueller Verkäufer: $longname");

		# Bon für aktuellen Verkäufer wiederherstellen
		update_bon();
		$entryVerkaeuferNummer->set_text("");
		$dialogVerkaeufer->hide;
	}
}

sub on_okbuttonExtras_clicked {
	$dialogExtras->hide;
	return 1;
}

sub on_cancelbuttonBonkopieNummer_clicked {
	$dialogBonkopieNummer->hide;
	return 1;
}

sub on_cancelbuttonAuftragerstellen_clicked {
	$dialogAuftragerstellen->hide;
	return 1;
}

sub on_cancelbuttonBonkopieListe_clicked {
	$dialogBonkopieListe->hide;
	return 1;
}

sub on_cancelbuttonDialogVerkaeufer_clicked {
	if ( $uid > 0 ) {

		# wechsel erlaubt weil uid schon definiert
		$dialogVerkaeufer->hide;
	}
	else {

		# uid nicht definiert, daher Fehler
		$dialogVerkaeufer->hide;
		$dialogVerkaeuferUndefiniert->show;
	}
	return 1;
}

sub on_buttonVerkaeuferWechseln_clicked {
	$dialogVerkaeufer->show;
}

sub on_okbuttonVerkaeuferUndefiniert_clicked {
	$dialogVerkaeuferUndefiniert->hide;
}

sub on_quitbuttonVerkaeuferUndefiniert_clicked {
	$dialogVerkaeuferUndefiniert->hide;
	beenden();
}

sub on_zurueckbuttonKassenIst_clicked {
	$aktstueckelung--;
	if ( $aktstueckelung < 0 ) {
		$aktstueckelung = 0;
	}
	my $temp  = $stueckelung[$aktstueckelung];
	my $temp2 = $kassenist{$temp}->{'label'};
	$labelKassenIst->set_text($temp2);
	$temp = $kassenist{$temp}->{"value"};
	$spinbuttonKassenIst->set_value($temp);
	$dialogKassenIst->reshow_with_initial_size;
}

sub on_buttonZbon_clicked {
	my $bondb = pos_hostname . "_bon";
	#my $timestamp = $year . $monat . $day;
	my $timestamp=pos_time()=~/(\d{8})\d{6}/;
	my $bonid     = "%" . pos_hostname . "_" . $timestamp . "%";

	# gibt den Z-Bon aus
	# Anzahl der verkauften Artikel
	my $getartikel =
	  $db->prepare(
"SELECT count(*) FROM $bondb WHERE bonid LIKE ? AND ttnr NOT LIKE \"90000000%\";"
	  );
	$getartikel->execute($bonid);
	my ($artikel) = $getartikel->fetchrow_array;

	# Anzahl der Bons
	my $getbon =
	  $db->prepare(
"SELECT DISTINCT(bonid) FROM $bondb WHERE bonid LIKE ? AND ttnr NOT LIKE
\"90000000%\";"
	  );
	$getbon->execute($bonid);
	my $verkaeufe = 0;
	while ( my ($dummy) = $getbon->fetchrow_array ) {
		$verkaeufe++;
	}

	# Maximaler Umsatz
	my $getumsatz =
	  $db->prepare(
"SELECT preis,anzahl,ttnr,mwst FROM $bondb WHERE bonid LIKE ? AND ttnr NOT
LIKE \"90000000%\";"
	  );
	$getumsatz->execute($bonid);
	my $maxumsatz = 0;
	my $umsatz    = 0;
	my %wgruppe   = ();
	my %mwst      = ();
	my %artikel   = ();
	while ( my ( $aktpreis, $aktanzahl, $aktttnr, $aktmwst ) =
		$getumsatz->fetchrow_array )
	{
		my $temp = $aktpreis * $aktanzahl;
		$temp += $temp / 100 * $aktmwst;
		if ( $temp > $maxumsatz ) {
			$maxumsatz = $temp;
		}
		$umsatz += $temp;

		my ( $aktmarke, $aktwgruppe, $id ) =
		  $aktttnr =~ /(\d{2})(\d{2})(\d{4})/;
		$aktwgruppe += 0;

		# zum Hash wgruppe wird der Umsatz für diese Warengruppe addiert
		$wgruppe{$aktwgruppe} += $temp;

		# zum Hash mwst die dabei bezahlte MwSt.
		$mwst{$aktwgruppe} += $temp - $aktpreis;

		# zum Hash artikel wird die Anzahl der Artikel / wgruppe gespeichert
		$artikel{$aktwgruppe}++;
	}
	$umsatz = sprintf( "%.2f €", $umsatz );
	$labelUmsatz->set_text($umsatz);
	$maxumsatz = sprintf( "%.2f €", $maxumsatz );
	$labelMaxUmsatz->set_text($maxumsatz);
	$labelverkaeufe->set_text($verkaeufe);
	$labelArtikel->set_text($artikel);

	# Bar-Zahlung
	my $getbar =
	  $db->prepare(
		"SELECT preis FROM $bondb WHERE bonid LIKE ? and ttnr=\"900000000\";");
	$getbar->execute($bonid);
	my $barsumme = 0;
	while ( my ($aktbar) = $getbar->fetchrow_array ) {
		$barsumme += $aktbar;
	}

	$barsumme = sprintf( "%.2f €", $barsumme );
	$labelBar->set_text($barsumme);

	# Zahlung mit Karte
	my $getkarte =
	  $db->prepare(
		"SELECT preis FROM $bondb WHERE bonid LIKE ? and ttnr=\"900000001\";");
	$getkarte->execute($bonid);
	my $kartensumme = 0;
	while ( my ($aktkarte) = $getkarte->fetchrow_array ) {
		$kartensumme += $aktkarte;
	}

	$kartensumme = sprintf( "%.2f €", $kartensumme );
	$labelKarte->set_text($kartensumme);

	# Zahlung mit Rechnung
	my $getrechnung =
	  $db->prepare(
		"SELECT preis FROM $bondb WHERE bonid LIKE ? and ttnr=\"900000003\";");
	$getrechnung->execute($bonid);
	my $rechnungsumme = 0;
	while ( my ($aktrechnung) = $getrechnung->fetchrow_array ) {
		$rechnungsumme += $aktrechnung;
	}

	$rechnungsumme = sprintf( "%.2f €", $rechnungsumme );
	$labelRechnung->set_text($rechnungsumme);

	# Zahlung mit Gutschein
	my $getgutschein =
	  $db->prepare(
"SELECT SUM(preis) FROM $bondb WHERE bonid LIKE ? and ttnr=\"900000004\";"
	  );
	$getgutschein->execute($bonid);
	my ($gutscheinsumme) = $getgutschein->fetchrow_array;
	$gutscheinsumme = sprintf( "%.2f €", $gutscheinsumme );
	$labelGutschein->set_text($gutscheinsumme);

	# Umsätze/Wgruppe in Tabelle eintragen
	@{ $listezbon->{data} } = ();
	foreach my $aktwgruppe ( sort keys %wgruppe ) {
		my $bez;
		if ( $aktwgruppe == 0 ) {
			$bez = "Sonstige";
		}
		else {
			$bez = pos_get_wgruppe($aktwgruppe);
			utf8::decode($bez);
		}
		push @{ $listezbon->{data} },
		  [
			$bez,
			$artikel{$aktwgruppe},
			sprintf( "%.2f €", $wgruppe{$aktwgruppe} ),
			sprintf( "%.2f €", $mwst{$aktwgruppe} )
		  ];
	}

	$dialogZbon->reshow_with_initial_size;
}

sub on_okbuttonZbon_clicked {
	$dialogZbon->hide;
	return 1;
}

sub on_buttonSuche_clicked {
	$dialogSuche->show;
}

sub on_buttonSucheStarten_clicked {
	my $search = $entrySuche->get_text;
	$search = "\%$search\%";

	my $searchlist =
	  $db->prepare(
"SELECT ttnr, marke, wgruppe, artbez, eigpreis, mwst, oem FROM stamm_artikel
WHERE wgruppe like ? OR marke like ? OR ean like ? OR drucker like ? OR
oem like ? OR kompatibel like ? OR ttnr like ? OR emstar like ? OR artnr
like ? OR artbez like ? OR regal like ? OR bemerk like ?"
	  );
	$searchlist->execute(
		$search, $search, $search, $search, $search, $search,
		$search, $search, $search, $search, $search, $search
	);

	@{ $listesuche->{data} } = ();
	while (
		my (
			$aktttnr,  $aktmarke, $aktwgruppe, $aktbez,
			$aktpreis, $aktmwst,  $aktoem
		)
		= $searchlist->fetchrow_array
	  )
	{
		$aktpreis += $aktpreis / 100 * $aktmwst;
		$aktpreis = sprintf( "%.2f", $aktpreis );
		push @{ $listesuche->{data} },
		  [
			$aktttnr, $aktoem,   pos_get_marke($aktmarke),
			$aktbez,  $aktpreis, $aktmwst
		  ];
	}

	$dialogSuche->show;
}

sub on_okbuttonSuche_clicked {
	return if commit() == 1;
	my $pos   = keys %{ $bon{$uid} };
	my @index = $listesuche->get_selected_indices;
	if ( @index > 0 ) {
		##debug print "Index >0\n";

	# nur wenn mindestens ein Artkel ausgewählt wurde, kann man was übernehmen
		foreach my $aktindex (@index) {
			##debug print "Aktindex $aktindex\n";
			$pos++;
			my $ttnr   = ${ $listesuche->{data} }[$aktindex][0];
			my $oem    = ${ $listesuche->{data} }[$aktindex][1];
			my $marke  = ${ $listesuche->{data} }[$aktindex][2];
			my $artbez = ${ $listesuche->{data} }[$aktindex][3];
			my $preis  = ${ $listesuche->{data} }[$aktindex][4];
			my $mwst   = ${ $listesuche->{data} }[$aktindex][5];

			# Preis steht brutto in der Tabelle
			$preis                             = float($preis);
			$preis                             = $preis / 116 * 100;
			$bon{$uid}->{$pos}->{"TTNr"}       = $ttnr;
			$bon{$uid}->{$pos}->{"Bezeichn"}   = $artbez;
			$bon{$uid}->{$pos}->{"Anzahl"}     = "1";
			$bon{$uid}->{$pos}->{"Stuckpreis"} = $preis;
			$bon{$uid}->{$pos}->{"MwSt"}       = $mwst;
			$bon{$uid}->{$pos}->{"OEM"}        = $oem;
		}
		update_bon();
	}

	$dialogSuche->hide;
}

sub on_buttonSucheInformationen_clicked {
	my @index = $listesuche->get_selected_indices;
	my $temp;
	if ( @index == 1 ) {

	 # nur wenn genau ein Artikel ausgwählt wurde, werden die Details angezeigt
		$temp = $index[0];

		my $getdetails = $db->prepare(
"SELECT wgruppe, ttnr, marke, oem, drucker, ean, kompatibel, emstar, artbez,
artnr, seiten, gruppe, farbe, bemerk, spez, 
inhalt, regal, eigpreis,fremdpreis,komppreis,verglpreis,mwst FROM stamm_artikel
WHERE ttnr=?;"
		);

		my $tempttnr = ${ $listesuche->{data} }[$temp][0];
		$getdetails->execute($tempttnr);
		my (
			$sqlwgruppe,    $sqlttnr,     $sqlmarke,      $sqloem,
			$sqldrucker,    $sqlean,      $sqlkompatibel, $sqlemstar,
			$sqlartbez,     $sqlartnr,    $sqlseiten,     $sqlgruppe,
			$sqlfarbe,      $sqlbemerk,   $sqlspez,       $sqlinhalt,
			$sqlregal,      $sqleigpreis, $sqlfremdpreis, $sqlkomppreis,
			$sqlverglpreis, $sqlmwst
		  )
		  = $getdetails->fetchrow_array;

		my $t1 = pos_get_wgruppe($sqlwgruppe);
		utf8::decode($t1);
		$labelwgruppe->set_text($t1);
		$labelttnr->set_text($sqlttnr);
		my $t2 = pos_get_marke($sqlmarke);
		$labelmarke->set_text($t2);
		$labeloem->set_text($sqloem);
		$labeldrucker->set_text($sqldrucker);
		$labelean->set_text($sqlean);
		$labelkompatibel->set_text($sqlkompatibel);
		$labelemstar->set_text($sqlemstar);
		utf8::decode($sqlartbez);
		$labelartbez->set_text($sqlartbez);
		$labelartnr->set_text($sqlartnr);
		$labelseiten->set_text($sqlseiten);
		$labelgruppe->set_text($sqlgruppe);
		$labelfarbe->set_text($sqlfarbe);
		utf8::decode($sqlbemerk);
		$labelbemerk->set_text($sqlbemerk);
		$labelspez->set_text($sqlspez);
		$labelinhalt->set_text($sqlinhalt);
		utf8::decode($sqlregal);
		$labelregal->set_text($sqlregal);

		# Preise schöner formatieren

		$sqleigpreis += $sqleigpreis / 100 * $sqlmwst;
		my $temppreis = sprintf( "%.2f", $sqleigpreis );
		$labeleigpreis->set_text($temppreis);

		$sqlfremdpreis += $sqlfremdpreis / 100 * $sqlmwst;
		$temppreis = sprintf( "%.2f", $sqlfremdpreis );
		$labelfremdpreis->set_text($temppreis);

		$sqlkomppreis += $sqlkomppreis / 100 * $sqlmwst;
		$temppreis = sprintf( "%.2f", $sqlkomppreis );
		$labelkomppreis->set_text($temppreis);

		$sqlverglpreis += $sqlverglpreis / 100 * $sqlmwst;
		$temppreis = sprintf( "%.2f", $sqlverglpreis );
		$labelverglpreis->set_text($temppreis);

		$dialogSucheInformationen->reshow_with_initial_size;
	}
}

sub on_okbuttonSucheInformationen_clicked {
	$dialogSucheInformationen->hide;
	return 1;
}

sub on_cancelbuttonSuche_clicked {
	$dialogSuche->hide;
	return 1;
}

sub on_okbuttonNeuerKunde_clicked {
	my $firma          = $labelNKFirma->get_text;
	my $person         = $labelNKPerson->get_text;
	my $anschrift      = $labelNKAnschrift->get_text;
	my $telefon        = $labelNKTelefon->get_text;
	my $durchwahl      = $labelNKDurchwahl->get_text;
	my $fax            = $labelNKFax->get_text;
	my $email          = $labelNKeMail->get_text;
	my $drucker        = $labelNKDrucker->get_text;
	my $druckerdesc    = $labelNKDruckerDesc->get_text;
	my $anfragen       = $labelNKAnfragen->get_text;
	my $anfragenstatus = $labelNKAnfragenStatus->get_text;
	my $bemerk         = $labelNKBemerk->get_text;

	if ( $firma eq "" ) {
		$labelFehler->set_text("Der Name der Firma muss angegeben werden.");
		$dialogFehler->reshow_with_initial_size;
		return;
	}
	if ( $person eq "" ) {
		$labelFehler->set_text(
			"Der Name des Ansprechpartners muss angegeben werden.");
		$dialogFehler->reshow_with_initial_size;
		return;
	}
	if ( $anschrift eq "" ) {
		$labelFehler->set_text("Die Anschrift muss angegeben werden.");
		$dialogFehler->reshow_with_initial_size;
		return;
	}
	my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
	  localtime();

	$year += 1900;
	my $monat;
	$mon++;
	if ( $mon < 10 ) {
		$monat = "0" . $mon;
	}
	else {
		$monat = $mon;
	}

	my $day;
	if ( $mday < 10 ) {
		$day = "0" . $mday;
	}
	else {
		$day = $mday;
	}

	if ( $hour < 10 ) {
		$hour = "0" . $hour;
	}

	if ( $min < 10 ) {
		$min = "0" . $min;
	}

	if ( $sec < 10 ) {
		$sec = "0" . $sec;
	}

	my $timestamp = $year . $monat . $day . $hour . $min . $sec;

	my $table        = pos_hostname() . "_kunden";
	my $savecustomer =
	  $db->prepare(
"INSERT INTO $table (firma, person, anschrift, telefon, durchwahl, fax,
email, drucker, druckerdesc, anfragen, anfragenstatus, bemerk, cuser, timestamp)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
	  );
	my $rc = $savecustomer->execute(
		$firma,       $person,   $anschrift,      $telefon,
		$durchwahl,   $fax,      $email,          $drucker,
		$druckerdesc, $anfragen, $anfragenstatus, $bemerk,
		$uid,         $timestamp
	);
	if ( $rc eq undef ) {
		$labelFehler->set_text(
			"Fehler beim Speichern des Kunden in die Datenbank.");
		$dialogFehler->reshow_with_initial_size;
	}
	$dialogNeuerKunde->hide;
}

sub on_okbuttonKassenIst_clicked {
	my $temp = $stueckelung[$aktstueckelung];
	$kassenist{$temp}->{'value'} = $spinbuttonKassenIst->get_value_as_int;
	$aktstueckelung++;
	if ( $aktstueckelung == @stueckelung ) {

		# Einmal durchgelaufen
		# Summe des Kassen-Ist bilden
		my $summe = $kassenist{'1cent'}->{'value'} * 0.01;
		$summe += $kassenist{'2cent'}->{'value'} * 0.02;
		$summe += $kassenist{'5cent'}->{'value'} * 0.05;
		$summe += $kassenist{'10cent'}->{'value'} * 0.10;
		$summe += $kassenist{'20cent'}->{'value'} * 0.20;
		$summe += $kassenist{'50cent'}->{'value'} * 0.50;
		$summe += $kassenist{'1euro'}->{'value'} * 1;
		$summe += $kassenist{'2euro'}->{'value'} * 2;
		$summe += $kassenist{'5euro'}->{'value'} * 5;
		$summe += $kassenist{'10euro'}->{'value'} * 10;
		$summe += $kassenist{'20euro'}->{'value'} * 20;
		$summe += $kassenist{'50euro'}->{'value'} * 50;
		$summe += $kassenist{'100euro'}->{'value'} * 100;
		$summe += $kassenist{'200euro'}->{'value'} * 200;
		$summe += $kassenist{'500euro'}->{'value'} * 500;

		# Tagessumsatz berechnen
		my $bondb = pos_hostname() . "_bon";
		my ($bonid) = pos_time() =~ /(\d{8})\d{6}/;
		$bonid = pos_hostname() . "_$bonid\%";
		##db print "BonID: $bonid\n";
		my $getsummebar =
		  $db->prepare(
"SELECT sum(preis) FROM $bondb WHERE bonid LIKE ? AND ttnr=900000000;"
		  );
		$getsummebar->execute($bonid);
		my ($dbsumme) = $getsummebar->fetchrow_array;

		# Summe des Wechselgelds berechnen
		my $getsummezurueck=$db->prepare("SELECT sum(preis) FROM $bondb WHERE
bonid LIKE ? AND ttnr=900000005;");
		$getsummezurueck->execute($bonid);
		my ($zurueck)=$getsummezurueck->fetchrow_array;
		
		$dbsumme-=$zurueck;

		# morgens wird Wechselgeld in die Kasse gelegt
		$dbsumme += 250;
		$dbsumme = sprintf( "%.2f", $dbsumme );
		$dbsumme = float($dbsumme);
		$summe   = float($summe);

		##db print "Kassen-Ist: $summe, Datenbank: $dbsumme\n";

		if ( $dbsumme != $summe ) {
			$kassenistkorrektur++;
			if ( $kassenistkorrektur < 3 ) {
				$dialogKassenIst->hide;
				if ( $kassenistkorrektur == 2 ) {
					$labelFehler->set_text(
"Der Kassen-Bericht stimmt nicht mit dem Tages-Umsatz überein. Bitte korrigieren
Sie Ihre Angaben. Sie können nur noch einmal die Daten korrigieren!"
					);
				}
				else {
					$labelFehler->set_text(
"Der Kassen-Bericht stimmt nicht mit dem Tages-Umsatz überein. Bitte korrigieren
Sie Ihre Angaben."
					);
				}
				$dialogFehler->reshow_with_initial_size;
				$aktstueckelung = 0;

				# Funktion verlassen, damit Speichern nicht aufgerufen wird
				return;
			}
			else {
				$dialogKassenIst->hide;
				$labelFehler->set_text(
"Der Kassen-Bericht stimmt nicht mit dem Tages-Umsatz überein. Der Kassen-Bericht
wird gedruckt und abgespeichert. Eine weitere Korrektur ist nicht möglich."
				);
				$dialogFehler->reshow_with_initial_size;
			}
		}
		else {

			# Kassen-Bericht stimmt
			$dialogKassenIst->hide;
			$labelInfo->set_text(
"Kassen-Ist ist korrekt. Der Kassen-Bericht wird gedruckt und abgespeichert."
			);
			$dialogInfo->reshow_with_initial_size;

		}

		# Speichern
		my $table         = pos_hostname() . "_kassenist";
		my $savekassenist =
		  $db->prepare(
"INSERT INTO $table (user,timestamp,summe,dbsumme,1cent,2cent,5cent,10cent,20cent,50cent,1euro,2euro,5euro,10euro,20euro,50euro,100euro,200euro,500euro)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?);"
		  );
		my $timestamp = pos_time();
		my $rc        = $savekassenist->execute(
			$uid,
			$timestamp,
			$summe,
			$dbsumme,
			$kassenist{'1cent'}->{'value'},
			$kassenist{'2cent'}->{'value'},
			$kassenist{'5cent'}->{'value'},
			$kassenist{'10cent'}->{'value'},
			$kassenist{'20cent'}->{'value'},
			$kassenist{'50cent'}->{'value'},
			$kassenist{'1euro'}->{'value'},
			$kassenist{'2euro'}->{'value'},
			$kassenist{'5euro'}->{'value'},
			$kassenist{'10euro'}->{'value'},
			$kassenist{'20euro'}->{'value'},
			$kassenist{'50euro'}->{'value'},
			$kassenist{'100euro'}->{'value'},
			$kassenist{'200euro'}->{'value'},
			$kassenist{'500euro'}->{'value'}
		);

		if ( $rc eq undef ) {
			$labelFehler->set_text(
"Fehler beim Speichern des Kassen-Ist in die Datenbank! Bitte benachrichtigen
Sie umgehend Ihren Administrator."
			);
			$dialogFehler->reshow_with_initial_size;
		}

	}
	else {

		# noch nicht komplett durchgelaufen, also nächste Stückelung abfragen
		my $temp  = $stueckelung[$aktstueckelung];
		my $temp2 = $kassenist{$temp}->{'label'};
		$labelKassenIst->set_text($temp2);
		$temp = $kassenist{$temp}->{"value"};
		$spinbuttonKassenIst->set_value($temp);
		$dialogKassenIst->reshow_with_initial_size;
	}

}

sub on_okbuttonKunde_clicked {
	my $suchekunde =
	  $db->prepare(
"SELECT id, person, telefon, durchwahl, fax, email, firma, anschrift, drucker,
druckerdesc, anfragen, anfragenstatus,  zahlungsart, rabatt, bemerk, ctime,
cuser, atime, auser FROM stamm_kunden WHERE id LIKE ? OR firma LIKE ? OR
person LIKE ?;"
	  );
	my $muster = $displayKunde->get_text;
	$muster = "%" . $muster . "%";
	my $rc = $suchekunde->execute( $muster, $muster, $muster );
	if ( $rc != 1 ) {
		$labelFehler->set_text("Der Kunde wurde nicht gefunden.");
		$dialogFehler->reshow_with_initial_size;

		return;
	}
	my (
		$kundennummer, $person,      $telefon,  $durchwahl,
		$fax,          $email,       $firma,    $anschrift,
		$drucker,      $druckerdesc, $anfragen, $anfragenstatus,
		$zahlungsart,  $rabatt,      $bemerk,   $ctime,
		$cuser,        $atime,       $auser
	  )
	  = $suchekunde->fetchrow_array;

	$labelKundennummer->set_text($kundennummer);
	utf8::decode($person);
	$labelPerson->set_text($person);
	$labelTelefon->set_text($telefon);
	$labelDurchwahl->set_text($durchwahl);
	$labelFax->set_text($fax);
	$labeleMail->set_text($email);
	utf8::decode($firma);
	$labelFirma->set_text($firma);
	utf8::decode($anschrift);
	$labelAnschrift->set_text($anschrift);
	$labelDrucker->set_text($drucker);
	utf8::decode($druckerdesc);
	$labelDruckerDesc->set_text($druckerdesc);
	utf8::decode($anfragen);
	$labelAnfragen->set_text($anfragen);
	$labelAnfragenstatus->set_text($anfragenstatus);
	$labelZahlungsart->set_text($zahlungsart);
	$labelRabatt->set_text($rabatt);
	utf8::decode($bemerk);
	$labelBemerk->set_text($bemerk);
	my ( $jahr, $monat, $tag, $stunde, $min, $sekunde ) =
	  $ctime =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;
	$labelctime->set_text("$stunde:$min:$sekunde am $tag.$monat.$jahr");
	( $jahr, $monat, $tag, $stunde, $min, $sekunde ) =
	  $atime =~ /(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;

	if ( $jahr eq undef ) {
		$labelatime->set_text("keine Änderung");
	}
	else {
		$labelatime->set_text("$stunde:$min:$sekunde am $tag.$monat.$jahr");
	}
	$cuser = pos_get_longname($cuser);
	utf8::decode($cuser);
	$labelcuser->set_text($cuser);
	$auser = pos_get_longname($auser);
	utf8::decode($auser);
	if ( $auser eq undef ) {
		$labelauser->set_text("keine Änderung");
	}
	else {
		$labelauser->set_text($auser);
	}

	$kunde{$uid}  = $kundennummer;
	$rabatt{$uid} = $rabatt;
	$dialogKunde->hide;
	$dialogKundeErgebnis->show;
	update_bon();
}

sub on_cancelbuttonKundeErgebnis_clicked {
	$kunde{$uid}  = 0;
	$rabatt{$uid} = 0;
	$dialogKundeErgebnis->hide;
	update_bon();
	return 1;
}

sub on_okbuttonKundeErgebnis_clicked {
	$dialogKundeErgebnis->hide;
}

sub on_cancelbuttonNeuerKunde_clicked {
	$dialogNeuerKunde->hide;
	return 1;
}

sub on_cancelbuttonKassenIst_clicked {
	$dialogKassenIst->hide;
	$aktstueckelung = 0;
	return 1;
}

sub on_cancelbuttonKunde_clicked {
	$kunde{$uid}  = 0;
	$rabatt{$uid} = 0;
	$dialogKunde->hide;
	update_bon();
	return 1;
}

#
#
# Sub Routinen
#
#

sub reset_vars {

	# setzt alle Variablen zurück
	$bon{$uid}               = ();
	$bonid{$uid}             = "";
	$bar{$uid}               = 0;
	$rechnung{$uid}          = 0;
	$karte{$uid}             = 0;
	$kunde{$uid}             = 0;
	$rabatt{$uid}            = 0;
	$gutschein{$uid}         = 0;
	$gutscheinnr{$uid}       = 0;
	$calculaterechnung{$uid} = 0;

}

sub commit {

#	# wurde heute schon ein Kassen-Ist gespeichert?
#	my ($timestamp) = pos_time() =~ /(\d{8})\d{6}/;
#	$timestamp .= "%";
#	my $rc = $checkkassenist->execute($timestamp);
#	if ( $rc >= 1 ) {
#		$labelFehler->set_text(
#"Es wurde bereits ein Kassen-Abschluss durchgeführt. Es sind keine weiteren
Bezahlvorgänge mehr möglich."
#		);
#		$dialogFehler->reshow_with_initial_size;
#		return 1;
#	}

# wenn die Variable $bonid{$uid} gesetzt ist, kann der aktuelle Bon OHNE
speichern gelöscht werden
	if ( $bonid{$uid} ne "" ) {
		reset_vars();
		update_bon();
	}

# ist der Bezahlvorgang abgeschlossen?
# dann ist folgendes erfüllt:
# mehr als zu zahlender Betrag wurde eingegeben (egal ob Karte, Bar oder
Gutschein)
# dann löst eine beliebige Funktionen einen neuen Vorgang aus

	my $tempbar       = $bar{$uid} + 0;
	my $tempkarte     = $karte{$uid} + 0;
	my $temprechnung  = $rechnung{$uid} + 0;
	my $tempgutschein = $gutschein{$uid} + 0;
	if (   ( $tempbar == 0 )
		&& ( $tempkarte == 0 )
		&& ( $temprechnung == 0 )
		&& ( $tempgutschein == 0 ) )
	{

		# nichts zu tun
		return;
	}

	# bei Rechnung ist bar und Karte nicht erlaubt
	if ( $temprechnung > 0 ) {
		if ( ( $tempbar > 0 ) || ( $tempkarte > 0 ) ) {
			$labelFehler->set_text(
"Bei Zahlung per Rechung ist keine Bar- oder Karten-Zahlung möglich."
			);
			$dialogFehler->reshow_with_initial_size;
			$bar{$uid}   = 0;
			$karte{$uid} = 0;
			update_bon();
			return;
		}
	}

	# Gesamtpreis ermitteln
	my $summe = 0;
	foreach my $aktkey ( keys %{ $bon{$uid} } ) {
		my $temp =
		  $bon{$uid}->{$aktkey}->{"Stuckpreis"} *
		  $bon{$uid}->{$aktkey}->{"Anzahl"};
		my $mwst =
		  $bon{$uid}->{$aktkey}->{"Stuckpreis"} *
		  $bon{$uid}->{$aktkey}->{"Anzahl"} / 100 *
		  $bon{$uid}->{$aktkey}->{"MwSt"};
		$temp  += $mwst;
		$summe += $temp;
	}

	# Rabatt abziehen
	$summe = $summe - $summe / 100 * $rabatt{$uid};

	my $gezahlt = $tempbar + $tempkarte + $temprechnung + $tempgutschein;

	##db print "$gezahlt - $summe\n";
	if ( $gezahlt >= $summe ) {

		# enthält Return-Code von SQL-Aufrufen
		my $rc = 0;

		# wenn kein Kunde ausgewählt, dann kunden-Nummer = 0
		my $kd;
		if ( $kunde{$uid} eq undef ) {
			$kd = 0;
		}
		else {
			$kd = $kunde{$uid};
		}

		# Kartenbetrag übersteigt Rechungsbetrag
		if ( $tempkarte > $summe ) {
			$labelFehler->set_text(
"Der mit Karte bezahlte Betrag ist höher als der fällige Rechnungsbetrag.\n
Bitte korrigieren Sie den mit Karte bezahlten Betrag."
			);
			$dialogFehler->reshow_with_initial_size;
			$karte{$uid} = 0;
			$tempkarte = 0;
			update_bon();
			return;
		}

		# Vorgang wurde abgeschlossen
		# Bon in DB speichern
		my $hostname = pos_hostname();
		my $bondb    = $hostname . "_bon";
		my $savebon  =
		  $db->prepare(
"INSERT INTO $bondb (bonid, pos, ttnr, preis, anzahl, mwst, user, timestamp,
kunde) VALUES (?,?,?,?,?,?,?,?,?);"
		  );

		my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
		  localtime();

		$year += 1900;
		my $monat;
		$mon++;
		if ( $mon < 10 ) {
			$monat = "0" . $mon;
		}
		else {
			$monat = $mon;
		}

		my $day;
		if ( $mday < 10 ) {
			$day = "0" . $mday;
		}
		else {
			$day = $mday;
		}

		if ( $hour < 10 ) {
			$hour = "0" . $hour;
		}

		if ( $min < 10 ) {
			$min = "0" . $min;
		}

		if ( $sec < 10 ) {
			$sec = "0" . $sec;
		}

		my $timestamp = $year . $monat . $day . $hour . $min . $sec;
		my $bonid     = pos_hostname . "_" . $timestamp;

		foreach my $aktkey ( keys %{ $bon{$uid} } ) {
			my $ttnr   = $bon{$uid}->{$aktkey}->{"TTNr"};
			my $preis  = $bon{$uid}->{$aktkey}->{"Stuckpreis"};
			my $anzahl = $bon{$uid}->{$aktkey}->{"Anzahl"};
			my $mwst   = $bon{$uid}->{$aktkey}->{"MwSt"};
			$preis = float($preis);
			$rc    = $savebon->execute(
				$bonid, $aktkey, $ttnr,      $preis, $anzahl,
				$mwst,  $uid,    $timestamp, $kd
			);

			if ( $rc != 1 ) {
				$labelFehler->set_text(
"Ein kritischer Fehler beim Arbeiten mit der Datenbank ist aufgetreten.
Notieren Sie alle Positionen des aktuellen Bons und beenden Sie die Kasse
umgehend!\nBenachrichtigen Sie schnellstens einen Administrator!"
				);

				$dialogFehler->reshow_with_initial_size;
			}
		}

		# bar speichern
		my $temp = 0;
		if ( $bar{$uid} eq undef ) {
			$temp = 0;
		}
		else {
			$temp = float( $bar{$uid} );
		}
		$rc =
		  $savebon->execute( $bonid, "0", "900000000", $temp, "1", "0", $uid,
			$timestamp, $kd );

		if ( $rc != 1 ) {
			$labelFehler->set_text(
"Ein kritischer Fehler beim Arbeiten mit der Datenbank ist aufgetreten.
Notieren Sie alle Positionen des aktuellen Bons und beenden Sie die Kasse
umgehend!\nBenachrichtigen Sie schnellstens einen Administrator!"
			);

			$dialogFehler->reshow_with_initial_size;
		}

		# karte speichern
		if ( $karte{$uid} eq undef ) {
			$temp = 0;
		}
		else {
			$temp = float( $karte{$uid} );
		}
		$rc =
		  $savebon->execute( $bonid, "0", "900000001", $temp, "1", "0", $uid,
			$timestamp, $kd );

		if ( $rc != 1 ) {
			$labelFehler->set_text(
"Ein kritischer Fehler beim Arbeiten mit der Datenbank ist aufgetreten.
Notieren Sie alle Positionen des aktuellen Bons und beenden Sie die Kasse
umgehend!\nBenachrichtigen Sie schnellstens einen Administrator!"
			);

			$dialogFehler->reshow_with_initial_size;
		}

		# Rabatt speichern
		if ( $rabatt{$uid} eq undef ) {
			$temp = 0;
		}
		else {
			$temp = float( $rabatt{$uid} );
		}
		$rc =
		  $savebon->execute( $bonid, "0", "900000002", $temp, "1", "0", $uid,
			$timestamp, $kd );

		if ( $rc != 1 ) {
			$labelFehler->set_text(
"Ein kritischer Fehler beim Arbeiten mit der Datenbank ist aufgetreten.
Notieren Sie alle Positionen des aktuellen Bons und beenden Sie die Kasse
umgehend!\nBenachrichtigen Sie schnellstens einen Administrator!"
			);

			$dialogFehler->reshow_with_initial_size;
		}

		# Rechnung speichern
		$temp = 0;
		if ( $rechnung{$uid} eq undef ) {
			$temp = 0;
		}
		else {
			$temp = float( $rechnung{$uid} );
		}
		$rc =
		  $savebon->execute( $bonid, "0", "900000003", $temp, "1", "0", $uid,
			$timestamp, $kd );

		if ( $rc != 1 ) {
			$labelFehler->set_text(
"Ein kritischer Fehler beim Arbeiten mit der Datenbank ist aufgetreten.
Notieren Sie alle Positionen des aktuellen Bons und beenden Sie die Kasse
umgehend!\nBenachrichtigen Sie schnellstens einen Administrator!"
			);

			$dialogFehler->reshow_with_initial_size;
		}

		# Gutschein speichern
		$temp = 0;
		if ( $gutschein{$uid} eq undef ) {
			$temp = 0;
		}
		else {
			$temp = float( $gutschein{$uid} );

			my $savegutschein =
			  $db->prepare(
"INSERT INTO $bondb (bonid, pos, ttnr, preis, anzahl, mwst, user, timestamp,
kunde, gutschein ) VALUES (?,?,?,?,?,?,?,?,?,?);"
			  );
			$rc =
			  $savegutschein->execute( $bonid, "0", "900000004", $temp, "1",
				"0", $uid, $timestamp, $kd, $gutscheinnr{$uid} );

			#			$rc =
			#			  $savebon->execute( $bonid, "0", "900000004", $temp, "1", "0",
			#				$uid, $timestamp, $kd );
			if ( $rc != 1 ) {
				$labelFehler->set_text(
"Ein kritischer Fehler beim Arbeiten mit der Datenbank ist aufgetreten.
Notieren Sie alle Positionen des aktuellen Bons und beenden Sie die Kasse
umgehend!\nBenachrichtigen Sie schnellstens einen Administrator!"
				);

				$dialogFehler->reshow_with_initial_size;
			}
		}

		reset_vars();
		update_bon();
	}
}

sub update_bon {
	my $summe      = int(0);
	my $summenetto = int(0);
	my $gesamtmwst = int(0);
	@{ $listebon->{data} } = ();
	foreach my $aktkey ( sort nummeric keys %{ $bon{$uid} } ) {
		my $netto =
		  $bon{$uid}->{$aktkey}->{"Stuckpreis"} *
		  $bon{$uid}->{$aktkey}->{"Anzahl"};
		my $stuckpreis = $bon{$uid}->{$aktkey}->{"Stuckpreis"};
		my $mwst       =
		  $bon{$uid}->{$aktkey}->{"Stuckpreis"} *
		  $bon{$uid}->{$aktkey}->{"Anzahl"} / 100 *
		  $bon{$uid}->{$aktkey}->{"MwSt"};

		# es soll immer der Brutto-Preis angezeigt werden
		my $brutto = $netto + $mwst;
		$gesamtmwst += $mwst;

		my $stuckpreisbrutto =
		  $bon{$uid}->{$aktkey}->{"Stuckpreis"} +
		  $bon{$uid}->{$aktkey}->{"Stuckpreis"} / 100 *
		  $bon{$uid}->{$aktkey}->{"MwSt"};

		push @{ $listebon->{data} },
		  [
			$aktkey,
			$bon{$uid}->{$aktkey}->{"TTNr"},
			$bon{$uid}->{$aktkey}->{"OEM"},
			$bon{$uid}->{$aktkey}->{"Bezeichn"},
			$bon{$uid}->{$aktkey}->{"Anzahl"},
			sprintf( "%.2f", $stuckpreisbrutto ),
			sprintf( "%.2f", $stuckpreis ),
			sprintf( "%.2f", $brutto )
		  ];
		$summenetto += $netto;
		$summe      += $brutto;
	}

	# Netto Summe anzeigen
	$summenetto = sprintf( "%.2f", $summenetto );
	$displayNetto->set_markup("$summenetto");

	my $tempbar       = $bar{$uid} + 0;
	my $tempkarte     = $karte{$uid} + 0;
	my $temprechnung  = $rechnung{$uid} + 0;
	my $tempgutschein = $gutschein{$uid} + 0;

	my $temprabatt = $rabatt{$uid} + 0;
	my $gegeben    = $tempbar + $tempkarte + $temprechnung + $tempgutschein;

	# Rabatt anzeigen
	if ( $temprabatt > 0 ) {
		my $rabattbetrag = $summe / 100 * $temprabatt;
		$summe -= $rabattbetrag;
		$rabattbetrag = sprintf( "%.2f", $rabattbetrag );
		push @{ $listebon->{data} },
		  [ "", "Rabatt", "$temprabatt %", "", "", "- $rabattbetrag €" ];
	}

	# eingelösten Gutschein anzeigen
	if ( $tempgutschein > 0 ) {
		my $gutscheinbetrag = sprintf( "%.2f", $tempgutschein );
		push @{ $listebon->{data} },
		  [
			"", "Gutschein",
			"", "Nummer: $gutscheinnr{$uid}",
			"", "$gutscheinbetrag €"
		  ];
	}

	# Rechnung anzeigen
	if ( $calculaterechnung{$uid} == 1 ) {
		$rechnung{$uid} = $summe - $gegeben;
		$gegeben = $summe;
		my $rechnungsbetrag = sprintf( "%.2f", $rechnung{$uid} );
		push @{ $listebon->{data} },
		  [ "", "Rechnung", "", "", "", "$rechnungsbetrag €" ];
	}

	# wenn bei Kartenzahlung zu viel gezahlt wird, ist das ein Fehler!
	# bei Kartenzahlung darf es kein Rückgeld geben
	if ( $tempkarte > $summe ) {
		$labelFehler->set_text(
"Der mit Karte bezahlte Betrag ist höher als der fällige Rechnungsbetrag.
Bitte korrigieren Sie den mit Karte bezahlten Betrag."
		);
		$dialogFehler->reshow_with_initial_size;
		$karte{$uid} = 0;
		$tempkarte = 0;
	}

	# Bei Rechnung ist kein Bar oder Karte erlaubt
	if ( $temprechnung > 0 ) {
		if ( ( $tempbar > 0 ) || ( $tempkarte > 0 ) ) {
			$labelFehler->set_text(
"Bei Zahlung per Rechung ist keine Bar- oder Karten-Zahlung möglich."
			);
			$dialogFehler->reshow_with_initial_size;
			$bar{$uid}   = 0;
			$karte{$uid} = 0;
			$tempbar     = 0;
			$tempkarte   = 0;
		}
	}

	my $zurueck = 0;
	my $rest    = 0;
	$rest    = $summe - $gegeben;
	$zurueck = $gegeben - $summe;

	my $tempgegeben = 0;

	$tempgegeben = sprintf( "%.2f", $gegeben );
	$displayGegeben->set_markup("$tempgegeben");
	if ( $tempbar > 0 ) {

		# bereits gezahlten Bar Betrag anzeigen
		push @{ $listebon->{data} },
		  [ "", "Bar", "", "", "", sprintf( "%.2f", $tempbar ) ];
	}
	if ( $tempkarte > 0 ) {

		# bereits gezahlten Karten Betrag anzeigen
		push @{ $listebon->{data} },
		  [ "", "Karte", "", "", "", sprintf( "%.2f", $tempkarte ) ];
	}
	if (   ( $tempkarte == 0 )
		&& ( $tempbar == 0 )
		&& ( $temprechnung == 0 )
		&& ( $tempgutschein == 0 ) )
	{

		# nichts zurückzugeben
		$displayGegeben->set_markup("0,00");
	}

	# Zurück und Rest korrekt anzeigen
	$zurueck =~ s/,/./g;
	if ( $zurueck > 0 ) {
		$zurueck = sprintf( "%.2f", $zurueck );
		$labelZurueck->set_markup(
			"Zurück:");
		$displayZurueck->set_markup(
			"$zurueck");
	}
	elsif ( ( $gegeben > 0 ) && ( $rest > 0 ) ) {

		$rest = sprintf( "%.2f", $rest );
		$labelZurueck->set_markup(
			"Rest:");
		$displayZurueck->set_markup(
			"$rest");
	}
	else {
		$labelZurueck->set_markup(
			"Zurück:");
		$displayZurueck->set_markup("0,00");
	}
	my $summetemp      = sprintf( "%.2f", $summe );
	my $gesamtmwsttemp = sprintf( "%.2f", $gesamtmwst );
	$displaySumme->set_markup("$summetemp");
	$displayMwst->set_markup("$gesamtmwsttemp");

	##debug
	##dbprint
"Gegeben: $gegeben, Zurück: $zurueck, Rest: $rest, Karte: $tempkarte, Bar:
$tempbar, Summe: $summe\n";
}

sub change_hotkeys {
	my $funktion = shift;
	my $aktkey   = shift;
	if ( $funktion =~ /^gruppe:/ ) {
		($gruppe) = $funktion =~ /^gruppe:(.*)/;
		if ( $gruppe =~ /start/ ) {
			$labelHotkey->set_text("Aktuelle Tastengruppe: Start");
		}
		else {
			my $hotkeylabel = $hotkey[$aktkey]->get_label;
			($hotkeylabel) = $hotkeylabel =~ /F\d+\s(.*)/;
			$labelHotkey->set_text("Aktuelle Tastengruppe: $hotkeylabel");
		}
		update_hotkeys();
	}
	elsif ( $funktion =~ /^artikel/ ) {
		return if commit() == 1;

		# wie viele Positionen hat der aktuelle Bon?
		my $pos = keys %{ $bon{$uid} };
		my ($ttnr) = $funktion =~ /^artikel:(\d{8})/;

		# befindet sich der Artikel schon im Bon?
		# ja - dann Anzahl erhöhen
		my $counter = 0;
		foreach my $aktpos ( keys %{ $bon{$uid} } ) {
			if ( $bon{$uid}->{$aktpos}->{"TTNr"} eq $ttnr ) {
				$bon{$uid}->{$aktpos}->{"Anzahl"}++;
				$counter++;
			}
		}
		if ( $counter == 0 ) {
			$get_artikel->execute($ttnr);
			my ( $artbez, $eigpreis, $mwst, $oem ) =
			  $get_artikel->fetchrow_array;
			$pos++;
			$bon{$uid}->{$pos}->{"TTNr"}       = $ttnr;
			$bon{$uid}->{$pos}->{"Bezeichn"}   = $artbez;
			$bon{$uid}->{$pos}->{"OEM"}        = $oem;
			$bon{$uid}->{$pos}->{"Anzahl"}     = "1";
			$bon{$uid}->{$pos}->{"Stuckpreis"} = $eigpreis;
			$bon{$uid}->{$pos}->{"MwSt"}       = $mwst;
		}
		update_bon();
	}
}

sub create_bon {
	$listebon = Gtk2::SimpleList->new_from_treeview(
		$listebonwidget,
		'Pos'         => 'int',
		'TT-Nummer'   => 'text',
		'OEM-Nummer'  => 'text',
		'Bezeichnung' => 'text',
		'Anzahl'      => 'text',
		'Stückpreis' => 'text',
		'Netto'       => 'text',
		'Gesamtpreis' => 'text'
	);
	foreach ( $listebon->get_columns() ) {
		$_->set_resizable(1);
	}
	$listebon->set_headers_visible(1);
}

sub create_zbon {
	$listezbon = Gtk2::SimpleList->new_from_treeview(
		$listezbonwidget,
		'Warengruppe'    => 'text',
		'Anzahl Artikel' => 'text',
		'Gesamtumsatz'   => 'text',
		'davon MwSt.'    => 'text'
	);
	foreach ( $listezbon->get_columns() ) {
		$_->set_resizable(1);
	}
	$listezbon->set_headers_visible(1);
}

sub create_bonkopieliste {
	$listebonkopieliste = Gtk2::SimpleList->new_from_treeview(
		$listebonkopieliste,
		'Datum'   => 'text',
		'Uhrzeit' => 'text',
		'Umsatz'  => 'text'
	);
	foreach ( $listebonkopieliste->get_columns() ) {
		$_->set_resizable(1);
	}
	$listebonkopieliste->set_headers_visible(1);
}

sub create_suchergebnis {
	$listesuche = Gtk2::SimpleList->new_from_treeview(
		$listesuchergebnis,
		'TT-Nummer'    => 'text',
		'OEM-Nummer'   => 'text',
		'Hersteller'   => 'text',
		'Artikel Bez.' => 'text',
		'Preis'        => 'text',
		'MwSt'         => 'text'
	);
	foreach ( $listesuchergebnis->get_columns() ) {
		$_->set_resizable(1);
	}
	$listesuchergebnis->set_headers_visible(1);
}

sub update_hotkeys {
	if ( $gruppe eq "" ) {
		$gruppe = "start";
	}

	my $get_hotkeys =
	  $db->prepare(
'SELECT label, bubble, funktion, pos FROM stamm_hotkeys WHERE gruppe=? ORDER
BY pos;'
	  );
	$get_hotkeys->execute($gruppe);

	# Tasten aus Datenbank auslesen
	my $index = 1;
	while ( my ( $label, $bubble, $funktion, $pos ) =
		$get_hotkeys->fetchrow_array )
	{
		utf8::decode($label);
		$hotkey[$pos]->set_label($label);
		utf8::decode($bubble);
		$tooltip->set_tip( $hotkey[$pos], $bubble, undef );
	}
}

sub nummeric {

	# für nummerisches sortieren
	$a <=> $b;
}

#
#
# Hauptprogramm
#
#

# Liste für Suchergebnis generieren
create_suchergebnis();

# Liste für Z-Bon generieren
create_zbon();

# Bon-Liste generieren
create_bon();

# Liste für Bonkopie generieren
create_bonkopieliste();

# Hotkeys befüllen
update_hotkeys();

# Hauptfenster anzeigen
$terminal->show;

# Main Loop
Gtk2->main;

exit 0;

jploski wrote on Mon Aug  7 15:38:16 MEST 2006:
Can you email the file to jploski@users.sourceforge.net? It is rather difficult
to extract the text from the forum message (encoding of characters and whitespace
may matter).
bapiede wrote on Mon Aug  7 14:47:28 MEST 2006:
Thank you for your fast answer!

You're suggested parms didn't work. I tried with
./eclipse -vmargs -Xmx512M -Xms512M
and the same error occured.

I'm not fimilar with those settings. Do you know other settings to try?

regards, Christian
jploski wrote on Mon Aug  7 18:12:28 MEST 2006:
I submitted a bug report describing your problem:

http://sourceforge.net/tracker/index.php?func=detail&aid=1536109&group_id=75859&atid=545274

A quick workaround would be to encode your source files in ISO-8859-1.
bapiede wrote on Mon Aug  7 18:59:15 MEST 2006:
it worked! I saved the file with iso-8859-1 encoding - and everything is
fine!

Thank you again and again... ;-)
jploski wrote on Mon Aug  7 19:23:45 MEST 2006:
You should upgrade to 0.4.1. The problem was not caused by encoding, as
long as you have an Euro sign in your file, you will still have trouble
in 0.4.0.

Note: The above is an archived snapshot of a forum thread. Use the original thread at sf.net to post comments.