Pages

Monday, June 1, 2009

Simple SugarCRM Logic Hook Example

Logic hooks are one of the most powerful features of SugarCRM, however, their power also introduces complexities. If you are not familiar with this feature, more detailed information on the topic can be found on the SugarCRM Developer site.
In a nutshell, their power lies in the fact that they allow a programmer to extend SugarCRM functionality with custom code which in turn can be designed do just about anything.
Some capabilities include:
  • Modifying values on a record before it is saved to the database
  • Updating other databases based on actions performed within SugarCRM
  • Conditional sending of e-mail messages
A common task that users will want to accomplish with a logic hook is to interact with the database at some level when an action is performed within SugarCRM.
Consider the following scenario:
Workflow requirements dictate that the Assigned To value of a Case always match the Assigned To value specified on the Account record to which the Case is linked.
Thus, we must do two things:

1. Determine the assigned_user_id value of the parent Account record
and
2. Ensure that the assigned_user_id value of the Case record matches that of the parent Account

Both steps are easily accomplished via a logic hook and demonstrate the feature's ability to query the database as well as modify the current record's values.
We will use the before_save hook in this example, causing it to trigger whenever a Case record is committed to the database.

First we'll need to create a file called logic_hooks.php and put the following PHP code in it:
$hook_version = 1;
$hook_array = Array();
$hook_array['before_save'][] = Array(1, 'assignUser', 'custom/modules/Cases/autoUserAssignment.php', 'UserAssignment', 'updateCase');


Make sure to save the file to the [sugar]/custom/modules/Cases directory.


The logic_hooks.php file described above provides the parameters necessary for SugarCRM to know not only when the custom code should execute, but also where the code can be found.
Notice the reference to the file autoUserAssignment.php. That is the file that SugarCRM will examine for the custom code that needs to be executed when the appropriate conditions are met. 


Create a PHP file by that name and store it in the [sugar]/custom/modules/Cases directory.
Add the following to said file:


<?php


class UserAssignment {
      function updateCase(&$bean, $event, $arguments) 

      {
           //Query ACCOUNTS table for assigned_user_id value of parent Account
           $case_id = $bean->id;
           $acct_id = $bean->account_id;
$query = "SELECT accts.assigned_user_id FROM accounts accts ";
$query .= "WHERE accts.id = '$acct_id' LIMIT 1";
$results = $bean->db->query($query, true);
$row = $bean->db->fetchByAssoc($results);
$user_id = $row['assigned_user_id'];


           //Change assigned_user_id value on Case
           $bean->assigned_user_id = $user_id;
}
}
?>



That should do it! 


From now on, whenever a user clicks Save on a Case, SugarCRM will automatically set the Assigned To value to match that of the related Account.



