Fix: Wizard kan nu hoppe direkte til specifik tidsregistrering via time_id parameter

This commit is contained in:
Christian 2026-01-02 15:53:00 +01:00
parent 8100432079
commit bf72fc4a49
2 changed files with 73 additions and 0 deletions

View File

@ -947,6 +947,41 @@ async def get_customer_time_entries(customer_id: int, status: Optional[str] = No
times = execute_query(query, tuple(params))
return {"times": times, "total": len(times)}
@router.get("/times/{time_id}", tags=["Times"])
async def get_time_entry(time_id: int):
"""
Hent en specifik tidsregistrering.
Path params:
- time_id: Time entry ID
"""
try:
query = """
SELECT t.*,
COALESCE(c.vtiger_data->>'case_no', c.title)::VARCHAR(500) AS case_title,
c.vtiger_id AS case_vtiger_id,
c.description AS case_description,
cust.name AS customer_name
FROM tmodule_times t
LEFT JOIN tmodule_cases c ON t.case_id = c.id
LEFT JOIN tmodule_customers cust ON t.customer_id = cust.id
WHERE t.id = %s
"""
time_entry = execute_query_single(query, (time_id,))
if not time_entry:
raise HTTPException(status_code=404, detail="Time entry not found")
return time_entry
except HTTPException:
raise
except Exception as e:
logger.error(f"Error fetching time entry {time_id}: {e}")
raise HTTPException(status_code=500, detail=str(e))
except Exception as e:
logger.error(f"❌ Error getting customer time entries: {e}")

View File

@ -371,10 +371,48 @@
// Get URL parameters
const urlParams = new URLSearchParams(window.location.search);
currentCustomerId = urlParams.get('customer_id');
const specificTimeId = urlParams.get('time_id');
// Load config on startup
loadConfig();
// Load specific entry or next entry
if (specificTimeId) {
loadSpecificEntry(parseInt(specificTimeId));
} else {
loadNextEntry();
}
// Load a specific time entry
async function loadSpecificEntry(timeId) {
document.getElementById('loading-state').classList.remove('d-none');
document.getElementById('time-entry-container').classList.add('d-none');
document.getElementById('completion-state').classList.add('d-none');
try {
const response = await fetch(`/api/v1/timetracking/times/${timeId}`);
if (!response.ok) {
throw new Error('Time entry not found');
}
const entry = await response.json();
// Show the entry
displayTimeEntry({
time_entry: entry,
has_next: true, // Assume there might be more
remaining_count: 1
});
} catch (error) {
console.error('Error loading specific entry:', error);
showToast('Kunne ikke indlæse tidsregistrering', 'danger');
// Fall back to loading next entry
setTimeout(() => loadNextEntry(), 1000);
}
}
// Load next entry
async function loadNextEntry() {
document.getElementById('loading-state').classList.remove('d-none');