Best Of
Re: Sales Order > Quantity Billed, Quantity Fulfilled
Oh apparently that is a system flag field! Are you all still missing a column though showing a certain qty or stage of fulfillment? I believe that "Total To Date" adds both "Fulfilled" and "Invoiced" as well as "Picking" and "Packed" in the case of using those features. (At least from what I see online and from behavior in our account)
Re: How do I edit this outsourced work order that's already In Process?
Hi @Dext3r,
This behavior is expected, as Work Orders can no longer be modified once an Assembly Build has been created.
As an alternative, users can take the following actions:
- To reduce the quantity: Close the Work Order, which will change its status from In Process to Closed. After closing, an Assembly Unbuild transaction can be used to remove any excess assemblies from inventory.
- To increase the quantity: Create a copy of the original Work Order and include a note in the Memo field indicating that it continues from a previously closed Work Order. Enter the additional quantity to be produced in this new Work Order.
Hope this helps with your concern.
Respectfully,
Trixie
Re: How to enable ACH in Netsuite?
Hi @User_ZA0IY,
I believe you have Payment Instruments Enabled in your account since it's part of the requirement in setting up ACH in SuiteCommerce.
Under the Customer Record > Financial Tab > Payment Instrument Subtab, the New ACH button should be present.
Possible reason for it is that you might have no ACH Payment Method created in your NetSuite Account.
Navigate to Setup > Accounting > Accounting List > FILTERS Type = Payment Method
Click New button > In the form, populate Name for the Payment Method > Set Type field = ACH > Select the Associated Payment Processing Profile > Set the Account to deposit to.
Hope this resolves the problem of New ACH button missing in the Customer Record.
—————
If you found this response helpful and think it might assist others with similar questions, mark 'Yes' beside 'Did this answer your question?'. Doing so will help the community find solutions more efficiently, saving them time reading through all replies. You'll also be on your way to earning your next Answer Accepter badge💎.
Re: Best Practice: Inactivating Employee vs Removing System Access ?
Hello @m ramana,
Great question—this is a common scenario in NetSuite administration. Both options serve different purposes, and best practice is to use them based on the employee’s lifecycle and business needs.
Inactivate Employee
- Use when the employee has left the company
- Removes them from lists and prevents future assignments
- Historical records remain intact
Remove “Give Access” only
- Use when the employee is still active but should not log in
- Example: on leave, role change, or temporary access removal
- Employee can still be used in records (approvals, transactions, etc.)
Best practice:
- If terminated → remove access and inactivate
- If still employed → remove access only
References:
- NetSuite Help > Setting Up Users and Roles
- NetSuite Help > Inactivating Records
- SuiteAnswers: Inactivating Employee Record (65837)
- SuiteAnswers: Giving an Employee Access to NetSuite (8518)
Hope this helps! If you have any specific question in mind please let me know.
Re: Best Practice: Inactivating Employee vs Removing System Access ?
In my experience inactivating employees can lead to issues saving transactions where the employee has been selected.
My preference is to remove access from the employee record and some time later make the employee inactive. This gives the business time to update values where the employee has been referenced.
If you expect to make many employees inactive it may be worth the time investment to create a series of saved searches to proactively update where they have been referred to.
Re: Can allocation journals created from allocation schedules be updates via a script?
Hi @User_G1YSQ
Unfortunately, as stated on the SuiteAnswers ID 7739 Creating Expense Allocation Journal Entries : "Journal entries created by allocation schedules cannot trigger User Event scripts."
Hence, your findings are correct. You have to update the allocation schedule, delete the existing journal entries, and then rerun or process the allocation schedules to create new journal entries that will have the custom segment populated. You can check NSC | How to Re-Run Allocation Schedule for further instructions on the steps.
Let me know if you neef further clarifications.
Thank you and regards,
Ayie
Re: Inline HTML field, how do I check when a field is not NULL/Empty?
Hi @Dext3r,
Other formulas that should work are:
- CASE WHEN {custbody5} IS NOT NULL THEN '<div style="background-color:yellow; color:black; font-weight:bold;">' || {custbody5} || '</div>' ELSE 'Empty' END
or
- CASE WHEN {custbody5} IS NULL THEN 'Empty' ELSE '<div style="background-color:yellow; color:black; font-weight:bold;">' || {custbody5} || '</div>' END
😊
Re: Intercompany Transfer Order
Hi @User_QQ76D
Create a custom record (e.g., Custom Intercompany Staging) and create the following custom fields.
- From Subsidiary: custrecord_icto_from_sub (Type: List/Record > Subsidiary)
- To Subsidiary: custrecord_icto_to_sub (Type: List/Record > Subsidiary)
- From Location: custrecord_icto_from_loc (Type: List/Record > Location)
- To Location: custrecord_icto_to_loc (Type: List/Record > Location)
- Item: custrecord_icto_item (Type: List/Record > Item)
- Quantity: custrecord_icto_qty (Type: Integer or Decimal)
- Created Order: custrecord_icto_created_order (Type: List/Record > Transaction) (Uncheck 'Mandatory')
- Error Log: custrecord_icto_error_log (Type: Long Text) (Uncheck 'Mandatory')
Save the following code as a .js file (e.g., UE_Create_ICTO_From_Staging.js) and upload it to your File Cabinet.
/**
- @NApiVersion 2 .1
- @NScriptType UserEventScript
- @NModuleScope SameAccount
- Description: Automatically creates an Intercompany Transfer Order when a Custom Staging Record is created via CSV or UI.
*/
define(['N/record', 'N/log'], (record, log) => {
const afterSubmit = (context) => {
// Only run on creation of a new staging record (prevents duplicates if someone edits the record later)
if (context.type !== context.UserEventType.CREATE) {
return;
}
const stagingRec = context.newRecord;
const stagingRecId = stagingRec.id;
const stagingRecType = stagingRec.type;
try {
// 1. Get values from the custom staging record
const fromSubsidiary = stagingRec.getValue({ fieldId: 'custrecord_icto_from_sub' });
const toSubsidiary = stagingRec.getValue({ fieldId: 'custrecord_icto_to_sub' });
const fromLocation = stagingRec.getValue({ fieldId: 'custrecord_icto_from_loc' });
const toLocation = stagingRec.getValue({ fieldId: 'custrecord_icto_to_loc' });
const item = stagingRec.getValue({ fieldId: 'custrecord_icto_item' });
const quantity = stagingRec.getValue({ fieldId: 'custrecord_icto_qty' });
// Validate that required fields are present
if (!fromSubsidiary || !toSubsidiary || !fromLocation || !toLocation || !item || !quantity) {
throw new Error('Missing required fields on the staging record.');
}
// 2. Initialize the Intercompany Transfer Order
// We use dynamic mode so NetSuite automatically sources pricing, accounts, etc.
let ictoRec = record.create({
type: record.Type.INTER_COMPANY_TRANSFER_ORDER,
isDynamic: true
});
// 3. Set Header Level Fields
ictoRec.setValue({ fieldId: 'subsidiary', value: fromSubsidiary });
ictoRec.setValue({ fieldId: 'tosubsidiary', value: toSubsidiary });
ictoRec.setValue({ fieldId: 'location', value: fromLocation });
ictoRec.setValue({ fieldId: 'transferlocation', value: toLocation });
// Default order status to Pending Fulfillment (Optional - configure as needed)
ictoRec.setValue({ fieldId: 'orderstatus', value: 'B' });
// 4. Add the Line Item
ictoRec.selectNewLine({ sublistId: 'item' });
ictoRec.setCurrentSublistValue({ sublistId: 'item', fieldId: 'item', value: item });
ictoRec.setCurrentSublistValue({ sublistId: 'item', fieldId: 'quantity', value: quantity });
ictoRec.commitLine({ sublistId: 'item' });
// 5. Save the Intercompany Transfer Order
let newIctoId = ictoRec.save({
enableSourcing: true,
ignoreMandatoryFields: false
});
log.audit('ICTO Created successfully', `Staging ID: ${stagingRecId} | ICTO ID: ${newIctoId}`);
// 6. Update Staging Record with the success link
record.submitFields({
type: stagingRecType,
id: stagingRecId,
values: {
'custrecord_icto_created_order': newIctoId,
'custrecord_icto_error_log': 'Success'
}
});
} catch (error) {
log.error('Error creating ICTO', `Staging ID: ${stagingRecId} | Error: ${error.message}`);
// If it fails, update the staging record with the error message so the user can fix it
record.submitFields({
type: stagingRecType,
id: stagingRecId,
values: {
'custrecord_icto_error_log': error.message
}
});
}
};
return {
afterSubmit: afterSubmit
};
});
Deploy the Script
- Go to Customization > Scripting > Scripts > New.
- Select your uploaded .js file.
- Click Create Script Record and name it something like “UE Create Intercompany Transfer Order”.
- Go to the Deployments tab.
- In the Applies To dropdown, select your Custom Record (e.g., Custom Intercompany Staging).
- Set Status to Released and Log Level to Debug.
- Save.
Re: Run Allocation Schedule Automatically
I know it can be done via scripting, but I don't have step-by-step guidance. I recommend working with an experienced NetSuite Consultant to build this customization.
NetSuite Admin Tip | Identifying the Smallest First Sales Order Value per Sales Rep Using SuiteQL
Understanding your total sales performance is important but digging deeper into how your sales reps onboard new customers can reveal even more powerful insights.
One valuable metric to track is this: Which sales reps have onboarded customers whose very first sales order had the lowest value?
Why does this matter?
- It helps evaluate onboarding quality and pricing strategy.
- It supports coaching opportunities for reps closing very small initial deals.
- It provides insight into sales minimum thresholds.
- It highlights trends in early customer acquisition behavior.
Using SuiteQL, you can extract this insight directly from your NetSuite data.
SuiteQL Query: Smallest First Sales Order Value Per Rep
SELECT
e.entityid AS salesrep_name, -- Sales rep's display name
MIN(first_orders.first_order_total) AS smallest_first_order_value -- Among all first sales, the lowest value for this rep
FROM (
-- Subquery: For each customer, find their sales rep,
-- their first sales order date, and the value of that earliest order
SELECT
c.id AS customer_id, -- Customer internal ID
c.salesrep, -- Sales rep's internal ID
MIN(t.trandate) AS first_sales_order_date, -- Earliest sales order date for each customer
MIN(t.foreigntotal) AS first_order_total -- Smallest total among all sales orders on the customer's first order date
FROM transaction t
JOIN customer c ON t.entity = c.id
WHERE t.type = 'SalesOrd' -- Only consider sales orders
GROUP BY c.id, c.salesrep
) first_orders
JOIN employee e ON first_orders.salesrep = e.id -- Link each customer’s first sales info to their sales rep for display
GROUP BY e.entityid
ORDER BY smallest_first_order_value ASC -- Show reps with the lowest first order win at the top
- The subquery finds, for each customer, the date of their first sales order and the value (foreigntotal) of that order.
- The outer query groups those first purchase values by sales rep and finds the minimum for each, so you see the lowest initial customer order for each rep.
- ORDER BY lets you quickly spot which reps have had the smallest customer “first win.”
To easily execute a SuiteQL query, see NetSuite Admin Tip | Running SUITEQL Using a Suitelet
The sample code described herein is provided on an "as is" basis, without warranty of any kind, to the fullest extent permitted by law. Oracle + NetSuite Inc. does not warrant or guarantee the individual success developers may have in implementing the sample code on their development platforms or in using their own Web server configurations.
Oracle + NetSuite Inc. does not warrant, guarantee or make any representations regarding the use, results of use, accuracy, timeliness or completeness of any data or information relating to the sample code. Oracle + NetSuite Inc. disclaims all warranties, express or implied, and in particular, disclaims all warranties of merchantability, fitness for a particular purpose, and warranties related to the code, or any service or software related thereto.
Oracle + NetSuite Inc. shall not be liable for any direct, indirect or consequential damages or costs of any type arising out of any action taken by you or others related to the sample code.
We’d love to hear how you integrate SuiteQL into your NetSuite processes! Share your insights and experiences in the NetSuite Admin Corner.











