├── src
├── staticresources
│ ├── Apx1Predeployment.resource
│ └── Apx1Predeployment.resource-meta.xml
├── objects
│ ├── User.object
│ ├── Contact.object
│ ├── Solution.object
│ ├── Opportunity.object
│ ├── AppConfig__c.object
│ ├── DebugInfo__c.object
│ └── AsyncRequest__c.object
├── triggers
│ ├── OnOpportunity1.trigger
│ ├── OnContact1.trigger
│ ├── OnAccount1.trigger-meta.xml
│ ├── OnContact1.trigger-meta.xml
│ ├── OnOpportunity1.trigger-meta.xml
│ ├── OnOpportunity2.trigger-meta.xml
│ ├── OnOpportunity3.trigger-meta.xml
│ ├── OnAsyncRequestInsert.trigger-meta.xml
│ ├── SolutionTrigger1.trigger-meta.xml
│ ├── SolutionTrigger2.trigger-meta.xml
│ ├── OnAccount1.trigger
│ ├── OnAsyncRequestInsert.trigger
│ ├── SolutionTrigger1.trigger
│ ├── SolutionTrigger2.trigger
│ ├── OnOpportunity3.trigger
│ └── OnOpportunity2.trigger
├── classes
│ ├── Benchmarking.cls-meta.xml
│ ├── Concurrency1.cls-meta.xml
│ ├── GoingAsync1.cls-meta.xml
│ ├── GoingAsync2.cls-meta.xml
│ ├── GoingAsync3.cls-meta.xml
│ ├── GoingAsync4.cls-meta.xml
│ ├── GoingAsync5.cls-meta.xml
│ ├── TestGoingAsync.cls-meta.xml
│ ├── ThinkingInApex.cls-meta.xml
│ ├── AppConfigSupport.cls-meta.xml
│ ├── BulkPatternBatch.cls-meta.xml
│ ├── DiagnosticsMain.cls-meta.xml
│ ├── FunWithCollections.cls-meta.xml
│ ├── SimulatedTranslator.cls-meta.xml
│ ├── TestBulkPatterns.cls-meta.xml
│ ├── TestDiagnostics1.cls-meta.xml
│ ├── TestDiagnostics2.cls-meta.xml
│ ├── TestForPackages.cls-meta.xml
│ ├── TestHeapAndSOQL.cls-meta.xml
│ ├── TestPersonAccount.cls-meta.xml
│ ├── TestThinkingInApex.cls-meta.xml
│ ├── TestTriggersExample.cls-meta.xml
│ ├── TriggersExample.cls-meta.xml
│ ├── DiagnosticsTriggers1.cls-meta.xml
│ ├── DiagnosticsTriggers2.cls-meta.xml
│ ├── PersonAccountSupport.cls-meta.xml
│ ├── ScheduledDispatcher2.cls-meta.xml
│ ├── SomeFutureOperations.cls-meta.xml
│ ├── TestThinkingInApexLimits.cls-meta.xml
│ ├── TriggerArchitectureMain1.cls-meta.xml
│ ├── DiagnosticsInstrumentation.cls-meta.xml
│ ├── ThinkingInApexBulkPatterns.cls-meta.xml
│ ├── TriggerArchitectureClass1.cls-meta.xml
│ ├── TriggerArchitectureClass2.cls-meta.xml
│ ├── SomeFutureOperations.cls
│ ├── ScheduledDispatcher2.cls
│ ├── TestThinkingInApex.cls
│ ├── BulkPatternBatch.cls
│ ├── AppConfigSupport.cls
│ ├── TestGoingAsync.cls
│ ├── TestTriggersExample.cls
│ ├── GoingAsync3.cls
│ ├── GoingAsync2.cls
│ ├── TriggersExample.cls
│ ├── GoingAsync5.cls
│ ├── TestPersonAccount.cls
│ ├── TriggerArchitectureClass1.cls
│ ├── TestHeapAndSOQL.cls
│ ├── DiagnosticsTriggers2.cls
│ ├── DiagnosticsInstrumentation.cls
│ ├── DiagnosticsMain.cls
│ ├── SimulatedTranslator.cls
│ ├── Benchmarking.cls
│ ├── TestForPackages.cls
│ ├── TriggerArchitectureClass2.cls
│ ├── TriggerArchitectureMain1.cls
│ ├── PersonAccountSupport.cls
│ ├── TestThinkingInApexLimits.cls
│ ├── Concurrency1.cls
│ ├── ThinkingInApex.cls
│ ├── GoingAsync1.cls
│ ├── TestDiagnostics1.cls
│ ├── GoingAsync4.cls
│ ├── TestBulkPatterns.cls
│ ├── FunWithCollections.cls
│ ├── DiagnosticsTriggers1.cls
│ └── TestDiagnostics2.cls
└── package.xml
├── RetrieveCurrentValue.cls
├── ControllingProgramFlow.cls
├── LeadRoundRobinQueueFor18Digit.tgr
├── Benchmarking
└── Benchmarking.cls
├── RHX_Subscription.tgr
├── RHX_Customer_Feedback.tgr
├── RHX_Product_User.tgr
├── RHX_Property_to_Opportunity.tgr
├── SomeFutureOperations.cls
├── PropertyToOpportunityRH.tgr
├── CacheCurrentValue.cls
├── RHXZuoraSubscriptionProductCharge.tgr
├── CurrentLog.cls
├── SpringCMAccount.tgr
├── SpringCMOpportunity.tgr
├── LeadTrigger.tgr
├── ContactTrigger.tgr
├── ThinkInApex.cls
├── HandleAfterInsert_LeadConversion.tgr
├── activityCreatesOpp (1).tgr
├── SubscriptionProductUserLeadConvert.tgr
├── UpdateCommunityUserRoles.tgr
├── CommunityUserBeforeTriggerClonned.tgr
├── CommunityUserBeforeTriggerCreateLead (1).tgr
├── CommunityUserBeforeTriggerCreateLead (2).tgr
└── README.md
/src/staticresources/Apx1Predeployment.resource:
--------------------------------------------------------------------------------
1 | disable:1
2 | disable:2
3 | Opportunity:TrackingNumber__c=somevalue
4 |
--------------------------------------------------------------------------------
/src/objects/User.object:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/RetrieveCurrentValue.cls:
--------------------------------------------------------------------------------
1 | User u = [SELECT UserIsSpecial__c FROM
2 | User WHERE ID = :UserInfo.getUserId()];
3 | Boolean UserIsSpecial = u.UserIsSpecial__c;
4 |
--------------------------------------------------------------------------------
/ControllingProgramFlow.cls:
--------------------------------------------------------------------------------
1 | /** Enforce that every opportunity is created with an OpportunityContactRole
2 | **/
3 |
4 | trigger OnOpportunity on Opportunity (before insert) {
5 | Think
6 |
--------------------------------------------------------------------------------
/src/triggers/OnOpportunity1.trigger:
--------------------------------------------------------------------------------
1 | trigger OnOpportunity1 on Opportunity (after insert) {
2 | /*
3 | ThinkingInApex.AfterInsertOpportunity(
4 | trigger.new, trigger.newMap);
5 | */
6 |
7 | }
--------------------------------------------------------------------------------
/src/triggers/OnContact1.trigger:
--------------------------------------------------------------------------------
1 | trigger OnContact1 on Contact (before insert, before update) {
2 | PersonAccountSupport.processContactTrigger1(
3 | trigger.isBefore, trigger.new, trigger.oldMap);
4 | }
--------------------------------------------------------------------------------
/src/classes/Benchmarking.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/Concurrency1.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/GoingAsync1.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/GoingAsync2.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/GoingAsync3.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/GoingAsync4.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/GoingAsync5.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestGoingAsync.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/ThinkingInApex.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/AppConfigSupport.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 31.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/BulkPatternBatch.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/DiagnosticsMain.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/FunWithCollections.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/SimulatedTranslator.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestBulkPatterns.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestDiagnostics1.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestDiagnostics2.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestForPackages.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestHeapAndSOQL.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 31.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestPersonAccount.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestThinkingInApex.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestTriggersExample.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TriggersExample.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/OnAccount1.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/OnContact1.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/DiagnosticsTriggers1.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/DiagnosticsTriggers2.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/PersonAccountSupport.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/ScheduledDispatcher2.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/SomeFutureOperations.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TestThinkingInApexLimits.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TriggerArchitectureMain1.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/OnOpportunity1.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/OnOpportunity2.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/OnOpportunity3.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 31.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/DiagnosticsInstrumentation.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/ThinkingInApexBulkPatterns.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 31.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TriggerArchitectureClass1.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/TriggerArchitectureClass2.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/OnAsyncRequestInsert.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 31.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/SolutionTrigger1.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 34.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/SolutionTrigger2.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 31.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/triggers/OnAccount1.trigger:
--------------------------------------------------------------------------------
1 | trigger OnAccount1 on Account
2 | (after insert, after update,
3 | before insert, before update) {
4 |
5 | PersonAccountSupport.processAccountTrigger1(
6 | trigger.isBefore, trigger.new, trigger.oldMap);
7 |
8 | }
--------------------------------------------------------------------------------
/src/triggers/OnAsyncRequestInsert.trigger:
--------------------------------------------------------------------------------
1 | trigger OnAsyncRequestInsert on AsyncRequest__c (after insert) {
2 | if(Limits.getLimitQueueableJobs() - Limits.getQueueableJobs() > 0)
3 | try
4 | {
5 | GoingAsync4.enqueueGoingAsync4(null);
6 | } catch(Exception ex)
7 | {
8 | // Ignore for now
9 | }
10 |
11 | }
--------------------------------------------------------------------------------
/src/staticresources/Apx1Predeployment.resource-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Private
4 | text/plain
5 | Predeployment resource
6 |
7 |
--------------------------------------------------------------------------------
/LeadRoundRobinQueueFor18Digit.tgr:
--------------------------------------------------------------------------------
1 | trigger LeadRoundRobinQueueFor18Digit on LeadRoundRobinQueue__c (before insert, before update)
2 | {
3 |
4 | Id sID;
5 |
6 | for(LeadRoundRobinQueue__c lrr : trigger.new) {
7 | sID = lrr.Standard_Queue_Id__c;
8 | lrr.Standard_Queue_Id__c = string.valueOf(sID);
9 | }
10 |
11 | }
--------------------------------------------------------------------------------
/src/triggers/SolutionTrigger1.trigger:
--------------------------------------------------------------------------------
1 | trigger SolutionTrigger1 on Solution (after insert, after update) {
2 |
3 | /*
4 | GoingAsync1.handleTrigger1(trigger.new, trigger.newMap,
5 | trigger.oldMap, trigger.isInsert);
6 | */
7 |
8 | /*
9 | GoingAsync1.handleTrigger5(trigger.new, trigger.newMap,
10 | trigger.oldMap, trigger.isInsert);
11 | */
12 | }
--------------------------------------------------------------------------------
/Benchmarking/Benchmarking.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | private class Benchmarking {
3 |
4 | @istest
5 | public static void TestNewAllocate()
6 | {
7 | for(Integer x = 0; x < 10000; x++)
8 | ReturnNewMap();
9 | }
10 |
11 | private static Map ReturnNewMap()
12 | {
13 | Map result = new Map();
14 | return result;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/triggers/SolutionTrigger2.trigger:
--------------------------------------------------------------------------------
1 | trigger SolutionTrigger2 on Solution (before insert, before update) {
2 |
3 | /*
4 | GoingAsync1.handleTrigger2(trigger.new,
5 | trigger.oldMap, trigger.isInsert);
6 | */
7 | /*
8 | GoingAsync1.handleTrigger3(trigger.new,
9 | trigger.oldMap, trigger.isInsert);
10 | */
11 |
12 |
13 | GoingAsync1.handleTrigger4(trigger.new,
14 | trigger.oldMap, trigger.isInsert);
15 |
16 |
17 |
18 | }
--------------------------------------------------------------------------------
/src/triggers/OnOpportunity3.trigger:
--------------------------------------------------------------------------------
1 | trigger OnOpportunity3 on Opportunity (after delete, after insert,
2 | after undelete, after update, before delete,
3 | before insert, before update) {
4 |
5 | DiagnosticsMain.mainEntry('Opportunity', trigger.isBefore,
6 | trigger.isDelete, trigger.isAfter, trigger.isInsert,
7 | trigger.isUpdate, trigger.isExecuting,
8 | trigger.new, trigger.newMap, trigger.old, trigger.oldMap);
9 |
10 |
11 | }
--------------------------------------------------------------------------------
/RHX_Subscription.tgr:
--------------------------------------------------------------------------------
1 | trigger RHX_Subscription on Subscription__c (after delete, after insert, after undelete, after update, before delete) {
2 |
3 | Type rollClass = System.Type.forName('rh2', 'ParentUtil');
4 |
5 | if(rollClass != null) {
6 | rh2.ParentUtil pu = (rh2.ParentUtil) rollClass.newInstance();
7 | if (trigger.isAfter) {
8 | pu.performTriggerRollups(trigger.oldMap, trigger.newMap, new String[]{'Subscription__c'}, null);
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/RHX_Customer_Feedback.tgr:
--------------------------------------------------------------------------------
1 | trigger RHX_Customer_Feedback on Customer_Feedback__c
2 | (after delete, after insert, after undelete, after update, before delete) {
3 | Type rollClass = System.Type.forName('rh2', 'ParentUtil');
4 | if(rollClass != null) {
5 | rh2.ParentUtil pu = (rh2.ParentUtil) rollClass.newInstance();
6 | if (trigger.isAfter) {
7 | pu.performTriggerRollups(trigger.oldMap, trigger.newMap, new String[]{'Customer_Feedback__c'}, null);
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/RHX_Product_User.tgr:
--------------------------------------------------------------------------------
1 | trigger RHX_Product_User on Product_User__c (after delete, after insert, after undelete, after update, before delete) {
2 |
3 | Type rollClass = System.Type.forName('rh2', 'ParentUtil');
4 |
5 | if(rollClass != null) {
6 | rh2.ParentUtil pu = (rh2.ParentUtil) rollClass.newInstance();
7 | if (trigger.isAfter) {
8 | pu.performTriggerRollups(trigger.oldMap, trigger.newMap, new String[]{'Product_User__c'}, null);
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/RHX_Property_to_Opportunity.tgr:
--------------------------------------------------------------------------------
1 | trigger RHX_Property_to_Opportunity on Property_to_Opportunity__c
2 | (after delete, after insert, after undelete, after update, before delete) {
3 | Type rollClass = System.Type.forName('rh2', 'ParentUtil');
4 | if(rollClass != null) {
5 | rh2.ParentUtil pu = (rh2.ParentUtil) rollClass.newInstance();
6 | if (trigger.isAfter) {
7 | pu.performTriggerRollups(trigger.oldMap, trigger.newMap, new String[]{'Property_to_Opportunity__c'}, null);
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/SomeFutureOperations.cls:
--------------------------------------------------------------------------------
1 | // indicates that the call has already been made
2 | public class SomeFutureOperations {
3 | private static Boolean FutureCallCalled = false;
4 | public static void DoFutureCall()
5 | {
6 | if(FutureCallCalled ||
7 | System.isFuture()) return;
8 | FutureCallCalled = true;
9 | ActualFutureCall();
10 | }
11 |
12 | @future
13 | private static void ActualFutureCall()
14 | {
15 | // Actual async code here
16 | system.debug('ActualFutureCall async operation');
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/PropertyToOpportunityRH.tgr:
--------------------------------------------------------------------------------
1 | trigger PropertyToOpportunityRH on Property_to_Opportunity__c (after delete, after insert, after undelete, after update, before delete) {
2 |
3 | Type rollClass = System.Type.forName('rh2', 'ParentUtil');
4 |
5 | if(rollClass != null) {
6 | rh2.ParentUtil pu = (rh2.ParentUtil) rollClass.newInstance();
7 | if (trigger.isAfter) {
8 | pu.performTriggerRollups(trigger.oldMap, trigger.newMap, new String[]{'Property_to_Opportunity__c'}, null);
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/src/classes/SomeFutureOperations.cls:
--------------------------------------------------------------------------------
1 | public class SomeFutureOperations {
2 |
3 | private static Boolean futureCallCalled = false;
4 |
5 | public static void doFutureCall()
6 | {
7 | if(futureCallCalled || System.isFuture()) return;
8 | futureCallCalled = true;
9 | actualFutureCall();
10 | // Code to call async here
11 | }
12 |
13 | @future
14 | private static void actualFutureCall()
15 | {
16 | // Actual async code here
17 | system.debug('actualFutureCall async operation');
18 | }
19 |
20 |
21 |
22 | }
--------------------------------------------------------------------------------
/CacheCurrentValue.cls:
--------------------------------------------------------------------------------
1 | public class ThinkingInApex {
2 |
3 | private static Boolean IsUserSpecialChecked = false;
4 |
5 | private static Boolean UserIsSpecial = false;
6 |
7 | public static Boolean IsUserSpecial()
8 | {
9 | if(IsUserSpecialChecked) return UserIsSpecial;
10 |
11 | User u = [SELECT UserIsSpecial__c from User where ID
12 | = :UserInfo.getUserId()];
13 | UserIsSpecial = u.UserIsSpecial__c;
14 | IsUserSpecialChecked = true;
15 | return UserIsSpecial;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/RHXZuoraSubscriptionProductCharge.tgr:
--------------------------------------------------------------------------------
1 | trigger RHXZuoraSubscriptionProductCharge on Zuora__SubscriptionProductCharge__c (after delete, after insert, after undelete, after update, before delete) {
2 |
3 | Type rollClass = System.Type.forName('rh2', 'ParentUtil');
4 |
5 | if(rollClass != null) {
6 | rh2.ParentUtil pu = (rh2.ParentUtil) rollClass.newInstance();
7 | if (trigger.isAfter) {
8 | pu.performTriggerRollups(trigger.oldMap, trigger.newMap, new String[]{'Zuora__SubscriptionProductCharge__c'}, null);
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/src/classes/ScheduledDispatcher2.cls:
--------------------------------------------------------------------------------
1 | global class ScheduledDispatcher2 Implements Schedulable {
2 |
3 | public Interface IScheduleDispatched
4 | {
5 | void execute(SchedulableContext sc);
6 | }
7 |
8 | global void execute(SchedulableContext sc)
9 | {
10 | Type targetType = Type.forName('GoingAsync5');
11 | if(targetType!=null) {
12 | IScheduleDispatched obj =
13 | (IScheduleDispatched)targettype.newInstance();
14 | obj.execute(sc);
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/CurrentLog.cls:
--------------------------------------------------------------------------------
1 | /**
2 | Function to display the current diagnostic log
3 | **/
4 |
5 | public static String CurrentLog()
6 | {
7 | if(DiagnosticLog == null) return null;
8 | String spaces = ' ';
9 | String result = '';
10 | for(DiagnosticEntry de: DiagnosticLog)
11 | {
12 | Integer endindex = 3 * de.level;
13 | if(endindex >= spaces.length())
14 | endindex = spaces.length()-1;
15 | result += spaces.substring(0,endindex) +
16 | de.description + '\n';
17 | }
18 | return result;
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/SpringCMAccount.tgr:
--------------------------------------------------------------------------------
1 | trigger SpringCMAccount on Account (after insert) {
2 | Map rtMap = Schema.SObjectType.Account.getRecordTypeInfosById();
3 | Map acc = new Map();
4 |
5 | for(Account a : Trigger.new) {
6 | String recordType = null;
7 | if(rtMap.size() > 1)
8 | recordType = rtMap.get((ID)a.get('RecordTypeId')).getName();
9 | acc.put(a.Id, recordType);
10 | }
11 | SpringCMRestWrap.BuildEOS(acc, 'Account', UserInfo.getSessionId(), 'CreateSubFolderStructure_CSV');
12 | }
--------------------------------------------------------------------------------
/SpringCMOpportunity.tgr:
--------------------------------------------------------------------------------
1 | trigger SpringCMOpportunity on Opportunity (after insert) {
2 | Map rtMap = Schema.SObjectType.Opportunity.getRecordTypeInfosById();
3 | Map opp = new Map();
4 |
5 | for(Opportunity o : Trigger.new) {
6 | String recordType = null;
7 | if(rtMap.size() > 1)
8 | recordType = rtMap.get((ID)o.get('RecordTypeId')).getName();
9 | opp.put(o.Id, recordType);
10 | }
11 | SpringCMRestWrap.BuildEOS(opp, 'Opportunity', UserInfo.getSessionId(), 'CreateSubFolderStructure_CSV');
12 | }
--------------------------------------------------------------------------------
/LeadTrigger.tgr:
--------------------------------------------------------------------------------
1 | trigger LeadTrigger on Lead (before insert, before update)
2 | {
3 | List records = trigger.isDelete ? trigger.old : trigger.new;
4 |
5 | if(trigger.isBefore)
6 | {
7 | if(trigger.isInsert)
8 | {
9 | ULead.runRules(records, trigger.oldMap);
10 | }
11 | else if(trigger.isUpdate)
12 | {
13 | ULead.runRules(records, trigger.oldMap);
14 | }
15 | //else if(trigger.isDelete)
16 | //{
17 | //}
18 | }
19 |
20 | //else
21 | /*
22 | if(trigger.isAfter)
23 | {
24 | if(trigger.isInsert)
25 | {
26 | }
27 | else if(trigger.isUpdate)
28 | {
29 | }
30 | else if(trigger.isDelete)
31 | {
32 | }
33 | else if(trigger.isUndelete)
34 | {
35 | }
36 | }
37 | */
38 | }
--------------------------------------------------------------------------------
/src/classes/TestThinkingInApex.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | private class TestThinkingInApex {
3 |
4 | // This test will fail when OnOpportunity1 trigger is enabled
5 | static testMethod void testOCRs1()
6 | {
7 | Opportunity op = new Opportunity(
8 | name='optest', StageName ='Prospecting',
9 | CloseDate = Date.Today() );
10 |
11 | insert op;
12 | }
13 |
14 | static testMethod void testOCRs2()
15 | {
16 | Opportunity op = new Opportunity(
17 | name='optest', StageName ='Prospecting',
18 | CloseDate = Date.Today() );
19 |
20 | Contact ct = new Contact(LastName = 'newct');
21 | insert ct;
22 | ThinkingInApex.associateContacts = new List{ct};
23 |
24 | insert op;
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/src/classes/BulkPatternBatch.cls:
--------------------------------------------------------------------------------
1 | global class BulkPatternBatch implements Database.Batchable {
2 |
3 | global final string query;
4 | global final Set opportunityIds;
5 |
6 |
7 | public bulkPatternBatch(Set opportunityIDsToUpdate)
8 | {
9 | opportunityids = opportunityIDsToUpdate;
10 | query = 'SELECT ID, OwnerID from Opportunity where ID in :opportunityids ';
11 | }
12 |
13 | global Database.QueryLocator start(Database.BatchableContext BC){
14 | return Database.getQueryLocator(query);
15 | }
16 |
17 | global void execute(Database.BatchableContext BC, List scope){
18 | List ops = (List)scope;
19 | Map newmap = new Map(ops);
20 | ThinkingInApexBulkPatterns.afterUpdateOpportunityBatchSupport(ops, newMap, null);
21 | return;
22 | }
23 |
24 | global void finish(Database.BatchableContext BC){
25 |
26 | }
27 |
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/src/objects/Contact.object:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Level2__c
5 | false
6 |
7 |
8 |
9 | Primary
10 | false
11 |
12 |
13 | Secondary
14 | false
15 |
16 |
17 | Tertiary
18 | false
19 |
20 | false
21 |
22 | false
23 | Picklist
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/classes/AppConfigSupport.cls:
--------------------------------------------------------------------------------
1 | public with sharing class AppConfigSupport {
2 |
3 | private static AppConfig__c testConfig = null;
4 |
5 | public static AppConfig__c getAppConfig()
6 | {
7 | if(Test.isRunningTest() && testConfig!=null) return testConfig;
8 |
9 | AppConfig__c theobject = AppConfig__c.getInstance('default');
10 | if(theObject==null || Test.isRunningTest())
11 | {
12 | theObject = new AppConfig__c();
13 | theObject.name = 'default';
14 | theObject.EnableDiagnostics__c = (Test.isRunningTest())? true: false;
15 | theObject.AppEnabled__c = true;
16 | if(!Test.isRunningTest()) Database.Insert(theobject);
17 | else testconfig = theObject;
18 | }
19 | return theObject;
20 | }
21 |
22 | public static Boolean diagnosticsEnabled
23 | {
24 | get
25 | {
26 | return GetAppConfig().EnableDiagnostics__c;
27 | }
28 | }
29 |
30 | public static Boolean appEnabled
31 | {
32 | get
33 | {
34 | return GetAppConfig().AppEnabled__c;
35 | }
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/src/objects/Solution.object:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | SolutionSpanish__c
5 | Solution auto-translated into Spanish
6 | false
7 |
8 | 32768
9 | false
10 | LongTextArea
11 | 3
12 |
13 |
14 | TranslationPending__c
15 | false
16 | Indicates this record has a translation pending
17 | false
18 | Indicates this record has a translation pending
19 |
20 | false
21 | Checkbox
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/objects/Opportunity.object:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | TestCounterAmount__c
5 | Test Amount field used for concurrency testing
6 | false
7 |
8 | 18
9 | false
10 | 0
11 | false
12 | false
13 | Number
14 | false
15 |
16 |
17 | Enforce_Tracking_Number
18 | false
19 | ISBLANK(TrackingNumber__c )
20 | TrackingNumber__c
21 | Tracking number must be set for opportunities
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/classes/TestGoingAsync.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | private class TestGoingAsync {
3 |
4 | private static Integer bulkTestSize = 101;
5 |
6 | static testMethod void testSolutionsInsert() {
7 |
8 | List sols = new List();
9 |
10 | for(Integer x = 0; x solsmap = new Map(sols);
27 |
28 | List results =
29 | [Select ID, SolutionNote, SolutionSpanish__c
30 | from Solution where ID in :solsmap.keyset()];
31 | for(Solution sol: results)
32 | System.AssertEquals(sol.SolutionNote + ' in Spanish',
33 | sol.SolutionSpanish__c);
34 |
35 | }
36 |
37 | }
--------------------------------------------------------------------------------
/src/classes/TestTriggersExample.cls:
--------------------------------------------------------------------------------
1 | @istest
2 | public class TestTriggersExample {
3 |
4 | private static final Integer numberOfOpportunities = 5;
5 |
6 | static testMethod void testTaskCount() {
7 |
8 | List ops = new List();
9 |
10 | for(Integer x=0; x opMap = new Map(ops);
29 |
30 | List tasks =
31 | [Select ID, WhatID from Task
32 | where WhatID in :opmap.keyset()
33 | And Subject ='Opportunity stage update'];
34 |
35 | System.AssertEquals(numberOfOpportunities, tasks.size());
36 | }
37 |
38 | }
--------------------------------------------------------------------------------
/ContactTrigger.tgr:
--------------------------------------------------------------------------------
1 | /*
2 | Name: ContactTrigger
3 | Created By: Raja Yeccherla(GearsCRM)
4 | Created Date: 06/22/2016
5 | Description: Trigger for Contact
6 |
7 | Modified By:
8 | Modified Date:
9 | Description:
10 | */
11 | trigger ContactTrigger on contact (after insert, after update) {
12 |
13 | List records = trigger.isDelete ? trigger.old :trigger.new;
14 |
15 | /*if(trigger.isBefore)
16 | {
17 | if(trigger.isInsert)
18 | {
19 | }
20 | else if(trigger.isUpdate)
21 | {
22 | }
23 | else if(trigger.isDelete)
24 | {
25 | }
26 | }
27 | else if(trigger.isAfter)*/
28 |
29 | if(trigger.isafter )
30 | {
31 | if(trigger.isInsert)
32 | {
33 | UContact.setAccountTeamMember4(records, trigger.oldMap);
34 | }
35 | else if(trigger.isUpdate)
36 | {
37 | UContact.setAccountTeamMember4(records, trigger.oldMap);
38 | }
39 | /*else if(trigger.isDelete)
40 | {
41 | }
42 | else if(trigger.isUndelete)
43 | {
44 | } */
45 | }
46 | }
--------------------------------------------------------------------------------
/src/classes/GoingAsync3.cls:
--------------------------------------------------------------------------------
1 | public without sharing class GoingAsync3
2 | implements queueable, Database.AllowsCallouts {
3 |
4 | public void execute(QueueableContext context)
5 | {
6 | if(!AppConfigSupport.appEnabled) return; // On/off switch
7 |
8 | Integer allowedCallouts =
9 | Limits.getLimitCallouts() - Limits.getCallouts();
10 |
11 | if(allowedCallouts<=0) return;
12 | List solutionsToUpdate =
13 | [SELECT ID, SolutionNote, SolutionSpanish__c
14 | from Solution
15 | where LastModifiedDate > :DateTime.Now().addHours(-24)
16 | And TranslationPending__c = true LIMIT :allowedCallouts];
17 | for(Solution sl: solutionsToUpdate)
18 | {
19 | sl.SolutionSpanish__c =
20 | SimulatedTranslator.translate(sl.SolutionNote);
21 | sl.TranslationPending__c = false;
22 | }
23 | update solutionsToUpdate;
24 |
25 |
26 | if(solutionsToUpdate.size()== allowedCallouts &&
27 | Limits.getLimitQueueableJobs() - Limits.getQueueableJobs() > 0)
28 | try
29 | {
30 | system.enqueueJob(new GoingAsync3());
31 | } catch(Exception ex)
32 | {
33 | // Alternate chaining mechanism
34 | }
35 |
36 | }
37 |
38 |
39 | }
--------------------------------------------------------------------------------
/src/objects/AppConfig__c.object:
--------------------------------------------------------------------------------
1 |
2 |
3 | List
4 | Protected
5 | Application configuration
6 | false
7 |
8 | AppEnabled__c
9 | false
10 | Application is enabled
11 | false
12 | Application is enabled
13 |
14 | false
15 | Checkbox
16 |
17 |
18 | EnableDiagnostics__c
19 | false
20 | True to enable diagnostics
21 | false
22 |
23 | false
24 | Checkbox
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ThinkInApex.cls:
--------------------------------------------------------------------------------
1 | /** With this approach, you can cache all necessary information from an object with only one SOQL call
2 | With this approach you can run into trouble if you try to cache large amount of data.
3 | **/
4 |
5 | public class ThinkingInApex {
6 |
7 | private static Boolean UserCacheLoaded = false;
8 | private static Boolean UserIsSpecial = false;
9 | private static String UserTimeZone = null;
10 |
11 | public static Boolean IsUserSpecial()
12 | {
13 | if(UserCacheLoaded) return UserIsSpecial;
14 | CacheUserInfo();
15 | return UserIsSpecial:
16 | }
17 |
18 | public static String UserTimeZone()
19 | {
20 | if(UserCacheLoaded) return UserTimeZone;
21 | CacheUserInfo();
22 | return UserTimeZone;
23 | }
24 |
25 | private static void CacheUserInfo()
26 | {
27 | if(UserCacheLoaded) return UserTimeZone;
28 | CacheUserInfo();
29 | return UserTimeZone;
30 | }
31 |
32 | private static void CacheUserInfo()
33 | {
34 | if(UserCahceLoaded) return;
35 | User u = [SELECT UserIsSpecial__c,
36 | TimeZoneSidKey from User where
37 | ID = :UserInfo.getUserId()];
38 | UserIsSpecial = u.UserIsSpecial__c;
39 | UserTimeZone = u.TimeZoneSidKey;
40 | UserCacheLoaded = true;
41 | }
42 |
43 | }
44 |
45 |
--------------------------------------------------------------------------------
/HandleAfterInsert_LeadConversion.tgr:
--------------------------------------------------------------------------------
1 | trigger HandleAfterInsert_LeadConversion on Contact (after insert) {
2 |
3 | if(LithiumRecursionController.HandleAfterInsert_LeadConversion == true)
4 | return;
5 | LithiumRecursionController.HandleAfterInsert_LeadConversion = true;
6 |
7 | Map mapLithmIdToCntcs = new Map();
8 | List updLiCmmUsrs = new List();
9 |
10 | for(Contact aContact : Trigger.new) {
11 | System.debug('___lithiumid___'+aContact.LithiumId__c);
12 | if(aContact.LithiumId__c != NULL) {
13 | mapLithmIdToCntcs.put(Integer.valueOf(aContact.LithiumId__c),aContact.Id);
14 | }
15 | }
16 |
17 | System.debug('___mapLithmIdToCntcs____'+mapLithmIdToCntcs);
18 |
19 | for(Li_Community_User1__c aCommunityUser : [SELECT Id,Contact__c,Lithium_User_Id__c from Li_Community_User1__c Where Lithium_User_Id__c != NULL AND Lithium_User_Id__c IN : mapLithmIdToCntcs.keySet()]) {
20 | if(mapLithmIdToCntcs.containsKey(Integer.valueOf(aCommunityUser.Lithium_User_Id__c))) {
21 | System.debug('____contact_id____'+mapLithmIdToCntcs.get(Integer.valueOf(aCommunityUser.Lithium_User_Id__c)));
22 | aCommunityUser.Contact__c = mapLithmIdToCntcs.get(Integer.valueOf(aCommunityUser.Lithium_User_Id__c));
23 | updLiCmmUsrs.Add(aCommunityUser);
24 | }
25 | }
26 | System.debug('___updLiCmmUsrs____'+updLiCmmUsrs);
27 | update updLiCmmUsrs;
28 | }
--------------------------------------------------------------------------------
/src/classes/GoingAsync2.cls:
--------------------------------------------------------------------------------
1 | global class GoingAsync2 implements
2 | Database.Batchable,
3 | Database.AllowsCallouts {
4 |
5 | global Database.Querylocator start(Database.BatchableContext bc)
6 | {
7 | return Database.getQueryLocator('SELECT ID, SolutionNote, SolutionSpanish__c From Solution Where TranslationPending__c = true');
8 | }
9 |
10 | global void execute(Database.BatchableContext BC, List scope)
11 | {
12 |
13 | for(Solution sl: scope)
14 | {
15 | sl.SolutionSpanish__c = SimulatedTranslator.translate(sl.SolutionNote);
16 | sl.TranslationPending__c = false;
17 | }
18 | update scope;
19 |
20 | }
21 |
22 | global void finish(Database.BatchableContext BC)
23 | {
24 | List stillPending =
25 | [SELECT ID From Solution
26 | Where TranslationPending__c = true Limit 1];
27 | if(stillPending.size()>0) StartBatch(true);
28 | }
29 |
30 | public static Boolean isBatchActive(String classname)
31 | {
32 | List activeStatuses =
33 | new List{'Completed','Aborted','Failed'};
34 | AsyncApexJob[] activeJobs =
35 | [select id, CompletedDate, Status, ExtendedStatus, ApexClassID
36 | from AsyncApexJob where ApexClass.Name = :classname
37 | and JobType='BatchApex'
38 | And Status Not in :activeStatuses
39 | Order By CreatedDate Desc Limit 1];
40 | return activeJobs.size() >0;
41 | }
42 |
43 | private static Boolean batchRequested = false;
44 |
45 | public static void startBatch(Boolean forceStart)
46 | {
47 | if(!forceStart &&
48 | (batchRequested || isBatchActive('GoingAsync2'))) return;
49 |
50 | GoingAsync2 ga = new GoingAsync2();
51 | Integer batchSize = Limits.getLimitCallouts();
52 | if(batchSize>200) batchSize = 200;
53 | try
54 | {
55 | Database.executeBatch(ga, batchSize);
56 | } catch(Exception ex)
57 | {
58 | return;
59 | }
60 |
61 | batchRequested = true;
62 | }
63 |
64 |
65 |
66 | }
--------------------------------------------------------------------------------
/src/classes/TriggersExample.cls:
--------------------------------------------------------------------------------
1 | public class TriggersExample {
2 |
3 | public static void afterUpdateOpportunityCreateTasks1(
4 | List newList, Map newMap,
5 | Map oldMap)
6 | {
7 | List newTasks = new List();
8 |
9 | for(Opportunity op: newList)
10 | {
11 | system.debug('old probability ' +
12 | oldMap.get(op.id).Probability +
13 | ' new probability ' + op.Probability);
14 | if(oldMap.get(op.id).Probability == 10 && op.Probability > 10)
15 | {
16 | newTasks.add(
17 | new Task(ownerId = op.OwnerID,
18 | WhatID = op.id,
19 | ActivityDate = Date.Today().addDays(2),
20 | Subject='Opportunity stage update',
21 | Type='Other'));
22 | }
23 | }
24 | insert newTasks;
25 | }
26 |
27 | private static Map probabilityOverrides = null;
28 |
29 | public static void afterUpdateOpportunityCreateTasks2(
30 | List newList, Map newMap,
31 | Map oldMap)
32 | {
33 | List newTasks = new List();
34 | if(probabilityOverrides==null) probabilityOverrides = new Map();
35 |
36 | for(Opportunity op: newList)
37 | {
38 | Double oldProbability = (probabilityOverrides.containskey(op.id))?
39 | probabilityOverrides.get(op.id) :
40 | oldMap.get(op.id).Probability;
41 | system.debug('old probability ' + oldMap.get(op.id).Probability +
42 | ' new probability ' + op.Probability);
43 | if(oldProbability == 10 && op.Probability > 10)
44 | {
45 | newTasks.add(
46 | new Task(ownerId = op.OwnerID, WhatID = op.id,
47 | ActivityDate = Date.Today().addDays(2),
48 | Subject='Opportunity stage update',
49 | Type='Other'));
50 | }
51 | if(oldProbability != op.Probability)
52 | probabilityOverrides.put(op.id, op.Probability);
53 |
54 | }
55 | insert newTasks;
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/activityCreatesOpp (1).tgr:
--------------------------------------------------------------------------------
1 | trigger activityCreatesOpp on Opportunity (after insert) {
2 |
3 | // create set of Activity Ids that are Events; create map of Activity Id to Event
4 | set eventIds = new set();
5 | map eventMap = new map();
6 | // create set of Activity Ids that are Tasks; create map of Activity Id to Task
7 | set taskIds = new set();
8 | map taskMap = new map();
9 |
10 | // If the Activity Id on the opp is an Event or Task, add it to the appropriate set
11 | for(Opportunity opp : Trigger.new) {
12 | String actId = opp.ActivityId__c;
13 | if(String.isNotBlank(actId) && actId.startsWith('00U')) {
14 | eventIds.add(opp.ActivityId__c);
15 | }
16 | if(String.isNotBlank(actId) && actId.startsWith('00T')) {
17 | taskIds.add(opp.ActivityId__c);
18 | }
19 | }
20 |
21 | // If there are any Events that led to opp creation, create a mapping pair
22 | if(eventIds.size() > 0) {
23 | for(Event e : [SELECT Id from Event WHERE Id IN :eventIds]) {
24 | eventMap.put(e.Id, e);
25 | }
26 | }
27 |
28 | // If there are any Tasks that led to opp creation, create a mapping pair
29 | if(taskIds.size() > 0) {
30 | for(Task t : [SELECT Id from Task WHERE Id IN :taskIds]) {
31 | taskMap.put(t.Id, t);
32 | }
33 | }
34 |
35 | // changes the WhatId to the Opportunity Id on any Events or Tasks that are referenced on the Opportunity
36 | for(Opportunity opp : Trigger.new) {
37 | if(eventMap.containsKey(opp.ActivityId__c)) {
38 | eventMap.get(opp.ActivityId__c).WhatId = opp.Id;
39 | }
40 | if(taskMap.containsKey(opp.ActivityId__c)) {
41 | taskMap.get(opp.ActivityId__c).WhatId = opp.Id;
42 | }
43 | }
44 |
45 | // update the Events or Tasks that created an Opportunity
46 | if(eventMap.size() > 0) {
47 | update eventMap.values();
48 | }
49 | if(taskMap.size() > 0) {
50 | update taskMap.values();
51 | }
52 |
53 |
54 | }
--------------------------------------------------------------------------------
/SubscriptionProductUserLeadConvert.tgr:
--------------------------------------------------------------------------------
1 | trigger SubscriptionProductUserLeadConvert on Lead (before update) {
2 |
3 | // create mapping of Lead Id to Contact Id
4 | Map mapLeadIdContactId = new Map();
5 | // create mapping of Lead Id to Account Id
6 | Map mapLeadIdAccountId = new Map();
7 |
8 | // add the Lead Id:Contact Id pair to the mapping above for each Lead converted into a Contact
9 | for (Lead l : Trigger.new) {
10 | if (l.isConverted) {
11 | mapLeadIdContactId.put(l.Id, l.convertedContactId);
12 | mapLeadIdAccountId.put(l.Id, l.convertedAccountId);
13 | }
14 | /*if (l.isConverted && l.convertedAccountId != null) {
15 | mapLeadIdAccountId.put(l.Id, l.convertedAccountId);
16 | }*/
17 | }
18 |
19 | // store a list of Product User records, including the Subscription Account Id, looking up to a Lead stored in the Lead:Contact mapping
20 | List listProductUser = [SELECT Lead__c, Contact__c, Subscription__c, Subscription__r.Account__c, External_Id__c
21 | FROM Product_User__c
22 | WHERE Lead__c IN :mapLeadIdContactId.keySet()];
23 |
24 | Map subscriptionMap = new Map();
25 | // iterate through all Product User records that lookup to a Lead
26 | for (Product_User__c p : listProductUser) {
27 | p.Contact__c = mapLeadIdContactId.get(p.Lead__c);
28 | if (String.isBlank(p.Subscription__r.Account__c)) {
29 | Subscription__c subscription = new Subscription__c(
30 | Id = p.Subscription__c,
31 | Account__c = mapLeadIdAccountId.get(p.Lead__c));
32 | subscriptionMap.put(subscription.Id, subscription);
33 | }
34 |
35 | }
36 |
37 | List listSubscriptions = subscriptionMap.values();
38 | try {
39 | update listSubscriptions;
40 | }
41 | catch (DmlException dmx)
42 | {
43 | // always handle DML Exceptions on cross object updates from a trigger
44 | }
45 |
46 | update listProductUser;
47 |
48 | }
--------------------------------------------------------------------------------
/src/classes/GoingAsync5.cls:
--------------------------------------------------------------------------------
1 | public class GoingAsync5
2 | implements ScheduledDispatcher2.IScheduleDispatched {
3 |
4 | public void execute(SchedulableContext sc)
5 | {
6 | // When used as a backup to start the asnyc framework
7 | system.enqueueJob(new GoingAsync4());
8 | // Always abort the job on completion
9 | system.abortJob(sc.getTriggerID());
10 | }
11 |
12 | public static String getSchedulerExpression(Datetime dt) {
13 | // Don't try to schedule Apex before current time + buffer
14 | if(dt < DateTime.Now().AddMinutes(1))
15 | dt = DateTime.Now().AddMinutes(1);
16 | return ('' + dt.second() + ' ' + dt.minute() + ' ' +
17 | dt.hour() + ' ' + dt.day() + ' ' +
18 | dt.month() + ' ? ' + dt.year());
19 | }
20 |
21 | public static void startScheduler(DateTime scheduledTime, String jobName)
22 | {
23 |
24 | // Is the job already running?
25 | List jobs =
26 | [SELECT Id, CronJobDetail.Name, State, NextFireTime
27 | FROM CronTrigger
28 | WHERE CronJobDetail.Name= :jobName];
29 | if(jobs.size()>0 && jobs[0].state!='COMPLETED' &&
30 | jobs[0].state!='ERROR' && jobs[0].state!='DELETED')
31 | {
32 | // It's already running/scheduled
33 |
34 | // Depending on your design you might want to exit,
35 | // or abort and reschedule if the requested start time
36 | // is earlier
37 | return;
38 | }
39 |
40 | // If the job exists, it needs to be deleted
41 | if(jobs.size()>0) system.abortJob(jobs[0].id);
42 |
43 |
44 | try
45 | {
46 | System.schedule(jobName,
47 | getSchedulerExpression(scheduledTime),
48 | new ScheduledDispatcher2());
49 | } catch(Exception ex)
50 | {
51 | system.Debug(ex.getMessage());
52 | // Log the error?
53 | // Or throw the error to the caller?
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/classes/TestPersonAccount.cls:
--------------------------------------------------------------------------------
1 | @istest
2 | public class TestPersonAccount {
3 |
4 | static testMethod void testWithContacts() {
5 | List contacts = TestDiagnostics2.createContacts('patst', 3);
6 | contacts[0].LeadSource='Web';
7 | contacts[1].LeadSource='Phone Inquiry';
8 | contacts[2].LeadSource='Other';
9 | Test.StartTest();
10 | insert contacts;
11 | Test.StopTest();
12 | // Seealldata is false, so we'll get the same 3 contacts
13 | Map contactMap =
14 | new Map([Select ID, Level2__c from Contact Limit 3]);
15 | system.assertEquals(contactMap.get(contacts[0].id).Level2__c,'Primary');
16 | system.assertEquals(contactMap.get(contacts[1].id).Level2__c,'Primary');
17 | system.assertEquals(contactMap.get(contacts[2].id).Level2__c,'Secondary');
18 | }
19 |
20 | static testMethod void testWithAccounts() {
21 | List contacts =
22 | TestDiagnostics2.createContacts('patst', 3);
23 | List accounts =
24 | TestDiagnostics2.createAccounts('patest', 3);
25 | contacts[0].LeadSource='Web';
26 | contacts[1].LeadSource='Phone Inquiry';
27 | contacts[2].LeadSource='Other';
28 | PersonAccountSupport.fakePersonContactIDs = new List();
29 | PersonAccountSupport.fakePersonAccountDuringTest = true;
30 | insert contacts;
31 | for(Contact ct: contacts)
32 | PersonAccountSupport.fakePersonContactIDs.add(ct.id);
33 | Test.StartTest();
34 | insert accounts;
35 | Test.StopTest();
36 | // Seealldata is false, so we'll get the same 3 contacts
37 | Map contactMap =
38 | new Map(
39 | [Select ID, Level2__c
40 | from Contact Limit 3]);
41 | system.assertEquals(contactMap.get(contacts[0].id).Level2__c,'Primary');
42 | system.assertEquals(contactMap.get(contacts[1].id).Level2__c,'Primary');
43 | system.assertEquals(contactMap.get(contacts[2].id).Level2__c,'Secondary');
44 | }
45 |
46 | }
--------------------------------------------------------------------------------
/src/triggers/OnOpportunity2.trigger:
--------------------------------------------------------------------------------
1 | trigger OnOpportunity2 on Opportunity (after update) {
2 |
3 | // Samples for use with ThinkingInApexBulkPatterns.cls
4 | //ThinkingInApexBulkPatterns.afterUpdateOpportunityAwful(trigger.new, trigger.oldmap);
5 | //ThinkingInApexBulkPatterns.afterUpdateOpportunityCommon(trigger.new, trigger.newmap, trigger.oldmap);
6 | //ThinkingInApexBulkPatterns.afterUpdateOpportunitySets(trigger.new, trigger.newmap, trigger.oldmap);
7 | //ThinkingInApexBulkPatterns.afterUpdateOpportunityBetterQueries(trigger.new, trigger.newmap, trigger.oldmap);
8 | //ThinkingInApexBulkPatterns.afterUpdateOpportunityBetterQueries2(trigger.new, trigger.newmap, trigger.oldmap);
9 | //ThinkingInApexBulkPatterns.afterUpdateOpportunityFutureSupport(trigger.new, trigger.newmap, trigger.oldmap);
10 | //ThinkingInApexBulkPatterns.afterUpdateOpportunityBatchSupport(trigger.new, trigger.newmap, trigger.oldmap);
11 |
12 |
13 | // Trigger arhitecture examples
14 | // Example using parameters to track update objects
15 | /*Map objectsToUpdate = new Map();
16 | TriggerArchitectureClass1.Entry1(trigger.new, trigger.newMap, trigger.old, trigger.oldMap, objectsToUpdate);
17 | TriggerArchitectureClass2.Entry1(trigger.new, trigger.newMap, trigger.old, trigger.oldMap, objectsToUpdate);
18 | if(objectstoupdate.size()>0) update objectsToUpdate.values();
19 | */
20 |
21 | // Examples using a dispatcher class
22 |
23 | //TriggerArchitectureMain1.Entry2(trigger.new, trigger.newMap, trigger.old, trigger.oldMap);
24 | //TriggerArchitectureMain1.Entry3(trigger.new, trigger.newMap, trigger.old, trigger.oldMap);
25 |
26 | // Compelte centralized dispatching
27 | /* TriggerArchitectureMain1.entry4('Opportunity', trigger.isBefore, trigger.isDelete, trigger.isAfter,
28 | trigger.isInsert, trigger.isUpdate, trigger.isExecuting,
29 | trigger.new, trigger.newMap, trigger.old, trigger.oldMap);
30 | */
31 |
32 |
33 | // Samples for use with TriggerExample.cls
34 | //TriggersExample.afterUpdateOpportunityCreateTasks1(trigger.new, trigger.newmap, trigger.oldmap);
35 | TriggersExample.afterUpdateOpportunityCreateTasks2(trigger.new, trigger.newmap, trigger.oldmap);
36 |
37 | }
--------------------------------------------------------------------------------
/src/classes/TriggerArchitectureClass1.cls:
--------------------------------------------------------------------------------
1 | public class TriggerArchitectureClass1 implements TriggerArchitectureMain1.ITriggerEntry {
2 |
3 | public static void entry1(List newlist,
4 | Map newMap, List oldList,
5 | Map oldMap, Map objectsToUpdate)
6 | {
7 | // Do some processing here
8 | // Add entries to the objectstoupdate map if they need to be updated
9 | }
10 |
11 |
12 | public static void entry2(List newList,
13 | Map newMap, List oldList,
14 | Map oldMap)
15 | {
16 | // Do some processing here
17 | // Add entries to the dispatcher static variable
18 | // if they need to be updated
19 | }
20 |
21 |
22 | public static void entry3(List newList,
23 | Map newMap, List oldList,
24 | Map oldMap)
25 | {
26 | // Do some processing here
27 | // Add entries to the dispatcher static variable if they need to be updated
28 | }
29 |
30 | public void mainEntry(String triggerObject, Boolean isBefore,
31 | Boolean isDelete, Boolean isAfter, Boolean isInsert,
32 | Boolean isUpdate, Boolean isExecuting,
33 | List newList, Map newMap,
34 | List oldList, Map oldMap)
35 | {
36 | List opNewList = (List)newList;
37 | List opOldList = (List)oldList;
38 | Map opNewMap = (Map)newMap;
39 | Map opOldMap = (Map)oldMap;
40 |
41 | // Do some processing here
42 | // Add entries to the dispatcher static variable
43 | //if they need to be updated or do direct DML
44 |
45 | }
46 |
47 | public void inProgressEntry(String triggerObject, Boolean isBefore,
48 | Boolean isDelete, Boolean isAfter, Boolean isInsert,
49 | Boolean isUpdate, Boolean isExecuting,
50 | List newList, Map newMap,
51 | List oldList, Map oldMap)
52 | {
53 | // Be sure to detect for the objects you actually want to handle.
54 | // Can dispatch to other classes is necessary
55 | }
56 |
57 |
58 | }
--------------------------------------------------------------------------------
/src/classes/TestHeapAndSOQL.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | private class TestHeapAndSOQL {
3 |
4 | @testsetup static void setup()
5 | {
6 | // Build a 10K long string for description
7 | String longString = '';
8 | for(Integer x = 0; x<500; x++) longstring += '0123456789';
9 |
10 | List newLeads = new List();
11 | for(Integer x = 0; x<8000; x++)
12 | newLeads.add(new Lead(
13 | Company = 'comp' + string.ValueOf(x),
14 | LastName = 'joe'+string.ValueOf(x),
15 | Description = longString));
16 | insert newLeads;
17 | }
18 |
19 |
20 | static testMethod void testAllRecords() {
21 |
22 | Test.startTest();
23 |
24 | List leadNames = new List();
25 |
26 | List leads = [Select ID, Company, LastName, Description from Lead];
27 | system.debug(logginglevel.info, 'lead count ' + leads.size());
28 | for(Lead ld: leads) leadNames.add(ld.LastName);
29 |
30 | ShowLimits();
31 | Test.stopTest();
32 |
33 | }
34 |
35 | static testMethod void testSoqlLoop1() {
36 |
37 | Test.startTest();
38 |
39 | List leadNames = new List();
40 |
41 | for(List leads: [Select ID, Company, LastName, Description from Lead])
42 | {
43 | system.debug(logginglevel.info, 'lead count ' + leads.size());
44 | for(Lead ld: leads) leadNames.add(ld.LastName);
45 | }
46 | ShowLimits();
47 | Test.stopTest();
48 |
49 | }
50 |
51 | static testMethod void testSoqlLoop2() {
52 |
53 | Test.startTest();
54 |
55 | List leadNames = new List();
56 |
57 | for(Lead ld: [Select ID, Company, LastName, Description from Lead])
58 | leadNames.add(ld.LastName);
59 |
60 | ShowLimits();
61 | Test.stopTest();
62 |
63 | }
64 |
65 | private static void ShowLimits()
66 | {
67 | system.debug(LoggingLevel.info, 'SOQL count ' + limits.getQueries());
68 | system.debug(LoggingLevel.info, 'SOQL rows ' + limits.getQueryRows());
69 | system.debug(LoggingLevel.info, 'Heap size ' + limits.getHeapSize());
70 |
71 | }
72 |
73 |
74 | }
--------------------------------------------------------------------------------
/src/classes/DiagnosticsTriggers2.cls:
--------------------------------------------------------------------------------
1 | public class DiagnosticsTriggers2 Implements DiagnosticsMain.ITriggerEntry {
2 |
3 | private static Map probabilityOverrides = null;
4 |
5 | public void mainEntry(String triggerObject, Boolean isBefore,
6 | Boolean isDelete, Boolean isAfter, Boolean isInsert,
7 | Boolean isUpdate, Boolean isExecuting,
8 | List newList, Map newMap,
9 | List oldList, Map oldMap)
10 | {
11 | DiagnosticsInstrumentation.push('DiagnosticsTriggers2.MainEntry');
12 | afterUpdateOpportunityCreateTasks2((List)newList, (Map) newMap, (Map) oldMap);
13 | DiagnosticsInstrumentation.pop();
14 |
15 | }
16 | public void inProgressEntry(String triggerObject, Boolean isBefore, Boolean isDelete, Boolean isAfter, Boolean isInsert, Boolean isUpdate, Boolean IsExecuting, List newlist, Map newmap, List oldlist, Map oldmap)
17 | {
18 | // Ignore triggers within triggers
19 | }
20 |
21 |
22 | private static void afterUpdateOpportunityCreateTasks2(
23 | List newList, Map newMap,
24 | Map oldMap)
25 | {
26 | DiagnosticsInstrumentation.push(
27 | 'DiagnosticsTriggers2.AfterUpdateOpportunityCreateTasks2');
28 |
29 | List newTasks;
30 | // Comment out the following line to fake a runtime error
31 | // newtasks = new List();
32 | if(probabilityOverrides==null)
33 | probabilityOverrides = new Map();
34 |
35 | for(Opportunity op: newList)
36 | {
37 | Double oldProbability = (probabilityOverrides.containsKey(op.id))?
38 | probabilityOverrides.get(op.id) : oldMap.get(op.id).Probability;
39 | system.debug('old probability ' + oldMap.get(op.id).Probability +
40 | ' new probability ' + op.Probability);
41 | if(oldProbability == 10 && op.Probability > 10)
42 | {
43 | newTasks.add(new Task(OwnerId = op.OwnerID, WhatID = op.id,
44 | ActivityDate = Date.Today().addDays(2),
45 | Subject='Opportunity stage update', Type='Other'));
46 | }
47 | if(oldProbability != op.Probability)
48 | probabilityOverrides.put(op.id, op.Probability);
49 |
50 | }
51 | insert newTasks;
52 | DiagnosticsInstrumentation.pop();
53 |
54 | }
55 |
56 | }
--------------------------------------------------------------------------------
/UpdateCommunityUserRoles.tgr:
--------------------------------------------------------------------------------
1 | trigger UpdateCommunityUserRoles on Account (after Update) {
2 |
3 | Map qualifiedAccounts = new Map();
4 |
5 | if(Trigger.isUpdate && Trigger.isAfter){
6 |
7 | for(Account acc : Trigger.new){
8 | system.debug('__old___'+Lithium_Roles_With_IDs__c.getAll().containskey(Trigger.oldMap.get(acc.id).Market_Segment__c));
9 | system.debug('__new___'+Lithium_Roles_With_IDs__c.getAll().containskey(acc.Market_Segment__c));
10 |
11 | if(!qualifiedAccounts.containsKey(String.valueOf(acc.id).substring(0,15)) && acc.Market_Segment__c != null && (Trigger.oldMap.get(acc.id).Market_Segment__c == null ||
12 | !Lithium_Roles_With_IDs__c.getAll().containskey(Trigger.oldMap.get(acc.id).Market_Segment__c)) && (Lithium_Roles_With_IDs__c.getAll().containskey(acc.Market_Segment__c))){
13 | qualifiedAccounts.put(String.valueOf(acc.id).substring(0,15),acc);
14 | }
15 | }
16 |
17 | Map allRoles = Lithium_Roles_With_IDs__c.getAll();
18 | Map rolesIDs = new Map();
19 |
20 | for(Lithium_Roles_With_IDs__c role : allRoles.values()) {
21 | rolesIDs.put(role.name, role);
22 | }
23 |
24 | System.debug('__qualifiedAccounts___'+qualifiedAccounts);
25 |
26 | if(!qualifiedAccounts.isEmpty()){
27 |
28 | List commUsersWithRelatedAccount = [SELECT id,Lithium_User_Id__c,Account_ID__c FROM Li_Community_User1__c WHERE Contact__r.AccountId =: qualifiedAccounts.keyset()];
29 | for(Li_Community_User1__c cm : commUsersWithRelatedAccount){
30 | if(cm.Account_ID__c != null){
31 | if(qualifiedAccounts.get(cm.Account_ID__c) !=null){
32 | System.debug('__userid___'+cm.Lithium_User_Id__c);
33 | System.debug('___market_segment___'+rolesIDs.get(qualifiedAccounts.get(cm.Account_ID__c).market_segment__c).role_id__c);
34 | Lithium_Revised_ConnectorUtils.sendAPIRequestV1UpdateUser(cm.Lithium_User_Id__c,rolesIDs.get(qualifiedAccounts.get(cm.Account_ID__c).market_segment__c).role_id__c);
35 | }
36 | }
37 | }
38 |
39 | System.debug('___commUsersWithRelatedAccount___'+commUsersWithRelatedAccount);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/src/classes/DiagnosticsInstrumentation.cls:
--------------------------------------------------------------------------------
1 | public without sharing class DiagnosticsInstrumentation {
2 |
3 | //public static Boolean diagnosticsEnabled = true; // Chapter 9
4 | public static Boolean diagnosticsEnabled = AppConfigSupport.diagnosticsEnabled;
5 |
6 | private static List diagnosticLog;
7 | private static Integer currentLevel = 0;
8 |
9 | private static List stackTrace = new List();
10 | public static string exceptionTrace = '';
11 |
12 | private class DiagnosticEntry
13 | {
14 | Integer level;
15 | String description;
16 |
17 | public diagnosticEntry(string entryDescription)
18 | {
19 | level = currentLevel;
20 | description = entryDescription;
21 | }
22 | }
23 |
24 | public static void push(String functionName)
25 | {
26 | debug('Entering: ' + functionName);
27 | currentLevel+=1;
28 | stacktrace.add(functionName);
29 | }
30 |
31 | public static void debug(String debugString)
32 | {
33 | if(!diagnosticsEnabled) return;
34 | if(diagnosticLog==null) diagnosticLog = new List();
35 | diagnosticLog.add(new DiagnosticEntry(debugString));
36 | }
37 |
38 | public static void debugException(Exception ex)
39 | {
40 | String exceptionInfo = 'Exception occurred line ' +
41 | ex.getLineNumber() + ' - ' + ex.getMessage() +
42 | ' stack: ' + ex.getStackTraceString();
43 | debug(exceptionInfo);
44 | DebugInfo__c dbg = new DebugInfo__c(DebugData__c = currentLog());
45 | exceptionTrace = ' Exception occurred line ' +
46 | ex.getLineNumber() + ' - ' + ex.getMessage();
47 | for(String st: stackTrace) exceptionTrace += ' | ' + st;
48 | exceptionTrace += ' |\n ';
49 | if(diagnosticsEnabled) insert dbg;
50 | }
51 |
52 | public static void pop()
53 | {
54 | if(currentLevel>0) currentLevel-=1;
55 | if(currentLevel==0) System.Debug(LoggingLevel.Info,
56 | 'Diagnostic Log\n' + currentLog());
57 | if(stackTrace.size()>0)
58 | stackTrace.remove(stackTrace.size()-1);
59 | }
60 |
61 | public static void popAll()
62 | {
63 | currentLevel=0;
64 | pop();
65 | }
66 |
67 | public static String currentLog()
68 | {
69 | if(diagnosticLog == null) return null;
70 | String spaces = ' ';
71 | String result = '';
72 | for(DiagnosticEntry de: diagnosticLog)
73 | {
74 | Integer endIndex = 3 * de.level;
75 | if(endIndex >= spaces.length()) endIndex = spaces.length()-1;
76 | result += spaces.substring(0,endIndex) + de.description + '\n';
77 | }
78 | return result;
79 | }
80 |
81 |
82 | }
--------------------------------------------------------------------------------
/src/classes/DiagnosticsMain.cls:
--------------------------------------------------------------------------------
1 | public class DiagnosticsMain {
2 |
3 | public interface ITriggerEntry
4 | {
5 | void mainEntry(String triggerObject, Boolean isBefore,
6 | Boolean isDelete, Boolean isAfter, Boolean isInsert,
7 | Boolean isUpdate, Boolean isExecuting,
8 | List newList, Map newMap,
9 | List oldList, Map oldMap);
10 |
11 | void inProgressEntry(String triggerObject, Boolean isBefore,
12 | Boolean isDelete, Boolean isAfter, Boolean isInsert,
13 | Boolean isUpdate, Boolean isExecuting,
14 | List newList, Map newMap,
15 | List oldList, Map oldMap);
16 | }
17 |
18 | public static ITriggerEntry activeFunction = null;
19 |
20 | public static Boolean fakeException = false;
21 |
22 | public static void mainEntry(String triggerObject, Boolean isBefore,
23 | Boolean isDelete, Boolean isAfter, Boolean isInsert,
24 | Boolean isUpdate, Boolean isExecuting,
25 | List newList, Map newMap,
26 | List oldList, Map oldMap)
27 | {
28 | DiagnosticsInstrumentation.push('MainEntry TriggerObject: ' +
29 | triggerObject + ' IsBefore: ' + isBefore + ' IsInsert: ' +
30 | isInsert + ' IsUpdate: ' + isUpdate);
31 | try
32 | {
33 | if(fakeException && activeFunction==null )
34 | activefunction.inProgressEntry(triggerObject, isBefore, isDelete,
35 | isAfter, isInsert, isUpdate, isExecuting,
36 | newList, newMap, oldList, oldMap);
37 |
38 | if(activeFunction != null)
39 | {
40 | activefunction.inProgressEntry(
41 | triggerObject, isBefore, isDelete,
42 | isAfter, isInsert, isUpdate, isExecuting,
43 | newList, newMap, oldList, oldMap);
44 | return;
45 | }
46 |
47 | if(triggerObject == 'Opportunity' && isAfter && isUpdate)
48 | {
49 | activeFunction = new DiagnosticsTriggers1();
50 | activeFunction.mainEntry(triggerObject, isBefore, isDelete,
51 | isAfter, isInsert, isUpdate, isExecuting,
52 | newList, newMap, oldList, oldMap);
53 | }
54 |
55 | if(TriggerObject == 'Opportunity' && isAfter && isUpdate)
56 | {
57 | activeFunction = new DiagnosticsTriggers2();
58 | activefunction.mainEntry(triggerObject, isBefore, isDelete,
59 | isAfter, isInsert, isUpdate, isExecuting,
60 | newList, newMap, oldList, oldMap);
61 | }
62 | diagnosticsInstrumentation.Pop();
63 |
64 | }
65 | catch(Exception ex)
66 | {
67 | diagnosticsInstrumentation.debugException(ex);
68 | diagnosticsInstrumentation.popAll();
69 | }
70 | }
71 | }
--------------------------------------------------------------------------------
/src/classes/SimulatedTranslator.cls:
--------------------------------------------------------------------------------
1 | global class SimulatedTranslator {
2 |
3 |
4 | global class MockTranslator implements HttpCalloutMock
5 | {
6 | global HTTPResponse respond(HTTPRequest req)
7 | {
8 | String requestBody = req.getBody();
9 | HttpResponse res = new HttpResponse();
10 | res.setHeader('Content-Type', 'text');
11 | res.setBody(requestBody + ' in Spanish');
12 | res.setStatusCode(200);
13 | return res;
14 | }
15 | }
16 |
17 | public static HTTPResponse translate(HTTPRequest req)
18 | {
19 | // Replace following with call to actual translation service
20 | //req.setEndpoint('http://api.salesforce.com/foo/bar');
21 |
22 | // Just simulate the call for now - remove this code if you've implemented
23 | // real translation
24 | if(!Test.isRunningTest())
25 | {
26 | // Call the mock translator
27 | //MockTranslator mock = new MockTranslator();
28 | //return mock.respond(req);
29 |
30 | // or, if you enable this endpoint in your security settings, you
31 | // can uncomment these lines and have some fun :-)
32 | String endpoint ='http://isithackday.com/arrpi.php?format=text&text=' + EncodingUtil.urlEncode( req.getBody(),'UTF-8');
33 | req.setBody('');
34 | req.setEndpoint(endpoint);
35 | }
36 | req.setMethod('GET');
37 | Http h = new Http();
38 | HttpResponse res = h.send(req);
39 | return res;
40 | }
41 |
42 | // Note - there is an existing platform bug in which mock callouts fails in
43 | // queueable Apex. We are temporarily bypassing this issue by detecting the
44 | // failure and calling code that simulates the callout directly.
45 | public static String translate(String sourcetext)
46 | {
47 | HttpRequest req = new HttpRequest();
48 | req.setBody(sourcetext);
49 | req.setHeader('Content-Type','text');
50 | HttpResponse result;
51 | try
52 | {
53 | result = translate(req);
54 | } catch(System.CalloutException ex)
55 | {
56 | if (System.isBatch() && Test.isRunningTest() && ex.getMessage()=='Callout loop not allowed')
57 | return translate2(sourceText);
58 | else throw ex;
59 | }
60 | return result.getBody();
61 | }
62 |
63 |
64 | private static Integer callCounter = 0;
65 |
66 | // Workaround for mock Apex issue in queueable
67 | public static String translate2(String sourceText)
68 | {
69 | if(!Test.isRunningTest())
70 | {
71 | return translate(sourcetext);
72 | }
73 | callCounter++;
74 | if(callCounter > Limits.getLimitCallouts())
75 | throw new SimulatedException('Too many simulated callouts');
76 | return sourceText + ' in Spanish';
77 | }
78 |
79 | public class SimulatedException extends Exception{}
80 |
81 | }
--------------------------------------------------------------------------------
/src/classes/Benchmarking.cls:
--------------------------------------------------------------------------------
1 | @isTest
2 | private class Benchmarking {
3 |
4 | @istest
5 | public static void testNewAllocate()
6 | {
7 | for(Integer x = 0; x<10000; x++)
8 | returnNewMap();
9 | }
10 |
11 | private static Map returnNewMap()
12 | {
13 | Map result = new Map();
14 | return result;
15 | }
16 |
17 | @istest
18 | public static void testSorts()
19 | {
20 | List unsortedData = new List();
21 | for(Integer x = 0; x<500; x++)
22 | {
23 | unsortedData.add(x); unsortedData.add(x+500);
24 | }
25 | for(Integer x = 0; x< 10000; x++)
26 | {
27 | returnSorted(unsortedData);
28 | }
29 |
30 | }
31 |
32 | private static List returnSorted(List inputList)
33 | {
34 | List sortedList1 = inputList.clone();
35 | sortedList1.sort();
36 | return sortedList1;
37 | }
38 |
39 |
40 | @istest
41 | public static void testProperties()
42 | {
43 | Lead ld = new Lead(LastName ='test', Email = 'someone@myemail.com');
44 | for(Integer x = 0; x< 10000; x++)
45 | {
46 | checkForSpam(ld);
47 | }
48 | for(Integer x = 0; x< 10000; x++)
49 | {
50 | checkForSpam2(ld);
51 | }
52 | for(Integer x = 0; x< 10000; x++)
53 | {
54 | checkForSpam3(ld);
55 | }
56 |
57 | }
58 |
59 | private static Boolean checkForSpam(Lead ld)
60 | {
61 | if(ld.Email == null) return false;
62 | if(ld.Email.endsWithIgnoreCase('@yahoo.com')) return true;
63 | if(ld.Email.endsWithIgnoreCase('@gmail.com')) return true;
64 | if(ld.Email.endsWithIgnoreCase('@hotmail.com')) return true;
65 | return false;
66 | }
67 |
68 | private static Boolean checkForSpam2(Lead ld)
69 | {
70 | String testEmail = ld.Email;
71 | if(testEmail == null) return false;
72 | if(testEmail.endsWithIgnoreCase('@yahoo.com')) return true;
73 | if(testEmail.endsWithIgnoreCase('@gmail.com')) return true;
74 | if(testEmail.endsWithIgnoreCase('@hotmail.com')) return true;
75 | return false;
76 | }
77 |
78 | private static Boolean checkForSpam3(Lead ld)
79 | {
80 | String testEmail = ld.Email;
81 | if(testEmail == null) return false;
82 | testEmail = testEmail.toLowerCase();
83 | if(testEmail.endsWith('@yahoo.com')) return true;
84 | if(testEmail.endsWith('@gmail.com')) return true;
85 | if(testEmail.endsWith('@hotmail.com')) return true;
86 | return false;
87 | }
88 |
89 | }
--------------------------------------------------------------------------------
/src/classes/TestForPackages.cls:
--------------------------------------------------------------------------------
1 | @istest(seealldata = true)
2 | public class TestForPackages {
3 |
4 | static testMethod void recordTypeTest() {
5 | // This will fail to work on any org that doesn't have record types defined on leads
6 | // List rtypes = [Select ID, RecordTypeID from Lead Limit 1];
7 |
8 | Boolean leadHasRecordType =
9 | Schema.Sobjecttype.Lead.Fields.getMap().containskey('recordtypeid');
10 |
11 | String fieldString = 'ID ';
12 | if(leadHasRecordType) fieldString += ', RecordTypeID ';
13 | List rtypes =
14 | Database.Query('Select ' + fieldstring + ' from Lead Limit 1');
15 | if(rtypes.size()>0 && leadHasRecordType)
16 | {
17 | system.debug(rtypes[0].get('RecordTypeID'));
18 | }
19 | system.debug(fieldString + ' ' + rtypes);
20 | }
21 |
22 | static testMethod void addProduct()
23 | {
24 | // Adding this line adds a Product2 dependency to the package
25 | //List aproduct = [Select ID from Product2 Limit 1];
26 | }
27 |
28 | static testmethod void testPersonAccount()
29 | {
30 | PersonAccountSupport.isPersonAccountOrg();
31 | }
32 |
33 | static testmethod void testCorporateCurrency()
34 | {
35 | String corporate = corporateCurrency;
36 | }
37 |
38 | private static Map
39 | cachedCurrencyConversionMap = null;
40 |
41 | private static string m_CorporateCurrency = null;
42 |
43 | public static string corporateCurrency {
44 | get {
45 | getCurrencyConversionMap();
46 | return corporateCurrency;
47 | }
48 | }
49 |
50 | public static Map getCurrencyConversionMap()
51 | {
52 | Boolean currencyTestMode = false;
53 |
54 | if(cachedCurrencyConversionMap!=null)
55 | return cachedCurrencyConversionMap;
56 |
57 | if(Test.isRunningTest() &&
58 | !userinfo.isMultiCurrencyOrganization())
59 | currencyTestMode = true;
60 | if(!userinfo.isMultiCurrencyOrganization() &&
61 | !currencyTestMode) return null;
62 |
63 | List ctypes = null;
64 | if(!currencyTestMode) ctypes =
65 | database.query('Select conversionrate, isocode, iscorporate from currencytype');
66 |
67 | Map isoMap = new Map();
68 | if(!currencyTestMode)
69 | {
70 | for(SObject ct: ctypes)
71 | {
72 | string ctCode = string.ValueOf(ct.get('isocode'));
73 | if(Boolean.valueOf(ct.get('iscorporate')))
74 | {
75 | m_CorporateCurrency = ctCode;
76 | }
77 | double conversionRate = double.valueOf(ct.get('conversionrate'));
78 | if(conversionRate!=0) isoMap.put(ctcode, 1/conversionRate);
79 | }
80 | }
81 | cachedCurrencyConversionMap = (currencyTestMode)? null: isoMap;
82 | return cachedCurrencyConversionMap;
83 | }
84 | }
--------------------------------------------------------------------------------
/src/classes/TriggerArchitectureClass2.cls:
--------------------------------------------------------------------------------
1 | public class TriggerArchitectureClass2 implements TriggerArchitectureMain1.ITriggerEntry {
2 |
3 | public static void entry1(List newlist,
4 | Map newMap, List oldList,
5 | Map oldMap, Map objectsToUpdate)
6 | {
7 | // Do some processing here
8 | // Add entries to the objectstoupdate map if they need to be updated
9 | }
10 |
11 |
12 | public static void entry2(List newList,
13 | Map newMap, List oldList,
14 | Map oldMap)
15 | {
16 | // Do some processing here
17 | // Add entries to the dispatcher static variable
18 | // if they need to be updated
19 | }
20 |
21 | public static void entry3(List newList,
22 | Map newMap, List oldList,
23 | Map oldMap)
24 | {
25 | // Do some processing here
26 | // Add entries to the dispatcher static variable if they need to be updated
27 | // Can examine the TriggerArchitectureMain1.inClass2 static variable to
28 | // modify behavior based on the knowledge of reentrancy
29 | }
30 |
31 | public void mainEntry(String triggerObject, Boolean isBefore,
32 | Boolean isDelete, Boolean isAfter, Boolean isInsert,
33 | Boolean isUpdate, Boolean isExecuting,
34 | List newList, Map newMap,
35 | List oldList, Map oldMap)
36 | {
37 | List opNewList = (List)newList;
38 | List opOldList = (List)oldList;
39 | Map opNewMap = (Map)newMap;
40 | Map opOldMap = (Map)oldMap;
41 |
42 | // Do some processing here
43 | // Add entries to the dispatcher static variable
44 | //if they need to be updated or do direct DML
45 |
46 | }
47 |
48 | public void inProgressEntry(String triggerObject, Boolean isBefore,
49 | Boolean isDelete, Boolean isAfter, Boolean isInsert,
50 | Boolean isUpdate, Boolean isExecuting,
51 | List newList, Map newMap,
52 | List oldList, Map oldMap)
53 | {
54 | // Be sure to detect for the objects you actually want to handle.
55 | // Can dispatch to other classes is necessary
56 |
57 | // Here's an example:
58 |
59 | if(TriggerObject == 'Opportunity' && IsAfter)
60 | {
61 | TriggerArchitectureMain1.activeFunction = new TriggerArchitectureClass1();
62 | TriggerArchitectureMain1.activeFunction.mainEntry(
63 | triggerObject, isBefore, isDelete, isAfter, isInsert, isUpdate, isExecuting,
64 | newList, newMap, oldList, oldMap);
65 | TriggerArchitectureMain1.activeFunction = this;
66 | }
67 | }
68 |
69 | }
--------------------------------------------------------------------------------
/src/objects/DebugInfo__c.object:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Accept
5 | Default
6 |
7 |
8 | CancelEdit
9 | Default
10 |
11 |
12 | Clone
13 | Default
14 |
15 |
16 | Delete
17 | Default
18 |
19 |
20 | Edit
21 | Default
22 |
23 |
24 | Follow
25 | Default
26 |
27 |
28 | List
29 | Default
30 |
31 |
32 | New
33 | Default
34 |
35 |
36 | SaveEdit
37 | Default
38 |
39 |
40 | Tab
41 | Default
42 |
43 |
44 | View
45 | Default
46 |
47 | SYSTEM
48 | Deployed
49 | Debug Logs
50 | true
51 | true
52 | false
53 | false
54 | true
55 | true
56 | true
57 |
58 | DebugData__c
59 | Debug data entry
60 | false
61 |
62 | 131072
63 | false
64 | LongTextArea
65 | 3
66 |
67 |
68 |
69 | All
70 | Everything
71 |
72 |
73 |
74 | DBG-{0000}
75 |
76 | AutoNumber
77 |
78 | DebugInfos
79 |
80 | ReadWrite
81 |
82 |
--------------------------------------------------------------------------------
/src/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AppConfigSupport
5 | Benchmarking
6 | BulkPatternBatch
7 | Concurrency1
8 | DiagnosticsInstrumentation
9 | DiagnosticsMain
10 | DiagnosticsTriggers1
11 | DiagnosticsTriggers2
12 | FunWithCollections
13 | GoingAsync1
14 | GoingAsync2
15 | GoingAsync3
16 | GoingAsync4
17 | GoingAsync5
18 | PersonAccountSupport
19 | ScheduledDispatcher2
20 | SimulatedTranslator
21 | SomeFutureOperations
22 | TestBulkPatterns
23 | TestDiagnostics1
24 | TestDiagnostics2
25 | TestForPackages
26 | TestGoingAsync
27 | TestHeapAndSOQL
28 | TestPersonAccount
29 | TestThinkingInApex
30 | TestThinkingInApexLimits
31 | TestTriggersExample
32 | ThinkingInApex
33 | ThinkingInApexBulkPatterns
34 | TriggerArchitectureClass1
35 | TriggerArchitectureClass2
36 | TriggerArchitectureMain1
37 | TriggersExample
38 | ApexClass
39 |
40 |
41 | OnAccount1
42 | OnAsyncRequestInsert
43 | OnContact1
44 | OnOpportunity1
45 | OnOpportunity2
46 | OnOpportunity3
47 | SolutionTrigger1
48 | SolutionTrigger2
49 | ApexTrigger
50 |
51 |
52 | Contact.Level2__c
53 | Opportunity.TestCounterAmount__c
54 | Solution.SolutionSpanish__c
55 | Solution.TranslationPending__c
56 | CustomField
57 |
58 |
59 | *
60 | CustomObject
61 |
62 |
63 | *
64 | StaticResource
65 |
66 |
67 | Opportunity.Enforce_Tracking_Number
68 | ValidationRule
69 |
70 | 33.0
71 |
72 |
--------------------------------------------------------------------------------
/src/classes/TriggerArchitectureMain1.cls:
--------------------------------------------------------------------------------
1 | public class TriggerArchitectureMain1 {
2 |
3 | public static Map opsToUpdate = new Map();
4 |
5 | public static void entry2(List newList,
6 | Map newMap, List oldList,
7 | Map oldMap)
8 | {
9 | TriggerArchitectureClass1.entry2(newList, newMap, oldList, oldMap);
10 | TriggerArchitectureClass2.entry2(newList, newMap, oldList, oldMap);
11 | if(opsToUpdate.size()>0) update opsToUpdate.values();
12 | }
13 |
14 | public static Boolean inClass1 = false;
15 | public static Boolean inClass2 = false;
16 |
17 | public static void entry3(List newList,
18 | Map newMap, List oldList,
19 | Map oldMap)
20 | {
21 | if(!inClass1)
22 | {
23 | inClass1= true;
24 | TriggerArchitectureClass1.entry3(newList, newMap, oldList, oldMap);
25 | inClass1 = false;
26 | }
27 | inClass2 = true;
28 | TriggerArchitectureClass2.entry3(newList, newMap, oldList, oldMap);
29 | inClass2 = false;
30 | if(opsToUpdate.size()>0) update opsToUpdate.values();
31 | }
32 |
33 |
34 | public interface ITriggerEntry
35 | {
36 | void mainEntry(String triggerObject, Boolean isBefore,
37 | Boolean isDelete, Boolean isAfter,
38 | Boolean isInsert, Boolean isUpdate,
39 | Boolean isExecuting,
40 | List newList, Map newMap,
41 | List oldList, Map oldMap);
42 | void inProgressEntry(String triggerObject, Boolean isBefore,
43 | Boolean isDelete, Boolean isAfter,
44 | Boolean isInsert, Boolean isUpdate,
45 | Boolean isExecuting, List newList,
46 | Map newMap,
47 | List oldList, Map oldMap);
48 | }
49 |
50 | public static ITriggerEntry activeFunction = null;
51 |
52 | public static void entry4(String triggerObject, Boolean isBefore,
53 | Boolean isDelete, Boolean isAfter,
54 | Boolean isInsert, Boolean isUpdate,
55 | Boolean isExecuting, List newList,
56 | Map newMap, List oldList,
57 | Map oldMap)
58 | {
59 | if(activeFunction != null)
60 | {
61 | activeFunction.inProgressEntry(triggerObject, isBefore,
62 | isDelete, isAfter, isInsert, isUpdate, isExecuting,
63 | newList, newMap, oldList, oldMap);
64 | return;
65 | }
66 |
67 | if(triggerObject == 'Opportunity' && isAfter && isUpdate)
68 | {
69 | activeFunction = new TriggerArchitectureClass1();
70 | activeFunction.mainEntry(triggerObject,
71 | isBefore, isDelete, isAfter, isInsert, isUpdate, isExecuting,
72 | newList, newMap, oldList, oldMap);
73 |
74 | activeFunction = new TriggerArchitectureClass2();
75 | activeFunction.mainEntry(triggerObject,
76 | isBefore, isDelete, isAfter, isInsert, isUpdate, isExecuting,
77 | newList, newMap, oldList, oldMap);
78 |
79 | if(opstoupdate.size()>0) update opsToUpdate.values();
80 | activeFunction = null;
81 | }
82 | }
83 |
84 |
85 |
86 | }
--------------------------------------------------------------------------------
/src/classes/PersonAccountSupport.cls:
--------------------------------------------------------------------------------
1 | public class PersonAccountSupport {
2 |
3 | @TestVisible public static Boolean fakePersonAccountDuringTest = false;
4 |
5 | private static Set accountFields = null;
6 |
7 | public static Boolean isPersonAccountOrg()
8 | {
9 | if(accountFields==null) accountFields =
10 | Schema.Sobjecttype.Account.fields.getMap().keyset();
11 | return AccountFields.contains('personcontactid');
12 | }
13 |
14 | // Map from contact field to account field
15 | public static String getPersonAccountAlias(String fieldName)
16 | {
17 | fieldName = fieldname.toLowerCase(); // Case insensitive
18 |
19 | // Unchanged - FirstName, LastName, etc.
20 | if(accountFields.contains(fieldName)) return fieldName;
21 |
22 | // Replace aliased __c with __pc
23 | fieldName = fieldName.replace('__c', '__pc');
24 | if(accountFields.contains(fieldName)) return fieldname;
25 |
26 | if(accountFields.contains('person' + fieldName))
27 | return ('person' + fieldName);
28 |
29 | return null;
30 | }
31 |
32 | public static void processContactTrigger1(
33 | Boolean isBefore, List newList, Map oldMap)
34 | {
35 | for(Contact ct: newList)
36 | {
37 | if(ct.LeadSource=='Web' || ct.LeadSource=='Phone Inquiry')
38 | ct.Level2__c = 'Primary';
39 | else ct.Level2__c = 'Secondary';
40 | }
41 | }
42 |
43 | public static List fakePersonContactIDs = null;
44 |
45 | private static Boolean updatingPersonContact = false;
46 |
47 | public static void processAccountTrigger1(
48 | Boolean isBefore, List newList, Map oldMap)
49 | {
50 | if(!isPersonAccountOrg() && !fakePersonAccountDuringTest ||
51 | updatingPersonContact) return;
52 |
53 | if(isBefore)
54 | {
55 | // Using before approach
56 | String leadSourceAlias = getPersonAccountAlias('LeadSource');
57 | String levelAlias = getPersonAccountAlias('Level2__c');
58 | for(Account act: newList)
59 | {
60 | if(leadSourceAlias!=null && levelAlias!=null &&
61 | (!fakePersonAccountDuringTest && act.get('PersonContactID')!=null))
62 | { // Will only be valid on person accounts
63 | if(act.get(leadSourceAlias)=='Web' ||
64 | act.get(leadSourceAlias)=='Phone Inquiry')
65 | act.put(levelAlias,'Primary');
66 | else act.put(levelAlias,'Secondary');
67 | }
68 | }
69 | }
70 | else
71 | { // Better approach can work on after trigger
72 | Set personContactIds = new Set();
73 | for(Integer x = 0; x personContacts =
84 | new Map(
85 | [Select ID, LeadSource, Level2__c
86 | from Contact where ID in :personContactIds]);
87 | processContactTrigger1(true,
88 | personcontacts.values(), personcontacts);
89 | updatingPersonContact = true;
90 | update personcontacts.values();
91 | updatingPersonContact = false;
92 | }
93 |
94 |
95 | }
96 |
97 | }
--------------------------------------------------------------------------------
/src/classes/TestThinkingInApexLimits.cls:
--------------------------------------------------------------------------------
1 | @istest
2 | public class TestThinkingInApexLimits {
3 |
4 | // Demonstration of using a single query for an object and related object to reduce SOQL calls
5 | // First examples shows a straightforward approach:
6 |
7 | static testMethod void testContactsWithAccountRevenue1() {
8 | // Set up a dummy account and contact
9 | Account newact = new Account(Name = 'testaccount');
10 | insert newact;
11 | Contact newct = new Contact(LastName = 'testcontactln');
12 | newct.AccountId = newact.id;
13 | insert newct;
14 |
15 | Test.startTest();
16 |
17 | // Query for contact info
18 | List cts = [SELECT ID, AccountID from Contact
19 | where Name = 'testcontactln'];
20 |
21 | // Some code that operates on the contacts here....
22 |
23 | // Get list of account IDs.
24 | Set accountIds = new Set();
25 | for(Contact ct: cts)
26 | if(ct.AccountID!=null) accountIds.add(ct.AccountID);
27 |
28 | if(accountIds.size()>0)
29 | {
30 | List accounts = [Select ID, AnnualRevenue from Account
31 | where ID in :accountids];
32 | for(Account accountfound: accounts)
33 | if(accountfound.AnnualRevenue == null)
34 | accountfound.AnnualRevenue = 500;
35 | update accounts;
36 | }
37 |
38 | Test.stopTest();
39 |
40 | // Make sure it worked
41 | if(accountIds.size()>0)
42 | {
43 | List accounts2 = [Select ID, AnnualRevenue from Account where ID in :accountids];
44 | for(Account accountFound: accounts2) system.assertEquals(500, accountFound.AnnualRevenue);
45 | }
46 |
47 |
48 | }
49 |
50 | // Second example shows how you can use a related query
51 | static testMethod void testContactsWithAccountRevenue2() {
52 | // Set up a dummy account and contact
53 | Account newact = new Account(Name = 'testaccount');
54 | insert newact;
55 | Contact newct = new Contact(LastName = 'testcontactln');
56 | newct.AccountId = newact.id;
57 | insert newct;
58 |
59 | Test.startTest();
60 |
61 | // Query for contact info and annual revenue on
62 | // account in a single query
63 | List cts = [SELECT ID, AccountID, Account.ID,
64 | Account.AnnualRevenue from Contact
65 | where Name = 'testcontactln'];
66 |
67 | // Some code that operates on the contacts here....
68 |
69 | Map accountsToUpdate = new Map();
70 |
71 | for(Contact ct: cts)
72 | {
73 | if (ct.Account.AnnualRevenue == null)
74 | {
75 | ct.Account.AnnualRevenue = 500;
76 | accountsToUpdate.put(ct.AccountID, ct.Account);
77 | }
78 | }
79 |
80 | if(accountsToUpdate.size()>0)
81 | update accountsToUpdate.values();
82 |
83 | Test.stopTest();
84 |
85 | // Make sure it worked
86 | if(accountsToUpdate.size()>0)
87 | {
88 | List accounts2 = [Select ID, AnnualRevenue from Account where ID in :accountstoupdate.keyset()];
89 | for(Account accountFound: accounts2) system.assertEquals(500, accountFound.AnnualRevenue);
90 | }
91 |
92 |
93 | }
94 |
95 | }
--------------------------------------------------------------------------------
/src/classes/Concurrency1.cls:
--------------------------------------------------------------------------------
1 | public class Concurrency1 {
2 |
3 | public static void delay(Integer seconds)
4 | {
5 | List largeArray = new List();
6 | for(Integer x =0; x<10000; x++) largeArray.add(x);
7 | for(Integer counter = 0; counter0) delay(delayBefore);
22 | List ops =
23 | [Select ID, Amount From Opportunity
24 | where Name = :opportunityName];
25 | for(Opportunity op: ops)
26 | op.Amount = (op.Amount==null)?
27 | amount: op.Amount + Amount;
28 | if(delayFromQuery>0) delay(delayFromQuery);
29 | update ops;
30 | if(delayAfter>0) delay(delayAfter);
31 | }
32 |
33 | @future
34 | public static void incrementPessimistic(
35 | double amount, Integer delayBefore,
36 | Integer delayFromQuery, Integer delayAfter)
37 | {
38 | if(DelayBefore>0) delay(delayBefore);
39 | List ops =
40 | [Select ID, Amount From Opportunity
41 | where Name = :opportunityName For Update];
42 | for(Opportunity op: ops)
43 | op.Amount = (op.Amount==null)?
44 | amount: op.Amount + Amount;
45 | if(delayFromQuery>0) delay(delayFromQuery);
46 | update ops;
47 | if(delayAfter>0) delay(delayAfter);
48 | }
49 |
50 |
51 |
52 | @future
53 | public static void incrementOptimisticWithCapture(
54 | double amount, Integer delayBefore,
55 | Integer delayFromQuery, Integer delayAfter)
56 | {
57 | if(delayBefore>0) delay(delayBefore);
58 | List ops =
59 | [Select ID, Amount From Opportunity
60 | where Name = :opportunityName];
61 | for(Opportunity op: ops)
62 | op.Amount = (op.Amount==null)?
63 | amount: op.Amount + Amount;
64 | if(delayFromQuery>0) delay(delayFromQuery);
65 | List
66 | dmlResults = Database.Update(ops, false);
67 | List failedUpdates = new List();
68 | for(Integer x = 0; x< ops.size(); x++)
69 | {
70 | Database.SaveResult sr = dmlResults[x];
71 | if(!sr.isSuccess())
72 | {
73 | for(Database.Error err: sr.getErrors())
74 | {
75 | if(err.getStatusCode() == StatusCode.UNABLE_TO_LOCK_ROW)
76 | {
77 | failedUpdates.add(ops[x]);
78 | break;
79 | }
80 | }
81 | }
82 |
83 | }
84 |
85 | if(failedUpdates.size()>0)
86 | {
87 | // Do a logging or recovery operation here
88 | recordRecoveryInformation(failedUpdates, amount);
89 | }
90 |
91 | if(delayAfter>0) delay(delayAfter);
92 | }
93 |
94 | @testvisible
95 | private static void recordRecoveryInformation(
96 | List failedOps, double amount)
97 | {
98 | List