Displaying a total at bottom of Opportunities listview in 7.10.5

I am trying to display the sum of a column on the Opportunities listview in the way described in the below article:

I used the logic hook given by user ‘Webber’ to try and show the total for “amount” at the bottom of the View Opportunities page, but seem to have broken the Opportunities module altogether, as trying to view Opportunities or Create Opportunities leads me to a screen saying “An error has occurred: There was an error processing your request, please try again at a later time.”

I am wondering if the html code portion was not upgrade safe from the time it was posted (3 years ago) until now, and how to move from here in terms of getting it to work with 7.10.5.

I am using SuiteP theme, and am posting my .php files below (all credit on code goes to user ‘Webber’)

custom/modules/Opportunities/logic_hooks.php

<?php
// Do not store anything in this file that is not part of the array or the hook version.  This file will
// be automatically rebuilt in the future.
 $hook_version = 1;
$hook_array = Array();
// position, file, function
$hook_array['before_save'] = Array();
$hook_array['before_save'][] = Array(77, 'updateGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateGeocodeInfo');
$hook_array['after_save'] = Array();
$hook_array['after_save'][] = Array(77, 'updateRelatedMeetingsGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateRelatedMeetingsGeocodeInfo');
$hook_array['after_save'][] = Array(78, 'updateRelatedProjectGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateRelatedProjectGeocodeInfo');
$hook_array['after_relationship_add'] = Array();
$hook_array['after_relationship_add'][] = Array(77, 'addRelationship', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'addRelationship');
$hook_array['after_relationship_delete'] = Array();
$hook_array['after_relationship_delete'][] = Array(77, 'deleteRelationship', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'deleteRelationship');

//above this comment was default arrays, below was added by instruction of referenced article

$hook_array['after_retrieve'] = Array();
$hook_array['process_record'] = Array();
$hook_array['after_ui_frame'] = Array();
$hook_array['process_record'][] = Array(1, 'callForEachRecord', 'custom/modules/Opportunities/OpportunitiesaddTotalToOpp_LogicHook.php','addTotalToOpp', 'callForEachRecord');
$hook_array['after_ui_frame'][] = Array(1, 'addSumToPage', 'custom/modules/Opportunities/OpportunitiesaddTotalToOpp_LogicHook.php','addTotalToOpp', 'addSumToPage');

?>

custom/modules/Opportunities/OpportunitiesaddTotalToOpp_LogicHook.php

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

class addTotalToOpp {

        protected static $yourSum = 0;
        function callForEachRecord(&$focus, $event, $arguments) {
                $focus->custom_fields->retrieve();
                self::$yourSum += $focus->amount;
        }

        function addSumToPage(&$focus, $event, $arguments) {
                if ($GLOBALS['action'] == 'index' || $GLOBALS['action'] == 'ListView') {
                        $yourSum = self::$yourSum;
                        echo <<<EOHTML
<script type="text/javascript">
<!--
$('<p align="center" vertical-align="middle"><b>Total Amount: {$yourSum}</b></p>').insertBefore('.paginationChangeButtons');
-->
</script>
EOHTML;
                }
        }
}
?>

You need to check your web server log to see what the PHP error is.

If you’re using Apache, on many installations it’s called php_errors.log

1 Like
  1. Before you do this:
$hook_array['process_record'][] = Array(1, 'callForEachRecord', 'custom/modules/Opportunities/OpportunitiesaddTotalToOpp_LogicHook.php','addTotalToOpp', 'callForEachRecord');

You should declare the array:

$hook_array['process_record'] = Array();

However you have to be sure that you are not overwriting the array as it may have been already declared elsewhere.

  1. Other point: Why do you declare things that you are not using?:
$hook_array['after_retrieve'] = Array();
$hook_array['process_record'] = Array();
$hook_array['after_ui_frame'] = Array();

In any case, if I were you I would initialise all these arrays at the top of the file.

  1. Your function callForEachRecord only adds one amount, when I understand that you would like to run a a for each loop and add all amounts. Is this correct?
    Do yu know the names of the variables that you want to sum? Have you looked in the database? Do you know the data structure? Are you sure that this is the way you get these values?

