fix: Update Trial Balance to use real VBAL VIEW structure

After database verification, VBAL is a VIEW (not a table) that exists
in each company schema with a different structure than initially assumed.

Backend Changes:
- Updated models (trial_balance.py):
  - Changed column names to match real VBAL VIEW
  - CONT (account number)
  - DENUMIRE (account description, not DCONT)
  - PRECDEB/PRECCRED (previous balance, not SD_PREC/SC_PREC)
  - RULDEB/RULCRED (monthly movement, not RD_LUNA/RC_LUNA)
  - SOLDDEB/SOLDCRED (final balance, not SD_FINAL/SC_FINAL)
  - Made DENUMIRE optional (can be NULL in VIEW)

- Updated router (trial_balance.py):
  - Removed COD_FIRMA filter (not in VIEW)
  - Query now uses: {schema}.VBAL WHERE AN = :an AND LUNA = :luna
  - Fixed column names in SELECT (DENUMIRE instead of DCONT)
  - Updated sort columns validation
  - Fixed result processing to match new column order

Frontend Changes:
- Updated TrialBalanceView.vue:
  - Changed field from 'dcont' to 'denumire' in DataTable column

Database Verification:
- VBAL VIEW confirmed in ROMFAST schema (24,217 records)
- Current data available up to November 2025
- Structure verified with 22 columns
- VIEW exists in all company schemas

Testing Notes:
- Backend endpoint ready for testing
- Frontend field names now match API response
- Ready for manual testing with real company data

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-20 00:57:14 +02:00
parent 0b00b66ed5
commit 6c373c609e
5 changed files with 728 additions and 26 deletions

View File

