NetSuite Bin Transfer Custom Fields

NetSuite Bin Transfer Custom Fields

Sometimes it becomes necessary to customize the NetSuite Bin Transfer, unfortunately as of 2018.2 this ability is still not supported. I looked around and couldn't find an existing workaround published so I decided to share mine. Perhaps you want to change the page layout or just add some custom fields, in either case here is the simple yet effective workaround I have used for both.

You will need to create the following

  1. Custom Record - For storing your custom fields
  2. Custom fields - Fields you want to see on your bin transfer, add them to your custom record.
  3. A User Event Suite Script - For managing your bin transfer UI and the custom record.

Step 1: Lay the ground work with a Custom Record

While I assume you are familiar with custom records and fields I'll run through it quickly.

  1. In the UI Navigate to Customization -> Lists, Records, & Fields -> Record Types -> New
  2. Fill in the "NAME" (i.e. Bin Transfer Fields) and "ID" (i.e. _yourco_bin_transfer_fields) Fields.
  3. Uncheck "INCLUDE NAME FIELD"
  4. Select your desired "ACCESS TYPE"
  5. Select / deselect the remaining options as necessary / desired.
  6. Save

Step 2: Custom Fields

To link your custom record to your bin transfer the following custom field is required:

  1. Click "NEW FIELD"
  2. Fill out the "LABEL" (i.e. Related Bin Transfer) and give it an "ID" (i.e. _yourco_rel_bin_trnsfr)
  3. Select "TYPE" as List/Record
  4. Select "LIST/RECORD" as Transaction
  5. Select Sourcing & Filtering Subtab
  6. Add a new Filter: "FILTER USING" = Type, "COMPARE TYPE" = equal, "VALUE IS" = bin transfer
  7. Add, then Save

The remaining custom fields can be added as needed / desired to your custom record the same way using whatever types your project requires.

Step 3: Using SuiteScript to pull it all together

I'm also assuming you are familiar with NetSuite SuiteScripts, creating them, and deploying them. You will need to create a new USER EVENT script and deploy it to your bin transfer records. Your SuiteScript will require the following modules:

/**
 * @NApiVersion 2.x
 * @NScriptType UserEventScript
 * @NModuleScope SameAccount
 */
