Files
gomag-vending/docs/PRD.md
Marius Mutu 461b26e8a7 Actualizare documentatie si plan pentru VFP Orchestrator
- CLAUDE.md: Actualizare completa cu architecture multi-tier si status project
- PRD.md: Adaugat plan detaliat pentru sync-comenzi-web.prg cu:
  * Flux complet de procesare (input/output/logging)
  * Helper functions necesare (CleanGoMagText, BuildArticlesJSON, etc.)
  * Cod complet pentru procesarea articolelor GoMag → Oracle
  * Gestionare cazuri speciale (shipping/billing/discounts)
  * Mapare detaliata Phase 2 cu P2-001 prin P2-004
- LLM_PROJECT_MANAGER_PROMPT.md: Update comenzi disponibile

Phase 1 Database Foundation: 75% complete, ready for P1-004 testing
Phase 2 VFP Integration: Fully planned, ready for implementation

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-09 20:33:31 +03:00

18 KiB

Product Requirements Document (PRD)

Import Comenzi Web → Sistem ROA

Versiune: 1.1
Data: 08 septembrie 2025
Status: Phase 1 - în progres (P1-001 complet)


📋 Overview

Sistem ultra-minimal pentru importul comenzilor de pe platforme web (GoMag, etc.) în sistemul ERP ROA Oracle. Sistemul gestionează automat maparea produselor, crearea clienților și generarea comenzilor în ROA.

Obiective Principale

  • Import automat comenzi web → ROA
  • Mapare flexibilă SKU → CODMAT (reîmpachetări + seturi)
  • Crearea automată a partenerilor noi
  • Interfață web pentru administrare mapări
  • Logging complet pentru troubleshooting

🎯 Scope & Limitations

În Scope

  • Import comenzi din orice platformă web (nu doar GoMag)
  • Mapare SKU complexe (1:1, 1:N, reîmpachetări, seturi)
  • Crearea automată parteneri + adrese
  • Interfață web admin pentru mapări
  • Logging în fișiere text

Out of Scope

  • Modificarea comenzilor existente în ROA
  • Sincronizare bidirectională
  • Gestionarea stocurilor
  • Interfață pentru utilizatori finali

🏗️ Architecture Overview

[Web Platform API] → [VFP Orchestrator] → [Oracle PL/SQL] → [Web Admin Interface]
       ↓                    ↓                    ↑                  ↑
   JSON Orders        Process & Log        Store/Update      Configuration

Tech Stack

  • Backend: Oracle PL/SQL packages
  • Integration: Visual FoxPro 9
  • Admin Interface: Flask + Oracle
  • Data: Oracle 11g/12c

📊 Data Model

Tabel Nou: ARTICOLE_TERTI

CREATE TABLE ARTICOLE_TERTI (
    sku           VARCHAR2(100),      -- SKU din platforma web
    codmat        VARCHAR2(50),       -- CODMAT din nom_articole
    cantitate_roa NUMBER(10,3),       -- Câte unități ROA = 1 web
    procent_pret  NUMBER(5,2),        -- % din preț pentru seturi
    activ         NUMBER(1),          -- 1=activ, 0=inactiv
    PRIMARY KEY (sku, codmat)
);

Exemple Mapări

  • Simplu: SKU "CAF01" → caută direct în nom_articole (nu se stochează)
  • Reîmpachetare: SKU "CAFE100" → CODMAT "CAF01", cantitate_roa=10
  • Set compus:
    • SKU "SET01" → CODMAT "CAF01", cantitate_roa=2, procent_pret=60
    • SKU "SET01" → CODMAT "FILT01", cantitate_roa=1, procent_pret=40

🔧 Components Specification

1. Package IMPORT_PARTENERI

Funcții:

  • cauta_sau_creeaza_partener() - Găsește partener existent sau creează unul nou
  • parseaza_adresa_semicolon() - Parsează adrese format: "JUD:București;BUCURESTI;Str.Victoriei;10"

Logica Căutare Parteneri:

  1. Caută după cod_fiscal (dacă > 3 caractere)
  2. Caută după denumire exactă
  3. Creează partener nou folosind pack_def.adauga_partener()
  4. Adaugă adresa folosind pack_def.adauga_adresa_partener2()

2. Package IMPORT_COMENZI