@@ -0,0 +1,587 @@
# Feature: Balanță de Verificare Sintetică (Trial Balance)
**Branch**: `feature/trial-balance`
**Status**: 📋 Planning
**Created**: 2025-11-20
**Assigned to**: Claude Code
---
## 📋 Overview
Implementare pagină nouă în frontend pentru afișarea balanței de verificare sintetice simplificate din tabelul Oracle `VBAL`, cu filtrare dinamică și integrare completă în aplicație.
---
## 🎯 Business Requirements
### Functional Requirements
1. **Afișare Date Balanță de Verificare**:
- Solduri precedente (debit/credit)
- Rulaje lunare (debit/credit)
- Solduri finale (debit/credit)
- Cont contabil (cod)
- Denumire cont
2. **Filtrare și Căutare**:
- Filtrare după **număr cont** (ex: "512", "4111")
- Filtrare după **denumire cont** (căutare parțială, case-insensitive)
- Filtrare combinată (și după cont și după denumire)
- Clear filters option
3. **Navigare și UX**:
- Adăugare în meniul hamburger (secțiune Rapoarte / Reports)
- Ordonare pe coloane (ascendent/descendent)
- Paginare pentru volume mari de date
- Loading states și error handling
- Responsive design (mobile-friendly)
4. **Date Contextualizate**:
- Afișare pentru compania activă curentă
- Afișare pentru luna/anul curent (sau filtru de perioadă - opțional faza 2)
### Non-Functional Requirements
- **Performance**: Răspuns API < 2s pentru 10,000 înregistrări
- **Security**: Autentificare JWT obligatorie
- **Accessibility**: Conform design system existent
- **CSS**: Respectare strictă a arhitecturii CSS (ONBOARDING_CSS.md, CSS_PATTERNS.md)
---
## 🏗️ Technical Architecture
### Database Schema (Oracle `VBAL` table)
```sql
-- Structura tabelului VBAL (să fie verificată în Oracle)
SELECT
CONT, -- Număr cont contabil
DCONT, -- Denumire cont
SD_PREC, -- Sold precedent debit
SC_PREC, -- Sold precedent credit
RD_LUNA, -- Rulaj lunar debit
RC_LUNA, -- Rulaj lunar credit
SD_FINAL, -- Sold final debit
SC_FINAL, -- Sold final credit
COD_FIRMA, -- Cod firmă (pentru filtering)
LUNA, -- Luna (1-12)
AN -- An
FROM VBAL
WHERE COD_FIRMA = :cod_firma
AND AN = :an
AND LUNA = :luna
AND (CONT LIKE :cont_filter OR DCONT LIKE :denumire_filter)
ORDER BY CONT
```
### Backend API Endpoint
**Endpoint**: `GET /api/trial-balance`
**Request Parameters**:
```json
{
"cod_firma": "string (required, from JWT)",
"luna": "integer (1-12, optional, default: current month)",
"an": "integer (optional, default: current year)",
"cont_filter": "string (optional, partial match)",
"denumire_filter": "string (optional, partial match, case-insensitive)",
"sort_by": "string (optional, default: 'CONT')",
"sort_order": "string (optional, 'asc' | 'desc', default: 'asc')",
"page": "integer (optional, default: 1)",
"page_size": "integer (optional, default: 50)"
}
```
**Response**:
```json
{
"success": true,
"data": {
"items": [
{
"cont": "4111",
"dcont": "Furnizori interni",
"sold_precedent_debit": 0.00,
"sold_precedent_credit": 15000.00,
"rulaj_lunar_debit": 5000.00,
"rulaj_lunar_credit": 8000.00,
"sold_final_debit": 0.00,
"sold_final_credit": 18000.00
}
],
"pagination": {
"total_items": 150,
"total_pages": 3,
"current_page": 1,
"page_size": 50
},
"filters_applied": {
"luna": 11,
"an": 2025,
"cont_filter": null,
"denumire_filter": "furnizori"
}
}
}
```
**Error Responses**:
- `401 Unauthorized`: Missing/invalid JWT token
- `403 Forbidden`: User doesn't have access to company
- `500 Internal Server Error`: Database connection/query error
---
### Frontend Architecture
**Location**: `reports-app/frontend/src/views/TrialBalanceView.vue`
**Store**: `reports-app/frontend/src/stores/trialBalanceStore.js`
**Route**: `/trial-balance` (added to `router/index.js`)
**Menu Integration**:
- Add to hamburger menu in `src/components/layout/HamburgerMenu.vue`
- Section: "Rapoarte" / "Reports"
- Icon: Calculator/Table icon (PrimeVue icon)
- Label: "Balanță de Verificare"
**Component Structure**:
```vue
<template>
<div class="trial-balance-view">
<!-- Page Header -->
<div class="roa-page-header">
<h1>Balanță de Verificare</h1>
<p class="roa-subtitle">Luna: {{ currentMonth }}/{{ currentYear }}</p>
</div>
<!-- Filters Section -->
<div class="roa-card roa-filters-card">
<!-- Cont filter -->
<!-- Denumire filter -->
<!-- Clear filters button -->
</div>
<!-- Data Table -->
<div class="roa-card">
<DataTable
:value="trialBalanceData"
:loading="loading"
paginator
:rows="50"
sortField="cont"
:sortOrder="1"
>
<!-- Columns definition -->
</DataTable>
</div>
<!-- Empty State / Error State -->
</div>
</template>
```
**CSS Patterns to Use**:
- `.roa-page-header` - Page header (CSS_PATTERNS.md)
- `.roa-card` - Card container (CSS_PATTERNS.md)
- `.roa-filters-card` - Filters section (CSS_PATTERNS.md)
- Design tokens from DESIGN_TOKENS.md (colors, spacing)
- **NO `:deep()`** - Use `src/assets/css/vendor/primevue/datatable.css` for PrimeVue overrides
**State Management** (Pinia store):
```javascript
// src/stores/trialBalanceStore.js
export const useTrialBalanceStore = defineStore('trialBalance', {
state: () => ({
trialBalanceData: [],
loading: false,
error: null,
filters: {
cont: '',
denumire: '',
luna: new Date().getMonth() + 1,
an: new Date().getFullYear()
},
pagination: {
totalItems: 0,
currentPage: 1,
pageSize: 50
}
}),
actions: {
async fetchTrialBalance() { /* ... */ },
async applyFilters(filters) { /* ... */ },
clearFilters() { /* ... */ }
}
})
```
---
## 📝 Implementation Plan (Phases)
### ✅ Phase 0: Preparation & Branch Setup
**Status**: 🔲 Not Started
**Tasks**:
- [ ] Create feature branch `feature/trial-balance` from `main`
- [ ] Verify Oracle `VBAL` table structure and test queries
- [ ] Review existing code patterns (InvoicesView, DashboardView)
- [ ] Read CSS documentation (ONBOARDING_CSS.md, CSS_PATTERNS.md)
**Estimated Time**: 30 minutes
---
### ✅ Phase 1: Backend API Implementation
**Status**: 🔲 Not Started
**Tasks**:
- [ ] Create Pydantic schema: `backend/app/schemas/trial_balance.py`
- `TrialBalanceItem` model
- `TrialBalanceRequest` model
- `TrialBalanceResponse` model
- [ ] Create router: `backend/app/routers/trial_balance.py`
- `GET /api/trial-balance` endpoint
- Query parameters validation
- Oracle stored procedure/query execution
- Pagination logic
- Filtering logic (cont, denumire)
- Sorting logic
- [ ] Register router in `backend/app/main.py`
- [ ] Test endpoint manually with Postman/curl
- Test with valid JWT token
- Test filtering by cont
- Test filtering by denumire
- Test pagination
- Test sorting
- Test error cases (invalid token, DB errors)
**Files to Create/Modify**:
- `reports-app/backend/app/schemas/trial_balance.py` (NEW)
- `reports-app/backend/app/routers/trial_balance.py` (NEW)
- `reports-app/backend/app/main.py` (MODIFY)
**Acceptance Criteria**:
- API returns correct data from `VBAL` table
- Filtering works for cont and denumire
- Pagination returns correct page counts
- Sorting works for all columns
- Proper error handling and status codes
**Estimated Time**: 2-3 hours
---
### ✅ Phase 2: Frontend Store Implementation
**Status**: 🔲 Not Started
**Tasks**:
- [ ] Create Pinia store: `frontend/src/stores/trialBalanceStore.js`
- State definition (data, loading, error, filters, pagination)
- `fetchTrialBalance()` action with Axios
- `applyFilters()` action
- `clearFilters()` action
- Getters for computed values
- [ ] Add API service: `frontend/src/services/trialBalanceService.js` (optional)
- [ ] Test store in browser DevTools
**Files to Create**:
- `reports-app/frontend/src/stores/trialBalanceStore.js` (NEW)
- `reports-app/frontend/src/services/trialBalanceService.js` (NEW, optional)
**Acceptance Criteria**:
- Store successfully fetches data from API
- Filters update correctly
- Loading states work properly
- Error handling displays user-friendly messages
**Estimated Time**: 1-2 hours
---
### ✅ Phase 3: Frontend View Component
**Status**: 🔲 Not Started
**Tasks**:
- [ ] Create Vue component: `frontend/src/views/TrialBalanceView.vue`
- Page header with title and period info
- Filters card (cont input, denumire input, clear button)
- PrimeVue DataTable with columns:
- Cont
- Denumire Cont
- Sold Precedent (Debit/Credit)
- Rulaj Lunar (Debit/Credit)
- Sold Final (Debit/Credit)
- Loading spinner
- Empty state (no data)
- Error state
- [ ] Use **existing CSS patterns** (NO new custom CSS unless necessary)
- `.roa-page-header`
- `.roa-card`
- `.roa-filters-card`
- Design tokens (spacing, colors)
- [ ] Implement responsive design (mobile breakpoints)
- [ ] Add number formatting (Romanian locale, 2 decimals)
**Files to Create**:
- `reports-app/frontend/src/views/TrialBalanceView.vue` (NEW)
**Acceptance Criteria**:
- Page displays correctly with data
- Filters work and update table
- Sorting on columns works
- Pagination works
- Loading/error states display correctly
- CSS follows design system (NO `:deep()`, NO custom colors)
- Responsive on mobile devices
**Estimated Time**: 3-4 hours
---
### ✅ Phase 4: Routing & Navigation
**Status**: 🔲 Not Started
**Tasks**:
- [ ] Add route in `frontend/src/router/index.js`:
```javascript
{
path: '/trial-balance',
name: 'TrialBalance',
component: () => import('@/views/TrialBalanceView.vue'),
meta: { requiresAuth: true }
}
```
- [ ] Add menu item in `frontend/src/components/layout/HamburgerMenu.vue`:
- Section: "Rapoarte"
- Icon: `pi-calculator` or `pi-table`
- Label: "Balanță de Verificare"
- Route: `/trial-balance`
- [ ] Test navigation from menu
**Files to Modify**:
- `reports-app/frontend/src/router/index.js` (MODIFY)
- `reports-app/frontend/src/components/layout/HamburgerMenu.vue` (MODIFY)
**Acceptance Criteria**:
- ✅ Route is accessible at `/trial-balance`
- ✅ Menu item appears in hamburger menu
- ✅ Clicking menu item navigates to page
- ✅ Auth guard prevents unauthorized access
**Estimated Time**: 30 minutes
---
### ✅ Phase 5: Testing & Refinement
**Status**: 🔲 Not Started
**Tasks**:
- [ ] Manual testing:
- Test with different companies
- Test with different date ranges
- Test filtering edge cases (empty results, special characters)
- Test sorting on all columns
- Test pagination with large datasets
- Test on mobile devices (responsive)
- Test error scenarios (API down, invalid token)
- [ ] Add Playwright E2E tests (optional, recommended):
- `frontend/tests/e2e/trial-balance/trial-balance.spec.js`
- Test navigation
- Test filtering
- Test data display
- [ ] Code review & refinement:
- Check CSS adherence (no `:deep()`, use patterns)
- Check error handling
- Check loading states
- Check accessibility (keyboard navigation, screen readers)
- [ ] Performance testing:
- Test with 10,000+ rows
- Check API response time
- Check frontend rendering performance
**Files to Create** (optional):
- `reports-app/frontend/tests/e2e/trial-balance/trial-balance.spec.js` (NEW)
**Acceptance Criteria**:
- ✅ All manual tests pass
- ✅ E2E tests pass (if implemented)
- ✅ Performance benchmarks met (API < 2s)
- ✅ Code follows project conventions
- ✅ CSS follows design system strictly
**Estimated Time**: 2-3 hours
---
### ✅ Phase 6: Documentation & PR
**Status**: 🔲 Not Started
**Tasks**:
- [ ] Update `README.md` - add Trial Balance to features list
- [ ] Update `CLAUDE.md` - add Trial Balance to documentation index (if needed)
- [ ] Add API documentation in backend README
- [ ] Create PR from `feature/trial-balance` to `main`:
- Title: "feat: Add Trial Balance (Balanță de Verificare) page"
- Description: Link to this feature file, list phases completed
- Screenshots of UI
- API endpoint documentation
- [ ] Request code review
- [ ] Address review comments
- [ ] Merge to `main`
**Acceptance Criteria**:
- ✅ All documentation updated
- ✅ PR created with complete description
- ✅ Code review approved
- ✅ Branch merged successfully
**Estimated Time**: 1 hour
---
## 📊 Progress Tracking
### Overall Progress
- **Phase 0**: 🔲 Not Started (0%)
- **Phase 1**: 🔲 Not Started (0%)
- **Phase 2**: 🔲 Not Started (0%)
- **Phase 3**: 🔲 Not Started (0%)
- **Phase 4**: 🔲 Not Started (0%)
- **Phase 5**: 🔲 Not Started (0%)
- **Phase 6**: 🔲 Not Started (0%)
**Total Progress**: 0% Complete
### Status Legend
- 🔲 Not Started
- 🔄 In Progress
- ✅ Completed
- ⚠️ Blocked
- ❌ Cancelled
---
## 🚀 Getting Started
### Prerequisites
1. SSH tunnel running (`./ssh_tunnel.sh status`)
2. Backend running (`cd reports-app/backend && uvicorn app.main:app --reload --port 8001`)
3. Frontend running (`cd reports-app/frontend && npm run dev`)
4. Valid JWT token for testing API
### Starting Development
```bash
# 1. Create feature branch
git checkout main
git pull origin main
git checkout -b feature/trial-balance
# 2. Verify Oracle VBAL table
# Connect to Oracle and run:
# SELECT * FROM VBAL WHERE ROWNUM <= 10;
# 3. Start backend (Phase 1)
cd reports-app/backend
# Create schemas/trial_balance.py
# Create routers/trial_balance.py
# Test with curl/Postman
# 4. Start frontend (Phases 2-4)
cd reports-app/frontend
# Create stores/trialBalanceStore.js
# Create views/TrialBalanceView.vue
# Update router and menu
# 5. Test and refine (Phase 5)
# Manual testing
# E2E tests (optional)
# 6. Create PR (Phase 6)
git add .
git commit -m "feat: Add Trial Balance page with filtering and pagination"
git push origin feature/trial-balance
# Create PR on GitHub/GitLab
```
---
## 📚 Reference Documentation
**MUST READ before coding**:
- `docs/ONBOARDING_CSS.md` - CSS quick start (5 min read)
- `docs/CSS_PATTERNS.md` - All available CSS patterns
- `docs/DESIGN_TOKENS.md` - Colors, spacing, typography
- `reports-app/frontend/README.md` - Frontend architecture
- `reports-app/backend/README.md` - Backend architecture
**Similar implementations to reference**:
- `reports-app/frontend/src/views/InvoicesView.vue` - Table + filters pattern
- `reports-app/frontend/src/views/DashboardView.vue` - Cards + data display
- `reports-app/backend/app/routers/invoices.py` - API with filtering/pagination
---
## ⚠️ Important Notes
### CSS Architecture Compliance
**CRITICAL**: This feature MUST follow the established CSS architecture:
✅ **DO**:
- Use existing `.roa-*` patterns from `CSS_PATTERNS.md`
- Use design tokens (`var(--color-primary)`, `var(--spacing-4)`)
- Use vendor overrides in `src/assets/css/vendor/primevue/` for PrimeVue
- Keep component styles minimal and semantic
- Follow BEM naming if creating new components
❌ **DON'T**:
- Use `:deep()` in Vue components
- Hardcode colors or spacing values
- Duplicate existing patterns
- Create custom CSS without checking patterns first
- Override PrimeVue styles in component `<style>` blocks
### Database Considerations
- **Performance**: Use indexes on `VBAL(COD_FIRMA, AN, LUNA, CONT)`
- **Data Volume**: Consider pagination for companies with many accounts
- **Filters**: Use Oracle `LIKE` with wildcards efficiently: `CONT LIKE :cont || '%'`
### Security
- **JWT Auth**: Required for all API calls
- **Company Access**: Verify user has access to `cod_firma` in request
- **SQL Injection**: Use parameterized queries (`:param` syntax)
### Future Enhancements (Not in Initial Scope)
- Export to Excel/PDF
- Drill-down to account details (sold și rulaj pe luni)
- Comparison between periods (current vs previous month/year)
- Charts/visualizations (rulaj pe conturi)
- Advanced filters (by account class/category)
---
## 🐛 Known Issues / Risks
1. **Oracle VBAL table structure unknown**: Verify column names and types in Phase 0
2. **Performance with large datasets**: Monitor query performance, add indexes if needed
3. **Decimal precision**: Ensure proper handling of Romanian decimal separator (comma vs dot)
4. **Company switching**: Ensure data refreshes when user switches active company
---
## 📞 Support
For questions or blockers, refer to:
- **Architecture**: `docs/ARCHITECTURE_SCHEMA.md`, `docs/MICROSERVICES_GUIDE.md`
- **CSS Issues**: `docs/ONBOARDING_CSS.md`, `docs/STYLING_GUIDELINES.md`
- **Backend Issues**: `reports-app/backend/README.md`, `README.md` (troubleshooting)
- **Frontend Issues**: `reports-app/frontend/README.md`
---
**Last Updated**: 2025-11-20
**Feature Owner**: Claude Code
**Reviewers**: TBD

