253 lines
15 KiB
OpenEdge ABL
253 lines
15 KiB
OpenEdge ABL
public with sharing class PropertyTemplateController {
|
|
|
|
@AuraEnabled(cacheable=true)
|
|
public static List<Property_Template__c> getPropertyTemplates() {
|
|
try {
|
|
return [SELECT Id, Name, Description__c, Preview_Image_URL__c, Tags__c,
|
|
Is_Active__c, Template_Definition__c
|
|
FROM Property_Template__c
|
|
WHERE Is_Active__c = true
|
|
ORDER BY Name];
|
|
} catch (Exception e) {
|
|
throw new AuraHandledException('Error fetching templates: ' + e.getMessage());
|
|
}
|
|
}
|
|
|
|
@AuraEnabled(cacheable=true)
|
|
public static Property_Template__c getPropertyTemplateById(String templateId) {
|
|
try {
|
|
return [SELECT Id, Name, Description__c, Preview_Image_URL__c, Tags__c,
|
|
Is_Active__c, Template_Definition__c
|
|
FROM Property_Template__c
|
|
WHERE Id = :templateId AND Is_Active__c = true
|
|
LIMIT 1];
|
|
} catch (Exception e) {
|
|
throw new AuraHandledException('Error fetching template: ' + e.getMessage());
|
|
}
|
|
}
|
|
|
|
@AuraEnabled(cacheable=true)
|
|
public static List<pcrm__Property__c> getPropertyData() {
|
|
try {
|
|
return [SELECT Id, Name, pcrm__Property_Type__c, pcrm__Sub_Locality_Bayut_Dubizzle__c,
|
|
pcrm__Sale_Price_max__c, pcrm__Rent_Price_max__c, pcrm__Bedrooms__c,
|
|
pcrm__Bathrooms__c, pcrm__Size__c, pcrm__Description_English__c,
|
|
pcrm__Title_English__c, pcrm__Unit_Number__c, pcrm__Completion_Status__c,
|
|
pcrm__Furnished__c, pcrm__Tower_Bayut_Dubizzle__c,
|
|
pcrm__Community_Propertyfinder__c, pcrm__Sub_Community_Propertyfinder__c,
|
|
pcrm__City_Propertyfinder__c, pcrm__City_Bayut_Dubizzle__c
|
|
FROM pcrm__Property__c
|
|
ORDER BY Name];
|
|
} catch (Exception e) {
|
|
throw new AuraHandledException('Error fetching properties: ' + e.getMessage());
|
|
}
|
|
}
|
|
|
|
@AuraEnabled(cacheable=true)
|
|
public static pcrm__Property__c getPropertyById(String propertyId) {
|
|
try {
|
|
return [SELECT Id, Name, pcrm__Property_Type__c, pcrm__Sub_Locality_Bayut_Dubizzle__c,
|
|
pcrm__Sale_Price_max__c, pcrm__Rent_Price_max__c, pcrm__Bedrooms__c,
|
|
pcrm__Bathrooms__c, pcrm__Size__c, pcrm__Description_English__c,
|
|
pcrm__Title_English__c, pcrm__Unit_Number__c, pcrm__Completion_Status__c,
|
|
pcrm__Furnished__c, pcrm__Tower_Bayut_Dubizzle__c,
|
|
pcrm__Community_Propertyfinder__c, pcrm__Sub_Community_Propertyfinder__c,
|
|
pcrm__City_Propertyfinder__c, pcrm__City_Bayut_Dubizzle__c
|
|
FROM pcrm__Property__c
|
|
WHERE Id = :propertyId
|
|
LIMIT 1];
|
|
} catch (Exception e) {
|
|
throw new AuraHandledException('Error fetching property: ' + e.getMessage());
|
|
}
|
|
}
|
|
|
|
@AuraEnabled(cacheable=true)
|
|
public static Map<String, Object> getMarketData() {
|
|
try {
|
|
// For now, return default market data since you might not have Market_Analytics__c
|
|
Map<String, Object> result = new Map<String, Object>();
|
|
|
|
// Default Dubai market data
|
|
result.put('marketTrend', 'Rising');
|
|
result.put('roiPotential', '8.5');
|
|
result.put('avgPricePerSqft', '1200');
|
|
result.put('marketDemand', 'High');
|
|
result.put('investmentType', 'Buy-to-Rent');
|
|
result.put('rentalYield', '6.2');
|
|
result.put('investmentHighlights', 'Prime location with high rental demand and capital appreciation potential');
|
|
result.put('locationAdvantages', 'Excellent connectivity, premium amenities, and strong infrastructure');
|
|
List<String> contentModules = new List<String>{'Market Analysis', 'Investment Overview', 'Location Highlights'};
|
|
result.put('contentModules', contentModules);
|
|
result.put('additionalContent', 'Dubai real estate market shows strong growth potential with government initiatives and Expo 2020 legacy');
|
|
|
|
return result;
|
|
} catch (Exception e) {
|
|
throw new AuraHandledException('Error fetching market data: ' + e.getMessage());
|
|
}
|
|
}
|
|
|
|
// Helper method to create template HTML content
|
|
private static String createTemplateHTML(Map<String, Object> propertyMap, String templateName) {
|
|
try {
|
|
String propertyName = (String) propertyMap.get('propertyName') != null ? (String) propertyMap.get('propertyName') : 'Property Name';
|
|
String propertyType = (String) propertyMap.get('propertyType') != null ? (String) propertyMap.get('propertyType') : 'Property Type';
|
|
String location = (String) propertyMap.get('location') != null ? (String) propertyMap.get('location') : 'Location';
|
|
String price = (String) propertyMap.get('price') != null ? (String) propertyMap.get('price') : 'Price';
|
|
String bedrooms = (String) propertyMap.get('bedrooms') != null ? (String) propertyMap.get('bedrooms') : 'N/A';
|
|
String bathrooms = (String) propertyMap.get('bathrooms') != null ? (String) propertyMap.get('bathrooms') : 'N/A';
|
|
String area = (String) propertyMap.get('area') != null ? (String) propertyMap.get('area') : 'N/A';
|
|
String description = (String) propertyMap.get('description') != null ? (String) propertyMap.get('description') : 'Property Description';
|
|
|
|
// Create a professional property brochure HTML
|
|
String htmlContent = '<!DOCTYPE html><html><head><meta charset="UTF-8">';
|
|
htmlContent += '<title>' + propertyName + ' - Property Brochure</title>';
|
|
htmlContent += '<style>';
|
|
htmlContent += 'body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background: #f5f5f5; }';
|
|
htmlContent += '.brochure { max-width: 800px; margin: 0 auto; background: white; border-radius: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); overflow: hidden; }';
|
|
htmlContent += '.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px; text-align: center; }';
|
|
htmlContent += '.header h1 { margin: 0; font-size: 2.5em; font-weight: 300; }';
|
|
htmlContent += '.header .subtitle { margin: 10px 0 0 0; font-size: 1.2em; opacity: 0.9; }';
|
|
htmlContent += '.content { padding: 40px; }';
|
|
htmlContent += '.property-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; margin: 30px 0; }';
|
|
htmlContent += '.stat-box { background: #f8f9fa; padding: 20px; border-radius: 8px; text-align: center; border: 1px solid #dee2e6; }';
|
|
htmlContent += '.stat-label { font-weight: bold; color: #667eea; font-size: 14px; text-transform: uppercase; margin-bottom: 8px; }';
|
|
htmlContent += '.stat-value { font-size: 18px; color: #333; font-weight: 600; }';
|
|
htmlContent += '.description { background: #f8f9fa; padding: 25px; border-radius: 10px; margin: 25px 0; }';
|
|
htmlContent += '.description h2 { color: #667eea; margin-bottom: 15px; font-size: 20px; border-bottom: 2px solid #667eea; padding-bottom: 8px; }';
|
|
htmlContent += '.footer { text-align: center; color: #666; font-size: 12px; border-top: 1px solid #dee2e6; padding-top: 20px; margin-top: 30px; }';
|
|
htmlContent += '</style></head><body>';
|
|
htmlContent += '<div class="brochure">';
|
|
htmlContent += '<div class="header">';
|
|
htmlContent += '<h1>' + propertyName + '</h1>';
|
|
htmlContent += '<div class="subtitle">' + propertyType + ' • ' + location + '</div>';
|
|
htmlContent += '</div>';
|
|
htmlContent += '<div class="content">';
|
|
htmlContent += '<div class="property-stats">';
|
|
htmlContent += '<div class="stat-box"><div class="stat-label">Price</div><div class="stat-value">' + price + '</div></div>';
|
|
htmlContent += '<div class="stat-box"><div class="stat-label">Bedrooms</div><div class="stat-value">' + bedrooms + '</div></div>';
|
|
htmlContent += '<div class="stat-box"><div class="stat-label">Bathrooms</div><div class="stat-value">' + bathrooms + '</div></div>';
|
|
htmlContent += '<div class="stat-box"><div class="stat-label">Area</div><div class="stat-value">' + area + '</div></div>';
|
|
htmlContent += '</div>';
|
|
htmlContent += '<div class="description">';
|
|
htmlContent += '<h2>Property Description</h2>';
|
|
htmlContent += '<p>' + description + '</p>';
|
|
htmlContent += '</div>';
|
|
htmlContent += '</div>';
|
|
htmlContent += '<div class="footer">';
|
|
htmlContent += '<p><strong>Generated on:</strong> ' + Datetime.now().format('MMMM dd, yyyy \'at\' h:mm a') + '</p>';
|
|
htmlContent += '<p><em>Property CRM System - Professional Brochure</em></p>';
|
|
htmlContent += '</div>';
|
|
htmlContent += '</div></body></html>';
|
|
|
|
return htmlContent;
|
|
} catch (Exception e) {
|
|
System.debug('Error creating template HTML: ' + e.getMessage());
|
|
return '<html><body><h1>Error generating template</h1><p>' + e.getMessage() + '</p></body></html>';
|
|
}
|
|
}
|
|
|
|
@AuraEnabled
|
|
public static Map<String, Object> generatePropertyPDF(String propertyData, String templateName, Boolean generatePDF, String htmlContent) {
|
|
try {
|
|
// Parse property data
|
|
Map<String, Object> propertyMap = (Map<String, Object>) JSON.deserializeUntyped(propertyData);
|
|
|
|
// Call external Python API for PDF generation
|
|
String apiEndpoint = 'https://salesforce.tech4biz.io/generate-pdf'; // Production PDF Generator API
|
|
|
|
// Prepare request body - using the format that was working in first prompt
|
|
Map<String, Object> requestBody = new Map<String, Object>();
|
|
|
|
// Debug: Log the property data and template name
|
|
System.debug('=== DEBUG INFO ===');
|
|
System.debug('propertyMap: ' + propertyMap);
|
|
System.debug('templateName: ' + templateName);
|
|
System.debug('propertyMap keys: ' + propertyMap.keySet());
|
|
System.debug('HTML Content Length: ' + (htmlContent != null ? htmlContent.length() : 0));
|
|
|
|
// Use the provided HTML content directly instead of generating it
|
|
String finalHTMLContent = htmlContent;
|
|
|
|
// If no HTML content provided, fall back to generating it (for backward compatibility)
|
|
if (String.isBlank(finalHTMLContent)) {
|
|
System.debug('No HTML content provided, generating fallback HTML...');
|
|
finalHTMLContent = createTemplateHTML(propertyMap, templateName);
|
|
}
|
|
|
|
// Validate that HTML content exists
|
|
if (String.isBlank(finalHTMLContent)) {
|
|
Map<String, Object> result = new Map<String, Object>();
|
|
result.put('success', false);
|
|
result.put('message', 'Error: HTML content is empty - cannot generate PDF');
|
|
System.debug('ERROR: Final HTML content is empty!');
|
|
return result;
|
|
}
|
|
|
|
System.debug('Final HTML content length: ' + finalHTMLContent.length());
|
|
System.debug('Final HTML content preview: ' + finalHTMLContent.substring(0, Math.min(200, finalHTMLContent.length())));
|
|
|
|
requestBody.put('html_content', finalHTMLContent);
|
|
requestBody.put('property_data', propertyMap);
|
|
requestBody.put('template_name', templateName);
|
|
requestBody.put('filename', 'property_brochure.pdf');
|
|
|
|
// Make HTTP callout to Python API
|
|
Http http = new Http();
|
|
HttpRequest request = new HttpRequest();
|
|
request.setEndpoint(apiEndpoint);
|
|
request.setMethod('POST');
|
|
request.setHeader('Content-Type', 'application/json');
|
|
request.setHeader('Accept', 'application/json');
|
|
request.setBody(JSON.serialize(requestBody));
|
|
request.setTimeout(120000); // 2 minutes timeout
|
|
|
|
System.debug('Calling Python API at: ' + apiEndpoint);
|
|
System.debug('Request body: ' + JSON.serialize(requestBody));
|
|
|
|
HttpResponse response = http.send(request);
|
|
|
|
System.debug('Response status: ' + response.getStatusCode());
|
|
System.debug('Response body: ' + response.getBody());
|
|
|
|
if (response.getStatusCode() == 200) {
|
|
Map<String, Object> responseMap = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
|
|
|
|
Map<String, Object> result = new Map<String, Object>();
|
|
result.put('success', true);
|
|
result.put('pdfUrl', responseMap.get('pdf_url'));
|
|
result.put('message', 'PDF generated successfully');
|
|
|
|
System.debug('PDF generation successful: ' + result);
|
|
return result;
|
|
} else {
|
|
Map<String, Object> result = new Map<String, Object>();
|
|
result.put('success', false);
|
|
result.put('message', 'Failed to generate PDF: ' + response.getStatus() + ' - ' + response.getBody());
|
|
|
|
System.debug('PDF generation failed: ' + result);
|
|
return result;
|
|
}
|
|
|
|
} catch (Exception e) {
|
|
Map<String, Object> result = new Map<String, Object>();
|
|
result.put('success', false);
|
|
result.put('message', 'Error: ' + e.getMessage());
|
|
return result;
|
|
}
|
|
}
|
|
|
|
@AuraEnabled
|
|
public static List<Property_Template__c> searchPropertyTemplates(String searchTerm) {
|
|
try {
|
|
String searchQuery = '%' + searchTerm + '%';
|
|
return [SELECT Id, Name, Description__c, Preview_Image_URL__c, Tags__c,
|
|
Is_Active__c, Template_Definition__c
|
|
FROM Property_Template__c
|
|
WHERE Is_Active__c = true
|
|
AND (Name LIKE :searchQuery OR Tags__c LIKE :searchQuery)
|
|
ORDER BY Name];
|
|
} catch (Exception e) {
|
|
throw new AuraHandledException('Error searching templates: ' + e.getMessage());
|
|
}
|
|
}
|
|
} |