Clone/Copy Quote line item

MontooG
Giga Expert

Hi All,

 

I am currently exploring the SOM functionalities and want to know if following functionalities are available in the current release or if it's on the roadmap.

 

1. Clone/Copy Quote line item - As there could be complex product configuration in B2B scenario which user wants to copy quote line items in the quote and change some characteristics value on it.

2. Import bulk Quote line item - Sometimes its easy to work in excel when you have large no of quote line items. User should be able to upload the excel to create new/modify the quote line items.

 

TIA for your feedback.

Montoo Garg

 

1 ACCEPTED SOLUTION

Kenta Koizumi
Kilo Sage
Kilo Sage

Hi @MontooG 

 

I have the same requirements as both of you.

For number 1, it seems not be an out-of-the-box function, so we need to configure a script.

Here is my sample code for UI Action that can be used to copy Quote Line Items.

 

(function() {
    try {
        gs.addInfoMessage('Copy Quote button clicked');
        
        var currentQuote = new GlideRecord('sn_quote_mgmt_core_quote');
        if (currentQuote.get(current.sys_id)) {
            gs.addInfoMessage('Current Quote record retrieved successfully');

            var newQuote = new GlideRecord('sn_quote_mgmt_core_quote');
            newQuote.initialize();
            
            newQuote.setValue('short_description', currentQuote.getValue('short_description'));
            newQuote.setValue('account', currentQuote.getValue('account'));
            newQuote.setValue('consumer', currentQuote.getValue('consumer'));

            var newQuoteSysId = newQuote.insert();
            if (newQuoteSysId) {
                gs.addInfoMessage('New Quote record inserted with Sys ID: ' + newQuoteSysId);

                var lineItem = new GlideRecord('sn_quote_mgmt_core_quote_line_item');
                lineItem.addQuery('quote', currentQuote.sys_id); 
                lineItem.query();
                while (lineItem.next()) {
                    var newLineItem = new GlideRecord('sn_quote_mgmt_core_quote_line_item');
                    newLineItem.initialize();
                    newLineItem.setValue('quote', newQuoteSysId); 
                    newLineItem.setValue('item', lineItem.getValue('item')); 
                    newLineItem.setValue('product_offering', lineItem.getValue('product_offering')); 
                    newLineItem.setValue('quantity', lineItem.getValue('quantity')); 
                    newLineItem.setValue('list_price', lineItem.getValue('list_price')); 
                    newLineItem.setValue('unit_list_price', lineItem.getValue('unit_list_price')); 
                    newLineItem.setValue('total_adjustment', lineItem.getValue('total_adjustment')); 
                    newLineItem.setValue('total_one_time_price', lineItem.getValue('total_one_time_price')); 
                    newLineItem.setValue('unit_net_price', lineItem.getValue('unit_net_price')); 
                    newLineItem.setValue('total_recurring_price', lineItem.getValue('total_recurring_price')); 
                    newLineItem.setValue('unit_cost', lineItem.getValue('unit_cost')); 
                    newLineItem.setValue('cumulative_one_time_price', lineItem.getValue('cumulative_one_time_price')); 
                    newLineItem.setValue('unit_margin_amount', lineItem.getValue('unit_margin_amount'));
                    newLineItem.setValue('cumulative_monthly_recurring_price', lineItem.getValue('cumulative_monthly_recurring_price')); 
                    newLineItem.setValue('unit_margin_percentage', lineItem.getValue('unit_margin_percentage')); 
                    newLineItem.setValue('cumulative_annual_recurring_price', lineItem.getValue('cumulative_annual_recurring_price')); 
                    var newLineItemSysId = newLineItem.insert();
                    if (newLineItemSysId) {
                        gs.addInfoMessage('Line Item copied with Sys ID: ' + newLineItemSysId);

                        var priceAdjustment = new GlideRecord('sn_quote_mgmt_core_pricing_adjustment');
                        priceAdjustment.addQuery('quote_line_item', lineItem.sys_id); 
                        priceAdjustment.query();
                        while (priceAdjustment.next()) {
                            var adjustmentValue = priceAdjustment.getValue('adjustment_value');
                            var listPrice = lineItem.getValue('list_price');
                            
                            if (adjustmentValue <= listPrice) { 
                                var newPriceAdjustment = new GlideRecord('sn_quote_mgmt_core_pricing_adjustment');
                                newPriceAdjustment.initialize();
                                newPriceAdjustment.setValue('quote', newQuoteSysId);
                                newPriceAdjustment.setValue('quote_line_item', newLineItemSysId);
                                newPriceAdjustment.setValue('adjustment_type', priceAdjustment.getValue('adjustment_type'));
                                newPriceAdjustment.setValue('amount', priceAdjustment.getValue('amount'));
                                newPriceAdjustment.setValue('start_date', priceAdjustment.getValue('start_date'));
                                newPriceAdjustment.setValue('end_date', priceAdjustment.getValue('end_date'));
                                newPriceAdjustment.setValue('adjustment_value', adjustmentValue); 
                                newPriceAdjustment.insert();
                                gs.addInfoMessage('Price Adjustment copied with Sys ID: ' + newPriceAdjustment.getUniqueValue());
                            } else {
                                gs.addErrorMessage('Failed to copy Price Adjustment for Line Item: Adjustment value exceeds list price');
                            }
                        }
                    }
                }

                gs.addInfoMessage('Line Items and Price Adjustments copied successfully');

                action.setRedirectURL(newQuote);
            } else {
                gs.addErrorMessage('Failed to insert new Quote record');
            }
        } else {
            gs.addErrorMessage('Failed to retrieve the current Quote record');
        }
    } catch (e) {
        gs.addErrorMessage('An error occurred: ' + e.toString());
    }
})();

