Troubleshooting Vendor Feeds

Diagnose a vendor catalog or inventory feed from its run tallies, error message, and failure report — with the cause and fix for every guard the importer trips.

A vendor feed that misbehaves almost always leaves a precise trail: a tally grid on the feed row, an error line on the feed, and — when individual rows were rejected — a downloadable failure report. This article maps what you see to what the importer actually did, and what to change.

Where to look first

Work these three places in order. Most questions are answered by the first one.

  1. The feed row — go to Purchasing → Vendors, open the vendor, and use the Integration tab, then the Products or Inventory section. Each feed shows a badge (Product Catalog / Inventory, Upload / SFTP), the last run’s tallies, and — if the last cycle failed — a red Error: line. The message is truncated at 90 characters on screen; hover it to read the whole thing.
  2. The run’s detail page — an inventory feed’s last run links straight to it with View run details →. It shows rows processed, successful, errors, start/finish/duration, and the Download report button when rows were rejected. A catalog run creates the same kind of job, but the feed row spends its link on the review queue instead — find the catalog run under Import → Recent Imports.
  3. The catalog review queue — for a Product Catalog feed, Review N to review → on the feed row opens Catalog review, where everything the run decided is waiting. Nothing there has touched your catalog yet.

ℹ️ Note: A vendor can hold several feeds at once — an item-master product feed, an enrichment feed, and one or more inventory feeds. Each has its own schedule, its own configuration and its own last-run tallies, so always read the tallies on the specific feed row you are diagnosing rather than the vendor as a whole.

📷 Screenshot: A Product Catalog feed row on the Integration tab showing the “Last run” badge, “N rows read”, the “Review N to review →” button, and the stat grid tiles (matched / created / need review / flagged / not carried / filtered out / vendor categories / filtered out / failed). (placeholder — replace with /docs-images/vendors/vendor-troubleshooting-feed-row-run-summary.png)

Reading the run tallies

The tiles are not interchangeable. Each one means a specific decision. They appear in the order below, and a tile whose value is zero is hidden — except matched, the create tile and need review, which are always shown so you can see a genuine zero.

Product Catalog feeds

Tile Hint on screen What it counts
matched linked to products you already have Rows whose vendor part number is already aliased to one of your products. Their cost and availability were refreshed in place, and any content this feed carries was applied to the product
created / would create new products from this vendor Products actually minted by this run. On a normal staged catalog run this is 0 — creating happens later, from the review queue. On a dry run the label changes to would create and the number is the forecast
need review new products or ambiguous matches — your call Rows staged with a needs a decision status: genuine ambiguities (two of your products share the identifier), new products staged for approval, and the “this product is already aliased under a different vendor part number” case
flagged held — a suspect brand, your call New products held by the brand gate, in Flagged
not carried vendor stocks it, you don’t No match, and “Create products for vendor items that don’t match anything” is off. Informational — not a worklist
filtered out excluded by your import rules Rows excluded by the Which items to import rules, or by a SKU/brand blacklist. Treated as if they were never in the file
vendor categories found in their hierarchy Distinct nodes discovered in the vendor’s category tree
filtered out excluded by your rules Rows the run made no decision about: unmatched rows that the New Products rules blocked from being created, plus rows whose vendor part number a person has already decided on in an earlier run
failed rows we could not read Rejected rows — these are the ones in the report

ℹ️ Note: Two tiles read filtered out, and they are different gates. The one hinted excluded by your import rules is the Which items to import filter — those rows are invisible to the entire import: not matched, no cost recorded, no category counted. The one hinted excluded by your rules is the create gate under New Products. A row only lands in that second tile if it matched nothing you carry; a row that did match is counted under matched (or staged for review) regardless of the create gate, because the gate only decides whether new products may be minted. That second tile also absorbs every part number a person has already approved or dismissed, so it grows on each re-run of a vendor whose queue you have been working — that growth is normal.

💡 Tip: On a live catalog run, a row this feed newly matched does not land in the matched tile. It is staged as a proposal, and it shows up in the Review N to review → count instead. A live run whose matched tile is large is telling you those rows were already linked from a previous run.

Inventory feeds

Tile Hint on screen What it counts
applied stock levels set Distinct (vendor part number, location) pairs written — not rows
unknown SKU no catalog link yet Rows whose part number has no link to any of your products
failed rows we could not read Rejected rows — these are in the report

