Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /**
- * @purpose: Represents the business logic as the deletion candidate.
- *
- * @author: nilavan.manokaran@onivation.de
- *
- * @history:
- * version | author | changes
- * ====================================================================================
- * 0.1 (17.04.2018) | nilavan.manokaran@onivation.de | initial version
- * 0.2 (24.04.2018) | julian.saarkamm@onivation.de | continue to work
- * 0.3 (30.04.2017) | christian.schwabe@onivation.de | final version
- * 0.4 (11.07.2018) | christian.schwabe@onivation.de | added contructor with List<Id>
- * 0.5 (13.09.2018) | johannes.heinrich@onivation.de | +NumberOfRowsToDelete__c, Status__c, Operation__c;
- * renamed labels; also logging besides the initial run
- * 0.6 (17.10.2018) | selahattin.tuglu@onivation.de | added new Criteria "Contact includes DOI" in
- * Method "checkContactActivity()";
- * 0.7 (18.10.2018) | johannes.heinrich@onivation.de | load labels during tests; added params to helper constr
- * 0.8 (12.12.2018) | yassin.oulghazi@onivation.de | added if-statement that skips Account with Subtyp "WWN Partner"
- */
- global class ContactDeletionAssessment implements Database.Batchable<sObject>, Database.Stateful, Schedulable {
- public Integer tresholdValueDeleteCandidate;
- public Boolean initialRunDeleteCandidate;
- private Id id;
- private List<Id> listOfContactId;
- private Datetime startdate = Datetime.now();
- private Integer numberOfSuccessfullyDeletedRecords = 0;
- private Integer numberOfNonDeletedRecords = 0;
- private Integer numberOfSuccessfullyUpdatedRecords = 0;
- private Integer numberOfNonUpdatedRecords = 0;
- private String batchJobURL = '';
- private AsyncApexJob aaj;
- // Task
- private Set<Id> setOfContactIdFromTask;
- private Set<Id> setOfAccountIdFromTask;
- // Opportunity
- private Set<Id> opportunityAccountIds;
- // Case
- private Set<Id> setOfContactIdFromCase;
- private Set<Id> setOfAccountIdFromCase;
- // Campaign
- private Set<Id> campaignContactIds;
- // Nutzungsberechtigter
- private Set<Id> authorizedUserIds;
- // Account
- private Set<Id> setOfAccountIdWithTerritory;
- // SAP Contract
- private Set<Id> setOfAccountIdFromSapVertrag;
- // Contact to delete
- private List<Id> setOfContactIdsToDelete;
- private Map<Id, Account> mapOfAccountById;
- global ContactDeletionAssessment(List<Id> listOfContactId){
- this();
- this.listOfContactId = listOfContactId;
- }
- global ContactDeletionAssessment(Id id){
- this();
- this.id = id;
- }
- global ContactDeletionAssessment() {
- this.setOfContactIdFromTask = new Set<Id>();
- this.setOfContactIdFromCase = new Set<Id>();
- this.setOfAccountIdFromCase = new Set<Id>();
- this.campaignContactIds = new Set<Id>();
- this.authorizedUserIds = new Set<Id>();
- this.setOfAccountIdFromSapVertrag = new Set<Id>();
- this.setOfAccountIdFromTask = new Set<Id>();
- this.opportunityAccountIds = new Set<Id>();
- this.setOfContactIdsToDelete = new List<Id>();
- this.mapOfAccountById = new Map<Id, Account>();
- this.setOfAccountIdWithTerritory = new Set<Id>();
- if(this.tresholdValueDeleteCandidate == null){
- this.tresholdValueDeleteCandidate = Integer.valueOf(System.Label.ContactThresholdValueDeleteCandidate);
- }
- if(this.initialRunDeleteCandidate == null){
- this.initialRunDeleteCandidate = Boolean.valueOf(System.Label.ContactInitialRunDeleteCandidate);
- }
- }
- global Database.QueryLocator start(Database.BatchableContext batchContext) {
- this.aaj = [SELECT Id, Status, NumberOfErrors, ExtendedStatus, JobType, MethodName, JobItemsProcessed, TotalJobItems, CompletedDate, CreatedDate FROM AsyncApexJob WHERE Id = :batchContext.getJobId()];
- String query = 'SELECT ' +
- 'Id, Name, CreatedDate, CONT_DeletionIndicator__c, CONT_DeletionIndicatorDate__c, CONT_Double_Opt_in_Mail_bestaetigt__c, ' +
- 'AccountId, Account.Name, Account.Type, Account.ACCT_Subtyp__c, Account.Owner.Name, ' +
- 'Account.ACCT_Vertriebsgebiet__c, Account.ACCT_Vertriebsgebiet__r.Name, Account.ACCT_Vertriebsgebiet__r.Owner.Name ' +
- 'FROM Contact';
- if(String.isNotBlank(this.id)){
- query += ' WHERE Id = \'' + this.id + '\'';
- }
- if(this.listOfContactId != null && this.listOfContactId.size() > 0){
- query += ' WHERE Id IN (\'' + String.join(this.listOfContactId, '\',\'') + '\')';
- }
- //System.debug('>>>query: ' + query);
- return Database.getQueryLocator(query);
- }
- global void execute(SchedulableContext sc) {
- ContactDeletionAssessment cda = new ContactDeletionAssessment();
- Database.executeBatch(cda, 50);
- }
- global void execute(Database.BatchableContext batchContext, List<Contact> scope) {
- // Contact List to Update Deletion Indicator
- List<Contact> contactsToUpdate = new List<Contact>();
- this.prepare(scope);
- List<ApexDebugLog__c> listOfApexDebugLog = new List<ApexDebugLog__c>();
- for(Contact contact : scope) {
- Boolean toBeDeleted = false;
- Id accountId = contact.AccountId;
- Account relatedAccount = null;
- if(String.isNotBlank(accountId) && this.mapOfAccountById.containsKey(accountId)){
- relatedAccount = mapOfAccountById.get(contact.AccountId);
- }
- //Kontakte unter Account mit Subtyp "WWN Partner" von der Verarbeitung ausnehmen.
- if(relatedAccount != null) {
- if(relatedAccount.ACCT_Subtyp__c != null && relatedAccount.ACCT_Subtyp__c == 'WWN Partner'){
- continue;
- }
- }
- Boolean contactActivity = this.checkContactActivity(contact);
- Boolean accountActivity = this.checkAccountActivity(relatedAccount);
- if(contactActivity) {
- if(contact.CONT_DeletionIndicator__c){//Löschen eines vorh. Löschkennzeichen (CONT_DeletionIndicator__c) aufgrund einer aktiven Nutzung.
- contact.CONT_DeletionIndicator__c = false;
- contactsToUpdate.add(contact);
- }
- }
- //Keine Nutzung des Kontakts - Überprüfung der Account-Nutzung.
- if(contactActivity == false && accountActivity) {
- if(contact.CONT_DeletionIndicator__c == true) {//Der Kontakt ist als Löschkandidat vorgemerkt: Ja
- if(contact.CONT_DeletionIndicatorDate__c < System.now().addMonths(-6)) {//Sechs (6) Monate lang wurde die Markierung des Löschkandidaten nicht verändert und weiterhin aktiv.
- this.setOfContactIdsToDelete.add(contact.Id);
- toBeDeleted = true;
- }
- } else{//Der Kontakt ist als Löschkandidat vorgemerkt: Nein
- if(contact.CONT_DeletionIndicatorDate__c == null || (contact.CONT_DeletionIndicatorDate__c != null && contact.CONT_DeletionIndicatorDate__c < System.now().addMonths(-12))) {
- contact.CONT_DeletionIndicator__c = true;
- contactsToUpdate.add(contact);
- }
- }
- }
- //Keine Nutzung des Kontakts und keine Nutzung des Accounts
- if(contactActivity == false && accountActivity == false) {
- this.setOfContactIdsToDelete.add(contact.Id);
- toBeDeleted = true;
- }
- if(this.tresholdValueDeleteCandidate == 0 && toBeDeleted){//Create a detailed log for every to be deleted contact
- ApexDebugLog__c apexDebugLog = this.createApexDebugLog(contact);
- apexDebugLog.Notice__c = 'To be deleted';
- if(this.initialRunDeleteCandidate){
- apexDebugLog = this.attachDetailedLog(apexDebugLog, contact);
- }
- listOfApexDebugLog.add(apexDebugLog);
- }
- }
- insert listOfApexDebugLog;
- if (contactsToUpdate.size() > 0 && (this.setOfContactIdsToDelete.size() < this.tresholdValueDeleteCandidate)) {
- this.updateList(contactsToUpdate, false);
- }
- }
- global void finish(Database.BatchableContext batchContext) {
- //"Master log" erstellen
- this.aaj = [SELECT Id, Status, NumberOfErrors, ExtendedStatus, JobType, MethodName, JobItemsProcessed, TotalJobItems, CompletedDate, CreatedDate FROM AsyncApexJob WHERE Id = :batchContext.getJobId() limit: 1];
- if(!Test.isRunningTest()){
- String reportId = [SELECT Id FROM Report WHERE DeveloperName = 'ApexDebugLog'].id;
- batchJobURL = URL.getSalesforceBaseUrl().toExternalForm() + '/' + reportId + '?pv0=' + batchContext.getJobId();
- }
- if(this.setOfContactIdsToDelete.size() > 0) {
- if(this.setOfContactIdsToDelete.size() < this.tresholdValueDeleteCandidate) {
- ContactDeletionAssessmentHelper cdah = new ContactDeletionAssessmentHelper(
- this.setOfContactIdsToDelete,
- batchContext.getJobId(),
- this.aaj.CreatedDate,
- this.numberOfSuccessfullyUpdatedRecords,
- this.numberOfNonUpdatedRecords);
- Database.executeBatch(cdah, 50);
- } else {
- ApexDebugLog__c masterAdl = new ApexDebugLog__c();
- masterAdl.NumberOfRowsToDelete__c = setOfContactIdsToDelete.size();
- masterAdl.Notice__c = 'Master';
- masterAdl.Notice__c += '\nErreichen des Schwellwerts. Zu löschende Kontakte: '
- + masterAdl.NumberOfRowsToDelete__c + '. Schwellwert: '
- + this.tresholdValueDeleteCandidate + '.';
- masterAdl.JobName__c = 'ContactDeletionAssessment';
- masterAdl.Master__c = true;
- masterAdl.BatchJobId18__c = this.aaj.Id;
- masterAdl.JobStartDatetime__c = this.startdate;
- masterAdl.JobEndDatetime__c = this.aaj.CompletedDate;
- masterAdl.NumberOfDeletedRows__c = this.numberOfSuccessfullyDeletedRecords;
- masterAdl.NumberOfNonDeletedRows__c = this.numberOfNonDeletedRecords;
- masterAdl.NumberOfUpdatedRows__c = this.numberOfSuccessfullyUpdatedRecords;
- masterAdl.NumberOfNonUpdatedRows__c = this.numberOfNonUpdatedRecords;
- masterAdl.ReportToLink__c = this.batchJobURL;
- insert masterAdl;
- }
- } else {
- ApexDebugLog__c masterAdl = new ApexDebugLog__c();
- masterAdl.Notice__c = 'Master';
- masterAdl.JobName__c = 'ContactDeletionAssessment';
- masterAdl.Master__c = true;
- masterAdl.BatchJobId18__c = this.aaj.Id;
- masterAdl.JobStartDatetime__c = this.startdate;
- masterAdl.JobEndDatetime__c = this.aaj.CompletedDate;
- masterAdl.NumberOfDeletedRows__c = this.numberOfSuccessfullyDeletedRecords;
- masterAdl.NumberOfNonDeletedRows__c = this.numberOfNonDeletedRecords;
- masterAdl.NumberOfUpdatedRows__c = this.numberOfSuccessfullyUpdatedRecords;
- masterAdl.NumberOfNonUpdatedRows__c = this.numberOfNonUpdatedRecords;
- masterAdl.ReportToLink__c = this.batchJobURL;
- insert masterAdl;
- }
- }
- /**
- * Dient zur Auslagerung der Abfragen hinsichtlich der Methoden checkAccountActivity und checkContactActivity.
- *
- * @param listOfContact
- */
- public void prepare(List<Contact> listOfContact){
- List<Id> accountIds = new List<Id>();
- List<Contact> scope = listOfContact;
- for(Contact contact : (List<Contact>) scope) {
- if(String.isNotBlank(contact.AccountId)){
- accountIds.add(contact.AccountId);
- }
- }
- this.mapOfAccountById = new Map<Id, Account>([SELECT Id, ACCT_Vertriebsgebiet__c, ACCT_Subtyp__c FROM Account WHERE Id = :accountIds]);
- List<Task> taskList = [SELECT Id, WhoId, WhatId, CreatedDate FROM Task WHERE CreatedDate > :System.now().addMonths(-38) AND (WhoId IN :scope OR WhatId IN :accountIds) AND IsDeleted = false ALL ROWS];
- for(Task task : taskList) {
- if( String.isNotBlank(task.whoId)){
- this.setOfContactIdFromTask.add(task.whoId);
- }
- if(String.isNotBlank(task.whatId)){
- this.setOfAccountIdFromTask.add(task.whatId);
- }
- }
- //Map<Id, Opportunity> mapOfOpportunityById = new Map<Id, Opportunity>([SELECT Id, AccountId FROM Opportunity WHERE CreatedDate > :System.now().addMonths(-38) AND (AccountId = :accountIds OR OPP_Abw_ReEmpf_Kontaktname__c IN :scope OR OPP_Kontaktname__c IN :scope OR OPP_Rechnung_Kontaktname__c IN :scope)]);
- for(Opportunity opportunity : [SELECT Id, AccountId
- FROM Opportunity
- WHERE CreatedDate > :System.now().addMonths(-38) AND
- (AccountId = :accountIds OR
- OPP_Abw_ReEmpf_Kontaktname__c IN :scope OR
- OPP_Kontaktname__c IN :scope OR
- OPP_Rechnung_Kontaktname__c IN :scope)]) {
- //Opportunity opportunity = mapOfOpportunityById.get(opportunityId);
- if(String.isNotBlank(opportunity.AccountId)){
- this.opportunityAccountIds.add(opportunity.AccountId);
- }
- }
- /*List<Case> caseList = [SELECT
- Id,
- ContactId,
- AccountId
- FROM
- Case
- WHERE
- CreatedDate > :System.now().addMonths(-38) AND
- (ContactId IN :scope OR AccountId IN :accountIds)
- ];*/
- for(Case caseObj : [SELECT Id, ContactId, AccountId
- FROM
- Case
- WHERE
- CreatedDate > :System.now().addMonths(-38) AND
- (ContactId IN :scope OR AccountId IN :accountIds)
- ]) {
- If(String.isNotBlank(caseObj.ContactId)){
- this.setOfContactIdFromCase.add(caseObj.ContactId);
- }
- if(String.isNotBlank(caseObj.AccountId)){
- this.setOfAccountIdFromCase.add(caseObj.AccountId);
- }
- }
- for(CampaignMember campaignMember : [SELECT Id, CampaignId, ContactId
- FROM
- CampaignMember
- WHERE
- ContactId IN :scope AND
- CreatedDate > :System.now().addMonths(-38)
- ]) {
- this.campaignContactIds.add(campaignMember.ContactId);
- }
- for(Nutzungsberechtiger__c authorizedUser : [SELECT Id, UID_User__c
- FROM Nutzungsberechtiger__c
- WHERE
- UID_Status__c = 'Aktiv' AND
- CreatedDate > :System.now().addMonths(-38) AND
- UID_User__c IN :scope
- ]) {
- this.authorizedUserIds.add(authorizedUser.UID_User__c);
- }
- //List<SAP_Vertrag__c> sapContractList = new List<SAP_Vertrag__c>([SELECT Id, SAPV_Account__c FROM SAP_Vertrag__c WHERE CreatedDate > :System.now().addMonths(-38) AND SAPV_Account__c = :accountIds]);
- for(SAP_Vertrag__c sapVertrag : [SELECT Id, SAPV_Account__c
- FROM SAP_Vertrag__c
- WHERE CreatedDate > :System.now().addMonths(-38)
- AND SAPV_Account__c = :accountIds]) {
- if(String.isNotBlank(sapVertrag.SAPV_Account__c)){
- this.setOfAccountIdFromSapVertrag.add(sapVertrag.SAPV_Account__c);
- }
- }
- for(Id accountId : this.mapOfAccountById.keySet()){
- Account account = this.mapOfAccountById.get(accountId);
- if(String.isNotBlank(account.ACCT_Vertriebsgebiet__c)){
- this.setOfAccountIdWithTerritory.add(accountId);
- }
- }
- }
- private void updateList(Contact[] contactsToUpdate, Boolean allOrNone) {
- List<Database.SaveResult> saveResult = Database.update(contactsToUpdate, allOrNone);
- List<ApexDebugLog__c> listOfApexDebugLog = new List<ApexDebugLog__c>();
- Integer i = 0;
- for (Database.saveResult result : saveResult) {
- Contact contact = contactsToUpdate.get(i);
- if (result.isSuccess()) {
- this.numberOfSuccessfullyUpdatedRecords++;
- ApexDebugLog__c adl = this.createApexDebugLog(contact);
- adl.Notice__c = 'SUCCESS -- UPDATED';
- adl.Operation__c = 'Update';
- adl.Status__c = 'Info';
- if(this.initialRunDeleteCandidate){
- adl = this.attachDetailedLog(adl, contactsToUpdate.get(i));
- }
- listOfApexDebugLog.add(adl);
- } else {
- this.numberOfNonUpdatedRecords++;
- for(Database.Error err : result.getErrors()) {
- //Id id15 = String.valueOf(contactsToUpdate.get(i).Id).left(15);
- ApexDebugLog__c adl = this.createApexDebugLog(contact,
- err.getFields(),
- err.getMessage(),
- err.getStatusCode());
- adl.Notice__c = 'FAILURE -- UPDATED';
- adl.Operation__c = 'Update';
- adl.Status__c = 'Error';
- if(this.initialRunDeleteCandidate){
- adl = this.attachDetailedLog(adl, contact);
- }
- listOfApexDebugLog.add(adl);
- }
- }
- i++;
- }
- insert listOfApexDebugLog;
- }
- // Check First Criteria
- private Boolean checkContactActivity(Contact contact) {
- if(contact.CreatedDate > System.now().addMonths(-26)) { // Check Contact Date
- return true;
- }
- else if(contact.CONT_Double_Opt_in_Mail_bestaetigt__c) {
- // Returns true when Lead includes DOI
- return true;
- }
- else if(this.checkTasks(contact)) {
- return true;
- }
- /*else if(this.checkOpportunityContactRole(contact)) {
- return true;
- }*/
- else if(this.checkCases(contact)) {
- return true;
- }
- else if(this.checkCampaigns(contact)) {
- return true;
- } else if(this.checkAuthorizedUsers(contact)){
- return true;
- } else {
- return false;
- }
- }
- // Check second Criteria
- public Boolean checkAccountActivity(Account account) {
- //System.debug('>>>account: ' + account);
- if(account == null){
- return false;
- }
- else if(this.checkSapVertrag(account)) {
- //System.debug('>>>true.');
- return true;
- }
- else if(this.checkTerritory(account)) {
- //System.debug('>>>true.');
- return true;
- }
- else if(this.checkTaskAccount(account)) {
- //System.debug('>>>true.');
- return true;
- }
- else if(this.checkOpportunitiesAccount(account)) {
- //System.debug('>>>true.');
- return true;
- }
- else if(this.checkCaseAccount(account)) {
- //System.debug('>>>true.');
- return true;
- }
- else {
- //System.debug('>>>false.');
- return false;
- }
- }
- // --------------------------------------
- //Second Criteria
- private Boolean checkCaseAccount(Account account) {
- if(this.setOfAccountIdFromCase.contains(account.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- private Boolean checkOpportunitiesAccount(Account account) {
- if(this.opportunityAccountIds.contains(account.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- private Boolean checkTaskAccount(Account account) {
- if(this.setOfAccountIdFromTask.contains(account.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- private Boolean checkSapVertrag(Account account) {
- if(this.setOfAccountIdFromSapVertrag.contains(account.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- private Boolean checkTerritory(Account account) {
- if(this.setOfAccountIdWithTerritory.contains(account.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- // --------------------------------------
- // First Criteria
- private Boolean checkTasks(Contact contact) {
- if(this.setOfContactIdFromTask.contains(contact.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- /* private Boolean checkOpportunityContactRole(Contact contact) {
- if(this.opportunityContactIds.contains(contact.Id)) {
- return true;
- } else {
- return false;
- }
- }*/
- private Boolean checkCases(Contact contact) {
- if(this.setOfContactIdFromCase.contains(contact.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- private Boolean checkCampaigns(Contact contact) {
- if(this.campaignContactIds.contains(contact.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- private Boolean checkAuthorizedUsers(Contact contact) {
- if(this.authorizedUserIds.contains(contact.Id)) {
- //System.debug('>>>true.');
- return true;
- } else {
- //System.debug('>>>false.');
- return false;
- }
- }
- private ApexDebugLog__c createApexDebugLog(Contact contact, List<String> errorFields, String errorMessage, StatusCode statusCode){
- ApexDebugLog__c adl = new ApexDebugLog__c();
- Id id15 = String.valueOf(contact.Id).left(15);
- adl.BatchJobId18__c = this.aaj.Id;
- adl.JobName__c = 'ContactDeletionAssessment';
- adl.Id15__c = id15;
- adl.Fields__c = String.join(errorFields, ',');
- adl.Notice__c = errorMessage;
- adl.Statuscode__c = String.valueOf(statusCode);
- return adl;
- }
- private ApexDebugLog__c createApexDebugLog(Contact contact){
- ApexDebugLog__c adl = new ApexDebugLog__c();
- Id id15 = String.valueOf(contact.Id).left(15);
- adl.BatchJobId18__c = this.aaj.Id;
- adl.JobName__c = 'ContactDeletionAssessment';
- adl.Id15__c = id15;
- return adl;
- }
- private ApexDebugLog__c attachDetailedLog(ApexDebugLog__c adl, Contact contact){
- adl.Notice__c += '\nKontaktname: ' + contact.Name + '\n';
- adl.Notice__c += 'Account-Id: ' + contact.AccountId + '\n';
- adl.Notice__c += 'Account-Name: ' + contact.Account.Name + '\n';
- adl.Notice__c += 'Account-Typ: ' + contact.Account.Type + '\n';
- adl.Notice__c += 'Account-Subtyp: ' + contact.Account.ACCT_Subtyp__c + '\n';
- adl.Notice__c += 'Name des Account-Inhabers: ' + contact.Account.Owner.Name + '\n';
- adl.Notice__c += 'Vertriebsgebiet: ' + contact.Account.ACCT_Vertriebsgebiet__r.Name + '\n';
- adl.Notice__c += 'Name des Vertriebsgebiet-Inhabers: ' + contact.Account.ACCT_Vertriebsgebiet__r.Owner.Name;
- return adl;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement