From 458616401646cec186746670626e2db73e3ab522 Mon Sep 17 00:00:00 2001 From: Tiago Vasconcelos Date: Tue, 4 Jul 2023 08:17:31 +0100 Subject: [PATCH 01/65] Fix updating event (#9) * passing a copy of original data to dialog data --- templates/events/index.html | 16 +++------------- templates/events/ticket.html | 10 +++++++--- views_api.py | 2 +- 3 files changed, 11 insertions(+), 17 deletions(-) diff --git a/templates/events/index.html b/templates/events/index.html index 2125893..57afb19 100644 --- a/templates/events/index.html +++ b/templates/events/index.html @@ -387,9 +387,7 @@ this.g.user.wallets[0].inkey ) .then(function (response) { - console.log(response) self.tickets = response.data.map(function (obj) { - console.log(obj) return mapEvents(obj) }) }) @@ -464,21 +462,13 @@ }, updateformDialog: function (formId) { var link = _.findWhere(this.events, {id: formId}) - console.log(link.id) - this.formDialog.data.id = link.id - this.formDialog.data.wallet = link.wallet - this.formDialog.data.name = link.name - this.formDialog.data.info = link.info - this.formDialog.data.closing_date = link.closing_date - this.formDialog.data.event_start_date = link.event_start_date - this.formDialog.data.event_end_date = link.event_end_date - this.formDialog.data.amount_tickets = link.amount_tickets - this.formDialog.data.price_per_ticket = link.price_per_ticket + + this.formDialog.data = {...link} + this.formDialog.show = true }, updateEvent: function (wallet, data) { var self = this - console.log(data) LNbits.api .request( diff --git a/templates/events/ticket.html b/templates/events/ticket.html index e8fcd79..e2f4166 100644 --- a/templates/events/ticket.html +++ b/templates/events/ticket.html @@ -12,11 +12,15 @@
- +
- Print + Print @@ -38,4 +42,4 @@ } }) -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/views_api.py b/views_api.py index cad2cb6..c0d9809 100644 --- a/views_api.py +++ b/views_api.py @@ -3,7 +3,7 @@ from http import HTTPStatus from fastapi import Depends, Query from starlette.exceptions import HTTPException -from lnbits.core.crud import get_user, get_standalone_payment +from lnbits.core.crud import get_standalone_payment, get_user from lnbits.core.services import create_invoice from lnbits.decorators import WalletTypeInfo, get_key_type From c8b31d8e3f5dc73e83c62d6207f8c446ea9ffa28 Mon Sep 17 00:00:00 2001 From: Tiago Vasconcelos Date: Fri, 18 Aug 2023 07:17:29 +0100 Subject: [PATCH 02/65] [FEAT] add timestamp on register (#15) * add timestamp on register --- README.md | 1 + config.json | 8 ++++---- crud.py | 3 ++- manifest.json | 14 +++++++------- migrations.py | 11 +++++++++-- models.py | 2 ++ views_api.py | 9 ++++++++- 7 files changed, 33 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index c55b8b2..ebd7194 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ # Events - [LNbits](https://github.com/lnbits/lnbits) extension + For more about LNBits extension check [this tutorial](https://github.com/lnbits/lnbits/wiki/LNbits-Extensions) ## Sell tickets for events and use the built-in scanner for registering attendants diff --git a/config.json b/config.json index a62bcc4..bdc8ba6 100644 --- a/config.json +++ b/config.json @@ -1,6 +1,6 @@ { - "name": "Events", - "short_description": "Sell and register event tickets", - "tile": "/events/static/image/events.png", - "contributors": ["benarc"] + "name": "Events", + "short_description": "Sell and register event tickets", + "tile": "/events/static/image/events.png", + "contributors": ["benarc"] } diff --git a/crud.py b/crud.py index fc3de9d..00c7b72 100644 --- a/crud.py +++ b/crud.py @@ -135,7 +135,8 @@ async def get_event_tickets(event_id: str, wallet_id: str) -> List[Ticket]: async def reg_ticket(ticket_id: str) -> List[Ticket]: await db.execute( - "UPDATE events.ticket SET registered = ? WHERE id = ?", (True, ticket_id) + f"UPDATE events.ticket SET registered = ?, reg_timestamp = {db.timestamp_now} WHERE id = ?", + (True, ticket_id), ) ticket = await db.fetchone("SELECT * FROM events.ticket WHERE id = ?", (ticket_id,)) rows = await db.fetchall( diff --git a/manifest.json b/manifest.json index 13726a7..cee435b 100644 --- a/manifest.json +++ b/manifest.json @@ -1,9 +1,9 @@ { - "repos": [ - { - "id": "events", - "organisation": "lnbits", - "repository": "events" - } - ] + "repos": [ + { + "id": "events", + "organisation": "lnbits", + "repository": "events" + } + ] } diff --git a/migrations.py b/migrations.py index 5b9d53b..77424eb 100644 --- a/migrations.py +++ b/migrations.py @@ -1,5 +1,4 @@ async def m001_initial(db): - await db.execute( """ CREATE TABLE events.events ( @@ -38,7 +37,6 @@ async def m001_initial(db): async def m002_changed(db): - await db.execute( """ CREATE TABLE events.ticket ( @@ -81,3 +79,12 @@ async def m002_changed(db): (row[0], row[1], row[2], row[3], row[4], row[5], True), ) await db.execute("DROP TABLE events.tickets") + + +async def m003_add_register_timestamp(db): + """ + Add a column to register the timestamp of ticket register + """ + await db.execute( + "ALTER TABLE events.ticket ADD COLUMN reg_timestamp TIMESTAMP;" + ) # NULL means not registered, or old ticket diff --git a/models.py b/models.py index b9bf7c0..62cba60 100644 --- a/models.py +++ b/models.py @@ -1,5 +1,6 @@ from fastapi import Query from pydantic import BaseModel +from typing import Optional class CreateEvent(BaseModel): @@ -39,5 +40,6 @@ class Ticket(BaseModel): name: str email: str registered: bool + reg_timestamp: Optional[int] paid: bool time: int diff --git a/views_api.py b/views_api.py index c0d9809..de53202 100644 --- a/views_api.py +++ b/views_api.py @@ -109,7 +109,13 @@ async def api_ticket_make_ticket(event_id, name, email): memo=f"{event_id}", extra={"tag": "events", "name": name, "email": email}, ) - await create_ticket(payment_hash=payment_hash, wallet=event.wallet, event=event.id, name=name, email=email) + await create_ticket( + payment_hash=payment_hash, + wallet=event.wallet, + event=event.id, + name=name, + email=email, + ) except Exception as e: raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) return {"payment_hash": payment_hash, "payment_request": payment_request} @@ -167,6 +173,7 @@ async def api_event_tickets(wallet_id, event_id): @events_ext.get("/api/v1/register/ticket/{ticket_id}") async def api_event_register_ticket(ticket_id): ticket = await get_ticket(ticket_id) + if not ticket: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="Ticket does not exist." From 00f552c7510eef5cd7e5cb13bb87af3914029bfd Mon Sep 17 00:00:00 2001 From: Tiago Vasconcelos Date: Fri, 18 Aug 2023 07:18:44 +0100 Subject: [PATCH 03/65] Fix ticket create (#13) * don't set ticket as paid on create * use crud fn in tasks.py * create ticket is unpaid by default --- crud.py | 52 +++++++++++++++++++++++------------ tasks.py | 9 ++---- templates/events/display.html | 1 - views_api.py | 3 ++ 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/crud.py b/crud.py index 00c7b72..f347936 100644 --- a/crud.py +++ b/crud.py @@ -9,34 +9,52 @@ from .models import CreateEvent, Event, Ticket async def create_ticket( - payment_hash: str, wallet: str, event: str, name: str, email: str -) -> Ticket: + payment_hash: str, wallet: str, event: str, name: str, email: str) -> Ticket: await db.execute( """ INSERT INTO events.ticket (id, wallet, event, name, email, registered, paid) VALUES (?, ?, ?, ?, ?, ?, ?) """, - (payment_hash, wallet, event, name, email, False, True), - ) - - # UPDATE EVENT DATA ON SOLD TICKET - eventdata = await get_event(event) - assert eventdata, "Couldn't get event from ticket being paid" - sold = eventdata.sold + 1 - amount_tickets = eventdata.amount_tickets - 1 - await db.execute( - """ - UPDATE events.events - SET sold = ?, amount_tickets = ? - WHERE id = ? - """, - (sold, amount_tickets, event), + (payment_hash, wallet, event, name, email, False, False), ) ticket = await get_ticket(payment_hash) assert ticket, "Newly created ticket couldn't be retrieved" return ticket +async def set_ticket_paid(payment_hash: str) -> Ticket: + ticket = await get_ticket(payment_hash) + assert ticket, "Ticket couldn't be retrieved" + + await db.execute( + """ + UPDATE events.ticket + SET paid = ? + WHERE id = ? + """, + (True, ticket.id), + ) + + await update_event_sold(ticket.event) + + return ticket + +async def update_event_sold(event_id: str): + event = await get_event(event_id) + assert event, "Couldn't get event from ticket being paid" + sold = event.sold + 1 + amount_tickets = event.amount_tickets - 1 + await db.execute( + """ + UPDATE events.events + SET sold = ?, amount_tickets = ? + WHERE id = ? + """, + (sold, amount_tickets, event_id), + ) + + return + async def get_ticket(payment_hash: str) -> Optional[Ticket]: row = await db.fetchone("SELECT * FROM events.ticket WHERE id = ?", (payment_hash,)) diff --git a/tasks.py b/tasks.py index 68a3908..d2ed732 100644 --- a/tasks.py +++ b/tasks.py @@ -4,8 +4,7 @@ from lnbits.core.models import Payment from lnbits.helpers import get_current_extension_name from lnbits.tasks import register_invoice_listener -from .models import CreateTicket -from .views_api import api_ticket_send_ticket +from .crud import set_ticket_paid async def wait_for_paid_invoices(): @@ -25,8 +24,6 @@ async def on_invoice_paid(payment: Payment) -> None: and payment.extra.get("name") and payment.extra.get("email") ): - await api_ticket_send_ticket( - payment.memo, - payment.payment_hash, - ) + + await set_ticket_paid(payment.payment_hash) return diff --git a/templates/events/display.html b/templates/events/display.html index 45c2aca..74fd871 100644 --- a/templates/events/display.html +++ b/templates/events/display.html @@ -86,7 +86,6 @@ {% endblock %} {% block scripts %} -{% endblock %} +{% endblock %} \ No newline at end of file diff --git a/templates/events/index.html b/templates/events/index.html index 57afb19..9bd1e4c 100644 --- a/templates/events/index.html +++ b/templates/events/index.html @@ -4,9 +4,7 @@
- New Event + New Event @@ -17,19 +15,11 @@
Events
- Export to CSV + Export to CSV
- + {% raw %}