View File

@@ -0,0 +1,106 @@
# 🎯 Prompt pentru Implementare Balanță de Verificare
## Promptul de folosit:
```
Implementează feature-ul "Balanță de Verificare" conform specificațiilor din features/TRIAL_BALANCE_FEATURE.md.
Cerințe:
1. Creează branch nou: feature/trial-balance
2. Implementează toate fazele (0-6) în ordine
3. Urmărește progresul actualizând statusul fazelor în TRIAL_BALANCE_FEATURE.md
4. Respectă STRICT arhitectura CSS (ONBOARDING_CSS.md, CSS_PATTERNS.md) - fără :deep(), doar pattern-uri existente
5. Testează manual după fiecare fază înainte de a trece la următoarea
Prioritate: Phases 0-4 (backend + frontend + navigare)
Phases 5-6 (testing + PR) - opțional pentru MVP
Start cu Phase 0: Preparation & Branch Setup.
```
---
## Sau versiunea extinsă:
```
# Task: Implementare completă Balanță de Verificare (Trial Balance)
## Context
Implementează o pagină nouă în frontend pentru afișarea balanței de verificare sintetice din Oracle VBAL cu filtrare, paginare și integrare completă în aplicație.
## Specificații
Vezi: features/TRIAL_BALANCE_FEATURE.md
## Plan de lucru
1. **Phase 0**: Setup branch feature/trial-balance + verificare VBAL table
2. **Phase 1**: Backend API (schemas + router + endpoint GET /api/trial-balance)
3. **Phase 2**: Frontend Store (Pinia trialBalanceStore)
4. **Phase 3**: Frontend View (TrialBalanceView.vue cu DataTable)
5. **Phase 4**: Routing + Menu (router.js + HamburgerMenu.vue)
6. **Phase 5**: Testing manual + E2E (opțional)
7. **Phase 6**: Documentation + PR
## Reguli CRITICE
✅ Respectă CSS architecture: DOAR pattern-uri din CSS_PATTERNS.md, FĂRĂ :deep()
✅ Folosește design tokens (var(--color-primary), var(--spacing-4))
✅ Testează manual după fiecare fază
✅ Actualizează progresul în TRIAL_BALANCE_FEATURE.md la finalul fiecărei faze
## Start
Începe cu Phase 0 și confirmă structura tabelului VBAL înainte de a trece la Phase 1.
Urmărește progresul în features/TRIAL_BALANCE_FEATURE.md actualizând:
- Status fază: 🔲 → 🔄 → ✅
- Checkboxes task-uri: [ ] → [x]
- Overall Progress: X% Complete
```
---
## Alternative scurte pentru faze individuale:
### Pentru Phase 1 (Backend):
```
Implementează Phase 1 din features/TRIAL_BALANCE_FEATURE.md:
- Creează schemas/trial_balance.py (TrialBalanceItem, Request, Response)
- Creează routers/trial_balance.py (GET /api/trial-balance cu filtering/pagination)
- Testează cu curl/Postman
- Marchează task-urile ca [x] în feature file
```
### Pentru Phase 3 (Frontend View):
```
Implementează Phase 3 din features/TRIAL_BALANCE_FEATURE.md:
- Creează TrialBalanceView.vue
- Folosește DOAR pattern-uri CSS existente (.roa-card, .roa-page-header)
- FĂRĂ :deep(), FĂRĂ custom CSS
- DataTable cu coloane: Cont, Denumire, Sold Prec (D/C), Rulaj Lunar (D/C), Sold Final (D/C)
- Marchează task-urile ca [x] în feature file
```
---
## Tips pentru urmărire progres:
Actualizează manual în TRIAL_BALANCE_FEATURE.md:
```markdown
### ✅ Phase 1: Backend API Implementation
**Status**: ✅ Completed
**Tasks**:
- [x] Create Pydantic schema
- [x] Create router
- [x] Register router in main.py
- [x] Test endpoint manually
```
Apoi actualizează Overall Progress:
```markdown
### Overall Progress
- **Phase 0**: ✅ Completed (100%)
- **Phase 1**: ✅ Completed (100%)
- **Phase 2**: 🔄 In Progress (50%)
...
**Total Progress**: 35% Complete
```

