Den Pfad zu den Vorlagen richtig setzen. Ging mit dem letzten Commit kaputt.
[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   if (-f "css/lx-office-erp.css") {
164     $myconfig->{stylesheet} = "lx-office-erp.css";
165   }
166
167   $myconfig->{vclimit}      = 200;
168   $myconfig->{countrycode}  = "de";
169   $myconfig->{numberformat} = "1000,00";
170   $myconfig->{dateformat}   = "dd.mm.yy";
171
172   &form_header;
173   &form_footer;
174
175 }
176
177 sub edit {
178
179   $form->{title} =
180       "Lx-Office ERP "
181     . $locale->text('Administration') . " / "
182     . $locale->text('Edit User');
183   $form->{edit} = 1;
184
185   &form_header;
186   &form_footer;
187
188 }
189
190 sub form_footer {
191
192   if ($form->{edit}) {
193     $delete =
194       qq|<input type=submit class=submit name=action value="|
195       . $locale->text('Delete') . qq|">
196 <input type=hidden name=edit value=1>|;
197   }
198
199   print qq|
200
201 <input name=callback type=hidden value="$form->{script}?action=list_users&rpw=$form->{rpw}">
202 <input type=hidden name=rpw value=$form->{rpw}>
203
204 <input type=submit class=submit name=action value="|
205     . $locale->text('Save') . qq|">
206 $delete
207
208 </form>
209
210 </body>
211 </html>
212 |;
213
214 }
215
216 sub form_header {
217
218   # if there is a login, get user
219   if ($form->{login}) {
220
221     # get user
222     $myconfig = new User "$memberfile", "$form->{login}";
223
224     $myconfig->{signature} =~ s/\\n/\r\n/g;
225     $myconfig->{address}   =~ s/\\n/\r\n/g;
226
227     # strip basedir from templates directory
228     $myconfig->{templates} =~ s/^$templates\///;
229
230     # $myconfig->{dbpasswd} = unpack 'u', $myconfig->{dbpasswd};
231   }
232
233   foreach $item (qw(mm-dd-yy mm/dd/yy dd-mm-yy dd/mm/yy dd.mm.yy yyyy-mm-dd)) {
234     $dateformat .=
235       ($item eq $myconfig->{dateformat})
236       ? "<option selected>$item\n"
237       : "<option>$item\n";
238   }
239
240   foreach $item (qw(1,000.00 1000.00 1.000,00 1000,00)) {
241     $numberformat .=
242       ($item eq $myconfig->{numberformat})
243       ? "<option selected>$item\n"
244       : "<option>$item\n";
245   }
246
247   %countrycodes = User->country_codes;
248   $countrycodes = "";
249   foreach $key (sort { $countrycodes{$a} cmp $countrycodes{$b} }
250                 keys %countrycodes
251     ) {
252     $countrycodes .=
253       ($myconfig->{countrycode} eq $key)
254       ? "<option selected value=$key>$countrycodes{$key}"
255       : "<option value=$key>$countrycodes{$key}";
256   }
257   $countrycodes = qq|<option value="">American English\n$countrycodes|;
258
259   # is there a templates basedir
260   if (!-d "$templates") {
261     $form->error(  $locale->text('Directory')
262                  . ": $templates "
263                  . $locale->text('does not exist'));
264   }
265
266   opendir TEMPLATEDIR, "$templates/." or $form->error("$templates : $!");
267   my @all = readdir(TEMPLATEDIR);
268   my @alldir = sort(grep({ -d "$templates/$_" && !/^\.\.?$/ } @all));
269   my @allhtml = sort(grep({ -f "$templates/$_" && /\.html$/ } @all));
270   closedir TEMPLATEDIR;
271
272   @alldir = grep !/\.(html|tex|sty|odt|xml|txb)$/, @alldir;
273   @alldir = grep !/^(webpages|\.svn)$/, @alldir;
274
275   @allhtml = reverse grep !/Default/, @allhtml;
276   push @allhtml, 'Default';
277   @allhtml = reverse @allhtml;
278
279   foreach $item (@alldir) {
280     if ($item eq $myconfig->{templates}) {
281       $usetemplates .= qq|<option selected>$item\n|;
282     } else {
283       $usetemplates .= qq|<option>$item\n|;
284     }
285   }
286
287   $lastitem = $allhtml[0];
288   $lastitem =~ s/-.*//g;
289   $mastertemplates = qq|<option>$lastitem\n|;
290   foreach $item (@allhtml) {
291     $item =~ s/-.*//g;
292
293     if ($item ne $lastitem) {
294       my $selected = $item eq "German" ? " selected" : "";
295       $mastertemplates .= qq|<option$selected>$item\n|;
296       $lastitem = $item;
297     }
298   }
299
300 #  opendir CSS, "css/.";
301 #  @all = grep /.*\.css$/, readdir CSS;
302 #  closedir CSS;
303
304 # css dir has styles that are not intended as general layouts.
305 # reverting to hardcoded list
306   @all = qw(lx-office-erp.css Win2000.css);
307
308   foreach $item (@all) {
309     if ($item eq $myconfig->{stylesheet}) {
310       $selectstylesheet .= qq|<option selected>$item\n|;
311     } else {
312       $selectstylesheet .= qq|<option>$item\n|;
313     }
314   }
315
316   $form->header;
317
318   if ($myconfig->{menustyle} eq "v3") {
319     $menustyle_v3 = "checked";
320   } elsif ($myconfig->{menustyle} eq "neu") {
321     $menustyle_neu = "checked";
322   } else {
323     $menustyle_old = "checked";
324   }
325
326   print qq|
327 <body class=admin>
328
329 <form method=post action=$form->{script}>
330
331 <table width=100%>
332   <tr class=listheading><th colspan=2>$form->{title}</th></tr>
333   <tr size=5></tr>
334   <tr valign=top>
335     <td>
336       <table>
337         <tr>
338           <th align=right>| . $locale->text('Login') . qq|</th>
339           <td><input name="login" value="$myconfig->{login}"></td>
340         </tr>
341         <tr>
342           <th align=right>| . $locale->text('Password') . qq|</th>
343           <td><input type="password" name="password" size="8" value="$myconfig->{password}"></td>
344           <input type="hidden" name="old_password" value="$myconfig->{password}">
345         </tr>
346         <tr>
347           <th align=right>| . $locale->text('Name') . qq|</th>
348           <td><input name="name" size="15" value="$myconfig->{name}"></td>
349         </tr>
350         <tr>
351           <th align=right>| . $locale->text('E-mail') . qq|</th>
352           <td><input name=email size=30 value="$myconfig->{email}"></td>
353         </tr>
354         <tr valign=top>
355           <th align=right>| . $locale->text('Signature') . qq|</th>
356           <td><textarea name=signature rows=3 cols=35>$myconfig->{signature}</textarea></td>
357         </tr>
358         <tr>
359           <th align=right>| . $locale->text('Phone') . qq|</th>
360           <td><input name=tel size=14 value="$myconfig->{tel}"></td>
361         </tr>
362         <tr>
363           <th align=right>| . $locale->text('Fax') . qq|</th>
364           <td><input name=fax size=14 value="$myconfig->{fax}"></td>
365         </tr>
366         <tr>
367           <th align=right>| . $locale->text('Company') . qq|</th>
368           <td><input name=company size=35 value="$myconfig->{company}"></td>
369         </tr>
370         <tr valign=top>
371           <th align=right>| . $locale->text('Address') . qq|</th>
372           <td><textarea name=address rows=4 cols=35>$myconfig->{address}</textarea></td>
373         </tr>
374         <tr valign=top>
375           <th align=right>| . $locale->text('Tax number') . qq|</th>
376           <td><input name=taxnumber size=14 value="$myconfig->{taxnumber}"></td>
377         </tr>
378         <tr valign=top>
379           <th align=right>| . $locale->text('Ust-IDNr') . qq|</th>
380           <td><input name=co_ustid size=14 value="$myconfig->{co_ustid}"></td>
381         </tr>
382         <tr valign=top>
383           <th align=right>| . $locale->text('DUNS-Nr') . qq|</th>
384           <td><input name=duns size=14 value="$myconfig->{duns}"></td>
385         </tr>
386       </table>
387     </td>
388     <td>
389       <table>
390         <tr>
391           <th align=right>| . $locale->text('Date Format') . qq|</th>
392           <td><select name=dateformat>$dateformat</select></td>
393         </tr>
394         <tr>
395           <th align=right>| . $locale->text('Number Format') . qq|</th>
396           <td><select name=numberformat>$numberformat</select></td>
397         </tr>
398         <tr>
399           <th align=right>| . $locale->text('Dropdown Limit') . qq|</th>
400           <td><input name=vclimit value="$myconfig->{vclimit}"></td>
401         </tr>
402         <tr>
403           <th align=right>| . $locale->text('Language') . qq|</th>
404           <td><select name=countrycode>$countrycodes</select></td>
405         </tr>
406         <tr>
407           <th align=right>| . $locale->text('Stylesheet') . qq|</th>
408           <td><select name=userstylesheet>$selectstylesheet</select></td>
409         </tr>
410         <tr>
411           <th align=right>| . $locale->text('Printer') . qq|</th>
412           <td><input name=printer size=20 value="$myconfig->{printer}"></td>
413         </tr>
414         <tr>
415           <th align=right>| . $locale->text('Use Templates') . qq|</th>
416           <td><select name=usetemplates>$usetemplates</select></td>
417         </tr>
418         <tr>
419           <th align=right>| . $locale->text('New Templates') . qq|</th>
420           <td><input name=newtemplates></td>
421         </tr>
422         <tr>
423           <th align=right>| . $locale->text('Setup Templates') . qq|</th>
424           <td><select name=mastertemplates>$mastertemplates</select></td>
425         </tr>
426        <tr>
427            <th align=right>| . $locale->text('Setup Menu') . qq|</th>
428            <td><input name=menustyle type=radio class=radio value=v3 $menustyle_v3>&nbsp;| .
429            $locale->text("Top (CSS)") . qq|
430            <input name=menustyle type=radio class=radio value=neu $menustyle_neu>&nbsp;| .
431            $locale->text("Top (Javascript)") . qq|
432            <input name=menustyle type=radio class=radio value=old $menustyle_old>&nbsp;| .
433            $locale->text("Old (on the side)") . qq|
434            </td>
435          </tr>
436         <input type=hidden name=templates value=$myconfig->{templates}>
437       </table>
438     </td>
439   </tr>
440   <tr class=listheading>
441     <th colspan=2>| . $locale->text('Database') . qq|</th>
442   </tr>|;
443
444   # list section for database drivers
445   foreach $item (User->dbdrivers) {
446
447     print qq|
448   <tr>
449     <td colspan=2>
450       <table>
451         <tr>|;
452
453     $checked = "";
454     if ($myconfig->{dbdriver} eq $item) {
455       map { $form->{"${item}_$_"} = $myconfig->{$_} }
456         qw(dbhost dbport dbuser dbpasswd dbname sid);
457       $checked = "checked";
458     }
459
460     print qq|
461           <th align=right>| . $locale->text('Driver') . qq|</th>
462           <td><input name="dbdriver" type="radio" class="radio" value="$item" $checked>&nbsp;$item</td>
463           <th align=right>| . $locale->text('Host') . qq|</th>
464           <td><input name="${item}_dbhost" size=30 value="$form->{"${item}_dbhost"}"></td>
465         </tr>
466         <tr>|;
467
468     if ($item eq 'Pg') {
469     
470       print qq|
471           <th align=right>| . $locale->text('Dataset') . qq|</th>
472           <td><input name="Pg_dbname" size="15" value="$form->{Pg_dbname}"></td>
473           <th align=right>| . $locale->text('Port') . qq|</th>
474           <td><input name="Pg_dbport" size="4" value="$form->{Pg_dbport}"></td>
475         </tr>
476         <tr>
477           <th align=right>| . $locale->text('User') . qq|</th>
478           <td><input name="${item}_dbuser" size=15 value="$form->{"${item}_dbuser"}"></td>
479           <th align=right>| . $locale->text('Password') . qq|</th>
480           <td><input name="${item}_dbpasswd" type=password size=10 value="$form->{"${item}_dbpasswd"}"></td>
481         </tr>|;
482
483     }
484
485     if ($item eq 'Oracle') {
486       print qq|
487           <th align=right>SID</th>
488           <td><input name=Oracle_sid value=$form->{Oracle_sid}></td>
489           <th align=right>| . $locale->text('Port') . qq|</th>
490           <td><input name=Oracle_dbport size=4 value=$form->{Oracle_dbport}></td>
491         </tr>
492         <tr>
493           <th align=right>| . $locale->text('Dataset') . qq|</th>
494           <td><input name="${item}_dbuser" size=15 value=$form->{"${item}_dbuser"}></td>
495           <th align=right>| . $locale->text('Password') . qq|</th>
496           <td><input name="${item}_dbpasswd" type=password size=10 value="$form->{"${item}_dbpasswd"}"></td>
497
498         </tr>|;
499     }
500
501     print qq|
502         <input type="hidden" name="old_dbpasswd" value="$myconfig->{dbpasswd}">
503       </table>
504     </td>
505   </tr>
506   <tr>
507     <td colspan=2><hr size=2 noshade></td>
508   </tr>
509 |;
510
511   }
512
513   # access control
514   open(FH, $menufile) or $form->error("$menufile : $!");
515
516   # scan for first menu level
517   @a = <FH>;
518   close(FH);
519
520   foreach $item (@a) {
521     next unless $item =~ /\[/;
522     next if $item =~ /\#/;
523
524     $item =~ s/(\[|\])//g;
525     chop $item;
526
527     if ($item =~ /--/) {
528       ($level, $menuitem) = split /--/, $item, 2;
529     } else {
530       $level    = $item;
531       $menuitem = $item;
532       push @acsorder, $item;
533     }
534
535     push @{ $acs{$level} }, $menuitem;
536
537   }
538
539   %role = ('admin'      => $locale->text('Administrator'),
540            'user'       => $locale->text('User'),
541            'manager'    => $locale->text('Manager'),
542            'supervisor' => $locale->text('Supervisor'));
543
544   $selectrole = "";
545   foreach $item (qw(user supervisor manager admin)) {
546     $selectrole .=
547       ($myconfig->{role} eq $item)
548       ? "<option selected value=$item>$role{$item}\n"
549       : "<option value=$item>$role{$item}\n";
550   }
551
552   print qq|
553   <tr class=listheading>
554     <th colspan=2>| . $locale->text('Access Control') . qq|</th>
555   </tr>
556   <tr>
557     <td><select name=role>$selectrole</select></td>
558   </tr>
559 |;
560
561   foreach $item (split(/;/, $myconfig->{acs})) {
562     ($key, $value) = split /--/, $item, 2;
563     $excl{$key}{$value} = 1;
564   }
565
566   foreach $key (@acsorder) {
567
568     $checked = "checked";
569     if ($form->{login}) {
570       $checked = ($excl{$key}{$key}) ? "" : "checked";
571     }
572
573     # can't have variable names with spaces
574     # the 1 is for apache 2
575     $item = $form->escape("${key}--$key", 1);
576
577     $acsheading = $key;
578     $acsheading =~ s/ /&nbsp;/g;
579
580     $acsheading = qq|
581     <th align=left><input name="$item" class=checkbox type=checkbox value=1 $checked>&nbsp;$acsheading</th>\n|;
582     $menuitems .= "$item;";
583     $acsdata = "
584     <td>";
585
586     foreach $item (@{ $acs{$key} }) {
587       next if ($key eq $item);
588
589       $checked = "checked";
590       if ($form->{login}) {
591         $checked = ($excl{$key}{$item}) ? "" : "checked";
592       }
593
594       $acsitem = $form->escape("${key}--$item", 1);
595
596       $acsdata .= qq|
597     <br><input name="$acsitem" class=checkbox type=checkbox value=1 $checked>&nbsp;$item|;
598       $menuitems .= "$acsitem;";
599     }
600
601     $acsdata .= "
602     </td>";
603
604     print qq|
605   <tr valign=top>$acsheading $acsdata
606   </tr>
607 |;
608   }
609
610   print qq|<input type=hidden name=acs value="$menuitems">
611 |;
612   if ($webdav) {
613     @webdavdirs =
614       qw(angebote bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen);
615     foreach $directory (@webdavdirs) {
616       if ($myconfig->{$directory}) {
617         $webdav{"${directory}c"} = "checked";
618       } else {
619         $webdav{"${directory}c"} = "";
620       }
621     }
622     print qq|
623    <tr>
624     <td colspan=2><hr size=3 noshade></td>
625   </tr>
626   <tr class=listheading>
627     <th colspan=2>| . $locale->text('WEBDAV-Zugriff') . qq|</th>
628   </tr>
629   <table width=100%>
630         <tr>
631         <td><input name=angebote class=checkbox type=checkbox value=1 $webdav{angebotec}>&nbsp;Angebot</td>
632         <td><input name=bestellungen class=checkbox type=checkbox value=1 $webdav{bestellungenc}>&nbsp;Bestellung</td>
633         <td><input name=rechnungen class=checkbox type=checkbox value=1 $webdav{rechnungenc}>&nbsp;Rechnung</td>
634         </tr>
635         <tr>
636         <td><input name=anfragen class=checkbox type=checkbox value=1 $webdav{anfragenc}>&nbsp;Angebot</td>
637         <td><input name=lieferantenbestellungen class=checkbox type=checkbox value=1 $webdav{lieferantenbestellungenc}>&nbsp;Lieferantenbestellung</td>
638         <td><input name=einkaufsrechnungen class=checkbox type=checkbox value=1 $webdav{einkaufsrechnungenc}>&nbsp;Einkaufsrechnung</td>
639         </tr>
640   </table>
641   <tr>
642     <td colspan=2><hr size=3 noshade></td>
643   </tr>
644 |;
645   }
646   print qq|
647 </table>
648 </div>
649 |;
650
651 }
652
653 sub save {
654
655   # no driver checked
656   $form->error($locale->text('Database Driver not checked!'))
657     unless $form->{dbdriver};
658
659   # no spaces allowed in login name
660   ($form->{login}) = split / /, $form->{login};
661
662   $form->isblank("login", $locale->text('Login name missing!'));
663
664   # check for duplicates
665   if (!$form->{edit}) {
666     $temp = new User "$memberfile", "$form->{login}";
667
668     if ($temp->{login}) {
669       $form->error("$form->{login} " . $locale->text('is already a member!'));
670     }
671   }
672
673   # no spaces allowed in directories
674   ($form->{newtemplates}) = split / /, $form->{newtemplates};
675
676   if ($form->{newtemplates}) {
677     $form->{templates} = $form->{newtemplates};
678   } else {
679     $form->{templates} =
680       ($form->{usetemplates}) ? $form->{usetemplates} : $form->{login};
681   }
682
683   # is there a basedir
684   if (!-d "$templates") {
685     $form->error(  $locale->text('Directory')
686                  . ": $templates "
687                  . $locale->text('does not exist'));
688   }
689
690   # add base directory to $form->{templates}
691   $form->{templates} = "$templates/$form->{templates}";
692
693   $myconfig = new User "$memberfile", "$form->{login}";
694
695   # redo acs variable and delete all the acs codes
696   @acs = split(/;/, $form->{acs});
697
698   $form->{acs} = "";
699   foreach $item (@acs) {
700     $item = $form->escape($item, 1);
701
702     if (!$form->{$item}) {
703       $form->{acs} .= $form->unescape($form->unescape($item)) . ";";
704     }
705     delete $form->{$item};
706   }
707
708   # check which database was filled in
709   if ($form->{dbdriver} eq 'Oracle') {
710     $form->{sid}      = $form->{Oracle_sid},;
711     $form->{dbhost}   = $form->{Oracle_dbhost},;
712     $form->{dbport}   = $form->{Oracle_dbport};
713     $form->{dbpasswd} = $form->{Oracle_dbpasswd};
714     $form->{dbuser}   = $form->{Oracle_dbuser};
715     $form->{dbname}   = $form->{Oracle_dbuser};
716
717     $form->isblank("dbhost", $locale->text('Hostname missing!'));
718     $form->isblank("dbport", $locale->text('Port missing!'));
719     $form->isblank("dbuser", $locale->text('Dataset missing!'));
720   }
721   if ($form->{dbdriver} eq 'Pg') {
722     $form->{dbhost}   = $form->{Pg_dbhost};
723     $form->{dbport}   = $form->{Pg_dbport};
724     $form->{dbpasswd} = $form->{Pg_dbpasswd};
725     $form->{dbuser}   = $form->{Pg_dbuser};
726     $form->{dbname}   = $form->{Pg_dbname};
727
728     $form->isblank("dbname", $locale->text('Dataset missing!'));
729     $form->isblank("dbuser", $locale->text('Database User missing!'));
730   }
731
732   if ($webdav) {
733     @webdavdirs =
734       qw(angebote bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen);
735     foreach $directory (@webdavdirs) {
736       if ($form->{$directory}) {
737         $form->{$directory} = $form->{$directory};
738       } else {
739         $form->{$directory} = 0;
740       }
741     }
742   }
743
744   foreach $item (keys %{$form}) {
745     $myconfig->{$item} = $form->{$item};
746   }
747
748   delete $myconfig->{stylesheet};
749   if ($form->{userstylesheet}) {
750     $myconfig->{stylesheet} = $form->{userstylesheet};
751   }
752
753   $myconfig->save_member($memberfile, $userspath);
754
755   if ($webdav) {
756     @webdavdirs =
757       qw(angebote bestellungen rechnungen anfragen lieferantenbestellungen einkaufsrechnungen);
758     foreach $directory (@webdavdirs) {
759       $file = "webdav/" . $directory . "/webdav-user";
760       if ($form->{$directory}) {
761         if (open(HTACCESS, "$file")) {
762           while (<HTACCESS>) {
763             ($login, $password) = split(/:/, $_);
764             if ($login ne $form->{login}) {
765               $newfile .= $_;
766             }
767           }
768           close(HTACCESS);
769         }
770         open(HTACCESS, "> $file") or die "cannot open $file $!\n";
771         $newfile .= $myconfig->{login} . ":" . $myconfig->{password} . "\n";
772         print(HTACCESS $newfile);
773         close(HTACCESS);
774       } else {
775         $form->{$directory} = 0;
776         if (open(HTACCESS, "$file")) {
777           while (<HTACCESS>) {
778             ($login, $password) = split(/:/, $_);
779             if ($login ne $form->{login}) {
780               $newfile .= $_;
781             }
782           }
783           close(HTACCESS);
784         }
785         open(HTACCESS, "> $file") or die "cannot open $file $!\n";
786         print(HTACCESS $newfile);
787         close(HTACCESS);
788       }
789     }
790   }
791
792   $form->{templates}       =~ s|.*/||;
793   $form->{templates}       =  "${templates}/$form->{templates}";
794   $form->{mastertemplates} =~ s|.*/||;
795
796   # create user template directory and copy master files
797   if (!-d "$form->{templates}") {
798     umask(002);
799
800     if (mkdir "$form->{templates}", oct("771")) {
801
802       umask(007);
803
804       # copy templates to the directory
805       opendir TEMPLATEDIR, "$templates/." or $form - error("$templates : $!");
806       @templates = grep /$form->{mastertemplates}.*?\.(html|tex|sty|xml|txb)$/,
807         readdir TEMPLATEDIR;
808       closedir TEMPLATEDIR;
809
810       foreach $file (@templates) {
811         open(TEMP, "$templates/$file")
812           or $form->error("$templates/$file : $!");
813
814         $file =~ s/$form->{mastertemplates}-//;
815         open(NEW, ">$form->{templates}/$file")
816           or $form->error("$form->{templates}/$file : $!");
817
818         while ($line = <TEMP>) {
819           print NEW $line;
820         }
821         close(TEMP);
822         close(NEW);
823       }
824     } else {
825       $form->error("$!: $form->{templates}");
826     }
827   }
828
829   $form->redirect($locale->text('User saved!'));
830
831 }
832
833 sub delete {
834
835   $form->{templates} =
836     ($form->{templates})
837     ? "$templates/$form->{templates}"
838     : "$templates/$form->{login}";
839
840   $form->error($locale->text('File locked!')) if (-f ${memberfile} . LCK);
841   open(FH, ">${memberfile}.LCK") or $form->error("${memberfile}.LCK : $!");
842   close(FH);
843
844   open(CONF, "+<$memberfile") or $form->error("$memberfile : $!");
845
846   @config = <CONF>;
847
848   seek(CONF, 0, 0);
849   truncate(CONF, 0);
850
851   while ($line = shift @config) {
852
853     if ($line =~ /^\[/) {
854       last if ($line =~ /\[$form->{login}\]/);
855       $login = &login_name($line);
856     }
857
858     if ($line =~ /^templates=/) {
859       $user{$login} = &get_value($line);
860     }
861
862     print CONF $line;
863   }
864
865   # remove everything up to next login or EOF
866   # and save template variable
867   while ($line = shift @config) {
868     if ($line =~ /^templates=/) {
869       $templatedir = &get_value($line);
870     }
871     last if ($line =~ /^\[/);
872   }
873
874   # this one is either the next login or EOF
875   print CONF $line;
876
877   $login = &login_name($line);
878
879   while ($line = shift @config) {
880     if ($line =~ /^\[/) {
881       $login = &login_name($line);
882     }
883
884     if ($line =~ /^templates=/) {
885       $user{$login} = &get_value($line);
886     }
887
888     print CONF $line;
889   }
890
891   close(CONF);
892   unlink "${memberfile}.LCK";
893
894   # scan %user for $templatedir
895   foreach $login (keys %user) {
896     last if ($found = ($templatedir eq $user{$login}));
897   }
898
899   # if found keep directory otherwise delete
900   if (!$found) {
901
902     # delete it if there is a template directory
903     $dir = "$form->{templates}";
904     if (-d "$dir") {
905       unlink <$dir/*.html>;
906       unlink <$dir/*.tex>;
907       unlink <$dir/*.sty>;
908       rmdir "$dir";
909     }
910   }
911
912   # delete config file for user
913   unlink "$userspath/$form->{login}.conf";
914
915   $form->redirect($locale->text('User deleted!'));
916
917 }
918
919 sub login_name {
920   my $login = shift;
921
922   $login =~ s/\[\]//g;
923   return ($login) ? $login : undef;
924
925 }
926
927 sub get_value {
928   my $line = shift;
929
930   my ($null, $value) = split(/=/, $line, 2);
931
932   # remove comments
933   $value =~ s/\s#.*//g;
934
935   # remove any trailing whitespace
936   $value =~ s/^\s*(.*?)\s*$/$1/;
937
938   $value;
939 }
940
941 sub change_admin_password {
942
943   $form->{title} =
944       qq|Lx-Office ERP |
945     . $locale->text('Administration') . " / "
946     . $locale->text('Change Admin Password');
947
948   $form->header();
949   print $form->parse_html_template("admin/change_admin_password");
950 }
951
952 sub change_password {
953   if ($form->{"password"} ne $form->{"password_again"}) {
954     $form->{title} =
955       qq|Lx-Office ERP |
956       . $locale->text('Administration') . " / "
957       . $locale->text('Change Admin Password');
958
959     $form->header();
960     $form->error($locale->text("The passwords do not match."));
961   }
962
963   $root->{password} = $form->{password};
964
965   $root->{'root login'} = 1;
966   $root->save_member($memberfile);
967
968   $form->{callback} =
969     "$form->{script}?action=list_users&rpw=$root->{password}";
970
971   $form->redirect($locale->text('Password changed!'));
972 }
973
974 sub check_password {
975   $root = new User "$memberfile", $form->{root};
976
977   if (!defined($root->{password}) || ($root->{password} ne $form->{rpw})) {
978     $form->error($locale->text('Incorrect Password!'));
979   }
980
981 }
982
983 sub pg_database_administration {
984
985   $form->{dbdriver} = 'Pg';
986   &dbselect_source;
987
988 }
989
990 sub oracle_database_administration {
991
992   $form->{dbdriver} = 'Oracle';
993   &dbselect_source;
994
995 }
996
997 sub dbdriver_defaults {
998
999   # load some defaults for the selected driver
1000   %driverdefaults = (
1001                      'Pg' => { dbport        => '5432',
1002                                dbuser        => 'postgres',
1003                                dbdefault     => 'template1',
1004                                dbhost        => 'localhost',
1005                                connectstring => $locale->text('Connect to')
1006                      },
1007                      'Oracle' => { dbport        => '1521',
1008                                    dbuser        => 'oralin',
1009                                    dbdefault     => $sid,
1010                                    dbhost        => `hostname`,
1011                                    connectstring => 'SID'
1012                      });
1013
1014   map { $form->{$_} = $driverdefaults{ $form->{dbdriver} }{$_} }
1015     keys %{ $driverdefaults{Pg} };
1016
1017 }
1018
1019 sub dbselect_source {
1020
1021   &dbdriver_defaults;
1022
1023   $msg{Pg} =
1024     $locale->text(
1025     'Leave host and port field empty unless you want to make a remote connection.'
1026     );
1027   $msg{Oracle} =
1028     $locale->text(
1029            'You must enter a host and port for local and remote connections!');
1030
1031   $form->{title} =
1032     "Lx-Office ERP / " . $locale->text('Database Administration');
1033
1034   $form->header;
1035
1036   print qq|
1037 <body class=admin>
1038
1039
1040 <center>
1041 <h2>$form->{title}</h2>
1042
1043 <form method=post action=$form->{script}>
1044
1045 <table>
1046 <tr><td>
1047
1048 <table>
1049
1050   <tr class=listheading>
1051     <th colspan=4>| . $locale->text('Database') . qq|</th>
1052   </tr>
1053
1054 <input type=hidden name=dbdriver value=$form->{dbdriver}>
1055
1056   <tr><td>
1057    <table>
1058
1059   <tr>
1060
1061     <th align=right>| . $locale->text('Host') . qq|</th>
1062     <td><input name=dbhost size=25 value=$form->{dbhost}></td>
1063     <th align=right>| . $locale->text('Port') . qq|</th>
1064     <td><input name=dbport size=5 value=$form->{dbport}></td>
1065
1066   </tr>
1067
1068   <tr>
1069
1070     <th align=right>| . $locale->text('User') . qq|</th>
1071     <td><input name="dbuser" size="10" value="$form->{dbuser}"></td>
1072     <th align=right>| . $locale->text('Password') . qq|</th>
1073     <td><input type="password" name="dbpasswd" size="10"></td>
1074
1075   </tr>
1076
1077   <tr>
1078
1079     <th align=right>$form->{connectstring}</th>
1080     <td colspan=3><input name=dbdefault size=10 value=$form->{dbdefault}></td>
1081
1082   </tr>
1083
1084 </table>
1085
1086 </td></tr>
1087 </table>
1088
1089 <input name=callback type=hidden value="$form->{script}?action=list_users&rpw=$form->{rpw}">
1090 <input type=hidden name=rpw value=$form->{rpw}>
1091
1092 <br>
1093
1094 <input type=submit class=submit name=action value="|
1095     . $locale->text('Create Dataset') . qq|">|;
1096 # Vorübergehend Deaktiviert
1097 # <input type=submit class=submit name=action value="|
1098 #     . $locale->text('Update Dataset') . qq|">
1099 print qq| <input type=submit class=submit name=action value="|
1100     . $locale->text('Delete Dataset') . qq|">
1101
1102 </form>
1103
1104 </td></tr>
1105 </table>
1106
1107 <p>|
1108     . $locale->text(
1109     'This is a preliminary check for existing sources. Nothing will be created or deleted at this stage!'
1110     )
1111
1112     . qq|
1113 <br>$msg{$form->{dbdriver}}
1114
1115
1116 </body>
1117 </html>
1118 |;
1119
1120 }
1121
1122 sub continue {
1123   call_sub($form->{"nextsub"});
1124 }
1125
1126 sub update_dataset {
1127
1128   %needsupdate = User->dbneedsupdate(\%$form);
1129
1130   $form->{title} =
1131       "Lx-Office ERP "
1132     . $locale->text('Database Administration') . " / "
1133     . $locale->text('Update Dataset');
1134
1135   $form->header;
1136
1137   print qq|
1138 <body class=admin>
1139
1140
1141 <center>
1142 <h2>$form->{title}</h2>
1143 |;
1144   my $field_id = 0;
1145   foreach $key (sort keys %needsupdate) {
1146     if ($needsupdate{$key} ne $form->{dbversion}) {
1147       $upd .= qq|<input id="$field_id" name="db$key" type="checkbox" value="1" checked> $key\n|;
1148       $form->{dbupdate} .= "db$key ";
1149       $field_id++;
1150     }
1151   }
1152
1153   chop $form->{dbupdate};
1154
1155   if ($form->{dbupdate}) {
1156
1157     print qq|
1158 <table width=100%>
1159 <form method=post action=$form->{script}>
1160
1161 <input type=hidden name="dbdriver"  value="$form->{dbdriver}">
1162 <input type=hidden name="dbhost"    value="$form->{dbhost}">
1163 <input type=hidden name="dbport"    value="$form->{dbport}">
1164 <input type=hidden name="dbuser"    value="$form->{dbuser}">
1165 <input type=hidden name="dbpasswd"  value="$form->{dbpasswd}">
1166 <input type=hidden name="dbdefault" value="$form->{dbdefault}">
1167
1168 <tr class=listheading>
1169   <th>| . $locale->text('The following Datasets need to be updated') . qq|</th>
1170 </tr>
1171 <tr>
1172 <td>
1173
1174 $upd
1175
1176 </td>
1177 </tr>
1178 <tr>
1179 <td>
1180
1181 <input name=dbupdate type=hidden value="$form->{dbupdate}">
1182
1183 <input name=callback type=hidden value="$form->{script}?action=list_users&rpw=$form->{rpw}">
1184
1185 <input type=hidden name=rpw value=$form->{rpw}>
1186
1187 <input type=hidden name=nextsub value=dbupdate>
1188
1189 <hr size=3 noshade>
1190
1191 <br>
1192 <input type=submit class=submit name=action value="|
1193       . $locale->text('Continue') . qq|">
1194
1195 </td></tr>
1196 </table>
1197 </form>
1198 |;
1199
1200   } else {
1201
1202     print $locale->text('All Datasets up to date!');
1203
1204   }
1205
1206   print qq|
1207
1208 </body>
1209 </html>
1210 |;
1211
1212 }
1213
1214 sub dbupdate {
1215   $form->{"stylesheet"} = "lx-office-erp.css";
1216   $form->{"title"} = $main::locale->text("Dataset upgrade");
1217   $form->header();
1218   my $dbname =
1219     join(" ",
1220          map({ s/\s//g; s/^db//; $_; }
1221              grep({ $form->{$_} }
1222                   split(/\s+/, $form->{"dbupdate"}))));
1223   print($form->parse_html_template("dbupgrade/header",
1224                                    { "dbname" => $dbname }));
1225
1226   User->dbupdate(\%$form);
1227
1228   print qq|
1229 <hr>
1230
1231 | . $locale->text('Dataset updated!') . qq|
1232
1233 <br>
1234
1235 <a id="enddatasetupdate" href="admin.pl?action=login&| .
1236 join("&", map({ "$_=" . $form->escape($form->{$_}); } qw(rpw))) .
1237 qq|">| . $locale->text("Continue") . qq|</a>|;
1238
1239 }
1240
1241 sub create_dataset {
1242   $form->{dbsources} = join " ", map { "[${_}]" } sort User->dbsources(\%$form);
1243
1244   $form->{CHARTS} = [];
1245
1246   opendir SQLDIR, "sql/." or $form - error($!);
1247   foreach $item (sort grep /-chart\.sql\z/, readdir SQLDIR) {
1248     next if ($item eq 'Default-chart.sql');
1249     $item =~ s/-chart\.sql//;
1250     push @{ $form->{CHARTS} }, { "name"     => $item,
1251                                  "selected" => $item eq "Germany-DATEV-SKR03EU" };
1252   }
1253   closedir SQLDIR;
1254
1255   my $default_charset = $dbcharset;
1256   $default_charset ||= Common::DEFAULT_CHARSET;
1257
1258   $form->{DBENCODINGS} = [];
1259
1260   foreach my $encoding (@Common::db_encodings) {
1261     push @{ $form->{DBENCODINGS} }, { "dbencoding" => $encoding->{dbencoding},
1262                                       "label"      => $encoding->{label},
1263                                       "selected"   => $encoding->{charset} eq $default_charset };
1264   }
1265
1266   $form->{title} =
1267       "Lx-Office ERP "
1268     . $locale->text('Database Administration') . " / "
1269     . $locale->text('Create Dataset');
1270
1271   $form->header();
1272   print $form->parse_html_template("admin/create_dataset");
1273 }
1274
1275 sub dbcreate {
1276   $form->isblank("db", $locale->text('Dataset missing!'));
1277
1278   User->dbcreate(\%$form);
1279
1280   $form->{title} =
1281       "Lx-Office ERP "
1282     . $locale->text('Database Administration') . " / "
1283     . $locale->text('Create Dataset');
1284
1285   $form->header();
1286   print $form->parse_html_template("admin/dbcreate");
1287 }
1288
1289 sub delete_dataset {
1290   @dbsources = User->dbsources_unused(\%$form, $memberfile);
1291   $form->error($locale->text('Nothing to delete!')) unless @dbsources;
1292
1293   $form->{title} =
1294       "Lx-Office ERP "
1295     . $locale->text('Database Administration') . " / "
1296     . $locale->text('Delete Dataset');
1297   $form->{DBSOURCES} = [ map { { "name", $_ } } sort @dbsources ];
1298
1299   $form->header();
1300   print $form->parse_html_template("admin/delete_dataset");
1301 }
1302
1303 sub dbdelete {
1304
1305   if (!$form->{db}) {
1306     $form->error($locale->text('No Dataset selected!'));
1307   }
1308
1309   User->dbdelete(\%$form);
1310
1311   $form->{title} =
1312       "Lx-Office ERP "
1313     . $locale->text('Database Administration') . " / "
1314     . $locale->text('Delete Dataset');
1315
1316   $form->header();
1317   print $form->parse_html_template("admin/dbdelete");
1318 }
1319
1320 sub unlock_system {
1321
1322   unlink "$userspath/nologin";
1323
1324   $form->{callback} =
1325     "$form->{script}?action=list_users&rpw=$root->{password}";
1326
1327   $form->redirect($locale->text('Lockfile removed!'));
1328
1329 }
1330
1331 sub lock_system {
1332
1333   open(FH, ">$userspath/nologin")
1334     or $form->error($locale->text('Cannot create Lock!'));
1335   close(FH);
1336
1337   $form->{callback} =
1338     "$form->{script}?action=list_users&rpw=$root->{password}";
1339
1340   $form->redirect($locale->text('Lockfile created!'));
1341
1342 }