102a8603-26df-462f-a56d-01cee292f6f6

This commit is contained in:
Z User committed 2026-10-26 16:00:34 +00:00
1 parent 40805e16cd
commit 85c4006803
19 files changed
+987

No files matched your search

+109
View File
@@ -0,0 +1,109 @@
#!/usr/bin/env bash
# Verify Accounting module (Haben-inspired German accounting)
set -u
cd /home/z/my-project
BASE=http://127.0.0.1:3000
SHOTS=/home/z/my-project/aos-shots
mkdir -p "$SHOTS"
echo "=== Start server ==="
pkill -f "next dev" 2>/dev/null; pkill -f "tee dev.log" 2>/dev/null; sleep 2
bun run dev > dev.log 2>&1 &
SRV=$!
for i in $(seq 1 90); do curl -s -o /dev/null "$BASE/" 2>/dev/null && break; sleep 1; done
echo " ready after ${i}s"; sleep 2
echo "=== API tests ==="
echo -n " /api/aos/accounting -> "; curl -s -o /dev/null -w "HTTP %{http_code}\n" "$BASE/api/aos/accounting"
curl -s "$BASE/api/aos/accounting" | python3 -c "
import sys,json
d=json.load(sys.stdin)
v=d['vat']
print(f' VAT: current period {v[\"current\"][\"periodMonth\"]}/{v[\"current\"][\"periodYear\"]} status={v[\"current\"][\"status\"]} payable={v[\"current\"][\"payableCents\"]/100:.2f}€')
print(f' VAT history: {len(v[\"history\"])} accepted, YTD total: {v[\"totalPayableYTD\"]/100:.2f}€')
e=d['eur']
print(f' EÜR: profit {e[\"totalProfit\"]/100:.2f}€, income {e[\"totalIncome\"]/100:.2f}€, cost {e[\"totalCost\"]/100:.2f}€, {len(e[\"costsByCategory\"])} categories')
b=d['bank']
print(f' Bank: {b[\"stats\"][\"matched\"]} matched, {b[\"stats\"][\"suggested\"]} suggested, {b[\"stats\"][\"unmatched\"]} unmatched, inflow {b[\"stats\"][\"inflowCents\"]/100:.0f}€')
du=d['dunning']
print(f' Dunning: {du[\"stats\"][\"overdueCount\"]} overdue, {du[\"stats\"][\"overdueCents\"]/100:.2f}€, {du[\"stats\"][\"dunningSent\"]} runs')
" 2>/dev/null
echo ""
echo "=== Test VAT submit to ELSTER ==="
VAT_ID=$(curl -s "$BASE/api/aos/accounting" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['vat']['current']['id'])" 2>/dev/null)
echo " current VAT id: $VAT_ID"
if [ -n "$VAT_ID" ]; then
RES=$(curl -s -X PATCH "$BASE/api/aos/accounting/vat/$VAT_ID/submit")
echo " submit result: $(echo "$RES" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'status={d[\"vat\"][\"status\"]}, elsterRef={d[\"elsterRef\"]}')" 2>/dev/null)"
fi
echo ""
echo "=== Test bank match ==="
# find a suggested bank tx
TX_ID=$(curl -s "$BASE/api/aos/accounting" | python3 -c "
import sys,json
d=json.load(sys.stdin)
for t in d['bank']['transactions']:
if t['matchedStatus']=='suggested':
print(t['id']); break
" 2>/dev/null)
echo " suggested tx id: $TX_ID"
# find an unpaid invoice to match against
INV_ID=$(curl -s "$BASE/api/aos/finance" | python3 -c "
import sys,json
d=json.load(sys.stdin)
for i in d['invoices']:
if i['status'] in ('sent','overdue'):
print(i['id']); break
" 2>/dev/null)
echo " invoice id to match: $INV_ID"
if [ -n "$TX_ID" ] && [ -n "$INV_ID" ]; then
RES=$(curl -s -X POST "$BASE/api/aos/accounting/bank/$TX_ID/match" -H 'content-type: application/json' -d "{\"invoiceId\":\"$INV_ID\"}")
echo " match result: $(echo "$RES" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'tx status={d[\"transaction\"][\"matchedStatus\"]}, invoice={d[\"invoiceNumber\"]}')" 2>/dev/null)"
fi
echo ""
echo "=== Browser: Accounting view ==="
agent-browser open "$BASE/" >/dev/null 2>&1
agent-browser wait --load networkidle >/dev/null 2>&1 || true
agent-browser wait 3000 >/dev/null 2>&1
agent-browser set viewport 1440 900 >/dev/null 2>&1
# navigate via snapshot ref (more reliable than find text)
agent-browser snapshot -i >/tmp/s.txt 2>&1
ACCT=$(grep -i 'button "Buchhaltung"' /tmp/s.txt | grep -oE 'ref=e[0-9]+' | head -1)
echo " Buchhaltung nav ref: $ACCT"
[ -n "$ACCT" ] && agent-browser click "$ACCT" >/dev/null 2>&1
agent-browser wait 3000 >/dev/null 2>&1
H1=$(agent-browser get text h1 2>/dev/null | head -1)
echo " Accounting H1: $H1"
agent-browser screenshot --full "$SHOTS/v13-accounting-vat.png" >/dev/null 2>&1 && echo " VAT shot OK"
echo "=== Switch to EÜR tab ==="
agent-browser find role tab click --name "EÜR" >/dev/null 2>&1 || agent-browser find text "EÜR" click >/dev/null 2>&1
agent-browser wait 2000 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v13-accounting-eur.png" >/dev/null 2>&1 && echo " EÜR shot OK"
echo "=== Switch to Bankabgleich tab ==="
agent-browser find role tab click --name "Bankabgleich" >/dev/null 2>&1 || agent-browser find text "Bankabgleich" click >/dev/null 2>&1
agent-browser wait 2000 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v13-accounting-bank.png" >/dev/null 2>&1 && echo " Bank shot OK"
echo "=== Switch to Mahnwesen tab ==="
agent-browser find role tab click --name "Mahnwesen" >/dev/null 2>&1 || agent-browser find text "Mahnwesen" click >/dev/null 2>&1
agent-browser wait 2000 >/dev/null 2>&1
agent-browser screenshot --full "$SHOTS/v13-accounting-dunning.png" >/dev/null 2>&1 && echo " Dunning shot OK"
echo ""
echo "=== Errors ==="
agent-browser errors 2>&1 | head -8
echo "--- console last 5 ---"
agent-browser console 2>&1 | tail -5
echo ""
agent-browser close >/dev/null 2>&1
kill $SRV 2>/dev/null
echo "=== dev.log errors ==="
grep -iE "error|⨯|500" dev.log | grep -v SIGTERM | tail -8
echo "=== DONE ==="
ls -la "$SHOTS"/v13-* 2>/dev/null | tail -6