🔹 What is EDI Automation?
EDI (Electronic Data Interchange) is a standard way for businesses to exchange documents (like purchase orders, invoices, and shipping notices) electronically instead of using paper or email.
In simple words:
👉 EDI lets your NetSuite system talk directly with your customers, suppliers, and partners.
🔹 Why Use EDI with NetSuite?
Without EDI, businesses often spend hours manually entering orders, invoices, or shipment details into NetSuite. This can lead to:
❌ Delays
❌ Errors in data entry
❌ Higher costs
With EDI automation, transactions move system-to-system with little or no human involvement.
🔹 Common EDI Documents in NetSuite
Here are the most common EDI documents you’ll see in NetSuite automation:
- EDI 850 → Purchase Order
- EDI 810 → Invoice
- EDI 856 → Advance Ship Notice (ASN)
- EDI 846 → Inventory Inquiry/Advice
- EDI 870 → Order Status Report
🔹 How EDI Automation Works in NetSuite (Simplified Flow)
- Trading Partner Sends EDI File
Example: A retailer (like Walmart) sends an EDI 850 Purchase Order. - Integration Layer Translates File
The EDI file is converted into a NetSuite-friendly format (XML/JSON).- Tools like Dell Boomi, Celigo, SPS Commerce, or custom RESTlets are often used.
- NetSuite Creates a Transaction Record
The translated order automatically creates a Sales Order inside NetSuite. - Outbound EDI Document
When you ship goods, NetSuite generates an Invoice (EDI 810) or ASN (EDI 856) that is sent back to your trading partner automatically.
🔹 Example: Automating an EDI 850 Purchase Order to NetSuite
Imagine Walmart sends you an order:
- EDI 850 File → “Order 100 T-Shirts”
- Middleware (like Boomi/Celigo) → Translates file → Pushes to NetSuite
- NetSuite → Creates a Sales Order record with item, quantity, and customer info
- When shipped → NetSuite automatically sends EDI 856 ASN back
This means: No manual typing, fewer errors, faster order-to-cash cycle.
🔹 Benefits of EDI Automation in NetSuite
✅ Faster order processing
✅ Less manual work → fewer errors
✅ Compliance with big retailers (many require EDI)
✅ Scales easily as you grow
✅ Improves customer & vendor relationships
🔹 Beginner Tip
If you’re just starting with EDI in NetSuite:
- Begin with one partner (e.g., Walmart, Amazon, Home Depot).
- Automate one document (like EDI 850 → Sales Order).
- Test thoroughly in sandbox before live trading.
NetSuite doesn’t natively parse X12/EDIFACT, but you can build EDI automation with SuiteScript by handling transport, translation, and mapping yourself (or with a lightweight external translator). Many teams do this when they have a few trading partners and stable specs.
How it typically works with SuiteScript
- Transport
- Pull/push files via SFTP using
N/sftp
. - AS2 is not native to NetSuite—use an external AS2 gateway if required.
- Pull/push files via SFTP using
- Translation
- Convert X12 ↔ JSON/XML. SuiteScript has no built-in EDI parser, so:
- Either run a small off-platform translator (serverless, iPaaS, or a gateway that outputs JSON/XML), or
- Only handle “already translated” CSV/JSON in NetSuite.
- Convert X12 ↔ JSON/XML. SuiteScript has no built-in EDI parser, so:
- Mapping + Record Creation
- Use Map/Reduce or Scheduled Scripts to read translated payloads and create/update NetSuite records (SO, Item Fulfillment, Invoice, etc.).
- Outbound
- Query NetSuite (Saved Search / SuiteQL), build JSON/flat structures, hand off to the translator to make X12, then SFTP/AS2 to the partner.
- Control/Config
- Store partner configs (qualifiers, IDs, document versions, account/terms mapping) in Custom Records.
When a SuiteScript-only approach makes sense
- You have a small number of partners and docs (e.g., 850, 856, 810).
- Partners can accept/produce JSON/XML or CSV (translator/gateway handles X12).
- You want full control and to avoid ongoing iPaaS fees.
When to use middleware (Celigo, Boomi, SPS, TrueCommerce…)
- Many partners / changing specs.
- Need AS2, 997/999, compliance testing, partner onboarding tools.
- You prefer prebuilt adapters and managed monitoring.
Example architecture (lightweight, SuiteScript-led)
Inbound 850 → Sales Order
- Partner → (X12 850) → Translator → JSON → NetSuite SFTP inbox
- Scheduled/MapReduce script downloads file, validates, creates Sales Order, logs results.
- Optional: create 997 via translator.
Outbound 856/810
- Shipment/Invoice event in NetSuite → Map/Reduce builds JSON → Translator → X12 → SFTP/AS2 to partner.
Minimal code sketches (beginner-friendly)
1) SFTP download + process (Scheduled)
/**
* @NApiVersion 2.1
* @NScriptType ScheduledScript
*/
define(['N/sftp','N/file','N/record','N/log'], (sftp, file, record, log) => {
const HOST_KEY = 'AAAAB3NzaC1yc2EAAAADAQABAAABAQ...'; // from partner
const REMOTE_DIR = '/inbound/edi850';
const execute = () => {
try {
// 1) Connect SFTP
const conn = sftp.createConnection({
username: 'ftp_user',
passwordGuid: 'custsecret_sftp_pwd_guid', // use a Secret
url: 'sftp.partner.com',
hostKey: HOST_KEY,
port: 22,
directory: REMOTE_DIR
});
// 2) List & fetch files
const files = conn.list({ path: REMOTE_DIR }) || [];
files.forEach(f => {
try {
if (!f || !f.name.endsWith('.json')) return; // assume translator output
const content = conn.download({ directory: REMOTE_DIR, filename: f.name }).getContents();
const po = JSON.parse(content); // translated 850
// 3) Create Sales Order (simple example)
const so = record.create({ type: record.Type.SALES_ORDER, isDynamic: true });
so.setValue({ fieldId: 'entity', value: getCustomerId(po.header.buyerId) });
so.setValue({ fieldId: 'trandate', value: new Date() });
(po.lines || []).forEach(l => {
so.selectNewLine({ sublistId: 'item' });
so.setCurrentSublistValue({ sublistId: 'item', fieldId: 'item', value: mapSku(l.sku) });
so.setCurrentSublistValue({ sublistId: 'item', fieldId: 'quantity', value: l.qty });
so.commitLine({ sublistId: 'item' });
});
const soId = so.save();
log.audit('850→SO', `Created SO ${soId} from ${f.name}`);
// 4) Archive the processed file in File Cabinet
file.create({
name: `processed_${f.name}`,
fileType: file.Type.JSON,
contents: content,
folder: 12345 // your archive folder
}).save();
// 5) Optionally move/delete on SFTP
// conn.move({ from: REMOTE_DIR + '/' + f.name, to: '/archive/' + f.name });
} catch (inner) {
log.error('Process850Error', inner);
}
});
} catch (e) {
log.error('SFTP/Execute Error', e);
}
};
// --- helpers (stubbed for beginners) ---
const getCustomerId = buyerId => 456; // map trading partner → NetSuite customer
const mapSku = sku => 789; // map partner SKU → NetSuite item internalId
return { execute };
});
2) Outbound Invoice (810) producer (Map/Reduce → JSON)
/**
* @NApiVersion 2.1
* @NScriptType MapReduceScript
*/
define(['N/search','N/file','N/log','N/sftp'], (search, file, log, sftp) => {
const getInputData = () => {
// Saved Search of invoices ready for EDI
return search.load({ id: 'customsearch_invoices_ready_for_edi' });
};
const map = (ctx) => {
try {
const row = JSON.parse(ctx.value);
const payload = {
header: { invoiceNumber: row.values.tranid, partnerId: 'WALMART' },
lines: [{ sku: row.values.item, qty: row.values.quantity, price: row.values.rate }]
};
ctx.write(row.id, payload);
} catch (e) { log.error('MapError', e); }
};
const reduce = (ctx) => {
try {
// Combine lines per invoice
const doc = ctx.values.map(JSON.parse).reduce((acc, v) => {
acc.lines = (acc.lines || []).concat(v.lines); acc.header = v.header; return acc;
}, {});
const json = JSON.stringify(doc);
// Drop JSON to SFTP outbox for translator to convert to X12 810
const conn = sftp.createConnection({ /* …same pattern as above… */ });
conn.upload({
directory: '/outbound/edi810',
filename: `${doc.header.invoiceNumber}.json`,
file: file.create({ name: 'tmp.json', fileType: file.Type.JSON, contents: json })
});
} catch (e) { log.error('ReduceError', e); }
};
return { getInputData, map, reduce };
});
Key limitations & notes
- No native X12/EDIFACT parser in SuiteScript. Use a translator/gateway (can be very small/cheap) to convert to/from JSON/XML.
- AS2 requires an external service. SFTP is fine natively.
- Handle acknowledgments (997/999), 855, 860 as your partners require—easiest via your translator.
- Watch governance: prefer Map/Reduce for large batches; use checkpoints and idempotency.
- Centralize partner-specific maps in Custom Records so you can change mappings without code releases.
TL;DR
For the X12/EDIFACT part, use a translator (external microservice, iPaaS, or gateway) to keep your NetSuite code simple and maintainable.
Yes, you can implement EDI automation using SuiteScript for transport (SFTP), orchestration, mapping, and NetSuite record creation.