F4311 and F4301: JD Edwards Purchase Order Tables
Aug 12, 2026
Aug 12, 2026
Convert a purchase order to Excel, CSV, or JSON
Submit your purchase orders
Drop documents here, or click to file
Up to 50 files per batch
Uploading...
In JD Edwards EnterpriseOne, purchase order headers live in F4301 (Purchase Order Header) and the lines live in F4311 (Purchase Order Detail File). You join them on the four-part order key: order company, order type, order number, and order suffix. Receipts and voucher matches sit in F43121, and the change history for every detail line sits in F43199.
Last updated August 2026
That is the short version, and it covers most of what people need when they are writing a report or tracing an order. The longer version matters because JDE stores this data in a way that will quietly give you wrong numbers if you treat it like a normal relational schema. Dates are Julian. Amounts have implied decimals. The order key is four columns, not one. Status lives on the line, not the header. Below is the reference I wish existed when I first had to pull open purchase orders out of an E1 database.
Oracle publishes the full list of tables used by EnterpriseOne Procurement Management. These are the ones you will actually touch.
| Table | Official name | What it holds | Prefix |
|---|---|---|---|
| F4301 | Purchase Order Header | One row per purchase order: supplier, order date, currency, buyer, and the supplier classification codes copied from the address book. | PH |
| F4311 | Purchase Order Detail File | One row per order line. This is where quantity, price, branch/plant, dates, and status actually live. It is a wide table, over two hundred columns. | PD |
| F4311T | Purchase Order Detail Tag File | Extra detail attributes kept in a tag file alongside F4311 rather than added to it. | |
| F43121 | Purchase Order Receiver File | Receipt records and voucher match records, with open quantity and open amount. Where receiving and three-way match history is read from. | |
| F43199 | P.O. Detail Ledger File (Flexible Version) | The purchasing ledger. A history row for each change to a detail line, including quantity, price, and amount. | |
| F4301Z1 / F4311Z1 | Unedited Transaction Tables | The inbound staging tables. External systems write here and a batch program creates the real orders. | |
| F40203 | Order Activity Rules | Defines the legal last-status and next-status pairs per order type and line type. The reason status numbers mean different things at different sites. | |
| F43092 | Purchase Order Receipt Routing File | Receipt routing information, for sites that inspect or stage goods before stocking them. | |
| F4322 | Purchasing Tolerance Rules | Unit price and extended amount tolerances used during receipt and match. | |
| F4321 | Supplier Schedule Master File | Scheduling data behind blanket orders in supplier release scheduling. | |
| F4330 | Supplier Selection File | Quote and supplier selection information. | |
| F0401 / F0101 | Supplier Master / Address Book Master | Supplier setup and the name behind the address number on the order. | |
| F4101 / F41021 | Item Master / Item Location File | Item description and the on-hand and committed quantities by branch/plant. | |
| F0411 | Accounts Payable Ledger | The voucher the matched receipt becomes. Reached from F43121, not directly from F4311. | RP |
Every column in a JDE table carries a two-character table prefix in front of the data dictionary alias. The alias for the order number is DOCO, so on the header it is PHDOCO and on the detail it is PDDOCO. Once you know the prefix, you can read any JDE table by looking up the alias rather than hunting for a column name.
This is the part that trips people up. A purchase order is not identified by one number. It is identified by four columns together, and joining on the order number alone will merge documents that have nothing to do with each other.
| Alias | Meaning | Why it is in the key |
|---|---|---|
| KCOO | Order Company | Document numbers are assigned per company, so the same number can exist in two companies. |
| DCTO | Order Type | A purchase order, a requisition, a blanket, and a quote can share a number. Order type separates them. |
| DOCO | Document (Order Number) | The number a buyer would quote you. |
| SFXO | Order Suffix | Distinguishes documents that were split or that share the number with a different suffix. |
| LNID | Line Number | Detail only. Together with the four key columns it is the primary key of F4311. |
SELECT h.PHDOCO AS order_number,
h.PHDCTO AS order_type,
h.PHAN8 AS supplier_number,
ab.ABALPH AS supplier_name,
d.PDLNID AS line_number,
d.PDLITM AS item,
d.PDDSC1 AS description,
d.PDUORG / 10000.0 AS qty_ordered,
d.PDUOPN / 10000.0 AS qty_open,
d.PDPRRC / 10000.0 AS unit_cost,
d.PDAEXP / 100.0 AS extended_amount,
d.PDNXTR AS next_status,
d.PDLTTR AS last_status
FROM F4301 h
JOIN F4311 d
ON d.PDKCOO = h.PHKCOO -- order company
AND d.PDDCTO = h.PHDCTO -- order type
AND d.PDDOCO = h.PHDOCO -- order number
AND d.PDSFXO = h.PHSFXO -- order suffix
LEFT JOIN F0101 ab ON ab.ABAN8 = h.PHAN8
WHERE h.PHDCTO = 'OP'The divisors are not decoration. See the implied decimals section below before you trust any number that comes out of this.
EnterpriseOne stores calendar dates in a Julian format, written as CYYDDD: a century digit, a two-digit year, and the day of the year. So 12 August 2026 is stored as 126224, not as a date type your reporting tool understands. Order date (TRDJ), requested date (DRQJ), and scheduled pick date (PDDJ) are all stored this way. Every report has to convert them, and comparing them as integers works only inside the same century.
-- SQL Server: JDE Julian (CYYDDD) to a real date
SELECT DATEADD(DAY,
CAST(RIGHT(CAST(d.PDTRDJ AS varchar(6)), 3) AS int) - 1,
DATEFROMPARTS(1900 + CAST(LEFT(CAST(d.PDTRDJ AS varchar(6)), 3) AS int),
1, 1)) AS order_date
FROM F4311 d
WHERE d.PDTRDJ > 0Numeric fields are stored as integers with the decimal point implied rather than present. A quantity of 12.5 is commonly stored as 125000 and an amount of 1,499.99 as 149999. The number of implied places is set by the data dictionary for each field, so it is not always the same, and it can differ between a quantity field and an amount field in the same row. Check the dictionary for your fields rather than assuming, because dividing by the wrong power of ten produces numbers that look plausible and are wrong by two orders of magnitude.
Short string fields are space padded to their defined length, so a comparison against an untrimmed literal will silently miss. And a large share of the interesting columns are user-defined codes that mean nothing until you decode them against F0005. Order type, line type, and hold codes are all UDCs.
Two columns on the detail line carry status: PDLTTR is the last status and PDNXTR is the next status. A line moves forward when a program updates the next status to the following step. The legal steps are not hard-coded. They are configured per order type and line type in Order Activity Rules (F40203), which is why status 400 can mean one thing at one site and something slightly different at another.
A common default progression for a standard purchase order looks like this, and it is a reasonable starting point when you have no documentation for a system you inherited.
| Last to next | Step |
|---|---|
| 220 to 230 | Order entered |
| 230 to 230 | Sitting in approval |
| 230 to 240 | Approved |
| 240 to 400 | Printed and ready to receive |
| 400 to 999 | Received and closed |
Read your own rules before you write the report. One query against F40203 tells you exactly which numbers your site uses:
SELECT OAOKCO, OADCTO, OALNTY, OALTTR, OANXTR, OADESC
FROM F40203
WHERE OADCTO = 'OP'
ORDER BY OALTTR, OANXTRStatus lives on the line, never on the header. A purchase order with ten lines can have four received, five open, and one canceled at the same moment. There is no single header status that describes that, so any report that tries to classify a whole order has to aggregate the lines and decide what mixed means.
Filter the detail lines, not the headers, and use open quantity rather than a status number where you can. Open quantity (PDUOPN) is maintained by the receiving process and is the most reliable single indicator that a line still has something outstanding. Excluding the closed and canceled statuses on top of that removes lines that were closed short.
SELECT h.PHDOCO, h.PHDCTO, ab.ABALPH AS supplier,
d.PDLNID, d.PDLITM, d.PDDSC1,
d.PDUORG / 10000.0 AS qty_ordered,
d.PDUOPN / 10000.0 AS qty_open,
d.PDAOPN / 100.0 AS amount_open,
d.PDNXTR AS next_status
FROM F4311 d
JOIN F4301 h ON h.PHKCOO = d.PDKCOO AND h.PHDCTO = d.PDDCTO
AND h.PHDOCO = d.PDDOCO AND h.PHSFXO = d.PDSFXO
LEFT JOIN F0101 ab ON ab.ABAN8 = h.PHAN8
WHERE d.PDDCTO = 'OP'
AND d.PDUOPN <> 0
AND d.PDNXTR NOT IN (999, 998)
ORDER BY h.PHDOCO, d.PDLNIDIf the number that comes back does not match what the buyers believe, the usual explanation is order type. A site that also uses OR for requisitions, OB for blanket orders, and OQ for quotes will have all of them sitting in the same F4311, and a report that forgets to filter DCTO counts documents that were never real purchase orders.
F4311 is the purchase order detail file and F4211 is the sales order detail file. They are deliberately parallel: F4201 and F4211 are the sales side of the same design that gives you F4301 and F4311 on the purchasing side, with the same four-part order key and the same last-status and next-status mechanics driven by Order Activity Rules. The confusion is worth naming because reports get written against the wrong one, particularly at companies that run transfer orders, where a single physical movement can produce documents on both sides.
For anyone arriving here from a different ERP, the equivalents are worth having in one place.
| System | PO header | PO line |
|---|---|---|
| JD Edwards EnterpriseOne | F4301 | F4311 |
| Oracle E-Business Suite and Fusion | PO_HEADERS_ALL | PO_LINES_ALL |
| SAP ECC and S/4HANA | EKKO | EKPO |
| Dynamics 365 Finance and Operations | PurchTable | PurchLine |
| Dynamics GP | POP10100 | POP10110 |
Receiving does not update F4311 alone. It writes a row to F43121, the Purchase Order Receiver File, which carries the receipt record and later the voucher match record along with open quantity and open amount. That table is the bridge between the order and accounts payable: the voucher itself lands in F0411, the Accounts Payable Ledger, and the accounting entries in F0911. So the chain for a three-way match question is F4311 to F43121 to F0411, and trying to join F4311 straight to F0411 skips the table that actually holds the link.
When a buyer asks why a purchase order line changed, the answer is in F43199, the purchasing ledger. It keeps a history row per change to a detail line, including quantity, price, and amount, which makes it the right table for change tracking and for audit questions about who moved a price after the order was cut.
Not by inserting into F4301 and F4311. Those tables sit behind business functions that maintain commitments, ledgers, status, and next numbers, so a direct insert leaves an order the application cannot process correctly. The supported batch route is the pair of unedited transaction tables: an external system writes to F4301Z1 and F4311Z1, and the Inbound Purchase Order program R4311Z1I copies those staged rows into the real F4301 and F4311. The transaction type for inbound purchase orders is JDEPOIN, and if your source is a flat file rather than a direct write, the Inbound Flat File Conversion program R47002C loads the file into the Z tables first. R4311Z1I is built for adding orders rather than updating existing ones, which is worth knowing before you design a two-way interface around it.
All of which assumes you have rows to stage. That is where most projects actually stall, because the orders arrive as PDFs from suppliers, as scans of mailed documents, or as attachments in a purchasing mailbox, and somebody has to turn them into columns first. Teams building this kind of pipeline usually end up with a small stack: something that reads the document, something that maps the fields, and a data integration layer that moves the result between systems on a schedule. Our own piece of that is the reading step. Purchase order to JD Edwards covers the capture path in more detail, and the output shape is easiest to see by running one order through the purchase order PDF to Excel converter.
F4311 is the Purchase Order Detail File, the table that stores one row per purchase order line in JD Edwards EnterpriseOne. It holds the item, branch/plant, quantity ordered and open, unit cost, extended amount, dates, and the last and next status codes. Its primary key is the four-part order key plus the line number: KCOO, DCTO, DOCO, SFXO, and LNID.
F4301 is the Purchase Order Header table. It stores one row per purchase order with the supplier address number, order date, order company, currency, buyer, and the supplier classification codes copied from the address book. It carries no line detail and no line status, so almost every practical purchasing report reads F4311 and joins back to F4301 for the header attributes.
F43121, the Purchase Order Receiver File. It holds both the receipt record and the voucher match record for a line, along with open quantity and open amount. Receipt routing, used where goods are inspected or staged before being stocked, is tracked separately in F43092, and the resulting supplier voucher lands in F0411.
Reading is normally fine and is how most reporting is done, though check with whoever owns the environment first and read from a replica if one exists. Writing is not. Inserts and updates straight into F4301 or F4311 bypass the business functions that keep commitments, the purchasing ledger, next numbers, and status in step, and leave orders the application will not handle correctly. Use the Z tables and R4311Z1I, an orchestration, or the published business functions instead.
In the status codes on the detail line rather than in a dedicated approval column. A line waiting for approval typically sits at a next status configured for that step in Order Activity Rules, and held orders are recorded in F4209. Because approval routing is configurable, the only reliable way to know which number means approved in a given environment is to read F40203 for that order type and line type.
Largely yes at the table-name level. World and EnterpriseOne share the F4301 and F4311 heritage and the same data dictionary aliases, which is why a query written for one often reads correctly against the other. The tooling around them differs substantially, and World environments are more likely to store data on DB2 for i with library-based schemas, so the SQL dialect and the way you reach the tables will not carry across unchanged.
Sources for the table names and descriptions in this article are Oracle's JD Edwards EnterpriseOne Procurement Management and Interoperability documentation. Status values and implied-decimal settings are configurable per environment, so confirm them against your own F40203 and data dictionary before relying on a report.
Stop retyping purchase orders
Upload a PDF, scan, or photo of any PO and get clean Excel, CSV, or JSON line items in seconds.
Try it free25 pages free. No credit card required.