Thursday, 28 February 2013

Add custom module in Site Map

Greetings!

To set custom module in site map, you need to follow some steps.

Step 1: First, check if you have Menu.php under modules/<YOUR_CUSTOM_MODULE>/

If no, please add it.

Step 2: Copy modules/Home/sitemap.tpl in custom/modules/Home/ and following line wherever you want to show your module.

<div>{$<YOUR_MODULE_NAME_ALL_IN_CAPS>}</div>

We hereby consider, your custom module is visible in module tab.

Hope it helps. Feel free to drop your comments below.

Create Date time combo manually

Greetings!

In a manual page if you want to give a date time combo field, here is the code snippet you'd need on javascript.


var now = new Date();
        if (now.getMonth() == 11) {
            var currentTime = new Date(now.getFullYear() + 1, 0, 1);
        } else {
            var currentTime = new Date(now.getFullYear(), now.getMonth() + 1, 1);
        }
        var month = currentTime.getMonth() + 1;
        var day = currentTime.getDate();
        var year = currentTime.getFullYear();
        day = day.toString();
        month = month.toString();
     
        if(day.length == '1')
            day = '0' + day;
     
        if(month.length == '1')
            month = '0' + month;
 
    var defaultDate  = month + '/' + day +'/' + year;
    var datetimecombo = '<tr valign="middle"><td width="25%" valign="top" scope="row" id="date_start_label">LABEL_OF_YOUR_FIELD<span class="required">*</span></td><td nowrap=""><input type="text"  tabindex="102" title="" maxlength="10" size="11" value="' + defaultDate +'" name="date_start" id="date_start" autocomplete="off"><img border="0" align="absmiddle" id="date_start_trigger" alt="Enter Date" src="index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName=jscalendar.gif""index.php?entryPoint=getImage&themeName='+SUGAR.themes.theme_name+'&imageName=jscalendar.gif">&nbsp;</td><td nowrap=""><div id="date_start_time_section"><select tabindex="102" id="date_start_hours" size="1" class="datetimecombo_time"><option></option><option value="00">00</option><option value="01">01</option><option value="02">02</option><option value="03">03</option><option value="04">04</option><option value="05">05</option><option value="06">06</option><option value="07">07</option><option value="08">08</option><option selected="" value="09">09</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option></select>&nbsp;:&nbsp;<select onchange tabindex="102" id="date_start_minutes" size="1" class "datetimecombo_time"><option></option><option value="00">00</option><option selected="" value="15">15</option><option value="30">30</option><option value="45">45</option></select></div></td></tr>';

For now the dropdown is hard coded, but you can get it by > Getting dropdown options in Javascript

Get current date in logged in user's format by

var todayDate = new Date();
var todayDateinUserFormat = todayDate.toLocaleFormat(cal_date_format);
alert(todayDateinUserFormat);

Tuesday, 26 February 2013

Hide Select and Cancel buttons from Relate type fields

Greetings!

To Do: Hide select and cancel buttons from relate type field.


Before
After

Step 1: To make it happen, you first need to check if you have a file editviewdefs.php under custom/modules/<Desired_module>/metadata/ if not, go to Admin > Studio > <Desired_module> > Layout > Edit View > and press Save and Deploy.

Then you will see that  custom/modules/<Desired_module>/metadata/ has editviewdefs.php in it. Open it and search for the field you want to hide those buttons.

If the field is defined in following manner,

0 => '<YOUR_FIELD_NAME>',

Then you need to change it to,

0 => array('name' => '<YOUR_FIELD_NAME>',
'displayParams' => array('hide_Buttons' => true,)),

If your field is already an array like,

0 =>
          array (
            'name' => '<YOUR_FIELD_NAME>',
            'studio' => 'visible',
            'label' => '<LBL_YOUR_FIELD_NAME>',
),

 just add following line in that array

'displayParams' => array('hide_Buttons' => true,)

So it should look like following at the end

0 =>
          array (
            'name' => '<YOUR_FIELD_NAME>',
            'studio' => 'visible',
            'label' => '<LBL_YOUR_FIELD_NAME>',
            'displayParams' => array('hideButtons' => true),
          ),

Step 2: Go to Admin > Repair > Quick Repair and Rebuild. And done!

Feel free to leave comments below.

Monday, 25 February 2013

Mark a field Required conditionally

Greetings!

To Do: On my custom module "UT_Blogs" I will mark "Description" field required if status of My Blog Post is Publish.

Step 1: Check if you have a file named view.edit.php under custom/modules/<desired_module>/views folder.

  • If you have, skip to Step 2.
  • If you do not have, like me, follow..

Check if you have a file named view.edit.php under modules/<desired_module>/views folder.

  • If you have, copy that file and paste under custom/modules/<desired_module>/views folder and skip to Step 2.
  • If you do not have it, create a file named view.edit.php under custom/modules/<desired_module>/views folder.