View File

@@ -1,6 +1,6 @@
"""
Pydantic models for Trial Balance (Balanță de Verificare)
Maps to Oracle VBAL table
Maps to Oracle VBAL VIEW (exists in each company schema)
"""
from pydantic import BaseModel, Field
from typing import Optional, List
@@ -8,16 +8,22 @@ from decimal import Decimal
class TrialBalanceItem(BaseModel):
"""
Individual trial balance record from VBAL table
Individual trial balance record from VBAL VIEW
Real structure from Oracle:
- CONT: account number
- DENUMIRE: account description
- PRECDEB/PRECCRED: previous balance debit/credit
- RULDEB/RULCRED: monthly movement debit/credit
- SOLDDEB/SOLDCRED: final balance debit/credit
"""
cont: str = Field(description="Număr cont contabil")
dcont: str = Field(description="Denumire cont")
sold_precedent_debit: Decimal = Field(description="Sold precedent debit", decimal_places=2)
sold_precedent_credit: Decimal = Field(description="Sold precedent credit", decimal_places=2)
rulaj_lunar_debit: Decimal = Field(description="Rulaj lunar debit", decimal_places=2)
rulaj_lunar_credit: Decimal = Field(description="Rulaj lunar credit", decimal_places=2)
sold_final_debit: Decimal = Field(description="Sold final debit", decimal_places=2)
sold_final_credit: Decimal = Field(description="Sold final credit", decimal_places=2)
cont: str = Field(description="Număr cont contabil (CONT)")
denumire: Optional[str] = Field(default="", description="Denumire cont (DENUMIRE)")
sold_precedent_debit: Decimal = Field(description="Sold precedent debit (PRECDEB)", decimal_places=2)
sold_precedent_credit: Decimal = Field(description="Sold precedent credit (PRECCRED)", decimal_places=2)
rulaj_lunar_debit: Decimal = Field(description="Rulaj lunar debit (RULDEB)", decimal_places=2)
rulaj_lunar_credit: Decimal = Field(description="Rulaj lunar credit (RULCRED)", decimal_places=2)
sold_final_debit: Decimal = Field(description="Sold final debit (SOLDDEB)", decimal_places=2)
sold_final_credit: Decimal = Field(description="Sold final credit (SOLDCRED)", decimal_places=2)
class Config:
from_attributes = True

