This commit extends the SuperOffice connector to support the creation and linking of Sale \(Opportunity\) and Project \(Campaign\) entities, providing a comprehensive foundation for both sales and marketing automation workflows.
Key achievements:
- **`SUPEROFFICE_INTEGRATION_PLAN.md`**: Updated to include strategic mapping of D365 concepts \(Opportunity, Campaign\) to SuperOffice entities \(Sale, Project\).
- **`connector-superoffice/superoffice_client.py`**:
- Implemented `create_sale` method to generate new opportunities, correctly mapping `Title` to SuperOffices
70 lines
3.2 KiB
Python
70 lines
3.2 KiB
Python
import os
|
|
import logging
|
|
import json
|
|
from dotenv import load_dotenv
|
|
from auth_handler import AuthHandler
|
|
from superoffice_client import SuperOfficeClient
|
|
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
def discover_fields():
|
|
load_dotenv(dotenv_path="../.env")
|
|
auth = AuthHandler()
|
|
client = SuperOfficeClient(auth)
|
|
|
|
try:
|
|
logger.info("Fetching general Contact metadata...")
|
|
general_metadata_url = client._get_url("v1/Metadata/Contact")
|
|
resp = client.session.get(general_metadata_url, headers=client._get_headers())
|
|
resp.raise_for_status()
|
|
general_metadata = resp.json()
|
|
print("\n--- GENERAL CONTACT METADATA (partial) ---")
|
|
print(f"DisplayName: {general_metadata.get('DisplayName')}")
|
|
print(f"HasUserDefinedFields: {general_metadata.get('HasUserDefinedFields')}")
|
|
print("----------------------------------------")
|
|
|
|
logger.info("Attempting to fetch UDF metadata...")
|
|
# Get metadata for Contact (Company)
|
|
url = client._get_url("v1/Metadata/Contact/UserDefinedFields")
|
|
resp = client.session.get(url, headers=client._get_headers())
|
|
resp.raise_for_status()
|
|
fields = resp.json()
|
|
|
|
print("\n--- AVAILABLE UDF FIELDS ---")
|
|
for field in fields.get("value", []):
|
|
label = field.get('FieldLabel')
|
|
prog_id = field.get('ProgId')
|
|
field_type = field.get('FieldType')
|
|
print(f"Label: {label} -> Technical Name: {prog_id} (Type: {field_type})")
|
|
|
|
# Check if the field is a list type
|
|
if field_type in ["List", "DropDown", "UserDefinedList"]: # Common types, might need adjustment
|
|
logger.info(f" -> Fetching list items for {label} (ProgId: {prog_id})...")
|
|
# Attempt to get the list items. The actual endpoint might vary.
|
|
# Assuming a pattern like 'v1/List/UserDefinedField/{ProgId}' or 'v1/UserDefinedFieldList/{ProgId}/Items'
|
|
list_url = client._get_url(f"v1/List/UserDefinedField/{prog_id}")
|
|
try:
|
|
list_resp = client.session.get(list_url, headers=client._get_headers())
|
|
list_resp.raise_for_status()
|
|
list_items = list_resp.json()
|
|
|
|
if list_items.get("value"):
|
|
print(" --- List Items ---")
|
|
for item in list_items["value"]:
|
|
print(f" ID: {item.get('Id')}, Name: {item.get('Name')}")
|
|
else:
|
|
print(" (No list items found or unexpected response structure)")
|
|
|
|
except Exception as list_e:
|
|
logger.warning(f" Failed to fetch list items for {label}: {list_e}")
|
|
if hasattr(list_e, 'response') and list_e.response is not None:
|
|
logger.warning(f" List fetch details: {list_e.response.text}")
|
|
|
|
except Exception as e:
|
|
logger.error(f"Failed to fetch metadata: {e}")
|
|
if hasattr(e, 'response') and e.response is not None:
|
|
print(f"Details: {e.response.text}")
|
|
|
|
if __name__ == "__main__":
|
|
discover_fields() |