SatSale

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit d3b0e170dd8698f7b4edfb34063719371852e397
parent 9592d4218fca15abda9dc6df80332538e60fa39e
Author: Kristaps Kaupe <kristaps@blogiem.lv>
Date:   Wed, 19 Jan 2022 17:39:27 +0200

Script to generate received payment report csv (#30)


Diffstat:
Mpayments/database.py | 13+++++++++----
Ascripts/generate_payment_report.py | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+), 4 deletions(-)

diff --git a/payments/database.py b/payments/database.py @@ -11,7 +11,7 @@ def create_database(name="database.db"): def write_to_database(invoice, name="database.db"): - with sqlite3.connect("database.db") as conn: + with sqlite3.connect(name) as conn: cur = conn.cursor() cur.execute( "INSERT INTO payments (uuid,fiat_value,btc_value,method,address,time,webhook,rhash) VALUES (?,?,?,?,?,?,?,?)", @@ -29,13 +29,18 @@ def write_to_database(invoice, name="database.db"): return -def load_invoice_from_db(uuid): - with sqlite3.connect("database.db") as conn: +def load_invoices_from_db(where, name="database.db"): + with sqlite3.connect(name) as conn: conn.row_factory = sqlite3.Row cur = conn.cursor() rows = cur.execute( - "select * from payments where uuid='{}'".format(uuid) + "SELECT * FROM payments WHERE {}".format(where) ).fetchall() + return rows + + +def load_invoice_from_db(uuid, name="database.db"): + rows = load_invoices_from_db("uuid='{}'".format(uuid), name) if len(rows) > 0: return [dict(ix) for ix in rows][0] else: diff --git a/scripts/generate_payment_report.py b/scripts/generate_payment_report.py @@ -0,0 +1,87 @@ +import argparse +import csv +from datetime import datetime, timedelta + +import config +from payments import database +from node import bitcoind +from node import lnd +from node import clightning + + +def valid_date(s): + try: + return datetime.strptime(s, "%Y-%m-%d") + except ValueError: + msg = "not a valid date: {0!r}".format(s) + raise argparse.ArgumentTypeError(msg) + + +def main(): + parser = argparse.ArgumentParser( + description="Generate CSV report about received payments.") + parser.add_argument("report_file") + parser.add_argument("--date-from", required=False, dest="date_from", + help="from date (YYYY-MM-DD)", type=valid_date) + parser.add_argument("--date-to", required=False, dest="date_to", + help="to date (YYYY-MM-DD)", type=valid_date) + + try: + args = parser.parse_args() + except Exception as e: + print("Error: {}".format(e)) + return + + bitcoin_node = bitcoind.btcd() + if config.pay_method == "lnd": + lightning_node = lnd.lnd() + elif config.pay_method == "clightning": + lightning_node = clightning.clightning() + + where = "1" + if args.date_from: + where = where + " AND time >= {}".format( + datetime.timestamp(args.date_from)) + if args.date_to: + where = where + " AND time < {}".format( + datetime.timestamp(args.date_to + timedelta(days=1))) + invoices = database.load_invoices_from_db(where) + + with open(args.report_file, "w", newline="") as csvfile: + reportwriter = csv.writer(csvfile) + reportwriter.writerow([ + "Date", "Invoice ID", "Fiat value", "BTC value", + "BTC paid", "Payment method", "Address" + ]) + num_rows = 0 + for invoice in invoices: + conf_paid = 0 + if invoice["method"] == "bitcoind": + conf_paid, unconf_paid = bitcoin_node.check_payment( + invoice["uuid"]) + elif invoice["method"] == "lnd": + conf_paid, unconf_paid = lightning_node.check_payment( + invoice["rhash"]) + elif invoice["method"] == "clightning": + conf_paid, unconf_paid = lightning_node.check_payment( + invoice["uuid"]) + + if conf_paid > 0: + reportwriter.writerow([ + datetime.utcfromtimestamp( + int(invoice["time"])).strftime("%Y-%m-%d"), + invoice["uuid"], + invoice["fiat_value"], + "%.8f" % float(invoice["btc_value"]), + "%.8f" % float(conf_paid), + invoice["method"], + invoice["address"] + ]) + num_rows = num_rows + 1 + + print("Report generated and saved to {} ({} rows).".format( + args.report_file, num_rows)) + + +if __name__ == "__main__": + main()