aboutsummaryrefslogtreecommitdiffstats
path: root/thallium-backend/src/routes/orders.py
diff options
context:
space:
mode:
authorGravatar Chris Lovering <[email protected]>2024-09-13 19:12:07 +0100
committerGravatar Chris Lovering <[email protected]>2024-09-13 19:12:07 +0100
commitda8fdd31bafbd6c16049c8cd40b55200432f0b14 (patch)
tree2100935c158f04b0e42ab55c4773bc4a94278119 /thallium-backend/src/routes/orders.py
parentAdd the printful store ID to the authorized client as a header (diff)
Add an endpoint to submit an order to printful
Diffstat (limited to 'thallium-backend/src/routes/orders.py')
-rw-r--r--thallium-backend/src/routes/orders.py38
1 files changed, 38 insertions, 0 deletions
diff --git a/thallium-backend/src/routes/orders.py b/thallium-backend/src/routes/orders.py
new file mode 100644
index 0000000..c5126a8
--- /dev/null
+++ b/thallium-backend/src/routes/orders.py
@@ -0,0 +1,38 @@
+import logging
+
+from fastapi import APIRouter, Depends, HTTPException, Request
+from sqlalchemy import select
+
+from src.auth import TokenAuth
+from src.dto import Order, OrderCreate, Voucher
+from src.orm import Voucher as DBVoucher
+from src.settings import DBSession, PrintfulClient
+
+router = APIRouter(prefix="/orders", tags=["Orders"], dependencies=[Depends(TokenAuth(allow_vouchers=True))])
+
+log = logging.getLogger(__name__)
+
+
+async def create_order(request: Request, db: DBSession, client: PrintfulClient, order: OrderCreate) -> Order | None:
+ """
+ Create the order in printful and deduct the order cost from the voucher.
+
+ If the voucher does not have enough funds, the order is cancelled.
+ """
+ resp = await client.post("/orders", json=order.as_printful_payload(), params={"confirm": False})
+ resp.raise_for_status()
+ submitted_order = Order.model_validate(resp.json()["result"])
+
+ voucher: Voucher = request.state.voucher
+ stmt = select(DBVoucher).where(DBVoucher.id == voucher.id).with_for_update()
+ db_voucher = await db.scalar(stmt)
+ if submitted_order.costs.total > db_voucher.balance:
+ await client.delete(f"/orders/{submitted_order.id}")
+ raise HTTPException(
+ status_code=400,
+ detail=f"Order totals {submitted_order.costs.total}, only {db_voucher.balance} remaining on voucher.",
+ )
+
+ db_voucher.balance = db_voucher.balance - submitted_order.costs.total
+ return submitted_order