Quantcast
Channel: Urdhva Tech | SugarCRM and SuiteCRM Customization and Development
Viewing all 66 articles
Browse latest View live

Urdhva-Tech welcomes you!

$
0
0
Welcome to Urdhva-Tech's blog post.

We, at Urdhva-Tech work mostly on SugarCRM since 5 years. We have worked with small to medium to largest organizations to help them customize SugarCRM and to use it at its best extent.

We have experience customizing all flavors and versions of SugarCRM.

Here you will find all small to big everyday issues people come across while using SugarCRM.

This blog posts will help a novice, developers or even someone who doesn't know PHP, but can follow instructions strictly.


Remove Check box and Edit link from List View

$
0
0
Many times users find it necessary to remove the check box and/or edit links from the list view of any module.

SugarCRM doesn't provide a setting to achieve this from admin panel.

There are few simple steps to follow and you are sorted.

First thing, you should have access to file base, if you have it, go ahead, world is all yours.



Throughout the blog, we will use custom module "UT_Blogs" if the blog post is not about specific OOB(out of box) modules.



Step 1: Check if you have a file named view.list.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.list.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.list.php under custom/modules/<desired_module>/views folder and write following code.





<?php 
require_once('include/MVC/View/views/view.list.php'); 
class <desired_module>ViewList extends ViewList 
{  
     function display()
     {
         parent::display(); 
     }
}

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


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 2: Now add following lines in function display().

$this->lv->multiSelect = false; //This removes Check Box       
$this->lv->quickViewLinks = false; //This removes Edit Link
P.S. If your copied file does not have function display, you will have to add that from code above.

Step 3: This should be it, just refresh the list view and you should be able to see the effect instantly, no Quick Repair and Rebuild required.


Before
After

Hope you may find this blog post helpful.

Feel free to add comments and queries, that helps us to improve the quality of posts.

You can contact us at contact@urdhva-tech.com

Thank you.

Restricting editing a record conditionally

$
0
0
If you wish to restrict users to edit a record after for example, the Sales Stage is marked as "Closed Lost" or something similar kind, you have reached to a right place.

As mentioned above, today's task is to stop users to editing any detail of an opportunity after the Sales Stage is "Closed Lost".

Here we go!


In this blog post, we are using SugarCRM's OOB module Opportunities, if you wish to implement same functionality to your custom module, just make sure you are accessing right directory.


Step 1: Copy modules/Opportunities/controller.php if exists, and paste it to custom/modules/Opportunities or else create a file under custom/modules/Opportunities/controller.php

Step 2: Write following code in there and voila!

<?php

class OpportunitiesController extends SugarController {

    function action_editview() {
        if ($this->bean->sales_stage == "Closed Lost") {
            $this->view = 'noaccess';
        }
        else
            $this->view = 'edit';
    }

}

Hope you find it helpful.

Feel free to leave your comments.

Filter by related module's field

$
0
0
At times we have clients asking for similar requirement, that they want to filter results by related module's field.

Lets take basic modules and achieve similar goal by coding. Here, one needs to have idea about creating basic mysql query.

We have Accounts and Contacts module in SugarCRM. Accounts has one-many relationship with Contacts. We will add Accounts module's type field in Contacts search.


Create non-db field in Contacts module named as account_type_search. Write following code into custom/Extensions/modules/Contacts/Ext/Vardefs/<anyname>.php

<?php
 $dictionary["Contact"]["fields"]["account_type_search"]= array(
   'name' => 'account_type_search',
   'vname' => 'LBL_ACCOUNT_TYPE_SEARCH',
   'query_type' => 'default',
   'source' => 'non-db',
   'type' => 'enum',
   'options' => 'account_type_dom',
   'studio' => array('searchview'=>true,'visible'=>false),
);

Write following code into search field definition. Copy modules/Contacts/metadata/SearchFields.php to custom/modules/Contacts/metadata/SearchFields.php if doesn't exist and write following code into it. If it exists at custom/modules/Contacts/metadata/SearchFields.php then add following code with <?php.

