Commit graph

110 commits

Author SHA1 Message Date
Juerd Waalboer
5d8ff672f1 Don't show intermediate cart results
Also, move "Done:" display from users plugin to global messages
2024-11-17 01:16:16 +01:00
Juerd Waalboer
807d255b53 Expose deltas
In preparation for future plugin
2024-11-17 01:15:18 +01:00
Juerd Waalboer
a303cad131 Remove support for unbalanced transaction, release v7.0.0 2024-11-17 01:14:43 +01:00
Juerd Waalboer
f16e406063 Revert "Handle huge numbers better"
This reverts commit ef0039bc33.

Abysmal performance: revbank2beancount went from 0.7 to 11 seconds for
revspace's 2024 .revbank.log to date.
2024-08-28 06:41:02 +02:00
Juerd Waalboer
ef0039bc33 Handle huge numbers better
A sufficiently big number, i.e. longer than a long long, had interesting
effects. Perl would promote it to a float, and format it as -1 in
sprintf, which RevBank::Amount didn't handle correctly. In extreme cases
the number got rounded to Inf and would no longer round-trip.

As a result, numbers returned by RevBank::Amount are now Math::BigInt
and Math::BigFloat objects. Those should be transparent to all existing
code. It's amazing to see the unit tests pass.

I don't think there is any actual use case in RevBank for numbers this
large and I don't think anyone will have actually encountered the
aforementioned weird effects. Mostly, the input would be parsed with
parse_amount which refuses any number greater than 99900 anyway. Only
where parse_string was used directly, such large numbers could actually
have been used, but in stock RevBank that is only done when reading the
accounts file.

This change also introduces a new global function parse_any_amount that
is like parse_amount but doesn't complain about negative or large
numbers, to further improve the adduser plugin (see previous commit) in
insane edge cases. It differs from RevBank::Amount->parse_string in that
it does support addition and subtraction operators.
2024-08-28 05:19:02 +02:00
Juerd Waalboer
04cf728010 Inflation
Roughly 4%
2024-05-17 22:48:18 +02:00
Juerd Waalboer
459093dba9 v6.2.0: Use reject/retry instead of exception for bad amount
Since the first versions of RevBank, negative and huge amounts are
handled centrally, and since v2 (2013) they've been implemented through
an exception that caused the pending transaction to be aborted. Since v3
(2019), RevBank has had a retry mechanism for rejected input to improve
the user experience, but it required a REJECT return message from a
plugin, not an exception. Now there's an exception class to trigger the
same semantics.
2024-05-09 03:09:27 +02:00
Juerd Waalboer
e3b054272d v6.1.4: fix bug (0.00 balance account not usable)
Introduced in f2d09b4d
2024-04-28 03:43:20 +02:00
Juerd Waalboer
6c74097707 v6.1.2: fix retry prompt
Broken since 2b0f8feb.
2024-04-25 01:08:15 +02:00
Juerd Waalboer
f2d09b4da5 v6.1.1: Feature: warning messages for invalid accounts 2024-04-25 01:08:15 +02:00
Juerd Waalboer
33b08f99ea v6.1.0: improve handling of invalid balance in revbank.accounts
This small change makes it possible to reserve an account name by just
giving it an invalid balance in `revbank.accounts`.
2024-04-25 01:08:15 +02:00
Juerd Waalboer
c7c7977a80 Fix bug: double entries in history
Introduced in 2b0f8feb.
2024-04-03 00:44:14 +02:00
Juerd Waalboer
2b0f8febf0 v6.0.4: use readline's internal loop
This fixes the bug that empty lines would be inserted after each prompt,
starting from the first use of ^D.

Readline considers ^D end-of-file even when it's not, and for whatever
reason then adds a \n after BRACK_PASTE_FINI, which results in empty
lines after subsequent prompts.

With readline's internal loop, rl_found_eof gets reset to false, but
users of a custom loop don't get that luxury, and Term::ReadLine::Gnu
doesn't expose rl_found_eof (which was added to readline's API only a
few years ago) to do it manually.

One workaround, used briefly but not committed, would be to disable
bracketed paste.

A better workaround, as implemented by this commit, is to abandon the
custom loop and use readline's blocking call instead.
2024-02-11 04:14:05 +01:00
Juerd Waalboer
9c779d022a Whitespace 2023-12-28 21:02:07 +01:00
Juerd Waalboer
71d2179ea2 Better cursor position after input syntax error 2023-12-28 20:38:37 +01:00
Juerd Waalboer
0b2ea27117 Move prompt code to RevBank::Prompt
Wanted to move split_input() to a package for unit testing, thought I'd
move prompt() too since the main executable has become messy, and this
would be a good first step in resolving that.
2023-12-28 03:45:28 +01:00
Juerd Waalboer
0cd178d950 Support control character escapes, add :AllChars attribute
Also:
- fix warning in RevBank::Plugin->Tab when there are attrs but no :Tab
- reconstruct quotes and escapes in prompt on retry
2023-12-28 03:07:40 +01:00
Juerd Waalboer
0de7e2dda6 Tweak output (increase indendation) 2023-12-26 19:33:11 +01:00
Juerd Waalboer
212dba11c8 Remove unnecessary space in front of non-positive number 2023-12-26 05:47:32 +01:00
Juerd Waalboer
3670a72c31 Fix padding
Somehow the %8s for the amount got turned into %6s in commit ef5babd3,
which should only have changed the padding for the quantity.
2023-12-26 05:47:29 +01:00
Juerd Waalboer
6b04ecc256 undo: deal with checkout exception
The ancient decision to let undo perform the checkout by itself still
makes sense from a UX perspective, but keeps requiring specific handling
of edge cases.

