Finance-Accounts/ar-aging-app/README.md

6.5 KiB
Raw Blame History

Amazon Accounts Receivable Aging Dashboard

Automates the Finance team's month-end Amazon Accounts Receivable Aging workbook: upload the month's Amazon Custom Unified Transaction files → get a structurally- and financially-identical Accounts Receivable Aging workbook, with validation, settlement reconciliation, exceptions, drill-down, and an audit trail.

Amazon only (no Walmart/TikTok/Temu/Shein/eBay/Shopify). Reverse-engineered from the Jan-2026 files; the USA receivable reproduces to the penny (11,110,433 = Detail!D11). See docs/accounts-receivable-logic.md.

Layout

backend/
  app/core/        # streaming parser + receivable engine (stdlib + openpyxl only)
  app/api/         # FastAPI app: routes, auth (login), deps
  app/services/    # jobs, persistence, FX-rate fetch, controls, retention
  app/db/          # SQLAlchemy models (20 tables) + engine (SQLite / MySQL)
  tests/           # 150+ tests: engine, API, auth, FX, dedup, Jan-2026 integration
  cli.py           # process files from the command line
  manage.py        # admin: add-user / set-password / dedupe-files / …
  migrate_sqlite_to_mysql.py   # one-time data migration for the AWS cutover
frontend/          # React + TS + Vite dashboard (nginx-served in production)
scripts/           # launchers: start.ps1 / start.bat (Windows) · start.command (macOS)
deploy/            # DEPLOY.md runbook + backup.sh (nightly mysqldump + S3 sync)
docs/              # system guide · AR logic · audit reports
docker-compose.yml            # dev stack        docker-compose.prod.yml  # production
.env.example                  # every setting, LOCAL + PRODUCTION sections

Production deployment (AWS)

One 8 GB server runs the whole stack with automatic HTTPS, MySQL, per-user login, and nightly S3 backups — see deploy/DEPLOY.md for the full runbook (provisioning, user creation, SQLite→MySQL migration, backups, updates). ≈ $5055/month.

cp .env.example .env.production    # fill the PRODUCTION section (domain, passwords, AR_SECRET_KEY)
docker compose --env-file .env.production -f docker-compose.prod.yml up -d --build
docker compose --env-file .env.production -f docker-compose.prod.yml exec backend \
  python manage.py add-user <user> --name "Full Name"

Key production behaviors:

  • One closing per month — every month stays saved and selectable (month switcher in the closing header); creating a second closing for an existing month requires an explicit override.
  • Duplicate-proof uploads — re-uploading a filename replaces it; identical content under another name is skipped. A month can never count a file twice.
  • Login (AR_AUTH) — per-user accounts via manage.py add-user; journal review/approval and FX confirmations record the signed-in user's verified name.
  • Password self-service — users change or recover passwords with a 6-digit code emailed to their account address (Settings, or "Forgot password?" on the login screen). Sent via the company Mail API (AR_MAIL_API_*), SMTP fallback; manage.py set-password remains the admin override.
  • Exchange rates — "Fetch month-end rates" pulls central-bank rates (Frankfurter, free, keyless; AR_FX_PROVIDER); fetched rates still require human confirmation (Control C5).
  • Completed closings are locked read-only; corrections need an explicit Reopen.
  • Crash-safe jobs — a restart mid-processing marks the closing as interrupted instead of leaving it stuck; generated exports are purged after AR_RETENTION_DAYS (uploads never are).

Run the app (development)

# 1. Configure the environment (SQLite by default — no database setup needed)
cp .env.example .env   # then fill the LOCAL section (AR_SECRET_KEY at minimum)

# Option A — Docker (backend + Vite hot reload)
docker compose up --build
# → http://localhost:5173  (API on :8000; uploads/exports on the ar_data volume)

# Option B — local processes
make install          # backend deps + npm install
make backend          # terminal 1 → FastAPI on :8000
make frontend         # terminal 2 → dashboard on http://localhost:5173

# Option C — Windows one-click (ports 8010/5174)
scripts\start.bat     # or: powershell -ExecutionPolicy Bypass -File scripts\start.ps1
# macOS one-click:
scripts/start.command

Then open the dashboard → New Closing → pick the month → drag in the month's Amazon files → Run processing → review → Download Full A/R Aging Excel.

Uploads and exports are stored under AR_DATA_DIR (default backend/data locally, /data in Docker). The database is a local SQLite file by default; set MYSQL_* in .env to use MySQL.

Run the engine headless (CLI)

cd backend && pip install -r requirements.txt
python cli.py "/path/USA…01 to 10 January,2026.xlsx" \
              "/path/USA…11 to 20 January,2026.xlsx" \
              "/path/USA…21 to 31 January,2026.xlsx" \
              --month-end 2026-01-31 --lag 2 --reserve-standard 125.44 --out AR_Aging_Jan26.xlsx

Tests

make test        # 155 fast tests: engine, API, auth, FX, upload dedup, month locking
make test-all    # + Jan-2026 reconciliation & sample-comparison (integration, ~4 min)
# point the integration tests at the sample files if not in the repo root:
AR_SAMPLE_DIR="/path/to/samples" make test-all

The suite runs against an isolated temporary database — it can never touch real data (a session-scoped guard asserts the isolation before anything runs).

Feature summary

Calculation engine

  • Settlement classification + receivable; USA Jan-26 = 11,110,433 verified to the penny
  • All 13 marketplaces reconcile to the penny vs the Finance workbook — per-market currency & FX, settlement-owner logic for cross-market EU chains, helper-row/pivot-sheet detection
  • AR roll-forward (opening + net revenue payouts = closing) with auto carry-forward, AR Ledger, Finance Summary, per-marketplace Journal Entry, Reconciliation Control
  • Header mapping with localized alias tables + admin rules UI; unmapped amounts are never silently excluded; storage-fee detection; full Excel audit workbook + Finance pack

Operations & security

  • Per-user login with emailed password codes; verified names on every sign-off
  • Six month-end controls (C1C6) block publication of any untrusted figure
  • Month-end FX fetched from central-bank data, gated by human confirmation
  • Duplicate-proof uploads, one-closing-per-month guard, completed-month locking
  • Production Docker stack (auto-HTTPS · MySQL · nightly S3 backups) + Gitea Actions CI