'account_type_search' => array (
            'db_field' =>
            array (
              0 => 'id',
            ),
            'query_type' => 'format',
            'operator' => 'subquery',
            'subquery' => 'SELECT accounts_contacts.contact_id FROM accounts_contacts
                           INNER JOIN accounts ON accounts.id = accounts_contacts.account_id AND accounts.deleted = 0
                           WHERE accounts_contacts.deleted = 0 AND accounts.account_type IN ({0})',
        ),


Create custom/modules/Contacts/metadata/metafiles.php and write following code into it. If it exists at custom/modules/Contacts/metadata/metafiles.php, then do changes as per your needs.


<?php
$metafiles['Contacts']['searchfields']='custom/modules/Contacts/metadata/SearchFields.php';

Add account_type_search field for searching into custom/modules/Contacts/metadata/searchdefs.php through studio.

Do "Quick Repair And Rebuild" from admin.

And voila!

Export Workflows (PRO+)

$
0
0
At times it happens to developers that they create workflows on their working copy and find it difficult to export to client's copy.

Workflows are managed by files and entries in database tables.

Files can be found at

custom/modules/<module_name>/workflow


and database table entries to export are

expressions
workflow
workflow_actions
workflow_actionshells
workflow_alerts
workflow_alertshells
workflow_triggershells


If you have created workflow email template then filter records in table email_templates where type = workflow and point out which template you just created for the workflow.

Hope these instructions are useful for developers out there!

Feel free to leave comments.

Make field Importable Required

$
0
0
How to make importable required in custom field
It will be done by one step only! You need to extend vardefs to make importable required.
Let's see how

To extend vardefs we need to create a file.

custom/Extension/modules/<module_name>/Ext/Vardefs/<anyname>.php

<?php
$dictionary["<MODULE_OBJECT_NAME>"]["fields"]["<FIELD_NAME>"]["importable"]='required';

Now go to Admin > Repair > Quick Repair and Rebuild. 
You are done!

Feel free to leave comments.

Display more than 10 records in SQS search.

$
0
0
SugarCRM by default displays 10 records as a search result after SQS. As an example, we take Opportunities module with after_ui_frame logic hook.

Step 1 : Create logic hook entry as follows

$hook_array['after_ui_frame'] = Array();
$hook_array['after_ui_frame'][] = Array(5, 'Change SQS result records', 'custom/modules/Opportunities/logic_hooks/changeSQSRecordCount.php','changeSQSRecordCountC','changeSQSRecordCountF');


Step 2 : Open custom/modules/Opportunities/logic_hooks/changeSQSRecordCount.php and write following code into it.

class changeSQSRecordCountC
{
    function changeSQSRecordCountF()
    {
        echo "<script language='javascript'>YAHOO.widget.AutoComplete.prototype.maxResultsDisplayed=20;</script>";
    }
}

Before
After
Feel free to leave comments.

Showing related module's related data

$
0
0
Today I came across a requirement where client wanted to see Contacts related to a Case at Account's level.

That means, if I open an account, and it has a Case linked to it, I should be able to see the Contacts related to that Case right in the same subpanel.

Few steps and done!

Step 1: Is to create a non-db field in Cases module. Create a file in custom/Extension/Cases/Ext/Vardefs/<any_name>.php and write following code.

<?php
$dictionary["Case"]["fields"]["contact_non_db"] = array (
    'name' => 'contact_non_db',
    'type' => 'varchar',
    'default'=> '',
    'vname' => 'LBL_CONTACTS',
    'reportable' =>true,
    'source' => 'non-db'
);

Step 2: Place the field in subpanel. Go to Admin > Studio > Accounts > Subpanels > Cases and press Save.


We cannot find non-db fields here, so we need to change it from file manually.


This will create a file under custom/modules/Cases/metadata/subpanels/Account_subpanel_cases.php

Open that and add following code where you want to see your field.

'contacts_non_db' =>
  array (
    'name' => 'contacts_non_db',
    'vname' => 'LBL_CONTACTS',
    'width' => '30%',
    'default' => true,
    'sortable' => false,
  ), 
Step 3: Now we need to give the value to the field. We need to create logic hook to process and display contacts.

Check if you have logic_hooks.php under folder custom/modules/Cases? If no, create one and add following code.

