+ Start a Discussion
Jan Kopejtko 2Jan Kopejtko 2 

Simple code to update a file name

Following the previous question: https://developer.salesforce.com/forums/ForumsMain?id=9062I000000XsipQAC

Hello,

I need to update a file title after it's upload.

That is an easy trigger, but here is the catch:

On object A is a text field. Each record of object A has some value in the text field. After I upload the file to the object A's record, I need to take the value in the text field of the record and set is as a title of the newly uploaded file.

Mr. PRAKASH JADA 13 helped me with the code:
 
Hi,


Trigger:
--------------------------
trigger AttcahmentTrigger on Attachment (before insert) {
    if(Trigger.isBefore) {
        if(Trigger.isInsert) {
            AttcahmentTriggerHandler.onBeforeInsert(Trigger.New);
        }
    }
}


Trigger Handler:
----------------------------------
/*
 * Author: Prakash
 * CreatedDate: Feb 14, 20202
*/
public with sharing class AttcahmentTriggerHandler {
    public static void onBeforeInsert(List<Attachment> attachments) {
        
        List<Id> accountIds = new List<Id>();
        
        //Loop to iterate over the list of attachments        
        for(Attachment att : attachments) {
            if(att.ParentId != null) {
                accountIds.add(att.ParentId); // Preparing the account Ids
            }
        }
        
        if(!accountIds.isEmpty()) {
            // Preparing the map that holds the account Name as a value and Id as a key
            Map<Id, Account> accountMap = new Map<Id,Account>([SELECT ID, Name FROM Account WHERE Id = :accountIds]);
            
            // Loop to iterate over the list of Attachments
            for(Attachment att : attachments) {
                att.Name = accountMap.get(att.ParentId).Name;
            }
            
        }
        
    }
}
But there is another catch to it - by object A I mean object SERVICE APPOINTMENT, which does not support the Attachment object.

Help me please!
 
Best Answer chosen by Jan Kopejtko 2
PRAKASH JADA 13PRAKASH JADA 13
are you using content version to upload the files if that is the care you need to change your trigger from content document to content version

All Answers

PRAKASH JADA 13PRAKASH JADA 13
Hi,

Are you using ContentDocument to upload the files? If so Here is the code. else please ignore the below code.

Trigger:
-------------------

trigger AttachmentTrigger on ContentDocument (before insert) {
    if(Trigger.isBefore) {
        if(Trigger.isInsert) {
            AttcahmentTriggerHandler.onBeforeInsert(Trigger.New);
        }
    }
}


Handler:
---------------------

public with sharing class AttcahmentTriggerHandler {
    public static void onBeforeInsert(List<ContentDocument> contentDocuments) {
        
        List<Id> accountIds = new List<Id>();
        
        //Loop to iterate over the list of Content Document        
        for(ContentDocument doc : contentDocuments) {
            if(doc.ParentId != null) {
                accountIds.add(doc.ParentId); // Preparing the account Ids
            }
        }
        
        if(!accountIds.isEmpty()) {
            // Preparing the map that holds the account Name as a value and Id as a key
            Map<Id, Account> accountMap = new Map<Id,Account>([SELECT ID, Name FROM Account WHERE Id = :accountIds]);
            
            // Loop to iterate over the list of Attachments
            for(ContentDocument doc : contentDocuments) {
                doc.Title = accountMap.get(doc.ParentId).Name;
            }
            
        }
        
    }
}


I hope this helps. 

Thanks
Jan Kopejtko 2Jan Kopejtko 2
Hello Prakash, thanks alot. I am really thankful man, I did not know that ContentDocument has ParentId which is linked to the records.

Anyways - could you help me with this - I can't upload files if I put any trigger on ContentDocument. It throws me an error when I upload any file. If I disable the trigger it starts working again. The things is that there is no error message. I'm trying the debug log now.
Jan Kopejtko 2Jan Kopejtko 2
This is my very simple code:
 
trigger ContentDocumentDescription on ContentDocument (after insert) {
    for(ContentDocument a :Trigger.New) {
        a.Description = 'test';
    }
}
And this is the bug I'm recieving:
 
