Steuerzonen und Buchungsgruppen bearbeiten
authorNiclas Zimmermann <niclas@kivitendo-premium.de>
Thu, 18 Jul 2013 12:05:09 +0000 (14:05 +0200)
committerG. Richardson <information@kivitendo-premium.de>
Mon, 4 Aug 2014 15:31:39 +0000 (17:31 +0200)
Nachdem man Steuerzonen und Buchungsgruppen auf Datenbankebene
bearbeiten kann, ist jetzt auch eine Bearbeitung an der Ober-
fläche möglich.

Alter Code, der für die Anzeige/Bearbeitung/Erstellung von
Buchungsgruppen entwickelt wurde hat nicht mehr funktioniert
und wurde vollständig ersetzt.

22 files changed:
SL/AM.pm
SL/Controller/Buchungsgruppen.pm [new file with mode: 0644]
SL/Controller/CustomVariableConfig.pm
SL/Controller/Taxzones.pm [new file with mode: 0644]
SL/DB/Buchungsgruppe.pm
SL/DB/Manager/TaxZone.pm [new file with mode: 0644]
SL/DB/Manager/TaxzoneChart.pm [new file with mode: 0644]
SL/DB/MetaSetup/Buchungsgruppe.pm
SL/DB/MetaSetup/TaxZone.pm
SL/DB/TaxZone.pm
SL/DB/TaxzoneChart.pm
bin/mozilla/am.pl
locale/de/all
menus/erp.ini
sql/Pg-upgrade2/taxzone_default_id.sql [new file with mode: 0644]
sql/Pg-upgrade2/taxzone_sortkey.pl [new file with mode: 0644]
templates/webpages/am/buchungsgruppe_header.html [deleted file]
templates/webpages/am/buchungsgruppe_list.html [deleted file]
templates/webpages/buchungsgruppen/form.html [new file with mode: 0644]
templates/webpages/buchungsgruppen/list.html [new file with mode: 0644]
templates/webpages/taxzones/form.html [new file with mode: 0644]
templates/webpages/taxzones/list.html [new file with mode: 0644]

index c18cfd7..acae102 100644 (file)
--- a/SL/AM.pm
+++ b/SL/AM.pm
@@ -739,205 +739,6 @@ sub delete_language {
   $main::lxdebug->leave_sub();
 }
 