<?php
$hook_array['process_record'][] = Array(2, 'Show contacts', 'custom/modules/Cases/showContacts.php','showContactsC', 'showContactsF'); 

Then create file at custom/modules/Cases/showContacts.php and add following code in there.

<?php
class showContactsC{
    function showContactsF($bean, $event, $args){
        // fetching related contacts
        get_linked_beans('contacts', 'Contacts');
       
        $contact = '';
       
        foreach($oContacts as $iContacts => $oContact)
        {  
            if($iContacts < 3)
                $contact .= ",<a href="index.php?action=DetailView&module=Contacts&record=".$oContact->id.">".$oContact->full_name."</a>";
            else{
                $contact .= ',...';
                break;
            }
        }
        $bean->contacts_non_db = substr($contact,1);
    }
}
There you are! No need to do Quick Repair and Rebuild! The result should be in front of your eyes!


P.S. To optimize the view I have shown only first 3 Contacts, if you want to show all Contacts, remove condition on $iContacts.




Add custom subpanel in Accounts module.

$
0
0
There comes the time when sales rep finds it irritating to view opportunities Closed Won and Closed Lost under same subpanel.

Lets make custom subpanels separating Closed Won and Closed Lost.

In this blog post, we will add those subpanels under Accounts module.

Step 1 : Create custom/Extension/modules/Accounts/Ext/Layoutdefs/<any_name>.php and write the following code into it.

<?php 
$layout_defs['Accounts']['subpanel_setup']['opp_closed_lost'] =
        array('order' => 49,
            'module' => 'Opportunities',
            'subpanel_name' => 'ForAccounts',
            'get_subpanel_data' => 'function:get_closed_lost_closed_won_opportunities',
            'generate_select' => true,
            'title_key' => 'LBL_OPPORTUNITIES_WITH_CLOSED_LOST',
            'top_buttons' => array(),
            'function_parameters' => array(
                'import_function_file' => 'custom/modules/Accounts/customOpportunitiesSubpanel.php',
                'sales_stage' => 'Closed Lost',
                'account_id' => $this->_focus->id,
                'return_as_array' => 'true'
            ),
);
$layout_defs['Accounts']['subpanel_setup']['opp_closed_won'] =
        array('order' => 50,
            'module' => 'Opportunities',
            'subpanel_name' => 'ForAccounts',
            'get_subpanel_data' => 'function:get_closed_lost_closed_won_opportunities',
            'generate_select' => true,
            'title_key' => 'LBL_OPPORTUNITIES_WITH_CLOSED_WON',
            'top_buttons' => array(),
            'function_parameters' => array(
                'import_function_file' => 'custom/modules/Accounts/customOpportunitiesSubpanel.php',
                'sales_stage' => 'Closed Won',
                'account_id' => $this->_focus->id,
                'return_as_array' => 'true'
            ),
);

Step 2 : Create custom/modules/Accounts/customOpportunitiesSubpanel.php and write following code into it.

<?php 
function get_closed_lost_closed_won_opportunities($params) {
    $args = func_get_args();
    $opportunitiesSalesStage = $args[0]['sales_stage'];
    $accountId = $args[0]['account_id'];
    $return_array['select'] = " SELECT opportunities.*";
    $return_array['from'] = " FROM opportunities ";
    $return_array['where'] = " WHERE opportunities.deleted = '0' AND opportunities.sales_stage = '" . $opportunitiesSalesStage . "'";
    $return_array['join'] = " INNER JOIN accounts_opportunities ON accounts_opportunities.opportunity_id = opportunities.id AND accounts_opportunities.deleted = '0' INNER JOIN accounts ON accounts.id = accounts_opportunities.account_id AND accounts.deleted = '0' AND accounts.id = '" . $accountId . "'";
    $return_array['join_tables'] = '';
    return $return_array;
}

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

<?php 
$mod_strings['LBL_OPPORTUNITIES_WITH_CLOSED_LOST'] = "Opportunities With Closed Lost";
$mod_strings['LBL_OPPORTUNITIES_WITH_CLOSED_WON'] = "Opportunities With Closed Won";

Step 4 : Do Quick Repair and Rebuild from Admin panel.



Feel free to leave comments.

