Data_request / sheets_integration.py
Rathapoom's picture
Update sheets_integration.py
c59bc01 verified
raw
history blame
8.66 kB
import os
import json
from datetime import datetime
from enum import Enum
import gspread
from google.oauth2 import service_account
class RequestStatus(Enum):
NEW = "New"
IN_PROGRESS = "In Progress"
PENDING_INFO = "Pending Additional Info"
DATA_COLLECTION = "Data Collection"
READY_FOR_REVIEW = "Ready for Review"
COMPLETED = "Completed"
CANCELLED = "Cancelled"
ON_HOLD = "On Hold"
class SheetsLogger:
def __init__(self):
self.gc = None
self.sheet = None
self.initialize_client()
def initialize_client(self):
"""Initialize Google Sheets client"""
try:
# Get credentials from environment variable
creds_json = os.getenv('GOOGLE_SHEETS_CREDS')
if not creds_json:
raise ValueError("Google Sheets credentials not found in environment")
# Parse credentials JSON
creds_dict = json.loads(creds_json)
# Create credentials object
credentials = service_account.Credentials.from_service_account_info(
creds_dict,
scopes=['https://spreadsheets.google.com/feeds',
'https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive']
)
# Initialize gspread client
self.gc = gspread.authorize(credentials)
# Open spreadsheet by ID
SHEET_ID = os.getenv('GOOGLE_SHEET_ID')
if not SHEET_ID:
raise ValueError("Google Sheet ID not found in environment")
self.sheet = self.gc.open_by_key(SHEET_ID).sheet1
# Initialize headers if needed
self.initialize_sheet()
except Exception as e:
print(f"Error initializing Google Sheets client: {str(e)}")
self.gc = None
self.sheet = None
def initialize_sheet(self):
"""Initialize sheet with headers if needed"""
headers = [
"Timestamp",
"Name",
"Employee ID",
"Email",
"Department",
"Request Details",
"Frequency",
"Urgency",
"User Summary",
"Technical Analysis",
"Status",
"Notes",
"Last Updated"
]
try:
# Check if headers exist
existing_headers = self.sheet.row_values(1)
if not existing_headers:
self.sheet.insert_row(headers, 1)
# Format header row
self.sheet.format('A1:M1', {
"backgroundColor": {"red": 0.2, "green": 0.2, "blue": 0.2},
"textFormat": {"bold": True, "foregroundColor": {"red": 1, "green": 1, "blue": 1}}
})
# Set column widths
self.sheet.format('A:M', {
"wrapStrategy": "WRAP"
})
except Exception as e:
print(f"Error initializing headers: {str(e)}")
def log_request(self, data):
"""Log a request to Google Sheets"""
if not self.sheet:
print("Sheet not initialized")
return False
try:
# Prepare row data
row = [
data.get('timestamp', datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
data.get('name', ''),
data.get('employee_id', ''),
data.get('email', ''),
data.get('department', ''),
data.get('request_details', ''),
data.get('frequency', ''),
data.get('urgency', ''),
data.get('user_summary', ''),
data.get('system_analysis', ''),
RequestStatus.NEW.value, # Initial status
'', # Empty notes
datetime.now().strftime("%Y-%m-%d %H:%M:%S") # Last updated
]
# Append row to sheet
self.sheet.append_row(row)
# Get the row number that was just added
last_row = len(self.sheet.get_all_values())
# Apply conditional formatting for status
self.apply_status_formatting(last_row)
print(f"Successfully logged request to row {last_row}")
return True
except Exception as e:
print(f"Error logging to sheet: {str(e)}")
return False
def apply_status_formatting(self, row_number):
"""Apply conditional formatting based on status"""
status_cell = f'K{row_number}'
formats = {
RequestStatus.NEW.value: {
"backgroundColor": {"red": 1, "green": 1, "blue": 0.8} # Light yellow
},
RequestStatus.IN_PROGRESS.value: {
"backgroundColor": {"red": 0.8, "green": 0.9, "blue": 1} # Light blue
},
RequestStatus.PENDING_INFO.value: {
"backgroundColor": {"red": 1, "green": 0.8, "blue": 0.8} # Light red
},
RequestStatus.DATA_COLLECTION.value: {
"backgroundColor": {"red": 0.8, "green": 1, "blue": 0.8} # Light green
},
RequestStatus.READY_FOR_REVIEW.value: {
"backgroundColor": {"red": 0.9, "green": 0.9, "blue": 1} # Light purple
},
RequestStatus.COMPLETED.value: {
"backgroundColor": {"red": 0.9, "green": 1, "blue": 0.9} # Lighter green
},
RequestStatus.CANCELLED.value: {
"backgroundColor": {"red": 0.9, "green": 0.9, "blue": 0.9} # Gray
},
RequestStatus.ON_HOLD.value: {
"backgroundColor": {"red": 1, "green": 0.9, "blue": 0.8} # Light orange
}
}
try:
status = self.sheet.acell(status_cell).value
if status in formats:
self.sheet.format(status_cell, formats[status])
except Exception as e:
print(f"Error applying formatting: {str(e)}")
def update_status(self, row_number, new_status, notes=None):
"""Update the status and notes of a request"""
try:
if not isinstance(new_status, str):
if isinstance(new_status, RequestStatus):
new_status = new_status.value
else:
raise ValueError("Invalid status type")
# Update status
self.sheet.update_cell(row_number, 11, new_status) # Column K
# Update notes if provided
if notes:
current_notes = self.sheet.cell(row_number, 12).value # Column L
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
updated_notes = f"{current_notes}\n{timestamp}: {notes}" if current_notes else f"{timestamp}: {notes}"
self.sheet.update_cell(row_number, 12, updated_notes)
# Update last updated timestamp
self.sheet.update_cell(row_number, 13, datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
# Apply formatting
self.apply_status_formatting(row_number)
return True
except Exception as e:
print(f"Error updating status: {str(e)}")
return False
def get_request_history(self, request_id=None, employee_id=None):
"""Get request history filtered by ID or employee"""
try:
all_data = self.sheet.get_all_records()
if request_id:
return [row for row in all_data if str(row.get('Employee ID', '')).strip() == str(request_id).strip()]
elif employee_id:
return [row for row in all_data if str(row.get('Employee ID', '')).strip() == str(employee_id).strip()]
return all_data
except Exception as e:
print(f"Error getting history: {str(e)}")
return []
def get_request_by_row(self, row_number):
"""Get a specific request by row number"""
try:
if row_number < 2: # Row 1 is headers
return None
row_data = self.sheet.row_values(row_number)
headers = self.sheet.row_values(1)
return dict(zip(headers, row_data))
except Exception as e:
print(f"Error getting row {row_number}: {str(e)}")
return None