]> wagnertech.de Git - kivitendo-erp.git/commitdiff
CsvImport Waren: Preisupdate auch bei Erzeugnissen u. Dienstleistungen ermöglichen.
authorBernd Bleßmann <bernd@kivitendo-premium.de>
Wed, 14 May 2014 14:13:40 +0000 (16:13 +0200)
committerBernd Bleßmann <bernd@kivitendo-premium.de>
Wed, 14 May 2014 14:54:01 +0000 (16:54 +0200)
Zusätzlich beim Preisupdate prüfen, ob vorhandene Artikel von einem anderen Typ
als angegeben sind, falls in der CSV-Datei angegeben.

Problem war, dass Artikelnummern jetzt über Waren, Dienstleistungen und
Erzeugnisse eindeutig sind. Um aber schon vorhandene Artikel zu finden,
wurde nur nach dem angegenbenen oder eingestellten Typ gesucht. Der
voreingestellte Typ ist Waren, dabei werden Dienstleistungen und Erzeugnisse
nicht gefunden und es wurde versucht, den entspr. Eintrag neu als Ware
anzulegen, allerdings ist die Artikelnummer ja schon vergeben und es kam zu
einem DB-Fehler.

SL/Controller/CsvImport/Part.pm
locale/de/all
locale/en/all
templates/webpages/csv_import/form.html

index 8b9cb133505497fca30dd759e59a9594b1b21155..34bdd73655e637d61b19d5ebb2c4059a4dfa2f0d 100644 (file)
@@ -16,6 +16,8 @@ use SL::DB::Price;
 use SL::DB::Translation;
 use SL::DB::Unit;
 
+use List::MoreUtils qw(none);
+
 use parent qw(SL::Controller::CsvImport::Base);
 
 use Rose::Object::MakeMethods::Generic
@@ -204,31 +206,35 @@ sub check_existing {
   my $object = $entry->{object};
 
   if ($object->partnumber && $self->parts_by->{partnumber}{$object->partnumber}) {
-    $entry->{part} = SL::DB::Manager::Part->find_by(
-      SL::DB::Manager::Part->type_filter($object->type),
-      ( partnumber => $object->partnumber )                 x!! $object->partnumber,
-    );
+    $entry->{part} = SL::DB::Manager::Part->find_by(partnumber => $object->partnumber);
   }
 
   if ($entry->{part}) {
     if ($self->settings->{article_number_policy} eq 'update_prices') {
-      map { $entry->{part}->$_( $object->$_ ) if defined $object->$_ } qw(sellprice listprice lastcost);
+      if ($self->settings->{parts_type} eq 'mixed' && $entry->{part}->type ne $object->type) {
+        push(@{$entry->{errors}}, $::locale->text('Skipping due to existing entry in database with different type'));
+      } else {
+        map { $entry->{part}->$_( $object->$_ ) if defined $object->$_ } qw(sellprice listprice lastcost);
 
-      # merge prices
-      my %prices_by_pricegroup_id = map { $_->pricegroup->id => $_ } $entry->{part}->prices, $object->prices;
-      $entry->{part}->prices(grep { $_ } map { $prices_by_pricegroup_id{$_->id} } @{ $self->all_pricegroups });
+        # merge prices
+        my %prices_by_pricegroup_id = map { $_->pricegroup->id => $_ } $entry->{part}->prices, $object->prices;
+        $entry->{part}->prices(grep { $_ } map { $prices_by_pricegroup_id{$_->id} } @{ $self->all_pricegroups });
 
-      push @{ $entry->{information} }, $::locale->text('Updating prices of existing entry in database');
-      $entry->{object_to_save} = $entry->{part};
+        push @{ $entry->{information} }, $::locale->text('Updating prices of existing entry in database');
+        $entry->{object_to_save} = $entry->{part};
+      }
     } elsif ( $self->settings->{article_number_policy} eq 'skip' ) {
       push(@{$entry->{errors}}, $::locale->text('Skipping due to existing entry in database'));
+
     } else {
       $object->partnumber('####');
+      push(@{$entry->{errors}}, $::locale->text('Skipping, for assemblies are not importable (yet)')) if $object->type eq 'assembly';
     }
+  } else {
+    push(@{$entry->{errors}}, $::locale->text('Skipping, for assemblies are not importable (yet)')) if $object->type eq 'assembly';
   }
 }
 