View solution in original post

3 REPLIES 3

Kenta Koizumi
Kilo Sage
Kilo Sage

Hi @MontooG 

 

I have the same requirements as both of you.

For number 1, it seems not be an out-of-the-box function, so we need to configure a script.

Here is my sample code for UI Action that can be used to copy Quote Line Items.

 

(function() {
    try {
        gs.addInfoMessage('Copy Quote button clicked');
        
        var currentQuote = new GlideRecord('sn_quote_mgmt_core_quote');
        if (currentQuote.get(current.sys_id)) {
            gs.addInfoMessage('Current Quote record retrieved successfully');

            var newQuote = new GlideRecord('sn_quote_mgmt_core_quote');
            newQuote.initialize();
            
            newQuote.setValue('short_description', currentQuote.getValue('short_description'));
            newQuote.setValue('account', currentQuote.getValue('account'));
            newQuote.setValue('consumer', currentQuote.getValue('consumer'));

            var newQuoteSysId = newQuote.insert();
            if (newQuoteSysId) {
                gs.addInfoMessage('New Quote record inserted with Sys ID: ' + newQuoteSysId);

                var lineItem = new GlideRecord('sn_quote_mgmt_core_quote_line_item');
                lineItem.addQuery('quote', currentQuote.sys_id); 
                lineItem.query();
                while (lineItem.next()) {
                    var newLineItem = new GlideRecord('sn_quote_mgmt_core_quote_line_item');
                    newLineItem.initialize();
                    newLineItem.setValue('quote', newQuoteSysId); 
                    newLineItem.setValue('item', lineItem.getValue('item')); 
                    newLineItem.setValue('product_offering', lineItem.getValue('product_offering')); 
                    newLineItem.setValue('quantity', lineItem.getValue('quantity')); 
                    newLineItem.setValue('list_price', lineItem.getValue('list_price')); 
                    newLineItem.setValue('unit_list_price', lineItem.getValue('unit_list_price')); 
                    newLineItem.setValue('total_adjustment', lineItem.getValue('total_adjustment')); 
                    newLineItem.setValue('total_one_time_price', lineItem.getValue('total_one_time_price')); 
                    newLineItem.setValue('unit_net_price', lineItem.getValue('unit_net_price')); 
                    newLineItem.setValue('total_recurring_price', lineItem.getValue('total_recurring_price')); 
                    newLineItem.setValue('unit_cost', lineItem.getValue('unit_cost')); 
                    newLineItem.setValue('cumulative_one_time_price', lineItem.getValue('cumulative_one_time_price')); 
                    newLineItem.setValue('unit_margin_amount', lineItem.getValue('unit_margin_amount'));
                    newLineItem.setValue('cumulative_monthly_recurring_price', lineItem.getValue('cumulative_monthly_recurring_price')); 
                    newLineItem.setValue('unit_margin_percentage', lineItem.getValue('unit_margin_percentage')); 
                    newLineItem.setValue('cumulative_annual_recurring_price', lineItem.getValue('cumulative_annual_recurring_price')); 
                    var newLineItemSysId = newLineItem.insert();
                    if (newLineItemSysId) {
                        gs.addInfoMessage('Line Item copied with Sys ID: ' + newLineItemSysId);

                        var priceAdjustment = new GlideRecord('sn_quote_mgmt_core_pricing_adjustment');
                        priceAdjustment.addQuery('quote_line_item', lineItem.sys_id); 
                        priceAdjustment.query();
                        while (priceAdjustment.next()) {
                            var adjustmentValue = priceAdjustment.getValue('adjustment_value');
                            var listPrice = lineItem.getValue('list_price');
                            
                            if (adjustmentValue <= listPrice) { 
                                var newPriceAdjustment = new GlideRecord('sn_quote_mgmt_core_pricing_adjustment');
                                newPriceAdjustment.initialize();
                                newPriceAdjustment.setValue('quote', newQuoteSysId);
                                newPriceAdjustment.setValue('quote_line_item', newLineItemSysId);
                                newPriceAdjustment.setValue('adjustment_type', priceAdjustment.getValue('adjustment_type'));
                                newPriceAdjustment.setValue('amount', priceAdjustment.getValue('amount'));
                                newPriceAdjustment.setValue('start_date', priceAdjustment.getValue('start_date'));
                                newPriceAdjustment.setValue('end_date', priceAdjustment.getValue('end_date'));
                                newPriceAdjustment.setValue('adjustment_value', adjustmentValue); 
                                newPriceAdjustment.insert();
                                gs.addInfoMessage('Price Adjustment copied with Sys ID: ' + newPriceAdjustment.getUniqueValue());
                            } else {
                                gs.addErrorMessage('Failed to copy Price Adjustment for Line Item: Adjustment value exceeds list price');
                            }
                        }
                    }
                }

                gs.addInfoMessage('Line Items and Price Adjustments copied successfully');

                action.setRedirectURL(newQuote);
            } else {
                gs.addErrorMessage('Failed to insert new Quote record');
            }
        } else {
            gs.addErrorMessage('Failed to retrieve the current Quote record');
        }
    } catch (e) {
        gs.addErrorMessage('An error occurred: ' + e.toString());
    }
})();

RanjaniR
ServiceNow Employee
ServiceNow Employee

@MontooG  Thanks for the great suggestions.

We are tracking Copy/Clone Line Item on our roadmap and will add Import as well to our list. 

 

Thanks @RanjaniR for considering the request.