48.0 APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;NBA,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WAVE,INFO;WORKFLOW,INFO
16:13:41.0 (369414)|USER_INFO|[EXTERNAL]|0052o000009Stq8|developerbase1@gmail.com|(GMT+00:00) Greenwich Mean Time (Europe/Dublin)|GMTZ
16:13:41.0 (469039)|EXECUTION_STARTED
16:13:41.0 (489104)|CODE_UNIT_STARTED|[EXTERNAL]|01q2o000000IeDj|ContentDocumentDescription on ContentDocument trigger event AfterInsert|__sfdc_trigger/ContentDocumentDescription
16:13:41.0 (579276)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
16:13:41.0 (1304843)|HEAP_ALLOCATE|[79]|Bytes:3
16:13:41.0 (1432889)|HEAP_ALLOCATE|[84]|Bytes:152
16:13:41.0 (1486084)|HEAP_ALLOCATE|[399]|Bytes:408
16:13:41.0 (1505604)|HEAP_ALLOCATE|[412]|Bytes:408
16:13:41.0 (1522488)|HEAP_ALLOCATE|[520]|Bytes:48
16:13:41.0 (1666585)|HEAP_ALLOCATE|[139]|Bytes:6
16:13:41.0 (1847124)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
16:13:41.0 (1968250)|VARIABLE_SCOPE_BEGIN|[1]|this|ContentDocumentDescription|true|false
16:13:41.0 (2253847)|VARIABLE_ASSIGNMENT|[1]|this|{}|0x21582ece
16:13:41.0 (2318228)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
16:13:41.0 (2395300)|VARIABLE_SCOPE_BEGIN|[1]|this|ContentDocumentDescription|true|false
16:13:41.0 (2444352)|VARIABLE_ASSIGNMENT|[1]|this|{}|0x21582ece
16:13:41.0 (2459843)|STATEMENT_EXECUTE|[1]
16:13:41.0 (2509051)|HEAP_ALLOCATE|[52]|Bytes:5
16:13:41.0 (3769735)|HEAP_ALLOCATE|[58]|Bytes:5
16:13:41.0 (3863683)|HEAP_ALLOCATE|[66]|Bytes:7
16:13:41.0 (4482827)|HEAP_ALLOCATE|[2]|Bytes:5
16:13:41.0 (4578258)|VARIABLE_SCOPE_BEGIN|[2]|a|ContentDocument|true|false
16:13:41.0 (5256004)|VARIABLE_ASSIGNMENT|[2]|a|{"LastModifiedDate":"2020-02-15T16:13:40.000Z","IsDeleted":false,"SharingPrivacy":"N","Title":"testfile","SystemModstamp":"2020-02-15T16:13:40.000Z","IsArchived":false,"CreatedById":"0052o000009Stq8AAC","OwnerId":"0052o000009Stq8AAC","ContentModifiedDate":"2020-02-15T16:13:40.000Z","SharingOption":"A","CreatedDate":"2020-02-15T16:13:40.000Z","Id":"0692o00000AHzh7AAD","LastModifiedById":"0052o000009Stq8AAC","PublishStatus":"U"}|0x4744bf2f
16:13:41.0 (5282434)|STATEMENT_EXECUTE|[2]
16:13:41.0 (5287240)|STATEMENT_EXECUTE|[3]
16:13:41.0 (5295899)|HEAP_ALLOCATE|[3]|Bytes:4
16:13:41.0 (5490650)|EXCEPTION_THROWN|[3]|System.FinalException: Record is read-only
16:13:41.0 (5610683)|HEAP_ALLOCATE|[3]|Bytes:23
16:13:41.0 (5825301)|FATAL_ERROR|System.FinalException: Record is read-only

Trigger.ContentDocumentDescription: line 3, column 1
16:13:41.0 (5850694)|FATAL_ERROR|System.FinalException: Record is read-only

Trigger.ContentDocumentDescription: line 3, column 1
16:13:41.5 (5907681)|CUMULATIVE_LIMIT_USAGE
16:13:41.5 (5907681)|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 0 out of 150
  Number of DML rows: 0 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10

