New feature: percentage addons (discounts etc)
This commit is contained in:
parent
eb55aa0eb5
commit
7c05b3108c
2 changed files with 60 additions and 31 deletions
|
@ -72,6 +72,17 @@ sub attribute($self, $key, $new = undef) {
|
||||||
return $$ref;
|
return $$ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub amount($self, $new = undef) {
|
||||||
|
my $ref = \$self->{amount};
|
||||||
|
if (defined $new) {
|
||||||
|
$new = RevBank::Amount->parse_string($new) if not ref $new;
|
||||||
|
$$ref = $new;
|
||||||
|
$self->attribute('changed', 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $$ref;
|
||||||
|
}
|
||||||
|
|
||||||
sub quantity($self, $new = undef) {
|
sub quantity($self, $new = undef) {
|
||||||
my $ref = \$self->{quantity};
|
my $ref = \$self->{quantity};
|
||||||
if (defined $new) {
|
if (defined $new) {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
HELP1 "<productID>" => "Add a product to pending transaction";
|
HELP1 "<productID>" => "Add a product to pending transaction";
|
||||||
|
|
||||||
my $filename = 'revbank.products';
|
my $filename = 'revbank.products';
|
||||||
|
my $default_contra = '+sales/products';
|
||||||
|
|
||||||
sub _read_products() {
|
sub _read_products() {
|
||||||
my %products;
|
my %products;
|
||||||
|
@ -23,11 +24,20 @@ sub _read_products() {
|
||||||
my ($price, $contra) = split /\@/, $p, 2;
|
my ($price, $contra) = split /\@/, $p, 2;
|
||||||
|
|
||||||
my $sign = $price =~ s/^-// ? -1 : 1;
|
my $sign = $price =~ s/^-// ? -1 : 1;
|
||||||
|
my $percent = $price =~ s/%$//;
|
||||||
|
|
||||||
$price = eval { parse_amount($price) };
|
if ($percent) {
|
||||||
if (not defined $price) {
|
if (grep !/^\+/, @ids) {
|
||||||
warn "Invalid price for '$ids[0]' at $filename line $line.\n";
|
warn "Percentage invalid for non-addon at $filename line $line.\n";
|
||||||
next;
|
next;
|
||||||
|
}
|
||||||
|
$price = 0 + $price;
|
||||||
|
} else {
|
||||||
|
$price = eval { parse_amount($price) };
|
||||||
|
if (not defined $price) {
|
||||||
|
warn "Invalid price for '$ids[0]' at $filename line $line.\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my @addons;
|
my @addons;
|
||||||
|
@ -36,8 +46,9 @@ sub _read_products() {
|
||||||
$products{$_} = {
|
$products{$_} = {
|
||||||
id => $ids[0],
|
id => $ids[0],
|
||||||
price => $sign * $price,
|
price => $sign * $price,
|
||||||
|
percent => $percent,
|
||||||
description => $desc,
|
description => $desc,
|
||||||
contra => $contra || '+sales/products',
|
contra => $contra || $default_contra,
|
||||||
addons => \@addons,
|
addons => \@addons,
|
||||||
line => $line,
|
line => $line,
|
||||||
} for @ids;
|
} for @ids;
|
||||||
|
@ -64,17 +75,26 @@ sub command :Tab(&tab) ($self, $cart, $command, @) {
|
||||||
return ACCEPT;
|
return ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $total = $price;
|
|
||||||
my $contra_desc = "\$you bought $product->{description}";
|
my $contra_desc = "\$you bought $product->{description}";
|
||||||
|
|
||||||
my @addons = @{ $product->{addons} };
|
my $entry = $cart->add(
|
||||||
my @infos = @addons ? (
|
-$price,
|
||||||
$price->cents > 0 ? ([ $price, "Product" ])
|
$product->{description},
|
||||||
: $price->cents < 0 ? ([ $price, "Reimbursement" ])
|
{ product_id => $product->{id}, plugin => $self->id, addons => $product->{addons} }
|
||||||
: () # price == 0: only addons
|
);
|
||||||
) : ();
|
$entry->add_contra(
|
||||||
|
$product->{contra},
|
||||||
|
+$price,
|
||||||
|
$contra_desc
|
||||||
|
);
|
||||||
|
|
||||||
|
my @addons = @{ $product->{addons} }
|
||||||
|
or return ACCEPT;
|
||||||
|
|
||||||
|
|
||||||
|
$entry->add_info($price, "Product") if $price->cents > 0;
|
||||||
|
$entry->add_info($price, "Reimbursement") if $price->cents < 0;
|
||||||
|
|
||||||
my @contras;
|
|
||||||
my %ids_seen = ($product->{id} => 1);
|
my %ids_seen = ($product->{id} => 1);
|
||||||
|
|
||||||
while (my $addon_id = shift @addons) {
|
while (my $addon_id = shift @addons) {
|
||||||
|
@ -87,33 +107,31 @@ sub command :Tab(&tab) ($self, $cart, $command, @) {
|
||||||
my $addon = $products->{$addon_id}
|
my $addon = $products->{$addon_id}
|
||||||
or return REJECT, "Addon '$addon_id' does not exist.";
|
or return REJECT, "Addon '$addon_id' does not exist.";
|
||||||
|
|
||||||
$total += $addon->{price};
|
my $addon_price = $addon->{price};
|
||||||
|
if ($addon->{percent}) {
|
||||||
|
my $sum = List::Util::sum map {
|
||||||
|
$_->{amount}
|
||||||
|
} grep {
|
||||||
|
$_->{user} eq $addon->{contra}
|
||||||
|
} $entry->contras;
|
||||||
|
|
||||||
push @infos, [ $addon->{price}, $addon->{description} ]
|
$addon_price = $addon_price / 100 * $sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
$entry->amount( $entry->amount - $addon_price );
|
||||||
|
|
||||||
|
$entry->add_info($addon_price, $addon->{description})
|
||||||
if $addon->{contra} =~ /^[-+]/;
|
if $addon->{contra} =~ /^[-+]/;
|
||||||
|
|
||||||
push @contras, [
|
$entry->add_contra(
|
||||||
$addon->{contra},
|
$addon->{contra},
|
||||||
$addon->{price},
|
$addon_price,
|
||||||
"$addon->{description} ($contra_desc)"
|
"$addon->{description} ($contra_desc)"
|
||||||
];
|
);
|
||||||
|
|
||||||
push @addons, @{ $addon->{addons} };
|
push @addons, @{ $addon->{addons} };
|
||||||
}
|
}
|
||||||
|
|
||||||
my $entry = $cart->add(
|
|
||||||
-$total,
|
|
||||||
$product->{description},
|
|
||||||
{ product_id => $product->{id}, plugin => $self->id, addons => $product->{addons} }
|
|
||||||
);
|
|
||||||
$entry->add_contra(
|
|
||||||
$product->{contra},
|
|
||||||
+$price,
|
|
||||||
$contra_desc
|
|
||||||
);
|
|
||||||
$entry->add_info(@$_) for @infos;
|
|
||||||
$entry->add_contra(@$_) for @contras;
|
|
||||||
|
|
||||||
return ACCEPT;
|
return ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue