5.3 KiB
Time Tracking - Billed Via Hub Order ID
Oversigt
Implementeret tracking af hvilken Hub ordre (og dermed e-conomic ordre) hver tidsregistrering er blevet faktureret gennem.
Database Ændringer
Migration: 060_add_billed_via_thehub_id.sql
Tilføjet nyt felt til tmodule_times tabellen:
ALTER TABLE tmodule_times ADD COLUMN billed_via_thehub_id INTEGER;
ALTER TABLE tmodule_times
ADD CONSTRAINT tmodule_times_billed_via_thehub_id_fkey
FOREIGN KEY (billed_via_thehub_id)
REFERENCES tmodule_orders(id)
ON DELETE SET NULL;
CREATE INDEX idx_tmodule_times_billed_via_thehub_id ON tmodule_times(billed_via_thehub_id);
Felt beskrivelse:
billed_via_thehub_id: Hub ordre ID som tidsregistreringen er faktureret gennem- Foreign key til
tmodule_orders.id - Via Hub ordren kan man finde
economic_order_numbersom er ordrenummeret i e-conomic
Kode Ændringer
1. app/timetracking/backend/models.py
Tilføjet felt til TModuleTime Pydantic model:
billed_via_thehub_id: Optional[int] = Field(None, description="Hub order ID this time was billed through")
is_travel: bool = False # Også tilføjet manglende felt
2. app/timetracking/backend/economic_export.py
Opdateret export_order_to_economic() til at sætte billed_via_thehub_id når ordren eksporteres:
# Marker time entries som billed og opdater billed_via_thehub_id
execute_update(
"""UPDATE tmodule_times
SET status = 'billed',
billed_via_thehub_id = %s
WHERE id IN (
SELECT UNNEST(time_entry_ids)
FROM tmodule_order_lines
WHERE order_id = %s
)""",
(request.order_id, request.order_id)
)
Vigtig note: vTiger opdateres også via update_timelog_billed() som sætter billed_via_thehub_id i vTiger's Timelog records.
3. app/timetracking/backend/order_service.py
FJERNET for tidlig status opdatering:
# BEFORE: Time entries blev sat til 'billed' når Hub ordre blev oprettet
# AFTER: Time entries forbliver 'approved' indtil e-conomic eksporten er succesfuld
Nu opdateres status='billed' og billed_via_thehub_id KUN i economic_export.py efter succesfuld eksport.
4. app/timetracking/backend/vtiger_sync.py
BESKYTTELSE MOD OVERSKRIVNING: Tidsregistreringer med billed_via_thehub_id opdateres IKKE ved sync:
# Update only if NOT yet approved AND NOT yet billed
result = execute_update(
"""UPDATE tmodule_times
SET description = %s, original_hours = %s, worked_date = %s,
user_name = %s, billable = %s, vtiger_data = %s::jsonb,
sync_hash = %s, last_synced_at = CURRENT_TIMESTAMP
WHERE vtiger_id = %s
AND status = 'pending'
AND billed_via_thehub_id IS NULL""",
...
)
Dette sikrer at allerede fakturerede tidsregistreringer forbliver låst og ikke overskrevet af vTiger sync.
Workflow
Før ændringerne:
- Godkendte tider →
status='approved' - Opret ordre i Hub →
status='billed'⚠️ (for tidligt!) - Eksporter til e-conomic →
economic_order_numbersættes på Hub ordre
Efter ændringerne:
- Godkendte tider →
status='approved' - Opret ordre i Hub → tider forbliver
status='approved' - Eksporter til e-conomic →
status='billed'+billed_via_thehub_idsættes - vTiger opdateres også med
billed_via_thehub_id
Data Relations
tmodule_times.billed_via_thehub_id
↓ (foreign key)
tmodule_orders.id
→ tmodule_orders.economic_order_number (e-conomic ordre nummer)
→ tmodule_orders.economic_draft_id (e-conomic kladde ID)
Queries
Find alle tidsregistreringer for en e-conomic ordre:
SELECT t.*, o.economic_order_number
FROM tmodule_times t
JOIN tmodule_orders o ON t.billed_via_thehub_id = o.id
WHERE o.economic_order_number = '12345';
Find tider der er faktureret via en specifik Hub ordre:
SELECT * FROM tmodule_times
WHERE billed_via_thehub_id = 123;
Find tider der IKKE er faktureret endnu:
SELECT * FROM tmodule_times
WHERE status = 'approved'
AND billed_via_thehub_id IS NULL;
vTiger Integration
vTiger's Timelog records opdateres også via app/timetracking/backend/vtiger_sync.py:
async def update_timelog_billed(self, vtiger_ids: List[str], hub_order_id: int):
payload = {
"elementType": "Timelog",
"element": {
"id": vtiger_id,
"billed_via_thehub_id": str(hub_order_id),
"cf_timelog_invoiced": "1"
}
}
Note: cf_timelog_invoiced (IS BILLED) feltet i vTiger kan vi IKKE ændre fra Hub (vTiger begrænsning), men vi opdaterer vores eget billed_via_thehub_id felt.
Testing
Migrationen er kørt og verificeret:
docker exec bmc-hub-postgres psql -U bmc_hub -d bmc_hub -c "\d tmodule_times"
# Viser: billed_via_thehub_id | integer med foreign key
Deployment
- Migration er kørt på dev (060_add_billed_via_thehub_id.sql)
- Kode ændringer deployed i samme commit
- Eksisterende tidsregistreringer har
billed_via_thehub_id = NULL - Fremtidige eksporter vil populere feltet korrekt
Relaterede Filer
migrations/060_add_billed_via_thehub_id.sqlapp/timetracking/backend/models.pyapp/timetracking/backend/economic_export.pyapp/timetracking/backend/order_service.pyapp/timetracking/backend/vtiger_sync.py