import json import os import gspread from google.oauth2 import service_account def get_sheets_credentials(): """Get Google Sheets credentials from environment.""" key = os.environ.get('SERVICE_ACCOUNT_KEY') if not key: key_file_path = os.environ.get('SERVICE_ACCOUNT_KEY_FILE', '/app/service_account_key.json') if os.path.exists(key_file_path): with open(key_file_path, 'r') as f: return json.load(f) return None return json.loads(key) if isinstance(key, str) else key def fill_new_punchlist(data, sheet_id): """ Fills out a new punchlist from template. Arguments: data: dict : Data from the request sheet_id: str : Google Sheet ID Returns: str : URL to the filled sheet, or None on error """ try: scopes = ["https://www.googleapis.com/auth/spreadsheets"] key = get_sheets_credentials() impersonator = os.environ.get('DISPATCH_EMAIL', 'dispatch@example.com') creds = service_account.Credentials.from_service_account_info( key, scopes=scopes, subject=impersonator ) client = gspread.authorize(creds) workbook = client.open_by_key(sheet_id) sheet = workbook.worksheet("Sheet1") # Map form fields to sheet cells # Customize this mapping based on your punchlist template fields_cell_map = { 'store': 'B4', 'date': 'D4', 'notes': 'A52', # Add your punchlist fields here # 'fieldName': 'CellReference', } updates = [] for key, cell in fields_cell_map.items(): if key not in data: continue if key == 'notes': notes_data = [[line] for line in data['notes'].splitlines()] updates.append({'range': cell, 'values': notes_data}) else: value = data[key] if value == 'on': updates.append({'range': cell, 'values': [['yes']]}) elif not value: updates.append({'range': cell, 'values': [['no']]}) else: updates.append({'range': cell, 'values': [[value]]}) if updates: sheet.batch_update(updates) return f"https://docs.google.com/spreadsheets/d/{sheet_id}/edit" except gspread.exceptions.APIError as e: print(f"Google Sheets API error: {e}") return None except KeyError as e: print(f"Missing key in data: {e}") return None except Exception as e: print(f"An unexpected error occurred: {e}") return None