# How to migrate to Odoo from CONTPAQi, Aspel, SAP Business One, NetSuite or Business Central

> Migrating to Odoo from another system is not a version upgrade: the Odoo 20 documentation leaves migration from another ERP outside its upgrade service, so it is done by importing data. You bring over master data, the balances at the cut-off date —trial balance, open invoices and bills, inventory and banks— and, in Mexico, what you need to keep issuing payment complements; history stays in the previous system for reference. The migration is done when Odoo's trial balance, receivables and inventory reconcile with the previous system's at the same date.

- Author: Fabio Soto, Business Analyst, Quantum Garage
- Published: 2026-10-17T00:00:00-06:00
- Updated: 2026-10-17T00:00:00-06:00
- Odoo version: 20
- URL: https://web.quantumgarage.io/en/guides/migrate-to-odoo-from-another-erp/

## Migrating means importing data, not upgrading a version

Switching systems and moving to a newer Odoo version are different jobs. An upgrade converts an Odoo database into a newer one; a migration from another system rebuilds in Odoo the data the company needs to keep operating. The Odoo documentation spells it out when it lists what its upgrade service does not cover:

> “An upgrade does not cover: \[…] Migrating from another ERP to Odoo”

Odoo, “Upgrade”, official Odoo 20.0 documentation, accessed October 17, 2026.

