From 02d9fcfbfdfd5192f81ef4782d1d8c0b50c673ca Mon Sep 17 00:00:00 2001 From: Vlad Stan Date: Tue, 4 Jul 2023 18:13:17 +0300 Subject: [PATCH] feat: update shipping zone when re-issuing invoice --- models.py | 16 ++++-- services.py | 1 - static/components/order-list/order-list.html | 30 ++++++---- static/components/order-list/order-list.js | 58 ++++++++++++++++++-- views_api.py | 25 ++++++--- 5 files changed, 100 insertions(+), 30 deletions(-) diff --git a/models.py b/models.py index a5b7100..8d29e16 100644 --- a/models.py +++ b/models.py @@ -45,6 +45,7 @@ class MerchantConfig(MerchantProfile): active: bool = False restore_in_progress: Optional[bool] = False + class PartialMerchant(BaseModel): private_key: str public_key: str @@ -400,6 +401,11 @@ class OrderStatusUpdate(BaseModel): shipped: Optional[bool] +class OrderReissue(BaseModel): + id: str + shipping_id: Optional[str] = None + + class PaymentOption(BaseModel): type: str link: str @@ -414,14 +420,15 @@ class PaymentRequest(BaseModel): ######################################## MESSAGE ######################################## - class DirectMessageType(Enum): """Various types os direct messages.""" + PLAIN_TEXT = -1 CUSTOMER_ORDER = 0 PAYMENT_REQUEST = 1 ORDER_PAID_OR_SHIPPED = 2 + class PartialDirectMessage(BaseModel): event_id: Optional[str] event_created_at: Optional[int] @@ -437,7 +444,7 @@ class PartialDirectMessage(BaseModel): msg_json = json.loads(msg) if "type" in msg_json: return DirectMessageType(msg_json["type"]), msg_json - + return DirectMessageType.PLAIN_TEXT, None except Exception: return DirectMessageType.PLAIN_TEXT, None @@ -452,7 +459,6 @@ class DirectMessage(PartialDirectMessage): return dm - ######################################## CUSTOMERS ######################################## @@ -471,5 +477,7 @@ class Customer(BaseModel): @classmethod def from_row(cls, row: Row) -> "Customer": customer = cls(**dict(row)) - customer.profile = CustomerProfile(**json.loads(row["meta"])) if "meta" in row else None + customer.profile = ( + CustomerProfile(**json.loads(row["meta"])) if "meta" in row else None + ) return customer diff --git a/services.py b/services.py index 6d26d8a..de619ad 100644 --- a/services.py +++ b/services.py @@ -275,7 +275,6 @@ async def process_nostr_message(msg: str): if type.upper() == "EVENT": subscription_id, event = rest event = NostrEvent(**event) - print("kind: ", event.kind, ": ", msg) if event.kind == 0: await _handle_customer_profile_update(event) elif event.kind == 4: diff --git a/static/components/order-list/order-list.html b/static/components/order-list/order-list.html index 7472b20..8be42e5 100644 --- a/static/components/order-list/order-list.html +++ b/static/components/order-list/order-list.html @@ -121,13 +121,6 @@
-
-
Address:
-
- -
-
-
Customer Public Key:
@@ -137,6 +130,14 @@
+
+
Address:
+
+ +
+
+
+
Phone:
@@ -151,20 +152,29 @@
+
+
Shipping Zone:
+
+ +
+
+
Invoice ID:
- +
- +
- +
diff --git a/static/components/order-list/order-list.js b/static/components/order-list/order-list.js index 8a566ba..849ebb1 100644 --- a/static/components/order-list/order-list.js +++ b/static/components/order-list/order-list.js @@ -17,6 +17,7 @@ async function orderList(path) { data: function () { return { orders: [], + stalls: [], selectedOrder: null, shippingMessage: '', showShipDialog: false, @@ -48,6 +49,7 @@ async function orderList(path) { id: 'false' } ], + zoneOptions: [], ordersTable: { columns: [ { @@ -205,22 +207,26 @@ async function orderList(path) { this.search.restoring = false } }, - reissueOrderInvoice: async function (orderId) { + reissueOrderInvoice: async function (order) { try { const { data } = await LNbits.api.request( 'PUT', - `/nostrmarket/api/v1/order/${orderId}/reissue`, - this.adminkey + `/nostrmarket/api/v1/order/reissue`, + this.adminkey, + { + id: order.id, + shipping_id: order.shipping_id + } ) this.$q.notify({ type: 'positive', message: 'Order invoice reissued!' }) + data.expanded = order.expanded - const i = this.orders.map(o => o.id).indexOf(orderId) - console.log('### order', i) + const i = this.orders.map(o => o.id).indexOf(order.id) if (i !== -1) { - this.orders[i] = { ...this.orders[i], ...data} + this.orders[i] = { ...this.orders[i], ...data } } } catch (error) { LNbits.utils.notifyApiError(error) @@ -265,6 +271,44 @@ async function orderList(path) { order.isNew = false this.orders = [order] }, + getZones: async function () { + try { + const { data } = await LNbits.api.request( + 'GET', + '/nostrmarket/api/v1/zone', + this.inkey + ) + return data.map(z => ({ + id: z.id, + value: z.id, + label: z.name + ? `${z.name} (${z.countries.join(', ')})` + : z.countries.join(', ') + })) + } catch (error) { + LNbits.utils.notifyApiError(error) + } + return [] + }, + getStalls: async function (pending = false) { + try { + const { data } = await LNbits.api.request( + 'GET', + `/nostrmarket/api/v1/stall?pending=${pending}`, + this.inkey + ) + return data.map(s => ({ ...s, expanded: false })) + } catch (error) { + LNbits.utils.notifyApiError(error) + } + return [] + }, + getStallZones: function (stallId) { + const stall = this.stalls.find(s => s.id === stallId) + if (!stall) return [] + + return this.zoneOptions.filter(z => stall.shipping_zones.find(s => s.id === z.id)) + }, showShipOrderDialog: function (order) { this.selectedOrder = order this.shippingMessage = order.shipped @@ -312,6 +356,8 @@ async function orderList(path) { await this.getOrders() } await this.getCustomers() + this.zoneOptions = await this.getZones() + this.stalls = await this.getStalls() } }) } diff --git a/views_api.py b/views_api.py index e1c5e30..22fdc19 100644 --- a/views_api.py +++ b/views_api.py @@ -66,6 +66,7 @@ from .models import ( DirectMessageType, Merchant, Order, + OrderReissue, OrderStatusUpdate, PartialDirectMessage, PartialMerchant, @@ -864,31 +865,37 @@ async def api_restore_orders( ) -@nostrmarket_ext.put("/api/v1/order/{order_id}/reissue") +@nostrmarket_ext.put("/api/v1/order/reissue") async def api_reissue_order_invoice( - order_id: str, + reissue_data: OrderReissue, 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) + data = await get_order(merchant.id, reissue_data.id) assert data, "Order cannot be found" + if reissue_data.shipping_id: + data.shipping_id = reissue_data.shipping_id + order, invoice = await build_order_with_payment( merchant.id, merchant.public_key, PartialOrder(**data.dict()) ) + order_update = { + "stall_id": order.stall_id, + "total": order.total, + "invoice_id": order.invoice_id, + "shipping_id": order.shipping_id, + "extra_data": json.dumps(order.extra.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()), - }, + **order_update, ) payment_req = PaymentRequest( id=data.id, payment_options=[PaymentOption(type="ln", link=invoice)]