Yetiforcecrm: [Feature] Actions on Related list (like send email to accounts/contacts in campaign module)

Created on 29 Jan 2020  ·  6Comments  ·  Source: YetiForceCompany/YetiForceCRM

Hi,

Feature : option to enable select/actions on M:M related list records

Use case : send email or sms to a related list, for example contacts who buy a service, members of a club, etc.

For now, it seems not possible to do this by using filters as they only support 1:M relationships.

actions_related_list

❌ ignored 💹 enhancement

Most helpful comment

Hi,
I've juste found that Occurrences module has this feature yet so you just have to copy/paste a few files, change class names and you're done ! 👍

So if you need actions like Mass Email in related list view of a custom module, you will need to create/edit the following files :

  • /modules/YOUR_CUSTOM_MODULE/views/Detail.php
<?php
/**
 * Detail view.
 *
 * @package   View
 *
 * @copyright YetiForce Sp. z o.o
 * @license   YetiForce Public License 3.0 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Radosław Skrzypczak <[email protected]>
 */
/**
 * YOUR_CUSTOM_MODULE_Detail_View class.
 */
class YOUR_CUSTOM_MODULE_Detail_View extends Vtiger_Detail_View
{
    /**
     * {@inheritdoc}
     */
    public function getFooterScripts(App\Request $request)
    {
        $moduleName = $request->getModule();
        return array_merge(parent::getFooterScripts($request), $this->checkAndConvertJsScripts([
            'modules.Vtiger.resources.List',
            'modules.{$moduleName}.resources.List'

        ]));
    }
}


  • /modules/YOUR_CUSTOM_MODULE/models/RelationListView.php
<?php
/**
 * Relations.
 *
 * @package   Model
 *
 * @copyright YetiForce Sp. z o.o
 * @license   YetiForce Public License 3.0 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Radosław Skrzypczak <[email protected]>
 * @author    Arkadiusz Dudek <[email protected]>
 */
class YOUR_CUSTOM_MODULE_RelationListView_Model extends Vtiger_RelationListView_Model
{
    /**
     * {@inheritdoc}
     */
    public function getLinks()
    {
        $relatedLink = parent::getLinks();
        $relationModelInstance = $this->getRelationModel();
        $relatedModuleModel = $relationModelInstance->getRelationModuleModel();

        if ('Contacts' === $relatedModuleModel->getName() && $relatedModuleModel->isPermitted('MassComposeEmail') && App\Config::main('isActiveSendingMails') && App\Mail::getDefaultSmtp()) {
            $relatedLink['RELATEDLIST_MASSACTIONS'][] = Vtiger_Link_Model::getInstanceFromValues([
                'linktype' => 'LISTVIEWMASSACTION',
                'linklabel' => 'LBL_MASS_SEND_EMAIL',
                'linkurl' => 'javascript:YOUR_CUSTOM_MODULE_RelatedList_Js.triggerSendEmail();',
                'linkicon' => 'fas fa-envelope',
            ]);

        }

        return $relatedLink;
    }
}


  • and public_html/layouts/basic/modules/YOUR_CUSTOM_MODULE/resources/RelatedList.js
/* {[The file is published on the basis of YetiForce Public License 3.0 that can be found in the following directory: licenses/LicenseEN.txt or yetiforce.com]} */
'use strict';
Vtiger_RelatedList_Js(
    'YOUR_CUSTOM_MODULE_RelatedList_Js',
    {
        /*
         * function to trigger send Email
         * @params: send email url , module name.
         */
        triggerSendEmail: function() {
            let params = Vtiger_RelatedList_Js.relatedListInstance.getDefaultParams();
            Vtiger_List_Js.triggerSendEmail(
                $.extend(params, {
                    relatedLoad: true,
                    module: Vtiger_RelatedList_Js.relatedListInstance.moduleName,
                    sourceModule: app.getModuleName(),
                    sourceRecord: app.getRecordId()
                })
            );
        }
    },
    {}
);


Note : replace YOUR_CUSTOM_MODULE with the name of your custom module.

All 6 comments

We don't have time for this, someone has to order it.

Hi,
I've juste found that Occurrences module has this feature yet so you just have to copy/paste a few files, change class names and you're done ! 👍

