feat: allow invoice re-issue

This commit is contained in:
Vlad Stan 2023-07-04 16:40:33 +03:00
parent 4539e3a515
commit b5aed1224a
4 changed files with 110 additions and 10 deletions

View file

@ -407,7 +407,9 @@ async def _handle_incoming_dms(
merchant, new_dm, json_data
)
if dm_reply:
await _reply_to_structured_dm(merchant, event, reply_type.value, dm_reply)
await reply_to_structured_dm(
merchant, event.pubkey, reply_type.value, dm_reply
)
async def _handle_outgoing_dms(
@ -474,15 +476,15 @@ async def _persist_dm(
return new_dm
async def _reply_to_structured_dm(
merchant: Merchant, event: NostrEvent, dm_type: int, dm_reply: str
async def reply_to_structured_dm(
merchant: Merchant, customer_pubkey: str, dm_type: int, dm_reply: str
):
dm_event = merchant.build_dm_event(dm_reply, event.pubkey)
dm_event = merchant.build_dm_event(dm_reply, customer_pubkey)
dm = PartialDirectMessage(
event_id=dm_event.id,
event_created_at=dm_event.created_at,
message=dm_reply,
public_key=event.pubkey,
public_key=customer_pubkey,
type=dm_type,
)
await create_direct_message(merchant.id, dm)

View file

@ -156,7 +156,16 @@
<div class="col-6 col-sm-8 q-pr-lg">
<q-input filled dense readonly disabled v-model.trim="props.row.invoice_id" type="text"></q-input>
</div>
<div class="col-3 col-sm-1"></div>
<div class="col-3">
</div>
</div>
<div class="row items-center no-wrap q-mb-md">
<div class="col-3 q-pr-lg"></div>
<div class="col-9">
<q-btn @click="reissueOrderInvoice(props.row.id)" unelevated color="primary" type="submit" class="float-left" label="Reissue Invoice"></q-btn>
</div>
</div>
</q-td>
</q-tr>

View file

@ -205,6 +205,27 @@ async function orderList(path) {
this.search.restoring = false
}
},
reissueOrderInvoice: async function (orderId) {
try {
const { data } = await LNbits.api.request(
'PUT',
`/nostrmarket/api/v1/order/${orderId}/reissue`,
this.adminkey
)
this.$q.notify({
type: 'positive',
message: 'Order invoice reissued!'
})
const i = this.orders.map(o => o.id).indexOf(orderId)
console.log('### order', i)
if (i !== -1) {
this.orders[i] = { ...this.orders[i], ...data}
}
} catch (error) {
LNbits.utils.notifyApiError(error)
}
},
updateOrderShipped: async function () {
this.selectedOrder.shipped = !this.selectedOrder.shipped
try {

View file

@ -53,6 +53,7 @@ from .crud import (
touch_merchant,
update_customer_no_unread_messages,
update_merchant,
update_order,
update_order_shipped_status,
update_product,
update_stall,
@ -68,14 +69,19 @@ from .models import (
OrderStatusUpdate,
PartialDirectMessage,
PartialMerchant,
PartialOrder,
PartialProduct,
PartialStall,
PartialZone,
PaymentOption,
PaymentRequest,
Product,
Stall,
Zone,
)
from .services import (
reply_to_structured_dm,
build_order_with_payment,
create_or_update_order_from_dm,
sign_and_send_to_nostr,
update_merchant_to_nostr,
@ -102,7 +108,7 @@ async def api_create_merchant(
await create_zone(
merchant.id,
PartialZone(
id=f"online-{merchant.id}",
id=f"online-{merchant.public_key}",
name="Online",
currency="sat",
cost=0,
@ -210,6 +216,7 @@ async def api_republish_merchant(
detail="Cannot get merchant",
)
@nostrmarket_ext.put("/api/v1/merchant/{merchant_id}/toggle")
async def api_republish_merchant(
merchant_id: str,
@ -237,7 +244,6 @@ async def api_republish_merchant(
)
@nostrmarket_ext.delete("/api/v1/merchant/{merchant_id}/nostr")
async def api_delete_merchant(
merchant_id: str,
@ -802,7 +808,13 @@ async def api_update_order_status(
await nostr_client.publish_nostr_event(dm_event)
await websocketUpdater(
merchant.id,
json.dumps({ "type": f"dm:{dm.type}", "customerPubkey": order.public_key, "dm": dm.dict() }),
json.dumps(
{
"type": f"dm:{dm.type}",
"customerPubkey": order.public_key,
"dm": dm.dict(),
}
),
)
return order
@ -852,6 +864,62 @@ async def api_restore_orders(
)
@nostrmarket_ext.put("/api/v1/order/{order_id}/reissue")
async def api_reissue_order_invoice(
order_id: str,
wallet: WalletTypeInfo = Depends(require_admin_key),
) -> Order:
try:
merchant = await get_merchant_for_user(wallet.wallet.user)
assert merchant, "Merchant cannot be found"
data = await get_order(merchant.id, order_id)
assert data, "Order cannot be found"
order, invoice = await build_order_with_payment(
merchant.id, merchant.public_key, PartialOrder(**data.dict())
)
await update_order(
merchant.id,
order.id,
**{
"stall_id": order.stall_id,
"total": order.total,
"invoice_id": order.invoice_id,
"extra_data": json.dumps(order.extra.dict()),
},
)
payment_req = PaymentRequest(
id=data.id, payment_options=[PaymentOption(type="ln", link=invoice)]
)
response = {
"type": DirectMessageType.PAYMENT_REQUEST.value,
**payment_req.dict(),
}
dm_reply = json.dumps(response, separators=(",", ":"), ensure_ascii=False)
await reply_to_structured_dm(
merchant,
order.public_key,
DirectMessageType.PAYMENT_REQUEST.value,
dm_reply,
)
return order
except AssertionError as ex:
raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST,
detail=str(ex),
)
except Exception as ex:
logger.warning(ex)
raise HTTPException(
status_code=HTTPStatus.INTERNAL_SERVER_ERROR,
detail="Cannot restore orders",
)
######################################## DIRECT MESSAGES ########################################