Does anyone have a map of context.newRecord.type t...
# suitescript
g
Does anyone have a map of context.newRecord.type to record.Type?
for example I've got context.newRecord.type with a value of
vendorpayment
and
N/search
filter expects the numeric value for record type, which corresponds to
record.Type.VENDOR_PAYMENT
so if I want my script to work on multiple record types I need the map of all possible
context.newRecord.type
values
a
umm.. there's no "numeric" value...
record.Type.VENDOR_PAYMENT
is just an enum that returns the string you already have `'vendorpayment``
💯 1
e
Worth mentioning that
record.Type
and
search.Type
are two separate enumerations, so beware of that.
context.newRecord
is an instance of a
record.Record
, so
context.newRecord.type
should always be an element from the
record.Type
enumeration. Not sure I've ever seen a search filter expect the numeric type, though. 🤔
💯 1
n
A note on this. If you look in the external library in your IDE (assuming WebStorm, possibly the same for VSCode and others) you can open the SuiteScript 2.0 modules If you open search.js and find "searchType()" in that you will see the various values for each record search type:
Copy code
function searchType() {
    this.ACCOUNT = 'account';
    this.ACCOUNTING_BOOK = 'accountingbook';
    this.ACCOUNTING_CONTEXT = 'accountingcontext';
    this.ACCOUNTING_PERIOD = 'accountingperiod';[...]
If you open the record.js and search for "recordType()" you will see similar:
Copy code
function recordType() {
    this.ACCOUNT = 'account';
    this.ACCOUNTING_BOOK = 'accountingbook';
    this.ACCOUNTING_CONTEXT = 'accountingcontext';
    this.ACCOUNTING_PERIOD = 'accountingperiod';
Maybe this will be useful to you. I also do not believe there's a numeric equivalent for the search/record types it's always a string value. If there's a difference between either and you know the search.Type you can perform a lookup on a known record returning "recordType" as a column, or simple search and look at one result. (note, case sensitive). This will return you the string value you can see in the record.Type enumeration. As an aside, this is useful when looking at "Created From".
👍 1
g
Search filter removedFilter expecting numeric value was removed, as non-numeric value 'vendorpayment' was provided
That's why I was asking about numeric
but when I use record.Type.VENDOR_PAYMENT instead of context.newRecord.type it works fine
weird, right?
Copy code
/**
 * @NApiVersion 2.x
 * @NScriptType UserEventScript
 * @NModuleScope SameAccount
 *
 */

define(["N/log","N/search","N/record"], function (log, search, record) {

    function beforeSubmit(context) {
        // Get the subsidiary
        const subsidiary = context.newRecord.getValue({ fieldId: "subsidiary" });
        log.debug({"title": "Subsidiary", "details": subsidiary});
        // Get the current record type
        const recordType = context.newRecord.type;

        log.debug({"title": "Record Type", "details": recordType});

        const recordTypeEnum = record.Type.VENDOR_PAYMENT;
        log.debug({"title": "Record Type Number", "details": recordTypeEnum});

        var customrecord_sub_form_settingsSearchObj = search.create({
            type: "customrecord_sub_form_settings",
            filters:
                [
                    ["custrecord_subform_type", "anyof", recordTypeEnum],
                    "AND",
                    ["custrecord_subform_subsidiary", "anyof", subsidiary],
                    "AND",
                    ["isinactive", "is", "F"]
                ],
            columns:
                [
                    search.createColumn({ name: "name", label: "Name" }),
                    search.createColumn({ name: "custrecord_subform_form", label: "Form" })
                ]
        });
        customrecord_sub_form_settingsSearchObj.run().each(function (result) {
            const formId = result.getValue({ name: "custrecord_subform_form" });
            log.debug({"title": "Form ID", "details": formId});

            context.newRecord.setValue({ fieldId: "customform", value: formId });
            return true;
        });
    }

    return {
        beforeSubmit: beforeSubmit
    }
});
We've got too many subisidiaries that need different forms and the end users often don't think to select the right one, so I created a custom record to hold the mapping of each sub to its transaction forms.
custrecord_subform_type
is a list/record of transaction types and
custrecord_subform_subsidiary
is a multi-select of subsidiaries
A large proportion of transactions are created through integrations and SuiteApps that do not specify a form so most of them are going straight to the default form for all subsidiaries. This fixes that problem so that each sub gets the right PDF to print.
I guess what I'm looking for then is a map of search record types to record.Type
That just gave me an idea, just make a saved search of the custom record, export it using the saved search export chrome extension, and export to see the value
Copy code
var customrecord_sub_form_settingsSearchObj = search.create({
   type: "customrecord_sub_form_settings",
   filters:
   [
      ["custrecord_subform_type","anyof","18"], 
      "AND", 
      ["custrecord_subform_subsidiary","anyof","6"], 
      "AND", 
      ["isinactive","is","F"]
   ],
   columns:
   [
      search.createColumn({name: "name", label: "Name"}),
      search.createColumn({name: "custrecord_subform_form", label: "Form"})
   ]
});
var searchResultCount = customrecord_sub_form_settingsSearchObj.runPaged().count;
log.debug("customrecord_sub_form_settingsSearchObj result count",searchResultCount);
customrecord_sub_form_settingsSearchObj.run().each(function(result){
   // .run().each has a limit of 4,000 results
   return true;
});

/*
customrecord_sub_form_settingsSearchObj.id="customsearch1723063266732";
customrecord_sub_form_settingsSearchObj.title="Subsidiary Form Settings Search (copy)";
var newSearchId = customrecord_sub_form_settingsSearchObj.save();
*/
yup, definitely numeric!
Made a list of the transaction types that have subsidiary specific forms, then DOM hacked the IDs out of the select list of transaction types and stored it as a javascript object where the record.Type is the key:
Copy code
const transactionType = {
            check: {
                id: 3,
                label: "Check"
            },
            creditmemo: {
                id: 10,
                label: "Credit Memo"
            },
            invoice: {
                id: 7,
                label: "Invoice"
            },
            customerpayment: {
                id: 15,
                label: "Payment"
            },
            vendorbill: {
                id: 17,
                label: "Vendor Bill"
            },
            vendorpayment: {
                id: 18,
                label: "Vendor Payment"
            }
        }
n
If you wanted the internalid's of a list you didn't need to "DOM Hack it" You can write a few lines of code or use a plugin.
Copy code
let dummy = record.create({type:record.Type.TIME_ENTRY,isDynamic:true});
const projectsTable  = dummy.getField({fieldId:'customer'}).getSelectOptions();
In the code above I'm retrieving all the select options for the projects on a record. I have no intention of saving "dummy" it's just there, in dynamic mode to allow me to pull the select options. This will give me an array of objects that have a value (internal id) and text. Using a plugin (see the image) A select list internalid is not the same as the record type that you'd use in a search or to load a record, you are talking about 2 different things. That being said, it is possible to add a select list to a SuiteLet and rather than add each select option, specify the "source", which can be a record type that is sometimes a numeric id. However, I would never dream of attempting to use that id as a recordtype id in a search. I feel you've missed something simple along the way I just don't quite know what it is yet.
👍 1
Also if you are not adding subsidiaries often or creating new forms per subsidiary a simple object may have sufficed. Something like:
Copy code
const FORM_MAP = {
"vendorbill":{
    "subsidiarya":12,
    "subsidiaryb":22
}
}
A User Event that includes that directly or as a library file could then:
Copy code
const  SUBSIDIARY = context.newRecord.getValue({fieldId:'subsidiary'});
const thisForm = FORM_MAP[context.newRecord.type][SUBSIDIARY];
You just deploy the same UE to whatever records you need to apply this logic to.
g
One of our subsidiaries creates sub-subsidiaries for each of their clients haha
🧐 1
Kind of fun to have the conversation with NetSuite support that gets them to say, "well, we've never tested the technical limit of the number of subsidiaries before..."
The form doesn't change very often though, so all the child subsidiaries use the parent one's form
shruggie
a
unrelated but you can use
/shrug
in slack to append ascii shrug .. like this >> ¯\_(ツ)_/¯
🤭 1
n
You could easily introduce a lookup for the parent subsidiary in that case and stick with the table as mentioned previously. 😉
a
not sure if anyone needs to see this, but I just had a need for this and remembered this thread when I was done. JSON.parse the string below and you'll get an object with 3 arrays one for search only Types, one for record only Types, and one both
Copy code
'{"searchOnly":["ACTIVITY","AGGR_FIN_DAT","ALLOC_RECOMMENDATION_DEMAND","ALLOC_RECOMMENDATION_DETAIL","AUTHENTICATE_DEVICE_INPUT","BALANCING_DETAIL","BALANCING_RESULT","BALANCING_TRANSACTION","BILLING_ACCOUNT_BILL_CYCLE","BILLING_ACCOUNT_BILL_REQUEST","BIN_ITEM_BALANCE","CARDHOLDER_AUTHENTICATION_EVENT","CHALLENGE_SHOPPER_INPUT","COM_SEARCH_BOOST","COM_SEARCH_BOOST_TYPE","COM_SEARCH_GROUP_SYN","COM_SEARCH_ONE_WAY_SYN","COMM_AN_SESSION","COMMERCE_SEARCH_ACTIVITY_DATA","CURRENCY_EXCHANGE_RATE","DELETED_RECORD","EMPLOYEE_CHANGE_TYPE","EMPLOYEE_PAYROLL_ITEM","END_TO_END_TIME","ENTITY","EXPENSE_AMORT_PLAN_AND_SCHEDULE","GATEWAY_NOTIFICATION","GL_LINES_AUDIT_LOG","INSTALLMENT","INVENTORY_BALANCE","INVENTORY_DEMAND","INVENTORY_NUMBER_BIN","INVENTORY_NUMBER_ITEM","INVENTORY_STATUS_LOCATION","INVT_NUMBER_ITEM_BALANCE","ITEM","ITEM_BIN_NUMBER","LABOR_BASED_PROJECT_REVENUE_RULE","LABOR_CATEGORY","LABOR_COST_CARD","LABOR_COST_CARD_ITEM","LABOR_COST_CARD_SEGMENT","LABOR_COST_ELEMENT","MERCHANDISE _HIERARCHY_LEVEL","PAYMENT_EVENT","PAYMENT_INSTRUMENT","PAYMENT_OPTION","PAYMENT_RESULT_PREVIEW","PAYROLL_SETUP","PERMISSION","PLANNING_ENGINE_MESSAGE","PLANNING_ENGINE_PEGGING","PLANNING_ENGINE_RESULT","PLANNING_REPOSITORY_ALLOCATION","PLANNING_REPOSITORY_BOM_EDGE","PLANNING_REPOSITORY_ITEM_LOCATION","PLANNING_REPOSITORY_SOURCE","PRICING","PROMISING_SETUP","RECENT_RECORD","RECEIVED_VENDOR_BILL","RES_ALLOCATION_TIME_OFF_CONFLICT","REV_REC_PLAN_AND_SCHEDULE","ROLE","S_C_M_PREDICTED_RISKS","S_C_M_PREDICTION_TRAIN_HISTORY","S_C_M_PREDICTION_TRAIN_W_Q_STATUS","SAVED_SEARCH","SHOPPING_CART","STATE","SUBSCRIPTION_LINE_REVISION","SUBSCRIPTION_RENEWAL_HISTORY","SUITE_SCRIPT_DETAIL","SUPPLY_CHAIN_SNAPSHOT_DETAILS","SYSTEM_NOTE","TAX_DETAIL","TIMESHEET_APPROVAL","TIME_APPROVAL","TRANSACTION","UBER"],"recordOnly":["ALLOCATION_SCHEDULE","AUTOMATED_CLEARING_HOUSE","CAMPAIGN_RESPONSE","CAMPAIGN_TEMPLATE","EMPLOYEE_EXPENSE_SOURCE_TYPE","FORMAT_PROFILE","GENERAL_TOKEN","INTERCOMP_ALLOCATION_SCHEDULE","ISSUE_PRODUCT","ISSUE_PRODUCT_VERSION","LABOR_ BASED_PROJECT_REVENUE_RULE","MERCHANDISE_HIERARCHY_LEVEL","ORDER_SCHEDULE","PAYMENT_CARD","PAYMENT_CARD_TOKEN","REALLOCATE_ITEM","RECEIVE_INBOUND_SHIPMENT","SUBSIDIARY_SETTINGS","SUPPLY_CHAIN_SNAPSHOT_SIMULATION","TAX_ACCT"],"both":["ACCOUNT","ACCOUNTING_BOOK","ACCOUNTING_CONTEXT","ACCOUNTING_PERIOD","ADV_INTER_COMPANY_JOURNAL_ENTRY","AMORTIZATION_SCHEDULE","AMORTIZATION_TEMPLATE","ASSEMBLY_BUILD","ASSEMBLY_ITEM","ASSEMBLY_UNBUILD","BALANCE_TRX_BY_SEGMENTS","BILLING_ACCOUNT","BILLING_CLASS","BILLING_RATE_CARD","BILLING_REVENUE_EVENT","BILLING_SCHEDULE","BIN","BIN_TRANSFER","BIN_WORKSHEET","BLANKET_PURCHASE_ORDER","BOM","BOM_REVISION","BONUS","BONUS_TYPE","BUDGET_EXCHANGE_RATE","BULK_OWNERSHIP_TRANSFER","BUNDLE_INSTALLATION_SCRIPT","CALENDAR_EVENT","CAMPAIGN","CARDHOLDER_AUTHENTICATION","CASH_REFUND","CASH_SALE","CHARGE","CHARGE_RULE","CHECK","CLASSIFICATION","CLIENT_SCRIPT","CMS_CONTENT","CMS_CONTENT_TYPE","CMS_PAGE","COMMERCE_CATEGORY","COMPETITOR","CONSOLIDATED_EXCHANGE_RATE","CONTACT","CONTACT_CATEGORY","CONTACT_ROLE","COST_CATEGORY","COUPON_CODE","CREDIT_CARD_CHARGE","CREDIT_CARD_REFUND","CREDIT_MEMO","CURRENCY","CUSTOM_PURCHASE","CUSTOM_SALE","CUSTOMER","CUSTOMER_CATEGORY","CUSTOMER_DEPOSIT","CUSTOMER_MESSAGE","CUSTOMER_PAYMENT","CUSTOMER_PAYMENT_AUTHORIZATION","CUSTOM_RECORD","CUSTOMER_REFUND","CUSTOMER_STATUS","CUSTOMER_SUBSIDIARY_RELATIONSHIP","CUSTOM_TRANSACTION","DEPARTMENT","DEPOSIT","DEPOSIT_APPLICATION","DESCRIPTION_ITEM","DISCOUNT_ITEM","DOWNLOAD_ITEM","EMAIL_TEMPLATE","EMPLOYEE","EMPLOYEE_CHANGE_REQUEST","EMPLOYEE_CHANGE_REQUEST_TYPE","EMPLOYEE_STATUS","EMPLOYEE_TYPE","ENTITY_ACCOUNT_MAPPING","ESTIMATE","EXPENSE_AMORTIZATION_EVENT","EXPENSE_CATEGORY","EXPENSE_PLAN","EXPENSE_REPORT","EXPENSE_REPORT_POLICY","FAIR_VALUE_PRICE","FINANCIAL_INSTITUTION","FIXED_AMOUNT_PROJECT_REVENUE_RULE","FOLDER","FULFILLMENT_REQUEST","GENERIC_RESOURCE","GIFT_CERTIFICATE","GIFT_CERTIFICATE_ITEM","GLOBAL_ACCOUNT_MAPPING","GLOBAL_INVENTORY_RELATIONSHIP","GL_NUMBERING_SEQUENCE","GOAL","IMPORTED_EMPLOYEE_EXPENSE","INBOUND_SHIPMENT","INTER_COMPANY_JOURNAL_ENTRY","INTER_COMPANY_TRANSFER_ORDER","INVENTORY_ADJUSTMENT","INVENTORY_COST_REVALUATION","INVENTORY_COUNT","INVENTORY_DETAIL","INVENTORY_ITEM","INVENTORY_NUMBER","INVENTORY_STATUS","INVENTORY_STATUS_CHANGE","INVENTORY_TRANSFER","INVOICE","INVOICE_GROUP","ISSUE","ITEM_ACCOUNT_MAPPING","ITEM_COLLECTION","ITEM_COLLECTION_ITEM_MAP","ITEM_DEMAND_PLAN","ITEM_FULFILLMENT","ITEM_GROUP","ITEM_LOCATION_CONFIGURATION","ITEM_PROCESS_FAMILY","ITEM_PROCESS_GROUP","ITEM_RECEIPT","ITEM_REVISION","ITEM_SUPPLY_PLAN","JOB","JOB_STATUS","JOB_TYPE","JOURNAL_ENTRY","KIT_ITEM","LEAD","LOCATION","LOT_NUMBERED_ASSEMBLY_ITEM","LOT_NUMBERED_INVENTORY_ITEM","MANUFACTURING_COST_TEMPLATE","MANUFACTURING_OPERATION_TASK","MANUFACTURING_ROUTING","MAP_REDUCE_SCRIPT","MARKUP_ITEM","MASSUPDATE_SCRIPT","MEM_DOC","MERCHANDISE_HIERARCHY_NODE","MERCHANDISE_HIERARCHY_VERSION","MESSAGE","MFG_PLANNED_TIME","NEXUS","NON_INVENTORY_ITEM","NOTE","NOTE_TYPE","OPPORTUNITY","ORDER_RESERVATION","ORDER_TYPE","OTHER_CHARGE_ITEM","OTHER_NAME","OTHER_NAME_CATEGORY","PARTNER","PARTNER_CATEGORY","PAYCHECK","PAYCHECK_JOURNAL","PAYMENT_ITEM","PAYMENT_METHOD","PAYROLL_ITEM","PCT_COMPLETE_PROJECT_REVENUE_RULE","PERFORMANCE_METRIC","PERFORMANCE_REVIEW","PERFORMANCE_REVIEW_SCHEDULE","PERIOD_END_JOURNAL","PHONE_CALL","PICK_STRATEGY","PICK_TASK","PLANNED_ORDER","PLANNING_ITEM_CATEGORY","PLANNING_ITEM_GROUP","PLANNING_RULE_GROUP","PLANNING_VIEW","PORTLET","PRICE_BOOK","PRICE_LEVEL","PRICE_PLAN","PRICING_GROUP","PROJECT_EXPENSE_TYPE","PROJECT_IC_CHARGE_REQUEST","PROJECT_TASK","PROJECT_TEMPLATE","PROMOTION_CODE","PROSPECT","PURCHASE_CONTRACT","PURCHASE_ORDER","PURCHASE_REQUISITION","RESOURCE_ALLOCATION","RESTLET","RETURN_AUTHORIZATION","REVENUE_ARRANGEMENT","REVENUE_COMMITMENT","REVENUE_COMMITMENT_REVERSAL","REVENUE_PLAN","REV_REC_SCHEDULE","REV_REC_TEMPLATE","SALES_CHANNEL","SALES_ORDER","SALES_ROLE","SALES_TAX_ITEM","SCHEDULED_SCRIPT","SCHEDULED_SCRIPT_INSTANCE","SCRIPT_DEPLOYMENT","SERIALIZED_ASSEMBLY_ITEM","SERIALIZED_INVENTORY_ITEM","SERVICE_ITEM","SHIP_ITEM","SOLUTION","STATISTICAL_JOURNAL_ENTRY","STORE_PICKUP_FULFILLMENT","SUBSCRIPTION","SUBSCRIPTION_CHANGE_ORDER","SUBSCRIPTION_LINE","SUBSCRIPTION_PLAN","SUBSCRIPTION_TERM","SUBSIDIARY","SUBTOTAL_ITEM","SUITELET","SUPPLY_CHAIN_SNAPSHOT","SUPPLY_CHANGE_ORDER","SUPPLY_PLAN_DEFINITION","SUPPORT_CASE","TASK","TAX_GROUP","TAX_PERIOD","TAX_TYPE","TERM","TIME_BILL","TIME_ENTRY","TIME_OFF_CHANGE","TIME_OFF_PLAN","TIME_OFF_REQUEST","TIME_OFF_RULE","TIME_OFF_TYPE","TIME_SHEET","TOPIC","TRANSFER_ORDER","UNITS_TYPE","UNLOCKED_TIME_PERIOD","USAGE","USEREVENT_SCRIPT","VENDOR","VENDOR_BILL","VENDOR_CATEGORY","VENDOR_CREDIT","VENDOR_PAYMENT","VENDOR_PREPAYMENT","VENDOR_PREPAYMENT_APPLICATION","VENDOR_RETURN_AUTHORIZATION","VENDOR_SUBSIDIARY_RELATIONSHIP","WAVE","WBS","WEBSITE","WORKFLOW_ACTION_SCRIPT","WORK_ORDER","WORK_ORDER_CLOSE","WORK_ORDER_COMPLETION","WORK_ORDER_ISSUE","WORKPLACE","ZONE"]}'
image.png