From 39083eafb477f2b02f18aaefb9c220aa0a1df9af Mon Sep 17 00:00:00 2001 From: xmrcheckout Date: Fri, 9 Jan 2026 14:01:02 +0000 Subject: [PATCH] invoices: search by amount and refine archive copy --- api/app/routes.py | 14 +++++++++++++- ui/components/invoice-panel.tsx | 18 +++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/api/app/routes.py b/api/app/routes.py index deb0dad..d4baef6 100644 --- a/api/app/routes.py +++ b/api/app/routes.py @@ -1,7 +1,7 @@ import uuid from typing import Any from datetime import datetime, timedelta, timezone -from decimal import Decimal, ROUND_DOWN +from decimal import Decimal, ROUND_DOWN, InvalidOperation import csv import io import json @@ -1048,9 +1048,15 @@ def list_invoices_for_user( invoice_uuid = uuid.UUID(needle) except ValueError: invoice_uuid = None + try: + amount_xmr = Decimal(needle) + except (InvalidOperation, ValueError): + amount_xmr = None matchers = [] if invoice_uuid is not None: matchers.append(Invoice.id == invoice_uuid) + if amount_xmr is not None: + matchers.append(Invoice.amount_xmr == amount_xmr) matchers.append(Invoice.address.ilike(f"%{needle}%")) matchers.append(cast(Invoice.metadata_json, SqlString).ilike(f"%{needle}%")) query = query.filter(or_(*matchers)) @@ -1090,9 +1096,15 @@ def list_invoices_for_user( invoice_uuid = uuid.UUID(needle) except ValueError: invoice_uuid = None + try: + amount_xmr = Decimal(needle) + except (InvalidOperation, ValueError): + amount_xmr = None matchers = [] if invoice_uuid is not None: matchers.append(Invoice.id == invoice_uuid) + if amount_xmr is not None: + matchers.append(Invoice.amount_xmr == amount_xmr) matchers.append(Invoice.address.ilike(f"%{needle}%")) matchers.append(cast(Invoice.metadata_json, SqlString).ilike(f"%{needle}%")) total_query = total_query.filter(or_(*matchers)) diff --git a/ui/components/invoice-panel.tsx b/ui/components/invoice-panel.tsx index 063704a..fb99764 100644 --- a/ui/components/invoice-panel.tsx +++ b/ui/components/invoice-panel.tsx @@ -824,7 +824,7 @@ export default function InvoicePanel({ id="invoice_search" type="search" value={searchInput} - placeholder="Invoice id, subaddress, or metadata" + placeholder="Invoice id, amount (XMR), subaddress, or metadata" onChange={(event) => setSearchInput(event.target.value)} /> @@ -1006,9 +1006,11 @@ export default function InvoicePanel({ Archive invoice ) : ( -

- Invoice actions are unavailable for this status. -

+ !invoice.archived_at ? ( +

+ {formatStatus(invoice.status)} invoices cannot be archived. +

+ ) : null )} {archiveState.error && archiveModalInvoiceId === invoice.id ? (

@@ -1199,9 +1201,11 @@ export default function InvoicePanel({ Archive invoice ) : ( -

- Invoice actions are unavailable for this status. -

+ !invoice.archived_at ? ( +

+ {formatStatus(invoice.status)} invoices cannot be archived. +

+ ) : null )} {archiveState.error && archiveModalInvoiceId === invoice.id ? (