By the end of this guide, you'll understand the full sequence of a QuickBooks-to-Odoo accounting migration: what to prepare, what gets moved, and where the real work happens. Prerequisites are access to your QuickBooks file (Desktop or Online) and an Odoo instance with the Accounting module enabled. Budget two to four weeks for the finance-side work, depending on the complexity of your chart of accounts and the volume of open transactions you're carrying.
Phase 1: Assess What You're Moving
Before touching Odoo, spend time inside QuickBooks documenting exactly what exists. Migrations that skip this step tend to surface surprises mid-setup, which is far more expensive than a careful audit upfront.
- Export your Chart of Accounts. In QuickBooks Online, go to Accounting → Chart of Accounts and use the Export button to download a CSV. In QuickBooks Desktop, go to Lists → Chart of Accounts and choose Excel → Export all Accounts. Note every account type (Asset, Liability, Equity, Income, Expense) and the account code convention you're using.
- Pull your open transactions report. Run a report of all open invoices (Accounts Receivable aging) and all unpaid bills (Accounts Payable aging) as of your chosen cutover date. These are the balances you'll re-enter in Odoo as opening entries. Write down the total for each.
- List your active vendors and customers. Export a customer list and a vendor list. QuickBooks Online: Reports → Contact List. Desktop: Lists → Customer:Job List or Vendor List, then export to Excel. Check for duplicates and missing contact details now, not after import.
- Document your tax codes. Note every sales tax rate, jurisdiction, and how it maps to your products or services. Odoo's tax setup is more granular than QuickBooks', so understanding your current structure saves configuration time later.
- Identify your bank and credit card accounts. Record each account, the bank name, and the closing balance at your cutover date. You'll use these to set up journal entries in Odoo.
At the end of Phase 1 you should have five spreadsheets: chart of accounts, open AR, open AP, contacts, and bank balances. That's your migration source of truth.
Phase 2: Configure Odoo's Chart of Accounts
Odoo ships with a localized chart of accounts template. For US companies this is based on the standard US GAAP structure. Your job is to adapt it to match what QuickBooks had, not build from scratch.
- Open the Chart of Accounts. Navigate to Accounting → Configuration → Chart of Accounts. You'll see Odoo's default accounts already in place.
- Match or remap account codes. Compare your QuickBooks export to the Odoo defaults. Where the purpose is identical (e.g., both have a "Sales Revenue" income account), update the Odoo account code and name to match your QuickBooks convention. This keeps your historical reports comparable.
- Create any missing accounts. Click New to add accounts that don't exist in the default template. Set the Type field carefully: Current Assets, Current Liabilities, Payable, Receivable, Income, Expense, etc. The type drives how transactions post and how financial statements display.
- Archive unused default accounts. Don't delete accounts Odoo ships with, they may be referenced by system taxes or journal entries. Instead, open the account and toggle Deprecated to hide it from dropdown lists going forward.
- Set default accounts on journals. Go to Accounting → Configuration → Journals. Open each journal (Bank, Cash, Customer Invoices, Vendor Bills) and confirm the Default Account field is pointing to the correct account from your mapped chart.
The chart of accounts is the skeleton of every report you'll run. Getting account types right at setup is significantly cheaper than correcting misclassified transactions later.
Phase 3: Import Contacts and Set Up Taxes
Contacts and taxes need to be in place before you enter any open transactions, because invoices and bills reference both.
- Import customers and vendors. In Odoo, go to Contacts → Import. Map the columns from your QuickBooks export to Odoo fields: Name, Email, Phone, Street, City, State, Zip, Country. For contacts who are both customers and vendors, check both the Customer and Vendor checkboxes on the contact form after import.
- Review imported contacts. After import, run a quick filter in Contacts for records missing a country or a payment term. These gaps will block invoice posting later, so clean them up now.
- Set up tax rates. Navigate to Accounting → Configuration → Taxes. For each tax code from your QuickBooks list, either find the matching Odoo default or create a new one. Set the Tax Type (Sales or Purchase), the Tax Computation method (Percentage of Price is most common), and the Tax Account where the liability posts.
- Configure fiscal positions if needed. If you sell into multiple states or countries with different tax treatment, set up Fiscal Positions under Accounting → Configuration → Fiscal Positions. A fiscal position tells Odoo to automatically substitute one tax for another based on the customer's location.
- Assign default taxes to your products. Open Inventory → Products (or Sales → Products) and confirm each product has the correct customer tax and vendor tax set in the General Information tab. This is what QuickBooks handled through item-level tax codes.
Phase 4: Enter Opening Balances
This is the most consequential phase of the migration. Your opening balances anchor every financial report going forward. Work with your implementation partner to choose a clean cutover date, typically the last day of a fiscal month.
- Set your lock date. Go to Accounting → Accounting → Lock Dates and set the Tax Return Lock Date to the day before your cutover. This prevents any accidental posting to the prior period once you go live in Odoo.
- Post a general opening journal entry for balance sheet accounts. Go to Accounting → Accounting → Journal Entries → New. Select the Miscellaneous journal. On each line, debit or credit the balance sheet accounts (bank, AR, AP, fixed assets, loans, equity) to match the closing balances from QuickBooks. The entry must balance to zero, any difference goes to your Opening Equity account.
- Enter open customer invoices. For each outstanding invoice in your AR aging report, create an invoice in Odoo: Accounting → Customers → Invoices → New. Set the invoice date to the original invoice date in QuickBooks, enter the customer, the amount, and the correct revenue account. Confirm and post each one. Do not use a lump-sum journal entry here, entering invoices individually preserves the customer aging and lets your team apply future payments correctly.
- Enter open vendor bills. Repeat the same process for your AP aging: Accounting → Vendors → Bills → New. Enter the original bill date, vendor, amount, and expense account. Post each bill.
- Connect and reconcile bank accounts. Go to Accounting → Configuration → Journals, open each bank journal, and add the bank feed connection under the Bank Account tab. Once connected, import your transactions from the cutover date forward. Then reconcile the starting balance against the opening journal entry you posted in step 2.
After Phase 4, run a Balance Sheet in Odoo (Accounting → Reporting → Balance Sheet) and compare it line-by-line against your QuickBooks balance sheet at the cutover date. They should match exactly. If they don't, the delta is almost always in AR, AP, or an account type mismatch. Fix discrepancies before going live.
Phase 5: Validate Reporting and Go Live
The technical migration is done. What's left is confirming that Odoo reports correctly and that your finance team can operate day-to-day without reverting to QuickBooks for answers.
- Run a Profit and Loss comparison. Go to Accounting → Reporting → Profit and Loss. If you've entered historical data, compare the current period to what QuickBooks showed for the same period. If you've only entered a balance sheet opening entry (common when cutting over mid-year), confirm that income and expense accounts start from zero as expected.
- Test the invoice and payment workflow end-to-end. Create a test customer invoice, post it, register a payment against it, and confirm the bank journal reflects the deposit. Verify that the AR account clears properly and that the bank account balance updates.
- Test vendor bill payment. Create a test vendor bill, post it, register a payment, and confirm the AP account and bank account both update correctly. Run Accounting → Reporting → Aged Payable and confirm the paid bill no longer appears as outstanding.
- Set up recurring entries if needed. QuickBooks memorized transactions translate to Odoo's recurring journal entries. Find these under Accounting → Accounting → Recurring Entries. Set the recurrence model (monthly, quarterly) and the date range so fixed expenses like rent or depreciation post automatically.
- Archive your QuickBooks access, but don't cancel it yet. Keep view-only access to QuickBooks for at least 90 days after go-live. Your team will need to look up historical transaction details that predate the cutover, and having the source data available avoids a lot of back-and-forth.
Common Pitfalls to Watch For
A few patterns come up in almost every QuickBooks-to-Odoo migration, regardless of company size.
- Account type mismatches. QuickBooks is forgiving about account types; Odoo is not. An expense account coded as "Other Current Asset" in QuickBooks will cause financial statements to display incorrectly in Odoo. Review every account type before posting any transactions.
- Contacts with inconsistent names. If "Acme Corp" appears as "ACME Corp", "Acme Corporation", and "Acme" in your QuickBooks data, Odoo will create three separate contacts. Deduplication before import is worth the hour it takes.
- Sales tax rounding differences. Odoo calculates tax per line item by default; QuickBooks often calculates tax on the invoice total. For invoices with many line items, this produces small rounding differences. Your implementation partner can configure Odoo's tax rounding method to match your previous behavior under Accounting → Configuration → Settings → Tax Calculation.
- Missing payment terms. Odoo uses payment terms (Net 30, Net 60, 2/10 Net 30) to calculate due dates on invoices. If your QuickBooks contacts didn't have payment terms set, the corresponding Odoo contacts won't either. Bulk-assign default payment terms before entering open invoices, or your AR aging will show incorrect due dates.
Where Odoo Goes Further Than QuickBooks
Once the migration is stable, most finance teams find that Odoo's accounting ties into the rest of the business in ways QuickBooks never did. Sales orders automatically create invoices. Purchase orders create vendor bills. Inventory valuation posts to the general ledger in real time. If you're running manufacturing, work orders feed into cost of goods sold without any manual journal entries.
The reporting layer also extends beyond what QuickBooks offered at similar price points: multi-entity consolidation, analytic accounting (cost centers and projects), and audit logs that track every change with a user name and timestamp.
The migration itself takes two to four weeks of focused finance-team effort. What comes after is an accounting system that's wired into every other part of your operations, which is the actual reason most teams make the switch.
Is Odoo What You Need?
Our team will help you discover if Odoo is the right fit, and get you a tailored demonstration of Odoo for your use case.