+ Start a Discussion
ZurMilesZurMiles 

Delete Account if ....

Hello all,

 

I'm trying to look for the best way to delete an Account if there is not Opportunies, Contacts, Tasks or Events active on that Account. Wat would be the best a more simple way to wirte this on Apex?

 

Thanks on advance.

 

 

 

All Answers

crop1645crop1645

ZurMiles

 

Sounds like you are trying to delete 'dead' accounts automatically?

 

Automatic Options:

1. Use Scheduled Apex and a schedulable class that runs through your database on some cycle looking for qualifying accounts and then using APEX DML to delete them (ideally, logging its actions). This 'qualifying' code could do 

 

select id, (select id from Contacts limit 1), (select id from Opportunities limit 1), ... from Account 

 

and then inspect the size of the relationships to see if children records are present

 

Manual Options:

1. Use tools like Mass Delete Anything or Data Loader.  For these to work, you'll need to have fields in Account that unambigously tell you that it is safe to delete. Count of Opporutnities is easy with a RSF field, other child SObjects would require triggers that ask the Account to maintain a count of the child records

 

ZurMilesZurMiles

Hello Eric,

 

 

Do you think you could put a short scrip to explain that?

I will really appreciate it if you could.

 

 

ZurMilesZurMiles

Thanks for those links, they are definitely a good approach.

Here is a piece of code from someone that was working in my company. We have no developers right now and my level on APEX is not even close to this. The problem is that this code is not working for some reason and I can't figure out why. I was thinking on writing something my self but I still need to understand better apex before building something that will delete our accounts in case they are part of a  specify criteria. 

 

Can someone let me know if there is something wrong on this script?

 

Thanks in advance!

 

public class Account_To_Be_Deleted_Methods {

    Id accId;
    Account acc;
    List<Contact> con;
    List<Id> contactIds = new List<Id>();
    List<Id> whatIds = new List<Id>();
    User hiddenOwner;
    List<Opportunity> opp, openOpps;
    List<Task> tsk, openTsks;
    List<Event> evt, openEvts;
  boolean hasOpenOpps, hasOpenTsks, hasOpenEvts;

    public Account_To_Be_Deleted_Methods(ApexPages.StandardController controller) {
        accId = ApexPages.currentPage().getParameters().get('id').substring(0, 15);
        acc = [SELECT Id, OwnerId, Name, Account_Status__c FROM Account WHERE Id = :accId];
        con = [SELECT Id, OwnerId FROM Contact WHERE AccountId = :accId];
        for (Contact c : con) {
          contactIds.add(c.Id);
        }
        hiddenOwner = [SELECT Id FROM User WHERE Name = 'Hidden Accounts' or Name = 'Accounts Hidden' LIMIT 1];
        opp = [SELECT Id, Name, StageName, Amount, CloseDate, AccountId, IsClosed FROM Opportunity WHERE AccountId = :accId];
        whatIds.add(accId);
        for (Opportunity o : opp) {
          whatIds.add(o.Id);
        }
        tsk = [SELECT Id, Subject, ActivityDate, Status, WhatId, WhoId, IsClosed FROM Task WHERE WhatId IN :whatIds OR WhoId IN :contactIds]; 
        evt = [SELECT Id, Subject, WhatId, WhoId, StartDateTime, EndDateTime FROM Event WHERE WhatId IN :whatIds OR WhoId IN :contactIds];
    }
  
