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 517 ahitrov my @items_session = $keeper->get_documents (
119 198 ahitrov class => 'webshop::Basket',
120 status => [1,0],
121 session => $opts{session},
122 517 ahitrov order_id => 0,
123 198 ahitrov );
124 517 ahitrov my @items_user = $keeper->get_documents (
125 198 ahitrov class => 'webshop::Basket',
126 471 ahitrov status => [1,0],
127 198 ahitrov order_id=> 0,
128 uid => $opts{uid},
129 );
130 471 ahitrov my ($basket_total, $basket_sum, $wishlist_total, $wishlist_sum) = (0,0,0,0);
131 802 ahitrov my %p_ids = map { $_->item_id => 1 } (@items_user, @items_session);
132 my @p_ids = keys %p_ids;
133 my $products = @p_ids ? $keeper->get_documents(
134 id => \@p_ids,
135 class => $state->{webshop}->{item_document_class},
136 return_mode => 'hash_ref',
137 ) : {};
138
139 517 ahitrov foreach my $item ( @items_user ) {
140 802 ahitrov my $product = exists $products->{$item->item_id} ? $products->{$item->item_id} : undef;
141 517 ahitrov my ($item_from_session) = grep {
142 $_->item_id == $item->item_id
143 && $_->status == $item->status
144 && ($_->color_id || 0) == ($item->color_id || 0)
145 && ($_->size_id || 0) == ($item->size_id || 0)
146 && ($_->colour || '') eq ($item->colour || '')
147 && ($_->size || '') eq ($item->size || '')
148 } @items_session;
149 if ( ref $item_from_session ) {
150 warn "Merge basket: Found identical item id=".$item_from_session->id."\n" if $DEBUG;
151 $item->number( $item->number + $item_from_session->number );
152 802 ahitrov $item->price( ref $product ? $product->price : $item_from_session->price );
153 517 ahitrov $item->store;
154 $item_from_session->status(-1);
155 $item_from_session->delete;
156 }
157 471 ahitrov if ( $item->status == 1 ) {
158 $basket_total += $item->number;
159 $basket_sum += $item->number * $item->price;
160 } else {
161 $wishlist_total += $item->number;
162 $wishlist_sum += $item->number * $item->price;
163 }
164 198 ahitrov }
165 517 ahitrov foreach my $item ( @items_session ) {
166 802 ahitrov my $product = exists $products->{$item->item_id} ? $products->{$item->item_id} : undef;
167 517 ahitrov if ( $item->status > 0 ) {
168 $item->session(undef);
169 $item->uid( $opts{uid} );
170 802 ahitrov if ( ref $product ) {
171 $item->price( $product->price );
172 }
173 517 ahitrov $item->store;
174 if ( $item->status == 1 ) {
175 $basket_total += $item->number;
176 $basket_sum += $item->number * $item->price;
177 } else {
178 $wishlist_total += $item->number;
179 $wishlist_sum += $item->number * $item->price;
180 }
181 }
182 }
183 471 ahitrov warn "Merge end\n" if $DEBUG;
184 return ($basket_total, $basket_sum, $wishlist_total, $wishlist_sum);
185 198 ahitrov }
186
187
188 sub get_basket {
189 my $self = shift;
190 my (%opts) = @_;
191
192 return unless $opts{uid} || $opts{session} || $opts{order_id};
193
194 429 ahitrov my $with_products = delete $opts{with_products} || 0;
195 449 ahitrov my $product_status = exists $opts{product_status} ? delete $opts{product_status} : 'positive';
196 198 ahitrov my $uid = delete $opts{uid};
197 363 ahitrov my $session_id = delete $opts{session};
198 198 ahitrov unless ( exists $opts{order_id} && $opts{order_id} ) {
199 $opts{order_id} = 0;
200 if ( $uid ) {
201 $opts{uid} = $uid;
202 363 ahitrov } elsif ( $session_id ) {
203 $opts{session} = $session_id;
204 198 ahitrov }
205 }
206 $opts{status} = 1 unless exists $opts{status} && defined $opts{status};
207 429 ahitrov my @basket = $keeper->get_documents (
208 198 ahitrov class => 'webshop::Basket',
209 %opts,
210 );
211 my $total = 0;
212 my $sum = 0;
213 429 ahitrov my $items;
214 if ( $with_products ) {
215 my %ids = map { $_->item_id => 1 } @basket;
216 my @ids = keys %ids;
217 $items = @ids ? $keeper->get_documents (
218 id => \@ids,
219 class => $state->{webshop}->{item_document_class},
220 449 ahitrov status => $product_status,
221 429 ahitrov return_mode => 'hash_ref',
222 ) : {};
223 }
224 foreach my $bi ( @basket ) {
225 if ( $bi->status == 1 ) {
226 $total += $bi->number;
227 $sum += $bi->number * ($bi->price || 0);
228 198 ahitrov }
229 429 ahitrov if ( ref $items eq 'HASH' && exists $items->{$bi->item_id} ) {
230 $bi->{item} = $items->{$bi->item_id};
231 }
232 198 ahitrov }
233 429 ahitrov return \@basket;
234 198 ahitrov }
235
236
237 270 ahitrov sub basket_count {
238 my $self = shift;
239 my $basket = shift;
240 return (0,0) unless ref $basket eq 'ARRAY' && @$basket;
241 572 ahitrov my (%opts) = @_;
242 my $with_products = delete $opts{with_products};
243 270 ahitrov
244 my $total = 0;
245 my $sum = 0;
246 foreach my $item ( @$basket ) {
247 if ( $item->status == 1 ) {
248 $total += $item->number;
249 767 ahitrov if ( exists $item->{item} && $item->{item}->status && $item->{item}->price && $item->{item}->storage ) {
250 509 ahitrov $sum += $item->number * $item->{item}->price;
251 572 ahitrov } elsif ( !$with_products ) {
252 509 ahitrov $sum += $item->number * $item->price;
253 }
254 270 ahitrov }
255 }
256 return ($total, $sum);
257 }
258
259
260 399 ahitrov sub wishlist_count {
261 my $self = shift;
262 my $basket = shift;
263 return (0,0) unless ref $basket eq 'ARRAY' && @$basket;
264
265 my $total = 0;
266 my $sum = 0;
267 foreach my $item ( @$basket ) {
268 if ( $item->status == 0 ) {
269 $total += $item->number;
270 $sum += $item->number * $item->price;
271 }
272 }
273 return ($total, $sum);
274 }
275
276
277 198 ahitrov sub clear_basket {
278 my $self = shift;
279 my (%opts) = @_;
280
281 return unless exists $opts{uid} || exists $opts{session};
282
283 my $table_name = webshop::SQL::Basket->db_table;
284 my $request = "delete from $table_name where order_id = 0 AND status = 1 AND";
285 my $dbh = $keeper->SQL;
286 my @vals;
287 if ( exists $opts{uid} && $opts{uid} ) {
288 $request .= " uid in (?)";
289 push @vals, $opts{uid};
290 } elsif ( exists $opts{session} ) {
291 $request .= " session in (?)";
292 push @vals, $opts{session};
293 }
294 warn "CLEAR: [$request]. VALS: [".join(',',@vals)."]\n" if $DEBUG;
295 my $statement = $dbh->prepare ($request);
296 $statement->execute( @vals ) || $log->error("DBI execute error on $request\n"."\ncalled with opts:\n".Data::Dumper::Dumper(\%opts));;
297 $statement->finish;
298
299 my @plugins = split (/[\ |\t]+/, $state->{plugins});
300 363 ahitrov if ( grep { $_ eq 'session' } @plugins && ref $session ) {
301 $session->set ( basket_total => 0, basket_sum => 0 );
302 198 ahitrov }
303 }
304
305
306 sub clear_wishlist {
307 my $self = shift;
308 my (%opts) = @_;
309
310 return unless exists $opts{uid} || exists $opts{session};
311
312 my $table_name = webshop::SQL::Basket->db_table;
313 my $request = "delete from $table_name where order_id = 0 AND status = 0 AND";
314 my $dbh = $keeper->SQL;
315 my @vals;
316 if ( exists $opts{uid} ) {
317 $request .= " uid in (?)";
318 push @vals, $opts{uid};
319 } elsif ( exists $opts{session} ) {
320 $request .= " session in (?)";
321 push @vals, $opts{session};
322 }
323 my $statement = $dbh->prepare ($request);
324 $statement->execute( @vals ) || $log->error("DBI execute error on $request\n"."\ncalled with opts:\n".Data::Dumper::Dumper(\%opts));;
325 $statement->finish;
326 }
327
328
329 ### Метод пересчета корзины
330 # Принимает на вход параметры:
331 # session => session_id пользователя
332 # uid => UID пользователя
333 # delete => массив или отдельный item_id
334 # renumber => ссылка на хеш вида item => number
335 #############################################################
336 sub recount {
337 my $self = shift;
338 my (%opts) = @_;
339
340 warn "Recount Started!!!\n" if $DEBUG;
341 return unless exists $opts{uid} || exists $opts{session} || exists $opts{order_id};
342 my $basket = $self->get_basket ( %opts );
343 return unless ref $basket eq 'ARRAY' && @$basket;
344
345 warn Dumper(\%opts) if $DEBUG;
346
347 my $total = 0;
348 my $sum = 0;
349 my @new_basket;
350 my $session_no_store = delete $opts{session_no_store};
351 foreach my $item ( @$basket ) {
352 my $delete = 0;
353 if ( exists $opts{renumber} && ref $opts{renumber} eq 'HASH' && exists $opts{renumber}{$item->id} && int($opts{renumber}{$item->id}) == 0 ) {
354 $delete = 1;
355 } elsif ( exists $opts{delete} && ref $opts{delete} eq 'ARRAY' ) {
356 $delete = 1 if grep { $_ == $item->id } @{ $opts{delete} };
357 } elsif ( exists $opts{delete} && $opts{delete} ) {
358 $delete = 1 if $item->id == $opts{delete};
359 }
360 if ( $delete ) {
361 warn "Item ID=".$item->id." DELETE\n" if $DEBUG;
362 $item->delete();
363 next;
364 } else {
365 my $store = 0;
366 if ( exists $opts{renumber} && ref $opts{renumber} eq 'HASH' && exists $opts{renumber}{$item->id} && $opts{renumber}{$item->id} != $item->number ) {
367 $item->number( $opts{renumber}{$item->id} );
368 $store = 1;
369 }
370 if ( exists $opts{price} && ref $opts{price} eq 'HASH' && exists $opts{price}{$item->id} && $opts{price}{$item->id} != $item->price ) {
371 $item->price( $opts{price}{$item->id} );
372 $store = 1;
373 }
374 $item->store if $store;
375 $total += $item->number;
376 $sum += $item->number * $item->price;
377 push @new_basket, $item;
378 }
379 }
380 my @plugins = split (/[\ |\t]+/, $state->{plugins});
381 363 ahitrov if ( !$session_no_store && grep { $_ eq 'session' } @plugins && ref $session ) {
382 $session->set ( basket_total => $total, basket_sum => $sum );
383 198 ahitrov }
384 return ($total, $sum, \@new_basket);
385 }
386
387
388 sub get_orders {
389 my $self = shift;
390 my (%opts) = @_;
391
392 my $list = delete $opts{list};
393 434 ahitrov my $count = delete $opts{count};
394 if ( $count ) {
395 delete $opts{order_by};
396 my $item_count = $keeper->get_documents (
397 class => 'webshop::Order',
398 count => 1,
399 %opts,
400 );
401 return $item_count;
402 198 ahitrov } else {
403 434 ahitrov $opts{order_by} ||= 'status';
404 my @items = $keeper->get_documents (
405 class => 'webshop::Order',
406 %opts,
407 );
408 if ( exists $opts{id} && defined $opts{id} && !ref $opts{id} ) {
409 if ( $list ) {
410 $items[0]->{list} = $self->get_order_list( order_id => $opts{id} );
411 }
412 return $items[0];
413 } else {
414 if ( $list ) {
415 map { $_->{list} = $self->get_order_list( order_id => $_->id ) } @items;
416 }
417 return \@items;
418 198 ahitrov }
419 }
420 }
421
422
423 sub get_order_list {
424 my $self = shift;
425 my (%opts) = @_;
426
427 return unless $opts{order_id};
428
429 $opts{status} = 1;
430 my @items = $keeper->get_documents (
431 class => 'webshop::Basket',
432 %opts,
433 );
434 my $total = 0;
435 my $sum = 0;
436 foreach my $item ( @items ) {
437 my $Item = $item->class->new( $keeper, $item->id );
438 $item->{item} = $Item;
439 if ( $item->status == 1 ) {
440 $total += $item->number;
441 $sum += $item->number * $item->price;
442 }
443 }
444 return \@items;
445 }
446
447 270 ahitrov
448 ### Метод приведения купонов для пользователя в момент логина
449 #############################################################
450 sub merge_coupons {
451 my $self = shift;
452 my (%opts) = @_;
453
454 warn "Merge (coupons) begin: ".Dumper(\%opts)."\n" if $DEBUG;
455 return unless $opts{uid} && $opts{session};
456
457 my @items = $keeper->get_links (
458 class => 'webshop::OrderCouponLink',
459 session => $opts{session},
460 source_id => 0,
461 );
462 578 ahitrov my $merge_to = $keeper->get_links (
463 270 ahitrov class => 'webshop::OrderCouponLink',
464 uid => $opts{uid},
465 source_id => 0,
466 578 ahitrov return_mode => 'array_ref',
467 270 ahitrov );
468 578 ahitrov my %merge_to;
469 foreach my $link ( @$merge_to ) {
470 if ( exists $merge_to{$link->dest_id} ) {
471 $link->delete;
472 } else {
473 $merge_to{$link->dest_id} = $link;
474 }
475 }
476 270 ahitrov foreach my $item ( @items ) {
477 if ( exists $merge_to{$item->dest_id} ) {
478 $item->delete;
479 } else {
480 $item->session( undef );
481 $item->uid( $opts{uid} );
482 $item->store;
483 }
484 }
485 }
486
487
488 424 ahitrov sub check_discount {
489 my $self = shift;
490 my (%opts) = @_;
491 270 ahitrov
492 432 ahitrov warn "Check discount begin:\n" if $DEBUG;
493 424 ahitrov my %dopts;
494 if ( exists $opts{uid} && $opts{uid} ) {
495 $dopts{uid} = [0,1];
496 } else {
497 $dopts{uid} = 0;
498 }
499 429 ahitrov my $basket = exists $opts{basket} ? $opts{basket} : $self->get_basket( %opts, with_products => 1 );
500 return 0 unless ref $basket eq 'ARRAY' && @$basket;
501 my @basket = grep { exists $_->{item} && $_->{item} } @$basket;
502 return 0 unless @basket;
503 424 ahitrov
504 787 ahitrov my $payment = delete $opts{payment};
505 if ( $payment && !ref $payment ) {
506 if ( $payment =~ /^\d+$/ ) {
507 $payment = $keeper->get_document_by_id($payment, class => 'webshop::Payment');
508 }
509 }
510
511 425 ahitrov my $now = Contenido::DateTime->new;
512 424 ahitrov my @discounts = $keeper->get_documents(
513 class => 'webshop::Discount',
514 status => 1,
515 425 ahitrov interval=> [$now, $now],
516 %dopts,
517 424 ahitrov );
518 425 ahitrov my @summoned = sort { $b->min_sum <=> $a->min_sum } grep { $_->min_sum && $_->discount && $_->min_sum =~ /^\d+$/ } @discounts;
519 429 ahitrov my ($total, $sum) = $self->basket_count( \@basket );
520 425 ahitrov return 0 unless $sum;
521 my $result = 0;
522 foreach my $discount ( @summoned ) {
523 if ( $sum > $discount->min_sum ) {
524 429 ahitrov my $res = $discount->get_discount( basket => \@basket );
525 425 ahitrov $result = $res if $res > $result;
526 }
527 }
528 787 ahitrov
529 my $summarize = 0;
530 if ( ref $payment && $payment->discount && $payment->discount > 0 ) {
531 my $payment_discount = $payment->discount / 100;
532 my $payment_discount_sum = 0;
533 if ( $payment->exclude_specials ) {
534 foreach my $item ( @basket ) {
535 next if $item->special_price;
536 $payment_discount_sum += $item->price;
537 }
538 $payment_discount_sum = int($payment_discount_sum * $payment_discount);
539 } else {
540 $payment_discount_sum = int($sum * $payment_discount);
541 }
542 if ( $payment->summarize ) {
543 $summarize = 1;
544 $result += $payment_discount_sum if $payment_discount_sum + $result < $sum;
545 } else {
546 $result = $payment_discount_sum if $payment_discount_sum > $result;
547 }
548 }
549
550 425 ahitrov $result = 0 if $result >= $sum;
551 787 ahitrov return ($result, $summarize);
552 424 ahitrov }
553
554
555 432 ahitrov sub check_coupons {
556 my $self = shift;
557 my (%opts) = @_;
558
559 warn "Check coupons begin:\n" if $DEBUG;
560 my %dopts;
561 if ( exists $opts{uid} && $opts{uid} ) {
562 $dopts{luid} = $opts{uid};
563 } else {
564 $dopts{lsession} = $opts{session};
565 }
566 my $basket = exists $opts{basket} ? $opts{basket} : $self->get_basket( %opts, with_products => 1 );
567 return (0, []) unless ref $basket eq 'ARRAY' && @$basket;
568 my @basket = grep { exists $_->{item} && $_->{item} } @$basket;
569 return (0, []) unless @basket;
570
571 my $now = Contenido::DateTime->new;
572 my @coupons = exists $opts{coupons} && ref $opts{coupons} eq 'ARRAY' ? @{$opts{coupons}} : $keeper->get_documents(
573 class => 'webshop::Coupon',
574 lclass => 'webshop::OrderCouponLink',
575 lsource => 0,
576 status => 1,
577 interval=> [$now->ymd, $now->ymd],
578 %dopts,
579 );
580 return (0, []) unless @coupons;
581 684 ahitrov my @usable = grep { $_->discount } @coupons;
582 685 ahitrov warn "We count on ".scalar(@usable)." coupons: [".join(', ', map { $_->id.'. '.$_->name } @usable)."]\n" if $DEBUG;
583 432 ahitrov my ($total, $sum) = $self->basket_count( \@basket );
584 684 ahitrov return (0, \@usable) unless $sum;
585 my %summoned = ( coupons => [], discount => 0 );
586 my @groups;
587 foreach my $coupon ( @usable ) {
588 if ( $coupon->summon ) {
589 push @{$summoned{coupons}}, $coupon;
590 } else {
591 push @groups, { coupons => [$coupon], discount => 0 };
592 }
593 }
594 432 ahitrov my $result = 0;
595 684 ahitrov foreach my $coupon ( @usable ) {
596 432 ahitrov my $res = $coupon->get_discount( basket => \@basket );
597 $coupon->{result} = $res;
598 }
599 684 ahitrov foreach my $group ( @groups ) {
600 $group->{discount} = $group->{coupons}->[0]->{result};
601 $group->{coupons}->[0]->{afflict_order} = 1;
602 }
603 if ( @{$summoned{coupons}} ) {
604 @{$summoned{coupons}} = sort { $b->{result} <=> $a->{result} } @{$summoned{coupons}};
605 my $check = $sum;
606 foreach my $coupon ( @{$summoned{coupons}} ) {
607 if ( ($coupon->{result} > 0) && ($check - $coupon->{result} > 0) ) {
608 $summoned{discount} += $coupon->{result};
609 $check -= $coupon->{result};
610 $coupon->{afflict_order} = 1;
611 } else {
612 $coupon->{afflict_order} = 0;
613 }
614 432 ahitrov }
615 684 ahitrov unshift @groups, \%summoned;
616 432 ahitrov }
617 684 ahitrov
618 @groups = sort { $b->{discount} <=> $a->{discount} } @groups;
619 687 ahitrov my %chosen = map { $_->id => $_ } @{$groups[0]->{coupons}};
620 foreach my $coupon ( @usable ) {
621 if ( !exists $chosen{$coupon->id} ) {
622 $coupon->{afflict_order} = 0;
623 }
624 }
625 685 ahitrov warn "We choose ".scalar(@{$groups[0]->{coupons}})." coupons: [".join(', ', map { $_->id.'. '.$_->name } @{$groups[0]->{coupons}})."]\n" if $DEBUG;
626 687 ahitrov return ($groups[0]->{discount}, \@usable);
627 432 ahitrov }
628
629
630 675 ahitrov sub register_coupon {
631 my $self = shift;
632 my ($code, $session) = @_;
633 my %result;
634 my %opts;
635
636 if ( ref $session ) {
637 if ( $code ) {
638 $code =~ s/([%_\\])/\\$1/g;
639 if ( $session->id ) {
640 $opts{uid} = $session->{id};
641 } else {
642 $opts{session} = $session->_session_id;
643 }
644 my $basket = $self->get_basket (
645 %opts,
646 with_products => 1
647 );
648 my $now = Contenido::DateTime->new;
649 my @reglinks = $keeper->get_links (
650 class => 'webshop::OrderCouponLink',
651 source_id => 0,
652 %opts,
653 );
654 my %cids = map { $_->dest_id => 1 } @reglinks;
655 my @cids = keys %cids;
656 my @registered = @cids ? $keeper->get_documents(
657 id => \@cids,
658 class => 'webshop::Coupon',
659 ) : ();
660 679 ahitrov my ($coupon) = grep { uc(Encode::decode('utf-8', $_->code)) eq uc(Encode::decode('utf-8', $code)) } @registered;
661 675 ahitrov @registered = grep {
662 my $bt = Contenido::DateTime->new( postgres => $_->dtime );
663 my $et = Contenido::DateTime->new( postgres => $_->etime );
664 $now >= $bt && $now <= $et && $_->status == 1
665 } @registered;
666 $result{coupons} = \@registered;
667 if ( ref $coupon ) {
668 $result{error} = 'Такой купон уже зарегистрирован';
669 $result{found} = $coupon;
670 } else {
671 ($coupon) = $keeper->get_documents(
672 class => 'webshop::Coupon',
673 code => $code,
674 uid => 0,
675 status => [1,3],
676 interval => [$now, $now],
677 ilike => 1,
678 );
679 if ( $session->id && !ref $coupon ) {
680 ($coupon) = $keeper->get_documents(
681 class => 'webshop::Coupon',
682 code => $code,
683 uid => $session->id,
684 status => [1,3],
685 interval => [$now, $now],
686 ilike => 1,
687 );
688 }
689 if ( ref $coupon ) {
690 if ( $coupon->uid && $coupon->status == 3 ) {
691 $result{error} = 'Купон уже использован';
692 }
693 unless ( exists $result{error} && $result{error} ) {
694 my $coupon_link = webshop::OrderCouponLink->new( $keeper );
695 $coupon_link->status( 0 );
696 if ( $session->id ) {
697 $coupon_link->uid( $session->id );
698 } else {
699 $coupon_link->uid( 0 );
700 $coupon_link->session( $session->_session_id );
701 }
702 $coupon_link->dest_id( $coupon->id );
703 $coupon_link->dest_class( $coupon->class );
704 $coupon_link->source_id( 0 );
705 $coupon_link->source_class( 'webshop::Order' );
706 $coupon_link->store;
707 $result{created} = $coupon;
708 push @registered, $coupon;
709 }
710 } else {
711 $result{error} = 'Купон не найден';
712 }
713 }
714 } else {
715 $result{error} = 'Вы не указали код купона';
716 }
717 } else {
718 $result{error} = 'Фатальная ошибка. Не работают сессии! Обратитесь в службу поддержки магазина';
719 }
720
721 return \%result;
722 }
723
724
725 198 ahitrov sub price_format {
726 my $self = shift;
727 my $price = shift;
728
729 572 ahitrov if ( defined $price ) {
730 $price = reverse $price;
731 $price =~ s/(\d{3})/$1\ /g;
732 $price = reverse $price;
733 }
734 198 ahitrov
735 return $price;
736 }
737
738
739 1;