So if you need actions like Mass Email in related list view of a custom module, you will need to create/edit the following files :

  • /modules/YOUR_CUSTOM_MODULE/views/Detail.php
<?php
/**
 * Detail view.
 *
 * @package   View
 *
 * @copyright YetiForce Sp. z o.o
 * @license   YetiForce Public License 3.0 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Radosław Skrzypczak <[email protected]>
 */
/**
 * YOUR_CUSTOM_MODULE_Detail_View class.
 */
class YOUR_CUSTOM_MODULE_Detail_View extends Vtiger_Detail_View
{
    /**
     * {@inheritdoc}
     */
    public function getFooterScripts(App\Request $request)
    {
        $moduleName = $request->getModule();
        return array_merge(parent::getFooterScripts($request), $this->checkAndConvertJsScripts([
            'modules.Vtiger.resources.List',
            'modules.{$moduleName}.resources.List'

        ]));
    }
}


  • /modules/YOUR_CUSTOM_MODULE/models/RelationListView.php
<?php
/**
 * Relations.
 *
 * @package   Model
 *
 * @copyright YetiForce Sp. z o.o
 * @license   YetiForce Public License 3.0 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Radosław Skrzypczak <[email protected]>
 * @author    Arkadiusz Dudek <[email protected]>
 */
class YOUR_CUSTOM_MODULE_RelationListView_Model extends Vtiger_RelationListView_Model
{
    /**
     * {@inheritdoc}
     */
    public function getLinks()
    {
        $relatedLink = parent::getLinks();
        $relationModelInstance = $this->getRelationModel();
        $relatedModuleModel = $relationModelInstance->getRelationModuleModel();

        if ('Contacts' === $relatedModuleModel->getName() && $relatedModuleModel->isPermitted('MassComposeEmail') && App\Config::main('isActiveSendingMails') && App\Mail::getDefaultSmtp()) {
            $relatedLink['RELATEDLIST_MASSACTIONS'][] = Vtiger_Link_Model::getInstanceFromValues([
                'linktype' => 'LISTVIEWMASSACTION',
                'linklabel' => 'LBL_MASS_SEND_EMAIL',
                'linkurl' => 'javascript:YOUR_CUSTOM_MODULE_RelatedList_Js.triggerSendEmail();',
                'linkicon' => 'fas fa-envelope',
            ]);

        }

        return $relatedLink;
    }
}


  • and public_html/layouts/basic/modules/YOUR_CUSTOM_MODULE/resources/RelatedList.js
/* {[The file is published on the basis of YetiForce Public License 3.0 that can be found in the following directory: licenses/LicenseEN.txt or yetiforce.com]} */
'use strict';
Vtiger_RelatedList_Js(
    'YOUR_CUSTOM_MODULE_RelatedList_Js',
    {
        /*
         * function to trigger send Email
         * @params: send email url , module name.
         */
        triggerSendEmail: function() {
            let params = Vtiger_RelatedList_Js.relatedListInstance.getDefaultParams();
            Vtiger_List_Js.triggerSendEmail(
                $.extend(params, {
                    relatedLoad: true,
                    module: Vtiger_RelatedList_Js.relatedListInstance.moduleName,
                    sourceModule: app.getModuleName(),
                    sourceRecord: app.getRecordId()
                })
            );
        }
    },
    {}
);


Note : replace YOUR_CUSTOM_MODULE with the name of your custom module.

Now, I would also like to add 'Send SMS' action for related list.

So, I've modified /modules/MY_CUSTOM_MODULE/models/RelationListView.php

<?php
/**
 * Relations.
 *
 * @package   Model
 *
 * @copyright YetiForce Sp. z o.o
 * @license   YetiForce Public License 3.0 (licenses/LicenseEN.txt or yetiforce.com)
 * @author    Radosław Skrzypczak <[email protected]>
 * @author    Arkadiusz Dudek <[email protected]>
 */
