Skip to main content

Go live with existing stock

Core module For: Administrator, Compliance manager Checked on 18.0.0.2.0

Load your products, trading partners and licenses in bulk, then bring the prescription stock already on your shelves into the package ledger, so every unit can be shipped, counted and traced like a received unit. Then prove the whole chain once, from sale to document.

Load products, trading partners and licenses from a spreadsheet​

When you start with many products, customers, suppliers and licenses, import them from spreadsheet files instead of entering each one: the products, then the trading partners, then their licenses, then verify each license. The import can't verify a license: your procedure decides how each license is checked at its source, and the software counts a license only after a manager marks it verified with that source (see Record and verify a trading partner's license).

Who: Administrator (Administration: Settings) with Inventory Administrator and Rx Tracking Manager, as the administrator is after installation. Some columns need an Rx Tracking right besides the right to create the records:

ColumnsRx Tracking right needed
DSCSA Product (products)Manager
DSCSA Role, Small Business Dispenser, Small Dispenser Attested On (partners)User or Manager
every license columnManager (a User can only read licenses)
Verified By, Verified On (licenses)none: they can't be imported, only set by Mark verified (part 4)

Requires: Rx Tracking (DSCSA) and the Contacts app. Works in Odoo Community and Enterprise.

Before you start:

  • Items 1 to 5 of the first-configuration checklist are done: access, company GLN (Global Location Number) and address, settings, your own licenses. See The first 30 minutes: configure Rx Tracking.
  • Your data is in three spreadsheet files (.xlsx or .csv), one per kind of record, with the column names below in the first row. Odoo matches each column to the field of the same name.
  • Products you already have in stock: import them without the DSCSA Product column, then flag them as in Go live with stock and records you already have.
  • You have checked each partner's license at its source and kept the proof.

The example files below are fictitious: two products, a pharmacy, a wholesaler and their state licenses.

Known issue

Known issue (PF-A01-05): the import accepts a DSCSA product whose Use Expiration Date is False or missing, although the product form selects Expiration Date for every DSCSA product. Keep the column at True, and check the products after the import (part 1, step 6).

Known issue (PF-A01-04): the import accepts a state license without a Jurisdiction, which the license form requires, and the license authorizes the partner once verified. Fill in Jurisdiction on every state license, and check the list after the import (part 5, step 2).

Part 1: import the products​

A DSCSA product must be tracked in inventory and by lots, so the file needs these columns. NDC is the National Drug Code as printed on the package; the GTIN (Global Trade Item Number) is computed from it:

Name,Internal Reference,Product Type,Track Inventory,Tracking,Use Expiration Date,DSCSA Product,NDC
"Exampletide 5 mg Tablets, 30 count",DEMO-EXT-05,Goods,True,By Lots,True,True,99990-110-30
"Mocklofen 200 mg Capsules, 60 count",DEMO-MKF-200,Goods,True,By Lots,True,True,99990-111-60

Optional columns: Manufacturer, Strength, Dosage Form, Container Size, and GS1 Company Prefix Length with a GTIN you enter yourself. Set up a DSCSA product explains each field.

  1. Go to Inventory ‣ Products ‣ Products.

  2. Select the ⚙ (Actions) menu next to Products, then Import records.

    Result: the import screen says "Drop or upload a file to import" and has the Upload Data File button.

  3. Select Upload Data File and choose the products file.

    Result: each File Column is listed with the Odoo Field it goes to, for example DSCSA Product to DSCSA Product. A column shown with "To import, select a field..." has no field and isn't imported.

  4. Select Test.

    Result: "Everything seems valid." Otherwise the errors are listed ("The file contains blocking errors (see below)"): correct the file, select Load Data File to choose it again, and select Test again.

  5. Select Import.

    Result: a notification says "2 records successfully imported", and the Products list opens.

  6. Open the search options (the ▾ at the right of the search bar), select DSCSA Products, then open each imported product.

    Result: on the DSCSA tab, DSCSA Product is selected and GTIN shows the GTIN of the NDC (for example 00399990110302); on the Inventory tab, Expiration Date is selected. Where it's cleared (PF-A01-05), select it and save.

