Salesforce introduced Files related list in Winter’16, and now Salesforce is going to replace Notes and Attachment section with Files. Basically, Files that you upload to the Notes & Attachments related list on records in Salesforce Classic are now Salesforce Files objects, rather than the old attachment objects.
Sometimes you may have requirement to move attachment documents to file using apex. Before creating Files in Salesforce you have to understand the Object relationship. Here is an example to create File from Attachment using apex.
ContentDocument: This object record you don’t have to create. It gets created when you create ContentVersion which is the child of ContentDocument.
ContentVersion: This object stores document information similar like Attachment.
ContentDocumentLink: This object will share the files with Users, Records, Groups etc. You can create multiple records to attach the same files under multiple records.
Sample Code:
//Get attachment
Attachment attach = [SELECT Id, Name, Body, ContentType, ParentId From Attachment LIMIT 1];
//Insert ContentVersion
ContentVersion cVersion = new ContentVersion();
cVersion.ContentLocation = 'S'; //S-Document is in Salesforce. E-Document is outside of Salesforce. L-Document is on a Social Netork.
cVersion.PathOnClient = attach.Name;//File name with extention
cVersion.Origin = 'H';//C-Content Origin. H-Chatter Origin.
cVersion.OwnerId = attach.OwnerId;//Owner of the file
cVersion.Title = attach.Name;//Name of the file
cVersion.VersionData = attach.Body;//File content
Insert cVersion;
//After saved the Content Verison, get the ContentDocumentId
Id conDocument = [SELECT ContentDocumentId FROM ContentVersion WHERE Id =:cVersion.Id].ContentDocumentId;
//Insert ContentDocumentLink
ContentDocumentLink cDocLink = new ContentDocumentLink();
cDocLink.ContentDocumentId = conDocument;//Add ContentDocumentId
cDocLink.LinkedEntityId = attach.ParentId;//Add attachment parentId
cDocLink.ShareType = 'I';//V - Viewer permission. C - Collaborator permission. I - Inferred permission.
cDocLink.Visibility = 'InternalUsers';//AllUsers, InternalUsers, SharedUsers
Insert cDocLink;
Here I’ve a custom “Student__c” object. There is a validation rule on “Date_of_Birth__c” field, that Date of Birth cannot be greater than today. And I’m using a visualforce page to insert the data in “Student__c” object. So, I need to show the validation rule error message in visualforce page.
Validation Rule:
Below is my controller which gave the solution for displaying validation error message on visualforce page.
Controller:
public with sharing class StudentExt {
public Student__c student{get;set;}
public StudentExt(ApexPages.StandardController controller) {
student = (Student__c)controller.getRecord();
}
public Pagereference saveStudent() {
try {
Upsert student;
return new Pagereference('/' + student.Id);
}
catch(DMLException de) {
Apexpages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.FATAL, de.getDmlMessage(0)));
return NULL;
}
catch(Exception e) {
Apexpages.addMessage(new ApexPages.Message(ApexPages.SEVERITY.FATAL, e.getMessage()));
return NULL;
}
}
}
//Create Product
Product2 pro = new Product2(Name = 'iPhone X', Family = 'Mobile');
Insert pro;
//Instantiate the Pricebook2 record with StandardPricebookId
Pricebook2 standardPricebook = new Pricebook2(
Id = Test.getStandardPricebookId(),
IsActive = true
);
//Execute an update DML on the Pricebook2 record, to make IsStandard to true
Update standardPricebook;
//Query for the Pricebook2 record, to check IsStandard field
standardPricebook = [SELECT Id, IsStandard FROM Pricebook2 WHERE Id = :standardPricebook.Id];
//It should return true
System.assertEquals(true, standardPricebook.IsStandard);
//Create the PricebookEntry
PricebookEntry pbe = new PricebookEntry(
Pricebook2Id = standardPricebook.Id,
Product2Id = pro.Id,
UnitPrice = 1020,
IsActive = true
);
Insert pbe;
//Query the PricebookEntry record
pbe = [SELECT Id, Pricebook2.IsStandard FROM PricebookEntry];
//It should return true
System.assertEquals(true, pbe.Pricebook2.IsStandard);
Action Region will wrap only the input Field and not the complete pageBlockSectionItem. Place pageBlockSectionItem tags inside a pageBlockSection, which in turn should be in a pageBlock. This will provide the correct formatting.