  public PageReference deleteAccount() {
    
    if ((UserInfo.getUserId() == acc.OwnerId || UserInfo.getUserRoleId().substring(0, 15) == '00E30000000oNdM' || UserInfo.getUserId().substring(0,15) == '00580000003Ll8Y' || UserInfo.getUserId().substring(0,15) == '00580000003LkKd') && opp.isEmpty() && tsk.isEmpty() && evt.isEmpty()) {
          Database.DeleteResult dr = Database.delete(acc);
    }
    else {
      hasOpenOpps = checkOpenOpportunities();
      hasOpenTsks = checkOpenTasks();
      hasOpenEvts = checkOpenEvents();

      // If it is not the owner of the Account or a System Admin, do not allow the Account Deletion to occur
      // Also set the boolean 'has' variables to false . This prevents the related list vies appearing on the page
      if (UserInfo.getUserId() != acc.OwnerId && UserInfo.getUserRoleId().subString(0, 15) != '00E30000000oNdM' && UserInfo.getUserId().substring(0, 15) != '00580000003Ll8Y' && UserInfo.getUserId().substring(0, 15) != '00580000003LkKd') {
        Apexpages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Your are not the owner of the Account ' + acc.Name + '. Only the Account Owner can delete the Account.'));
        hasOpenOpps = false;
        hasOpenTsks = false;
        hasOpenEvts = false;
      }
      else {
        if (hasOpenOpps || hasOpenTsks || hasOpenEvts) {
                 if (hasOpenOpps) {
                   Apexpages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Account ' + acc.Name + ' contains an open Opportunity'));
                 }
                 if (hasOpenTsks) {
                   Apexpages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Account ' + acc.Name + ' (or an associated Contact) contains an incompleted Task'));
                 }
                 if (hasOpenEvts) {
                   Apexpages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Account ' + acc.Name + ' (or an associated Contact) contains an open Event'));
                }
        }
        else {
          acc.OwnerId = hiddenOwner.Id;
          acc.Account_Status__c = 'Deactivated';
          acc.To_Be_Deleted__c = true;
          acc.RecordTypeId = '012300000001X5I';
          update(acc);
          if (!con.isEmpty()) {
            for (Contact c : con) {
              c.OwnerId = hiddenOwner.Id;
              c.RecordTypeId = '012300000001X5S';
            }
            update(con);
          }
        }
      }
    }
        if (!Apexpages.getMessages().isEmpty()) {
          return null;
        }
        PageReference pageRef = new PageReference('/001/o');
        pageRef.setRedirect(true);
        return pageRef;
  }
  
  public boolean checkOpenOpportunities() {

        // Place any open Opportunities into the openOpps List.
        // Return true if any open Opportunities are found. Otherwise return false.
        openOpps = new List<Opportunity>();       
         for (Opportunity o : opp) {
             if (!o.IsClosed) {
               openOpps.add(o);
             }
        }
        if (openOpps.isEmpty()) {
          return false;
        }
        return true;
  }
  
  public boolean checkOpenTasks() {
        // Place any open Tasks into the openTsks List.
        // Return true if any open Tasks are found. Otherwise return false.    
    openTsks = new List<Task>();
    for (Task t : tsk) {
      if (!t.IsClosed) {
        openTsks.add(t);
      }
    }
    if (openTsks.isEmpty()) {
      return false;
    }
    return true;
  }
  
  public boolean checkOpenEvents() {
        // Place any open Events into the openOpps List.
        // Return true if any open Events are found. Otherwise return false.
        openEvts = new List<Event>();    
    for (Event e : evt) {
      if (e.EndDateTime > Datetime.now()) {
        openEvts.add(e);
      }
    }
    if (openEvts.isEmpty()) {
      return false;
    }
    return true;
  }
  
  public String getName() {
    return acc.Name;
  }
  
  public List<Opportunity> getOpenOpps() {
    return openOpps;
  }
  
  public List<Task> getOpenTsks() {
    return openTsks;
  }

  public List<Event> getOpenEvts() {
    return openEvts;
  }
  
  public boolean getHasOpenOpps() {
    return hasOpenOpps;
  }
  
  public boolean getHasOpenTasks() {
    return hasOpenTsks;
  }
  
  public boolean getHasOpenEvents() {
    return hasOpenEvts;
  }
}

 

crop1645crop1645

zurMiles

 

This code looks like it might be associated with an override of the Delete button for a single Account

 

It will either

 

a) delete the Account

b) Change the account status to Deactivated (and not delete)

c) Issue an error message saying action can't be done

 

This is not a solution for a scheduled job that auto-deletes qualifying accounts

ZurMilesZurMiles

Thanks Eric, 

 

I have been looking to our Accounts delete button and it use the default SFDC. I think that probably I need to create a new scrip and use the schedule that you was mentioning. 

Thanks again.

 

I will try and see how far can I go !!