I reccommend that yo have a look at this example:
http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_6.5/Module_Framework/Logic_Hooks/Module_Hooks/

And the Manual:
http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_6.5/Module_Framework/Logic_Hooks/Application_Hooks/after_ui_frame/

http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_6.5/Module_Framework/Logic_Hooks/Application_Hooks/

http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_6.5/Module_Framework/Logic_Hooks/Module_Hooks/

http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_6.5/Module_Framework/Logic_Hooks/

I don’t know these answers but I hope they will help you!

2 Likes

Thank you both for your replies!

[color=#ff0000]In response to pgr, I was unable to find php_errors.log, but in suitecrm.log I was able to find the following error:
[FATAL] field_defs should be an array
I am not sure what that means in terms of my hook, can you help me understand what exactly this means?[/color]

[color=#000088]In response to amariussi, am I not declaring the “process_record” array beforehand in the original code? I had thought I had those in the right order. I have taken out the declaration for “after_retrieve”, for I realize its not being used, thank you for pointing that out. As for your third point, I do not have a firm grasp on this but am reading and learning toward getting it, I just used the code that has been claimed as functional by multiple users in the referenced article. I am mainly concerned with the fact that it seems to break all Opportunities pages, which leads me to believe that it is an issue with the javascript portion as that would be the only part affecting the page itself and its layout. If I’m understanding it correctly, that is, feel free to correct me if I am not. [/color]

Once again, thank you both for your responses! I will continue to work on it and report back with any progress, and will take any further suggestions/corrections/advice you all have to offer.

I am sorry I just realised the the array was in fact declared.

Maybe you can try some test like:

As soon as you enter one logic hook function you echo something and then exit

Then you can do it at the end of the function.

You may also do it at the top and in the middle and at the end of the files you have modified, and so on in each part of your script.

This will help you to find where your script is failing.

You should also lokk at both the PHP/Apache error log and the SuiteCRM log.

1 Like

Sorry for my late reply on here, when testing where would I see the echos? I cannot seem to get any logic hook, no matter how simple running on the Opportunities listview without it breaking all of the module and displaying an error whenever I try to view or create Opportunities.

I have a report generating the sum of all amounts in opportunities, would it be easier to try to display that report value on the Opportunities listview than to try and calculate the sum and display it all in one Logic Hook? I wouldn’t know where to start in terms of taking the value from the report to get it on the listview page, but maybe someone has an idea that may work to get me started?

Once again, thank all for your time and for any advice/help given.

What is the path to your web server log? Do you know? That’s where the answers are.

Sorry if I am way off, still an intern learning the CRM, but I had found some edits made to make the error message I was receiving more descriptive at the following link:
https://github.com/salesagility/SuiteCRM/commit/b89c4853f562d8cdb9ac76e0ed3eb4156e68978a?diff=split

The specific error message I am currently getting in suitecrm.log is:
[5067][58b312ec-3a89-431f-eec9-5b1803cb1e69][FATAL] SugarBean::populateDefaultValues $field_defs should be an array

Is this the error log file you were talking about? If so, can you help me interpret it? And if not, can you help point me in the right direction please?

I believe that error is a false positive: I’ve seen it happen in many installations in the past month, even when there are no problems. It is likely not related to your difficulty.

That is not the log I’m asking for.

You need to follow this sequence

  1. What is the name of my web server? e.g. Apache
  2. Where is the configuration file it uses?
  3. That file specifies the error log is placed where? What is it called (usually php_errors.log)

If you place this line of code at the beginning of index.php

$kaboom=3/0;

Then it will generate a warning “division by zero” in the web server log. That is a way to make sure you’re looking in the right place.

1 Like

I see in the php.ini file that there should be a php_errors.log file being created, but I cannot seem to find it…is there a specific directory it is usually under?

php.ini lines 57-58

error_log = php_errors.log;
error_log = syslog;

Look for it with

find / -name php_errors.log 2>/dev/null
1 Like

strike that, I found it, give me a moment to try and interpret what I see and I will be back either with a solution or more questions shortly

posting here, I’l be reading through it and trying to figure it out but if its something that stand out, please let me know

[Thu Jun 21 12:29:10.389435 2018] [php7:error] [pid 47189] [client 10.1.10.153:52595] PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function addTotal::stepTwo(), 2 passed in /var/www/html/include/utils/LogicHook.php on line 264 and exactly 3 expected in /var/www/html/custom/modules/Opportunities/Total_LogicHook.php:13\nStack trace:\n#0 /var/www/html/include/utils/LogicHook.php(264): addTotal->stepTwo('after_ui_frame', NULL)\n#1 /var/www/html/include/utils/LogicHook.php(199): LogicHook->process_hooks(Array, 'after_ui_frame', NULL)\n#2 /var/www/html/include/MVC/View/SugarView.php(209): LogicHook->call_custom_logic('Opportunities', 'after_ui_frame')\n#3 /var/www/html/include/MVC/Controller/SugarController.php(432): SugarView->process()\n#4 /var/www/html/include/MVC/Controller/SugarController.php(375): SugarController->processView()\n#5 /var/www/html/include/MVC/SugarApplication.php(109): SugarController->execute()\n#6 /var/www/html/index.php(52): SugarApplication->execute()\n#7 {main}\n  thrown in /var/www/html/custom/modules/Opportunities/Total_LogicHook.php on line 13, referer: http://my.url/index.php?action=ajaxui
[Thu Jun 21 12:29:10.474386 2018] [php7:error] [pid 45822] [client 10.1.10.153:52594] script '/var/www/html/cache/index.php' not found or unable to stat, referer: http://my.url/cache/themes/SuiteP/css/customTheme/style.css?v=xAOwt6SbYw2fTsqinI0eyw

Also to note: I changed the second file name to Total_LogicHook.php, class name to addTotal and the two functions respectively to stepOne and stepTwo, for reference

Ok, so the error is telling you exactly what your problem is, the number of parameters you’re passing to the function - I’m sure you can fix it with this information.

1 Like

removing the &$focus argument from the second function got it working, thank you for your help! I am working on making it better in terms of two issues I am running into that the others who worked on this years ago were also running into, which are that the total displays on the top and the bottom of the list, and that it only sums the items in the list that are visible on the current page, but slow and steady progress. At least it displays now. :slight_smile:

Once again, shoutout to user Webber for the initial code referenced and used!

here are the final two forms of the code that work if anyone viewing needs a reference, along with a snippet of the result:

[color=#ff0000]/…/…/custom/modules/Opportunities/logic_hook.php[/color]

<?php
// Do not store anything in this file that is not part of the array or the hook version.  This file will
// be automatically rebuilt in the future.
 $hook_version = 1;
$hook_array = Array();
// position, file, function
$hook_array['before_save'] = Array();
$hook_array['before_save'][] = Array(77, 'updateGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateGeocodeInfo');
$hook_array['after_save'] = Array();
$hook_array['after_save'][] = Array(77, 'updateRelatedMeetingsGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateRelatedMeetingsGeocodeInfo');
$hook_array['after_save'][] = Array(78, 'updateRelatedProjectGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateRelatedProjectGeocodeInfo');
$hook_array['after_relationship_add'] = Array();
$hook_array['after_relationship_add'][] = Array(77, 'addRelationship', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'addRelationship');
$hook_array['after_relationship_delete'] = Array();
$hook_array['after_relationship_delete'][] = Array(77, 'deleteRelationship', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'deleteRelationship');

$hook_array['process_record'] = Array();
$hook_array['after_ui_frame'] = Array();
$hook_array['process_record'][] = Array(1, 'addTotalToOpp', 'custom/modules/Opportunities/Total_LogicHook.php','addTotalToOpp', 'callForEachRecord');
$hook_array['after_ui_frame'][] = Array(1, 'addTotalToOpp', 'custom/modules/Opportunities/Total_LogicHook.php','addTotalToOpp', 'addSumToPage');

?>

[color=#ff0000]/…/…/custom/modules/Opportunities/Total_LogicHook.php[/color]

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');

class addTotal {

        protected static $yourSum = 0;
        function stepOne(&$focus, $event, $arguments) {
                $focus->custom_fields->retrieve();      //necessary if the field you're summing is a custom field
                self::$yourSum += $focus->probability_forecast_c;              
        }

        function stepTwo($event, $arguments) {
                if ($GLOBALS['action'] == 'index' || $GLOBALS['action'] == 'ListView') {
                        $yourSum = self::$yourSum;
                        echo <<<EOHTML
<script type="text/javascript">
<!--
$('<p align="center" vertical-align="middle"><b>Total Probability Forecast: {$yourSum}</b></p>').insertBefore('.paginationChangeButtons');
-->
</script>
EOHTML;
                }

        }

}
//&$focus,
?>

1 Like

If you’re still subscribed to this thread, I wanted to make a correction to the code I posted in my last comment (I changed variable names in one file but not the other when copying and pasting here, rendering it confusing and not functional) and also ask one more question…here is the corrected code, followed by my question:

[color=#000088]/custom/modules/Opportunities/logic_hooks.php[/color]


<?php
// Do not store anything in this file that is not part of the array or the hook version.  This file will
// be automatically rebuilt in the future.
 $hook_version = 1;
$hook_array = Array();
// position, file, function
$hook_array['before_save'] = Array();
$hook_array['before_save'][] = Array(77, 'updateGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateGeocodeInfo');
$hook_array['after_save'] = Array();
$hook_array['after_save'][] = Array(77, 'updateRelatedMeetingsGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateRelatedMeetingsGeocodeInfo');
$hook_array['after_save'][] = Array(78, 'updateRelatedProjectGeocodeInfo', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'updateRelatedProjectGeocodeInfo');
$hook_array['after_relationship_add'] = Array();
$hook_array['after_relationship_add'][] = Array(77, 'addRelationship', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'addRelationship');
$hook_array['after_relationship_delete'] = Array();
$hook_array['after_relationship_delete'][] = Array(77, 'deleteRelationship', 'modules/Opportunities/OpportunitiesJjwg_MapsLogicHook.php','OpportunitiesJjwg_MapsLogicHook', 'deleteRelationship');
//above this comment was default arrays, below was added by instruction of referenced article
$hook_array['process_record'] = Array();
$hook_array['after_ui_frame'] = Array();
$hook_array['process_record'][] = Array(1, 'addTotal', 'custom/modules/Opportunities/Total_LogicHook.php','addTotal', 'stepOne');
$hook_array['after_ui_frame'][] = Array(1, 'addTotal', 'custom/modules/Opportunities/Total_LogicHook.php','addTotal', 'stepTwo');
?>

[color=#000088]/custom/modules/Opportunities/Total_LogicHook.php[/color]

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
class addTotal {
        protected static $yourSum = 0;
        function stepOne(&$focus, $event, $arguments) {
                $focus->custom_fields->retrieve();
                self::$yourSum += $focus->probability_forecast_c;
        }
        function stepTwo($event, $arguments) {
                if ($GLOBALS['action'] == 'index' || $GLOBALS['action'] == 'ListView') {
                        $yourSum = self::$yourSum;
                        echo <<<EOHTML
<script type="text/javascript">
<!--
$('<p align="center" vertical-align="middle"><b>Total Probability Forecast: {$yourSum}</b></p>').insertBefore('.paginationChangeButtons');
-->
</script>
EOHTML;
                }
        }
}
?>

My question being, this code displays the total for the selections viewed on that page, but not the total throughout the module (shows sum of results 1-20, on next page shows sum of 21-40, etc)…I am not familiar enough with Suite to be able to sum up this value pulling from the database instead of just the current page, but I have a report running that has the grand total, is there a way that you are familiar with for me to pull that value from the report and display it here in place of the calculated ‘yourSum’ value?

In step One you don’t need to use focus as that has the limited records shown in the list view. Also remove the Hook from Process record as it will slow down the VIEW to show records if the Number of users are more. Having the Hook only for Step Two, Do something like below.

$myOpportunities = BeanFactory::getBean('Opportunities');
$allOpportunities = $myOpportunities->get_full_list('','status ="open"',false, 0);

if ($allOpportunities != null) {
foreach( $allOpportunities as $opportunity)
{
       self::$yourSum += $opportunity->probability_forecast_c;
}

The syntax/parameters for get_full_list Function is as below

get_full_list($order_by = "", $where = "", $check_dates=false,  $show_deleted = 0)
2 Likes