Skip to content

Commit

Permalink
Delete invoices (#1)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
bitkarrot authored Mar 23, 2023
1 parent f9f1023 commit 913f8b6
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 49 deletions.
32 changes: 32 additions & 0 deletions crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
27 changes: 27 additions & 0 deletions templates/invoices/_api_docs.html
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,31 @@ <h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
</q-card-section>
</q-card>
</q-expansion-item>

<q-expansion-item
group="api"
dense
expand-separator
label="Delete Invoice"
>
<q-card>
<q-card-section>
<code
><span class="text-blue">DELETE</span>
/invoices/api/v1/invoice/{invoice_id}</code
>
<h5 class="text-caption q-mt-sm q-mb-none">Headers</h5>
<h5 class="text-caption q-mt-sm q-mb-none">Body (application/json)</h5>
<h5 class="text-caption q-mt-sm q-mb-none">
Returns 200 OK (application/json)
</h5>
<h5 class="text-caption q-mt-sm q-mb-none">Curl example</h5>
<code
>curl -X DELETE {{ request.base_url
}}invoices/api/v1/invoice/{invoice_id} -H
"X-Api-Key: &lt;admin_key&gt;"
</code>
</q-card-section>
</q-card>
</q-expansion-item>
</q-expansion-item>
113 changes: 65 additions & 48 deletions templates/invoices/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
<div class="col-12 col-md-8 col-lg-7 q-gutter-y-md">
<q-card>
<q-card-section>
<q-btn unelevated color="primary" @click="formDialog.show = true"
>New Invoice</q-btn
>
<q-btn unelevated color="primary" @click="formDialog.show = true"></q-btn>
New Invoice
</q-btn>
</q-card-section>
</q-card>

Expand Down Expand Up @@ -64,6 +64,14 @@ <h5 class="text-subtitle1 q-my-none">Invoices</h5>
<q-td v-for="col in props.cols" :key="col.name" :props="props">
{{ col.value }}
</q-td>
<q-btn
flat
dense
size="xs"
@click="deleteInvoice(props.row.id)"
icon="cancel"
color="pink"
></q-btn>
</q-tr>
</template>
{% endraw %}
Expand All @@ -81,13 +89,13 @@ <h6 class="text-subtitle1 q-my-none">
</q-card-section>
<q-card-section class="q-pa-none">
<q-separator></q-separator>
<q-list> {% include "invoices/_api_docs.html" %} </q-list>
<q-list>{% include "invoices/_api_docs.html" %}</q-list>
</q-card-section>
</q-card>
</div>

<q-dialog v-model="formDialog.show" position="top" @hide="closeFormDialog">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px">
<q-card class="q-pa-lg q-pt-xl" style="width: 500px;">
<q-form @submit="saveInvoice" class="q-gutter-md">
<q-select
filled
Expand Down Expand Up @@ -208,19 +216,21 @@ <h6 class="text-subtitle1 q-my-none">
:disable="formDialog.data.wallet == null || formDialog.data.currency == null"
type="submit"
v-if="typeof formDialog.data.id == 'undefined'"
>Create Invoice</q-btn
>
Create Invoice
</q-btn>
<q-btn
unelevated
color="primary"
:disable="formDialog.data.wallet == null || formDialog.data.currency == null"
type="submit"
v-if="typeof formDialog.data.id !== 'undefined'"
>Save Invoice</q-btn
>
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
>Cancel</q-btn
>
Save Invoice
</q-btn>
<q-btn v-close-popup flat color="grey" class="q-ml-auto">
Cancel
</q-btn>
</div>
</q-form>
</q-card>
Expand All @@ -231,7 +241,7 @@ <h6 class="text-subtitle1 q-my-none">
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
Expand Down Expand Up @@ -421,51 +431,56 @@ <h6 class="text-subtitle1 q-my-none">
'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: {
Expand All @@ -486,7 +501,7 @@ <h6 class="text-subtitle1 q-my-none">
.request('GET', '/invoices/api/v1/invoice/' + invoice_id)
.then(function (response) {
self.formDialog.invoiceItems = response.data.items.map(function (
obj
obj,
) {
return mapInvoiceItems(obj)
})
Expand All @@ -499,7 +514,7 @@ <h6 class="text-subtitle1 q-my-none">
.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) {
Expand All @@ -516,9 +531,10 @@ <h6 class="text-subtitle1 q-my-none">
.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) {
Expand All @@ -534,38 +550,39 @@ <h6 class="text-subtitle1 q-my-none">
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()
}
}
},
})
</script>
{% endblock %}
12 changes: 11 additions & 1 deletion views_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
get_payments_total,
update_invoice_internal,
update_invoice_items,
delete_invoice,
)
from .models import CreateInvoiceData, UpdateInvoiceData

Expand Down Expand Up @@ -66,14 +67,23 @@ 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,
invoice_id: str,
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
Expand Down

0 comments on commit 913f8b6

Please sign in to comment.