define(['N/record', 'N/search','N/log', 'N/ui/serverWidget'],
/**
 * @param {record} record
 * @param {search} search
 * @param {log} log
 * @param {serverWidget} serverWidget
 */
function(record, search, log, serverWidget) {

You will need to use all 3 methods, Before Load, Before Submit, and After Submit.

Before Load serves 3 functions, it is where you can modify your UI layout like:

You can add form groups like:

var form = scriptContext.form;

//Add Form Groups to Bin Transfer
form.addFieldGroup({
    id : 'custpage_yourco_bt_priFG',
    label : 'Primary Information'
});


form.addFieldGroup({
    id : 'custpage_yourco_bt_related_FG',
    label : 'Related Information'
});

You can move existing fields into the new field groups like this, I added a marker field to start my placement with:

var marker = form.addField({
    id : 'custpage_yourco_bt_marker',
    type : serverWidget.FieldType.INLINEHTML,
    label : 'Marker',
    container : 'custpage_yourco_bt_priFG'
});


marker.defaultValue = "<script></script>"

Grab your pre-existing fields like:

var transactionnumber = form.getField({
    id : 'transactionnumber'
});


var tranid = form.getField({
    id : 'tranid'
});


var trandate = form.getField({
    id : 'trandate'
});


var location = form.getField({
    id : 'location'
});


var subsidiary = form.getField({
    id : 'subsidiary'
});


var generatetranidonsave = form.getField({
    id : 'generatetranidonsave'
});


var memo = form.getField({
    id : 'memo'
});

Then insert your fields into the new form group:

form.insertField({
    field : memo,
    nextfield : 'custpage_yourco_bt_marker'
});


form.insertField({
    field : trandate,
    nextfield : 'memo'
});


form.insertField({
    field : subsidiary,
    nextfield : 'trandate'
});


form.insertField({
    field : location,
    nextfield : 'subsidiary'
});


if(scriptContext.type == 'create'){
    form.insertField({
        field : generatetranidonsave,
        nextfield : 'location'
    });
    
    form.insertField({
        field : transactionnumber,
        nextfield : 'generatetranidonsave'
    });
} else {
    form.insertField({
        field : transactionnumber,
        nextfield : 'location'
    });
}


form.insertField({
    field : tranid,
    nextfield : 'transactionnumber'
});

Keep in mind you are inserting fields from the marker backwards, right to left, bottom to top. When your done your bin transfer should now look a little cleaner, like:

No alt text provided for this image

To add your custom fields simply create and stick them into your new field group:

var moveType = form.addField({
    id : 'custpage_yourco_bt_type',
    type : serverWidget.FieldType.SELECT,
    source : 'customlist_yourco_bt_types',
    label : 'Move Type',
    container : 'custpage_yourco_bt_related_FG'
});


moveType.setHelpText({
    help : "Select the move type, Bin Move is the default."
});


moveType.defaultValue = 1;

This particular field is used to show what type of bin transfer we are doing, this is for a particular business use case but shows a good example. Don't forget to set the help text for your fields, its a courtesy for the end user!

Now you have a cleaned up UI AND a custom field on your ui like:

No alt text provided for this image

Now you load & link existing related field data from your custom record:

if(scriptContext.type == 'edit' || scriptContext.type == 'view'){
    var cRecord = scriptContext.newRecord;
    var bm = getAdditionalFields(cRecord.getValue({fieldId: 'id'}));
    
    if(bm.internalid > 0){
        moveType.defaultValue = bm.type;
    }
}

The getAdditionalFields is a simple shared method to use across the 3 primary User Event methods:

function getAdditionalFields(bmId){
    var bm = {
        internalid: -1,
        type: 1,
        binMove: -1,
    }


    if(bmId > 0){
        search.create({
            type: 'customrecord_yourco_bin_transfer_fields',
            columns: [{
                name: 'internalid'
            },{
                name: 'custrecord_yourco_rel_bin_trnsfr'
            },{
                name: 'custrecord_yourco_bin_move_type'
            }],
            filters: ["custrecord_yourco_bt","anyof", bmId]
        }).run().each(function(result) {
            bm.internalid = result.getValue({name: 'internalid'});
            bm.binMove = result.getValue({name: 'custrecord_yourco_rel_bin_trnsfr'});
            bm.type = result.getValue({name: 'custrecord_yourco_bin_move_type'});
        });
    }


    return bm;
}
}

Before Submit handles your data for the Edit, View, & Delete contexts.

function beforeSubmit(scriptContext) {
    //Save Existing Bin Transfer related fields if changed
    try{
        var cRecord = scriptContext.newRecord;
        var toSave = false;
        var bm = getAdditionalFields(scriptContext.newRecord.id);


        //Were are deleting the Bin Transfer, delete related record
        if(scriptContext.type == 'delete'){
            var bm = getAdditionalFields(scriptContext.oldRecord.id);
            if(bm.internalid > 0){
                record.delete({
                    type: 'customrecord_yourco_bin_transfer_fields',
                    id: bm.internalid,
                 });
            }
        }


        //Check for and Save changes from Bin Transfer
        if((scriptContext.type == 'edit' || scriptContext.type == 'view') && bm.internalid > 0){
            var bmFields = record.load({
                type: 'customrecord_yourco_bin_transfer_fields', 
                id: bm.internalid,
                isDynamic: true,
            });
            
            var newType = cRecord.getValue({fieldId: 'custpage_yourco_bm_type'});


            if(newType != bm.type){
                toSave = true;
                bmFields.setValue({
                    fieldId: 'custrecord_yourco_bin_move_type',
                    value: newType
                });
            }


            if(toSave == true){
                bmFields.save();
            }
        }
    }catch(e){
        log.error({
            title: 'Bin Transfer Related Fields Save Error',
            details: e.message
        });
    }
}

After Submit handles your create context:

function afterSubmit(scriptContext) {
    //Create New Bin Transfer related fields
    try{
        if(scriptContext.type == 'create'){
            var cRecord = scriptContext.newRecord;


            var bmFields = record.create({
                type: 'customrecord_yourco_bin_transfer_fields', 
                isDynamic: false
            });
            bmFields.setValue({
                fieldId: 'custrecord_yourco_rel_bin_trnsfr',
                value: scriptContext.newRecord.id
            });
            bmFields.setValue({
                fieldId: 'custrecord_yourco_bin_move_type',
                value: cRecord.getValue({fieldId: 'custpage_yourco_bm_type'})
            });


            bmFields.save();
        }
    }catch(e){
        log.error({
            title: 'Bin Transfer Related Fields Save Error',
            details: e.message
        });
    }
}

Finally, to conclude

While this post seems longer than I intended when I began, the concepts should be familiar. This is a great way to use existing components to solve a small limitation. Feel free to reach out to me any time with questions, feedback, or suggestions.

Hi Andre, your instruction are very usefull. Thank you so much!! I used them. Do you know how to do for adding some line field to Bin Transfer? Thank you in advance

Like
Reply

To view or add a comment, sign in

Others also viewed

Explore content categories