class MY_CUSTOM_MODULE_RelationListView_Model extends Vtiger_RelationListView_Model
{
    /**
     * {@inheritdoc}
     */
    public function getLinks()
    {
        $relatedLink = parent::getLinks();
        $relationModelInstance = $this->getRelationModel();
        $relatedModuleModel = $relationModelInstance->getRelationModuleModel();

        if ('Contacts' === $relatedModuleModel->getName() && $relatedModuleModel->isPermitted('MassComposeEmail') && App\Config::main('isActiveSendingMails') && App\Mail::getDefaultSmtp()) {
            $relatedLink['RELATEDLIST_MASSACTIONS'][] = Vtiger_Link_Model::getInstanceFromValues([
                'linktype' => 'LISTVIEWMASSACTION',
                'linklabel' => 'LBL_MASS_SEND_EMAIL',
                'linkurl' => 'javascript:YOUR_CUSTOM_MODULE_RelatedList_Js.triggerSendEmail();',
                'linkicon' => 'fas fa-envelope',
            ]);

        }

            $relatedLink['RELATEDLIST_MASSACTIONS'][] = Vtiger_Link_Model::getInstanceFromValues([
                'linktype' => 'LISTVIEWMASSACTION',
                'linklabel' => 'LBL_MASS_SEND_SMS',
                'linkurl' => 'javascript:Vtiger_List_Js.triggerSendSms("index.php?module=Contacts&view=MassActionAjax&mode=showSendSMSForm","SMSNotifier");',
                'linkicon' => 'fas fa-envelope',
            ]);

        return $relatedLink;
    }
}


Everything is working except the "message" field from the modal popup which content is not detected (error: "this field is required").
Also, I've noticed that Emoji button is not working.
I'm still searching but I think this is too difficult for me right now, I really need some javascript skills ;)

mass_sms_yf

@apcloic how to add mass edit for related list?

@vovpff You could try adding the following action :

        if ($relatedModuleModel->isPermitted('MassEdit')) {
            $relatedLink['RELATEDLIST_MASSACTIONS'][] = Vtiger_Link_Model::getInstanceFromValues([
                'linktype' => 'LISTVIEWMASSACTION',
                'linklabel' => 'LBL_EDIT',
                'linkurl' => 'javascript:Vtiger_List_Js.triggerMassEdit("index.php?module='.$relatedModuleModel->getName().'&view=MassActionAjax&mode=showMassEditForm");',
                'linkicon' => 'fas fa-edit',
            ]);
        }

But unfortunately It just works partially, I mean you can only modify related entities from the first page and also it throws the following error "Entered invalid value"

So, it's not really usable and requires more work.

12034

Regards,

Regarding Send SMS to related list mass action, here's a quick and dirty fix by using a custom layout.

So you have to create the following file in /layouts/basic/modules/Your_Custom_Module_Name/SendSmsForm.tpl

With the following code :

{*<!--
/*********************************************************************************
** The contents of this file are subject to the vtiger CRM Public License Version 1.0
* ("License"); You may not use this file except in compliance with the License
* The Original Code is:  vtiger CRM Open Source
* The Initial Developer of the Original Code is vtiger.
* Portions created by vtiger are Copyright (C) vtiger.
* All Rights Reserved.
* Contributor(s): YetiForce.com
********************************************************************************/
-->*}
{strip}
    <!-- tpl-Base-SendSMSForm -->
    <div id="sendSmsContainer" class="js-send-sms__container modelContainer modal fade" tabindex="-1" data-js="hasClass">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">{\App\Language::translate('LBL_SEND_SMS_TO_SELECTED_NUMBERS', $MODULE)}</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="{\App\Language::translate('LBL_CLOSE')}">
                        <span aria-hidden="true" title="{\App\Language::translate('LBL_CLOSE')}">&times;</span>
                    </button>
                </div>
                <form class="form-horizontal validateForm" id="massSave" method="post" action="index.php">
                    <input type="hidden" name="module" value="{$MODULE}" />
                    <input type="hidden" name="source_module" value="{$SOURCE_MODULE}" />
                    <input type="hidden" name="action" value="MassSaveAjax" />
                    <input type="hidden" name="viewname" value="{$VIEWNAME}" />
                    <input type="hidden" name="selected_ids" value="{\App\Purifier::encodeHtml(\App\Json::encode($SELECTED_IDS))}">
                    <input type="hidden" name="excluded_ids" value="{\App\Purifier::encodeHtml(\App\Json::encode($EXCLUDED_IDS))}">
                    <input type="hidden" name="search_key" value="{$SEARCH_KEY}"/>
                    <input type="hidden" name="entityState" value="{$ENTITY_STATE}"/>
                    <input type="hidden" name="operator" value="{$OPERATOR}" />
                    <input type="hidden" name="search_value" value="{$ALPHABET_VALUE}" />
                    <input type="hidden" name="search_params" value="{\App\Purifier::encodeHtml(\App\Json::encode($SEARCH_PARAMS))}" />
                    <div class="modal-body">
                        <div class="alert alert-info" role="alert">
                            <span class="fas fa-info-circle"></span>&nbsp;&nbsp;
                            {\App\Language::translate('LBL_MASS_SEND_SMS_INFO', $MODULE)}
                        </div>
                        <div class="col-12">
                            <div class="form-group">
                                <span><strong>{\App\Language::translate('LBL_STEP_1',$MODULE)}</strong></span>
                                &nbsp;:&nbsp;
                                {\App\Language::translate('LBL_SELECT_THE_PHONE_NUMBER_FIELDS_TO_SEND',$MODULE)}
                                <select name="fields[]" data-placeholder="{\App\Language::translate('LBL_ADD_MORE_FIELDS',$MODULE)}" multiple class="select2 form-control" data-validation-engine="validate[ required]">
                                    <optgroup>
                                        {foreach item=PHONE_FIELD from=$PHONE_FIELDS}
                                            {if $PHONE_FIELD->isEditable() eq false} {continue} {/if}
                                            {assign var=PHONE_FIELD_NAME value=$PHONE_FIELD->get('name')}
                                            <option value="{$PHONE_FIELD_NAME}">
                                                {if !empty($SINGLE_RECORD)}
                                                    {assign var=FIELD_VALUE value=$SINGLE_RECORD->getDisplayValue($PHONE_FIELD_NAME)}
                                                {/if}
                                                {\App\Language::translate($PHONE_FIELD->get('label'), $SOURCE_MODULE)}{if !empty($FIELD_VALUE)} ({$FIELD_VALUE}){/if}
                                            </option>
                                        {/foreach}
                                    </optgroup>
                                </select>
                            </div>
                            <div class="form-group">
                                <div>
                                    <span><strong>{\App\Language::translate('LBL_STEP_2',$MODULE)}</strong></span>
                                    &nbsp;:&nbsp;
                                    {\App\Language::translate('LBL_TYPE_THE_MESSAGE',$MODULE)}
                                    &nbsp;(&nbsp;{\App\Language::translate('LBL_SMS_MAX_CHARACTERS_ALLOWED',$MODULE)}&nbsp;)
                                </div>
                                <div class="c-completions js-completions__actions">
                                    <span class="c-completions__item js-completions__emojis far fa-smile"></span>
                                </div>
                                <textarea name="message" id="message" class="form-control" data-validation-engine="validate[ required]" placeholder="{\App\Language::translate('LBL_WRITE_YOUR_MESSAGE_HERE', $MODULE)}"></textarea>

                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-success" type="submit" name="saveButton">
                            <span class="fas fa-check"></span>&nbsp;<strong>{\App\Language::translate('LBL_SEND', $MODULE)}</strong>
                        </button>
                        <button class="btn btn-warning" type="reset" data-dismiss="modal">
                            <span class="fas fa-times"></span>&nbsp;<strong>{\App\Language::translate('LBL_CANCEL', $MODULE)}</strong>
                        </button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    <script type="text/javasctipt">
    $(document).ready(function(){
         console.log('changed');
    });
    </script>
    <!-- /tpl-Base-SendSMSForm -->
{/strip}




So basically, here's the only change from original SenSmsForm.tpl

Replace :

````

````

with :

<textarea name="message" id="message" class="form-control" data-validation-engine="validate[ required]" placeholder="{\App\Language::translate('LBL_WRITE_YOUR_MESSAGE_HERE', $MODULE)}"></textarea>

Was this page helpful?
0 / 5 - 0 ratings

Related issues

johntonji picture johntonji  ·  3Comments

vovpff picture vovpff  ·  3Comments

serbiaserbia picture serbiaserbia  ·  3Comments

ezbank picture ezbank  ·  3Comments

vovpff picture vovpff  ·  3Comments