That is why a migration from CONTPAQi, Aspel, SAP Business One, NetSuite or Business Central is planned as part of the implementation, with its own cut-off date and reconciliation. The guide [How to implement Odoo in a mid-sized company](https://web.quantumgarage.io/en/guides/odoo-implementation-mid-sized-company/) explains where it fits in the project.

If you are moving a Mexican entity, three local terms run through this guide: the SAT (Servicio de Administración Tributaria, Mexico's tax authority), the RFC (Registro Federal de Contribuyentes, the Mexican tax ID) and the [CFDI](https://web.quantumgarage.io/en/glossary/cfdi/) (Comprobante Fiscal Digital por Internet, Mexico's electronic invoice, stamped through an authorized provider).

- **Previous system**: The software where the company records its operation and its books today, and which stops being the source of truth on cut-off day.
- **Cut-off date**: The date whose balances are carried into Odoo as the starting point.
- **Opening balances**: The company's snapshot at the cut-off date: the trial balance, what it is owed, what it owes, its inventory and its banks.
- **Clearing account**: An account that temporarily holds an amount while its detail is loaded, so that nothing is recorded twice.
- **External ID**: The key Odoo uses to recognize an imported record, which can be the same key it had in the previous system.

## What moves and what stays

The Odoo 20 accounting documentation asks you to prepare four sets of data from the previous system: the opening account balances, the open customer invoices with their credit notes, the open vendor bills with their refunds, and the opening inventory count. Master data goes first, because everything else depends on it.

Table: What is brought into Odoo and how it goes in

| Data                     | What it includes                                     | How it goes into Odoo                                                                |
| ------------------------ | ---------------------------------------------------- | ------------------------------------------------------------------------------------ |
| Chart of accounts        | The accounts the company uses, with their codes      | Matching standard accounts are renamed and recoded; the rest are created or imported |
| Contacts                 | Customers and vendors with current activity          | Import with the contacts template                                                    |
| Products                 | Current products, with their category and cost       | Import, categories first                                                             |
| Trial balance at cut-off | The balance of each account at the cut-off date      | One journal entry, using the miscellaneous operations template                       |
| Receivables and payables | Open invoices and bills, for the amount still due    | Import of invoices at their open balance, against a clearing account                 |
| Inventory                | Counted quantity by product, location and lot        | Import into the physical inventory                                                   |
| Banks                    | The balance of each bank account                     | Starting balance of the first statement                                              |
| History                  | Paid invoices, past journal entries and transactions | Stays in the previous system for reference                                           |

History stays where it is. A full year of paid invoices does nothing for tomorrow's operation and multiplies what has to be reconciled; the Odoo documentation names the end of the fiscal year as the easiest moment to switch precisely because it minimizes the data to transfer. The previous system is kept for reference for as long as the company must retain its records, a period to confirm with your accountant.

## Which system you are coming from

The core work is the same from any source; what changes is how many sources you have to bring together. Each vendor organizes its product its own way, and the best starting point is how its own public documentation describes it:

Table: How each source system organizes its information, according to its vendor's public documentation

| Source system                           | How its offering is organized                                                                                                                                                    | What it means for the migration                                                                                                                             |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CONTPAQi                                | Specialized solutions by area: accounting and tax, payroll, administration and sales, point of sale and treasury                                                                 | If the company uses several, data comes from more than one source, and collections in the sales system are reconciled against accounting before the cut-off |
| Aspel                                   | Separate systems, among them the accounting system (COI) and the administrative system (SAE), which runs from quotation to payment, plus payroll and point-of-sale systems       | Same as above: receivables in the administrative system are reconciled against accounting                                                                   |
| SAP Business One                        | Its help portal covers inventory, production, material requirements planning and the year-end closing within one product                                                         | If the whole operation lives there, there is one source, and the work is mapping its master data structure to Odoo's                                        |
| NetSuite                                | Its help center brings accounting, order management, supply chain and employee management together in one product                                                                | The same mapping work, from a single source                                                                                                                 |
| Microsoft Dynamics 365 Business Central | Microsoft describes it as a business management solution for small and mid-sized organizations covering finance, manufacturing, sales, shipping, project management and services | Its lists, such as customers or invoices, export to Excel, which is the format Odoo's templates read                                                        |

There are cases where the current system is still the right choice, or where it is better to wait. If the company only needs accounting and invoicing and its system handles them well, the benefit of integrating departments is smaller; if the switch would fall in the middle of a tax period, it is better to wait for the next close. Migration pays off when the company wants sales, purchasing, inventory and accounting to work on the same data.

## How data is imported into Odoo

Odoo's import tool loads spreadsheets: the documentation mentions Excel and CSV, and the version 20 code also reads the OpenDocument format. The most common data comes with templates, and the documentation sets the order: related records are imported first, from their own list. To keep relationships intact, each record can keep the key it had in the previous system as its external ID; the documentation requires it to be unique across all objects and recommends prefixing it with the name of the source table, so that customer 1 and product 1 do not collide.

The path, one master list at a time, is this:

1. Get each master list and each balance report out of the previous system into a spreadsheet.
2. Fit each file to the matching Odoo template, with its external ID.
3. Load into a test database, in order: master data first, then whatever depends on it.
4. Test each file before importing it: the Odoo 20 code runs the full import with its validations and then rolls back the writes, so it shows the errors without touching the database.
5. Import, and compare counts and totals against the previous system.
6. Repeat the full rehearsal before the cut-off and, on cut-off day, load only the balances.

Two warnings in the documentation shape that path: imports are permanent and cannot be undone, and a very large file can time out, which is solved by importing in smaller batches.

## How to reconcile the balances

The risk in an accounting migration is recording the same thing twice. If the trial balance says customers owe 1,000 and the open invoices add up to that same 1,000, loading both as they are leaves receivables of 2,000 in Odoo: 1,000 from the trial balance plus 1,000 from the invoices. The Odoo documentation solves this with clearing accounts. In the trial balance you import, the receivables account is replaced by a receivables clearing account, and the open invoices are loaded against that same clearing account; at the end, the clearing account sits at zero and receivables carry the balance of the invoices. The same applies to payables.

Before loading anything, the documentation asks for four checks. The first one reads:

> “The sum of the opening trial balances of all receivable accounts must equal the sum of the open customer invoices minus credit notes.”

Odoo, “Get started”, official Odoo 20.0 documentation (Accounting), accessed October 17, 2026.

Table: What must reconcile before the balances are loaded

| Trial balance account   | Must equal                                                  |
| ----------------------- | ----------------------------------------------------------- |
| Receivables             | Open customer invoices, minus their credit notes            |
| Payables                | Open vendor bills, minus their refunds                      |
| Inventory               | The sum, product by product, of counted quantity times cost |
| The whole trial balance | Its own debits and credits: it must balance                 |

For inventory, the math is done in plain sight: with 10 units of one product at 250 and 8 of another at 350, inventory is worth 2,500 plus 2,800, that is 5,300, and the trial balance's inventory account must read 5,300. Open invoices, in turn, are loaded with a single line for the amount due, as the documentation recommends to avoid hitting the tax accounts twice. Finally, once the clearing accounts are at zero, they are switched to off-balance sheet so they no longer appear in reports.

## Mexico: stamped invoices and payment complements

Invoices issued in the previous system are already stamped and are not stamped again in Odoo. What does cross the cut-off is their collection. When an invoice was issued with the [PPD](https://web.quantumgarage.io/en/glossary/pue-ppd/) payment method (pago en parcialidades o diferido, paid in installments or deferred), the SAT's filling guide requires an additional CFDI carrying the payment receipt complement for each payment received:

> «En este supuesto la clave del método de pago debe ser “PPD” (Pago en parcialidades o diferido) y cuando se reciba el pago total o parcial se debe emitir adicionalmente un CFDI al que se le incorpore el “Complemento para recepción de pagos” por cada pago que se reciba.»

SAT, Annex 20, “Guía de llenado de los comprobantes fiscales digitales por Internet” (CFDI filling guide), accessed October 17, 2026.

Odoo generates that complement only for invoices with the PPD policy, and sends it through the update payments button when a reconciled payment belongs to an invoice with a fiscal folio (the CFDI's unique identifier). For invoices issued in another system, the Odoo 20 Mexican localization includes an XML reader: when you upload an invoice's XML, Odoo creates it as a draft with its customer and taxes, and those invoices can issue [payment complements](https://web.quantumgarage.io/en/glossary/payment-complement/). If the invoice was already created as a draft through an import, the documentation says its fiscal folio is retrieved by dragging the XML into its chatter as a log note.

The two routes have different accounting effects: the XML brings the lines and taxes of the original invoice, while the open-balance import uses a single line against the clearing account. That is why the route for open PPD invoices is decided with your accountant and fully tested in the test database before the cut-off. The documentation also warns that an XML created in another system may carry totals different from those Odoo calculates, and asks you to always double-check what is uploaded this way.

The customer list is cleaned against the SAT before migrating. In CFDI 4.0, the invoice carries the customer's RFC, its name or business name exactly as registered under that RFC, the postal code of its tax address and its tax regime (régimen fiscal), and Odoo asks for them on each contact. Each product also needs its SAT product code so the invoice does not fail validation.

## What changes for the accounting team

The Mexican localization's chart of accounts follows the SAT's account grouping code (código agrupador). You can create any account that respects that structure —`NNN.XX.YY`, `NNN.XX.YYY` or `NNN.XX.YYY.ZZ`—, and Odoo validates it when it is created. Standard accounts that have an equivalent in the company's chart are renamed and recoded instead of deleted, because the documentation warns that deleting them or changing their type can break basic processes such as issuing an invoice. And the localization package is chosen before the first journal entry: once one is posted, it can no longer be changed.

Daily work shifts too. In Odoo, each invoice is itself a journal entry —in the version 20 code, invoices, credit notes and manual entries are the same kind of record—, and Odoo creates the journal entries of all invoices and payments. The accountant moves from keying in entries to reviewing the ones the operation generates, reconciling banks and closing the month, and Mexico's electronic accounting (contabilidad electrónica) comes out of the system: chart of accounts, trial balance and journal entries, in XML.

## What changes for operations

Sales, purchasing, inventory and accounting share one database. The invoice is created from the sales order —the Odoo 20 code generates invoices from orders— and its journal entry is born with it, so what was sold, what the warehouse delivered and what was invoiced are read in the same system. If data used to be passed from one system to another, that hand-off disappears.

For a while, the team will keep looking up the past in the previous system. Decide at the cut-off who keeps access and for what, and make sure everything new is captured only in Odoo.

## Before the cut-off: the short list

1. Customers and vendors with RFC, business name as registered under the RFC, tax postal code and tax regime.
2. Products with their category, cost and SAT product code.
3. A chart of accounts that follows the grouping code structure.
4. A trial balance at the cut-off date that balances.
5. Receivables and payables that reconcile with the trial balance, with the fiscal folio of open PPD invoices.
6. Inventory counted on the cut-off date, with its cost.
7. The balance of each bank account at the cut-off date.
8. A full rehearsal in the test database, with one payment complement tested.

## Frequently asked questions

### Can Odoo import the CONTPAQi, Aspel or SAP Business One database directly?

Odoo's import tool works with spreadsheets —Excel, CSV or OpenDocument— and ships templates for the most common data. The bridge is getting the data out of your current system into those formats and fitting it to the templates, keeping each record's key as its external ID.

### Can we migrate our full history to Odoo?

Journal entries and documents can be imported, but what is worth bringing over is the balances at the cut-off date and the open documents. The Odoo 20 documentation names the end of the fiscal year as the easiest moment to switch because it minimizes the data to transfer; history is looked up in the previous system.

### What happens to invoices already stamped in the previous system?

They stay as they are: they are already stamped and are not stamped again. Those still awaiting payment come into Odoo at their open balance, and if they are PPD (paid in installments or deferred), bringing in their fiscal folio lets you issue the payment complement from Odoo when they are collected.

### When is the best time to switch systems?

At the end of the fiscal year, which is the easiest option according to the Odoo 20 documentation, or at the end of a tax period. The middle of a period is not recommended, because the data from both systems has to be combined for the same tax filing.

### Do we have to stop using our previous system on go-live day?

For day-to-day work, yes: from the cut-off, whatever was migrated is recorded only in Odoo. For reference, the previous system is kept for as long as the company must retain its records, a period to confirm with your accountant.

## Sources

1. Odoo S.A., “Upgrade”, official Odoo 20.0 documentation. <https://www.odoo.com/documentation/20.0/administration/upgrade.html>. Accessed 2026-10-17T00:00:00-06:00.
2. Odoo S.A., “Get started (Accounting)”, official Odoo 20.0 documentation. <https://www.odoo.com/documentation/20.0/applications/finance/accounting/get_started.html>. Accessed 2026-10-17T00:00:00-06:00.
3. Odoo S.A., “Export and import data”, official Odoo 20.0 documentation. <https://www.odoo.com/documentation/20.0/applications/essentials/export_import_data.html>. Accessed 2026-10-17T00:00:00-06:00.
4. Odoo S.A., “Mexico (fiscal localization)”, official Odoo 20.0 documentation. <https://www.odoo.com/documentation/20.0/applications/finance/fiscal_localizations/mexico.html>. Accessed 2026-10-17T00:00:00-06:00.
5. Odoo S.A., “addons/base_import/models/base_import.py”, Odoo source code, branch 20.0, commit eaef8b21. <https://github.com/odoo/odoo/blob/eaef8b21ca849cc8b12be2379a5c87a7dea8f3ff/addons/base_import/models/base_import.py>. Accessed 2026-10-17T00:00:00-06:00.
6. Odoo S.A., “addons/account/models/account_move.py”, Odoo source code, branch 20.0, commit eaef8b21. <https://github.com/odoo/odoo/blob/eaef8b21ca849cc8b12be2379a5c87a7dea8f3ff/addons/account/models/account_move.py>. Accessed 2026-10-17T00:00:00-06:00.
7. Odoo S.A., “addons/sale/models/sale_order.py”, Odoo source code, branch 20.0, commit eaef8b21. <https://github.com/odoo/odoo/blob/eaef8b21ca849cc8b12be2379a5c87a7dea8f3ff/addons/sale/models/sale_order.py>. Accessed 2026-10-17T00:00:00-06:00.
8. Servicio de Administración Tributaria (SAT), “Anexo 20. Guía de llenado de los comprobantes fiscales digitales por Internet”, SAT, Mexico. <http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Anexo_20_Guia_de_llenado_CFDI.pdf>. Accessed 2026-10-17T00:00:00-06:00.
9. CONTPAQi, “CONTPAQi® software empresarial y administrativo”, CONTPAQi official website. <https://www.contpaqi.com/>. Accessed 2026-10-17T00:00:00-06:00.
10. Siigo Aspel, “Siigo Aspel México”, Siigo Aspel official website. <https://www.aspel.com.mx/>. Accessed 2026-10-17T00:00:00-06:00.
11. SAP SE, “SAP Business One”, SAP Help Portal. <https://help.sap.com/docs/SAP_BUSINESS_ONE>. Accessed 2026-10-17T00:00:00-06:00.
12. Oracle, “Welcome to the NetSuite Help Center”, Oracle Help Center, NetSuite Applications Online Help. <https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/index.html>. Accessed 2026-10-17T00:00:00-06:00.
13. Microsoft, “Welcome to Microsoft Dynamics 365 Business Central”, Microsoft Learn. <https://learn.microsoft.com/en-us/dynamics365/business-central/welcome>. Accessed 2026-10-17T00:00:00-06:00.
14. Microsoft, “View and edit in Excel from Business Central”, Microsoft Learn. <https://learn.microsoft.com/en-us/dynamics365/business-central/across-work-with-excel>. Accessed 2026-10-17T00:00:00-06:00.
