Sorry for being a bit late but yesterday was local holiday in Valencia so I didn’t check the forums. Ok, here we go. Remember that this code doesn’t accomplish what you are trying to but counts years between 2 given dates (birthdate and current date). Anyway, it should be easy to adapt it.
First we begin by adding the field definition to the module. In my case, it is Contacts, change Contacts for your module name as your convenience.
Create custom\Extension\modules\Contacts\Ext\Vardefs\sugarfield_XXXXXXXX.php where XXXXXXXX is the name of your calculated field. And below you find the definition:
$dictionary[‘Contact’][‘fields’][‘age_year_calc’] = array( //change age_year_calc for XXXXXXXX. Careful, Contact!!! Not Contacts!!! Module name in singular.
‘name’ => ‘age_year_calc’, //Again change age_year_calc for XXXXXXXX
‘vname’ => ‘LBL_AGE_YEAR_CALC’, //You’ll have to add this label to the language files you’re managing. Not sure if you can do this from studio.
‘type’ => ‘varchar’, //As you can see, I chose varchar. This is because I show “N/A” if birthdate is empty or “Error” when birthdate is greater than current date.
‘len’ => ‘3’, //Nobody is older than 999, right? xD
‘source’ => ‘non-db’, //<- Important as it is calculated and we don’t want to store it in the DB (at least not yet).
//‘studio’ => ‘visible’, //I can’t remember how I added it to the views, but maybe this makes the task easier for you (I was such a noob and still I am xD)
);
Well, I guess until this point everything was quite clear for any familiarized SuiteCRM user. Now we’ll fight against the Logic Hook but in fact he’s our friend
If you want more info on Logic Hooks there are lots of out there. Sorry for not getting deeper.
We have to edit 2 files.
1.- Edit custom\modules\Contacts\logic_hooks.php and add the following lines of code.
$hook_array[‘after_retrieve’] = Array();
$hook_array[‘after_retrieve’][] = Array(1, ‘Here goes YOUR description’, ‘custom/modules/Contacts/logic_hooks_class.php’,‘logic_hooks_class’, ‘f_age_year_calc’);
For your info, I’ll explain the 2nd line a bit. Array has 5 parameters:
1.1 -> 1 is the index of the hook in the after_retrieve array. By the way, we use after_retrieve because after retrieving the field (hence the name) from DB we wanna show it in the Detailview page. If I remember well, you should add the same function to [‘process_record’] in order to diplay the field in the Listview. Don’t ask me why but it worked that way 
1.2 -> Any text you wanna use for describing your hook.
1.3 -> Route to the file where your logic hooks class is stored. Don’t know if you can change the name.
1.4 -> Name of the class (found inside the file previously named).
1.5 -> Name of the class function we want to use.
2.- Edit or create custom\modules\Contacts\logic_hooks_class.php It should look like below. Some comments also to help you.
<?php
if (!defined('sugarEntry') || !sugarEntry) die('Not a valid Entry Point');
class logic_hooks_class{ //Name we used in point 1.4
function f_age_year_calc($bean, $event, $arguments){ //Name we used in point 1.5
////// $bean->age_year_calc <- This is our important field.
$focus = $bean->custom_fields->retrieve();
if ($bean->birthdate != null){
$currentDate = new DateTime();
$currentDateformat = $currentDate->format('Y-m-d');
$dateDB = $bean->birthdate;
$dateDBimport = DateTime::createFromFormat('d/m/Y', $dateDB);
$dateDBformat = $dateDBimport->format('Y-m-d');
$dateDBformatDate = new DateTime($dateDBformat);
$dateDifference = $currentDate->diff($dateDBformatDate);
$bean->age_year_calc = $dateDifference->y; //I think you could use $dateDifference->d so you have days between those 2 dates.
if ($dateDBformat > $currentDateformat){
$bean->age_year_calc="Error";
}
} else {
$bean->age_year_calc = "N/A";
}
}
}
?>
I hope all this helps you. Please, let me know if adding ‘studio’ => ‘visible’ to the vardef file makes the work. If not, I’ll search for the insetion of the field in Detailview and Listview.
Kind regards!!!
Chemi