From: G. Richardson Date: Thu, 30 Jul 2015 04:36:03 +0000 (+0200) Subject: Steuerzonen überarbeitet - Prüfung und Löschen X-Git-Tag: release-3.3.0beta~20 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=bdc944eae9567aa4bd256b56b89f6004890fc585;p=kivitendo-erp.git Steuerzonen überarbeitet - Prüfung und Löschen Nicht benutzte Steuerzonen können jetzt gelöscht werden, sowie deren Kontenzuordnungen geändert werden (wie bei Buchungsgruppen). Siehe Feature #70. Schlägt die Speicherung neuer Steuerzonen fehl, weil z.B. die Buchungsgruppenkonten fehlen, gibt es nun einen Rollback und eine ordentliche Fehlermeldung, siehe Fehler #68. --- diff --git a/SL/Controller/Taxzones.pm b/SL/Controller/Taxzones.pm index 6f5adf7f1..60b820d4f 100644 --- a/SL/Controller/Taxzones.pm +++ b/SL/Controller/Taxzones.pm @@ -4,8 +4,6 @@ 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; @@ -18,7 +16,7 @@ use Rose::Object::MakeMethods::Generic ( ); __PACKAGE__->run_before('check_auth'); -__PACKAGE__->run_before('load_config', only => [ qw(edit update) ]); #destroy +__PACKAGE__->run_before('load_config', only => [ qw(edit update delete) ]); # # actions @@ -29,7 +27,6 @@ sub action_list { my $taxzones = SL::DB::Manager::TaxZone->get_all_sorted(); - $::form->header; $self->render('taxzones/list', title => t8('List of tax zones'), TAXZONES => $taxzones); @@ -69,6 +66,24 @@ sub action_update { $self->create_or_update; } +sub action_delete { + my ($self) = @_; + + # allow deletion of unused tax zones. Will fail, due to database + # constraints, if tax zone is used anywhere + + my $db = $self->{config}->db; + $db->do_transaction(sub { + my $taxzone_charts = SL::DB::Manager::TaxzoneChart->get_all(where => [ taxzone_id => $self->config->id ]); + foreach my $taxzonechart ( @{$taxzone_charts} ) { $taxzonechart->delete }; + $self->config->delete(); + flash_later('info', $::locale->text('The tax zone has been deleted.')); + }) || flash_later('error', $::locale->text('The tax zone is in use and cannot be deleted.')); + + $self->redirect_to(action => 'list'); + +} + sub action_reorder { my ($self) = @_; @@ -100,35 +115,54 @@ sub create_or_update { my $is_new = !$self->config->id; my $params = delete($::form->{config}) || { }; + delete $params->{id}; - $self->config->assign_attributes(%{ $params }); + my @errors; + + my $db = $self->config->db; + $db->do_transaction( sub { + + # always allow editing of description and obsolete + $self->config->assign_attributes( %{$params} ) ; + + push(@errors, $self->config->validate); # check for description + + if (@errors) { + die @errors . "\n"; + }; - my @errors = $self->config->validate; + $self->config->save; - if (@errors) { - flash('error', @errors); - $self->show_form(title => $is_new ? t8('Add taxzone') : t8('Edit taxzone')); - return; - } + if ( $is_new or $self->config->orphaned ) { + # Save taxzone_charts + my $buchungsgruppen = SL::DB::Manager::Buchungsgruppe->get_all_sorted(); - $self->config->save; - $self->config->obsolete($::form->{"obsolete"}); + foreach my $bg (@{ $buchungsgruppen }) { + my $income_accno_id = $::form->{"income_accno_id_" . $bg->id}; + my $expense_accno_id = $::form->{"expense_accno_id_" . $bg->id}; - #Save taxzone_charts for new taxzones: - if ($is_new) { - my $buchungsgruppen = SL::DB::Manager::Buchungsgruppe->get_all_sorted(); + my ($income_accno, $expense_accno); + $income_accno = SL::DB::Manager::Chart->find_by( id => $income_accno_id ) if $income_accno_id; + $expense_accno = SL::DB::Manager::Chart->find_by( id => $expense_accno_id ) if $expense_accno_id; - foreach my $bg (@{ $buchungsgruppen }) { - my $taxzone_chart = SL::DB::Manager::TaxzoneChart->find_by_or_create(buchungsgruppen_id => $bg->id, taxzone_id => $self->config->id); + push(@errors, t8('Buchungsgruppe #1 needs a valid income account' , $bg->description)) unless $income_accno; + push(@errors, t8('Buchungsgruppe #1 needs a valid expense account', $bg->description)) unless $expense_accno; - $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; + my $taxzone_chart = SL::DB::Manager::TaxzoneChart->find_by_or_create(buchungsgruppen_id => $bg->id, taxzone_id => $self->config->id); + # if taxzonechart doesn't exist an empty new TaxzoneChart object is + # created by find_by_or_create, so we have to assign buchungsgruppe and + # taxzone again for the new case to work + $taxzone_chart->taxzone_id($self->config->id); + $taxzone_chart->buchungsgruppen_id($bg->id); + $taxzone_chart->income_accno_id($income_accno->id); + $taxzone_chart->expense_accno_id($expense_accno->id); + $taxzone_chart->save; + } } - } + } ) || die @errors ? join("\n", @errors) . "\n" : $db->error . "\n"; + # die with rollback of taxzone save if saving of any of the taxzone_charts fails + # only show the $db->error if we haven't already identified the likely error ourselves flash_later('info', $is_new ? t8('The taxzone has been created.') : t8('The taxzone has been saved.')); $self->redirect_to(action => 'list'); diff --git a/SL/DB/TaxZone.pm b/SL/DB/TaxZone.pm index ad96ee259..6545d0854 100644 --- a/SL/DB/TaxZone.pm +++ b/SL/DB/TaxZone.pm @@ -23,4 +23,18 @@ sub validate { return @errors; } +sub orphaned { + my ($self) = @_; + die 'not an accessor' if @_ > 1; + + my @classes = qw(Customer Vendor Invoice Order DeliveryOrder PurchaseInvoice); + foreach my $class ( @classes ) { + my $module = 'SL::DB::' . $class; + eval "require $module"; + my $manager = 'SL::DB::Manager::' . $class; + return 0 if $manager->get_all_count( query => [ taxzone_id => $self->id ] ); + }; + return 1; +} + 1; diff --git a/locale/de/all b/locale/de/all index 2c0905f52..50018d8a7 100755 --- a/locale/de/all +++ b/locale/de/all @@ -416,6 +416,8 @@ $self->{texts} = { 'Break up the update and contact a service provider.' => 'Diese Option bricht das Update ab. Bitte kontaktieren Sie Ihren Administrator oder beauftragen einen Dienstleister.', 'Buchungsdatum' => 'Buchungsdatum', 'Buchungsgruppe' => 'Buchungsgruppe', + 'Buchungsgruppe #1 needs a valid expense account' => 'Buchungsgruppe #1 braucht ein gültiges Aufwandskonto', + 'Buchungsgruppe #1 needs a valid income account' => 'Buchungsgruppe #1 braucht ein gültiges Erfolgskonto', 'Buchungsgruppe (database ID)' => 'Buchungsgruppe (Datenbank-ID)', 'Buchungsgruppe (name)' => 'Buchungsgruppe (Name)', 'Buchungsgruppen' => 'Buchungsgruppen', @@ -2807,6 +2809,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 tax zone has been deleted.' => 'Die Steuerzone wurde gelöscht.', + 'The tax zone is in use and cannot be deleted.' => 'Die Steuerzone wird benutzt und kann nicht gelöscht werden', '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.', diff --git a/templates/webpages/taxzones/form.html b/templates/webpages/taxzones/form.html index bce8371f4..b12739962 100644 --- a/templates/webpages/taxzones/form.html +++ b/templates/webpages/taxzones/form.html @@ -12,18 +12,22 @@ [%- FOREACH bg = BUCHUNGSGRUPPEN %] [% 'Revenue' | $T8 %] [% HTML.escape(bg.description) %] - [%- IF SELF.config.id %] - [% CHARTLIST.${bg.id}.income_accno %] -- [% CHARTLIST.${bg.id}.income_accno_description %] - [%- ELSE %] + [%- IF NOT SELF.config.id %] [% L.chart_picker('income_accno_id_' _ bg.id, SELF.defaults.income_accno_id, choose=1, type='IC_income,IC_sale', style=style) %] + [%- ELSIF SELF.config.id AND SELF.config.orphaned %] + [% L.chart_picker('income_accno_id_' _ bg.id, CHARTLIST.${bg.id}.income_accno_id, choose=1, type='IC_income,IC_sale', style=style) %] + [%- ELSE %] + [% CHARTLIST.${bg.id}.income_accno %] -- [% CHARTLIST.${bg.id}.income_accno_description %] [%- END %] [% 'Expense' | $T8 %] [% HTML.escape(bg.description) %] - [%- IF SELF.config.id %] - [% CHARTLIST.${bg.id}.expense_accno %] -- [% CHARTLIST.${bg.id}.expense_accno_description %] - [%- ELSE %] + [%- IF NOT SELF.config.id %] [% L.chart_picker('expense_accno_id_' _ bg.id, SELF.defaults.expense_accno_id, choose=1, type='IC_expense,IC_cogs', style=style) %] + [%- ELSIF SELF.config.id AND SELF.config.orphaned %] + [% L.chart_picker('expense_accno_id_' _ bg.id, CHARTLIST.${bg.id}.expense_accno_id, choose=1, type='IC_expense,IC_cogs', style=style) %] + [%- ELSE %] + [% CHARTLIST.${bg.id}.expense_accno %] -- [% CHARTLIST.${bg.id}.expense_accno_description %] [%- END %] [%- END %] @@ -34,6 +38,9 @@

[% L.hidden_tag("action", "Taxzones/dispatch") %] [% L.submit_tag("action_" _ (SELF.config.id ? "update" : "create"), LxERP.t8('Save'), onclick="return check_prerequisites();") %] + [%- IF SELF.config.id AND SELF.config.orphaned %] + [% L.submit_tag("action_delete", LxERP.t8('Delete'), confirm=LxERP.t8('Are you sure?')) %] + [%- END %] [%- LxERP.t8("Cancel") %]