16:13:41.5 (5907681)|CUMULATIVE_LIMIT_USAGE_END

16:13:41.0 (7545993)|CODE_UNIT_FINISHED|ContentDocumentDescription on ContentDocument trigger event AfterInsert|__sfdc_trigger/ContentDocumentDescription
16:13:41.0 (9643965)|EXECUTION_FINISHED

 
PRAKASH JADA 13PRAKASH JADA 13
ContentDocument trigger event AfterInsert why the trigger is on After event it should be on before event, right?


I gave you the trigger before event. It should not lock the record can you please check if there are any other triggers? or something related to isAfter on the content document?
PRAKASH JADA 13PRAKASH JADA 13
Please change the code like this
trigger ContentDocumentDescription on ContentDocument (before insert) { --> line changed
    for(ContentDocument a :Trigger.New) {
        a.Description = 'test';
    }
}

if you use after insert then you will get the error because the record is in ready only mode


 
Jan Kopejtko 2Jan Kopejtko 2
Prakash:

Oh I see it, yes I fixed it, code looks like this now:
 
trigger ContentDocumentDescription on ContentDocument (before insert) { 
    for(ContentDocument a :Trigger.New) {
        a.Description = 'test';
    }
}

I'm now getting an error:
 
48.0 APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;NBA,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WAVE,INFO;WORKFLOW,INFO
16:26:31.0 (393526)|USER_INFO|[EXTERNAL]|0052o000009Stq8|developerbase1@gmail.com|(GMT+00:00) Greenwich Mean Time (Europe/Dublin)|GMTZ
16:26:31.0 (516138)|EXECUTION_STARTED
16:26:31.0 (533759)|CODE_UNIT_STARTED|[EXTERNAL]|TRIGGERS
16:26:31.0 (578188)|CODE_UNIT_STARTED|[EXTERNAL]|01q2o000000IeDj|ContentDocumentDescription on ContentDocument trigger event BeforeInsert|__sfdc_trigger/ContentDocumentDescription
16:26:31.0 (664057)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
16:26:31.0 (1586083)|HEAP_ALLOCATE|[79]|Bytes:3
16:26:31.0 (1720127)|HEAP_ALLOCATE|[84]|Bytes:152
16:26:31.0 (1758367)|HEAP_ALLOCATE|[399]|Bytes:408
16:26:31.0 (1803445)|HEAP_ALLOCATE|[412]|Bytes:408
16:26:31.0 (1830199)|HEAP_ALLOCATE|[520]|Bytes:48
16:26:31.0 (1897770)|HEAP_ALLOCATE|[139]|Bytes:6
16:26:31.0 (1944579)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
16:26:31.0 (2067383)|VARIABLE_SCOPE_BEGIN|[1]|this|ContentDocumentDescription|true|false
16:26:31.0 (2405289)|VARIABLE_ASSIGNMENT|[1]|this|{}|0xfc3879b
16:26:31.0 (2505623)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
16:26:31.0 (2616625)|VARIABLE_SCOPE_BEGIN|[1]|this|ContentDocumentDescription|true|false
16:26:31.0 (2695991)|VARIABLE_ASSIGNMENT|[1]|this|{}|0xfc3879b
16:26:31.0 (2727724)|STATEMENT_EXECUTE|[1]
16:26:31.0 (2821067)|HEAP_ALLOCATE|[52]|Bytes:5
16:26:31.0 (2892949)|HEAP_ALLOCATE|[58]|Bytes:5
16:26:31.0 (2914244)|HEAP_ALLOCATE|[66]|Bytes:7
16:26:31.0 (3408262)|HEAP_ALLOCATE|[2]|Bytes:5
16:26:31.0 (3502841)|HEAP_ALLOCATE|[2]|Bytes:4
16:26:31.0 (3559695)|VARIABLE_SCOPE_BEGIN|[2]|a|ContentDocument|true|false
16:26:31.0 (8141827)|VARIABLE_ASSIGNMENT|[2]|a|{"IsArchived":false,"LastModifiedDate":"2020-02-15T16:26:31.000Z","IsDeleted":false,"CreatedById":"0052o000009Stq8AAC","OwnerId":"0052o000009Stq8AAC","SharingOption":"A","SharingPrivacy":"N","CreatedDate":"2020-02-15T16:26:31.000Z","Title":"testfile","LastModifiedById":"0052o000009Stq8AAC","PublishStatus":"U"}|0x32b3b21e
16:26:31.0 (8189248)|STATEMENT_EXECUTE|[2]
16:26:31.0 (8196401)|STATEMENT_EXECUTE|[3]
16:26:31.0 (8207367)|HEAP_ALLOCATE|[3]|Bytes:4
16:26:31.0 (8381429)|HEAP_ALLOCATE|[3]|Bytes:55
16:26:31.0 (8727359)|FATAL_ERROR|System.SObjectException: Field is not writeable: ContentDocument.Description