Step 2: Write following code in that file.

<?php

require_once('include/MVC/View/views/view.edit.php');
/*
 * replace UT_Blogs with the module your are dealing with
 */

class UT_BlogsViewEdit extends ViewEdit {

    public function __construct() {
        parent::ViewEdit();
        $this->useForSubpanel = true; // this variable specifies that these changes should work for subpanel
        $this->useModuleQuickCreateTemplate = true; // quick create template too
    }

    function display() {
       
        global $mod_strings;
        //JS to make field mendatory
        $jsscript = <<<EOQ
                   <script>
                       // Change blog_status_c to the field of your module
                       $('#blog_status_c').change(function() {
                            makerequired(); // onchange call function to mark the field required
                       });
                     function makerequired()
                     {
                        var status = $('#blog_status_c').val(); // get current value of the field
                         if(status == 'Publish'){ // check if it matches the condition: if true,
                                addToValidate('EditView','description','varchar',true,'{$mod_strings['LBL_DESCRIPTION']}');    // mark Description field required
                                $('#description_label').html('{$mod_strings['LBL_DESCRIPTION']}: <font color="red">*</font>'); // with red * sign next to label
                            }
                            else{
                                removeFromValidate('EditView','description');                        // else remove the validtion applied
                                $('#description_label').html('{$mod_strings['LBL_DESCRIPTION']}: '); // and give the normal label back
                            }
                    }
                    makerequired(); //Call at onload while editing a Published blog record
                </script>
EOQ;
        parent::display();
        echo $jsscript;     //echo the script
    }

}

Read the comments in code carefully and replace the variables as asked.

P.S. Here, <desired_module> means the module name you see in the url, for example, Contacts, Leads, UT_Blogs, etc.

You may find the field names and its labels in Admin > Studio > <Your_module> > Fields > <Choose correct field> > Take Field Name and System Label.


Here is a special mention about custom module: if you have a custom module, we prefer to create/change the file under modules/<my_custom_module>/views


Step 3: Done! Refresh the page and start testing.



Before
After

    Works with 6.5+ Versions as here we have used jQuery, but can easily changed to work with just Javascript for < 6.5 versions. Compatible with all SugarCRM flavors.

Saturday, 23 February 2013

Date control on a varchar type field

Greetings!

If you wish to give a date control on a "NON" date type field, this code snippet is what you need!

Step 1: Create a file under custom/modules/<module_name>/views named view.edit.php Do check if that file already exists under modules/<module_name>/views, if yes, copy over to custom folder and add/edit function display with following code.



global $timedate;
        $cal_dateformat = $timedate->get_cal_date_format();
        $calendar = <<<EOQ
            <script language = "javascript">
            Calendar.setup({
        inputField : "<Your_field_name>", daFormat : "{$cal_dateformat}", ifFormat : "{$cal_dateformat}", showsTime : false, button : "
<Your_field_name>", singleClick : true, step : 1
            });
            </script>
EOQ;
        echo $calendar; 

 


Change the <Your_field_name> matching with correct field name.


C'est tout!! Yup, just 1 step!

Feel free to leave your comments.

Friday, 22 February 2013

Getting dropdown options in Javascript

Greetings!

At times, I have ran into requirement of getting drop down options of a field in Javascript in SugarCRM.

Here is the code that will get you options as an array.

For example, you want to fetch values of case_status_dom, the code will be,


var statusOptions = SUGAR.language.languages.app_list_strings['case_status_dom'];

alert(statusOptions['Closed']); // alert a key and you will have its value

// You can loop through them to create an dropdown in JS itself.

var status_dd = "<select name= 'status' id='status'>";

for(var key in statusOptions){ 

    // Here "key" gives the key of options and "statusOptions[key]" gives the value of it. 
    status_dd += '<option value="'+key+'">'+statusOptions[key]+'</option>';    
}
status_dd +="</select>";



Hope this helps!

Feel free to drop your valuable comments below.


Wednesday, 20 February 2013

Creating new Dashlets based on default

Here are the steps to create new dashlet based on SugarCRM's OOB dashlet.

In this blog, we are extending My Open Tasks dashlet to show Tasks until NOW.

Step 1: Copy modules/Tasks/Dashlets/MyTasksDashlet to custom/modules/Tasks/Dashlets folder. Rename MyTasksDashlet folder to MyTasksUntilNowDashlet.

Step 2: Go to custom/modules/Tasks/Dashlets/MyTasksUntilNowDashlet/

Rename MyTasksDashlet.data.php to MyTasksUntilNowDashlet.data.php
Rename MyTasksDashlet.meta.php to MyTasksUntilNowDashlet.meta.php
Rename MyTasksDashlet.php to MyTasksUntilNowDashlet.php

