Prevent logic hook from saving

I have a logic hook triggering before_relationship_add for the Accounts module.

This checks all contacts if certain flags are set and throws an error if not all the flags are found on the related contacts.

After throwing the error, it looks like the save was prevented, but as soon as I refresh, I can see that the change has been saved even though an error was thrown in the logic hook!

How do I prevent the save from happening?

Derick

Parents Reply Children
  • I am triggering this on 'before_relationship_delete' and 'before_relationship_add' on Contacts and 'before_save' on both Contacts and Accounts.

    It basically checks if all 5 communication flags are set across all contacts related to an account. If not, it should throw an error unless the update is done by a system script via the api.

    I'm not sure how much is relevant, but here it is:

        function check_valid_prefs($bean, $event, $arguments) {
            $relAccounts = [];
            $currentContactId = null;
            $isContact = ($bean->object_name == 'Contact');
            $isAccount = ($bean->object_name == 'Account');
            $isRelationshipHook = (strpos($event, 'relationship') !== false);
           
            if($isRelationshipHook) {
                if($isContact) {
                    $contactBean = clone $bean;
                }
                if($isAccount) { // We only need to trigger this logic once for a relationship
                    return true;
                }
            }

            if ($isContact) {
                if ($_SESSION['authenticated_user_id'] == '1') { // System user (not available in bean on 'before_save')
                    return true; // Do not do any checks if the system is creating the account (most likely Marketo)
                }
                $relAccounts = $bean->get_linked_beans('accounts', 'Account');
                //$accBean = new Account();
                //$accBean->retrieve($bean->account_id);
                //$relAccounts[] = $accBean;
                $currentContactId = $bean->id;
               
            } elseif ($isAccount) {
                $relAccounts[] = $bean;
            }
           
            // Check if this change affects any related accounts
            foreach ($relAccounts as $Account) {
                if ($Account->performance_opt_out_c == 1)
                    continue; // ignore the subscription logic if opted out

                $sem = $seo = $net = $prt = $srv = false;
               
                // This call overwrites the data in the current bean ( if this $bean is a Contact type)
                $relContacts = $Account->get_linked_beans('contacts', 'Contacts');
                foreach ($relContacts as $Contact) {
                   
                    if($isContact && $isRelationshipHook && $contactBean->id == $Contact->id) {
                        $Contact = $contactBean;
                    }
                   
                    if (count($relContacts) == 1) {
                        // If it's the only contact, set all preferences
                        $this->_setAllPreferenceForContact($Contact);
                    }

                    if ($Contact->id == $currentContactId
                            && $event == 'before_relationship_delete'
                            && count($relContacts) > 1) {       // unless it's the only contact left
                        continue;
                    }                   

                    if ($Contact->accounts_contacts_contact_status != 'Active')
                        continue; // Ignore this contact if it's not Active

                    $sem = $sem || $Contact->preference_sem_report_c == 1;
                    $seo = $seo || $Contact->preference_seo_report_c == 1;
                    $net = $net || $Contact->preference_network_report_c == 1;
                    $prt = $prt || $Contact->preference_print_rollovers_c == 1;
                    $srv = $srv || $Contact->preference_service_messages_c == 1;
                }
                // are any of the flags not set?
                if (!($sem && $seo && $net && $prt && $srv)
                        && (count($relContacts) > 0)
                        && $Account->na_account_status_c != 'verified_lead') {
                    $missing = array();
                    if (!$sem)
                        $missing[] = 'SEM Report';
                    if (!$seo)
                        $missing[] = 'SEO Report';
                    if (!$net)
                        $missing[] = 'Network Report';
                    if (!$prt)
                        $missing[] = 'Print Rollovers';
                    if (!$srv)
                        $missing[] = 'Service Messages';


                    $msg = "When trying to save '{$bean->object_name}' ($bean->id). "
                            . "These changes will cause account '{$Account->name}' ({$Account->id}) "
                            . "to have invalid preference centre settings. "
                            . "Please make sure there is at least one contact for each setting. "
                            . "The missing flags are: " . implode(', ', $missing);

                    throw new SugarApiExceptionInvalidParameter($msg);
                }
            }
        }

    This seems to work ok on the 'before_save' hooks, but on the 'before_relationship_add' hook, the error message triggers, but it saves anyway.

  • Adding the logic to a before_save event solved my issue. By the time the before_relationship_add is triggered, the beans have already been saved and it's too late to prevent it from saving. It would be possible to roll back the changes, but it was easier just to change the logic hook event. 'before_save' gets triggered when a relationship is added anyway.