View File

@@ -64,8 +64,9 @@ async def get_trial_balance(
sort_order = 'asc'
# Validează sort_by (previne SQL injection)
valid_sort_columns = ['CONT', 'DCONT', 'SD_PREC', 'SC_PREC', 'RD_LUNA',
'RC_LUNA', 'SD_FINAL', 'SC_FINAL']
# Real column names from VBAL VIEW
valid_sort_columns = ['CONT', 'DENUMIRE', 'PRECDEB', 'PRECCRED',
'RULDEB', 'RULCRED', 'SOLDDEB', 'SOLDCRED']
if sort_by.upper() not in valid_sort_columns:
sort_by = 'CONT'
@@ -90,25 +91,25 @@ async def get_trial_balance(
schema = schema_result[0]
# Construiește query-ul de bază pentru VBAL
# Construiește query-ul de bază pentru VBAL VIEW
# VBAL este un VIEW în fiecare schemă de companie
# Structura reală: CONT, DENUMIRE, AN, LUNA, PRECDEB, PRECCRED, RULDEB, RULCRED, SOLDDEB, SOLDCRED
base_query = f"""
SELECT
CONT,
DCONT,
NVL(SD_PREC, 0) as SD_PREC,
NVL(SC_PREC, 0) as SC_PREC,
NVL(RD_LUNA, 0) as RD_LUNA,
NVL(RC_LUNA, 0) as RC_LUNA,
NVL(SD_FINAL, 0) as SD_FINAL,
NVL(SC_FINAL, 0) as SC_FINAL
NVL(DENUMIRE, '') as DENUMIRE,
NVL(PRECDEB, 0) as PRECDEB,
NVL(PRECCRED, 0) as PRECCRED,
NVL(RULDEB, 0) as RULDEB,
NVL(RULCRED, 0) as RULCRED,
NVL(SOLDDEB, 0) as SOLDDEB,
NVL(SOLDCRED, 0) as SOLDCRED
FROM {schema}.VBAL
WHERE COD_FIRMA = :cod_firma
AND AN = :an
WHERE AN = :an
AND LUNA = :luna
"""
params = {
'cod_firma': company,
'an': an,
'luna': luna
}
@@ -119,7 +120,7 @@ async def get_trial_balance(
params['cont_filter'] = f"{cont_filter}%"
if denumire_filter:
base_query += " AND UPPER(DCONT) LIKE UPPER(:denumire_filter)"
base_query += " AND UPPER(DENUMIRE) LIKE UPPER(:denumire_filter)"
params['denumire_filter'] = f"%{denumire_filter}%"
# Count total pentru paginare
@@ -148,11 +149,13 @@ async def get_trial_balance(
rows = cursor.fetchall()
# Procesează rezultatele
# Index columns: CONT(0), DENUMIRE(1), PRECDEB(2), PRECCRED(3),
# RULDEB(4), RULCRED(5), SOLDDEB(6), SOLDCRED(7), rnum(8)
items = []
for row in rows:
item = TrialBalanceItem(
cont=row[0] or '',
dcont=row[1] or '',
denumire=row[1] or '',
sold_precedent_debit=Decimal(str(row[2] or 0)),
sold_precedent_credit=Decimal(str(row[3] or 0)),
rulaj_lunar_debit=Decimal(str(row[4] or 0)),

View File

@@ -119,7 +119,7 @@
</template>
</Column>
<Column field="dcont" header="Denumire Cont" sortable :style="{ width: '25%' }" />
<Column field="denumire" header="Denumire Cont" sortable :style="{ width: '25%' }" />
<Column header="Sold Precedent" :style="{ width: '15%' }">
<template #body="slotProps">