-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Neuer Backgroundjob zum Massen-generieren von Shop Artikeln aus Artikeln
x
- Loading branch information
Showing
1 changed file
with
240 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
package SL::BackgroundJob::ShopPartMassCreate; | ||
|
||
use strict; | ||
|
||
use parent qw(SL::BackgroundJob::Base); | ||
|
||
use List::Util qw(first); | ||
use File::MimeInfo::Magic; # for mimetype | ||
use File::Slurp; # for read_file | ||
|
||
use SL::Shop; | ||
use SL::DB::Part; | ||
use SL::DB::ShopPart; | ||
use SL::DB::File; | ||
use SL::CVar; | ||
use SL::File; | ||
|
||
use Data::Dumper; | ||
|
||
sub recurse_categories { | ||
my ($categories, $categories_by_names) = @_; | ||
foreach my $category (@{ $categories }) { | ||
${ $categories_by_names }{$category->{name}} = $category->{id}; | ||
recurse_categories($category->{children}, $categories_by_names); | ||
} | ||
} | ||
|
||
sub get_shop_part { | ||
my ($part_id, $shop_id) = @_; | ||
my $exists = SL::DB::Manager::ShopPart->find_by( part_id => $part_id, shop_id => $shop_id ); | ||
if ($exists) { | ||
return $exists; | ||
} | ||
return SL::DB::ShopPart->new( part_id => $part_id, shop_id => $shop_id ); | ||
} | ||
|
||
sub get_shop_categories { | ||
my ($cvar_categories, $categories_by_names) = @_; | ||
# split on the pipe character | ||
my @categories_names = split(/\|/, $cvar_categories); | ||
|
||
my @shop_categories; | ||
foreach my $category_name (@categories_names) { | ||
# if the category exists in the shop | ||
if (exists $categories_by_names->{$category_name}) { | ||
push @shop_categories, [ | ||
$categories_by_names->{$category_name}, | ||
$category_name | ||
]; | ||
} | ||
} | ||
return \@shop_categories; | ||
} | ||
|
||
sub warn { | ||
my ($messages, $message) = @_; | ||
$main::lxdebug->message(LXDEBUG::WARN(), $message); | ||
push @$messages, $message; | ||
} | ||
|
||
sub run { | ||
my ($self, $db_obj) = @_; | ||
my $data = $db_obj->data_as_hash; | ||
|
||
# get parameters | ||
my $shop_id = $data->{shop_id} || 1; | ||
my $images_import_path = $data->{images_import_path} || 'shopimages/product/'; | ||
my $cvar_categories = $data->{cvar_categories} || 'vm_product_categories'; | ||
|
||
my @messages; | ||
|
||
# initialize shop | ||
my $shop_config = SL::DB::Manager::Shop->get_first( query => [ id => $shop_id ] ); | ||
my $shop = SL::Shop->new( config => $shop_config ); | ||
|
||
# get the categories from the shop | ||
my $connect = $shop->check_connectivity; | ||
if (!$connect->{success}) { | ||
return 'Error: could not connect to shop'; | ||
} | ||
my $categories_shopdata = $shop->connector->get_categories(); | ||
if (!$categories_shopdata) { | ||
return 'Error: could not get categories from shop'; | ||
} | ||
|
||
# generate a hash of the category names and their ids | ||
my %categories_by_names; | ||
recurse_categories($categories_shopdata, \%categories_by_names); | ||
|
||
# get all the parts from the database, that are marked as shop parts | ||
my $parts = SL::DB::Manager::Part->get_all(query => [ shop => 1 ]); | ||
|
||
# for every part | ||
for my $part (@{ $parts }) { | ||
|
||
# check if shop part already exists | ||
my $shop_part = get_shop_part($part->id, $shop_id); | ||
|
||
# get the custom variables from the part | ||
my $cvars = CVar->get_custom_variables(module => 'IC', trans_id => $part->id); | ||
my $cvar_categories = first { $_->{name} eq $cvar_categories } @{ $cvars }; | ||
|
||
# assign categories | ||
my $shop_categories = get_shop_categories($cvar_categories->{value}, \%categories_by_names); | ||
|
||
$shop_part->assign_attributes( | ||
shop_description => '', | ||
front_page => '', | ||
active => 1, | ||
shop_category => $shop_categories, | ||
active_price_source => 'master_data/sellprice', | ||
metatag_keywords => '', | ||
metatag_description => '', | ||
metatag_title => '', | ||
); | ||
|
||
$shop_part->save; | ||
$main::lxdebug->message(LXDebug->DEBUG1(), 'Shop part saved: ' . $shop_part->id); | ||
|
||
if (!$shop_part->id) { | ||
warn(\@messages, 'Warning: shop part not saved, part id: ' . $part->id . ' part number: ' . $part->partnumber); | ||
next; | ||
} | ||
|
||
# handle the images, | ||
# the file names are under part->image | ||
|
||
if (!$part->image) { | ||
# go to next part if no images are found | ||
next; | ||
} | ||
|
||
# get existing images from shop part | ||
my $image_files = SL::DB::Manager::File->get_all( where => [ object_id => $part->id, object_type => 'shop_image' ] ); | ||
|
||
my %images_by_names = map { $_->{file_name} => $_ } @{ $image_files }; | ||
|
||
for my $image_name (split '\|', $part->image) { | ||
|
||
my $fileobj; | ||
if (exists $images_by_names{$image_name}) { | ||
# I tried updating the file, but it didn't work right away | ||
# so instead I delete the file and create a new one | ||
# (this is also the way it is done in the UI, there's only a delete button, | ||
# no update button) | ||
$images_by_names{$image_name}->delete; | ||
} | ||
|
||
my $image_path = $images_import_path . $image_name; | ||
|
||
# uses File::MimeInfo::Magic | ||
my $mime_type = mimetype($image_path); | ||
|
||
# read file data into memory | ||
my $file_data = File::Slurp::read_file($image_path); | ||
|
||
$fileobj = SL::File->save( | ||
object_id => $part->id, | ||
object_type => 'shop_image', | ||
mime_type => $mime_type, | ||
source => 'uploaded', | ||
file_type => 'image', | ||
file_name => $image_name, | ||
title => substr($part->description, 0, 45), | ||
description => '', | ||
file_contents => $file_data, | ||
file_path => $image_path, | ||
); | ||
if (!$fileobj) { | ||
warn(\@messages, 'Warning: file not saved for part: ' . $part->id . ' file: ' . $image_name); | ||
} | ||
} | ||
} | ||
|
||
if (@messages) { | ||
return join("\n", @messages); | ||
} | ||
return 'Shop parts created successfully'; | ||
} | ||
|
||
1; | ||
|
||
__END__ | ||
=encoding utf8 | ||
=head1 NAME | ||
SL::BackgroundJob::ShopPartMassCreateRevamp - Background job to create shop | ||
parts for all parts in the database that are marked as shop parts. | ||
=head1 SYNOPSIS | ||
This background job provides the basic functionality to create shop parts for | ||
all parts in the database that are marked as shop parts. | ||
It can also import images from a directory and assign them to the respective | ||
shop parts. See configuration below. | ||
It also assigns categories to the shop parts based on a custom variable of the | ||
part. | ||
The script may need individual adjustments to fit your specific use case. | ||
=head1 CONFIGURATION | ||
Accepts the following parameters: | ||
=over 4 | ||
=item C<shop_id> | ||
The id of the shop to create the shop parts in, defaults to 1 | ||
=item C<images_import_path> | ||
The path to the images to import, defaults to 'shopimages/product/' | ||
The file names of the images should be present in the 'image' field of the part, | ||
in the following format: | ||
image1.jpg|image2.png|image3.gif | ||
The images themselves should be present in the images_import_path. | ||
=item C<cvar_categories> | ||
The name of the custom variable that contains the categories, defaults to 'vm_product_categories' | ||
Expects the Categories to be set in the custom variable of the part in the following format: | ||
Category1|Category2|Category3 | ||
Categories should be present in the shop under the same names. | ||
=back | ||
=head1 AUTHOR | ||
Cem Aydin E<lt>[email protected]E<gt> | ||
=cut |