feat: Add data-entry-app for fiscal receipts with approval workflow
New application for entering fiscal receipts (bonuri fiscale) with: Backend (FastAPI + SQLModel + Alembic): - Receipt, ReceiptAttachment, AccountingEntry models - CRUD operations with async SQLite database - Workflow: DRAFT → PENDING_REVIEW → APPROVED/REJECTED - Auto-generation of accounting entries with VAT calculation - File upload support (images, PDFs) - Predefined expense types (Fuel, Materials, Office, etc.) - Nomenclature service for partners, accounts, cash registers Frontend (Vue.js 3 + PrimeVue + Pinia): - ReceiptsListView with filters and stats - ReceiptCreateView with image upload - ReceiptDetailView with accounting entries - ReceiptApprovalView for accountant approval Documentation: - REQUIREMENTS.md with functional specifications - ARCHITECTURE.md with technical decisions - CLAUDE.md for AI assistant guidance Phase 1 MVP uses SQLite, prepared for Oracle integration in Phase 2. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
275
docs/data-entry/ARCHITECTURE.md
Normal file
275
docs/data-entry/ARCHITECTURE.md
Normal file
@@ -0,0 +1,275 @@
|
||||
# Architecture: Data Entry App
|
||||
|
||||
## Overview
|
||||
|
||||
Aplicatie separata pentru introducere date in ERP, cu workflow de aprobare si staging area inainte de sincronizare in Oracle.
|
||||
|
||||
## Decizii Arhitecturale
|
||||
|
||||
### 1. SQLModel + Alembic
|
||||
|
||||
**Alegere**: SQLModel (Pydantic + SQLAlchemy) cu Alembic pentru migrari
|
||||
|
||||
**Motivatie**:
|
||||
- Creat de autorul FastAPI - integrare perfecta
|
||||
- Un model = Pydantic + SQLAlchemy - nu duplici definitii
|
||||
- Async support nativ
|
||||
- Alembic - standard industrial pentru migrari
|
||||
- Validare automata - Pydantic valideaza input, SQLAlchemy gestioneaza DB
|
||||
|
||||
**Alternative considerate**:
|
||||
- SQLAlchemy pur: Mai verbose, necesita scheme Pydantic separate
|
||||
- Tortoise ORM: Async nativ dar comunitate mai mica
|
||||
- Peewee: Simplu dar fara async
|
||||
|
||||
### 2. Separare de Reports-App
|
||||
|
||||
**Alegere**: Aplicatie separata in `data-entry-app/`
|
||||
|
||||
**Motivatie**:
|
||||
- Responsabilitati diferite: reports = read-only, data-entry = write
|
||||
- Lifecycle diferit: data-entry poate avea releases mai frecvente
|
||||
- Risc izolat: bug in data-entry nu afecteaza raportarile
|
||||
- Scalare independenta
|
||||
|
||||
**Shared Components**:
|
||||
- `shared/database/oracle_pool.py` - conexiune Oracle pentru nomenclatoare
|
||||
- `shared/auth/` - autentificare JWT comuna
|
||||
|
||||
### 3. Workflow cu Staging Area
|
||||
|
||||
**Alegere**: SQLite local ca staging, apoi sync in Oracle
|
||||
|
||||
**Motivatie**:
|
||||
- Permite lucru offline (utilizator poate completa bonuri)
|
||||
- Review de contabil inainte de date in Oracle
|
||||
- Rollback simplu (stergem din SQLite)
|
||||
- Audit trail complet
|
||||
|
||||
**Flow**:
|
||||
```
|
||||
User Input → SQLite (staging) → Contabil Review → Oracle (final)
|
||||
```
|
||||
|
||||
### 4. Storage Fisiere
|
||||
|
||||
**Alegere**: Filesystem local cu referinte in DB
|
||||
|
||||
**Motivatie**:
|
||||
- Simplu de implementat si backup
|
||||
- Performanta buna pentru imagini
|
||||
- Poate migra la S3/Azure Blob daca e nevoie
|
||||
|
||||
**Structura**:
|
||||
```
|
||||
data/uploads/
|
||||
{year}/
|
||||
{month}/
|
||||
{uuid}.{ext}
|
||||
```
|
||||
|
||||
## Diagrama Componente
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ data-entry-app │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Frontend │────▶│ Backend │────▶│ SQLite │ │
|
||||
│ │ Vue.js │ │ FastAPI │ │ (staging) │ │
|
||||
│ │ :3010 │ │ :8003 │ │ │ │
|
||||
│ └──────────────┘ └──────┬───────┘ └──────────────┘ │
|
||||
│ │ │
|
||||
│ │ Nomenclatoare │
|
||||
│ ▼ │
|
||||
│ ┌──────────────┐ │
|
||||
│ │ Oracle │ │
|
||||
│ │ (read-only) │ │
|
||||
│ └──────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Model de Date
|
||||
|
||||
### Receipt (Bon Fiscal)
|
||||
|
||||
```
|
||||
receipts
|
||||
├── id (PK)
|
||||
├── receipt_type: enum(bon_fiscal, chitanta)
|
||||
├── direction: enum(cheltuiala, incasare)
|
||||
├── receipt_number, receipt_series
|
||||
├── receipt_date, amount, description
|
||||
├── company_id, partner_id, partner_name
|
||||
├── cash_register_id, cash_register_name
|
||||
├── expense_type_code
|
||||
├── status: enum(draft, pending_review, approved, rejected, synced)
|
||||
├── created_by, created_at, updated_at
|
||||
├── submitted_at, reviewed_by, reviewed_at
|
||||
├── rejection_reason
|
||||
└── oracle_synced_at, oracle_act_id, oracle_error
|
||||
```
|
||||
|
||||
### ReceiptAttachment (Atasamente)
|
||||
|
||||
```
|
||||
receipt_attachments
|
||||
├── id (PK)
|
||||
├── receipt_id (FK)
|
||||
├── filename, stored_filename
|
||||
├── file_path, file_size, mime_type
|
||||
└── uploaded_at
|
||||
```
|
||||
|
||||
### AccountingEntry (Note Contabile)
|
||||
|
||||
```
|
||||
accounting_entries
|
||||
├── id (PK)
|
||||
├── receipt_id (FK)
|
||||
├── entry_type: enum(debit, credit)
|
||||
├── account_code, account_name
|
||||
├── amount
|
||||
├── partner_id, cost_center_id
|
||||
├── is_auto_generated
|
||||
└── modified_by, modified_at
|
||||
```
|
||||
|
||||
## Workflow States
|
||||
|
||||
```
|
||||
┌─────────┐
|
||||
│ DRAFT │◀────────────────────┐
|
||||
└────┬────┘ │
|
||||
│ submit() │ (edit after reject)
|
||||
▼ │
|
||||
┌──────────────┐ │
|
||||
│PENDING_REVIEW│──────────────────┤
|
||||
└──────┬───────┘ │
|
||||
│ │
|
||||
┌─────┴─────┐ │
|
||||
▼ ▼ │
|
||||
┌────────┐ ┌────────┐ │
|
||||
│APPROVED│ │REJECTED│──────────────┘
|
||||
└────┬───┘ └────────┘ resubmit()
|
||||
│
|
||||
│ (Faza 2)
|
||||
▼
|
||||
┌──────┐
|
||||
│SYNCED│
|
||||
└──────┘
|
||||
```
|
||||
|
||||
## Generare Note Contabile
|
||||
|
||||
### Algoritm
|
||||
|
||||
```python
|
||||
def generate_entries(receipt):
|
||||
expense_type = EXPENSE_TYPES[receipt.expense_type_code]
|
||||
entries = []
|
||||
|
||||
if expense_type.has_vat:
|
||||
net_amount = receipt.amount / Decimal('1.19')
|
||||
vat_amount = receipt.amount - net_amount
|
||||
|
||||
# Cheltuiala (debit)
|
||||
entries.append(Entry(DEBIT, expense_type.account, net_amount))
|
||||
# TVA (debit)
|
||||
entries.append(Entry(DEBIT, "4426", vat_amount))
|
||||
else:
|
||||
entries.append(Entry(DEBIT, expense_type.account, receipt.amount))
|
||||
|
||||
# Credit casa/banca
|
||||
entries.append(Entry(CREDIT, receipt.cash_register_account, receipt.amount))
|
||||
|
||||
return entries
|
||||
```
|
||||
|
||||
### Exemplu: Bon Benzina 200 RON
|
||||
|
||||
```
|
||||
Debit 6022 Cheltuieli combustibil 168.07
|
||||
Debit 4426 TVA deductibila 31.93
|
||||
Credit 5311 Casa in lei 200.00
|
||||
```
|
||||
|
||||
## Integrare Oracle (Faza 2)
|
||||
|
||||
### Proceduri Stocate
|
||||
|
||||
```sql
|
||||
-- 1. Initializare
|
||||
pack_contafin.init_scriere_act_rul_local()
|
||||
|
||||
-- 2. Insert linii
|
||||
INSERT INTO ACT_TEMP (
|
||||
ID_ACT, DATAIREG, DATAACT, SCD, ASCD, SCC, ASCC,
|
||||
SUMA, ID_CTR, ID_PARTD, EXPLICATIA, ...
|
||||
)
|
||||
|
||||
-- 3. Finalizare
|
||||
pack_contafin.finalizeaza_scriere_act_rul()
|
||||
→ SCRIE_IN_ACT()
|
||||
→ SCRIE_IN_RUL()
|
||||
→ Actualizare situatii (BV, BP, TVA)
|
||||
```
|
||||
|
||||
## Securitate
|
||||
|
||||
### Autentificare
|
||||
- JWT tokens din shared auth
|
||||
- Middleware valideaza token si injecteaza user
|
||||
|
||||
### Autorizare
|
||||
- Permisiuni verificate in services
|
||||
- Utilizator poate edita doar bonurile proprii in DRAFT
|
||||
- Doar contabil poate aproba/respinge
|
||||
|
||||
### Upload Fisiere
|
||||
- Validare MIME type (whitelist)
|
||||
- Sanitizare nume fisier
|
||||
- Limita dimensiune (10MB)
|
||||
- Stocare cu UUID (previne path traversal)
|
||||
|
||||
## Configuratie
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# SQLite Database
|
||||
SQLITE_DATABASE_PATH=data/receipts.db
|
||||
|
||||
# File Storage
|
||||
UPLOAD_PATH=data/uploads
|
||||
MAX_UPLOAD_SIZE=10485760 # 10MB
|
||||
|
||||
# Oracle (pentru nomenclatoare)
|
||||
ORACLE_USER=CONTAFIN_ORACLE
|
||||
ORACLE_PASSWORD=***
|
||||
ORACLE_HOST=localhost
|
||||
ORACLE_PORT=1526
|
||||
ORACLE_SID=ROA
|
||||
|
||||
# JWT (shared)
|
||||
JWT_SECRET_KEY=***
|
||||
JWT_ALGORITHM=HS256
|
||||
```
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Unit Tests
|
||||
- CRUD operations
|
||||
- Workflow transitions
|
||||
- Entry generation logic
|
||||
|
||||
### Integration Tests
|
||||
- API endpoints
|
||||
- File upload/download
|
||||
- Oracle nomenclature fetch
|
||||
|
||||
### E2E Tests
|
||||
- Complete workflow: create → submit → approve
|
||||
- File upload cu preview
|
||||
155
docs/data-entry/REQUIREMENTS.md
Normal file
155
docs/data-entry/REQUIREMENTS.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# Requirements: Data Entry - Bonuri Fiscale (Faza 1)
|
||||
|
||||
## Obiectiv
|
||||
|
||||
Sistem de introducere bonuri fiscale cu:
|
||||
- **Upload poze** bonuri de la utilizatori
|
||||
- **Generare automata** note contabile (staging area)
|
||||
- **Aprobare de contabil** inainte de finalizare
|
||||
- SQLite + ORM (SQLModel) + Migrari (Alembic)
|
||||
- Pregatit pentru integrare Oracle in Faza 2
|
||||
|
||||
## Cerinte Functionale
|
||||
|
||||
### 1. Gestiune Bonuri Fiscale
|
||||
|
||||
#### 1.1 Creare Bon
|
||||
- Utilizatorul poate uploada o poza a bonului fiscal
|
||||
- Campuri obligatorii: tip document, directie, data, suma, furnizor, casa/banca
|
||||
- Campuri optionale: numar bon, serie, descriere
|
||||
- Tipuri document: Bon Fiscal, Chitanta
|
||||
- Directii: Cheltuiala (plata), Incasare
|
||||
|
||||
#### 1.2 Upload Atasamente
|
||||
- Suport pentru imagini (JPEG, PNG) si PDF
|
||||
- Limita dimensiune: 10MB per fisier
|
||||
- Multiple atasamente per bon
|
||||
- Previzualizare imagine in UI
|
||||
|
||||
#### 1.3 Workflow Aprobare
|
||||
```
|
||||
DRAFT → PENDING_REVIEW → APPROVED/REJECTED → (Faza 2: SYNCED)
|
||||
```
|
||||
|
||||
- **DRAFT**: Utilizator completeaza datele
|
||||
- **PENDING_REVIEW**: Trimis spre aprobare, sistem genereaza note contabile
|
||||
- **APPROVED**: Contabil a aprobat
|
||||
- **REJECTED**: Contabil a respins (cu motiv)
|
||||
- **SYNCED**: (Faza 2) Sincronizat in Oracle
|
||||
|
||||
### 2. Note Contabile
|
||||
|
||||
#### 2.1 Generare Automata
|
||||
- La trimiterea spre aprobare, sistemul genereaza propuneri note contabile
|
||||
- Logica bazata pe tip cheltuiala selectat
|
||||
- Include calcul TVA automat (19%)
|
||||
|
||||
#### 2.2 Editare de Contabil
|
||||
- Contabilul poate modifica conturile propuse
|
||||
- Poate adauga/sterge linii
|
||||
- Modificarile sunt logate
|
||||
|
||||
#### 2.3 Tipuri Cheltuieli Predefinite
|
||||
|
||||
| Tip Cheltuiala | Cont Debit | TVA | Descriere |
|
||||
|----------------|------------|-----|-----------|
|
||||
| Combustibil | 6022 | 4426 (19%) | Benzina, motorina |
|
||||
| Materiale consumabile | 6028 | 4426 (19%) | Diverse materiale |
|
||||
| Rechizite birou | 6024 | 4426 (19%) | Papetarie, toner |
|
||||
| Telefonie | 626 | 4426 (19%) | Telefon, internet |
|
||||
| Parcare | 6022 | 4426 (19%) | Taxe parcare |
|
||||
| Alimentatie | 6028 | - | Fara TVA deductibila |
|
||||
| Transport | 624 | 4426 (19%) | Taxi, transport |
|
||||
| Altele | 628 | 4426 (19%) | Alte cheltuieli |
|
||||
|
||||
### 3. Roluri si Permisiuni
|
||||
|
||||
#### 3.1 Utilizator Standard
|
||||
- Creare bonuri noi (DRAFT)
|
||||
- Editare bonuri proprii in DRAFT
|
||||
- Trimitere spre aprobare
|
||||
- Vizualizare status bonuri proprii
|
||||
|
||||
#### 3.2 Contabil (Rol Aprobare)
|
||||
- Toate permisiunile utilizator
|
||||
- Vizualizare toate bonurile in asteptare
|
||||
- Aprobare/Respingere bonuri
|
||||
- Editare note contabile propuse
|
||||
- Aprobare in masa
|
||||
|
||||
### 4. Nomenclatoare
|
||||
|
||||
Preluate din Oracle (read-only):
|
||||
- **Parteneri**: Furnizori si clienti
|
||||
- **Conturi**: Plan conturi sintetice
|
||||
- **Case/Banci**: Registre casa si conturi bancare
|
||||
- **Firme**: Lista firme disponibile
|
||||
|
||||
## Cerinte Non-Functionale
|
||||
|
||||
### Performance
|
||||
- Timp raspuns API < 200ms (fara upload)
|
||||
- Upload fisiere < 5s pentru 10MB
|
||||
- Paginare pentru liste > 50 elemente
|
||||
|
||||
### Securitate
|
||||
- Autentificare JWT (shared cu reports-app)
|
||||
- Validare MIME type pentru fisiere
|
||||
- Sanitizare nume fisiere
|
||||
- Acces bazat pe rol
|
||||
|
||||
### Scalabilitate
|
||||
- Arhitectura pregatita pentru Oracle (Faza 2)
|
||||
- Separare clara intre storage local si DB
|
||||
- API design RESTful consistent
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Bonuri
|
||||
```
|
||||
POST /api/receipts/ # Creare bon
|
||||
GET /api/receipts/ # Lista bonuri
|
||||
GET /api/receipts/{id} # Detalii bon
|
||||
PUT /api/receipts/{id} # Modificare bon (DRAFT)
|
||||
DELETE /api/receipts/{id} # Stergere bon (DRAFT)
|
||||
```
|
||||
|
||||
### Workflow
|
||||
```
|
||||
POST /api/receipts/{id}/submit # DRAFT → PENDING
|
||||
POST /api/receipts/{id}/approve # PENDING → APPROVED
|
||||
POST /api/receipts/{id}/reject # PENDING → REJECTED
|
||||
POST /api/receipts/{id}/resubmit # REJECTED → PENDING
|
||||
```
|
||||
|
||||
### Note Contabile
|
||||
```
|
||||
GET /api/receipts/{id}/entries # Lista note
|
||||
PUT /api/receipts/{id}/entries # Modificare note
|
||||
POST /api/receipts/{id}/entries/regenerate # Re-generare
|
||||
```
|
||||
|
||||
### Atasamente
|
||||
```
|
||||
POST /api/receipts/{id}/attachments # Upload
|
||||
GET /api/receipts/{id}/attachments # Lista
|
||||
GET /api/attachments/{id}/download # Download
|
||||
DELETE /api/attachments/{id} # Stergere
|
||||
```
|
||||
|
||||
### Nomenclatoare
|
||||
```
|
||||
GET /api/receipts/partners # Furnizori/Clienti
|
||||
GET /api/receipts/accounts # Conturi
|
||||
GET /api/receipts/cash-registers # Case/Banci
|
||||
GET /api/receipts/expense-types # Tipuri cheltuieli
|
||||
```
|
||||
|
||||
## Criterii de Succes (Faza 1)
|
||||
|
||||
- [ ] Utilizator poate uploada poza bon + date de baza
|
||||
- [ ] Sistem genereaza automat note contabile
|
||||
- [ ] Contabil poate vedea, edita si aproba note
|
||||
- [ ] Bonurile aprobate sunt vizibile in lista
|
||||
- [ ] Migrarile Alembic functioneaza corect
|
||||
- [ ] Poze bonuri se salveaza si se afiseaza corect
|
||||
Reference in New Issue
Block a user