From 913f8b6b2df3f73e01534f4485b9c0b1ed7b2242 Mon Sep 17 00:00:00 2001 From: Bitkarrot <73979971+bitkarrot@users.noreply.github.com> Date: Thu, 23 Mar 2023 06:46:49 -0700 Subject: [PATCH] Delete invoices (#1) * add delete invoice * Update manifest.json * fix js * api delete param * debug stmts * fix crud * fix updated invoices * Update crud.py * Update index.html * Update views_api.py remove /delete from api endpoint * Update _api_docs.html update docs to reflect api endpoint changes * format with prettier --- crud.py | 32 +++++++++ templates/invoices/_api_docs.html | 27 +++++++ templates/invoices/index.html | 113 +++++++++++++++++------------- views_api.py | 12 +++- 4 files changed, 135 insertions(+), 49 deletions(-) diff --git a/crud.py b/crud.py index 3965280..19d8718 100644 --- a/crud.py +++ b/crud.py @@ -146,6 +146,38 @@ async def update_invoice_internal( assert invoice, "Newly updated invoice couldn't be retrieved" return invoice +async def delete_invoice( + invoice_id: str, +) -> bool: + await db.execute( + f""" + DELETE FROM invoices.payments + WHERE invoice_id = ? + """, + ( + invoice_id, + ), + ) + await db.execute( + f""" + DELETE FROM invoices.invoice_items + WHERE invoice_id = ? + """, + ( + invoice_id, + ), + ) + await db.execute( + f""" + DELETE FROM invoices.invoices + WHERE id = ? + """, + ( + invoice_id, + ), + ) + return True + async def update_invoice_items( invoice_id: str, data: List[UpdateInvoiceItemData] diff --git a/templates/invoices/_api_docs.html b/templates/invoices/_api_docs.html index 6e2a635..3ac869a 100644 --- a/templates/invoices/_api_docs.html +++ b/templates/invoices/_api_docs.html @@ -150,4 +150,31 @@
Curl example
+ + + + + DELETE + /invoices/api/v1/invoice/{invoice_id} +
Headers
+
Body (application/json)
+
+ Returns 200 OK (application/json) +
+
Curl example
+ curl -X DELETE {{ request.base_url + }}invoices/api/v1/invoice/{invoice_id} -H + "X-Api-Key: <admin_key>" + +
+
+
diff --git a/templates/invoices/index.html b/templates/invoices/index.html index 4ef3b7f..8a8d843 100644 --- a/templates/invoices/index.html +++ b/templates/invoices/index.html @@ -4,9 +4,9 @@
- New Invoice + + New Invoice + @@ -64,6 +64,14 @@
Invoices
{{ col.value }} + {% endraw %} @@ -81,13 +89,13 @@
- {% include "invoices/_api_docs.html" %} + {% include "invoices/_api_docs.html" %}
- + :disable="formDialog.data.wallet == null || formDialog.data.currency == null" type="submit" v-if="typeof formDialog.data.id == 'undefined'" - >Create Invoice + Create Invoice + Save Invoice - Cancel + Save Invoice + + + Cancel + @@ -231,7 +241,7 @@
var mapInvoice = function (obj) { obj.time = Quasar.utils.date.formatDate( new Date(obj.time * 1000), - 'YYYY-MM-DD HH:mm' + 'YYYY-MM-DD HH:mm', ) return obj @@ -421,51 +431,56 @@
'YER', 'ZAR', 'ZMW', - 'ZWL' + 'ZWL', ], invoicesTable: { columns: [ - {name: 'id', align: 'left', label: 'ID', field: 'id'}, - {name: 'status', align: 'left', label: 'Status', field: 'status'}, - {name: 'time', align: 'left', label: 'Created', field: 'time'}, - {name: 'wallet', align: 'left', label: 'Wallet', field: 'wallet'}, + { name: 'id', align: 'left', label: 'ID', field: 'id' }, + { name: 'status', align: 'left', label: 'Status', field: 'status' }, + { name: 'time', align: 'left', label: 'Created', field: 'time' }, + { name: 'wallet', align: 'left', label: 'Wallet', field: 'wallet' }, { name: 'currency', align: 'left', label: 'Currency', - field: 'currency' + field: 'currency', }, { name: 'company_name', align: 'left', label: 'Company Name', - field: 'company_name' + field: 'company_name', }, { name: 'first_name', align: 'left', label: 'First Name', - field: 'first_name' + field: 'first_name', }, { name: 'last_name', align: 'left', label: 'Last Name', - field: 'last_name' + field: 'last_name', + }, + { name: 'email', align: 'left', label: 'Email', field: 'email' }, + { name: 'phone', align: 'left', label: 'Phone', field: 'phone' }, + { + name: 'address', + align: 'left', + label: 'Address', + field: 'address', }, - {name: 'email', align: 'left', label: 'Email', field: 'email'}, - {name: 'phone', align: 'left', label: 'Phone', field: 'phone'}, - {name: 'address', align: 'left', label: 'Address', field: 'address'} ], pagination: { - rowsPerPage: 10 - } + rowsPerPage: 10, + }, }, formDialog: { show: false, data: {}, - invoiceItems: [] - } + invoiceItems: [], + }, } }, methods: { @@ -486,7 +501,7 @@
.request('GET', '/invoices/api/v1/invoice/' + invoice_id) .then(function (response) { self.formDialog.invoiceItems = response.data.items.map(function ( - obj + obj, ) { return mapInvoiceItems(obj) }) @@ -499,7 +514,7 @@
.request( 'GET', '/invoices/api/v1/invoices?all_wallets=true', - this.g.user.wallets[0].inkey + this.g.user.wallets[0].inkey, ) .then(function (response) { self.invoices = response.data.map(function (obj) { @@ -516,9 +531,10 @@
.request( 'POST', '/invoices/api/v1/invoice' + (data.id ? '/' + data.id : ''), - _.findWhere(this.g.user.wallets, {id: this.formDialog.data.wallet}) - .inkey, - data + _.findWhere(this.g.user.wallets, { + id: this.formDialog.data.wallet, + }).inkey, + data, ) .then(function (response) { if (!data.id) { @@ -534,38 +550,39 @@
LNbits.utils.notifyApiError(error) }) }, - deleteTPoS: function (tposId) { - var self = this - var tpos = _.findWhere(this.tposs, {id: tposId}) - + deleteInvoice(invoice_id) { + const adminkey = this.g.user.wallets[0].adminkey LNbits.utils - .confirmDialog('Are you sure you want to delete this TPoS?') - .onOk(function () { + .confirmDialog('Are you sure you want to delete this Invoice?') + .onOk(() => { LNbits.api .request( 'DELETE', - '/tpos/api/v1/tposs/' + tposId, - _.findWhere(self.g.user.wallets, {id: tpos.wallet}).adminkey + '/invoices/api/v1/invoice/' + invoice_id + '/delete', + adminkey, ) - .then(function (response) { - self.tposs = _.reject(self.tposs, function (obj) { - return obj.id == tposId - }) + .then((response) => { + if (response.status == 200) { + this.invoices = _.reject( + this.invoices, + (obj) => obj.id === invoice_id, + ) + } }) - .catch(function (error) { - LNbits.utils.notifyApiError(error) + .catch((err) => { + LNbits.utils.notifyApiError(err) }) }) }, exportCSV: function () { LNbits.utils.exportCSV(this.invoicesTable.columns, this.invoices) - } + }, }, created: function () { if (this.g.user.wallets.length) { this.getInvoices() } - } + }, }) {% endblock %} diff --git a/views_api.py b/views_api.py index 60dea9a..83701de 100644 --- a/views_api.py +++ b/views_api.py @@ -21,6 +21,7 @@ get_payments_total, update_invoice_internal, update_invoice_items, + delete_invoice, ) from .models import CreateInvoiceData, UpdateInvoiceData @@ -66,6 +67,15 @@ async def api_invoice_create( return invoice_dict +@invoices_ext.delete("/api/v1/invoice/{invoice_id}", status_code=HTTPStatus.OK) +async def api_invoice_delete(invoice_id: str): + try: + status = await delete_invoice(invoice_id=invoice_id) + return {"status": status} + except Exception as e: + raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) + + @invoices_ext.post("/api/v1/invoice/{invoice_id}", status_code=HTTPStatus.OK) async def api_invoice_update( data: UpdateInvoiceData, @@ -73,7 +83,7 @@ async def api_invoice_update( wallet: WalletTypeInfo = Depends(get_key_type), ): invoice = await update_invoice_internal(wallet_id=wallet.wallet.id, data=data) - items = await update_invoice_items(invoice_id=invoice.id, data=data.items) + items = await update_invoice_items(invoice_id=invoice_id, data=data.items) invoice_dict = invoice.dict() invoice_dict["items"] = items return invoice_dict