changelog zu Workflow zu Lieferantenauftrag
[kivitendo-erp.git] / SL / AccTransCorrections.pm
index 1d423d6..2ecad9f 100644 (file)
@@ -1,11 +1,13 @@
 package AccTransCorrections;
 
 package AccTransCorrections;
 
+use utf8;
 use strict;
 
 use List::Util qw(first);
 
 use SL::DBUtils;
 use SL::Taxkeys;
 use strict;
 
 use List::Util qw(first);
 
 use SL::DBUtils;
 use SL::Taxkeys;
+use SL::DB;
 
 sub new {
   my $type = shift;
 
 sub new {
   my $type = shift;
@@ -53,7 +55,7 @@ sub _fetch_transactions {
   }
 
   my $query = qq!
   }
 
   my $query = qq!
-    SELECT at.oid, at.*,
+    SELECT at.*,
       c.accno, c.description AS chartdescription, c.charttype, c.category AS chartcategory, c.link AS chartlink,
       COALESCE(gl.reference, COALESCE(ap.invnumber, ar.invnumber)) AS reference,
       COALESCE(ap.invoice, COALESCE(ar.invoice, FALSE)) AS invoice,
       c.accno, c.description AS chartdescription, c.charttype, c.category AS chartcategory, c.link AS chartlink,
       COALESCE(gl.reference, COALESCE(ap.invnumber, ar.invnumber)) AS reference,
       COALESCE(ap.invoice, COALESCE(ar.invoice, FALSE)) AS invoice,
@@ -74,7 +76,7 @@ sub _fetch_transactions {
     LEFT JOIN ap      ON (at.trans_id = ap.id)
     LEFT JOIN ar      ON (at.trans_id = ar.id)
     $where
     LEFT JOIN ap      ON (at.trans_id = ap.id)
     LEFT JOIN ar      ON (at.trans_id = ar.id)
     $where
-    ORDER BY at.trans_id, at.oid
+    ORDER BY at.trans_id, at.acc_trans_id
 !;
 
   my @transactions = ();
 !;
 
   my @transactions = ();
@@ -129,8 +131,8 @@ sub _prepare_data {
     delete $entry->{chartlink};
   }
 
     delete $entry->{chartlink};
   }
 
-  # Verknüpfungen zwischen Steuerschlüsseln und zum Zeitpunkt der Transaktion
-  # gültigen Steuersätze
+  # Verknüpfungen zwischen Steuerschlüsseln und zum Zeitpunkt der Transaktion
+  # gültigen Steuersätze
   my %all_taxes = $self->{taxkeys}->get_full_tax_info('transdate' => $transaction->[0]->{transdate});
 
   my ($trans_type, $previous_non_tax_entry);
   my %all_taxes = $self->{taxkeys}->get_full_tax_info('transdate' => $transaction->[0]->{transdate});
 
   my ($trans_type, $previous_non_tax_entry);
@@ -184,8 +186,8 @@ sub _prepare_data {
     }
   }
 
     }
   }
 
