Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public with sharing class OpportunityService {
- public static final String STAGE_MEETING_BOOKED = 'Meeting Booked';
- public static final String STAGE_LICENCE_OUT = 'Licence Out';
- public static final String STAGE_COMPLETED = 'Completed';
- public static final String STAGE_CHECK_COMPLETE = 'Check Complete';
- public static final String STAGE_INSTRUCTED = 'Instructed';
- public static final String STAGE_EXCHANGED = 'Exchanged';
- public static final String STAGE_QUALIFIED = 'Qualified';
- public static final String STAGE_CLOSED_LOST = 'Closed Lost';
- public static final String STAGE_VIEWING = 'Viewing';
- public static final String STAGE_TERMS_OUT = 'Terms Out';
- public static final String CAR_PARKING_PRODUCT = 'Car Parking';
- public static final String RETAIL_PRODUCT = 'Retail';
- public static final String VIRTUAL_RECORD_TYPE_NAME = 'Virtual';
- public static final String CONVENTIONAL_RECORD_TYPE = 'Conventional';
- public static final String SERVICED_RECORD_TYPE = 'Serviced';
- public static final Id VIRTUAL_RECORD_TYPE_ID;
- public static final Id CONVENTIONAL_RECORD_TYPE_ID;
- public static final Id SERVICED_RECORD_TYPE_ID;
- public static final String COMPLETION_NOTIFICATION_SCHEDULED_JOB = 'COMPLETION_NOTIFICATION_SENDER';
- public static final Integer NOTIFICATION_DELAY_MIN = 2;
- static {
- VIRTUAL_RECORD_TYPE_ID = RecordTypeHelper.getOpportunityRtIdByName(VIRTUAL_RECORD_TYPE_NAME);
- CONVENTIONAL_RECORD_TYPE_ID = RecordTypeHelper.getOpportunityRtIdByName(CONVENTIONAL_RECORD_TYPE);
- SERVICED_RECORD_TYPE_ID = RecordTypeHelper.getOpportunityRtIdByName(SERVICED_RECORD_TYPE);
- }
- private static Set<String> conventionalProductsOppClosing = new Set<String>{
- ProductService.PRODUCT_CODE_LAB_SPACE,
- ProductService.PRODUCT_CODE_OFFICE_RENT,
- ProductService.PRODUCT_CODE_RETAIL_RENT,
- ProductService.PRODUCT_CODE_STORAGE,
- ProductService.PRODUCT_CODE_ALL_INCLUSIVE
- };
- private static Map<Id, RecordType> opportunityRecordTypes;
- public static Map<Id, RecordType> getRecordTypes() {
- if (opportunityRecordTypes == null) {
- opportunityRecordTypes = new Map<Id, RecordType>(
- RecordTypeHelper.getRecordTypesForSObject(SObjectConstants.OPPORTUNITY_SOBJECT)
- );
- }
- return opportunityRecordTypes;
- }
- public static List<Opportunity> completeContractOpportunity(Id recordTypeId, List<Opportunity> opportunities, Map<Id, Contract> contractsMap) {
- List<Opportunity> opportunitiesToUpdate = new List<Opportunity>();
- List<Opportunity> opportunitiesToCompletionNotification = new List<Opportunity>();
- for (Opportunity theOpportunity : opportunities) {
- if (recordTypeId == CONVENTIONAL_RECORD_TYPE_ID) {
- if (theOpportunity.Product__c != CAR_PARKING_PRODUCT) {
- opportunitiesToCompletionNotification.add(theOpportunity);
- }
- theOpportunity.Contract_Ready_For_Finance__c = true;
- } else if (recordTypeId == SERVICED_RECORD_TYPE_ID) {
- if (theOpportunity.Product__c != CAR_PARKING_PRODUCT) {
- theOpportunity.Contract_Ready_For_Finance__c = true;
- opportunitiesToCompletionNotification.add(theOpportunity);
- } else {
- theOpportunity.StageName = OpportunityService.STAGE_COMPLETED;
- }
- } else if (theOpportunity.Product__c == CAR_PARKING_PRODUCT) {
- theOpportunity.StageName = OpportunityService.STAGE_COMPLETED;
- }
- opportunitiesToUpdate.add(theOpportunity);
- }
- pushCompletionNotifications(opportunitiesToCompletionNotification);
- return opportunitiesToUpdate;
- }
- public static void createTaskForCoordinator(List<Opportunity> opportunities) {
- Map<Id, Opportunity> completedOpportunitiesMap = new Map<Id, Opportunity>();
- Map<String, Opportunity> meetingBookedOpportunitiesMap = new Map<String, Opportunity>();
- List<Task> tasksToCreate = new List<Task>();
- for (Opportunity theOpportunity : opportunities) {
- if (theOpportunity.StageName.equals(STAGE_COMPLETED) && theOpportunity.Deposit_Paid__c) {
- completedOpportunitiesMap.put(theOpportunity.Id, theOpportunity);
- }
- if (theOpportunity.StageName.equals(STAGE_MEETING_BOOKED) && theOpportunity.Last_Event_ID__c != null) {
- meetingBookedOpportunitiesMap.put(theOpportunity.Last_Event_ID__c, theOpportunity);
- }
- }
- if (!completedOpportunitiesMap.isEmpty()) {
- Set<Id> contractIds = SObjectUtils.getIdSetFromObjects(completedOpportunitiesMap.values(), 'ContractId');
- List<Contract> contracts = [
- SELECT Id, Name,
- StartDate,
- SBQQ__Opportunity__c,
- SBQQ__Quote__c,
- SBQQ__Quote__r.SBQQ__PrimaryContact__c,
- SBQQ__Quote__r.SBQQ__PrimaryContact__r.Name,
- SBQQ__Quote__r.Property__c,
- SBQQ__Quote__r.Property__r.Serviced_Space_Coordinator__c
- FROM Contract
- WHERE Id IN :contractIds
- AND SBQQ__Quote__r.Property__r.Serviced_Space_Coordinator__c != NULL
- ];
- for (Contract theContract : contracts) {
- Id opportunityId = theContract.SBQQ__Opportunity__c;
- if (completedOpportunitiesMap.containsKey(opportunityId)) {
- Opportunity theOpportunity = completedOpportunitiesMap.get(opportunityId);
- tasksToCreate.add(TaskService.generateVirtualOnboardingTask(theOpportunity, theContract));
- }
- }
- }
- if (!meetingBookedOpportunitiesMap.isEmpty()) {
- List<Event> events = [
- SELECT Id, RecordTypeId, Property__c, Property__r.Serviced_Space_Coordinator__c, WhoId, ActivityDate
- FROM Event
- WHERE Id IN:meetingBookedOpportunitiesMap.keySet()
- AND Property__r.Serviced_Space_Coordinator__c != NULL
- ];
- for (Event theEvent : events) {
- Id eventId = theEvent.Id;
- if (meetingBookedOpportunitiesMap.containsKey(eventId)) {
- Opportunity theOpportunity = meetingBookedOpportunitiesMap.get(eventId);
- tasksToCreate.add(TaskService.generateVirtualMeetingTask(theOpportunity, theEvent));
- }
- }
- }
- insert tasksToCreate;
- }
- /**
- * @description Calculates Opportunity statuses for specified Opportunities
- */
- public static void calculateOpportunitiesStatuses(List<Opportunity> theOpportunities) {
- Set<Id> automatedStatusCalculationRecordTypes = new Set<Id>{
- CONVENTIONAL_RECORD_TYPE_ID, SERVICED_RECORD_TYPE_ID, VIRTUAL_RECORD_TYPE_ID
- };
- for (Opportunity theOpportunity : theOpportunities) {
- if (automatedStatusCalculationRecordTypes.contains(theOpportunity.RecordTypeId)) {
- theOpportunity.StageName = OppStatusCalculatorFactory.getStatusCalculator(theOpportunity.RecordTypeId).calculateNewStatus(theOpportunity);
- theOpportunity.Automated_Status_Change__c = true;
- }
- }
- }
- public static Map<Id, List<Opportunity>> getOpportunitiesMapByRecordTypeId(List<Opportunity> theOpportunities) {
- Map<Id, List<Opportunity>> opportunitiesMap = new Map<Id, List<Opportunity>>();
- for (Opportunity theOpportunity : theOpportunities) {
- if (!opportunitiesMap.containsKey(theOpportunity.RecordTypeId)) {
- opportunitiesMap.put(theOpportunity.RecordTypeId, new List<Opportunity>());
- }
- opportunitiesMap.get(theOpportunity.RecordTypeId).add(theOpportunity);
- }
- return opportunitiesMap;
- }
- public static Map<String, SBQQ__Quote__c> getAcceptedQuotesByOpportunities(List<Opportunity> opportunities) {
- Map<String, SBQQ__Quote__c> opportunityAcceptedQuoteMap = new Map<String, SBQQ__Quote__c>();
- List<SBQQ__Quote__c> acceptedQuotes = [
- SELECT Id, SBQQ__Opportunity2__c, Inventory__r.Name, Inventory__c, Net_Fill_Sq_ft__c,
- Total_deal_size_Sq_ft__c, Discount_Term_Certain_Percent__c,
- Discount_Term_Certain__c, Total_Parking_Spaces__c, Term__c,
- Term_Certain__c, Rent_per_Sq_Ft_annual__c, Property_Name__c,
- toLabel(SBQQ__Type__c), Total_deal_size_Workstations__c, Net_Fill_Workstations__c,
- Deposit_Payment_Total__c, Average_Workstation_Rate__c, Rent_Per_Workstation__c, Account_Name__c,
- Net_Subtotal__c, Serviced_Retail_Cost_Per_Week__c, Contract__c
- FROM SBQQ__Quote__c
- WHERE SBQQ__Status__c = :SBQQ_QuoteConstants.STATUS_ACCEPTED
- AND SBQQ__Opportunity2__c IN :opportunities
- ];
- for (SBQQ__Quote__c theQuote : acceptedQuotes) {
- opportunityAcceptedQuoteMap.put(theQuote.SBQQ__Opportunity2__c, theQuote);
- }
- return opportunityAcceptedQuoteMap;
- }
- public static void updateOpportunityStage(List<Opportunity> opportunities, String stage) {
- for (Opportunity opp : opportunities) {
- opp.StageName = stage;
- }
- update opportunities;
- }
- public static void pushCompletionNotifications(List<Opportunity> opportunities) {
- // get all primary quotes related to Opportunity
- Map<String, SBQQ__Quote__c> opportunityToQuote = OpportunityService.getAcceptedQuotesByOpportunities(opportunities);
- // filter just Serviced, because we have to work with QLI later for serviced message
- Set<SBQQ__Quote__c> servicedQuotes = new Set<SBQQ__Quote__c>();
- for (Opportunity theOpportunity : opportunities) {
- if (theOpportunity.RecordTypeId == SERVICED_RECORD_TYPE_ID && opportunityToQuote.containsKey(theOpportunity.Id)) {
- servicedQuotes.add(opportunityToQuote.get(theOpportunity.Id));
- }
- }
- // get all QLIs for Serviced opportunities
- Map<Id, List<SBQQ__QuoteLine__c>> servicedQuoteLines = SBQQ_QuoteService.getQuoteLinesMap(new List<SBQQ__Quote__c>(servicedQuotes));
- List<String> feedItemsBodies = new List<String>();
- for (Opportunity theOpportunity : opportunities) {
- SBQQ__Quote__c quote = opportunityToQuote.get(theOpportunity.Id);
- if (quote != null) {
- String message = '';
- if (theOpportunity.RecordTypeId == SERVICED_RECORD_TYPE_ID) {
- List<SBQQ__QuoteLine__c> quoteLines = servicedQuoteLines.get(quote.Id) != null
- ? servicedQuoteLines.get(quote.Id)
- : new List<SBQQ__QuoteLine__c>();
- if (theOpportunity.Product__c == RETAIL_PRODUCT) {
- message = OpportunityService.getServicedRetailNotificationMessageText(theOpportunity, quote, quoteLines);
- } else {
- message = OpportunityService.getServicedNotificationMessageText(theOpportunity, quote, quoteLines);
- }
- } else {
- message = OpportunityService.getNotificationMessageText(theOpportunity, quote);
- }
- feedItemsBodies.add(message);
- }
- }
- ChatterService.pushFeedItems(feedItemsBodies, ChatterService.findChatterGroupByName(Constants.OPPORTUNITY_NOTIFICATION_GROUP_NAME));
- }
- private static String getNotificationMessageText(Opportunity theOpportunity, SBQQ__Quote__c quote) {
- String opportunityUrl = URL.getSalesforceBaseUrl().toExternalForm() + '/' + theOpportunity.Id;
- String quoteUrl = quote != null ? URL.getSalesforceBaseUrl().toExternalForm() + '/' + quote.Id : '';
- String contractUrl = quote.Contract__c != null ? URL.getSalesforceBaseUrl().toExternalForm() + '/' + quote.Contract__c : null;
- return '<p>' + (theOpportunity.Completion_Notification__c != null
- ? theOpportunity.Completion_Notification__c + '</p>'
- : 'I am pleased to announce the deal to ' + theOpportunity.Account.Name + ' at ' + quote.Property_Name__c + ' has now ' + theOpportunity.StageName + '.</p><p> Further details below:</p>')
- + '<p> </p>' +
- +'<p> <b>Opportunity Owner:</b> ' + theOpportunity.Owner.Name + '</p>' +
- +'<p> <b>Customer:</b> ' + StringUtils.convertNullToEmptySpace(quote.Account_Name__c) + '</p>' +
- +'<p> <b>Property:</b> ' + StringUtils.convertNullToEmptySpace(quote.Property_Name__c) + '</p>' +
- +'<p> <b>Inventory:</b> ' + StringUtils.convertNullToEmptySpace(quote.Inventory__r.Name) + '</p>' +
- +'<p> <b>Lead Source:</b> ' + StringUtils.convertNullToEmptySpace(theOpportunity.LeadSource) + '</p>' +
- +'<p> <b>Net Fill:</b> ' + NumberUtils.convertDecimalToNumberWithPrecision(quote.Net_Fill_Sq_ft__c, 0) + ' sq ft</p>' +
- +'<p> <b>Total Deal Size:</b> ' + NumberUtils.convertDecimalToNumberWithPrecision(quote.Total_deal_size_Sq_ft__c, 0) + ' sq ft</p>' +
- +'<p> <b>Deal Type:</b> ' + StringUtils.convertNullToEmptySpace(theOpportunity.Type) + '</p>' +
- +'<p> <b>Term (Months):</b> ' + NumberUtils.convertDecimalToNumber(quote.Term__c) + '</p>'
- + '<p> <b>Term Certain (Months):</b> ' + NumberUtils.convertDecimalToNumber(quote.Term_Certain__c) + '</p>' +
- +'<p> <b>Rent per sq ft:</b> ' + NumberUtils.convertCurrencyIntoString(quote.Rent_per_Sq_Ft_annual__c) + '</p>' +
- +'<p> <b>Discount Term Certain:</b> ' + NumberUtils.convertDecimalToNumber(quote.Discount_Term_Certain_Percent__c.setScale(2)) + '%</p>' +
- +'<p> <b>Total parking spaces:</b> ' + NumberUtils.convertDecimalToNumberWithPrecision(quote.Total_Parking_Spaces__c, 0) + '</p>' +
- +'<p> </p>' +
- +'<p> <b>Opportunity:</b> ' + opportunityUrl + '</p>' +
- +'<p> <b>Quote:</b> ' + quoteUrl + '</p>' +
- +(contractUrl != null ? '<p><b>Contract:</b> ' + contractUrl + '</p>' : '');
- }
- private static String getServicedNotificationMessageText(Opportunity theOpportunity, SBQQ__Quote__c quote, List<SBQQ__QuoteLine__c> quoteLines) {
- String contractUrl = theOpportunity.ContractId != null ? URL.getSalesforceBaseUrl().toExternalForm() + '/' + theOpportunity.ContractId : null;
- List<String> msg = new List<String>();
- msg.add('<p>' + (theOpportunity.Completion_Notification__c != null
- ? theOpportunity.Completion_Notification__c
- : 'I am pleased to announce the deal to ' + theOpportunity.Account.Name + ' at ' + quote.Property_Name__c + ' has now ' + theOpportunity.StageName + '.</p><p> Further details below:') + '</p>');
- msg.add('<p> </p>');
- msg.add('<p> <b>Opportunity Owner:</b> ' + theOpportunity.Owner.Name + '</p>');
- msg.add('<p><b>Customer:</b> ' + StringUtils.convertNullToEmptySpace(quote.Account_Name__c) + '</p>');
- msg.add('<p><b>Property:</b> ' + StringUtils.convertNullToEmptySpace(quote.Property_Name__c) + '</p>');
- msg.add('<p><b>Inventory:</b> ' + StringUtils.convertNullToEmptySpace(quote.Inventory__r.Name) + '</p>');
- msg.add('<p><b>Deal Type:</b> ' + StringUtils.convertNullToEmptySpace(quote.SBQQ__Type__c) + '</p>');
- msg.add('<p><b>Number of workstations:</b> ' + NumberUtils.convertDecimalToNumberWithPrecision(quote.Total_deal_size_Workstations__c, 0) + '</p>');
- msg.add('<p><b>Net Fill Workstations:</b> ' + NumberUtils.convertDecimalToNumberWithPrecision(quote.Net_Fill_Workstations__c, 0) + '</p>');
- SBQQ__QuoteLine__c headLine;
- SBQQ__QuoteLine__c depositLine;
- SBQQ__QuoteLine__c internetLine;
- SBQQ__QuoteLine__c handSetLine;
- for (SBQQ__QuoteLine__c qLine : quoteLines) {
- if (ProductService.isServicedOrDeskHeadline(qLine.SBQQ__ProductCode__c)) {
- headLine = qLine;
- }
- if (qLine.SBQQ__ProductCode__c == ProductService.PRODUCT_CODE_DEPOSIT) {
- depositLine = qLine;
- }
- if (qLine.SBQQ__ProductCode__c == ProductService.PRODUCT_CODE_INCLUSIVE_INTERNET
- || qLine.SBQQ__ProductCode__c.startsWith('BSDM')) {
- internetLine = qLine;
- }
- if (qLine.SBQQ__ProductCode__c == ProductService.PRODUCT_CODE_HANDSETS
- || qLine.SBQQ__ProductCode__c == ProductService.PRODUCT_CODE_HANDSETS_INCLUSIVE) {
- handSetLine = qLine;
- }
- }
- msg.add('<p><b>Headline Monthly Rent:</b> ' + NumberUtils.convertCurrencyIntoString(quote.Rent_Per_Workstation__c) + '</p>');
- msg.add('<p><b>Average Workstation Rate (PCM):</b> ' + NumberUtils.convertCurrencyIntoString(quote.Average_Workstation_Rate__c) + '</p>');
- msg.add(
- '<p><b>Start Date:</b> ' +
- (headLine != null && headLine.Start_Date__c != null ? headLine.Start_Date__c.format() : '') +
- '</p>'
- );
- msg.add('<p><b>Term (Months):</b> ' + NumberUtils.convertDecimalToNumber(headLine.Term__c) + '</p>');
- msg.add('<p><b>Deposit:</b> ' + NumberUtils.convertCurrencyIntoString(depositLine.Net_Subtotal__c) + '</p>');
- msg.add('<p><b>Deposit Already Held:</b> ' + NumberUtils.convertCurrencyIntoString(depositLine.Deposit_Already_Held__c) + '</p>');
- msg.add(
- '<p><b>Internet Product Name:</b> '
- + (internetLine != null && internetLine.SBQQ__Product__c != null ? internetLine.SBQQ__Product__r.Name : '')
- + '</p>'
- );
- msg.add(
- '<p><b>Number of Telephone Handsets:</b> '
- + (handSetLine != null && handSetLine.SBQQ__Quantity__c != null ? handSetLine.SBQQ__Quantity__c.format() : '0')
- + '</p>'
- );
- msg.add('<p><b>Number of Parking within Licence Agreement:</b> '
- + NumberUtils.convertDecimalToNumberWithPrecision(quote.Total_Parking_Spaces__c, 0) + '</p>');
- msg.add('<p><b>Total Deal Value:</b> ' + NumberUtils.convertCurrencyIntoString(headLine.Net_Total__c) + '</p>');
- msg.add('<p> </p>');
- msg.add('<p><b>Opportunity:</b> ' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + theOpportunity.Id + '</p>');
- msg.add('<p><b>Quote:</b> ' + URL.getSalesforceBaseUrl().toExternalForm() + '/' + quote.Id + '</p>');
- msg.add(contractUrl != null ? '<p><b>Contract:</b> ' + contractUrl + '</p>' : '');
- return String.join(msg, '');
- }
- private static String getServicedRetailNotificationMessageText(Opportunity theOpportunity, SBQQ__Quote__c quote, List<SBQQ__QuoteLine__c> quoteLines) {
- List<String> msg = new List<String>();
- SBQQ__QuoteLine__c headLine;
- SBQQ__QuoteLine__c depositLine;
- for (SBQQ__QuoteLine__c qLine : quoteLines) {
- if (ProductService.isServicedOrDeskHeadline(qLine.SBQQ__ProductCode__c)) {
- headLine = qLine;
- }
- if (qLine.SBQQ__ProductCode__c == ProductService.PRODUCT_CODE_DEPOSIT) {
- depositLine = qLine;
- }
- }
- msg.add('<p>' + theOpportunity.Completion_Notification__c + '</p>');
- msg.add('<p> </p>');
- msg.add('<p> <b>Opportunity Owner: </b>' + theOpportunity.Owner.Name + '</p>');
- msg.add('<p> <b>Customer: </b>' + StringUtils.convertNullToEmptySpace(quote.Account_Name__c) + '</p>');
- msg.add('<p> <b>Property: </b>' + StringUtils.convertNullToEmptySpace(quote.Property_Name__c) + '</p>');
- msg.add('<p> <b>Inventory: </b> ' + StringUtils.convertNullToEmptySpace(quote.Inventory__r.Name) + '</p>');
- msg.add('<p> <b>Lead Source: </b>' + StringUtils.convertNullToEmptySpace(theOpportunity.LeadSource) + '</p>');
- msg.add('<p> <b>Net Fill: </b>' + NumberUtils.convertDecimalToNumberWithPrecision(quote.Net_Fill_Sq_ft__c, 0) + ' sq ft</p>');
- msg.add('<p> <b>Total Deal Size: </b>' + NumberUtils.convertDecimalToNumberWithPrecision(quote.Total_deal_size_Sq_ft__c, 0) + ' sq ft</p>');
- msg.add('<p> <b>Deal Type: </b>' + StringUtils.convertNullToEmptySpace(theOpportunity.Type) + '</p>');
- msg.add('<p> <b>Headline Weekly Rent: </b>' + NumberUtils.convertCurrencyIntoString(quote.Serviced_Retail_Cost_Per_Week__c) + '</p>');
- msg.add('<p> <b>Start Date: </b>' + headLine.Start_Date__c.format() + '</p>');
- msg.add('<p> <b>Term (Months): </b>' + NumberUtils.convertDecimalToNumber(quote.Term__c) + '</p>');
- msg.add('<p> <b>Deposit: </b>' + NumberUtils.convertCurrencyIntoString(depositLine.Net_Subtotal__c) + '</p>');
- msg.add('<p> <b>Deposit Already Held: </b>' + NumberUtils.convertCurrencyIntoString(depositLine.Deposit_Already_Held__c) + '</p>');
- msg.add('<p> <b>Total Deal Value: </b>' + NumberUtils.convertCurrencyIntoString(headLine.Net_Total__c) + '</p>');
- return String.join(msg, '');
- }
- public static Opportunity getOpportunityWithAllFieldsExceptNotValidById(String opportunityId, List<String> fieldsNotNeedToSelect) {
- List<String> opportunityFieldsForSelect = new List<String>();
- Map<String, SObjectField> opportunityFieldsMap = Opportunity.SObjectType.getDescribe().fields.getMap();
- for (SObjectField field : opportunityFieldsMap.values()) {
- DescribeFieldResult describeFieldResult = field.getDescribe();
- if (describeFieldResult.accessible &&
- !fieldsNotNeedToSelect.contains(describeFieldResult.name)) {
- opportunityFieldsForSelect.add(describeFieldResult.name);
- }
- }
- Opportunity clonedOpportunity = getOpportunityWithSelectedFieldsById(opportunityId, opportunityFieldsForSelect).clone(false, false);
- return clonedOpportunity;
- }
- private static Opportunity getOpportunityWithSelectedFieldsById(String opportunityId, List<String> selectedFields) {
- String soqlGetAllFieldsFromOpportunity = ''
- + ' SELECT ' + String.join(selectedFields, ', ')
- + ' FROM Opportunity'
- + ' WHERE Id = \'' + opportunityId + '\'';
- List<Opportunity> opportunities = Database.query(soqlGetAllFieldsFromOpportunity);
- if (opportunities.size() != 0) {
- return opportunities.get(0);
- }
- return null;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement