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:
parent
6c4042b9b6
commit
7cb38663bc
73
RELEASE_NOTES_v1.3.76.md
Normal file
73
RELEASE_NOTES_v1.3.76.md
Normal 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
|
||||
@ -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 på 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)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user