Revision cd3150ed
Von Bernd Bleßmann vor mehr als 10 Jahren hinzugefügt
SL/Controller/CsvImport/Part.pm | ||
---|---|---|
16 | 16 |
use SL::DB::Translation; |
17 | 17 |
use SL::DB::Unit; |
18 | 18 |
|
19 |
use List::MoreUtils qw(none); |
|
20 |
|
|
19 | 21 |
use parent qw(SL::Controller::CsvImport::Base); |
20 | 22 |
|
21 | 23 |
use Rose::Object::MakeMethods::Generic |
... | ... | |
204 | 206 |
my $object = $entry->{object}; |
205 | 207 |
|
206 | 208 |
if ($object->partnumber && $self->parts_by->{partnumber}{$object->partnumber}) { |
207 |
$entry->{part} = SL::DB::Manager::Part->find_by( |
|
208 |
SL::DB::Manager::Part->type_filter($object->type), |
|
209 |
( partnumber => $object->partnumber ) x!! $object->partnumber, |
|
210 |
); |
|
209 |
$entry->{part} = SL::DB::Manager::Part->find_by(partnumber => $object->partnumber); |
|
211 | 210 |
} |
212 | 211 |
|
213 | 212 |
if ($entry->{part}) { |
214 | 213 |
if ($self->settings->{article_number_policy} eq 'update_prices') { |
215 |
map { $entry->{part}->$_( $object->$_ ) if defined $object->$_ } qw(sellprice listprice lastcost); |
|
214 |
if ($self->settings->{parts_type} eq 'mixed' && $entry->{part}->type ne $object->type) { |
|
215 |
push(@{$entry->{errors}}, $::locale->text('Skipping due to existing entry in database with different type')); |
|
216 |
} else { |
|
217 |
map { $entry->{part}->$_( $object->$_ ) if defined $object->$_ } qw(sellprice listprice lastcost); |
|
216 | 218 |
|
217 |
# merge prices |
|
218 |
my %prices_by_pricegroup_id = map { $_->pricegroup->id => $_ } $entry->{part}->prices, $object->prices; |
|
219 |
$entry->{part}->prices(grep { $_ } map { $prices_by_pricegroup_id{$_->id} } @{ $self->all_pricegroups }); |
|
219 |
# merge prices
|
|
220 |
my %prices_by_pricegroup_id = map { $_->pricegroup->id => $_ } $entry->{part}->prices, $object->prices;
|
|
221 |
$entry->{part}->prices(grep { $_ } map { $prices_by_pricegroup_id{$_->id} } @{ $self->all_pricegroups });
|
|
220 | 222 |
|
221 |
push @{ $entry->{information} }, $::locale->text('Updating prices of existing entry in database'); |
|
222 |
$entry->{object_to_save} = $entry->{part}; |
|
223 |
push @{ $entry->{information} }, $::locale->text('Updating prices of existing entry in database'); |
|
224 |
$entry->{object_to_save} = $entry->{part}; |
|
225 |
} |
|
223 | 226 |
} elsif ( $self->settings->{article_number_policy} eq 'skip' ) { |
224 | 227 |
push(@{$entry->{errors}}, $::locale->text('Skipping due to existing entry in database')); |
228 |
|
|
225 | 229 |
} else { |
226 | 230 |
$object->partnumber('####'); |
231 |
push(@{$entry->{errors}}, $::locale->text('Skipping, for assemblies are not importable (yet)')) if $object->type eq 'assembly'; |
|
227 | 232 |
} |
233 |
} else { |
|
234 |
push(@{$entry->{errors}}, $::locale->text('Skipping, for assemblies are not importable (yet)')) if $object->type eq 'assembly'; |
|
228 | 235 |
} |
229 | 236 |
} |
230 | 237 |
|
231 |
|
|
232 | 238 |
sub handle_prices { |
233 | 239 |
my ($self, $entry) = @_; |
234 | 240 |
|
... | ... | |
258 | 264 |
if ($type eq 'mixed') { |
259 | 265 |
$type = $entry->{raw_data}->{type} =~ m/^p/i ? 'part' |
260 | 266 |
: $entry->{raw_data}->{type} =~ m/^s/i ? 'service' |
267 |
: $entry->{raw_data}->{type} =~ m/^a/i ? 'assembly' |
|
261 | 268 |
: undef; |
262 | 269 |
} |
263 | 270 |
|
264 |
$entry->{object}->income_accno_id( $bg->income_accno_id_0 ); |
|
265 |
$entry->{object}->expense_accno_id( $bg->expense_accno_id_0 ); |
|
271 |
$entry->{object}->assembly($type eq 'assembly'); |
|
272 |
|
|
273 |
$entry->{object}->income_accno_id( $bg->income_accno_id_0 ); |
|
274 |
|
|
275 |
if ($type eq 'part' || $type eq 'service') { |
|
276 |
$entry->{object}->expense_accno_id( $bg->expense_accno_id_0 ); |
|
277 |
} |
|
266 | 278 |
|
267 | 279 |
if ($type eq 'part') { |
268 | 280 |
$entry->{object}->inventory_accno_id( $bg->inventory_accno_id ); |
281 |
} |
|
282 |
|
|
269 | 283 |
|
270 |
} elsif ($type ne 'service') {
|
|
284 |
if (none { $_ eq $type } qw(part service assembly)) {
|
|
271 | 285 |
push @{ $entry->{errors} }, $::locale->text('Error: Invalid part type'); |
272 | 286 |
return 0; |
273 | 287 |
} |
locale/de/all | ||
---|---|---|
251 | 251 |
'Article type' => 'Artikeltyp', |
252 | 252 |
'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önnen die gespeicherten Mengen entweder in ein Lager überführt werden, oder für eine frische Lagerverwaltung resettet werden.', |
253 | 253 |
'Assemblies' => 'Erzeugnisse', |
254 |
'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.', |
|
254 | 255 |
'Assembly' => 'Erzeugnis', |
255 | 256 |
'Assembly Description' => 'Erzeugnis-Beschreibung', |
256 | 257 |
'Assembly Number' => 'Erzeugnis-Nummer', |
... | ... | |
2151 | 2152 |
'Skip' => 'Überspringen', |
2152 | 2153 |
'Skip entry' => 'Eintrag überspringen', |
2153 | 2154 |
'Skipping due to existing entry in database' => 'Wegen existierendem Eintrag mit selber Nummer übersprungen', |
2155 |
'Skipping due to existing entry in database with different type' => 'Wegen existierendem Eintrag von unterschiedlichem Artikeltyp übersprungen', |
|
2156 |
'Skipping, for assemblies are not importable (yet)' => 'Übersprungen, da Erzeugnisse (noch) nicht importiert werden können', |
|
2154 | 2157 |
'Skonto' => 'Skonto', |
2155 | 2158 |
'Skonto Terms' => 'Zahlungsziel Skonto', |
2156 | 2159 |
'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 | 2653 |
'Trial balance between %s and %s' => 'Summen- und Saldenlisten vom %s bis zum %s', |
2651 | 2654 |
'Trying to call a sub without a name' => 'Es wurde versucht, eine Unterfunktion ohne Namen aufzurufen.', |
2652 | 2655 |
'Type' => 'Typ', |
2653 |
'Type can be either \'part\' or \'service\'.' => 'Der Typ kann entweder \'part\' (für Waren) oder \'service\' (für Dienstleistungen) enthalten.',
|
|
2656 |
'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.',
|
|
2654 | 2657 |
'Type of Business' => 'Kunden-/Lieferantentyp', |
2655 | 2658 |
'Type of Customer' => 'Kundentyp', |
2656 | 2659 |
'Type of Vendor' => 'Lieferantentyp', |
locale/en/all | ||
---|---|---|
232 | 232 |
'Article type' => '', |
233 | 233 |
'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' => '', |
234 | 234 |
'Assemblies' => '', |
235 |
'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.' => '', |
|
235 | 236 |
'Assembly' => '', |
236 | 237 |
'Assembly Description' => '', |
237 | 238 |
'Assembly Number' => '', |
... | ... | |
2345 | 2346 |
'Trial balance between %s and %s' => '', |
2346 | 2347 |
'Trying to call a sub without a name' => '', |
2347 | 2348 |
'Type' => '', |
2348 |
'Type can be either \'part\' or \'service\'.' => '',
|
|
2349 |
'Type can be either \'part\', \'service\' or \'assembly\'.' => '',
|
|
2349 | 2350 |
'Type of Business' => '', |
2350 | 2351 |
'Type of Customer' => '', |
2351 | 2352 |
'Type of Vendor' => '', |
templates/webpages/csv_import/form.html | ||
---|---|---|
127 | 127 |
<p> |
128 | 128 |
[3]: |
129 | 129 |
[% LxERP.t8("If the article type is set to 'mixed' then a column called 'type' must be present.") %] |
130 |
[% LxERP.t8("Type can be either 'part' or 'service'.") %] |
|
130 |
[% LxERP.t8("Type can be either 'part', 'service' or 'assembly'.") %] |
|
131 |
[% 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.") %] |
|
131 | 132 |
</p> |
132 | 133 |
|
133 | 134 |
[%- ELSIF SELF.type == 'orders' %] |
Auch abrufbar als: Unified diff
CsvImport Waren: Preisupdate auch bei Erzeugnissen u. Dienstleistungen ermöglichen.
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.