Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision a1c5130b

Von Tamino Steinert vor 10 Monaten hinzugefügt

  • ID a1c5130b2018453fe7a0aa0904f4b3b2c860219a
  • Vorgänger 051db7cc
  • Nachfolger d4b19075

kuw: CSV-Import-Script angepasst

Unterschiede anzeigen:

scripts/import_variant_csv.pl
13 13

  
14 14
use Data::Dumper;
15 15
use List::Util qw(first);
16
use List::MoreUtils qw(any);
16 17
use File::Basename;
17 18

  
18 19
use SL::DBUtils;
......
93 94
  VK                      => 'sellprice',
94 95
  EANNR                   => 'ean',
95 96
  EIGENEARTIKELNR         => 'description',
96
  WAR_KURZBEZEICHNUNG     => 'warengruppe',
97
  WARENGRUPPE             => 'warengruppe_nummer',
98
  WAR_KURZBEZEICHNUNG     => 'warengruppe_name',
97 99
  GROESSE                 => 'varianten_groesse',
98 100
  LAENGE                  => 'varianten_laenge',
99 101
  FARBNR                  => 'varianten_farbnummer',
100 102
  INFO1                   => 'varianten_farbname',
101 103
  ARTIKELNR               => 'makemodel_model',
102
  LIEFERANT               => 'vendor_name',
104
  LST_ID                  => 'vendor_number',
103 105
  FIL_KURZBEZEICHNUNG     => 'warehouse_description',
104 106
  STUECK                  => 'part_qty',
105 107
);
......
152 154
my $part_hrefs = $part_csv->get_data;
153 155

  
154 156
my %parent_variants_to_variants;
157
my $row = 0;
155 158
foreach my $part_row (@$part_hrefs) {
156 159
  my %part =
157 160
    map {$parts_mapping{$_} => $part_row->{$_}}
158 161
    grep {$part_row->{$_}}
159 162
    keys %parts_mapping;
163
  $part{csv_row} = $row++;
160 164

  
161 165
  if ($part{varianten_farbnummer} || $part{varianten_farbname}) {
162 166
    $part{varianten_farbnummer} ||= '';
......
164 168
    $part{varianten_farbe} = (delete $part{varianten_farbnummer}) . '-' . (delete $part{varianten_farbname});
165 169
  }
166 170

  
171
  if ($part{varianten_groesse}) {
172
    # map to valid sizes
173
    unless ($part{warengruppe_nummer} eq '114310' || $part{warengruppe_nummer} eq '124310') { # nicht für gürtel
174
      $part{varianten_groesse} =~ s/^([0-9][0-9])5$/$1,5/; # 345 -> 34,5
175
    }
176
    $part{varianten_groesse} =~ s/^([0-9][0-9])\.5$/$1,5/; # 34.5 -> 34,5
177
    $part{varianten_groesse} =~ s/^2XL$/XXL/;
178
    $part{varianten_groesse} =~ s/^XXXL$/3XL/;
179
    $part{varianten_groesse} =~ s/^([0-9]*)½$/$1 ½/;
180
    $part{varianten_groesse} =~ s/^([0-9]*)\/½$/$1 ½/;
181
    $part{varianten_groesse} =~ s/^([0-9]*) 1\/2$/$1 ½/;
182
    $part{varianten_groesse} =~ s/\/U//; # 34/U -> 34
183
    $part{varianten_groesse} =~ s/\/I//; # 34/I -> 34
184
    $part{varianten_groesse} =~ s/\/M//; # 34/M -> 34
185
    $part{varianten_groesse} =~ s/\/L//; # 34/L -> 34
186
    $part{varianten_groesse} =~ s/\/XL//; # 34/XL -> 34
187
    $part{varianten_groesse} =~ s/\/XX//; # 34/XX -> 34
188

  
189
    if (any {$part{varianten_groesse} eq $_} ('.', '_', 'ONE', 'ONE S', 'ONES', 'OSFA', 'ONESI', 'O/S', 'OSO')) {
190
      delete $part{varianten_groesse};
191
    }
192
    if ($part{warengruppe_nummer} eq '114415') { # Hosenträger haben keine Größe
193
      delete $part{varianten_groesse};
194
    }
195
  }
196
  if ($part{varianten_groesse} && $part{varianten_groesse} =~ m/^([0-9][0-9])([0-9][0-9])$/) {
197
    my $weite = $1;
198
    my $laenge = $2;
199
    $part{varianten_groesse} = $weite;
200
    $part{varianten_laenge} = $laenge;
201
  }
202
  if ($part{varianten_laenge}) {
203
    if (any {$part{varianten_laenge} eq $_} ('.', 'U')) {
204
      delete $part{varianten_laenge};
205
    }
206
  }
207

  
167 208
  push @{$parent_variants_to_variants{$part_row->{LIEFERANT}}->{$part_row->{ARTIKELNR}}}, \%part;
168 209
}
169 210

  
......
193 234
) or die "Could no find transfer_type";
194 235

  
195 236
SL::DB->client->with_transaction(sub {
237
  my @errors;
196 238

  
197 239
  # create farben listen
198 240
  foreach my $farb_csv_file (glob( $opt_farben_folder . '/*' )) {
......
203 245
      quote_char  => '"',     # default '"'
204 246
      escape_char => '"',     # default '"'
205 247
    );
206
    $farb_csv->parse or die "Could not parse csv";
248
    unless ($farb_csv->parse) {
249
      push @errors, "Could not parse csv '$farb_csv_file'";
250
      next;
251
    }
207 252
    my $farb_hrefs = $farb_csv->get_data;
208 253

  
209 254
    my $vendor_name = basename($farb_csv_file);
......
215 260
      abbreviation => "fa",
216 261
    )->save;
217 262

  
263
    my $pos = 1;
264
    SL::DB::VariantPropertyValue->new(
265
      variant_property => $variant_property,
266
      value            => $_->{Joined},
267
      abbreviation     => $_->{Joined},
268
      sortkey => $pos++,
269
    )->save for @$farb_hrefs;
270
  }