Part 2: import the trading partners​

Each partner is a company with its DSCSA role, its GLN and a full address: the address is printed in your EPCIS (Electronic Product Code Information Services) files. State is the state's name; DSCSA Role is one of Manufacturer, Repackager, Wholesale distributor, Third-party logistics provider (3PL) or Dispenser:

Name,Is a Company,Street,City,State,Zip,Country,DSCSA Role,GLN
Harbor View Pharmacy,True,12 Harbor Street,Monterey,California,93940,United States,Dispenser,0614141003013
Northgate Wholesale Drug Inc.,True,500 Industrial Way,Reno,Nevada,89502,United States,Wholesale distributor,0614141003020
  1. Go to Contacts, select the ⚙ (Actions) menu next to Contacts, then Import records.

  2. Select Upload Data File and choose the partners file.

  3. Select Test, then Import.

    Result: "2 records successfully imported". Each partner's DSCSA tab shows its DSCSA Role; the partner isn't an authorized trading partner yet, because it has no license.

A small-business dispenser also needs Small Business Dispenser and Small Dispenser Attested On: see Flag a small-dispenser customer.

Part 3: import the licenses​

Put each license on the partner's company, not on one of its contacts or addresses. Type is one of State license, FDA establishment registration, FDA 503(e) annual report, DEA registration or Other; Jurisdiction is the issuing state's name, required for a state license (PF-A01-04); dates are YYYY-MM-DD:

Trading Partner,Type,Number,Jurisdiction,Issue Date,Expiry Date,Verification Source
Harbor View Pharmacy,State license,DEMO-CA-PHY-71204,California,2025-01-15,2027-12-31,"California Board of Pharmacy license look-up, checked 09/28/2026"
Northgate Wholesale Drug Inc.,State license,DEMO-NV-WHL-30551,Nevada,2025-03-01,2027-06-30,"Nevada Board of Pharmacy license look-up, checked 09/28/2026"
  1. Go to Inventory ‣ Rx Tracking ‣ Licenses, select the ⚙ (Actions) menu next to Licenses, then Import records.

  2. Select Upload Data File and choose the licenses file.

  3. Select Test, then Import.

    Result: "2 records successfully imported". The Licenses list shows each new license with its Jurisdiction (for example California (US)) and the status Unverified.

Part 4: verify each license​

  1. In Inventory ‣ Rx Tracking ‣ Licenses, open the search options and select Unverified.

  2. Open the first license, check it against its Verification Source, attach your proof under Evidence (MD-08 step 5) and select the save icon.

  3. Select Mark verified.

    Result: the status is Valid, and the chatter logs "License verified by YOUR-NAME on DATE. Source: …".

  4. Select the next-record arrow (Next) at the top right, and repeat steps 2 and 3 for each license.

Part 5: check the result​

  1. Go to Contacts, open the search options and select Authorized Trading Partners.

    Result: the imported partners are listed once their license is Valid, for example Harbor View Pharmacy and Northgate Wholesale Drug Inc.

  2. In Inventory ‣ Rx Tracking ‣ Licenses, check that every State license has a Jurisdiction.

Result: the products, trading partners and licenses are in Odoo, and each partner with a verified license is an authorized trading partner. Records: the products (with DSCSA Product, NDC and GTIN), the partners (with their role, GLN and address), and the licenses, each with its verification in its chatter.

If it doesn't work

Next: Go live with stock and records you already have

Go live with stock and records you already have​

Register the units you already hold when you start with Rx Tracking: stock that isn't in Odoo yet (it comes from another system or from a physical count), and stock that is in Odoo but was received before the product was a DSCSA product. The order is fixed: quantities first, then the DSCSA Product flag, then one scan per unit.

Background: the modules track every unit by its own serial number in a package ledger, so units that entered stock before the ledger existed need their serials recorded once. See Packages and the serial ledger.

Which path?

