How to call DocMerge from a Hook ?

Hi guys,

does one of you already try to call DocMerge from a Hook (or similar code context) ?

Of course I know it can be done through BPM ; but what we want to do can be trigger and handle using BPM.

Also, I would like to see if error handling is better with code generation.

Best regards,


  • Hi ,

    I had a quick chat with engineering and they believe you can achieve what you need through DocMergeApi, as for error handling, most (if not all) are coming directly from the DocMerge service.

    Perhaps if you share a little more about your use case, I can get a better answer from the team.


    SugarCRM | Principal Developer Advocate

  • Hi ,

    Thanks for your feedback.

    Here is our use case

    • we need to generate a mail for several customers
    • using DocMerge, I can generate a single document merging all record for printing --> that is OK
    • I also need to generate a single document for each customer, in ordre to archive the document in the EDM solution

    we were thinking about doing this using BPM but we face several issues without any way to be sure that the document was correctly generated.

    So we would like to trigger a hook and create several individual job action to perform the docmerge.

    Best regards,


  • Hi ,

    Here is some ideas we came up with:

    You can create the hook and call the merge function from the DocumentMergeApi. Just instantiate the class and call the function. The function should receive the proper arguments. They can be identified from the code inside the function

       $data = [
                'mergeType' => $request->getValidInputPost('mergeType'),
                'useRevision' => $request->getValidInputPost('useRevision') ?? true,
                'templateName' => $request->getValidInputPost('templateName'),
                'templateId' => $request->getValidInputPost('templateId', 'Assert\Guid'),
                'recordId' => $request->getValidInputPost('recordId', 'Assert\Guid'),
                'recordModule' => $request->getValidInputPost('recordModule'),
                'parentId' => $request->getValidInputPost('parentId'),
                'parentModule' => $request->getValidInputPost('parentModule'),
                'maxRelate' => $request->getValidInputPost('maxRelate') ?? static::MAX_RETRIEVE,
    Also you'd need to create for each merge, a DocumentMerge record. This actually tracks the merge status. Once you call the merge function they will immediately get a response from the server. The response is the merge request id. After that, the server will update the DocumentMerge record that was created earlier, with the status messages, like Retrieving data , Document Generated or error messages.

    SugarCRM | Principal Developer Advocate

  • Hi ,

    I tried with the following code:

        $api = new DocumentMergeApi();
        $args = [
            'mergeType' => 'convert',
            'useRevision' => 1,
            'templateName' => 'test',
            'templateId' => '9a7a7546-e5c8-11ed-af10-0242ac11002e',
            'recordId' => '497703a6-efd9-11ed-88c2-0242ac11002a',
            'recordModule' => 'Accounts',
        $service = new RestService();
        $merge_req_id = $api->merge($service, $args);

    I can see the document_merge record in the DocMerge popup as well as in the document_merges db table.

    But it ends up with an error in the sugarcrm.log:

    Exception in Controller: SugarException: Server error: `POST` resulted in a `504 Gateway Time-out` response:
     in /var/www/html/modules/DocumentMerges/clients/base/api/DocumentMergeApi.php:141

    I launched the same document generation using the interface and it went well. I don't see any difference in the 2 document generations (looking at the db records and at the parameters send to the api).

    Any idea about what is going wrong?

    Thank you,


  • Hi ,

    Here's the feedback I got from engineering:

    Example code should be inside the bpm modules/pmse_Inbox/engine/PMSEElements/PMSEDocumentMerge.php

    public function merge($data, \SugarBean $bean, $flowData): void
            $convert = $data->act_convert_to_pdf ?? false;
            $templateId = $data->act_document_template->value;
            $templateName = $data->act_document_template->text;
            $recordId = $bean->id;
            $recordModule = $bean->module_dir;
            $mergeType = $this->getMergeType($convert, $templateId);
            if ($mergeType) {
                $docMerge = new DocumentMergeApi();
                $api = new \RestService();
                $docMerge->merge($api, [
                    'mergeType' => $mergeType,
                    'templateId' => $templateId,
                    'templateName' => $templateName,
                    'useRevision' => true,
                    'recordId' => $recordId,
                    'recordModule' => $recordModule,
                    'flowData' => json_encode($flowData),
            } else {
                throw new PMSEElementException("Document Merge: No merge type", $mergeType, $this);

    $flowData shouldn't matter but for safety, I would put something like '{}'
    You are sending all the params that are needed. You could debug it by adding the 'flowData' param and if it still doesn't work you could check the network settings. 


    SugarCRM | Principal Developer Advocate

  • Hi  ,

    Do you know if it is possible to set the name of the file that is generated?  Right now, it concatenates the Name of the record and the name of the Document Template.  I'd like to be able to set a custom filename result.

    Thank you,
    Justin Kuehlthau

  •  ,

    You can set a prefix and a suffix in the UI (see image below), but it will be static, meaning you cannot set something-{name}-contract.docx.


    SugarCRM | Principal Developer Advocate