"""Streamlit UI for Oracle Fusion AR MCP Server."""
import streamlit as st
import httpx
import json
from datetime import datetime
# Configure page
st.set_page_config(
page_title="Oracle AR Invoice Viewer",
page_icon="π",
layout="wide"
)
# Server URL
API_BASE_URL = "https://web-production-7eb7.up.railway.app"
# Custom CSS
st.markdown("""
<style>
.main-header {
font-size: 2.5rem;
font-weight: bold;
color: #1f77b4;
margin-bottom: 0.5rem;
}
.sub-header {
font-size: 1.2rem;
color: #666;
margin-bottom: 2rem;
}
.result-box {
background-color: #f0f2f6;
padding: 1.5rem;
border-radius: 0.5rem;
margin-top: 1rem;
}
</style>
""", unsafe_allow_html=True)
# Header
st.markdown('<div class="main-header">π Oracle Fusion AR Invoice Viewer</div>', unsafe_allow_html=True)
st.markdown('<div class="sub-header">Query your Oracle Fusion Accounts Receivable data</div>', unsafe_allow_html=True)
# Sidebar for credentials
with st.sidebar:
st.header("π Oracle Credentials")
username = st.text_input("Username", key="username", help="Your Oracle Fusion username")
password = st.text_input("Password", type="password", key="password", help="Your Oracle Fusion password")
st.divider()
st.info("π‘ **Tip**: Your credentials are only sent to the MCP server and are never stored.")
if st.button("Test Connection"):
if username and password:
with st.spinner("Testing connection..."):
try:
response = httpx.post(
f"{API_BASE_URL}/api/list-invoices",
json={"username": username, "password": password, "limit": 1},
timeout=30.0
)
if response.status_code == 200:
st.success("β
Connection successful!")
else:
st.error(f"β Connection failed: {response.json().get('error', 'Unknown error')}")
except Exception as e:
st.error(f"β Error: {str(e)}")
else:
st.warning("Please enter both username and password")
# Main content area with tabs
tab1, tab2, tab3 = st.tabs(["π List Invoices", "π Invoice Details", "π Advanced Search"])
# Tab 1: List Invoices
with tab1:
st.subheader("List and Filter Invoices")
col1, col2 = st.columns(2)
with col1:
customer_name = st.text_input("Customer Name (optional)", key="customer_name")
invoice_number = st.text_input("Invoice Number (optional)", key="invoice_number")
status = st.selectbox("Status (optional)", ["", "Open", "Closed", "Disputed", "Pending", "Cancelled"])
with col2:
date_from = st.date_input("From Date (optional)", value=None, key="date_from")
date_to = st.date_input("To Date (optional)", value=None, key="date_to")
limit = st.slider("Number of results", min_value=1, max_value=100, value=20)
if st.button("π List Invoices", key="list_btn", type="primary"):
if not username or not password:
st.error("β οΈ Please enter your Oracle credentials in the sidebar first!")
else:
with st.spinner("Fetching invoices..."):
try:
payload = {
"username": username,
"password": password,
"limit": limit
}
if customer_name:
payload["customer_name"] = customer_name
if invoice_number:
payload["invoice_number"] = invoice_number
if status:
payload["status"] = status
if date_from:
payload["date_from"] = date_from.strftime("%Y-%m-%d")
if date_to:
payload["date_to"] = date_to.strftime("%Y-%m-%d")
response = httpx.post(
f"{API_BASE_URL}/api/list-invoices",
json=payload,
timeout=30.0
)
if response.status_code == 200:
result = response.json()
if result["success"]:
st.success("β
Successfully retrieved invoices!")
for item in result["data"]:
st.markdown(item["text"])
else:
st.error(f"β Error: {result.get('error', 'Unknown error')}")
else:
st.error(f"β Server error: {response.status_code}")
except Exception as e:
st.error(f"β Error: {str(e)}")
# Tab 2: Invoice Details
with tab2:
st.subheader("Get Invoice Details")
invoice_id = st.text_input("Invoice ID", key="invoice_id", help="Enter the invoice ID to retrieve details")
if st.button("π Get Details", key="details_btn", type="primary"):
if not username or not password:
st.error("β οΈ Please enter your Oracle credentials in the sidebar first!")
elif not invoice_id:
st.error("β οΈ Please enter an Invoice ID!")
else:
with st.spinner("Fetching invoice details..."):
try:
response = httpx.post(
f"{API_BASE_URL}/api/invoice-details",
json={
"username": username,
"password": password,
"invoice_id": invoice_id
},
timeout=30.0
)
if response.status_code == 200:
result = response.json()
if result["success"]:
st.success("β
Successfully retrieved invoice details!")
for item in result["data"]:
st.markdown(item["text"])
else:
st.error(f"β Error: {result.get('error', 'Unknown error')}")
else:
st.error(f"β Server error: {response.status_code}")
except Exception as e:
st.error(f"β Error: {str(e)}")
# Tab 3: Advanced Search
with tab3:
st.subheader("Advanced Invoice Search")
search_query = st.text_input("Search Query (optional)", key="search_query",
help="Free text search across invoice data")
st.write("**Filter Options:**")
col1, col2 = st.columns(2)
with col1:
amount_gt = st.number_input("Amount Greater Than", min_value=0.0, value=0.0, step=100.0, key="amount_gt")
amount_lt = st.number_input("Amount Less Than", min_value=0.0, value=0.0, step=100.0, key="amount_lt")
with col2:
overdue_days = st.number_input("Overdue Days", min_value=0, value=0, step=1, key="overdue_days")
customer_id = st.text_input("Customer ID", key="customer_id")
search_limit = st.slider("Number of results", min_value=1, max_value=100, value=20, key="search_limit")
if st.button("π Search Invoices", key="search_btn", type="primary"):
if not username or not password:
st.error("β οΈ Please enter your Oracle credentials in the sidebar first!")
else:
with st.spinner("Searching invoices..."):
try:
payload = {
"username": username,
"password": password,
"limit": search_limit
}
if search_query:
payload["q"] = search_query
filters = {}
if amount_gt > 0:
filters["amountGreaterThan"] = amount_gt
if amount_lt > 0:
filters["amountLessThan"] = amount_lt
if overdue_days > 0:
filters["overdueDays"] = overdue_days
if customer_id:
filters["customerId"] = customer_id
if filters:
payload["filters"] = filters
response = httpx.post(
f"{API_BASE_URL}/api/search-invoices",
json=payload,
timeout=30.0
)
if response.status_code == 200:
result = response.json()
if result["success"]:
st.success("β
Successfully searched invoices!")
for item in result["data"]:
st.markdown(item["text"])
else:
st.error(f"β Error: {result.get('error', 'Unknown error')}")
else:
st.error(f"β Server error: {response.status_code}")
except Exception as e:
st.error(f"β Error: {str(e)}")
# Footer
st.divider()
st.markdown("""
<div style='text-align: center; color: #666; padding: 1rem;'>
<p>π Secure connection to Oracle Fusion AR MCP Server</p>
<p>Server: <code>https://web-production-7eb7.up.railway.app</code></p>
</div>
""", unsafe_allow_html=True)