Step 3: Open custom/modules/Tasks/Dashlets/MyTasksUntilNowDashlet/MyTasksUntilNowDashlet.data.php

Find and replace MyTasksDashlet to MyTasksUntilNowDashlet

Step 4:  Open custom/modules/Tasks/Dashlets/MyTasksUntilNowDashlet/MyTasksUntilNowDashlet.meta.php

Find and replace MyTasksDashlet to MyTasksUntilNowDashlet

Change LBL_LIST_MY_TASKS to LBL_LIST_MY_TASKS_UNTIL_NOW

Step 5: Open custom/modules/Tasks/Dashlets/MyTasksUntilNowDashlet/MyTasksUntilNowDashlet.php

Find and replace MyTasksDashlet to MyTasksUntilNowDashlet

Step 6: Lets guide Sugar to take new path
Change
require('modules/Tasks/Dashlets/MyTasksDashlet/MyTasksDashlet.data.php');
to
require('custom/modules/Tasks/Dashlets/MyTasksUntilNowDashlet/MyTasksUntilNowDashlet.data.php');

Step 7: Lets now add custom functionality.

Add following function in the class

function process($lvsParams = array()) {
        global $timedate, $current_user;
        $format = $timedate->get_date_time_format($current_user);
        $dbformat = date('Y-m-d H:i:s', strtotime(date($format)));

// MYSQL database
        $lvsParams['custom_where'] = ' AND DATE_FORMAT(tasks.date_start, "%Y-%m-%d %H:%i:%s") <= "'.  $dbformat.'" ';
        // MSSQL 

// $lvsParams['custom_where'] = " AND REPLACE(CONVERT(varchar, tasks.date_start,111),'/','-') = '".$dbformat."')";
        parent::process($lvsParams);
     }

Step 8:
Lets now change label of the Dashlet to know which is new dashlet we just created.
Create/Open custom/modules/Tasks/language/en_us.lang.php and add following line

<?php
$mod_strings['LBL_LIST_MY_TASKS_UNTIL_NOW'] = 'My Open Tasks until now';

Change the name which suits you more.

Step 9: Go to Admin > Repair > Quick Repair and Rebuild. Go to Home > Add dashlet and you should see the new dashlet there.

Hope it works as easy as it was while writing.


Just to make life easier pasting the final look of the main class file.
I.e. custom/modules/Tasks/Dashlets/MyTasksUntilNowDashlet/MyTasksUntilNowDashlet.php


<?php

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

require_once('include/Dashlets/DashletGeneric.php');

class MyTasksUntilNowDashlet extends DashletGeneric {

    function MyTasksUntilNowDashlet($id, $def = null) {
        require('custom/modules/Tasks/Dashlets/MyTasksUntilNowDashlet/MyTasksUntilNowDashlet.data.php');

        parent::DashletGeneric($id, $def);

        if (empty($def['title']))
            $this->title = translate('LBL_LIST_MY_TASKS', 'Tasks');

        $this->searchFields = $dashletData['MyTasksUntilNowDashlet']['searchFields'];
        $this->columns = $dashletData['MyTasksUntilNowDashlet']['columns'];
        $this->seedBean = new Task();
    }

    function process($lvsParams = array()) {
        global $timedate, $current_user;
        $format = $timedate->get_date_time_format($current_user);
        $dbformat = date('Y-m-d H:i:s', strtotime(date($format)));
       

// MYSQL database
        $lvsParams['custom_where'] = ' AND DATE_FORMAT(tasks.date_start, "%Y-%m-%d %H:%i:%s") <= "'.  $dbformat.'" ';
        // MSSQL 

// $lvsParams['custom_where'] = " AND REPLACE(CONVERT(varchar, tasks.date_start,111),'/','-') = '".$dbformat."')";
        parent::process($lvsParams);
    }

}


P.S. Comment out Mysql Query and uncomment MSSql query if you are using MSSQL database.


Feel free to leave comments.

Tuesday, 19 February 2013

Audit relate fields

Plenty of times the forums have hit the same question, since I know SugarCRM.

"How to audit relate fields?" No out of box solution for it!

But I simply love the power of logic hooks.

Lets win the world!

For this blog post, we will audit Account name field under Contacts module.

Step 1: Create a before save definition logic hook under custom/modules/Contacts/logic_hooks.php

<?php
$hook_array['before_save'][] = Array(90, 'Audit account name', 'custom/modules/Contacts/auditAcc.php','auditAccC', 'auditAccF');

Step 2: Create file auditAcc.php under custom/modules/Contacts folder and add following code.

