feat: filter orders
This commit is contained in:
parent
21ecf6c3c7
commit
5b03c324f1
5 changed files with 138 additions and 26 deletions
31
crud.py
31
crud.py
|
|
@ -445,21 +445,34 @@ async def get_order_by_event_id(merchant_id: str, event_id: str) -> Optional[Ord
|
|||
return Order.from_row(row) if row else None
|
||||
|
||||
|
||||
async def get_orders(merchant_id: str) -> List[Order]:
|
||||
async def get_orders(merchant_id: str, **kwargs) -> List[Order]:
|
||||
q = " AND ".join(
|
||||
[f"{field[0]} = ?" for field in kwargs.items() if field[1] != None]
|
||||
)
|
||||
values = ()
|
||||
if q:
|
||||
q = f"AND {q}"
|
||||
values = (v for v in kwargs.values() if v != None)
|
||||
rows = await db.fetchall(
|
||||
"SELECT * FROM nostrmarket.orders WHERE merchant_id = ? ORDER BY time DESC",
|
||||
(merchant_id,),
|
||||
f"SELECT * FROM nostrmarket.orders WHERE merchant_id = ? {q} ORDER BY time DESC",
|
||||
(merchant_id, *values),
|
||||
)
|
||||
return [Order.from_row(row) for row in rows]
|
||||
|
||||
|
||||
async def get_orders_for_stall(merchant_id: str, stall_id: str) -> List[Order]:
|
||||
async def get_orders_for_stall(
|
||||
merchant_id: str, stall_id: str, **kwargs
|
||||
) -> List[Order]:
|
||||
q = " AND ".join(
|
||||
[f"{field[0]} = ?" for field in kwargs.items() if field[1] != None]
|
||||
)
|
||||
values = ()
|
||||
if q:
|
||||
q = f"AND {q}"
|
||||
values = (v for v in kwargs.values() if v != None)
|
||||
rows = await db.fetchall(
|
||||
"SELECT * FROM nostrmarket.orders WHERE merchant_id = ? AND stall_id = ? ORDER BY time DESC",
|
||||
(
|
||||
merchant_id,
|
||||
stall_id,
|
||||
),
|
||||
f"SELECT * FROM nostrmarket.orders WHERE merchant_id = ? AND stall_id = ? {q} ORDER BY time DESC",
|
||||
(merchant_id, stall_id, *values),
|
||||
)
|
||||
return [Order.from_row(row) for row in rows]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,45 @@
|
|||
<div>
|
||||
<div class="row q-mb-md">
|
||||
<div class="col">
|
||||
<div class="col-3 q-pr-lg">
|
||||
<q-select
|
||||
v-model="search.publicKey"
|
||||
:options="customers.map(c => ({label: buildCustomerLabel(c), value: c.public_key}))"
|
||||
label="Customer"
|
||||
emit-value
|
||||
class="text-wrap"
|
||||
>
|
||||
</q-select>
|
||||
</div>
|
||||
<div class="col-3 q-pr-lg">
|
||||
<q-select
|
||||
v-model="search.isPaid"
|
||||
:options="ternaryOptions"
|
||||
label="Paid"
|
||||
emit-value
|
||||
>
|
||||
</q-select>
|
||||
</div>
|
||||
<div class="col-3 q-pr-lg">
|
||||
<q-select
|
||||
v-model="search.isShipped"
|
||||
:options="ternaryOptions"
|
||||
label="Shipped"
|
||||
emit-value
|
||||
>
|
||||
</q-select>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<q-btn
|
||||
unelevated
|
||||
color="secondary"
|
||||
outline
|
||||
icon="refresh"
|
||||
icon="search"
|
||||
@click="getOrders()"
|
||||
class="float-left"
|
||||
>Refresh Orders</q-btn
|
||||
class="float-right"
|
||||
>Search Orders</q-btn
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row q-mt-md">
|
||||
<div class="col">
|
||||
<q-table
|
||||
flat
|
||||
|
|
|
|||
|
|
@ -12,6 +12,26 @@ async function orderList(path) {
|
|||
shippingMessage: '',
|
||||
showShipDialog: false,
|
||||
filter: '',
|
||||
search: {
|
||||
publicKey: '',
|
||||
isPaid: null,
|
||||
isShipped: null
|
||||
},
|
||||
customers: [],
|
||||
ternaryOptions: [
|
||||
{
|
||||
label: 'All',
|
||||
value: null
|
||||
},
|
||||
{
|
||||
label: 'Yes',
|
||||
value: 'true'
|
||||
},
|
||||
{
|
||||
label: 'No',
|
||||
value: 'false'
|
||||
}
|
||||
],
|
||||
ordersTable: {
|
||||
columns: [
|
||||
{
|
||||
|
|
@ -83,11 +103,22 @@ async function orderList(path) {
|
|||
getOrders: async function () {
|
||||
try {
|
||||
const ordersPath = this.stallId
|
||||
? `/stall/order/${this.stallId}`
|
||||
: '/order'
|
||||
? `stall/order/${this.stallId}`
|
||||
: 'order'
|
||||
|
||||
const query = []
|
||||
if (this.search.publicKey) {
|
||||
query.push(`pubkey=${this.search.publicKey}`)
|
||||
}
|
||||
if (this.search.isPaid) {
|
||||
query.push(`paid=${this.search.isPaid}`)
|
||||
}
|
||||
if (this.search.isShipped) {
|
||||
query.push(`shipped=${this.search.isShipped}`)
|
||||
}
|
||||
const {data} = await LNbits.api.request(
|
||||
'GET',
|
||||
'/nostrmarket/api/v1' + ordersPath,
|
||||
`/nostrmarket/api/v1/${ordersPath}?${query.join('&')}`,
|
||||
this.inkey
|
||||
)
|
||||
this.orders = data.map(s => ({...s, expanded: false}))
|
||||
|
|
@ -129,10 +160,35 @@ async function orderList(path) {
|
|||
},
|
||||
customerSelected: function (customerPubkey) {
|
||||
this.$emit('customer-selected', customerPubkey)
|
||||
},
|
||||
getCustomers: async function () {
|
||||
try {
|
||||
const {data} = await LNbits.api.request(
|
||||
'GET',
|
||||
'/nostrmarket/api/v1/customers',
|
||||
this.inkey
|
||||
)
|
||||
this.customers = data
|
||||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
}
|
||||
},
|
||||
buildCustomerLabel: function (c) {
|
||||
let label = `${c.profile.name || 'unknown'} ${c.profile.about || ''}`
|
||||
if (c.unread_messages) {
|
||||
label += `[new: ${c.unread_messages}]`
|
||||
}
|
||||
label += ` (${c.public_key.slice(0, 16)}...${c.public_key.slice(
|
||||
c.public_key.length - 16
|
||||
)}`
|
||||
return label
|
||||
}
|
||||
},
|
||||
created: async function () {
|
||||
await this.getOrders()
|
||||
if (this.stallId) {
|
||||
await this.getOrders()
|
||||
}
|
||||
await this.getCustomers()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,9 +62,13 @@
|
|||
<q-card class="q-mt-lg">
|
||||
<q-card-section>
|
||||
<div class="row">
|
||||
<div class="col-2"></div>
|
||||
<div class="col-8"></div>
|
||||
<div class="col-2"></div>
|
||||
<div class="col-12">
|
||||
<order-list
|
||||
:adminkey="g.user.wallets[0].adminkey"
|
||||
:inkey="g.user.wallets[0].inkey"
|
||||
@customer-selected="customerSelectedForOrder"
|
||||
></order-list>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
|
|
|
|||
20
views_api.py
20
views_api.py
|
|
@ -1,6 +1,6 @@
|
|||
import json
|
||||
from http import HTTPStatus
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Union
|
||||
|
||||
from fastapi import Depends
|
||||
from fastapi.exceptions import HTTPException
|
||||
|
|
@ -448,12 +448,17 @@ async def api_get_stall_products(
|
|||
@nostrmarket_ext.get("/api/v1/stall/order/{stall_id}")
|
||||
async def api_get_stall_orders(
|
||||
stall_id: str,
|
||||
paid: Optional[bool] = None,
|
||||
shipped: Optional[bool] = None,
|
||||
pubkey: Optional[str] = None,
|
||||
wallet: WalletTypeInfo = Depends(require_invoice_key),
|
||||
):
|
||||
try:
|
||||
merchant = await get_merchant_for_user(wallet.wallet.user)
|
||||
assert merchant, "Merchant cannot be found"
|
||||
orders = await get_orders_for_stall(merchant.id, stall_id)
|
||||
orders = await get_orders_for_stall(
|
||||
merchant.id, stall_id, paid=paid, shipped=shipped, public_key=pubkey
|
||||
)
|
||||
return orders
|
||||
except AssertionError as ex:
|
||||
raise HTTPException(
|
||||
|
|
@ -673,12 +678,19 @@ async def api_get_order(order_id: str, wallet: WalletTypeInfo = Depends(get_key_
|
|||
|
||||
|
||||
@nostrmarket_ext.get("/api/v1/order")
|
||||
async def api_get_orders(wallet: WalletTypeInfo = Depends(get_key_type)):
|
||||
async def api_get_orders(
|
||||
paid: Optional[bool] = None,
|
||||
shipped: Optional[bool] = None,
|
||||
pubkey: Optional[str] = None,
|
||||
wallet: WalletTypeInfo = Depends(get_key_type),
|
||||
):
|
||||
try:
|
||||
merchant = await get_merchant_for_user(wallet.wallet.user)
|
||||
assert merchant, "Merchant cannot be found"
|
||||
|
||||
orders = await get_orders(merchant.id)
|
||||
orders = await get_orders(
|
||||
merchant_id=merchant.id, paid=paid, shipped=shipped, public_key=pubkey
|
||||
)
|
||||
return orders
|
||||
except AssertionError as ex:
|
||||
raise HTTPException(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue