feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
"""
e - conomic Export Service for Time Tracking Module
== == == == == == == == == == == == == == == == == == == == == == == == ==
🚨 KRITISK : Denne service skal respektere safety flags .
Eksporterer ordrer til e - conomic som draft orders .
Safety Flags :
- TIMETRACKING_ECONOMIC_READ_ONLY = True ( default )
- TIMETRACKING_ECONOMIC_DRY_RUN = True ( default )
"""
import logging
2025-12-10 18:29:13 +01:00
import json
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
from typing import Optional , Dict , Any
import aiohttp
from fastapi import HTTPException
from app . core . config import settings
2025-12-16 22:07:20 +01:00
from app . core . database import execute_query , execute_update , execute_query_single
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
from app . timetracking . backend . models import (
TModuleEconomicExportRequest ,
TModuleEconomicExportResult
2025-12-16 22:07:20 +01:00
)
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
from app . timetracking . backend . audit import audit
2025-12-23 01:44:14 +01:00
from app . timetracking . backend . vtiger_sync import vtiger_service
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
logger = logging . getLogger ( __name__ )
class EconomicExportService :
"""
e - conomic integration for Time Tracking Module .
🔒 SAFETY - FIRST service - all writes controlled by flags .
"""
def __init__ ( self ) :
self . api_url = settings . ECONOMIC_API_URL
self . app_secret_token = settings . ECONOMIC_APP_SECRET_TOKEN
self . agreement_grant_token = settings . ECONOMIC_AGREEMENT_GRANT_TOKEN
# Safety flags
self . read_only = settings . TIMETRACKING_ECONOMIC_READ_ONLY
self . dry_run = settings . TIMETRACKING_ECONOMIC_DRY_RUN
self . export_type = settings . TIMETRACKING_EXPORT_TYPE
# Log safety status
if self . read_only :
logger . warning ( " 🔒 TIMETRACKING e-conomic READ-ONLY mode: Enabled " )
if self . dry_run :
logger . warning ( " 🏃 TIMETRACKING e-conomic DRY-RUN mode: Enabled " )
if not self . read_only :
logger . error ( " ⚠️ WARNING: TIMETRACKING e-conomic READ-ONLY disabled! " )
def _get_headers ( self ) - > Dict [ str , str ] :
""" Get e-conomic API headers """
return {
' X-AppSecretToken ' : self . app_secret_token ,
' X-AgreementGrantToken ' : self . agreement_grant_token ,
' Content-Type ' : ' application/json '
}
def _check_write_permission ( self , operation : str ) - > bool :
"""
Check om write operation er tilladt .
Returns :
True hvis operationen må udføres , False hvis blokeret
"""
if self . read_only :
logger . error ( f " 🚫 BLOCKED: { operation } - READ_ONLY mode enabled " )
return False
if self . dry_run :
logger . warning ( f " 🏃 DRY-RUN: { operation } - Would execute but not sending " )
return False
logger . warning ( f " ⚠️ EXECUTING WRITE: { operation } " )
return True
async def test_connection ( self ) - > bool :
""" Test e-conomic connection """
try :
logger . info ( " 🔍 Testing e-conomic connection... " )
async with aiohttp . ClientSession ( ) as session :
async with session . get (
f " { self . api_url } /self " ,
headers = self . _get_headers ( ) ,
timeout = aiohttp . ClientTimeout ( total = 10 )
) as response :
if response . status == 200 :
logger . info ( " ✅ e-conomic connection successful " )
return True
else :
logger . error ( f " ❌ e-conomic connection failed: { response . status } " )
return False
except Exception as e :
logger . error ( f " ❌ e-conomic connection error: { e } " )
return False
2025-12-15 12:28:12 +01:00
async def check_draft_exists ( self , draft_id : int ) - > bool :
"""
Tjek om en draft order stadig eksisterer i e - conomic .
Args :
draft_id : e - conomic draft order nummer
Returns :
True hvis draft findes , False hvis slettet eller ikke fundet
"""
try :
logger . info ( f " 🔍 Checking if draft { draft_id } exists in e-conomic... " )
async with aiohttp . ClientSession ( ) as session :
async with session . get (
f " { self . api_url } /orders/drafts/ { draft_id } " ,
headers = self . _get_headers ( ) ,
timeout = aiohttp . ClientTimeout ( total = 10 )
) as response :
if response . status == 200 :
logger . info ( f " ✅ Draft { draft_id } exists in e-conomic " )
return True
elif response . status == 404 :
logger . info ( f " ✅ Draft { draft_id } NOT found in e-conomic (deleted) " )
return False
else :
error_text = await response . text ( )
logger . error ( f " ❌ e-conomic check failed ( { response . status } ): { error_text } " )
raise Exception ( f " e-conomic API error: { response . status } " )
except aiohttp . ClientError as e :
logger . error ( f " ❌ e-conomic connection error: { e } " )
raise Exception ( f " Kunne ikke forbinde til e-conomic: { str ( e ) } " )
except Exception as e :
logger . error ( f " ❌ Draft check error: { e } " )
raise
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
async def export_order (
self ,
request : TModuleEconomicExportRequest ,
user_id : Optional [ int ] = None
) - > TModuleEconomicExportResult :
"""
Eksporter ordre til e - conomic som draft order .
Args :
request : Export request med order_id
user_id : ID på brugeren der eksporterer
Returns :
Export result med success status
"""
try :
# Hent ordre med linjer
order_query = """
SELECT o . * , c . name as customer_name , c . vtiger_id as customer_vtiger_id
FROM tmodule_orders o
JOIN tmodule_customers c ON o . customer_id = c . id
WHERE o . id = % s
"""
2025-12-16 15:36:11 +01:00
order = execute_query_single ( order_query , ( request . order_id , ) )
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
if not order :
raise HTTPException ( status_code = 404 , detail = " Order not found " )
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
# Check if order is posted (locked)
if order [ ' status ' ] == ' posted ' :
raise HTTPException (
status_code = 403 ,
detail = f " Ordre er bogført til e-conomic og kan ikke ændres. e-conomic ordre nr.: { order . get ( ' economic_order_number ' ) } "
)
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
# Check if already exported
if order [ ' economic_draft_id ' ] and not request . force :
raise HTTPException (
status_code = 400 ,
detail = f " Order already exported (draft ID: { order [ ' economic_draft_id ' ] } ). Use force=true to re-export. "
)
# Hent ordre-linjer
lines_query = """
SELECT * FROM tmodule_order_lines
WHERE order_id = % s
ORDER BY line_number
"""
2025-12-17 07:56:33 +01:00
lines = execute_query ( lines_query , ( request . order_id , ) )
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
if not lines :
raise HTTPException (
status_code = 400 ,
detail = " Order has no lines "
)
# Log export start
audit . log_export_started (
order_id = request . order_id ,
user_id = user_id
)
# Check safety flags
operation = f " Export order { request . order_id } to e-conomic "
if not self . _check_write_permission ( operation ) :
# Dry-run or read-only mode
result = TModuleEconomicExportResult (
success = True ,
dry_run = True ,
order_id = request . order_id ,
economic_draft_id = None ,
economic_order_number = None ,
message = f " DRY-RUN: Would export order { order [ ' order_number ' ] } to e-conomic " ,
details = {
" order_number " : order [ ' order_number ' ] ,
" customer_name " : order [ ' customer_name ' ] ,
" total_amount " : float ( order [ ' total_amount ' ] ) ,
" line_count " : len ( lines ) ,
" read_only " : self . read_only ,
" dry_run " : self . dry_run
}
)
# Log dry-run completion
audit . log_export_completed (
order_id = request . order_id ,
economic_draft_id = None ,
economic_order_number = None ,
dry_run = True ,
user_id = user_id
)
return result
# REAL EXPORT (kun hvis safety flags er disabled)
logger . warning ( f " ⚠️ REAL EXPORT STARTING for order { request . order_id } " )
2025-12-13 12:06:28 +01:00
# Hent e-conomic customer number fra Hub customers via hub_customer_id
2025-12-10 18:29:13 +01:00
customer_number_query = """
2025-12-13 12:06:28 +01:00
SELECT c . economic_customer_number
FROM tmodule_customers tc
LEFT JOIN customers c ON tc . hub_customer_id = c . id
WHERE tc . id = % s
2025-12-10 18:29:13 +01:00
"""
2025-12-17 07:56:33 +01:00
customer_data = execute_query_single ( customer_number_query , ( order [ ' customer_id ' ] , ) )
2025-12-10 18:29:13 +01:00
if not customer_data or not customer_data . get ( ' economic_customer_number ' ) :
2026-01-05 10:42:57 +01:00
# Check if customer is linked at all
check_link = execute_query_single (
" SELECT hub_customer_id FROM tmodule_customers WHERE id = %s " ,
( order [ ' customer_id ' ] , )
2025-12-10 18:29:13 +01:00
)
2026-01-05 10:42:57 +01:00
if not check_link or not check_link . get ( ' hub_customer_id ' ) :
raise HTTPException (
status_code = 400 ,
detail = f " Customer ' { order [ ' customer_name ' ] } ' er ikke linket til en Hub kunde. Gå til vTiger kunder og link kunden først. "
)
else :
raise HTTPException (
status_code = 400 ,
detail = f " Customer ' { order [ ' customer_name ' ] } ' mangler e-conomic kundenummer. Opdater kunde i Customers modulet. "
)
2025-12-10 18:29:13 +01:00
customer_number = customer_data [ ' economic_customer_number ' ]
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
2026-01-10 01:37:08 +01:00
# 🔍 VALIDATE: Check if customer exists in e-conomic
logger . info ( f " 🔍 Validating customer { customer_number } exists in e-conomic... " )
async with aiohttp . ClientSession ( ) as session :
async with session . get (
f " { self . api_url } /customers/ { customer_number } " ,
headers = self . _get_headers ( ) ,
timeout = aiohttp . ClientTimeout ( total = 10 )
) as response :
if response . status == 404 :
raise HTTPException (
status_code = 400 ,
detail = f " Kunde ' { order [ ' customer_name ' ] } ' med e-conomic nummer ' { customer_number } ' findes ikke i e-conomic. Kontroller kundenummeret i Customers modulet. "
)
elif response . status != 200 :
logger . warning ( f " ⚠️ Could not validate customer: { response . status } " )
# Continue anyway - might be network issue
# 🔍 VALIDATE: Check if layout exists in e-conomic
layout_number = settings . TIMETRACKING_ECONOMIC_LAYOUT
logger . info ( f " 🔍 Validating layout { layout_number } exists in e-conomic... " )
async with aiohttp . ClientSession ( ) as session :
async with session . get (
f " { self . api_url } /layouts/ { layout_number } " ,
headers = self . _get_headers ( ) ,
timeout = aiohttp . ClientTimeout ( total = 10 )
) as response :
if response . status == 404 :
raise HTTPException (
status_code = 400 ,
detail = f " Layout nummer ' { layout_number } ' findes ikke i e-conomic. Opdater TIMETRACKING_ECONOMIC_LAYOUT i .env filen med et gyldigt layout nummer fra e-conomic. "
)
elif response . status != 200 :
logger . warning ( f " ⚠️ Could not validate layout: { response . status } " )
# Continue anyway - might be network issue
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
# Build e-conomic draft order payload
economic_payload = {
2025-12-10 18:29:13 +01:00
" date " : order [ ' order_date ' ] . isoformat ( ) if hasattr ( order [ ' order_date ' ] , ' isoformat ' ) else str ( order [ ' order_date ' ] ) ,
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
" currency " : " DKK " ,
" exchangeRate " : 100 ,
2025-12-23 01:33:19 +01:00
" otherReference " : order [ ' order_number ' ] , # Hub ordre nummer (TT-20251222-005)
2025-12-10 18:29:13 +01:00
" customer " : {
" customerNumber " : customer_number
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
} ,
2025-12-10 18:29:13 +01:00
" recipient " : {
" name " : order [ ' customer_name ' ] ,
" vatZone " : {
" vatZoneNumber " : 1 # Domestic Denmark
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
}
2025-12-10 18:29:13 +01:00
} ,
" paymentTerms " : {
" paymentTermsNumber " : 1 # Default payment terms
} ,
" layout " : {
2025-12-23 01:04:44 +01:00
" layoutNumber " : settings . TIMETRACKING_ECONOMIC_LAYOUT
2025-12-10 18:29:13 +01:00
} ,
" notes " : {
2026-01-05 18:56:24 +01:00
" heading " : " Tidsregistrering "
2025-12-10 18:29:13 +01:00
} ,
" lines " : [ ]
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
}
2025-12-10 18:29:13 +01:00
# Add notes if present
if order . get ( ' notes ' ) :
economic_payload [ ' notes ' ] [ ' textLine1 ' ] = order [ ' notes ' ]
# Build order lines
for idx , line in enumerate ( lines , start = 1 ) :
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
# Format: "CC0042. 3 timer 1200,- 3600 / Fejlsøgning / 27.05.2025 - Kontaktnavn"
# Extract case number and title from existing description
desc_parts = line [ ' description ' ] . split ( ' - ' , 1 )
case_number = desc_parts [ 0 ] if desc_parts else " "
case_title = desc_parts [ 1 ] if len ( desc_parts ) > 1 else line [ ' description ' ]
# Build formatted description
hours = float ( line [ ' quantity ' ] )
price = float ( line [ ' unit_price ' ] )
total = hours * price
# Format date (Danish format DD.MM.YYYY)
date_str = " "
if line . get ( ' time_date ' ) :
time_date = line [ ' time_date ' ]
if isinstance ( time_date , str ) :
from datetime import datetime
time_date = datetime . fromisoformat ( time_date ) . date ( )
date_str = time_date . strftime ( " %d . % m. % Y " )
2025-12-23 01:33:19 +01:00
# Build description (case_number + task details)
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
contact_part = f " - { line [ ' case_contact ' ] } " if line . get ( ' case_contact ' ) else " "
travel_marker = " - (Udkørsel) " if line . get ( ' is_travel ' ) else " "
2025-12-23 01:33:19 +01:00
formatted_desc = f " { case_number } / { case_title } / { date_str } { contact_part } { travel_marker } "
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
2025-12-10 18:29:13 +01:00
economic_line = {
" lineNumber " : idx ,
" sortKey " : idx ,
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
" description " : formatted_desc ,
" quantity " : hours ,
" unitNetPrice " : price ,
" product " : {
2025-12-23 01:11:58 +01:00
" productNumber " : line . get ( ' product_number ' ) or settings . TIMETRACKING_ECONOMIC_PRODUCT
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
} ,
2025-12-10 18:29:13 +01:00
" unit " : {
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
" unitNumber " : 2 # timer (unit 2 in e-conomic)
2025-12-10 18:29:13 +01:00
}
}
# Add discount if present
if line . get ( ' discount_percentage ' ) :
economic_line [ ' discountPercentage ' ] = float ( line [ ' discount_percentage ' ] )
economic_payload [ ' lines ' ] . append ( economic_line )
logger . info ( f " 📤 Sending to e-conomic: { json . dumps ( economic_payload , indent = 2 , default = str ) } " )
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
# Call e-conomic API
async with aiohttp . ClientSession ( ) as session :
async with session . post (
f " { self . api_url } /orders/drafts " ,
headers = self . _get_headers ( ) ,
json = economic_payload ,
timeout = aiohttp . ClientTimeout ( total = 30 )
) as response :
2025-12-10 18:29:13 +01:00
response_text = await response . text ( )
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
if response . status not in [ 200 , 201 ] :
2025-12-10 18:29:13 +01:00
logger . error ( f " ❌ e-conomic export failed: { response . status } " )
logger . error ( f " Response: { response_text } " )
logger . error ( f " Payload: { json . dumps ( economic_payload , indent = 2 , default = str ) } " )
# Try to parse error message
try :
error_data = json . loads ( response_text )
error_msg = error_data . get ( ' message ' , response_text )
# Parse detailed validation errors if present
if ' errors ' in error_data :
error_details = [ ]
for entity , entity_errors in error_data [ ' errors ' ] . items ( ) :
if isinstance ( entity_errors , dict ) and ' errors ' in entity_errors :
for err in entity_errors [ ' errors ' ] :
field = err . get ( ' propertyName ' , entity )
msg = err . get ( ' errorMessage ' , err . get ( ' message ' , ' Unknown ' ) )
error_details . append ( f " { field } : { msg } " )
if error_details :
error_msg = ' ; ' . join ( error_details )
except :
error_msg = response_text
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
# Log failed export
audit . log_export_failed (
order_id = request . order_id ,
2025-12-10 18:29:13 +01:00
error = error_msg ,
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
user_id = user_id
)
raise HTTPException (
status_code = response . status ,
2025-12-10 18:29:13 +01:00
detail = f " e-conomic API error: { error_msg } "
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
)
result_data = await response . json ( )
2025-12-10 18:29:13 +01:00
logger . info ( f " ✅ e-conomic response: { json . dumps ( result_data , indent = 2 , default = str ) } " )
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
# e-conomic returnerer orderNumber direkte for draft orders
order_number = result_data . get ( ' orderNumber ' ) or result_data . get ( ' draftOrderNumber ' )
economic_draft_id = int ( order_number ) if order_number else None
economic_order_number = str ( order_number ) if order_number else None
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
# Update order med e-conomic IDs og status = posted (bogført)
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
execute_update (
""" UPDATE tmodule_orders
SET economic_draft_id = % s ,
economic_order_number = % s ,
exported_at = CURRENT_TIMESTAMP ,
exported_by = % s ,
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
status = ' posted '
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
WHERE id = % s """ ,
( economic_draft_id , economic_order_number , user_id , request . order_id )
)
2026-01-08 18:57:04 +01:00
# Marker time entries som billed og opdater billed_via_thehub_id
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
execute_update (
""" UPDATE tmodule_times
2026-01-08 18:57:04 +01:00
SET status = ' billed ' ,
billed_via_thehub_id = % s
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
WHERE id IN (
SELECT UNNEST ( time_entry_ids )
FROM tmodule_order_lines
WHERE order_id = % s
) """ ,
2026-01-08 18:57:04 +01:00
( request . order_id , request . order_id )
feat: Implement email processing system with scheduler, fetching, classification, and rule matching
- Added EmailProcessorService to orchestrate email workflow: fetching, saving, classifying, and matching rules.
- Introduced EmailScheduler for background processing of emails every 5 minutes.
- Developed EmailService to handle email fetching from IMAP and Microsoft Graph API.
- Created database migration for email system, including tables for email messages, rules, attachments, and analysis.
- Implemented AI classification and extraction for invoices and time confirmations.
- Added logging for better traceability and error handling throughout the email processing pipeline.
2025-12-11 02:31:29 +01:00
)
2025-12-23 01:44:14 +01:00
# Hent vTiger IDs for tidsregistreringerne
vtiger_ids_query = """
SELECT t . vtiger_id
FROM tmodule_times t
WHERE t . id IN (
SELECT UNNEST ( time_entry_ids )
FROM tmodule_order_lines
WHERE order_id = % s
)
"""
vtiger_time_records = execute_query ( vtiger_ids_query , ( request . order_id , ) )
vtiger_ids = [ r [ ' vtiger_id ' ] for r in vtiger_time_records ]
# Opdater Timelog records i vTiger med Hub ordre ID
if vtiger_ids :
logger . info ( f " 📝 Updating { len ( vtiger_ids ) } timelogs in vTiger with Hub order { request . order_id } ... " )
try :
vtiger_update_result = await vtiger_service . update_timelog_billed (
vtiger_ids = vtiger_ids ,
hub_order_id = request . order_id
)
logger . info ( f " ✅ vTiger update: { vtiger_update_result } " )
except Exception as vtiger_error :
# Don't fail export if vTiger update fails - just log it
logger . error ( f " ⚠️ Could not update vTiger timelogs: { vtiger_error } " )
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
# Log successful export
audit . log_export_completed (
order_id = request . order_id ,
economic_draft_id = economic_draft_id ,
economic_order_number = economic_order_number ,
dry_run = False ,
user_id = user_id
)
logger . info ( f " ✅ Exported order { request . order_id } → e-conomic draft { economic_draft_id } " )
return TModuleEconomicExportResult (
success = True ,
dry_run = False ,
order_id = request . order_id ,
economic_draft_id = economic_draft_id ,
economic_order_number = economic_order_number ,
message = f " Successfully exported to e-conomic draft { economic_draft_id } " ,
details = result_data
)
except HTTPException :
raise
except Exception as e :
logger . error ( f " ❌ Error exporting order: { e } " )
# Log failed export
audit . log_export_failed (
order_id = request . order_id ,
error = str ( e ) ,
user_id = user_id
)
raise HTTPException ( status_code = 500 , detail = str ( e ) )
# Singleton instance
economic_service = EconomicExportService ( )