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:
| Columns | Rx Tracking right needed |
|---|---|
| DSCSA Product (products) | Manager |
| DSCSA Role, Small Business Dispenser, Small Dispenser Attested On (partners) | User or Manager |
| every license column | Manager (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 (
.xlsxor.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 (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.
-
Go to Inventory ‣ Products ‣ Products.
-
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.
-
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.
-
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.
-
Select Import.
Result: a notification says "2 records successfully imported", and the Products list opens.
-
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
-
Go to Contacts, select the ⚙ (Actions) menu next to Contacts, then Import records.
-
Select Upload Data File and choose the partners file.
-
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"
-
Go to Inventory ‣ Rx Tracking ‣ Licenses, select the ⚙ (Actions) menu next to Licenses, then Import records.
-
Select Upload Data File and choose the licenses file.
-
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
-
In Inventory ‣ Rx Tracking ‣ Licenses, open the search options and select Unverified.
-
Open the first license, check it against its Verification Source, attach your proof under Evidence (MD-08 step 5) and select the save icon.
-
Select Mark verified.
Result: the status is Valid, and the chatter logs "License verified by YOUR-NAME on DATE. Source: …".
-
Select the next-record arrow (Next) at the top right, and repeat steps 2 and 3 for each license.
Part 5: check the result
-
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.
-
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
- Test lists "… is a DSCSA product, so it must be tracked in inventory (Track Inventory) and tracked by lots.": add the Track
Inventory (
True) and Tracking (By Lots) columns. See Error: "… is a DSCSA product and must be tracked by lots …". - Test lists "Only DSCSA managers can change whether … is a DSCSA product: …": you aren't an Rx Tracking Manager. Ask one to import the file, or import it without the DSCSA Product column and have a manager flag the products. See Error: "Only DSCSA managers …".
- Test lists "Only DSCSA users can set or change the DSCSA role of …: …": you have no Rx Tracking right. See Error: "Only DSCSA users …".
- Test refuses an NDC, a GLN or a GTIN: see Error: "NDC '…' has 10 digits but no hyphens …", Error: "GLN '…' has an invalid check digit …" and Error: "The GTIN … of … is already used by …".
- Test refuses a license with "Record license … on the company …, not on its contact or address …": the Trading Partner column names a contact or an address. Use the company's name. See Error: "Record license … on the company …".
- Mark verified says "Enter where … was verified …": the row had no Verification Source. Enter it, then select Mark verified again. See Error: "Enter where … was verified …".
- The ⚙ (Actions) menu has no Import records: you can't create records in that list (for licenses, you aren't an Rx Tracking Manager).
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 situation | What to do |
|---|---|
| Your own units, not in Odoo yet, or in Odoo for a product that isn't a DSCSA product yet | this procedure, parts 1 to 6 |
| Your own units, but the product is already a DSCSA product and its stock wasn't entered | the 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-live | a normal receipt: Import the supplier's EPCIS file on the receipt |
| Orders open at cut-over | receive 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 system | kept 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 (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.
-
Go to Inventory ‣ Products ‣ Products and open the product, or select New and enter its name.
-
On the General Information tab, select Track Inventory and choose By Lots.
-
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
-
Go to Inventory ‣ Operations ‣ Physical Inventory and select New.
Result: a new, editable line appears at the bottom of the list.
-
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
- Product: the product, for example
-
Select Save.
Result: the line shows On Hand Quantity
0.00, Counted Quantity3.00, a Difference of3.00and an Apply button. -
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. -
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.
-
Go to Inventory ‣ Products ‣ Lots / Serial Numbers, search for the lot, for example
BPPLB2507A, and open it. -
Select the Dates tab and read Expiration Date.
-
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
-
Go to Inventory ‣ Products ‣ Products and open the product.
-
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.
-
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. -
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
-
Go to Inventory ‣ Rx Tracking ‣ Opening Balance.
-
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 Registered0and Units Without Package3. -
Optional: in Reference, enter where the count comes from, for example
Go-live count. -
In the scan box, scan the DataMatrix of each unit of the lot, one per line.
-
Select Register.
Result: a notification says, for example, "3 DSCSA package(s) of lot BPPLB2507A registered as opening balance.".
-
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
-
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
- Give your customers' contacts portal access to their documents, if you use the portal: Give a customer portal access to its DSCSA documents.
- 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.
- 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
wkhtmltopdf0.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.urlsystem parameter, orweb.base.urlwhen 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.
- the server has
- 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.
-
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.
-
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.
-
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). -
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."
-
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.
-
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.
-
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.
-
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
- Step 1 is refused with "… can't be confirmed: it contains DSCSA products …": the customer isn't an authorized trading partner; the message names the reason. See Error: "… can't be confirmed: it contains DSCSA products …".
- Step 1 or 2 warns that the document of this shipment has no EPCIS file: the company or the customer has no GLN. See Warning: "The DSCSA document of this shipment …".
- Step 2 refuses the scan with "Serial … is not in the package ledger …": that unit wasn't registered at go-live. See Error: "Serial … is not in the package ledger …".
- Step 3 has no Download EPCIS button, and the document shows "No EPCIS file was generated: sender.street is required." (or
sender.city,sender.state,sender.zip): your company's address is incomplete, and nothing warned before the delivery (Known issue PF-A03-01). Complete it as in Set the company GLN, GS1 prefix length and address before the next delivery; this document keeps its T3 only. Withreceiver.…, complete the customer's address (Onboard a trading partner). See Warning: "No EPCIS file was generated: …". - Step 3 has no Download EPCIS button, or the document is under the EPCIS Missing filter, for another reason: a GLN or the product's NDC was missing when the delivery became Done. See Handle a document posted without an EPCIS file.
- The T3 PDF looks plain, in a serif font without bold text: the report address wasn't reachable (Known issue PF-W08-04); fix it as in Finish the go-live step 3 before more deliveries become Done.
- Step 4 reports a broken chain or a changed file. See Verify the integrity of the DSCSA documents.
- The export of step 6 is named and dated for tomorrow: it uses the server's date (UTC), not yours (Known issue PF-W29-02).