Revision 198 (by ahitrov, 2012/03/15 18:29:29) |
Simple webshop support plugin
|
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;