feat: add ship/unship functionality
This commit is contained in:
parent
8094bcaf8a
commit
612d31eae0
5 changed files with 129 additions and 50 deletions
8
crud.py
8
crud.py
|
|
@ -392,10 +392,12 @@ async def update_order_paid_status(order_id: str, paid: bool) -> Optional[Order]
|
|||
return Order.from_row(row) if row else None
|
||||
|
||||
|
||||
async def update_order_shipped_status(order_id: str, shipped: bool) -> Optional[Order]:
|
||||
async def update_order_shipped_status(
|
||||
user_id: str, order_id: str, shipped: bool
|
||||
) -> Optional[Order]:
|
||||
await db.execute(
|
||||
f"UPDATE nostrmarket.orders SET shipped = ? WHERE id = ?",
|
||||
(order_id, shipped),
|
||||
f"UPDATE nostrmarket.orders SET shipped = ? WHERE user_id = ? AND id = ?",
|
||||
(shipped, user_id, order_id),
|
||||
)
|
||||
|
||||
row = await db.fetchone(
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
<q-td key="shipped" :props="props">
|
||||
<q-checkbox
|
||||
v-model="props.row.shipped"
|
||||
@input="showShipOrderDialog(props.row)"
|
||||
:label="props.row.shipped ? 'Yes' : 'No'"
|
||||
size="sm"
|
||||
></q-checkbox>
|
||||
|
|
@ -49,6 +50,33 @@
|
|||
</q-tr>
|
||||
<q-tr v-if="props.row.expanded" :props="props">
|
||||
<q-td colspan="100%">
|
||||
<div class="row items-center no-wrap q-mb-md">
|
||||
<div class="col-3 q-pr-lg">Products:</div>
|
||||
<div class="col-8">
|
||||
<div class="row items-center no-wrap q-mb-md">
|
||||
<div class="col-1">Quantity</div>
|
||||
<div class="col-1"></div>
|
||||
<div class="col-10">Name</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1"></div>
|
||||
</div>
|
||||
<div class="row items-center no-wrap q-mb-md">
|
||||
<div class="col-3 q-pr-lg"></div>
|
||||
<div class="col-8">
|
||||
<div
|
||||
v-for="item in props.row.items"
|
||||
class="row items-center no-wrap q-mb-md"
|
||||
>
|
||||
<div class="col-1">{{item.quantity}}</div>
|
||||
<div class="col-1">x</div>
|
||||
<div class="col-10">
|
||||
{{productOverview(props.row, item.product_id)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1"></div>
|
||||
</div>
|
||||
<div class="row items-center no-wrap q-mb-md q-mt-md">
|
||||
<div class="col-3 q-pr-lg">Order ID:</div>
|
||||
<div class="col-6 col-sm-8 q-pr-lg">
|
||||
|
|
@ -78,33 +106,7 @@
|
|||
</div>
|
||||
<div class="col-3 col-sm-1"></div>
|
||||
</div>
|
||||
<div class="row items-center no-wrap q-mb-md">
|
||||
<div class="col-3 q-pr-lg">Products:</div>
|
||||
<div class="col-8">
|
||||
<div class="row items-center no-wrap q-mb-md">
|
||||
<div class="col-1">Quantity</div>
|
||||
<div class="col-1"></div>
|
||||
<div class="col-10">Name</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1"></div>
|
||||
</div>
|
||||
<div class="row items-center no-wrap q-mb-md">
|
||||
<div class="col-3 q-pr-lg"></div>
|
||||
<div class="col-8">
|
||||
<div
|
||||
v-for="item in props.row.items"
|
||||
class="row items-center no-wrap q-mb-md"
|
||||
>
|
||||
<div class="col-1">{{item.quantity}}</div>
|
||||
<div class="col-1">x</div>
|
||||
<div class="col-10">
|
||||
{{productOverview(props.row, item.product_id)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-1"></div>
|
||||
</div>
|
||||
|
||||
<div class="row items-center no-wrap q-mb-md">
|
||||
<div class="col-3 q-pr-lg">Customer Public Key:</div>
|
||||
<div class="col-6 col-sm-8 q-pr-lg">
|
||||
|
|
@ -172,4 +174,32 @@
|
|||
</q-tr>
|
||||
</template>
|
||||
</q-table>
|
||||
|
||||
<q-dialog v-model="showShipDialog" position="top">
|
||||
<q-card v-if="selectedOrder" class="q-pa-lg q-pt-xl" style="width: 500px">
|
||||
<q-form @submit="updateOrderShipped" class="q-gutter-md">
|
||||
<q-input
|
||||
filled
|
||||
dense
|
||||
v-model.trim="shippingMessage"
|
||||
label="Shipping Message"
|
||||
type="textarea"
|
||||
rows="4"
|
||||
></q-input>
|
||||
|
||||
<div class="row q-mt-lg">
|
||||
<q-btn
|
||||
unelevated
|
||||
color="primary"
|
||||
type="submit"
|
||||
:label="selectedOrder.shipped? 'Unship Order' : 'Ship Order'"
|
||||
></q-btn>
|
||||
|
||||
<q-btn v-close-popup flat color="grey" class="q-ml-auto"
|
||||
>Cancel</q-btn
|
||||
>
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,9 @@ async function orderList(path) {
|
|||
data: function () {
|
||||
return {
|
||||
orders: [],
|
||||
|
||||
selectedOrder: null,
|
||||
shippingMessage: '',
|
||||
showShipDialog: false,
|
||||
filter: '',
|
||||
ordersTable: {
|
||||
columns: [
|
||||
|
|
@ -93,6 +95,39 @@ async function orderList(path) {
|
|||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
}
|
||||
},
|
||||
updateOrderShipped: async function () {
|
||||
console.log('### order', this.selectedOrder)
|
||||
this.selectedOrder.shipped = !this.selectedOrder.shipped
|
||||
try {
|
||||
await LNbits.api.request(
|
||||
'PATCH',
|
||||
`/nostrmarket/api/v1/order/${this.selectedOrder.id}`,
|
||||
this.adminkey,
|
||||
{
|
||||
id: this.selectedOrder.id,
|
||||
message: this.shippingMessage,
|
||||
shipped: this.selectedOrder.shipped
|
||||
}
|
||||
)
|
||||
this.$q.notify({
|
||||
type: 'positive',
|
||||
message: 'Order updated!'
|
||||
})
|
||||
} catch (error) {
|
||||
LNbits.utils.notifyApiError(error)
|
||||
}
|
||||
this.showShipDialog = false
|
||||
},
|
||||
showShipOrderDialog: function (order) {
|
||||
this.selectedOrder = order
|
||||
this.shippingMessage = order.shipped
|
||||
? `The order has been shipped! Order ID: '${order.id}' `
|
||||
: `The order has NOT yet been shipped! Order ID: '${order.id}'`
|
||||
|
||||
// do not change the status yet
|
||||
this.selectedOrder.shipped = !order.shipped
|
||||
this.showShipDialog = true
|
||||
}
|
||||
},
|
||||
created: async function () {
|
||||
|
|
|
|||
3
tasks.py
3
tasks.py
|
|
@ -45,7 +45,6 @@ async def on_invoice_paid(payment: Payment) -> None:
|
|||
await handle_order_paid(order_id, merchant_pubkey)
|
||||
|
||||
|
||||
|
||||
async def handle_order_paid(order_id: str, merchant_pubkey: str):
|
||||
try:
|
||||
order = await update_order_paid_status(order_id, True)
|
||||
|
|
@ -55,7 +54,7 @@ async def handle_order_paid(order_id: str, merchant_pubkey: str):
|
|||
)
|
||||
|
||||
merchant = await get_merchant_by_pubkey(merchant_pubkey)
|
||||
assert merchant, f"Merchant cannot be foud for order {order_id}"
|
||||
assert merchant, f"Merchant cannot be found for order {order_id}"
|
||||
dm_content = json.dumps(
|
||||
order_status.dict(), separators=(",", ":"), ensure_ascii=False
|
||||
)
|
||||
|
|
|
|||
47
views_api.py
47
views_api.py
|
|
@ -38,6 +38,7 @@ from .crud import (
|
|||
get_wallet_for_product,
|
||||
get_zone,
|
||||
get_zones,
|
||||
update_order_shipped_status,
|
||||
update_product,
|
||||
update_stall,
|
||||
update_zone,
|
||||
|
|
@ -47,6 +48,7 @@ from .models import (
|
|||
Nostrable,
|
||||
Order,
|
||||
OrderExtra,
|
||||
OrderStatusUpdate,
|
||||
PartialMerchant,
|
||||
PartialOrder,
|
||||
PartialProduct,
|
||||
|
|
@ -542,24 +544,35 @@ async def api_get_orders(wallet: WalletTypeInfo = Depends(get_key_type)):
|
|||
)
|
||||
|
||||
|
||||
# @nostrmarket_ext.patch("/api/v1/order/{order_id}")
|
||||
# async def api_update_order(
|
||||
# data: OrderStatusUpdate,
|
||||
# wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||
# ) -> Zone:
|
||||
# try:
|
||||
@nostrmarket_ext.patch("/api/v1/order/{order_id}")
|
||||
async def api_update_order_status(
|
||||
data: OrderStatusUpdate,
|
||||
wallet: WalletTypeInfo = Depends(require_admin_key),
|
||||
) -> Order:
|
||||
try:
|
||||
assert data.shipped != None, "Shipped value is required for order"
|
||||
order = await update_order_shipped_status(
|
||||
wallet.wallet.user, data.id, data.shipped
|
||||
)
|
||||
assert order, "Cannot find updated order"
|
||||
|
||||
# zone = await update_order(wallet.wallet.user, data)
|
||||
# assert zone, "Cannot find updated zone"
|
||||
# return zone
|
||||
# except HTTPException as ex:
|
||||
# raise ex
|
||||
# except Exception as ex:
|
||||
# logger.warning(ex)
|
||||
# raise HTTPException(
|
||||
# status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
# detail="Cannot update order",
|
||||
# )
|
||||
merchant = await get_merchant_for_user(wallet.wallet.user)
|
||||
assert merchant, f"Merchant cannot be found for order {data.id}"
|
||||
|
||||
data.paid = order.paid
|
||||
dm_content = json.dumps(data.dict(), separators=(",", ":"), ensure_ascii=False)
|
||||
|
||||
dm_event = merchant.build_dm_event(dm_content, order.pubkey)
|
||||
await publish_nostr_event(dm_event)
|
||||
|
||||
return order
|
||||
|
||||
except Exception as ex:
|
||||
logger.warning(ex)
|
||||
raise HTTPException(
|
||||
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
|
||||
detail="Cannot update order",
|
||||
)
|
||||
|
||||
|
||||
######################################## OTHER ########################################
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue