Item fulfillments
The shipment of an order's goods. It is the transaction that carries cost of goods into the margin, which is why an order can show revenue before it shows cogs.
An item fulfillment is the outbound shipment for a sales order: the goods leaving the warehouse. It arrives from NetSuite with the lines that shipped and the cost price of each, which is what makes it the carrier of cost of goods sold.
Where it comes from
app/jobs/netsuite/itemfulfillments.php consumes the ns_itemfulfillments batch type, one batch per date. Orders before ingest.modernera were loaded from verkoopdump, which writes fulfillments alongside the orders and invoices in the same import.
A fulfillment points back at its order through createdfrom, so classify/itemfulfillments.php calls getblocked(array('ns_salesorders')) and ends the run while any sales order batch is still queued.
Tables
| Table | Holds |
|---|---|
itemfulfillments | The header |
itemfulfillmentlines | Item lines, carrying the cost price of what shipped |
itemfulfillmentlinesnoninv | Non-inventory lines |
itemfulfillmentclassifications | Header flags |
itemfulfillmentlineclassifications | Line flags |
There are no discount or tax tables here, because a shipment prices nothing: the money was settled on the order and the invoice.
What classification records
The order it ships, the transaction date, the fulfillment status, the sales channel, and the three line-shape flags multiline, linesinvonly and linesnoshipping. It is the shortest classification of the seven types, because a shipment carries no promotional or payment attributes of its own.
What it contributes to margin
Cost of goods. calculate/itemfulfillments.php prices the shipped lines through the calculation rules. A GL rule preserves the signed posting amount and maps it to a CCC account; cogs is one possible destination. See dates, currency and signs.
The job rebuilds a day at a time: it deletes that date's fulfillment impacts from all four contribution groups, recalculates, and re-queues every order it touched into cm_impact_salesorders.
This is why realised cogs can lag realised revenue. The invoice and the fulfillment are separate NetSuite transactions and they do not have to arrive on the same day, so an order between the two shows revenue with no cost against it. The expected figure does not have this gap: it fakes a fulfillment from the order's own lines with the cost price sign flipped, so expected cogs exists from the moment its expected-margin worker finishes.
Where to look, and where to change
| What | Where |
|---|---|
| The fulfillments themselves | /transactions/itemfulfillments |
| One fulfillment in the context of its order | /transactions/salesorderdetail, under related records |
| The cogs it booked | /contributionmargin/impact, filtered on the cogs accounts |
Nothing about a fulfillment is editable in CCC. Correct it in NetSuite and let the import bring it through.
Related
- Sales orders
- Item receipts, the inbound counterpart on a return
- Expected margin
- Contribution margin
Evidence
Import and blocking from app/jobs/netsuite/itemfulfillments.php and app/jobs/classify/itemfulfillments.php. Classification fields from the INSERT in that classify job and classify->classifyitemfulfillment(). Table family from app/jobs/install/install.php. Day rebuild and re-queueing from app/jobs/calculate/itemfulfillments.php. The faked fulfillment and its flipped sign from app/models/expectedimpact.php. Columns from templates/main/transactions/itemfulfillments.tpl. Basis: code-checked against the current implementation.
- Type
object - Status
active - Updated
2026-09-14 - Created
2026-09-13 - Covers
transactions/itemfulfillments