<?php
class auditAccC{
    function auditAccF($bean){
        // check for the change
        if($bean->fetched_rel_row['account_id'] != $bean->account_id){
            // prepare an array to audit the changes in parent module's audit table
            $aChange = array();
            $aChange['field_name'] = 'account_id';
            $aChange['data_type'] = 'relate';
            $aChange['before'] = $bean->fetched_rel_row['account_id'];
            $aChange['after'] = $bean->account_id;
            // save audit entry
            $bean->db->save_audit_records($bean, $aChange);
        }
    }
}

Blink of an eye! Done! Test it out!

Hope this helps and feels like missing piece is just found!

Feel free to drop your comments.

Your valuable feedback means a lot.

Monday, 18 February 2013

[Outdated] Password settings Community Edition

SugarCRM Community Edition comes with password generation settings by default, and it is not configurable from admin panel.

You can change it by changing config_override.php file.

// Showing default values, change it as per your need 

// System generated password true/false
$sugar_config['passwordsetting']['SystemGeneratedPasswordON'] = true;

// Sent email to user with system generated password, email template id
$sugar_config['passwordsetting']['generatepasswordtmpl'] = '42378328-8034-a0f5-ae7b-510f7f8cc422';
 

// Sent email when asked for lost password, email template id
$sugar_config['passwordsetting']['lostpasswordtmpl'] = '4ebb5a24-1ab4-4c07-19d0-510f7f4b3a2b';

// Allow user to ask for forgot password true/false
$sugar_config['passwordsetting']['forgotpasswordON'] = true;


// Link sent for reset/system generated password expires true/false
$sugar_config['passwordsetting']['linkexpiration'] = true;


// Link sent for
reset/system generated password expires in integer
$sugar_config['passwordsetting']['linkexpirationtime'] = 24;

// Link sent for
reset/system generated password expires in Minutes(1), Hours(60), Days(1440) 0 is false
$sugar_config['passwordsetting']['linkexpirationtype'] = 60;

// System generated password expiration true/false

$sugar_config['passwordsetting']['systexpiration'] = 1;

// System generated password expiration time in integer 
$sugar_config['passwordsetting']['systexpirationtime'] = 7;
 

// System generated password expiration in Days(1), Weeks (7), 30 (Months)
0 is false
$sugar_config['passwordsetting']['systexpirationtype'] = '0';

// Password expires after N number of logins

$sugar_config['passwordsetting']['systexpirationlogin'] = '';

// Restriction on user/system generated password


// Minimum length of password integer
$sugar_config['passwordsetting']['minpwdlength'] = 6;
 

// One Upper Case character mandatory true/false
$sugar_config['passwordsetting']['oneupper'] = true;
 

// One lower case character mandatory true/false
$sugar_config['passwordsetting']['onelower'] = true;

// One numeric integer mandatory true/false 
$sugar_config['passwordsetting']['onenumber'] = true;

Hope this helps.

Feel free to leave your comments.

Sunday, 17 February 2013

Extending List View query

Greetings!

Today I came across a forum question which asked to hide "Closed Lost" opportunities from list view.

Simple steps and you are through!

Step 1: Create or edit custom/modules/Opportunities/views/view.list.php and add following code,


<?php

require_once('include/MVC/View/views/view.list.php');

class OpportunitiesViewList extends ViewList {

    function listViewProcess() {
        global $current_user;
        $this->processSearchForm();
        if(!$current_user->is_admin) // remove this condition if you dont want admin user to view the "Closed Lost" Opportunities.
            $this->params['custom_where'] = ' AND opportunities.sales_stage <> "Closed Lost" ';
      
        if (empty($_REQUEST['search_form_only']) || $_REQUEST['search_form_only'] == false) {
            $this->lv->setup($this->seed, 'include/ListView/ListViewGeneric.tpl', $this->where, $this->params);
            $savedSearchName = empty($_REQUEST['saved_search_select_name']) ? '' : (' - ' . $_REQUEST['saved_search_select_name']);
            echo $this->lv->display();
        }
    }

}

Step 2: Refresh list view!

P.S. Possible customizations in the query are:
> custom_select
> custom_from
> custom_where
> custom_order_by
Order by will be considered as second order by field when user clicks on other field to sort records.

Friday, 15 February 2013

REST api Example



At times developers find it so difficult to find simple and running example of REST API to perform CRUD operations on SugarCRM.. There are plenty of tutorials, blogs, developer guides explaining same thing. Still for an ease for ourselves and to the hunters of same, writing the same thing all over again. 

REST Example

This blog post explains how to login to SugarCRM instance with admin user.


<?php

// specify the REST web service to interact with

$url = '<SITE_URL_OF_SUGAR>/service/v2/rest.php';

// Open a curl session for making the call
$curl = curl_init($url);

// Tell curl to use HTTP POST

curl_setopt($curl, CURLOPT_POST, true);

// Tell curl not to return headers, but do return the response

curl_setopt($curl, CURLOPT_HEADER, false);

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);



// Set the POST arguments to pass to the Sugar server

