invoices: search by amount and refine archive copy

This commit is contained in:
xmrcheckout
2026-01-09 14:01:02 +00:00
parent 4c86be83f5
commit 39083eafb4
2 changed files with 24 additions and 8 deletions
+13 -1
View File
@@ -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))
+11 -7
View File
@@ -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)}
/>
</div>
@@ -1006,9 +1006,11 @@ export default function InvoicePanel({
Archive invoice
</button>
) : (
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-ink-soft">
Invoice actions are unavailable for this status.
</p>
!invoice.archived_at ? (
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-ink-soft">
{formatStatus(invoice.status)} invoices cannot be archived.
</p>
) : null
)}
{archiveState.error && archiveModalInvoiceId === invoice.id ? (
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-clay">
@@ -1199,9 +1201,11 @@ export default function InvoicePanel({
Archive invoice
</button>
) : (
<p className="text-sm text-ink-soft">
Invoice actions are unavailable for this status.
</p>
!invoice.archived_at ? (
<p className="text-sm text-ink-soft">
{formatStatus(invoice.status)} invoices cannot be archived.
</p>
) : null
)}
{archiveState.error && archiveModalInvoiceId === invoice.id ? (
<p className="rounded-lg border border-red-200 bg-red-50 px-3 py-2 text-sm font-semibold text-red-700">