In this case, the easiest way to deal with trailing input is to just
abort entirely.

Also: updated lib/RevBank/Plugins.pm to import 'isa' and get up to 5.32
level.
2023-12-26 02:08:24 +01:00
Juerd Waalboer
daf0077d0d Introduce ';' as command/transaction separator
There's a slight mismatch between what users experience as a command,
and how commands are defined in RevBank. Specifically, the common input
"<productid> <username>" is two separate commands: the first adds the
product to the cart, the second finalizes the transaction. This also
means that "<productid> <username> <productid> <username>" was four
separate commands, resulting in TWO transactions.

That's all fine and useful, but when using this advanced input method,
where input is split on whitespace, it lead to unexpected results if
there are insufficient arguments for the follow-up questions of a
command. For example, "take jantje 10 take pietje 10" will interpret the
second "take" as the description, then "pietje" als the first command of
a new transaction, and finally, "10" which is typically not a valid
command. It is much more likely that the user intended two separate
"take" commands and just forgot to provide the description argument, but
RevBank had no way of inferring that intent.

From this commit on, whenever the user intends to enter further input
words beyond the one that finalizes a transaction ($cart->checkout), a
';' is required. If trailing input is present, the checkout is refused
and the user gets a retry prompt.

Similarly, if the user indicates the intention of having finished a
command by inserting a ';' while there are insufficient words in the
command line to satisfy all follow-up prompts (command arguments), the
rest of the command line is rejected with a retry prompt.

There is, however, still no specific requirement for a ';' separator
after a command that does not finalize a transaction (e.g. "<productid>
<username>" or even "<productid> x2 <productid> <username>" remains
valid), or for a command that precedes a ';' to finalize a transaction
(e.g. "<productid>; <username>;" is also valid).

This change catches many, but not all, mistakes.
2023-12-26 00:21:01 +01:00
Juerd Waalboer
dd47bfbdf7 Remove redundant code
Harmless but distracting leftovers from a previous, more complicated, approach.
2023-12-25 04:47:27 +01:00
Juerd Waalboer
3dab71fdbf support simple arithmetic (only + and -) for monetary amounts 2023-12-25 00:33:46 +01:00
Juerd Waalboer
3470ebeb1c Explicitly use Perl 5.32
Was already implicitly required (since 59387ddb) because RevBank::Amount
uses the "isa" feature, which was introduced in Perl 5.32 (but no longer
experimental since 5.36, not 5.32 as the old comment said).

Perl 5.32 was released in June 2020, and ships with Debian bullseye
("oldstable") which was released in August 2021.
2023-12-12 00:28:17 +01:00
Juerd Waalboer
99154a4b62 Show deprecation notice for unbalanced entries 2023-11-24 06:22:30 +01:00
Juerd Waalboer
dbe75efe7f Remove references to deprecated calling convention
Deprecated 4 years ago, no longer supported since 2 years ago.
2023-11-24 05:52:04 +01:00
Juerd Waalboer
52749df5f3 Ignore all hook exceptions except in hook_checkout_prepare
A space had a custom plugin that died during hook_checkout, which caused
the CHECKOUT lines to be logged without the corresponding BALANCE, and
indeed no account balances were updated. While the plugin had a bug, it
should not cause a half transaction in RevBank.

After some hesitation, I went with ON ERROR RESUME NEXT because if a
hook throws an exception, that should not interfere with other plugins
(the hook can return ABORT if this it was intentional), including the
calling plugin. An error message is printed (but not logged... TODO: add
hook_plugin_fail to plugins/log) but the show must go on.

During hook_checkout_prepare, however, nothing is set in stone yet, so
this could be used for something that might die, and this instance of
call_hooks() is now the one place where a failing hook should result in
the transaction getting aborted. For this, call_hooks() now returns a
success status boolean. Maybe it would make sense in more places, but I
didn't identify any such calls yet.

RevBank::Cart->checkout used to return a success status boolean, but it
could just as well just die (indirectly, to abort the transaction) since
it can't be called a second time within the same transaction anyway
(because ->set_user must be called exactly once), so continuing with the
same transaction can't result in anything useful anyway.