-
 sub handle_prices {
   my ($self, $entry) = @_;
 
@@ -258,16 +264,24 @@ sub check_type {
   if ($type eq 'mixed') {
     $type = $entry->{raw_data}->{type} =~ m/^p/i ? 'part'
           : $entry->{raw_data}->{type} =~ m/^s/i ? 'service'
+          : $entry->{raw_data}->{type} =~ m/^a/i ? 'assembly'
           :                                        undef;
   }
 
-  $entry->{object}->income_accno_id(  $bg->income_accno_id_0 );
-  $entry->{object}->expense_accno_id( $bg->expense_accno_id_0 );
+  $entry->{object}->assembly($type eq 'assembly');
+
+  $entry->{object}->income_accno_id( $bg->income_accno_id_0 );
+
+  if ($type eq 'part' || $type eq 'service') {
+    $entry->{object}->expense_accno_id( $bg->expense_accno_id_0 );
+  }
 
   if ($type eq 'part') {
     $entry->{object}->inventory_accno_id( $bg->inventory_accno_id );
+  }
+
 
-  } elsif ($type ne 'service') {
+  if (none { $_ eq $type } qw(part service assembly)) {
     push @{ $entry->{errors} }, $::locale->text('Error: Invalid part type');
     return 0;
   }
index 5fb5508f48bacc3565f6227534378b69e83a3537..9c2a9fc17235f10a91a5bf57f402d3c19a3d162b 100755 (executable)
@@ -251,6 +251,7 @@ $self->{texts} = {
   'Article type'                => 'Artikeltyp',
   'As a result, the saved onhand values of the present goods can be stored into a warehouse designated by you, or will be reset for a proper warehouse tracking' => 'Als Konsequenz k&ouml;nnen die gespeicherten Mengen entweder in ein Lager &uuml;berf&uuml;hrt werden, oder f&uuml;r eine frische Lagerverwaltung resettet werden.',
   'Assemblies'                  => 'Erzeugnisse',
+  'Assemblies can not be imported (yet). But the type column is used for sanity checks on price updates in order to prevent that articles with the wrong type will be updated.' => 'Erzeugnisse können (noch) nicht importiert werden. Aber die Typ-Spalte wird für Plausibilitätsprüfungen bei Preisaktualisierungen verwendet, um zu verhindern, dass Artikel vom falschen Typ aktualisiert werden.',
   'Assembly'                    => 'Erzeugnis',
   'Assembly Description'        => 'Erzeugnis-Beschreibung',
   'Assembly Number'             => 'Erzeugnis-Nummer',
@@ -2151,6 +2152,8 @@ $self->{texts} = {
   'Skip'                        => 'Überspringen',
   'Skip entry'                  => 'Eintrag überspringen',
   'Skipping due to existing entry in database' => 'Wegen existierendem Eintrag mit selber Nummer übersprungen',
+  'Skipping due to existing entry in database with different type' => 'Wegen existierendem Eintrag von unterschiedlichem Artikeltyp übersprungen',
+  'Skipping, for assemblies are not importable (yet)' => 'Übersprungen, da Erzeugnisse (noch) nicht importiert werden können',
   'Skonto'                      => 'Skonto',
   'Skonto Terms'                => 'Zahlungsziel Skonto',
   'So far you could use one partnumber for severel parts, for example a service and an article.' => 'Bisher war es möglich eine Artikelnummer für mehrere Artikel zu verwenden, zum Beispiel eine Artikelnummer für eine Dienstleistung, eine Ware und ein Erzeugnis.',
@@ -2650,7 +2653,7 @@ $self->{texts} = {
   'Trial balance between %s and %s' => 'Summen- und Saldenlisten vom %s bis zum %s',
   'Trying to call a sub without a name' => 'Es wurde versucht, eine Unterfunktion ohne Namen aufzurufen.',
   'Type'                        => 'Typ',
-  'Type can be either \'part\' or \'service\'.' => 'Der Typ kann entweder \'part\' (für Waren) oder \'service\' (für Dienstleistungen) enthalten.',
+  'Type can be either \'part\', \'service\' or \'assembly\'.' => 'Der Typ kann entweder \'part\' (für Waren), \'service\' (für Dienstleistungen) oder \'assembly\' (für Erzeugnisse) enthalten.',
   'Type of Business'            => 'Kunden-/Lieferantentyp',
   'Type of Customer'            => 'Kundentyp',
   'Type of Vendor'              => 'Lieferantentyp',
index af1bf991de8d3c0148d8a62f124425b4268fa77e..30a729adc6214f290b151b95ae6ec3d3f1109d27 100644 (file)
@@ -232,6 +232,7 @@ $self->{texts} = {
   'Article type'                => '',
   'As a result, the saved onhand values of the present goods can be stored into a warehouse designated by you, or will be reset for a proper warehouse tracking' => '',
   'Assemblies'                  => '',
+  'Assemblies can not be imported (yet). But the type column is used for sanity checks on price updates in order to prevent that articles with the wrong type will be updated.' => '',
   'Assembly'                    => '',
   'Assembly Description'        => '',
   'Assembly Number'             => '',
@@ -2345,7 +2346,7 @@ $self->{texts} = {
   'Trial balance between %s and %s' => '',
   'Trying to call a sub without a name' => '',
   'Type'                        => '',
-  'Type can be either \'part\' or \'service\'.' => '',
+  'Type can be either \'part\', \'service\' or \'assembly\'.' => '',
   'Type of Business'            => '',
   'Type of Customer'            => '',
   'Type of Vendor'              => '',
index cbe49771ddf4e36c532b0ac76930954c68af668a..24af07e5b8706d68a1932b086f4853a9a78095a1 100644 (file)
    <p>
     [3]:
     [% LxERP.t8("If the article type is set to 'mixed' then a column called 'type' must be present.") %]
-    [% LxERP.t8("Type can be either 'part' or 'service'.") %]
+    [% LxERP.t8("Type can be either 'part', 'service' or 'assembly'.") %]
+    [% LxERP.t8("Assemblies can not be imported (yet). But the type column is used for sanity checks on price updates in order to prevent that articles with the wrong type will be updated.") %]
    </p>
 
 [%- ELSIF SELF.type == 'orders' %]