Skip to content

Duplicate customers and vendors in Odoo: find and clean them

Maxime VanderhaeghePublished 10 min read

In short, A duplicate contact is the same company recorded twice in Odoo, usually after an import or a quick create from a quotation or a bill. You find them by grouping contacts by VAT number, email and name, then merge them with the "Merge" action in the contact list, after checking open documents first. Their most expensive consequence is a vendor bill entered twice, sometimes on two different records, and paid twice. Prevention comes down to three rules: always capture the VAT number, search before you create, and check vendor references.

Nobody creates a duplicate on purpose. A salesperson types "Dupont" into a quotation, doesn't spot "Dupont & Sons Ltd" in the dropdown and clicks "Create". A post-migration import adds the vendors from an old tool without checking which ones already existed. Every step is reasonable, and the result is a contact base where the same company lives under two, three or four names.

The problem stays invisible because Odoo works perfectly well with duplicates. Quotations get confirmed, bills get posted, payments go out. Nothing blocks. The cost only shows up downstream: a payables balance that doesn't reconcile, a reminder sent to a customer who already paid on their other record, or a vendor bill settled twice without anyone noticing.

This article walks you through finding duplicates by hand in Odoo, merging them without breaking history, spotting duplicate vendor bills, and keeping the problem from coming back.

Why duplicates appear in Odoo#

In Odoo, customers, vendors, companies and individual contacts all share the same contact list. A vendor isn't a separate kind of record, it's a contact that has already received a purchase order or a vendor bill. The design is flexible, but it opens a lot of doors. The most common causes:

  • Imports. Data migrated from a previous ERP, a spreadsheet of prospects or a sync with a third-party tool creates records without checking what's already there. This is where duplicates come from in bulk.
  • Quick create from a document. In a customer or vendor field, typing a name and hitting "Create" produces a record with nothing but the name. No VAT number, no address, nothing that ties it back to the existing record.
  • Name variants. "Dupont Ltd", "DUPONT", "Dupont & Sons", "Dupont Trading": to Odoo, those are four different companies. Legal forms (SA, SRL, NV, BV, Ltd, GmbH) added or left out are a classic.
  • Company versus person. Odoo separates the company from the individual contacts attached to it. Creating "Marie Martin" as a standalone contact when she works for an existing vendor, then addressing bills to her, amounts to creating a second vendor. Accounting relies on the company a person is attached to, so a badly attached person skews balances.
  • No VAT number. It's the only truly reliable key for identifying a business. When it's missing, nothing tells Odoo, or a busy human, that two records describe the same entity.

What it costs you#

A duplicate customer mostly costs you in operations. History gets split across records: revenue per customer is understated, overdue follow-up happens on one record while payments land on the other, and a credit limit set on one record protects nothing if orders go through the second. Reminders get sloppy, and the customer is the first to notice.

A duplicate vendor costs you more directly, because it touches cash going out. Two records for the same vendor means potentially two different bank accounts, two sets of payment terms and, above all, two places where the same bill can be entered. The textbook case: a bill arrives by email and accounts payable enters it; the vendor's reminder arrives three weeks later and gets entered again, on the other record. Both get posted, both land in the payment run.

Recovering a double payment is possible, but it takes time, depends on the vendor's good faith and cash position, and first requires you to notice. Many double payments are only discovered at year-end close, or never, when the vendor turns the overpayment into a credit note nobody uses.

Finding them by hand in Odoo, step by step#

All of this works in standard Odoo. The menus below are the same in recent versions; if you don't have the full Accounting app (Enterprise edition), read "Invoicing" wherever this says "Accounting".

1. Group contacts by VAT number. Open the Contacts app, switch to list view and remove the default filters. In the search bar, open the filter panel, then "Group By" and "Add Custom Group" (or "Custom Group", depending on your Odoo version), and pick "Tax ID". Any group with two or more rows is suspicious. Be aware that Odoo compares exact values. Odoo usually normalizes the format on save (spaces and dots are removed), but a number entered without its country prefix or older data ends up in a different group. Sort by name inside the groups to catch those formatting variants.

2. Group by email. Same approach with the Email field. Set aside generic addresses (info@, contact@, office@): several contacts at the same company often share the general inbox. A personal email that appears on two records not attached to the same company, on the other hand, is almost certainly a duplicate.

3. Look for name variants. Standard Odoo has no "group by similarity". The most effective approach is a partial search: type the stem of the name ("dupont" rather than "Dupont Ltd") in the search bar and see what comes back. For a full review, export the list (select all rows, Action menu, Export) with ID, name, VAT, email, phone and parent company, then sort by name in a spreadsheet. Name duplicates end up next to each other.

