Merge branch 'master' of vc.linet-services.de:public/lx-office-erp
[kivitendo-erp.git] / sql / Pg-upgrade2 / fix_acc_trans_ap_taxkey_bug.pl
1 # @tag: fix_acc_trans_ap_taxkey_bug
2 # @description: Korrektur falscher Steuerschlüssel in acc_trans bei Eingangsrechnungen
3 # @depends: release_2_6_0
4
5 use strict;
6
7 die "This script cannot be run from the command line." unless $::form;
8
9 sub mydberror {
10   my $msg = shift;
11   die $dbup_locale->text("Database update error:") . "<br>$msg<br>" . $DBI::errstr;
12 }
13
14 sub do_query {
15   my $query    = shift;
16   my $may_fail = shift;
17
18   if (!$dbh->do($query)) {
19     mydberror($query) unless $may_fail;
20     $dbh->rollback();
21     $dbh->begin_work();
22   }
23 }
24
25 sub do_update {
26   my $q_find = <<SQL;
27     SELECT * FROM (
28       SELECT
29         -- Einige Felder zum Debuggen:
30         ap.id, c.accno, c.description AS chartdescription,
31         -- Felder, die zum eigentlichen Vergleich und zum spaeteren Update
32         -- benoetigt werden:
33         ac.acc_trans_id, ac.taxkey AS actual_taxkey,
34         -- Zum Rechnungsdatum gueltigen Steuerschluessel fuer Konto auslesen:
35         (SELECT tk.taxkey_id
36          FROM taxkeys tk
37          WHERE (tk.chart_id = c.id)
38            AND (tk.startdate <= ap.transdate)
39          ORDER BY tk.startdate DESC
40          LIMIT 1) AS wanted_taxkey
41         FROM acc_trans ac
42         LEFT JOIN ap ON (ac.trans_id = ap.id)
43         LEFT JOIN chart c ON (ac.chart_id = c.id)
44         WHERE
45           -- Nur Einkaufsrechnungen, aber keine Kreditorenbuchungen betrachten.
46               (ap.id IS NOT NULL)
47           AND ap.invoice
48           -- Nur Eintraege betrachten, die Konten bebuchen, die fuer die
49           -- jeweils aktuelle Rechnung in der dazugehoerigen Buchungsgruppe
50           -- angesprochen werden. Die Buchungsgruppen sind all diejenigen,
51           -- die in der Rechnung in mindestens einer Position ueber die
52           -- Parts verlinkt sind.
53           AND (ac.chart_id IN (
54                 -- Teil 1: Aufwandskonto der Buchungsgruppe fuer die in der
55                 -- aktuellen Rechnung ausgewaehlte Steuerzone
56                 SELECT
57                   CASE
58                     WHEN ap.taxzone_id = 0 THEN bg.expense_accno_id_0
59                     WHEN ap.taxzone_id = 1 THEN bg.expense_accno_id_1
60                     WHEN ap.taxzone_id = 2 THEN bg.expense_accno_id_2
61                     ELSE                        bg.expense_accno_id_3
62                   END
63                 FROM invoice i
64                 LEFT JOIN parts p ON (i.parts_id = p.id)
65                 LEFT JOIN buchungsgruppen bg ON (p.buchungsgruppen_id = bg.id)
66                 WHERE (i.trans_id = ap.id)
67
68                 UNION
69
70                 -- Teil 2: Inventarkonto der Buchungsgruppe fuer Nicht-Dienstleistungen
71                 SELECT bg.inventory_accno_id
72                 FROM invoice i
73                 LEFT JOIN parts p ON (i.parts_id = p.id)
74                 LEFT JOIN buchungsgruppen bg ON (p.buchungsgruppen_id = bg.id)
75                 WHERE (i.trans_id = ap.id)
76                   AND (COALESCE(p.inventory_accno_id, 0) <> 0)
77               ))
78         ORDER BY ap.id
79       ) AS the_query
80     WHERE the_query.actual_taxkey <> the_query.wanted_taxkey
81 SQL
82
83   my $q_change = <<SQL;
84     UPDATE acc_trans
85     SET taxkey = ?
86     WHERE acc_trans_id = ?
87 SQL
88
89   my $h_find   = $dbh->prepare($q_find)   || mydberror($q_find);
90   my $h_change = $dbh->prepare($q_change) || mydberror($q_change);
91
92   $h_find->execute() || mydberror($q_find);
93
94   my $num_changed = 0;
95
96   while (my $ref = $h_find->fetchrow_hashref()) {
97     # $::lxdebug->dump(0, "ref", $ref);
98     $h_change->execute($ref->{wanted_taxkey}, $ref->{acc_trans_id}) || mydberror($q_change);
99     $num_changed++;
100   }
101
102   $h_find->finish();
103   $h_change->finish();
104
105   print $dbup_locale->text('Number of entries changed: #1', $num_changed) . "<br/>\n";
106 }
107
108 do_update();
109 return 1;
110