271

  
272
  # create groessen staffeln
273
  foreach my $groessen_staffel_row (@$groessen_staffel_hrefs) {
274
    my $name = delete $groessen_staffel_row->{BEZEICHNUNG};
275
    my $variant_property = SL::DB::VariantProperty->new(
276
      name         => $name,
277
      unique_name  => $name,
278
      abbreviation => "gr",
279
    )->save;
280

  
218 281
    my $pos = 1;
219 282
    SL::DB::VariantPropertyValue->new(
220 283
      variant_property => $variant_property,
......
222 285
      abbreviation     => $_,
223 286
      sortkey => $pos++,
224 287
    )->save for
225
      map {$_->{Joined}}
226
      @$farb_hrefs;
288
      map {$groessen_staffel_row->{$_}}
289
      sort
290
      grep {defined $groessen_staffel_row->{$_}}
291
      keys %$groessen_staffel_row;
227 292
  }
228 293

  
229 294
  # create partsgroups
295
  my %partsgroup_id_to_groessen_staffeln;
230 296
  my @hierachy_descrioptions = qw(
231 297
    Bereich Hauptabteilung Abteilung Hauptwarengruppe Warengruppe
232 298
  );
233 299
  my %current_partsgroup_hierachy;
234 300
  foreach my $partsgroup_row (@$warengruppen_hrefs) {
235
    # TODO: store valid groessen staffeln
236 301
    my $valid_groessen_staffen = delete $partsgroup_row->{Größenstaffeln};
237 302
    my $last_hierachy_key;
238 303
    foreach my $hierachy_key (@hierachy_descrioptions) {
......
240 305
        my ($number, @rest) = split(' ', $partsgroup_row->{$hierachy_key});
241 306
        my $name = join(' ', @rest);
242 307
        unless ($number && $name) {
243
          die "Could not find number and name for $hierachy_key partsgroup '".$partsgroup_row->{$hierachy_key}."' in the row:'\n".
244
          join(';', map {$partsgroup_row->{$_}} @hierachy_descrioptions);
308
          push @errors, "Could not find number and name for $hierachy_key partsgroup '".$partsgroup_row->{$hierachy_key}."' in the row:'\n".
309
            join(';', map {$partsgroup_row->{$_}} @hierachy_descrioptions);
310
          next;
245 311
        }
246 312
        my $partsgroup = SL::DB::PartsGroup->new(
247 313
          partsgroup  => $name,
......
251 317
        )->save;
252 318
        $current_partsgroup_hierachy{$hierachy_key} = $partsgroup;
253 319
      }
254
      my $last_hierachy_key = $hierachy_key;
320
      $last_hierachy_key = $hierachy_key;
255 321
    }