Duplicate Alarm

$
0
0
Today I came across an interesting post on SugarCRM Forum which says give an indication next to phone number if it is found to be repeated over various Contacts.

Lets do it!

Step 1: Create a process_record logic hook in custom/modules/Contacts/logic_hooks.php
Add following code in it. If the file already exists, add following lines.

<?php
$hook_array['process_record'][] = Array(1, 'Check Dup', 'custom/modules/Contacts/checkDup.php','checkDupC', 'checkDupF'); 

Step 2: Lets add logic. Create a file checkDup.php under custom/modules/Contacts folder and add following code.

<?php
class checkDupC{
    function checkDupF($bean){
        $sContacts = $bean->db->query('SELECT contacts.id FROM contacts WHERE contacts.phone_work = "'.$bean->phone_work.'" AND contacts.id <> "'.$bean->id.'" AND contacts.phone_work IS NOT NULL', true);
        $bFound = false;
        while($aContacts = $bean->db->fetchByAssoc($sContacts)){
            if(!empty($aContacts['id']))
                $bFound = true;
        }
       
        if($bFound){
            $bean->phone_work = $bean->phone_work."&nbsp;".SugarThemeRegistry::current()->getImage('no');
        }
    }
}

And refresh the list view. You should have next to the duplicated phone numbers.

Hope you find the blog post helpful.

Please feel free to leave comments.

Mass convert Targets to Leads

$
0
0
Another interesting question on SugarCRM Forum attracted me to implement the request and here I go and write the solution for it.

Goal: Mass convert Targets to Leads.

Step 1: Create a flag field which allows you to mass convert Targets.

Create a file under custom/Extension/modules/Prospects/Ext/Vardefs/<any_name>.php and write following code in it.

<?php
$dictionary['Prospect']['fields']['convert_prospect'] = array('name' => 'convert_prospect',
    'vname' => 'LBL_CONVERT_PROSPECT',
    'type' => 'bool',
    'default' => '0',
    'massupdate' => true,
    );

Create a file under custom/Extension/modules/Prospects/Ext/Language/en_us.<any_name>.php and write following code.

<?php
$mod_strings['LBL_CONVERT_PROSPECT'] => 'Convert Leads';

Then do Quick Repair and Rebuild which will give you a query to add a new field in prospects table.

Step 2: Create a before_save logic hook in Prospects module.

Create a file logic_hooks.php under custom/modules/Prospects if doesn't exist, or else add following code in it.

<?php 
$hook_array['before_save'][] = Array(1, 'Mass Convert Prospects into Leads', 'custom/modules/Prospects/convertIntoLeads.php','convertIntoLeadsC', 'convertIntoLeadsF');

Step 3: Lets add logic behind.

Create a file convertIntoLeads.php under custom/modules/Prospects and add following code which copies the values from Prospect and creates a new lead.

<?php 
class convertIntoLeadsC {
    function convertIntoLeadsF($bean, $event, $args) {
        if (isset($bean->convert_prospect) && $bean->convert_prospect != $bean->fetched_row['convert_prospect'] && empty($bean-&gt;lead_id)) {
            $oLead = new Lead();
            foreach ($oLead->field_defs as $keyField => $aFieldName) {
                $oLead->$keyField = $bean->$keyField;
            }
            $oLead->id = '';
            $oLead->save(true);
            $bean->lead_id = $oLead->id;
        }
    }
}

Now go to List View of Prospects and select the records you want to convert into Leads and mass update them by selecting Convert to Leads "Yes".

That's all! All selected Prospects are now converted into Leads!!

Mission accomplished!!

P.S. This feature will allow all users to convert Targets into Leads.


Feel free to leave your comments. 

Compare Closed vs Won opportunities of selected timeframe

$
0
0
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.

Where are the queries?

$
0
0
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.

REST api Example

$
0
0


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;

Extending List View query

$
0
0
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.

Password settings Community Edition

$
0
0
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.

Audit relate fields

$
0
0
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.

Creating new Dashlets based on default

$
0
0
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.

Getting dropdown options in Javascript

$
0
0
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.


Date control on a varchar type field

$
0
0
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.
Viewing all 66 articles
Browse latest View live