⚠️ Warning: applied counts pairs, not lines. Vendors commonly ship the same item twice in one snapshot — one real drop contained 13,087 duplicated articles. The second copy is skipped, so applied will be lower than rows read, and that is correct, not lost data.

Symptom, cause, fix

Symptom Cause Fix
Run finished, nothing changed in the catalog A Product Catalog feed stages its decisions; it never writes products on its own Open Catalog review, approve, then Apply or Create
Dry run finished, nothing changed A dry run computes the whole outcome and writes nothing, by design Use Run now (inventory) or Run feed / Run again (catalog)
“Run finished” but zero rows read The vendor has not dropped a new file, or the same file was already ingested See The feed ran but nothing was imported below
Feed enabled, still nothing hours later A feed that has never run is not treated as overdue; enabling only starts the clock Use Run now / Run feed once, or wait one poll interval
Enable toggle is greyed out and says “Analyze first” / “Dry run first” A feed cannot be enabled until one run has produced a summary Run the feed once; the toggle unlocks
A run is already queued for this feed (409) A previous request is still waiting for the worker to claim it Wait for the queued run to be picked up, then request again
Enable the feed before running it for real. A live run was requested on a disabled feed that can write Enable the feed, or use a dry run
This feed has no connection assigned An SFTP feed with no endpoint attached Attach it under Connections on the Integration tab
feed has no connection — assign one on the vendor page Same, seen from the worker side Same fix
feed's connection no longer exists The connection was deleted while the feed still points at it Re-create the connection and re-attach the feed
connection is disabled The vendor connection is switched off Re-enable it
transport "…" has no delivery path yet The connection is not SFTP Only SFTP endpoints are polled today
host … is a private or internal address The hostname resolves to a private/internal address and is refused Use the vendor’s public hostname
list /dir: … The directory does not exist, or the account cannot read it Check the Directory value and the account’s permissions
bad filename pattern "…" The Filename Pattern is not a valid glob Fix the pattern, or clear it to take every file
download …: transfer failed after the file opened The connection broke mid-transfer — not a missing file Retry; if it repeats, the vendor endpoint is dropping large transfers
file … is no longer on the vendor server The vendor archived or deleted the file after pickup Set an Archive Directory — see below
skipped: a job for this feed is still running One job per feed at a time. Other feeds on the same vendor are unaffected Let the running job finish
rerun: nothing has been ingested yet and no new file is waiting A live “Run now” found no new file and nothing has ever been ingested Wait for the vendor’s first drop, or upload a file for an upload feed
no vendor_products aliases exist for this vendor The inventory feed ran before a product feed linked anything Run and apply the product feed first
refusing to zero unlisted stock A full-snapshot inventory file matched under half the known items See Refusing to zero unlisted stock below
feed has no column "X" (have: …) The Vendor Part-Number Column does not exist in the file Re-read the columns and pick from the real header
no quantity column mapped (expected a mapping to 'quantity') No column mapped to Quantity On Hand Add the mapping in Column Mapping
vendor feeds require a header row First row is a header is unchecked Turn it on; every vendor feed needs a header row
vendor_inventory job requires options.location_mapping No vendor warehouse code was mapped to one of your locations Add at least one mapping under Locations
no location mapping for vendor DC code "…" (per row) The file contains a warehouse code you have not mapped Map that code, exactly as it appears in the file
feed has no location column and location_mapping is not a single entry No Location Code Column and more than one mapping Either name the column, or keep exactly one mapping
Every row “failed” with a column-count error Wrong Delimiter, or Expected Columns no longer matches the vendor’s file Fix the delimiter; clear or correct Expected Columns
Products created with a junk brand The vendor’s brand column is not the real brand Configure Brand source rules, then Re-title products
Created products have no category No category columns mapped, or the vendor node was not mapped before creation Map category columns and the tree before creating products
Created products have no specs/attributes No column mapped to Attribute blob (Key: value) Map it, re-run the feed, then create
A proposal shows a “no content” chip The row is not in the vendor’s current file, or your filter excludes it Applying links vendor and routing only — no description, image, or category
create_failed on rows in the Rejected tab The create job hit the same error three times and stopped retrying Open the run’s failure report for the underlying reason
Stock applied, but the storefront still shows nothing sellable The product is neither drop ship nor drop-ship fallback Set Fulfillment on the product feed to Fallback or Always drop ship

