# GoMag Vending - Import Comenzi Web → ROA Oracle System automat de import comenzi din platforma GoMag in sistemul ERP ROA Oracle. ## Arhitectura ``` [GoMag API] → [VFP Orchestrator] → [Oracle PL/SQL] → [FastAPI Admin] ↓ ↓ ↑ ↑ JSON Orders Process & Log Store/Update Dashboard + Config ``` ### Stack Tehnologic - **Database:** Oracle PL/SQL packages (PACK_IMPORT_PARTENERI, PACK_IMPORT_COMENZI) - **Integrare:** Visual FoxPro 9 (gomag-vending.prg, sync-comenzi-web.prg) - **Admin/Dashboard:** FastAPI + Jinja2 + Oracle pool + SQLite - **Date:** Oracle 11g/12c (schema ROA), SQLite (tracking local) --- ## Quick Start ### Prerequisite - Python 3.10+ - Oracle Instant Client 21.x (optional — suporta si thin mode pentru Oracle 12.1+) ### Instalare ```bash # Din project root (gomag/) pip install -r api/requirements.txt cp api/.env.example api/.env # Editeaza api/.env cu datele de conectare Oracle ``` ### Pornire server **Important:** serverul trebuie pornit **din project root**, nu din `api/`: ```bash # Din gomag/ python -m uvicorn api.app.main:app --host 0.0.0.0 --port 5003 ``` Sau folosind scriptul inclus: ```bash ./start.sh ``` Deschide `http://localhost:5003` in browser. ### Testare **Test A - Basic (fara Oracle):** ```bash python api/test_app_basic.py ``` Verifica importuri de module + rute GET. Asteptat: 32/33 PASS (1 fail pre-existent `/sync` HTML). **Test C - Integrare Oracle:** ```bash python api/test_integration.py ``` Necesita Oracle activ. Verifica health, mappings CRUD, article search, validation, sync. --- ## Configurare (.env) Copiaza `.env.example` si completeaza: ```bash cp api/.env.example api/.env ``` | Variabila | Descriere | Exemplu | |-----------|-----------|---------| | `ORACLE_USER` | User Oracle | `MARIUSM_AUTO` | | `ORACLE_PASSWORD` | Parola Oracle | `secret` | | `ORACLE_DSN` | TNS alias | `ROA_CENTRAL` | | `TNS_ADMIN` | Cale absoluta la tnsnames.ora | `/mnt/e/.../gomag/api` | | `INSTANTCLIENTPATH` | Cale Instant Client (thick mode) | `/opt/oracle/instantclient_21_15` | | `FORCE_THIN_MODE` | Thin mode fara Instant Client | `true` | | `SQLITE_DB_PATH` | Path SQLite (relativ la project root) | `api/data/import.db` | | `JSON_OUTPUT_DIR` | Folder JSON-uri VFP (relativ la project root) | `vfp/output` | | `APP_PORT` | Port HTTP | `5003` | | `ID_POL` | ID Politica ROA | `39` | | `ID_GESTIUNE` | ID Gestiune ROA | `0` | | `ID_SECTIE` | ID Sectie ROA | `6` | **Nota Oracle mode:** - **Thick mode** (Oracle 10g/11g): seteaza `INSTANTCLIENTPATH` - **Thin mode** (Oracle 12.1+): seteaza `FORCE_THIN_MODE=true`, sterge `INSTANTCLIENTPATH` --- ## Structura Proiect ``` gomag/ ├── api/ # FastAPI Admin + Dashboard │ ├── app/ │ │ ├── main.py # Entry point, lifespan, logging │ │ ├── config.py # Settings (pydantic-settings + .env) │ │ ├── database.py # Oracle pool + SQLite schema + migrari │ │ ├── routers/ # Endpoint-uri HTTP │ │ │ ├── health.py # GET /health │ │ │ ├── dashboard.py # GET / (HTML) │ │ │ ├── mappings.py # /mappings, /api/mappings │ │ │ ├── articles.py # /api/articles/search │ │ │ ├── validation.py # /api/validate/* │ │ │ └── sync.py # /api/sync/* + /api/dashboard/orders │ │ ├── services/ │ │ │ ├── sync_service.py # Orchestrare: JSON→validate→import │ │ │ ├── import_service.py # Import comanda in Oracle ROA │ │ │ ├── mapping_service.py # CRUD ARTICOLE_TERTI + pct_total │ │ │ ├── sqlite_service.py # Tracking runs/orders/missing SKUs │ │ │ ├── order_reader.py # Citire gomag_orders_page*.json │ │ │ ├── validation_service.py │ │ │ ├── article_service.py │ │ │ └── scheduler_service.py # APScheduler timer │ │ ├── templates/ # Jinja2 HTML │ │ └── static/ # CSS + JS │ ├── database-scripts/ # Oracle SQL (ARTICOLE_TERTI, packages) │ ├── data/ # SQLite DB (import.db) │ ├── .env # Configurare locala (nu in git) │ ├── .env.example # Template configurare │ ├── test_app_basic.py # Test A - fara Oracle │ ├── test_integration.py # Test C - cu Oracle │ └── requirements.txt ├── vfp/ # VFP Integration │ ├── gomag-vending.prg # Client GoMag API (descarca JSON-uri) │ ├── sync-comenzi-web.prg # Orchestrator VFP │ ├── utils.prg # Utilitare (log, settings, connectivity) │ └── output/ # JSON-uri descarcate (gomag_orders_page*.json) ├── logs/ # Log-uri aplicatie (sync_comenzi_*.log) ├── docs/ # Documentatie (PRD, stories) ├── start.sh # Script pornire (Linux/WSL) └── CLAUDE.md # Instructiuni pentru AI assistants ``` --- ## Dashboard Features ### Sync Panel - Start sync manual sau scheduler automat (5/10/30 min) - Progress live: `"Import 45/80: #CMD-1234 Ion Popescu"` - Smart polling: 30s idle → 3s cand ruleaza → auto-refresh tabela - Last sync clickabil → jurnal detaliat ### Comenzi - Filtru perioada: 3z / 7z / 30z / 3 luni / toate / custom - Status pills cu conturi totale pe perioada (nu per-pagina) - Cautare integrata in bara de filtre - Coloana Client cu tooltip `▲` cand persoana livrare ≠ facturare - Paginare sus + jos, selector rezultate per pagina (25/50/100/250) ### Mapari SKU - Badge `✓ 100%` / `⚠ 80%` per grup SKU - Filtru Complete / Incomplete - Verificare duplicat SKU-CODMAT (409 cu optiune de restaurare) ### SKU-uri Lipsa - Cautare dupa SKU sau nume produs - Filtru Nerezolvate / Rezolvate / Toate cu conturi - Re-scan cu progress inline si banner rezultat --- ## Fluxul de Import ``` 1. VFP descarca comenzi GoMag API → vfp/output/gomag_orders_page*.json 2. FastAPI citeste JSON-urile (order_reader) 3. Valideaza SKU-uri contra ARTICOLE_TERTI + NOM_ARTICOLE (validation_service) 4. Import_service creeaza/cauta partener in Oracle (shipping person = facturare) 5. PACK_IMPORT_COMENZI.importa_comanda_web() insereaza comanda in ROA 6. Rezultate salvate in SQLite (orders, sync_run_orders, order_items) ``` ### Reguli Business - **Persoana**: shipping name = persoana pe eticheta = beneficiarul facturii - **Adresa**: cand billing ≠ shipping → adresa shipping pentru ambele (facturare + livrare) - **SKU simplu**: gasit direct in NOM_ARTICOLE → nu se stocheaza in ARTICOLE_TERTI - **SKU cu repackaging**: un SKU → CODMAT cu cantitate diferita - **SKU set complex**: un SKU → multiple CODMAT-uri cu procente de pret --- ## Status Implementare | Faza | Status | Descriere | |------|--------|-----------| | Phase 1: Database Foundation | ✅ Complet | ARTICOLE_TERTI, PACK_IMPORT_PARTENERI, PACK_IMPORT_COMENZI | | Phase 2: VFP Integration | ✅ Complet | gomag-vending.prg, sync-comenzi-web.prg | | Phase 3-4: FastAPI Dashboard | ✅ Complet | Redesign UI, smart polling, filter bar, paginare, tooltip | | Phase 5: Production | 🔄 In Progress | Logging ✅, Auth ⏳, SMTP ⏳, NSSM service ⏳ | --- ## WSL2 Note - `uvicorn --reload` **nu functioneaza** pe `/mnt/e/` (WSL2 limitation) — restarta manual - Serverul trebuie pornit din **project root** (`gomag/`), nu din `api/` - `JSON_OUTPUT_DIR` si `SQLITE_DB_PATH` sunt relative la project root