Funcții:

  • gaseste_articol_roa() - Rezolvă SKU → articole ROA
  • importa_comanda_web() - Import comandă completă

Logica Articole:

  1. Verifică ARTICOLE_TERTI pentru SKU
  2. Dacă nu există → caută direct în nom_articole (SKU = CODMAT)
  3. Calculează cantități și prețuri conform mapărilor
  4. Folosește PACK_COMENZI.adauga_comanda() și PACK_COMENZI.adauga_articol_comanda()

3. VFP Orchestrator (sync-comenzi-web.prg)

Responsabilități:

  • Rulare automată (timer 5 minute)
  • Citire comenzi din JSON-ul generat de gomag-vending.prg
  • Procesare comenzi GoMag cu mapare completă la Oracle
  • Apelare package-uri Oracle pentru import
  • Logging în fișiere text cu timestamp

Fluxul complet de procesare:

  1. Input: Citește output/gomag_orders_last7days_*.json
  2. Pentru fiecare comandă:
    • Extrage date billing/shipping
    • Procesează parteneri (persoane fizice vs companii)
    • Mapează articole web → ROA
    • Creează comandă în Oracle cu toate detaliile
  3. Output: Log complet în logs/sync_comenzi_YYYYMMDD.log

Funcții helper necesare:

  • CleanGoMagText() - Curățare HTML entities
  • ProcessGoMagOrder() - Procesare comandă completă
  • BuildArticlesJSON() - Transformare items → JSON Oracle
  • FormatAddressForOracle() - Adrese în format semicolon
  • HandleSpecialCases() - Shipping vs billing, discounts, etc.

Procesare Date GoMag pentru IMPORT_PARTENERI:

Decodare HTML entities în caractere simple (fără diacritice):

* Funcție de curățare text GoMag
FUNCTION CleanGoMagText(tcText)
  LOCAL lcResult
  lcResult = tcText
  lcResult = STRTRAN(lcResult, '&#259;', 'a')  && ă → a
  lcResult = STRTRAN(lcResult, '&#537;', 's')  && ș → s  
  lcResult = STRTRAN(lcResult, '&#539;', 't')  && ț → t
  lcResult = STRTRAN(lcResult, '&#238;', 'i')  && î → i
  lcResult = STRTRAN(lcResult, '&#226;', 'a')  && â → a
  RETURN lcResult
ENDFUNC

Pregătire date partener din billing GoMag:

* Pentru persoane fizice (când billing.company e gol):
IF EMPTY(loBilling.company.name)
  lcDenumire = CleanGoMagText(loBilling.firstname + ' ' + loBilling.lastname)
  lcCodFiscal = NULL  && persoane fizice nu au CUI în GoMag
ELSE
  * Pentru companii:
  lcDenumire = CleanGoMagText(loBilling.company.name)
  lcCodFiscal = loBilling.company.code  && CUI companie
ENDIF

* Formatare adresă pentru Oracle (format semicolon):
lcAdresa = "JUD:" + CleanGoMagText(loBilling.region) + ";" + ;
           CleanGoMagText(loBilling.city) + ";" + ;
           CleanGoMagText(loBilling.address)

* Date contact
lcTelefon = loBilling.phone
lcEmail = loBilling.email

Apel package Oracle IMPORT_PARTENERI:

* Apelare IMPORT_PARTENERI.cauta_sau_creeaza_partener
lcSQL = "SELECT IMPORT_PARTENERI.cauta_sau_creeaza_partener(?, ?, ?, ?, ?) AS ID_PART FROM dual"

* Executare cu parametri:
* p_cod_fiscal, p_denumire, p_adresa, p_telefon, p_email
lnIdPart = SQLEXEC(goConnectie, lcSQL, lcCodFiscal, lcDenumire, lcAdresa, lcTelefon, lcEmail, "cursor_result")

IF lnIdPart > 0 AND RECCOUNT("cursor_result") > 0
  lnPartnerID = cursor_result.ID_PART
  * Continuă cu procesarea comenzii...
ELSE
  * Log eroare partener
  WriteLog("ERROR: Nu s-a putut crea/găsi partenerul: " + lcDenumire)
ENDIF

Procesare Articole pentru IMPORT_COMENZI:

Construire JSON articole din items GoMag:

