'Number missing in Row' => 'Nummer fehlt in Zeile',
'Number of bins' => 'Anzahl Lagerplätze',
'Number of copies' => 'Anzahl Kopien',
+ 'Number of entries changed: #1' => 'Anzahl geänderter Einträge: #1',
'Number of new bins' => 'Anzahl neuer Lagerplä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.',
--- /dev/null
+# @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();