The feed ran but nothing was imported

This is the most common report, and it usually is not a fault. Work down the list.

  1. It was a dry run. A dry run reads the newest matching file, computes the complete outcome — matched, would-create, ambiguous, failed — and writes nothing at all. The feed row labels it Dry run and says so: Dry run — nothing was written. Use Run feed to apply it.
  2. It was a normal Product Catalog run. A Product Catalog feed stages every decision as a proposal. That is the entire run: no products, no aliases, no prices. The catalog changes only when you approve and then use Apply … matches to catalog or Create … new products on the review page. This is why the created tile reads 0 on a healthy live run.
  3. The vendor has not dropped a new file. The runner records every filename it has ingested for a feed and skips those. If nothing new is on the server, an ordinary scheduled cycle correctly does nothing.
  4. The file is byte-for-byte identical to one already ingested. Vendors re-drop unchanged full files. The runner hashes every download and, if that exact content already reached storage for this feed, marks it a duplicate and stops. Nothing is imported because nothing changed.
  5. The feed has never run and was only just enabled. Enabling arms the schedule; it does not import immediately. The first scheduled check lands one poll interval later. The toast says so: Feed enabled — first check in <interval>. Use Run now to start sooner.
  6. The feed is off. A disabled feed never runs on schedule, however overdue it looks. It runs only when you ask for it explicitly.
  7. Your import filter excludes everything. Every rule under Which items to import must pass, and a rule naming a column the file does not have excludes every row — deliberately, so a typo shows up as an empty import rather than quietly importing what you meant to exclude. Check the filtered out tile hinted excluded by your import rules. The New Products rules fail closed the same way: name a column the file lacks and no new product can ever be created.

💡 Tip: An explicit live Run now that finds nothing new does not silently do nothing — it re-reads the last file it ingested. That is what makes a config change (column mappings, category columns, brand rules, update policy) reach the existing queue without waiting for tomorrow’s file.

📷 Screenshot: The feed row’s “⋯” menu open, showing Run again, Fresh re-analyze, Edit feed, Category mapping, Re-title products and Delete feed. (placeholder — replace with /docs-images/vendors/vendor-troubleshooting-feed-row-actions-menu.png)

“No vendor_products aliases exist for this vendor”

The full message is:

no vendor_products aliases exist for this vendor — run the catalog feed first

An inventory feed resolves each row by the vendor’s own part number against the vendor products that a product feed created. It never guesses, never fuzzy-matches, and never creates a product. With no links at all there is nothing the file can be applied to, so the job stops before writing anything rather than running to completion and reporting 70,000 unknown SKUs.

Fix: run this vendor’s Product Catalog feed, work the review queue, and apply. Once your products carry this vendor’s part numbers, re-run the inventory feed.

ℹ️ Note: The inventory job also stops up front — writing nothing — when it has no vendor id, no Vendor Part-Number Column, or no Locations mapping. These are configuration errors, not data errors, and they are reported on the feed row, not in the row report.

Rows counted as “unknown SKU”

A row counts as unknown when its vendor part number does not match any vendor_sku recorded for this vendor. Matching is exact, after trimming spaces, and is case-insensitive.

A large unknown count is normal. Distributors ship their whole catalog; you carry a subset. A dealer with 3,000 linked items receiving a 70,000-line snapshot will see roughly 67,000 unknown. These are counted, not failed, precisely so a healthy run does not look broken and so the report does not fill with 65,000 rows every night.

It is a real problem when the count is near 100%. Then check, in order:

  1. The wrong column is set as the Vendor Part-Number Column. The product feed and the inventory feed must key on the same vendor identifier. If the product feed aliased on the vendor’s article number and the inventory feed reads their UPC column, nothing will ever match.
  2. The product feed staged but was never applied. Proposals in To approve or Needs a decision have created no vendor products yet. Only applying (or creating) writes them.
  3. The vendor renumbered their parts. Their new numbers are not the ones you aliased. Re-run the product feed so the new numbers are staged, then apply.
  4. The file’s part-number column shifted. A vendor adding a column silently changes positions if you mapped by position elsewhere; re-read the columns and re-check the mapping.

Refusing to zero unlisted stock

