Datenbankupgradescript zur Behebung falscher Steuerschlüssel in acc_trans bei Einkauf...
authorMoritz Bunkus <m.bunkus@linet-services.de>
Tue, 26 Jan 2010 10:22:51 +0000 (11:22 +0100)
committerMoritz Bunkus <m.bunkus@linet-services.de>
Fri, 5 Feb 2010 16:03:37 +0000 (17:03 +0100)
Frühere Lx-Office-Versionen hatten einen Bug beim Buchen von
Einkaufsrechnungen, bei denen falsche Steuerschlüssel in acc_trans
geschrieben wurden. Dieses Script behebt diese falschen Einträge.

locale/de/all
locale/de/fix_acc_trans_ap_taxkey_bug [new file with mode: 0644]
sql/Pg-upgrade2/fix_acc_trans_ap_taxkey_bug.pl [new file with mode: 0644]

index 8173d6a..305a847 100644 (file)
@@ -1080,6 +1080,7 @@ $self->{texts} = {
   'Number missing in Row'       => 'Nummer fehlt in Zeile',
   'Number of bins'              => 'Anzahl Lagerpl&auml;tze',
   'Number of copies'            => 'Anzahl Kopien',
+  'Number of entries changed: #1' => 'Anzahl geänderter Einträge: #1',
   'Number of new bins'          => 'Anzahl neuer Lagerpl&auml;tze',
   'Number pages'                => 'Seiten nummerieren',
   'Number variables: \'PRECISION=n\' forces numbers to be shown with exactly n decimal places.' => 'Zahlenvariablen: Mit \'PRECISION=n\' erzwingt man, dass Zahlen mit n Nachkommastellen formatiert werden.',
diff --git a/locale/de/fix_acc_trans_ap_taxkey_bug b/locale/de/fix_acc_trans_ap_taxkey_bug
new file mode 100644 (file)
index 0000000..31846ea
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/perl
+
+$self->{texts} = {
+  'Database update error:'      => 'Fehler beim Datenbankupgrade:',
+  'Number of entries changed: #1' => 'Anzahl geänderter Einträge: #1',
+};
+
+$self->{subs} = {
+  'do_query'                    => 'do_query',
+  'do_update'                   => 'do_update',
+  'mydberror'                   => 'mydberror',
+};
+
+1;
diff --git a/sql/Pg-upgrade2/fix_acc_trans_ap_taxkey_bug.pl b/sql/Pg-upgrade2/fix_acc_trans_ap_taxkey_bug.pl
new file mode 100644 (file)
index 0000000..a2e70f9
--- /dev/null
@@ -0,0 +1,108 @@
+# @tag: fix_acc_trans_ap_taxkey_bug
+# @description: Korrektur falscher Steuerschlüssel in acc_trans bei Eingangsrechnungen
+# @depends: release_2_6_0
+
+use strict;
+
+die "This script cannot be run from the command line." unless $::form;
+
+sub mydberror {
+  my $msg = shift;
+  die $dbup_locale->text("Database update error:") . "<br>$msg<br>" . $DBI::errstr;
+}
+
+sub do_query {
+  my $query    = shift;
+  my $may_fail = shift;
+
+  if (!$dbh->do($query)) {
+    mydberror($query) unless $may_fail;
+    $dbh->rollback();
+    $dbh->begin_work();
+  }
+}
+
+sub do_update {
+  my $q_find = <<SQL;
+    SELECT * FROM (
+      SELECT
+        -- Einige Felder zum Debuggen:
+        ap.id, c.accno, c.description AS chartdescription,
+        -- Felder, die zum eigentlichen Vergleich und zum spaeteren Update
+        -- benoetigt werden:
+        ac.acc_trans_id, ac.taxkey AS actual_taxkey,
+        -- Zum Rechnungsdatum gueltigen Steuerschluessel fuer Konto auslesen:
+        (SELECT tk.taxkey_id
+         FROM taxkeys tk
+         WHERE (tk.chart_id = c.id)
+           AND (tk.startdate <= ap.transdate)
+         ORDER BY tk.startdate DESC
+         LIMIT 1) AS wanted_taxkey
+        FROM acc_trans ac
+        LEFT JOIN ap ON (ac.trans_id = ap.id)
+        LEFT JOIN chart c ON (ac.chart_id = c.id)
+        WHERE
+          -- Nur Einkaufsrechnungen, aber keine Kreditorenbuchungen betrachten.
+              (ap.id IS NOT NULL)
+          AND ap.invoice
+          -- Nur Eintraege betrachten, die Konten bebuchen, die fuer die
+          -- jeweils aktuelle Rechnung in der dazugehoerigen Buchungsgruppe
+          -- angesprochen werden. Die Buchungsgruppen sind all diejenigen,
+          -- die in der Rechnung in mindestens einer Position ueber die
+          -- Parts verlinkt sind.
+          AND (ac.chart_id IN (
+                -- Teil 1: Aufwandskonto der Buchungsgruppe fuer die in der
+                -- aktuellen Rechnung ausgewaehlte Steuerzone
+                SELECT
+                  CASE
+                    WHEN ap.taxzone_id = 0 THEN bg.expense_accno_id_0
+                    WHEN ap.taxzone_id = 1 THEN bg.expense_accno_id_1
+                    WHEN ap.taxzone_id = 2 THEN bg.expense_accno_id_2
+                    ELSE                        bg.expense_accno_id_3
+                  END
+                FROM invoice i
+                LEFT JOIN parts p ON (i.parts_id = p.id)
+                LEFT JOIN buchungsgruppen bg ON (p.buchungsgruppen_id = bg.id)
+                WHERE (i.trans_id = ap.id)
+
+                UNION
+
+                -- Teil 2: Inventarkonto der Buchungsgruppe fuer Nicht-Dienstleistungen
+                SELECT bg.inventory_accno_id
+                FROM invoice i
+                LEFT JOIN parts p ON (i.parts_id = p.id)
+                LEFT JOIN buchungsgruppen bg ON (p.buchungsgruppen_id = bg.id)
+                WHERE (i.trans_id = ap.id)
+                  AND (COALESCE(p.inventory_accno_id, 0) <> 0)
+              ))
+        ORDER BY ap.id
+      ) AS the_query
+    WHERE the_query.actual_taxkey <> the_query.wanted_taxkey
+SQL
+
+  my $q_change = <<SQL;
+    UPDATE acc_trans
+    SET taxkey = ?
+    WHERE acc_trans_id = ?
+SQL
+
+  my $h_find   = $dbh->prepare($q_find)   || mydberror($q_find);
+  my $h_change = $dbh->prepare($q_change) || mydberror($q_change);
+
+  $h_find->execute() || mydberror($q_find);
+
+  my $num_changed = 0;
+
+  while (my $ref = $h_find->fetchrow_hashref()) {
+    # $::lxdebug->dump(0, "ref", $ref);
+    $h_change->execute($ref->{wanted_taxkey}, $ref->{acc_trans_id}) || mydberror($q_change);
+    $num_changed++;
+  }
+
+  $h_find->finish();
+  $h_change->finish();
+
+  print $dbup_locale->text('Number of entries changed: #1', $num_changed) . "<br/>\n";
+}
+
+do_update();