Projekt

Allgemein

Profil

Herunterladen (7,52 KB) Statistiken
| Zweig: | Markierung: | Revision:
18931692 Niclas Zimmermann
# @tag: tax_constraints
# @description: Setzt Fremdschlüssel und andere constraints auf die Tabellen tax und taxkeys
32ddb71c Niclas Zimmermann
# @depends: release_3_0_0 charts_without_taxkey
347f2cff Moritz Bunkus
package SL::DBUpgrade2::tax_constraints;
18931692 Niclas Zimmermann
use strict;
347f2cff Moritz Bunkus
use utf8;
18931692 Niclas Zimmermann
347f2cff Moritz Bunkus
use parent qw(SL::DBUpgrade2::Base);
18931692 Niclas Zimmermann
347f2cff Moritz Bunkus
sub run {
my ($self) = @_;
18931692 Niclas Zimmermann
32ddb71c Niclas Zimmermann
#CHECK CONSISTANCY OF tax
18931692 Niclas Zimmermann
#update tax.rate and tax.taxdescription in order to set later NOT NULL constraints
32ddb71c Niclas Zimmermann
my $query= <<SQL;
UPDATE tax SET rate=0 WHERE rate IS NULL;
UPDATE tax SET taxdescription='-' WHERE COALESCE(taxdescription, '') = '';
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
#check automatic tax accounts
$query= <<SQL;
32ddb71c Niclas Zimmermann
SELECT count(*) FROM tax WHERE chart_id NOT IN (SELECT id FROM chart);
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
my ($invalid_tax_account) = $self->dbh->selectrow_array($query);
32ddb71c Niclas Zimmermann
18931692 Niclas Zimmermann
if ($invalid_tax_account > 0){
#list all invalid tax accounts
$query = <<SQL;
32ddb71c Niclas Zimmermann
SELECT id,
taxkey,
taxdescription,
round(rate * 100, 2) AS rate
FROM tax WHERE chart_id NOT IN (SELECT id FROM chart);
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
my $sth = $self->dbh->prepare($query);
$sth->execute || $::form->dberror($query);
18931692 Niclas Zimmermann
347f2cff Moritz Bunkus
$::form->{TAX} = [];
18931692 Niclas Zimmermann
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
347f2cff Moritz Bunkus
push @{ $::form->{TAX} }, $ref;
18931692 Niclas Zimmermann
}
$sth->finish;

347f2cff Moritz Bunkus
$::form->{invalid_tax_account} = 1;
18931692 Niclas Zimmermann
print_error_message();
return 0;
32ddb71c Niclas Zimmermann
}
18931692 Niclas Zimmermann
#check entry tax.taxkey of NOT NULL
$query= <<SQL;
32ddb71c Niclas Zimmermann
SELECT count(*) FROM tax WHERE taxkey IS NULL;
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
my ($taxkey_is_null) = $self->dbh->selectrow_array($query);
32ddb71c Niclas Zimmermann
18931692 Niclas Zimmermann
if ($taxkey_is_null > 0){
#list all invalid tax accounts
$query = <<SQL;
32ddb71c Niclas Zimmermann
SELECT id,
taxdescription,
round(rate * 100, 2) AS rate,
(SELECT accno FROM chart WHERE id = chart_id) AS taxnumber,
(SELECT description FROM chart WHERE id = chart_id) AS account_description
FROM tax
WHERE taxkey IS NULL;
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
my $sth = $self->dbh->prepare($query);
$sth->execute || $::form->dberror($query);
18931692 Niclas Zimmermann
347f2cff Moritz Bunkus
$::form->{TAX} = [];
18931692 Niclas Zimmermann
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
347f2cff Moritz Bunkus
push @{ $::form->{TAX} }, $ref;
18931692 Niclas Zimmermann
}
$sth->finish;

