#!perl HELP "x, *" => "Set quantity of previous/next product"; HELP "-, +, *, x" => "Change quantity of previous product"; my $err_stacked = "Stacked repetition is not supported."; my $err_pfand = "Plugins 'pfand' and 'repeat' cannot be combined."; my $err_nope = "Entry does not support repetition."; my $err_postfix = "Addition/substraction is only supported the other way around."; my $limit = 200; my $err_limit = "Repetition is limited at $limit items."; sub command($self, $cart, $command, @) { my ($lhs, $op, $rhs) = $command =~ /^(\d+)?([x*+-])(\d+)?$/ or return NEXT; return ABORT, $err_pfand if $cart->entries('is_pfand'); my $last = $cart->selected; return NEXT if $lhs and $rhs; # 123x123 -> invalid, likely user or product if ($lhs) { return REJECT, $err_postfix if $op eq '+' or $op eq '-'; $lhs = abs $lhs; # withdrawal is negative return REJECT, $err_limit if $lhs > $limit; $cart ->add(0, "? (The next thing you add will be multiplied.)", { _repeat => 1, refuse_checkout => 1 }) ->quantity($lhs); return ACCEPT; } return ABORT, "Can't modify an empty transaction." if not $cart->size; return REJECT, $err_nope if $last->attribute('no_repeat'); if ($rhs) { return REJECT, $err_limit if $rhs > $limit; if ($op eq '+') { my $new = $last->quantity + $rhs; return REJECT, $err_limit if $new > $limit; $last->quantity($new); return ACCEPT; } if ($op eq '-') { my $new = $last->quantity - $rhs; if ($new > 0) { $last->quantity($new); } else { $cart->delete($last); print "Deleted.\n"; } return ACCEPT; } # $op is not + or -, so it must be * (or x). return REJECT, $err_stacked if $last->multiplied; $last->quantity($rhs); return ACCEPT; } if ($op eq '+' or $op eq '-') { $self->{op} = $op; return "$op how many?", \&plusminus; } # $op is not + or -, so it must be * (or x). return REJECT, $err_stacked if $last->multiplied; return "Multiply previous product by", \&repeat; } sub repeat($self, $cart, $arg, @) { $arg =~ /^\d+$/ and $arg > 0 or return REJECT, "Invalid value."; return REJECT, $err_limit if $arg > $limit; $cart->selected->quantity($arg); return ACCEPT; } sub plusminus($self, $cart, $arg, @) { $arg =~ /^\d+$/ and $arg > 0 or return REJECT, "Invalid value."; my $last = $cart->selected; my $new = $last->quantity; $new += $arg if $self->{op} eq '+'; $new -= $arg if $self->{op} eq '-'; return REJECT, $err_limit if $new > $limit; if ($new < 0) { $cart->delete($last); print "Deleted.\n"; } else { $cart->selected->quantity($new); } return ACCEPT; } sub hook_added_entry($class, $cart, $entry, @) { $cart->size >= 2 or return; my @entries = $cart->entries; my @planned = $cart->entries('_repeat'); return if not @planned; return ABORT, "Multiple repeats queued; I'm confused." if @planned > 1; return ABORT, $err_pfand if $cart->entries('is_pfand'); return if $planned[0] == $entries[-1]; return ABORT, "Queued repeat is not the penultimate item; I'm confused" if $entries[-2] != $planned[0]; my $num = $planned[0]->quantity; if ($entries[-1]->attribute('no_repeat')) { print $err_nope, "\n"; $num = 1; } $cart->delete($planned[0]); $entries[-1]->quantity($num); }