Copy Opportunity Record with all related linked RLI

I want to copy opportunity record with linked RLI. same as quotes and QLI. when we copying any Quotes record all related RLI is also gets copied. I want to do same functionality for opportunity module.

  • The Quotes module has a special implementation of the duplicate button which is executed in the JS controller  modules\Quotes\clients\base\views\record\record.js. Here you find a 100 lines long JS function duplicateClicked which implements the whole copy handling. You can adopt this code for Opportunties by writing a custom JS controller in custom\modules\Opportunities\clients\base\views\record\record.js. As this is a very long function it can take some time to adopt it to Opportunities and RLIs.

    Harald Kuske
    Principal Solution Architect – Professional Services, EMEA
    hkuske@sugarcrm.com
    SugarCRM Deutschland GmbH

  • Thanks Harald Kuske or your responce.

    I have already done that but still i am unable to prefill linked revenue line items to RLI's subpanel of opportunities record view. For your reference i have shared my code here. Correct me if i am wrong anywhere.

    Steps:

    1. I have add custom event for duplicate button of opportunity module i.e. 

    custom/modules/Opportunities/clients/base/views/record/record.php

    array (
    'type' => 'rowaction',
    'event' => 'button:cstm_duplicate_button:click',////cstm_
    'name' => 'duplicate_button',////cstm_
    'label' => 'LBL_DUPLICATE_BUTTON_LABEL',
    'acl_module' => 'Opportunities',
    'acl_action' => 'create',
    ),

    custom/modules/Opportunities/clients/base/views/record/record.js

    this.context.on('button:cstm_duplicate_button:click', this.cstm_duplicateClicked, this);

    cstm_duplicateClicked: function() {
    ////// Custom code for copy opportunity record with RLI
    this.loadViewObj;
    ////this.bundleModels = [];
    // create an empty Opportunity Bean
    var oppoModelCopy;
    var oppoContextCollection;
    var mainDropdownBtn;
    var copyItemCount = 0;

    // get the Edit dropdown button
    mainDropdownBtn = this.getField('main_dropdown');
    // close the dropdown menu
    mainDropdownBtn.$el.removeClass('open');

    oppoModelCopy = App.data.createBean(this.model.module);
    oppoContextCollection = this.context.get('collection');

    oppoModelCopy.copy(this.model);

    var rli_context = this.context.getChildContext({link: 'revenuelineitems'});
    rli_context.prepare();
    if (rli_context.get('collection').length > 1) {
    if(rli_context.attributes){
    if(rli_context.attributes.collection){
    this.bundleModels = [];
    _.each(rli_context.attributes.collection.models, function(bundle) {
    var items = [];
    var bundleData = bundle.toJSON();
    var tmpItem = bundle.toJSON();
    var newBean;
    //delete tmpItem.id;
    delete tmpItem.opportunity_id;

    if (_.isEmpty(tmpItem.product_template_name)) {
    // if product_template_name is empty, use the QLI's name
    tmpItem.product_template_name = tmpItem.name;
    } else {
    // if product_template_name is not empty, set that to the QLI's name
    tmpItem.name = tmpItem.product_template_name;
    }

    newBean = App.data.createBean(tmpItem._module, tmpItem);

    // set isCopied on the bean for currency fields to be set properly
    newBean.isCopied = true;

    copyItemCount++;

    // creates a Bean and pushes the individual Products|ProductBundleNotes to the array
    items.push(newBean);


    // remove any id or sugarlogic entries from the bundle data
    ///delete bundleData.id;
    delete bundleData['_products-rel_exp_values'];
    // remove any leftover create/delete arrays
    delete bundleData.products;

    // set items array onto the bundleData
    bundleData.product_bundle_items = items;
    if(bundleData){
    this.bundleModels.push(bundleData);//Here i got all RLI's record
    }
    }, this);
    }
    }
    }


    /*** get rid of the existing bundles data on the model
    oppoModelCopy.unset('bundles');

    // set the model onto the context->collection
    oppoContextCollection.reset(oppoModelCopy);
    this.loadViewObj = {
    action: 'edit',
    collection: oppoContextCollection,
    copy: true,
    create: true,
    layout: 'create',
    model: oppoModelCopy,
    module: 'Opportunities',
    relatedRecords: this.bundleModels,
    copyItemCount: copyItemCount
    };

    // lead the Quotes create layout
    App.controller.loadView(this.loadViewObj);


    // update the browser URL with the proper
    App.router.navigate('#Opportunities/create', {trigger: false});

    var self = this,prefill = App.data.createBean(this.model.module);

    prefill.copy(this.model);
    this._copyNestedCollections(this.model, prefill);
    self.model.trigger('duplicate:before', prefill);
    prefill.unset('id');
    App.drawer.open({
    layout: 'create',
    context: {
    create: true,
    model: prefill,
    copiedFromModelId: this.model.get('id')
    }
    }, function(context, newModel) {
    if (newModel && newModel.id) {
    App.router.navigate(self.model.module + '/' + newModel.id, {trigger: true});
    }
    });
    prefill.trigger('duplicate:field', self.model);
    }