* Funcție BuildArticlesJSON - transformă items GoMag în format Oracle
FUNCTION BuildArticlesJSON(loItems)
  LOCAL lcJSON, i, loItem
  lcJSON = "["
  
  FOR i = 1 TO loItems.Count
    loItem = loItems.Item(i)
    
    IF i > 1
      lcJSON = lcJSON + ","
    ENDIF
    
    * Format JSON conform package Oracle: {"sku":"...", "cantitate":..., "pret":...}
    lcJSON = lcJSON + "{" + ;
      '"sku":"' + CleanGoMagText(loItem.sku) + '",' + ;
      '"cantitate":' + TRANSFORM(VAL(loItem.quantity)) + ',' + ;
      '"pret":' + TRANSFORM(VAL(loItem.price)) + ;
      "}"
  ENDFOR
  
  lcJSON = lcJSON + "]"
  RETURN lcJSON
ENDFUNC

Gestionare cazuri speciale:

* Informații adiționale pentru observații
lcObservatii = "Payment: " + CleanGoMagText(loOrder.payment.name) + "; " + ;
               "Delivery: " + CleanGoMagText(loOrder.delivery.name) + "; " + ;
               "Status: " + CleanGoMagText(loOrder.status) + "; " + ;
               "Source: " + CleanGoMagText(loOrder.source) + " " + CleanGoMagText(loOrder.sales_channel)

* Adrese diferite shipping vs billing
IF NOT (CleanGoMagText(loOrder.shipping.address) == CleanGoMagText(loBilling.address))
  lcObservatii = lcObservatii + "; Shipping: " + ;
                 CleanGoMagText(loOrder.shipping.address) + ", " + ;
                 CleanGoMagText(loOrder.shipping.city)
ENDIF

Apel package Oracle IMPORT_COMENZI:

* Conversie dată GoMag → Oracle
ldDataComanda = CTOD(SUBSTR(loOrder.date, 1, 10))  && "2025-08-27 16:32:43" → date

* JSON articole
lcArticoleJSON = BuildArticlesJSON(loOrder.items)

* Apelare IMPORT_COMENZI.importa_comanda_web
lcSQL = "SELECT IMPORT_COMENZI.importa_comanda_web(?, ?, ?, ?, ?, ?) AS ID_COMANDA FROM dual"

lnResult = SQLEXEC(goConnectie, lcSQL, ;
  loOrder.number, ;        && p_nr_comanda_ext
  ldDataComanda, ;         && p_data_comanda  
  lnPartnerID, ;           && p_id_partener (din pas anterior)
  lcArticoleJSON, ;        && p_json_articole
  NULL, ;                  && p_id_adresa_livrare (opțional)
  lcObservatii, ;          && p_observatii
  "cursor_comanda")

IF lnResult > 0 AND cursor_comanda.ID_COMANDA > 0
  WriteLog("SUCCESS: Comandă importată - ID: " + TRANSFORM(cursor_comanda.ID_COMANDA))
ELSE
  WriteLog("ERROR: Import comandă eșuat pentru: " + loOrder.number)
ENDIF

Note Importante:

  • Toate caracterele HTML trebuie transformate în ASCII simplu (fără diacritice)
  • Package-ul Oracle așteaptă text curat, fără entități HTML
  • Adresa trebuie în format semicolon cu prefix "JUD:" pentru județ
  • Cod fiscal NULL pentru persoane fizice este acceptabil
  • JSON articole: exact formatul {"sku":"...", "cantitate":..., "pret":...}
  • Conversie date GoMag: "2025-08-27 16:32:43"CTOD() pentru Oracle
  • Observații: concatenează payment/delivery/status/source pentru tracking
  • Gestionează adrese diferite shipping vs billing în observații
  • Utilizează conexiunea Oracle existentă (goConnectie)

4. Web Admin Interface

Funcționalități:

  • Vizualizare mapări SKU existente
  • Adăugare/editare/ștergere mapări
  • Validare date înainte de salvare
  • Interface responsive cu Flask

📋 Implementation Phases

Phase 1: Database Foundation (Ziua 1) - 🎯 75% COMPLET

  • P1-001: Creare tabel ARTICOLE_TERTI + Docker setup
  • P1-002: Package IMPORT_PARTENERI complet
  • P1-003: Package IMPORT_COMENZI complet
  • 🔄 P1-004: Testare manuală package-uri (NEXT UP!)

Phase 2: VFP Integration (Ziua 2)

  • P2-001: Adaptare gomag-vending.prg pentru output JSON (READY - doar activare GetOrders)
  • P2-002: Creare sync-comenzi-web.prg cu toate helper functions
  • P2-003: Testare import comenzi end-to-end cu date reale GoMag
  • P2-004: Configurare logging și error handling complet

Detalii P2-002 (sync-comenzi-web.prg):

  • CleanGoMagText() - HTML entities cleanup
  • ProcessGoMagOrder() - Main orchestrator per order
  • BuildArticlesJSON() - Items conversion for Oracle
  • FormatAddressForOracle() - Semicolon format
  • HandleSpecialCases() - Shipping/billing/discounts/payments
  • Integration cu logging existent din utils.prg
  • Timer-based execution (5 minute intervals)
  • Complete error handling cu retry logic

Phase 3: Web Admin Interface (Ziua 3)

  • Flask app cu connection pool Oracle
  • HTML/CSS pentru admin mapări
  • JavaScript pentru CRUD operații
  • Testare interfață web

Phase 4: Testing & Deployment (Ziua 4)

  • Testare integrată pe comenzi reale
  • Validare mapări complexe (seturi)
  • Configurare environment production
  • Documentație utilizare

📁 File Structure

/api/                               # ✅ Flask Admin Interface
  ├── admin.py                      # ✅ Flask app cu Oracle pool
  ├── 01_create_table.sql           # ✅ Tabel ARTICOLE_TERTI 
  ├── 02_import_parteneri.sql       # ✅ Package parteneri (COMPLET)
  ├── 03_import_comenzi.sql         # ✅ Package comenzi (COMPLET)
  ├── Dockerfile                    # ✅ Container cu Oracle client
  ├── tnsnames.ora                  # ✅ Config Oracle ROA
  ├── .env                          # ✅ Environment variables
  └── requirements.txt              # ✅ Dependencies Python

/docs/                              # 📋 Project Documentation
  ├── PRD.md                        # ✅ Product Requirements Document
  ├── LLM_PROJECT_MANAGER_PROMPT.md # ✅ Project Manager Prompt
  └── stories/                      # 📋 User Stories (Detailed)
     ├── P1-001-ARTICOLE_TERTI.md   # ✅ Story P1-001 (COMPLET)
     ├── P1-002-Package-IMPORT_PARTENERI.md # ✅ Story P1-002 (COMPLET)
     ├── P1-003-Package-IMPORT_COMENZI.md   # ✅ Story P1-003 (COMPLET)
     └── P1-004-Testing-Manual-Packages.md  # 📋 Story P1-004

/vfp/                               # ⏳ VFP Integration (Phase 2)
  └── sync-comenzi-web.prg          # ⏳ Orchestrator principal

/docker-compose.yaml                # ✅ Container orchestration
/logs/                              # ✅ Logging directory

🔒 Business Rules

Parteneri

  • Căutare prioritate: cod_fiscal → denumire → creare nou
  • Persoane fizice (CUI 13 cifre): separă nume/prenume
  • Adrese: defaultează la București Sectorul 1 dacă nu găsește
  • Toate partenerele noi au ID_UTIL = -3 (sistem)

Articole

  • SKU simple (găsite direct în nom_articole): nu se stochează în ARTICOLE_TERTI
  • Mapări speciale: doar reîmpachetări și seturi complexe
  • Validare: suma procent_pret pentru același SKU să fie logic
  • Articole inactive: activ=0 (nu se șterg)

Comenzi

  • Folosește package-urile existente (PACK_COMENZI)
  • ID_GESTIUNE = 1, ID_SECTIE = 1, ID_POL = 0 (default)
  • Data livrare = data comenzii + 1 zi
  • Toate comenzile au INTERNA = 0 (externe)

📊 Success Metrics

Technical Metrics

  • Import success rate > 95%
  • Timpul mediu de procesare < 30s per comandă
  • Zero downtime pentru sistemul principal ROA
  • Log coverage 100% (toate operațiile logate)

Business Metrics

  • Reducerea timpului de introducere comenzi cu 90%
  • Eliminarea erorilor manuale de transcriere
  • Timpul de configurare mapări noi < 5 minute

🚨 Error Handling

