Discussions
- General Development
- Schema Development
- Apex Code Development
- Visualforce Development
- Formulas & Validation Rules
- Security
- Mobile
- Force.com Sites & Site.com
- Chatter Development
- Java Development
- .NET Development
- Perl, PHP, Python & Ruby
- Desktop Integration
- APIs and Integrations
- Visual Workflow
- Apple, Mac and OS X
- VB and Office Development
- AppExchange Directory & Packaging
- Salesforce Labs & Open Source Projects
- Other Salesforce Applications
- Jobs Board
- Force.com Discussion Boards
- :
- Developer Boards for Force.com and Database.com
- :
- Apex Code Development
- :
- Advanced Admin moving into development needs code ...
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic to the Top
- Bookmark
- Subscribe
- Printer Friendly Page
Advanced Admin moving into developmen t needs code review and feedback Please???
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
11-15-2012 10:40 AM
trigger CaseCloseNoOpen on Case (Before update)
{
List<Id> caseIds = new List<Id>();
Id caseRecordTypeId = [SELECT Id FROM RecordType WHERE Name = 'PM Case' AND SObjectType = 'Case'].Id;
Id TaskRecordTypeId = [SELECT Id FROM RecordType WHERE Name = 'PM Task' AND SObjectType = 'Task'].Id;
for(Case c : Trigger.New)
{
if(c.RecordTypeId == caseRecordTypeId && (c.Status == 'Completed' || c.Status == 'Closed'))
{
caseIds.add(c.Id);
}
}
for(Training_Information__c customobj : [Select Id, Status__c,Case__c From Training_Information__c Where Case__c in: caseIds])
{
if(customobj.Status__c == 'Pending' || customobj.Status__c == 'Scheduled')
{
Trigger.newMap.get(customobj.Case__c).addError('Tr aining has not been completed.');
}
}
for(Development_Request__c customobj : [Select Id, Stage__c,Case__c From Development_Request__c Where Case__c in: caseIds])
{
if(customobj.Stage__c != 'Completed' && customobj.Stage__c != 'Cancelled DR/ VOID' && customobj.Stage__c != 'Draft')
{
Trigger.newMap.get(customobj.Case__c).addError('Th ere are open Development Request associated with this Case.');
}
}
for(Task T : [Select Id, Status, WhatId, RecordTypeId From Task Where WhatId in: caseIds])
{
if(T.RecordTypeId == TaskRecordTypeId && (T.Status != 'Completed' && T.Status != 'Discarded'))
{
Trigger.newMap.get(T.WhatId).addError('There are still open PM Task on this Case.');
}
}
}This code works, but it is one of my first triggers. The idea of the trigger is to validate across lookup relationships between a case tha is related to project manager, development request, Training Information, and project management task. The end goal is to keep a PM from closing a case where there is uncompleted Training Information, uncompleted PM task, or uncompleted Development Request.
That said, I have to ask would this be better done in a single trigger like above or in a trigger and class format?
What is the benefit of doing something like this in a trigger and class approach if that is the suggested method?
How does either approach affect test coverage?
Thank you,
Steve Laycock
Certified Administrator, Certified Advanced Administrator, Beginning Developer Certs. Currently
Solved! Go to Solution.
Re: Advanced Admin moving into developmen t needs code review and feedback Please???
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
11-20-2012 06:14 PM
Steve:
The code you posted is typical of one's first trigger and is properly bulkified. Your question is more about logic in Trigger vs logic in classes.
Personally, my systems have lots of logic (and it is added to over time) so I adopted this pattern: http://developer.force.com/cookbook/recipe/trigger
It is good to have just a single trigger for an Sobject X because if you have multiple ones, their order of execution is not guaranteed.
Another very good pattern to use can be found here: http://advancedapex.com/ (you have to buy the book but it is well worth it)
Re: Advanced Admin moving into developmen t needs code review and feedback Please???
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
11-21-2012 08:25 AM
What do you think of this?
trigger CaseTrigger on Case (before update,before insert,before delete, after update, after insert, after delete)
{
Profile p = [SELECT Name FROM Profile WHERE ID =:UserInfo.getProfileId()];
if(p.Name != 'System Administrator')
{
if (Trigger.isInsert && Trigger.isbefore)
{
}
if (Trigger.isUpdate && Trigger.isbefore)
{
CaseFunctions.CaseValidationBeforeComplete(Trigger .oldMap, Trigger.newMap);
}
if (Trigger.isDelete && Trigger.isbefore)
{
}
if (Trigger.isInsert && Trigger.isafter)
{
}
if (Trigger.isUpdate && Trigger.isafter)
{
}
if (Trigger.isDelete && Trigger.isafter)
{
}
}
}
public class CaseFunctions
{
public static void CaseValidationBeforeComplete(Map<Id,Case> oldMap, Map<Id,Case> newMap)
{
List<Id> caseIds = new List<Id>();
//Possibly moving the next two statements to two static method map
Id caseRecordTypeId = [SELECT Id FROM RecordType WHERE Name = 'PM Case' AND SObjectType = 'Case'].Id;
Id taskRecordTypeId = [SELECT Id FROM RecordType WHERE Name = 'PM Task' AND SObjectType = 'Task'].Id;
for (Case c : newMap.Values()){
if(c.RecordTypeId == caseRecordTypeId && (c.Status == 'Completed' || c.Status == 'Closed'))
{
caseIds.add(c.Id);
}
}
for(Training_Information__c customobj : [Select Id, Status__c,Case__c From Training_Information__c Where Case__c in: caseIds])
{
if(customobj.Status__c == 'Pending' || customobj.Status__c == 'Scheduled')
{
newMap.get(customobj.Case__c).addError('Training has not been completed.');
}
}
for(Development_Request__c customobj : [Select Id, Stage__c,Case__c From Development_Request__c Where Case__c in: caseIds])
{
if(customobj.Stage__c != 'Completed' && customobj.Stage__c != 'Cancelled DR/ VOID' && customobj.Stage__c != 'Draft')
{
newMap.get(customobj.Case__c).addError('There are open Development Request associated with this Case.');
}
}
for(Task T : [Select Id, Status, WhatId, RecordTypeId From Task Where WhatId in: caseIds])
{
if(T.RecordTypeId == taskRecordTypeId && (T.Status != 'Completed' && T.Status != 'Discarded'))
{
newMap.get(T.WhatId).addError('There are still open PM Task on this Case.');
}
}
}
}
Thanks,
Steve Laycock
Certified Administrator, Certified Advanced Administrator, Beginning Developer Certs. Currently
Re: Advanced Admin moving into developmen t needs code review and feedback Please???
- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content
11-21-2012 05:25 PM
Steve
Well, this is a step in the right direction and reminds me of what I did initially many years back.
Over time, you're going to come to dislike using static methods to operate on SObjects and you're going to want to do everything with objects and methods on objects; leaving static methods for Utility operations
The gestalt of using the SFDC APEX language, which you can see from numerous SFDC examples in the doc, on blogs, etc. is objects and methods on those objects; not static 'subroutines'. You will also be encapsulating your operations more so that you're operating on single instances of an SObject when deciding if it is eligible for something (invalid, needing a changed value, etc.) and you let callers work through Triggered lists.
BTW -- You might want to consider abstracting away the 'don't execute if sysad' condition by using a static class variable in some static method Singleton class:
Code a method MySingletonClass.isImmuneFromValidationChecks()
The method does the SOQL query on Profile just once, storing the result in a static class variable within MySingletonClass. This way, if you have triggers on SObject X that cause downstream updates on SObject Y (that in turn have triggers) (or workflows fire that re-trigger SObject X -- you dont run out of SOQL calls.
Here's a sort-of-related example - http://corycowgill.blogspot.com/2010/12/salesforce
and another one - http://richardvanhook.com/2010/11/26/template-for-

