Before we begin discussing on this related list, it is
important to understand that Notes and Attachments are two separate object
‘Note’ and ‘Attachment’. You could check this out in Workbench or any Force IDE
tools.
Though Salesforce uses
NotesAndAttachment but it is read-only object contains all notes and
attachments associated with an object.
Notes and Attachments are available for Standard
Controller by default and when we create a custom object than in that case you
have to click on the checkbox to make it available.
Once this is done you can use it in any object by adding
it in a Page Layout related list. This is a basic functional Idea of this
object.
Customization:-
As we know that most of the objects in Salesforce can’t
be always used in the way it is designed. So in some cases we need to customize
it and use it the way we want to.
First way would be to display the section without using
it in a related list tab in a Visual Force page so that you could add your own
buttons and links.
For this simply create a Page Block table and use it in
related lists.
VF Page related list looks like:-
Sample Code:-
<apex:page
standardController="Account">
<apex:form >
<apex:pageblock title="Notes and
Attachments" >
<apex:pageBlockTable
Value="{!Account.NotesAndAttachments}" var="item"
columns="4" >
<apex:column
HeaderValue="Title" >
<apex:outputLink
value="/{!item.id}" id="the_link"
rendered="{!NOT(Contains(item.Title,'IN_'))}">
<apex:outputField value="{!item.Title}" />
<apex:outputField value="{!item.Title}" />
</apex:outputLink>
</apex:column>
<apex:column
HeaderValue="Last Modified Date" >
<apex:outputField value="{!item.LastModifiedDate }"
/>
</apex:column>
<apex:column
HeaderValue="Created By" >
<apex:outputField value="{!item.Createdbyid }"
/>
</apex:column>
</apex:pageBlockTable>
</apex:pageblock>
</apex:form>
</apex:page>
This was one of the way to use Notes and Attachments.
Let’s suppose there is a requirement when a user should
not be allowed to Edit/delete/create new notes and attachment based on the
opportunity stage value.
Let’s take Notes first:- It is nothing but a text
associated with a custom object or any standard objects created in Salesforce.
Attachment: - It is a file which you would like to be
associated with any Standard object.
So where do we write these triggers because they are standard
object yet it is not displayed in the list of Standard Objects.
Even I had to look for it and find how to get it done.
Here is the solution, first thing you could use Force.com
IDE there you can access the objects (Note/Attachment) directly and then write
a trigger on the same. But what if you want to add the trigger on the
Salesforce org itself. Well! For that you would need to use any custom objects
and click on new trigger.
Once that is done, You could easily paste the code
directly and it should work fine. Which means replace the object name in the
syntax and it should work.
Code Sample:-
trigger DisablelinksonAttacments on Attachment(Before
insert,before update,before delete) {
//List<Attachment> atts = Trigger.new;
List<Opportunity>
opp = new List<Opportunity>();
List<Id> OppIds = new List<Id>();
String
oppKeyPrefix = Opportunity.sObjectType.getDescribe().getKeyPrefix();
List<Opportunity> oppRecs = new List<Opportunity>();
Map<Id,String> oppByStage = new Map<Id,String>();
if
(Trigger.isDelete) {
// FOR
Delete
// Get
all the parent Ids from the attachment for Opportunity
for(Attachment atItem: Trigger.old) {
String ParentId = atItem.ParentId;
if(ParentId.startsWith(oppKeyPrefix))
{
OppIds.add(ParentId);
}
}
} else { //
FOR Insert and Update
// Get
all the parent Ids from the attachment for Opportunity
for(Attachment atItem: Trigger.new) {
String ParentId =
atItem.ParentId;
if(ParentId.startsWith(oppKeyPrefix)) {
OppIds.add(ParentId);
}
}
}
If
(OppIds.size() > 0) {
oppRecs
= [select Id,StageName from opportunity where id in: OppIds];
for(Opportunity o:oppRecs)
{
oppByStage.put(o.id, o.StageName);
}
}
if
(Trigger.isDelete) {
// FOR
Delete
for(Attachment a:Trigger.old){
if (oppByStage.containsKey(a.ParentId)
)
if (oppByStage.get(a.ParentId) == 'Closed Lost') {
a.addError('Opportunity has been Lost. Modification not allowed!');
}
}
} else {
// FOR
Insert and Update
for(Attachment a:Trigger.new){
if
(oppByStage.containsKey(a.ParentId) )
if (oppByStage.get(a.ParentId) == 'Closed Lost') {
a.addError('Opportunity has been Lost. Modification not allowed!');
}
}
}
}
You can use the same code for Notes as well, by simply
replacing the word Attachment as Note and doing some minor changes of
Variables.
I hope this helps you in your understanding of these
objects.
Feel free to write in at Forced2code@gmail.com for your views
and suggestion.