$parameters = array(

    'user_auth' => array(

        'user_name' => 'admin',

        'password' => md5('<ADMIN_PASSWORD>'),

        ),

    );

$json = json_encode($parameters);
$postArgs = array(
    'method' => 'login',
    'input_type' => 'JSON',
    'response_type' => 'JSON',
    'rest_data' => $json,
    );
curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);

// Make the REST call, returning the result
$response = curl_exec($curl);
// Convert the result from JSON format to a PHP array
$result = json_decode($response);
if ( !is_object($result) ) {
    die("Error handling result.\n");
}
if ( !isset($result->id) ) {
    die("Error: {$result->name} - {$result->description}\n.");
}
// Echo out the session id
echo $result->id."<br />";

$session = $result->id;

Create a new record in Lead module
 As we have session id, we are logged-in!, we will use that session id to create a new record.
Here we used set_entry method for that we need three parameters

1) session : pass current session id
2) module : module name to create a record
3) name_value_list : name value list combination

Let's see that in below code snippets


$parameters = array(
    'session' => $session, //Session ID
    'module' => 'Leads',  //Module name
    'name_value_list' => array (
            array('name' => 'first_name', 'value' => 'David'),
            array('name' => 'last_name', 'value' => 'Boris'),
            array('name' => 'status', 'value' => 'New'),
            array('name' => 'lead_source', 'value' => 'Web Site')
        ),
    );
$json = json_encode($parameters);
$postArgs = 'method=set_entry&input_type=JSON&response_type=JSON&rest_data=' . $json;

curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);

// Make the REST call, returning the result
$response = curl_exec($curl);


// Convert the result from JSON format to a PHP array
$result = json_decode($response,true);

// Get the newly created record id
$recordId = $result['id'];


print "New Record Created with ID ".$recordId;



Read detail of top 5 leads having work phone, as an example.


// Let us fetch detail of a Lead

$fields_array = array('first_name','last_name','phone_work');

$parameters = array(

    'session' => $
session,                                 //Session ID
    'module_name' => 'Leads',                             //Module name
    'query' => " leads.phone_work IS NOT NULL ",   //Where condition without "where" keyword
    'order_by' => " leads.last_name ",                 //$order_by
    'offset'  => 0,                                               //offset
    'select_fields' => $fields_array,                      //select_fields
    'link_name_to_fields_array' => array(array()),//optional
    'max_results' => 5,                                        //max results                 
    'deleted' => 'false',                                        //deleted
);

$json = json_encode($parameters);

$postArgs = array(
    'method' => 'get_entry_list',
    'input_type' => 'JSON',
    'response_type' => 'JSON',
    'rest_data' => $json,
    );

curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);

$response = curl_exec($curl);

// Convert the result from JSON format to a PHP array

$result = json_decode($response);


print "<pre>";
print_r($result);
die;

Update a lead status "New" to "Assigned" for lead which we have just created. We can use set_entry method with specified record id to update a value.


$recordId = "<Your 36 character record id>";

$parameters = array(
    'session' => $session,
    'module' => 'Leads',
    'name_value_list' => array(
            array('name' => 'id', 'value' => $recordId),  //Record id to update
            array('name' => 'status', 'value' => 'Assigned'),
        ),
    );
$json = json_encode($parameters);
$postArgs = 'method=set_entry&input_type=JSON&response_type=JSON&rest_data=' . $json;

curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);

// Make the REST call, returning the result
$response = curl_exec($curl);
// Convert the result from JSON format to a PHP array
$result = json_decode($response,true);

// Get the newly created record id
$recordId = $result['id'];
print "Record Updated, Updated id ".$recordId;

Delete a record via web-service.  It is as simple as we update record with id. Here we need to provide id and deleted equal 1.


$recordId = "<Your 36 character record id>";

$parameters = array(
    'session' => $session,
    'module' => 'Leads',
    'name_value_list' => array(
            array('name' => 'id', 'value' => $recordId),
            array('name' => 'deleted', 'value' => '1')        //Deleted flag
        ),
    );
$json = json_encode($parameters);
$postArgs = 'method=set_entry&input_type=JSON&response_type=JSON&rest_data=' . $json;

curl_setopt($curl, CURLOPT_POSTFIELDS, $postArgs);

// Make the REST call, returning the result
$response = curl_exec($curl);
// Convert the result from JSON format to a PHP array
$result = json_decode($response,true);

// Get the newly created record id
$recordId = $result['id'];

print "Record Deleted!, Deleted record id is ".$recordId;

Tuesday, 12 February 2013

Where are the queries?

Hey developers, some non-developers, have you ever thought of where the heck the queries are of List View and Sub panels?

Let me give you the file names and function names.

