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