Ported:
Guest Book Save bill Update bill Show bill Fix: Tax details was sending the rate multiplied by 100 but not dividing it on save/update Feature: Updated the auth service to check local storage for the latest user token
This commit is contained in:
parent
b19d8cc030
commit
6c06271315
|
@ -3,6 +3,7 @@ from fastapi import FastAPI
|
|||
from starlette.middleware.sessions import SessionMiddleware
|
||||
|
||||
from .routers import (
|
||||
guest_book,
|
||||
menu_category,
|
||||
modifier,
|
||||
modifier_category,
|
||||
|
@ -25,6 +26,7 @@ from .routers.reports import (
|
|||
sale_report,
|
||||
tax_report
|
||||
)
|
||||
from .routers.voucher import show, save, update
|
||||
|
||||
from .db.base_class import Base
|
||||
from .core.config import settings
|
||||
|
@ -66,6 +68,11 @@ app.include_router(product_sale_report.router, prefix="/api/product-sale-report"
|
|||
app.include_router(sale_report.router, prefix="/api/sale-report", tags=["reports"])
|
||||
app.include_router(tax_report.router, prefix="/api/tax-report", tags=["reports"])
|
||||
|
||||
app.include_router(guest_book.router, prefix="/api/guest-book", tags=["guest-book"])
|
||||
app.include_router(show.router, prefix="/api/voucher", tags=["voucher"])
|
||||
app.include_router(save.router, prefix="/api/voucher", tags=["voucher"])
|
||||
app.include_router(update.router, prefix="/api/voucher", tags=["voucher"])
|
||||
|
||||
# app.include_router(issue_grid.router, prefix="/api/issue-grid", tags=["vouchers"])
|
||||
# app.include_router(batch.router, prefix="/api/batch", tags=["vouchers"])
|
||||
# app.include_router(journal.router, prefix="/api/journal", tags=["vouchers"])
|
||||
|
|
|
@ -9,7 +9,7 @@ from ..schemas.auth import UserToken
|
|||
import barker.schemas.master as schemas
|
||||
from ..core.security import get_current_active_user as get_user
|
||||
from ..db.session import SessionLocal
|
||||
from ..models.master import SaleCategory, Printer
|
||||
from ..models.master import Printer
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
@ -87,7 +87,7 @@ def delete(
|
|||
|
||||
@router.get("")
|
||||
def show_blank(
|
||||
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=[""]),
|
||||
db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["printers"]),
|
||||
):
|
||||
return printer_info(None)
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import uuid
|
||||
from decimal import Decimal
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, HTTPException, status, Depends, Security
|
||||
|
@ -28,7 +29,7 @@ def save(
|
|||
data: schemas.TaxIn, db: Session = Depends(get_db), user: UserToken = Security(get_user, scopes=["taxes"]),
|
||||
):
|
||||
try:
|
||||
item = Tax(name=data.name, rate=data.rate)
|
||||
item = Tax(name=data.name, rate=round(data.rate / Decimal(100), 4))
|
||||
db.add(item)
|
||||
db.commit()
|
||||
return tax_info(item)
|
||||
|
@ -56,7 +57,7 @@ def update(
|
|||
status_code=status.HTTP_423_LOCKED, detail=f"{item.name} is a fixture and cannot be edited or deleted.",
|
||||
)
|
||||
item.name = data.name
|
||||
item.rate = data.rate
|
||||
item.rate = round(data.rate / Decimal(100), 4)
|
||||
db.commit()
|
||||
return tax_info(item)
|
||||
except SQLAlchemyError as e:
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import uuid
|
||||
|
||||
from fastapi import HTTPException
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.orm import Session
|
||||
from starlette import status
|
||||
|
||||
from barker.models import (
|
||||
VoucherType,
|
||||
|
@ -18,14 +21,16 @@ def get_tax(tax, voucher_type):
|
|||
elif voucher_type in [VoucherType.KOT, VoucherType.REGULAR_BILL]:
|
||||
return tax
|
||||
else:
|
||||
raise ValidationError("Unexpected Voucher Type")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Unexpected Voucher Type",
|
||||
)
|
||||
|
||||
|
||||
def get_bill_id(voucher_type, dbsession):
|
||||
def get_bill_id(voucher_type, db):
|
||||
if voucher_type == VoucherType.KOT:
|
||||
return None
|
||||
bill_id = (
|
||||
dbsession.query(func.coalesce(func.max(Voucher.bill_id), 0) + 1)
|
||||
db.query(func.coalesce(func.max(Voucher.bill_id), 0) + 1)
|
||||
.filter(Voucher.voucher_type == voucher_type.value)
|
||||
.scalar()
|
||||
)
|
||||
|
@ -34,46 +39,55 @@ def get_bill_id(voucher_type, dbsession):
|
|||
return bill_id
|
||||
|
||||
|
||||
def do_update_table(item, guest_book, dbsession):
|
||||
status = "running" if item.voucher_type == VoucherType.KOT else "printed"
|
||||
def do_update_table(item, guest_book, db):
|
||||
status_ = "running" if item.voucher_type == VoucherType.KOT else "printed"
|
||||
if item.status is None:
|
||||
item.status = Overview(
|
||||
voucher_id=item.id,
|
||||
food_table_id=item.food_table_id,
|
||||
guest_book_id=guest_book.id if guest_book is not None else None,
|
||||
status=status,
|
||||
status=status_,
|
||||
)
|
||||
dbsession.add(item.status)
|
||||
db.add(item.status)
|
||||
else:
|
||||
item.status.status = status
|
||||
item.status.status = status_
|
||||
|
||||
|
||||
def check_permissions(item, voucher_type, permissions):
|
||||
if voucher_type == VoucherType.KOT and "Print Kot" not in permissions:
|
||||
raise ValidationFailure("You are not allowed to print a kot")
|
||||
|
||||
if voucher_type != VoucherType.KOT and "Print Bill" not in permissions:
|
||||
raise ValidationFailure("You are not allowed to print bill")
|
||||
if voucher_type == VoucherType.KOT and "print-kot" not in permissions:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to print a kot",
|
||||
)
|
||||
if voucher_type != VoucherType.KOT and "print-bill" not in permissions:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to print bill",
|
||||
)
|
||||
|
||||
if item is None:
|
||||
return
|
||||
if item.voucher_type != VoucherType.KOT and "Edit Printed Bill" not in permissions:
|
||||
raise ValidationFailure("You are not allowed to edit a printed bill")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN, detail="You are not allowed to edit a printed bill",
|
||||
)
|
||||
|
||||
if item.voucher_type != VoucherType.KOT and voucher_type == VoucherType.KOT:
|
||||
raise ValidationFailure("This Bill is already printed\nCannot add a Kot to it.")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN, detail="This Bill is already printed\nCannot add a Kot to it.",
|
||||
)
|
||||
|
||||
if item.voucher_type == VoucherType.VOID:
|
||||
raise ValidationFailure("This Bill is already void.\nReason: {0}".format(item.reason))
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_403_FORBIDDEN, detail=f"This Bill is already void.\nReason: {item.reason}",
|
||||
)
|
||||
|
||||
|
||||
def get_guest_book(guest_book_id, dbsession):
|
||||
if guest_book_id is None:
|
||||
return guest_book_id
|
||||
return dbsession.query(GuestBook).filter(GuestBook.id == uuid.UUID(guest_book_id)).first()
|
||||
def get_guest_book(id_: uuid.UUID, db: Session):
|
||||
if id_ is None:
|
||||
return id_
|
||||
return db.query(GuestBook).filter(GuestBook.id == id_).first()
|
||||
|
||||
|
||||
def do_update_settlements(voucher, dbsession):
|
||||
def do_update_settlements(voucher, db: Session):
|
||||
settlements = []
|
||||
total_amount = voucher.amount
|
||||
settlements.append({"id": SettleOption.AMOUNT(), "amount": -total_amount})
|
||||
|
@ -91,8 +105,8 @@ def do_update_settlements(voucher, dbsession):
|
|||
else:
|
||||
s = Settlement(voucher.id, settlement_type_id, amount)
|
||||
voucher.settlements.append(s)
|
||||
dbsession.add(s)
|
||||
db.add(s)
|
||||
|
||||
for i in (i for i in voucher.settlements if i.settled not in [x["id"] for x in settlements]):
|
||||
voucher.settlements.remove(i)
|
||||
dbsession.delete(i)
|
||||
db.delete(i)
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
import datetime
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import Optional
|
||||
|
||||
import transaction
|
||||
from pyramid.view import view_config
|
||||
from fastapi import APIRouter, HTTPException, status, Depends, Security
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from barker.models import (
|
||||
Voucher,
|
||||
Kot,
|
||||
Inventory,
|
||||
InventoryModifier,
|
||||
VoucherType,
|
||||
Product,
|
||||
FoodTable,
|
||||
)
|
||||
from barker.models.validation_exception import ValidationError
|
||||
from barker.views.voucher import (
|
||||
from ...schemas.auth import UserToken
|
||||
import barker.schemas.voucher as schemas
|
||||
from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import Voucher, VoucherType, Kot, Product, Inventory, InventoryModifier
|
||||
from ...routers.voucher import (
|
||||
get_tax,
|
||||
do_update_settlements,
|
||||
get_bill_id,
|
||||
|
@ -25,61 +22,88 @@ from barker.views.voucher import (
|
|||
get_guest_book,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@view_config(request_method="POST", route_name="v1_vouchers_new", renderer="json", trans=True)
|
||||
def save(request):
|
||||
json = request.json_body
|
||||
now = datetime.datetime.now()
|
||||
update_table = request.GET["u"] == "true"
|
||||
voucher_type = VoucherType[request.GET["p"]]
|
||||
guest_book = get_guest_book(request.GET.get("g", None), request.dbsession)
|
||||
|
||||
check_permissions(None, voucher_type, request.effective_principals)
|
||||
# Dependency
|
||||
def get_db():
|
||||
try:
|
||||
db = SessionLocal()
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
bill_id = get_bill_id(voucher_type, request.dbsession)
|
||||
kot_id = request.dbsession.query(func.coalesce(func.max(Voucher.kot_id), 0) + 1).scalar()
|
||||
|
||||
item = Voucher(
|
||||
now,
|
||||
guest_book.pax if guest_book is not None else json["pax"],
|
||||
bill_id,
|
||||
kot_id,
|
||||
json["table"]["id"],
|
||||
json["customer"]["id"] if "id" in json["customer"] else None,
|
||||
voucher_type,
|
||||
uuid.UUID(request.authenticated_userid),
|
||||
)
|
||||
request.dbsession.add(item)
|
||||
for k in json["kots"]:
|
||||
code = request.dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar()
|
||||
kot = Kot(item.id, code, item.food_table_id, item.date, item.user_id)
|
||||
item.kots.append(kot)
|
||||
request.dbsession.add(kot)
|
||||
for index, i in enumerate(k["inventories"]):
|
||||
product = request.dbsession.query(Product).filter(Product.id == uuid.UUID(i["product"]["id"])).first()
|
||||
tax_rate = get_tax(product.sale_category.tax.rate, voucher_type)
|
||||
inv = Inventory(
|
||||
kot.id,
|
||||
product.id,
|
||||
round(Decimal(i["quantity"]), 2),
|
||||
product.price,
|
||||
round(Decimal(i["discount"]), 5),
|
||||
i["isHappyHour"],
|
||||
product.sale_category.tax_id,
|
||||
tax_rate,
|
||||
index,
|
||||
@router.post("/save")
|
||||
def save(
|
||||
data: schemas.VoucherIn,
|
||||
u: bool, # Update table?
|
||||
p: str, # Print type
|
||||
g: Optional[uuid.UUID] = None, # Guest book id
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user),
|
||||
):
|
||||
try:
|
||||
now = datetime.now()
|
||||
update_table = u
|
||||
voucher_type = VoucherType[p]
|
||||
guest_book = get_guest_book(g, db)
|
||||
|
||||
check_permissions(None, voucher_type, user.permissions)
|
||||
|
||||
bill_id = get_bill_id(voucher_type, db)
|
||||
kot_id = db.query(func.coalesce(func.max(Voucher.kot_id), 0) + 1).scalar()
|
||||
|
||||
item = Voucher(
|
||||
now,
|
||||
guest_book.pax if guest_book is not None else data.pax,
|
||||
bill_id,
|
||||
kot_id,
|
||||
data.table.id_,
|
||||
data.customer.id_ if data.customer is not None else None,
|
||||
voucher_type,
|
||||
user.id_,
|
||||
)
|
||||
db.add(item)
|
||||
for k in data.kots:
|
||||
code = db.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar()
|
||||
kot = Kot(item.id, code, item.food_table_id, item.date, item.user_id)
|
||||
item.kots.append(kot)
|
||||
db.add(kot)
|
||||
for index, i in enumerate(k.inventories):
|
||||
product = db.query(Product).filter(Product.id == i.product.id_).first()
|
||||
tax_rate = get_tax(product.sale_category.tax.rate, voucher_type)
|
||||
inv = Inventory(
|
||||
kot.id,
|
||||
product.id,
|
||||
round(i.quantity, 2),
|
||||
product.price,
|
||||
round(i.discount, 5),
|
||||
i.is_happy_hour,
|
||||
product.sale_category.tax_id,
|
||||
tax_rate,
|
||||
index,
|
||||
)
|
||||
kot.inventories.append(inv)
|
||||
db.add(inv)
|
||||
for m in i.modifiers:
|
||||
mod = InventoryModifier(None, m.id_, 0)
|
||||
inv.modifiers.append(mod)
|
||||
db.add(mod)
|
||||
do_update_settlements(item, db)
|
||||
if len(item.kots) == 0 or len(item.kots[0].inventories) == 0:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Please add some products",
|
||||
)
|
||||
kot.inventories.append(inv)
|
||||
request.dbsession.add(inv)
|
||||
for m in i["modifiers"]:
|
||||
mod = InventoryModifier(None, uuid.UUID(m["id"]), 0)
|
||||
inv.modifiers.append(mod)
|
||||
request.dbsession.add(mod)
|
||||
do_update_settlements(item, request.dbsession)
|
||||
if len(item.kots) == 0 or len(item.kots[0].inventories) == 0:
|
||||
raise ValidationError("Please add some products!")
|
||||
|
||||
if update_table:
|
||||
do_update_table(item, guest_book, request.dbsession)
|
||||
transaction.commit()
|
||||
return True
|
||||
if update_table:
|
||||
do_update_table(item, guest_book, db)
|
||||
db.commit()
|
||||
except SQLAlchemyError as e:
|
||||
db.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
|
||||
)
|
||||
except Exception:
|
||||
db.rollback()
|
||||
raise
|
||||
|
|
|
@ -1,65 +1,77 @@
|
|||
import re
|
||||
import uuid
|
||||
from typing import Optional
|
||||
|
||||
from pyramid.view import view_config
|
||||
from fastapi import APIRouter, HTTPException, status, Depends, Security
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from barker.exceptions import ValidationFailure
|
||||
from barker.models import Voucher, Overview, FoodTable, GuestBook, VoucherType
|
||||
from ...schemas.auth import UserToken
|
||||
from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import Voucher, Overview, FoodTable, GuestBook, VoucherType
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@view_config(
|
||||
request_method="GET", route_name="v1_vouchers_id", renderer="json", permission="Authenticated",
|
||||
)
|
||||
def show_id(request):
|
||||
id_ = uuid.UUID(request.matchdict["id"])
|
||||
item = request.dbsession.query(Voucher).filter(Voucher.id == id_).first()
|
||||
# Dependency
|
||||
def get_db():
|
||||
try:
|
||||
db = SessionLocal()
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
@router.get("/from-id/{id_}")
|
||||
def from_id(
|
||||
id_: str, db: Session = Depends(get_db), user: UserToken = Security(get_user),
|
||||
):
|
||||
item = db.query(Voucher).filter(Voucher.id == id_).first()
|
||||
return voucher_info(item)
|
||||
|
||||
|
||||
@view_config(
|
||||
request_method="GET", route_name="v1_vouchers_new", request_param="b", renderer="json", permission="Authenticated",
|
||||
)
|
||||
def show(request):
|
||||
bill_id = request.GET["b"]
|
||||
item = request.dbsession.query(Voucher)
|
||||
if re.compile("^\d{2,}-\d{4}$").match(bill_id):
|
||||
item = item.filter(Voucher.bill_id == int(bill_id.replace("-", "")), Voucher.voucher_type.in_([1, 3]),)
|
||||
elif re.compile("^NC-\d+$").match(bill_id):
|
||||
item = item.filter(Voucher.bill_id == int(bill_id.replace("NC-", "")), Voucher.voucher_type == 2,)
|
||||
elif re.compile("^ST-\d+$").match(bill_id):
|
||||
item = item.filter(Voucher.bill_id == int(bill_id.replace("ST-", "")), Voucher.voucher_type == 4,)
|
||||
@router.get("/from-bill/{id_}")
|
||||
def from_bill(
|
||||
id_: str, db: Session = Depends(get_db), user: UserToken = Security(get_user),
|
||||
):
|
||||
item: Voucher = db.query(Voucher)
|
||||
if re.compile(r"^\d{2,}-\d{4}$").match(id_):
|
||||
item = item.filter(Voucher.bill_id == int(id_.replace("-", "")), Voucher.voucher_type.in_([1, 3]),)
|
||||
elif re.compile(r"^NC-\d+$").match(id_):
|
||||
item = item.filter(Voucher.bill_id == int(id_.replace("NC-", "")), Voucher.voucher_type == 2,)
|
||||
elif re.compile(r"^ST-\d+$").match(id_):
|
||||
item = item.filter(Voucher.bill_id == int(id_.replace("ST-", "")), Voucher.voucher_type == 4,)
|
||||
item = item.first()
|
||||
if item is None:
|
||||
return {}
|
||||
return voucher_info(item)
|
||||
|
||||
|
||||
@view_config(
|
||||
request_method="GET", route_name="v1_vouchers_new", request_param="t", renderer="json", permission="Authenticated",
|
||||
)
|
||||
def show_for_table(request):
|
||||
table_id = uuid.UUID(request.GET["t"])
|
||||
voucher_id = request.GET.get("v", None)
|
||||
guest_id = request.GET.get("g", None)
|
||||
if voucher_id is not None:
|
||||
item = (
|
||||
request.dbsession.query(Overview)
|
||||
.filter(Overview.voucher_id == uuid.UUID(voucher_id), Overview.food_table_id == table_id,)
|
||||
.first()
|
||||
)
|
||||
@router.get("/from-table/{id_}")
|
||||
def from_bill(
|
||||
id_: str, # Table ID
|
||||
v: Optional[uuid.UUID] = None, # Voucher ID
|
||||
g: Optional[uuid.UUID] = None, # Guest ID
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user),
|
||||
):
|
||||
if v is not None:
|
||||
item = db.query(Overview).filter(Overview.voucher_id == v, Overview.food_table_id == id_,).first()
|
||||
if item is None:
|
||||
raise ValidationFailure("Bill Not Found")
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_404_NOT_FOUND, detail="Voucher not found",
|
||||
)
|
||||
else:
|
||||
return voucher_info(item.voucher)
|
||||
table = request.dbsession.query(FoodTable).filter(FoodTable.id == table_id).first()
|
||||
if guest_id is not None:
|
||||
guest = request.dbsession.query(GuestBook).filter(GuestBook.id == guest_id).first()
|
||||
table = db.query(FoodTable).filter(FoodTable.id == id_).first()
|
||||
if g is not None:
|
||||
guest = db.query(GuestBook).filter(GuestBook.id == g).first()
|
||||
else:
|
||||
guest = None
|
||||
return voucher_blank(table, guest)
|
||||
|
||||
|
||||
def voucher_info(item):
|
||||
def voucher_info(item: Voucher):
|
||||
return {
|
||||
"id": item.id,
|
||||
"date": item.date.strftime("%H:%M"),
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
import datetime
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from decimal import Decimal
|
||||
from typing import Optional
|
||||
|
||||
import transaction
|
||||
from pyramid.view import view_config
|
||||
from fastapi import APIRouter, HTTPException, status, Depends, Security
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from barker.models import (
|
||||
Voucher,
|
||||
Kot,
|
||||
Inventory,
|
||||
InventoryModifier,
|
||||
VoucherType,
|
||||
Product,
|
||||
)
|
||||
from barker.views.voucher import (
|
||||
from ...schemas.auth import UserToken
|
||||
import barker.schemas.voucher as schemas
|
||||
from ...core.security import get_current_active_user as get_user
|
||||
from ...db.session import SessionLocal
|
||||
from ...models import Voucher, VoucherType, Kot, Product, Inventory, InventoryModifier
|
||||
from ...routers.voucher import (
|
||||
get_tax,
|
||||
do_update_settlements,
|
||||
get_bill_id,
|
||||
|
@ -23,65 +22,89 @@ from barker.views.voucher import (
|
|||
get_guest_book,
|
||||
)
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
@view_config(request_method="PUT", route_name="v1_vouchers_id", renderer="json", trans=True)
|
||||
def update(request):
|
||||
json = request.json_body
|
||||
now = datetime.datetime.now()
|
||||
update_table = request.GET["u"] == "true"
|
||||
voucher_type = VoucherType[request.GET["p"]]
|
||||
guest_book = get_guest_book(request.GET.get("g", None), request.dbsession)
|
||||
item = request.dbsession.query(Voucher).filter(Voucher.id == uuid.UUID(request.matchdict["id"])).first()
|
||||
|
||||
check_permissions(item, voucher_type, request.effective_principals)
|
||||
# Dependency
|
||||
def get_db():
|
||||
try:
|
||||
db = SessionLocal()
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
if guest_book is not None:
|
||||
item.pax = guest_book.pax
|
||||
item.food_table_id = json["table"]["id"]
|
||||
if "customer" in json and "id" in json["customer"]:
|
||||
item.customer_id = json["customer"]["id"]
|
||||
if item.voucher_type == VoucherType.KOT and voucher_type != VoucherType.KOT:
|
||||
item.date = now
|
||||
item.bill_id = get_bill_id(voucher_type, request.dbsession)
|
||||
item.voucher_type = voucher_type
|
||||
item.user_id = uuid.UUID(request.authenticated_userid)
|
||||
item.last_edit_date = now
|
||||
for k in item.kots:
|
||||
for i in k.inventories:
|
||||
i.tax_rate = get_tax(i.tax_rate, voucher_type)
|
||||
i.discount = next(
|
||||
round(Decimal(inv["discount"]), 5)
|
||||
for ko in json["kots"]
|
||||
for inv in ko["inventories"]
|
||||
if uuid.UUID(inv["id"]) == i.id
|
||||
)
|
||||
for k in (k for k in json["kots"] if "id" not in k and len(k["inventories"]) > 0):
|
||||
code = request.dbsession.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar()
|
||||
kot = Kot(item.id, code, item.food_table_id, now, item.user_id)
|
||||
item.kots.append(kot)
|
||||
request.dbsession.add(kot)
|
||||
for index, i in enumerate(k["inventories"]):
|
||||
product = request.dbsession.query(Product).filter(Product.id == uuid.UUID(i["product"]["id"])).first()
|
||||
tax_rate = get_tax(product.sale_category.tax.rate, voucher_type)
|
||||
inv = Inventory(
|
||||
kot.id,
|
||||
product.id,
|
||||
round(Decimal(i["quantity"]), 2),
|
||||
product.price,
|
||||
round(Decimal(i["discount"]), 5),
|
||||
i["isHappyHour"],
|
||||
product.sale_category.tax_id,
|
||||
tax_rate,
|
||||
index,
|
||||
)
|
||||
kot.inventories.append(inv)
|
||||
request.dbsession.add(inv)
|
||||
for m in i["modifiers"]:
|
||||
mod = InventoryModifier(None, uuid.UUID(m["id"]), 0)
|
||||
inv.modifiers.append(mod)
|
||||
request.dbsession.add(mod)
|
||||
do_update_settlements(item, request.dbsession)
|
||||
if update_table:
|
||||
do_update_table(item, guest_book, request.dbsession)
|
||||
transaction.commit()
|
||||
return True
|
||||
|
||||
@router.put("/update/{id_}")
|
||||
def update(
|
||||
id_: uuid.UUID,
|
||||
data: schemas.VoucherIn,
|
||||
u: bool, # Update table?
|
||||
p: str, # Print type
|
||||
g: Optional[uuid.UUID] = None, # Guest book id
|
||||
db: Session = Depends(get_db),
|
||||
user: UserToken = Security(get_user),
|
||||
):
|
||||
try:
|
||||
now = datetime.now()
|
||||
update_table = u
|
||||
voucher_type = VoucherType[p]
|
||||
guest_book = get_guest_book(g, db)
|
||||
|
||||
item: Voucher = db.query(Voucher).filter(Voucher.id == id_).first()
|
||||
|
||||
check_permissions(item, voucher_type, user.permissions)
|
||||
|
||||
if guest_book is not None:
|
||||
item.pax = guest_book.pax
|
||||
item.food_table_id = data.table.id_
|
||||
if data.customer is not None:
|
||||
item.customer_id = data.customer.id_
|
||||
if item.voucher_type == VoucherType.KOT and voucher_type != VoucherType.KOT:
|
||||
item.date = now
|
||||
item.bill_id = get_bill_id(voucher_type, db)
|
||||
item.voucher_type = voucher_type
|
||||
item.user_id = user.id_
|
||||
item.last_edit_date = now
|
||||
for k in item.kots:
|
||||
for i in k.inventories:
|
||||
i.tax_rate = get_tax(i.tax_rate, voucher_type)
|
||||
i.discount = next(
|
||||
round(inv.discount, 5) for ko in data.kots for inv in ko.inventories if inv.id_ == i.id
|
||||
)
|
||||
for k in (k for k in data.kots if k.id_ is None and len(k.inventories) > 0):
|
||||
code = db.query(func.coalesce(func.max(Kot.code), 0) + 1).scalar()
|
||||
kot = Kot(item.id, code, item.food_table_id, now, item.user_id)
|
||||
item.kots.append(kot)
|
||||
db.add(kot)
|
||||
for index, i in enumerate(k.inventories):
|
||||
product = db.query(Product).filter(Product.id == i.product.id_).first()
|
||||
tax_rate = get_tax(product.sale_category.tax.rate, voucher_type)
|
||||
inv = Inventory(
|
||||
kot.id,
|
||||
product.id,
|
||||
round(i.quantity, 2),
|
||||
product.price,
|
||||
round(i.discount, 5),
|
||||
i.is_happy_hour,
|
||||
product.sale_category.tax_id,
|
||||
tax_rate,
|
||||
index,
|
||||
)
|
||||
kot.inventories.append(inv)
|
||||
db.add(inv)
|
||||
for m in i.modifiers:
|
||||
mod = InventoryModifier(None, m.id_, 0)
|
||||
inv.modifiers.append(mod)
|
||||
db.add(mod)
|
||||
do_update_settlements(item, db)
|
||||
if update_table:
|
||||
do_update_table(item, guest_book, db)
|
||||
db.commit()
|
||||
except SQLAlchemyError as e:
|
||||
db.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=str(e),
|
||||
)
|
||||
except Exception:
|
||||
db.rollback()
|
||||
raise
|
||||
|
|
|
@ -27,3 +27,12 @@ class Customer(CustomerIn):
|
|||
fields = {"id_": "id"}
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
|
||||
|
||||
class CustomerLink(BaseModel):
|
||||
id_: uuid.UUID = Field(...)
|
||||
name: Optional[str]
|
||||
|
||||
class Config:
|
||||
fields = {"id_": "id"}
|
||||
alias_generator = to_camel
|
||||
|
|
|
@ -9,7 +9,7 @@ from barker.schemas import to_camel
|
|||
|
||||
class TaxIn(BaseModel):
|
||||
name: str = Field(..., min_length=1)
|
||||
rate: Decimal = Field(ge=0, multiple_of=0.0001, default=0, le=1)
|
||||
rate: Decimal = Field(ge=0, multiple_of=0.01, default=0)
|
||||
|
||||
class Config:
|
||||
fields = {"id_": "id"}
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
import uuid
|
||||
from typing import Optional, List
|
||||
from decimal import Decimal
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from barker.schemas import to_camel
|
||||
from barker.schemas.customer import CustomerLink
|
||||
from barker.schemas.modifier import ModifierLink
|
||||
from barker.schemas.product import ProductLink
|
||||
from barker.schemas.table import TableLink
|
||||
from barker.schemas.tax import TaxLink
|
||||
|
||||
|
||||
class Inventory(BaseModel):
|
||||
id_: Optional[uuid.UUID]
|
||||
product: ProductLink
|
||||
quantity: Decimal = Field(ge=0, multiple_of=0.01)
|
||||
rate: Optional[Decimal]
|
||||
tax: Optional[TaxLink]
|
||||
taxRate: Optional[Decimal]
|
||||
discount: Decimal = Field(ge=0, multiple_of=0.00001, le=1)
|
||||
is_happy_hour: bool
|
||||
modifiers: Optional[List[ModifierLink]]
|
||||
amount: Optional[Decimal]
|
||||
|
||||
class Config:
|
||||
alias_generator = to_camel
|
||||
|
||||
|
||||
class Kot(BaseModel):
|
||||
id_: Optional[uuid.UUID]
|
||||
inventories: List[Inventory]
|
||||
|
||||
class Config:
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
|
||||
|
||||
class VoucherIn(BaseModel):
|
||||
pax: int
|
||||
table: TableLink
|
||||
customer: Optional[CustomerLink]
|
||||
kots: List[Kot]
|
||||
|
||||
class Config:
|
||||
fields = {"id_": "id"}
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
||||
|
||||
|
||||
class Voucher(VoucherIn):
|
||||
id_: uuid.UUID
|
||||
|
||||
class Config:
|
||||
fields = {"id_": "id"}
|
||||
anystr_strip_whitespace = True
|
||||
alias_generator = to_camel
|
|
@ -16,22 +16,39 @@ export class AuthService {
|
|||
public currentUser: Observable<User>;
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem(JWT_USER)));
|
||||
this.checkStorage();
|
||||
this.currentUser = this.currentUserSubject.asObservable();
|
||||
}
|
||||
|
||||
checkStorage(): User {
|
||||
const existingToken: User = JSON.parse(localStorage.getItem(JWT_USER));
|
||||
if (existingToken === null || Date.now() > existingToken.exp * 1000) {
|
||||
localStorage.removeItem(JWT_USER);
|
||||
this.currentUserSubject = new BehaviorSubject<User>(null);
|
||||
return null;
|
||||
} else {
|
||||
this.currentUserSubject = new BehaviorSubject<User>(existingToken);
|
||||
return existingToken;
|
||||
}
|
||||
}
|
||||
|
||||
public get user(): User {
|
||||
const val = this.currentUserSubject.value;
|
||||
let val = this.currentUserSubject.value;
|
||||
if (val == null) {
|
||||
return val;
|
||||
}
|
||||
const expired = Date.now() > val.exp * 1000;
|
||||
let expired = Date.now() > val.exp * 1000;
|
||||
if (expired) {
|
||||
val = this.checkStorage();
|
||||
}
|
||||
if (val == null) {
|
||||
return null;
|
||||
}
|
||||
expired = Date.now() > val.exp * 1000;
|
||||
if (expired) {
|
||||
this.logout();
|
||||
return null;
|
||||
} else {
|
||||
return this.currentUserSubject.value;
|
||||
}
|
||||
return this.currentUserSubject.value;
|
||||
}
|
||||
|
||||
login(username: string, password: string, otp: string) {
|
||||
|
@ -73,10 +90,6 @@ export class AuthService {
|
|||
return Date.now() > (this.user.exp - (environment.ACCESS_TOKEN_REFRESH_MINUTES * 60)) * 1000;
|
||||
}
|
||||
|
||||
expired(): boolean {
|
||||
return Date.now() > this.user.exp * 1000;
|
||||
}
|
||||
|
||||
logout() {
|
||||
// remove user from local storage to log user out
|
||||
localStorage.removeItem(JWT_USER);
|
||||
|
|
|
@ -10,9 +10,9 @@ const httpOptions = {
|
|||
headers: new HttpHeaders({'Content-Type': 'application/json'})
|
||||
};
|
||||
|
||||
const url = '/v1/vouchers';
|
||||
const urlMoveTable = '/v1/move-table';
|
||||
const urlMoveKot = '/v1/move-kot';
|
||||
const url = '/api/voucher';
|
||||
const urlMoveTable = '/api/move-table';
|
||||
const urlMoveKot = '/api/move-kot';
|
||||
const serviceName = 'VoucherService';
|
||||
|
||||
@Injectable({providedIn: 'root'})
|
||||
|
@ -22,7 +22,7 @@ export class VoucherService {
|
|||
}
|
||||
|
||||
get(id: string): Observable<Bill> {
|
||||
return <Observable<Bill>>this.http.get<Bill>(`${url}/${id}`)
|
||||
return <Observable<Bill>>this.http.get<Bill>(`${url}/from-id/${id}`)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, `get id=${id}`))
|
||||
);
|
||||
|
@ -30,9 +30,6 @@ export class VoucherService {
|
|||
|
||||
getFromTable(tableId: string, voucherId: string, guestId: string): Observable<Bill> {
|
||||
let params = new HttpParams();
|
||||
if (tableId !== null) {
|
||||
params = params.set('t', tableId);
|
||||
}
|
||||
if (voucherId !== null) {
|
||||
params = params.set('v', voucherId);
|
||||
}
|
||||
|
@ -40,7 +37,7 @@ export class VoucherService {
|
|||
params = params.set('g', guestId);
|
||||
}
|
||||
|
||||
return <Observable<Bill>>this.http.get<Bill>(`${url}/new`, {params: params})
|
||||
return <Observable<Bill>>this.http.get<Bill>(`${url}/from-table/${tableId}`, {params: params})
|
||||
.pipe(
|
||||
catchError(this.log.handleError(
|
||||
serviceName,
|
||||
|
@ -54,7 +51,7 @@ export class VoucherService {
|
|||
if (guest_book_id !== null) {
|
||||
options.params = options.params.set('g', guest_book_id);
|
||||
}
|
||||
return <Observable<boolean>>this.http.post<boolean>(`${url}/new`, voucher, options)
|
||||
return <Observable<boolean>>this.http.post<boolean>(`${url}/save`, voucher, options)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'save'))
|
||||
);
|
||||
|
@ -65,7 +62,7 @@ export class VoucherService {
|
|||
if (guest_book_id !== null) {
|
||||
options.params = options.params.set('g', guest_book_id);
|
||||
}
|
||||
return <Observable<boolean>>this.http.put<boolean>(`${url}/${voucher.id}`, voucher, options)
|
||||
return <Observable<boolean>>this.http.put<boolean>(`${url}/update/${voucher.id}`, voucher, options)
|
||||
.pipe(
|
||||
catchError(this.log.handleError(serviceName, 'update'))
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue