ef985f40c3ec002588b3f15cd65de55252a279db
[kivitendo-erp.git] / bin / mozilla / admin.pl
1 #=====================================================================
2 # LX-Office ERP
3 # Copyright (C) 2004
4 # Based on SQL-Ledger Version 2.1.9
5 # Web http://www.lx-office.org
6 #
7 #=====================================================================
8 # SQL-Ledger Accounting
9 # Copyright (c) 2002
10 #
11 #  Author: Dieter Simader
12 #   Email: dsimader@sql-ledger.org
13 #     Web: http://www.sql-ledger.org
14 #
15 #
16 # This program is free software; you can redistribute it and/or modify
17 # it under the terms of the GNU General Public License as published by
18 # the Free Software Foundation; either version 2 of the License, or
19 # (at your option) any later version.
20 #
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #======================================================================
29 #
30 # setup module
31 # add/edit/delete users
32 #
33 #======================================================================
34
35 $menufile = "menu.ini";
36
37 use DBI;
38 use CGI;
39
40 use SL::Form;
41 use SL::User;
42 use SL::Common;
43
44 require "bin/mozilla/common.pl";
45
46 our $cgi = new CGI('');
47
48 $form = new Form;
49 $form->{"root"} = "root login";
50
51 $locale = new Locale $language, "admin";
52
53 # customization
54 if (-f "bin/mozilla/custom_$form->{script}") {
55   eval { require "bin/mozilla/custom_$form->{script}"; };
56   $form->error($@) if ($@);
57 }
58
59 $form->{stylesheet} = "lx-office-erp.css";
60 $form->{favicon}    = "favicon.ico";
61
62 if ($form->{action}) {
63
64
65   $subroutine = $locale->findsub($form->{action});
66
67   if ($subroutine eq 'login') {
68     if ($form->{rpw}) {
69       $form->{rpw} = crypt $form->{rpw}, "ro";
70     }
71   }
72
73   check_password();
74
75   call_sub($subroutine);
76
77 } else {
78
79   # if there are no drivers bail out
80   $form->error($locale->text('No Database Drivers available!'))
81     unless (User->dbdrivers);
82
83   # create memberfile
84   if (!-f $memberfile) {
85     open(FH, ">$memberfile") or $form->error("$memberfile : $!");
86     print FH qq|# SQL-Ledger Accounting members
87
88 [root login]
89 password=
90
91 |;
92     close FH;
93   }
94
95   adminlogin();
96
97 }
98
99 1;
100
101 # end
102
103 sub adminlogin {
104
105   $form->{title} =
106     qq|Lx-Office ERP $form->{version} | . $locale->text('Administration');
107
108   $form->header();
109   print $form->parse_html_template('admin/adminlogin');
110 }
111
112 sub login {
113   list_users();
114 }
115
116 sub list_users {
117
118   $form->error($locale->text('File locked!')) if (-f "${memberfile}.LCK");
119
120   open(FH, "$memberfile") or $form->error("$memberfile : $!");
121
122   my %members;
123
124   while (<FH>) {
125     chomp;
126
127     if (/^\[.*\]/) {
128       $login = $_;
129       $login =~ s/(\[|\])//g;
130
131       $members{$login} = { "login" => $login };
132     }
133
134     if (/^([a-z]+)=(.*)/) {
135       $members{$login}->{$1} = $2;
136     }
137   }
138
139   close(FH);
140
141   delete $members{"root login"};
142   map { $_->{templates} =~ s|.*/||; } values %members;
143
144   $form->{title}  = "Lx-Office ERP " . $locale->text('Administration');
145   $form->{LOCKED} = -e "$userspath/nologin";
146   $form->{MEMBERS} = [ @members{sort { lc $a cmp lc $b } keys %members} ];
147
148   $form->header();
149   print $form->parse_html_template("admin/list_users");
150 }
151
152 sub add_user {
153
154   $form->{title} =
155       "Lx-Office ERP "
156     . $locale->text('Administration') . " / "
157     . $locale->text('Add User');
158
159   $form->{Oracle_sid}    = $sid;
160   $form->{Oracle_dbport} = '1521';
161   $form->{Oracle_dbhost} = `hostname`;
162
163   my $myconfig = {
164     "vclimit"      => 200,
165     "countrycode"  => "de",
166     "numberformat" => "1000,00",
167     "dateformat"   => "dd.mm.yy",
168     "stylesheet"   => "lx-office-erp.css",
169   };
170
171   edit_user_form($myconfig);
172 }
173
174 sub edit {
175
176   $form->{title} =
177       "Lx-Office ERP "
178     . $locale->text('Administration') . " / "
179     . $locale->text('Edit User');
180   $form->{edit} = 1;
181
182   $form->isblank("login", $locale->text("The login is missing."));
183
184   # get user
185   my $myconfig = new User "$memberfile", "$form->{login}";
186
187   $myconfig->{signature} =~ s/\\n/\r\n/g;
188   $myconfig->{address}   =~ s/\\n/\r\n/g;
189
190   # strip basedir from templates directory
191   $myconfig->{templates} =~ s|.*/||;
192
193   edit_user_form($myconfig);
194 }
195
196 sub edit_user_form {
197   my ($myconfig) = @_;
198
199   my @valid_dateformats = qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd);
200   $form->{ALL_DATEFORMATS} = [ map { { "format" => $_, "selected" => $_ eq $myconfig->{dateformat} } } @valid_dateformats ];
201
202   my @valid_numberformats = qw(1,000.00 1000.00 1.000,00 1000,00);
203   $form->{ALL_NUMBERFORMATS} = [ map { { "format" => $_, "selected" => $_ eq $myconfig->{numberformat} } } @valid_numberformats ];
204
205   %countrycodes = User->country_codes;
206   $form->{ALL_COUNTRYCODES} = [];
207   foreach $countrycode (sort { $countrycodes{$a} cmp $countrycodes{$b} } keys %countrycodes) {
208     push @{ $form->{ALL_COUNTRYCODES} }, { "value"    => $countrycode,
209                                            "name"     => $countrycodes{$countrycode},
210                                            "selected" => $countrycode eq $myconfig->{countrycode} };
211   }
212
213   # is there a templates basedir
214   if (!-d "$templates") {
215     $form->error(sprintf($locale->text("The directory %s does not exist."), $templates));
216   }
217
218   opendir TEMPLATEDIR, "$templates/." or $form->error("$templates : $!");
219   my @all     = readdir(TEMPLATEDIR);
220   my @alldir  = sort grep { -d "$templates/$_" && !/^\.\.?$/ } @all;
221   my @allhtml = sort grep { -f "$templates/$_" && /\.html$/ } @all;
222   closedir TEMPLATEDIR;
223
224   @alldir = grep !/\.(html|tex|sty|odt|xml|txb)$/, @alldir;
225   @alldir = grep !/^(webpages|\.svn)$/, @alldir;
226
227   @allhtml = reverse grep !/Default/, @allhtml;
228   push @allhtml, 'Default';
229   @allhtml = reverse @allhtml;
230
231   $form->{ALL_TEMPLATES} = [ map { { "name", => $_, "selected" => $_ eq $myconfig->{templates} } } @alldir ];
232
233   $lastitem = $allhtml[0];
234   $lastitem =~ s/-.*//g;
235   $form->{ALL_MASTER_TEMPLATES} = [ { "name" => $lastitem, "selected" => $lastitem eq "German" } ];
236   foreach $item (@allhtml) {
237     $item =~ s/-.*//g;
238     next if ($item eq $lastitem);
239
240     push @{ $form->{ALL_MASTER_TEMPLATES} }, { "name" => $item, "selected" => $item eq "German" };
241     $lastitem = $item;
242   }
243
244   # css dir has styles that are not intended as general layouts.
245   # reverting to hardcoded list
246   $form->{ALL_STYLESHEETS} = [ map { { "name" => $_, "selected" => $_ eq $myconfig->{stylesheet} } } qw(lx-office-erp.css Win2000.css) ];
247
248   $form->{"menustyle_" . $myconfig->{menustyle} } = 1;
249
250   map { $form->{"myc_${_}"} = $myconfig->{$_} } keys %{ $myconfig };
251
252   map { $form->{"Pg_${_}"} = $myconfig->{$_} } qw(dbhost dbport dbname dbuser dbpasswd);
253
254   # access control
255   my @acsorder = ();
256   my %acs      = ();
257   my %excl     = ();
258   open(FH, $menufile) or $form->error("$menufile : $!");
259
260   while ($item = <FH>) {
261     next unless $item =~ /\[/;
262     next if $item =~ /\#/;
263
264     $item =~ s/(\[|\])//g;
265     chomp $item;
266
267     my ($level, $menuitem);
268
269     if ($item =~ /--/) {
270       ($level, $menuitem) = split /--/, $item, 2;
271     } else {
272       $level    = $item;
273       $menuitem = $item;
274       push @acsorder, $item;
275     }
276
277     $acs{$level} ||= [];
278     push @{ $acs{$level} }, $menuitem;
279
280   }
281
282   foreach $item (split(/;/, $myconfig->{acs})) {
283     ($key, $value) = split /--/, $item, 2;
284     $excl{$key}{$value} = 1;
285   }
286
287   $form->{ACLS}    = [];
288   $form->{all_acs} = "";
289
290   foreach $key (@acsorder) {
291     my $acl = { "checked" => $form->{login} ? !$excl{$key}->{$key} : 1,
292                 "name"    => "${key}--${key}",
293                 "title"   => $key,
294                 "SUBACLS" => [], };
295     $form->{all_acs} .= "${key}--${key};";
296
297     foreach $item (@{ $acs{$key} }) {
298       next if ($key eq $item);
299
300       my $subacl = { "checked" => $form->{login} ? !$excl{$key}->{$item} : 1,
301                      "name"    => "${key}--${item}",
302                      "title"   => $item };
303       push @{ $acl->{SUBACLS} }, $subacl;
304       $form->{all_acs} .= "${key}--${item};";
305     }
306     push @{ $form->{ACLS} }, $acl;
307   }
308
309   chop $form->{all_acs};
310
311   $form->header();
312   print $form->parse_html_template("admin/edit_user");
313 }
314
315 sub save {
316
317   # no driver checked
318   $form->error($locale->text('Database Driver not checked!'))
319     unless $form->{dbdriver};
320
321   # no spaces allowed in login name
322   ($form->{login}) = split / /, $form->{login};
323
324   $form->isblank("login", $locale->text('Login name missing!'));
325
326   # check for duplicates
327   if (!$form->{edit}) {
328     $temp = new User "$memberfile", "$form->{login}";
329
330     if ($temp->{login}) {
331       $form->error("$form->{login} " . $locale->text('is already a member!'));
332     }
333   }
334
335   # no spaces allowed in directories
336   ($form->{newtemplates}) = split / /, $form->{newtemplates};
337
338   if ($form->{newtemplates}) {
339     $form->{templates} = $form->{newtemplates};
340   } else {
341     $form->{templates} =
342       ($form->{usetemplates}) ? $form->{usetemplates} : $form->{login};
343   }
344
345   # is there a basedir
346   if (!-d "$templates") {
347     $form->error(sprintf($locale->text("The directory %s does not exist."), $templates));
348   }
349
350   # add base directory to $form->{templates}
351   $form->{templates} =~ s|.*/||;
352   $form->{templates} =  "$templates/$form->{templates}";
353
354   $myconfig = new User "$memberfile", "$form->{login}";
355
356   # redo acs variable and delete all the acs codes
357   my @acs;
358   foreach $item (split m|;|, $form->{all_acs}) {
359     my $name =  "ACS_${item}";
360     $name    =~ s| |+|g;
361     push @acs, $item if !$form->{$name};
362     delete $form->{$name};
363   }
364   $form->{acs} = join ";", @acs;
365
366   # check which database was filled in
367   if ($form->{dbdriver} eq 'Oracle') {
368     $form->{sid}      = $form->{Oracle_sid},;
369     $form->{dbhost}   = $form->{Oracle_dbhost},;
370     $form->{dbport}   = $form->{Oracle_dbport};
371     $form->{dbpasswd} = $form->{Oracle_dbpasswd};
372     $form->{dbuser}   = $form->{Oracle_dbuser};
373     $form->{dbname}   = $form->{Oracle_dbuser};
374
375     $form->isblank("dbhost", $locale->text('Hostname missing!'));
376     $form->isblank("dbport", $locale->text('Port missing!'));
377     $form->isblank("dbuser", $locale->text('Dataset missing!'));
378   }
379   if ($form->{dbdriver} eq 'Pg') {
380     $form->{dbhost}   = $form->{Pg_dbhost};
381     $form->{dbport}   = $form->{Pg_dbport};
382     $form->{dbpasswd} = $form->{Pg_dbpasswd};
383     $form->{dbuser}   = $form->{Pg_dbuser};
384     $form->{dbname}   = $form->{Pg_dbname};
385
386     $form->isblank("dbname", $locale->text('Dataset missing!'));
387     $form->isblank("dbuser", $locale->text('Database User missing!'));
388   }
389
390   foreach $item (keys %{$form}) {
391     $myconfig->{$item} = $form->{$item};
392   }
393
394   delete $myconfig->{stylesheet};
395   if ($form->{userstylesheet}) {
396     $myconfig->{stylesheet} = $form->{userstylesheet};
397   }
398
399   $myconfig->save_member($memberfile, $userspath);
400
401   if ($webdav) {
402     @webdavdirs =
403       qw(angebote bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen);
404     foreach $directory (@webdavdirs) {
405       $file = "webdav/" . $directory . "/webdav-user";
406       if ($form->{$directory}) {
407         if (open(HTACCESS, "$file")) {
408           while (<HTACCESS>) {
409             ($login, $password) = split(/:/, $_);
410             if ($login ne $form->{login}) {
411               $newfile .= $_;
412             }
413           }
414           close(HTACCESS);
415         }
416         open(HTACCESS, "> $file") or die "cannot open $file $!\n";
417         $newfile .= $myconfig->{login} . ":" . $myconfig->{password} . "\n";
418         print(HTACCESS $newfile);
419         close(HTACCESS);
420       } else {
421         $form->{$directory} = 0;
422         if (open(HTACCESS, "$file")) {
423           while (<HTACCESS>) {
424             ($login, $password) = split(/:/, $_);
425             if ($login ne $form->{login}) {
426               $newfile .= $_;
427             }
428           }
429           close(HTACCESS);
430         }
431         open(HTACCESS, "> $file") or die "cannot open $file $!\n";
432         print(HTACCESS $newfile);
433         close(HTACCESS);
434       }
435     }
436   }
437
438   $form->{templates}       =~ s|.*/||;
439   $form->{templates}       =  "${templates}/$form->{templates}";
440   $form->{mastertemplates} =~ s|.*/||;
441
442   # create user template directory and copy master files
443   if (!-d "$form->{templates}") {
444     umask(002);
445
446     if (mkdir "$form->{templates}", oct("771")) {
447
448       umask(007);
449
450       # copy templates to the directory
451       opendir TEMPLATEDIR, "$templates/." or $form - error("$templates : $!");
452       @templates = grep /$form->{mastertemplates}.*?\.(html|tex|sty|xml|txb)$/,
453         readdir TEMPLATEDIR;
454       closedir TEMPLATEDIR;
455
456       foreach $file (@templates) {
457         open(TEMP, "$templates/$file")
458           or $form->error("$templates/$file : $!");
459
460         $file =~ s/$form->{mastertemplates}-//;
461         open(NEW, ">$form->{templates}/$file")
462           or $form->error("$form->{templates}/$file : $!");
463
464         while ($line = <TEMP>) {
465           print NEW $line;
466         }
467         close(TEMP);
468         close(NEW);
469       }
470     } else {
471       $form->error("$!: $form->{templates}");
472     }
473   }
474
475   $form->redirect($locale->text('User saved!'));
476
477 }
478
479 sub delete {
480
481   $form->{templates} =
482     ($form->{templates})
483     ? "$templates/$form->{templates}"
484     : "$templates/$form->{login}";
485
486   $form->error($locale->text('File locked!')) if (-f ${memberfile} . LCK);
487   open(FH, ">${memberfile}.LCK") or $form->error("${memberfile}.LCK : $!");
488   close(FH);
489
490   open(CONF, "+<$memberfile") or $form->error("$memberfile : $!");
491
492   @config = <CONF>;
493
494   seek(CONF, 0, 0);
495   truncate(CONF, 0);
496
497   while ($line = shift @config) {
498
499     if ($line =~ /^\[/) {
500       last if ($line =~ /\[$form->{login}\]/);
501       $login = login_name($line);
502     }
503
504     if ($line =~ /^templates=/) {
505       $user{$login} = get_value($line);
506     }
507
508     print CONF $line;
509   }
510
511   # remove everything up to next login or EOF
512   # and save template variable
513   while ($line = shift @config) {
514     if ($line =~ /^templates=/) {
515       $templatedir = get_value($line);
516     }
517     last if ($line =~ /^\[/);
518   }
519
520   # this one is either the next login or EOF
521   print CONF $line;
522
523   $login = login_name($line);
524
525   while ($line = shift @config) {
526     if ($line =~ /^\[/) {
527       $login = login_name($line);
528     }
529
530     if ($line =~ /^templates=/) {
531       $user{$login} = get_value($line);
532     }
533
534     print CONF $line;
535   }
536
537   close(CONF);
538   unlink "${memberfile}.LCK";
539
540   # scan %user for $templatedir
541   foreach $login (keys %user) {
542     last if ($found = ($templatedir eq $user{$login}));
543   }
544
545   # if found keep directory otherwise delete
546   if (!$found) {
547
548     # delete it if there is a template directory
549     $dir = "$form->{templates}";
550     if (-d "$dir") {
551       unlink <$dir/*.html>;
552       unlink <$dir/*.tex>;
553       unlink <$dir/*.sty>;
554       rmdir "$dir";
555     }
556   }
557
558   # delete config file for user
559   unlink "$userspath/$form->{login}.conf";
560
561   $form->redirect($locale->text('User deleted!'));
562
563 }
564
565 sub login_name {
566   my $login = shift;
567
568   $login =~ s/\[\]//g;
569   return ($login) ? $login : undef;
570
571 }
572
573 sub get_value {
574   my $line = shift;
575
576   my ($null, $value) = split(/=/, $line, 2);
577
578   # remove comments
579   $value =~ s/\s#.*//g;
580
581   # remove any trailing whitespace
582   $value =~ s/^\s*(.*?)\s*$/$1/;
583
584   $value;
585 }
586
587 sub change_admin_password {
588
589   $form->{title} =
590       qq|Lx-Office ERP |
591     . $locale->text('Administration') . " / "
592     . $locale->text('Change Admin Password');
593
594   $form->header();
595   print $form->parse_html_template("admin/change_admin_password");
596 }
597
598 sub change_password {
599   if ($form->{"password"} ne $form->{"password_again"}) {
600     $form->{title} =
601       qq|Lx-Office ERP |
602       . $locale->text('Administration') . " / "
603       . $locale->text('Change Admin Password');
604
605     $form->header();
606     $form->error($locale->text("The passwords do not match."));
607   }
608
609   $root->{password} = $form->{password};
610
611   $root->{'root login'} = 1;
612   $root->save_member($memberfile);
613
614   $form->{callback} =
615     "$form->{script}?action=list_users&rpw=$root->{password}";
616
617   $form->redirect($locale->text('Password changed!'));
618 }
619
620 sub check_password {
621   $root = new User "$memberfile", $form->{root};
622
623   if (!defined($root->{password}) || ($root->{password} ne $form->{rpw})) {
624     $form->error($locale->text('Incorrect Password!'));
625   }
626
627 }
628
629 sub pg_database_administration {
630
631   $form->{dbdriver} = 'Pg';
632   dbselect_source();
633
634 }
635
636 sub oracle_database_administration {
637
638   $form->{dbdriver} = 'Oracle';
639   dbselect_source();
640
641 }
642
643 sub dbdriver_defaults {
644
645   # load some defaults for the selected driver
646   %driverdefaults = (
647                      'Pg' => { dbport        => '5432',
648                                dbuser        => 'postgres',
649                                dbdefault     => 'template1',
650                                dbhost        => 'localhost',
651                                connectstring => $locale->text('Connect to')
652                      },
653                      'Oracle' => { dbport        => '1521',
654                                    dbuser        => 'oralin',
655                                    dbdefault     => $sid,
656                                    dbhost        => `hostname`,
657                                    connectstring => 'SID'
658                      });
659
660   map { $form->{$_} = $driverdefaults{ $form->{dbdriver} }{$_} }
661     keys %{ $driverdefaults{Pg} };
662
663 }
664
665 sub dbselect_source {
666
667   dbdriver_defaults();
668
669   $msg{Pg} =
670     $locale->text(
671     'Leave host and port field empty unless you want to make a remote connection.'
672     );
673   $msg{Oracle} =
674     $locale->text(
675            'You must enter a host and port for local and remote connections!');
676
677   $form->{title} =
678     "Lx-Office ERP / " . $locale->text('Database Administration');
679
680   $form->header;
681
682   print qq|
683 <body class=admin>
684
685
686 <center>
687 <h2>$form->{title}</h2>
688
689 <form method=post action=$form->{script}>
690
691 <table>
692 <tr><td>
693
694 <table>
695
696   <tr class=listheading>
697     <th colspan=4>| . $locale->text('Database') . qq|</th>
698   </tr>
699
700 <input type=hidden name=dbdriver value=$form->{dbdriver}>
701
702   <tr><td>
703    <table>
704
705   <tr>
706
707     <th align=right>| . $locale->text('Host') . qq|</th>
708     <td><input name=dbhost size=25 value=$form->{dbhost}></td>
709     <th align=right>| . $locale->text('Port') . qq|</th>
710     <td><input name=dbport size=5 value=$form->{dbport}></td>
711
712   </tr>
713
714   <tr>
715
716     <th align=right>| . $locale->text('User') . qq|</th>
717     <td><input name="dbuser" size="10" value="$form->{dbuser}"></td>
718     <th align=right>| . $locale->text('Password') . qq|</th>
719     <td><input type="password" name="dbpasswd" size="10"></td>
720
721   </tr>
722
723   <tr>
724
725     <th align=right>$form->{connectstring}</th>
726     <td colspan=3><input name=dbdefault size=10 value=$form->{dbdefault}></td>
727
728   </tr>
729
730 </table>
731
732 </td></tr>
733 </table>
734
735 <input name=callback type=hidden value="$form->{script}?action=list_users&rpw=$form->{rpw}">
736 <input type=hidden name=rpw value=$form->{rpw}>
737
738 <br>
739
740 <input type=submit class=submit name=action value="|
741     . $locale->text('Create Dataset') . qq|">|;
742 # Vorübergehend Deaktiviert
743 # <input type=submit class=submit name=action value="|
744 #     . $locale->text('Update Dataset') . qq|">
745 print qq| <input type=submit class=submit name=action value="|
746     . $locale->text('Delete Dataset') . qq|">
747
748 </form>
749
750 </td></tr>
751 </table>
752
753 <p>|
754     . $locale->text(
755     'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!'
756     )
757
758     . qq|
759 <br>$msg{$form->{dbdriver}}
760
761
762 </body>
763 </html>
764 |;
765
766 }
767
768 sub continue {
769   call_sub($form->{"nextsub"});
770 }
771
772 sub update_dataset {
773
774   %needsupdate = User->dbneedsupdate(\%$form);
775
776   $form->{title} =
777       "Lx-Office ERP "
778     . $locale->text('Database Administration') . " / "
779     . $locale->text('Update Dataset');
780
781   $form->header;
782
783   print qq|
784 <body class=admin>
785
786
787 <center>
788 <h2>$form->{title}</h2>
789 |;
790   my $field_id = 0;
791   foreach $key (sort keys %needsupdate) {
792     if ($needsupdate{$key} ne $form->{dbversion}) {
793       $upd .= qq|<input id="$field_id" name="db$key" type="checkbox" value="1" checked> $key\n|;
794       $form->{dbupdate} .= "db$key ";
795       $field_id++;
796     }
797   }
798
799   chop $form->{dbupdate};
800
801   if ($form->{dbupdate}) {
802
803     print qq|
804 <table width=100%>
805 <form method=post action=$form->{script}>
806
807 <input type=hidden name="dbdriver"  value="$form->{dbdriver}">
808 <input type=hidden name="dbhost"    value="$form->{dbhost}">
809 <input type=hidden name="dbport"    value="$form->{dbport}">
810 <input type=hidden name="dbuser"    value="$form->{dbuser}">
811 <input type=hidden name="dbpasswd"  value="$form->{dbpasswd}">
812 <input type=hidden name="dbdefault" value="$form->{dbdefault}">
813
814 <tr class=listheading>
815   <th>| . $locale->text('The following Datasets need to be updated') . qq|</th>
816 </tr>
817 <tr>
818 <td>
819
820 $upd
821
822 </td>
823 </tr>
824 <tr>
825 <td>
826
827 <input name=dbupdate type=hidden value="$form->{dbupdate}">
828
829 <input name=callback type=hidden value="$form->{script}?action=list_users&rpw=$form->{rpw}">
830
831 <input type=hidden name=rpw value=$form->{rpw}>
832
833 <input type=hidden name=nextsub value=dbupdate>
834
835 <hr size=3 noshade>
836
837 <br>
838 <input type=submit class=submit name=action value="|
839       . $locale->text('Continue') . qq|">
840
841 </td></tr>
842 </table>
843 </form>
844 |;
845
846   } else {
847
848     print $locale->text('All Datasets up to date!');
849
850   }
851
852   print qq|
853
854 </body>
855 </html>
856 |;
857
858 }
859
860 sub dbupdate {
861   $form->{"stylesheet"} = "lx-office-erp.css";
862   $form->{"title"} = $main::locale->text("Dataset upgrade");
863   $form->header();
864   my $dbname =
865     join(" ",
866          map({ s/\s//g; s/^db//; $_; }
867              grep({ $form->{$_} }
868                   split(/\s+/, $form->{"dbupdate"}))));
869   print($form->parse_html_template("dbupgrade/header",
870                                    { "dbname" => $dbname }));
871
872   User->dbupdate(\%$form);
873
874   print qq|
875 <hr>
876
877 | . $locale->text('Dataset updated!') . qq|
878
879 <br>
880
881 <a id="enddatasetupdate" href="admin.pl?action=login&| .
882 join("&", map({ "$_=" . $form->escape($form->{$_}); } qw(rpw))) .
883 qq|">| . $locale->text("Continue") . qq|</a>|;
884
885 }
886
887 sub create_dataset {
888   $form->{dbsources} = join " ", map { "[${_}]" } sort User->dbsources(\%$form);
889
890   $form->{CHARTS} = [];
891
892   opendir SQLDIR, "sql/." or $form - error($!);
893   foreach $item (sort grep /-chart\.sql\z/, readdir SQLDIR) {
894     next if ($item eq 'Default-chart.sql');
895     $item =~ s/-chart\.sql//;
896     push @{ $form->{CHARTS} }, { "name"     => $item,
897                                  "selected" => $item eq "Germany-DATEV-SKR03EU" };
898   }
899   closedir SQLDIR;
900
901   my $default_charset = $dbcharset;
902   $default_charset ||= Common::DEFAULT_CHARSET;
903
904   $form->{DBENCODINGS} = [];
905
906   foreach my $encoding (@Common::db_encodings) {
907     push @{ $form->{DBENCODINGS} }, { "dbencoding" => $encoding->{dbencoding},
908                                       "label"      => $encoding->{label},
909                                       "selected"   => $encoding->{charset} eq $default_charset };
910   }
911
912   $form->{title} =
913       "Lx-Office ERP "
914     . $locale->text('Database Administration') . " / "
915     . $locale->text('Create Dataset');
916
917   $form->header();
918   print $form->parse_html_template("admin/create_dataset");
919 }
920
921 sub dbcreate {
922   $form->isblank("db", $locale->text('Dataset missing!'));
923
924   User->dbcreate(\%$form);
925
926   $form->{title} =
927       "Lx-Office ERP "
928     . $locale->text('Database Administration') . " / "
929     . $locale->text('Create Dataset');
930
931   $form->header();
932   print $form->parse_html_template("admin/dbcreate");
933 }
934
935 sub delete_dataset {
936   @dbsources = User->dbsources_unused(\%$form, $memberfile);
937   $form->error($locale->text('Nothing to delete!')) unless @dbsources;
938
939   $form->{title} =
940       "Lx-Office ERP "
941     . $locale->text('Database Administration') . " / "
942     . $locale->text('Delete Dataset');
943   $form->{DBSOURCES} = [ map { { "name", $_ } } sort @dbsources ];
944
945   $form->header();
946   print $form->parse_html_template("admin/delete_dataset");
947 }
948
949 sub dbdelete {
950
951   if (!$form->{db}) {
952     $form->error($locale->text('No Dataset selected!'));
953   }
954
955   User->dbdelete(\%$form);
956
957   $form->{title} =
958       "Lx-Office ERP "
959     . $locale->text('Database Administration') . " / "
960     . $locale->text('Delete Dataset');
961
962   $form->header();
963   print $form->parse_html_template("admin/dbdelete");
964 }
965
966 sub unlock_system {
967
968   unlink "$userspath/nologin";
969
970   $form->{callback} =
971     "$form->{script}?action=list_users&rpw=$root->{password}";
972
973   $form->redirect($locale->text('Lockfile removed!'));
974
975 }
976
977 sub lock_system {
978
979   open(FH, ">$userspath/nologin")
980     or $form->error($locale->text('Cannot create Lock!'));
981   close(FH);
982
983   $form->{callback} =
984     "$form->{script}?action=list_users&rpw=$root->{password}";
985
986   $form->redirect($locale->text('Lockfile created!'));
987
988 }