| name | enable-customer |
| description | Configure a NetSuite parent customer (and its subcustomers) for EDI via the Orderful SuiteApp. Audits existing Orderful Enabled Transaction records, N1 ship-to fields on subcustomers, and the parent's "subcustomers represent" setting; cross-references with Orderful partner relationships and historical 850 ship-to IDs; then guides the user through creates/updates to close any gaps. Use when the user says "enable <customer> for EDI", "set up <customer> transactions", "configure <customer> in Orderful", "add <customer> to Orderful", or is bringing a new trading partner online and needs the NetSuite side wired up. Does NOT create customers or subcustomers (the SuiteApp does not create them either — an inbound ship-to that matches no subcustomer falls back to the parent customer). Does NOT delete records. |
Enable Customer: EDI Configuration for a NetSuite Customer
Guide the user through configuring a NetSuite parent customer and its subcustomers for EDI via Orderful. At the end, the parent should have:
- A complete set of
Orderful Enabled Transaction records matching the transaction types enabled on the Orderful partner relationship.
custentity_orderful_subcust_rep set to stores or dcs.
- Every subcustomer that the skill can match should have
custentity_orderful_shipto_n1_id filled in.
Many settings can now be set as subsidiary defaults instead of per-customer. Handling prefs, the split flags, packaging/label data source, salesOrderFormOverride, subCustomersRepresentation, and more each have a custrecord_orderful_sub_* field on the Subsidiary record that every (sub)customer under it inherits unless it sets a local value. For hundreds-of-subcustomers setups, set the default once on the subsidiary rather than stamping every child. See reference/settings-architecture.md for the full resolution chain (customer → parent → subsidiary default → hardcoded) and the field-ID tables.
Scope
In scope:
- Create new Enabled Transaction records (
customrecord_orderful_edi_customer_trans).
- Update existing Enabled Transaction records to match Orderful relationships.
- Set
custentity_orderful_subcust_rep on the parent.
- Set
custentity_orderful_shipto_n1_id on each subcustomer where a ship-to match can be inferred.
- Verify by reading back after writes.
Out of scope (do not attempt):
- Creating customers or subcustomers — the SuiteApp does not create either. If the inbound N1*ST doesn't match a subcustomer, the Sales Order falls back to the parent customer; no record is created automatically. Flag missing subcustomers in the report; don't create them.
- Deleting Enabled Transaction records or clearing fields.
- Configuring advanced flags:
isProcessAsCustom, consolidation method, JSONata advanced mapping, 860 change rules, 810 source type. Leave defaults; the user tunes these later by hand.
- Setting customer-level outbound handling preferences (
custentity_orderful_poack_handling_prefs, custentity_orderful_asn_handling_prefs, custentity_orderful_inv_handling_prefs). These gate WHEN each outbound MR fires; the skill leaves them alone but does report their current values in the audit and flags any unset ones. See "Post-enablement checklist" below — the invoice handling pref in particular is a footgun (it ships unset by default and silently prevents 810 outbound from ever firing).
Prerequisites
- The
netsuite-setup skill has already run for this customer. ~/orderful-onboarding/<slug>/.env exists and both connections validate.
- The parent NetSuite Customer record exists and has
custentity_orderful_isa_id set — this is the join key between NS and Orderful. If it's blank, stop and ask the user to populate it in NetSuite before running the skill.
- The
customrecord_orderful_edi_document_type seed records exist in the target NetSuite account (installed with the SuiteApp). These are the FKs that custrecord_edi_enab_trans_document_type points at.
Step 1 — Identify the parent customer
Ask the user for one of:
- NS Customer internal ID (fastest)
- NS Customer entity ID (business identifier)
- Company name (substring search)
Use the .env from netsuite-setup to query NetSuite (SuiteQL against customer). Confirm back with the user: internalid, entityid, companyname, custentity_orderful_isa_id. If the ISA ID is blank, stop — tell the user the skill requires it.
Step 2 — Audit (read-only)
Do ALL reads before asking the user anything. The audit has two halves.
NetSuite reads
Parent customer:
- Standard:
internalid, entityid, companyname, parent (should be null — it's the root).
custentity_orderful_isa_id
custentity_orderful_subcust_rep (value: stores | dcs | unset)
custentity_orderful_shipto_use_entityid (checkbox)
- Outbound handling preferences (read-only — surface to user, don't write):
custentity_orderful_poack_handling_prefs — gates 855 generation
custentity_orderful_asn_handling_prefs — gates 856 generation
custentity_orderful_inv_handling_prefs — gates 810 generation; if unset, 810 outbound never fires (silent failure)
All subcustomers (SuiteQL: SELECT ... FROM customer WHERE parent = <parent_internalid>):
- Standard:
internalid, entityid, companyname, primary shipping address.
custentity_orderful_shipto_n1_id
All existing Enabled Transactions for this parent:
- Query
customrecord_orderful_edi_customer_trans WHERE custrecord_edi_enab_trans_customer = <parent_internalid>.
- For each row, resolve the document type by joining to
customrecord_orderful_edi_document_type.
- Capture: document type (human-readable), direction, linked transaction type, test mode flag, any ISA overrides.
Historical ship-to hints (to pair subcustomers):
- Query the SuiteApp's
customrecord_orderful_transaction records for this customer, direction = inbound, document type = 850. Parse N1*ST identifiers from the stored payload or linked field. Build a de-duplicated list of seen N1 IDs.
Orderful reads
Using the parent's ISA ID:
- Look up the partner organization in Orderful.
- List active relationships involving that partner. Each relationship names the counterparty partner and the list of enabled transaction types.
- Optionally, if ship-to inference from NS data was thin, pull recent inbound transactions from Orderful's API for this partner (last ~30 days) and extract N1*ST identifiers as a fallback.
Audit output
Produce a concise report for the user. Include:
- Parent identification (internalid, entityId, companyname, ISA ID, whether it matched an Orderful partner).
- Current values of
custentity_orderful_subcust_rep and custentity_orderful_shipto_use_entityid on the parent.
- List of subcustomers with their N1 IDs (or "unset").
- List of existing Enabled Transactions on the parent.
- List of Orderful-side enabled transaction types for this partner.
- Gaps: transaction types Orderful has but NS doesn't, subcustomers missing N1 IDs,
subcust_rep unset.
- Ship-to hints: seen N1*ST IDs (from NS history + Orderful history), with suggested subcustomer matches where the name or entity ID contains the ID.
- Orphans: Enabled Transaction records in NS with no matching Orderful relationship (informational only — out of scope to delete).
Step 3 — Decide
Prompt the user to fill the gaps, one category at a time.
3a. Subcustomer representation
If custentity_orderful_subcust_rep is unset:
- Look at subcustomer names for patterns (e.g., "DC" or "Store") and suggest a default.
- Ask: "Subcustomers look like <stores | dcs>. Confirm or override?"
- Only allowed values:
stores, dcs. Anything else → ask again.
If already set, skip.
subCustomersRepresentation resolves customer → parent → subsidiary default. The customer field is customlist_orderful_subcust_rep_opt (exposed as custentity_orderful_subcust_rep); the subsidiary default is custrecord_orderful_sub_subcust_rep. If the parent's value is unset, the SuiteApp will inherit from the subsidiary default — so before writing it on the parent, check whether the subsidiary already supplies it (an unset parent + a populated subsidiary default is not a gap). See reference/settings-architecture.md. Note: this one subsidiary default is the empty-means-"None" case (its list only has Stores/DCs).
3b. Ship-to N1 IDs on subcustomers
For each subcustomer missing custentity_orderful_shipto_n1_id:
- If a seen N1*ST ID from the audit matches the subcustomer's name or entity ID, suggest it: "Assign N1 ID
555 to 'Northwind Store 555'? (y/n)"
- If no inference is possible, ask whether the user wants to provide one now or skip (skip is fine — SuiteApp can fall back via
custentity_orderful_shipto_use_entityid if enabled).
- Never write automatically — always confirm.
Seen N1*ST IDs with no matching subcustomer: report but don't act. The SuiteApp will not auto-create a subcustomer; the inbound Sales Order will fall back to the parent customer instead. The user can manually create the subcustomer in NetSuite later if they want a subcustomer-level link, but the skill should not do it.
3c. Enabled Transactions
For each Orderful transaction type with no matching Enabled Transaction record:
- Resolve the correct
customrecord_orderful_edi_document_type row.
- Ask direction (inbound, outbound, both). Suggest defaults: 850/875 → inbound; 855/856/810/846 → outbound.
- Ask linked NS transaction type. Suggest: 850/875 → Sales Order; 855 → Sales Order; 856 → Item Fulfillment; 810 → Invoice; 846 → (leave unset).
- Ask test vs prod mode. Default prod; flip to test if
.env's ENVIRONMENT=sandbox.
- Leave all advanced flags (
isProcessAsCustom, consolidation, JSONata, 860 rules, 810 source) at defaults.
For each existing Enabled Transaction that differs from Orderful (direction mismatch, wrong linked type, wrong test-mode setting): report the diff and ask yes/no to update. If yes, update only the changed fields; don't touch anything else.
Skip orphans entirely (out of scope to delete).
Step 4 — Configure
Before writing anything, summarize the full plan back to the user:
Plan:
Parent (Northwind Retail Inc., internal 12345):
- custentity_orderful_subcust_rep: unset → 'stores'
Subcustomers:
- Northwind Store 555 (internal 12346): shipto_n1_id: unset → '555'
- Northwind Store 892 (internal 12347): shipto_n1_id: unset → '892'
Enabled Transactions:
- Create: 856 ASN — outbound, Item Fulfillment, prod
- Create: 810 Invoice — outbound, Invoice, prod
- Update: 855 PO Ack — direction: inbound → outbound
No deletes.
Proceed? (y/n)
On y, execute writes in this order:
- Parent fields (
custentity_orderful_subcust_rep).
- Subcustomer fields (
custentity_orderful_shipto_n1_id) — one PATCH per subcustomer.
- Enabled Transaction records — one POST per new record, one PATCH per update.
On any write error, stop immediately. Report which writes succeeded and which failed. Do NOT attempt rollback; the user re-runs the skill to finish.
Step 5 — Verify
Re-read the same state as Step 2 (parent fields, subcustomer fields, Enabled Transactions for this parent). Produce a short pass/fail diff:
Verification:
✓ custentity_orderful_subcust_rep on parent = 'stores'
✓ shipto_n1_id on 'Northwind Store 555' = '555'
✓ shipto_n1_id on 'Northwind Store 892' = '892'
✓ Enabled Transaction 856 ASN — created (outbound, Item Fulfillment, prod)
✓ Enabled Transaction 810 Invoice — created (outbound, Invoice, prod)
✓ Enabled Transaction 855 PO Ack — direction updated to outbound
All writes verified.
If anything fails verification, surface which field/record and leave the user to decide: re-run the skill or inspect in the NetSuite UI.
Post-enablement checklist
This skill stops at writing Enabled Transaction records and the parent/subcustomer fields. Before the customer can actually exchange EDI, three customer-level outbound handling preferences need to be set on the parent — review-and-set these manually in NetSuite (or via REST PATCH) for each outbound doc type the customer will send:
| Field | Gates | Default if unset |
|---|
custentity_orderful_poack_handling_prefs | When 855 fires (auto on SO save / workflow / never) | Often null; some installs default to "auto on Sales Order save" |
custentity_orderful_asn_handling_prefs | When 856 fires (auto on IF save / workflow / never) | Often null |
custentity_orderful_inv_handling_prefs | When 810 fires (auto on Invoice creation / workflow / never) | Null — silently prevents 810 outbound from ever firing |
The list values come from customlist_orderful_invoice_handl_opts (and equivalents for the other prefs). For "auto-fire on record creation" behavior (the most common setup), set them to id 1 ("Process on invoice creation" — the customlist's first value). For customers that gate outbound via their own workflows, use id 2 ("Custom (Manual/Workflow)").
Verify post-set by saving an in-scope source record (SO / IF / Invoice) and checking that a customrecord_orderful_transaction row appears with the right document type and status Pending → Ready To Send. If nothing appears, the handling pref is still unset (or it resolves to "never" / a custom-process state). The handling preference is the only outbound gate — the ECT no longer needs an auto-send flag to dispatch, and it resolves with the full customer → parent → subsidiary-default chain (see reference/settings-architecture.md).
Legacy note: connector versions < v1.22.0 required a per-ECT auto_send_asn = T flag to dispatch the outbound. That flag was removed in v1.22.0 — the handling preference (with subsidiary-default resolution) is now the single gate. Don't look for custrecord_edi_enab_trans_auto_send_asn on current installs.
Troubleshooting
- Parent has no ISA ID: skill can't match to Orderful. Stop; ask the user to set
custentity_orderful_isa_id on the Customer record (NetSuite UI) and re-run.
- ISA ID doesn't resolve to an Orderful partner: either the ID is wrong, or the Orderful API key in
.env belongs to a different org than the partner is in. Check both.
- Document Type FK resolution fails — SuiteQL returns no row for "850" etc. in
customrecord_orderful_edi_document_type: the SuiteApp install may be missing seed records. This is an install-level issue, not a skill issue. Stop and tell the user.
- 403 on Enabled Transaction create/update: the access token's role lacks create/edit permission on
customrecord_orderful_edi_customer_trans. Have the customer grant the role the right permissions and re-run.
- "Parent is also a subcustomer" edge case: if the customer the user named has a non-null
parent field, ask whether they meant the parent instead. The skill operates on tree roots.
- Inbound SO has an empty shipping address even though the 850 carried a full
N1*ST: this is NOT a subcust_rep / sub-customer / ship-to config gap, and changing those settings won't fix it. custentity_orderful_subcust_rep (stores/dcs) only controls matching the inbound N104 against a sub-customer's custentity_orderful_shipto_n1_id so the SO is filed under that sub-customer — it is not an address lookup, and on no match the SO falls back to the parent. Separately, the SuiteApp maps N1*ST into its BDO correctly but the inbound SO write step persists billingAddress and drops shippingAddress — confirm by reading the BDO via inspect-inbound-diagnostics (the Order Split step shows transaction.shippingAddress fully populated while the created SO's shipping address is empty). That's a SuiteApp bug to escalate to devs, not a config change; the stopgap is to set the ship address on the IF/SO before the outbound 856.
Dry-run mode
If the user says "dry run" or "audit only", complete Steps 1, 2, and 3 (showing what would be written) but skip Step 4. Print the plan and stop. Useful for pre-change review or diffing two customers.