feat(T06): Verkaufsmodul + Rechtsdokumente + DATEV-Export + Sales UI
This commit is contained in:
+43
-26
@@ -1,38 +1,55 @@
|
||||
# Worklog
|
||||
|
||||
## T05: Dateiablage pro Fahrzeug + File UI - 2026-07-17
|
||||
## T06: Verkaufsmodul + Rechtsdokumente + DATEV-Export + Sales UI
|
||||
|
||||
**Date:** 2026-07-17
|
||||
**Status:** COMPLETED
|
||||
|
||||
### Files Created
|
||||
|
||||
**Backend:**
|
||||
- backend/app/models/file.py - File SQLAlchemy model (UUID, vehicle_id FK, filename, path, mime_type, size, thumbnail_path)
|
||||
- backend/app/schemas/file.py - Pydantic schemas (FileUploadResponse, FileResponse, FileListResponse, FileDeleteResponse)
|
||||
- backend/app/services/file_service.py - File service (upload, get, list, delete, validate_mime_type, validate_file_size)
|
||||
- backend/app/utils/thumbnails.py - Thumbnail generation (200x200) using Pillow for jpg/png/webp
|
||||
- backend/app/routers/files.py - Files router (GET list, POST upload, GET download, DELETE)
|
||||
- backend/tests/test_files.py - 43 tests covering all endpoints, validation, thumbnails, service unit tests
|
||||
#### Backend
|
||||
- backend/app/models/sale.py - Sale model with UUID PK, vehicle/buyer/seller FKs, sale_price, status, is_gwg, contract_pdf_path
|
||||
- backend/app/models/datev_export.py - DATEVExport model with start_date, end_date, file_path, total_amount
|
||||
- backend/app/schemas/sale.py - SaleCreate, SaleUpdate, SaleResponse, SaleListResponse, ContractResponse, UstIdVerifyResponse
|
||||
- backend/app/schemas/datev.py - DATEVExportCreate, DATEVExportResponse, DATEVExportListResponse
|
||||
- backend/app/services/sale_service.py - Full CRUD + contract PDF + GwG logic + USt-IdNr. verification
|
||||
- backend/app/services/datev_service.py - Export creation, listing, CSV download
|
||||
- backend/app/utils/contract_pdf.py - HTML template with WeasyPrint, GwG-Klausel §6 Abs. 2 EStG, USt-IdNr. field
|
||||
- backend/app/utils/datev.py - DATEV CSV Buchungsstapel format helper
|
||||
- backend/app/routers/sales.py - Sales CRUD + contract + USt-IdNr. endpoints
|
||||
- backend/app/routers/datev.py - DATEV export + list + download endpoints
|
||||
- backend/tests/test_sales.py - 20 tests covering CRUD, contract PDF, GwG, vehicle status, USt-IdNr.
|
||||
- backend/tests/test_datev.py - 14 tests covering export API, CSV format, validation
|
||||
|
||||
**Frontend:**
|
||||
- frontend/lib/files.ts - API functions, types, utilities (listFiles, uploadFile, deleteFile, formatFileSize, isImageMime)
|
||||
- frontend/components/files/FileUpload.tsx - Drag-and-drop multi-file upload with validation
|
||||
- frontend/components/files/FileList.tsx - File list with thumbnails, download, delete confirm dialog
|
||||
- frontend/components/files/FileGallery.tsx - Gallery view filtering images only
|
||||
- frontend/components/files/FilePreview.tsx - File preview modal with metadata and download
|
||||
- frontend/tests/files.test.tsx - 25 tests covering all components and utilities
|
||||
#### Frontend
|
||||
- frontend/lib/sales.ts - Sales API client functions and types
|
||||
- frontend/lib/datev.ts - DATEV API client functions and types
|
||||
- frontend/components/sales/SaleList.tsx - Sales table with filters and pagination
|
||||
- frontend/components/sales/SaleForm.tsx - Sale create form with GwG toggle
|
||||
- frontend/components/sales/ContractPreview.tsx - PDF preview with regenerate/download
|
||||
- frontend/components/sales/DatevExport.tsx - DATEV export page with date range picker
|
||||
- frontend/app/[locale]/verkauf/page.tsx - Sales list page
|
||||
- frontend/app/[locale]/verkauf/[id]/page.tsx - Sale detail with contract preview
|
||||
- frontend/app/[locale]/verkauf/neu/page.tsx - Sale create page
|
||||
- frontend/tests/sales.test.tsx - 11 frontend tests
|
||||
- frontend/tests/datev.test.tsx - 5 frontend tests
|
||||
|
||||
### Files Modified
|
||||
- backend/app/models/vehicle.py - Added files relationship to Vehicle model
|
||||
- backend/app/main.py - Registered files router
|
||||
- backend/requirements.txt - Added Pillow>=10.0.0
|
||||
- backend/app/config.py - Added BZST_API_ENABLED=False, WEASYPRINT_OUTPUT_DIR
|
||||
- backend/app/main.py - Registered sales + datev routers
|
||||
- backend/app/models/__init__.py - Added sale + datev_export imports for Base.metadata registration
|
||||
- backend/requirements.txt - Added weasyprint>=62.0
|
||||
|
||||
### Test Results
|
||||
- Backend: 43/43 passed, 82% coverage (file_service 95%, thumbnails 88%, files router 55%)
|
||||
- Frontend: 25/25 passed
|
||||
- TypeScript: tsc --noEmit passes with no errors
|
||||
- Backend: 34/34 passed (11.42s)
|
||||
- Frontend: 16/16 passed (1.85s)
|
||||
- Total: 50/50 passed
|
||||
|
||||
### Smoke Test
|
||||
- Backend API endpoints fully functional with real PostgreSQL (upload, list, download, delete)
|
||||
- Thumbnail generation verified for JPEG, PNG, WebP (200x200)
|
||||
- MIME validation enforces jpg/png/webp/pdf/doc/docx only
|
||||
- File size limit enforced at 20MB
|
||||
- Frontend drag-and-drop upload works, delete confirmation dialog works, gallery filters images
|
||||
- Backend: All endpoints respond correctly (200/201/404/422)
|
||||
- GwG logic: Clause appears when is_gwg=true AND price <= 800 EUR (§6 Abs. 2 EStG)
|
||||
- Vehicle status: Sale creation → 'sold', sale cancel → 'available'
|
||||
- DATEV CSV: Correct headers, comma decimal separator, DD.MM.YYYY date format
|
||||
- USt-IdNr. verify: Returns 'BZSt API not available' when feature flag disabled
|
||||
- WeasyPrint: Installed, async PDF generation via asyncio.to_thread
|
||||
- Frontend: All components render with mocked API, test IDs present
|
||||
|
||||
Reference in New Issue
Block a user