How to prevent logic hook firing from another module or on import

Hi all.

I've created a logic hook which basically checks if the record is updating and if so, check if there is a contact assigned and if not, do not allow save. This works fine on my test site but not on a customers site. They have two issues:

1) The first being when they save an account, it's also running this code, can I ONLY have this code run if the record is saved directly in opportunities?

2) Is there anyway to stop the code firing on import? So only on an actual edit it triggers?

Here is my code:

class oppcontactcheck
{
function validateDuplicateRecord( $bean, $event, $arguments )
{
if (!isset($arguments['isUpdate']) || $arguments['isUpdate'] == true)
{
//Opens Database variable
global $db;
$crm_id = $bean->id;
//Checks how many leads exist with the criteria contact name and mobile number
$oppContactCheck = "select count(*) as count from opportunities o join opportunities_contacts oc on o.id = oc.opportunity_id join contacts c on c.id = oc.contact_id"
. " where o.id = '".$crm_id."'";
$oppContactCheckResult = $db->query($oppContactCheck, true, 'Error Update');
$row = $db->fetchByAssoc($oppContactCheckResult);
//Assigns the count of the above to a variable
$count = $row['count'];
$id;
$conn = $GLOBALS['db']->getConnection();
$GLOBALS['log']->info('### Count: ' . $count);

//Change this to change the message that pops up
$duplicateoppContactMessage = "Please add a contact to the record";

//Checks if count is greater than 0
if ($count == 0)
{
throw new SugarApiExceptionInvalidParameter($duplicateoppContactMessage);
}
}
}
}

/resized-image/__size/320x240/__key/communityserver-discussions-components-files/54/Capture.PNG

I've also added a picture as my formatting is being wiped when copying.

Thanks! 

  • First of all - I think given you want to prevent a save - this actually feels more like a validation as opposed to a logic hook.

    You may want to consider reviewing this content: https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_10.0/Cookbook/Adding_Field_Validation_to_the_Record_View/

    Separately, if you were doing this via logic hooks, you generally want to use the bean framework to look for related records and count them. See https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_10.0/Data_Framework/Models/SugarBean/#Fetching_Relationships for guidance on how to do this. That way, you don't need to worry about checking for things like the opportunity record being deleted, or a deletion in the relationship table.

  • You can easily run this code only when saving directly from Opportunities by adding a logic hook before_relationship_add.

    André Lopes
    Lampada Global
    Skype: andre.lampada
  • Hello Daniel,

    I believe you are new to SugarCRM. There are a few improvements I would suggest that you make to your code.

    For example, I suggest that you use SugarQuery instead of using raw SQL query for your select statement.

    https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_9.2/Data_Framework/Database/SugarQuery/

    Secondly, regarding your question,

    There must be a bean of opportunities getting saved in one of the accounts logic hooks. You can set the

    $bean->processed bit to true if you don't want the logic hooks to trigger after the bean is getting saved.

    Or you can set a custom bean property like

    $bean->came_from_account = true;

    and then in your logic hook in opportunities, you can check where the bean save came from.

    Inside the logic hook write:

    if ( $bean-> came_from_account != true){

    //logic hook code

    }

    Kind Regards!
    Rolustech Support
    Email: support@rolustech.com 
    Website: www.rolustech.com 

  • Hi Hussain.

    Thank you for your reply, what is the benefit of SugarQuery over pure SQL? They both have the end goal of assigning data to variables but I find sugarQuery much harder to read (I am of SQL background).

    Thank you for your help and I'll try to implement this instead!

    Thanks,

    Daniel

  • Hi Adam.

    Thanks for your input. I don't believe I've ever seen the field validation so that might be a place to start instead which is good. Is there a downside to using SQL instead of Bean for simply assigning variables? I understand the need for Bean for saving but have yet to find a good reason for transitioning away from SQL for getting data/variables.

    Thanks!

    Daniel

  • Hi Daniel,

    Two reasons to consider SugarQuery:

    • Even if you are of SQL background (as many of us are), it does not mean we don't still make mistakes every now and then - eg forgetting an apostrophe in the wrong place. By wrapping an object layer around that, we reduce the opportunity for accidents ending up in production.
    • It makes your queries more portable between different database servers - may not be relevant for the implementation you're working on today - but I know a lot of people build libraries of code they reuse in different parts of an organisation, and you may one day reuse that code in a next client - or wish to share it publicly. SugarQuery makes that a lot easier.

    Equally, I acknowledge that it takes a bit more time to learn, and you may not feel its justified if you're just working on the one query that will never get used anywhere else. 

    Regards,

    Adam

  • ,

    Definitely i would use SugarQuery, also for security reasons (eg: what if a malicious user (or an integration coming from malicious places) pushes into your crm a record with id something like '"; truncate opportunities; --' ? The good old bobby tables!

    Even if it won't work due to further sanitisation, you get my point. Prepared statements would add an additional layer of protection thanks to SugarQuery.

    There is also an alternative ORM way of achieving what you attempted to do: "does this opportunity have any contacts related to it?" see here: https://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_10.0/Data_Framework/Models/SugarBean/#Fetching_Related_Record_IDs

    Finally, that type of validation I would probably put it on the api itself. I would extend the PUT /Opportunities/<id> api with this additional check. That way it would not trigger on imports, but only when an edit fires from the api perspective (if that's your overall objective).

    Cheers

    --

    Enrico Simonetti

    Sugar veteran (from 2007)

    www.naonis.tech


    Feel free to reach out for consulting regarding:

    • API Integration and Automation Services
    • Sugar Architecture
    • Sugar Performance Optimisation
    • Sugar Consulting, Best Practices and Technical Training
    • AWS and Sugar Technical Help
    • CTO-as-a-service
    • Solutions-as-a-service
    • and more!

    All active SugarCRM certifications

    Actively working remotely with customers based in APAC and in the United States

  • Hi Enrico.

    Thanks a lot for that explanation that's fantastic. I think the other parts are past my current developer knowledge but will try to find the time to extend my knowledge to learn these parts as they seem far more useful than what I am doing at the moment.

    Thanks,

    Daniel

  • Hi Adam.

    Thanks for taking the time to help me with that,I'll try to find the time to learn the SugarQuery syntax and implement this going forward instead. It's more of an "ease" thing than anything else, but it's cerainly something I should learn! 

    Thanks,

    Daniel