From 08fd2a04c766219f494e6826a8af7b2ec5b80b98 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 6 Jan 2026 13:16:25 +0100 Subject: [PATCH] feat: Complete activity logging system - customer CRUD, contacts, subscriptions, BMC Office --- app/core/config.py | 1 + app/customers/backend/bmc_office_router.py | 20 ++++++++------------ app/customers/backend/router.py | 22 ++++++++++++++++++++++ requirements.txt | 1 + 4 files changed, 32 insertions(+), 12 deletions(-) diff --git a/app/core/config.py b/app/core/config.py index 745bed0..7729129 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -68,6 +68,7 @@ class Settings(BaseSettings): EMAIL_MAX_FETCH_PER_RUN: int = 50 EMAIL_PROCESS_INTERVAL_MINUTES: int = 5 EMAIL_WORKFLOWS_ENABLED: bool = True + EMAIL_MAX_UPLOAD_SIZE_MB: int = 50 # Max file size for email uploads # vTiger Cloud Integration VTIGER_ENABLED: bool = False diff --git a/app/customers/backend/bmc_office_router.py b/app/customers/backend/bmc_office_router.py index c87d9be..b534e33 100644 --- a/app/customers/backend/bmc_office_router.py +++ b/app/customers/backend/bmc_office_router.py @@ -102,12 +102,10 @@ async def upload_bmc_office_subscriptions(file: UploadFile = File(...)): # Log deletion for each affected customer for customer in affected_customers: - execute_update( - """INSERT INTO customer_activities (customer_id, activity_type, description, user_id) - VALUES (%s, %s, %s, %s)""", - (customer['customer_id'], 'bmc_office_sync', - f"BMC Office abonnementer fjernet før ny import: {customer['count']} abonnementer (værdi: {float(customer['value']):,.2f} DKK)", - 1) # System user + CustomerActivityLogger.log( + customer_id=customer['customer_id'], + activity_type='bmc_office_sync', + description=f"BMC Office abonnementer fjernet før ny import: {customer['count']} abonnementer (værdi: {float(customer['value']):,.2f} DKK)" ) # Process rows @@ -160,12 +158,10 @@ async def upload_bmc_office_subscriptions(file: UploadFile = File(...)): # Log import for each customer for customer in new_subscriptions: - execute_update( - """INSERT INTO customer_activities (customer_id, activity_type, description, user_id) - VALUES (%s, %s, %s, %s)""", - (customer['customer_id'], 'bmc_office_sync', - f"BMC Office abonnementer importeret: {customer['count']} abonnementer (værdi: {float(customer['value']):,.2f} DKK) - Produkter: {customer['products'][:200]}", - 1) # System user + CustomerActivityLogger.log( + customer_id=customer['customer_id'], + activity_type='bmc_office_sync', + description=f"BMC Office abonnementer importeret: {customer['count']} abonnementer (værdi: {float(customer['value']):,.2f} DKK) - Produkter: {customer['products'][:200]}" ) beskrivelse = str(row.get('Beskrivelse', '')).strip() diff --git a/app/customers/backend/router.py b/app/customers/backend/router.py index c68bcf5..e66a170 100644 --- a/app/customers/backend/router.py +++ b/app/customers/backend/router.py @@ -805,6 +805,10 @@ async def create_customer_contact(customer_id: int, contact: ContactCreate): logger.info(f"✅ Created contact {contact_id} for customer {customer_id}") + # Log activity + contact_name = f"{contact.first_name} {contact.last_name}".strip() + CustomerActivityLogger.log_contact_added(customer_id, contact_name) + # Fetch and return created contact created = execute_query_single( "SELECT * FROM contacts WHERE id = %s", @@ -1053,6 +1057,10 @@ async def create_subscription(customer_id: int, subscription: SubscriptionCreate subscriptionstatus=subscription.subscriptionstatus, products=subscription.products ) + + # Log activity + subscription_name = subscription.subject or 'Nyt abonnement' + CustomerActivityLogger.log_subscription_created(customer_id, subscription_name) logger.info(f"✅ Created subscription {result.get('id')} for customer {customer_id}") return {"status": "success", "subscription": result} @@ -1098,6 +1106,15 @@ async def update_subscription(subscription_id: str, subscription: SubscriptionUp line_items=line_items ) + # Log activity if we can find customer_id + if result and result.get('account_id'): + customer = execute_query_single( + "SELECT id, name FROM customers WHERE vtiger_id = %s", + (result['account_id'],)) + if customer: + subscription_name = result.get('subject', subscription_id) + CustomerActivityLogger.log_subscription_updated(customer['id'], subscription_name) + logger.info(f"✅ Updated subscription {subscription_id}") return {"status": "success", "subscription": result} @@ -1131,6 +1148,11 @@ async def delete_subscription(subscription_id: str, customer_id: int = None): line_items=None ) + # Log activity + if customer_id: + subscription_name = result.get('subject', subscription_id) if result else subscription_id + CustomerActivityLogger.log_subscription_deleted(customer_id, subscription_name) + logger.info(f"✅ Cancelled subscription {subscription_id}") return {"status": "success", "message": "Subscription cancelled"} diff --git a/requirements.txt b/requirements.txt index e8f68cb..cc58307 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,3 +12,4 @@ paramiko==3.4.1 apscheduler==3.10.4 pandas==2.2.3 openpyxl==3.1.2 +extract-msg==0.48.8