Line # Revision Author
1 198 ahitrov package webshop::Keeper;
2
3 use strict;
4 use warnings 'all';
5 use base qw(Contenido::Keeper);
6
7 use Data::Dumper;
8 use Contenido::Globals;
9 use webshop::Basket;
10 use webshop::SQL::Basket;
11
12 sub add_item {
13 my $self = shift;
14 my $object = shift;
15 my (%options) = @_;
16
17 return unless ref $object;
18 return unless $object->item_id && $object->number;
19 return unless $object->uid || $object->session;
20
21
22 my %opts;
23 if ( $object->uid ) {
24 $opts{uid} = $object->uid;
25 } elsif ( $object->session ) {
26 $opts{session} = $object->session;
27 }
28 my @items = $keeper->get_documents (
29 class => 'webshop::Basket',
30 399 ahitrov status => 1,
31 198 ahitrov order_id=> 0,
32 %opts,
33 );
34 my $total = 0;
35 my $sum = 0;
36 my $found = 0;
37 if ( @items ) {
38 foreach my $item ( @items ) {
39 399 ahitrov if ( $object->item_id == $item->item_id && $object->color_id == $item->color_id &&
40 ((!$object->size_id && !$object->size) || ($object->size_id && $object->size_id == $item->size_id) || ($object->size && $object->size eq $item->size)) ) {
41 $item->number( $item->number + $object->number );
42 $item->price( $object->price );
43 198 ahitrov $item->store;
44 $found = 1;
45 }
46 $total += $item->number;
47 $sum += $item->number * $item->price;
48 }
49 }
50 unless ( $found ) {
51 $total += $object->number;
52 $sum += $object->number * $object->price;
53 $object->order_id(0);
54 $object->store;
55 }
56 my @plugins = split (/[\ |\t]+/, $state->{plugins});
57 363 ahitrov if ( grep { $_ eq 'session' } @plugins && ref $session ) {
58 $session->set ( basket_total => $total, basket_sum => $sum );
59 198 ahitrov }
60 return ($total, $sum);
61 }
62
63 391 ahitrov sub add_wishlist {
64 my $self = shift;
65 my $object = shift;
66 my (%options) = @_;
67
68 return unless ref $object;
69 return unless $object->item_id && $object->number;
70 return unless $object->uid || $object->session;
71
72
73 my %opts;
74 if ( $object->uid ) {
75 $opts{uid} = $object->uid;
76 } elsif ( $object->session ) {
77 $opts{session} = $object->session;
78 }
79 my @items = $keeper->get_documents (
80 class => 'webshop::Basket',
81 status => 0,
82 order_id=> 0,
83 %opts,
84 );
85 my $total = 0;
86 my $sum = 0;
87 my $found = 0;
88 if ( @items ) {
89 foreach my $item ( @items ) {
90 399 ahitrov if ( $object->item_id == $item->item_id && $object->color_id == $item->color_id &&
91 ((!$object->size_id && !$object->size) || ($object->size_id && $object->size_id == $item->size_id) || ($object->size && $object->size eq $item->size)) ) {
92 391 ahitrov $item->number($item->number + $object->number);
93 $item->store;
94 $found = 1;
95 }
96 $total += $item->number;
97 $sum += $item->number * $item->price;
98 }
99 }
100 unless ( $found ) {
101 $total += $object->number;
102 $sum += $object->number * $object->price;
103 $object->order_id(0);
104 $object->store;
105 }
106 return ($total, $sum);
107 }
108
109 198 ahitrov ### Метод приведения корзины для пользователя в момент логина
110 #############################################################
111 sub merge_basket {
112 my $self = shift;
113 my (%opts) = @_;
114
115 warn "Merge begin: ".Dumper(\%opts)."\n" if $DEBUG;
116 return unless $opts{uid} && $opts{session};
117
118 my @items = $keeper->get_documents (
119 class => 'webshop::Basket',
120 status => [1,0],
121 order_id=> 0,
122 session => $opts{session},
123 );
124 foreach my $item ( @items ) {
125 $item->session(undef);
126 $item->uid( $opts{uid} );
127 $item->store;
128 }
129 @items = $keeper->get_documents (
130 class => 'webshop::Basket',
131 status => 1,
132 order_id=> 0,
133 uid => $opts{uid},
134 );
135 my $total = 0;
136 my $sum = 0;
137 foreach my $item ( @items ) {
138 $total += $item->number;
139 $sum += $item->number * $item->price;
140 }
141 my @plugins = split (/[\ |\t]+/, $state->{plugins});
142 363 ahitrov if ( grep { $_ eq 'session' } @plugins && ref $session ) {
143 $session->set ( basket_total => $total, basket_sum => $sum );
144 198 ahitrov }
145 warn "Merge end\n" if $DEBUG;
146 return ($total, $sum);
147 }
148
149
150 sub get_basket {
151 my $self = shift;
152 my (%opts) = @_;
153
154 return unless $opts{uid} || $opts{session} || $opts{order_id};
155
156 my $uid = delete $opts{uid};
157 363 ahitrov my $session_id = delete $opts{session};
158 198 ahitrov unless ( exists $opts{order_id} && $opts{order_id} ) {
159 $opts{order_id} = 0;
160 if ( $uid ) {
161 $opts{uid} = $uid;
162 363 ahitrov } elsif ( $session_id ) {
163 $opts{session} = $session_id;
164 198 ahitrov }
165 }
166 $opts{status} = 1 unless exists $opts{status} && defined $opts{status};
167 my @items = $keeper->get_documents (
168 class => 'webshop::Basket',
169 %opts,
170 );
171 my $total = 0;
172 my $sum = 0;
173 foreach my $item ( @items ) {
174 if ( $item->status == 1 ) {
175 $total += $item->number;
176 $sum += $item->number * $item->price;
177 }
178 }
179 return \@items;
180 }
181
182
183 270 ahitrov sub basket_count {
184 my $self = shift;
185 my $basket = shift;
186 return (0,0) unless ref $basket eq 'ARRAY' && @$basket;
187
188 my $total = 0;
189 my $sum = 0;
190 foreach my $item ( @$basket ) {
191 if ( $item->status == 1 ) {
192 $total += $item->number;
193 $sum += $item->number * $item->price;
194 }
195 }
196 return ($total, $sum);
197 }
198
199
200 399 ahitrov sub wishlist_count {
201 my $self = shift;
202 my $basket = shift;
203 return (0,0) unless ref $basket eq 'ARRAY' && @$basket;
204
205 my $total = 0;
206 my $sum = 0;
207 foreach my $item ( @$basket ) {
208 if ( $item->status == 0 ) {
209 $total += $item->number;
210 $sum += $item->number * $item->price;
211 }
212 }
213 return ($total, $sum);
214 }
215
216
217 198 ahitrov sub clear_basket {
218 my $self = shift;
219 my (%opts) = @_;
220
221 return unless exists $opts{uid} || exists $opts{session};
222
223 my $table_name = webshop::SQL::Basket->db_table;
224 my $request = "delete from $table_name where order_id = 0 AND status = 1 AND";
225 my $dbh = $keeper->SQL;
226 my @vals;
227 if ( exists $opts{uid} && $opts{uid} ) {
228 $request .= " uid in (?)";
229 push @vals, $opts{uid};
230 } elsif ( exists $opts{session} ) {
231 $request .= " session in (?)";
232 push @vals, $opts{session};
233 }
234 warn "CLEAR: [$request]. VALS: [".join(',',@vals)."]\n" if $DEBUG;
235 my $statement = $dbh->prepare ($request);
236 $statement->execute( @vals ) || $log->error("DBI execute error on $request\n"."\ncalled with opts:\n".Data::Dumper::Dumper(\%opts));;
237 $statement->finish;
238
239 my @plugins = split (/[\ |\t]+/, $state->{plugins});
240 363 ahitrov if ( grep { $_ eq 'session' } @plugins && ref $session ) {
241 $session->set ( basket_total => 0, basket_sum => 0 );
242 198 ahitrov }
243 }
244
245
246 sub clear_wishlist {
247 my $self = shift;
248 my (%opts) = @_;
249
250 return unless exists $opts{uid} || exists $opts{session};
251
252 my $table_name = webshop::SQL::Basket->db_table;
253 my $request = "delete from $table_name where order_id = 0 AND status = 0 AND";
254 my $dbh = $keeper->SQL;
255 my @vals;
256 if ( exists $opts{uid} ) {
257 $request .= " uid in (?)";
258 push @vals, $opts{uid};
259 } elsif ( exists $opts{session} ) {
260 $request .= " session in (?)";
261 push @vals, $opts{session};
262 }
263 my $statement = $dbh->prepare ($request);
264 $statement->execute( @vals ) || $log->error("DBI execute error on $request\n"."\ncalled with opts:\n".Data::Dumper::Dumper(\%opts));;
265 $statement->finish;
266 }
267
268
269 ### Метод пересчета корзины
270 # Принимает на вход параметры:
271 # session => session_id пользователя
272 # uid => UID пользователя
273 # delete => массив или отдельный item_id
274 # renumber => ссылка на хеш вида item => number
275 #############################################################
276 sub recount {
277 my $self = shift;
278 my (%opts) = @_;
279
280 warn "Recount Started!!!\n" if $DEBUG;
281 return unless exists $opts{uid} || exists $opts{session} || exists $opts{order_id};
282 my $basket = $self->get_basket ( %opts );
283 return unless ref $basket eq 'ARRAY' && @$basket;
284
285 warn Dumper(\%opts) if $DEBUG;
286
287 my $total = 0;
288 my $sum = 0;
289 my @new_basket;
290 my $session_no_store = delete $opts{session_no_store};
291 foreach my $item ( @$basket ) {
292 my $delete = 0;
293 if ( exists $opts{renumber} && ref $opts{renumber} eq 'HASH' && exists $opts{renumber}{$item->id} && int($opts{renumber}{$item->id}) == 0 ) {
294 $delete = 1;
295 } elsif ( exists $opts{delete} && ref $opts{delete} eq 'ARRAY' ) {
296 $delete = 1 if grep { $_ == $item->id } @{ $opts{delete} };
297 } elsif ( exists $opts{delete} && $opts{delete} ) {
298 $delete = 1 if $item->id == $opts{delete};
299 }
300 if ( $delete ) {
301 warn "Item ID=".$item->id." DELETE\n" if $DEBUG;
302 $item->delete();
303 next;
304 } else {
305 my $store = 0;
306 if ( exists $opts{renumber} && ref $opts{renumber} eq 'HASH' && exists $opts{renumber}{$item->id} && $opts{renumber}{$item->id} != $item->number ) {
307 $item->number( $opts{renumber}{$item->id} );
308 $store = 1;
309 }
310 if ( exists $opts{price} && ref $opts{price} eq 'HASH' && exists $opts{price}{$item->id} && $opts{price}{$item->id} != $item->price ) {
311 $item->price( $opts{price}{$item->id} );
312 $store = 1;
313 }
314 $item->store if $store;
315 $total += $item->number;
316 $sum += $item->number * $item->price;
317 push @new_basket, $item;
318 }
319 }
320 my @plugins = split (/[\ |\t]+/, $state->{plugins});
321 363 ahitrov if ( !$session_no_store && grep { $_ eq 'session' } @plugins && ref $session ) {
322 $session->set ( basket_total => $total, basket_sum => $sum );
323 198 ahitrov }
324 return ($total, $sum, \@new_basket);
325 }
326
327
328 sub get_orders {
329 my $self = shift;
330 my (%opts) = @_;
331
332 my $list = delete $opts{list};
333 $opts{order_by} ||= 'status';
334 my @items = $keeper->get_documents (
335 class => 'webshop::Order',
336 %opts,
337 );
338 if ( exists $opts{id} && defined $opts{id} && !ref $opts{id} ) {
339 if ( $list ) {
340 $items[0]->{list} = $self->get_order_list( order_id => $opts{id} );
341 }
342 return $items[0];
343 } else {
344 if ( $list ) {
345 map { $_->{list} = $self->get_order_list( order_id => $_->id ) } @items;
346 }
347 return \@items;
348 }
349 }
350
351
352 sub get_order_list {
353 my $self = shift;
354 my (%opts) = @_;
355
356 return unless $opts{order_id};
357
358 $opts{status} = 1;
359 my @items = $keeper->get_documents (
360 class => 'webshop::Basket',
361 %opts,
362 );
363 my $total = 0;
364 my $sum = 0;
365 foreach my $item ( @items ) {
366 my $Item = $item->class->new( $keeper, $item->id );
367 $item->{item} = $Item;
368 if ( $item->status == 1 ) {
369 $total += $item->number;
370 $sum += $item->number * $item->price;
371 }
372 }
373 return \@items;
374 }
375
376 270 ahitrov
377 ### Метод приведения купонов для пользователя в момент логина
378 #############################################################
379 sub merge_coupons {
380 my $self = shift;
381 my (%opts) = @_;
382
383 warn "Merge (coupons) begin: ".Dumper(\%opts)."\n" if $DEBUG;
384 return unless $opts{uid} && $opts{session};
385
386 my @items = $keeper->get_links (
387 class => 'webshop::OrderCouponLink',
388 session => $opts{session},
389 source_id => 0,
390 );
391 my %merge_to = $keeper->get_links (
392 class => 'webshop::OrderCouponLink',
393 uid => $opts{uid},
394 source_id => 0,
395 return_mode => 'hash',
396 hash_by => 'dest_id',
397 );
398 foreach my $item ( @items ) {
399 if ( exists $merge_to{$item->dest_id} ) {
400 $item->delete;
401 } else {
402 $item->session( undef );
403 $item->uid( $opts{uid} );
404 $item->store;
405 }
406 }
407 }
408
409
410 424 ahitrov sub check_discount {
411 my $self = shift;
412 my (%opts) = @_;
413 270 ahitrov
414 424 ahitrov warn "Check discount begin: ".Dumper(\%opts)."\n" if $DEBUG;
415 my %dopts;
416 if ( exists $opts{uid} && $opts{uid} ) {
417 $dopts{uid} = [0,1];
418 } else {
419 $dopts{uid} = 0;
420 }
421 my $basket = exists $opts{basket} ? $opts{basket} : $self->get_basket( %opts );
422
423 my @discounts = $keeper->get_documents(
424 class => 'webshop::Discount',
425 status => 1,
426 %dopts
427 );
428 }
429
430
431 198 ahitrov sub price_format {
432 my $self = shift;
433 my $price = shift;
434
435 $price = reverse $price;
436 $price =~ s/(\d{3})/$1\ /g;
437 $price = reverse $price;
438
439 return $price;
440 }
441
442
443 1;