4. Focus on vendors. Repeat steps 1 to 3 from Accounting, Vendors, Vendors (or Purchase, Orders, Vendors). The list is shorter and the financial stakes are higher: if you're short on time, start here.

5. Hunt for duplicate vendor bills. Go to Accounting, Vendors, Bills. Remove the filters, group by Partner (the vendor), then add a custom group on "Reference" (shown as "Bill Reference" on the bill: the vendor's own invoice number). Any reference that shows up twice for the same vendor needs a look. Then do a second pass: group by vendor, sort by total amount, and look for two identical amounts a few days or weeks apart. Don't skip drafts: a bill duplicated by mistake often sits in draft with no bill date.

Be clear-eyed about the limit of this method: both groupings work per vendor. If the same bill was entered once on "Dupont Ltd" and once on "Dupont Trading", it shows up in neither group. That's why cleaning up the records has to come before the bill hunt, or at least go hand in hand with it.

Fixing them, in the right order#

1. Pick the record to keep. Usually the oldest one, carrying the most history and a correct VAT number. Before merging, compare the records: bank accounts, payment terms, fiscal position, pricelist, invoice address. Copy whatever is missing onto the record you keep.

2. Deal with open documents. Check unpaid bills, unreconciled payments and orders in progress on the record that will go away. Better to know about them before than after.

3. Merge. In the contact list view, tick the records involved, open the Action menu (the gear icon) and choose "Merge". The wizard asks for the destination record, then reassigns linked documents (quotations, orders, bills, journal items) to it and deletes the source records. A few limits worth knowing: the wizard refuses more than three records at a time, it refuses to merge a company with one of its own contacts or records linked to more than one user, and it blocks a non-administrator when emails differ. The wizard also has an automatic search mode (by email, name, VAT or parent company), but it has no menu entry in standard Odoo: the only way in is the "Deduplicate the other Contacts" button at the end of a merge, so don't treat it as the standard path. Finally, a merge can't be cleanly undone. Try it on a test database if you have one, and merge one pair at a time.

4. Sort out duplicate bills. A draft bill can be deleted or cancelled. A posted but unpaid bill can be reset to draft and cancelled, if your lock dates allow it and the journal is not locked (secured journal); otherwise, issue a credit note. A bill already paid twice needs a credit note plus a refund request to the vendor, or an offset against their next bill. Have your accountant sign off on the accounting treatment, especially if the period is closed or the VAT return already filed.

Keeping them from coming back#

Make the VAT number systematic. Standard Odoo doesn't make the VAT number mandatory, and enforcing it takes custom development or Studio. Until then, make it a written rule: no business vendor without a VAT number. Odoo already checks the number's format; also turn on "Verify VAT Numbers" (VIES service) in the Accounting settings to find out whether the numbers entered are actually active. Odoo also shows a warning on the contact form when another contact already carries the same VAT number (or the same company registry number), which only helps if the number is filled in. It's an invoicing requirement too, as covered in our Belgian invoicing compliance checklist.

Search before you create. The rule for the team fits in one sentence: in a customer or vendor field, type the stem of the name and wait before clicking "Create". Better still, remove contact creation rights from people who don't need them, and route new vendor creation through one person.

Always enter the vendor reference. On a vendor bill, the Bill Reference field isn't a detail. A banner warns you (without blocking) when a bill from the same vendor already carries the same reference. Without a reference, that safeguard does nothing, and it sees nothing if the bill was entered on another vendor record.

Run a routine. A monthly check is enough: group the month's new contacts by VAT and by email, and review vendor bills by reference before each payment run. Name an owner, usually accounts payable, and set a simple threshold: zero duplicate vendors before payments go out.

What the UpBoard scan checks here#

The scan reads your Odoo in read-only mode and combines several checks. On records: active contacts sharing the same VAT number or company registration number (after stripping spaces, dots and dashes), the same personal email (generic addresses are ignored), the same phone number, or a very similar name once legal forms are removed. For vendors, it also compares the names of those without a VAT number. On vendor bills from the past year, drafts included: same vendor and same reference, or same vendor and same amount less than 30 days apart. It flags the most recent record or bill as the likely duplicate and keeps the oldest as the reference. It detects and suggests: any merge or cancellation in Odoo goes through your approval.

Conclusion#

Duplicate contacts never block Odoo, which is exactly what makes them dangerous. The method comes in three moves: group by VAT, email and name to find them, merge record by record after checking open documents, then check vendor bill references before every payment run. The hard part is doing it regularly. If you want to know where your database stands before you spend an afternoon on it, the UpBoard scan runs 92 checks in a few minutes, duplicate contacts and duplicate vendor bills included, and shows you the score before it asks for your details.

See what your Odoo data has to tell you

A few minutes, read-only, no card. Then a trial on your real data: 14 days, or until the trial credit is used up.