CsvImport Taxzone für CustomerVendor und Order
authorG. Richardson <information@kivitendo-premium.de>
Fri, 16 Jan 2015 12:26:24 +0000 (13:26 +0100)
committerG. Richardson <information@kivitendo-premium.de>
Fri, 16 Jan 2015 12:26:24 +0000 (13:26 +0100)
check_taxzone aus Order nach CsvImport/Helper/Consistency.pm ausgelagert
und um die Option take_default für CustomerVendor Import erweitert.

Behebt Ticket 9.

SL/Controller/CsvImport.pm
SL/Controller/CsvImport/CustomerVendor.pm
SL/Controller/CsvImport/Helper/Consistency.pm
SL/Controller/CsvImport/Order.pm
locale/de/all
templates/webpages/csv_import/_form_customers_vendors.html

index 25558b9..088e8c3 100644 (file)
@@ -27,7 +27,7 @@ use parent qw(SL::Controller::Base);
 use Rose::Object::MakeMethods::Generic
 (
  scalar                  => [ qw(type profile file all_profiles all_charsets sep_char all_sep_chars quote_char all_quote_chars escape_char all_escape_chars all_buchungsgruppen all_units
-                                 import_status errors headers raw_data_headers info_headers data num_imported num_importable displayable_columns file) ],
+                                 import_status errors headers raw_data_headers info_headers data num_imported num_importable displayable_columns file all_taxzones) ],
  'scalar --get_set_init' => [ qw(worker task_server) ],
  'array'                 => [
    progress_tracker     => { },
@@ -267,6 +267,10 @@ sub render_inputs {
             : $self->type eq 'orders'            ? $::locale->text('CSV import: orders')
             : die;
 
+  if ($self->{type} eq 'customers_vendors' or $self->{type} eq 'orders'  ) {
+    $self->all_taxzones(SL::DB::Manager::TaxZone->get_all_sorted(query => [ obsolete => 0 ]));
+  };
+
   if ($self->{type} eq 'parts') {
     $self->all_buchungsgruppen(SL::DB::Manager::Buchungsgruppe->get_all_sorted);
     $self->all_units(SL::DB::Manager::Unit->get_all_sorted);
index 7d37904..0a5c121 100644 (file)
@@ -67,13 +67,14 @@ sub check_objects {
     $self->check_business($entry);
     $self->check_payment($entry);
     $self->check_delivery_term($entry);
+    $self->check_taxzone($entry,  take_default => 1);
     $self->check_currency($entry, take_default => 1);
     $self->handle_cvars($entry);
 
     next if @{ $entry->{errors} };
 
     my @cleaned_fields = $self->clean_fields(qr{[\r\n]}, $object, qw(name department_1 department_2 street zipcode city country contact phone fax homepage email cc bcc
-                                                                     taxnumber account_number bank_code bank username greeting));
+                                                                     taxnumber account_number bank_code bank username greeting taxzone));
 
     push @{ $entry->{information} }, $::locale->text('Illegal characters have been removed from the following fields: #1', join(', ', @cleaned_fields))
       if @cleaned_fields;
@@ -100,7 +101,7 @@ sub check_objects {
     $i++;
   }
 
-  $self->add_columns(map { "${_}_id" } grep { exists $self->controller->data->[0]->{raw_data}->{$_} } qw(language business payment delivery_term));
+  $self->add_columns(map { "${_}_id" } grep { exists $self->controller->data->[0]->{raw_data}->{$_} } qw(language business payment delivery_term taxzone));
   $self->add_cvar_raw_data_columns;
 }
 
@@ -267,7 +268,8 @@ sub setup_displayable_columns {
                                  { name => 'phone',             description => $::locale->text('Phone')                           },
                                  { name => 'street',            description => $::locale->text('Street')                          },
                                  { name => 'taxnumber',         description => $::locale->text('Tax Number / SSN')                },
-                                 { name => 'taxzone_id',        description => $::locale->text('Steuersatz')                      },
+                                 { name => 'taxzone',           description => $::locale->text('Tax zone (description)')          },
+                                 { name => 'taxzone_id',        description => $::locale->text('Tax zone (database ID)')          },
                                  { name => 'user_password',     description => $::locale->text('Password')                        },
                                  { name => 'username',          description => $::locale->text('Username')                        },
                                  { name => 'ustid',             description => $::locale->text('sales tax identification number') },
index bf1d4c0..36120a7 100644 (file)
@@ -4,11 +4,12 @@ use strict;
 
 use SL::DB::Default;
 use SL::DB::Currency;
+use SL::DB::TaxZone;
 
 use SL::Helper::Csv::Error;
 
 use parent qw(Exporter);
-our @EXPORT = qw(check_currency);
+our @EXPORT = qw(check_currency check_taxzone);
 
 #
 # public functions
@@ -47,6 +48,64 @@ sub check_currency {
   return 1;
 }
 
+sub check_taxzone {
+  my ($self, $entry, %params) = @_;
+
+  my $object = $entry->{object};
+
+  # Check whether the CSV contains the parameters taxzone_id or taxzone, and
+  # check them for validity. 
+  # If one of them was given, but is invalid, return an error
+
+  # If neither was given:
+  # a) if param take_default was set, use the taxzone_id from the profile
+  #    (customer/vendor import)
+  # b) if param take_default was not set, do nothing, return without error, and
+  #    taxzone_id may be set later by other means (order import uses cv settings)
+
+  # if $object->taxzone_id is defined (from CSV line), check if it is valid
+  if ($object->taxzone_id && ! _taxzones_by($self)->{id}->{ $object->taxzone_id }) {
+    push @{ $entry->{errors} }, $::locale->text('Error: Invalid tax zone');
+    return 0;
+  }
+
+  # if there was no taxzone_id in CSV, but a taxzone entry, check if it is a
+  # valid taxzone and set the id
+  if (!$object->taxzone_id && $entry->{raw_data}->{taxzone}) {
+    my $taxzone = _taxzones_by($self)->{description}->{ $entry->{raw_data}->{taxzone} };
+    if (!$taxzone) {
+      push @{ $entry->{errors} }, $::locale->text('Error: Invalid tax zone');
+      return 0;
+    }
+
+    $object->taxzone_id($taxzone->id);
+  }
+
+  # The take_default option should only be used for the customer/vendor case,
+  # as the default for imported orders is the taxzone according to the customer
+  # or vendor
+  # if neither taxzone_id nor taxzone were defined, use the default taxzone as
+  # defined from the import settings (a default/fallback taxzone that is to be
+  # used will always be selected)
+
+  if (!$object->taxzone_id && $params{take_default}) {
+    # my $default_id = $self->settings->{'default_taxzone'};
+    my $default_id = $self->controller->profile->get('default_taxzone');
+    $object->taxzone_id($default_id);
+    # check if default taxzone_id is valid just to be sure
+    if (! _taxzones_by($self)->{id}->{ $object->taxzone_id }) {
+      push @{ $entry->{errors} }, $::locale->text('Error with default taxzone');
+      return 0;
+    };
+  };
+
+  # for the order import at this stage $object->taxzone_id may still not be
+  # defined, in this case the customer/vendor taxzone will be used. 
+
+  return 1;
+}
+
 #
 # private functions
 #
@@ -69,4 +128,16 @@ sub _default_currency_id {
   return SL::DB::Default->get->currency_id;
 }
 
+sub _taxzones_by {
+  my ($self) = @_;
+
+  return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ _all_taxzones($self) } } ) } qw(id description) };
+}
+
+sub _all_taxzones {
+  my ($self) = @_;
+
+  return SL::DB::Manager::TaxZone->get_all_sorted(query => [ obsolete => 0 ]);
+}
+
 1;
index 31c786f..2f6b4e7 100644 (file)
@@ -25,7 +25,7 @@ use parent qw(SL::Controller::CsvImport::BaseMulti);
 
 use Rose::Object::MakeMethods::Generic
 (
- 'scalar --get_set_init' => [ qw(settings languages_by parts_by contacts_by departments_by projects_by ct_shiptos_by taxzones_by price_factors_by pricegroups_by) ],
+ 'scalar --get_set_init' => [ qw(settings languages_by parts_by contacts_by departments_by projects_by ct_shiptos_by price_factors_by pricegroups_by) ],
 );
 
 
@@ -227,13 +227,6 @@ sub init_ct_shiptos_by {
   return $sby;
 }
 
-sub init_taxzones_by {
-  my ($self) = @_;
-
-  my $all_taxzones = SL::DB::Manager::TaxZone->get_all;
-  return { map { my $col = $_; ( $col => { map { ( $_->$col => $_ ) } @{ $all_taxzones } } ) } qw(id description) };
-}
-
 sub init_price_factors_by {
   my ($self) = @_;
 
@@ -574,31 +567,6 @@ sub check_ct_shipto {
   return 1;
 }
 
-sub check_taxzone {
-  my ($self, $entry) = @_;
-
-  my $object = $entry->{object};
-
-  # Check wether or not taxzone ID is valid.
-  if ($object->taxzone_id && !$self->taxzones_by->{id}->{ $object->taxzone_id }) {
-    push @{ $entry->{errors} }, $::locale->text('Error: Invalid tax zone');
-    return 0;
-  }
-
-  # Map description to ID if given.
-  if (!$object->taxzone_id && $entry->{raw_data}->{taxzone}) {
-    my $taxzone = $self->taxzones_by->{description}->{ $entry->{raw_data}->{taxzone} };
-    if (!$taxzone) {
-      push @{ $entry->{errors} }, $::locale->text('Error: Invalid tax zone');
-      return 0;
-    }
-
-    $object->taxzone_id($taxzone->id);
-  }
-
-  return 1;
-}
-
 sub check_price_factor {
   my ($self, $entry) = @_;
 
index a423e1a..942b361 100755 (executable)
@@ -775,6 +775,7 @@ $self->{texts} = {
   'Default hourly rate for new customers' => 'Standard-Stundensatz für neue Kunden',
   'Default output medium'       => 'Standardausgabekanal',
   'Default printer'             => 'Standarddrucker',
+  'Default taxzone'             => 'Standardsteuerzone',
   'Default template format'     => 'Standardvorlagenformat',
   'Default transport article number' => 'Standard Versand / Transport-Erinnerungs-Artikel',
   'Default unit'                => 'Standardeinheit',
@@ -1040,6 +1041,7 @@ $self->{texts} = {
   'Error message from the database driver:' => 'Fehlermeldung des Datenbanktreibers:',
   'Error message from the database: #1' => 'Fehlermeldung der Datenbank: #1',
   'Error when saving: #1'       => 'Fehler beim Speichern: #1',
+  'Error with default taxzone'  => 'Ungültige Standardsteuerzone',
   'Error!'                      => 'Fehler!',
   'Error: Buchungsgruppe missing or invalid' => 'Fehler: Buchungsgruppe fehlt oder ungültig',
   'Error: Customer/vendor missing' => 'Fehler: Kunde/Lieferant fehlt',
index 960ef5c..4498565 100644 (file)
   [% L.select_tag('settings.update_policy', opts, default = SELF.profile.get('update_policy'), style = 'width: 300px') %]
  </td>
 </tr>
+
+<tr>
+ <th align="right" valign="top">[%- LxERP.t8('Default taxzone') %]:</th>
+ <td colspan="10" valign="top">
+  [% L.select_tag('settings.default_taxzone', SELF.all_taxzones, default = SELF.profile.get('default_taxzone'), title_key = 'description', style => 'width: 300px') %]
+ </td>
+</tr>
+