Trigger.ContentDocumentDescription: line 3, column 1
16:26:31.0 (8755062)|FATAL_ERROR|System.SObjectException: Field is not writeable: ContentDocument.Description

Trigger.ContentDocumentDescription: line 3, column 1
16:26:31.8 (8872872)|CUMULATIVE_LIMIT_USAGE
16:26:31.8 (8872872)|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 0 out of 150
  Number of DML rows: 0 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10

16:26:31.8 (8872872)|CUMULATIVE_LIMIT_USAGE_END

16:26:31.0 (10454414)|CODE_UNIT_FINISHED|ContentDocumentDescription on ContentDocument trigger event BeforeInsert|__sfdc_trigger/ContentDocumentDescription
16:26:31.0 (41762243)|CODE_UNIT_FINISHED|TRIGGERS
16:26:31.0 (41790430)|EXECUTION_FINISHED

System.SObjectException: Field is not writeable: ContentDocument.Description

If I open the file, I can edit it manually. Why is it not writeable?
User-added image
PRAKASH JADA 13PRAKASH JADA 13
Now you trying to write the description you need to the title to be updated so in your code change the field from description to Title
PRAKASH JADA 13PRAKASH JADA 13
are you using content version to upload the files if that is the care you need to change your trigger from content document to content version
This was selected as the best answer
Jan Kopejtko 2Jan Kopejtko 2
Thank you for your replies, I changed the code:
 
trigger ContentDocumentDescription on ContentDocument (before insert) {
    for(ContentDocument a :Trigger.New) {
        a.Title = 'test';
    }
}
I'm getting this error now:
 
