Skip to content

Commit

Permalink
Add writers for cart products sku, canonical_sku and name
Browse files Browse the repository at this point in the history
  • Loading branch information
melmothx committed Feb 12, 2018
1 parent ef7a715 commit 1e8cc27
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 22 deletions.
65 changes: 55 additions & 10 deletions lib/Interchange6/Cart.pm
Original file line number Diff line number Diff line change
Expand Up @@ -516,18 +516,25 @@ the zero-based index of the product within L</products>.

sub update {
my ( $self, @args ) = @_;
my @products;
$self->_update_cart_item(quantity => @args);
}

sub _update_cart_item {
my ($self, $key, @args) = @_;
croak "Missing attribute" unless $key;
my $accessor = $key;
my $mutator = "set_" . $key;
my @products;
ARGS: while ( @args > 0 ) {

my ( $product, $sku, $qty );
my ( $product, $sku, $attr );

if ( ref( $args[0] ) eq '' ) {

# original API expecting list of sku/qty pairs

$sku = shift @args;
$qty = shift @args;
$attr = shift @args;

croak "sku not defined in arg to update" unless defined $sku;

Expand All @@ -554,7 +561,7 @@ sub update {

my %selectors = %{ shift @args };

$qty = delete $selectors{quantity};
$attr = delete $selectors{$key};

if ( defined $selectors{index} ) {

Expand Down Expand Up @@ -602,18 +609,20 @@ sub update {

croak "Product not found for update" unless $product;

defined($qty) && ref($qty) eq ''
or croak "quantity argument to update must be defined";
defined($attr) && ref($attr) eq ''
or croak "$key argument to update must be defined";

if ( $qty == 0 ) {
if ($key eq 'quantity' and $attr == 0 ) {
$self->remove( $product->sku );
next;
}

# jump to next product if quantity stays the same
next ARGS if $qty == $product->quantity;
# jump to next product if the attribute stays the same
if (defined $product->$accessor and $attr eq $product->$accessor) {
next ARGS;
}

$product->set_quantity($qty);
$product->$mutator($attr);
push @products, $product;
}

Expand All @@ -622,6 +631,42 @@ sub update {
return @products;
}

=head2 update_sku
Change the sku of a product already in the cart (the first argument).
The API for the arguments are the same as C<update>
=head2 update_canonical_sku
Change the canonical sku of a product already in the cart.
The API for the arguments are the same as C<update>
=head2 update_name
Change the name of a product already in the cart.
The API for the arguments are the same as C<update>
=cut

sub update_sku {
my ($self, @args) = @_;
$self->_update_cart_item(sku => @args);
}

sub update_canonical_sku {
my ($self, @args) = @_;
$self->_update_cart_item(canonical_sku => @args);
}

sub update_name {
my ($self, @args) = @_;
$self->_update_cart_item(name => @args);
}


=head1 AUTHORS
Stefan Hornburg (Racke), <racke@linuxia.de>
Expand Down
27 changes: 15 additions & 12 deletions lib/Interchange6/Cart/Product.pm
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ has name => (
is => 'ro',
isa => NonEmptyStr,
required => 1,
writer => 'set_name',
);

=head2 price
Expand Down Expand Up @@ -133,10 +134,6 @@ sub _build_discount_percent {
return int( ( $self->price - $self->selling_price ) / $self->price * 100 );
}

after 'set_price', 'set_selling_price' => sub {
shift->clear_discount_percent;
};

=head2 quantity
Product quantity is optional and has to be a natural number greater
Expand All @@ -160,12 +157,6 @@ has quantity => (
writer => 'set_quantity',
);

after set_quantity => sub {
my $self = shift;
$self->clear_subtotal;
$self->clear_total;
};

=head2 sku
Unique product identifier is required.
Expand All @@ -176,6 +167,7 @@ has sku => (
is => 'ro',
isa => NonEmptyStr,
required => 1,
writer => 'set_sku',
);

=head2 canonical_sku
Expand All @@ -188,6 +180,7 @@ is the sku of the parent product.
has canonical_sku => (
is => 'ro',
default => undef,
writer => 'set_canonical_sku',
);

=head2 subtotal
Expand Down Expand Up @@ -372,17 +365,27 @@ sub should_combine_by_sku {
return $self->combine;
}

after 'set_price', 'set_selling_price', 'set_sku' => sub {
shift->clear_discount_percent;
};

after qw/set_quantity set_name set_sku set_canonical_sku set_quantity/ => sub {
my $self = shift;
$self->clear_subtotal;
$self->clear_total;
};

# after cost changes we need to clear the cart subtotal/total
# our own total is handled by the Costs role

after 'clear_costs', 'cost_set', 'apply_cost', 'set_quantity' => sub {
after 'clear_costs', 'cost_set', 'apply_cost', 'set_quantity', 'set_name', 'set_sku', 'set_canonical_sku' => sub {
my $self = shift;
if ( $self->cart ) {
$self->cart->clear_subtotal;
$self->cart->clear_total;
}
};
after 'set_quantity', 'set_weight' => sub {
after 'set_quantity', 'set_weight', 'set_name', 'set_sku', 'set_canonical_sku' => sub {
my $self = shift;
if ( $self->cart ) {
$self->cart->clear_weight;
Expand Down
24 changes: 24 additions & 0 deletions t/unit/cart.t
Original file line number Diff line number Diff line change
Expand Up @@ -629,4 +629,28 @@ cmp_ok( $cart->subtotal, '==', 5, "subtotal is 5" );
cmp_ok( $cart->total, '==', 5, "total is 5" );
cmp_ok( $cart->weight, '==', 10, "weight is 10" );

lives_ok { $cart->update_sku(ONE => 'THREE') };
{
my $product = $cart->products->[0];
is $product->sku, 'THREE';
}
lives_ok { $cart->update_sku(THREE => 'ONE') };

lives_ok { $cart->update_canonical_sku(ONE => 'Hello') };
lives_ok { $cart->update_name(ONE => 'Bau') };

{
my $product = $cart->products->[0];
is ($product->sku, 'ONE');
is ($product->canonical_sku, 'Hello');
is ($product->name, 'Bau');
}

cmp_ok( $cart->count, '==', 2, "count is 2" );
cmp_ok( $cart->quantity, '==', 3, "quantity is 3" );
cmp_ok( $cart->subtotal, '==', 5, "subtotal is 5" );
cmp_ok( $cart->total, '==', 5, "total is 5" );
cmp_ok( $cart->weight, '==', 10, "weight is 10" );


done_testing;
7 changes: 7 additions & 0 deletions t/unit/cart_product.t
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,11 @@ ok( !$product->defined_extra('undef'), "!defined_extra('undef')" );
lives_ok { $product->clear_extra } "ok clear_extra";
cmp_ok( $product->keys_extra, '==', 0, "keys_extra has 0 keys" );

dies_ok { $product->set_name('') } "fail set_name with empty string";
dies_ok { $product->set_sku('') } "fail set_sku with empty string";
dies_ok { $product->set_name(undef) } "fail set_name with undef";
dies_ok { $product->set_sku(undef) } "fail set_sku with undef";
lives_ok { $product->set_canonical_sku(undef) } "fail set_sku with empty string";
is $product->canonical_sku, undef, "canonical sku can be undef";

done_testing;

0 comments on commit 1e8cc27

Please sign in to comment.