stampli-bulk-editor/scan_pending.py

87 lines
2.5 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""
Scan the Stampli "Pending Approval" tab and report rows with incorrect pay dates.
Usage:
python scan_pending.py
python scan_pending.py --snap
"""
import argparse
import time
from pathlib import Path
from playwright.sync_api import sync_playwright
from stampli_core import (
launch_browser,
navigate,
active_page,
wait_for_login,
needs_login,
collect_scan_rows,
compute_scan_results,
PENDING_APPROVAL_URL,
)
def main():
parser = argparse.ArgumentParser(description="Scan Stampli Pending Approval")
parser.add_argument("--snap", action="store_true")
args = parser.parse_args()
with sync_playwright() as p:
browser = launch_browser(p)
navigate(browser, PENDING_APPROVAL_URL)
time.sleep(3)
page = active_page(browser)
if needs_login(page):
if not wait_for_login(browser, on_status=print):
browser.close()
return
page = active_page(browser)
print("Waiting for page to settle...")
time.sleep(3)
if args.snap:
html = page.content()
snap_path = Path(__file__).parent / "pending_snapshot.html"
with open(snap_path, "w") as f:
f.write(html)
print(f"Saved snapshot to {snap_path}")
print("\nScanning Pending Approval rows...\n")
all_rows = collect_scan_rows(page)
print(f"Found {len(all_rows)} rows\n")
results, incorrect = compute_scan_results(all_rows)
print(
f" {'Invoice':<20s} {'Vendor':<35s} {'Due':<12s} {'Pay Date':<12s} {'Expected':<12s} {'Status'}"
)
print(f" {'-' * 20} {'-' * 35} {'-' * 12} {'-' * 12} {'-' * 12} {'-' * 8}")
for r in results:
print(
f" {r['invoicesNumbers']:<20s} {r['vendorName'][:35]:<35s} "
f"{r['dueDate']:<12s} {r['sendPaymentOn']:<12s} {r['expected']:<12s} {r['status']}"
)
print(
f"\n{len(incorrect)} rows with incorrect pay dates out of {len(all_rows)} total."
)
if incorrect:
print("\nIncorrect rows:")
for r in incorrect:
print(
f" {r['invoicesNumbers']:<20s} {r['vendorName'][:35]:<35s} "
f"pay={r['sendPaymentOn']} (due={r['dueDate']})"
)
input("\nPress Enter to close the browser...")
browser.close()
if __name__ == "__main__":
main()