-
-sub buchungsgruppe {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  # connect to database
-  my $dbh = $form->dbconnect($myconfig);
-  # TODO: extract information about income/expense accounts from new table taxzone_chart
-  my $query = qq|SELECT id, description,
-                 inventory_accno_id,
-                 (SELECT accno FROM chart WHERE id = inventory_accno_id) AS inventory_accno
-                 FROM buchungsgruppen
-                 ORDER BY sortkey|;
-
-  my $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
-
-  $form->{ALL} = [];
-  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
-    push @{ $form->{ALL} }, $ref;
-  }
-
-  $sth->finish;
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub get_buchungsgruppe {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-  my $query;
-
-  # connect to database
-  my $dbh = $form->dbconnect($myconfig);
-
-  if ($form->{id}) {
-    # TODO: extract information about income/expense accounts from new table taxzone_chart
-    $query =
-      qq|SELECT description, inventory_accno_id,
-         (SELECT accno FROM chart WHERE id = inventory_accno_id) AS inventory_accno
-         FROM buchungsgruppen
-         WHERE id = ?|;
-    my $sth = $dbh->prepare($query);
-    $sth->execute($form->{id}) || $form->dberror($query . " ($form->{id})");
-
-    my $ref = $sth->fetchrow_hashref("NAME_lc");
-
-    map { $form->{$_} = $ref->{$_} } keys %$ref;
-
-    $sth->finish;
-
-    $query =
-      qq|SELECT count(id) = 0 AS orphaned
-         FROM parts
-         WHERE buchungsgruppen_id = ?|;
-    ($form->{orphaned}) = selectrow_query($form, $dbh, $query, $form->{id});
-  }
-
-  $query = "SELECT inventory_accno_id, income_accno_id, expense_accno_id ".
-    "FROM defaults";
-  ($form->{"std_inventory_accno_id"}, $form->{"std_income_accno_id"},
-   $form->{"std_expense_accno_id"}) = selectrow_query($form, $dbh, $query);
-
-  my $module = "IC";
-  $query = qq|SELECT c.accno, c.description, c.link, c.id,
-              d.inventory_accno_id, d.income_accno_id, d.expense_accno_id
-              FROM chart c, defaults d
-              WHERE c.link LIKE '%$module%'
-              ORDER BY c.accno|;
-
-
-  my $sth = $dbh->prepare($query);
-  $sth->execute || $form->dberror($query);
-  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
-    foreach my $key (split(/:/, $ref->{link})) {
-      if (!$form->{"std_inventory_accno_id"} && ($key eq "IC")) {
-        $form->{"std_inventory_accno_id"} = $ref->{"id"};
-      }
-      if ($key =~ /$module/) {
-        if (   ($ref->{id} eq $ref->{inventory_accno_id})
-            || ($ref->{id} eq $ref->{income_accno_id})
-            || ($ref->{id} eq $ref->{expense_accno_id})) {
-          push @{ $form->{"${module}_links"}{$key} },
-            { accno       => $ref->{accno},
-              description => $ref->{description},
-              selected    => "selected",
-              id          => $ref->{id} };
-        } else {
-          push @{ $form->{"${module}_links"}{$key} },
-            { accno       => $ref->{accno},
-              description => $ref->{description},
-              selected    => "",
-              id          => $ref->{id} };
-        }
-      }
-    }
-  }
-  $sth->finish;
-
-
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub save_buchungsgruppe {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  # connect to database
-  my $dbh = $form->dbconnect($myconfig);
-
-  my @values = ($form->{description}, $form->{inventory_accno_id},
-                $form->{income_accno_id_0}, $form->{expense_accno_id_0},
-                $form->{income_accno_id_1}, $form->{expense_accno_id_1},
-                $form->{income_accno_id_2}, $form->{expense_accno_id_2},
-                $form->{income_accno_id_3}, $form->{expense_accno_id_3});
-
-  my $query;
-
-  # id is the old record
-  if ($form->{id}) {
-    $query = qq|UPDATE buchungsgruppen SET
-                description = ?, inventory_accno_id = ?,
-                income_accno_id_0 = ?, expense_accno_id_0 = ?,
-                income_accno_id_1 = ?, expense_accno_id_1 = ?,
-                income_accno_id_2 = ?, expense_accno_id_2 = ?,
-                income_accno_id_3 = ?, expense_accno_id_3 = ?
-                WHERE id = ?|;
-    push(@values, $form->{id});
-  } else {
-    $query = qq|SELECT COALESCE(MAX(sortkey) + 1, 1) FROM buchungsgruppen|;
-    my ($sortkey) = $dbh->selectrow_array($query);
-    $form->dberror($query) if ($dbh->err);
-    push(@values, $sortkey);
-    $query = qq|INSERT INTO buchungsgruppen
-                (description, inventory_accno_id,
-                income_accno_id_0, expense_accno_id_0,
-                income_accno_id_1, expense_accno_id_1,
-                income_accno_id_2, expense_accno_id_2,
-                income_accno_id_3, expense_accno_id_3,
-                sortkey)
-                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)|;
-  }
-  do_query($form, $dbh, $query, @values);
-
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub delete_buchungsgruppe {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form) = @_;
-
-  # connect to database
-  my $dbh = $form->dbconnect($myconfig);
-
-  my $query = qq|DELETE FROM buchungsgruppen WHERE id = ?|;
-  do_query($form, $dbh, $query, $form->{id});
-
-  $dbh->disconnect;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub swap_sortkeys {
-  $main::lxdebug->enter_sub();
-
-  my ($self, $myconfig, $form, $table) = @_;
-
-  # connect to database
-  my $dbh = $form->get_standard_dbh($myconfig);
-
-  my $query =
-    qq|SELECT
-       (SELECT sortkey FROM $table WHERE id = ?) AS sortkey1,
-       (SELECT sortkey FROM $table WHERE id = ?) AS sortkey2|;
-  my @values   = ($form->{"id1"}, $form->{"id2"});
-  my @sortkeys = selectrow_query($form, $dbh, $query, @values);
-
-  $query  = qq|UPDATE $table SET sortkey = ? WHERE id = ?|;
-  my $sth = prepare_query($form, $dbh, $query);
-
-  do_statement($form, $sth, $query, $sortkeys[1], $form->{"id1"});
-  do_statement($form, $sth, $query, $sortkeys[0], $form->{"id2"});
-
-  $sth->finish();
-
-  $dbh->commit();
-
-  $main::lxdebug->leave_sub();
-}
-
 sub prepare_template_filename {
   $main::lxdebug->enter_sub();
 
diff --git a/SL/Controller/Buchungsgruppen.pm b/SL/Controller/Buchungsgruppen.pm
new file mode 100644 (file)
index 0000000..bbb5893
--- /dev/null
@@ -0,0 +1,141 @@
+package SL::Controller::Buchungsgruppen;
+
+use strict;
+
+use parent qw(SL::Controller::Base);
+
+use SL::DB::TaxZone;
+use SL::Helper::Flash;
+use SL::Locale::String;
+use SL::DB::TaxzoneChart;
+use SL::Controller::ClientConfig;
+
+use Rose::Object::MakeMethods::Generic (
+  scalar                  => [ qw(config) ],
+);
+
+__PACKAGE__->run_before('check_auth');
+__PACKAGE__->run_before('load_config', only => [ qw(edit update) ]); #destroy
+
+#
+# actions
+#
+
+sub action_list {
+  my ($self) = @_;
+
+  my $buchungsgruppen = SL::DB::Manager::Buchungsgruppe->get_all_sorted();
+  my $taxzones        = SL::DB::Manager::TaxZone->get_all_sorted();
+
+  my %chartlist = ();
+  foreach my $gruppe (@{ $buchungsgruppen }) {
+      $chartlist{ $gruppe->id } = SL::DB::TaxzoneChart->get_all_accounts_by_buchungsgruppen_id($gruppe->id);
+  }
+
+  $::form->header;
+  $self->render('buchungsgruppen/list',
+                title           => t8('Buchungsgruppen'),
+                BUCHUNGSGRUPPEN => $buchungsgruppen,
+                CHARTLIST       => \%chartlist,
+                TAXZONES        => $taxzones);
+}
+
+sub action_new {
+  my ($self) = @_;
+
+  $self->config(SL::DB::Buchungsgruppe->new());
+  $self->show_form(title => t8('Add Buchungsgruppe'));
+}
+
+sub show_form {
+  my ($self, %params) = @_;
+
+  $self->render('buchungsgruppen/form', %params,
+                 TAXZONES       => SL::DB::Manager::TaxZone->get_all_sorted(),
+                 ACCOUNTS       => SL::Controller::ClientConfig->init_accounts(),
+                 account_label  => sub { "$_[0]{accno}--$_[0]{description}" });
+}
+
+sub action_edit {
+  my ($self) = @_;
+
+  $self->show_form(title     => t8('Edit Buchungsgruppe'),
+                   CHARTLIST => SL::DB::TaxzoneChart->get_all_accounts_by_buchungsgruppen_id($self->config->id));
+}
+
+sub action_create {
+  my ($self) = @_;
+
+  $self->config(SL::DB::Buchungsgruppe->new());
+  $self->create_or_update;
+}
+
+sub action_update {
+  my ($self) = @_;
+  $self->create_or_update;
+}
+
+sub action_reorder {
+  my ($self) = @_;
+
+  SL::DB::Buchungsgruppe->reorder_list(@{ $::form->{bg_id} || [] });
+
+  $self->render(\'', { type => 'json' });
+}
+
+#
+# filters
+#
+
+sub check_auth {
+  $::auth->assert('config');
+}
+
+sub load_config {
+  my ($self) = @_;
+
+  $self->config(SL::DB::Buchungsgruppe->new(id => $::form->{id})->load);
+}
+
+#
+# helpers
+#
+
+sub create_or_update {
+  my ($self) = @_;
+  my $is_new = !$self->config->id;
+
+  my $params = delete($::form->{config}) || { };
+  delete $params->{id};
+
+  $self->config->assign_attributes(%{ $params });
+
+  my @errors = $self->config->validate;
+
+  if (@errors) {
+    flash('error', @errors);
+    $self->show_form(title => $is_new ? t8('Add taxzone') : t8('Edit taxzone'));
+    return;
+  }
+
+  $self->config->save;
+
+  #Save taxzone_charts:
+  if ($is_new) {
+    my $taxzones = SL::DB::Manager::TaxZone->get_all_sorted();
+
+    foreach my $tz (@{ $taxzones }) {
+      my $taxzone_chart = SL::DB::Manager::TaxzoneChart->find_by_or_create(buchungsgruppen_id => $self->config->id, taxzone_id => $tz->id);
+      $taxzone_chart->taxzone_id($tz->id);
+      $taxzone_chart->buchungsgruppen_id($self->config->id);
+      $taxzone_chart->income_accno_id($::form->{"income_accno_id_" . $tz->id});
+      $taxzone_chart->expense_accno_id($::form->{"expense_accno_id_" . $tz->id});
+      $taxzone_chart->save;
+    }
+  }
+
+  flash_later('info', $is_new ? t8('The Buchungsgruppe has been created.') : t8('The Buchungsgruppe has been saved.'));
+  $self->redirect_to(action => 'list');
+}
+
+1;
index d07c8a9..28ed179 100644 (file)
@@ -9,6 +9,7 @@ use List::Util qw(first);
 use SL::DB::CustomVariableConfig;
 use SL::Helper::Flash;
 use SL::Locale::String;
+use Data::Dumper;
 
 use Rose::Object::MakeMethods::Generic (
   scalar                  => [ qw(config module module_description flags) ],
diff --git a/SL/Controller/Taxzones.pm b/SL/Controller/Taxzones.pm
new file mode 100644 (file)
index 0000000..5f19ea6
--- /dev/null
@@ -0,0 +1,138 @@
+package SL::Controller::Taxzones;
+
+use strict;
+
+use parent qw(SL::Controller::Base);
+
+#use List::Util qw(first);
+
+use SL::DB::TaxZone;
+use SL::Helper::Flash;
+use SL::Locale::String;
+use SL::DB::Manager::Buchungsgruppe;
+use SL::DB::Manager::TaxzoneChart;
+use SL::Controller::ClientConfig;
+
+use Rose::Object::MakeMethods::Generic (
+  scalar                  => [ qw(config) ],
+);
+
+__PACKAGE__->run_before('check_auth');
+__PACKAGE__->run_before('load_config', only => [ qw(edit update) ]); #destroy
+
+#
+# actions
+#
+
+sub action_list {
+  my ($self) = @_;
+
+  my $taxzones = SL::DB::Manager::TaxZone->get_all_sorted();
+
+  $::form->header;
+  $self->render('taxzones/list',
+                title    => t8('List of tax zones'),
+                TAXZONES => $taxzones);
+}
+
+sub action_new {
+  my ($self) = @_;
+
+  $self->config(SL::DB::TaxZone->new());
+  $self->show_form(title => t8('Add taxzone'));
+}
+
+sub show_form {
+  my ($self, %params) = @_;
+
+  $self->render('taxzones/form', %params,
+                BUCHUNGSGRUPPEN => SL::DB::Manager::Buchungsgruppe->get_all_sorted,
+                ACCOUNTS        => SL::Controller::ClientConfig->init_accounts,
+                account_label   => sub { "$_[0]{accno}--$_[0]{description}" });
+}
+
+sub action_edit {
+  my ($self) = @_;
+
+  $self->show_form(title     => t8('Edit custom variable'),
+                   CHARTLIST => SL::DB::TaxzoneChart->get_all_accounts_by_taxzone_id($self->config->id));
+}
+
+sub action_create {
+  my ($self) = @_;
+
+  $self->config(SL::DB::TaxZone->new());
+  $self->create_or_update;
+}
+
+sub action_update {
+  my ($self) = @_;
+
+  $self->create_or_update;
+}
+
+sub action_reorder {
+  my ($self) = @_;
+
+  SL::DB::TaxZone->reorder_list(@{ $::form->{tzone_id} || [] });
+
+  $self->render(\'', { type => 'json' });
+}
+
+#
+# filters
+#
+
+sub check_auth {
+  $::auth->assert('config');
+}
+
+sub load_config {
+  my ($self) = @_;
+
+  $self->config(SL::DB::TaxZone->new(id => $::form->{id})->load);
+}
+
+#
+# helpers
+#
+
+sub create_or_update {
+  my ($self) = @_;
+  my $is_new = !$self->config->id;
+
+  my $params = delete($::form->{config}) || { };
+  delete $params->{id};
+
+  $self->config->assign_attributes(%{ $params });
+
+  my @errors = $self->config->validate;
+
+  if (@errors) {
+    flash('error', @errors);
+    $self->show_form(title => $is_new ? t8('Add taxzone') : t8('Edit taxzone'));
+    return;
+  }
+
+  $self->config->save;
+
+  #Save taxzone_charts for new taxzones:
+  if ($is_new) {
+    my $buchungsgruppen = SL::DB::Manager::Buchungsgruppe->get_all_sorted();
+
+    foreach my $bg (@{ $buchungsgruppen }) {
+      my $taxzone_chart = SL::DB::Manager::TaxzoneChart->find_by_or_create(buchungsgruppen_id => $bg->id, taxzone_id => $self->config->id);
+
+      $taxzone_chart->taxzone_id($self->config->id);
+      $taxzone_chart->buchungsgruppen_id($bg->id);
+      $taxzone_chart->income_accno_id($::form->{"income_accno_id_" . $bg->id});
+      $taxzone_chart->expense_accno_id($::form->{"expense_accno_id_" . $bg->id});
+      $taxzone_chart->save;
+    }
+  }
+
+  flash_later('info', $is_new ? t8('The taxzone has been created.') : t8('The taxzone has been saved.'));
+  $self->redirect_to(action => 'list');
+}
+
+1;
index 65f75a5..bac0f7b 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 
 use SL::DB::MetaSetup::Buchungsgruppe;
 use SL::DB::Manager::Buchungsgruppe;
+use SL::DB::Helper::ActsAsList;
 
 __PACKAGE__->meta->add_relationship(
   inventory_account => {
@@ -15,6 +16,26 @@ __PACKAGE__->meta->add_relationship(
 
 __PACKAGE__->meta->initialize;
 
+sub validate {
+  my ($self) = @_;
+
+  my @errors;
+  push @errors, $::locale->text('The description is missing.') if !$self->description;
+
+  return @errors;
+}
+
+sub inventory_accno {
+  my ($self) = @_;
+  require SL::DB::Manager::Chart;
+  return SL::DB::Manager::Chart->find_by(id => $self->inventory_accno_id) ? SL::DB::Manager::Chart->find_by(id => $self->inventory_accno_id)->accno() : undef;
+}
+
+sub inventory_accno_description {
+  my ($self) = @_;
+  require SL::DB::Manager::Chart;
+  return SL::DB::Manager::Chart->find_by(id => $self->inventory_accno_id) ? SL::DB::Manager::Chart->find_by(id => $self->inventory_accno_id)->description() : undef;
+}
 
 sub income_accno_id {
   my ($self, $taxzone) = @_;
@@ -44,6 +65,11 @@ sub expense_account {
   return $taxzone_chart->expense_accno if $taxzone_chart;
 }
 
+sub taxzonecharts {
+  my ($self) = @_;
+  return SL::DB::Manager::TaxzoneChart->get_all(where => [ buchungsgruppen_id => $self->id ]);
+}
+
 1;
 __END__
 
diff --git a/SL/DB/Manager/TaxZone.pm b/SL/DB/Manager/TaxZone.pm
new file mode 100644 (file)
index 0000000..6d61fad
--- /dev/null
@@ -0,0 +1,20 @@
+package SL::DB::Manager::TaxZone;
+
+use strict;
+
+use SL::DB::Helper::Manager;
+use base qw(SL::DB::Helper::Manager);
+
+use SL::DB::Helper::Paginated;
+use SL::DB::Helper::Sorted;
+
+sub object_class { 'SL::DB::TaxZone' }
+
+__PACKAGE__->make_manager_methods;
+
+sub _sort_spec {
+  return ( default => [ 'sortkey', 1 ],
+           columns => { SIMPLE => 'ALL' } );
+}
+
+1;
diff --git a/SL/DB/Manager/TaxzoneChart.pm b/SL/DB/Manager/TaxzoneChart.pm
new file mode 100644 (file)
index 0000000..41faf45
--- /dev/null
@@ -0,0 +1,20 @@
+package SL::DB::Manager::TaxzoneChart;
+
+use strict;
+
+use SL::DB::Helper::Manager;
+use base qw(SL::DB::Helper::Manager);
+
+use SL::DB::Helper::Sorted;
+
+sub object_class { 'SL::DB::TaxzoneChart' }
+
+__PACKAGE__->make_manager_methods;
+
+sub _sort_spec {
+  return ( default => [ 'taxzone_id', 1 ],
+           columns => { SIMPLE      => 'ALL',
+                      });
+}
+
+1;
index b81fb12..55d600c 100644 (file)
@@ -10,6 +10,7 @@ __PACKAGE__->meta->table('buchungsgruppen');
 
 __PACKAGE__->meta->columns(
   description        => { type => 'text' },
+  id                 => { type => 'integer', not_null => 1, sequence => 'id' },
   inventory_accno_id => { type => 'integer' },
   sortkey            => { type => 'integer', not_null => 1 },
 );
index b294531..993d28f 100644 (file)
@@ -10,7 +10,8 @@ __PACKAGE__->meta->table('tax_zones');
 
 __PACKAGE__->meta->columns(
   description => { type => 'text' },
-  id          => { type => 'integer', not_null => 1 },
+  id          => { type => 'integer', not_null => 1, sequence => 'id' },
+  sortkey     => { type => 'integer', not_null => 1 },
 );
 
 __PACKAGE__->meta->primary_key_columns([ 'id' ]);
index 3dfb313..ad96ee2 100644 (file)
@@ -6,10 +6,21 @@ package SL::DB::TaxZone;
 use strict;
 
 use SL::DB::MetaSetup::TaxZone;
+use SL::DB::Manager::TaxZone;
+use SL::DB::Helper::ActsAsList;
 
 __PACKAGE__->meta->initialize;
 
 # Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
-__PACKAGE__->meta->make_manager_class;
+#__PACKAGE__->meta->make_manager_class;
+
+sub validate {
+  my ($self) = @_;
+
+  my @errors;
+  push @errors, $::locale->text('The description is missing.') if !$self->description;
+
+  return @errors;
+}
 
 1;
index 540f49b..4eb0ea8 100644 (file)
@@ -6,10 +6,80 @@ package SL::DB::TaxzoneChart;
 use strict;
 
 use SL::DB::MetaSetup::TaxzoneChart;
+use SL::DB::Manager::TaxzoneChart;
+use SL::DB::MetaSetup::Buchungsgruppe;
 
 __PACKAGE__->meta->initialize;
 
 # Creates get_all, get_all_count, get_all_iterator, delete_all and update_all.
-__PACKAGE__->meta->make_manager_class;
+#__PACKAGE__->meta->make_manager_class;
+
+sub get_all_accounts_by_buchungsgruppen_id {
+  my ($self, $buchungsgruppen_id) = @_;
+
+  my $all_taxzonecharts = SL::DB::Manager::TaxzoneChart->get_all(where   => [ buchungsgruppen_id => $buchungsgruppen_id ],
+                                                                 sort_by => 'taxzone_id');
+
+  my %list = ();
+
+  #inventory_accno der Buchungsgruppe:
+  $list{inventory_accno} = SL::DB::Manager::Buchungsgruppe->find_by(id => $buchungsgruppen_id)->inventory_accno;
+  $list{inventory_accno_description} = SL::DB::Manager::Buchungsgruppe->find_by(id => $buchungsgruppen_id)->inventory_accno_description;
+
+  foreach my $taxzonechart (@{ $all_taxzonecharts }) {
+    $list{ $taxzonechart->taxzone_id }{taxzone_chart_id}          = $taxzonechart->id;
+    $list{ $taxzonechart->taxzone_id }{income_accno}              = $taxzonechart->get_income_accno;
+    $list{ $taxzonechart->taxzone_id }{expense_accno}             = $taxzonechart->get_expense_accno;
+    $list{ $taxzonechart->taxzone_id }{income_accno_id}           = $taxzonechart->income_accno_id;
+    $list{ $taxzonechart->taxzone_id }{expense_accno_id}          = $taxzonechart->expense_accno_id;
+    $list{ $taxzonechart->taxzone_id }{income_accno_description}  = $taxzonechart->get_income_accno_description;
+    $list{ $taxzonechart->taxzone_id }{expense_accno_description} = $taxzonechart->get_expense_accno_description;
+  }
+  return \%list;
+}
+
+sub get_all_accounts_by_taxzone_id {
+  my ($self, $taxzone_id) = @_;
+
+  my $all_taxzonecharts = SL::DB::Manager::TaxzoneChart->get_all(where => [ taxzone_id => $taxzone_id ]);
+
+  my %list = ();
+
+  foreach my $tzchart (@{ $all_taxzonecharts }) {
+    $list{ $tzchart->buchungsgruppen_id }{taxzone_chart_id}          = $tzchart->id;
+    $list{ $tzchart->buchungsgruppen_id }{income_accno}              = $tzchart->get_income_accno;
+    $list{ $tzchart->buchungsgruppen_id }{expense_accno}             = $tzchart->get_expense_accno;
+    $list{ $tzchart->buchungsgruppen_id }{income_accno_id}           = $tzchart->income_accno_id;
+    $list{ $tzchart->buchungsgruppen_id }{expense_accno_id}          = $tzchart->expense_accno_id;
+    $list{ $tzchart->buchungsgruppen_id }{income_accno_description}  = $tzchart->get_income_accno_description;
+    $list{ $tzchart->buchungsgruppen_id }{expense_accno_description} = $tzchart->get_expense_accno_description;
+  }
+
+  return \%list;
+}
+
+sub get_income_accno {
+  my $self = shift;
+  require SL::DB::Manager::Chart;
+  return SL::DB::Manager::Chart->find_by(id => $self->income_accno_id)->accno();
+}
+
+sub get_expense_accno {
+  my $self = shift;
+  require SL::DB::Manager::Chart;
+  return SL::DB::Manager::Chart->find_by(id => $self->expense_accno_id)->accno();
+}
+
+sub get_income_accno_description {
+  my $self = shift;
+  require SL::DB::Manager::Chart;
+  return SL::DB::Manager::Chart->find_by(id => $self->income_accno_id)->description();
+}
+
+sub get_expense_accno_description {
+  my $self = shift;
+  require SL::DB::Manager::Chart;
+  return SL::DB::Manager::Chart->find_by(id => $self->expense_accno_id)->description();
+}
 
 1;
index e141696..e18246b 100644 (file)
@@ -790,153 +790,6 @@ sub delete_language {
   $main::lxdebug->leave_sub();
 }
 
-
-sub add_buchungsgruppe {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-  my $locale   = $main::locale;
-
-  $main::auth->assert('config');
-
-  # $locale->text("Add Buchungsgruppe")
-  # $locale->text("Edit Buchungsgruppe")
-  $form->{title} = "Add";
-
-  $form->{callback} = "am.pl?action=add_buchungsgruppe" unless $form->{callback};
-
-  AM->get_buchungsgruppe(\%myconfig, \%$form);
-  $form->{"inventory_accno_id"} = $form->{"std_inventory_accno_id"};
-  for (my $i = 0; 4 > $i; $i++) {
-    map({ $form->{"${_}_accno_id_$i"} = $form->{"std_${_}_accno_id"}; }
-        qw(income expense));
-  }
-
-  &buchungsgruppe_header;
-  &form_footer;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub edit_buchungsgruppe {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-
-  $main::auth->assert('config');
-
-  $form->{title} = "Edit";
-
-  AM->get_buchungsgruppe(\%myconfig, \%$form);
-
-  &buchungsgruppe_header;
-
-  &form_footer;
-
-  $main::lxdebug->leave_sub();
-}
-
-sub list_buchungsgruppe {
-  $::lxdebug->enter_sub;
-  $::auth->assert('config');
-
-  AM->buchungsgruppe(\%::myconfig, $::form);
-
-  $::form->{callback} = "am.pl?action=list_buchungsgruppe";
-  $::form->{title}    = $::locale->text('Buchungsgruppen');
-  $::form->header;
-
-  print $::form->parse_html_template('am/buchungsgruppe_list', {
-    swap_link => qq|am.pl?action=swap_buchungsgruppen&|,
-  });
-
-  $::lxdebug->leave_sub;
-}
-
-sub buchungsgruppe_header {
-  $::lxdebug->enter_sub;
-  $::auth->assert('config');
-
-  # $locale->text('Add Accounting Group')
-  # $locale->text('Edit Accounting Group')
-  $::form->{title}    = $::locale->text("$::form->{title} Buchungsgruppe");
-
-  my ($acc_inventory, $acc_income, $acc_expense) = ({}, {}, {});
-  my %acc_type_map = (
-    IC         => $acc_inventory,
-    IC_income  => $acc_income,
-    IC_sale    => $acc_income,
-    IC_expense => $acc_expense,
-    IC_cogs    => $acc_expense,
-  );
-
-  for my $key (keys %acc_type_map) {
-    for my $ref (@{ $::form->{IC_links}{$key} }) {
-      $acc_type_map{$key}{$ref->{id}} = $ref;
-    }
-  }
-
-  my %sorted_accounts = map {
-    $_ => [ sort { $a->{accno} cmp $b->{accno} } values %{ $acc_type_map{$_} } ],
-  } keys %acc_type_map;
-
-  $::form->header;
-  print $::form->parse_html_template('am/buchungsgruppe_header', {
-    accounts      => \%sorted_accounts,
-    account_label => sub { "$_[0]{accno}--$_[0]{description}" },
-  });
-
-  $::lxdebug->leave_sub;
-}
-
-sub save_buchungsgruppe {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-  my $locale   = $main::locale;
-
-  $main::auth->assert('config');
-
-  $form->isblank("description", $locale->text('Description missing!'));
-
-  AM->save_buchungsgruppe(\%myconfig, \%$form);
-  $form->redirect($locale->text('Accounting Group saved!'));
-
-  $main::lxdebug->leave_sub();
-}
-
-sub delete_buchungsgruppe {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-  my $locale   = $main::locale;
-
-  $main::auth->assert('config');
-
-  AM->delete_buchungsgruppe(\%myconfig, \%$form);
-  $form->redirect($locale->text('Accounting Group deleted!'));
-
-  $main::lxdebug->leave_sub();
-}
-
-sub swap_buchungsgruppen {
-  $main::lxdebug->enter_sub();
-
-  my $form     = $main::form;
-  my %myconfig = %main::myconfig;
-
-  $main::auth->assert('config');
-
-  AM->swap_sortkeys(\%myconfig, $form, "buchungsgruppen");
-  list_buchungsgruppe();
-
-  $main::lxdebug->leave_sub();
-}
-
 sub _build_cfg_options {
   my $form     = $main::form;
   my %myconfig = %main::myconfig;
index c211cc8..1e27fb6 100755 (executable)
@@ -182,6 +182,7 @@ $self->{texts} = {
   'Add picture to text block'   => 'Bild dem Textblock hinzufügen',
   'Add section'                 => 'Abschnitt hinzufügen',
   'Add sub function block'      => 'Unterfunktionsblock hinzufügen',
+  'Add taxzone'                 => 'Steuerzone hinzufügen',
   'Add text block'              => 'Textblock erfassen',
   'Add unit'                    => 'Einheit hinzuf&uuml;gen',
   'Added sections and function blocks: #1' => 'Hinzugefügte Abschnitte und Funktionsblöcke: #1',
@@ -962,6 +963,7 @@ $self->{texts} = {
   'Edit requirement spec type'  => 'Pflichtenhefttypen bearbeiten',
   'Edit risk level'             => 'Risikograd bearbeiten',
   'Edit section #1'             => 'Abschnitt #1 bearbeiten',
+  'Edit taxzone'                => 'Steuerzone bearbeiten',
   'Edit templates'              => 'Vorlagen bearbeiten',
   'Edit text block'             => 'Textblock bearbeiten',
   'Edit text block \'#1\''      => 'Textblock \'#1\' bearbeiten',
@@ -1400,6 +1402,7 @@ $self->{texts} = {
   'List of bank collections'    => 'Bankeinzugsliste',
   'List of bank transfers'      => 'Überweisungsliste',
   'List of custom variables'    => 'Liste der benutzerdefinierten Variablen',
+  'List of tax zones'           => 'Liste der Steuerzonen',
   'List open SEPA exports'      => 'Noch nicht ausgeführte SEPA-Exporte anzeigen',
   'Load draft'                  => 'Entwurf laden',
   'Load profile'                => 'Profil laden',
@@ -2303,6 +2306,7 @@ $self->{texts} = {
   'Taxlink_coa'                 => 'Steuerautomatik',
   'Taxnumber'                   => 'Steuernummer',
   'Taxrate missing!'            => 'Prozentsatz fehlt!',
+  'Taxzones'                    => 'Steuerzonen',
   'Tel'                         => 'Tel',
   'Tel.'                        => 'Telefon',
   'Telephone'                   => 'Telefon',
@@ -2547,6 +2551,8 @@ $self->{texts} = {
   'The task server is not running.' => 'Der Task-Server läuft nicht.',
   'The task server was started successfully.' => 'Der Task-Server wurde erfolgreich gestartet.',
   'The task server was stopped successfully.' => 'Der Task-Server wurde erfolgreich beendet.',
+  'The taxzone has been created.' => 'Die Steuerzone wurde erstellt.',
+  'The taxzone has been saved.' => 'Die Steuerzone wurde gespeichert.',
   'The third way is to download the module from the above mentioned URL and to install the module manually following the installations instructions contained in the source archive.' => 'Die dritte Variante besteht darin, das Paket von der oben genannten URL herunterzuladen und es manuell zu installieren. Beachten Sie dabei die im Paket enthaltenen Installationsanweisungen.',
   'The three columns "make_X", "model_X" and "lastcost_X" with the same number "X" are used to import vendor part numbers and vendor prices.' => 'Die drei Spalten "make_X", "model_X" und "lastcost_X" mit derselben Nummer "X" werden zum Import von Lieferantenartikelnummern und -preisen genutzt.',
   'The title is missing.'       => 'Der Titel fehlt.',
index 3297621..73de88e 100644 (file)
@@ -570,8 +570,12 @@ module=am.pl
 action=list_account
 
 [System--Buchungsgruppen]
-module=am.pl
-action=list_buchungsgruppe
+module=controller.pl
+action=Buchungsgruppen/list
+
+[System--Taxzones]
+module=controller.pl
+action=Taxzones/list
 
 [System--Taxes]
 module=am.pl
diff --git a/sql/Pg-upgrade2/taxzone_default_id.sql b/sql/Pg-upgrade2/taxzone_default_id.sql
new file mode 100644 (file)
index 0000000..29476b4
--- /dev/null
@@ -0,0 +1,5 @@
+-- @tag: taxzone_default_id
+-- @description: In der Tabelle tax_zones wird die id nun automatisch vergeben.
+-- @depends: release_3_0_0 convert_taxzone taxzone_charts
+
+ALTER TABLE tax_zones ALTER id SET DEFAULT nextval(('id'::text)::regclass);
diff --git a/sql/Pg-upgrade2/taxzone_sortkey.pl b/sql/Pg-upgrade2/taxzone_sortkey.pl
new file mode 100644 (file)
index 0000000..88897d7
--- /dev/null
@@ -0,0 +1,40 @@
+# @tag: taxzone_sortkey
+# @description: Setzt eine neue Spalte sortkey in der Datenbank, um Steuerzonen sortierbar zu machen.
+# @depends: taxzone_charts
+package SL::DBUpgrade2::taxzone_sortkey;
+
+use strict;
+use utf8;
+
+use SL::DB::Manager::TaxZone;
+
+use parent qw(SL::DBUpgrade2::Base);
+
+sub run {
+  my ($self) = @_;
+
+  my $query = qq|ALTER TABLE tax_zones ADD COLUMN sortkey INTEGER|;
+  $self->db_query($query);
+  $self->dbh->commit;
+
+  my $sortkey = 1;
+  $query = qq|SELECT * FROM tax_zones ORDER BY id|;
+
+  my $sth = $self->dbh->prepare($query);
+  $sth->execute || $::form->dberror($query);
+
+  while (my $ref = $sth->fetchrow_hashref("NAME_lc")) {
+    $self->db_query(qq|UPDATE tax_zones SET sortkey = $sortkey WHERE id = | . $ref->{id});
+    $sortkey++;
+  }
+  $sth->finish;
+
+  $self->dbh->commit;
+
+  $query = qq|ALTER TABLE tax_zones ALTER COLUMN sortkey SET NOT NULL|;
+  $self->db_query($query);
+
+  return 1;
+} # end run
+
+1;
diff --git a/templates/webpages/am/buchungsgruppe_header.html b/templates/webpages/am/buchungsgruppe_header.html
deleted file mode 100644 (file)
index 4843f86..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-[%- USE HTML %]
-[%- USE L %]
-[%- USE LxERP %]
-[%- USE T8 %]
-
-<h1>[% title | html %]</h1>
-
-<form method=post action=am.pl>
-
-<input type=hidden name=id value='[% id %]'>
-<input type=hidden name=type value=buchungsgruppe>
-
-<table width=100%>
-  <tr>
-    <th align=right>[% 'Buchungsgruppe' | $T8 %]</th>
-    <td><input name=description size=30 value="[% description | html %]"></td>
-  </tr>
-[%- IF INSTANCE_CONF.get_inventory_system == 'perpetual' %]
-  <tr>
-   <th align=right>[% 'Inventory' | $T8 %]</th>
-   <td>[% L.select_tag('inventory_accno_id', accounts.IC, title_sub=\account_label, default=invetory_accno_id) %]</td>
-  </tr>
-[%- ELSE %]
-  <tr style='display:none'>
-    <td>[% L.hidden_tag('inventory_accno_id', inventory_accno_id) %]</td>
-  </tr>
-[%- END %]
-  <tr>
-    <th align=right>[% 'National Revenues' | $T8 %]</th>
-    <td>[% L.select_tag('income_accno_id_0', accounts.IC_income, title_sub=\account_label, default=income_accno_id_0) %]</td>
-  </tr>
-  <tr>
-    <th align=right>[% 'National Expenses' | $T8 %]</th>
-    <td>[% L.select_tag('expense_accno_id_0', accounts.IC_expense, title_sub=\account_label, default=expense_accno_id_0) %]</td>
-  </tr>
-  <tr>
-    <th align=right>[% 'Revenues EU with UStId' | $T8 %]</th>
-    <td>[% L.select_tag('income_accno_id_1', accounts.IC_income, title_sub=\account_label, default=income_accno_id_1) %]</td>
-  </tr>
-  <tr>
-    <th align=right>[% 'Expenses EU with UStId' | $T8 %]</th>
-    <td>[% L.select_tag('expense_accno_id_1', accounts.IC_expense, title_sub=\account_label, default=expense_accno_id_1) %]</td>
-  </tr>
-  <tr>
-    <th align=right>[% 'Revenues EU without UStId' | $T8 %]</th>
-    <td>[% L.select_tag('income_accno_id_2', accounts.IC_income, title_sub=\account_label, default=income_accno_id_2) %]</td>
-  </tr>
-  <tr>
-    <th align=right>[% 'Expenses EU without UStId' | $T8 %]</th>
-    <td>[% L.select_tag('expense_accno_id_2', accounts.IC_expense, title_sub=\account_label, default=expense_accno_id_2) %]</td>
-  </tr>
-  <tr>
-    <th align=right>[% 'Foreign Revenues' | $T8 %]</th>
-    <td>[% L.select_tag('income_accno_id_3', accounts.IC_income, title_sub=\account_label, default=income_accno_id_3) %]</td>
-  </tr>
-  <tr>
-    <th align=right>[% 'Foreign Expenses' | $T8 %]</th>
-    <td>[% L.select_tag('expense_accno_id_3', accounts.IC_expense, title_sub=\account_label, default=expense_accno_id_3) %]</td>
-  </tr>
-  <td colspan=2><hr size=3 noshade></td>
-  </tr>
-</table>
diff --git a/templates/webpages/am/buchungsgruppe_list.html b/templates/webpages/am/buchungsgruppe_list.html
deleted file mode 100644 (file)
index 55380c7..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-[%- USE HTML %]
-[%- USE L %]
-[%- USE LxERP %]
-[%- USE T8 %]
-
-<h1>[% title | html %]</h1>
-
-<table width=100%>
-  <tr>
-  </tr>
-  <tr height="5"></tr>
-  <tr>
-    <td>
-      <table width=100%>
-        <tr class=listheading>
-         <th class="listheading" width="16"><img src="image/up.png" alt="[% 'up' | $T8 %]"></th>
-         <th class="listheading" width="16"><img src="image/down.png" alt="[% 'down' | $T8 %]"></th>
-         <th class="listheading" width="40%">[% 'Description' | $T8 %]</th>
-         <th class=listheading>[% 'Bestandskonto' | $T8 %]</th>
-         <th class=listheading>[% 'National Revenues' | $T8 %]</th>
-         <th class=listheading>[% 'National Expenses' | $T8 %]</th>
-         <th class=listheading>[% 'Revenues EU with UStId' | $T8 %]</th>
-         <th class=listheading>[% 'Expenses EU with UStId' | $T8 %]</th>
-         <th class=listheading>[% 'Revenues EU without UStId' | $T8 %]</th>
-         <th class=listheading>[% 'Expenses EU without UStId' | $T8 %]</th>
-         <th class=listheading>[% 'Foreign Revenues' | $T8 %]</th>
-         <th class=listheading>[% 'Foreign Expenses' | $T8 %]</th>
-        </tr>
-[%- FOREACH row IN ALL %]
-        <tr valign=top class=listrow[% loop.count % 2 %]>
-          <td align="center" valign="center">[% IF !loop.first %]<a href="[% swap_link %]id1=[% row.id %]&id2=[% loop.prev.id %]"><img border="0" src="image/up.png" alt="[% 'up' | $T8 %]"></a>[% ELSE %]&nbsp;[% END %]</td>
-          <td align="center" valign="center">[% IF !loop.last %]<a href="[% swap_link %]id1=[% row.id %]&id2=[% loop.next.id %]"><img border="0" src="image/down.png" alt="[% 'down' | $T8 %]"></a>[% ELSE %]&nbsp;[% END %]</td>
-          <td><a href="am.pl?action=edit_buchungsgruppe&id=[%row.id %]&callback=[% callback | html %]">[% row.description | html %]</a></td>
-          <td align=right>[% row.inventory_accno | html %]</td>
-          <td align=right>[% row.income_accno_0  | html %]</td>
-          <td align=right>[% row.expense_accno_0 | html %]</td>
-          <td align=right>[% row.income_accno_1  | html %]</td>
-          <td align=right>[% row.expense_accno_1 | html %]</td>
-          <td align=right>[% row.income_accno_2  | html %]</td>
-          <td align=right>[% row.expense_accno_2 | html %]</td>
-          <td align=right>[% row.income_accno_3  | html %]</td>
-          <td align=right>[% row.expense_accno_3 | html %]</td>
-        </tr>
-[%- END %]
-      </table>
-    </td>
-  </tr>
-  <tr>
-  <td><hr size=3 noshade></td>
-  </tr>
-</table>
-
-<br>
-
-<a href="am.pl?action=add&type=buchungsgruppe&callback=[% HTML.url(callback) %]">[%- LxERP.t8('Add') %]</a>
diff --git a/templates/webpages/buchungsgruppen/form.html b/templates/webpages/buchungsgruppen/form.html
new file mode 100644 (file)
index 0000000..5dad157
--- /dev/null
@@ -0,0 +1,59 @@
+[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%]<h1>[% HTML.escape(title) %]</h1>
+
+<form action="controller.pl" method="post">
+[%- L.hidden_tag("id", SELF.config.id) %]
+
+<table>
+  <tr>
+    <th align="right">[% 'Description' | $T8 %]</th>
+    <td>[%- L.input_tag("config.description", SELF.config.description) %]</td>
+  </tr>
+  <tr>
+    <th align="right">[% 'Inventory account' | $T8 %]</th>
+    [%- IF SELF.config.id %]
+    <td>[%- CHARTLIST.inventory_accno %] -- [%- CHARTLIST.inventory_accno_description %]</td>
+    [%- ELSE %]
+    <td>[%- L.select_tag("config.inventory_accno_id", ACCOUNTS.ic, title_sub=\account_label, default=SELF.config.inventory_accno_id) %]</td>
+    [%- END %]
+  </tr>
+[%- FOREACH tz = TAXZONES %]
+  <tr>
+    <th align="right">[% 'Revenue' | $T8 %] [% HTML.escape(tz.description) %]</th>
+    [%- IF SELF.config.id %]
+    <td>[% CHARTLIST.${tz.id}.income_accno %] -- [% CHARTLIST.${tz.id}.income_accno_description %]</td>
+    [%- ELSE %]
+    <td>[%- L.select_tag('income_accno_id_' _ tz.id, ACCOUNTS.ic_income, title_sub=\account_label, default=CHARTLIST.${tz.id}.income_accno_id) %]</td>
+    [%- END %]
+  </tr>
+  <tr>
+    <th align="right">[% 'Expense' | $T8 %] [% HTML.escape(tz.description) %]</th>
+    [%- IF SELF.config.id %]
+    <td>[% CHARTLIST.${tz.id}.expense_accno %] -- [% CHARTLIST.${tz.id}.expense_accno_description %]</td>
+    [%- ELSE %]
+    <td>[%- L.select_tag('expense_accno_id_' _ tz.id, ACCOUNTS.ic_expense, title_sub=\account_label, default=CHARTLIST.${tz.id}.expense_accno_id) %]</td>
+    [%- END %]
+  </tr>
+[%- END %]
+</table>
+
+ <p>
+  [% L.hidden_tag("action", "Buchungsgruppen/dispatch") %]
+  [% L.submit_tag("action_" _  (SELF.config.id ? "update" : "create"), LxERP.t8('Save'), onclick="return check_prerequisites();") %]
+  <a href="[% SELF.url_for(action='list') %]">[%- LxERP.t8("Cancel") %]</a>
+ </p>
+
+ <hr>
+
+<script type="text/javascript">
+<!--
+function check_prerequisites() {
+  if ($('#config_description').val() === "") {
+    alert(kivi.t8('The description is missing.'));
+    return false;
+  }
+
+  return true;
+}
+-->
+</script>
+</form>
diff --git a/templates/webpages/buchungsgruppen/list.html b/templates/webpages/buchungsgruppen/list.html
new file mode 100644 (file)
index 0000000..7998143
--- /dev/null
@@ -0,0 +1,41 @@
+[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%][%- INCLUDE 'common/flash.html' %]
+
+<h1>[% title %]</h1>
+
+<p>
+ <table width="100%" id="buchungsgruppen_list">
+  <thead>
+   <tr class="listheading">
+    <th align="center" width="1%"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></th>
+    <th width="20%">[% 'Description' | $T8 %]</th>
+    <th width="20%">[% 'Inventory' | $T8 %]</th>
+     [%- FOREACH tz = TAXZONES %]
+        <th width="20%">[% 'Revenue' | $T8 %] [% HTML.escape(tz.description) %]</th>
+        <th width="20%">[% 'Expense' | $T8 %] [% HTML.escape(tz.description) %]</th>
+     [%- END %]
+   </tr>
+  </thead>
+
+  <tbody>
+   [%- FOREACH bg = BUCHUNGSGRUPPEN %]
+    <tr class="listrow" id="bg_id_[% bg.id %]">
+     <td align="center" class="dragdrop"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></td>
+     <td><a href="[% SELF.url_for(action='edit', id=bg.id) %]">[% HTML.escape(bg.description) %]</a></td>
+     <td>[% HTML.escape(CHARTLIST.${bg.id}.inventory_accno) %]</td>
+     [%- FOREACH tz = TAXZONES %]
+        <td>[% HTML.escape(CHARTLIST.${bg.id}.${tz.id}.income_accno) %]</td>
+        <td>[% HTML.escape(CHARTLIST.${bg.id}.${tz.id}.expense_accno) %]</td>
+     [%- END %]
+   [%- END %]
+  </tbody>
+ </table>
+</p>
+
+<hr height="3">
+
+[% L.sortable_element('#buchungsgruppen_list tbody', url=SELF.url_for(action='reorder'), with='bg_id') %]
+
+<p>
+ <a href="[% SELF.url_for(action='new') %]">[%- 'Add' | $T8 %]</a>
+</p>
+
diff --git a/templates/webpages/taxzones/form.html b/templates/webpages/taxzones/form.html
new file mode 100644 (file)
index 0000000..4e1c89e
--- /dev/null
@@ -0,0 +1,51 @@
+[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%]<h1>[% HTML.escape(title) %]</h1>
+
+<form action="controller.pl" method="post">
+[%- L.hidden_tag("id", SELF.config.id) %]
+
+<table>
+  <tr>
+    <th align="right">[% 'Description' | $T8 %]</th>
+    <td>[%- L.input_tag("config.description", SELF.config.description) %]</td>
+  </tr>
+[%- FOREACH bg = BUCHUNGSGRUPPEN %]
+  <tr>
+    <th align="right">[% 'Revenue' | $T8 %] [% HTML.escape(bg.description) %]</th>
+    [%- IF SELF.config.id %]
+    <td>[% CHARTLIST.${bg.id}.income_accno %] -- [% CHARTLIST.${bg.id}.income_accno_description %]</td>
+    [%- ELSE %]
+    <td>[%- L.select_tag('income_accno_id_' _ bg.id, ACCOUNTS.ic_income, title_sub=\account_label, default=CHARTLIST.${bg.id}.income_accno_id) %]</td>
+    [%- END %]
+  </tr>
+  <tr>
+    <th align="right">[% 'Expense' | $T8 %] [% HTML.escape(bg.description) %]</th>
+    [%- IF SELF.config.id %]
+    <td>[% CHARTLIST.${bg.id}.expense_accno %] -- [% CHARTLIST.${bg.id}.expense_accno_description %]</td>
+    [%- ELSE %]
+    <td>[%- L.select_tag('expense_accno_id_' _ bg.id, ACCOUNTS.ic_expense, title_sub=\account_label, default=CHARTLIST.${bg.id}.expense_accno_id) %]</td>
+    [%- END %]
+  </tr>
+[%- END %]
+</table>
+
+ <p>
+  [% L.hidden_tag("action", "Taxzones/dispatch") %]
+  [% L.submit_tag("action_" _  (SELF.config.id ? "update" : "create"), LxERP.t8('Save'), onclick="return check_prerequisites();") %]
+  <a href="[% SELF.url_for(action='list') %]">[%- LxERP.t8("Cancel") %]</a>
+ </p>
+
+ <hr>
+
+<script type="text/javascript">
+<!--
+function check_prerequisites() {
+  if ($('#config_description').val() === "") {
+    alert(kivi.t8('The description is missing.'));
+    return false;
+  }
+
+  return true;
+}
+-->
+</script>
+</form>
diff --git a/templates/webpages/taxzones/list.html b/templates/webpages/taxzones/list.html
new file mode 100644 (file)
index 0000000..0229804
--- /dev/null
@@ -0,0 +1,32 @@
+[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE T8 -%][%- INCLUDE 'common/flash.html' %]
+
+<h1>[% title %]</h1>
+
+<p>
+ <table width="100%" id="taxzone_list">
+  <thead>
+   <tr class="listheading">
+    <th align="center" width="1%"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></th>
+    <th>[% 'Description' | $T8 %]</th>
+   </tr>
+  </thead>
+
+  <tbody>
+   [%- FOREACH tz = TAXZONES %]
+    <tr class="listrow" id="tzone_id_[% tz.id %]">
+     <td align="center" class="dragdrop"><img src="image/updown.png" alt="[ LxERP.t8('reorder item') %]"></td>
+     <td><a href="[% SELF.url_for(action='edit', id=tz.id) %]">[% HTML.escape(tz.description) %]</a></td>
+    </tr>
+   [%- END %]
+  </tbody>
+ </table>
+</p>
+
+<hr height="3">
+
+[% L.sortable_element('#taxzone_list tbody', url=SELF.url_for(action='reorder'), with='tzone_id') %]
+
+<p>
+ <a href="[% SELF.url_for(action='new') %]">[%- 'Add' | $T8 %]</a>
+</p>
+