|
@@ -81,13 +81,48 @@ class ResCompany(models.Model):
|
|
|
'Authorization': f'Bearer {access_token}',
|
|
'Authorization': f'Bearer {access_token}',
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- # Test access to the specific folder
|
|
|
|
|
|
|
+ # Test access to the specific folder - try both regular Drive and Shared Drive endpoints
|
|
|
|
|
+ folder_found = False
|
|
|
|
|
+ folder_name = 'Unknown'
|
|
|
|
|
+
|
|
|
|
|
+ # First, try the regular Drive API endpoint
|
|
|
drive_api_url = f"https://www.googleapis.com/drive/v3/files/{self.google_drive_crm_folder_id}"
|
|
drive_api_url = f"https://www.googleapis.com/drive/v3/files/{self.google_drive_crm_folder_id}"
|
|
|
drive_response = requests.get(drive_api_url, headers=headers, timeout=10)
|
|
drive_response = requests.get(drive_api_url, headers=headers, timeout=10)
|
|
|
|
|
|
|
|
if drive_response.status_code == 200:
|
|
if drive_response.status_code == 200:
|
|
|
folder_data = drive_response.json()
|
|
folder_data = drive_response.json()
|
|
|
folder_name = folder_data.get('name', 'Unknown')
|
|
folder_name = folder_data.get('name', 'Unknown')
|
|
|
|
|
+ folder_found = True
|
|
|
|
|
+ elif drive_response.status_code == 404:
|
|
|
|
|
+ # If not found in regular Drive, try Shared Drive endpoint
|
|
|
|
|
+ shared_drive_api_url = f"https://www.googleapis.com/drive/v3/drives/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+ shared_drive_response = requests.get(shared_drive_api_url, headers=headers, timeout=10)
|
|
|
|
|
+
|
|
|
|
|
+ if shared_drive_response.status_code == 200:
|
|
|
|
|
+ shared_drive_data = shared_drive_response.json()
|
|
|
|
|
+ folder_name = shared_drive_data.get('name', 'Unknown')
|
|
|
|
|
+ folder_found = True
|
|
|
|
|
+
|
|
|
|
|
+ # For shared drives, we also need to check if we can access files within it
|
|
|
|
|
+ files_in_drive_url = f"https://www.googleapis.com/drive/v3/files?supportsAllDrives=true&includeItemsFromAllDrives=true&corpora=drive&driveId={self.google_drive_crm_folder_id}&pageSize=1"
|
|
|
|
|
+ files_response = requests.get(files_in_drive_url, headers=headers, timeout=10)
|
|
|
|
|
+
|
|
|
|
|
+ if files_response.status_code != 200:
|
|
|
|
|
+ raise UserError(_('Access denied to Shared Drive. Please check your permissions in the Shared Drive.'))
|
|
|
|
|
+ elif shared_drive_response.status_code == 403:
|
|
|
|
|
+ raise UserError(_('Access denied to Shared Drive. Please check your permissions in the Shared Drive.'))
|
|
|
|
|
+ elif shared_drive_response.status_code == 404:
|
|
|
|
|
+ raise UserError(_('Google Drive folder not found. Please verify the Folder ID is correct. This could be a regular folder or Shared Drive.'))
|
|
|
|
|
+ else:
|
|
|
|
|
+ raise UserError(_('Shared Drive API test failed. Status: %s') % shared_drive_response.status_code)
|
|
|
|
|
+ elif drive_response.status_code == 403:
|
|
|
|
|
+ raise UserError(_('Access denied to Google Drive folder. Please check folder permissions.'))
|
|
|
|
|
+ elif drive_response.status_code == 401:
|
|
|
|
|
+ raise UserError(_('OAuth token expired or invalid. Please reconnect your Google account in Google API settings.'))
|
|
|
|
|
+ else:
|
|
|
|
|
+ raise UserError(_('Google Drive API test failed. Status: %s') % drive_response.status_code)
|
|
|
|
|
+
|
|
|
|
|
+ if folder_found:
|
|
|
return {
|
|
return {
|
|
|
'type': 'ir.actions.client',
|
|
'type': 'ir.actions.client',
|
|
|
'tag': 'display_notification',
|
|
'tag': 'display_notification',
|
|
@@ -98,14 +133,6 @@ class ResCompany(models.Model):
|
|
|
'sticky': False,
|
|
'sticky': False,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- elif drive_response.status_code == 404:
|
|
|
|
|
- raise UserError(_('Google Drive folder not found. Please verify the Folder ID is correct.'))
|
|
|
|
|
- elif drive_response.status_code == 403:
|
|
|
|
|
- raise UserError(_('Access denied to Google Drive folder. Please check folder permissions.'))
|
|
|
|
|
- elif drive_response.status_code == 401:
|
|
|
|
|
- raise UserError(_('OAuth token expired or invalid. Please reconnect your Google account in Google API settings.'))
|
|
|
|
|
- else:
|
|
|
|
|
- raise UserError(_('Google Drive API test failed. Status: %s') % drive_response.status_code)
|
|
|
|
|
|
|
|
|
|
except requests.exceptions.Timeout:
|
|
except requests.exceptions.Timeout:
|
|
|
raise UserError(_('Connection timeout. Please check your internet connection.'))
|
|
raise UserError(_('Connection timeout. Please check your internet connection.'))
|
|
@@ -121,7 +148,40 @@ class ResCompany(models.Model):
|
|
|
if not self.google_drive_crm_folder_id:
|
|
if not self.google_drive_crm_folder_id:
|
|
|
raise UserError(_('No Google Drive CRM folder configured'))
|
|
raise UserError(_('No Google Drive CRM folder configured'))
|
|
|
|
|
|
|
|
- folder_url = f"https://drive.google.com/drive/folders/{self.google_drive_crm_folder_id}"
|
|
|
|
|
|
|
+ # For shared drives, the URL format is different
|
|
|
|
|
+ # Try to determine if it's a shared drive by checking the API
|
|
|
|
|
+ try:
|
|
|
|
|
+ import requests
|
|
|
|
|
+
|
|
|
|
|
+ access_token = self.env['ir.config_parameter'].sudo().get_param('google_api.access_token')
|
|
|
|
|
+ if access_token:
|
|
|
|
|
+ headers = {'Authorization': f'Bearer {access_token}'}
|
|
|
|
|
+
|
|
|
|
|
+ # First try regular folder
|
|
|
|
|
+ drive_api_url = f"https://www.googleapis.com/drive/v3/files/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+ drive_response = requests.get(drive_api_url, headers=headers, timeout=5)
|
|
|
|
|
+
|
|
|
|
|
+ if drive_response.status_code == 404:
|
|
|
|
|
+ # Try shared drive
|
|
|
|
|
+ shared_drive_api_url = f"https://www.googleapis.com/drive/v3/drives/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+ shared_drive_response = requests.get(shared_drive_api_url, headers=headers, timeout=5)
|
|
|
|
|
+
|
|
|
|
|
+ if shared_drive_response.status_code == 200:
|
|
|
|
|
+ # It's a shared drive
|
|
|
|
|
+ folder_url = f"https://drive.google.com/drive/u/0/folders/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+ else:
|
|
|
|
|
+ # Regular folder
|
|
|
|
|
+ folder_url = f"https://drive.google.com/drive/folders/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+ else:
|
|
|
|
|
+ # Regular folder
|
|
|
|
|
+ folder_url = f"https://drive.google.com/drive/folders/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+ else:
|
|
|
|
|
+ # Fallback to regular folder URL
|
|
|
|
|
+ folder_url = f"https://drive.google.com/drive/folders/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+
|
|
|
|
|
+ except Exception:
|
|
|
|
|
+ # Fallback to regular folder URL
|
|
|
|
|
+ folder_url = f"https://drive.google.com/drive/folders/{self.google_drive_crm_folder_id}"
|
|
|
|
|
|
|
|
return {
|
|
return {
|
|
|
'type': 'ir.actions.act_url',
|
|
'type': 'ir.actions.act_url',
|
|
@@ -162,6 +222,26 @@ class ResCompany(models.Model):
|
|
|
if self.google_drive_crm_folder_id:
|
|
if self.google_drive_crm_folder_id:
|
|
|
folder_metadata['parents'] = [self.google_drive_crm_folder_id]
|
|
folder_metadata['parents'] = [self.google_drive_crm_folder_id]
|
|
|
|
|
|
|
|
|
|
+ # Create folder - check if parent is a shared drive and adjust accordingly
|
|
|
|
|
+ is_shared_drive = False
|
|
|
|
|
+
|
|
|
|
|
+ # Check if the parent folder is a shared drive
|
|
|
|
|
+ if self.google_drive_crm_folder_id:
|
|
|
|
|
+ # Try to get parent folder info to determine if it's a shared drive
|
|
|
|
|
+ parent_check_url = f"https://www.googleapis.com/drive/v3/files/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+ parent_response = requests.get(parent_check_url, headers=headers, timeout=10)
|
|
|
|
|
+
|
|
|
|
|
+ if parent_response.status_code == 404:
|
|
|
|
|
+ # Parent might be a shared drive, try shared drive endpoint
|
|
|
|
|
+ shared_drive_check_url = f"https://www.googleapis.com/drive/v3/drives/{self.google_drive_crm_folder_id}"
|
|
|
|
|
+ shared_drive_response = requests.get(shared_drive_check_url, headers=headers, timeout=10)
|
|
|
|
|
+
|
|
|
|
|
+ if shared_drive_response.status_code == 200:
|
|
|
|
|
+ is_shared_drive = True
|
|
|
|
|
+ # For shared drives, we need to add specific parameters
|
|
|
|
|
+ folder_metadata['supportsAllDrives'] = True
|
|
|
|
|
+ folder_metadata['includeItemsFromAllDrives'] = True
|
|
|
|
|
+
|
|
|
# Create folder
|
|
# Create folder
|
|
|
response = requests.post(
|
|
response = requests.post(
|
|
|
'https://www.googleapis.com/drive/v3/files',
|
|
'https://www.googleapis.com/drive/v3/files',
|
|
@@ -209,11 +289,13 @@ class ResCompany(models.Model):
|
|
|
'Authorization': f'Bearer {access_token}',
|
|
'Authorization': f'Bearer {access_token}',
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- # List folders
|
|
|
|
|
|
|
+ # List folders - include both regular folders and shared drives
|
|
|
params = {
|
|
params = {
|
|
|
'q': "mimeType='application/vnd.google-apps.folder' and trashed=false",
|
|
'q': "mimeType='application/vnd.google-apps.folder' and trashed=false",
|
|
|
'fields': 'files(id,name,webViewLink)',
|
|
'fields': 'files(id,name,webViewLink)',
|
|
|
- 'pageSize': 10
|
|
|
|
|
|
|
+ 'pageSize': 10,
|
|
|
|
|
+ 'supportsAllDrives': 'true',
|
|
|
|
|
+ 'includeItemsFromAllDrives': 'true'
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
response = requests.get(
|
|
response = requests.get(
|