Bump to v3.4; make all transactions balanced using hidden accounts
See UPGRADING.md for details.
This commit is contained in:
parent
e3a04a0e36
commit
441bf05fde
14 changed files with 116 additions and 40 deletions
17
UPGRADING.md
17
UPGRADING.md
|
@ -1,3 +1,20 @@
|
|||
# (2022-06-11) RevBank 3.4
|
||||
|
||||
RevBank now has built-in hidden accounts and balanced transactions. These
|
||||
accounts will be made automatically, and hidden from the user interface. Apart
|
||||
from that, they function as normal accounts (for now).
|
||||
|
||||
If you have scripts that parse `.revbank.log` or `revbank.products`, you may
|
||||
want to ignore all accounts that start with `-` or `+`.
|
||||
|
||||
In the hopefully very unlikely event that you have existing user accounts that
|
||||
start with `-` or `+`, those will have to be renamed manually, as such accounts
|
||||
are no longer accessible.
|
||||
|
||||
For your custom plugins, you may want to add `->add_contra` calls to every
|
||||
`$cart->add` call that does not already have them. Unbalanced transactions will
|
||||
probably be deprecated in a future version.
|
||||
|
||||
# (2022-06-04) RevBank 3.3
|
||||
|
||||
Raw amounts without a command are no longer supported. There was already an
|
||||
|
|
|
@ -66,11 +66,7 @@ sub checkout($self, $user) {
|
|||
return;
|
||||
}
|
||||
|
||||
if ($user =~ /^[-+]/) {
|
||||
# Hidden internal accounts
|
||||
my $canonical = RevBank::Users::parse_user($user);
|
||||
$user = $canonical // RevBank::Users::create($user);
|
||||
}
|
||||
$user = RevBank::Users::assert_user($user);
|
||||
|
||||
my $entries = $self->{entries};
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ sub new($class, $amount, $description, $attributes = {}) {
|
|||
|
||||
sub add_contra($self, $user, $amount, $description) {
|
||||
$amount = RevBank::Amount->parse_string($amount) if not ref $amount;
|
||||
$user = RevBank::Users::assert_user($user);
|
||||
|
||||
$description =~ s/\$you/$self->{user}/g if defined $self->{user};
|
||||
|
||||
|
@ -84,7 +85,7 @@ sub as_printable($self) {
|
|||
push @s, sprintf "%8s %s", $self->{amount}->string_flipped, $self->{description};
|
||||
|
||||
for my $c ($self->contras) {
|
||||
next if RevBank::Users::is_hidden($c->{user});
|
||||
next if RevBank::Users::is_hidden($c->{user}) and not $ENV{REVBANK_DEBUG};
|
||||
|
||||
push @s, sprintf(
|
||||
"%11s %s %s",
|
||||
|
|
|
@ -55,7 +55,7 @@ sub hook_reject($class, $plugin, $reason, $abort, @) {
|
|||
}
|
||||
|
||||
sub hook_user_balance($class, $username, $old, $delta, $new, @) {
|
||||
return if hidden $username;
|
||||
return if hidden $username and not $ENV{REVBANK_DEBUG};
|
||||
|
||||
my $sign = $delta->cents >= 0 ? '+' : '-';
|
||||
my $rood = $new->cents < 0 ? '31;' : '';
|
||||
|
@ -67,7 +67,7 @@ sub hook_user_balance($class, $username, $old, $delta, $new, @) {
|
|||
}
|
||||
|
||||
sub hook_user_created($class, $username, @) {
|
||||
return if hidden $username;
|
||||
return if hidden $username and not $ENV{REVBANK_DEBUG};
|
||||
|
||||
say "New account '$username' created.";
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ no warnings qw(experimental::signatures);
|
|||
|
||||
use RevBank::Global;
|
||||
use RevBank::Plugins;
|
||||
use Carp ();
|
||||
|
||||
my $filename = "revbank.accounts";
|
||||
|
||||
|
@ -77,16 +78,30 @@ sub update($username, $delta, $transaction_id) {
|
|||
);
|
||||
}
|
||||
|
||||
sub parse_user($username) {
|
||||
my $users = _read();
|
||||
return undef if not exists $users->{ lc $username };
|
||||
return $users->{ lc $username }->[0];
|
||||
}
|
||||
|
||||
sub is_hidden($username) {
|
||||
return $username =~ /^[-+]/;
|
||||
}
|
||||
|
||||
sub parse_user($username) {
|
||||
return undef if is_hidden($username);
|
||||
|
||||
my $users = _read();
|
||||
return exists $users->{ lc $username }
|
||||
? $users->{ lc $username }->[0]
|
||||
: undef;
|
||||
}
|
||||
|
||||
sub assert_user($username) {
|
||||
my $users = _read();
|
||||
|
||||
return exists $users->{ lc $username }
|
||||
? $users->{ lc $username }->[0]
|
||||
: (is_hidden($username)
|
||||
? create($username)
|
||||
: Carp::croak("Account '$username' does not exist")
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@ sub amount :Tab(13.37,42) ($self, $cart, $amount, @) {
|
|||
return $message . "How are we receiving this $amount?", \&how
|
||||
if keys %{ $self->{deposit_methods} };
|
||||
|
||||
$cart->add(+$self->{amount}, "Deposit", { is_deposit => 1 });
|
||||
$cart
|
||||
->add(+$self->{amount}, "Deposit", { is_deposit => 1 })
|
||||
->add_contra("-deposits/other", -$self->{amount}, "Deposited by \$you");
|
||||
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
|
@ -35,7 +38,15 @@ sub how :Tab(&how_tab) ($self, $cart, $input, @) {
|
|||
return shift @{ $how->{prompts} }, \&how_prompt;
|
||||
}
|
||||
|
||||
$cart->add(+$self->{amount}, $how->{description}, { is_deposit => 1, method => $how->{_key} });
|
||||
my $contra =
|
||||
$how->{_key} eq 'cash' ? '-cash'
|
||||
: $how->{_key} eq 'reimburse' ? '-expenses/reimbursed'
|
||||
: "-deposits/$how->{_key}";
|
||||
|
||||
$cart
|
||||
->add(+$self->{amount}, $how->{description}, { is_deposit => 1, method => $how->{_key} })
|
||||
->add_contra($contra, -$self->{amount}, "$how->{description} by \$you");
|
||||
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
|
@ -53,7 +64,11 @@ sub how_prompt($self, $cart, $input, @) {
|
|||
}
|
||||
|
||||
my $desc = sprintf $how->{description}, @{ $how->{answers} };
|
||||
my $contra = $how->{_key} eq 'cash' ? '-cash' : "-deposits/$how->{_key}";
|
||||
|
||||
$cart
|
||||
->add(+$self->{amount}, $desc, { is_deposit => 1, method => $how->{_key} })
|
||||
->add_contra($contra, -$self->{amount}, "$desc by \$you");
|
||||
|
||||
$cart->add(+$self->{amount}, $desc, { is_deposit => 1, method => $how->{_key} });
|
||||
return ACCEPT;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,9 @@ sub product :Tab(&tab) ($self, $cart, $product, @) {
|
|||
or return REJECT, "Invalid pfand amount for $product";
|
||||
|
||||
if ($pfand) {
|
||||
$cart->add(+$pfand, "Pfand zurueck", { is_return => 1 });
|
||||
$cart
|
||||
->add(+$pfand, "Pfand zurueck", { is_return => 1 })
|
||||
->add_contra("-pfand", -$pfand, "Pfand fuer \$you");
|
||||
} else {
|
||||
say "$product: Kein Pfand";
|
||||
}
|
||||
|
@ -44,7 +46,9 @@ sub hook_add_entry ($class, $cart, $entry, @) {
|
|||
|
||||
my $pfand = _read_pfand->{ $entry->attribute('product_id') } or return;
|
||||
|
||||
$cart->add(-$pfand, "Pfand", { is_pfand => 1 });
|
||||
$cart
|
||||
->add(-$pfand, "Pfand", { is_pfand => 1 })
|
||||
->add_contra("-pfand", +$pfand, "Pfand von \$you");
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -42,11 +42,17 @@ sub command :Tab(edit,&tab) ($self, $cart, $command, @) {
|
|||
return ACCEPT;
|
||||
}
|
||||
|
||||
$cart->add(
|
||||
-$price,
|
||||
$product->{description},
|
||||
{ product_id => $product->{id}, plugin => $self->id }
|
||||
);
|
||||
$cart
|
||||
->add(
|
||||
-$price,
|
||||
$product->{description},
|
||||
{ product_id => $product->{id}, plugin => $self->id }
|
||||
)
|
||||
->add_contra(
|
||||
"+sales/products",
|
||||
+$price,
|
||||
"\$you bought $product->{description}"
|
||||
);
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,11 +14,19 @@ sub command :Tab(barcode) ($self, $cart, $command, @) {
|
|||
}
|
||||
|
||||
sub data($self, $cart, $input, @) {
|
||||
$cart->add(
|
||||
-0.07,
|
||||
"Barcode <$input>",
|
||||
{ is_barcode => 1, barcode_data => $input }
|
||||
);
|
||||
my $price = 0.07;
|
||||
|
||||
$cart
|
||||
->add(
|
||||
-$price,
|
||||
"Barcode <$input>",
|
||||
{ is_barcode => 1, barcode_data => $input }
|
||||
)
|
||||
->add_contra(
|
||||
"+sales/barcodes",
|
||||
+$price,
|
||||
"\$you bought barcode <$input>"
|
||||
);
|
||||
|
||||
return ACCEPT;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ my %bounties = (
|
|||
|
||||
sub command :Tab(BOUNTY1,BOUNTY2,BOUNTY3,BOUNTY4) ($self, $cart, $command, @) {
|
||||
if ($command =~ /BOUNTY(\d+)/) {
|
||||
$cart->add(+$bounties{$1}[0], $bounties{$1}[1]);
|
||||
$cart
|
||||
->add(+$bounties{$1}[0], $bounties{$1}[1])
|
||||
->add_contra("-expenses/bounties", -$bounties{$1}[0], "$command by \$you");
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,11 +35,17 @@ sub command($self, $cart, $command, @) {
|
|||
$description .= " TEST MODE ($result->{test_amount})";
|
||||
}
|
||||
|
||||
$cart->add(
|
||||
+$amount,
|
||||
$description,
|
||||
{ is_deposit => 1, method => 'online', mollie_id => $id, no_repeat => 1 }
|
||||
);
|
||||
$cart
|
||||
->add(
|
||||
+$amount,
|
||||
$description,
|
||||
{ is_deposit => 1, method => 'online', mollie_id => $id, no_repeat => 1 }
|
||||
)
|
||||
->add_contra(
|
||||
"-deposits/online",
|
||||
-$amount,
|
||||
"$description by \$you"
|
||||
);
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,10 @@ sub amount($self, $cart, $arg, @) {
|
|||
$self->{amount} = parse_amount($arg) or return REJECT, "Invalid amount.";
|
||||
|
||||
if ($self->{command} eq 'donate') {
|
||||
$cart->add(-$self->{amount}, "Donation (THANK YOU!)");
|
||||
$cart
|
||||
->add(-$self->{amount}, "Donation (THANK YOU!)")
|
||||
->add_contra("+donations", +$self->{amount}, "Donation by \$you");
|
||||
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
|
@ -21,7 +24,10 @@ sub amount($self, $cart, $arg, @) {
|
|||
}
|
||||
|
||||
sub description($self, $cart, $desc, @) {
|
||||
$cart->add(-$self->{amount}, "Unlisted: $desc");
|
||||
$cart
|
||||
->add(-$self->{amount}, "Unlisted: $desc")
|
||||
->add_contra("+sales/unlisted", +$self->{amount}, "Unlisted: $desc by \$you");
|
||||
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,12 +28,12 @@ sub hook_checkout($class, $cart, $user, $transaction_id, @) {
|
|||
}
|
||||
|
||||
sub list($self) {
|
||||
system "sort -f revbank.accounts | grep -v ^# | perl -pe's/( -[\\d.]+)/\\e[31;1m\$1\\e[0m/' | more";
|
||||
system "sort -f revbank.accounts | grep -v ^# | perl -ne's/( -[\\d.]+)/\\e[31;1m\$1\\e[0m/; print if not /^[-+]/' | more";
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
sub shame($self) {
|
||||
system "sort -k2 -n revbank.accounts | grep -v ^# | grep -- ' -' | perl -pe's/( -[\\d.]+)/\\e[31;1m\$1\\e[0m/' | more";
|
||||
system "sort -k2 -n revbank.accounts | grep -v ^# | grep -- ' -' | perl -ne's/( -[\\d.]+)/\\e[31;1m\$1\\e[0m/; print if not /^[-+]/' | more";
|
||||
return ACCEPT;
|
||||
}
|
||||
|
||||
|
|
2
revbank
2
revbank
|
@ -18,7 +18,7 @@ use RevBank::Global;
|
|||
use RevBank::Messages;
|
||||
use RevBank::Cart;
|
||||
|
||||
our $VERSION = "3.3";
|
||||
our $VERSION = "3.4";
|
||||
our %HELP1 = (
|
||||
"abort" => "Abort the current transaction",
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue