Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 4c50d0e0

Von Cem Aydin vor 3 Monaten hinzugefügt

  • ID 4c50d0e04907f1a01b4aea965114dbb4773d4e74
  • Vorgänger bb658827
  • Nachfolger 3ccf9595

Neuer Backgroundjob zum Massen-generieren von Shop Artikeln aus Artikeln

Unterschiede anzeigen:

SL/BackgroundJob/ShopPartMassCreate.pm
1
package SL::BackgroundJob::ShopPartMassCreate;
2

  
3
use strict;
4

  
5
use parent qw(SL::BackgroundJob::Base);
6

  
7
use List::Util qw(first);
8
use File::MimeInfo::Magic; # for mimetype
9
use File::Slurp; # for read_file
10

  
11
use SL::Shop;
12
use SL::DB::Part;
13
use SL::DB::ShopPart;
14
use SL::DB::File;
15
use SL::CVar;
16
use SL::File;
17
use SL::LXDebug;
18

  
19
sub recurse_categories {
20
  my ($categories, $categories_by_names) = @_;
21
  foreach my $category (@{ $categories }) {
22
    ${ $categories_by_names }{$category->{name}} = $category->{id};
23
    recurse_categories($category->{children}, $categories_by_names);
24
  }
25
}
26

  
27
sub get_shop_part {
28
  my ($part_id, $shop_id) = @_;
29
  my $exists = SL::DB::Manager::ShopPart->find_by( part_id => $part_id, shop_id => $shop_id );
30
  if ($exists) {
31
    return $exists;
32
  }
33
  return SL::DB::ShopPart->new( part_id => $part_id, shop_id => $shop_id );
34
}
35

  
36
sub get_shop_categories {
37
  my ($cvar_categories, $categories_by_names) = @_;
38
  # split on the pipe character
39
  my @categories_names = split(/\|/, $cvar_categories);
40

  
41
  my @shop_categories;
42
  foreach my $category_name (@categories_names) {
43
    # if the category exists in the shop
44
    if (exists $categories_by_names->{$category_name}) {
45
      push @shop_categories, [
46
        $categories_by_names->{$category_name},
47
        $category_name
48
      ];
49
    }
50
  }
51
  return \@shop_categories;
52
}
53

  
54
sub _warn {
55
  my ($messages, $message) = @_;
56
  $main::lxdebug->message(LXDebug::WARN(), $message);
57
  push @$messages, $message;
58
}
59

  
60
sub run {
61
  my ($self, $db_obj)     = @_;
62
  my $data       = $db_obj->data_as_hash;
63

  
64
  # get parameters
65
  my $shop_id = $data->{shop_id} || 1;
66
  my $images_import_path = $data->{images_import_path} || 'shopimages/product/';
67
  my $cvar_categories = $data->{cvar_categories} || 'vm_product_categories';
68

  
69
  my @messages;
70

  
71
  # initialize shop
72
  my $shop_config = SL::DB::Manager::Shop->get_first( query => [ id => $shop_id ] );
73
  my $shop = SL::Shop->new( config => $shop_config );
74

  
75
  # get the categories from the shop
76
  my $connect = $shop->check_connectivity;
77
  if (!$connect->{success}) {
78
    return 'Error: could not connect to shop';
79
  }
80
  my $categories_shopdata = $shop->connector->get_categories();
81
  if (!$categories_shopdata) {
82
    return 'Error: could not get categories from shop';
83
  }
84

  
85
  # generate a hash of the category names and their ids
86
  my %categories_by_names;
87
  recurse_categories($categories_shopdata, \%categories_by_names);
88

  
89
  # get all the parts from the database, that are marked as shop parts
90
  my $parts = SL::DB::Manager::Part->get_all(query => [ shop => 1 ]);
91

  
92
  # for every part
93
  for my $part (@{ $parts }) {
94

  
95
    # check if shop part already exists
96
    my $shop_part = get_shop_part($part->id, $shop_id);
97

  
98
    # get the custom variables from the part
99
    my $cvars = CVar->get_custom_variables(module => 'IC', trans_id => $part->id);
100
    my $cvar_categories = first { $_->{name} eq $cvar_categories } @{ $cvars };
101

  
102
    # assign categories
103
    my $shop_categories = get_shop_categories($cvar_categories->{value}, \%categories_by_names);
104

  
105
    $shop_part->assign_attributes(
106
      shop_description => '',
107
      front_page       => '',
108
      active           => 1,
109
      shop_category    => $shop_categories,
110
      active_price_source => 'master_data/sellprice',
111
      metatag_keywords => '',
112
      metatag_description => '',
113
      metatag_title => '',
114
    );
115

  
116
    $shop_part->save;
117
    $main::lxdebug->message(LXDebug->DEBUG1(), 'Shop part saved: ' . $shop_part->id);
118

  
119
    if (!$shop_part->id) {
120
      _warn(\@messages, 'Warning: shop part not saved, part id: ' . $part->id . ' part number: ' . $part->partnumber);
121
      next;
122
    }
123

  
124
    # handle the images,
125
    # the file names are under part->image
126

  
127
    if (!$part->image) {
128
      # go to next part if no images are found
129
      next;
130
    }
131

  
132
    # get existing images from shop part
133
    my $image_files = SL::DB::Manager::File->get_all( where => [ object_id => $part->id, object_type => 'shop_image' ] );
134

  
135
    my %images_by_names = map { $_->{file_name} => $_ } @{ $image_files };
136

  
137
    for my $image_name (split '\|', $part->image) {
138

  
139
      my $fileobj;
140
      if (exists $images_by_names{$image_name}) {
141
        # I tried updating the file, but it didn't work right away
142
        # so instead I delete the file and create a new one
143
        # (this is also the way it is done in the UI, there's only a delete button,
144
        #  no update button)
145
        $images_by_names{$image_name}->delete;
146
      }
147

  
148
      my $image_path = $images_import_path . $image_name;
149

  
150
      # uses File::MimeInfo::Magic
151
      my $mime_type = mimetype($image_path);
152

  
153
      # check if the file exists
154
      if (! -e $image_path) {
155
        _warn(\@messages, 'Warning: image file not found for part: ' . $part->id . ' file: ' . $image_name);
156
        next;
157
      }
158
      # read file data into memory
159
      my $file_data = File::Slurp::read_file($image_path);
160

  
161
      $fileobj = SL::File->save(
162
        object_id        => $part->id,
163
        object_type      => 'shop_image',
164
        mime_type        => $mime_type,
165
        source           => 'uploaded',
166
        file_type        => 'image',
167
        file_name        => $image_name,
168
        title            => substr($part->description, 0, 45),
169
        description      => '',
170
        file_contents    => $file_data,
171
        file_path        => $image_path,
172
      );
173
      if (!$fileobj) {
174
        _warn(\@messages, 'Warning: file not saved for part: ' . $part->id . ' file: ' . $image_name);
175
      }
176
    }
177
  }
178

  
179
  if (@messages) {
180
    return join("\n", @messages);
181
  }
182
  return 'Shop parts created successfully';
183
}
184

  
185
1;
186

  
187
__END__
188

  
189
=encoding utf8
190

  
191
=head1 NAME
192

  
193
SL::BackgroundJob::ShopPartMassCreate - Background job to create shop
194
parts for all parts in the database that are marked as shop parts.
195

  
196
=head1 SYNOPSIS
197

  
198
This background job provides the basic functionality to create shop parts for
199
all parts in the database that are marked as shop parts.
200

  
201
It can also import images from a directory and assign them to the respective
202
shop parts. See configuration below.
203

  
204
It also assigns categories to the shop parts based on a custom variable of the
205
part.
206

  
207
The script may need individual adjustments to fit your specific use case.
208

  
209
=head1 CONFIGURATION
210

  
211
Accepts the following parameters:
212

  
213
=over 4
214

  
215
=item C<shop_id>
216

  
217
The id of the shop to create the shop parts in, defaults to 1
218

  
219
=item C<images_import_path>
220

  
221
The path to the images to import, defaults to 'shopimages/product/'
222

  
223
The file names of the images should be present in the 'image' field of the part,
224
in the following format:
225
  image1.jpg|image2.png|image3.gif
226

  
227
The images themselves should be present in the images_import_path.
228

  
229
=item C<cvar_categories>
230

  
231
The name of the custom variable that contains the categories, defaults to 'vm_product_categories'
232

  
233
Expects the Categories to be set in the custom variable of the part in the following format:
234
  Category1|Category2|Category3
235

  
236
Categories should be present in the shop under the same names.
237

  
238
=back
239

  
240
=head1 AUTHOR
241

  
242
Cem Aydin E<lt>cem.aydin@revamp-it.chE<gt>
243

  
244
=cut

Auch abrufbar als: Unified diff