feat: add ship/unship functionality

This commit is contained in:
Vlad Stan 2023-03-07 14:30:58 +02:00
parent 8094bcaf8a
commit 612d31eae0
5 changed files with 129 additions and 50 deletions

View file

@ -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 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( await db.execute(
f"UPDATE nostrmarket.orders SET shipped = ? WHERE id = ?", f"UPDATE nostrmarket.orders SET shipped = ? WHERE user_id = ? AND id = ?",
(order_id, shipped), (shipped, user_id, order_id),
) )
row = await db.fetchone( row = await db.fetchone(

View file

@ -37,6 +37,7 @@
<q-td key="shipped" :props="props"> <q-td key="shipped" :props="props">
<q-checkbox <q-checkbox
v-model="props.row.shipped" v-model="props.row.shipped"
@input="showShipOrderDialog(props.row)"
:label="props.row.shipped ? 'Yes' : 'No'" :label="props.row.shipped ? 'Yes' : 'No'"
size="sm" size="sm"
></q-checkbox> ></q-checkbox>
@ -49,6 +50,33 @@
</q-tr> </q-tr>
<q-tr v-if="props.row.expanded" :props="props"> <q-tr v-if="props.row.expanded" :props="props">
<q-td colspan="100%"> <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="row items-center no-wrap q-mb-md q-mt-md">
<div class="col-3 q-pr-lg">Order ID:</div> <div class="col-3 q-pr-lg">Order ID:</div>
<div class="col-6 col-sm-8 q-pr-lg"> <div class="col-6 col-sm-8 q-pr-lg">
@ -78,33 +106,7 @@
</div> </div>
<div class="col-3 col-sm-1"></div> <div class="col-3 col-sm-1"></div>
</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="row items-center no-wrap q-mb-md">
<div class="col-3 q-pr-lg">Customer Public Key:</div> <div class="col-3 q-pr-lg">Customer Public Key:</div>
<div class="col-6 col-sm-8 q-pr-lg"> <div class="col-6 col-sm-8 q-pr-lg">
@ -172,4 +174,32 @@
</q-tr> </q-tr>
</template> </template>
</q-table> </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> </div>

View file

@ -8,7 +8,9 @@ async function orderList(path) {
data: function () { data: function () {
return { return {
orders: [], orders: [],
selectedOrder: null,
shippingMessage: '',
showShipDialog: false,
filter: '', filter: '',
ordersTable: { ordersTable: {
columns: [ columns: [
@ -93,6 +95,39 @@ async function orderList(path) {
} catch (error) { } catch (error) {
LNbits.utils.notifyApiError(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 () { created: async function () {

View file

@ -45,7 +45,6 @@ async def on_invoice_paid(payment: Payment) -> None:
await handle_order_paid(order_id, merchant_pubkey) await handle_order_paid(order_id, merchant_pubkey)
async def handle_order_paid(order_id: str, merchant_pubkey: str): async def handle_order_paid(order_id: str, merchant_pubkey: str):
try: try:
order = await update_order_paid_status(order_id, True) 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) 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( dm_content = json.dumps(
order_status.dict(), separators=(",", ":"), ensure_ascii=False order_status.dict(), separators=(",", ":"), ensure_ascii=False
) )

View file

@ -38,6 +38,7 @@ from .crud import (
get_wallet_for_product, get_wallet_for_product,
get_zone, get_zone,
get_zones, get_zones,
update_order_shipped_status,
update_product, update_product,
update_stall, update_stall,
update_zone, update_zone,
@ -47,6 +48,7 @@ from .models import (
Nostrable, Nostrable,
Order, Order,
OrderExtra, OrderExtra,
OrderStatusUpdate,
PartialMerchant, PartialMerchant,
PartialOrder, PartialOrder,
PartialProduct, PartialProduct,
@ -542,24 +544,35 @@ async def api_get_orders(wallet: WalletTypeInfo = Depends(get_key_type)):
) )
# @nostrmarket_ext.patch("/api/v1/order/{order_id}") @nostrmarket_ext.patch("/api/v1/order/{order_id}")
# async def api_update_order( async def api_update_order_status(
# data: OrderStatusUpdate, data: OrderStatusUpdate,
# wallet: WalletTypeInfo = Depends(require_admin_key), wallet: WalletTypeInfo = Depends(require_admin_key),
# ) -> Zone: ) -> Order:
# try: 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) merchant = await get_merchant_for_user(wallet.wallet.user)
# assert zone, "Cannot find updated zone" assert merchant, f"Merchant cannot be found for order {data.id}"
# return zone
# except HTTPException as ex: data.paid = order.paid
# raise ex dm_content = json.dumps(data.dict(), separators=(",", ":"), ensure_ascii=False)
# except Exception as ex:
# logger.warning(ex) dm_event = merchant.build_dm_event(dm_content, order.pubkey)
# raise HTTPException( await publish_nostr_event(dm_event)
# status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
# detail="Cannot update order", return order
# )
except Exception as ex:
logger.warning(ex)
raise HTTPException(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail="Cannot update order",
)
######################################## OTHER ######################################## ######################################## OTHER ########################################