# Proiect: Import Bonuri Fiscale via Telegram/WhatsApp → ROA **Data:** 2026-02-03 **Status:** Analiză completă **Tags:** @work @project --- ## TL;DR Sistem pentru importul bonurilor fiscale de achiziție din Telegram/WhatsApp în contabilitatea ROA. OCR prin Doctr (cost zero, local). Integrare cu Oracle prin proceduri existente (PACK_CONTAFIN). --- ## 1. Obiective - **Input:** Bonuri fiscale trimise pe Telegram/WhatsApp (PDF/imagine) - **Procesare:** OCR local (Doctr) - cost zero - **Output:** Note contabile în Oracle (ACT, BAL, etc.) - **Aprobare:** Opțional - contabil verifică înainte de salvare finală --- ## 2. Arhitectură ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Telegram │ │ │ │ │ │ │ │ WhatsApp │────▶│ Clawdbot │────▶│ roa2web │────▶│ ROA Oracle │ └─────────────┘ │ (Bridge) │ │ (OCR+API) │ │ (PACK_ │ └─────────────┘ └─────────────┘ │ CONTAFIN) │ │ │ └─────────────┘ ▼ ▼ │ • Primește fișier • Doctr OCR • ACT_TEMP • Forward la API • PDF text layer • ACT, BAL • Răspuns user • JSON extrase • IREG_PART ``` --- ## 3. Componente Existente ### 3.1 roa2web (LXC 171 - claude-agent) | Component | Status | Locație | |-----------|--------|---------| | **OCR Engine** | ✅ Complet | `/workspace/roa2web/backend/modules/data_entry/services/ocr_engine.py` | | **Doctr** | ✅ Instalat | PyTorch backend, db_resnet50 + crnn_vgg16_bn | | **PaddleOCR** | ✅ Instalat | Backup engine | | **API OCR** | ✅ Funcțional | `POST /api/data-entry/ocr/extract` | | **Job Queue** | ✅ Complet | Async processing cu worker pool | | **Bot Telegram** | ⚠️ Parțial | Dashboard/sold, NU handler fișiere | ### 3.2 Schema Date OCR (ExtractionData) ```python ExtractionData: partner_name: str # nume furnizor cui: str # CUI furnizor receipt_date: date # data bon receipt_number: str # număr bon receipt_series: str # serie bon amount: Decimal # total tva_entries: List[TvaEntry] # TVA pe cote (A=19%, B=9%, etc.) tva_total: Decimal # total TVA payment_methods: List # CARD/NUMERAR address: str # adresă furnizor confidence_*: float # scoruri încredere ``` ### 3.3 Oracle (MARIUSM_AUTO) **Tabele principale:** | Tabel | Scop | |-------|------| | **ACT** | Note contabile | | **ACT_TEMP** | Staging pentru note | | **RUL** | Rulaje gestiuni | | **STOC** | Solduri stoc | | **BAL** | Balanță verificare | | **IREG_PARTENERI** | Evidență parteneri | | **BALANTA_PARTENERI** | Balanță parteneri | | **ATAS_ATASAMENTE** | Fișiere atașate (BLOB) | | **ATAS_REFERINTE** | Legături atașamente | | **NOM_FDOC** | Nomenclator tipuri documente | **Package-uri relevante:** | Package | Scop | |---------|------| | **PACK_CONTAFIN** | Salvare note contabile (principal) | | **PACK_FACTURARE** | Exemple de salvare (pentru vânzări) | | **PACK_PARTENERI** | Gestiune parteneri | --- ## 4. Formula Contabilă - Bon Fiscal Achiziție ### 4.1 Bon simplu (plătit cash) ``` Cheltuială = Furnizor: 6xx = 401 (valoare fără TVA) TVA deductibil = Furn: 4426 = 401 (TVA) Plată cash: 401 = 5311 (total cu TVA) ``` **Exemplu bon benzină 119 RON (100 + 19 TVA):** ```sql -- Linia 1: Cheltuială combustibil SCD='6022', SCC='401', SUMA=100.00 -- Linia 2: TVA deductibil SCD='4426', SCC='401', SUMA=19.00, PROC_TVA=1.19 -- Linia 3: Plată din casă SCD='401', SCC='5311', SUMA=119.00 ``` ### 4.2 Bon cu TVA la încasare ``` Cheltuială = Furnizor: 6xx = 401 TVA neexigibil = Furn: 4428 = 401 Plată cash: 401 = 5311 Exigibilizare TVA: 4426 = 4428 ``` ### 4.3 Conturi cheltuieli uzuale | Tip | Cont | Descriere | |-----|------|-----------| | Combustibil | 6022 | Combustibili | | Materiale | 6021 | Materiale auxiliare | | Rechizite | 6021 | Materiale auxiliare | | Piese | 6024 | Piese schimb | | Întreținere | 611 | Cheltuieli întreținere | | Transport | 624 | Cheltuieli transport | --- ## 5. Flux Oracle - Salvare Note Contabile ### 5.1 Proceduri PACK_CONTAFIN ```sql -- 1. INIȚIALIZARE SESIUNE PACK_CONTAFIN.INITIALIZEAZA_SCRIERE_ACT_RUL( TNIDUTIL NUMBER, -- ID utilizator TDDATAORA DATE, -- Data și ora TNAN NUMBER, -- An TNLUNA NUMBER, -- Luna TNSUPRASCRIERECOD NUMBER, -- 0/1 TNSUPRASCRIEREANLUNA NUMBER, -- 0/1 TNSCRIESTERGE NUMBER, -- 0=scrie, 2=șterge TNIDSUCURSALA NUMBER -- ID sucursală ); -- 2. INSERT ÎN ACT_TEMP (pentru fiecare linie) INSERT INTO ACT_TEMP ( LUNA, AN, COD, DATAIREG, DATAACT, DATASCAD, NRACT, SERIE_ACT, EXPLICATIA, SCD, ASCD, -- cont debit, analitic SCC, ASCC, -- cont credit, analitic SUMA, PROC_TVA, ID_FDOC, -- tip document ID_PARTD, ID_PARTC, -- parteneri ID_FACT, ID_VALUTA, ID_SUCURSALA ) VALUES (...); -- 3. FINALIZARE (transferă în ACT, actualizează BAL, etc.) PACK_CONTAFIN.FINALIZEAZA_SCRIERE_ACT_RUL( TNIDUTIL NUMBER, -- ID utilizator TNCOD NUMBER, -- Cod document TNSCRIESTERGE NUMBER, -- 0=scrie TNMODIFICARENOTA NUMBER, -- 0/1 TNSCRIECUMPVANZ NUMBER, -- 0/1 TCMESAJREFACERENOTA OUT VARCHAR2 -- Mesaj rezultat ); ``` ### 5.2 Ce face FINALIZEAZA intern ```sql -- La linia 8059 în PACK_CONTAFIN: pack_contafin.SCRIE_IN_ACT(user); -- ACT_TEMP → ACT + BAL pack_contafin.SCRIE_IN_RUL(user); -- RUL_TEMP → RUL (dacă există) pack_contafin.SCRIE_IN_RUL_OBINV(user); -- pentru obiecte inventar ``` --- ## 6. Structura ACT_TEMP ```sql ACT_TEMP ( LUNA NUMBER, AN NUMBER, COD NUMBER, DATAIREG DATE, NRACT NUMBER, DATAACT DATE, EXPLICATIA VARCHAR2(100), SCD VARCHAR2(10), -- Cont DEBIT ASCD VARCHAR2(20), -- Analitic debit SCC VARCHAR2(10), -- Cont CREDIT ASCC VARCHAR2(20), -- Analitic credit SUMA NUMBER, PROC_TVA NUMBER, -- Procent TVA (1.19, 1.09, etc.) ID_FDOC NUMBER, -- Tip document (din NOM_FDOC) ID_PARTD NUMBER, -- Partner debit ID_PARTC NUMBER, -- Partner credit ID_FACT NUMBER, -- ID factură (opțional) ID_VALUTA NUMBER, ID_SUCURSALA NUMBER, SERIE_ACT VARCHAR2(10), TVA_INCASARE NUMBER, -- 0/1 pentru TVA la încasare ... ) ``` --- ## 7. Optimizări Propuse ### 7.1 PDF Text Layer Extraction Adobe Scan creează PDF-uri cu text layer. Verificăm înainte de OCR: ```python import pdfplumber def extract_text_or_ocr(pdf_path): with pdfplumber.open(pdf_path) as pdf: text = "" for page in pdf.pages: page_text = page.extract_text() if page_text: text += page_text if text.strip(): # PDF are text layer - folosește-l direct return {"source": "pdf_layer", "text": text} else: # Nu are text - fallback la Doctr OCR return doctr_ocr(pdf_path) ``` **Beneficii:** - Instant vs. 2-5 sec OCR - 100% acuratețe vs. ~95% OCR - Zero procesare GPU ### 7.2 Mapare CUI → Cont Tabel pentru auto-detectare tip cheltuială: ```python CUI_CONT_MAP = { # Benzinării "RO1234567": "6022", # OMV "RO2345678": "6022", # Petrom "RO3456789": "6022", # Mol # Magazine bricolaj "RO10562600": "6021", # Dedeman # Default "DEFAULT": "6028" # Alte cheltuieli } ``` --- ## 8. Status Implementare (2026-02-03) | Component | Status | Note | |-----------|--------|------| | OCR (Doctr/PaddleOCR) | ✅ Testat | 34 sec per PDF | | Script OCR standalone | ✅ Funcțional | `/workspace/roa2web-telegram-test/` | | Python: INSERT ACT_TEMP | ✅ Testat | 3 linii: cheltuială + TVA + plată | | Mapare CUI → cont | ✅ Bază | 6022=combustibil, 6021=materiale | | Găsire partener | ✅ Funcțional | Caută în NOM_PARTENERI | | Conexiune Oracle | ✅ Testat | Server 10.0.20.121 | | Handler WhatsApp | 🔄 În pregătire | Clawdbot poate primi fișiere | | CALL PACK_CONTAFIN | ⏳ TODO | Finalizare cu procedurile Oracle | | UI aprobare | ⏳ TODO | Opțional | ### Scripturi create: - `/workspace/roa2web-telegram-test/process_and_save.py` - OCR → Oracle - `/workspace/roa2web-telegram-test/save_to_oracle.py` - test salvare Oracle ### Test efectuat: ``` PDF "benzina 07 aug. 2024.pdf" → OCR → Oracle ACT_TEMP CUI: RO11201891 Data: 2024-08-01 Total: 263.28 RON TVA: 42.04 (19%) Note: 6022=401, 4426=401, 401=5311 Status: DRY RUN OK ``` --- ## 9. Plan Implementare ### Faza 1: Handler Telegram (3-4h) - [ ] MessageHandler pentru imagini/PDF în bot - [ ] Forward la `/api/data-entry/ocr/extract` - [ ] Răspuns cu datele extrase (preview) ### Faza 2: PDF Optimization (1-2h) - [ ] Verificare text layer în PDF - [ ] Extracție directă dacă există - [ ] Fallback la Doctr ### Faza 3: Integrare Oracle (5-7h) - [ ] Conexiune Oracle din roa2web - [ ] Găsire/creare partener după CUI - [ ] INSERT în ACT_TEMP - [ ] Apel PACK_CONTAFIN proceduri - [ ] Salvare atașament (ATAS_ATASAMENTE) ### Faza 4: WhatsApp Bridge (4-6h) - [ ] Clawdbot handler pentru fișiere - [ ] Forward la roa2web API - [ ] Răspuns pe canal ### Faza 5: Aprobare & Polish (3-5h) - [ ] Workflow aprobare (opțional) - [ ] Mapare automată CUI → cont - [ ] Logging și error handling --- ## 10. Credențiale Test **Oracle Test Server:** ``` Host: 10.0.20.121 Port: 1521 SID: ROA User: CONTAFIN_ORACLE Pass: (în secrets/test.oracle_pass) Schema: MARIUSM_AUTO ``` **roa2web:** ``` LXC: 171 (claude-agent) Path: /workspace/roa2web Start: ./start.sh test ``` --- ## 11. Fișiere Proiect ``` roa2web-telegram-import/ ├── README.md # Acest fișier ├── schema-oracle.md # Detalii schema Oracle ├── flux-contabil.md # Formule contabile detaliate ├── api-spec.md # Specificații API (de creat) └── implementation-notes.md # Note implementare (de creat) ``` --- ## 12. Întrebări Deschise 1. **Workflow aprobare:** E necesar ca un contabil să aprobe înainte de salvare? 2. **Tip document (ID_FDOC):** Ce valoare pentru bonuri fiscale achiziție? 3. **Analitice:** Sunt necesare analitice pe conturi (ASCD, ASCC)? 4. **Sucursală:** Valoare default pentru ID_SUCURSALA? 5. **Atașamente:** Unde se face legătura ATAS_REFERINTE (ID_ENTITATE = ID_ACT)? --- *Analiză generată de Echo • 2026-02-03*