Not an answer but rather a kind of half temporary workaround, posting in case someone finds it useful, and beacuse you metioned you are familiar with creating an extension/module.
You can use hook_civicrm_buildForm to alter the form status id based on activity type_id/name, this soultion is not user friendly and it won't work from standalone
context, ie when using Contacts -> New Activity, but it can do the trick if you can live with that and don't have a ton of Activities Types.
Hope it helps, and let me know if there's anything unclear.
// Implement myextension_civicrm_buildForm
function myextension_civicrm_buildForm( $formName, &$form ){
if ( $formName == 'CRM_Activity_Form_Activity' ) {
// Hook only when adding an Activity and the context is not standalone
if ( $form->getAction() == CRM_Core_Action::ADD && $form->_context != 'standalone' ) {
// The array that holds the Status and Activities that should have that status by default
// and the only bit that you'll have to change/upadte when you add more activities and statuses
$activities = array(
'Completed' => array( 'Meeting', 'Phone Call' ),
'No-Show' => array( 'Custom Activity' ),
'My Custom Status' => ( 'Another Custom Activity', 'Yet Another Custom Activity' )
);
foreach ($activities as $status => $activity_types) {
if ( in_array( $form->_activityTypeName, $activity_types ) ) {
// Get status_id by Label
$result = civicrm_api3('OptionValue', 'getsingle', array(
'sequential' => 1,
'option_group_id' => 'activity_status',
'label' => $status,
));
// Set the default value in the form
$defaults['status_id'] = $result['value'];
$form->setDefaults($defaults);
}
}
}
}
}
EDIT
If you want to do the same thing when in standalone
context you could add some jQuery/JavaScript to the form, see below updated snippet and JS snippet.
// Implement myextension_civicrm_buildForm
function myextension_civicrm_buildForm( $formName, &$form ){
if ( $formName == 'CRM_Activity_Form_Activity' ) {
// Hook only when adding an Activity and the context is not standalone
if ( $form->getAction() == CRM_Core_Action::ADD ) {
// The array that holds the Status and Activities that should have that status by default
// and the only bit that you'll have to change/upadte when you add more activities and statuses
$activities = array(
'Completed' => array( 'Meeting', 'Phone Call' ),
'No-Show' => array( 'Custom Activity' ),
'My Custom Status' => ( 'Another Custom Activity', 'Yet Another Custom Activity' )
);
if( $form->_context != 'standalone' ){
foreach ($activities as $status => $activity_types) {
if ( in_array( $form->_activityTypeName, $activity_types ) ) {
// Get status_id by Label
$result = civicrm_api3('OptionValue', 'getsingle', array(
'sequential' => 1,
'option_group_id' => 'activity_status',
'label' => $status,
));
// Set the default value in the form
$defaults['status_id'] = $result['value'];
$form->setDefaults($defaults);
}
}
} else {
// Make $activites available in JS
CRM_Core_Resources::singleton()->addVars( 'myextension', array( 'defaultedActivites' => $activities ) );
// Add JS script
CRM_Core_Resources::singleton()->addScriptFile( 'myextension', 'defaultedActivites.js' );
}
}
}
}
// in your JS script => defaultedActivites.js
// Same principle as above, there might a better way to do this JS-wise but that should do it
CRM.$(function($) {
$( '#activity_type_id' ).change( function(){
var defaultedActivites = CRM.vars.myextension.defaultedActivites; // Store defaultedActivites
var activity = $( this ).select2( 'data' ); // Get the select2 Activity object, ie Activty type
$.each( defaultedActivites, function( status, activityTypes ){
activityTypes.map( function( currentActivity ){
if( currentActivity == activity.text ){
// Get status_id by label
CRM.api3( 'OptionValue', 'getsingle', {
'sequential': 1,
'option_group_id': 'activity_status',
'label': status
}).done( function( statusId ) {
// Set default value
$("#status_id").val( statusId.value ).trigger("change");
});
}
})
})
});
});