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