322
    my $last_partsgroup = $current_partsgroup_hierachy{$last_hierachy_key};
323
    my @valid_groessen_staffen =
324
      grep { $_ }
325
      map {
326
        my $variant = SL::DB::Manager::VariantProperty->find_by(unique_name => $_);
327
        push @errors, "Could not find Variant Property '$_' while importing partsgroups." unless $variant;
328
        $variant;
329
      }
330
      grep { $_ ne 'ohne'}
331
      split(', ', $valid_groessen_staffen);
332
    $partsgroup_id_to_groessen_staffeln{$last_partsgroup->id} = \@valid_groessen_staffen;
256 333
  }
257 334

  
258
  # create groessen staffeln
259
  foreach my $groessen_staffel_row (@$groessen_staffel_hrefs) {
260
    my $name = delete $groessen_staffel_row->{BEZEICHNUNG};
261
    my $variant_property = SL::DB::VariantProperty->new(
262
      name         => $name,
263
      unique_name  => $name,
264
      abbreviation => "gr",
265
    )->save;
266

  
267
    my $pos = 1;
268
    SL::DB::VariantPropertyValue->new(
269
      variant_property => $variant_property,
270
      value            => $_,
271
      abbreviation     => $_,
272
      sortkey => $pos++,
273
    )->save for
274
      map {$groessen_staffel_row->{$_}}
275
      sort
276
      grep {defined $groessen_staffel_row->{$_}}
277
      keys %$groessen_staffel_row;
278
  }
279

  
280
  my %partsgroup_name_to_partsgroup = map {lc($_->partsgroup) => $_} @{SL::DB::Manager::PartsGroup->get_all()};
281
  my %vendor_name_to_vendor = map {lc($_->name) => $_} @{SL::DB::Manager::Vendor->get_all()};
335
  my %partsgroup_number_to_partsgroup = map {my ($number) = split(' ', $_->description); $number => $_} @{SL::DB::Manager::PartsGroup->get_all()};
336
  my %vendor_number_to_vendor = map {$_->vendornumber => $_} @{SL::DB::Manager::Vendor->get_all()};
282 337
  my %warehouse_description_to_warehouse = map {lc($_->description) => $_} @{SL::DB::Manager::Warehouse->get_all()};
283 338

  
284
  my @all_variant_properties = @{SL::DB::Manager::VariantProperty->get_all()};
285 339
  # create parts
