Custom Scheduler Code - Account Record - Seems to “Break” Email Relationship on Save - Please help!?

(Sorry to post this here ‘and’ in the Developer channel…I’m not really quite sure where it belongs?)

I have built a custom schedule job to calculate how many day’s it’s been since an ‘activity’ has been made on this record.

I’ve created a custom field that gets updated whenever an activity is logged, which sets a datetime field in the Account record to the current datetime.

Then, I want this scheduled job to run overnight, to update another custom field (days_since_last_activity) to calculate the difference between ‘today’ and that date, and enter that number into the field.

My Code seem to run correctly, it does the calculation correctly, and it updates the field to the new value…

However…for some reason, the Account record seems to ‘lose’ it’s email address. (ie. the email field will be blank after the update)

After some more research, it’s really just losing the ‘relationship’ between the Account and the email field.

I’m guessing there is some way I’d need to save the related Bean as well???

Any guidance ???
(I’m kinda stuck)

Thanks!

My Code Below:

function accountActivityAgingUpdater()
{
   //LoggerManager::getLogger();
   //Get the cutoff date for which meetings will be considered
   date_default_timezone_set("America/New_York");
   $todaysDate = date('Y-m-d h:i:s');
   $todaysDate = strtotime($todaysDate);

   //LoggerManager::getLogger()->error('Account -- Todays date ' . $todaysDate);
   //Get an instance of the Accounts bean for querying
   //see the Working With Beans chapter.
   $bean = BeanFactory::getBean('Accounts');

   //Get the list of Accounts - 
   //this can likely be optimized to only find accounts with
   //some value in the $account->last_activity_date_c field
   $query = "accounts_cstm.ams_sid_c != ''";
   $accounts = $bean->get_full_list('', $query);

   foreach($accounts as $account)
   {
         //Get the date the case was created
         $lastActivityDate = $account->last_activity_date_c;

         //LoggerManager::getLogger()->error('Last Activity Date ' . $lastActivityDate);
         $lastActivityDate = strtotime($lastActivityDate);

         //Determine the date difference in days
         //$timeDiff = abs($todaysDate - $lastActivityDate);
         $timeDiff = abs($todaysDate - $lastActivityDate);

         //LoggerManager::getLogger()->error('Time Diff ' . $timeDiff);
         // 86400 seconds in one day
         $numberDays = $timeDiff/86400;
         $numberDays = intval($numberDays);

         //LoggerManager::getLogger()->error('The Diff ' . $numberDays);  

         //this handles if the last activity date is empty
         if (!empty($lastActivityDate)) {
            $account->days_since_last_activity_c = $numberDays;
         } else {
            $account->days_since_last_activity_c = 999;
         }

         //Save the cases changes
         $account->save();
   }
   //Signify we have successfully ran
   return true;
}

Calling in Super @pgr and Magic @clemente.raposo to the rescue! :bat: :symbols:

I would avoid the problem altogether, and save a ton of time in terms of performance (especially if you have many accounts) by running a single UPDATE SQL statement doing all the calculations at once.

1 Like

I believe you should do
$account->in_workflow=true;

just before $account->save();

Wow…that works!!
Would you mind explaining to me ‘why’ that works??
(Or perhaps point me at the documentation that explains?)
I’ve VERY new to building things on this platform, and I was flying by the seat of my pants on this one…heh.

Thank you Sir!!

@pgr
So, basically, do the calculation directly in the Database?
(No need to loop through beans or any of that nonsense…right???)

Conceptually, that totally makes sense…I guess I was trying to stay in the ‘scheduler/logic hook’ flow concept, but If I’m understanding what you’re saying, this would be FAR simpler!

This was introduced to fix that problem with workflows removing email fields, then also in inline editing that also removed email fields

Ok…great…Thank you again!
Are there other modules that this is relevant for as well??

I’ve seen really convoluted cases of those bean save logics. One routines calls a bean save, and then some strange condition somewhere updates something on a related record, and then that gets saved, and new hooks are triggered… it can get messy and the only way to find out is to go in deep with the debugger.

Then there are some mechanisms like that in_workflow field which is used to make some of that save logic conditional. There are others.

See for example this save function:

SuiteCRM/Person.php at master · salesagility/SuiteCRM · GitHub

About the SQL statement again. Although it’s possibly not the best design to go for a direct SQL query, sometimes I think it can be adequate. For example, if you have 10000 accounts, that process with the scheduler is going to take ages to run, and it will likely break, even regardless of these email problems caused by tangled code. A single UPDATE query would handle that in a highly optimized way.

@pgr @blqt
I apologize AGAIN.

The solution @blqt proposed DID in fact work.
I was ‘forgetting’ to Repair and ReBuild.

@pgr - your solution ALSO works…and I’m going to implement in some instances.

Thank you all!!!

2 Likes