package webshop::Keeper; use strict; use warnings 'all'; use base qw(Contenido::Keeper); use Data::Dumper; use Contenido::Globals; use webshop::Basket; use webshop::SQL::Basket; sub add_item { my $self = shift; my $object = shift; my (%options) = @_; return unless ref $object; return unless $object->item_id && $object->number; return unless $object->uid || $object->session; my %opts; if ( $object->uid ) { $opts{uid} = $object->uid; } elsif ( $object->session ) { $opts{session} = $object->session; } my @items = $keeper->get_documents ( class => 'webshop::Basket', status => [0,1], order_id=> 0, %opts, ); my $total = 0; my $sum = 0; my $found = 0; if ( @items ) { foreach my $item ( @items ) { if ( $object->item_id == $item->item_id && $object->color_id == $item->color_id ) { $item->number($item->number + $object->number); $item->status(1); $item->store; $found = 1; } $total += $item->number; $sum += $item->number * $item->price; } } unless ( $found ) { $total += $object->number; $sum += $object->number * $object->price; $object->order_id(0); $object->store; } my @plugins = split (/[\ |\t]+/, $state->{plugins}); if ( grep { $_ eq 'session' } @plugins ) { $keeper->{session}->store_value ( basket_total => $total, basket_sum => $sum ); } return ($total, $sum); } ### Метод приведения корзины для пользователя в момент логина ############################################################# sub merge_basket { my $self = shift; my (%opts) = @_; warn "Merge begin: ".Dumper(\%opts)."\n" if $DEBUG; return unless $opts{uid} && $opts{session}; my @items = $keeper->get_documents ( class => 'webshop::Basket', status => [1,0], order_id=> 0, session => $opts{session}, ); foreach my $item ( @items ) { $item->session(undef); $item->uid( $opts{uid} ); $item->store; } @items = $keeper->get_documents ( class => 'webshop::Basket', status => 1, order_id=> 0, uid => $opts{uid}, ); my $total = 0; my $sum = 0; foreach my $item ( @items ) { $total += $item->number; $sum += $item->number * $item->price; } my @plugins = split (/[\ |\t]+/, $state->{plugins}); if ( grep { $_ eq 'session' } @plugins ) { $keeper->{session}->store_value ( basket_total => $total, basket_sum => $sum ); } warn "Merge end\n" if $DEBUG; return ($total, $sum); } sub get_basket { my $self = shift; my (%opts) = @_; return unless $opts{uid} || $opts{session} || $opts{order_id}; my $uid = delete $opts{uid}; my $session = delete $opts{session}; unless ( exists $opts{order_id} && $opts{order_id} ) { $opts{order_id} = 0; if ( $uid ) { $opts{uid} = $uid; } elsif ( $session ) { $opts{session} = $session; } } $opts{status} = 1 unless exists $opts{status} && defined $opts{status}; my @items = $keeper->get_documents ( class => 'webshop::Basket', %opts, ); my $total = 0; my $sum = 0; foreach my $item ( @items ) { if ( $item->status == 1 ) { $total += $item->number; $sum += $item->number * $item->price; } } my @plugins = split (/[\ |\t]+/, $state->{plugins}); if ( grep { $_ eq 'session' } @plugins ) { $keeper->{session}->store_value ( basket_total => $total, basket_sum => $sum ); } return \@items; } sub clear_basket { my $self = shift; my (%opts) = @_; return unless exists $opts{uid} || exists $opts{session}; my $table_name = webshop::SQL::Basket->db_table; my $request = "delete from $table_name where order_id = 0 AND status = 1 AND"; my $dbh = $keeper->SQL; my @vals; if ( exists $opts{uid} && $opts{uid} ) { $request .= " uid in (?)"; push @vals, $opts{uid}; } elsif ( exists $opts{session} ) { $request .= " session in (?)"; push @vals, $opts{session}; } warn "CLEAR: [$request]. VALS: [".join(',',@vals)."]\n" if $DEBUG; my $statement = $dbh->prepare ($request); $statement->execute( @vals ) || $log->error("DBI execute error on $request\n"."\ncalled with opts:\n".Data::Dumper::Dumper(\%opts));; $statement->finish; my @plugins = split (/[\ |\t]+/, $state->{plugins}); if ( grep { $_ eq 'session' } @plugins ) { $keeper->{session}->store_value ( basket_total => 0, basket_sum => 0 ); } } sub clear_wishlist { my $self = shift; my (%opts) = @_; return unless exists $opts{uid} || exists $opts{session}; my $table_name = webshop::SQL::Basket->db_table; my $request = "delete from $table_name where order_id = 0 AND status = 0 AND"; my $dbh = $keeper->SQL; my @vals; if ( exists $opts{uid} ) { $request .= " uid in (?)"; push @vals, $opts{uid}; } elsif ( exists $opts{session} ) { $request .= " session in (?)"; push @vals, $opts{session}; } my $statement = $dbh->prepare ($request); $statement->execute( @vals ) || $log->error("DBI execute error on $request\n"."\ncalled with opts:\n".Data::Dumper::Dumper(\%opts));; $statement->finish; } ### Метод пересчета корзины # Принимает на вход параметры: # session => session_id пользователя # uid => UID пользователя # delete => массив или отдельный item_id # renumber => ссылка на хеш вида item => number ############################################################# sub recount { my $self = shift; my (%opts) = @_; warn "Recount Started!!!\n" if $DEBUG; return unless exists $opts{uid} || exists $opts{session} || exists $opts{order_id}; my $basket = $self->get_basket ( %opts ); return unless ref $basket eq 'ARRAY' && @$basket; warn Dumper(\%opts) if $DEBUG; my $total = 0; my $sum = 0; my @new_basket; my $session_no_store = delete $opts{session_no_store}; foreach my $item ( @$basket ) { my $delete = 0; if ( exists $opts{renumber} && ref $opts{renumber} eq 'HASH' && exists $opts{renumber}{$item->id} && int($opts{renumber}{$item->id}) == 0 ) { $delete = 1; } elsif ( exists $opts{delete} && ref $opts{delete} eq 'ARRAY' ) { $delete = 1 if grep { $_ == $item->id } @{ $opts{delete} }; } elsif ( exists $opts{delete} && $opts{delete} ) { $delete = 1 if $item->id == $opts{delete}; } if ( $delete ) { warn "Item ID=".$item->id." DELETE\n" if $DEBUG; $item->delete(); next; } else { my $store = 0; if ( exists $opts{renumber} && ref $opts{renumber} eq 'HASH' && exists $opts{renumber}{$item->id} && $opts{renumber}{$item->id} != $item->number ) { $item->number( $opts{renumber}{$item->id} ); $store = 1; } if ( exists $opts{price} && ref $opts{price} eq 'HASH' && exists $opts{price}{$item->id} && $opts{price}{$item->id} != $item->price ) { $item->price( $opts{price}{$item->id} ); $store = 1; } $item->store if $store; $total += $item->number; $sum += $item->number * $item->price; push @new_basket, $item; } } my @plugins = split (/[\ |\t]+/, $state->{plugins}); if ( !$session_no_store && grep { $_ eq 'session' } @plugins ) { $keeper->{session}->store_value ( basket_total => $total, basket_sum => $sum ); } return ($total, $sum, \@new_basket); } sub get_orders { my $self = shift; my (%opts) = @_; my $list = delete $opts{list}; $opts{order_by} ||= 'status'; my @items = $keeper->get_documents ( class => 'webshop::Order', %opts, ); if ( exists $opts{id} && defined $opts{id} && !ref $opts{id} ) { if ( $list ) { $items[0]->{list} = $self->get_order_list( order_id => $opts{id} ); } return $items[0]; } else { if ( $list ) { map { $_->{list} = $self->get_order_list( order_id => $_->id ) } @items; } return \@items; } } sub get_order_list { my $self = shift; my (%opts) = @_; return unless $opts{order_id}; $opts{status} = 1; my @items = $keeper->get_documents ( class => 'webshop::Basket', %opts, ); my $total = 0; my $sum = 0; foreach my $item ( @items ) { my $Item = $item->class->new( $keeper, $item->id ); $item->{item} = $Item; if ( $item->status == 1 ) { $total += $item->number; $sum += $item->number * $item->price; } } return \@items; } sub price_format { my $self = shift; my $price = shift; $price = reverse $price; $price =~ s/(\d{3})/$1\ /g; $price = reverse $price; return $price; } 1;