From bb34cbbbd07c0983ece79a2af6ff7cc48bf9c4dd Mon Sep 17 00:00:00 2001
From: matograine <tom.ngr@zaclys.net>
Date: Wed, 22 Jan 2020 17:41:00 +0100
Subject: [PATCH] [feat] #111: Send multiple outputs: change click options:

* Breaking change: Rename `--output` option to `--recipient`
* Add extra small options to ease passing multiple amounts and recipients:
  * `-a/--amount`
  * `-d/--amountUD`
  * `-r/--recipient`
* Add possibility to pass multiple options:
  * Breaking change: recipients public keys are no longer `:` separated: `-r A -r B`
* Store the options in variables names in plural for preciseness
* Fix: Handle the case when no option specifying the amount is passed
* Restrict `--allSources` option to a single recipient, case not handle for now
* Extend tests with two upper checks
* Improve help
---
 silkaj/tx.py     | 55 +++++++++++++++++++++++++++++++++---------------
 tests/test_tx.py | 11 ++++++++++
 2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/silkaj/tx.py b/silkaj/tx.py
index 1ad3e7ed..f372e8a4 100644
--- a/silkaj/tx.py
+++ b/silkaj/tx.py
@@ -42,30 +42,42 @@ from duniterpy.documents.transaction import OutputSource, Unlock, SIGParameter
 
 @command("tx", help="Send transaction")
 @option(
+    "amounts",
     "--amount",
+    "-a",
+    multiple=True,
     type=FloatRange(0.01),
-    help="Quantitative value",
+    help="Quantitative amount(s):\n-a <amount>\nMinimum amount is 0.01.",
     cls=MutuallyExclusiveOption,
-    mutually_exclusive=["amountud", "allsources"],
+    mutually_exclusive=["amountsud", "allsources"],
 )
 @option(
+    "amountsud",
     "--amountUD",
+    "-d",
+    multiple=True,
     type=float,
-    help="Relative value",
+    help="Relative amount(s):\n-d <amount_UD>",
     cls=MutuallyExclusiveOption,
-    mutually_exclusive=["amount", "allsources"],
+    mutually_exclusive=["amounts", "allsources"],
 )
 @option(
     "--allSources",
     is_flag=True,
-    help="Send all sources",
+    help="Send all sources to one recipient",
     cls=MutuallyExclusiveOption,
-    mutually_exclusive=["amount", "amountud"],
+    mutually_exclusive=["amounts", "amountsud"],
 )
 @option(
-    "--output",
+    "recipients",
+    "--recipient",
+    "-r",
+    multiple=True,
     required=True,
-    help="Pubkey(s)’ recipients + optional checksum: <pubkey>[!checksum]:[<pubkey>[!checksum]]",
+    help="Pubkey(s)’ recipients + optional checksum:\n-r <pubkey>[!checksum]\n\
+Sending to many recipients is possible:\n\
+* With one amount, all will receive the amount\n\
+* With many amounts (one per recipient)",
 )
 @option("--comment", default="", help="Comment")
 @option(
@@ -75,24 +87,33 @@ from duniterpy.documents.transaction import OutputSource, Unlock, SIGParameter
 @option("--yes", "-y", is_flag=True, help="Assume yes. Do not prompt confirmation")
 @coroutine
 async def send_transaction(
-    amount, amountud, allsources, output, comment, outputbackchange, yes
+    amounts, amountsud, allsources, recipients, comment, outputbackchange, yes
 ):
     """
     Main function
     """
-    tx_amount = await transaction_amount(amount, amountud, allsources)
+    if not (amounts or amountsud or allsources):
+        message_exit("Error: amount, amountUD or allSources is not set.")
+    if allsources and len(recipients) > 1:
+        message_exit(
+            "Error: the --allSources option can only be used with one recipient."
+        )
+    # compute amounts and amountsud
+    if not allsources:
+        tx_amounts = await transaction_amount(amounts, amountsud, recipients)
+
     key = auth_method()
     issuer_pubkey = key.pubkey
 
     pubkey_amount = await get_amount_from_pubkey(issuer_pubkey)
     if allsources:
-        tx_amount = pubkey_amount[0]
-    outputAddresses = output.split(":")
+        tx_amounts = [pubkey_amount[0]]
+
     check_transaction_values(
         comment,
-        outputAddresses,
+        recipients,
         outputbackchange,
-        pubkey_amount[0] < tx_amount * len(outputAddresses),
+        pubkey_amount[0] < sum(tx_amounts),
         issuer_pubkey,
     )
 
@@ -103,8 +124,8 @@ async def send_transaction(
                 await transaction_confirmation(
                     issuer_pubkey,
                     pubkey_amount[0],
-                    tx_amount,
-                    outputAddresses,
+                    tx_amounts,
+                    recipients,
                     outputbackchange,
                     comment,
                 ),
@@ -115,7 +136,7 @@ async def send_transaction(
         == "yes"
     ):
         await handle_intermediaries_transactions(
-            key, issuer_pubkey, tx_amount, outputAddresses, comment, outputbackchange
+            key, issuer_pubkey, tx_amounts, recipients, comment, outputbackchange,
         )
     else:
         client = ClientInstance().client
diff --git a/tests/test_tx.py b/tests/test_tx.py
index 77185802..03ce41a4 100644
--- a/tests/test_tx.py
+++ b/tests/test_tx.py
@@ -53,3 +53,14 @@ def test_tx_passed_amount_cli():
     )
     assert "Error: Usage" in result.output
     assert result.exit_code == 2
+
+    result = CliRunner().invoke(cli, ["tx", "-r", "A"])
+    assert "Error: amount, amountUD or allSources is not set." in result.output
+    assert result.exit_code == 1
+
+    result = CliRunner().invoke(cli, ["tx", "-r", "A", "-r", "B", "--allSources"])
+    assert (
+        "Error: the --allSources option can only be used with one recipient."
+        in result.output
+    )
+    assert result.exit_code == 1
-- 
GitLab