List View:
  • Go to include/ListView/ListViewData.php  
  • Search for function getListViewData 
  • Scroll down until you see $main_query = $ret_array['select'] . $params['custom_select'] . $ret_array['from']
  • Right below that you can print the query for List View.
Sub Panel:

  • Go to data/SugarBean.php 
  • Search for function get_union_related_list 
  • Go to the end of the function and before it returns the result echo $final_query to see the queries of subpanels.
Hope you find this post useful.

Feel free to post your comments.

Monday, 11 February 2013

Compare Closed vs Won opportunities of selected timeframe

SugarCRM by default provides a Dashlet "My Closed Opportunities", which only gives you overview of Closed Won opportunity vs Total number of Opportunities and that too doesn't have a filter.

Lets create a new dashlet extending functionality a little more, where you can filter Opportunities by 'This month', 'This Year', etc. and give you in results "Closed Won" and "Closed Lost" numbers to easily compare.

Step 1:  Create folder custom/modules/Opportunities/Dashlets/MySummaryOpportunitiesDashlet.

Step 2: Create custom/modules/Opportunities/Dashlets/MySummaryOpportunitiesDashlet/MySummaryOpportunitiesDashlet.meta.php and write following code into it.

<?php
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
global $app_strings;
$dashletMeta['MySummaryOpportunitiesDashlet'] = array('module'        => 'Opportunities',
                                                      'title'       => translate('LBL_MY_SUMMARY_OPPORTUNITIES', 'Opportunities'),
                                                      'description' => 'Indicate Opportunity On Closed Won and Closed Lost Sales Stage',
                                                      'category'    => 'Module Views');

Step 3: Create custom/modules/Opportunities/Dashlets/MySummaryOpportunitiesDashlet/MySummaryOpportunitiesDashlet.php and write following code into it.

<?php

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

require_once('include/Dashlets/Dashlet.php');

class MySummaryOpportunitiesDashlet extends Dashlet {

    var $height = '100'; // height of the pad
    var $opportunitySelectedRange = array();
    var $opportunityDateModifiedWhere = array();
    protected $total_opportunities;
    protected $total_opportunities_won;
    protected $total_opportunities_lost;

    /**
     * Constructor
     *
     * @global string current language
     * @param guid $id id for the current dashlet (assigned from Home module)
     * @param array $def options saved for this dashlet
     */
    function MySummaryOpportunitiesDashlet($id, $def) {
        global $current_user, $app_strings, $app_list_strings,$app_strings,$current_language;
        parent::Dashlet($id, $def);
        if (empty($def['title']))
            $this->title = translate('LBL_MY_SUMMARY_OPPORTUNITIES', 'Opportunities');
        if (!empty($def['height'])) // set a default height if none is set
            $this->height = $def['height'];

        parent::Dashlet($id); // call parent constructor

        $this->isConfigurable = true; // dashlet is configurable
        $this->hasScript = false;  // dashlet has javascript attached to it

        $selectedOpportunityDateOption = array();
        if (!empty($def['opportunity_date_range']))
            $selectedOpportunityDateOption = $def['opportunity_date_range'];
        $this->opportunityDateModifiedWhere = $selectedOpportunityDateOption;
        //$home_mod_strings = return_module_language($current_language, 'Home');
        $this->opportunitySelectedRange = $selectedOpportunityDateOption;
    }

