How to show total sum in ListView in VtigerCRM 6.5

How to show total sum in ListView in VtigerCRM 6.5

It is often necessary to calculate the total amount in a VtigerCRM directory or ListView. With a similar task to me recently asked the customer. He asked to calculate the balance sheet total in the list of accounts. Those. so that the total amount for all accounts in the list is displayed below the list. An example implementation is shown in the picture.

Below I will describe in detail how such a solution was implemented.

So, the first thing we start with is calculate the total amount we receive in the list. The simplest solution is to bypass the array and sum up the balance field on the array — this is the name of the final field in the Vtiger CRM accounts.

To do this, we edit the modules / Invoice / views / List.php file, by default there is an empty class there, so you can safely delete and paste everything here:

<?php

class Invoice_List_View extends Inventory_List_View {

    /*

 * Function to initialize the required data in smarty to display the List View Contents

 */

    public function initializeListViewContents(Vtiger_Request $request, Vtiger_Viewer $viewer) {

        $moduleName = $request->getModule();

        $cvId = $this->viewName;

        $pageNumber = $request->get('page');

        $orderBy = $request->get('orderby');

        $sortOrder = $request->get('sortorder');

        if($sortOrder == "ASC"){

            $nextSortOrder = "DESC";

            $sortImage = "icon-chevron-down";

        }else{

            $nextSortOrder = "ASC";

            $sortImage = "icon-chevron-up";

        }

 

        if(empty ($pageNumber)){

            $pageNumber = '1';

        }

 

        $listViewModel = Vtiger_ListView_Model::getInstance($moduleName, $cvId);

        $currentUser = Users_Record_Model::getCurrentUserModel();

 

        $linkParams = array('MODULE'=>$moduleName, 'ACTION'=>$request->get('view'), 'CVID'=>$cvId);

        $linkModels = $listViewModel->getListViewMassActions($linkParams);

 

        $pagingModel = new Vtiger_Paging_Model();

        $pagingModel->set('page', $pageNumber);

        $pagingModel->set('viewid', $request->get('viewname'));

 

        if(!empty($orderBy)) {

            $listViewModel->set('orderby', $orderBy);

            $listViewModel->set('sortorder',$sortOrder);

        }

 

        $searchKey = $request->get('search_key');

        $searchValue = $request->get('search_value');

        $operator = $request->get('operator');

        if(!empty($operator)) {

            $listViewModel->set('operator', $operator);

            $viewer->assign('OPERATOR',$operator);

            $viewer->assign('ALPHABET_VALUE',$searchValue);

        }

        if(!empty($searchKey) && !empty($searchValue)) {

            $listViewModel->set('search_key', $searchKey);

            $listViewModel->set('search_value', $searchValue);

        }

 

        $searchParmams = $request->get('search_params');

        if(empty($searchParmams)) {

            $searchParmams = array();

        }

        $transformedSearchParams = $this->transferListSearchParamsToFilterCondition($searchParmams, $listViewModel->getModule());

        $listViewModel->set('search_params',$transformedSearchParams);

 

 

        //To make smarty to get the details easily accesible

        foreach($searchParmams as $fieldListGroup){

            foreach($fieldListGroup as $fieldSearchInfo){

                $fieldSearchInfo['searchValue'] = $fieldSearchInfo[2];

                $fieldSearchInfo['fieldName'] = $fieldName = $fieldSearchInfo[0];

                $searchParmams[$fieldName] = $fieldSearchInfo;

            }

        }

 

 

        if(!$this->listViewHeaders){

            $this->listViewHeaders = $listViewModel->getListViewHeaders();

        }

        if(!$this->listViewEntries){

            $this->listViewEntries = $listViewModel->getListViewEntries($pagingModel);

        }

        $noOfEntries = count($this->listViewEntries);

 

        $viewer->assign('MODULE', $moduleName);

 

        if(!$this->listViewLinks){

            $this->listViewLinks = $listViewModel->getListViewLinks($linkParams);

        }

        $viewer->assign('LISTVIEW_LINKS', $this->listViewLinks);

 

        $viewer->assign('LISTVIEW_MASSACTIONS', $linkModels['LISTVIEWMASSACTION']);

 

        $viewer->assign('PAGING_MODEL', $pagingModel);

        $viewer->assign('PAGE_NUMBER',$pageNumber);

 

        $viewer->assign('ORDER_BY',$orderBy);

        $viewer->assign('SORT_ORDER',$sortOrder);

        $viewer->assign('NEXT_SORT_ORDER',$nextSortOrder);

        $viewer->assign('SORT_IMAGE',$sortImage);

        $viewer->assign('COLUMN_NAME',$orderBy);

 

        $viewer->assign('LISTVIEW_ENTRIES_COUNT',$noOfEntries);

        $viewer->assign('LISTVIEW_HEADERS', $this->listViewHeaders);

        $viewer->assign('LISTVIEW_ENTRIES', $this->listViewEntries);

 

        if (PerformancePrefs::getBoolean('LISTVIEW_COMPUTE_PAGE_COUNT', false)) {

            if(!$this->listViewCount){

                $this->listViewCount = $listViewModel->getListViewCount();

            }

            $totalCount = $this->listViewCount;

            $pageLimit = $pagingModel->getPageLimit();

            $pageCount = ceil((int) $totalCount / (int) $pageLimit);

 

            if($pageCount == 0){

                $pageCount = 1;

            }

            $viewer->assign('PAGE_COUNT', $pageCount);

            $viewer->assign('LISTVIEW_COUNT', $totalCount);

        }

        // Sergey Emelyanov add calculation of current balance on list view page

        $curbal = 0;

        if (!empty($this->listViewEntries)) {

            foreach ($this->listViewEntries as $entry) {

                $curbal += $entry->get('balance');

            }

        }

        $viewer->assign('CURBALANCE', $curbal);

        // Sergey Emelyanov end calculation

        $viewer->assign('LIST_VIEW_MODEL', $listViewModel);

        $viewer->assign('GROUPS_IDS', Vtiger_Util_Helper::getGroupsIdsForUsers($currentUser->getId()));

        $viewer->assign('IS_RECORD_CREATABLE', $listViewModel->getModule()->isPermitted('CreateView'));

        $viewer->assign('IS_MODULE_EDITABLE', $listViewModel->getModule()->isPermitted('EditView'));

        $viewer->assign('IS_MODULE_DELETABLE', $listViewModel->getModule()->isPermitted('Delete'));

        $viewer->assign('SEARCH_DETAILS', $searchParmams);

    }

}

