talk2bks | Posts: 34

Uploading Signed Documents to Salesforce Files, Getting Error

0 votes

I'm working on the callbacks into Salesforce. The callbacks are triggering just fine. And the provided code where we are uploading the signed documents into the document object is working perfectly. However, I need to upload the documents into Content Versions instead of the document library.

I keep getting the same error: System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

I've redone the code several times to get it to work. Just wondering if anyone else was having the same issue.

 

OneSpanSDK sdk= new OneSpanSDK();
OneSpanAPIObjects.Package_x pack = sdk.getPackage(ossCallback.packageId);

//create the file
//Loop through the oss pack;
Map<String, String> docs = new Map<String, String>();

        for(OneSpanAPIObjects.Document document: pack.documents){
            System.debug('document IDs '+document.id);
            docs.put(document.id, document.name);
        }

        for(String doc : docs.keySet()){
            System.debug('Document key = '+doc);
            System.debug('Document value = '+docs.get(doc));
            Blob download = sdk.downloadDocument(ossCallback.packageId, doc);

            //create the new version
            ContentVersion cVersion = new ContentVersion();
            cVersion.ContentLocation = 'S';
            cVersion.Title = docs.get(doc);
            cVersion.PathOnClient = docs.get(doc) + 'pdf';
            cVersion.VersionData = download;
            insert cVersion;          

            id contentDoc = [SELECT ContentDocumentId FROM contentVersion WHERE Id=:cVersion.Id].ContentDocumentId;
            ContentDocumentLink cDocLink = new ContentDocumentLink();
            cDocLink.ContentDocumentId = contentDoc;
            cDocLink.LinkedEntityId = ossTransaction.Related_to__c;   //this is referenced outside this
            cDocLink.Visibility = 'AllUsers';
            cDocLink.ShareType = 'V';
            insert cDocLink;
        }


Approved Answer
Duo_Liang | Posts: 3776

Reply to: Uploading Signed Documents to Salesforce Files, Getting Error

0 votes

Hi Brian,

 

From my understanding, Salesforce doesn't allow mix of Callout method(external API calls) and DML operations(query is fine, but not delete and upsert, etc).

In your case, sdk.downloadDocument is callout and insert ContentVersion and ContentDocumentLink is DML and they are in a for loop. 

Try to store the ContentVersion and ContentDocumentLink in a local variable and do DML at the very end. Let me know how this works for you.

 

Duo


talk2bks | Posts: 34

Reply to: Uploading Signed Documents to Salesforce Files, Getting Error

1 votes

Thanks Duo,

I created a new class Here's the final code (but not all the code for the entire class). I created a new class to temporarily store the returned package info, and the blob info in. Then I create all the ContentVersions. 

I also created a custom object called "OneSpan Transactions" and I'm storing some info in there as well, such as transaction status.

~~~~~

//Create a new object to store OSS Package Info
public class OssDocument
    {
        public String id;
        public String name;
        public Blob file;
    }

private static OneSpan_Transaction__c getTransaction(String ossPackageId)
    {
        OneSpan_Transaction__c ossTransaction = [SELECT Id, Related_to__c, Notes__c, File_ID__c, Status__c FROM OneSpan_Transaction__c WHERE OneSpan_Package_ID__c=:ossPackageId LIMIT 1];
        return ossTransaction;
    }

private static void packageCreate(OssCallback ossCallback){
        OneSpanSDK sdk= new OneSpanSDK();
        OneSpanAPIObjects.Package_x pack = sdk.getPackage(ossCallback.packageId);      

        List<OssDocument> docs = new List<OssDocument>();
        for(OneSpanAPIObjects.Document document: pack.documents){
            System.debug('document IDs '+document.id);
            Blob download = sdk.downloadDocument(ossCallback.packageId, document.id);
            OssDocument doc = new OssDocument();
            doc.name = document.name;
            doc.id = document.id;
            doc.file = download;
            docs.add(doc);
        }

        for(OssDocument doc: docs){
            System.debug('document IDs '+doc.id);
            ContentVersion cVersion = new ContentVersion();
            cVersion.ContentLocation = 'S';
            cVersion.Title = doc.name;
            cVersion.PathOnClient = doc.name+'.pdf';
            cVersion.VersionData = doc.file;
            insert cVersion;

            id contentDocId = [SELECT ContentDocumentId FROM contentVersion WHERE Id=:cVersion.Id].ContentDocumentId;
            ContentDocumentLink cDocLink = new ContentDocumentLink();
            cDocLink.ContentDocumentId = contentDocId;
            cDocLink.LinkedEntityId = ossTransaction.Related_to__c;
            cDocLink.Visibility = 'AllUsers';
            cDocLink.ShareType = 'V';
            insert cDocLink;
        }

}


Duo_Liang | Posts: 3776

Reply to: Uploading Signed Documents to Salesforce Files, Getting Error

0 votes

Thanks a lot for the sharing! This is very helpful for any future developer who has the similar issue!

 

Duo


talk2bks | Posts: 34

Reply to: Uploading Signed Documents to Salesforce Files, Getting Error

0 votes

In case someone else is having the same error, Salesforce will trigger a record to be updated or created, and while that is going on, will run the next line of code. So if the next line of code is dowloading another document, this error will be triggered.

For this problem, it wasn't really the new ContentVersions, but it was an update to my custom OneSpan_Transaction__c record. I was updating that record, then starting the loop to download the files. I've updated the code and put that update at the end.


Hello! Looks like you're enjoying the discussion, but haven't signed up for an account.

When you create an account, we remember exactly what you've read, so you always come right back where you left off