How to import lot and expiry stock with an Inventory Adjustment CSV in NetSuite

Load opening stock for lot-numbered items with a lot number and expiration date on every line: map the Inventory Adjustment header, line and Inventory Detail fields, run the import, then check the adjustment, its lots and the item.

The quick answer

Go to Setup > Import/Export > Import CSV Records, set Import Type to Transactions and Record Type to Inventory Adjustment, and keep Data Handling on Add. On Field Mapping, map the header fields, the line fields in Inventory Adjustment - Adjustments and the lot fields in Inventory Adjustment - Adjustments - Inventory Detail: Quantity, Receipt Inventory Number and Expiration Date. Set the values that repeat, such as Subsidiary, as default values. Then save, run and check the adjustment, its Inventory Detail and the item's lots.

The screenshots show sample data. Person and company names are fictional. Use your own items, accounts and values when you follow the steps.

Before you start

You need a role that can import CSV records and create inventory adjustments. The items have to exist already as lot-numbered inventory items, which needs lot tracking (Advanced Bin / Numbered Inventory Management) to be on, and they have to be available to the adjustment's subsidiary and location. The location has to belong to that subsidiary, the adjustment account has to be active and usable for it, and the posting period has to be open.

This example uses a OneWorld account with Inventory Status on, and Use Bins off for the items. The lots came in with the status Good without a Status column being mapped. Your account may require a Status, and its values depend on your setup. If your items use bins, map the bin fields in Inventory Detail as well. Auto-generated numbering is on for adjustments. Your account may differ, so go by the (Req) markers on your own Field Mapping page, and test with a small file first.

Harborline Foods is loading opening stock for four sauce and chutney items. The stock comes in opening-lot-stock.csv, with one row per lot.

01. Check the lot items

Go to Lists > Accounting > Items. CHL-250, CHL-500, MNG-250 and MNG-500 are listed as Lot Numbered Inventory Items. Then open CHL-250 and its Inventory Detail tab. No lots are listed, so nothing is on hand yet. Look first, so you can see what the import added.

The four lot items that will receive stock.
CHL-250 has no lots yet.

02. Review the file

Open opening-lot-stock.csv. It has a header row and five data rows. Row 2 is CHL-250, line 1, quantity 120, unit cost 1.85, lot CH250-A1, expiry 03/31/2027 and location Newark. Row 3 is the same item on line 2, with a different lot, CH250-A2, quantity 80 and expiry 05/31/2027. All five rows share Ref STK-OPEN-01.

Each lot is its own row, and each row is its own line. In this test, the shared Ref made the five rows import as one adjustment. A repeated External ID is the most dependable grouping value, so test the grouping on a small file before a large one.

Five rows, one per lot. CHL-250 appears twice with different lots.

03. Upload the file

Go to Setup > Import/Export > Import CSV Records. Set Import Type to Transactions and Record Type to Inventory Adjustment. Keep Character Encoding and CSV column delimiter as they are, unless your file uses another encoding or separator. Click Select..., choose opening-lot-stock.csv and click Next.

Transactions, Inventory Adjustment, and the file.

04. Choose Add

On Import Options, keep Data Handling on Add, because these are new transactions. Open Advanced Options to see the Custom Form whose fields can be mapped. Here it is Inventory Adjustment Form. If your account uses a different adjustment form, pick it here so its fields appear on the next page. Click Next.

Add, and the form that decides which fields you can map.

05. Map the header fields

Field Mapping lists Subsidiary, Date and Adjust Qty. By first. Subsidiary and Adjust Qty. By are required and still empty. Date is italic because NetSuite proposes today's date as its default. NetSuite also pairs three columns by their headings: Location with Adjustments : Location, Unit Cost with Est. Unit Cost and Quantity with Inventory Detail : Quantity.

NetSuite proposes three pairs and leaves two required rows empty.

Click Ref under Your Fields, then Reference # under Inventory Adjustment in NetSuite Fields. Click Adjustment Expense Account, then Adjustment Account. The account has to resolve for the adjustment's subsidiary. When you map names, write it as NetSuite shows it, including any parent account. Internal IDs or external IDs are safer.

06. Map the line fields

Expand Inventory Adjustment - Adjustments. Map Item Name to Item, Line ID to Line and Quantity to Adjust Qty. By (Req). Quantity is now mapped twice: once for the line and once, from the proposal, for its lot. Line is the line's position. Adjust Qty. By is the change in quantity, not the new total, so a positive number adds stock.

Item, Line and Adjust Qty. By join the mapping.

07. Map the Inventory Detail

Expand Inventory Adjustment - Adjustments - Inventory Detail. Map Lot Number to Receipt Inventory Number and Expiry date to Expiration Date. For a positive adjustment, Receipt Inventory Number names the lot you are adding, which is why it fits opening stock. The Inventory Detail quantities for a line have to reconcile to that line's Adjust Qty. By. Here each line has one lot, so the same Quantity column feeds both. The expiration date applies when the item and account track expiry.

Lot number and expiry date map to the Inventory Detail group.

08. Set the values that repeat

Subsidiary, Adjustment Location and Posting Period are the same for the whole file, so set them as default values instead of adding columns. Click the pencil on the Subsidiary (Req) row, choose Harborline Foods : US East and click OK. For the other two, double-click the field in NetSuite Fields, click the pencil on the row it adds, and choose Newark and Oct 2026. Adjustment Location is the header's classification. The line Location still comes from the file's Location column. Check that the proposed Date is the date you want and falls in an open period. The defaults show in italics. Every column now has a pair and every required row has a column or a default. Click Next.

