am: fehlendes include für Historiensuche(2)
[kivitendo-erp.git] / bin / mozilla / gl.pl
index 719f222..cb2ebb2 100644 (file)
@@ -24,7 +24,8 @@
 # GNU General Public License for more details.
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+# MA 02110-1335, USA.
 #======================================================================
 #
 # Genereal Ledger
@@ -40,11 +41,12 @@ use List::Util qw(sum);
 use SL::FU;
 use SL::GL;
 use SL::IS;
-use SL::PE;
 use SL::ReportGenerator;
+use SL::DBUtils qw(selectrow_query selectall_hashref_query);
+use SL::Webdav;
+use SL::Locale::String qw(t8);
 
 require "bin/mozilla/common.pl";
-require "bin/mozilla/drafts.pl";
 require "bin/mozilla/reportgenerator.pl";
 
 # this is for our long dates
@@ -78,13 +80,11 @@ require "bin/mozilla/reportgenerator.pl";
 sub add {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
 
-  return $main::lxdebug->leave_sub() if (load_draft_maybe());
-
   $form->{title} = "Add";
 
   $form->{callback} = "gl.pl?action=add" unless $form->{callback};
@@ -99,16 +99,7 @@ sub add {
   $form->{credit} = 0;
   $form->{tax}    = 0;
 
-  # departments
-  $form->all_departments(\%myconfig);
-  if (@{ $form->{all_departments} || [] }) {
-    $form->{selectdepartment} = "<option>\n";
-
-    map {
-      $form->{selectdepartment} .=
-        "<option>$_->{description}--$_->{id}\n"
-    } (@{ $form->{all_departments} || [] });
-  }
+  $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
 
   $form->{show_details} = $myconfig{show_form_details} unless defined $form->{show_details};
 
@@ -120,7 +111,7 @@ sub add {
 sub prepare_transaction {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
@@ -129,16 +120,7 @@ sub prepare_transaction {
 
   $form->{amount} = $form->format_amount(\%myconfig, $form->{amount}, 2);
 
-  # departments
-  $form->all_departments(\%myconfig);
-  if (@{ $form->{all_departments} || [] }) {
-    $form->{selectdepartment} = "<option>\n";
-
-    map {
-      $form->{selectdepartment} .=
-        "<option>$_->{description}--$_->{id}\n"
-    } (@{ $form->{all_departments} || [] });
-  }
+  $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
 
   my $i        = 1;
   my $tax      = 0;
@@ -158,7 +140,7 @@ sub prepare_transaction {
       $form->{"project_id_$j"} = $ref->{project_id};
 
     } else {
-      $form->{"accno_$i"} = "$ref->{accno}--$ref->{tax_id}";
+      $form->{"accno_id_$i"} = $ref->{chart_id};
       for (qw(fx_transaction source memo)) { $form->{"${_}_$i"} = $ref->{$_} }
       if ($ref->{amount} < 0) {
         $form->{totaldebit} -= $ref->{amount};
@@ -167,7 +149,7 @@ sub prepare_transaction {
         $form->{totalcredit} += $ref->{amount};
         $form->{"credit_$i"} = $ref->{amount};
       }
-      $form->{"taxchart_$i"} = "0--0.00";
+      $form->{"taxchart_$i"} = $ref->{id}."--0.00000";
       $form->{"project_id_$i"} = $ref->{project_id};
       $i++;
     }
@@ -191,7 +173,7 @@ sub prepare_transaction {
 sub edit {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
@@ -202,6 +184,18 @@ sub edit {
 
   $form->{show_details} = $myconfig{show_form_details} unless defined $form->{show_details};
 
+  if ($form->{reference} && $::instance_conf->get_webdav) {
+    my $webdav = SL::Webdav->new(
+      type     => 'general_ledger',
+      number   => $form->{reference},
+    );
+    my $webdav_path = $webdav->webdav_path;
+    my @all_objects = $webdav->get_all_objects;
+    @{ $form->{WEBDAV} } = map { { name => $_->filename,
+                                   type => t8('File'),
+                                   link => File::Spec->catfile($_->full_filedescriptor),
+                               } } @all_objects;
+  }
   form_header();
   display_rows();
   form_footer();
@@ -212,17 +206,16 @@ sub edit {
 
 sub search {
   $::lxdebug->enter_sub;
-  $::auth->assert('general_ledger');
+  $::auth->assert('general_ledger | gl_transactions');
 
-  $::form->all_departments(\%::myconfig);
   $::form->get_lists(
     projects  => { key => "ALL_PROJECTS", all => 1 },
   );
-  $::form->{ALL_EMPLOYEES} = SL::DB::Manager::Employee->get_all(query => [ deleted => 0 ]);
+  $::form->{ALL_EMPLOYEES} = SL::DB::Manager::Employee->get_all_sorted(query => [ deleted => 0 ]);
+  $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
 
   $::form->header;
   print $::form->parse_html_template('gl/search', {
-    department_label => sub { ("$_[0]{description}--$_[0]{id}")x2 },
     employee_label => sub { "$_[0]{id}--$_[0]{name}" },
   });
 
@@ -251,22 +244,22 @@ sub create_subtotal_row {
 sub generate_report {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('general_ledger | gl_transactions');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
   my $locale   = $main::locale;
 
-  # generate_report wird beim ersten Aufruf per Weiter-Knopf und POST mit der hidden Variablen sort mit Wert "datesort" (früher "transdate" als Defaultsortiervariable) übertragen
+  # generate_report wird beim ersten Aufruf per Weiter-Knopf und POST mit der hidden Variablen sort mit Wert "datesort" (früher "transdate" als Defaultsortiervariable) übertragen
 
   # <form method=post action=gl.pl>
   # <input type=hidden name=sort value=datesort>    # form->{sort} setzen
   # <input type=hidden name=nextsub value=generate_report>
 
   # anhand von neuer Variable datesort wird jetzt $form->{sort} auf transdate oder gldate gesetzt
-  # damit ist die Hidden Variable "sort" wahrscheinlich sogar überflüssig
+  # damit ist die Hidden Variable "sort" wahrscheinlich sogar überflüssig
 
-  # ändert man die Sortierreihenfolge per Klick auf eine der Überschriften wird die Variable "sort" per GET übergeben, z.B. id,transdate, gldate, ...
+  # ändert man die Sortierreihenfolge per Klick auf eine der Überschriften wird die Variable "sort" per GET übergeben, z.B. id,transdate, gldate, ...
   # gl.pl?action=generate_report&employee=18383--Jan%20B%c3%bcren&datesort=transdate&category=X&l_transdate=Y&l_gldate=Y&l_id=Y&l_reference=Y&l_description=Y&l_source=Y&l_debit=Y&l_credit=Y&sort=gldate&sortdir=0
 
   if ( $form->{sort} eq 'datesort' ) {   # sollte bei einem Post (Aufruf aus Suchmaske) immer wahr sein
@@ -304,11 +297,10 @@ sub generate_report {
   );
 
   # add employee here, so that variable is still known and passed in url when choosing a different sort order in resulting table
-  my @hidden_variables = qw(accno source reference department description notes project_id datefrom dateto employee datesort category l_subtotal);
+  my @hidden_variables = qw(accno source reference description notes project_id datefrom dateto employee_id datesort category l_subtotal);
   push @hidden_variables, map { "l_${_}" } @columns;
-  foreach ( @hidden_variables ) {
-      print URL "$_\n";
-  };
+
+  my $employee = $form->{employee_id} ? SL::DB::Employee->new(id => $form->{employee_id})->load->name : '';
 
   my (@options, @date_options);
   push @options,      $locale->text('Account')     . " : $form->{accno} $form->{account_description}" if ($form->{accno});
@@ -316,22 +308,19 @@ sub generate_report {
   push @options,      $locale->text('Reference')   . " : $form->{reference}"                          if ($form->{reference});
   push @options,      $locale->text('Description') . " : $form->{description}"                        if ($form->{description});
   push @options,      $locale->text('Notes')       . " : $form->{notes}"                              if ($form->{notes});
-  push @options,      $locale->text('Employee')       . " : $form->{employee_name}"                              if ($form->{employee_name});
+  push @options,      $locale->text('Employee')    . " : $employee"                                   if $employee;
   my $datesorttext = $form->{datesort} eq 'transdate' ? $locale->text('Invoice Date') :  $locale->text('Booking Date');
   push @date_options,      "$datesorttext"                              if ($form->{datesort} and ($form->{datefrom} or $form->{dateto}));
   push @date_options, $locale->text('From'), $locale->date(\%myconfig, $form->{datefrom}, 1)          if ($form->{datefrom});
   push @date_options, $locale->text('Bis'),  $locale->date(\%myconfig, $form->{dateto},   1)          if ($form->{dateto});
   push @options,      join(' ', @date_options)                                                        if (scalar @date_options);
 
-  if ($form->{department}) {
-    my ($department) = split /--/, $form->{department};
-    push @options, $locale->text('Department') . " : $department";
+  if ($form->{department_id}) {
+    my $department = SL::DB::Manager::Department->find_by( id => $form->{department_id} );
+    push @options, $locale->text('Department') . " : " . $department->description;
   }
 
-
   my $callback = build_std_url('action=generate_report', grep { $form->{$_} } @hidden_variables);
-  print URL $callback;
-  close URL;
 
   $form->{l_credit_accno}     = 'Y';
   $form->{l_debit_accno}      = 'Y';
@@ -515,10 +504,16 @@ sub generate_report {
   $main::lxdebug->leave_sub();
 }
 
+sub show_draft {
+  $::form->{transdate} = DateTime->today_local->to_kivitendo if !$::form->{transdate};
+  $::form->{gldate}    = $::form->{transdate} if !$::form->{gldate};
+  update();
+}
+
 sub update {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
@@ -533,6 +528,10 @@ sub update {
   my $creditcount = 0;
   my ($debitcredit, $amount);
 
+  my $dbh = SL::DB->client->dbh;
+  my ($notax_id) = selectrow_query($form, $dbh, "SELECT id FROM tax WHERE taxkey = 0 LIMIT 1", );
+  my $zerotaxes  = selectall_hashref_query($form, $dbh, "SELECT id FROM tax WHERE rate = 0", );
+
   my @flds =
     qw(accno debit credit projectnumber fx_transaction source memo tax taxchart);
 
@@ -571,10 +570,10 @@ sub update {
         $form->{debitlock} = 1;
       }
       if ($debitcredit && $credittax) {
-        $form->{"taxchart_$i"} = "0--0.00";
+        $form->{"taxchart_$i"} = "$notax_id--0.00";
       }
       if (!$debitcredit && $debittax) {
-        $form->{"taxchart_$i"} = "0--0.00";
+        $form->{"taxchart_$i"} = "$notax_id--0.00";
       }
       $amount =
         ($form->{"debit_$i"} == 0)
@@ -582,24 +581,20 @@ sub update {
         : $form->{"debit_$i"};
       my $j = $#a;
       if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
-        $form->{"taxchart_$i"} = "0--0.00";
+        $form->{"taxchart_$i"} = "$notax_id--0.00";
         $form->{"tax_$i"}      = 0;
       }
       my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
-      if ($taxkey > 1) {
+      my $iswithouttax = grep { $_->{id} == $taxkey } @{ $zerotaxes };
+      if (!$iswithouttax) {
         if ($debitcredit) {
           $debittax = 1;
         } else {
           $credittax = 1;
         }
-        if ($form->{taxincluded}) {
-          $form->{"tax_$i"} = $amount / ($rate + 1) * $rate;
-        } else {
-          $form->{"tax_$i"} = $amount * $rate;
-        }
-      } else {
-        $form->{"tax_$i"} = 0;
-      }
+      };
+      my ($tmpnetamount,$tmpdiff);
+      ($tmpnetamount,$form->{"tax_$i"},$tmpdiff) = $form->calculate_tax($amount,$rate,$form->{taxincluded} *= 1,2);
 
       for (@flds) { $a[$j]->{$_} = $form->{"${_}_$i"} }
       $count++;
@@ -626,7 +621,7 @@ sub display_form {
   my ($init) = @_;
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
@@ -649,12 +644,14 @@ sub display_rows {
   my ($init) = @_;
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
   my $cgi      = $::request->{cgi};
 
+  my %balances = GL->get_chart_balances(map { $_->{id} } @{ $form->{ALL_CHARTS} });
+
   $form->{debit_1}     = 0 if !$form->{"debit_1"};
   $form->{totaldebit}  = 0;
   $form->{totalcredit} = 0;
@@ -666,31 +663,9 @@ sub display_rows {
     $project_labels{$item->{"id"}} = $item->{"projectnumber"};
   }
 
-  my %chart_labels = ();
-  my @chart_values = ();
-  my %charts = ();
-  my $taxchart_init;
-  foreach my $item (@{ $form->{ALL_CHARTS} }) {
-    if ($item->{charttype} eq 'H'){ #falls überschrift
-      next;                         #überspringen (Bug 1150)
-    }
-    my $key = $item->{accno} . "--" . $item->{tax_id};
-    $taxchart_init = $item->{tax_id} unless (@chart_values);
-    push(@chart_values, $key);
-    $chart_labels{$key} = $item->{accno} . "--" . $item->{description};
-    $charts{$item->{accno}} = $item;
-  }
-
-  my %taxchart_labels = ();
-  my @taxchart_values = ();
-  my %taxcharts = ();
-  foreach my $item (@{ $form->{ALL_TAXCHARTS} }) {
-    my $key = $item->{id} . "--" . $item->{rate};
-    $taxchart_init = $key if ($taxchart_init == $item->{id});
-    push(@taxchart_values, $key);
-    $taxchart_labels{$key} = $item->{taxdescription} . " " . $item->{rate} * 100 . ' %';
-    $taxcharts{$item->{id}} = $item;
-  }
+  my %charts_by_id  = map { ($_->{id} => $_) } @{ $::form->{ALL_CHARTS} };
+  my $default_chart = $::form->{ALL_CHARTS}[0];
+  my $transdate     = $::form->{transdate} ? DateTime->from_kivitendo($::form->{transdate}) : DateTime->today_local;
 
   my ($source, $memo, $source_hidden, $memo_hidden);
   for my $i (1 .. $form->{rowcount}) {
@@ -706,43 +681,39 @@ sub display_rows {
       <input type="hidden" name="memo_$i" value="$form->{"memo_$i"}" size="16">|;
     }
 
-    my $selected_accno_full;
-    my ($accno_row) = split(/--/, $form->{"accno_$i"});
-    my $item = $charts{$accno_row};
-    $selected_accno_full = "$item->{accno}--$item->{tax_id}";
+    my %taxchart_labels = ();
+    my @taxchart_values = ();
+
+    my $accno_id          = $::form->{"accno_id_$i"};
+    my $chart             = $charts_by_id{$accno_id} // $default_chart;
+    $accno_id             = $chart->{id};
+    my $chart_has_changed = $::form->{"previous_accno_id_$i"} && ($accno_id != $::form->{"previous_accno_id_$i"});
+    my ($first_taxchart, $default_taxchart, $taxchart_to_use);
 
-    my $selected_taxchart = $form->{"taxchart_$i"};
-    my ($selected_accno, $selected_tax_id) = split(/--/, $selected_accno_full);
-    my ($previous_accno, $previous_tax_id) = split(/--/, $form->{"previous_accno_$i"});
+    foreach my $item ( GL->get_active_taxes_for_chart($accno_id, $transdate) ) {
+      my $key             = $item->id . "--" . $item->rate;
+      $first_taxchart   //= $item;
+      $default_taxchart   = $item if $item->{is_default};
+      $taxchart_to_use    = $item if $key eq $form->{"taxchart_$i"};
 
-    if ($previous_accno &&
-        ($previous_accno eq $selected_accno) &&
-        ($previous_tax_id ne $selected_tax_id)) {
-      my $item = $taxcharts{$selected_tax_id};
-      $selected_taxchart = "$item->{id}--$item->{rate}";
+      push(@taxchart_values, $key);
+      $taxchart_labels{$key} = $item->taxdescription . " " . $item->rate * 100 . ' %';
     }
 
-    $selected_accno      = '' if ($init);
-    $selected_taxchart ||= $taxchart_init;
+    $taxchart_to_use      = $default_taxchart // $first_taxchart if $chart_has_changed || !$taxchart_to_use;
+    my $selected_taxchart = $taxchart_to_use->id . '--' . $taxchart_to_use->rate;
 
     my $accno = qq|<td>| .
-      NTI($cgi->popup_menu('-name' => "accno_$i",
-                           '-id' => "accno_$i",
-                           '-onChange' => "setTaxkey($i)",
-                           '-style' => 'width:200px',
-                           '-values' => \@chart_values,
-                           '-labels' => \%chart_labels,
-                           '-default' => $selected_accno_full))
-      . $cgi->hidden('-name' => "previous_accno_$i",
-                     '-default' => $selected_accno_full)
+      $::request->presenter->chart_picker("accno_id_$i", $accno_id, style => "width: 300px") .
+      $::request->presenter->hidden_tag("previous_accno_id_$i", $accno_id)
       . qq|</td>|;
     my $tax_ddbox = qq|<td>| .
       NTI($cgi->popup_menu('-name' => "taxchart_$i",
-                           '-id' => "taxchart_$i",
-                           '-style' => 'width:200px',
-                           '-values' => \@taxchart_values,
-                           '-labels' => \%taxchart_labels,
-                           '-default' => $selected_taxchart))
+            '-id' => "taxchart_$i",
+            '-style' => 'width:200px',
+            '-values' => \@taxchart_values,
+            '-labels' => \%taxchart_labels,
+            '-default' => $selected_taxchart))
       . qq|</td>|;
 
     my ($fx_transaction, $checked);
@@ -810,10 +781,11 @@ sub display_rows {
     <input type="hidden" name="project_id_$i" value="$form->{"project_id_$i"}">|;
 
     my $copy2credit = $i == 1 ? 'onkeyup="copy_debit_to_credit()"' : '';
+    my $balance     = $form->format_amount(\%::myconfig, $balances{$accno_id} // 0, 2, 'DRCR');
 
     print qq|<tr valign=top>
     $accno
-    <td id="chart_balance_$i" align="right">&nbsp;</td>
+    <td id="chart_balance_$i" align="right">${balance}</td>
     $fx_transaction
     <td><input name="debit_$i" size="8" value="$form->{"debit_$i"}" accesskey=$i $copy2credit $debitreadonly></td>
     <td><input name="credit_$i" size=8 value="$form->{"credit_$i"}" $creditreadonly></td>
@@ -844,22 +816,28 @@ sub display_rows {
 
 }
 
+sub _get_radieren {
+  return ($::instance_conf->get_gl_changeable == 2) ? ($::form->current_date(\%::myconfig) eq $::form->{gldate}) : ($::instance_conf->get_gl_changeable == 1);
+}
+
 sub form_header {
   $::lxdebug->enter_sub;
-  $::auth->assert('general_ledger');
+  $::auth->assert('gl_transactions');
 
   my ($init) = @_;
 
+  $::request->layout->add_javascripts("autocomplete_chart.js", "kivi.GL.js");
+
   my @old_project_ids = grep { $_ } map{ $::form->{"project_id_$_"} } 1..$::form->{rowcount};
 
   $::form->get_lists("projects"  => { "key"       => "ALL_PROJECTS",
                                     "all"       => 0,
                                     "old_id"    => \@old_project_ids },
+
                    "charts"    => { "key"       => "ALL_CHARTS",
-                                    "transdate" => $::form->{transdate} },
-                   "taxcharts" => "ALL_TAXCHARTS");
+                                    "transdate" => $::form->{transdate} });
 
-  GL->get_chart_balances('charts' => $::form->{ALL_CHARTS});
+  $::form->{ALL_DEPARTMENTS} = SL::DB::Manager::Department->get_all;
 
   my $title      = $::form->{title};
   $::form->{title} = $::locale->text("$title General Ledger Transaction");
@@ -869,15 +847,11 @@ sub form_header {
   map { $::form->{$_} =~ s/\"/&quot;/g }
     qw(chart taxchart);
 
-  $::form->{selectdepartment} =~ s/ selected//;
-  $::form->{selectdepartment} =~
-    s/option>\Q$::form->{department}\E/option selected>$::form->{department}/;
-
   if ($init) {
     $::request->{layout}->focus("#reference");
     $::form->{taxincluded} = "1";
   } else {
-    $::request->{layout}->focus("#accno_$::form->{rowcount}");
+    $::request->{layout}->focus("#accno_id_$::form->{rowcount}_name");
   }
 
   $::form->{previous_id}     ||= "--";
@@ -886,6 +860,7 @@ sub form_header {
   $::form->header;
   print $::form->parse_html_template('gl/form_header', {
     hide_title => $title,
+    readonly   => $::form->{id} && ($::form->{locked} || !_get_radieren()),
   });
 
   $::lxdebug->leave_sub;
@@ -894,21 +869,17 @@ sub form_header {
 
 sub form_footer {
   $::lxdebug->enter_sub;
-  $::auth->assert('general_ledger');
+  $::auth->assert('gl_transactions');
 
   my ($follow_ups, $follow_ups_due);
 
   if ($::form->{id}) {
-    $follow_ups     = FU->follow_ups('trans_id' => $::form->{id});
+    $follow_ups     = FU->follow_ups('trans_id' => $::form->{id}, 'not_done' => 1);
     $follow_ups_due = sum map { $_->{due} * 1 } @{ $follow_ups || [] };
   }
 
-  my $radieren = ($::instance_conf->get_gl_changeable == 2)
-                    ? ($::form->current_date(\%::myconfig) eq $::form->{gldate})
-                    : ($::instance_conf->get_gl_changeable == 1);
-
   print $::form->parse_html_template('gl/form_footer', {
-    radieren       => $radieren,
+    radieren       => _get_radieren(),
     follow_ups     => $follow_ups,
     follow_ups_due => $follow_ups_due,
   });
@@ -962,8 +933,9 @@ sub yes {
   if (GL->delete_transaction(\%myconfig, \%$form)){
     # saving the history
       if(!exists $form->{addition} && $form->{id} ne "") {
-        $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
+        $form->{snumbers} = qq|gltransaction_| . $form->{id};
         $form->{addition} = "DELETED";
+        $form->{what_done} = "gl_transaction";
         $form->save_history;
       }
     # /saving the history
@@ -998,6 +970,10 @@ sub post_transaction {
   my $debitcredit;
   my %split_safety = ();
 
+  my $dbh = SL::DB->client->dbh;
+  my ($notax_id) = selectrow_query($form, $dbh, "SELECT id FROM tax WHERE taxkey = 0 LIMIT 1", );
+  my $zerotaxes  = selectall_hashref_query($form, $dbh, "SELECT id FROM tax WHERE rate = 0", );
+
   my @flds = qw(accno debit credit projectnumber fx_transaction source memo tax taxchart);
 
   for my $i (1 .. $form->{rowcount}) {
@@ -1038,36 +1014,36 @@ sub post_transaction {
       $form->{debitlock} = 1;
     }
     if ($debitcredit && $credittax) {
-      $form->{"taxchart_$i"} = "0--0.00";
+      $form->{"taxchart_$i"} = "$notax_id--0.00";
     }
     if (!$debitcredit && $debittax) {
-      $form->{"taxchart_$i"} = "0--0.00";
+      $form->{"taxchart_$i"} = "$notax_id--0.00";
     }
     my $amount = ($form->{"debit_$i"} == 0)
             ? $form->{"credit_$i"}
             : $form->{"debit_$i"};
     my $j = $#a;
     if (($debitcredit && $credittax) || (!$debitcredit && $debittax)) {
-      $form->{"taxchart_$i"} = "0--0.00";
+      $form->{"taxchart_$i"} = "$notax_id--0.00";
       $form->{"tax_$i"}      = 0;
     }
     my ($taxkey, $rate) = split(/--/, $form->{"taxchart_$i"});
-    if ($taxkey > 1) {
+    my $iswithouttax = grep { $_->{id} == $taxkey } @{ $zerotaxes };
+    if (!$iswithouttax) {
       if ($debitcredit) {
         $debittax = 1;
       } else {
         $credittax = 1;
       }
-      if ($form->{taxincluded}) {
-        $form->{"tax_$i"} = $amount / ($rate + 1) * $rate;
-        if ($debitcredit) {
-          $form->{"debit_$i"} = $form->{"debit_$i"} - $form->{"tax_$i"};
-        } else {
-          $form->{"credit_$i"} = $form->{"credit_$i"} - $form->{"tax_$i"};
-        }
+
+      my ($tmpnetamount,$tmpdiff);
+      ($tmpnetamount,$form->{"tax_$i"},$tmpdiff) = $form->calculate_tax($amount,$rate,$form->{taxincluded} *= 1,2);
+      if ($debitcredit) {
+        $form->{"debit_$i"} = $tmpnetamount;
       } else {
-        $form->{"tax_$i"} = $amount * $rate;
+        $form->{"credit_$i"} = $tmpnetamount;
       }
+
     } else {
       $form->{"tax_$i"} = 0;
     }
@@ -1077,7 +1053,8 @@ sub post_transaction {
   }
 
   if ($split_safety{-1} > 1 && $split_safety{1} > 1) {
-    $::form->error($::locale->text("Split entry detected. The values you have entered will result in an entry with more than one position on both debit and credit. Due to known problems involving accounting software Lx-Office does not allow these."));
+    $::form->error($::locale->text("Split entry detected. The values you have entered will result in an entry with more than one position on both debit and credit. " .
+                                   "Due to known problems involving accounting software kivitendo does not allow these."));
   }
 
   for my $i (1 .. $count) {
@@ -1105,6 +1082,9 @@ sub post_transaction {
   $form->{taxincluded} = 0 if !$taxtotal;
 
   # this is just for the wise guys
+
+  $form->error($locale->text('Cannot post transaction above the maximum future booking date!'))
+    if ($form->date_max_future($form->{"transdate"}, \%myconfig));
   $form->error($locale->text('Cannot post transaction for a closed period!'))
     if ($form->date_closed($form->{"transdate"}, \%myconfig));
   if ($form->round_amount($debit, 2) != $form->round_amount($credit, 2)) {
@@ -1127,9 +1107,9 @@ sub post_transaction {
   undef($form->{callback});
   # saving the history
   if(!exists $form->{addition} && $form->{id} ne "") {
-    $form->{snumbers} = qq|ordnumber_| . $form->{ordnumber};
-    $form->{addition} = "SAVED";
-    $form->{what_done} = $locale->text("Buchungsnummer") . " = " . $form->{id};
+    $form->{snumbers} = qq|gltransaction_| . $form->{id};
+    $form->{addition} = "POSTED";
+    $form->{what_done} = "gl transaction";
     $form->save_history;
   }
   # /saving the history
@@ -1140,12 +1120,12 @@ sub post_transaction {
 sub post {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
   my $locale   = $main::locale;
 
-  if ($::myconfig{mandatory_departments} && !$form->{department}) {
+  if ($::myconfig{mandatory_departments} && !$form->{department_id}) {
     $form->{saved_message} = $::locale->text('You have to specify a department.');
     update();
     exit;
@@ -1155,10 +1135,13 @@ sub post {
   $form->{storno} = 0;
 
   post_transaction();
+  if ($::instance_conf->get_webdav) {
+    SL::Webdav->new(type     => 'general_ledger',
+                    number   => $form->{reference},
+                   )->webdav_path;
+  }
 
-  remove_draft() if $form->{remove_draft};
-
-  $form->{callback} = build_std_url("action=add&DONT_LOAD_DRAFT=1", "show_details");
+  $form->{callback} = build_std_url("action=add", "show_details");
   $form->redirect($form->{callback});
 
   $main::lxdebug->leave_sub();
@@ -1167,7 +1150,7 @@ sub post {
 sub post_as_new {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
 
@@ -1180,7 +1163,7 @@ sub post_as_new {
 sub storno {
   $main::lxdebug->enter_sub();
 
-  $main::auth->assert('general_ledger');
+  $main::auth->assert('gl_transactions');
 
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
@@ -1196,8 +1179,9 @@ sub storno {
 
   # saving the history
   if(!exists $form->{addition} && $form->{id} ne "") {
-    $form->{snumbers} = "ordnumber_$form->{ordnumber}";
+    $form->{snumbers} = qq|gltransaction_| . $form->{id};
     $form->{addition} = "STORNO";
+    $form->{what_done} = "gl_transaction";
     $form->save_history;
   }
   # /saving the history
@@ -1211,4 +1195,19 @@ sub continue {
   call_sub($main::form->{nextsub});
 }
 
+sub get_tax_dropdown {
+  my $transdate    = $::form->{transdate} ? DateTime->from_kivitendo($::form->{transdate}) : DateTime->today_local;
+  my @tax_accounts = GL->get_active_taxes_for_chart($::form->{accno_id}, $transdate);
+  my $html         = $::form->parse_html_template("gl/update_tax_accounts", { TAX_ACCOUNTS => \@tax_accounts });
+
+  print $::form->ajax_response_header, $html;
+}
+
+sub get_chart_balance {
+  my %balances = GL->get_chart_balances($::form->{accno_id});
+  my $balance  = $::form->format_amount(\%::myconfig, $balances{ $::form->{accno_id} }, 2, 'DRCR');
+
+  print $::form->ajax_response_header, $balance;
+}
+
 1;