function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Vishal SawVishal Saw 

there 2 account and each have 5 opportunity, so after your batch is executed then it should delete the 8 opportunity and account should have only one latest opportunity

Batch Apex I am unable to do it
Best Answer chosen by Vishal Saw
Mukesh pal 7Mukesh pal 7

The start method queries for all accounts that have multiple opportunities, and the execute method deletes all but the latest opportunity for each account. The query used in the start method retrieves the Account records along with their Opportunities subquery, sorted by CloseDate in ascending order. We then use the opportunities.sort method to sort the opportunities list in ascending order by CloseDate, and use the opportunitiesToDelete.addAll method to add all but the latest opportunity to a list of opportunities to delete. Finally, we use the delete statement to delete all opportunities in the opportunitiesToDelete list.
Try the code :


global class DeleteDuplicateOpportunities implements Database.Batchable<SObject> {
    
    global Database.QueryLocator start(Database.BatchableContext context) {
        // Query for all accounts that have multiple opportunities
        String query = 'SELECT Id, (SELECT Id, CloseDate FROM Opportunities ORDER BY CloseDate DESC LIMIT 1 OFFSET 1) FROM Account WHERE Id IN (SELECT AccountId FROM Opportunity GROUP BY AccountId HAVING COUNT(Id) > 1)';
        return Database.getQueryLocator(query);
    }
    
    global void execute(Database.BatchableContext context, List<Account> scope) {
        List<Opportunity> opportunitiesToDelete = new List<Opportunity>();
        for (Account acc : scope) {
            List<Opportunity> opportunities = acc.Opportunities;
            opportunities.sort((a, b) => a.CloseDate.compareTo(b.CloseDate));
            opportunitiesToDelete.addAll(opportunities.subList(0, opportunities.size() - 1));
        }
        delete opportunitiesToDelete;
    }
    
    global void finish(Database.BatchableContext context) {
        // Optional: add post-batch processing logic here
    }
}

All Answers

Sai PraveenSai Praveen (Salesforce Developers) 
Hi Vishal,

Do you mean the batch should delete all the opportunities related to Account other than the recent opportunity?

Thanks,
 
Mukesh pal 7Mukesh pal 7

The start method queries for all accounts that have multiple opportunities, and the execute method deletes all but the latest opportunity for each account. The query used in the start method retrieves the Account records along with their Opportunities subquery, sorted by CloseDate in ascending order. We then use the opportunities.sort method to sort the opportunities list in ascending order by CloseDate, and use the opportunitiesToDelete.addAll method to add all but the latest opportunity to a list of opportunities to delete. Finally, we use the delete statement to delete all opportunities in the opportunitiesToDelete list.
Try the code :


global class DeleteDuplicateOpportunities implements Database.Batchable<SObject> {
    
    global Database.QueryLocator start(Database.BatchableContext context) {
        // Query for all accounts that have multiple opportunities
        String query = 'SELECT Id, (SELECT Id, CloseDate FROM Opportunities ORDER BY CloseDate DESC LIMIT 1 OFFSET 1) FROM Account WHERE Id IN (SELECT AccountId FROM Opportunity GROUP BY AccountId HAVING COUNT(Id) > 1)';
        return Database.getQueryLocator(query);
    }
    
    global void execute(Database.BatchableContext context, List<Account> scope) {
        List<Opportunity> opportunitiesToDelete = new List<Opportunity>();
        for (Account acc : scope) {
            List<Opportunity> opportunities = acc.Opportunities;
            opportunities.sort((a, b) => a.CloseDate.compareTo(b.CloseDate));
            opportunitiesToDelete.addAll(opportunities.subList(0, opportunities.size() - 1));
        }
        delete opportunitiesToDelete;
    }
    
    global void finish(Database.BatchableContext context) {
        // Optional: add post-batch processing logic here
    }
}

This was selected as the best answer
Sai Krishna 609Sai Krishna 609
# Sai Praveen ......... shall we connect once .... 

Regards 
+91-9494966720 (whats app)
Vishal SawVishal Saw
Thanks for your support !! its Completed Bro.