When Full snapshot is on, anything the vendor stops listing is treated as out of stock at the vendor and zeroed. That is correct — silently keeping stale availability oversells. But it is only correct if the file was actually readable.

Before zeroing, the importer checks how much of your known catalog the file matched. If it matched fewer than half, it refuses and fails the run:

refusing to zero unlisted stock: the feed matched only 41 of 3,120 known items (1%) —
expected the vendor's full catalog, so this file looks wrong (column count, delimiter,
or a truncated download) [70532 rows failed]

A snapshot you could not read is not a snapshot saying everything is gone.

Common causes: the vendor changed the delimiter or added a column; the download was truncated; an HTML error page was staged instead of the data file; the part-number column moved; Expected Columns no longer matches.

What already happened: rows that applied before the refusal are written and stand. The zeroing sweep did not run, so no product was taken out of stock. Nothing was over-corrected.

⚠️ Warning: When a vendor job fails, its file is put back into the pending state and re-driven on the next cycle. If the underlying config is still wrong, it will fail again on each cycle. Fix the feed’s configuration (or turn Full snapshot off while you investigate) rather than waiting it out.

The file is no longer on the vendor server

file ACE_ARTICLE_20260814.txt is no longer on the vendor server

Some vendors move a file out of the pickup directory the moment it is collected. If a run then tries to re-read that exact file, it is gone.

Fix: set Archive Directory in the feed’s SFTP settings. The runner checks the pickup directory first and the archive directory as a fallback, both when listing new files and when re-reading a named one — so a missed poll recovers the file instead of losing the drop.

A related message means something different:

no file matching "*.TXT" to examine

That is not an archived file — nothing in either directory matched the Filename Pattern. Check the pattern (it is a glob against the base filename) or clear it to accept every file in the directory.

Duplicate rows, and why applied is lower than rows read

Within one snapshot, the first row for a given (part number, location) wins. A later row repeating that pair is skipped and counted as a duplicate, because a repeated pair either says the same thing (a wasted write) or contradicts itself (a decision not worth making silently).

Two consequences worth knowing:

  • applied < rows read on any vendor that duplicates lines. Nothing was doubled — stock writes are absolute sets, not increments.
  • Location matters. Duplicate detection is per part number and location, so an item still listed for one distribution centre but dropped from another correctly keeps the first and zeroes the second.

Negative quantities are clamped to zero rather than treated as unlisted, so a vendor quirk does not sweep an item into the zeroing pass.

Failed rows and the failure report

Failed rows are the ones the importer could not read or could not write. When there are any, the run’s detail page shows Some rows didn’t import with a Download report button. The report is a CSV with three columns:

row,vendor_sku,error_reason
45,SX50353,"bad quantity ""N/A"""
1902,,"expected 24 columns, got 23"
7734,QC2500,"real (non-derived) inventory row exists at this location — refusing to project vendor stock onto it"

📷 Screenshot: The run detail page showing the amber “Some rows didn’t import” panel with the Download report button, above the success/error counters. (placeholder — replace with /docs-images/vendors/vendor-troubleshooting-run-detail-failure-report.png)

How many rows the report lists depends on which job produced it:

Job Rows listed Behaviour past the limit
Inventory feed run Up to 5,000 Extra failures are still counted, and the run summary carries a failures not listed number so the count is never quietly wrong
Product Catalog feed run No limit Every rejected row is listed. A pathological run — wrong delimiter, wrong column count — produces a very large report
Create job (from the review queue) Up to 500 The error count stays complete; only the listed reasons stop at 500. Beyond that, use the job’s error log

Row-level reasons you will see

Reason Meaning
parse: … The line itself is malformed. One torn line does not stop the run
expected N columns, got M Expected Columns is set and this row does not match
empty vendor SKU The part-number column is blank on this row
bad quantity "…" The quantity is not a whole number
no location mapping for vendor DC code "…" The file names a warehouse you have not mapped
alias points at unknown product … The vendor product points at a product that no longer exists
a kit's derived inventory row exists at this location A bundle’s computed availability sits here. Vendor stock will not overwrite it
real (non-derived) inventory row exists at this location You hold real stock at this location for this product. Vendor stock is never projected on top of your own
write batch: … A batch of writes failed. Those rows did not apply; the rest of the run continued

