ActionBar: Verwendung bei »Steuern«
[kivitendo-erp.git] / bin / mozilla / am.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) 1998-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., 51 Franklin Street, Fifth Floor, Boston,
28 # MA 02110-1335, USA.
29 #======================================================================
30 #
31 # administration
32 #
33 #======================================================================
34
35 use utf8;
36
37 use SL::Auth;
38 use SL::Auth::PasswordPolicy;
39 use SL::AM;
40 use SL::CA;
41 use SL::Form;
42 use SL::User;
43 use SL::USTVA;
44 use SL::Iconv;
45 use SL::Locale::String qw(t8);
46 use SL::TODO;
47 use SL::DB::Printer;
48 use SL::DB::Tax;
49 use SL::DB::Language;
50 use SL::DB::Default;
51 use SL::DBUtils qw(selectall_array_query conv_dateq);
52 use CGI;
53
54 require "bin/mozilla/common.pl";
55
56 use strict;
57
58 1;
59
60 # end of main
61
62 sub add      { call_sub("add_$main::form->{type}"); }
63 sub delete   { call_sub("delete_$main::form->{type}"); }
64 sub save     { call_sub("save_$main::form->{type}"); }
65 sub edit     { call_sub("edit_$main::form->{type}"); }
66 sub continue { call_sub($main::form->{"nextsub"}); }
67 sub save_as_new { call_sub("save_as_new_$main::form->{type}"); }
68
69 sub add_account {
70   $main::lxdebug->enter_sub();
71
72   my $form     = $main::form;
73   my %myconfig = %main::myconfig;
74
75   $main::auth->assert('config');
76
77   $form->{title}     = "Add";
78   $form->{charttype} = "A";
79   AM->get_account(\%myconfig, \%$form);
80
81   $form->{callback} = "am.pl?action=list_account" unless $form->{callback};
82
83   &account_header;
84   &form_footer;
85
86   $main::lxdebug->leave_sub();
87 }
88
89 sub edit_account {
90   $main::lxdebug->enter_sub();
91
92   my $form     = $main::form;
93   my %myconfig = %main::myconfig;
94   my $defaults = SL::DB::Default->get;
95
96   $main::auth->assert('config');
97
98   $form->{title} = "Edit";
99   $form->{feature_balance} = $defaults->feature_balance;
100   $form->{feature_datev} = $defaults->feature_datev;
101   $form->{feature_erfolgsrechnung} = $defaults->feature_erfolgsrechnung;
102   $form->{feature_eurechnung} = $defaults->feature_eurechnung;
103   $form->{feature_ustva} = $defaults->feature_ustva;
104
105   AM->get_account(\%myconfig, \%$form);
106
107   foreach my $item (split(/:/, $form->{link})) {
108     $form->{$item} = "checked";
109   }
110
111   &account_header;
112
113   $main::lxdebug->leave_sub();
114 }
115
116 sub account_header {
117   $main::lxdebug->enter_sub();
118
119   my $form     = $main::form;
120   my %myconfig = %main::myconfig;
121   my $locale   = $main::locale;
122
123   $main::auth->assert('config');
124
125   if ( $form->{action} eq 'edit_account') {
126     $form->{account_exists} = '1';
127   }
128
129   $form->{title} = $locale->text("$form->{title} Account");
130
131   $form->{"$form->{charttype}_checked"} = "checked";
132   $form->{"$form->{category}_checked"}  = "checked";
133
134   $form->{select_tax} = "";
135
136   my @tax_report_pos = USTVA->report_variables({
137       myconfig   => \%myconfig,
138       form       => $form,
139       type       => '',
140       attribute  => 'position',
141       calc       => '',
142   });
143
144   if (@{ $form->{TAXKEY} }) {
145     foreach my $item (@{ $form->{TAXKEY} }) {
146       $item->{rate} = $item->{rate} * 100 . '%';
147     }
148
149     # Fill in empty row for new Taxkey
150     my $newtaxkey_ref = {
151       id             => '',
152       chart_id       => '',
153       accno          => '',
154       tax_id         => '',
155       taxdescription => '',
156       rate           => '',
157       taxkey_id      => '',
158       pos_ustva      => '',
159       startdate      => $form->{account_exists} ? '' : DateTime->new(year => 1970, month => 1, day => 1)->to_lxoffice,
160     };
161
162     push @{ $form->{ACCOUNT_TAXKEYS} }, $newtaxkey_ref;
163
164     my $i = 0;
165     foreach my $taxkey_used (@{ $form->{ACCOUNT_TAXKEYS} } ) {
166
167       # Fill in a runningnumber
168       $form->{ACCOUNT_TAXKEYS}[$i]{runningnumber} = $i;
169
170       # Fill in the Taxkeys as select options
171       foreach my $item (@{ $form->{TAXKEY} }) {
172         if ($item->{id} == $taxkey_used->{tax_id}) {
173           $form->{ACCOUNT_TAXKEYS}[$i]{selecttaxkey} .=
174             qq|<option value="$item->{id}" selected="selected">|
175             . sprintf("%.2d", $item->{taxkey})
176             . qq|. $item->{taxdescription} ($item->{rate}) |
177             . $locale->text('Tax-o-matic Account')
178             . qq|: $item->{chart_accno}\n|;
179         }
180         else {
181           $form->{ACCOUNT_TAXKEYS}[$i]{selecttaxkey} .=
182             qq|<option value="$item->{id}">|
183             . sprintf("%.2d", $item->{taxkey})
184             . qq|. $item->{taxdescription} ($item->{rate}) |
185             . $locale->text('Tax-o-matic Account')
186             . qq|: $item->{chart_accno}\n|;
187         }
188
189       }
190
191       # Fill in the USTVA Numbers as select options
192       foreach my $item ( '', sort({ $a cmp $b } @tax_report_pos) ) {
193         if ($item eq ''){
194           $form->{ACCOUNT_TAXKEYS}[$i]{select_tax} .= qq|<option value="" selected="selected">-\n|;
195         }
196         elsif ( $item eq $taxkey_used->{pos_ustva} ) {
197           $form->{ACCOUNT_TAXKEYS}[$i]{select_tax} .= qq|<option value="$item" selected="selected">$item\n|;
198         }
199         else {
200           $form->{ACCOUNT_TAXKEYS}[$i]{select_tax} .= qq|<option value="$item">$item\n|;
201         }
202
203       }
204
205       $i++;
206     }
207   }
208
209   # Newaccount Folgekonto
210   if (@{ $form->{NEWACCOUNT} || [] }) {
211     if (!$form->{new_chart_valid}) {
212       $form->{selectnewaccount} = qq|<option value=""> |. $locale->text('None') .q|</option>|;
213     }
214     foreach my $item (@{ $form->{NEWACCOUNT} }) {
215       if ($item->{id} == $form->{new_chart_id}) {
216         $form->{selectnewaccount} .=
217           qq|<option value="$item->{id}" selected>$item->{accno}--$item->{description}</option>|;
218       } elsif (!$form->{new_chart_valid}) {
219         $form->{selectnewaccount} .=
220           qq|<option value="$item->{id}">$item->{accno}--$item->{description}</option>|;
221       }
222
223     }
224   }
225
226   my $select_eur = q|<option value=""> |. $locale->text('None') .q|</option>\n|;
227   my %eur = (
228           1  => "Umsatzerlöse",
229           2  => "sonstige Erlöse",
230           3  => "Privatanteile",
231           4  => "Zinserträge",
232           5  => "Ausserordentliche Erträge",
233           6  => "Vereinnahmte Umsatzst.",
234           7  => "Umsatzsteuererstattungen",
235           8  => "Wareneingänge",
236           9  => "Löhne und Gehälter",
237           10 => "Gesetzl. sozialer Aufw.",
238           11 => "Mieten",
239           12 => "Gas, Strom, Wasser",
240           13 => "Instandhaltung",
241           14 => "Steuern, Versich., Beiträge",
242           15 => "Kfz-Steuern",
243           16 => "Kfz-Versicherungen",
244           17 => "Sonst. Fahrzeugkosten",
245           18 => "Werbe- und Reisekosten",
246           19 => "Instandhaltung u. Werkzeuge",
247           20 => "Fachzeitschriften, Bücher",
248           21 => "Miete für Einrichtungen",
249           22 => "Rechts- und Beratungskosten",
250           23 => "Bürobedarf, Porto, Telefon",
251           24 => "Sonstige Aufwendungen",
252           25 => "Abschreibungen auf Anlagever.",
253           26 => "Abschreibungen auf GWG",
254           27 => "Vorsteuer",
255           28 => "Umsatzsteuerzahlungen",
256           29 => "Zinsaufwand",
257           30 => "Ausserordentlicher Aufwand",
258           31 => "Betriebliche Steuern");
259   foreach my $item (sort({ $a <=> $b } keys(%eur))) {
260     my $text = H($::locale->{iconv_utf8}->convert($eur{$item}));
261     if ($item == $form->{pos_eur}) {
262       $select_eur .= qq|<option value=$item selected>|. sprintf("%.2d", $item) .qq|. $text</option>\n|;
263     } else {
264       $select_eur .= qq|<option value=$item>|. sprintf("%.2d", $item) .qq|. $text</option>\n|;
265     }
266
267   }
268
269   my $select_er = q|<option value=""> |. $locale->text('None') .q|</option>\n|;
270   my %er = (
271        1  => "Ertrag",
272        6  => "Aufwand");
273   foreach my $item (sort({ $a <=> $b } keys(%er))) {
274     my $text = H($::locale->{iconv_utf8}->convert($er{$item}));
275     if ($item == $form->{pos_er}) {
276       $select_er .= qq|<option value=$item selected>|. sprintf("%.2d", $item) .qq|. $text</option>\n|;
277     } else {
278       $select_er .= qq|<option value=$item>|. sprintf("%.2d", $item) .qq|. $text</option>\n|;
279     }
280
281   }
282
283   my $select_bwa = q|<option value=""> |. $locale->text('None') .q|</option>\n|;
284
285   my %bwapos = (
286              1  => 'Umsatzerlöse',
287              2  => 'Best.Verdg.FE/UE',
288              3  => 'Aktiv.Eigenleistung',
289              4  => 'Mat./Wareneinkauf',
290              5  => 'So.betr.Erlöse',
291              10 => 'Personalkosten',
292              11 => 'Raumkosten',
293              12 => 'Betriebl.Steuern',
294              13 => 'Vers./Beiträge',
295              14 => 'Kfz.Kosten o.St.',
296              15 => 'Werbe-Reisek.',
297              16 => 'Kosten Warenabgabe',
298              17 => 'Abschreibungen',
299              18 => 'Rep./instandhlt.',
300              19 => 'Übrige Steuern',
301              20 => 'Sonst.Kosten',
302              30 => 'Zinsauwand',
303              31 => 'Sonst.neutr.Aufw.',
304              32 => 'Zinserträge',
305              33 => 'Sonst.neutr.Ertrag',
306              34 => 'Verr.kalk.Kosten',
307              35 => 'Steuern Eink.u.Ertr.');
308   foreach my $item (sort({ $a <=> $b } keys %bwapos)) {
309     my $text = H($::locale->{iconv_utf8}->convert($bwapos{$item}));
310     if ($item == $form->{pos_bwa}) {
311       $select_bwa .= qq|<option value="$item" selected>|. sprintf("%.2d", $item) .qq|. $text\n|;
312     } else {
313       $select_bwa .= qq|<option value="$item">|. sprintf("%.2d", $item) .qq|. $text\n|;
314     }
315
316   }
317
318 # Wieder hinzugefügt zu evaluationszwecken (us) 09.03.2007
319   my $select_bilanz = q|<option value=""> |. $locale->text('None') .q|</option>\n|;
320   foreach my $item ((1, 2, 3, 4)) {
321     if ($item == $form->{pos_bilanz}) {
322       $select_bilanz .= qq|<option value=$item selected>|. sprintf("%.2d", $item) .qq|.\n|;
323     } else {
324       $select_bilanz .= qq|<option value=$item>|. sprintf("%.2d", $item) .qq|.\n|;
325     }
326
327   }
328
329   # this is for our parser only! Do not remove.
330   # type=submit $locale->text('Add Account')
331   # type=submit $locale->text('Edit Account')
332
333   $form->{type} = "account";
334
335   # preselections category
336
337   my $select_category = q|<option value=""> |. $locale->text('None') .q|</option>\n|;
338
339   my %category = (
340       'A'  => $locale->text('Asset'),
341       'L'  => $locale->text('Liability'),
342       'Q'  => $locale->text('Equity'),
343       'I'  => $locale->text('Revenue'),
344       'E'  => $locale->text('Expense'),
345       'C'  => $locale->text('Costs'),
346   );
347   foreach my $item ( sort({ $a <=> $b } keys %category) ) {
348     if ($item eq $form->{category}) {
349       $select_category .= qq|<option value="$item" selected="selected">$category{$item} (|. sprintf("%s", $item) .qq|)\n|;
350     } else {
351       $select_category .= qq|<option value="$item">$category{$item} (|. sprintf("%s", $item) .qq|)\n|;
352     }
353
354   }
355
356   # preselection chart type
357   my @all_charttypes = ({'name' => $locale->text('Account'), 'value' => 'A'},
358                         {'name' => $locale->text('Heading'), 'value' => 'H'},
359     );
360   my $selected_charttype = $form->{charttype};
361
362
363   # account where AR_tax or AP_tax is set are not orphaned if they are used as
364   # tax-o-matic account
365   if ( $form->{id} && $form->{orphaned} && ($form->{link} =~ m/(AP_tax|AR_tax)/) ) {
366     if (SL::DB::Manager::Tax->find_by(chart_id => $form->{id})) {
367       $form->{orphaned} = 0;
368     }
369   }
370
371   my $ChartTypeIsAccount = ($form->{charttype} eq "A") ? "1":"";
372   my $AccountIsPosted = ($form->{orphaned} ) ? "":"1";
373
374   setup_am_edit_account_action_bar();
375
376   $form->header();
377
378   my $parameters_ref = {
379     ChartTypeIsAccount         => $ChartTypeIsAccount,
380     AccountIsPosted            => $AccountIsPosted,
381     select_category            => $select_category,
382     all_charttypes             => \@all_charttypes,
383     selected_charttype         => $selected_charttype,
384     select_bwa                 => $select_bwa,
385     select_bilanz              => $select_bilanz,
386     select_eur                 => $select_eur,
387     select_er                  => $select_er,
388   };
389
390   # Ausgabe des Templates
391   print($form->parse_html_template('am/edit_accounts', $parameters_ref));
392
393
394   $main::lxdebug->leave_sub();
395 }
396
397 sub form_footer {
398   $::lxdebug->enter_sub;
399   $::auth->assert('config');
400
401   print $::form->parse_html_template('am/form_footer', {
402     show_save        => !$::form->{id}
403                      || ($::form->{id} && $::form->{orphaned})
404                      || ($::form->{type} eq "account" && !$::form->{new_chart_valid}),
405     show_delete      => $::form->{id} && $::form->{orphaned},
406     show_save_as_new => $::form->{id} && $::form->{type} eq "account",
407   });
408
409   $::lxdebug->leave_sub;
410 }
411
412 sub save_account {
413   $main::lxdebug->enter_sub();
414
415   my $form     = $main::form;
416   my %myconfig = %main::myconfig;
417   my $locale   = $main::locale;
418
419   $main::auth->assert('config');
420
421   $form->isblank("accno",       $locale->text('Account Number missing!'));
422   $form->isblank("description", $locale->text('Account Description missing!'));
423
424   if ($form->{charttype} eq 'A'){
425     $form->isblank("category",  $locale->text('Account Type missing!'));
426
427     my $found_valid_taxkey = 0;
428     foreach my $i (0 .. 10) { # 10 is maximum count of taxkeys in form
429       if ($form->{"taxkey_startdate_$i"} and !$form->{"taxkey_del_$i"}) {
430         $found_valid_taxkey = 1;
431         last;
432       }
433     }
434     if ($found_valid_taxkey == 0) {
435       $form->error($locale->text('A valid taxkey is missing!'));
436     }
437   }
438
439   $form->redirect($locale->text('Account saved!'))
440     if (AM->save_account(\%myconfig, \%$form));
441   $form->error($locale->text('Cannot save account!'));
442
443   $main::lxdebug->leave_sub();
444 }
445
446 sub save_as_new_account {
447   $main::lxdebug->enter_sub();
448
449   my $form     = $main::form;
450   my %myconfig = %main::myconfig;
451   my $locale   = $main::locale;
452
453   $main::auth->assert('config');
454
455   $form->isblank("accno",       $locale->text('Account Number missing!'));
456   $form->isblank("description", $locale->text('Account Description missing!'));
457
458   if ($form->{charttype} eq 'A'){
459     $form->isblank("category",  $locale->text('Account Type missing!'));
460   }
461
462   for my $taxkey (0 .. 9) {
463     if ($form->{"taxkey_id_$taxkey"}) {
464       $form->{"taxkey_id_$taxkey"} = "NEW";
465     }
466   }
467
468   $form->{id} = 0;
469   $form->redirect($locale->text('Account saved!'))
470     if (AM->save_account(\%myconfig, \%$form));
471   $form->error($locale->text('Cannot save account!'));
472
473   $main::lxdebug->leave_sub();
474 }
475
476 sub list_account {
477   $main::lxdebug->enter_sub();
478
479   my $form     = $main::form;
480   my %myconfig = %main::myconfig;
481   my $locale   = $main::locale;
482
483   $main::auth->assert('config');
484
485   $form->{callback}     = build_std_url('action=list_account');
486   my $link_edit_account = build_std_url('action=edit_account', 'callback');
487
488   CA->all_accounts(\%myconfig, \%$form);
489
490   foreach my $ca (@{ $form->{CA} }) {
491
492     $ca->{debit}  = "";
493     $ca->{credit} = "";
494
495     if ($ca->{amount} > 0) {
496       $ca->{credit} = $form->format_amount(\%myconfig, $ca->{amount}, 2);
497     }
498     if ($ca->{amount} < 0) {
499       $ca->{debit} = $form->format_amount(\%myconfig, -1 * $ca->{amount}, 2);
500     }
501     $ca->{heading}   = ( $ca->{charttype} eq 'H' ) ? 1:'';
502     $ca->{link_edit_account} = $link_edit_account . '&id=' . E($ca->{id});
503   }
504
505   $::request->{layout}->use_stylesheet("list_accounts.css");
506   $form->{title}       = $locale->text('Chart of Accounts');
507
508   $form->header;
509
510
511   my $parameters_ref = {
512   #   hidden_variables                => $_hidden_variables_ref,
513   };
514
515   # Ausgabe des Templates
516   print($form->parse_html_template('am/list_accounts', $parameters_ref));
517
518   $main::lxdebug->leave_sub();
519
520 }
521
522
523 sub list_account_details {
524 # Ajax Funktion aus list_account_details
525   $main::lxdebug->enter_sub();
526
527   my $form     = $main::form;
528   my %myconfig = %main::myconfig;
529   my $locale   = $main::locale;
530
531   $main::auth->assert('config');
532
533   my $chart_id = $form->{args};
534
535   CA->all_accounts(\%myconfig, \%$form, $chart_id);
536
537   foreach my $ca (@{ $form->{CA} }) {
538
539     $ca->{debit}  = "&nbsp;";
540     $ca->{credit} = "&nbsp;";
541
542     if ($ca->{amount} > 0) {
543       $ca->{credit} =
544         $form->format_amount(\%myconfig, $ca->{amount}, 2, "&nbsp;");
545     }
546     if ($ca->{amount} < 0) {
547       $ca->{debit} =
548         $form->format_amount(\%myconfig, -1 * $ca->{amount}, 2, "&nbsp;");
549     }
550
551     my @links = split( q{:}, $ca->{link});
552
553     $ca->{link} = q{};
554
555     foreach my $link (@links){
556       $link =    ( $link eq 'AR')             ? $locale->text('Account Link AR')
557                : ( $link eq 'AP')             ? $locale->text('Account Link AP')
558                : ( $link eq 'IC')             ? $locale->text('Account Link IC')
559                : ( $link eq 'AR_amount' )     ? $locale->text('Account Link AR_amount')
560                : ( $link eq 'AR_paid' )       ? $locale->text('Account Link AR_paid')
561                : ( $link eq 'AR_tax' )        ? $locale->text('Account Link AR_tax')
562                : ( $link eq 'AP_amount' )     ? $locale->text('Account Link AP_amount')
563                : ( $link eq 'AP_paid' )       ? $locale->text('Account Link AP_paid')
564                : ( $link eq 'AP_tax' )        ? $locale->text('Account Link AP_tax')
565                : ( $link eq 'IC_sale' )       ? $locale->text('Account Link IC_sale')
566                : ( $link eq 'IC_cogs' )       ? $locale->text('Account Link IC_cogs')
567                : ( $link eq 'IC_taxpart' )    ? $locale->text('Account Link IC_taxpart')
568                : ( $link eq 'IC_income' )     ? $locale->text('Account Link IC_income')
569                : ( $link eq 'IC_expense' )    ? $locale->text('Account Link IC_expense')
570                : ( $link eq 'IC_taxservice' ) ? $locale->text('Account Link IC_taxservice')
571                : $locale->text('Unknown Link') . ': ' . $link;
572       $ca->{link} .= ($link ne '') ?  "[$link] ":'';
573     }
574
575     $ca->{category} = ($ca->{category} eq 'A') ? $locale->text('Account Category A')
576                     : ($ca->{category} eq 'E') ? $locale->text('Account Category E')
577                     : ($ca->{category} eq 'L') ? $locale->text('Account Category L')
578                     : ($ca->{category} eq 'I') ? $locale->text('Account Category I')
579                     : ($ca->{category} eq 'Q') ? $locale->text('Account Category Q')
580                     : ($ca->{category} eq 'C') ? $locale->text('Account Category C')
581                     : ($ca->{category} eq 'G') ? $locale->text('Account Category G')
582                     : $locale->text('Unknown Category') . ': ' . $ca->{category};
583   }
584
585   $form->{title} = $locale->text('Chart of Accounts');
586
587   print $form->ajax_response_header, $form->parse_html_template('am/list_account_details');
588
589   $main::lxdebug->leave_sub();
590
591 }
592
593 sub delete_account {
594   $main::lxdebug->enter_sub();
595
596   my $form     = $main::form;
597   my %myconfig = %main::myconfig;
598   my $locale   = $main::locale;
599
600   $main::auth->assert('config');
601
602   $form->{title} = $locale->text('Delete Account');
603
604   foreach my $id (
605     qw(inventory_accno_id income_accno_id expense_accno_id fxgain_accno_id fxloss_accno_id rndgain_accno_id rndloss_accno_id)
606     ) {
607     if ($form->{id} == $form->{$id}) {
608       $form->error($locale->text('Cannot delete default account!'));
609     }
610   }
611
612   $form->redirect($locale->text('Account deleted!'))
613     if (AM->delete_account(\%myconfig, \%$form));
614   $form->error($locale->text('Cannot delete account!'));
615
616   $main::lxdebug->leave_sub();
617 }
618
619 sub _build_cfg_options {
620   my $form     = $main::form;
621   my %myconfig = %main::myconfig;
622
623   my $idx   = shift;
624   my $array = uc($idx) . 'S';
625
626   $form->{$array} = [];
627   foreach my $item (@_) {
628     push @{ $form->{$array} }, {
629       'name'     => $item,
630       'value'    => $item,
631       'selected' => $item eq $myconfig{$idx},
632     };
633   }
634 }
635
636 sub config {
637   $main::lxdebug->enter_sub();
638
639   my $form     = $main::form;
640   my %myconfig = %main::myconfig;
641   my $locale   = $main::locale;
642
643   _build_cfg_options('dateformat', qw(mm/dd/yy dd/mm/yy dd.mm.yy yyyy-mm-dd));
644   _build_cfg_options('timeformat', qw(hh:mm hh:mm:ss));
645   _build_cfg_options('numberformat', ('1,000.00', '1000.00', '1.000,00', '1000,00', "1'000.00"));
646
647   my @formats = ();
648   if ($::lx_office_conf{print_templates}->{opendocument}
649       && $::lx_office_conf{applications}->{openofficeorg_writer} && (-x $::lx_office_conf{applications}->{openofficeorg_writer})
650       && $::lx_office_conf{applications}->{xvfb}                 && (-x $::lx_office_conf{applications}->{xvfb})) {
651     push(@formats, { "name" => $locale->text("PDF (OpenDocument/OASIS)"),
652                      "value" => "opendocument_pdf" });
653   }
654   if ($::lx_office_conf{print_templates}->{latex}) {
655     push(@formats, { "name" => $locale->text("PDF"), "value" => "pdf" });
656   }
657   push(@formats, { "name" => "HTML", "value" => "html" });
658   if ($::lx_office_conf{print_templates}->{latex}) {
659     push(@formats, { "name" => $locale->text("Postscript"),
660                      "value" => "postscript" });
661   }
662   if ($::lx_office_conf{print_templates}->{opendocument}) {
663     push(@formats, { "name" => $locale->text("OpenDocument/OASIS"),
664                      "value" => "opendocument" });
665   }
666
667   if (!$myconfig{"template_format"}) {
668     $myconfig{"template_format"} = "pdf";
669   }
670   $form->{TEMPLATE_FORMATS} = [];
671   foreach my $item (@formats) {
672     push @{ $form->{TEMPLATE_FORMATS} }, {
673       'name'     => $item->{name},
674       'value'    => $item->{value},
675       'selected' => $item->{value} eq $myconfig{template_format},
676     };
677   }
678
679   if (!$myconfig{"default_media"}) {
680     $myconfig{"default_media"} = "screen";
681   }
682
683   my %selected = ($myconfig{"default_media"} => "selected");
684   $form->{MEDIA} = [
685     { 'name' => $locale->text('Screen'),  'value' => 'screen',  'selected' => $selected{screen}, },
686     { 'name' => $locale->text('Printer'), 'value' => 'printer', 'selected' => $selected{printer}, },
687     { 'name' => $locale->text('Queue'),   'value' => 'queue',   'selected' => $selected{queue}, },
688     ];
689
690   $form->{PRINTERS} = SL::DB::Manager::Printer->get_all_sorted;
691
692   my %countrycodes = User->country_codes;
693
694   $form->{COUNTRYCODES} = [];
695   foreach my $countrycode (sort { $countrycodes{$a} cmp $countrycodes{$b} } keys %countrycodes) {
696     push @{ $form->{COUNTRYCODES} }, {
697       'name'     => $countrycodes{$countrycode},
698       'value'    => $countrycode,
699       'selected' => $countrycode eq $myconfig{countrycode},
700     };
701   }
702
703   $form->{STYLESHEETS} = [];
704   foreach my $item (qw(lx-office-erp.css kivitendo.css)) {
705     push @{ $form->{STYLESHEETS} }, {
706       'name'     => $item,
707       'value'    => $item,
708       'selected' => $item eq $myconfig{stylesheet},
709     };
710   }
711
712   $myconfig{show_form_details} = 1 unless (defined($myconfig{show_form_details}));
713   $form->{CAN_CHANGE_PASSWORD} = $main::auth->can_change_password();
714   $form->{todo_cfg}            = { TODO->get_user_config('login' => $::myconfig{login}) };
715
716   $form->{title}               = $locale->text('Edit Preferences for #1', $::myconfig{login});
717
718   setup_am_config_action_bar();
719
720   $form->header();
721
722   $form->{full_signature} = $form->create_email_signature();
723
724   print $form->parse_html_template('am/config');
725
726   $main::lxdebug->leave_sub();
727 }
728
729 sub save_preferences {
730   $main::lxdebug->enter_sub();
731
732   my $form     = $main::form;
733   my %myconfig = %main::myconfig;
734   my $locale   = $main::locale;
735
736   $form->{stylesheet} = $form->{usestylesheet};
737
738   TODO->save_user_config('login' => $::myconfig{login}, %{ $form->{todo_cfg} || { } });
739
740   if (AM->save_preferences($form)) {
741     if ($::auth->can_change_password()
742         && defined $form->{new_password}
743         && ($form->{new_password} ne '********')) {
744       my $verifier = SL::Auth::PasswordPolicy->new;
745       my $result   = $verifier->verify($form->{new_password});
746
747       if ($result != SL::Auth::PasswordPolicy->OK()) {
748         $form->error($::locale->text('The settings were saved, but the password was not changed.') . ' ' . join(' ', $verifier->errors($result)));
749       }
750
751       $::auth->change_password($::myconfig{login}, $form->{new_password});
752     }
753
754     $form->redirect($locale->text('Preferences saved!'));
755   }
756
757   $form->error($locale->text('Cannot save preferences!'));
758
759   $main::lxdebug->leave_sub();
760 }
761
762 sub audit_control {
763   $::lxdebug->enter_sub;
764   $::auth->assert('config');
765
766   $::form->{title} = $::locale->text('Audit Control');
767
768   AM->closedto(\%::myconfig, $::form);
769
770   $::form->header;
771   print $::form->parse_html_template('am/audit_control');
772
773   $::lxdebug->leave_sub;
774 }
775
776 sub doclose {
777   $main::lxdebug->enter_sub();
778
779   my $form     = $main::form;
780   my %myconfig = %main::myconfig;
781   my $locale   = $main::locale;
782
783   $main::auth->assert('config');
784
785   AM->closebooks(\%myconfig, \%$form);
786
787   if ($form->{closedto}) {
788     $form->redirect(
789                     $locale->text('Books closed up to') . " "
790                       . $locale->date(\%myconfig, $form->{closedto}, 1));
791   } else {
792     $form->redirect($locale->text('Books are open'));
793   }
794
795   $main::lxdebug->leave_sub();
796 }
797
798 sub edit_units {
799   $main::lxdebug->enter_sub();
800
801   my $form     = $main::form;
802   my %myconfig = %main::myconfig;
803   my $locale   = $main::locale;
804
805   $main::auth->assert('config');
806
807   my $units = AM->retrieve_units(\%myconfig, $form, "resolved_");
808   AM->units_in_use(\%myconfig, $form, $units);
809   map({ $units->{$_}->{"BASE_UNIT_DDBOX"} = AM->unit_select_data($units, $units->{$_}->{"base_unit"}, 1); } keys(%{$units}));
810
811   my @languages = AM->language(\%myconfig, $form, 1);
812
813   my @unit_list = sort({ $a->{"sortkey"} <=> $b->{"sortkey"} } values(%{$units}));
814
815   my $i = 1;
816   foreach (@unit_list) {
817     $_->{"factor"} = $form->format_amount(\%myconfig, $_->{"factor"} * 1) if ($_->{"factor"});
818     $_->{"UNITLANGUAGES"} = [];
819     foreach my $lang (@languages) {
820       push(@{ $_->{"UNITLANGUAGES"} },
821            { "idx" => $i,
822              "unit" => $_->{"name"},
823              "language_id" => $lang->{"id"},
824              "localized" => $_->{"LANGUAGES"}->{$lang->{"template_code"}}->{"localized"},
825              "localized_plural" => $_->{"LANGUAGES"}->{$lang->{"template_code"}}->{"localized_plural"},
826            });
827     }
828     $i++;
829   }
830
831   $units = AM->retrieve_units(\%myconfig, $form);
832   my $ddbox = AM->unit_select_data($units, undef, 1);
833
834   $form->{"title"} = $locale->text("Add and edit units");
835   $form->header();
836   print($form->parse_html_template("am/edit_units",
837                                    { "UNITS"               => \@unit_list,
838                                      "NEW_BASE_UNIT_DDBOX" => $ddbox,
839                                      "LANGUAGES"           => \@languages,
840                                    }));
841
842   $main::lxdebug->leave_sub();
843 }
844
845 sub add_unit {
846   $main::lxdebug->enter_sub();
847
848   my $form     = $main::form;
849   my %myconfig = %main::myconfig;
850   my $locale   = $main::locale;
851
852   $main::auth->assert('config');
853
854   $form->isblank("new_name", $locale->text("The name is missing."));
855   my $units = AM->retrieve_units(\%myconfig, $form);
856   my $all_units = AM->retrieve_units(\%myconfig, $form);
857   $form->show_generic_error($locale->text("A unit with this name does already exist.")) if ($all_units->{$form->{"new_name"}});
858
859   my ($base_unit, $factor);
860   if ($form->{"new_base_unit"}) {
861     $form->show_generic_error($locale->text("The base unit does not exist.")) unless (defined($units->{$form->{"new_base_unit"}}));
862
863     $form->isblank("new_factor", $locale->text("The factor is missing."));
864     $factor = $form->parse_amount(\%myconfig, $form->{"new_factor"});
865     $form->show_generic_error($locale->text("The factor is missing.")) unless ($factor);
866     $base_unit = $form->{"new_base_unit"};
867   }
868
869   my @languages;
870   foreach my $lang (AM->language(\%myconfig, $form, 1)) {
871     next unless ($form->{"new_localized_$lang->{id}"} || $form->{"new_localized_plural_$lang->{id}"});
872     push(@languages, { "id" => $lang->{"id"},
873                        "localized" => $form->{"new_localized_$lang->{id}"},
874                        "localized_plural" => $form->{"new_localized_plural_$lang->{id}"},
875          });
876   }
877
878   AM->add_unit(\%myconfig, $form, $form->{"new_name"}, $base_unit, $factor, \@languages);
879
880   $form->{"saved_message"} = $locale->text("The unit has been saved.");
881
882   edit_units();
883
884   $main::lxdebug->leave_sub();
885 }
886
887 sub set_unit_languages {
888   $main::lxdebug->enter_sub();
889
890   my $form     = $main::form;
891
892   $main::auth->assert('config');
893
894   my ($unit, $languages, $idx) = @_;
895
896   $unit->{"LANGUAGES"} = [];
897
898   foreach my $lang (@{$languages}) {
899     push(@{ $unit->{"LANGUAGES"} },
900          { "id" => $lang->{"id"},
901            "localized" => $form->{"localized_${idx}_$lang->{id}"},
902            "localized_plural" => $form->{"localized_plural_${idx}_$lang->{id}"},
903          });
904   }
905
906   $main::lxdebug->leave_sub();
907 }
908
909 sub save_unit {
910   $main::lxdebug->enter_sub();
911
912   my $form     = $main::form;
913   my %myconfig = %main::myconfig;
914   my $locale   = $main::locale;
915
916   $main::auth->assert('config');
917
918   my $old_units = AM->retrieve_units(\%myconfig, $form, "resolved_");
919   AM->units_in_use(\%myconfig, $form, $old_units);
920
921   my @languages = AM->language(\%myconfig, $form, 1);
922
923   my $new_units = {};
924   my @delete_units = ();
925   foreach my $i (1..($form->{"rowcount"} * 1)) {
926     my $old_unit = $old_units->{$form->{"old_name_$i"}};
927     if (!$old_unit) {
928       $form->show_generic_error(sprintf($locale->text("The unit in row %d has been deleted in the meantime."), $i));
929     }
930
931     if ($form->{"unchangeable_$i"}) {
932       $new_units->{$form->{"old_name_$i"}} = $old_units->{$form->{"old_name_$i"}};
933       $new_units->{$form->{"old_name_$i"}}->{"unchanged_unit"} = 1;
934       set_unit_languages($new_units->{$form->{"old_name_$i"}}, \@languages, $i);
935       next;
936     }
937
938     if ($old_unit->{"in_use"}) {
939       $form->show_generic_error(sprintf($locale->text("The unit in row %d has been used in the meantime and cannot be changed anymore."), $i));
940     }
941
942     if ($form->{"delete_$i"}) {
943       push(@delete_units, $old_unit->{"name"});
944       next;
945     }
946
947     $form->isblank("name_$i", sprintf($locale->text("The name is missing in row %d."), $i));
948
949     $form->show_generic_error(sprintf($locale->text("The name in row %d has already been used before."), $i)) if ($new_units->{$form->{"name_$i"}});
950     my %h = map({ $_ => $form->{"${_}_$i"} } qw(name base_unit factor old_name));
951     $new_units->{$form->{"name_$i"}} = \%h;
952     $new_units->{$form->{"name_$i"}}->{"row"} = $i;
953     set_unit_languages($new_units->{$form->{"old_name_$i"}}, \@languages, $i);
954   }
955
956   foreach my $unit (values(%{$new_units})) {
957     next unless ($unit->{"old_name"});
958     if ($unit->{"base_unit"}) {
959       $form->show_generic_error(sprintf($locale->text("The base unit does not exist or it is about to be deleted in row %d."), $unit->{"row"}))
960         unless (defined($new_units->{$unit->{"base_unit"}}));
961       $unit->{"factor"} = $form->parse_amount(\%myconfig, $unit->{"factor"});
962       $form->show_generic_error(sprintf($locale->text("The factor is missing in row %d."), $unit->{"row"})) unless ($unit->{"factor"} >= 1.0);
963     } else {
964       $unit->{"base_unit"} = undef;
965       $unit->{"factor"} = undef;
966     }
967   }
968
969   foreach my $unit (values(%{$new_units})) {
970     next if ($unit->{"unchanged_unit"});
971
972     map({ $_->{"seen"} = 0; } values(%{$new_units}));
973     my $new_unit = $unit;
974     while ($new_unit->{"base_unit"}) {
975       $new_unit->{"seen"} = 1;
976       $new_unit = $new_units->{$new_unit->{"base_unit"}};
977       if ($new_unit->{"seen"}) {
978         $form->show_generic_error(sprintf($locale->text("The base unit relations must not contain loops (e.g. by saying that unit A's base unit is B, " .
979                                                         "B's base unit is C and C's base unit is A) in row %d."), $unit->{"row"}));
980       }
981     }
982   }
983
984   AM->save_units(\%myconfig, $form, $new_units, \@delete_units);
985
986   $form->{"saved_message"} = $locale->text("The units have been saved.");
987
988   edit_units();
989
990   $main::lxdebug->leave_sub();
991 }
992
993 sub show_history_search {
994   $main::lxdebug->enter_sub();
995
996   my $form     = $main::form;
997   my $locale   = $main::locale;
998
999   $main::auth->assert('config');
1000
1001   $form->{title} = $locale->text("History Search");
1002   $form->header();
1003
1004   print $form->parse_html_template("common/search_history");
1005
1006   $main::lxdebug->leave_sub();
1007 }
1008
1009 sub show_am_history {
1010   $main::lxdebug->enter_sub();
1011
1012   my $form     = $main::form;
1013   my %myconfig = %main::myconfig;
1014   my $locale   = $main::locale;
1015
1016   $main::auth->assert('config');
1017
1018   my $callback     = build_std_url(qw(action einschraenkungen fromdate todate mitarbeiter searchid what2search));
1019   $form->{order} ||= 'h.itime--1';
1020
1021   # my %search = ( "Artikelnummer"          => "parts",
1022   #                "Kundennummer"           => "customer",
1023   #                "Lieferantennummer"      => "vendor",
1024   #                "Projektnummer"          => "project",
1025   #                "Auftragsnummer"         => "oe",
1026   #                "Angebotsnummer"         => "oe",
1027   #                "Eingangsrechnungnummer" => "ap",
1028   #                "Ausgangsrechnungnummer" => "ar",
1029   #                "Mahnungsnummer"         => "dunning",
1030   #                "Buchungsnummer"         => "gl",
1031   # );
1032
1033   my %searchNo = ( "Artikelnummer"          => "partnumber",
1034                    "Kundennummer"           => "customernumber",
1035                    "Lieferantennummer"      => "vendornumber",
1036                    "Projektnummer"          => "projectnumber",
1037                    "Auftragsnummer"         => "ordnumber",
1038                    "Angebotsnummer"         => "quonumber",
1039                    "Eingangsrechnungnummer" => "invnumber",
1040                    "Ausgangsrechnungnummer" => "invnumber",
1041                    "Mahnungsnummer"         => "dunning_id",
1042                    "Buchungsnummer"         => "gltransaction"
1043     );
1044
1045   my $dbh = $form->dbconnect(\%myconfig);
1046
1047   my $restriction;
1048   $restriction     = qq| AND (| . join(' OR ', map { " addition = " . $dbh->quote($_) } split(m/\,/, $form->{einschraenkungen})) . qq|)| if $form->{einschraenkungen};
1049   $restriction    .= qq| AND h.itime::date >= | . conv_dateq($form->{fromdate})                                                          if $form->{fromdate};
1050   $restriction    .= qq| AND h.itime::date <= | . conv_dateq($form->{todate})                                                            if $form->{todate};
1051   if ($form->{mitarbeiter} =~ m/^\d+$/) {
1052     $restriction  .= qq| AND employee_id = |    . $form->{mitarbeiter};
1053   } elsif ($form->{mitarbeiter}) {
1054     $restriction  .= qq| AND employee_id = (SELECT id FROM employee WHERE name ILIKE | . $dbh->quote('%' . $form->{mitarbeiter} . '%') . qq|)|;
1055   }
1056
1057   my $snumbers_where = '';
1058   my $snumbers_value;
1059   if ($form->{'searchid'}) {
1060     $snumbers_where = ' WHERE snumbers = ?';
1061     $snumbers_value = $searchNo{$form->{'what2search'}} . '_' . $form->{'searchid'};
1062   } else {
1063     $snumbers_where = ' WHERE snumbers ~ ?';
1064     $snumbers_value = '^' . $searchNo{$form->{'what2search'}};
1065   }
1066   my $query = qq|SELECT trans_id AS id FROM history_erp $snumbers_where|;
1067
1068   my @ids    = grep { $_ * 1 } selectall_array_query($form, $dbh, $query, $snumbers_value);
1069   my $daten .= shift @ids;
1070   if (scalar(@ids) > 0 ) {
1071     $daten  .= ' OR trans_id IN (' . join(',', @ids) . ')';
1072   }
1073   my ($sort, $sortby) = split(/\-\-/, $form->{order});
1074   $sort =~ s/.*\.(.*)$/$1/;
1075
1076   $form->{title} = $locale->text("History Search");
1077   $form->header();
1078
1079   print $form->parse_html_template("common/show_history",
1080                                    { "DATEN"          => $form->get_history($dbh, $daten, $restriction, $form->{order}),
1081                                      "SUCCESS"        => ($form->get_history($dbh, $daten, $restriction, $form->{order}) ne "0"),
1082                                      "NONEWWINDOW"    => 1,
1083                                      uc($sort)        => 1,
1084                                      uc($sort) . "BY" => $sortby,
1085                                      'callback'       => $callback,
1086                                    });
1087   $dbh->disconnect();
1088
1089   $main::lxdebug->leave_sub();
1090 }
1091
1092 sub add_tax {
1093   $main::lxdebug->enter_sub();
1094
1095   my $form     = $main::form;
1096   my $locale   = $main::locale;
1097
1098   $main::auth->assert('config');
1099
1100   $form->{title} =  $locale->text('Add');
1101
1102   $form->{callback} ||= "am.pl?action=add_tax";
1103
1104   _get_taxaccount_selection();
1105
1106   $form->{asset}      = 1;
1107   $form->{liability}  = 1;
1108   $form->{equity}     = 1;
1109   $form->{revenue}    = 1;
1110   $form->{expense}    = 1;
1111   $form->{costs}      = 1;
1112
1113   setup_am_edit_tax_action_bar();
1114   $form->header();
1115
1116   my $parameters_ref = {
1117     LANGUAGES => SL::DB::Manager::Language->get_all_sorted,
1118   };
1119
1120   # Ausgabe des Templates
1121   print($form->parse_html_template('am/edit_tax', $parameters_ref));
1122
1123   $main::lxdebug->leave_sub();
1124 }
1125
1126 sub edit_tax {
1127   $main::lxdebug->enter_sub();
1128
1129   my $form     = $main::form;
1130   my %myconfig = %main::myconfig;
1131   my $locale   = $main::locale;
1132
1133   $main::auth->assert('config');
1134
1135   $form->{title} =  $locale->text('Edit');
1136
1137   AM->get_tax(\%myconfig, \%$form);
1138
1139   _get_taxaccount_selection();
1140
1141   $form->{asset}      = $form->{chart_categories} =~ 'A' ? 1 : 0;
1142   $form->{liability}  = $form->{chart_categories} =~ 'L' ? 1 : 0;
1143   $form->{equity}     = $form->{chart_categories} =~ 'Q' ? 1 : 0;
1144   $form->{revenue}    = $form->{chart_categories} =~ 'I' ? 1 : 0;
1145   $form->{expense}    = $form->{chart_categories} =~ 'E' ? 1 : 0;
1146   $form->{costs}      = $form->{chart_categories} =~ 'C' ? 1 : 0;
1147
1148   $form->{rate} = $form->format_amount(\%myconfig, $form->{rate}, 2);
1149
1150   setup_am_edit_tax_action_bar();
1151   $form->header();
1152
1153   my $parameters_ref = {
1154     LANGUAGES => SL::DB::Manager::Language->get_all_sorted,
1155     TAX       => SL::DB::Manager::Tax->find_by(id => $form->{id}),
1156   };
1157
1158   # Ausgabe des Templates
1159   print($form->parse_html_template('am/edit_tax', $parameters_ref));
1160
1161   $main::lxdebug->leave_sub();
1162 }
1163
1164 sub list_tax {
1165   $main::lxdebug->enter_sub();
1166
1167   my $form     = $main::form;
1168   my %myconfig = %main::myconfig;
1169   my $locale   = $main::locale;
1170
1171   $main::auth->assert('config');
1172
1173   AM->taxes(\%myconfig, \%$form);
1174
1175   map { $_->{rate} = $form->format_amount(\%myconfig, $_->{rate}, 2) } @{ $form->{TAX} };
1176
1177   $form->{callback} = build_std_url('action=list_tax');
1178
1179   $form->{title} = $locale->text('Tax-O-Matic');
1180
1181   setup_am_list_tax_action_bar();
1182   $form->header();
1183
1184   # Ausgabe des Templates
1185   print($form->parse_html_template('am/list_tax'));
1186
1187   $main::lxdebug->leave_sub();
1188 }
1189
1190 sub _get_taxaccount_selection{
1191   $main::lxdebug->enter_sub();
1192
1193   my $form     = $main::form;
1194   my %myconfig = %main::myconfig;
1195
1196   $main::auth->assert('config');
1197
1198   AM->get_tax_accounts(\%myconfig, \%$form);
1199
1200   map { $_->{selected} = $form->{chart_id} == $_->{id} } @{ $form->{ACCOUNTS} };
1201
1202   $main::lxdebug->leave_sub();
1203 }
1204
1205 sub save_tax {
1206   $main::lxdebug->enter_sub();
1207
1208   my $form     = $main::form;
1209   my %myconfig = %main::myconfig;
1210   my $locale   = $main::locale;
1211
1212   $main::auth->assert('config');
1213
1214   $form->error($locale->text('Taxkey  missing!')) unless length($form->{taxkey}) != 0;
1215   $form->error($locale->text('Taxdescription  missing!')) unless length($form->{taxdescription}) != 0;
1216   $form->error($locale->text('Taxrate missing!')) unless length($form->{rate}) != 0;
1217
1218   $form->{rate} = $form->parse_amount(\%myconfig, $form->{rate});
1219
1220   if ($form->{taxkey} == 0 and $form->{rate} > 0) {
1221     $form->error($locale->text('Taxkey 0 is reserved for rate 0'));
1222   }
1223
1224   if ( $form->{rate} < 0 || $form->{rate} >= 100 ) {
1225     $form->error($locale->text('Tax Percent is a number between 0 and 100'));
1226   }
1227
1228   if ( $form->{rate} <= 0.99 && $form->{rate} > 0 ) {
1229     $form->error($locale->text('Tax Percent is a number between 0 and 100'));
1230   }
1231
1232   my @translation_keys  =  grep { $_ =~ '^translation_\d+' } keys %$form;
1233   $form->{translations} = { map { $_ =~ '^translation_(\d+)'; $1 => $form->{$_} } @translation_keys };
1234
1235   AM->save_tax(\%myconfig, \%$form);
1236   $form->redirect($locale->text('Tax saved!'));
1237
1238   $main::lxdebug->leave_sub();
1239 }
1240
1241 sub delete_tax {
1242   $main::lxdebug->enter_sub();
1243
1244   my $form     = $main::form;
1245   my %myconfig = %main::myconfig;
1246   my $locale   = $main::locale;
1247
1248   $main::auth->assert('config');
1249
1250   AM->delete_tax(\%myconfig, \%$form);
1251   $form->redirect($locale->text('Tax deleted!'));
1252
1253   $main::lxdebug->leave_sub();
1254 }
1255
1256 sub add_warehouse {
1257   $main::lxdebug->enter_sub();
1258
1259   my $form     = $main::form;
1260   my $locale   = $main::locale;
1261
1262   $main::auth->assert('config');
1263
1264   $form->{title}      = $locale->text('Add Warehouse');
1265   $form->{callback} ||= build_std_url('action=add_warehouse');
1266
1267   $form->header();
1268   print $form->parse_html_template('am/edit_warehouse');
1269
1270   $main::lxdebug->leave_sub();
1271 }
1272
1273 sub edit_warehouse {
1274   $main::lxdebug->enter_sub();
1275
1276   my $form     = $main::form;
1277   my %myconfig = %main::myconfig;
1278   my $locale   = $main::locale;
1279
1280   $main::auth->assert('config');
1281
1282   AM->get_warehouse(\%myconfig, $form);
1283
1284   $form->get_lists('employees' => 'EMPLOYEES');
1285
1286   $form->{title}      = $locale->text('Edit Warehouse');
1287   $form->{callback} ||= build_std_url('action=list_warehouses');
1288
1289   $form->header();
1290   print $form->parse_html_template('am/edit_warehouse');
1291
1292   $main::lxdebug->leave_sub();
1293 }
1294
1295 sub list_warehouses {
1296   $main::lxdebug->enter_sub();
1297
1298   my $form     = $main::form;
1299   my %myconfig = %main::myconfig;
1300   my $locale   = $main::locale;
1301
1302   $main::auth->assert('config');
1303
1304   AM->get_all_warehouses(\%myconfig, $form);
1305
1306   $form->{callback} = build_std_url('action=list_warehouses');
1307   $form->{title}    = $locale->text('Warehouses');
1308   $form->{url_base} = build_std_url('callback');
1309
1310   $form->header();
1311   print $form->parse_html_template('am/list_warehouses');
1312
1313   $main::lxdebug->leave_sub();
1314 }
1315
1316 sub save_warehouse {
1317   $main::lxdebug->enter_sub();
1318
1319   my $form     = $main::form;
1320   my %myconfig = %main::myconfig;
1321   my $locale   = $main::locale;
1322
1323   $main::auth->assert('config');
1324
1325   $form->isblank("description", $locale->text('Description missing!'));
1326
1327   $form->{number_of_new_bins} = $form->parse_amount(\%myconfig, $form->{number_of_new_bins});
1328
1329   AM->save_warehouse(\%myconfig, $form);
1330
1331   $form->{callback} .= '&saved_message=' . E($locale->text('Warehouse saved.')) if ($form->{callback});
1332
1333   $form->redirect($locale->text('Warehouse saved.'));
1334
1335   $main::lxdebug->leave_sub();
1336 }
1337
1338 sub delete_warehouse {
1339   $main::lxdebug->enter_sub();
1340
1341   my $form     = $main::form;
1342   my %myconfig = %main::myconfig;
1343   my $locale   = $main::locale;
1344
1345   $main::auth->assert('config');
1346
1347   if (!$form->{confirmed}) {
1348     $form->{title} = $locale->text('Confirmation');
1349
1350     $form->header();
1351     print $form->parse_html_template('am/confirm_delete_warehouse');
1352     $::dispatcher->end_request;
1353   }
1354
1355   if (AM->delete_warehouse(\%myconfig, $form)) {
1356     $form->{callback} .= '&saved_message=' . E($locale->text('Warehouse deleted.')) if ($form->{callback});
1357     $form->redirect($locale->text('Warehouse deleted.'));
1358
1359   } else {
1360     $form->error($locale->text('The warehouse could not be deleted because it has already been used.'));
1361   }
1362
1363   $main::lxdebug->leave_sub();
1364 }
1365
1366 sub save_bin {
1367   $main::lxdebug->enter_sub();
1368
1369   my $form     = $main::form;
1370   my %myconfig = %main::myconfig;
1371   my $locale   = $main::locale;
1372
1373   $main::auth->assert('config');
1374
1375   AM->save_bins(\%myconfig, $form);
1376
1377   $form->{callback} .= '&saved_message=' . E($locale->text('Bins saved.')) if ($form->{callback});
1378
1379   $form->redirect($locale->text('Bins saved.'));
1380
1381   $main::lxdebug->leave_sub();
1382 }
1383
1384 sub setup_am_config_action_bar {
1385   my %params = @_;
1386
1387   for my $bar ($::request->layout->get('actionbar')) {
1388     $bar->add(
1389       action => [
1390         t8('Save'),
1391         submit    => [ '#form', { action => "save_preferences" } ],
1392         accesskey => 'enter',
1393       ],
1394     );
1395   }
1396 }
1397
1398 sub setup_am_edit_account_action_bar {
1399   my %params = @_;
1400
1401   for my $bar ($::request->layout->get('actionbar')) {
1402     $bar->add(
1403       combobox => [
1404         action => [
1405           t8('Save'),
1406           submit    => [ '#form', { action => "save_account" } ],
1407           disabled  => $::form->{id} && !$::form->{orphaned} ? t8('The object is in use and cannot be changed.')
1408                      :                                         undef,
1409           accesskey => 'enter',
1410         ],
1411
1412         action => [
1413           t8('Save as new'),
1414           submit   => [ '#form', { action => "save_as_new_account" } ],
1415           disabled => !$::form->{id} ? t8('The object has not been saved yet.') : undef,
1416         ],
1417       ],
1418
1419       action => [
1420         t8('Delete'),
1421         submit   => [ '#form', { action => "delete_account" } ],
1422         disabled => !$::form->{id}                         ? t8('The object has not been saved yet.')
1423                   :  $::form->{id} && !$::form->{orphaned} ? t8('The object is in use and cannot be deleted.')
1424                   :                                          undef,
1425         confirm  => t8('Do you really want to delete this object?'),
1426       ],
1427     );
1428   }
1429 }
1430
1431 sub setup_am_list_tax_action_bar {
1432   my %params = @_;
1433
1434   for my $bar ($::request->layout->get('actionbar')) {
1435     $bar->add(
1436       link => [
1437         t8('Add'),
1438         link => 'am.pl?action=add_tax',
1439       ],
1440     );
1441   }
1442 }
1443
1444 sub setup_am_edit_tax_action_bar {
1445   my %params = @_;
1446
1447   for my $bar ($::request->layout->get('actionbar')) {
1448     $bar->add(
1449       action => [
1450         t8('Save'),
1451         submit    => [ '#form', { action => "save_tax" } ],
1452         accesskey => 'enter',
1453       ],
1454
1455       action => [
1456         t8('Delete'),
1457         submit   => [ '#form', { action => "delete_tax" } ],
1458         disabled => !$::form->{id}                                      ? t8('The object has not been saved yet.')
1459                   : !$::form->{orphaned} || $::form->{tax_already_used} ? t8('The object is in use and cannot be deleted.')
1460                   :                                                       undef,
1461         confirm  => t8('Do you really want to delete this object?'),
1462       ],
1463     );
1464   }
1465 }