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 ###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() result = await (method)(
await db.execute(
f""" f"""
INSERT INTO diagonalley.orders (id, wallet, shippingzone, address, email, total, invoiceid, paid, shipped) INSERT INTO diagonalley.orders (wallet, shippingzone, address, email, total, invoiceid, paid, shipped)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
{returning}
""", """,
( (
order_id, data.wallet,
wallet_id,
data.shippingzone, data.shippingzone,
data.address, data.address,
data.email, data.email,
data.total, data.total,
data.invoiceid, invoiceid,
False, False,
False, False,
), ),
) )
if db.type == SQLITE:
link = await get_diagonalley_order(order_id) return result._result_proxy.lastrowid
assert link, "Newly created link couldn't be retrieved" else:
return link 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( async def create_diagonalley_order_details(
@ -243,7 +247,7 @@ async def create_diagonalley_order_details(
item_id = urlsafe_short_hash() item_id = urlsafe_short_hash()
await db.execute( await db.execute(
""" """
INSERT INTO diagonalley.order_details (id, orderid, productid, quantity) INSERT INTO diagonalley.order_details (id, order_id, product_id, quantity)
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""", """,
( (

View file

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

View file

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

View file

@ -80,7 +80,7 @@
alt="Product Image" alt="Product Image"
loading="lazy" loading="lazy"
spinner-color="white" spinner-color="white"
fit="cover" fit="contain"
height="300px" height="300px"
></q-img> ></q-img>
@ -166,15 +166,15 @@
<q-input <q-input
filled filled
dense dense
v-model.trim="checkoutDialog.data.address_1" v-model.trim="checkoutDialog.data.address"
label="Address (line 1)" label="Address"
></q-input> ></q-input>
<q-input <!-- <q-input
filled filled
dense dense
v-model.trim="checkoutDialog.data.address_2" v-model.trim="checkoutDialog.data.address_2"
label="Address (line 2)" label="Address (line 2)"
></q-input> ></q-input> -->
<q-input <q-input
v-model="checkoutDialog.data.email" v-model="checkoutDialog.data.email"
filled filled
@ -182,16 +182,28 @@
type="email" type="email"
label="Email" label="Email"
></q-input> ></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"> <div class="row q-mt-lg">
<q-btn <q-btn
unelevated unelevated
color="primary" color="primary"
:disable="checkoutDialog.data.address_1 == null :disable="checkoutDialog.data.address == null
|| checkoutDialog.data.email == null" || checkoutDialog.data.email == null
|| checkoutDialog.data.shippingzone == null"
type="submit" type="submit"
>Checkout</q-btn >Checkout</q-btn
> >
<q-btn <q-btn
v-close-popup v-close-popup
flat flat
@ -238,9 +250,25 @@
p.categories.includes(this.searchText) 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: { methods: {
resetCart() {
this.cart = {
total: 0,
size: 0,
products: new Map()
}
},
addToCart(item) { addToCart(item) {
let prod = this.cart.products let prod = this.cart.products
if (prod.has(item.id)) { if (prod.has(item.id)) {
@ -266,17 +294,28 @@
this.cartMenu = Array.from(this.cart.products, item => { this.cartMenu = Array.from(this.cart.products, item => {
return {id: item[0], ...item[1]} return {id: item[0], ...item[1]}
}) })
console.log(this.cartMenu) console.log(this.cartMenu, this.cart)
}, },
placeOrder() { placeOrder() {
// productid: str = Query(...) let dialog = this.checkoutDialog.data
// stall: str = Query(...) let data = {
// product: str = Query(...) ...this.checkoutDialog.data,
// quantity: int = Query(..., ge=1) wallet: this.stall.wallet,
// shippingzone: int = Query(...) total: this.finalCost,
// address: str = Query(...) products: Array.from(this.cart.products, p => {
// email: str = Query(...) return {product_id: p[0], quantity: p[1].quantity}
// invoiceid: str = Query(...) })
}
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 return
} }
}, },
@ -287,7 +326,7 @@
//let stall_ids = new Set() //let stall_ids = new Set()
//this.products.map(p => stall_ids.add(p.stall)) //this.products.map(p => stall_ids.add(p.stall))
console.log(this.stall) console.log(this.stall, this.products)
} }
}) })
</script> </script>

View file

@ -3,6 +3,7 @@ from http import HTTPStatus
from fastapi import Request from fastapi import Request
from fastapi.params import Depends from fastapi.params import Depends
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
from loguru import logger
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from starlette.responses import HTMLResponse 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.decorators import check_user_exists # type: ignore
from lnbits.extensions.diagonalley import diagonalley_ext, diagonalley_renderer 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") 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): async def display(request: Request, stall_id):
stall = await get_diagonalley_stall(stall_id) stall = await get_diagonalley_stall(stall_id)
products = await get_diagonalley_products(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: if not stall:
raise HTTPException( raise HTTPException(
@ -34,6 +47,7 @@ async def display(request: Request, stall_id):
stall = stall.dict() stall = stall.dict()
del stall["privatekey"] del stall["privatekey"]
stall["zones"] = zones
return diagonalley_renderer().TemplateResponse( return diagonalley_renderer().TemplateResponse(
"diagonalley/stall.html", "diagonalley/stall.html",

View file

@ -5,6 +5,7 @@ from uuid import uuid4
from fastapi import Request from fastapi import Request
from fastapi.param_functions import Query from fastapi.param_functions import Query
from fastapi.params import Depends from fastapi.params import Depends
from loguru import logger
from starlette.exceptions import HTTPException from starlette.exceptions import HTTPException
from lnbits.core.crud import get_user from lnbits.core.crud import get_user
@ -16,9 +17,11 @@ from lnbits.decorators import (
require_invoice_key, require_invoice_key,
) )
from ...helpers import urlsafe_short_hash
from . import db, diagonalley_ext from . import db, diagonalley_ext
from .crud import ( from .crud import (
create_diagonalley_order, create_diagonalley_order,
create_diagonalley_order_details,
create_diagonalley_product, create_diagonalley_product,
create_diagonalley_stall, create_diagonalley_stall,
create_diagonalley_zone, create_diagonalley_zone,
@ -254,10 +257,26 @@ async def api_diagonalley_orders(
@diagonalley_ext.post("/api/v1/orders") @diagonalley_ext.post("/api/v1/orders")
async def api_diagonalley_order_create( 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) ref = urlsafe_short_hash()
return order.dict()
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}") @diagonalley_ext.delete("/api/v1/orders/{order_id}")