Hard Inventory Reservation for Blanket Orders
NetSuite has no blanket order type that holds 100 units for later releases to draw down. Three ways to build that reservation, compared.

On this page
An EDI customer sends an 850 Blanket Order (BK) for 100 units. You need those units hard-reserved. Then three 850 Release Orders (RL) arrive: 30, 20, and 50 units. Each release must consume from the original 100-unit reservation until exhausted. NetSuite doesn't give you a native "blanket order" transaction type that behaves this way, so you're left choosing between native features and build-around approaches.
With Advanced Inventory Management (AIM) and SCM enabled, you have several paths. Here's how to evaluate them against the hard reservation requirement.
Why Standard Sales Orders Fail This Pattern
A standard Sales Order with a commitment will reserve inventory, but it ties the reservation to that specific transaction. When your EDI integration creates a BK as a sales order, the 100-unit commitment sits on that order. Release orders arrive as separate transactions. Nothing in native NetSuite automatically transfers a committed quantity from one sales order to another.
The commitment is a quantity on a line. It isn't a pool you can draw from across transactions.
That's the core friction. You need either a mechanism that pools inventory separately, or a custom layer that reallocates commitments programmatically.
Option 1: Sub-Location Segregation with Inventory Transfers
Create a dedicated sub-location for blanket inventory, for example BLANKET under your main warehouse. When the BK arrives, create an Inventory Transfer from the main location to the BLANKET sub-location for the full 100 units. That transfer physically moves the stock into a location where normal sales orders won't accidentally consume it.
When RL1 arrives for 30 units, create the sales order against the BLANKET sub-location and fulfill from there. The Item Fulfillment decrements the sub-location quantity. Repeat for RL2 and RL3.
The validation step: run a saved search on the BLANKET sub-location after each release. You should see quantity on hand drop from 100 to 70, then 50, then 0.
What Breaks Here
This approach treats the sub-location as the reservation mechanism. The inventory is physically segregated, so it can't be sold elsewhere. That's a true hard reservation in practice.
The failure point is timing. If the EDI integration creates the release sales order before the transfer posts, the fulfillment will fail with insufficient quantity. You need a dependency check: release order creation must wait for transfer approval and posting.
Also, users with fulfillment rights can still fulfill from the BLANKET sub-location outside your release process. You're relying on process discipline, not system enforcement.
Option 2: Fulfillment Requests and Supply Allocation
NetSuite's Supply Allocation feature, available with Advanced Inventory Management, can allocate supply to demand based on priority. You can create the BK as a sales order, then use Supply Allocation to assign the 100 units to that order.
The problem: Supply Allocation allocates to a demand line. It doesn't natively support the "release order consumes from blanket" relationship. You would still need to reallocate supply from the BK demand to each RL demand as releases arrive.
This is where the native feature falls short. Supply Allocation handles priority-based allocation across independent demand lines, not a parent-child consumption model.
Fulfillment Requests have similar limitations. A Fulfillment Request creates a demand record that can be fulfilled, but it doesn't provide a mechanism to track remaining blanket quantity across multiple releases.
Option 3: Custom SuiteScript with Commitment Reallocation
If you need the reservation to be system-enforced, a custom script layer is the reliable path. The approach: create the BK as a sales order with a custom field tracking blanket quantity. Each release order gets a custom field referencing the BK.
When a release order is created, a SuiteScript (triggered by a User Event) checks the remaining blanket quantity, creates an inventory commitment on the release order line, and decrements the BK's remaining quantity.
Here's the core pattern using SuiteScript 2.1:
/**
* @NApiVersion 2.1
* @NScriptType UserEventScript
*/
define(['N/record', 'N/log'], function(record, log) {
function afterSubmit(context) {
if (context.type !== context.UserEventType.CREATE) return;
var releaseOrder = context.newRecord;
var blanketId = releaseOrder.getValue({
fieldId: 'custbody_blanket_order_ref'
});
if (!blanketId) return;
var blanketOrder = record.load({
type: record.Type.SALES_ORDER,
id: blanketId
});
var remainingQty = blanketOrder.getValue({
fieldId: 'custbody_blanket_remaining_qty'
});
var releaseQty = releaseOrder.getValue({
fieldId: 'custcol_release_qty'
});
if (releaseQty > remainingQty) {
throw new Error('Release quantity exceeds remaining blanket quantity');
}
// Find the item line on the release order
var itemLine = releaseOrder.findSublistLineWithValue({
sublistId: 'item',
fieldId: 'item',
value: releaseOrder.getValue({ fieldId: 'custbody_release_item' })
});
// Set the commitment on the release order line
releaseOrder.setSublistValue({
sublistId: 'item',
fieldId: 'quantitycommitted',
line: itemLine,
value: releaseQty
});
releaseOrder.save();
// Decrement remaining blanket quantity
blanketOrder.setValue({
fieldId: 'custbody_blanket_remaining_qty',
value: remainingQty - releaseQty
});
blanketOrder.save();
log.audit({
title: 'Blanket Release Processed',
details: 'Release ' + releaseOrder.id + ' consumed ' + releaseQty +
' from blanket ' + blanketId + '. Remaining: ' +
(remainingQty - releaseQty)
});
}
return {
afterSubmit: afterSubmit
};
});This is the pattern that gives you true hard reservation. The commitment is created on the release order, and the blanket quantity is decremented atomically. No other transaction can consume those units because the commitment exists on a real sales order line.
For more on how item commitment works with inventory availability, see the Inventory Management Guide.
The Idempotency Concern
This is where most integrations break. If the release order creation triggers the script twice, you'll double-decrement the blanket quantity. You need a guard: check whether the release order already has a commitment before applying another.
Add a custom field on the release order line, for example custcol_blanket_commitment_applied, and check it before processing.
Which Approach Fits Your EDI Flow?
| Approach | True Hard Reservation | Native Features Only | Complexity | Risk |
|---|---|---|---|---|
| Sub-location + Transfer | Yes (physical segregation) | Yes | Low | Process discipline required |
| Supply Allocation | Partial | Yes | Medium | No parent-child consumption |
| Custom SuiteScript | Yes | No | High | Idempotency and error handling |
The sub-location approach works well if your releases always come from the same warehouse and you control fulfillment permissions tightly. The custom script approach is the only one that gives you system-enforced reservation with a clear audit trail.
For the EDI integration through Celigo, the sub-location approach is easier to map. Your Celigo flows create the BK, trigger the inventory transfer, and create release orders against the BLANKET sub-location. No custom scripting required in the EDI layer.
The custom script approach requires Celigo to pass the blanket order reference on each release order, then the script handles the commitment logic.
Test This With a Single Record First
Before you build the full EDI mapping, test the reservation pattern manually. Create a blanket sales order for 100 units. Create three release orders for 30, 20, and 50 units. Confirm the remaining quantity hits zero exactly.
Then run an Item Fulfillment on each release order in sequence and verify the inventory decrements correctly from the sub-location or the committed quantity.
This is where you'll find the edge cases: partial releases, releases that exceed the blanket, and releases that arrive after the blanket expires. The error response from your script or the transfer failure tells you exactly what went wrong.
For a deeper look at how inventory status records interact with commitment and allocation, review the inventory status configuration steps in the documentation.
But the core reservation logic needs to be solid in NetSuite first.


