PA2 / app.py
prudhviLatha's picture
Update app.py
e7cfd45 verified
import os
import sys
import logging
from datetime import datetime
from simple_salesforce import Salesforce, SalesforceError
from dotenv import load_dotenv
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[logging.StreamHandler()]
)
logger = logging.getLogger(__name__)
# Load environment variables from .env file
logger.info("Loading environment variables")
load_dotenv()
# Salesforce credentials from environment variables
SF_USERNAME = os.getenv('SF_USERNAME')
SF_PASSWORD = os.getenv('SF_PASSWORD')
SF_SECURITY_TOKEN = os.getenv('SF_SECURITY_TOKEN')
SF_INSTANCE_URL = os.getenv('SF_INSTANCE_URL', 'https://orgfarm-59728c4604-dev-ed.develop.my.salesforce.com')
def validate_credentials():
"""
Validate that all required Salesforce credentials are present.
Returns True if valid, False otherwise.
"""
logger.info("Validating Salesforce credentials")
if not all([SF_USERNAME, SF_PASSWORD, SF_SECURITY_TOKEN, SF_INSTANCE_URL]):
missing = [k for k, v in {
'SF_USERNAME': SF_USERNAME,
'SF_PASSWORD': SF_PASSWORD,
'SF_SECURITY_TOKEN': SF_SECURITY_TOKEN,
'SF_INSTANCE_URL': SF_INSTANCE_URL
}.items() if not v]
logger.error(f"Missing required environment variables: {missing}")
return False
logger.info("Credentials validated successfully")
return True
def get_valid_status_values(sf):
"""
Retrieve valid picklist values for Status__c field on Contract_Document__c.
Returns a list of active picklist values.
"""
logger.info("Retrieving Status__c picklist values")
try:
describe = sf.Contract_Document__c.describe()
status_field = next(field for field in describe['fields'] if field['name'] == 'Status__c')
valid_values = [value['value'] for value in status_field['picklistValues'] if value['active']]
logger.info(f"Valid Status__c values: {valid_values}")
return valid_values
except Exception as e:
logger.error(f"Error retrieving Status__c picklist values: {e}")
return ['Draft'] # Fallback to a safe default
def get_required_fields(sf):
"""
Retrieve required fields for Contract_Document__c.
Returns a list of required field names.
"""
logger.info("Retrieving required fields for Contract_Document__c")
try:
describe = sf.Contract_Document__c.describe()
required_fields = [f['name'] for f in describe['fields'] if not f['nillable'] and not f['defaultedOnCreate']]
logger.info(f"Required fields: {required_fields}")
return required_fields
except Exception as e:
logger.error(f"Error retrieving required fields: {e}")
return ['Name', 'Status__c', 'Document_URL__c', 'Upload_Date__c']
def create_contract_document(sf, name, status='Draft', document_url='https://example.com/contract.pdf'):
"""
Create a Contract_Document__c record if it doesn't exist.
Checks for existing records by Name to prevent duplicates.
"""
logger.info("Checking for existing Contract_Document__c record")
try:
query = f"SELECT Id, Name, Status__c, Document_URL__c, Upload_Date__c FROM Contract_Document__c WHERE Name = '{name}' LIMIT 1"
result = sf.query(query)
if result['totalSize'] > 0:
logger.info(f"Record with Name '{name}' already exists: {result['records'][0]['Id']}")
return result['records'][0]
except SalesforceError as e:
logger.error(f"Error checking for existing record: {e}")
return None
logger.info("Creating new Contract_Document__c record")
valid_statuses = get_valid_status_values(sf)
if status not in valid_statuses:
logger.warning(f"Invalid Status__c value: {status}. Using default: {valid_statuses[0]}")
status = valid_statuses[0]
# Set Upload_Date__c to current date in YYYY-MM-DD format
upload_date = datetime.now().strftime('%Y-%m-%d')
payload = {
'Name': name,
'Status__c': status,
'Document_URL__c': document_url,
'Upload_Date__c': upload_date
}
# Check for additional required fields
required_fields = get_required_fields(sf)
missing_fields = [f for f in required_fields if f not in payload]
if missing_fields:
logger.error(f"Missing required fields in payload: {missing_fields}")
return None
try:
logger.info(f"Sending payload: {payload}")
result = sf.Contract_Document__c.create(payload)
logger.info(f"Successfully created Contract_Document__c record with ID: {result['id']}")
return result
except SalesforceError as e:
if 'REQUIRED_FIELD_MISSING' in str(e):
logger.error(f"Required field error: {e}. Missing fields: {e.content[0]['fields']}")
elif 'INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST' in str(e):
logger.error(f"Picklist error: {e}. Valid Status__c values: {valid_statuses}")
elif 'INVALID_FIELD' in str(e):
logger.error(f"Invalid field error: {e}")
else:
logger.error(f"Error creating Contract_Document__c record: {e}")
return None
def main():
"""
Main function to initialize Salesforce connection and create a sample record.
"""
logger.info("Starting main function")
# Validate credentials before attempting connection
if not validate_credentials():
logger.error("Cannot proceed without valid Salesforce credentials")
sys.exit(1)
try:
logger.info("Initializing Salesforce connection")
sf = Salesforce(
username=SF_USERNAME,
password=SF_PASSWORD,
security_token=SF_SECURITY_TOKEN,
instance_url=SF_INSTANCE_URL,
version='58.0'
)
logger.info("Successfully connected to Salesforce")
# Create a sample Contract_Document__c record
logger.info("Attempting to create Contract_Document__c record")
result = create_contract_document(
sf,
name="Sample Contract Document",
status="Draft",
document_url="https://example.com/contract.pdf"
)
if not result:
logger.error("Failed to create Contract_Document__c record")
sys.exit(1)
logger.info("Application completed successfully")
sys.exit(0)
except SalesforceError as e:
logger.error(f"Error initializing Salesforce connection: {e}")
sys.exit(1)
except Exception as e:
logger.error(f"Unexpected error: {e}")
sys.exit(1)
if __name__ == "__main__":
logger.info("Application entry point")
main()