1 #=====================================================================
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
7 #=====================================================================
8 # SQL-Ledger Accounting
11 # Author: Dieter Simader
12 # Email: dsimader@sql-ledger.org
13 # Web: http://www.sql-ledger.org
17 # This program is free software; you can redistribute it and/or modify
18 # it under the terms of the GNU General Public License as published by
19 # the Free Software Foundation; either version 2 of the License, or
20 # (at your option) any later version.
22 # This program is distributed in the hope that it will be useful,
23 # but WITHOUT ANY WARRANTY; without even the implied warranty of
24 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 # GNU General Public License for more details.
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #=====================================================================
31 # user related functions
33 #=====================================================================
47 $main::lxdebug->enter_sub();
49 my ($type, $login) = @_;
54 my %user_data = $main::auth->read_user($login);
55 map { $self->{$_} = $user_data{$_} } keys %user_data;
58 $main::lxdebug->leave_sub();
64 $main::lxdebug->enter_sub();
71 # scan the locale directory and read in the LANGUAGE files
72 opendir(DIR, "locale");
74 my @dir = grep(!/(^\.\.?$|\..*)/, readdir(DIR));
76 foreach my $dir (@dir) {
77 next unless open(FH, "locale/$dir/LANGUAGE");
81 $cc{$dir} = "@language";
86 $main::lxdebug->leave_sub();
92 $main::lxdebug->enter_sub();
94 my ($self, $form) = @_;
100 if ($self->{login}) {
101 my %myconfig = $main::auth->read_user($self->{login});
103 # check if database is down
105 DBI->connect($myconfig{dbconnect}, $myconfig{dbuser},
107 or $self->error(DBI::errstr);
109 # we got a connection, check the version
110 my $query = qq|SELECT version FROM defaults|;
111 my $sth = $dbh->prepare($query);
112 $sth->execute || $form->dberror($query);
114 my ($dbversion) = $sth->fetchrow_array;
117 $self->create_employee_entry($form, $dbh, \%myconfig);
119 $self->create_schema_info_table($form, $dbh);
126 parse_dbupdate_controls($form, $myconfig{"dbdriver"});
128 map({ $form->{$_} = $myconfig{$_} }
129 qw(dbname dbhost dbport dbdriver dbuser dbpasswd dbconnect dateformat));
131 if (update_available($myconfig{"dbdriver"}, $dbversion) ||
132 update2_available($form, $controls)) {
134 $form->{"stylesheet"} = "lx-office-erp.css";
135 $form->{"title"} = $main::locale->text("Dataset upgrade");
137 print $form->parse_html_template("dbupgrade/header");
139 $form->{dbupdate} = "db$myconfig{dbname}";
140 $form->{ $form->{dbupdate} } = 1;
142 if ($form->{"show_dbupdate_warning"}) {
143 print $form->parse_html_template("dbupgrade/warning");
148 open(FH, ">$main::userspath/nologin") or die("$!");
150 # required for Oracle
151 $form->{dbdefault} = $sid;
153 # ignore HUP, QUIT in case the webserver times out
154 $SIG{HUP} = 'IGNORE';
155 $SIG{QUIT} = 'IGNORE';
157 $self->dbupdate($form);
158 $self->dbupdate2($form, $controls);
163 unlink("$main::userspath/nologin");
166 $self->{"menustyle"} eq "v3" ? "menuv3.pl" :
167 $self->{"menustyle"} eq "neu" ? "menunew.pl" :
168 $self->{"menustyle"} eq "xml" ? "menuXML.pl" :
171 print $form->parse_html_template("dbupgrade/footer", { "menufile" => $menufile });
178 $main::lxdebug->leave_sub();
184 $main::lxdebug->enter_sub();
186 my ($form, $db) = @_;
189 'Pg' => { 'yy-mm-dd' => 'set DateStyle to \'ISO\'',
190 'yyyy-mm-dd' => 'set DateStyle to \'ISO\'',
191 'mm/dd/yy' => 'set DateStyle to \'SQL, US\'',
192 'mm-dd-yy' => 'set DateStyle to \'POSTGRES, US\'',
193 'dd/mm/yy' => 'set DateStyle to \'SQL, EUROPEAN\'',
194 'dd-mm-yy' => 'set DateStyle to \'POSTGRES, EUROPEAN\'',
195 'dd.mm.yy' => 'set DateStyle to \'GERMAN\''
198 'yy-mm-dd' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YY-MM-DD\'',
199 'yyyy-mm-dd' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'YYYY-MM-DD\'',
200 'mm/dd/yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM/DD/YY\'',
201 'mm-dd-yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'MM-DD-YY\'',
202 'dd/mm/yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD/MM/YY\'',
203 'dd-mm-yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD-MM-YY\'',
204 'dd.mm.yy' => 'ALTER SESSION SET NLS_DATE_FORMAT = \'DD.MM.YY\'',
207 $form->{dboptions} = $dboptions{ $form->{dbdriver} }{ $form->{dateformat} };
209 if ($form->{dbdriver} eq 'Pg') {
210 $form->{dbconnect} = "dbi:Pg:dbname=$db";
213 if ($form->{dbdriver} eq 'Oracle') {
214 $form->{dbconnect} = "dbi:Oracle:sid=$form->{sid}";
217 if ($form->{dbhost}) {
218 $form->{dbconnect} .= ";host=$form->{dbhost}";
220 if ($form->{dbport}) {
221 $form->{dbconnect} .= ";port=$form->{dbport}";
224 $main::lxdebug->leave_sub();
228 $main::lxdebug->enter_sub();
230 my @drivers = DBI->available_drivers();
232 $main::lxdebug->leave_sub();
234 return (grep { /(Pg|Oracle)/ } @drivers);
238 $main::lxdebug->enter_sub();
240 my ($self, $form) = @_;
245 $form->{dbdefault} = $form->{dbuser} unless $form->{dbdefault};
246 $form->{sid} = $form->{dbdefault};
247 &dbconnect_vars($form, $form->{dbdefault});
250 DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
253 if ($form->{dbdriver} eq 'Pg') {
255 qq|SELECT datname FROM pg_database | .
256 qq|WHERE NOT datname IN ('template0', 'template1')|;
257 $sth = $dbh->prepare($query);
258 $sth->execute() || $form->dberror($query);
260 while (my ($db) = $sth->fetchrow_array) {
262 if ($form->{only_acc_db}) {
264 next if ($db =~ /^template/);
266 &dbconnect_vars($form, $db);
268 DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
272 qq|SELECT tablename FROM pg_tables | .
273 qq|WHERE (tablename = 'defaults') AND (tableowner = ?)|;
274 my $sth = $dbh->prepare($query);
275 $sth->execute($form->{dbuser}) ||
276 $form->dberror($query . " ($form->{dbuser})");
278 if ($sth->fetchrow_array) {
279 push(@dbsources, $db);
285 push(@dbsources, $db);
289 if ($form->{dbdriver} eq 'Oracle') {
290 if ($form->{only_acc_db}) {
292 qq|SELECT owner FROM dba_objects | .
293 qq|WHERE object_name = 'DEFAULTS' AND object_type = 'TABLE'|;
295 $query = qq|SELECT username FROM dba_users|;
298 $sth = $dbh->prepare($query);
299 $sth->execute || $form->dberror($query);
301 while (my ($db) = $sth->fetchrow_array) {
302 push(@dbsources, $db);
309 $main::lxdebug->leave_sub();
315 $main::lxdebug->enter_sub();
317 my ($self, $form) = @_;
319 $form->{sid} = $form->{dbdefault};
320 &dbconnect_vars($form, $form->{dbdefault});
322 DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
324 $form->{db} =~ s/\"//g;
326 'Pg' => qq|CREATE DATABASE "$form->{db}"|,
328 qq|CREATE USER "$form->{db}" DEFAULT TABLESPACE USERS | .
329 qq|TEMPORARY TABLESPACE TEMP IDENTIFIED BY "$form->{db}"|
336 push(@{$dboptions{"Pg"}}, "ENCODING = " . $dbh->quote($form->{"encoding"}))
337 if ($form->{"encoding"});
338 if ($form->{"dbdefault"}) {
339 my $dbdefault = $form->{"dbdefault"};
340 $dbdefault =~ s/[^a-zA-Z0-9_\-]//g;
341 push(@{$dboptions{"Pg"}}, "TEMPLATE = $dbdefault");
344 my $query = $dbcreate{$form->{dbdriver}};
345 $query .= " WITH " . join(" ", @{$dboptions{"Pg"}}) if (@{$dboptions{"Pg"}});
347 # Ignore errors if the database exists.
350 if ($form->{dbdriver} eq 'Oracle') {
351 $query = qq|GRANT CONNECT, RESOURCE TO "$form->{db}"|;
352 do_query($form, $dbh, $query);
356 # setup variables for the new database
357 if ($form->{dbdriver} eq 'Oracle') {
358 $form->{dbuser} = $form->{db};
359 $form->{dbpasswd} = $form->{db};
362 &dbconnect_vars($form, $form->{db});
364 $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
367 my $db_charset = $Common::db_encoding_to_charset{$form->{encoding}};
368 $db_charset ||= Common::DEFAULT_CHARSET;
371 $self->process_query($form, $dbh, "sql/lx-office.sql", undef, $db_charset);
373 # load chart of accounts
374 $self->process_query($form, $dbh, "sql/$form->{chart}-chart.sql", undef, $db_charset);
376 $query = "UPDATE defaults SET coa = ?";
377 do_query($form, $dbh, $query, $form->{chart});
381 $main::lxdebug->leave_sub();
384 # Process a Perl script which updates the database.
385 # If the script returns 1 then the update was successful.
386 # Return code "2" means "needs more interaction; remove
387 # users/nologin and exit".
388 # All other return codes are fatal errors.
389 sub process_perl_script {
390 $main::lxdebug->enter_sub();
392 my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
394 my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
396 my $file_charset = Common::DEFAULT_CHARSET;
398 if (ref($version_or_control) eq "HASH") {
399 $file_charset = $version_or_control->{charset};
404 next if !/^--\s*\@charset:\s*(.+)/;
408 $fh->seek(0, SEEK_SET);
411 my $contents = join "", <$fh>;
414 $db_charset ||= Common::DEFAULT_CHARSET;
416 my $iconv = SL::Iconv::get_converter($file_charset, $db_charset);
420 my %dbup_myconfig = ();
421 map({ $dbup_myconfig{$_} = $form->{$_}; }
422 qw(dbname dbuser dbpasswd dbhost dbport dbconnect));
424 my $nls_file = $filename;
425 $nls_file =~ s|.*/||;
426 $nls_file =~ s|.pl$||;
427 my $dbup_locale = Locale->new($main::language, $nls_file);
429 my $result = eval($contents);
436 if (!defined($result)) {
437 print $form->parse_html_template("dbupgrade/error",
438 { "file" => $filename,
441 } elsif (1 != $result) {
442 unlink("users/nologin") if (2 == $result);
446 if (ref($version_or_control) eq "HASH") {
447 $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
448 $dbh->quote($version_or_control->{"tag"}) . ", " .
449 $dbh->quote($form->{"login"}) . ")");
450 } elsif ($version_or_control) {
451 $dbh->do("UPDATE defaults SET version = " .
452 $dbh->quote($version_or_control));
456 $main::lxdebug->leave_sub();
460 $main::lxdebug->enter_sub();
462 my ($self, $form, $dbh, $filename, $version_or_control, $db_charset) = @_;
464 my $fh = IO::File->new($filename, "r") or $form->error("$filename : $!\n");
469 my $file_charset = Common::DEFAULT_CHARSET;
472 next if !/^--\s*\@charset:\s*(.+)/;
476 $fh->seek(0, SEEK_SET);
478 $db_charset ||= Common::DEFAULT_CHARSET;
483 $_ = SL::Iconv::convert($file_charset, $db_charset, $_);
485 # Remove DOS and Unix style line endings.
491 for (my $i = 0; $i < length($_); $i++) {
492 my $char = substr($_, $i, 1);
494 # Are we inside a string?
496 if ($char eq $quote_chars[-1]) {
502 if (($char eq "'") || ($char eq "\"")) {
503 push(@quote_chars, $char);
505 } elsif ($char eq ";") {
507 # Query is complete. Send it.
509 $sth = $dbh->prepare($query);
510 if (!$sth->execute()) {
511 my $errstr = $dbh->errstr;
514 $form->dberror("The database update/creation did not succeed. " .
515 "The file ${filename} containing the following " .
516 "query failed:<br>${query}<br>" .
517 "The error message was: ${errstr}<br>" .
518 "All changes in that file have been reverted.");
531 if (ref($version_or_control) eq "HASH") {
532 $dbh->do("INSERT INTO schema_info (tag, login) VALUES (" .
533 $dbh->quote($version_or_control->{"tag"}) . ", " .
534 $dbh->quote($form->{"login"}) . ")");
535 } elsif ($version_or_control) {
536 $dbh->do("UPDATE defaults SET version = " .
537 $dbh->quote($version_or_control));
543 $main::lxdebug->leave_sub();
547 $main::lxdebug->enter_sub();
549 my ($self, $form) = @_;
550 $form->{db} =~ s/\"//g;
551 my %dbdelete = ('Pg' => qq|DROP DATABASE "$form->{db}"|,
552 'Oracle' => qq|DROP USER "$form->{db}" CASCADE|);
554 $form->{sid} = $form->{dbdefault};
555 &dbconnect_vars($form, $form->{dbdefault});
557 DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
559 my $query = $dbdelete{$form->{dbdriver}};
560 do_query($form, $dbh, $query);
564 $main::lxdebug->leave_sub();
567 sub dbsources_unused {
568 $main::lxdebug->enter_sub();
570 my ($self, $form) = @_;
572 $form->{only_acc_db} = 1;
574 my %members = $main::auth->read_all_users();
575 my %dbexcl = map { $_ => 1 } grep { $_ } map { $_->{dbname} } values %members;
577 $dbexcl{$form->{dbdefault}} = 1;
578 $dbexcl{$main::auth->{DB_config}->{db}} = 1;
580 my @dbunused = grep { !$dbexcl{$_} } dbsources("", $form);
582 $main::lxdebug->leave_sub();
588 $main::lxdebug->enter_sub();
590 my ($self, $form) = @_;
592 my %members = $main::auth->read_all_users();
593 my $controls = parse_dbupdate_controls($form, $form->{dbdriver});
595 my ($query, $sth, %dbs_needing_updates);
597 foreach my $login (grep /[a-z]/, keys %members) {
598 my $member = $members{$login};
600 map { $form->{$_} = $member->{$_} } qw(dbname dbuser dbpasswd dbhost dbport);
601 dbconnect_vars($form, $form->{dbname});
603 my $dbh = DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd});
609 $query = qq|SELECT version FROM defaults|;
610 $sth = prepare_query($form, $dbh, $query);
611 if ($sth->execute()) {
612 ($version) = $sth->fetchrow_array();
617 next unless $version;
619 if (update_available($form->{dbdriver}, $version) || update2_available($form, $controls)) {
621 map { $dbinfo->{$_} = $member->{$_} } grep /^db/, keys %{ $member };
622 $dbs_needing_updates{$member->{dbhost} . "::" . $member->{dbname}} = $dbinfo;
626 $main::lxdebug->leave_sub();
628 return values %dbs_needing_updates;
632 $main::lxdebug->enter_sub(2);
634 my (@v, $version, $i);
636 @v = split(/\./, $_[0]);
637 while (scalar(@v) < 4) {
641 for ($i = 0; $i < 4; $i++) {
646 $main::lxdebug->leave_sub(2);
650 sub cmp_script_version {
651 my ($a_from, $a_to, $b_from, $b_to);
652 my ($i, $res_a, $res_b);
653 my ($my_a, $my_b) = ($a, $b);
655 $my_a =~ s/.*-upgrade-//;
657 $my_b =~ s/.*-upgrade-//;
659 ($my_a_from, $my_a_to) = split(/-/, $my_a);
660 ($my_b_from, $my_b_to) = split(/-/, $my_b);
662 $res_a = calc_version($my_a_from);
663 $res_b = calc_version($my_b_from);
665 if ($res_a == $res_b) {
666 $res_a = calc_version($my_a_to);
667 $res_b = calc_version($my_b_to);
670 return $res_a <=> $res_b;
673 sub update_available {
674 my ($dbdriver, $cur_version) = @_;
678 opendir SQLDIR, "sql/${dbdriver}-upgrade" || error("", "sql/${dbdriver}-upgrade: $!");
679 my @upgradescripts = grep /${dbdriver}-upgrade-\Q$cur_version\E.*\.(sql|pl)$/, readdir SQLDIR;
682 return ($#upgradescripts > -1);
685 sub create_schema_info_table {
686 $main::lxdebug->enter_sub();
688 my ($self, $form, $dbh) = @_;
690 my $query = "SELECT tag FROM schema_info LIMIT 1";
691 if (!$dbh->do($query)) {
694 qq|CREATE TABLE schema_info (| .
697 qq| itime timestamp DEFAULT now(), | .
698 qq| PRIMARY KEY (tag))|;
699 $dbh->do($query) || $form->dberror($query);
702 $main::lxdebug->leave_sub();
706 $main::lxdebug->enter_sub();
708 my ($self, $form) = @_;
712 $form->{sid} = $form->{dbdefault};
714 my @upgradescripts = ();
718 if ($form->{dbupdate}) {
720 # read update scripts into memory
721 opendir(SQLDIR, "sql/" . $form->{dbdriver} . "-upgrade")
722 or &error("", "sql/" . $form->{dbdriver} . "-upgrade : $!");
724 sort(cmp_script_version
725 grep(/$form->{dbdriver}-upgrade-.*?\.(sql|pl)$/,
730 my $db_charset = $main::dbcharset;
731 $db_charset ||= Common::DEFAULT_CHARSET;
733 foreach my $db (split(/ /, $form->{dbupdate})) {
735 next unless $form->{$db};
737 # strip db from dataset
739 &dbconnect_vars($form, $db);
742 DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
745 $dbh->do($form->{dboptions}) if ($form->{dboptions});
748 $query = qq|SELECT version FROM defaults|;
749 my ($version) = selectrow_query($form, $dbh, $query);
751 next unless $version;
753 $version = calc_version($version);
755 foreach my $upgradescript (@upgradescripts) {
756 my $a = $upgradescript;
757 $a =~ s/^\Q$form->{dbdriver}\E-upgrade-|\.(sql|pl)$//g;
760 my ($mindb, $maxdb) = split /-/, $a;
761 my $str_maxdb = $maxdb;
762 $mindb = calc_version($mindb);
763 $maxdb = calc_version($maxdb);
765 next if ($version >= $maxdb);
767 # if there is no upgrade script exit
768 last if ($version < $mindb);
771 $main::lxdebug->message(LXDebug::DEBUG2, "Applying Update $upgradescript");
772 if ($file_type eq "sql") {
773 $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
774 "-upgrade/$upgradescript", $str_maxdb, $db_charset);
776 $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
777 "-upgrade/$upgradescript", $str_maxdb, $db_charset);
789 $main::lxdebug->leave_sub();
795 $main::lxdebug->enter_sub();
797 my ($self, $form, $controls) = @_;
799 $form->{sid} = $form->{dbdefault};
801 my @upgradescripts = ();
802 my ($query, $sth, $tag);
805 @upgradescripts = sort_dbupdate_controls($controls);
807 my $db_charset = $main::dbcharset;
808 $db_charset ||= Common::DEFAULT_CHARSET;
810 foreach my $db (split / /, $form->{dbupdate}) {
812 next unless $form->{$db};
814 # strip db from dataset
816 &dbconnect_vars($form, $db);
819 DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd})
822 $dbh->do($form->{dboptions}) if ($form->{dboptions});
824 map({ $_->{"applied"} = 0; } @upgradescripts);
826 $self->create_schema_info_table($form, $dbh);
828 $query = qq|SELECT tag FROM schema_info|;
829 $sth = $dbh->prepare($query);
830 $sth->execute() || $form->dberror($query);
831 while (($tag) = $sth->fetchrow_array()) {
832 $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
837 foreach (@upgradescripts) {
838 if (!$_->{"applied"}) {
844 next if ($all_applied);
846 foreach my $control (@upgradescripts) {
847 next if ($control->{"applied"});
849 $control->{description} = SL::Iconv::convert($control->{charset}, $db_charset, $control->{description});
851 $control->{"file"} =~ /\.(sql|pl)$/;
855 $main::lxdebug->message(LXDebug::DEBUG2, "Applying Update $control->{file}");
856 print $form->parse_html_template("dbupgrade/upgrade_message2", $control);
858 if ($file_type eq "sql") {
859 $self->process_query($form, $dbh, "sql/" . $form->{"dbdriver"} .
860 "-upgrade2/$control->{file}", $control, $db_charset);
862 $self->process_perl_script($form, $dbh, "sql/" . $form->{"dbdriver"} .
863 "-upgrade2/$control->{file}", $control, $db_charset);
872 $main::lxdebug->leave_sub();
877 sub update2_available {
878 $main::lxdebug->enter_sub();
880 my ($form, $controls) = @_;
882 map({ $_->{"applied"} = 0; } values(%{$controls}));
884 dbconnect_vars($form, $form->{"dbname"});
887 DBI->connect($form->{dbconnect}, $form->{dbuser}, $form->{dbpasswd}) ||
890 my ($query, $tag, $sth);
892 $query = qq|SELECT tag FROM schema_info|;
893 $sth = $dbh->prepare($query);
894 if ($sth->execute()) {
895 while (($tag) = $sth->fetchrow_array()) {
896 $controls->{$tag}->{"applied"} = 1 if (defined($controls->{$tag}));
902 map({ $main::lxdebug->leave_sub() and return 1 if (!$_->{"applied"}) }
903 values(%{$controls}));
905 $main::lxdebug->leave_sub();
910 $main::lxdebug->enter_sub();
914 # format dbconnect and dboptions string
915 dbconnect_vars($self, $self->{dbname});
917 map { $self->{$_} =~ s/\r//g; } qw(address signature);
919 $main::auth->save_user($self->{login}, map { $_, $self->{$_} } config_vars());
921 my $dbh = DBI->connect($self->{dbconnect}, $self->{dbuser}, $self->{dbpasswd});
923 $self->create_employee_entry($form, $dbh, $self);
927 $main::lxdebug->leave_sub();
930 sub create_employee_entry {
931 $main::lxdebug->enter_sub();
936 my $myconfig = shift;
938 # add login to employee table if it does not exist
939 # no error check for employee table, ignore if it does not exist
940 my ($login) = selectrow_query($form, $dbh, qq|SELECT id FROM employee WHERE login = ?|, $self->{login});
943 $query = qq|INSERT INTO employee (login, name, workphone, role) VALUES (?, ?, ?, ?)|;
944 do_query($form, $dbh, $query, ($self->{login}, $myconfig->{name}, $myconfig->{tel}, "user"));
947 $main::lxdebug->leave_sub();
951 $main::lxdebug->enter_sub();
953 my @conf = qw(acs address admin businessnumber company countrycode
954 currency dateformat dbconnect dbdriver dbhost dbport dboptions
955 dbname dbuser dbpasswd email fax name numberformat password
956 printer role sid signature stylesheet tel templates vclimit angebote
957 bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen
958 taxnumber co_ustid duns menustyle template_format default_media
959 default_printer_id copies show_form_details favorites
960 pdonumber sdonumber);
962 $main::lxdebug->leave_sub();
968 $main::lxdebug->enter_sub();
970 my ($self, $msg) = @_;
972 $main::lxdebug->show_backtrace();
974 if ($ENV{HTTP_USER_AGENT}) {
975 print qq|Content-Type: text/html
977 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
979 <body bgcolor=ffffff>
981 <h2><font color=red>Error!</font></h2>
988 $main::lxdebug->leave_sub();