Your situationWhat to do
Your own units, not in Odoo yet, or in Odoo for a product that isn't a DSCSA product yetthis procedure, parts 1 to 6
Your own units, but the product is already a DSCSA product and its stock wasn't enteredthe count fallback in the known issues before part 1
Units you hold for another company as a 3PL (owner stock)Go live as a 3PL: the setup order, and owner stock you already hold
Units that arrive after go-livea normal receipt: Import the supplier's EPCIS file on the receipt
Orders open at cut-overreceive what is on the dock and ship what can ship before you select DSCSA Product (part 4): transfers made Done before it have no DSCSA records; those made Done after it follow the DSCSA checks
Records from a previous track-and-trace systemkept outside Odoo: they can't be imported as DSCSA documents. Your procedure decides where and how they are kept

Who: Administrator (Administration: Settings) with Inventory Administrator and Rx Tracking Manager, as the administrator is after installation. Parts 1 to 4 change products and stock (Inventory Administrator); parts 5 and 6 need Rx Tracking Manager, so a compliance manager can do them.

Requires: Rx Tracking (DSCSA). Works in Odoo Community and Enterprise.

Before you start:

  • Items 1 to 5 and 7 to 9 of the first-configuration checklist are done: access, company GLN, address and settings, your licenses, trading partners, scanner. See The first 30 minutes: configure Rx Tracking.
  • You know, per product, the quantity of each lot at each location, and each lot's expiration date as printed on the units.
  • Every unit carries a serialized DataMatrix (the 2D barcode with GTIN, serial, expiry and lot). Units without one can't be registered.
  • Nobody ships or receives the product while you do parts 2 to 5.

The example below is a product entered for go-live, Placebrin 10 mg Tablets, 100 count (DEMO-PLB-10, NDC 99990-104-01), with three bottles of lot BPPLB2507A, expiry 12/31/2027.

Known issue

