0

Hi I'm new to suitescript I've added a custom print button to the inventory item record, it works totally fine in edit mode but in view mode the client script can't get the field value for my print type, it returns an undefined value. it gives this error:

{"type":"error.SuiteScriptError","name":"MISSING_PDF_PARAMETERS","message":"Missing parameters required to generate PDF","stack":["renderAsPdf(N/render)","onRequest(/SuiteScripts/rtt/add-print-button/acq_sl_form_print.js:66)"],"cause":{"type":"internal error","code":"MISSING_PDF_PARAMETERS","details":"Missing parameters required to generate PDF","userEvent":null,"stackTrace":["renderAsPdf(N/render)","onRequest(/SuiteScripts/rtt/add-print-button/acq_sl_form_print.js:66)"],"notifyOff":false},"id":"","notifyOff":false,"userFacing":false}

i'm using a user event script


/**

  • @NApiVersion 2.1
  • @NScriptType UserEventScript
  • @NModuleScope SameAccount */

define(['N/runtime', 'N/log', 'N/currentRecord'], function (runtime, log, currentRecord) {

    /**
    * beforeLoad event handler
    *
    * @gov 0
    *
    * @param context
    *        {Object}
    * @param context.newRecord
    *        {record} The new record being loaded
    * @param context.type
    *        {UserEventType} The action type that triggered this event
    * @param context.form
    *        {form} The current UI form
    *
    * @return {void}
    * @static
    * @function beforeLoad
    */
    function beforeLoad(scriptContext) {
        var objForm = scriptContext.form;
        objForm.clientScriptModulePath = "SuiteScripts/rtt/add-print-button/acq_cs_get_record.js";
        objForm.addButton({
            id: 'custpage_printbutton',
            label: 'Print Custom Label',
            functionName: 'onClickPrint'
        });
    }

    return {
        beforeLoad : beforeLoad
    }; 
});

a client script (to get the record and calling the suitelet page). In edit mode it gets normally the printType but i want it to work even if it's view mode.


/**

  • @NApiVersion 2.1
  • @NScriptType ClientScript
  • @NModuleScope SameAccount */

define(['N/currentRecord'], function (currentRecord) {

    function pageInit(context) {

    }
    function onClickPrint(context) {
        var objRecord = currentRecord.get();
        var intRecId = objRecord.id;
        var printType = objRecord.getValue({
            fieldId: "custitem_acq_print_type"
        });
        console.log(printType);
        if(intRecId!= null && intRecId !="") {
            window.open('/app/site/hosting/scriptlet.nl?script=2553&deploy=1&printType=' + printType + '&recID=' + intRecId,'_blank');
        }
    }
    return {
        pageInit : pageInit,
        onClickPrint : onClickPrint
    }
}); 

and then a suitelet that renders my custom templates, based on which prinType is selected in the page


/**

  • @NApiVersion 2.x
  • @NScriptType Suitelet */

define(['N/render', 'N/file', 'N/record'],

function (render, file, record) {

    function onRequest(context) {

        if (context.request.method === 'GET') {
            log.debug('phase', 'inizio');
            
            if (context.request.parameters.printType && context.request.parameters.recID) {
                var intRecId = context.request.parameters.recID;
                var printType = context.request.parameters.printType;
                log.debug('print type', printType);
                log.debug('record id', intRecId);
                var renderer = render.create();
            
                var temp = record.load({
                    id: intRecId,
                    type: record.Type.INVENTORY_ITEM
                });
                renderer.addRecord('record', temp);
    
                var linecount = temp.getLineCount({
                    sublistId: 'recmachcustrecord_acq_link'
                });
                log.debug(' righe ', linecount);
    
                var extraInformation = [];
                for (var i = 0; linecount > i; i++) {
                    extraInformation.push({
                        description: temp.getSublistValue({
                            fieldId: 'custrecord_acq_descriptions',
                            sublistId: 'recmachcustrecord_acq_link',
                            line: i
                        }),
                        detail: temp.getSublistValue({
                            fieldId: 'custrecord_acq_detail',
                            sublistId: 'recmachcustrecord_acq_link',
                            line: i
                        })
                    });
                }
            
                renderer.addCustomDataSource({
                    format: render.DataSource.OBJECT,
                    alias: "customData",
                    data: {extraInformation : extraInformation}
                });
                if(printType == 1){
                    renderer.setTemplateByScriptId("CUSTTMPL_ITEM_LABEL_A4");
                } else if(printType == 2){
                    renderer.setTemplateByScriptId("CUSTTMPL_ITEM_LABEL_A5");
                } else if(printType == 3){
                    renderer.setTemplateByScriptId("CUSTTMPL_ITEM_LABEL_A6");
                } else if(printType == 4){
                    renderer.setTemplateByScriptId("CUSTTMPL_ITEM_LABEL_6X3");
                }
                

                // render PDF
                var finalPDF = renderer.renderAsPdf();
                log.debug('render page', finalPDF);
                /* newfile.folder = -15; // ID of folder where file created
                newfile.name = "itemLabel.pdf";
                var fileId = newfile.save(); */
                context.response.addHeader({
                    name: 'Content-Type', value: 'application/pdf'
                });
                context.response.addHeader({
                    name: 'Content-Disposition', value: 'inline; filename=itemLabel.pdf'
                });
                context.response.writePage(finalPDF);
            }
        }
    }

    return {
        onRequest: onRequest
    };
});