112 comments:

  1. Hi Angel - I followed you here from the SugarCRM forums...

    I have posted a question regarding the most logical way to create a new record in a custom module based on a Opp being closed won, and then associating and assigning a series of (set unchanging) activities on the new custom mod record. While quite complex, I'm hoping I can achieve this task fairly rapidly.

    While I've been developing within sugar for over a year (soap, custom modules for business logic, etc), I have yet to dive into writing logic_hooks. Thanks for this post. Your blog contains much insight to taking my Sugar development to the next level.

    Oh, and I'm a programmer with a running problem too ;-) the problem being that I don't seem to have enough time to run as much as I would like!

    Cheers!

    ReplyDelete
  2. I am a newbie sugarcrm. Simple question here how do I stop a save action or any other action from taking place if my logic-hook determines that the triggered action should stop and perhaps an error message returned to the user?

    Specifically what I am trying to achieve is this: I am in the travel industry, my travel agents will create accounts and contacts, when the account is in a certain state - maybe a ticket issued, I want to prevent my agents from making changes to the account, but still have the account assigned to them. A supervisor can still make changes. In my research I found logic_hooks but I have not seen in any of the documentation how to prevent edits of the data, or to prevent saving if a field contains a particular value and the role of the user is not that of supervisor.

    In other event driven programing a Boolean return value would dictate the outcome, I don't see that in documents about logic_hooks yet.

    ReplyDelete
  3. @carey
    The logic hooks functionality is not really designed to interact with the interface or user. They are more akin to database triggers.

    I think the most effective way of accomplishing what you want is through some custom JavaScript on the EditView for the module in question.

    ReplyDelete
  4. Can you provide guidance on how to package the logic hooks?

    ReplyDelete
  5. @itl
    Take a look at my Cases->Twitter integration project on SugarForge:
    http://www.sugarforge.org/projects/casetwit/

    If you examine the manifest.php file it contains, you'll see an example of how to package logic hooks. Note that the logic hooks portion of the manifest.php file does not work with pre-5.2 releases. For those releases, use the copy approach and simply copy the logic_hooks.php file to the appropriate directory.

    ReplyDelete
  6. Hello Angel,

    This is a great tutorial, i have a few questions.

    I'm writing 2 before_save hooks

    What / How are these values derived?

    $case_id = $bean->id; // What id? defined where?

    $acct_id = $bean->account_id; // once again how and where

    overall it seems the code just doesn't give enough info to accomplish anything. It's like the first 1/2 of the instruction is there, but the later portion to tell it what to do isn't?

    I'm thinking completely along the lines of doing this via php/mysql, don't know what beans are mean etc...

    i suppose if every line was commented with an explaination that'd help.

    there just aren't that many sugar specialists...

    ReplyDelete
  7. @ProjectJerel

    I don't understand what it is you are trying to do.

    Logic hooks are a feature of SugarCRM which are used to extend functionality via one's own custom code. The $bean is a representation of the current record within SugarCRM. It cannot be used outside the scope of SugarCRM, at least not without instantiating the same objects yourself within your code, but that is a whole other subject.

    ReplyDelete
  8. Sugar CRM 5.2k

    here's the object, excuse this as it's going to be a long description.

    I'll need 2 hooks, i'm going to talk about 1 for the time being.

    The object:
    I have created a custom field in accounts "tumclientstatus_c" drop down with 4 values.

    There is an existing field in contacts "lead source" i've added the 4 values from the accounts custom field i created to lead source
    OR
    I've also created a custom field also called "tumclienttype_c" in contacts which is the same as the field by the same name in accounts.

    Either would work, although lead source needs less querying than tumclienttype_c as it's in the contacts table rather than the contacts_cstm

    i've created some code that would accomplish my goal using tumclienttype_c in contacts_cstm table

    let's use this as the scenerio, even though it's most likely more difficult.

    I want to create a logic hook that, when an account's tumclienttype_c is changed, it will automatically update ALL the account's assigned contacts tumclienttype_c field to the same.

    i've created a file in /custom/modules/accounts/logic_hooks.php

    php

    $hook_version = 1;

    $hook_array = Array();

    // working
    $hook_array['before_save'][] = Array(1, 'acctTOcont', 'custom/modules/Cases/accounttocontact.php', 'AcctPushCont', 'updateContact');



    i've also created a file containing some of the tutorial's aspects, less the bean? The query and php with the commented variables populated correctly should accomplish what i want to do. If it was simply a matter of php, all i'd need is the "current account id" variable (as per the comments)

    the file is in the same directory

    accounttocontact.php

    php

    // for sugar
    class AcctPushCont {

    function updateContact(&$bean, $event, $arguments) {

    // currnet account id
    $acctid = "";

    // current/changed account tumclienttype_c
    $acctclienttype = "";

    // QUERY grabs all contact id's associated with the account
    $res1 = mysql_query("SELECT * FROM `accounts_contacts` WHERE `account_id` = '$acctid' ") or die (mysql_error());

    // Creates the batch process for each individual contact associated with the account
    while($row = mysql_fetch_array($res1)
    {

    // Writes the updated value to the contact
    mysql_query( "UPDATE `contacts_cstm` SET `tumclienttype_c` = '$acctclienttype' WHERE `id_c` = $row['contact_id']" );

    }

    }




    Granted the bean's are gone as i don't understand their function / purpose.

    Seems i'm on the cusp of having a correct syntax, i just have no peers to dot my i's so to speak.

    the query ONLY as a query with the php does what i need in theory, so whatever the syntax is it needs rewritten.

    The other hook which is actually more important, when creating a new contact, when you select an account to assign it to, it would automatically set the "tumclienttype_c" or "lead source" field to the same status.

    Keep in mind i have tumclienttype_c in 2 different places, contacts and accounts... just to make it all more confusing.

    any thoughts on this would be helpful.

    thanks

    ReplyDelete
  9. well just typed for 1/2 hour only to have blogger kill it when it said it was submitted.

    2nd try

    i've created 2 files

    custom/modules/Accounts/logic_hooks.php

    $hook_version = 1;

    $hook_array = Array();

    // working
    $hook_array['before_save'][] = Array(1, 'acctTOcont', 'custom/modules/Cases/accounttocontact.php', 'AcctPushCont', 'updateContact');

    and

    same dir accounttocontact.php
    (note while i used portions of the tutorial to encase the php / sql queries this is only to illustrate an actual solution, i realize that this isn't the sugar logic hook method, just actual code to accomplish my task)

    // for sugar
    class AcctPushCont {

    function updateContact(&$bean, $event, $arguments) {

    // currnet account id
    $acctid = "";

    // current/changed account tumclienttype_c
    $acctclienttype = "";

    // QUERY grabs all contact id's associated with the account
    $res1 = mysql_query("SELECT * FROM `accounts_contacts` WHERE `account_id` = '$acctid' ") or die (mysql_error());

    // Creates the batch process for each individual contact associated with the account
    while($row = mysql_fetch_array($res1)
    {

    // Writes the updated value to the contact
    mysql_query( "UPDATE `contacts_cstm` SET `tumclienttype_c` = '$acctclienttype' WHERE `id_c` = $row['contact_id']" );

    }

    }

    Here is the issue

    i have a custom drop down field in accounts called "tumclienttype_c" 4 values

    i have created another custom drop down field in contacts also called "tumclienttype_c" with the same values

    when an account's "tumclienttype_c" is changed, I want all the account's assigned contact's "tumclienttype_c" to inherit the same value.

    I have another logic hook that i've yet to start to write that when a contact is created, and an account is assigned, it will set "tumclienttype_c" to the assigned account's "tumclienttype_c" value.

    If i can figure out how to translate my sql query to a working logic hook, the 2nd one shouldn't be an issue.

    keep in mind there are 2 fields tumclienttype_c with the same name, just to make it all more confusing.

    any thoughts / direction on this would be much appreciated.

    thanks

    ReplyDelete
  10. You need to have the $bean in there. Per my previous comment, $bean represents the current record one is working with within Sugar.

    Thus, in your case, it would the Account record. If you $bean->id would give you the current Account's ID value, which you need to your query.

    $bean->tumclienttype_c would give you the value from the tumclienttype_c field from the current Account.

    Thus, $acctid = $bean->id; and $acctclienttype = $bean->tumclienttype_c; would give you what you need.

    Lastly, where is accounttocontact.php being stored? You state "in the same dir" which I am interpreting as /custom/modules/Accounts, but in the logic_hooks.php file, the reference to the file points to /custom/modules/Leads.

    ReplyDelete
  11. Ok, here's the 2 files, and the error i get... seems it's not liking the while loop?

    logic_hooks.php


    $hook_version = 1;

    $hook_array = Array();

    // working
    $hook_array['before_save'][] = Array(1, 'acctTOcont', 'custom/modules/Accounts/accounttocontact.php', 'AcctPushCont', 'updateContact');

    accounttocontact.php

    // for sugar
    class AcctPushCont {

    function updateContact(&$bean, $event, $arguments) {

    // currnet account id
    $acctid = $bean->id;

    // current/changed account tumclienttype_c
    $acctclienttype = $bean->tumclienttype_c;

    // QUERY grabs all contact id's associated with the account
    $res1 = mysql_query("SELECT * FROM `accounts_contacts` WHERE `account_id` = '$acctid' ") or die (mysql_error());

    // Creates the batch process for each individual contact associated with the account
    while($row = mysql_fetch_array($res1))
    {

    // Writes the updated value to the contact
    mysql_query( "UPDATE contacts_cstm SET `tumclienttype_c` = '$acctclienttype' WHERE `id_c` = $row['contact_id']" );

    }
    }

    the error
    Parse error: syntax error, unexpected T_ENCAPSED_AND_WHITESPACE, expecting T_STRING or T_VARIABLE or T_NUM_STRING in /home/pittsbur/public_html/custom/modules/Accounts/accounttocontact.php on line 22
    (line 22 is mysql_query( "UPDATE contacts_cstm SET `tumclienttype_c` = '$acctclienttype' WHERE `id_c` = $row['contact_id']" );

    the while loop is to change the value for all the associated contacts v just the first one.

    With this bean, I think I have this correct?

    if we're in teh accounts module and we set $var = $bean->any db cell in accounts OR any db cell in accounts and any accounts_additionaltable

    i'm going to try to write the other hook as it only needs to change 1 field for 1 contact at a time... Unless you tell me to go away i'll post my results with that as well.

    thank you for your help and patience.

    ReplyDelete
  12. update:

    i got everything working, but i had to make my sql connections with user and password within my file? I'm happy with it working, but if it can be streamlined via a proper method that would be great. aside from my user/pass/db info here's the final code.

    Thank you for all your help. Feel free to use this code in any tutorial that would help your subscribers.


    // for sugar
    class AcctPushCont
    {

    function updateContact(&$bean, $event, $arguments)
    {

    $usr = "xxx";
    $pwd = "xxx";
    $database = "xxx";

    mysql_connect("localhost", "$usr", "$pwd") or die(mysql_error());
    mysql_select_db("$database") or die(mysql_error());

    // currnet account id
    $acctid = $bean->id;

    // current/changed account tumclienttype_c
    $acctclienttype = $bean->tumclienttype_c;

    // QUERY grabs all contact id's associated with the account
    $res1 = mysql_query("SELECT * FROM `accounts_contacts` WHERE `account_id` = '$acctid' ") or die (mysql_error());

    // Creates the batch process for each individual contact associated with the account
    while($row = mysql_fetch_array($res1))
    {

    // Writes the updated value to the contact
    $change = $row["contact_id"];
    mysql_query( "UPDATE `contacts_cstm` SET `tumclienttype_c` = '$acctclienttype' WHERE `id_c` = '$change' ");

    }
    }
    }

    ReplyDelete
  13. It is not necessary to use mysql_query or other mysql functions directly.

    You can use the already existing connection that Sugar utilizes. Notice that my example uses the $bean to execute the query:

    $results = $bean->db->query($query, true);

    $row = $bean->db->fetchByAssoc($results)

    $user_id = $row['assigned_user_id'];

    You can do a similar thing in your code too.

    ReplyDelete
  14. Hi Angel,

    Is there a logic hook, something like "before_create" ?

    What I am looking for is this :

    I have relational dropdowns in my Cases editview.
    I have achieved this with a Java script and having it pointed in editviewdefs.php in /custom/modules/cases.

    Now I want to include ALL the fields in the cases editview into the cases subpanel under "Accounts".

    I have created the layout using the studio and I can see all the fields. But the relational function is missing.

    How can I create a logic hook to trigger when I hit the "Create" button appearing in the "Cases" subpanel shown under Accounts editview ?

    Please help.
    Thank you,
    Berny

    ReplyDelete
  15. @Berny
    You could probably accomplish that via modifications to SugarWidgetSubPanelTopButtonQuickCreate.php in includes/generic/SugarWidgets

    However, said changes wouldn't be upgrade-safe. I don't think there is a way to making that type of change in an upgrade-safe manner. If there is, I don't know what it is at the moment.

    ReplyDelete
  16. Thank you Angel for your very quick reply.
    Can you kindly tell me what kind of changes should I do to SugarWidgetSubPanelTopButtonQuickCreate.php ?
    Please forgive me for troubles, I m a newbee and not a programmer.

    Thanks & Regards,
    Berny

    ReplyDelete
  17. @Berny
    I don't know enough about what it is you are trying to do to comment. Regardless, this is going to require a little bit of programming expertise and this is probably not the best medium for trying to communicate exactly how to accomplish your goal.

    ReplyDelete
  18. Thank you Angel,
    It's ok, we tried.

    Now I have another question for you, only if you don't mind.

    Is there a way (perhaps by making use of a logic hook) for us to impose a restriction on creating sugar users ?

    (eg. The admin should not be able to create more than 25 users)

    Thanks & Regards,
    Berny

    ReplyDelete
  19. @Berny

    Best way would be to override the view.edit.php template and inject your custom code in there to check the record count and abort/save accordingly.

    ReplyDelete
  20. Thank you for your kindness. I have a question.
    After deploy the relevant package, the two file of Logic_hook disappear in custom/modules/

    Is there any workaround to prevent the Logic-hook files to go away??

    ReplyDelete
  21. @Sixx: Apologies, but I don't understand what you have done to get to that point. Nothing in my article talks about deploying any packages.

    Please elaborate so I may help you.

    ReplyDelete
  22. Hello Angel ,

    I am a newbie in sugarCRM.It would be great if you could help me.I am having problem.When clicking on save in quick create, soap is showing error since the values tat are retrieved from db are not available.
    I have a custom module booking related to opportunity. I have logic hook.Here is the code.



    custom/custom_logic.php

    name;
    $possBooking =(int) $possBooking;
    if($possBooking <1)
    {
    //Get the id
    $id = $bean->id;
    //Date from
    $dateFrom = $bean->book_from;
    //Date To
    $dateTo = $bean->book_to;
    $sql = "SELECT opportunities.assigned_user_id,opportunities.id FROM jcd1_bookinpportunities_c,opportunities WHERE jcd1_bookinpportunities_c .jcd1_bookid9c7booking_idb='".$id."' and jcd1_bookinpportunities_c.jcd1_bookia98cunities_ida = opportunities.id ";
    $results = $bean->db->query($sql,true);
    $row = $bean->db->fetchByAssoc($results);
    $userId = $row['assigned_user_id'];
    $opportunitiesId = $row['id'];
    $sql = "SELECT first_name,last_name,phone_other FROM users WHERE id = '".$userId."'";
    $results = $bean->db->query($sql,true);
    $row = $bean->db->fetchByAssoc($results);
    $userName = trim($row['first_name'])." ".trim($row['last_name']);
    $salesMan = $row['phone_other'];

    //Retrieve all the values from database
    $client = new soapclient('http://xxx.xx.xxx.xx/CRMService.asmx?wsdl',array());
    $ap_param = array('pUsername' => $userName, 'pSalesman' =>intval($salesMan),'pAdvId' =>$advId,'pFacelist' => $faceList,'pDateFrom' =>$dateFrom,'pDateTo' => $dateTo,'upgradeBkId'=>intval($chance));


    try {
    $return = $client->__soapCall('SetBookings', array($ap_param));
    }
    catch (Exception $e) {
    echo "Trace: ".$e->getTraceAsString()."
    Error in line: ".$e->getLine()."
    Error in script: \n".$e->getMessage()."
    \n";
    //$bean->name = $e->getMessage();

    }



    $bean->name = $return->SetBookingsResult->booking->bookingId;

    }
    else{
    $bean->name = $possBooking;
    }


    }
    }
    ?>

    ReplyDelete
  23. @Swetha: Apologies, but I am having a hard time understanding your desired goal by looking at this code, let alone figuring out what the problem might be.

    Perhaps you can share with me what it is you are trying to do and I might be able to provide some guidance.

    ReplyDelete
    Replies
    1. hii can you help me for make suggestion box in suitecrm

      Delete
  24. Hi Angel,

    I have a custom module booking.It has fields like date from,amount etc.I am sending these to web service and returning the bookid and displaying it on the list view or the booking module.

    For the web service i need date frm,amount and user name etc.I take username from database thru query.When i create booking from quick create the web service fails.But when i try editing it from edit view , my web service is success and gets me the booking Id.

    I wanted to know how to access the fields from table and send it to the web service.


    Thanks a lot for the help!!!!

    ReplyDelete
  25. This comment has been removed by the author.

    ReplyDelete
  26. Logic code is as follows :

    $hook_version = 1;
    $hook_array = Array();
    $hook_array['before_save'] = Array();
    $hook_array['before_save'][] = Array(1,'combine_fields','custom/JCDcustom_logic.php','custom_logic','combine_fields_setbooking');

    ReplyDelete
  27. Hi Angel,

    I have a custom module made in sugar 5.5 which maintains the records of a employee.

    I need to trigger a event before save where the system should check for the employee ID that the user is entering, means whether the new entry they are creating already exists or not.

    I am getting very hard time to solve this, please help me with this regard.

    Thanks a lot.

    ReplyDelete
  28. @King:

    You need to tell me what your problem is.

    I am happy to help you fix your problem best as I can or my time permits, but I am not going to do your work for you.

    ReplyDelete
  29. @Swetha: I am not sure I understand why you are using the SOAP API to do that..

    Say that in my logic hook code for the booking module I want to have my code create a contact in Sugar. I could do it via something along the lines of the following:

    //some code

    //include Contact class
    include('modules/Contacts/Contact.php');

    //Create Contact object
    $contact = new Contact();

    //Populate Contact fields
    $contact->first_name = "Angel";
    $contact->last_name = "Magaña";

    //Populate the rest of your fields

    //Save the record
    $contact->save();

    The process if pretty much the same for other objects, you just need to include the appropriate class file.

    ReplyDelete
  30. This comment has been removed by the author.

    ReplyDelete
  31. This comment has been removed by the author.

    ReplyDelete
  32. Hi Angel,

    Thank you for your response, I also do not want you to work for me...actually my query is that I have made a custom module which manages the records of the employees, now whenever I enter a record I need to fill some fields like emp ID first name last name etc...but I do not want to fill the entry which already exists, so I need to check before the save that if the emp ID already exists then the system should notify me..

    I have gone through various posts in sugar forum and your blog as well and got to know that logic hooks would do the work for me..so I have made a file logic_hook.php in the custom/module/mymodule/logic_hook.php

    $hook_version = 1;
    $hook_array = Array();
    $hook_array['before_save'] = Array();
    $hook_array['before_save'][] = Array(1, 'emp_id','custom/modules/emp_employee_asset_tracking/custom_id.php','custom_id', 'custom_id');

    where emp_id is my field name in the module

    and the other file is custom_id.php within the same directory as well

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

    class custom_id
    {
    function custom_id(&$bean, $event, $arguments)
    {

    if ($bean->value !="")
    {
    $query = I think i need a correct sql query here and work would be done
    $result = $bean->db->query($sql,true);
    $row = $db->fetchByAssoc($result);
    }
    }
    }
    ?>

    Please correct me if I am following a wrong approach.
    ---------------------------------------
    Also I have a other module named as resource planner, now is there any possibility that when I enter a new record and fill a field name as employee name then it should fetch out the data from the database of sugarcrm and pre fill with some fields and rest of the fields I can fill.

    Say I have a form where I have fields.

    Name, Phone Number, Address, currently working over which case.

    now whenever I enter a name then it should search for the respective record in the database of employee module and would auto fill the data like phone number, address which are already fixed and then I can fill the field "currently working over which case " and then I can save the record..
    I think this can also be achieved by the logic hooks but just I need to play around with the variables and queries.

    Sorry to bother you again but I would really appreciate if you can guide me in this regard whenever your time permits.

    keep up the good work !!

    Cheers
    Jatin

    ReplyDelete
  33. Hello Angel,

    I will trying explaining better what i wanted to do.
    I am wanted to create a booking through quick create module from opportunities.
    Conditions:
    1. The booking has few fields taken from sugar database through queries and some field entered in the booking quick create module.
    2. Once i grab all the data required, i send all these to web service and return a booking name.
    3. In list view i display this booking name and the details.

    I just donot want to create a booking need to get a name through soap.

    Could you plz help me out.I am very sorry for troubling you.It would be great if you give me permission to contact you through email.so that i can send you the screenshot and describe you better what i wanted to do.

    Thanks a lot!!

    ReplyDelete
  34. Thank you Angel.Fixed my problem.

    ReplyDelete
  35. i have created/deployed a new module (create a credit/debit transaction) and created a very simple hook to change the description field "after_save" - as a first attempt to using hooks. Later it will compute the balance.

    by using print statements in my hook (to print a file) , i can see my hook is not getting called from the create a new transaction panel when I click save. the location of the class file is correct. any ideas on how to troubleshoot / fix this ? Common mistakes? I don't see any errors on the log file, set to DEBUG.

    thanks

    ReplyDelete
  36. @Jeff

    A couple of notes..

    print and echo won't always return something when used within logic hook code, so it is not a reliable way of tracing the code.

    As for debug, you are not seeing anything because you need to add debug lines to your code.

    Adding the following to your code would do it:

    $GLOBALS['log']->debug('my debug message');

    Lastly, the fastest way of troubleshooting this type of thing is by collectively looking at the code. Post it if you can as it will make the task of troubleshooting it far easier.

    ReplyDelete
  37. Hello Angel,
    I am wondering if a logic hook is what I should use for what I want to do.

    I have to modify or enhance the search of contacts.

    I have created a module to keep track in the different positions a contact can have. I need to be able to include these positions in the search results resulting in a LEFT JOIN type of list, one row for every position of a contact. I am also searching in other fields like company, title, address... so I can't just search in the Position module.

    My question is can a logic hook work for me here? Maybe before_retrieve? I have been trying and failed and can find any examples of this on the web.

    Thanks for any help in this matter. Tom

    ReplyDelete
  38. @Tom: I am a bit fuzzy as to what it is you are trying to accomplish, but logic hooks aren't an ideal approach for attempting to modify the mechanics of the search code.

    Take a look at the Advanced Search module available on SugarForge as it directly modified the internals of the search features. It might give you some clues as to how to approach your problem.

    ReplyDelete
  39. hi
    Angel Magaña

    i have created one module in sugarCRM 6.0.2. i have copied this module from who's online module available on sugarforge. i have changed everything and installed on my local server.

    now my question is as user login i have created hooks after_login where it insert's record in databse but in my case login hooks are not being called do have any idea..?

    if you didn't get my question or you want to ask something more pls mail me on barkamlesh@gmail.com

    ReplyDelete
  40. @Kamal
    after_login triggers after a user logs in. I don't understand what the part about inserting records has anything to do with it.

    Are you trying to get a logic to fire after a login or after a record is created?

    ReplyDelete
  41. Angel -

    Good morning! I am a novice at PHP code and have tried to follow your example with a custom module called cnx_Sales_Opportunities. The objective is to update a field called last_touch with the date modified of the Sales Opportunitiy record.

    I have go into the server and changed the permissions of the two files so that the web server can access them. When I modify a Sales Opportunity, the last touch field is not updated with the date modified as expected. Any thoughts?

    Here are the file locations and code.

    custom/modules/cnx_Sales_Opportunities/logic_hooks.php file:




    custom/modules/cnx_Sales_Opporunities/cnx_Sales_OpportunitiesHooks.php
    id;
    $query = "SELECT so.date_modified FROM cnx_sales_opportunities so";
    $query .= "WHERE so.id = Sales_Opportunities_id LIMIT 1";
    $results = $bean->db->query($query, true);
    $row = $bean->db->fetchByAssoc($results);
    $date_modified = $row['date_modified'];
    $bean->last_touch = $date_modified;

    }
    }

    ?>

    Any help would be greatly appreciated!

    Thank you,
    Jen

    ReplyDelete
  42. This comment has been removed by the author.

    ReplyDelete
  43. Sorry! Code from the logic_hooks.php file did not copy in correctly:


    $hook_version = 1;
    $hook_array = Array();
    $hook_array[after_save] = Array();
    $hook_array[after_save][] = Array(1, cnx_Sales_OpportunitiesHooks, custom/modules/cnx_Sales_Opportunities/cnx_Sales_OpportunitiesHooks.php, cnx_Sales_OpportunitiesHooks, updateLastTouch);
    ?>

    ReplyDelete
  44. Apparently, nor did the cnx_Sales_OpportunitiesHooks.php

    require_once(modules/cnx_Sales_Opportunities/cnx_Sales_Opportunities.php);

    class cnx_Sales_OpportunitiesHooks
    {
    public function updateLastTouch(
    SugarBean
    $bean,
    $event,
    $arguments
    )
    {
    $Sales_Opportunities_id = $bean->id;
    $query = "SELECT so.date_modified FROM cnx_sales_opportunities so";
    $query .= "WHERE so.id = Sales_Opportunities_id LIMIT 1";
    $results = $bean->db->query($query, true);
    $row = $bean->db->fetchByAssoc($results);
    $date_modified = $row['date_modified'];
    $bean->last_touch = $date_modified;

    }
    }

    ReplyDelete
  45. Does it work if you put a static value in this line:

    $bean->last_touch = $date_modified?

    Also, you need to change:

    $query .= "WHERE so.id = Sales_Opportunities_id LIMIT 1";

    To:

    $query .= "WHERE so.id = '$Sales_Opportunities_id' LIMIT 1";

    ReplyDelete
  46. Angel -

    Thank you for the response. I tried the following and the result was still the same. The Last Touch field is null.

    class cnx_Sales_OpportunitiesHooks
    {
    public function updateLastTouch(
    SugarBean
    $bean,
    $event,
    $arguments
    )
    {
    $Sales_Opportunities_id = $bean->id;
    $query = "SELECT so.date_modified FROM cnx_sales_opportunities so";
    $query .= "WHERE so.id = '$Sales_Opportunities_id' LIMIT 1";
    $results = $bean->db->query($query, true);
    $row = $bean->db->fetchByAssoc($results);
    $date_modified = $row['date_modified'];
    $bean->last_touch = '1';

    }
    }

    ReplyDelete
  47. Does $date_modified contact a value?

    ReplyDelete
  48. Angel -

    I am not sure I understand the question. The record that I am working with has been saved numerous times so there is a $date_modified value for the one and only record I have entered.

    Does that answer your question?

    Thank you,
    jen

    ReplyDelete
  49. No, it doesn't, and I just noticed I wrote "contact" instead of "contain."

    What I am asking is the following..

    Given your logic hook is attempting to populate $bean->last_touch with the value of $date_modified, which in turn is being retrieved by the SQL query you are executing, does the variable $date_modified actually a value in it?

    Secondly, is last_touch a custom field? If so, it should be referenced as last_touch_c, assuming the field was created via Studio.

    ReplyDelete
  50. Angel -

    Found some help on the Sugar user forum. Here are the changes:

    class cnx_Sales_OpportunitiesHooks
    {
    public function updateLastTouch(
    SugarBean
    $bean,
    $event,
    $arguments
    )
    {
    $Sales_Opportunities_id = $bean->id;
    $query = "SELECT so.date_modified FROM cnx_sales_opportunities so ";
    $query .= "WHERE so.id = '".$Sales_Opportunities_id."' LIMIT 1";
    $results = $bean->db->query($query, true);
    $row = $bean->db->fetchByAssoc($results);
    $date_modified = $row['date_modified'];
    $bean->last_touch = $date_modified;

    }
    }

    ReplyDelete
  51. Angel -

    I have used your tutuorial as well as another that I found in searching how to write logic hooks. Unfortunatly, I am not familiar enough with PHP to understand where I am going wrong. My goal is to update the last_touch date/time field in my Sales_Opportunities module when a Call record is added.

    This is in my /custom/modules/Calls/logic_hooks.php file:

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

    $hook_version = 1;
    $hook_array = Array();
    $hook_array['after_save'] = Array();
    $hook_array['after_save'][] = Array(1, 'CallsHooks', 'custom/modules/Calls/CallsHooks.php', 'CallsHooks', 'updateSalesOppsLastTouch');

    Then in my /custom/modules/Calls/Callhooks.php file I have the following:

    require_once('modules/Calls/Call.php');
    require_once('modules/cnx_Sales_Opportunities/cnx_Sales_Opportunities.php');


    class CallsHooks
    {
    public function updateSalesOppsLastTouch(
    SugarBean
    &$bean,
    $event,
    $arguments
    )
    {
    $Call_id = $bean->id;
    $related_opportunities = $bean->parent_id;
    $query = "SELECT CURRENT_TIMESTAMP() AS timestamp FROM calls c ";
    $query .= "WHERE c.parent_id = '".$related_opportunities."' LIMIT 1";
    $results = $bean->db->query($query, true);
    $row = $bean->db->fetchByAssoc($results);
    $last_touch = $row['timestamp'];
    $Sales_Opportunities = $bean->get_linked_beans('cnx_sales_opportunities', 'cnx_Sales_Opportunities');
    foreach($cnx_sales_opportunities as $Sales_Opportunity)
    {
    $Sales_Opportunity->last_touch = $last_touch;
    $Sales_Opportunity->save(FALSE);
    }

    }

    }

    My thought process was that I needed to determine the Call bean, then pull the query, determine if the query is true, and then fetch the related Sales Opportunity and update the Last Touch field.

    I'm probably overcomplicating things....

    Any hits, tips, insight would be greatly appreciated!

    Thank you,
    Jen

    ReplyDelete
  52. @Jen: I've asked you very specific questions in my previous reply. I am not sure how to help you if you are unable to answer them.

    ReplyDelete
  53. Angel -

    Sincere apologies!!! I have no PHP experience and am trying to teach myself. My first post on 11/4 pertained to updating the cnx_Sales_Opportunities.last_touch field in my custom built module (cnx_Sales_Opportunities). I wanted the last_touch field updated each time a cnx_Sales_Opportunity was modified. It is now working with the information below....

    $Date_Modified has the current date/time stamp value in it.

    The field last touch is part of my custom module that was built through Module Builder. In the database it does not have an _c for the field name.

    I was able to get that working with the following code:

    $Sales_Opportunities_id = $bean->id;
    $query = "SELECT CURRENT_TIMESTAMP() AS timestamp FROM cnx_sales_opportunities so ";
    $query .= "WHERE so.id = '".$Sales_Opportunities_id."' LIMIT 1";
    $results = $bean->db->query($query, true);
    $row = $bean->db->fetchByAssoc($results);
    $date_modified = $row['timestamp'];
    $bean->last_touch = $date_modified;




    However, now my objective is to update the cnx_Sales_Opportunities.last_touch field if a Call record is added. The cnx_Sales_opportunity will always be the parent record to a Call record.

    I am using the code posted on 11/8 at 7:07 AM. It is essentially the same except I am trying to call the related cnx_Sales_Opportunity and clearly not having much luck.

    Sorry to be such a pest! I am trying to learn it on my own but it is just a little overwhelming!

    Thank you,
    Jen

    ReplyDelete
  54. Hi,

    I have to create a logic hook to update the custom fiels which is of type datatime when a record is added or edited from its Subpanel. I m using the Sugar Prof 6.1 version.

    Eg:
    Module: Contacts I have subpanels Tasks and Notes.
    When I go to detail view of a contact and add new Task from the subpanel I have to update the custom field on Contacts.

    Looking forward for your reply.

    Thanks

    ReplyDelete
  55. Create your hook within the Tasks module. It will be triggered when a Task is added via subpanel or other means.

    $bean->contact_id should give you the id of the linked contact.

    ReplyDelete
  56. Do you have any exampel how to use relationship_add-logic hooks?
    Best regards
    Pele

    ReplyDelete
  57. Hi angel
    i want to populate address fields of my custom module through accounts module...please help me

    ReplyDelete
  58. @swapnil

    OK, and what is the problem you are having doing so? Or are you looking for advice on how to do it? Please elaborate.

    ReplyDelete
  59. Hi Angel,

    many thx for your forum here.

    I am a newbie to sugar and trying to understand why the accounts_tasks relationship table is not being updated when I create a new task.

    I manually imported 1000 tasks and updated the relationship table with the tasks IDs and account IDs (using mysql UUID() for new tasks ID )and that worked perfectly, all of the imported tasks are now related and everything is working as expected.

    However, I am absolutely bewildered why the releationship table is not updated automatically when I create a new task.

    I am using CE 6.03.

    Any advice for me? Do I have to add some lines of code to a logic hook?

    Thanks

    Peter

    ReplyDelete
  60. @leggy:

    It is not clear from your message whether or not you are actually relating the Task to an account when the task is created. Are you saying you are doing so, but it is not linking them? If so, I don't know a reason why it would do that. I've never seen or heard of that.

    ReplyDelete
  61. Hi Angel.
    I'm a newbie willing to interface sugarcrm with OpenERP. For example, if a new Account is created in SugarCRM, all the data entered in there is automatically reflected in the Address Book in OpenERP.

    Can you please point me to link, or inform me, about the dependencies in the SugarCRM database. For example, accounts table is related to contacts table and so on.

    Also if you have any information about how I can conduct this interfacing , please let me know.

    Thanking you in advance,
    Avinash

    ReplyDelete
  62. I don't have any insight on the OpenERP, but my best suggestion to you would be to first sit down and write out exactly what you want the system to do.

    I know that the example you provided sounds "easy," but people often overlook the details if they don't write things down and then end up blaming the technology or someone they've hired to do the work for the lack of planning.

    For example, what happens if the account is already in the ERP system? The fact it is not in Sugar doesn't necessary mean it won't be in the ERP. Point being, there are a lot of fine details you need to figure out first.

    As for the technical side corresponding to Sugar, check out the Developers Site at http://developer.sugarcrm.com

    ReplyDelete
  63. Hi Angel,

    I want a custom field which will auto increment itself.
    have looked a lot of forum but none solved my issue.

    the field will be in contact module and disabled in UI for user to edit
    on save it should auto update the number with the incremented value,

    Kindly help

    ReplyDelete
    Replies
    1. The easiest way to implement this would be through the auto_increment feature of MySQL. See here: http://dev.mysql.com/doc/refman/5.5/en/example-auto-increment.html

      Delete
  64. Hi Angel,
    I am new to sugarCRM and have managed some simple logic hooks thanks to your post here!

    I was just wondering if it is possible to have multiple after_save hooks and what I would have to put into my logic_hooks.php file to achieve this?

    For example this is already present in my logic_hooks.php file for tasks:


    $hook_array['after_save'] = Array();
    $hook_array['after_save'][] = Array(1, 'INSERT_INTO_PM_ENTRY_TABLE', 'modules/PM_ProcessManager/insertIntoPmEntryTable.php','insertIntoPmEntryTable', 'setPmEntryTable');

    I would like add my own after_save logic

    Thanks,

    Nick

    ReplyDelete
    Replies
    1. Hi Nick,

      It certainly is possible. You'd want to append the following to your logic_hooks.php file:

      $hook_array['after_save'][] = Array(2, 'My Hook', 'custom/modules/MyHook.php','MyHookClass', 'MyHookMethod');

      Notice the change in the first value, from 1 to 2. That determines the order in which it will fire. Give we have more than 1 hook of the same type, it is important that these numbers do not clash. The rest are just normal changes to point it to our custom code file.

      Delete
  65. Dear Angel,
    I need your help in making a logic hook.
    I have two tables one called S_CUSTOMERS and other called SMS_OUTBOUND , S_CUSTOMERS table have a lot of columns but what i want from them are column called number of points and column called phone number.
    What i need is to check number of points for each customer if this number changed the code insert into SMS_OUTBOUND table phone number, number of points and status (decrease or increase) according to the change.
    I've created MySQL trigger for this but i need to do it in logic hook and I've no experience in it.
    Need help ASAP.

    ReplyDelete
    Replies
    1. There are a number of examples on my blog that cover this topic.

      See here: http://cheleguanaco.blogspot.com/search?q=logic+hook

      Also: http://cheleguanaco.blogspot.com/2009/06/simple-sugarcrm-logic-hook-example.html

      If you have a specific problem, feel free to post it and I will try to assist you.

      Delete
  66. Thanks' for your answer my problem is that I'm not familiar with Sugarcrm logic hook so I wonder if you can help me writing this code with information's I've gave to you before.
    Thank's in advanced.

    ReplyDelete
    Replies
    1. The links I included in my prior post provide various examples on how to create them and should help.

      I am happy to help you with a specific problem, but you need to put some effort in on your part.

      Delete
  67. This comment has been removed by the author.

    ReplyDelete
  68. This comment has been removed by the author.

    ReplyDelete
  69. dear angel,
    i've tried to write logic hook code for the situation told you before but
    it didn't work could you help me.....
    this is the code tried:
    class DataSync{

    function updateCase($bean, $event, $arguments){
    $query="select number_of_points,phone_number from s_customers
    where id='{$bean->id}'";
    $result=$bean->db->query($query,true);
    if ($bean->fetched_row['number_of_points'] > $bean->number_of_points){
    $query="insert into sms_outbound (number_of_points,phone_number,message)
    values ($bean->number_of_points,$bean->phone_number,`increase`)
    };
    if ($bean->fetched_row['number_of_points'] < $bean->number_of_points){
    $query="insert into sms_outbound (number_of_points,phone_number,message)
    values ($bean->number_of_points,$bean->phone_number,`increase`)
    }
    }
    }
    ?>
    i want to check s_customers module when updating any record see if number of points is changed or not if so check the change if bigger than number exists before insert into sms_outbound table in the database the new number of points and phone number for this customer and message (increase) if the value is smaller then message would be (decrease).
    Please need argent help in this case.
    thank you in advanced.

    ReplyDelete
    Replies
    1. Values that come from a result of query are extracted this way:

      $row = $bean->db->fetchByAssoc($results);

      $user_id = $row['assigned_user_id'];

      Thus, you would want to do something like:

      $points = $row['number_of_points'];

      if ($bean->fetched_row['number_of_points'] > $points)

      Also, fetched_row gives you the values of a record when it was retrieved from the database, rather than the values the user input for the current submit. That may have impact on what you are trying to do.

      Delete
    2. i've updated the code as you told me but still doesn't work:


      class DataSync{

      function updateCase($bean, $event, $arguments){
      $query="select number_of_points,phone_number from s_customers
      where id='{$bean->id}'";
      $points = $row['number_of_points'];
      $phone=$row['phone_number'];
      if ($bean->fetched_row['number_of_points'] > $points){
      $query="insert into sms_outbound (number_of_points,phone_number,message)
      values ($points,$phone,`increase`)
      };
      if ($bean->fetched_row['number_of_points'] < $points){
      $query="insert into sms_outbound (number_of_points,phone_number,message)
      values ($points,$phone,`increase`)
      };
      }
      }
      }
      ?>

      Delete
    3. hello Angel,
      i've done writing the code it work fine with me when i'm trying to update value but here 2 problem i can't resolve:
      1- when trying to insert new record it raise me error page to see sugarcrm.log which tell me it can't insert this value in sms_outbound table.
      2- when trying to export the module logic hook removed.
      thank's in advanced.
      oh here the code :

      class DataSync{

      function updateCase($bean, $event, $arguments){



      $query="select number_of_points,phone_number from s_customers where id='{$bean->id}'";
      $results = $bean->db->query($query, true);

      $result=$bean->db->fetchByAssoc($results);

      $number_of_points=$result['number_of_points'];
      $phone_number=$result['phone_number'];

      $number=$bean->number_of_points;
      $phone=$bean->phone_number;


      if ($number > $number_of_points){
      $q="insert into sms_outbound (number_of_points,phone_number,message)values ($number_of_points,$phone_number,'increase')";
      $bean->db->query($q, true);


      }

      else if ($number < $number_of_points){
      $q="insert into sms_outbound (number_of_points,phone_number,message)values ($number_of_points,$phone_number,'decrease')";
      $bean->db->query($q, true);

      }
      else
      {
      }
      }

      }

      ?>

      Delete
  70. Hi Angel,

    I have a query. I want use logic_hooks.php and Addtofile.php(file I created) to save the contents of the database to a doc file. I created a custom module with just the username,subject and a description. Now I want to save the data to a file. I tried using

    $query = "SELECT * FROM `data_base'\n";
    $result = $bean->db->query($query,true);
    $row = $bean->db->fetchrow($result);

    Then I am struck. Please help me.

    ReplyDelete
    Replies
    1. I am not sure I understand what it is you are having problems with. Are you not able to query the data or you don't know how to create a file?

      Delete
    2. Yes. I have the row results now. How can I save them in a doc file.

      Delete
    3. I don't know how you would specifically create a DOC file, but this example shows you how to create a TXT file. Maybe that'll give you what you need:

      http://www.tizag.com/phpT/filewrite.php

      Delete
    4. Right, thanks for the reply. I know how to do it in the normal PHP. I want to do it for my custom module in sugarcrm. How do I proceed to do that

      Delete
    5. I don't understand your problem. If all you are wanting to do is write data you are already retrieving to a text file, then you already have what you need.

      I don't understand what your module has to do with it.

      Delete
  71. This comment has been removed by the author.

    ReplyDelete
  72. I wnat to convert title field of lead into oppertunity title_c field thourgh convert lead option .I have make a hook for this but not working for me here is the code
    of both files i have put into custom/modules/leads/

    id;
    $titlemain=$bean->title;
    $opportunity = new Opportunity();
    $bean->load_relationship('title_c');
    $bean->title_c=$titlemain;
    $bean->save();
    }
    }
    }

    ?>

    ReplyDelete
    Replies
    1. If you are going to do it in a logic hook, you would want to do something like this:

      $opp = new Opportunity();
      $opp_id = $bean->opportunity_id;
      $opp->retrieve($opp_id);
      $opp->title_c = $bean->title (I am assuming this should actually be $bean->name, not $bean->title);
      $opp->save();

      Of course, there are other ways to do this, as you could also change the convert lead code to map that field to the opportunity's title field.

      Either way, there are a number of errors in your code.

      Delete
  73. Angel,

    First of all, I would like to thank you for the very informative blog that helped me, along with many others answer questions and suggest ideas for implementing code customization. I posted my question on the sugar forums but no one seems to be able to help me with this. I was wondering if you could take a look at my post at http://forums.sugarcrm.com/f3/help-logic-hook-syntax-81906/#post285543

    If you are short on time, the short version is I am creating a logic hook that would send an email to the account salesman every time there is a call initiated by somebody other than the salesman. My problem is I cannot figure out how to get the account salesman when my current bean is a call. Something like this is what I am looking for:

    $bean->load_relationship('account_calls');
    $account_salesman_id = $bean->account_calls->assigned_user_id;

    Any help with this would be greatly appreciated! Sorry to post this at your blog :)

    ReplyDelete
    Replies
    1. Hi Joe,

      Happy to hear you have found it helpful.

      If your current bean is a call, $bean->parent_id would give you the ID of the linked Account. So you could do something like this:

      require_once('modules/Accounts/Account.php');
      $acct = new Account();
      $acct->retrieve($bean->parent_id);
      $account_salesman_id = $acct->assigned_user_id;

      Delete
    2. Angel,

      Thank you so much for the quick reply. That is exactly what I was looking for. Do you have any tips on debugging/diagnosing logic hooks? Mine is not returning any errors in the logs but it still does not work. My code is below, in case you have a second to look at it:

      //get account salesman and account name
      require_once('modules/Accounts/Account.php');
      $acct = new Account();
      $acct->retrieve($bean->parent_id);
      $account_salesman_id = $acct->assigned_user_id;
      $account_full_name= $acct->name;

      if ($current_user->id != $account_salesman_id) {

      require_once('include/SugarPHPMailer.php');
      $welcome_msg = new SugarPHPMailer();

      //get salesman's email address and name
      require_once('modules/Users/User.php');
      $salesman = new User();
      $salesman->retrieve($account_salesman_id);
      $salesman_details = $salesman->getUsersNameAndEmail();

      $rcpt_name = $salesman_details['name'];
      $rcpt_email = $salesman_details['email'];

      $cstm_CALL_DESCRIPTION = $bean->description;
      $cstm_CALL_ID = $bean-> id;

      //Set RCPT address
      $welcome_msg->AddAddress($rcpt_email, $rcpt_name);

      //Setup template
      require_once('XTemplate/xtpl.php');
      $xtpl = new XTemplate('custom/modules/Calls/WelcomeMessage.html');`


      //Send message to Salesman about Call
      $template_name = 'Call';

      $xtpl->assign('ACCOUNT_NAME', $account_full_name);
      $xtpl->assign('CALL_DESCRIPTION', $cstm_CALL_DESCRIPTION);
      $xtpl->assign('CALL_ID', $cstm_CALL_ID);

      $xtpl->parse($template_name);

      $welcome_msg->Body = from_html(trim($xtpl->text($template_name)));
      $welcome_msg->Subject = 'New SugarCRM Call logged for one of your accounts';
      $welcome_msg->prepForOutbound();
      $welcome_msg->setMailerForSystem();
      $welcome_msg->From = 'xxx@xxx.com';
      $welcome_msg->FromName = 'SUGAR CRM';

      //Send the message, log if error occurs
      if (!$welcome_msg->Send())
      {
      $GLOBALS['log']->fatal('Error sending e-mail: ' . $welcome_msg->ErrorInfo);
      }

      Again thank you so much. The help you provided me in a few minutes would have taken me weeks at the forums. I had my question posted for a week at the forum with no luck! :)

      Delete
    3. The log file is about the best way. You should insert some log calls in your code at different points to see where it is failing, assuming it is even being executed.

      Delete
  74. Hi friends,
    I am newbie in SugarCE v 6.5.4 , I need a requirement in which when I create a new campaign I need to create a desktop or popup notification to Administrator , and can see when he login .
    Do you please help me to do the same . Please advise me with code and ideas .

    Thanks,

    Anes

    ReplyDelete
    Replies
    1. Logic hooks don't interact with the interface, or better stated, aren't designed to, so a popup is not something that can be easily accomplished via a logic hook.

      You could create an after_save hook that sends an email instead or executes code that sets the desktop notification.

      Delete
    2. Could you help me to do this. I want to create a after_save hook that will send a email to multiple person in a department once a record is assign to that department.
      I would really appreciate your help.

      Delete
  75. Angel, I am new to SugarCRM and currently trying this out. Though I an idea that I want to do but don't know how. Here's the scenario:
    - I want to configure the CRM so that when "Agent A" saves a Case, it gets assigned to "Supervisor C".
    - Also, when "Agent J" saves a Case, it gets assigned to "Supervisor D".

    It's more like whenever an agent creates and saves a Case, it should automatically assign it to that agent's supervisor.

    ReplyDelete
    Replies
    1. There are a couple of ways of tackling this, but the most basic way would be to have some sort of switch statement in your logic hook which examines the ID of the current user saving the case and then based on that value, it changes the assigned user to the appropriate supervisor.

      For example,

      $saving_user_id = $bean->modified_user_id;

      switch($saving_user_id)
      {
      case 'agent_j_id':
      $bean->assigned_user_id = 'agent_j_supervisor_id';
      break;
      case 'agent_a_id':
      $bean->assigned_user_id = 'agent_a_supervisor_id';
      break;
      }

      ..and so forth...

      Delete
  76. How would the handling of the variable $results change if the SQL call was a COUNT?
    So far I have:

    $query = "SELECT COUNT(name) from cutsom_table";
    $result = $bean->db->query($query, true);
    $row = $bean->db->fetchByAssoc($result);
    $num = $row['name'];

    And $num variable is blank. Thoughts?

    ReplyDelete
    Replies
    1. It is blank for a couple of reasons...

      Your query is not returning the column named "name," it is instead returning a count of records in the table named "cutsom_table," based on the "name" column. This would return a number, not the contents of the name table.

      This is why $row['name'] fails, as there isn't a column named "name" in the result set.


      Given you didn't give the count a column, it would be returned without a label. If you want to access the result, change your query to "SELECT COUNT(name) as the_count FROM cutsom_table" and use $row['the_count'] to access it.

      Lastly, I don't know if your table is actually named "custsom_table" but it seems you have spelling error there, unless it actually was created with a misspelled "custom."

      Delete
  77. the one question i am trying to get is to have a logic hook to send an email when a case is assigned.

    email address must be static.
    subject is assigned users mobile number
    description is case subject, one custom field and account name,and 2 custom accounts fields?

    and a string open http://blablabla/do.php?case_number = $case_number?assigned_user=$assigned_user(case)?account_name = account_name?yaxis=yaxis?xaxis=$xaxis?case_subject=$case_subject? etc

    the reason is we have email to sms. and i need the case assigned users cell number in the subject with case and account info in detail as assigned case username. the link takes them to a form where they update the form and it updates the case again.

    Regards

    ReplyDelete
    Replies
    1. Here are a couple of examples of how to send email using code. You could incorporate that into your logic hook and accomplish your goal:

      http://cheleguanaco.blogspot.com/2011/06/sugarcrm-customization-workflow-emails.html

      http://cheleguanaco.blogspot.com/2009/11/sugarcrm-customization-custom-workflow.html

      http://cheleguanaco.blogspot.com/2012/04/sugarcrm-customization-email-templates.html

      Delete
  78. Hello Angel

    Can you please tell how to integrate sugarcrm with drupal through logic hooks

    ReplyDelete
  79. I am new to sugar and php and i Could really use your help. I want to create a after_save hook that will send a email to multiple person in a department once a record is assign to that department.
    I would really appreciate your help.

    ReplyDelete
  80. Hey Angel, may I know, when user changes his password how to get that new password at the same time using logic hook when user presses save button to change password. I have checked using after_save, but no result. Thank you.

    ReplyDelete
  81. Hi, I am using Sugarcrm Version 6.5.18. I would like to link the fields up such as when I choose "Product" as my Type field and my subject box field will appear as "RE: Product". How can I link both of them up and where do I edit the code at using Logic Hook? Am I suppose to use ['before_save']? I am new to Sugarcrm. Thanks.

    ReplyDelete
  82. Hi, I am using Sugarcrm Version 6.5.18. I would like to link the fields up such as when I choose "Product" as my Type field and my subject box field will appear as "RE: Product". How can I link both of them up and where do I edit the code at using Logic Hook? Am I suppose to use ['before_save']? I am new to Sugarcrm. Thanks.

    ReplyDelete
    Replies
    1. If you intend to do that at the time that the user select "Product" in the Type field, you wouldn't be able to do it via a logic hook. You need to create a dependency between the type and subject fields, which is not done through logic hooks.

      If you are using Community Edition, you should take a look at using this tool: http://www.sugarforge.org/projects/devtoolkit/

      Delete
  83. Hi Angel,

    I don't know if you are still contributing to this blog, but thought I'd ask anyway! I need to populate a custom field from Accounts to Contacts so I can then expose that to MailChimp. The field in Accounts is Account_Type.

    I have copied your initial code and modified it for what I thought would work. Unfortunately it doesn't. I was hoping that you could take a look at my code and let me know where I have gone wrong (btw, I am not a coder, so am bumbling through!).

    Here is Logic_Hooks.php in public_html/sugar/custom/modules/Contacts:



    And here is the code from AccountToContact.php, also in public_html/sugar/custom/modules/Contacts:

    id;
    $acct_id = $bean->account_id;
    $query = "SELECT accts.account_type FROM accounts accts ";
    $query .= "WHERE accts.id = '$acct_id' LIMIT 1";
    $results = $bean->db->query($query, true);
    $row = $bean->db->fetchByAssoc($results);
    $account_type = $row['account_type'];

    //Change assigned_user_id value on Case
    $bean->account_type = $account_type;
    }
    }
    ?>

    My field in Contacts for Account_Type is not populating with the value from Accounts.

    Thanks heaps for your help!

    John

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. If the hook is being executed when a Contact is saved, wouldn't the "account_type" field on the Contact record have a name other than "account_type?"

      I would assume it would be a custom field, but even if not, I doubt it is "$bean->account_type" as $bean = current contact in this context, not the Account record.

      Also, can you define what you mean by things not working?

      Delete
  84. Hello Angel i am using ases as refunds and i have refund_amount_c in cases and refund_amount_c in accounts what i need is whenever i create a case related to the account and add refund amount then that refund amount should show in the accounts detail view... I tried to modify your Query but it is not working can you help me with that please??

    ReplyDelete
  85. Thank you. It helped Me. And a small suggestion, it would be really very good if related information about the code is given for each line of code since i am newbie.

    ReplyDelete
    Replies
    1. Thanks for the feedback. I will take it into consideration for future posts.

      Delete

Your comments, feedback and suggestions are welcome, but please refrain from using offensive language and/or berating others. Thank you in advance.