fix: Timetracking wizard approval endpoint (v1.3.76)

- Fix parameter handling in approve_time_entry endpoint
- Change from query params to body Dict[str, Any]
- Send all required fields to wizard.approve_time_entry()
- Calculate rounded_to if auto-rounding enabled
- Add approval_note, billable, is_travel fields
- Add Dict, Any imports
This commit is contained in:
Christian 2026-01-02 12:45:25 +01:00
parent 6c4042b9b6
commit 7cb38663bc
3 changed files with 97 additions and 11 deletions

73
RELEASE_NOTES_v1.3.76.md Normal file
View File

@ -0,0 +1,73 @@
# Release Notes - v1.3.76
**Release Date:** 2. januar 2026
## 🐛 Bug Fixes
### Timetracking Wizard Approval
- **Fixed approval endpoint** - Wizard approval nu virker korrekt
- **Fixed parameter handling** - Router modtager nu body params korrekt som Dict
- **Fixed missing fields** - Sender nu alle nødvendige felter til wizard.approve_time_entry():
- `rounded_to` beregnes hvis auto-rounding er enabled
- `approval_note` sendes med fra frontend
- `billable` sættes til true som default
- `is_travel` sendes med fra checkbox
### Technical Details
- Ændret `/api/v1/timetracking/wizard/approve/{time_id}` endpoint
- Modtager nu `request: Dict[str, Any]` i stedet for individuelle query params
- Tilføjet `Dict, Any` imports i router
- Beregner `rounded_to` baseret på TIMETRACKING_AUTO_ROUND setting
## 📝 Files Changed
- `app/timetracking/backend/router.py` - Fixed approve_time_entry endpoint
## 🚀 Deployment Instructions
### Production Server Update
1. **SSH til serveren:**
```bash
ssh bmcadmin@172.16.31.183
```
2. **Naviger til projekt directory:**
```bash
cd /opt/bmc_hub
```
3. **Pull ny version:**
```bash
git fetch --tags
git checkout v1.3.76
```
4. **Genstart containers:**
```bash
docker-compose restart api
```
5. **Verificer:**
```bash
curl http://localhost:8001/health
# Test approval:
# Gå til http://172.16.31.183:8000/timetracking/wizard
# Godkend en tidsregistrering
```
## ⚠️ Breaking Changes
None - this is a bug fix
## 📊 Impact
- Timetracking wizard approval virker nu igen
- Ingen database ændringer nødvendige
- Ingen configuration ændringer nødvendige
---
**Git Tag:** v1.3.76
**Previous Version:** v1.3.75
**Commit:** TBD

View File

@ -1 +1 @@
1.3.75
1.3.76

View File

@ -7,7 +7,7 @@ Isoleret routing uden påvirkning af existing Hub endpoints.
"""
import logging
from typing import Optional, List
from typing import Optional, List, Dict, Any
from fastapi import APIRouter, HTTPException, Depends
from fastapi.responses import JSONResponse
@ -218,9 +218,7 @@ async def get_next_pending_entry(
@router.post("/wizard/approve/{time_id}", response_model=TModuleTimeWithContext, tags=["Wizard"])
async def approve_time_entry(
time_id: int,
billable_hours: Optional[float] = None,
hourly_rate: Optional[float] = None,
rounding_method: Optional[str] = None,
request: Dict[str, Any],
user_id: Optional[int] = None
):
"""
@ -229,10 +227,12 @@ async def approve_time_entry(
Path params:
- time_id: ID tidsregistreringen
Body (optional):
- billable_hours: Timer efter godkendelse (hvis ikke angivet, bruges original_hours med auto-rounding)
- hourly_rate: Timepris i DKK (override customer rate)
- rounding_method: "up", "down", "nearest" (override default)
Body:
- billable_hours: Timer efter godkendelse (optional)
- hourly_rate: Timepris i DKK (optional)
- is_travel: True hvis kørsel (optional)
- approval_note: Godkendelsesnote (optional)
- rounding_method: "up", "down", "nearest" (optional)
"""
try:
from app.core.config import settings
@ -253,6 +253,9 @@ async def approve_time_entry(
raise HTTPException(status_code=404, detail="Time entry not found")
# Beregn approved_hours
billable_hours = request.get('billable_hours')
rounding_method = request.get('rounding_method')
if billable_hours is None:
approved_hours = Decimal(str(entry['original_hours']))
@ -267,20 +270,30 @@ async def approve_time_entry(
approved_hours = (approved_hours / increment).quantize(Decimal('1'), rounding='ROUND_DOWN') * increment
else:
approved_hours = (approved_hours / increment).quantize(Decimal('1'), rounding='ROUND_HALF_UP') * increment
rounded_to = increment
else:
rounded_to = None
else:
approved_hours = Decimal(str(billable_hours))
rounded_to = None
# Opdater med hourly_rate hvis angivet
hourly_rate = request.get('hourly_rate')
if hourly_rate is not None:
execute_update(
"UPDATE tmodule_times SET hourly_rate = %s WHERE id = %s",
(Decimal(str(hourly_rate)), time_id)
)
# Godkend
# Godkend med alle felter
approval = TModuleTimeApproval(
time_id=time_id,
approved_hours=float(approved_hours)
approved_hours=float(approved_hours),
rounded_to=float(rounded_to) if rounded_to else None,
approval_note=request.get('approval_note'),
billable=True, # Default til fakturerbar
is_travel=request.get('is_travel', False)
)
return wizard.approve_time_entry(approval, user_id=user_id)