286
  foreach my $vendor (keys %parent_variants_to_variants) {
287
    foreach my $partnumber (keys %{$parent_variants_to_variants{$vendor}}) {
288
      my $grouped_variant_values = $parent_variants_to_variants{$vendor}->{$partnumber};
340
  foreach my $vendor_kurz_name (keys %parent_variants_to_variants) {
341
    foreach my $partnumber (keys %{$parent_variants_to_variants{$vendor_kurz_name}}) {
342
      my $count_errors_at_start = scalar @errors;
343
      # TODO: logic for
344
      # bestand anpasen
345
      # stammartikel da neue variante
346
      # alles neu
347
      my $grouped_variant_values = $parent_variants_to_variants{$vendor_kurz_name}->{$partnumber};
289 348

  
290 349
      #get data for parent_variant
291 350
      my $first_part = $grouped_variant_values->[0];
292
      my $description = $first_part->{description};
293
      my $partsgroup_name = $first_part->{warengruppe};
351
      my $description = $first_part->{description} || '';
352
      my $partsgroup_number = $first_part->{warengruppe_nummer};
294 353
      my $warehouse_description = $first_part->{warehouse_description};
295
      my $vendor_name = $first_part->{vendor_name};
354
      my $vendor_number = $first_part->{vendor_number};
296 355
      my $makemodel_model = $first_part->{makemodel_model};
297 356
      my $best_sellprice = first {$_} sort map {$_->{sellprice}} @$grouped_variant_values;
298 357
      $best_sellprice =~ s/,/./;
299
      my $partsgroup = $partsgroup_name_to_partsgroup{lc($partsgroup_name)} or die
300
        die "Could not find partsgroup '$partsgroup_name' for part '$makemodel_model $description'";
301
      my $vendor = $vendor_name_to_vendor{lc($vendor_name)} or
302
        die "Could not find vendor: '$vendor_name' for part '$makemodel_model $description'";
358
      my $partsgroup = $partsgroup_number_to_partsgroup{$partsgroup_number} or
359
        push @errors, "Could not find partsgroup '$partsgroup_number' for part '$makemodel_model $description' in row " . $first_part->{csv_row};
360
      my $vendor = $vendor_number_to_vendor{$vendor_number} or
361
        push @errors, "Could not find vendor: '$vendor_number' for part '$makemodel_model $description' in row " . $first_part->{csv_row};
303 362
      my $warehouse = $warehouse_description_to_warehouse{lc($warehouse_description)} or
304
        die "Could not find warehouse '$warehouse_description' for part '$makemodel_model $description'";
363
        push @errors, "Could not find warehouse '$warehouse_description' for part '$makemodel_model $description' in row " . $first_part->{csv_row};
364
      next if $count_errors_at_start != scalar @errors;
305 365
      my $parent_variant = SL::DB::Part->new_parent_variant(
366
        partnumber  => $vendor_number . '-' . $makemodel_model,
306 367
        description => $description,
307 368
        sellprice   => $best_sellprice,
308 369
        partsgroup  => $partsgroup,
......
334 395
      # find variant_properties
335 396
      my %property_name_to_variant_property;
336 397
      foreach my $property_name (keys %group_variant_property_vales) {
337
        # TODO find valid properties for partsgroup
338 398
        my $needed_property_values = $group_variant_property_vales{$property_name};
399

  
400
        my @valid_variant_properties;
401
        if ($property_name eq 'varianten_groesse') {
402
          @valid_variant_properties = @{$partsgroup_id_to_groessen_staffeln{$partsgroup->id}};
403
          unless (scalar @valid_variant_properties) {
404
            push @errors, "NO variant property for key '$property_name' and partsgroup '${\$partsgroup->partsgroup}'. values '@$needed_property_values' in part '$makemodel_model $description' in row " . $first_part->{csv_row};
405
            next;
406
          }
407
        } elsif ($property_name eq 'varianten_farbe') {
408
          my $color = SL::DB::Manager::VariantProperty->find_by(
409
            name => { ilike => "Farbliste $vendor_kurz_name" },
410
          );
411
          unless ($color) {
412
            push @errors, "Could not find variant property 'Farbliste $vendor_kurz_name'";
413
            next;
414
          }
415
          @valid_variant_properties = ($color);
416
        } elsif ($property_name eq 'varianten_laenge') {
417
          # Only 'Jeanslängen' is vaild
418
          my $laenge = SL::DB::Manager::VariantProperty->find_by(
419
              name => { ilike => "Jeanslängen" },
420
          );
421
          unless ($laenge) {
422
            push @errors, "Could not find variant property 'Jenaslänge'";
423
            next;
424
          }
425
          @valid_variant_properties = ($laenge);
426
        } else {
427
          push @errors, "Not implemented for property '$property_name'";
428
          next;
429
        }
430

  
339 431
        my ($best_match) =
340 432
          sort {scalar @{$a->{missing}} <=> scalar @{$b->{missing}}}
341 433
          map {
......
346 438
            }
347 439
            {property => $_, missing => \@missing};
348 440
          }
349
          @all_variant_properties;
441
          @valid_variant_properties;
350 442

  
351 443
        if (scalar @{$best_match->{missing}}) {
352
          die "Could not find variant property with values for $property_name '@{$needed_property_values}' of part '$makemodel_model $description'.\n" .
353
          "Best match is ${\$best_match->{property}->name} with missing values '@{$best_match->{missing}}'";
444
          push @errors, "Could not find variant property with values for $property_name '@{$needed_property_values}' of part '$makemodel_model $description' in row " . $first_part->{csv_row} . "\n" .
445
          "Best match is '${\$best_match->{property}->name}' with missing values '@{$best_match->{missing}}'.\n" .
446
          "Valid properties are: " . join(', ', map {$_->name} @valid_variant_properties) . "\n"
447
          ;
448
          next;
354 449
        }
355 450
        $property_name_to_variant_property{$property_name} = $best_match->{property};
356 451
      }
357 452
      my @variant_properties = values %property_name_to_variant_property;
358 453
      $parent_variant->variant_properties(@variant_properties);
359 454

  
455
      next if $count_errors_at_start != scalar @errors;
360 456
      $parent_variant->save();
361 457

  
362 458
      foreach my $variant_values (@$grouped_variant_values) {
......
367 463
          grep { $_ =~ m/^variant/ }
368 464
          keys %$variant_values;
369 465

  
370
        my $variant = $parent_variant->create_new_variant(\@property_values);
466
        if (scalar @property_values != scalar keys %property_name_to_variant_property) {
467
          push @errors, "Missing property value for part '$makemodel_model $description' in row " . $variant_values->{csv_row};
468
          next;
469
        }
470

  
471
        my $variant = first {join(' ', sort map {$_->id} @property_values) eq join(' ', sort map {$_->id} $_->variant_property_values)}
472
          $parent_variant->variants;
473
        $variant ||= $parent_variant->create_new_variant(\@property_values);
474

  
475
        my $warehouse_description = $variant_values->{warehouse_description};
476
        my $warehouse = $warehouse_description_to_warehouse{lc($warehouse_description)};
477
        unless ($warehouse) {
478
          push @errors, "Could not find warehouse '$warehouse_description' for part '$makemodel_model $description' in row " . $variant_values->{csv_row};
479
          next;
480
        }
371 481

  
372 482
        my $sellprice = $variant_values->{sellprice};
373 483
        $sellprice =~ s/,/./;
374 484
        $variant->update_attributes(
375
          ean => $variant_values->{ean},
485
          ean         => $variant_values->{ean},
376 486
          description => $variant_values->{description},
377
          sellprice => $sellprice,
487
          sellprice   => $sellprice,
488
          warehouse   => $warehouse,
489
          bin         => $warehouse->bins->[0],
378 490
        );
379 491

  
380 492
        # set stock
......
394 506
      }
395 507
    }
396 508
  }
397
  1;
509
  if (scalar @errors) {
510
    say join("\n", @errors);
511
    die join("\n", @errors);
512
  } else {
513
    return 1;
514
  }
398 515
}) or do {
399
  die t8('Error while creating variants: '), SL::DB->client->error;
516
  if (SL::DB->client->error) {
517
    say t8('Error while creating variants: '), SL::DB->client->error;
518
  }
400 519
};
401 520

  

Auch abrufbar als: Unified diff