Duplicate records from listview

Hi all,
in general I know how to add a button to “Bulk action” in listview but is it possible to create a button that allows to duplicate the selected records? Unfortunately for my company this function seems indispensable.
Thanks in advance for the suggestions.

This should be pretty simple if all you need is to duplicate the bean. If you need more elaborate duplicating (of related records, etc), it might get more complicated.

But it’s all a matter of coding it. You can also look (depending on your module) if there is already an elaborate duplicate function that exists. Some modules have “Duplicate” buttons on the detail view, so it’s there.

Hi prg,
Thanks for reply.
This is a custom module: the lines to be duplicated contain both text and related fields but should be copied exactly as they are. The only difference with the “Duplicate” in detail view is that here I have to copy all the selected ones.
I will try to look at the existing duplicate function even if I still don’t have in mind how to set everything up.

1 Like

Hi prg, only help if you can give me this indication: where do I find the “DUPLICATE” function (I would then need to put together duplicate and save …).
Thanks so much.

Hhmm it’s not the easiest thing to find in the code because the word “duplicate” appears in tons of places, and sometimes it is the verb “to duplicate”, sometimes it is the noun “this record is a duplicate”…

Are you using a debugger? The best thing would be to follow the code to where it leads you.

Hi pgr, I only use the browser console.
I have never practiced other suitecrm debugging tools. Can you suggest something to me? (not too complicated to manage on the server to avoid the continuous need of the IT department)

Normally to do PHP debugging the general approach is

  • get a second environment so you’re not working directly in production - a test system on a VM, on your laptop, whatever

  • install XDEBUG server-side

  • run some IDE like PhpStorm, Eclipse, VS Code, etc

If you tell me which OS’s and which IDE you want to work from I can try helping a bit further, although there is probably plenty of stuff on the Internet, tutorials, etc

Hi all,
I bring up this post because I think I have made progress.

After studying various examples, I managed to add the “DUPLICATE” action in Bulk Action on my custom module (not yet tested on large quantities of row).

So, custom/MYMODULE/views/view.list.php
(please note that here are some lines that are not needed for this function such as references to ViewSmarty that I’m using for other reasons)

<?php
if (!defined('sugarEntry') || !sugarEntry) {
die('Not A Valid Entry Point');
}

require_once('custom/include/CustomListViewSmarty.php');
require_once('include/MVC/View/views/view.list.php');

class MYMODULEViewList extends ViewList {
function preDisplay() {
    $this->lv = new CustomListViewSmarty();
    $this->lv->actionsMenuExtraItems[] = $this->buildMyMenuItem();
}
    
    protected function buildMyMenuItem()
{
    global $app_strings;

    return <<<EOHTML
<a class="menuItem" style="width: 150px;" href="#" onmouseover='hiliteItem(this,"yes");' 
    onmouseout='unhiliteItem(this);' 
    onclick="sugarListView.get_checks();
    if(sugarListView.get_checks_count() &lt; 1) {
        alert('{$app_strings['LBL_LISTVIEW_NO_SELECTED']}');
        return false;
    }
    document.MassUpdate.action.value='copypassedids';
    document.MassUpdate.submit();">DUPLICA</a>
EOHTML;
}
}?>

and custom/MYMODULE//controller.php

<?php
class MYMODULEController extends SugarController
{
    public function action_copypassedids() {
        if ( !empty($_REQUEST['uid']) ) {
            $recordIds = explode(',',$_REQUEST['uid']);
            foreach ( $recordIds as $recordId ) {
                $bean = SugarModule::get($_REQUEST['module'])->loadBean();
                $bean->retrieve($recordId);
                $original_cond_id = $bean->id;
                
                $new_cond = BeanFactory::getBean('MYMODULE', $original_cond_id);
                $new_cond->id = create_guid();
                $new_cond->new_with_id = true;

                $new_cond->name = 'COPY_'.$bean->get_summary_text();
                $new_cond->save();
                
            }
        }
        sugar_die('');
    } 
}

Ok, copy seems work well but I have a little problem: once the redord are copied, I get a white page and I don’t go back to listview.
I am wrong a banality … someone can help me?

Thank you very much.

1 Like

When you get the white screen, that could be a PHP FATAL, you should have some message in your php_errors.log (or whatever it’s called in your php.ini, error_log setting).

Hi prg, Thanks for reply.
Inside log I found this

Wed Apr 8 10:04:40 2020 [7944][1][FATAL] Exception handling in /var/www/html/suitecrmtest/include/MVC/Controller/SugarController.php:400
Wed Apr 8 10:04:40 2020 [7944][1][FATAL] Exception in Controller:
Wed Apr 8 10:04:40 2020 [7944][1][FATAL] backtrace:
#0 /var/www/html/suitecrmtest/custom/modules/clobc_CLOB_condizioni/controller.php(25): sugar_die(’’)
#1 /var/www/html/suitecrmtest/include/MVC/Controller/SugarController.php(525): clobc_CLOB_condizioniController->action_copypassedids()
#2 /var/www/html/suitecrmtest/include/MVC/Controller/SugarController.php(494): SugarController->do_action()
#3 /var/www/html/suitecrmtest/include/MVC/Controller/SugarController.php(468): SugarController->handle_action()
#4 /var/www/html/suitecrmtest/include/MVC/Controller/SugarController.php(373): SugarController->process()
#5 /var/www/html/suitecrmtest/include/MVC/SugarApplication.php(113): SugarController->execute()
#6 /var/www/html/suitecrmtest/index.php(52): SugarApplication->execute()
#7 {main}

What’s it mean?

I think that is just the consequence of calling sugar_die, it throws an exception.

function sugar_die($error_message, $exit_code = 1)
{
    global $focus;
    sugar_cleanup();
    echo $error_message;
    throw new \Exception($error_message, $exit_code);
}

If you have another error, even if it looks less serious, it might help.

Just to elaborate, I think that sugar_die is there because the action is not supposed to render a screen, so it should get interrupted without sending any HTML back to the front-end. But that shouldn’t be an issue, and it shouldn’t take you away from the screen where you are currently…

Ok,
if I try to delete “sugar_die (’’);”, I don’t see any errors but the URL is cut and I can’t go back to listview.

If I go back to listview , I find correctly copied records too (I tested the same procedure on the standard module Accounts and the result is the same).

have you tried using a redirect, like

  SugarApplication::redirect('index.php');

?

1 Like

Yes, if at the end of the controller I use (the basic listview link of my module)

SugarApplication::redirect('index.php?action=ajaxui#ajaxUILoc=index.php%3Fmodule%3Dclobc_CLOB_condizioni%26action%3Dindex%26return_module%3Dclobc_CLOB_condizioni%26return_action%3DDetailView');

It works but maybe this isn’t the best way.

I think instead I should edit onclick by adding something like this:
return sListView.send_form(true, \'clobc_CLOB_condizioni\', \'index.php?entryPoint=index\',\'{$app_strings['LBL_LISTVIEW_NO_SELECTED']}\');

but if I do this, the function in the control is no longer called (because code execution must jump from one file to another).

Have yo looked at the other mass operations, what they use to terminate and redirect?

I don’t know but but perhaps the indication of diligent is the right one.
The guide on this page https://docs.suitecrm.com/developer/best-practices/ mentions
SugarApplication :: redirect
with reference to controllers

Yes, my only question is whether we couldn’t just leave it where it is, instead of redirecting to the same screen… other mass operations don’t seem to need a redirect…