In some places, error messages were slightly improved to contain a bit
more information.
2023-11-24 05:15:22 +01:00
Juerd Waalboer
aa589d59cb Document RevBank::Users (accounts) 2023-11-05 21:19:39 +01:00
Juerd Waalboer
7dd94eda9b Add assertions
There should already be external checks to prevent double entries in
revbank.accounts, but better safe than sorry.
2023-11-05 21:19:17 +01:00
Juerd Waalboer
d54428b092 Add support for user-accessible accounts that are excluded from grandtotal 2023-11-02 05:33:33 +01:00
Juerd Waalboer
8956d8a483 Move :Tab introspection from main:: to RevBank::Plugin
- Exposes the introspection as a public method.
- Removes undocumented support for NOABORT special-case.
2023-11-02 03:16:55 +01:00
Juerd Waalboer
b50bbfef96 Update comment 2023-09-20 21:11:19 +02:00
Juerd Waalboer
560242a4bc Bump version to 4.0.0; change transaction ID scheme 2023-09-20 20:15:43 +02:00
Juerd Waalboer
fbb178d5ac Formal mechanism for retrying input
This allows for alias plugins with better error messages and better
logging than with the $_[2] =~ s/// hack.
2023-09-18 01:31:13 +02:00
Juerd Waalboer
59387ddba4 Use formerly experimental Perl features with "use experimental"
This is semantically equivalent to use feature + no warnings, but less
noisy. I've also added comments to indicate when the line can be
removed.
2023-09-10 02:13:33 +02:00
Juerd Waalboer
c43764afbb Deal with @_ in signatured sub being experimental in Perl 5.36 2023-07-17 21:56:13 +02:00
Juerd Waalboer
bf8d69b5e6 Split documentation for RevBank::Global 2023-05-23 12:56:34 +02:00
Juerd Waalboer
dd5b77ce47 Update limit 19.84 -> 22.00 2023-04-11 23:53:55 +02:00
Juerd Waalboer
b052292a22 ChatGPT wrote some unit tests and found a small bug.
When asked to fix the bug, it came up with a different regex, which
would completely change what's valid and what's not, so that's totally
wrong:

    /^\s*(-)?([0-9]+)(?:[,.]([0-9]{1,2}))?\s*$/

When asked to fix it in another way, without changing the regex, it
suggested stripping the sign completely, which is even more wrong.

So I fixed it myself :)
2023-03-16 00:00:26 +01:00
Juerd Waalboer
0e1aa77fe5 statiegeld_tokens: simplify void
- No more red messages
- Accept "yes" case insensitively
- Change entry description and amount so the voiding is logged, which is
  more code but less complex than passing an attribute to be used during
  checkout.
2023-02-13 02:44:02 +01:00
Juerd Waalboer
fffb2d72e9 Fix deduplication bug, refactor deduplication to own plugin
(Bumps version to 3.8 because admins should update the plugin list.)

Deduplication didn't work on quantified additions, i.e. if you added
"20x clubmate" when there was already clubmate in the cart, it would add
just ONE item, and have a lingering message that the next thing would be
multiplied by 20.

This old bug was especially annoying if there is a barcode "20x
clubmate" to scan 20 bottles (which is the size of a crate), and this is
repeated.

The fix also uncovered another bug: newly added entries were selected
too early. There are two hooks, hook_add_entry and hook_added_entry, and
of course the selection should happen in between, not before the former.
No entry in UPGRADING.md, because I think it is extremely unlikely that
any plugin author will have used the selection feature yet, which is
very new.
2023-02-12 17:53:14 +01:00
Juerd Waalboer
248681631d More contrast
Some terminals (notably: linux non-framebuffer vt) do support colors,
but do not support the bold/bright attribute.
2023-02-12 17:51:17 +01:00
Juerd Waalboer
416c722511 Pad differently
Experimental code (never committed) had ANSI escape sequences there, and
required manual padding. Those were gone, but I forgot to change the
manual padding into normal sprintf padding.

This also makes it explicit that the left alignment is actually intended
here. (Actually looks better here.)
2023-01-30 05:05:26 +01:00
Juerd Waalboer
e5c004958f Always show quantity if quantity changed 2023-01-30 04:42:12 +01:00
Juerd Waalboer
99435cef17 Highlight change; apply operators to last scanned instead of last added 2023-01-30 04:40:42 +01:00
Juerd Waalboer
ef5babd3df More compact display for repeated products
Might revert later
2023-01-30 03:59:42 +01:00
Juerd Waalboer
f479060576 Fix bug: ->changed is getter only, not a setter 2023-01-19 05:24:50 +01:00
Juerd Waalboer
16d530ae16 Allow hook_prompt to mutate the prompt, like before, and use that
This functionality was accidentally broken by eed0db78

Also: ignore readline terminal sequence (\x01...\x02) in detection of ">"
2023-01-19 03:04:35 +01:00
Juerd Waalboer
5b0c85d770 Refactor read_products and its callers
- Promote to public function since it's used in other plugins anyway
- Move resolving of addons to read_products (print errors immediately)
- Cache product list based on mtime; mostly to reduce the amount of spam
  from errors as performance was never an issue.
- Cache product object in cart entry, so statiegeld_tokens plugin
  doesn't have to do the lookup all over again.
2023-01-17 20:28:35 +01:00