diff --git a/README.md b/README.md index fb8ebe2..a14bdef 100644 --- a/README.md +++ b/README.md @@ -102,3 +102,12 @@ On the regular TPoS you can also add value to a total. Enter a value and click t ![atm withdraw](https://i.imgur.com/rYXtn93.png) 6. After successful withdraw, the green check will show and TPOS exists ATM mode\ ![atm success](https://i.imgur.com/FaHltvW.png) + +## Tax settings + +For tax settings, by default tax is included in the price. You'll need to set a default tax rate in percentage (ex: 13). If items have a tax value, as some products may have different tax (VAT usually), it overides the default value. + +- **Tax Exclusive means tax is applied on top of the unit price.** +- **Tax Inclusive means the unit price includes tax.** + +When using the normal keypad PoS, the default tax value is used, and tax value is always included in the value. diff --git a/crud.py b/crud.py index baa5ed7..12ef7c3 100644 --- a/crud.py +++ b/crud.py @@ -1,10 +1,11 @@ from typing import List, Optional, Union +from loguru import logger + from lnbits.helpers import urlsafe_short_hash from . import db -from .models import CreateTposData, TPoS, TPoSClean, LNURLCharge -from loguru import logger +from .models import CreateTposData, LNURLCharge, TPoS, TPoSClean async def get_current_timestamp(): diff --git a/migrations.py b/migrations.py index 60ff7f0..3936daa 100644 --- a/migrations.py +++ b/migrations.py @@ -78,7 +78,7 @@ async def m005_initial(db): Initial withdraws table. """ await db.execute( - f""" + """ CREATE TABLE tpos.withdraws ( id TEXT PRIMARY KEY, tpos_id TEXT NOT NULL, @@ -108,10 +108,23 @@ async def m007_atm_premium(db): await db.execute("ALTER TABLE tpos.pos ADD COLUMN withdrawpremium FLOAT;") - async def m008_atm_time_option_and_pin_toggle(db): """ Add a time mins/sec and pin toggle """ - await db.execute("ALTER TABLE tpos.pos ADD COLUMN withdrawtimeopt TEXT DEFAULT 'mins';") - await db.execute("ALTER TABLE tpos.pos ADD COLUMN withdrawpindisabled BOOL NOT NULL DEFAULT false;") + await db.execute( + "ALTER TABLE tpos.pos ADD COLUMN withdrawtimeopt TEXT DEFAULT 'mins';" + ) + await db.execute( + "ALTER TABLE tpos.pos ADD COLUMN withdrawpindisabled BOOL NOT NULL DEFAULT false;" + ) + + +async def m009_tax_inclusive(db): + """ + Add tax_inclusive column + """ + await db.execute( + "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;") diff --git a/models.py b/models.py index c41fc83..79d2379 100644 --- a/models.py +++ b/models.py @@ -1,11 +1,11 @@ from sqlite3 import Row -from typing import Optional, Any, List +from typing import List, Optional from fastapi import Request from lnurl import Lnurl, LnurlWithdrawResponse from lnurl import encode as lnurl_encode -from lnurl.models import ClearnetUrl, MilliSatoshi -from pydantic import BaseModel, Field +from lnurl.types import ClearnetUrl, MilliSatoshi +from pydantic import BaseModel, Field, validator class CreateTposData(BaseModel): @@ -22,32 +22,8 @@ class CreateTposData(BaseModel): withdrawbtwn: int = Field(10, ge=1) withdrawpremium: float = Field(None) withdrawpindisabled: bool = Field(False) - - -class TPoS(BaseModel): - id: str - wallet: str - name: str - currency: str - tip_options: Optional[str] - tip_wallet: Optional[str] - withdrawlimit: Optional[int] - withdrawpin: Optional[int] - withdrawamt: int - withdrawtime: int - withdrawtimeopt: Optional[str] - withdrawbtwn: int - withdrawpremium: Optional[float] - withdrawpindisabled: Optional[bool] - items: Optional[str] - - @classmethod - def from_row(cls, row: Row) -> "TPoS": - return cls(**dict(row)) - - @property - def withdrawamtposs(self) -> int: - return self.withdrawlimit - self.withdrawamt if self.withdrawlimit else 0 + tax_inclusive: bool = Field(True) + tax_default: float = Field(None) class TPoSClean(BaseModel): @@ -63,6 +39,8 @@ class TPoSClean(BaseModel): withdrawpremium: Optional[float] withdrawpindisabled: Optional[bool] items: Optional[str] + tax_inclusive: bool + tax_default: Optional[float] @classmethod def from_row(cls, row: Row) -> "TPoSClean": @@ -73,6 +51,12 @@ def withdrawamtposs(self) -> int: return self.withdrawlimit - self.withdrawamt if self.withdrawlimit else 0 +class TPoS(TPoSClean, BaseModel): + wallet: str + tip_wallet: Optional[str] + withdrawpin: Optional[int] + + class LNURLCharge(BaseModel): id: str tpos_id: str @@ -120,10 +104,14 @@ class Item(BaseModel): price: float title: str description: Optional[str] - tax: Optional[float] = 0.0 + tax: Optional[float] = Field(0, ge=0.0) disabled: bool = False categories: Optional[List[str]] = [] + @validator("tax", pre=True, always=True) + def set_default_tax(cls, v): + return v or 0 + class CreateUpdateItemData(BaseModel): items: List[Item] diff --git a/static/components/item-list/item-list.html b/static/components/item-list/item-list.html new file mode 100644 index 0000000..cb153cb --- /dev/null +++ b/static/components/item-list/item-list.html @@ -0,0 +1,53 @@ +
+ {{ tpos.name }}
{{ request.url }}
+
- ${item.formattedPrice}
+
+ ${item.formattedPrice}
+
|
|
- {{ tpos.name }}
{{ request.url }}
-