?>

In this code, we supplement our class, overwrite the method of receiving invoices and in it transfer the total amount of the balances to the template.

So, we have transferred the balances to the template, now it is up to the small thing - layout. It is necessary to display all this on the screen.

To do this, we create a file layouts / vlayout / modules / Invoice / ListViewContents.tpl with the following contents:

{strip}

<input type="hidden" id="view" value="{$VIEW}" />

<input type="hidden" id="pageStartRange" value="{$PAGING_MODEL->getRecordStartRange()}" />

<input type="hidden" id="pageEndRange" value="{$PAGING_MODEL->getRecordEndRange()}" />

<input type="hidden" id="previousPageExist" value="{$PAGING_MODEL->isPrevPageExists()}" />

<input type="hidden" id="nextPageExist" value="{$PAGING_MODEL->isNextPageExists()}" />

<input type="hidden" id="alphabetSearchKey" value= "{$MODULE_MODEL->getAlphabetSearchField()}" />

<input type="hidden" id="Operator" value="{$OPERATOR}" />

<input type="hidden" id="alphabetValue" value="{$ALPHABET_VALUE}" />

<input type="hidden" id="totalCount" value="{$LISTVIEW_COUNT}" />

<input type='hidden' value="{$PAGE_NUMBER}" id='pageNumber'>

<input type='hidden' value="{$PAGING_MODEL->getPageLimit()}" id='pageLimit'>

<input type="hidden" value="{$LISTVIEW_ENTRIES_COUNT}" id="noOfEntries">

 

{assign var = ALPHABETS_LABEL value = vtranslate('LBL_ALPHABETS', 'Vtiger')}

{assign var = ALPHABETS value = ','|explode:$ALPHABETS_LABEL}

 

<div class="alphabetSorting noprint">

<table width="100%" class="table-bordered" style="border: 1px solid #ddd;table-layout: fixed">

<tbody>

<tr>

{foreach item=ALPHABET from=$ALPHABETS}

<td class="alphabetSearch textAlignCenter cursorPointer {if $ALPHABET_VALUE eq $ALPHABET} highlightBackgroundColor {/if}" style="padding : 0px !important"><a id="{$ALPHABET}" href="#">{$ALPHABET}</a></td>

{/foreach}

</tr>

</tbody>

</table>

</div>

<div id="selectAllMsgDiv" class="alert-block msgDiv noprint">

<strong><a id="selectAllMsg">{vtranslate('LBL_SELECT_ALL',$MODULE)}&nbsp;{vtranslate($MODULE ,$MODULE)}&nbsp;(<span id="totalRecordsCount"></span>)</a></strong>

</div>

<div id="deSelectAllMsgDiv" class="alert-block msgDiv noprint">

