create order

This commit is contained in:
Tiago vasconcelos 2022-08-18 10:49:04 +01:00
parent 58b046254f
commit 4cd86d0daf
6 changed files with 124 additions and 50 deletions

View file

@ -210,30 +210,34 @@ async def delete_diagonalley_stall(stall_id: str) -> None:
###Orders
async def create_diagonalley_order(wallet_id: str, data: createOrder) -> Orders:
async def create_diagonalley_order(data: createOrder, invoiceid: str) -> Orders:
returning = "" if db.type == SQLITE else "RETURNING ID"
method = db.execute if db.type == SQLITE else db.fetchone
order_id = urlsafe_short_hash()
await db.execute(
result = await (method)(
f"""
INSERT INTO diagonalley.orders (id, wallet, shippingzone, address, email, total, invoiceid, paid, shipped)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
INSERT INTO diagonalley.orders (wallet, shippingzone, address, email, total, invoiceid, paid, shipped)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
{returning}
""",
(
order_id,
wallet_id,
data.wallet,
data.shippingzone,
data.address,
data.email,
data.total,
data.invoiceid,
invoiceid,
False,
False,
),
)
link = await get_diagonalley_order(order_id)
assert link, "Newly created link couldn't be retrieved"
return link
if db.type == SQLITE:
return result._result_proxy.lastrowid
else:
return result[0]
# link = await get_diagonalley_order(link.id)
# assert link, "Newly created link couldn't be retrieved"
# return link
async def create_diagonalley_order_details(
@ -243,7 +247,7 @@ async def create_diagonalley_order_details(
item_id = urlsafe_short_hash()
await db.execute(
"""
INSERT INTO diagonalley.order_details (id, orderid, productid, quantity)
INSERT INTO diagonalley.order_details (id, order_id, product_id, quantity)
VALUES (?, ?, ?, ?)
""",
(

View file

@ -11,7 +11,8 @@ async def m001_initial(db):
publickey TEXT,
privatekey TEXT,
relays TEXT,
shippingzones TEXT NOT NULL
shippingzones TEXT NOT NULL,
rating INTEGER DEFAULT 0
);
"""
)
@ -20,7 +21,7 @@ async def m001_initial(db):
Initial products table.
"""
await db.execute(
"""
f"""
CREATE TABLE diagonalley.products (
id TEXT PRIMARY KEY,
stall TEXT NOT NULL REFERENCES {db.references_schema}stalls (id),
@ -30,7 +31,7 @@ async def m001_initial(db):
image TEXT,
price INTEGER NOT NULL,
quantity INTEGER NOT NULL,
rating INTEGER NOT NULL
rating INTEGER DEFAULT 0
);
"""
)
@ -53,12 +54,13 @@ async def m001_initial(db):
Initial orders table.
"""
await db.execute(
"""
f"""
CREATE TABLE diagonalley.orders (
id {db.serial_primary_key},
wallet TEXT NOT NULL,
username TEXT,
pubkey TEXT,
shippingzone INTEGER NOT NULL,
shippingzone TEXT NOT NULL,
address TEXT NOT NULL,
email TEXT NOT NULL,
total INTEGER NOT NULL,
@ -76,11 +78,11 @@ async def m001_initial(db):
Initial order details table.
"""
await db.execute(
"""
f"""
CREATE TABLE diagonalley.order_details (
id TEXT PRIMARY KEY,
orderid INTEGER NOT NULL REFERENCES {db.references_schema}orders (id)
productid TEXT NOT NULL REFERENCES {db.references_schema}products (id),
order_id INTEGER NOT NULL REFERENCES {db.references_schema}orders (id),
product_id TEXT NOT NULL REFERENCES {db.references_schema}products (id),
quantity INTEGER NOT NULL
);
"""
@ -103,7 +105,7 @@ async def m001_initial(db):
Initial market stalls table.
"""
await db.execute(
"""
f"""
CREATE TABLE diagonalley.market_stalls (
id TEXT PRIMARY KEY,
marketid TEXT NOT NULL REFERENCES {db.references_schema}markets (id),

View file

@ -71,15 +71,11 @@ class createOrderDetails(BaseModel):
class createOrder(BaseModel):
wallet: str = Query(...)
pubkey: str = Query(None)
shippingzone: int = Query(...)
shippingzone: str = Query(...)
address: str = Query(...)
email: str = Query(...)
total: int = Query(...)
invoiceid: str = Query(...)
products: List[createOrderDetails]
# stall: str = Query(...)
# product: str = Query(...)
# quantity: int = Query(..., ge=1)
class Orders(BaseModel):
@ -89,7 +85,7 @@ class Orders(BaseModel):
pubkey: str
product: str
quantity: int
shippingzone: int
shippingzone: str
address: str
email: str
invoiceid: str

View file

@ -80,7 +80,7 @@
alt="Product Image"
loading="lazy"
spinner-color="white"
fit="cover"
fit="contain"
height="300px"
></q-img>
@ -166,15 +166,15 @@
<q-input
filled
dense
v-model.trim="checkoutDialog.data.address_1"
label="Address (line 1)"
v-model.trim="checkoutDialog.data.address"
label="Address"
></q-input>
<q-input
<!-- <q-input
filled
dense
v-model.trim="checkoutDialog.data.address_2"
label="Address (line 2)"
></q-input>
></q-input> -->
<q-input
v-model="checkoutDialog.data.email"
filled
@ -182,16 +182,28 @@
type="email"
label="Email"
></q-input>
<p>Select the shipping zone:</p>
<div class="row q-mt-lg">
<q-option-group
:options="stall.zones"
type="radio"
emit-value
v-model="checkoutDialog.data.shippingzone"
/>
</div>
<div class="row q-mt-lg">
{% raw %} Total: {{ finalCost }} {% endraw %}
</div>
<div class="row q-mt-lg">
<q-btn
unelevated
color="primary"
:disable="checkoutDialog.data.address_1 == null
|| checkoutDialog.data.email == null"
:disable="checkoutDialog.data.address == null
|| checkoutDialog.data.email == null
|| checkoutDialog.data.shippingzone == null"
type="submit"
>Checkout</q-btn
>
<q-btn
v-close-popup
flat
@ -238,9 +250,25 @@
p.categories.includes(this.searchText)
)
})
},
finalCost() {
if (!this.checkoutDialog.data.shippingzone) return this.cart.total
let zoneCost = this.stall.zones.find(
z => z.value == this.checkoutDialog.data.shippingzone
)
return this.cart.total + zoneCost.cost
}
},
methods: {
resetCart() {
this.cart = {
total: 0,
size: 0,
products: new Map()
}
},
addToCart(item) {
let prod = this.cart.products
if (prod.has(item.id)) {
@ -266,17 +294,28 @@
this.cartMenu = Array.from(this.cart.products, item => {
return {id: item[0], ...item[1]}
})
console.log(this.cartMenu)
console.log(this.cartMenu, this.cart)
},
placeOrder() {
// productid: str = Query(...)
// stall: str = Query(...)
// product: str = Query(...)
// quantity: int = Query(..., ge=1)
// shippingzone: int = Query(...)
// address: str = Query(...)
// email: str = Query(...)
// invoiceid: str = Query(...)
let dialog = this.checkoutDialog.data
let data = {
...this.checkoutDialog.data,
wallet: this.stall.wallet,
total: this.finalCost,
products: Array.from(this.cart.products, p => {
return {product_id: p[0], quantity: p[1].quantity}
})
}
LNbits.api
.request('POST', '/diagonalley/api/v1/orders', null, data)
.then(res => {
this.checkoutDialog = {show: false, data: {}}
this.resetCart()
console.log(res.data)
})
.catch(error => LNbits.utils.notifyApiError(error))
return
}
},
@ -287,7 +326,7 @@
//let stall_ids = new Set()
//this.products.map(p => stall_ids.add(p.stall))
console.log(this.stall)
console.log(this.stall, this.products)
}
})
</script>

View file

@ -3,6 +3,7 @@ from http import HTTPStatus
from fastapi import Request
from fastapi.params import Depends
from fastapi.templating import Jinja2Templates
from loguru import logger
from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse
@ -10,7 +11,12 @@ from lnbits.core.models import User
from lnbits.decorators import check_user_exists # type: ignore
from lnbits.extensions.diagonalley import diagonalley_ext, diagonalley_renderer
from .crud import get_diagonalley_products, get_diagonalley_stall
from .crud import (
get_diagonalley_products,
get_diagonalley_stall,
get_diagonalley_zone,
get_diagonalley_zones,
)
templates = Jinja2Templates(directory="templates")
@ -26,6 +32,13 @@ async def index(request: Request, user: User = Depends(check_user_exists)):
async def display(request: Request, stall_id):
stall = await get_diagonalley_stall(stall_id)
products = await get_diagonalley_products(stall_id)
zones = []
for id in stall.shippingzones.split(","):
z = await get_diagonalley_zone(id)
z = z.dict()
zones.append({"label": z["countries"], "cost": z["cost"], "value": z["id"]})
logger.debug(f"ZONES {zones}")
if not stall:
raise HTTPException(
@ -34,6 +47,7 @@ async def display(request: Request, stall_id):
stall = stall.dict()
del stall["privatekey"]
stall["zones"] = zones
return diagonalley_renderer().TemplateResponse(
"diagonalley/stall.html",

View file

@ -5,6 +5,7 @@ from uuid import uuid4
from fastapi import Request
from fastapi.param_functions import Query
from fastapi.params import Depends
from loguru import logger
from starlette.exceptions import HTTPException
from lnbits.core.crud import get_user
@ -16,9 +17,11 @@ from lnbits.decorators import (
require_invoice_key,
)
from ...helpers import urlsafe_short_hash
from . import db, diagonalley_ext
from .crud import (
create_diagonalley_order,
create_diagonalley_order_details,
create_diagonalley_product,
create_diagonalley_stall,
create_diagonalley_zone,
@ -254,10 +257,26 @@ async def api_diagonalley_orders(
@diagonalley_ext.post("/api/v1/orders")
async def api_diagonalley_order_create(
data: createOrder, wallet: WalletTypeInfo = Depends(get_key_type)
data: createOrder
):
order = await create_diagonalley_order(wallet_id=wallet.wallet.id, data=data)
return order.dict()
ref = urlsafe_short_hash()
payment_hash, payment_request = await create_invoice(
wallet_id=data.wallet,
amount=data.total,
memo=f"New order on Diagon alley",
extra={
"tag": "diagonalley",
"reference": ref,
}
)
order_id = await create_diagonalley_order(invoiceid=payment_hash, data=data)
logger.debug(f"ORDER ID {order_id}")
logger.debug(f"PRODUCTS {data.products}")
await create_diagonalley_order_details(order_id=order_id, data=data.products)
return {"payment_hash": payment_hash, "payment_request": payment_request, "order_reference": ref}
# order = await create_diagonalley_order(wallet_id=wallet.wallet.id, data=data)
# return order.dict()
@diagonalley_ext.delete("/api/v1/orders/{order_id}")