347f2cff Moritz Bunkus
$::form->{taxkey_is_null} = 1;
18931692 Niclas Zimmermann
print_error_message();
return 0;
32ddb71c Niclas Zimmermann
}
#END CHECK OF tax
18931692 Niclas Zimmermann
32ddb71c Niclas Zimmermann
#CHECK CONSISTANCY OF taxkeys
18931692 Niclas Zimmermann
#delete invalide entries in taxkeys
$query= <<SQL;
32ddb71c Niclas Zimmermann
DELETE FROM taxkeys
WHERE chart_id IS NULL
OR chart_id NOT IN (SELECT id FROM chart)
OR startdate IS NULL;
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
32ddb71c Niclas Zimmermann
#There are 3 cases for taxkeys.tax_id and taxkeys.taxkey_id
#taxkeys.taxkey_id is NULL and taxkeys.tax_id is not NULL:
18931692 Niclas Zimmermann
#Update taxkeys.taxkey_id with tax.taxkey
$query= <<SQL;
32ddb71c Niclas Zimmermann
UPDATE taxkeys
SET taxkey_id = (SELECT t.taxkey
FROM tax t
18931692 Niclas Zimmermann
WHERE t.id=tax_id)
32ddb71c Niclas Zimmermann
WHERE taxkey_id IS NULL
AND tax_id IS NOT NULL;
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
32ddb71c Niclas Zimmermann
#taxkeys.taxkey_id and taxkeys.tax_id are NULL:

18931692 Niclas Zimmermann
#Set taxkey 0 in this case:
$query= <<SQL;
32ddb71c Niclas Zimmermann
UPDATE taxkeys
SET taxkey_id = 0, tax_id = (SELECT id FROM tax WHERE taxkey=0)
WHERE taxkey_id IS NULL
AND tax_id IS NULL;
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
32ddb71c Niclas Zimmermann
#Last case where taxkeys.taxkey_id is not null and taxkeys.tax_id is null
18931692 Niclas Zimmermann
#If such entries exist we update with an entry in tax where tax.rate=0
#and tax.taxkey corresponds to taxkeys.taxkey_id.
32ddb71c Niclas Zimmermann
#If no entry in tax with rate 0 and taxkey taxkeys.taxkey_id exists
18931692 Niclas Zimmermann
#we create one.
$query= <<SQL;
32ddb71c Niclas Zimmermann
SELECT DISTINCT taxkey_id
FROM taxkeys
WHERE taxkey_id IS NOT NULL
AND tax_id IS NULL;
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
my $sth = $self->dbh->prepare($query);
$sth->execute || $::form->dberror($query);
18931692 Niclas Zimmermann
347f2cff Moritz Bunkus
$::form->{TAXID} = [];
18931692 Niclas Zimmermann
my $rowcount = 0;
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
347f2cff Moritz Bunkus
push @{ $::form->{TAXID} }, $ref;
18931692 Niclas Zimmermann
$rowcount++;
}
$sth->finish;
32ddb71c Niclas Zimmermann
18931692 Niclas Zimmermann
my $insertquery;
my $updatequery;
my $tax_id;
for my $i (0 .. $rowcount-1){
$query= qq|
347f2cff Moritz Bunkus
SELECT id FROM tax WHERE rate = 0 and taxkey=| . $::form->{TAXID}[$i]->{taxkey_id} . qq| LIMIT 1
32ddb71c Niclas Zimmermann
|;
347f2cff Moritz Bunkus
($tax_id) = $self->dbh->selectrow_array($query);
18931692 Niclas Zimmermann
if ( not $tax_id ){
$insertquery=qq|
347f2cff Moritz Bunkus
INSERT INTO tax (rate, taxdescription, taxkey) VALUES (0, '| . $::locale->text('0% tax with taxkey') . $::form->{TAXID}[$i]->{taxkey_id} . $::locale->text('. Automatically generated.') .
qq|', | . $::form->{TAXID}[$i]->{taxkey_id} . qq|);
18931692 Niclas Zimmermann
|;
347f2cff Moritz Bunkus
$self->db_query($insertquery);
($tax_id) = $self->dbh->selectrow_array($query);
$tax_id || $::form->dberror($query);
18931692 Niclas Zimmermann
}
$updatequery = qq|
347f2cff Moritz Bunkus
UPDATE taxkeys SET tax_id= | . $tax_id . qq| WHERE taxkey_id = | . $::form->{TAXID}[$i]->{taxkey_id} . qq| AND tax_id IS NULL
18931692 Niclas Zimmermann
|;
347f2cff Moritz Bunkus
$self->db_query($updatequery);
18931692 Niclas Zimmermann
}

32ddb71c Niclas Zimmermann
#The triple taxkey_id, chart_id, startdate in taxkeys has to be unique
18931692 Niclas Zimmermann
#Select these entries:
$query= <<SQL;
32ddb71c Niclas Zimmermann
SELECT DISTINCT tk1.chart_id AS chart_id, tk1.startdate AS startdate
FROM taxkeys tk1
WHERE (SELECT count(*)
FROM taxkeys tk2
WHERE tk2.chart_id = tk1.chart_id
AND tk2.startdate = tk1.startdate) > 1;
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
$sth = $self->dbh->prepare($query);
$sth->execute || $::form->dberror($query);
18931692 Niclas Zimmermann
347f2cff Moritz Bunkus
$::form->{TAXKEYS} = [];
18931692 Niclas Zimmermann
$rowcount = 0;
while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
347f2cff Moritz Bunkus
push @{ $::form->{TAXKEYS} }, $ref;
18931692 Niclas Zimmermann
$rowcount++;
}
$sth->finish;

for my $i (0 .. $rowcount-1){
1b960273 Moritz Bunkus
$query= <<SQL;
32ddb71c Niclas Zimmermann
DELETE FROM taxkeys tk1
1b960273 Moritz Bunkus
WHERE (tk1.chart_id = ?)
AND (tk1.startdate = ?)
AND (tk1.id <> (
SELECT id
FROM taxkeys
WHERE (chart_id = ?)
AND (startdate = ?)
LIMIT 1))
SQL
18931692 Niclas Zimmermann
1b960273 Moritz Bunkus
$self->db_query($query, bind => [ ($::form->{TAXKEYS}[$i]->{chart_id}, $::form->{TAXKEYS}[$i]->{startdate}) x 2 ]);
18931692 Niclas Zimmermann
}

32ddb71c Niclas Zimmermann
#END CHECK OF taxkeys
18931692 Niclas Zimmermann
32ddb71c Niclas Zimmermann
#ADD CONSTRAINTS:
#Now the database is consistent, so we can add constraints:
18931692 Niclas Zimmermann
#Crate NOT NULL constraint for tax.rate with default value 0
$query= <<SQL;
32ddb71c Niclas Zimmermann
ALTER TABLE tax ALTER COLUMN rate SET NOT NULL;
ALTER TABLE tax ALTER COLUMN rate SET DEFAULT 0;
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
#Create NOT NULL constraint for tax.description
$query= <<SQL;
32ddb71c Niclas Zimmermann
ALTER TABLE tax ALTER COLUMN taxdescription SET NOT NULL;
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
#Create foreign key for tax.chart_id to chart.id
$query= <<SQL;
32ddb71c Niclas Zimmermann
ALTER TABLE tax ADD FOREIGN KEY (chart_id) REFERENCES chart(id);
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
$self->db_query($query);
32ddb71c Niclas Zimmermann
18931692 Niclas Zimmermann
#Create NOT NULL constraint for tax.taxkey
$query= <<SQL;
32ddb71c Niclas Zimmermann
ALTER TABLE tax ALTER COLUMN taxkey SET NOT NULL;
18931692 Niclas Zimmermann
SQL

347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
#Create NOT NULL constraint for taxkey.chart_id and foreign key for taxkey.chart_id
$query= <<SQL;
32ddb71c Niclas Zimmermann
ALTER TABLE taxkeys ALTER COLUMN chart_id SET NOT NULL;
ALTER TABLE taxkeys ADD FOREIGN KEY (chart_id) REFERENCES chart(id);
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
#Create NOT NULL constraint for taxkey.startdate
$query= <<SQL;
32ddb71c Niclas Zimmermann
ALTER TABLE taxkeys ALTER COLUMN startdate SET NOT NULL;
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
#Create NOT NULL constraint for taxkey.taxkey_id
$query= <<SQL;
32ddb71c Niclas Zimmermann
ALTER TABLE taxkeys ALTER COLUMN taxkey_id SET NOT NULL;
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
#Create NOT NULL constraint for taxkey.tax_id
$query= <<SQL;
32ddb71c Niclas Zimmermann
ALTER TABLE taxkeys ALTER COLUMN tax_id SET NOT NULL;
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
$self->db_query($query);
18931692 Niclas Zimmermann
#The triple chart_id, taxkey_id, startdate should be unique:
$query= <<SQL;
32ddb71c Niclas Zimmermann
CREATE UNIQUE INDEX taxkeys_chartid_startdate ON taxkeys(chart_id, startdate);
18931692 Niclas Zimmermann
SQL
32ddb71c Niclas Zimmermann
347f2cff Moritz Bunkus
$self->db_query($query);
32ddb71c Niclas Zimmermann
#ALL CONSTRAINTS WERE ADDED
18931692 Niclas Zimmermann
return 1;
347f2cff Moritz Bunkus
} # end run
18931692 Niclas Zimmermann

sub print_error_message {
347f2cff Moritz Bunkus
print $::form->parse_html_template("dbupgrade/tax_constraints");
18931692 Niclas Zimmermann
}

347f2cff Moritz Bunkus
1;