<strong><a id="deSelectAllMsg">{vtranslate('LBL_DESELECT_ALL_RECORDS',$MODULE)}</a></strong>

</div>

<div class="contents-topscroll noprint">

<div class="topscroll-div">

&nbsp;

</div>

</div>

<div class="listViewEntriesDiv contents-bottomscroll">

<div class="bottomscroll-div">

<input type="hidden" value="{$ORDER_BY}" id="orderBy">

<input type="hidden" value="{$SORT_ORDER}" id="sortOrder">

<span class="listViewLoadingImageBlock hide modal noprint" id="loadingListViewModal">

<img class="listViewLoadingImage" src="{vimage_path('loading.gif')}" alt="no-image" title="{vtranslate('LBL_LOADING', $MODULE)}"/>

<p class="listViewLoadingMsg">{vtranslate('LBL_LOADING_LISTVIEW_CONTENTS', $MODULE)}........</p>

</span>

{assign var=WIDTHTYPE value=$CURRENT_USER_MODEL->get('rowheight')}

<table class="table table-bordered listViewEntriesTable">

<thead>

<tr class="listViewHeaders">

<th width="5%">

<input type="checkbox" id="listViewEntriesMainCheckBox" />

</th>

{foreach item=LISTVIEW_HEADER from=$LISTVIEW_HEADERS}

<th nowrap {if $LISTVIEW_HEADER@last} colspan="2" {/if}>

<a href="javascript:void(0);" class="listViewHeaderValues" data-nextsortorderval="{if $COLUMN_NAME eq $LISTVIEW_HEADER->get('column')}{$NEXT_SORT_ORDER}{else}ASC{/if}" data-columnname="{$LISTVIEW_HEADER->get('column')}">{vtranslate($LISTVIEW_HEADER->get('label'), $MODULE)}

&nbsp;&nbsp;{if $COLUMN_NAME eq $LISTVIEW_HEADER->get('column')}<img class="{$SORT_IMAGE} icon-white">{/if}</a>

</th>

{/foreach}

</tr>

</thead>

        {if $MODULE_MODEL->isQuickSearchEnabled()}

        <tr>

            <td></td>

{foreach item=LISTVIEW_HEADER from=$LISTVIEW_HEADERS}

             <td>

                 {assign var=FIELD_UI_TYPE_MODEL value=$LISTVIEW_HEADER->getUITypeModel()}

                {include file=vtemplate_path($FIELD_UI_TYPE_MODEL->getListSearchTemplateName(),$MODULE_NAME)

                    FIELD_MODEL= $LISTVIEW_HEADER SEARCH_INFO=$SEARCH_DETAILS[$LISTVIEW_HEADER->getName()] USER_MODEL=$CURRENT_USER_MODEL}

             </td>

{/foreach}

<td>

<button class="btn" data-trigger="listSearch">{vtranslate('LBL_SEARCH', $MODULE )}</button>

</td>

        </tr>

        {/if}

{foreach item=LISTVIEW_ENTRY from=$LISTVIEW_ENTRIES name=listview}

<tr class="listViewEntries" data-id='{$LISTVIEW_ENTRY->getId()}' data-recordUrl='{$LISTVIEW_ENTRY->getDetailViewUrl()}' id="{$MODULE}_listView_row_{$smarty.foreach.listview.index+1}">

            <td  width="5%" class="{$WIDTHTYPE}">

<input type="checkbox" value="{$LISTVIEW_ENTRY->getId()}" class="listViewEntriesCheckBox"/>

</td>

{foreach item=LISTVIEW_HEADER from=$LISTVIEW_HEADERS}

{assign var=LISTVIEW_HEADERNAME value=$LISTVIEW_HEADER->get('name')}

<td class="listViewEntryValue {$WIDTHTYPE}" data-field-type="{$LISTVIEW_HEADER->getFieldDataType()}" nowrap>

{if ($LISTVIEW_HEADER->isNameField() eq true or $LISTVIEW_HEADER->get('uitype') eq '4') and $MODULE_MODEL->isListViewNameFieldNavigationEnabled() eq true }

<a href="{$LISTVIEW_ENTRY->getDetailViewUrl()}">{$LISTVIEW_ENTRY->get($LISTVIEW_HEADERNAME)}</a>

{else if $LISTVIEW_HEADER->get('uitype') eq '72'}

{assign var=CURRENCY_SYMBOL_PLACEMENT value={$CURRENT_USER_MODEL->get('currency_symbol_placement')}}

{if $CURRENCY_SYMBOL_PLACEMENT eq '1.0$'}

{$LISTVIEW_ENTRY->get($LISTVIEW_HEADERNAME)}{$LISTVIEW_ENTRY->get('currencySymbol')}