Known issue (PF-A04-02): the opening balance never creates stock. If a product was made a DSCSA product before its quantities were entered, Units Without Package stays 0 (or the lot doesn't exist yet) and every scan is refused. Enter those units with a count instead: on the Physical Inventory line, Apply asks for each unit's serial and registers the packages with Origin Found in Inventory Count, not Opening Balance. Check the lot's expiration date first (part 3). See Record units found in a count.

Known issue (PF-W29-01): when the product has Expiration Date selected on its Inventory tab, Odoo gives a lot created in part 2 the moment it was created as its expiry. Part 5 then refuses every scan with "Line N: Serial …: the scan says expiry … but lot … expires …", the second date being the day the lot was created, and a count refuses them the same way. Correct the lot as in part 3 before you scan.

Known issue (PF-V02b-01): that refusal gives the lot's date in UTC: in a US evening it names tomorrow's date, while the lot's Dates tab shows today's.

Part 1: make the product lot-tracked​

Skip this part if the product is already tracked by lots.

  1. Go to Inventory ‣ Products ‣ Products and open the product, or select New and enter its name.

  2. On the General Information tab, select Track Inventory and choose By Lots.

  3. Select the save icon. Leave the DSCSA tab alone for now: DSCSA Product stays cleared until part 4.

    Result: the product is saved, tracked by lots, and not a DSCSA product yet.

Part 2: enter the quantities​

  1. Go to Inventory ‣ Operations ‣ Physical Inventory and select New.

    Result: a new, editable line appears at the bottom of the list.

  2. On the new line, fill in:

    • Product: the product, for example [DEMO-PLB-10] Placebrin 10 mg Tablets, 100 count
    • Location, if the column is shown (with several locations): where the units are
    • Lot/Serial Number: type the lot number, for example BPPLB2507A, and select Create "BPPLB2507A" if it doesn't exist yet
    • Counted Quantity: the number of units, for example 3
  3. Select Save.

    Result: the line shows On Hand Quantity 0.00, Counted Quantity 3.00, a Difference of 3.00 and an Apply button.

  4. Select Apply on the line.

    Result: the line's On Hand Quantity is 3.00. No serials are asked for, because the product isn't a DSCSA product yet.

  5. Repeat steps 1 to 4 for each lot and location of the product.

Part 3: check each lot's expiration date​

If the lot form has no Dates tab, the product doesn't use expiration dates yet: skip this part. Part 5 fills the lot's expiration date from the scans.

  1. Go to Inventory ‣ Products ‣ Lots / Serial Numbers, search for the lot, for example BPPLB2507A, and open it.

  2. Select the Dates tab and read Expiration Date.

  3. If it isn't the date printed on the units, enter that date, for example 12/31/2027 00:00:00, and select the save icon. An empty Expiration Date is fine: part 5 fills it from the scans.

    Result: the lot's Expiration Date is the one on the units' labels, or empty.

Part 4: make it a DSCSA product​

  1. Go to Inventory ‣ Products ‣ Products and open the product.

  2. Select the DSCSA tab, then select DSCSA Product.

    Result: NDC, GTIN and GS1 Company Prefix Length appear, and Expiration Date is selected on the Inventory tab.

  3. In NDC, enter the NDC as printed on the package, for example 99990-104-01, and fill in the Drug group.

    Result: GTIN shows 00399990104011.

  4. Select the save icon.

    Result: the product is a DSCSA product. From now on its orders are checked against the partners' licenses and its transfers ask for serials. For all the fields and messages, see Set up a DSCSA product.

Part 5: register the opening balance​

  1. Go to Inventory ‣ Rx Tracking ‣ Opening Balance.

  2. Choose the Product and the Lot, and change Location if the units aren't in your main stock location.

    Result: the counters show, for example, On Hand 3.00, Already Registered 0 and Units Without Package 3.

  3. Optional: in Reference, enter where the count comes from, for example Go-live count.

  4. In the scan box, scan the DataMatrix of each unit of the lot, one per line.

  5. Select Register.

    Result: a notification says, for example, "3 DSCSA package(s) of lot BPPLB2507A registered as opening balance.".

  6. Repeat steps 1 to 5 for each lot and location.

Every option and message of this dialog is in Register the opening balance for stock that predates the package ledger.

Part 6: check the ledger against the stock​

  1. Go to Inventory ‣ Rx Tracking ‣ Ledger vs Stock.

    Result: the list is empty and says "The package ledger matches the stock". A row still listed has units without a package (a negative Packages - On Hand) or packages without a unit: see Check the package ledger against the stock (Ledger vs Stock).

Result: every unit you hold has one package, In Stock, and can be sold, shipped, counted and scrapped. Records: the inventory adjustment moves of part 2 (Inventory ‣ Reporting ‣ Moves History); the lots with their expiration dates; the product's DSCSA Product flag and NDC, logged in its chatter; one package per unit with Origin Opening Balance, your reference, Registered At, Registered By and Registered On; and a note in each lot's chatter listing the registered serials.

Finish the go-live​

  1. Give your customers' contacts portal access to their documents, if you use the portal: Give a customer portal access to its DSCSA documents.
  2. If you use the off-site S3 archive: set it up, try it in test mode, then switch to compliance mode, prove it end to end on the real bucket, then queue the records posted before the archive was switched on. The queue's Queue Unarchived Records button fails (Known issue PF-W11-01): use the workaround on that page.
  3. Ask whoever runs your Odoo server to check two things before the first delivery, because each delivery's T3 PDF (transaction information, history and statement) is made once, when the delivery is Done, and never again:
    • the server has wkhtmltopdf 0.12.6 with patched Qt, as Odoo recommends for its PDF reports (with another build the PDF has no page-number footer; see Put the modules on the server);
    • Odoo's report address (the report.url system parameter, or web.base.url when it isn't set) is an address the server itself can reach. Otherwise the T3 is stored without its styles, in a plain font, for good (Known issue PF-W08-04, see The T3 report). System parameters are edited as in Tune the jobs through system parameters.
  4. Run the smoke test: Prove the whole chain once after go-live.

