diff --git a/crud.py b/crud.py index 9fe889b..70a54fb 100644 --- a/crud.py +++ b/crud.py @@ -22,14 +22,15 @@ async def create_tpos(data: CreateTposData) -> Tpos: tpos_id = urlsafe_short_hash() tpos = Tpos(id=tpos_id, **data.dict()) await db.execute( - insert_query("tpos.pos", data), - data.dict(), + insert_query("tpos.pos", tpos), + tpos.dict(), ) return tpos async def get_tpos(tpos_id: str) -> Optional[Tpos]: row = await db.fetchone("SELECT * FROM tpos.pos WHERE id = :id", {"id": tpos_id}) + print(row) return Tpos(**row) if row else None @@ -39,13 +40,15 @@ async def start_lnurlcharge(tpos_id: str): now = await get_current_timestamp() withdraw_time_seconds = ( - tpos.withdrawbtwn * 60 if tpos.withdrawtimeopt != "secs" else tpos.withdrawbtwn + tpos.withdraw_between * 60 + if tpos.withdraw_time_option != "secs" + else tpos.withdraw_between ) assert ( - now - tpos.withdrawtime > withdraw_time_seconds + now - tpos.withdraw_time > withdraw_time_seconds ), f""" Last withdraw was made too recently, please try again in - {int(withdraw_time_seconds - (now - tpos.withdrawtime))} secs + {int(withdraw_time_seconds - (now - tpos.withdraw_time))} secs """ token = urlsafe_short_hash() @@ -87,9 +90,11 @@ async def get_clean_tpos(tpos_id: str) -> Optional[TposClean]: async def update_tpos_withdraw(data: Tpos, tpos_id: str) -> Tpos: # Calculate the time between withdrawals in seconds now = await get_current_timestamp() - time_elapsed = now - data.withdrawtime + time_elapsed = now - data.withdraw_time withdraw_time_seconds = ( - data.withdrawbtwn * 60 if data.withdrawtimeopt != "secs" else data.withdrawbtwn + data.withdraw_between * 60 + if data.withdraw_time_option != "secs" + else data.withdraw_between ) logger.debug(f"Time between: {time_elapsed} seconds") diff --git a/migrations.py b/migrations.py index 3726220..fe15899 100644 --- a/migrations.py +++ b/migrations.py @@ -129,3 +129,28 @@ async def m009_tax_inclusive(db): "ALTER TABLE tpos.pos ADD COLUMN tax_inclusive BOOL NOT NULL DEFAULT true;" ) await db.execute("ALTER TABLE tpos.pos ADD COLUMN tax_default FLOAT DEFAULT 0;") + + +async def m010_rename_tpos_withdraw_columns(db): + """ + Add rename tpos withdraw columns + """ + await db.execute( + """ + CREATE TABLE tpos.pos_backup AS + SELECT + id, name, currency, items, wallet, tax_inclusive, + tax_default, tip_wallet, tip_options, + withdrawtime AS withdraw_time, + withdrawbtwn AS withdraw_between, + withdrawlimit AS withdraw_limit, + withdrawamt AS withdraw_amount, + withdrawtimeopt AS withdraw_time_option, + withdrawpremium AS withdraw_premium, + withdrawpindisabled AS withdraw_pin_disabled, + withdrawpin AS withdraw_pin + FROM tpos.pos + """ + ) + await db.execute("DROP TABLE tpos.pos") + await db.execute("ALTER TABLE tpos.pos_backup RENAME TO pos") diff --git a/models.py b/models.py index 00298ca..9dfd0fd 100644 --- a/models.py +++ b/models.py @@ -10,45 +10,47 @@ class CreateTposData(BaseModel): wallet: Optional[str] name: Optional[str] currency: Optional[str] - tip_options: str = Field("[]") - tip_wallet: str = Field("") - withdrawlimit: int = Field(None, ge=1) - withdrawpin: int = Field(None, ge=1) - withdrawamt: int = Field(None, ge=0) - withdrawtime: int = Field(0) - withdrawtimeopt: Optional[str] - withdrawbtwn: int = Field(10, ge=1) - withdrawpremium: float = Field(None) - withdrawpindisabled: bool = Field(False) tax_inclusive: bool = Field(True) tax_default: float = Field(None) + tip_options: str = Field("[]") + tip_wallet: str = Field("") + withdraw_time: int = Field(0) + withdraw_between: int = Field(10, ge=1) + withdraw_limit: Optional[int] = Field(None, ge=1) + withdraw_pin: Optional[int] = Field(None, ge=1) + withdraw_amount: Optional[int] = Field(None, ge=0) + withdraw_time_option: Optional[str] = Field(None) + withdraw_premium: Optional[float] = Field(None) + withdraw_pin_disabled: bool = Field(False) class TposClean(BaseModel): id: str name: str currency: str - tip_options: Optional[str] - withdrawlimit: Optional[int] - withdrawamt: int - withdrawtime: int - withdrawtimeopt: Optional[str] - withdrawbtwn: int - withdrawpremium: Optional[float] - withdrawpindisabled: Optional[bool] - items: Optional[str] tax_inclusive: bool - tax_default: Optional[float] + tax_default: Optional[float] = None + withdraw_time: int + withdraw_between: int + withdraw_limit: Optional[int] = None + withdraw_amount: Optional[int] = None + withdraw_time_option: Optional[str] = None + withdraw_premium: Optional[float] = None + withdraw_pin_disabled: Optional[bool] = None + items: Optional[str] = None + tip_options: Optional[str] = None @property - def withdrawamtposs(self) -> int: - return self.withdrawlimit - self.withdrawamt if self.withdrawlimit else 0 + def withdraw_maximum(self) -> int: + if not self.withdraw_amount or not self.withdraw_limit: + return 0 + return self.withdraw_limit - self.withdraw_amount class Tpos(TposClean, BaseModel): wallet: str - tip_wallet: Optional[str] - withdrawpin: Optional[int] + tip_wallet: Optional[str] = None + withdraw_pin: Optional[int] = None class LnurlCharge(BaseModel): diff --git a/static/js/tpos.js b/static/js/tpos.js index 8ade174..f659a47 100644 --- a/static/js/tpos.js +++ b/static/js/tpos.js @@ -11,9 +11,9 @@ const tposJS = async () => { return { tposId: tpos.id, currency: tpos.currency, - withdrawamtposs: tpos.withdrawamtposs, - atmPremium: tpos.withdrawpremium / 100, - withdrawpinopen: withdrawpinopen, + atmPremium: tpos.withdraw_premium / 100, + withdraw_maximum: withdraw_maximum, + withdraw_pin_open: withdraw_pin_open, tip_options: null, exchangeRate: null, stack: [], @@ -262,12 +262,12 @@ const tposJS = async () => { if (this.atmPremium > 0) { this.exchangeRate = this.exchangeRate / (1 + this.atmPremium) } - if (this.withdrawpinopen != 0) { - this.atmPin = this.withdrawpinopen + if (this.withdraw_pin_open != 0) { + this.atmPin = this.withdraw_pin_open this.atmSubmit() return } - if (this.withdrawamtposs > 0) { + if (this.withdraw_maximum > 0) { this.atmBox = true } }, @@ -289,7 +289,7 @@ const tposJS = async () => { atmGetWithdraw: function () { self = this var dialog = this.invoiceDialog - if (this.sat > this.withdrawamtposs) { + if (this.sat > this.withdraw_maximum) { this.$q.notify({ type: 'negative', message: 'Amount exceeds the maximum withdrawal limit.' @@ -710,7 +710,7 @@ const tposJS = async () => { created: function () { var getRates = this.getRates getRates() - this.pinDisabled = tpos.withdrawpindisabled + this.pinDisabled = tpos.withdraw_pin_disabled this.taxInclusive = tpos.tax_inclusive this.taxDefault = tpos.tax_default diff --git a/templates/tpos/index.html b/templates/tpos/index.html index ea47174..99f9022 100644 --- a/templates/tpos/index.html +++ b/templates/tpos/index.html @@ -7,7 +7,7 @@ New TPoS @@ -123,16 +123,16 @@
TPoS
${props.row.tip_options} N/A - - ${props.row.withdrawpin} + + ${props.row.withdraw_pin} N/A - - ${props.row.withdrawlimit} + + ${props.row.withdraw_limit} N/A - - ${props.row.withdrawpremium}% + + ${props.row.withdraw_premium}% 0 @@ -140,7 +140,7 @@
TPoS
flat dense size="xs" - @click="updateTPosForm(props.row.id)" + @click="updateTposForm(props.row.id)" icon="edit" color="blue" > @@ -150,7 +150,7 @@
TPoS
flat dense size="xs" - @click="deleteTPoS(props.row.id)" + @click="deleteTpos(props.row.id)" icon="cancel" color="pink" > @@ -323,7 +323,7 @@
{{SITE_TITLE}} TPoS extension
- + {{SITE_TITLE}} TPoS extension @@ -404,15 +404,15 @@
{{SITE_TITLE}} TPoS extension
@@ -424,7 +424,7 @@
{{SITE_TITLE}} TPoS extension
{{SITE_TITLE}} TPoS extension
@@ -443,7 +443,7 @@
{{SITE_TITLE}} TPoS extension
{{SITE_TITLE}} TPoS extension
@@ -650,7 +650,7 @@
{% endblock %} {% block scripts %} {{ window_vars(user) }} diff --git a/views.py b/views.py index ccfea47..7f9a380 100644 --- a/views.py +++ b/views.py @@ -1,15 +1,14 @@ from http import HTTPStatus -from fastapi import APIRouter, Depends, Request -from fastapi.templating import Jinja2Templates +from fastapi import APIRouter, Depends, HTTPException, Request from lnbits.core.models import User from lnbits.decorators import check_user_exists from lnbits.helpers import template_renderer from lnbits.settings import settings -from starlette.exceptions import HTTPException from starlette.responses import HTMLResponse from .crud import get_clean_tpos, get_tpos +from .models import TposClean tpos_generic_router = APIRouter() @@ -18,9 +17,6 @@ def tpos_renderer(): return template_renderer(["tpos/templates"]) -templates = Jinja2Templates(directory="templates") - - @tpos_generic_router.get("/", response_class=HTMLResponse) async def index(request: Request, user: User = Depends(check_user_exists)): return tpos_renderer().TemplateResponse( @@ -30,26 +26,20 @@ async def index(request: Request, user: User = Depends(check_user_exists)): @tpos_generic_router.get("/{tpos_id}") async def tpos(request: Request, tpos_id): - tpos = await get_clean_tpos(tpos_id) + tpos = await get_tpos(tpos_id) if not tpos: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist." ) - withdrawpinopen = 0 - if tpos.withdrawpindisabled: - tpos_dirty = await get_tpos(tpos_id) - if not tpos_dirty: - raise HTTPException( - status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist." - ) - withdrawpinopen = tpos_dirty.withdrawpin or 0 + withdraw_pin_open = tpos.withdraw_pin or 0 + tpos_clean = TposClean(**tpos.dict()) response = tpos_renderer().TemplateResponse( "tpos/tpos.html", { "request": request, - "tpos": tpos, - "withdrawpinopen": withdrawpinopen, - "withdrawamtposs": tpos.withdrawamtposs, + "tpos": tpos_clean, + "withdraw_pin_open": withdraw_pin_open, + "withdraw_maximum": tpos.withdraw_maximum, "web_manifest": f"/tpos/manifest/{tpos_id}.webmanifest", }, ) diff --git a/views_api.py b/views_api.py index 15b183d..c8cc335 100644 --- a/views_api.py +++ b/views_api.py @@ -253,7 +253,7 @@ async def api_tpos_atm_pin_check(tpos_id: str, atmpin: int): raise HTTPException( status_code=HTTPStatus.NOT_FOUND, detail="TPoS does not exist." ) - if int(tpos.withdrawpin or 0) != int(atmpin): + if int(tpos.withdraw_pin or 0) != int(atmpin): raise HTTPException(status_code=HTTPStatus.NOT_FOUND, detail="Wrong PIN.") token = await start_lnurlcharge(tpos_id) return token diff --git a/views_lnurl.py b/views_lnurl.py index 8ca0c75..a8c0b03 100644 --- a/views_lnurl.py +++ b/views_lnurl.py @@ -60,12 +60,12 @@ async def lnurl_params( "reason": f"TPoS {lnurlcharge.tpos_id} not found on this server", } - if amount > tpos.withdrawamtposs: + if amount > tpos.withdraw_maximum: return { "status": "ERROR", "reason": ( f"Amount requested {amount} is too high, " - f"maximum withdrawable is {tpos.withdrawamtposs}" + f"maximum withdrawable is {tpos.withdraw_maximum}" ), } @@ -111,10 +111,10 @@ async def lnurl_callback( assert tpos, f"TPoS with ID {lnurlcharge.tpos_id} not found" assert ( - lnurlcharge.amount < tpos.withdrawamtposs + lnurlcharge.amount < tpos.withdraw_maximum ), f""" Amount requested {lnurlcharge.amount} is too high, - maximum withdrawable is {tpos.withdrawamtposs} + maximum withdrawable is {tpos.withdraw_maximum} """ await update_lnurlcharge( @@ -126,7 +126,8 @@ async def lnurl_callback( ) ) - tpos.withdrawamt = int(tpos.withdrawamt) + int(lnurlcharge.amount) + assert tpos.withdraw_amount, f"TPoS {lnurlcharge.tpos_id} has no withdraw_amount" + tpos.withdraw_amount = int(tpos.withdraw_amount) + int(lnurlcharge.amount) logger.debug(f"Payment request: {pr}") await update_tpos_withdraw(data=tpos, tpos_id=lnurlcharge.tpos_id) logger.debug(f"Amount to withdraw: {int(lnurlcharge.amount)}")