Categorii Erori

  1. Erori conexiune Oracle: Retry logic + alertă
  2. SKU not found: Log warning + skip articol
  3. Partener invalid: Tentativă creare + log detalii
  4. Comenzi duplicate: Skip cu log info

Logging Format

2025-09-08 14:30:25 | COMANDA-123 | OK | ID:456789
2025-09-08 14:30:26 | COMANDA-124 | ERROR | SKU 'XYZ' not found

🔧 Configuration

Environment Variables (.env)

ORACLE_USER=CONTAFIN_ORACLE
ORACLE_PASSWORD=********
ORACLE_DSN=ROA_ROMFAST
TNS_ADMIN=/app
INSTANTCLIENTPATH=/opt/oracle/instantclient

VFP Configuration

  • Timer interval: 300 secunde (5 minute)
  • Conexiune Oracle prin goExecutor existent
  • Log files: sync_YYYYMMDD.log (rotație zilnică)

🎛️ Admin Interface Specification

Main Screen: SKU Mappings

  • Tabel editabil cu coloane: SKU, CODMAT, Cantitate ROA, Procent Preț, Activ
  • Inline editing cu auto-save
  • Filtrare și căutare
  • Export/Import mapări (CSV)
  • Validare în timp real

Features

  • Bulk operations (activare/dezactivare multiple)
  • Template mapări pentru tipuri comune
  • Preview calcul preț pentru teste
  • Audit trail (cine/când a modificat)

🏁 Definition of Done

Per Feature

  • Cod implementat și testat
  • Documentație actualizată
  • Error handling complet
  • Logging implementat
  • Review code efectuat

Per Phase

  • Toate feature-urile Phase complete
  • Testare integrată reușită
  • Performance requirements îndeplinite
  • Deployment verificat
  • Sign-off stakeholder

📞 Support & Maintenance

Monitoring

  • Log files în /logs/ cu rotație automată
  • Alertă email pentru erori critice
  • Dashboard cu statistici import (opcional Phase 2)

Backup & Recovery

  • Mapări ARTICOLE_TERTI incluse în backup-ul zilnic ROA
  • Config files versionate în Git
  • Procedură rollback pentru package-uri Oracle


📊 Progress Status - Phase 1 [🎯 75% COMPLET]

P1-001 COMPLET: Tabel ARTICOLE_TERTI

  • Implementat: 08 septembrie 2025, 22:30
  • Files: api/01_create_table.sql, api/admin.py, docker-compose.yaml
  • Status: Production ready

P1-002 COMPLET: Package IMPORT_PARTENERI

  • Implementat: 09 septembrie 2025, 10:30 (parallel development)
  • Key Features:
    • cauta_sau_creeaza_partener() - Search priority: cod_fiscal → denumire → create
    • parseaza_adresa_semicolon() - Flexible address parsing cu defaults
    • Individual vs company logic (CUI 13 digits)
    • Custom exceptions + autonomous transaction logging
  • Files: api/02_import_parteneri.sql
  • Status: Ready for testing

P1-003 COMPLET: Package IMPORT_COMENZI

  • Implementat: 09 septembrie 2025, 10:30 (parallel development)
  • Key Features:
    • gaseste_articol_roa() - Complex SKU mapping cu pipelined functions
    • importa_comanda_web() - Complete order import cu JSON parsing
    • Support mapări: simple, reîmpachetări, seturi complexe
    • Performance monitoring < 30s per comandă
    • Integration cu PACK_COMENZI.adauga_comanda/adauga_articol_comanda
  • Files: api/03_import_comenzi.sql, import_log table
  • Status: Ready for testing

🔄 NEXT UP: P1-004 Testing Manual Packages

  • Obiectiv: Testare completă cu date reale ROA
  • Dependencies: P1-001 , P1-002 , P1-003
  • Estimate: 4-6 ore
  • Risk: LOW (testing only)

📋 User Stories Reference

Toate story-urile pentru fiecare fază sunt stocate în docs/stories/ cu detalii complete:

Phase 1 Stories [🎯 75% COMPLET]

Faze Viitoare

  • Phase 2: VFP Integration (stories vor fi generate după P1 completion)
  • Phase 3: Web Admin Interface
  • Phase 4: Testing & Deployment

Document Owner: Development Team
Last Updated: 09 septembrie 2025, 12:15 (Updated VFP Orchestrator plan)
Next Review: După P1-004 completion (Phase 1 FINALIZAT!)