If it doesn't work

  • "Nothing was registered. Fix these scans and try again:" with "Line N: Serial …: the scan says expiry … but lot … expires …": the lot has another expiry in Odoo, often the day the lot was created (PF-W29-01). Correct it as in part 3. See Error: "Nothing was registered. Fix these scans and try again".
  • "Nothing was registered. Fix these scans and try again:" with "… has no lot … in stock.": the lot has no units at that location. The product was probably made a DSCSA product before its quantities were entered; see the known issue PF-A04-02 before part 1.
  • "… serial(s) scanned, but only … unit(s) of … have no package yet …": more scans than units without a package. Check the quantity of part 2 and the location. See Error: "… serial(s) scanned, but only … unit(s) … have no package yet".
  • In part 2, Apply opens a DSCSA Serials dialog asking for the serials: the product is already a DSCSA product. Select Cancel and see the known issue PF-A04-02 before part 1.
  • The product isn't offered in Opening Balance: part 4 wasn't saved. There is no Opening Balance menu item: you aren't an Rx Tracking Manager.
  • DSCSA Product is greyed out, or the product form can't be edited: you need Rx Tracking Manager and a product right such as Inventory Administrator. See Set up a DSCSA product.

Next: Prove the whole chain once after go-live

Prove the whole chain once after go-live​

Make one sale of a DSCSA product from start to finish, and use the records it creates once: the document, the integrity check, a trace request and a retention export. Each step that fails points to a setup gap, before your customers depend on it. Do it again after each module update.

Who: Rx Tracking Manager with a Sales right (the administrator, or a compliance manager who can also sell). A Sales user can make step 1 and a warehouse user (Rx Tracking User) steps 2 and 3.

Requires: Rx Tracking (DSCSA). Works in Odoo Community and Enterprise.

Before you start:

  • The go-live is done: Go live with stock and records you already have.
  • Your company has its GLN and full address, and a customer has a DSCSA role, a GLN, a full address and a verified license. One unit of a DSCSA product is in stock, and you can scan its DataMatrix.
  • Your procedure decides whether you run this with a real first order or on a copy of the database. In your working database, the delivery, its DSCSA document, the trace request and the export are permanent records. A copy must not write to your off-site archive: see Keep a staging or restored copy from writing to the archive.
  1. Create a quotation of one unit of the DSCSA product for the customer and select Confirm (Confirm a sales order for DSCSA products).

    Result: the quotation is a Sales Order, with no message.

  2. Open its delivery, select Scan Serials, scan the unit, select Register, then select Validate (Scan the serials of a delivery and validate it).

    Result: the delivery is Done and has a DSCSA Documents smart button.

  3. Select DSCSA Documents, then Download T3 and Download EPCIS (Open the DSCSA document a delivery posted).

    Result: the document (for example DSCSA/OUT/2026/00001) is Posted; your browser downloads its T3 PDF (T3-DSCSA-OUT-2026-00001.pdf) and its EPCIS file (EPCIS-DSCSA-OUT-2026-00001.xml).

  4. Go to Inventory ‣ Rx Tracking ‣ Verify Document Integrity (Verify the integrity of the DSCSA documents).

    Result: a notification "DSCSA document integrity" says, for example, "1 DSCSA documents verified: the hash chain and the stored files are intact."

  5. Log a trace request for the lot you shipped, select Search, then Respond and Ok, then Download Response (Log a trace request, search the records, respond with the response zip).

    Result: the search finds the document and the packages of the lot, the request is Responded, and your browser downloads the response zip.

  6. Go to Inventory ‣ Rx Tracking ‣ Retention Exports and select Export Now (Get the monthly retention export, or export on demand).

    Result: a new export, Kind On demand, with a package ledger file and a license register file.

  7. If the off-site archive is on, go to Inventory ‣ Rx Tracking ‣ S3 Archive Queue after the next run of the archive job (Watch the archive queue and each record's archive state).

    Result: the new document's and export's jobs are Done.

  8. Go to Inventory ‣ Rx Tracking ‣ Ledger vs Stock.

    Result: "The package ledger matches the stock".

Result: one of each record, all as expected. Records: the sales order and its delivery (Done); the outbound DSCSA document (Posted) with its T3 PDF and EPCIS file; the trace request (Responded) with its response zip; the on-demand retention export; with the archive on, its Done archive jobs. With the 3PL add-on, also receive and ship once for an owner: see Go live as a 3PL.

If it doesn't work