Logichook on copying bean ?

Hello everybody,

Is there a clean way within a before_save logichook to determine if the bean is being copied or "classically" modified ? 

I heritated such a code : 

if (!$arguments['isUpdate'] && preg_match('/picture_duplicateBeanId/', $_SERVER['QUERY_STRING'])){
	// $GLOBALS['log']->fatal("Copying an SLA Report :: ".$_SERVER['QUERY_STRING']);
    $split = explode('&',$_SERVER['QUERY_STRING']);
	$id = null;

    foreach($split as $k) {
		if (preg_match('/picture_duplicateBeanId/', $k)) {
            $aid = explode('=',$k);
            $id = $aid[1];
            continue;
		}
    }
}

The guy before me checked the query_string from the server global value, but is there a better way to do that ? 

Best regards and nice week to all :-)

Enes

  • I have not tried this but if you use the "copy" it's like a create but with data populated for you, so I would assume that the bean has no id until after the save. Having said this, you will have the same behavior when creating a brand new record, so it may not satisfy your needs.

    FrancescaS

  • Hello Enes

    Could you explain from the business perspective what user behavior should be identified prior to record save ?

    Best Regards,
    Dmytro Chupylka

    integroscrm.com
    We make work in Sugar CRM system faster, more convenient and efficient

  • Hello Dmytro,

    In fact I need to get the objects linked to the original to copy them to the new one : 

    $originalSlaReport = BeanFactory::retrieveBean('SLARE_c', $id);
    
    if ($originalSlaReport->load_relationship('slare_c_slait_c_1')) {
    	$bean->load_relationship('slare_c_slait_c_1');
    	foreach ($originalSlaReport->slare_c_slait_c_1->getBeans() as $slaItem) {
    		$copySlaItem = BeanFactory::newBean('SLAIT_c');
    		$copySlaItem->name = $slaItem->name;
    		$copySlaItem->active_c = $slaItem->active_c;
    		$copySlaItem->realized_c = $slaItem->realized_c;
    		$copySlaItem->objective_c = $slaItem->objective_c;
    		$copySlaItem->gap_c = $slaItem->gap_c;
    		$copySlaItem->penalty_c = $slaItem->penalty_c;
    		$copySlaItem->description = $slaItem->description;
    		$copySlaItem->target_c = $slaItem->target_c;
    		$copySlaItem->save();
    		$bean->slare_c_slait_c_1->add($copySlaItem);
    	}
    }

    where $id comes from the code I copied on my original post.

    The trick could be that I create my own button to copy the initial object and their childs ...

    If you have an idea to do it smartly, I'll take it.

    Best regards,

    Enes

  • Enes,

    A couple of things here: firstly I think you should be copying related records on the after_save event not the before_save. Whilst the before_save will probably work, by definition the record does not yet actually exist. I think the related records will still be created and linked if all is OK but you might run into issues if there is a problem with the database Save. It is likely in this case that you end up with orphaned relationship records that you have no way of removing other than directly in the database. Not in itself an issue to the CRM but a waste of db storage space anyway so not the best practice.

    Secondly, as Francesca says, what you really need is a way of differentiating between a clean "Create" event and a dirtied "Copy" event. For this I would use a boolean flag on the record that gets set in an intercept on the "Copy" button click event - it can be passed using a custom drawer open action easily enough in a parameter. For this bool flag I would be using a pseudo-field via the vardefs extensions and not create a real one in Studio otherwise you have to make sure you empty the field so that subsequent after_save events do not pick it up. As we would be in after_save, updating a "real" field like this would need SQL code or a second Save - neither of which are ideal. If you have a pseudo-field though you can set the value in the javascript (probably an initialize() function is best) and it will persist through the bean save event but not be stored anywhere leaving it empty (false) for subsequent saves.

    Depending on what you are doing elsewhere, you may also need to distinguish between a "Copy" event and a regular "Save" event. For this you should be able to use the after_save arguments.isUpdate value ( support.sugarcrm.com/.../ ), to see if it is a new record (which a "Copy" should be) or a regular update.

    Hopefully a couple of options in here to help you out.

    Good luck,

    JH.

  • Hello John,

    Thanks for your detailed explanation, in fact I need a smart and quick way to make what I need, but no doubt that your solution would work.

    For other devs we've done, we also use sql queries to update boolean flags in order to make some operations, for example running some BPM's in specific cases.

    Hope in the future we will have a specific logichook after_copy_bean :-)

    Thanks a lot everybody for your answers.

    Best regards,

    Enes

  • Hello again John,

    What I finally did is to create a "fake" field that is non-db, and it works like a charm !

    Thanks again for your proposition.

    Best regards,

    Enes