bmc_hub/docs/KASSEKLADDE.md

364 lines
9.3 KiB
Markdown
Raw Normal View History

# Kassekladde (Supplier Invoices) - BMC Hub
## Overview
BMC Hub's kassekladde module enables management of supplier invoices (incoming invoices that the company must pay) with full integration to e-conomic accounting system via the journals/vouchers API.
## Features
**Complete CRUD Operations**
- Create, view, update, and delete supplier invoices
- Multi-line invoice support with VAT breakdown
- Vendor linking and automatic creation in e-conomic
**Approval Workflow**
- Pending → Approved → Sent to e-conomic → Paid
- Approval tracking with user and timestamp
**e-conomic Integration**
- Automatic supplier matching and creation
- Journal/voucher posting to kassekladde
- PDF attachment upload to vouchers
- Configurable journal number and default accounts
**VAT Handling**
- Support for multiple VAT codes (I25, I0, IY25, etc.)
- Automatic VAT calculation per line
- VAT breakdown in e-conomic entries
**Nordic Top UI**
- Modern, clean design
- Real-time statistics dashboard
- Filter and search functionality
- Responsive mobile support
## Architecture
### Database Schema
**Main Tables:**
- `supplier_invoices` - Invoice headers with e-conomic tracking
- `supplier_invoice_lines` - Line items with VAT and account details
- `supplier_invoice_settings` - System configuration
- `vendors` - Supplier information with e-conomic IDs
**Views:**
- `overdue_supplier_invoices` - All overdue unpaid invoices
- `pending_economic_sync` - Approved invoices ready for e-conomic
### Backend Structure
```
app/
billing/
backend/
supplier_invoices.py # FastAPI router with endpoints
frontend/
supplier_invoices.html # Nordic Top UI
views.py # Frontend routes
services/
economic_service.py # e-conomic API integration
```
### API Endpoints
**CRUD Operations:**
- `GET /api/v1/supplier-invoices` - List invoices with filters
- `GET /api/v1/supplier-invoices/{id}` - Get invoice details
- `POST /api/v1/supplier-invoices` - Create new invoice
- `PUT /api/v1/supplier-invoices/{id}` - Update invoice
- `DELETE /api/v1/supplier-invoices/{id}` - Delete invoice
**Workflow Actions:**
- `POST /api/v1/supplier-invoices/{id}/approve` - Approve invoice
- `POST /api/v1/supplier-invoices/{id}/send-to-economic` - Send to e-conomic
**Statistics:**
- `GET /api/v1/supplier-invoices/stats/overview` - Payment overview
- `GET /api/v1/supplier-invoices/stats/by-vendor` - Stats by vendor
**e-conomic Integration:**
- `GET /api/v1/supplier-invoices/economic/journals` - Available kassekladder
## Installation & Setup
### 1. Database Migration
Run the migration to create tables:
```bash
# Execute migration SQL
psql -U bmc_hub -d bmc_hub < migrations/008_supplier_invoices.sql
```
Or via Docker:
```bash
docker-compose exec postgres psql -U bmc_hub -d bmc_hub < /app/migrations/008_supplier_invoices.sql
```
### 2. Configure e-conomic Credentials
Add to `.env` file:
```env
# e-conomic Integration
ECONOMIC_API_URL=https://restapi.e-conomic.com
ECONOMIC_APP_SECRET_TOKEN=your_app_secret_token
ECONOMIC_AGREEMENT_GRANT_TOKEN=your_agreement_grant_token
# Safety switches (ALWAYS start with these enabled)
ECONOMIC_READ_ONLY=true
ECONOMIC_DRY_RUN=true
```
### 3. Configure Default Settings
The default journal number and accounts can be configured via database:
```sql
-- Update default kassekladde number
UPDATE supplier_invoice_settings
SET setting_value = '1'
WHERE setting_key = 'economic_default_journal';
-- Update default expense account
UPDATE supplier_invoice_settings
SET setting_value = '5810'
WHERE setting_key = 'economic_default_contra_account';
```
### 4. Restart Application
```bash
docker-compose restart api
```
## Usage Guide
### Creating a Supplier Invoice
1. Navigate to `/billing/supplier-invoices`
2. Click "Ny Faktura" button
3. Fill in required fields:
- Invoice number (from supplier)
- Vendor (select from dropdown)
- Invoice date
- Total amount (incl. VAT)
4. Add line items with:
- Description
- Quantity & price
- VAT code (25%, 0%, reverse charge, etc.)
5. Click "Gem" to save
### Approval Workflow
**Status Flow:**
```
pending → approved → sent_to_economic → paid
```
**Steps:**
1. Invoice created → Status: `pending`
2. Review and approve → Status: `approved`
3. Send to e-conomic → Status: `sent_to_economic` (voucher created)
4. Mark as paid → Status: `paid`
### Sending to e-conomic
**Prerequisites:**
- Invoice must be `approved`
- Vendor must exist (auto-created if needed)
- At least one line item
**Process:**
1. Click "Send til e-conomic" button
2. System will:
- Check/create vendor in e-conomic
- Build VAT breakdown from lines
- Create journal voucher entry
- Upload PDF attachment (if available)
- Update invoice with voucher number
**Result:**
- Voucher created in e-conomic kassekladde
- Invoice status → `sent_to_economic`
- Voucher number stored for reference
## e-conomic Integration Details
### Safety Modes
**READ_ONLY Mode** (default: `true`)
- Blocks ALL write operations to e-conomic
- Only GET requests allowed
- Use for testing API connection
**DRY_RUN Mode** (default: `true`)
- Logs all operations but doesn't send to e-conomic
- Full payload preview in logs
- Safe for development/testing
**Production Mode** (both `false`)
- Actually sends data to e-conomic
- ⚠️ **Use with caution!**
- Always test with dry-run first
### Journal Voucher Structure
e-conomic vouchers use this format:
```json
{
"accountingYear": {"year": "2025"},
"journal": {"journalNumber": 1},
"entries": {
"supplierInvoices": [
{
"supplier": {"supplierNumber": 123},
"amount": 1250.00,
"contraAccount": {"accountNumber": 5810},
"currency": {"code": "DKK"},
"date": "2025-12-06",
"dueDate": "2026-01-05",
"supplierInvoiceNumber": "INV-12345",
"text": "Invoice description",
"contraVatAccount": {"vatCode": "I25"},
"contraVatAmount": 250.00
}
]
}
}
```
### VAT Code Mapping
| VAT Code | Description | Rate | Use Case |
|----------|-------------|------|----------|
| `I25` | Indenlandsk købsmoms 25% | 25% | Standard Danish purchases |
| `I0` | Momsfri køb | 0% | VAT exempt |
| `IY25` | Omvendt betalingspligt 25% | 25% | Reverse charge |
| `IYEU` | Omvendt EU | 0% | EU reverse charge |
| `IVEU` | Erhvervelse EU | 25% | EU acquisition |
### Account Number Mapping
Default expense accounts (can be customized per line):
- `5810` - Drift og materialer (default)
- `5820` - IT og software
- `5830` - Telefoni og internet
- `5840` - Kontorartikler
- `6000` - Løn og honorarer
## Development Guide
### Adding New Features
**1. Backend Endpoint:**
```python
# app/billing/backend/supplier_invoices.py
@router.post("/supplier-invoices/{invoice_id}/custom-action")
async def custom_action(invoice_id: int):
# Your logic here
return {"success": True}
```
**2. Frontend Integration:**
```javascript
// supplier_invoices.html
async function customAction(invoiceId) {
const response = await fetch(`/api/v1/supplier-invoices/${invoiceId}/custom-action`, {
method: 'POST'
});
// Handle response
}
```
### Testing e-conomic Integration
**1. Test Connection:**
```python
from app.services.economic_service import get_economic_service
economic = get_economic_service()
result = await economic.test_connection()
# Should return True if credentials are valid
```
**2. Test Dry-Run Mode:**
```bash
# In .env
ECONOMIC_READ_ONLY=false
ECONOMIC_DRY_RUN=true
```
Then create and approve an invoice, send to e-conomic. Check logs for full payload without actually posting.
**3. Production Test:**
```bash
# WARNING: This will create real data in e-conomic!
ECONOMIC_READ_ONLY=false
ECONOMIC_DRY_RUN=false
```
Start with a small test invoice to verify everything works.
## Troubleshooting
### Issue: "No journals found"
**Solution:** Check e-conomic credentials and ensure user has access to journals/kassekladder.
### Issue: "Supplier not found in e-conomic"
**Solution:** System will auto-create supplier if `ECONOMIC_DRY_RUN=false`. Verify vendor name is correct.
### Issue: "VAT validation failed"
**Solution:** Ensure VAT codes match e-conomic settings. Check `vat_code` in line items (I25, I0, etc.).
### Issue: "Voucher creation failed"
**Solution:**
1. Check e-conomic API logs in application logs
2. Verify journal number exists in e-conomic
3. Ensure all required fields are present (supplier, amount, date)
4. Check contra account number is valid
## Integration with OmniSync
This module is based on OmniSync's proven kassekladde implementation with the following enhancements:
- ✅ PostgreSQL instead of SQLite
- ✅ Nordic Top design instead of custom CSS
- ✅ Integrated with BMC Hub's vendor system
- ✅ Simplified approval workflow
- ✅ Better error handling and logging
## References
- **e-conomic API Docs:** https://restdocs.e-conomic.com/
- **Journals API:** https://restdocs.e-conomic.com/#journals
- **Vouchers API:** https://restdocs.e-conomic.com/#vouchers
- **Suppliers API:** https://restdocs.e-conomic.com/#suppliers
## Support
For issues or questions:
1. Check application logs: `docker-compose logs -f api`
2. Review e-conomic API response in logs
3. Test with DRY_RUN mode first
4. Contact system administrator
---
**Last Updated:** December 6, 2025
**Version:** 1.0.0
**Maintained by:** BMC Networks Development Team