- OCR via roa2web API - SQLite via API (payment_methods, tva_breakdown) - Oracle: partener, TVA încasare (4426/4428), ID_FDOC=17 - ID_JTVA_COLOANA per cotă TVA - TAXCODE (TVAI pentru firma TVA încasare) - Suport multiple cote TVA în același bon - Plată CARD: fără 401=5311 (se face la extras)
387 lines
11 KiB
Markdown
387 lines
11 KiB
Markdown
# 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*
|