Update Account fields when Enhanced Note is created/edited
I'll preface this with saying I'm in no way a developer and only have minimal experience with Apex code. I have a business requirement to update the following 2 Account custom fields whenever a new Enhanced Note is created or edited.
という質問がありましたので、腕試しにApexトリガーを書いてみました....
まずはオブジェクトのデータモデルを確認します。
ふむふむ、拡張メモ(Lightningのメモ)は ContentNoteオブジェクトだな、取引先とはContentDocumentLinkを介して参照関係にあるようです。
そうであれば、ContentDocumentLinkのトリガー(after insert)の処理でよさそうです。
というように基本方針が決まればあとは書くだけだ。
trigger NoteToAccount on ContentDocumentLink (after insert) {
Map<Id,Id> AccountIdMap = new Map<Id,Id>();
for(ContentDocumentLink cdl : Trigger.New){
String s = cdl.LinkedEntityId;
if (s.left(3) == '001') {
//Account Only
AccountIdMap.put(cdl.ContentDocumentid,cdl.LinkedEntityId);
}
}//end of for
List<ContentNote> ContentNoteList = [SELECT Id,Title,TextPreview,CreatedDate,Content FROM ContentNote WHERE ID =: AccountIdMap.keySet()];
System.debug('##############################' + ContentNoteList.size());
Set<Id> ContentNoteIdSet = new Set<Id>();
for (ContentNote cn : ContentNoteList){
ContentNoteIdSet.Add(cn.Id);
}
List<ContentVersion> cvList = [SELECT Id,Title,TextPreview,ContentDocumentId,VersionData FROM ContentVersion WHERE ContentDocumentId =:ContentNoteIdSet];
Map<Id,ContentVersion> cvMap = new Map<Id,ContentVersion>();
for (ContentVersion cv : cvList){
cvMap.put(cv.ContentDocumentId,cv);
}
List<Account> updateAccountList = new List<Account>();
for (ContentNote cn : ContentNoteList){
Account acc = new Account();
Id accId = (Id)AccountIdMap.get(cn.Id);
if (accId != null) {
acc.Id = accId;
//acc.TextPreview__c = cn.TextPreview;
//System.debug('##############################' + cn.TextPreview);// NG null
acc.TextPreview__c = cn.Content.toString();
System.debug('##############################' + cn.Content.toString());// NG null
//ContentVersion cv = (ContentVersion)cvMap.get(cn.Id);
//if (cv != null ) acc.TextPreview__c = cv.TextPreview;
//System.debug('##############################' + cv.TextPreview);//NG null
//if (cv != null ) acc.TextPreview__c = cv.VersionData.toString();
//System.debug('##############################' + cv.VersionData.toString().escapeHtml4());
//System.debug('##############################' + EncodingUtil.base64Decode(cv.VersionData.toString().escapeHtml4()) );
acc.LastModifiedDate__c = cn.CreatedDate;
updateAccountList.add(acc);
}
}
if (updateAccountList.size() > 0) update updateAccountList;
}
トリガー自体はものの30分くらいで完成。はい動作確認....
あれ! 何故かTextPreviewから値が取れていない。
しかし、SOQLをたたいてみると TextPreviewに値はあるんですねぇ。
何で?
もしかして、TextPreviewは特殊なフィールドか。
しかたないので、ContentVersionからTextPreviewを参照してみる。
結果は変わらず。
それじゃぁ、大元のVersionDataを使ってみる。これってBlob型でややこしい。
何だこれ、
どうなっているんでしょうねぇ。
色々探すと気になる投稿がでてきました。
ContentDocumentIDは、ContentVersionが挿入された直後は使用できませんが、soqlクエリの後で使用できます
https://salesforce.stackexchange.com/questions/229335/contentdocumentid-is-not-available-just-after-contentversion-getting-inserted-bu