Revision 7413a26e
Von Tamino Steinert vor etwa 1 Jahr hinzugefügt
scripts/import_variant_csv.pl | ||
---|---|---|
|
||
use Data::Dumper;
|
||
use List::Util qw(first);
|
||
use List::MoreUtils qw(any);
|
||
use File::Basename;
|
||
|
||
use SL::DBUtils;
|
||
... | ... | |
VK => 'sellprice',
|
||
EANNR => 'ean',
|
||
EIGENEARTIKELNR => 'description',
|
||
WAR_KURZBEZEICHNUNG => 'warengruppe',
|
||
WARENGRUPPE => 'warengruppe_nummer',
|
||
WAR_KURZBEZEICHNUNG => 'warengruppe_name',
|
||
GROESSE => 'varianten_groesse',
|
||
LAENGE => 'varianten_laenge',
|
||
FARBNR => 'varianten_farbnummer',
|
||
INFO1 => 'varianten_farbname',
|
||
ARTIKELNR => 'makemodel_model',
|
||
LIEFERANT => 'vendor_name',
|
||
LST_ID => 'vendor_number',
|
||
FIL_KURZBEZEICHNUNG => 'warehouse_description',
|
||
STUECK => 'part_qty',
|
||
);
|
||
... | ... | |
my $part_hrefs = $part_csv->get_data;
|
||
|
||
my %parent_variants_to_variants;
|
||
my $row = 0;
|
||
foreach my $part_row (@$part_hrefs) {
|
||
my %part =
|
||
map {$parts_mapping{$_} => $part_row->{$_}}
|
||
grep {$part_row->{$_}}
|
||
keys %parts_mapping;
|
||
$part{csv_row} = $row++;
|
||
|
||
if ($part{varianten_farbnummer} || $part{varianten_farbname}) {
|
||
$part{varianten_farbnummer} ||= '';
|
||
... | ... | |
$part{varianten_farbe} = (delete $part{varianten_farbnummer}) . '-' . (delete $part{varianten_farbname});
|
||
}
|
||
|
||
if ($part{varianten_groesse}) {
|
||
# map to valid sizes
|
||
unless ($part{warengruppe_nummer} eq '114310' || $part{warengruppe_nummer} eq '124310') { # nicht für gürtel
|
||
$part{varianten_groesse} =~ s/^([0-9][0-9])5$/$1,5/; # 345 -> 34,5
|
||
}
|
||
$part{varianten_groesse} =~ s/^([0-9][0-9])\.5$/$1,5/; # 34.5 -> 34,5
|
||
$part{varianten_groesse} =~ s/^2XL$/XXL/;
|
||
$part{varianten_groesse} =~ s/^XXXL$/3XL/;
|
||
$part{varianten_groesse} =~ s/^([0-9]*)½$/$1 ½/;
|
||
$part{varianten_groesse} =~ s/^([0-9]*)\/½$/$1 ½/;
|
||
$part{varianten_groesse} =~ s/^([0-9]*) 1\/2$/$1 ½/;
|
||
$part{varianten_groesse} =~ s/\/U//; # 34/U -> 34
|
||
$part{varianten_groesse} =~ s/\/I//; # 34/I -> 34
|
||
$part{varianten_groesse} =~ s/\/M//; # 34/M -> 34
|
||
$part{varianten_groesse} =~ s/\/L//; # 34/L -> 34
|
||
$part{varianten_groesse} =~ s/\/XL//; # 34/XL -> 34
|
||
$part{varianten_groesse} =~ s/\/XX//; # 34/XX -> 34
|
||
|
||
if (any {$part{varianten_groesse} eq $_} ('.', '_', 'ONE', 'ONE S', 'ONES', 'OSFA', 'ONESI', 'O/S', 'OSO')) {
|
||
delete $part{varianten_groesse};
|
||
}
|
||
if ($part{warengruppe_nummer} eq '114415') { # Hosenträger haben keine Größe
|
||
delete $part{varianten_groesse};
|
||
}
|
||
}
|
||
if ($part{varianten_groesse} && $part{varianten_groesse} =~ m/^([0-9][0-9])([0-9][0-9])$/) {
|
||
my $weite = $1;
|
||
my $laenge = $2;
|
||
$part{varianten_groesse} = $weite;
|
||
$part{varianten_laenge} = $laenge;
|
||
}
|
||
if ($part{varianten_laenge}) {
|
||
if (any {$part{varianten_laenge} eq $_} ('.', 'U')) {
|
||
delete $part{varianten_laenge};
|
||
}
|
||
}
|
||
|
||
push @{$parent_variants_to_variants{$part_row->{LIEFERANT}}->{$part_row->{ARTIKELNR}}}, \%part;
|
||
}
|
||
|
||
... | ... | |
) or die "Could no find transfer_type";
|
||
|
||
SL::DB->client->with_transaction(sub {
|
||
my @errors;
|
||
|
||
# create farben listen
|
||
foreach my $farb_csv_file (glob( $opt_farben_folder . '/*' )) {
|
||
... | ... | |
quote_char => '"', # default '"'
|
||
escape_char => '"', # default '"'
|
||
);
|
||
$farb_csv->parse or die "Could not parse csv";
|
||
unless ($farb_csv->parse) {
|
||
push @errors, "Could not parse csv '$farb_csv_file'";
|
||
next;
|
||
}
|
||
my $farb_hrefs = $farb_csv->get_data;
|
||
|
||
my $vendor_name = basename($farb_csv_file);
|
||
... | ... | |
abbreviation => "fa",
|
||
)->save;
|
||
|
||
my $pos = 1;
|
||
SL::DB::VariantPropertyValue->new(
|
||
variant_property => $variant_property,
|
||
value => $_->{Joined},
|
||
abbreviation => $_->{Joined},
|
||
sortkey => $pos++,
|
||
)->save for @$farb_hrefs;
|
||
}
|
||
|
||
# create groessen staffeln
|
||
foreach my $groessen_staffel_row (@$groessen_staffel_hrefs) {
|
||
my $name = delete $groessen_staffel_row->{BEZEICHNUNG};
|
||
my $variant_property = SL::DB::VariantProperty->new(
|
||
name => $name,
|
||
unique_name => $name,
|
||
abbreviation => "gr",
|
||
)->save;
|
||
|
||
my $pos = 1;
|
||
SL::DB::VariantPropertyValue->new(
|
||
variant_property => $variant_property,
|
||
... | ... | |
abbreviation => $_,
|
||
sortkey => $pos++,
|
||
)->save for
|
||
map {$_->{Joined}}
|
||
@$farb_hrefs;
|
||
map {$groessen_staffel_row->{$_}}
|
||
sort
|
||
grep {defined $groessen_staffel_row->{$_}}
|
||
keys %$groessen_staffel_row;
|
||
}
|
||
|
||
# create partsgroups
|
||
my %partsgroup_id_to_groessen_staffeln;
|
||
my @hierachy_descrioptions = qw(
|
||
Bereich Hauptabteilung Abteilung Hauptwarengruppe Warengruppe
|
||
);
|
||
my %current_partsgroup_hierachy;
|
||
foreach my $partsgroup_row (@$warengruppen_hrefs) {
|
||
# TODO: store valid groessen staffeln
|
||
my $valid_groessen_staffen = delete $partsgroup_row->{Größenstaffeln};
|
||
my $last_hierachy_key;
|
||
foreach my $hierachy_key (@hierachy_descrioptions) {
|
||
... | ... | |
my ($number, @rest) = split(' ', $partsgroup_row->{$hierachy_key});
|
||
my $name = join(' ', @rest);
|
||
unless ($number && $name) {
|
||
die "Could not find number and name for $hierachy_key partsgroup '".$partsgroup_row->{$hierachy_key}."' in the row:'\n".
|
||
join(';', map {$partsgroup_row->{$_}} @hierachy_descrioptions);
|
||
push @errors, "Could not find number and name for $hierachy_key partsgroup '".$partsgroup_row->{$hierachy_key}."' in the row:'\n".
|
||
join(';', map {$partsgroup_row->{$_}} @hierachy_descrioptions);
|
||
next;
|
||
}
|
||
my $partsgroup = SL::DB::PartsGroup->new(
|
||
partsgroup => $name,
|
||
... | ... | |
)->save;
|
||
$current_partsgroup_hierachy{$hierachy_key} = $partsgroup;
|
||
}
|
||
my $last_hierachy_key = $hierachy_key;
|
||
$last_hierachy_key = $hierachy_key;
|
||
}
|
||
my $last_partsgroup = $current_partsgroup_hierachy{$last_hierachy_key};
|
||
my @valid_groessen_staffen =
|
||
grep { $_ }
|
||
map {
|
||
my $variant = SL::DB::Manager::VariantProperty->find_by(unique_name => $_);
|
||
push @errors, "Could not find Variant Property '$_' while importing partsgroups." unless $variant;
|
||
$variant;
|
||
}
|
||
grep { $_ ne 'ohne'}
|
||
split(', ', $valid_groessen_staffen);
|
||
$partsgroup_id_to_groessen_staffeln{$last_partsgroup->id} = \@valid_groessen_staffen;
|
||
}
|
||
|
||
# create groessen staffeln
|
||
foreach my $groessen_staffel_row (@$groessen_staffel_hrefs) {
|
||
my $name = delete $groessen_staffel_row->{BEZEICHNUNG};
|
||
my $variant_property = SL::DB::VariantProperty->new(
|
||
name => $name,
|
||
unique_name => $name,
|
||
abbreviation => "gr",
|
||
)->save;
|
||
|
||
my $pos = 1;
|
||
SL::DB::VariantPropertyValue->new(
|
||
variant_property => $variant_property,
|
||
value => $_,
|
||
abbreviation => $_,
|
||
sortkey => $pos++,
|
||
)->save for
|
||
map {$groessen_staffel_row->{$_}}
|
||
sort
|
||
grep {defined $groessen_staffel_row->{$_}}
|
||
keys %$groessen_staffel_row;
|
||
}
|
||
|
||
my %partsgroup_name_to_partsgroup = map {lc($_->partsgroup) => $_} @{SL::DB::Manager::PartsGroup->get_all()};
|
||
my %vendor_name_to_vendor = map {lc($_->name) => $_} @{SL::DB::Manager::Vendor->get_all()};
|
||
my %partsgroup_number_to_partsgroup = map {my ($number) = split(' ', $_->description); $number => $_} @{SL::DB::Manager::PartsGroup->get_all()};
|
||
my %vendor_number_to_vendor = map {$_->vendornumber => $_} @{SL::DB::Manager::Vendor->get_all()};
|
||
my %warehouse_description_to_warehouse = map {lc($_->description) => $_} @{SL::DB::Manager::Warehouse->get_all()};
|
||
|
||
my @all_variant_properties = @{SL::DB::Manager::VariantProperty->get_all()};
|
||
# create parts
|
||
foreach my $vendor (keys %parent_variants_to_variants) {
|
||
foreach my $partnumber (keys %{$parent_variants_to_variants{$vendor}}) {
|
||
my $grouped_variant_values = $parent_variants_to_variants{$vendor}->{$partnumber};
|
||
foreach my $vendor_kurz_name (keys %parent_variants_to_variants) {
|
||
foreach my $partnumber (keys %{$parent_variants_to_variants{$vendor_kurz_name}}) {
|
||
my $count_errors_at_start = scalar @errors;
|
||
# TODO: logic for
|
||
# bestand anpasen
|
||
# stammartikel da neue variante
|
||
# alles neu
|
||
my $grouped_variant_values = $parent_variants_to_variants{$vendor_kurz_name}->{$partnumber};
|
||
|
||
#get data for parent_variant
|
||
my $first_part = $grouped_variant_values->[0];
|
||
my $description = $first_part->{description};
|
||
my $partsgroup_name = $first_part->{warengruppe};
|
||
my $description = $first_part->{description} || '';
|
||
my $partsgroup_number = $first_part->{warengruppe_nummer};
|
||
my $warehouse_description = $first_part->{warehouse_description};
|
||
my $vendor_name = $first_part->{vendor_name};
|
||
my $vendor_number = $first_part->{vendor_number};
|
||
my $makemodel_model = $first_part->{makemodel_model};
|
||
my $best_sellprice = first {$_} sort map {$_->{sellprice}} @$grouped_variant_values;
|
||
$best_sellprice =~ s/,/./;
|
||
my $partsgroup = $partsgroup_name_to_partsgroup{lc($partsgroup_name)} or die
|
||
die "Could not find partsgroup '$partsgroup_name' for part '$makemodel_model $description'";
|
||
my $vendor = $vendor_name_to_vendor{lc($vendor_name)} or
|
||
die "Could not find vendor: '$vendor_name' for part '$makemodel_model $description'";
|
||
my $partsgroup = $partsgroup_number_to_partsgroup{$partsgroup_number} or
|
||
push @errors, "Could not find partsgroup '$partsgroup_number' for part '$makemodel_model $description' in row " . $first_part->{csv_row};
|
||
my $vendor = $vendor_number_to_vendor{$vendor_number} or
|
||
push @errors, "Could not find vendor: '$vendor_number' for part '$makemodel_model $description' in row " . $first_part->{csv_row};
|
||
my $warehouse = $warehouse_description_to_warehouse{lc($warehouse_description)} or
|
||
die "Could not find warehouse '$warehouse_description' for part '$makemodel_model $description'";
|
||
push @errors, "Could not find warehouse '$warehouse_description' for part '$makemodel_model $description' in row " . $first_part->{csv_row};
|
||
next if $count_errors_at_start != scalar @errors;
|
||
my $parent_variant = SL::DB::Part->new_parent_variant(
|
||
partnumber => $vendor_number . '-' . $makemodel_model,
|
||
description => $description,
|
||
sellprice => $best_sellprice,
|
||
partsgroup => $partsgroup,
|
||
... | ... | |
# find variant_properties
|
||
my %property_name_to_variant_property;
|
||
foreach my $property_name (keys %group_variant_property_vales) {
|
||
# TODO find valid properties for partsgroup
|
||
my $needed_property_values = $group_variant_property_vales{$property_name};
|
||
|
||
my @valid_variant_properties;
|
||
if ($property_name eq 'varianten_groesse') {
|
||
@valid_variant_properties = @{$partsgroup_id_to_groessen_staffeln{$partsgroup->id}};
|
||
unless (scalar @valid_variant_properties) {
|
||
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};
|
||
next;
|
||
}
|
||
} elsif ($property_name eq 'varianten_farbe') {
|
||
my $color = SL::DB::Manager::VariantProperty->find_by(
|
||
name => { ilike => "Farbliste $vendor_kurz_name" },
|
||
);
|
||
unless ($color) {
|
||
push @errors, "Could not find variant property 'Farbliste $vendor_kurz_name'";
|
||
next;
|
||
}
|
||
@valid_variant_properties = ($color);
|
||
} elsif ($property_name eq 'varianten_laenge') {
|
||
# Only 'Jeanslängen' is vaild
|
||
my $laenge = SL::DB::Manager::VariantProperty->find_by(
|
||
name => { ilike => "Jeanslängen" },
|
||
);
|
||
unless ($laenge) {
|
||
push @errors, "Could not find variant property 'Jenaslänge'";
|
||
next;
|
||
}
|
||
@valid_variant_properties = ($laenge);
|
||
} else {
|
||
push @errors, "Not implemented for property '$property_name'";
|
||
next;
|
||
}
|
||
|
||
my ($best_match) =
|
||
sort {scalar @{$a->{missing}} <=> scalar @{$b->{missing}}}
|
||
map {
|
||
... | ... | |
}
|
||
{property => $_, missing => \@missing};
|
||
}
|
||
@all_variant_properties;
|
||
@valid_variant_properties;
|
||
|
||
if (scalar @{$best_match->{missing}}) {
|
||
die "Could not find variant property with values for $property_name '@{$needed_property_values}' of part '$makemodel_model $description'.\n" .
|
||
"Best match is ${\$best_match->{property}->name} with missing values '@{$best_match->{missing}}'";
|
||
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" .
|
||
"Best match is '${\$best_match->{property}->name}' with missing values '@{$best_match->{missing}}'.\n" .
|
||
"Valid properties are: " . join(', ', map {$_->name} @valid_variant_properties) . "\n"
|
||
;
|
||
next;
|
||
}
|
||
$property_name_to_variant_property{$property_name} = $best_match->{property};
|
||
}
|
||
my @variant_properties = values %property_name_to_variant_property;
|
||
$parent_variant->variant_properties(@variant_properties);
|
||
|
||
next if $count_errors_at_start != scalar @errors;
|
||
$parent_variant->save();
|
||
|
||
foreach my $variant_values (@$grouped_variant_values) {
|
||
... | ... | |
grep { $_ =~ m/^variant/ }
|
||
keys %$variant_values;
|
||
|
||
my $variant = $parent_variant->create_new_variant(\@property_values);
|
||
if (scalar @property_values != scalar keys %property_name_to_variant_property) {
|
||
push @errors, "Missing property value for part '$makemodel_model $description' in row " . $variant_values->{csv_row};
|
||
next;
|
||
}
|
||
|
||
my $variant = first {join(' ', sort map {$_->id} @property_values) eq join(' ', sort map {$_->id} $_->variant_property_values)}
|
||
$parent_variant->variants;
|
||
$variant ||= $parent_variant->create_new_variant(\@property_values);
|
||
|
||
my $warehouse_description = $variant_values->{warehouse_description};
|
||
my $warehouse = $warehouse_description_to_warehouse{lc($warehouse_description)};
|
||
unless ($warehouse) {
|
||
push @errors, "Could not find warehouse '$warehouse_description' for part '$makemodel_model $description' in row " . $variant_values->{csv_row};
|
||
next;
|
||
}
|
||
|
||
my $sellprice = $variant_values->{sellprice};
|
||
$sellprice =~ s/,/./;
|
||
$variant->update_attributes(
|
||
ean => $variant_values->{ean},
|
||
ean => $variant_values->{ean},
|
||
description => $variant_values->{description},
|
||
sellprice => $sellprice,
|
||
sellprice => $sellprice,
|
||
warehouse => $warehouse,
|
||
bin => $warehouse->bins->[0],
|
||
);
|
||
|
||
# set stock
|
||
... | ... | |
}
|
||
}
|
||
}
|
||
1;
|
||
if (scalar @errors) {
|
||
say join("\n", @errors);
|
||
die join("\n", @errors);
|
||
} else {
|
||
return 1;
|
||
}
|
||
}) or do {
|
||
die t8('Error while creating variants: '), SL::DB->client->error;
|
||
if (SL::DB->client->error) {
|
||
say t8('Error while creating variants: '), SL::DB->client->error;
|
||
}
|
||
};
|
||
|
Auch abrufbar als: Unified diff
kuw: CSV-Import-Script angepasst