    /**
     * Displays the dashlet
     *
     * @return string html to display dashlet
     */
    function display() {

        require_once('modules/Administration/Administration.php');
        $admin = new Administration();
        $admin->retrieveSettings();

        global $db, $current_language, $timedate,$current_user;
        $mod_strings = return_module_language($current_language, 'Opportunities');
        $ss = new Sugar_Smarty();

        $opportunitySearchWhere = "";
        if (!empty($this->opportunityDateModifiedWhere)) {
            if($this->opportunityDateModifiedWhere == "TP_today")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->get_day_begin();
                $end = $oSugarDateTime->get_day_end();
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_yesterday")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->get("-1 day")->get_day_begin();
                $end = $oSugarDateTime->get("-1 day")->get_day_end();
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_tomorrow")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->get("+1 day")->get_day_begin();
                $end = $oSugarDateTime->get("+1 day")->get_day_end();
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_this_month")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->get_day_by_index_this_month(0)->setTime(0, 0, 0);
                $end = clone($begin);
                $end->setDate($begin->year, $begin->month, $begin->days_in_month)->setTime(23, 59, 59);
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_this_year")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->setDate($oSugarDateTime->year, 1, 1)->setTime(0, 0, 0);
                $end = clone($begin);
                $end->setDate($begin->year, 12, 31)->setTime(23, 59, 59);
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_last_30_days")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->get("-29 days")->get_day_begin();
                $end = $oSugarDateTime->get_day_end();
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_last_7_days")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->get("-6 days")->get_day_begin();
                $end = $oSugarDateTime->get_day_end();
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_last_month")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->setDate($oSugarDateTime->year, $oSugarDateTime->month-1, 1)->setTime(0, 0, 0);
                $end = clone($begin);
                $end->setDate($begin->year, $begin->month, $begin->days_in_month)->setTime(23, 59, 59);
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_last_year")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->setDate($oSugarDateTime->year-1, 1, 1)->setTime(0, 0, 0);
                $end = clone($begin);
                $end->setDate($begin->year, 12, 31)->setTime(23, 59, 59);
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_next_30_days")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->get_day_begin();
                $end = $oSugarDateTime->get("+29 days")->get_day_end();
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_next_7_days")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->get_day_begin();
                $end = $oSugarDateTime->get("+6 days")->get_day_end();
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_next_month")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->setDate($oSugarDateTime->year, $oSugarDateTime->month+1, 1)->setTime(0, 0, 0);
                $end = clone($begin);
                $end->setDate($begin->year, $begin->month, $begin->days_in_month)->setTime(23, 59, 59);
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
            else if($this->opportunityDateModifiedWhere == "TP_next_year")
            {
                $oSugarDateTime = new SugarDateTime();
                $begin = $oSugarDateTime->setDate($oSugarDateTime->year+1, 1, 1)->setTime(0, 0, 0);
                $end = clone($begin);
                $end->setDate($begin->year, 12, 31)->setTime(23, 59, 59);
                $opportunitySearchWhere .= " AND opportunities.date_modified >='".$begin->asDb()."' AND opportunities.date_modified <= '".$end->asDb()."'";
            }
        }

        $this->seedBean = new Opportunity();

        $qry = "SELECT * from opportunities WHERE assigned_user_id = '" . $current_user->id . "' AND deleted=0".$opportunitySearchWhere;
        $result = $this->seedBean->db->query($this->seedBean->create_list_count_query($qry));
        $row = $this->seedBean->db->fetchByAssoc($result);

        $this->total_opportunities = $row['c'];
        $qry = "SELECT * from opportunities WHERE assigned_user_id = '" . $current_user->id . "' AND sales_stage = 'Closed Won'  AND deleted=0".$opportunitySearchWhere;
        $result = $this->seedBean->db->query($this->seedBean->create_list_count_query($qry));
        $row = $this->seedBean->db->fetchByAssoc($result);

        $this->total_opportunities_won = $row['c'];

        $qry = "SELECT * from opportunities WHERE assigned_user_id = '" . $current_user->id . "' AND sales_stage = 'Closed LOST'  AND deleted=0".$opportunitySearchWhere;
        $result = $this->seedBean->db->query($this->seedBean->create_list_count_query($qry));
        $row = $this->seedBean->db->fetchByAssoc($result);

        $this->total_opportunities_lost = $row['c'];


        $ss->assign('id', $this->id);
        $ss->assign('height', $this->height);
        $ss->assign('opportunitySelectedRange', $this->opportunitySelectedRange);
        $ss->assign('lblTotalOpportunities', translate('LBL_TOTAL_OPPORTUNITIES', 'Opportunities'));
        $ss->assign('lblClosedWonOpportunities', translate('LBL_CLOSED_WON_OPPORTUNITIES', 'Opportunities'));
        $ss->assign('lblClosedLostOpportunities', translate('LBL_CLOSED_LOST_OPPORTUNITIES', 'Opportunities'));
        $ss->assign('total_opportunities', $this->total_opportunities);
        $ss->assign('total_opportunities_won', $this->total_opportunities_won);
        $ss->assign('total_opportunities_lost', $this->total_opportunities_lost);
        $str = $ss->fetch('custom/modules/Opportunities/Dashlets/MySummaryOpportunitiesDashlet/MySummaryOpportunitiesDashlet.tpl');
        return parent::display($this->dashletStrings['LBL_DBLCLICK_HELP']) . $str; // return parent::display for title and such
    }