48.0 APEX_CODE,FINEST;APEX_PROFILING,INFO;CALLOUT,INFO;DB,INFO;NBA,INFO;SYSTEM,DEBUG;VALIDATION,INFO;VISUALFORCE,INFO;WAVE,INFO;WORKFLOW,INFO
16:39:44.0 (285124)|USER_INFO|[EXTERNAL]|0052o000009Stq8|developerbase1@gmail.com|(GMT+00:00) Greenwich Mean Time (Europe/Dublin)|GMTZ
16:39:44.0 (365442)|EXECUTION_STARTED
16:39:44.0 (377543)|CODE_UNIT_STARTED|[EXTERNAL]|TRIGGERS
16:39:44.0 (424395)|CODE_UNIT_STARTED|[EXTERNAL]|01q2o000000IeDj|ContentDocumentDescription on ContentDocument trigger event BeforeInsert|__sfdc_trigger/ContentDocumentDescription
16:39:44.0 (537245)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
16:39:44.0 (1238998)|HEAP_ALLOCATE|[79]|Bytes:3
16:39:44.0 (1344297)|HEAP_ALLOCATE|[84]|Bytes:152
16:39:44.0 (1375096)|HEAP_ALLOCATE|[399]|Bytes:408
16:39:44.0 (1405435)|HEAP_ALLOCATE|[412]|Bytes:408
16:39:44.0 (1432166)|HEAP_ALLOCATE|[520]|Bytes:48
16:39:44.0 (1477483)|HEAP_ALLOCATE|[139]|Bytes:6
16:39:44.0 (1520600)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
16:39:44.0 (1666164)|VARIABLE_SCOPE_BEGIN|[1]|this|ContentDocumentDescription|true|false
16:39:44.0 (1990706)|VARIABLE_ASSIGNMENT|[1]|this|{}|0x2000553d
16:39:44.0 (2087352)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
16:39:44.0 (2126968)|VARIABLE_SCOPE_BEGIN|[1]|this|ContentDocumentDescription|true|false
16:39:44.0 (2198002)|VARIABLE_ASSIGNMENT|[1]|this|{}|0x2000553d
16:39:44.0 (2218526)|STATEMENT_EXECUTE|[1]
16:39:44.0 (2287387)|HEAP_ALLOCATE|[52]|Bytes:5
16:39:44.0 (2364484)|HEAP_ALLOCATE|[58]|Bytes:5
16:39:44.0 (2393609)|HEAP_ALLOCATE|[66]|Bytes:7
16:39:44.0 (2959431)|HEAP_ALLOCATE|[2]|Bytes:5
16:39:44.0 (3049867)|HEAP_ALLOCATE|[2]|Bytes:4
16:39:44.0 (3110181)|VARIABLE_SCOPE_BEGIN|[2]|a|ContentDocument|true|false
16:39:44.0 (7421615)|VARIABLE_ASSIGNMENT|[2]|a|{"IsArchived":false,"LastModifiedDate":"2020-02-15T16:39:44.000Z","IsDeleted":false,"CreatedById":"0052o000009Stq8AAC","OwnerId":"0052o000009Stq8AAC","SharingOption":"A","SharingPrivacy":"N","CreatedDate":"2020-02-15T16:39:44.000Z","Title":"testfile","LastModifiedById":"0052o000009Stq8AAC","PublishStatus":"U"}|0x5a735cf9
16:39:44.0 (7473333)|STATEMENT_EXECUTE|[2]
16:39:44.0 (7480691)|STATEMENT_EXECUTE|[3]
16:39:44.0 (7494275)|HEAP_ALLOCATE|[3]|Bytes:4
16:39:44.0 (7687002)|HEAP_ALLOCATE|[3]|Bytes:49
16:39:44.0 (8015516)|FATAL_ERROR|System.SObjectException: Field is not writeable: ContentDocument.Title

Trigger.ContentDocumentDescription: line 3, column 1
16:39:44.0 (8042486)|FATAL_ERROR|System.SObjectException: Field is not writeable: ContentDocument.Title

Trigger.ContentDocumentDescription: line 3, column 1
16:39:44.8 (8156949)|CUMULATIVE_LIMIT_USAGE
16:39:44.8 (8156949)|LIMIT_USAGE_FOR_NS|(default)|
  Number of SOQL queries: 0 out of 100
  Number of query rows: 0 out of 50000
  Number of SOSL queries: 0 out of 20
  Number of DML statements: 0 out of 150
  Number of DML rows: 0 out of 10000
  Maximum CPU time: 0 out of 10000
  Maximum heap size: 0 out of 6000000
  Number of callouts: 0 out of 100
  Number of Email Invocations: 0 out of 10
  Number of future calls: 0 out of 50
  Number of queueable jobs added to the queue: 0 out of 50
  Number of Mobile Apex push calls: 0 out of 10

16:39:44.8 (8156949)|CUMULATIVE_LIMIT_USAGE_END

16:39:44.0 (9566353)|CODE_UNIT_FINISHED|ContentDocumentDescription on ContentDocument trigger event BeforeInsert|__sfdc_trigger/ContentDocumentDescription
16:39:44.0 (40206734)|CODE_UNIT_FINISHED|TRIGGERS
16:39:44.0 (40229914)|EXECUTION_FINISHED
What do I do?

 
Jan Kopejtko 2Jan Kopejtko 2
Prakash: Thanks alot man, that was it. Kudos to you.
Lionel Poncet 11Lionel Poncet 11
Hello Jan Kopejtko 2,
How did you solved your problem for "Field is not writeable: ContentDocument.Title" ?
Thanks.