revbank/plugins/products
Juerd Waalboer da523f8daa v3.6: products overhaul
New features, new documentation.
2022-12-25 05:32:00 +01:00

122 lines
3.1 KiB
Perl

#!perl
HELP1 "<productID>" => "Add a product to pending transaction";
my $filename = 'revbank.products';
sub _read_products() {
my %products;
my $line = 0;
for (slurp $filename) {
$line++;
/^\s*#/ and next;
/\S/ or next;
chomp;
my ($ids, $p, $desc) = split " ", $_, 3;
my @ids = split /,/, $ids;
$p ||= "invalid";
$desc ||= "(no description)";
my ($price, $contra) = split /\@/, $p, 2;
my $sign = $price =~ s/^-// ? -1 : 1;
$price = eval { parse_amount($price) };
if (not defined $price) {
warn "Invalid price for '$ids[0]' at $filename line $line.\n";
next;
}
my @addons;
unshift @addons, $1 while $desc =~ s/\s+ \+ (\S+) \s*$//x;
$products{$_} = {
id => $ids[0],
price => $sign * $price,
description => $desc,
contra => $contra || '+sales/products',
addons => \@addons,
line => $line,
} for @ids;
}
return \%products;
}
sub command :Tab(&tab) ($self, $cart, $command, @) {
$command =~ /\S/ or return NEXT;
$command =~ /^\+/ and return NEXT;
my $products = _read_products;
my $product = $products->{ $command } or return NEXT;
my $price = $product->{price};
my @existing = grep {
$_->attribute('plugin') eq $self->id and
$_->attribute('product_id') eq $product->{id}
} $cart->entries('plugin');
if (@existing) {
$existing[0]->quantity($existing[0]->quantity + 1);
return ACCEPT;
}
my $total = $price;
my $contra_desc = "\$you bought $product->{description}";
my @addons = @{ $product->{addons} };
my @infos = @addons ? (
$price->cents > 0 ? ([ $price, "Product" ])
: $price->cents < 0 ? ([ $price, "Reimbursement" ])
: () # price == 0: only addons
) : ();
my @contras;
my %ids_seen = ($product->{id} => 1);
while (my $addon_id = shift @addons) {
$addon_id = "+$addon_id" if exists $products->{"+$addon_id"};
if ($ids_seen{$addon_id}++) {
return REJECT, "Infinite addons are not supported.";
}
my $addon = $products->{$addon_id}
or return REJECT, "Addon '$addon_id' does not exist.";
$total += $addon->{price};
push @infos, [ $addon->{price}, $addon->{description} ]
if $addon->{contra} =~ /^[-+]/;
push @contras, [
$addon->{contra},
$addon->{price},
"$addon->{description} ($contra_desc)"
];
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;
}
sub tab {
return grep /\D/, keys %{ _read_products() };
}