    function displayOptions() {
        global $app_strings, $app_list_strings,$current_user,$current_language;
        $ss = new Sugar_Smarty();
        $ss->assign('saveLbl', $app_strings['LBL_SAVE_BUTTON_LABEL']);
        $ss->assign('clearLbl', $app_strings['LBL_SAVE_BUTTON_LABEL']);
        $ss->assign('title', translate('LBL_MY_SUMMARY_OPPORTUNITIES', 'Opportunities'));
        $ss->assign('id', $this->id);

        $home_mod_strings = return_module_language($current_language, 'Home');
        $filterTypes = array(''                 => $app_strings['LBL_NONE'],
                             'TP_today'         => $home_mod_strings['LBL_TODAY'],
                             'TP_yesterday'     => $home_mod_strings['LBL_YESTERDAY'],
                             'TP_tomorrow'      => $home_mod_strings['LBL_TOMORROW'],
                             'TP_this_month'    => $home_mod_strings['LBL_THIS_MONTH'],
                             'TP_this_year'     => $home_mod_strings['LBL_THIS_YEAR'],
                             'TP_last_30_days'  => $home_mod_strings['LBL_LAST_30_DAYS'],
                             'TP_last_7_days'   => $home_mod_strings['LBL_LAST_7_DAYS'],
                             'TP_last_month'    => $home_mod_strings['LBL_LAST_MONTH'],
                             'TP_last_year'     => $home_mod_strings['LBL_LAST_YEAR'],
                             'TP_next_30_days'  => $home_mod_strings['LBL_NEXT_30_DAYS'],
                             'TP_next_7_days'   => $home_mod_strings['LBL_NEXT_7_DAYS'],
                             'TP_next_month'    => $home_mod_strings['LBL_NEXT_MONTH'],
                             'TP_next_year'     => $home_mod_strings['LBL_NEXT_YEAR'],
                             );

        $ss->assign('opportunitySelectedRange', get_select_options_with_id($filterTypes, $this->opportunitySelectedRange));
        $ss->assign('opportunityDateModified', $app_strings['LBL_DATE_MODIFIED']);

        return parent::displayOptions() . $ss->fetch('custom/modules/Opportunities/Dashlets/MySummaryOpportunitiesDashlet/MySummaryOpportunitiesDashletOptions.tpl');
    }

    function saveOptions($req) {
        global $sugar_config, $timedate, $current_user, $theme;
        $options = array();
        $options['opportunity_date_range'] = $_REQUEST['opportunity_date_range'];
        return $options;
    }

}

Step 4:  Create custom/modules/Opportunities/Dashlets/MySummaryOpportunitiesDashlet/MySummaryOpportunitiesDashlet.tpl and write following code into it.

<div style="width:100%;vertical-align:middle;">
<table width="100%" border="0" align="center" class="list view" cellspacing="0" cellpadding="0">
    <tr>
        <th  align="center">{$lblTotalOpportunities}</td>
        <th  align="center">{$lblClosedWonOpportunities}</td>
        <th  align="center">{$lblClosedLostOpportunities}</td>
    </tr>
    <tr class="oddListRowS1">
        <td valign="top">{$total_opportunities}</td>
        <td valign="top"><b>{$total_opportunities_won}</b></td>
        <td valign="top"><b>{$total_opportunities_lost}</b></td>
    </tr>
</table>
</div>

Step 5:  Create custom/modules/Opportunities/Dashlets/MySummaryOpportunitiesDashlet/MySummaryOpportunitiesDashletOptions.tpl and write following code into it

<div>
<form name='configure_{$id}' action="index.php" method="post" onSubmit='return SUGAR.dashlets.postForm("configure_{$id}", SUGAR.mySugar.uncoverPage);'>
<input type='hidden' name='id' value='{$id}'>
<input type='hidden' name='module' value='Home'>
<input type='hidden' name='action' value='ConfigureDashlet'>
<input type='hidden' name='to_pdf' value='true'>
<input type='hidden' name='configure' value='true'>
<table width="100%" cellpadding="0" cellspacing="0" border="0" class="edit view" align="center">
<tr>
    <td valign='top' nowrap class='dataLabel'>{$opportunityDateModified}</td>
    <td valign='top' class='dataField'>
        <select name="opportunity_date_range">{$opportunitySelectedRange}</select>
    </td>
    <td valign='top' nowrap class='dataLabel'>&nbsp;</td>
    <td valign='top' class='dataField'>&nbsp;</td>
</tr>
<tr>
    <td colspan='4' align='right'>
        <input type='submit' class='button' value='{$saveLbl}'>
        <input type="submit" onclick="SUGAR.searchForm.clear_form(this.form,['dashletTitle','displayRows','autoRefresh']);return false;" value="Clear" class="button">
       </td>
</tr>
</table>
</form>
</div>

Step 6: Create custom/Extension/modules/Opportunities/Ext/Language/en_us.<any_name>.php and write the following custom label into it.

$mod_strings['LBL_MY_SUMMARY_OPPORTUNITIES'] = "Summary Opportunities";
$mod_strings['LBL_CLOSED_LOST_OPPORTUNITIES'] = "Closed Lost Opportunities ";

Step 7: Do "Quick Repair And Rebuild" from admin.

Step 8: Add new dashlet on Home page titled as "Summary Opportunities".

Voila!! Hope this works out as easily as possible for you.

Feel free to drop your valuable comments.
Urdhva Tech Pvt. Ltd. Powered by Blogger.

Urdhva Tech

My photo
SugarCRM Consultants Contact us at contact@urdhva-tech.com Skype : urdhvatech

Search This Blog

Stay connected Socially

     

Total Pageviews

Popular Posts