The last two are refusals, not bugs. They happen when a vendor’s distribution centre is mapped onto a location where you keep your own stock, or onto a location holding a kit. Fix: map that vendor warehouse to a dedicated location that represents the vendor, not one of your own stocking locations.

Wrong brand on created products

The brand a created product carries is resolved from the feed’s Brand source rules, in order, taking the first value that survives the reject rules. With no rules configured, the vendor’s mapped brand column is used as-is.

This matters because some distributors’ brand column is a junk drawer — a code, a 0, or a label — with the real manufacturer buried inside an attribute blob (Product Type: Peg Hook *Brand Name: Rust Oleum *Color: Black). Brand source rules exist to read the attribute first and fall back to the column.

The same resolved brand is used for matching (manufacturer part number + brand), for the {brand} token in the title, and for the brand stamped on the product — so all three always agree.

The brand gate and the Flagged tab

A new product is only auto-creatable if its resolved brand is trustworthy. Three cases are held instead of created, and land in the Flagged tab with a chip saying why:

Chip Held because
No brand found No rule produced a brand
Brand is just a number The value is all digits
Brand looks like a set/season, not a maker It starts with a four-digit year, e.g. “2025 Topps” or “2024/25 Panini Select”

Approve a flagged row to create it, or reject it. Flagged rows are never created silently, and a re-import promotes a proposal to flagged if the current run judges its brand suspect — so re-running cannot quietly mint the junk the gate exists to hold.

📷 Screenshot: The Catalog review page on the Flagged tab, showing rows with the ⚑ chip and the whole-tab “Approve all / Reject all” buttons. (placeholder — replace with /docs-images/vendors/vendor-troubleshooting-catalog-review-flagged.png)

Fixing brands after the fact

  1. Set the rules — open the feed, add Brand source rules (read the attribute first, fall back to the column), and use Also reject these exact values plus the numeric reject for known junk values.
  2. Add a brand blacklist if a “brand” is really a set name. Blacklisted brands are excluded from the import entirely, and a proposal approved before the blacklist existed will still be skipped at create time. An open proposal for a now-excluded row is closed into Rejected with the reason shown, so it cannot sit in the queue looking appliable.
  3. Re-run the feed — open proposals are refreshed in place with the vendor’s current data and the current rules. Rows a person already decided are never overwritten.
  4. Re-title products (in the feed row’s “⋯” menu) for products already created. When the feed carries brand rules, this re-derives both the title and the brand, repointing or clearing a junk brand. It only touches products this vendor created, only where the value actually changes, and never a title you have locked on the product.

See Brands for how brands are stored and merged.

Products created without categories

Category mapping is deliberately two steps, and skipping the first is the usual cause.

  1. The feed must name the vendor’s category columns — under Categories in the feed setup, broadest level first, each level as a code column plus an optional name column. A level whose code column is missing from the file stops the walk there, rather than building a tree with a hole in it.
  2. You must map their tree to yours — Category mapping in the feed row’s “⋯” menu. A run brings the vendor’s whole hierarchy in so you can map it; it never files anything into your catalog on its own.

Filing walks up the vendor’s tree: a group nobody mapped still files under whatever its class or department was mapped to. If no ancestor is mapped, the product is created unfiled.

⚠️ Warning: Filing happens at creation time. Products created before you mapped a node stay unfiled — mapping it later does not go back and file them. Map the tree first, then create. Anything already created has to be categorised from the catalog.

Use Suggest matches on the Category mapping page to pre-fill likely targets, Skip to mark a vendor group as not imported, and the Unmapped only filter to see what is left. See Vendor Categories and Categories.

Products created without attributes

Vendor specs arrive as one delimited blob (Key: value *Key: value). They become product attributes only when the feed maps that column to Attribute blob (Key: value) in Column Mapping. Mapped anywhere else — or not at all — you get no attributes.

Two ordering traps:

  • A proposal staged before the column was mapped does not carry the blob. Creating from that proposal produces a product with no attributes. Re-run the feed first: it refreshes open proposals with the vendor’s current data, including the blob.
  • Attribute writing is deliberately non-fatal. If a batch fails, the run logs it and keeps going rather than failing products that were minted correctly. Those products are aliased, so the next product feed run enriches them through the normal matched path.

The run summary for a create job reports how many attribute values were written, which is the only place that number is shown.

See Attributes.

