#!perl HELP1 "" => "[Pay with your account and] show balance"; HELP "list" => "List accounts and balances"; HELP "log" => "View transaction log"; HELP "shame" => "Display Hall of Shame (negative balances)"; sub command :Tab(list,ls,shame,log,USERS) ($self, $cart, $command, @) { return $self->list if $command eq 'list'; return $self->list if $command eq 'ls'; return $self->shame if $command eq 'shame'; return "Username", \&log_for if $command eq 'log'; my $user = parse_user($command) or return NEXT; return $self->balance($user) if not $cart->size; $cart->checkout($user); return ACCEPT; } sub list($self) { require RevBank::TextEditor; my $list = join "", sort { lc($a) cmp lc($b) } grep { !/^[-+]/ } slurp("revbank.accounts"); RevBank::TextEditor::pager("RevBank account list", $list); return ACCEPT; } sub shame($self) { my $list = join "", sort { (split " ", $a)[1] <=> (split " ", $b)[1] } grep { / -/ && !/^[-+]/ } slurp("revbank.accounts"); $list =~ s/( -[\d.]+)/\e[31;1m$1\e[0m/g; print $list; return ACCEPT; } sub _grep($user) { $user = lc $user; my @lines; open my $fh, "<", ".revbank.log" or die $!; while (defined($_ = readline $fh)) { length($_) > 28 or next; substr($_, 20, 8) eq 'CHECKOUT' or next; # fast check my ($dt, $c, $t_id, $u, $dir, $qty, $amount, undef, $desc) = split " ", $_, 9; $c eq 'CHECKOUT' or next; # real check after expensive split lc($u) eq $user or next; $qty = 1 if $qty eq 'EUR'; # log files before commit 63f81e37 (2019-11-05) push @lines, sprintf "%s %8s %s%-s", ( $dt =~ s/_/ /r, $dir eq 'GAIN' ? "+ $amount" : $amount, # like R::A->string_flipped $qty > 1 ? $qty . "x " : "", $desc ); } return @lines; } sub log_for :Tab(USERS) ($self, $cart, $input, @) { my $user = parse_user($input) or return REJECT, "Unknown user"; my @lines = _grep($user); require RevBank::TextEditor; RevBank::TextEditor::logpager("RevBank log for $user", join("", @lines, "(end)")); return ACCEPT; } sub _recent($n, $u) { $n += 0; print "Last $n transactions for $u:\n"; print grep defined, +(_grep($u))[-$n .. -1]; } sub balance($self, $u) { _recent(10, $u); call_hooks("user_info", $u); my $balance = RevBank::Users::balance($u); my $red = $balance->cents < 0 ? "31;" : ""; printf "Balance for $u is \e[%s1m%s\e[0m\n", $red, $balance->string("+"); say "NB: Products/amounts/commands FIRST, username LAST."; return ABORT; }