{else}

{$LISTVIEW_ENTRY->get('currencySymbol')}{$LISTVIEW_ENTRY->get($LISTVIEW_HEADERNAME)}

{/if}

{else}

                    {if $LISTVIEW_HEADER->getFieldDataType() eq 'double'}

                        {decimalFormat($LISTVIEW_ENTRY->get($LISTVIEW_HEADERNAME))}

                    {else}

                        {$LISTVIEW_ENTRY->get($LISTVIEW_HEADERNAME)}

                    {/if}

{/if}

{if $LISTVIEW_HEADER@last}

</td><td nowrap class="{$WIDTHTYPE}">

<div class="actions pull-right">

<span class="actionImages">

<a href="{$LISTVIEW_ENTRY->getFullDetailViewUrl()}"><i title="{vtranslate('LBL_SHOW_COMPLETE_DETAILS', $MODULE)}" class="icon-th-list alignMiddle"></i></a>&nbsp;

{if $IS_MODULE_EDITABLE}

<a href='{$LISTVIEW_ENTRY->getEditViewUrl()}'><i title="{vtranslate('LBL_EDIT', $MODULE)}" class="icon-pencil alignMiddle"></i></a>&nbsp;

{/if}

{if $IS_MODULE_DELETABLE}

<a class="deleteRecordButton"><i title="{vtranslate('LBL_DELETE', $MODULE)}" class="icon-trash alignMiddle"></i></a>

{/if}

</span>

</div></td>

{/if}

</td>

{/foreach}

</tr>

{/foreach}

</table>

 

<!--added this div for Temporarily -->

{if $LISTVIEW_ENTRIES_COUNT eq '0'}

<table class="emptyRecordsDiv">

<tbody>

<tr>

<td>

{assign var=SINGLE_MODULE value="SINGLE_$MODULE"}

                    {* SalesPlatform.ru begin *}

                    {vtranslate('LBL_NOT_FOUND')} {vtranslate($MODULE, $MODULE)}.{if $IS_MODULE_EDITABLE} {vtranslate('LBL_CREATE')} <a href="{$MODULE_MODEL->getCreateRecordUrl()}">{vtranslate($SINGLE_MODULE, $MODULE)}</a>{/if}

{*{vtranslate('LBL_NO')} {vtranslate($MODULE, $MODULE)} {vtranslate('LBL_FOUND')}.{if $IS_MODULE_EDITABLE} {vtranslate('LBL_CREATE')} <a href="{$MODULE_MODEL->getCreateRecordUrl()}">{vtranslate($SINGLE_MODULE, $MODULE)}</a>{/if}*}

                    {* SalesPlatform.ru end *}

</td>

</tr>

</tbody>

</table>

{/if}

</div>

{* Sergey Emelyanov add balance total*}

<br>

<div><p>{vtranslate('LBL_BALANCE TOTAL',$MODULE)} &nbsp;&nbsp; {$CURBALANCE} {decimalFormat($LISTVIEW_ENTRY->get('currencySymbol'))}</p></div>

</div>

{/strip}

Here we simply print the line we need in the p tag. If you wish, you can apply your styles to it by changing the color in it.

Notice that the text is output through the LBL_BALANCE_TOTAL language variable. To decrypt it, you need to add the following line to the languages / en_us / Invoice.php file: 'LBL_BALANCE TOTAL' => 'Total for balance:', or any other translation you wish.

After these manipulations and after several page updates, a line should appear under your table that will count the total for all accounts in the filter you selected.

Popular Posts

My most popular posts

Maximum productivity on remote job
Business

Maximum productivity on remote job

I started my own business and intentionally did my best to work from anywhere in the world. Sometimes I sit with my office with a large 27-inch monitor in my apartment in Cheboksary. Sometimes I’m in the office or in some cafe in another city.

Hello! I am Sergey Emelyanov and I am hardworker
Business PHP

Hello! I am Sergey Emelyanov and I am hardworker

I am a programmer. I am an entrepreneur in my heart. I started making money from the age of 11, in the harsh 90s, handing over glassware to a local store and exchanging it for sweets. I earned so much that was enough for various snacks.

Hire Professional CRM developer for $25 per hour

I will make time for your project. Knowledge of Vtiger CRM, SuiteCRM, Laravel, and Vue.js. I offer cooperation options that will help you take advantage of external experience, optimize costs and reduce risks. Full transparency of all stages of work and accounting for time costs. Pay only development working hours after accepting the task. Accept PayPal and Payoneer payment systems. How to hire professional developer? Just fill in the form

Telegram
@sergeyem
Telephone
+4915211100235