Three defaults, shown in italics, plus the proposed Date.

09. Save the mapping and run the import

Enter Opening lot stock adjustment in Import Map Name. Description and ID are optional. Click Save & Run. The confirmation says the CSV import has been saved and the job is in process. Saving the map lets you rerun it with a new file later.

A saved map can be rerun with the next file.

10. Check the job

Click Import Job Status. The Inventory Adjustment - opening-lot-stock.csv job is Complete at 100.0% with the message 1 of 1 records imported successfully. The message counts transactions, not rows: five rows became one adjustment. If a row fails, open the CSV Response to read its error, and check which transactions were created before you rerun the file, so you do not import duplicates. An account that does not resolve for the subsidiary fails with an Invalid account reference key message.

One adjustment from five rows.

11. Open the adjustment

Go to Transactions > Inventory > Adjust Inventory > List and open the newest adjustment, IA402 in this example. NetSuite numbered it itself. With auto-generated numbering on, the file's Ref is not guaranteed to become the document number, so do not rely on it to find the record. Adjustment Account is 5009 Cost of Goods Sold : COGS - Finished Goods, Adjustment Location is Newark, Posting Period is Oct 2026 and Estimated Total Value is 931.75.

IA402 carries the defaults and the account from the file.

On the Adjustments tab there are five lines, one per row. CHL-250 appears twice, with Adjust Qty. By 120 and 80, and both show New Quantity 200. Each line shows the item's resulting quantity after the whole adjustment, so the same total on both lines is not a duplicate. The numbers here, IA402 and 931.75, belong to this example.

Five lines. Both CHL-250 lines show New Quantity 200.

12. Check the lot, the expiry and the GL impact

Click the Inventory Detail icon on the first line. The popup shows Item CHL-250, Quantity 120 and one detail row: lot CH250-A1, Status Good, Expiration Date 03/31/2027 and Quantity 120. Close it.

Lot CH250-A1 expires 03/31/2027.

Open the GL Impact tab. The adjustment account is credited 931.75 and the inventory account is debited for each line: 222.00, 148.00, 186.00, 198.00 and 177.75. For a positive adjustment, the inventory account is normally debited and the adjustment account credited. GL Impact on the saved record is the authority, and costing, books and negative adjustments can change what it shows. Which account you offset an opening load against is an accounting decision for your company.

The credit equals the sum of the five debits.

13. Confirm the lots on the item

Click CHL-250 to open the item, then its Inventory Detail tab. It now lists lot CH250-A1 with 120 on hand and lot CH250-A2 with 80, both with status Good at Newark. The columns and status values depend on the features your account has on. Together the two lots hold the item's stock by lot.

Two lots, 200 on hand in total.

Check the result

  1. Import Job Status shows 1 of 1 records imported and the CSV Response has no failed rows.
  2. The adjustment has one line per row, with the Adjust Qty. By and unit cost from the file.
  3. Each line's Inventory Detail shows the right lot, expiration date and quantity.
  4. GL Impact credits the adjustment account and debits inventory for the total value.
  5. The item's Inventory Detail tab lists each lot with the quantity on hand.

Common questions

Why do I map Quantity twice?

One mapping sets the line's Adjust Qty. By. The other sets the quantity assigned to the lot in Inventory Detail. In this single-file layout each line has one lot, so the two numbers match. For a positive line they normally do.

Does Adjust Qty. By set the new quantity or add to it?

It adds. Adjust Qty. By is the change in quantity. A positive number adds stock and a negative number removes it. The New Quantity column on the saved adjustment shows the result.

Why did NetSuite number the adjustment IA402 and not use my Ref?

Reference # and the saved document number are separate. With auto-generated numbering on, NetSuite assigns the next number. In this test the repeated Ref grouped the five rows into one adjustment. It was not saved as the document number. For repeatable imports, use a repeated External ID to group rows and test it on a small file. Check Setup > Company > Auto-Generated Numbers if you need to control the numbering.

What does Invalid account reference key mean?

The account value did not resolve for the adjustment's subsidiary. The name or hierarchy may be wrong, the account may be inactive, or the subsidiary may not be allowed to use it. Internal IDs or unique external IDs are the safer choice. If you use names, copy the account's full name from NetSuite, including its parent, and confirm the account is available to that subsidiary.

How do I remove stock from an existing lot?

Use a negative Adjust Qty. By and name the existing lot in Issue Inventory Number instead of Receipt Inventory Number. Check that the lot has enough stock at the location and status, and supply bins if your items use them. Test it on a small file first.

What if one item line needs several lots?

This file has one lot per line, so it does not show that layout. For several lots on one line, the Inventory Detail rows have to be tied to the same line. In a single file that takes the grouping value the import expects for Inventory Detail, and a linked multi-file import uses file keys instead. Reconcile the lot quantities to the line quantity and test a small file.

Why does the lot show a Status?

A Status column appears when Inventory Status is on in your account. Good was the status here, and it came in without a Status column in the file. The values and defaults depend on your inventory setup. Without Inventory Status there is no Status, and if your items use bins you map the bin fields in Inventory Detail too.