-  # Alle Einträge entfernen, die die Gegenkonten zu Zahlungsein- und
-  # -ausgängen darstellen.
+  # Alle Einträge entfernen, die die Gegenkonten zu Zahlungsein- und
+  # -ausgängen darstellen.
   foreach my $payment (@{ $data->{payments} }) {
     my $idx = 0 < $payment->{amount} ? 'debit' : 'credit';
 
   foreach my $payment (@{ $data->{payments} }) {
     my $idx = 0 < $payment->{amount} ? 'debit' : 'credit';
 
@@ -253,14 +255,18 @@ sub _group_sub_transactions {
 }
 
 # Problemfall: Verkaufsrechnungen, bei denen Buchungen auf Warenbestandskonten
 }
 
 # Problemfall: Verkaufsrechnungen, bei denen Buchungen auf Warenbestandskonten
-# mit Steuerschlüssel != 0 durchgeführt wurden. Richtig wäre, dass alle
-# Steuerschlüssel für solche Warenbestandsbuchungen 0 sind.
+# mit Steuerschlüssel != 0 durchgeführt wurden. Richtig wäre, dass alle
+# Steuerschlüssel für solche Warenbestandsbuchungen 0 sind.
 sub _check_trans_invoices_inventory_with_taxkeys {
   $main::lxdebug->enter_sub();
 
   my $self   = shift;
   my %params = @_;
 
 sub _check_trans_invoices_inventory_with_taxkeys {
   $main::lxdebug->enter_sub();
 
   my $self   = shift;
   my %params = @_;
 
+  # ist nur für bestandsmethode notwendig. bei der Aufwandsmethode
+  # können Warenkonten mit Steuerschlüssel sein (5400 in SKR04)
+  return 0 if $::instance_conf->get_inventory_system eq 'periodic';
+
   if (!$params{transaction}->[0]->{invoice}) {
     $main::lxdebug->leave_sub();
     return 0;
   if (!$params{transaction}->[0]->{invoice}) {
     $main::lxdebug->leave_sub();
     return 0;
@@ -288,8 +294,51 @@ sub _check_trans_invoices_inventory_with_taxkeys {
   return 0;
 }
 
   return 0;
 }
 
-# Problemfall: Kreditorenbuchungen, bei denen mit Umsatzsteuerschlüsseln
-# gebucht wurde und Debitorenbuchungen, bei denen mit Vorsteuerschlüsseln
+# Problemfall: Verkaufsrechnungen, bei denen Steuern verbucht wurden, obwohl
+# kein Steuerschlüssel eingetragen ist.
+sub _check_missing_taxkeys_in_invoices {
+  $::lxdebug->enter_sub;
+
+  my $self        = shift;
+  my %params      = @_;
+  my $transaction = $params{transaction};
+  my $found_broken = 0;
+
+  $::lxdebug->leave_sub and return 0
+    if    !$transaction->[0]->{invoice};
+
+  my @sub_transactions = $self->_group_sub_transactions($transaction);
+
+  for my $sub_transaction (@sub_transactions) {
+    $::lxdebug->leave_sub and return 0
+      if    _is_split_transaction($sub_transaction)
+         || _is_simple_transaction($sub_transaction);
+
+    my $split_side_entries = _get_splitted_side($sub_transaction);
+    my $num_tax_rows;
+    my $num_taxed_rows;
+    for my $entry (@{ $split_side_entries }) {
+      my $is_tax = grep { m/(?:AP_tax|AR_tax)/ } keys %{ $entry->{chartlinks} };
+
+      $num_tax_rows++   if  $is_tax;
+      $num_taxed_rows++ if !$is_tax && $entry->{tax_key} != 0;
+    }
+
+    # now if this has tax rows but NO taxed rows, something is wrong.
+    if ($num_tax_rows > 0 && $num_taxed_rows == 0) {
+      $params{problem}->{type} = 'missing_taxkeys_in_invoices';
+      push @{ $self->{missing_taxkeys_in_invoices} ||= [] }, $params{problem};
+      $found_broken = 1;
+    }
+  }
+
+  $::lxdebug->leave_sub;
+
+  return $found_broken;
+}
+
+# Problemfall: Kreditorenbuchungen, bei denen mit Umsatzsteuerschlüsseln
+# gebucht wurde und Debitorenbuchungen, bei denen mit Vorsteuerschlüsseln
 # gebucht wurde.
 sub _check_trans_ap_ar_wrong_taxkeys {
   $main::lxdebug->enter_sub();
 # gebucht wurde.
 sub _check_trans_ap_ar_wrong_taxkeys {
   $main::lxdebug->enter_sub();
@@ -317,8 +366,8 @@ sub _check_trans_ap_ar_wrong_taxkeys {
 }
 
 # Problemfall: Splitbuchungen, die mehrere Haben- und Sollkonten ansprechen.
 }
 
 # Problemfall: Splitbuchungen, die mehrere Haben- und Sollkonten ansprechen.
-# Aber nur für Debitoren- und Kreditorenbuchungen, weil das bei Einkaufs- und
-# Verkaufsrechnungen hingegen völlig normal ist.
+# Aber nur für Debitoren- und Kreditorenbuchungen, weil das bei Einkaufs- und
+# Verkaufsrechnungen hingegen völlig normal ist.
 sub _check_trans_split_multiple_credit_and_debit {
   $main::lxdebug->enter_sub();
 
 sub _check_trans_split_multiple_credit_and_debit {
   $main::lxdebug->enter_sub();
 
@@ -342,7 +391,7 @@ sub _check_trans_split_multiple_credit_and_debit {
 }
 
 # Problemfall: Buchungen, bei denen Steuersummen nicht mit den Summen
 }
 
 # Problemfall: Buchungen, bei denen Steuersummen nicht mit den Summen
-# übereinstimmen, die nach ausgewähltem Steuerschlüssel hätten auftreten müssen.
+# übereinstimmen, die nach ausgewähltem Steuerschlüssel hätten auftreten müssen.
 sub _check_trans_wrong_taxkeys {
   $main::lxdebug->enter_sub();
 
 sub _check_trans_wrong_taxkeys {
   $main::lxdebug->enter_sub();
 
@@ -410,12 +459,12 @@ sub _check_trans_wrong_taxkeys {
       }
 
       foreach my $entry (@{ $data{$side}->{entries} }) {
       }
 
       foreach my $entry (@{ $data{$side}->{entries} }) {
-        $entry->{actual_tax}     = $form->round_amount(abs($entry->{tax_entry} ? $entry->{tax_entry}->{amount} : 0), 2);
-        $entry->{expected_tax}   = $form->round_amount(abs($entry->{expected_tax}), 2);
-        $entry->{taxkey_error}   =    ( $entry->{taxkey} && !$entry->{tax_entry})
-                                   || (!$entry->{taxkey} &&  $entry->{tax_entry})
-                                   || (abs($entry->{expected_tax} - $entry->{actual_tax}) >= 0.02);
-        $entry->{tax_entry_oid}  = $entry->{tax_entry}->{oid};
+        $entry->{actual_tax}              = $form->round_amount(abs($entry->{tax_entry} ? $entry->{tax_entry}->{amount} : 0), 2);
+        $entry->{expected_tax}            = $form->round_amount(abs($entry->{expected_tax}), 2);
+        $entry->{taxkey_error}            =    ( $entry->{taxkey} && !$entry->{tax_entry})
+                                            || (!$entry->{taxkey} &&  $entry->{tax_entry})
+                                            || (abs($entry->{expected_tax} - $entry->{actual_tax}) >= 0.02);
+        $entry->{tax_entry_acc_trans_id}  = $entry->{tax_entry}->{acc_trans_id};
         delete $entry->{tax_entry};
 
         $entry->{display_amount}       = $form->round_amount(abs($entry->{amount}) * $storno_mult, 2);
         delete $entry->{tax_entry};
 
         $entry->{display_amount}       = $form->round_amount(abs($entry->{amount}) * $storno_mult, 2);
@@ -438,7 +487,7 @@ sub _check_trans_wrong_taxkeys {
 
             my $tax_info = $all_taxes{taxkeys}->{$taxkey};
 
 
             my $tax_info = $all_taxes{taxkeys}->{$taxkey};
 
-            next if ((!$tax_info || (0 == $tax_info->{taxrate} * 1)) && $entry->{tax_entry_oid});
+            next if ((!$tax_info || (0 == $tax_info->{taxrate} * 1)) && $entry->{tax_entry_acc_trans_id});
 
             push @{ $entry->{correct_taxkeys} }, {
               'taxkey'      => $taxkey,
 
             push @{ $entry->{correct_taxkeys} }, {
               'taxkey'      => $taxkey,
@@ -467,16 +516,16 @@ sub _check_trans_wrong_taxkeys {
   return $retval;
 }
 
   return $retval;
 }
 
-# Inaktiver Code für das Erraten möglicher Verteilungen von
-# Steuerschlüsseln. Deaktiviert, weil er exponentiell Zeit
-# benötigt.
+# Inaktiver Code für das Erraten möglicher Verteilungen von
+# Steuerschlüsseln. Deaktiviert, weil er exponentiell Zeit
+# benötigt.
 
 #       if (abs($expected_tax - $data{$side}->{tax_sum}) >= 0.02) {
 #         my @potential_taxkeys = $trans_type eq 'AP' ? (0, 8, 9) : (0, 1, 2, 3);
 
 #         $main::lxdebug->dump(0, "pota", \@potential_taxkeys);
 
 
 #       if (abs($expected_tax - $data{$side}->{tax_sum}) >= 0.02) {
 #         my @potential_taxkeys = $trans_type eq 'AP' ? (0, 8, 9) : (0, 1, 2, 3);
 
 #         $main::lxdebug->dump(0, "pota", \@potential_taxkeys);
 
-#         # Über alle Kombinationen aus Buchungssätzen und potenziellen Steuerschlüsseln
+#         # Über alle Kombinationen aus Buchungssätzen und potenziellen Steuerschlüsseln
 #         # iterieren und jeweils die Summe ermitteln.
 #         my $num_entries    = scalar @{ $data{$side}->{entries} };
 #         my @taxkey_indices = (0) x $num_entries;
 #         # iterieren und jeweils die Summe ermitteln.
 #         my $num_entries    = scalar @{ $data{$side}->{entries} };
 #         my @taxkey_indices = (0) x $num_entries;
@@ -490,7 +539,7 @@ sub _check_trans_wrong_taxkeys {
 #         while ($num_entries == scalar @taxkey_indices) {
 #           my @tax_cache = ();
 
 #         while ($num_entries == scalar @taxkey_indices) {
 #           my @tax_cache = ();
 
-#           # Berechnen der Steuersumme für die aktuell angenommenen Steuerschlüssel.
+#           # Berechnen der Steuersumme für die aktuell angenommenen Steuerschlüssel.
 #           my $tax_sum = 0;
 #           foreach my $i (0 .. $num_entries - 1) {
 #             my $taxkey      = $potential_taxkeys[$taxkey_indices[$i]];
 #           my $tax_sum = 0;
 #           foreach my $i (0 .. $num_entries - 1) {
 #             my $taxkey      = $potential_taxkeys[$taxkey_indices[$i]];
@@ -500,9 +549,9 @@ sub _check_trans_wrong_taxkeys {
 #             $tax_sum       += $tax_cache[$i];
 #           }
 
 #             $tax_sum       += $tax_cache[$i];
 #           }
 
-#           # Entspricht die Steuersumme mit den aktuell angenommenen Steuerschlüsseln
+#           # Entspricht die Steuersumme mit den aktuell angenommenen Steuerschlüsseln
 #           # der verbuchten Steuersumme? Wenn ja, dann ist das eine potenzielle
 #           # der verbuchten Steuersumme? Wenn ja, dann ist das eine potenzielle
-#           # Lösung.
+#           # Lösung.
 #           if (abs($tax_sum - $data{$side}->{tax_sum}) < 0.02) {
 #             push @solutions, {
 #               'taxkeys' => [ @potential_taxkeys[@taxkey_indices] ],
 #           if (abs($tax_sum - $data{$side}->{tax_sum}) < 0.02) {
 #             push @solutions, {
 #               'taxkeys' => [ @potential_taxkeys[@taxkey_indices] ],
@@ -510,8 +559,8 @@ sub _check_trans_wrong_taxkeys {
 #             }
 #           }
 
 #             }
 #           }
 
-#           # Weiterzählen der Steuerschlüsselindices zum Interieren über
-#           # alle möglichen Kombinationen.
+#           # Weiterzählen der Steuerschlüsselindices zum Interieren über
+#           # alle möglichen Kombinationen.
 #           my $i = 0;
 #           while (1) {
 #             $taxkey_indices[$i]++;
 #           my $i = 0;
 #           while (1) {
 #             $taxkey_indices[$i]++;
@@ -552,7 +601,7 @@ sub _check_trans_wrong_taxkeys {
 #             $solution->{rows}->[$i]->{taxdescription} .= ' ' . $form->format_amount(\%myconfig, $tax_entry->{taxrate} * 100) . ' %';
 
 #             push @{ $solution->{changes} }, {
 #             $solution->{rows}->[$i]->{taxdescription} .= ' ' . $form->format_amount(\%myconfig, $tax_entry->{taxrate} * 100) . ' %';
 
 #             push @{ $solution->{changes} }, {
-#               'oid'    => $entry->{oid},
+#               'acc_trans_id'    => $entry->{acc_trans_id},
 #               'taxkey' => $solution->{taxkeys}->[$i],
 #             };
 #           }
 #               'taxkey' => $solution->{taxkeys}->[$i],
 #             };
 #           }
@@ -605,6 +654,8 @@ sub analyze {
 
   my @problems = @{ $self->{problems} };
 
 
   my @problems = @{ $self->{problems} };
 
+  map { $self->{$_} ||= [] } qw(ap_ar_taxkey_problems invoice_inventory_taxkey_problems missing_taxkeys_in_invoices);
+
   if (0 != scalar @{ $self->{ap_ar_taxkey_problems} }) {
     my $problem = {
       'type'        => 'ap_ar_wrong_taxkeys',
   if (0 != scalar @{ $self->{ap_ar_taxkey_problems} }) {
     my $problem = {
       'type'        => 'ap_ar_wrong_taxkeys',
@@ -623,8 +674,18 @@ sub analyze {
     unshift @problems, $problem;
   }
 
     unshift @problems, $problem;
   }
 
+  if (0 != scalar @{ $self->{missing_taxkeys_in_invoices} }) {
+    my $problem = {
+      'type'        => 'missing_taxkeys_in_invoices',
+      'ap_problems' => [ grep { $_->{data}->{module} eq 'ap' } @{ $self->{missing_taxkeys_in_invoices} } ],
+      'ar_problems' => [ grep { $_->{data}->{module} eq 'ar' } @{ $self->{missing_taxkeys_in_invoices} } ],
+    };
+    unshift @problems, $problem;
+  }
+
   $main::lxdebug->leave_sub();
 
   $main::lxdebug->leave_sub();
 
+#  $::lxdebug->dump(0, 'problems:', \@problems);
 
   return @problems;
 }
 
   return @problems;
 }
@@ -638,10 +699,10 @@ sub fix_ap_ar_wrong_taxkeys {
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
 
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
 
-  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+  my $dbh      = $params{dbh} || SL::DB->client->dbh;
 
   my $query    = qq|SELECT 'ap' AS module,
 
   my $query    = qq|SELECT 'ap' AS module,
-                      at.oid, at.trans_id, at.chart_id, at.amount, at.taxkey, at.transdate,
+                      at.acc_trans_id, at.trans_id, at.chart_id, at.amount, at.taxkey, at.transdate,
                       c.link
                     FROM acc_trans at
                     LEFT JOIN chart c ON (at.chart_id = c.id)
                       c.link
                     FROM acc_trans at
                     LEFT JOIN chart c ON (at.chart_id = c.id)
@@ -651,14 +712,14 @@ sub fix_ap_ar_wrong_taxkeys {
                     UNION
 
                     SELECT 'ar' AS module,
                     UNION
 
                     SELECT 'ar' AS module,
-                      at.oid, at.trans_id, at.chart_id, at.amount, at.taxkey, at.transdate,
+                      at.acc_trans_id, at.trans_id, at.chart_id, at.amount, at.taxkey, at.transdate,
                       c.link
                     FROM acc_trans at
                     LEFT JOIN chart c ON (at.chart_id = c.id)
                     WHERE (trans_id IN (SELECT id FROM ar WHERE NOT invoice))
                       AND (taxkey IN (8, 9, 18, 19))
 
                       c.link
                     FROM acc_trans at
                     LEFT JOIN chart c ON (at.chart_id = c.id)
                     WHERE (trans_id IN (SELECT id FROM ar WHERE NOT invoice))
                       AND (taxkey IN (8, 9, 18, 19))
 
-                    ORDER BY trans_id, oid|;
+                    ORDER BY trans_id, acc_trans_id|;
 
   my $sth      = prepare_execute_query($form, $dbh, $query);
   my @transactions;
 
   my $sth      = prepare_execute_query($form, $dbh, $query);
   my @transactions;
@@ -706,36 +767,37 @@ sub fix_ap_ar_wrong_taxkeys {
 
       my %all_taxes = $self->{taxkeys}->get_full_tax_info('transdate' => $non_tax->{transdate});
 
 
       my %all_taxes = $self->{taxkeys}->get_full_tax_info('transdate' => $non_tax->{transdate});
 
-      push @corrections, ({ 'oid'      => $non_tax->{oid},
-                            'taxkey'   => $taxkey_replacements{$non_tax->{taxkey}},
+      push @corrections, ({ 'acc_trans_id' => $non_tax->{acc_trans_id},
+                            'taxkey'       => $taxkey_replacements{$non_tax->{taxkey}},
                           },
                           {
                           },
                           {
-                            'oid'      => $tax->{oid},
-                            'taxkey'   => $taxkey_replacements{$non_tax->{taxkey}},
-                            'chart_id' => $all_taxes{taxkeys}->{ $taxkey_replacements{$non_tax->{taxkey}} }->{taxchart_id},
+                            'acc_trans_id' => $tax->{acc_trans_id},
+                            'taxkey'       => $taxkey_replacements{$non_tax->{taxkey}},
+                            'chart_id'     => $all_taxes{taxkeys}->{ $taxkey_replacements{$non_tax->{taxkey}} }->{taxchart_id},
                           });
     }
   }
 
   if (scalar @corrections) {
                           });
     }
   }
 
   if (scalar @corrections) {
-    my $q_taxkey_only     = qq|UPDATE acc_trans SET taxkey = ? WHERE oid = ?|;
-    my $h_taxkey_only     = prepare_query($form, $dbh, $q_taxkey_only);
-
-    my $q_taxkey_chart_id = qq|UPDATE acc_trans SET taxkey = ?, chart_id = ? WHERE oid = ?|;
-    my $h_taxkey_chart_id = prepare_query($form, $dbh, $q_taxkey_chart_id);
-
-    foreach my $entry (@corrections) {
-      if ($entry->{chart_id}) {
-        do_statement($form, $h_taxkey_chart_id, $q_taxkey_chart_id, $entry->{taxkey}, $entry->{chart_id}, $entry->{oid});
-      } else {
-        do_statement($form, $h_taxkey_only, $q_taxkey_only, $entry->{taxkey}, $entry->{oid});
+    SL::DB->client->with_transaction(sub {
+      my $q_taxkey_only     = qq|UPDATE acc_trans SET taxkey = ? WHERE acc_trans_id = ?|;
+      my $h_taxkey_only     = prepare_query($form, $dbh, $q_taxkey_only);
+
+      my $q_taxkey_chart_id = qq|UPDATE acc_trans SET taxkey = ?, chart_id = ? WHERE acc_trans_id = ?|;
+      my $h_taxkey_chart_id = prepare_query($form, $dbh, $q_taxkey_chart_id);
+
+      foreach my $entry (@corrections) {
+        if ($entry->{chart_id}) {
+          do_statement($form, $h_taxkey_chart_id, $q_taxkey_chart_id, $entry->{taxkey}, $entry->{chart_id}, $entry->{acc_trans_id});
+        } else {
+          do_statement($form, $h_taxkey_only, $q_taxkey_only, $entry->{taxkey}, $entry->{acc_trans_id});
+        }
       }
       }
-    }
-
-    $h_taxkey_only->finish();
-    $h_taxkey_chart_id->finish();
 
 
-    $dbh->commit() unless ($params{dbh});
+      $h_taxkey_only->finish();
+      $h_taxkey_chart_id->finish();
+      1;
+    }) or do { die SL::DB->client->error };
   }
 
   $main::lxdebug->leave_sub();
   }
 
   $main::lxdebug->leave_sub();
@@ -747,12 +809,16 @@ sub fix_invoice_inventory_with_taxkeys {
   my $self     = shift;
   my %params   = @_;
 
   my $self     = shift;
   my %params   = @_;
 
+  # ist nur für bestandsmethode notwendig. bei der Aufwandsmethode
+  # können Warenkonten mit Steuerschlüssel sein (5400 in SKR04)
+  return 0 if $::instance_conf->get_inventory_system eq 'periodic';
+
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
 
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
 
-  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
+  my $dbh      = $params{dbh} || SL::DB->client->dbh;
 
 
-  my $query    = qq|SELECT at.oid, at.*, c.link
+  my $query    = qq|SELECT at.*, c.link
                     FROM acc_trans at
                     LEFT JOIN ar      ON (at.trans_id = ar.id)
                     LEFT JOIN chart c ON (at.chart_id = c.id)
                     FROM acc_trans at
                     LEFT JOIN ar      ON (at.trans_id = ar.id)
                     LEFT JOIN chart c ON (at.chart_id = c.id)
@@ -760,13 +826,13 @@ sub fix_invoice_inventory_with_taxkeys {
 
                     UNION
 
 
                     UNION
 
-                    SELECT at.oid, at.*, c.link
+                    SELECT at.*, c.link
                     FROM acc_trans at
                     LEFT JOIN ap      ON (at.trans_id = ap.id)
                     LEFT JOIN chart c ON (at.chart_id = c.id)
                     WHERE (ap.invoice)
 
                     FROM acc_trans at
                     LEFT JOIN ap      ON (at.trans_id = ap.id)
                     LEFT JOIN chart c ON (at.chart_id = c.id)
                     WHERE (ap.invoice)
 
-                    ORDER BY trans_id, oid|;
+                    ORDER BY trans_id, acc_trans_id|;
 
   my $sth      = prepare_execute_query($form, $dbh, $query);
   my @transactions;
 
   my $sth      = prepare_execute_query($form, $dbh, $query);
   my @transactions;
@@ -792,23 +858,23 @@ sub fix_invoice_inventory_with_taxkeys {
 
       foreach my $entry (@{ $sub_transaction }) {
         next if ($entry->{taxkey} == 0);
 
       foreach my $entry (@{ $sub_transaction }) {
         next if ($entry->{taxkey} == 0);
-        push @corrections, $entry->{oid};
+        push @corrections, $entry->{acc_trans_id};
       }
     }
   }
 
   if (@corrections) {
       }
     }
   }
 
   if (@corrections) {
-    $query = qq|UPDATE acc_trans SET taxkey = 0 WHERE oid = ?|;
-    $sth   = prepare_query($form, $dbh, $query);
+    SL::DB->client->with_transaction(sub {
+      $query = qq|UPDATE acc_trans SET taxkey = 0 WHERE acc_trans_id = ?|;
+      $sth   = prepare_query($form, $dbh, $query);
 
 
-    foreach my $oid (@corrections) {
-      do_statement($form, $sth, $query, $oid);
-    }
-
-    $sth->finish();
+      foreach my $acc_trans_id (@corrections) {
+        do_statement($form, $sth, $query, $acc_trans_id);
+      }
 
 
-    $dbh->commit() unless ($params{dbh});
-#     $dbh->rollback();
+      $sth->finish();
+      1;
+    }) or do { die SL::DB->client->error };
   }
 
   $main::lxdebug->leave_sub();
   }
 
   $main::lxdebug->leave_sub();
@@ -825,41 +891,41 @@ sub fix_wrong_taxkeys {
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
 
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
 
-  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
-
-  my $q_taxkey_only  = qq|UPDATE acc_trans SET taxkey = ? WHERE oid = ?|;
-  my $h_taxkey_only  = prepare_query($form, $dbh, $q_taxkey_only);
+  my $dbh      = $params{dbh} || SL::DB->client->dbh;
 
 
-  my $q_taxkey_chart = qq|UPDATE acc_trans SET taxkey = ?, chart_id = ? WHERE oid = ?|;
-  my $h_taxkey_chart = prepare_query($form, $dbh, $q_taxkey_chart);
+  SL::DB->client->with_transaction(sub {
+    my $q_taxkey_only  = qq|UPDATE acc_trans SET taxkey = ? WHERE acc_trans_id = ?|;
+    my $h_taxkey_only  = prepare_query($form, $dbh, $q_taxkey_only);
 
 
-  my $q_transdate    = qq|SELECT transdate FROM acc_trans WHERE oid = ?|;
-  my $h_transdate    = prepare_query($form, $dbh, $q_transdate);
+    my $q_taxkey_chart = qq|UPDATE acc_trans SET taxkey = ?, chart_id = ? WHERE acc_trans_id = ?|;
+    my $h_taxkey_chart = prepare_query($form, $dbh, $q_taxkey_chart);
 
 
-  foreach my $fix (@{ $params{fixes} }) {
-    next unless ($fix->{oid});
+    my $q_transdate    = qq|SELECT transdate FROM acc_trans WHERE acc_trans_id = ?|;
+    my $h_transdate    = prepare_query($form, $dbh, $q_transdate);
 
 
-    do_statement($form, $h_taxkey_only, $q_taxkey_only, conv_i($fix->{taxkey}), conv_i($fix->{oid}));
+    foreach my $fix (@{ $params{fixes} }) {
+      next unless ($fix->{acc_trans_id});
 
 
-    next unless ($fix->{tax_entry_oid});
+      do_statement($form, $h_taxkey_only, $q_taxkey_only, conv_i($fix->{taxkey}), conv_i($fix->{acc_trans_id}));
 
 
-    do_statement($form, $h_transdate, $q_transdate, conv_i($fix->{tax_entry_oid}));
-    my ($transdate) = $h_transdate->fetchrow_array();
+      next unless ($fix->{tax_entry_acc_trans_id});
 
 
-    my %all_taxes = $self->{taxkeys}->get_full_tax_info('transdate' => $transdate);
-    my $tax_info  = $all_taxes{taxkeys}->{ $fix->{taxkey} };
+      do_statement($form, $h_transdate, $q_transdate, conv_i($fix->{tax_entry_acc_trans_id}));
+      my ($transdate) = $h_transdate->fetchrow_array();
 
 
-    next unless ($tax_info);
+      my %all_taxes = $self->{taxkeys}->get_full_tax_info('transdate' => $transdate);
+      my $tax_info  = $all_taxes{taxkeys}->{ $fix->{taxkey} };
 
 
-    do_statement($form, $h_taxkey_chart, $q_taxkey_chart, conv_i($fix->{taxkey}), conv_i($tax_info->{taxchart_id}), conv_i($fix->{tax_entry_oid}));
-  }
+      next unless ($tax_info);
 
 
-  $h_taxkey_only->finish();
-  $h_taxkey_chart->finish();
-  $h_transdate->finish();
+      do_statement($form, $h_taxkey_chart, $q_taxkey_chart, conv_i($fix->{taxkey}), conv_i($tax_info->{taxchart_id}), conv_i($fix->{tax_entry_acc_trans_id}));
+    }
 
 
-#   $dbh->rollback();
-  $dbh->commit() unless ($params{dbh});
+    $h_taxkey_only->finish();
+    $h_taxkey_chart->finish();
+    $h_transdate->finish();
+    1;
+  }) or do { die SL::DB->client->error };
 
   $main::lxdebug->leave_sub();
 }
 
   $main::lxdebug->leave_sub();
 }
@@ -875,19 +941,19 @@ sub delete_transaction {
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
 
   my $myconfig = \%main::myconfig;
   my $form     = $main::form;
 
-  my $dbh      = $params{dbh} || $form->get_standard_dbh($myconfig);
-
-  do_query($form, $dbh, qq|UPDATE ar SET storno_id = NULL WHERE storno_id = ?|, conv_i($params{trans_id}));
-  do_query($form, $dbh, qq|UPDATE ap SET storno_id = NULL WHERE storno_id = ?|, conv_i($params{trans_id}));
-  do_query($form, $dbh, qq|UPDATE gl SET storno_id = NULL WHERE storno_id = ?|, conv_i($params{trans_id}));
+  my $dbh      = $params{dbh} || SL::DB->client->dbh;
 
 
-  do_query($form, $dbh, qq|DELETE FROM ar        WHERE id       = ?|, conv_i($params{trans_id}));
-  do_query($form, $dbh, qq|DELETE FROM ap        WHERE id       = ?|, conv_i($params{trans_id}));
-  do_query($form, $dbh, qq|DELETE FROM gl        WHERE id       = ?|, conv_i($params{trans_id}));
-  do_query($form, $dbh, qq|DELETE FROM acc_trans WHERE trans_id = ?|, conv_i($params{trans_id}));
+  SL::DB->client->with_transaction(sub {
+    do_query($form, $dbh, qq|UPDATE ar SET storno_id = NULL WHERE storno_id = ?|, conv_i($params{trans_id}));
+    do_query($form, $dbh, qq|UPDATE ap SET storno_id = NULL WHERE storno_id = ?|, conv_i($params{trans_id}));
+    do_query($form, $dbh, qq|UPDATE gl SET storno_id = NULL WHERE storno_id = ?|, conv_i($params{trans_id}));
 
 
-#   $dbh->rollback();
-  $dbh->commit() unless ($params{dbh});
+    do_query($form, $dbh, qq|DELETE FROM ar        WHERE id       = ?|, conv_i($params{trans_id}));
+    do_query($form, $dbh, qq|DELETE FROM ap        WHERE id       = ?|, conv_i($params{trans_id}));
+    do_query($form, $dbh, qq|DELETE FROM gl        WHERE id       = ?|, conv_i($params{trans_id}));
+    do_query($form, $dbh, qq|DELETE FROM acc_trans WHERE trans_id = ?|, conv_i($params{trans_id}));
+    1;
+  }) or do { die SL::DB->client->error };
 
   $main::lxdebug->leave_sub();
 }
 
   $main::lxdebug->leave_sub();
 }