When the file itself will not parse

Setting What goes wrong What to check
Delimiter Every row fails, or everything lands in one column Comma, pipe, tab or semicolon — vendors ship all four, and sometimes different ones per file
First row is a header vendor feeds require a header row Vendor feeds always need one. See the note below if the vendor puts banner rows above the header
Expected Columns Mass expected N columns, got M The vendor added or removed a column. Update the number, or clear it
Vendor Part-Number Column feed has no column "X" (have: …) The error lists the real headers — pick from those

ℹ️ Note: For a spreadsheet upload feed, the file’s header does not have to be the first row: the upload wizard asks Header is on row, and anything above it (title or banner rows) is skipped. SFTP feeds have no equivalent control in the dashboard — the importer can be told to skip leading rows, but that value is not exposed in the feed setup form. If a vendor’s SFTP drop has banner rows above the header, ask the vendor to drop a headered file, or contact ILLUMA support to have the skip configured for you.

Stray quotes are tolerated: descriptions containing bare inch marks (6" clamp) will not abort the file. A byte-order mark on the first header is stripped automatically.

For an upload feed, the file is read at upload time and the errors are immediate: the uploaded file is empty, larger than 60MB, Could not read column headers from “…”. Check the header row setting., or No data rows found in “…” below the header.

💡 Tip: For an SFTP feed, use Read columns from the vendor in the feed editor before saving. It opens the newest matching file and shows the real headers with a sample value from the first row — which is faster than diagnosing a mapping from a failed run.

Stock applied but nothing is sellable

An inventory run can report thousands of rows applied while the storefront shows nothing available. This is a fulfillment setting, not a feed failure.

Vendor stock is the vendor’s inventory. It is recorded against the vendor product and projected as availability at the mapped location only for products that can actually be fulfilled from that vendor — products flagged drop ship, or drop-ship fallback. For any other product, the projection is not written (and any stale one is cleared), because showing an item in stock with no way to route the order is worse than showing it out of stock.

Fix: on the product feed, set Fulfillment:

Option Effect
Fallback — drop ship when local stock hits zero Your own shelf first, then the vendor. The usual choice
Always drop ship — the vendor fulfills every order For lines you never hold
Leave alone — don’t touch the product’s drop ship settings Records cost and part number only. This vendor’s stock will not make anything sellable

Vendor stock never passes through inventory adjustments, the ledger, FIFO layers, or bins — it is availability, not owned stock. See Fulfillment Overview and Integrations & Locations.

SKU minting errors on created products

New products get a SKU from the source chosen in SKU for new products. If the vendor’s value is blank, or already belongs to another product, the number series is used instead — a duplicate SKU does not produce a messy catalog, it produces orders against the wrong product.

Message Fix
no active "PROD" number series for org … — configure it under Settings → Number Series Create and activate the PROD series
PROD number series … kept producing in-use SKUs; move its starting_no past the dealer's highest SKU Raise the series’ starting number above your highest existing SKU
could not claim a PROD number … after 5 attempts (series contention) Two jobs were claiming numbers at once. Re-run
number series value "…" has no trailing number to increment The series’ last-used value ends in no digits. Correct the format

Re-analyzing from scratch

Run again refreshes what is already staged: open proposals are updated with the vendor’s current data, and decisions a person has made are never touched.

Fresh re-analyze clears the pending queue first — To approve, Needs a decision and Flagged — and rebuilds it from the vendor’s current file. Products you have already created and matched are left alone; nothing is written to your catalog. Use it after a substantial config change (new brand rules, a new filter, a different match strategy) when the existing queue was built under the old settings.

ℹ️ Note: Re-analyzing does not need the vendor to drop a new file. If nothing is currently re-drivable, the newest already-processed file is put back so the same bytes can be read again with your new settings.

⚠️ Warning: Both actions are per feed. Re-analyzing one of a vendor’s feeds does not re-run its other feeds, and the review queue is shared across the vendor — so a Fresh re-analyze on one product feed clears pending rows that another feed may have staged.

Next

Once the feed is clean, work the queue in Review Queue, then map the vendor’s tree in Vendor Categories. For the feeds themselves, see Product Feeds, Inventory Feeds, Enrichment Feeds and Spreadsheet Uploads. For the products, see Products and Bulk Import.

← PreviousSending Purchase Orders