Sorry fo my english, if anyone knows a workaround to make this work in view also, it will be a major uplift to my workday.

Fil
  • 3
  • 3
  • Call the suitelet directly from the userevent. No need to call the client script from user event and then call the suitelet. – HiddenOne1254 Dec 06 '22 at 10:53
  • I was thinking the same thing, i'll need a new function to call the suitlet . But can you get the record id with the scriptContext.newRecord? – Fil Dec 06 '22 at 11:10
  • Yes you can `let newRecord = context.newRecord;let recId = newRecord.id;let rectype = newRecord.type;` – HiddenOne1254 Dec 06 '22 at 11:12

3 Answers3

0

Client Scripts were not designed to work in View mode; thus, N/currentRecord does not load all of the record's data when used in View mode.

You will need to retrieve the value(s) of interest from the database via either N/record.load() or N/search.lookupFields(). lookupFields() will be quicker and use less governance, so I'd advise that you prefer that approach first.

erictgrubaugh
  • 8,519
  • 1
  • 20
  • 28
  • I've tried using lookupFields() in my clientscript but now when i click my button it doesn't work anymore. function onClickPrint(context) { var objRecord = currentRecord.get(); var intRecId = objRecord.id; var lookUp = search.lookupFields({ type: search.Type.INVENTORY_PART, id: intRecId, columns: ['custitem_acq_print_type'] }); var printType = lookUp.value; – Fil Dec 06 '22 at 09:52
0
/**
 *@NApiVersion 2.1
 *@NScriptType UserEventScript
 */
define(['N/record', 'N/search', 'N/runtime', 'N/url', 'N/ui/serverWidget'],
    function (record, search, runtime, url, serverWidget) {
        function beforeLoad(context) {
            if (context.type == context.UserEventType.VIEW) {

                let newRecord = context.newRecord;
                let recId = newRecord.id;
                let rectype = newRecord.type;

                let suiteletURL = url.resolveScript({
                    scriptId: 'your suitelet script id',
                    deploymentId: 'your suitelet deployment id'
                });

                suiteletURL = suiteletURL + '&recId=' + recId;
                suiteletURL = suiteletURL + '&recType=' + rectype;
                
                    log.debug('suiteletURL',suiteletURL)

                    let button = context.form.addButton({
                        id: 'custpage_click_button',
                        label: 'click me',
                        functionName: 'window.open("'+ suiteletURL +'", "_blank")'

                    });
            }
        }


        return {
            beforeLoad: beforeLoad
        };
    });
HiddenOne1254
  • 146
  • 1
  • 6
  • functionName it's not working only from a clientscript? and also i have a problem retrieving my custom field. – Fil Dec 06 '22 at 11:54
  • It will work. Replace your code with mine and try it. – HiddenOne1254 Dec 06 '22 at 12:00
  • I have updated my code now replace your code with mine it should work. `let suiteletURL = url.resolveScript({scriptId: 'your suitelet script id', deploymentId: 'your suitelet deployment id' });` in this pass your suitelet script id and deployment id. – HiddenOne1254 Dec 06 '22 at 12:03
  • Record id or suitelet id . Try to put your code inside try catch block. Are you using "acq_sl_form_print.js" as suitelet id? – HiddenOne1254 Dec 06 '22 at 13:18
0

I've tried to call the suitelet directly from the ue

function callForSuitelet(scriptContext){
            var rec = scriptContext.newRecord;
            var intRecId = newRecord.id;
            var recType = newRecord.type;
            var printType = rec.getValue({
                fieldId: "custitem_acq_print_type"
            });
            log.debug('record id', intRecId);
            log.debug('record type', recType);
            log.debug('print type', printType);

            if(intRecId!= null && intRecId !="") {
                var suiteletURL = url.resolveScript({
                    scriptId: "acq_sl_form_print.js",
                    deploymentId: "customdeploy_acq_sl_form_print",
                    params: { recordId: intRecId, recordType: recType, printType: printType },
                  });
                  document.location = suiteletURL;
                  log.debug("suiteletURL", suiteletURL);
            }
        }

but the button doesen't do anything at all

Fil
  • 3
  • 3