Apache-iNcom

 view release on metacpan or  search on metacpan

lib/Apache/iNcom/CartManager.pm  view on Meta::CPAN


use vars qw( $VERSION );

BEGIN {
    ($VERSION) = '$Revision: 1.7 $' =~ /Revision: ([\d.]+)/;
}

=pod

=head1 NAME

Apache::iNcom::CartManager - Object responsible for managing the user
shopping cart. 

=head1 SYNOPSIS

    $Cart->order( \%item );
    my $items = $Cart->items;
    $Cart->empty;

=head1 DESCRIPTION

This is the part of the Apache::iNcom framework that is responsible for
managing the user shopping cart. It keep tracks of the ordered items and
is also responsible for the pricing of the order. It this is module that
computes taxes, discount, price, shipping, etc.

=head1 DESIGN RATIONALE

Well not completly since all these operations are delegated to user
implemented functions implemented in a pricing profile. The idea
behind it is to make policy external to the framework. One thing that
varies considerably between different applications is the pricing,
discount, taxes, etc. So this is left to the implementation of the
application programmer.

=head1 PRICING PROFILE

The pricing profile is a file which is C{eval}-ed at runtime. (It is also
reloaded whenever it changes on disk. It should return an hash reference
which may contains the following key :

=over

=item item_price

The function should return the price of the item. The function is passed
only one parameter : the item which we should compute the price.

    Ex:	item_price => sub {
	my $item = shift;
	my $data = $DB->template_get( "product", $item->{code} );
	return $data->{price};
    }

=item item_discount

The function should return the discounts that apply for that
particular item. It can return zero or more discounts. It returning
more that one discount return a an array reference. Discount are
substracted from the item price so don't return a percentage.

    Ex:	item_discount => sub {
	my $item = shift;

	# Discount are relative to item and quantity
	my $data = $DB->template_get( "discount", $item->{code},
				      $item->{quantity} );
	return unless $data; # No discount

	# Discount is proportional to the price
	return $item->{price} * $data->{discount};
    }

The subtotal of the cart is equal to the sum of

	($item->{price} - $item->{discount}) * $item->{quantity}

=item shipping

This function determines the shipping charges that will be added to
the subtotal. The function receives as arguments the subtotal of the
cart and an array ref to the cart's items. It should return zero or
more shipping charges that will be added to the subtotal. If returning
more that one charges, return an array reference.

    Ex: shipping => sub {
	    # Flat fee based shipping charges
	    if ( $Session{shipping} eq "ONE_NIGHT" ) {
		return 45;
	    } else {
		return 15;
	    }
	}

=item discount

That function determines discount that will be substracted from the
subtotal. Function is called with 3 arguments, the subtotal of the
cart, the shipping charges and an array reference to the cart's items.
Again the function may elect to return zero or more discounts and should
return an array reference if returning more that one discounts.

    Ex: discount => sub {
	my $subtotal = shift;
	my $user = $Request->user;
	return unless $user->{discount};

	return $subtotal * $user->{discount};
    }

=item taxes

That functions determines the taxes charges that will be added to the
order. It should return zero or more taxes. If the functions returns
more that one taxes, it should return an array reference. The
functions receives 4 arguments, the cart's subtotal, the shipping
charges, the discount and the cart's items as an array reference.

    Ex: taxes => sub {
	my ( $sub, $ship, $disc ) = @_;



( run in 1.981 second using v1.01-cache-2.11-cpan-d8267643d1d )