re-work importer to allow new sources and targets to be implemented
[bse.git] / site / cgi-bin / modules / BSE / ImportTargetProduct.pm
CommitLineData
3709451d
TC
1package BSE::ImportTargetProduct;
2use strict;
3use base 'BSE::ImportTargetArticle';
4use BSE::API qw(bse_make_product bse_make_catalog bse_add_image);
5use Articles;
6use Products;
7
8sub new {
9 my ($class, %opts) = @_;
10
11 my $self = $class->SUPER::new(%opts);
12
13 my $importer = delete $opts{importer};
14
15 $self->{price_dollar} = $importer->cfg_entry('price_dollar', 0);
16 $self->{product_template} = $importer->cfg_entry('product_template');
17 $self->{catalog_template} = $importer->cfg_entry('catalog_template');
18
19 defined $map->{retailPrice}
20 or die "No retailPrice mapping found\n";
21
22 return $self;
23}
24
25sub xform_entry {
26 my ($self, $importer, $entry) = @_;
27
28 $self->SUPER::xform_entry($importer, $entry);
29
30 if ($self->{use_codes}) {
31 $entry->{product_code} =~ /\S/
32 or die "product_code blank with use_codes\n";
33 }
34 $entry->{retailPrice} =~ s/\$//; # in case
35
36 if ($entry->{retailPrice} =~ /\d/) {
37 $self->{price_dollar}
38 and $entry->{retailPrice} *= 100;
39 }
40 else {
41 $importer->warn("Warning: no price");
42 $entry->{retailPrice} = 0;
43 }
44}
45
46sub children_of {
47 my ($self, $parent) = @_;
48
49 return grep $_->{generator} eq 'Generate::Catalog',
50 Articles->children($parent);
51}
52
53sub make_parent {
54 my ($self, $importer, %entry) = @_;
55
56 exists $entry{template}
57 or $entry{template} = $importer->cfg_entry("catalog_template");
58
59 return bse_make_catalog(%entry);
60}
61
62sub find_leaf {
63 my ($self, $leaf_id) = @_;
64
65 my ($leaf) = Products->getBy($self->{id_field}, $leaf_id)
66 or return;
67
68 return $leaf;
69}
70
71sub make_leaf {
72 my ($self, $importer, %entry) = @_;
73
74 exists $entry{template}
75 or $entry{template} = $importer->cfg_entry("leaf_template");
76
77 return bse_make_product(%entry);
78}
79
80
81sub xxrow {
82 my ($self, $importer, $entry, $parents) = @_;
83
84 defined $entry->{template}
85 or $entry->{template} = $self->{product_template};
86
87 $entry->{title} =~ /\S/
88 or die "title blank\n";
89 if ($self->{use_codes}) {
90 $entry->{product_code} =~ /\S/
91 or die "product_code blank with use_codes\n";
92 }
93 $entry->{retailPrice} =~ s/\$//; # in case
94
95 if ($entry->{retailPrice} =~ /\d/) {
96 $self->{price_dollar}
97 and $entry->{retailPrice} *= 100;
98 }
99 else {
100 $importer->warn("Warning: no price");
101 $entry->{retailPrice} = 0;
102 }
103 $entry->{title} =~ /\n/
104 and die "Title may not contain newlines";
105 $entry->{summary}
106 or $entry->{summary} = $entry->{title};
107 $entry->{description}
108 or $entry->{description} = $entry->{title};
109 $entry->{body}
110 or $entry->{body} = $entry->{title};
111
112 $entry->{parentid} = $self->_find_parent($importer, $self->{parent}, @$parents);
113 my $product;
114 if ($self->{use_codes}) {
115 $product = Products->getBy(product_code => $entry->{product_code});
116 }
117 if ($product) {
118 @{$product}{keys %$entry} = values %$entry;
119 $product->save;
120 $importer->info("Updated $product->{id}: $entry->{title}");
121 if ($self->{reset_images}) {
122 $product->remove_images($importer->cfg);
123 $importer->info(" $product->{id}: Reset images");
124 }
125 }
126 else {
127 $product = bse_make_product
128 (
129 cfg => $self->{cfg},
130 %$entry
131 );
132 $importer->info("Added $product->{id}: $entry->{title}");
133 }
134 for my $image_index (1 .. 10) {
135 my $file = $entry->{"image${image_index}_file"};
136 $file
137 or next;
138 my $full_file = $importer->find_file($file);
139 $full_file
140 or die "File '$file' not found for image$image_index\n";
141
142 my %opts = ( file => $full_file );
143 for my $key (qw/alt name url storage/) {
144 my $fkey = "image${image_index}_$key";
145 $entry->{$fkey}
146 and $opts{$key} = $entry->{$fkey};
147 }
148
149 my %errors;
150 my $im = bse_add_image($self->{cfg}, $product, %opts,
151 errors => \%errors);
152 $im
153 or die join(", ",map "$_: $errors{$_}", keys %errors), "\n";
154 $importer->info(" $product->{id}: Add image '$file'");
155 }
156 push @{$self->{leaves}}, $product;
157}
158
159sub xx_find_parent {
160 my ($self, $importer, $parent, @parents) = @_;
161
162 @parents
163 or return $parent;
164 my $cache = $self->{parent_cache};
165 unless ($cache->{$parent}) {
166 my @kids = grep $_->{generator} eq 'Generate::Catalog',
167 Articles->children($parent);
168 $cache->{$parent} = \@kids;
169 }
170
171 my $title = shift @parents;
172 my ($cat) = grep lc $_->{title} eq lc $title, @{$cache->{$parent}};
173 unless ($cat) {
174 my %opts =
175 (
176 cfg => $self->{cfg},
177 parentid => $parent,
178 title => $title,
179 body => $title,
180 );
181 $self->{catalog_template}
182 and $opts{template} = $self->{catalog_template};
183 $cat = bse_make_catalog(%opts);
184 $importer->info("Add catalog $cat->{id}: $title");
185 push @{$cache->{$parent}}, $cat;
186 }
187
188 unless ($self->{catseen}{$cat->{id}}) {
189 $self->{catseen}{$cat->{id}} = 1;
190 push @{$self->{catalogs}}, $cat;
191 }
192
193 return $self->_find_parent($importer, $cat->{id}, @parents);
194}
195
196sub default_parent { 3 }
197
198sub default_code_field { "product_code" }
199
2001;