diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2022-07-26 16:14:28 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2022-07-26 16:17:47 +0200 |
| commit | 60f70889c21a02397c8eaeee8db8da268b0b1ca5 (patch) | |
| tree | aa70ca084ff2337669b99a02074e8244a6db1459 | |
| parent | 5b1e9657518c87acb89dde410393b52be81c2b96 (diff) | |
| download | geldschieberbot-60f70889c21a02397c8eaeee8db8da268b0b1ca5.tar.gz geldschieberbot-60f70889c21a02397c8eaeee8db8da268b0b1ca5.zip | |
geldschieberbot: support transaction with multiple recipients
All recipients receive amount making transactionswith multiple receipients
a shortcut for posting the same transaction with a changing recipient.
!schieb 5 alice bob
is equivalent to
!schieb 5 alice
!schieb 5 bob
Aliases are supported as well.
| -rw-r--r-- | geldschieberbot.py | 61 | ||||
| -rwxr-xr-x | test.py | 67 |
2 files changed, 107 insertions, 21 deletions
diff --git a/geldschieberbot.py b/geldschieberbot.py index 1ae85ed..4488114 100644 --- a/geldschieberbot.py +++ b/geldschieberbot.py @@ -227,10 +227,10 @@ class Geldschieberbot: split amount person [persons] - split amount between the sender and persons teil amount person [persons] - split amount between the sender and persons - schieb amount recipient - give money to recipient - gib amount recipient - give money to recipient - zieh amount donor - get money from donor - nimm amount donor - get money from donor + schieb amount recipient [recipients ...] - give money to one or more recipients + gib amount recipient [recipients ...] - give money to one or more recipients + zieh amount donor [donor ...] - get money from one or more donors + nimm amount donor [donor ...] - get money from one or more donors transfer amount source destination - transfer amount of your balance from source to destination @@ -365,22 +365,30 @@ class Geldschieberbot: def transaction(self, sender, args, msg) -> dict[str, str]: # pylint: disable=unused-argument """Record a transaction""" - if len(args) != 3: - return {'err': f'not in form "{args[0]} amount recipient"'} + if len(args) < 3: + return { + 'err': + f'not in form "{args[0]} amount recipient [recipient ...]"' + } if not sender in self.balance: if sender not in self.num2name: return {'err': 'you must register first'} sender = self.num2name[sender] - if args[1] in self.balance: - recipient, amount = args[1:3] - elif args[2] in self.balance: - amount, recipient = args[1:3] + if len(args) == 3: + if args[1] in self.balance or args[1] in self.aliases: + recipient, amount = args[1:3] + elif args[2] in self.balance or args[2] in self.aliases: + amount, recipient = args[1:3] + else: + return {'err': 'recipient not known'} + + recipients = self.expand_aliases([recipient]) else: - return {'err': 'recipient not known'} + amount, recipients = args[1], args[2:] - if sender == recipient: + if sender in recipients: return {'err': 'you can not transfer money to or from yourself'} try: @@ -388,19 +396,34 @@ class Geldschieberbot: except (ValueError, TypeError): return {'err': 'amount must be a positive number'} + for recipient in recipients: + if recipient not in self.balance: + return {'err': f'recipient "{recipient}" not known'} + if args[0] in ["!zieh", "!nimm"]: amount *= -1 - self.may_record_change(sender, [args, [sender, recipient, amount]]) + transaction_sum = '' - self.record(sender, recipient, amount) + change = [args] + for recipient in recipients: + change.append([sender, recipient, amount]) + self.record(sender, recipient, amount) - p_balance = self.balance[sender][recipient] + p_balance = self.balance[sender][recipient] - output = ("New Balance: {} {} {} {}\n".format( - sender, ("->" if p_balance > 0 else "<-"), to_euro(abs(p_balance)), - recipient)) - return {'msg': output} + transaction_sum += f'{"->" if amount > 0 else "<-"} {recipient} {to_euro(abs(amount))}\n' + + self.may_record_change(sender, change) + + output = '' + if len(recipients) > 1: + output += transaction_sum + output += 'New Balance:\n' + output += self.create_summary(sender, recipients) + else: + output = f'New Balance: {sender} {"->" if p_balance > 0 else "<-"} {to_euro(abs(p_balance))} {recipient}\n' + return {'msg': f'{output}'} def transfer(self, sender, args, msg) -> dict[str, str]: # pylint: disable=unused-argument """Transfer amount from one balance to another""" @@ -249,6 +249,33 @@ class TestTransactionCmd(unittest.TestCase): res.stdout, 'ERROR: you can not transfer money to or from yourself') + def test_transactions_with_multiple_recipients(self): + for cmds in [('schieb', 'zieh'), ('gib', 'nimm')]: + res = run_bot(self, num[charlie], f'!{cmds[0]} 5 {alice} {bob}') + self.assertEqual(res.stdout, \ +"""-> alice 5.00 +-> bob 5.00 +New Balance: +charlie: +\t<- alice 5.00 +\t<- bob 5.00 +\tBalance: 10.00""") + + res = run_bot(self, num[charlie], f'!{cmds[1]} 5 {alice} {bob}') + self.assertEqual(res.stdout, \ +"""<- alice 5.00 +<- bob 5.00 +New Balance: +charlie: +\tAll fine :)""") + + def test_invalid_transactions_with_multiple_recipients(self): + res = run_bot(self, num[charlie], f'!schieb {alice} 5 {bob}') + self.assertEqual(res.stdout, 'ERROR: amount must be a positive number') + + res = run_bot(self, num[charlie], f'!zieh 5 5 {bob}') + self.assertEqual(res.stdout, 'ERROR: recipient "5" not known') + class TestSumCmd(unittest.TestCase): @@ -501,6 +528,44 @@ class TestAlias(unittest.TestCase): self.assertEqual(res.stdout, 'ERROR: Alias "all" is already registered') + +class TestAliasUsage(unittest.TestCase): + + def setUp(self): + reset_state("test/state_3users_1alias.json") + + def test_schieb_alias(self): + expected = \ +"""-> alice 5.00 +-> bob 5.00 +New Balance: +charlie: +\t<- alice 5.00 +\t<- bob 5.00 +\tBalance: 10.00""" + + for cmd in ['gib', 'schieb']: + for args in ['5 alob', 'alob 5']: + res = run_bot(self, num[charlie], f'!{cmd} {args}') + self.assertEqual(res.stdout, expected) + self.setUp() + + def test_zieh_alias(self): + expected = \ +"""<- alice 5.00 +<- bob 5.00 +New Balance: +charlie: +\t-> alice 5.00 +\t-> bob 5.00 +\tBalance: -10.00""" + + for cmd in ['nimm', 'zieh']: + for args in ['5 alob', 'alob 5']: + res = run_bot(self, num[charlie], f'!{cmd} {args}') + self.assertEqual(res.stdout, expected) + self.setUp() + def test_split_all(self): res = run_bot(self, num[alice], "!split 9 all") self.assertEqual(res.stdout, \ @@ -512,7 +577,6 @@ alice: \tBalance: 6.00""") def test_split_alias(self): - run_bot(self, num[alice], f"!alias alob {alice} {bob}") res = run_bot(self, num[charlie], "!split 9 alob") self.assertEqual(res.stdout, \ """Split 9.00 between 3 -> 3.00 each @@ -535,7 +599,6 @@ alice: \tBalance: 6.66""") def test_tanken_alias(self): - run_bot(self, num[alice], f"!alias alob {alice} {bob}") res = run_bot(self, num[charlie], "!tanken 8\n10 alob") self.assertEqual(res.stdout, \ """alice: 10km = fuel: 4.00, service charge: 0.00 |
