
Don't worry, that won't happen for at least months. First we'll just log warnings for a while.
82 lines
2.3 KiB
Perl
82 lines
2.3 KiB
Perl
#!perl
|
|
|
|
HELP1 "undo <transactionID>" => "Undo a transaction";
|
|
|
|
my $filename = ".revbank.undo";
|
|
|
|
my @TAB;
|
|
|
|
sub command :Tab(undo) ($self, $cart, $command, @) {
|
|
$command eq 'undo' or return NEXT;
|
|
|
|
$cart->size and return ABORT, "Undo is not available mid-transaction.";
|
|
|
|
my @log;
|
|
open my $in, '<', $filename or die "$filename: $!";
|
|
while (defined(my $line = readline $in)) {
|
|
my ($tid, $user, $delta, $dt) = split " ", $line;
|
|
if (@log and $log[-1]{tid} eq $tid) {
|
|
push @{ $log[-1]{deltas} }, [ $user, $delta ];
|
|
} else {
|
|
push @log, { tid => $tid, dt => $dt, deltas => [ [ $user, $delta ] ] };
|
|
}
|
|
}
|
|
|
|
@TAB = ();
|
|
|
|
my $max = @log < 15 ? @log : 15;
|
|
for my $txn (@log[-$max .. -1]) {
|
|
print "ID: $txn->{tid} $txn->{dt} ", (
|
|
join ", ", map { sprintf "%s:%+.2f", @$_ } @{ $txn->{deltas} }
|
|
), "\n";
|
|
|
|
push @TAB, $txn->{tid};
|
|
}
|
|
|
|
return "Transaction ID", \&undo;
|
|
}
|
|
|
|
sub tab { @TAB }
|
|
|
|
my $doing_undo = 0; # Ugly but works, just like the rest of this plugin
|
|
|
|
sub undo :Tab(&tab) ($self, $cart, $tid, @) {
|
|
open my $in, '<', $filename or die "$filename: $!";
|
|
open my $out, '>', "$filename.$$" or die "$filename.$$: $!";
|
|
my $description = "Undo $tid";
|
|
|
|
my $entry;
|
|
|
|
while (defined(my $line = readline $in)) {
|
|
if ($line =~ /^\Q$tid\E\s/) {
|
|
my (undef, $user, $delta) = split " ", $line;
|
|
|
|
$entry ||= $cart->add(0, $description);
|
|
$entry->{FORCE_UNBALANCED} = 1;
|
|
|
|
$entry->add_contra($user, $delta, "Undo $tid");
|
|
} else {
|
|
print {$out} $line;
|
|
}
|
|
}
|
|
close $in;
|
|
close $out or die $!;
|
|
if ($cart->size) {
|
|
rename "$filename.$$", $filename or die $!;
|
|
$doing_undo = 1; # don't allow undoing undos
|
|
$cart->checkout('-undo');
|
|
$doing_undo = 0;
|
|
} else {
|
|
return ABORT, "Transaction ID '$tid' not found in undo log.";
|
|
}
|
|
|
|
return ACCEPT;
|
|
}
|
|
|
|
sub hook_user_balance($class, $username, $old, $delta, $new, $transaction_id, @) {
|
|
return if $doing_undo; # don't allow undoing undos
|
|
|
|
open my $fh, '>>', $filename or die "$filename: $!";
|
|
print {$fh} join " ", $transaction_id, $username, -$delta, now(), "\n";
|
|
close $fh or die "$filename: $!";
|
|
}
|