Public Access
Four follow-up defects found beyond the 2026-10-27 SEO audit (no copy changes): 1. legal.html canonical was https://ODOO4projects.com/legal — uppercase host AND a path that 404s. Now https://odoo4projects.com/legal.html. The file's og:url keeps its path /legal but its host is lowercased (path fix awaiting a decision). 2. The no-"4" domain typo in reader-visible <pre><code> body text of blog/posts/{guide-migrate-enterprise,speed-run-deploy,my-first-post}.html: odooprojects.com -> odoo4projects.com. Domain string only, no other wording. 3. Lowercase host in every machine-read value: the robots.txt Sitemap line, the homepage + de/ + es/ Organization JSON-LD url / contactPoint.url / offers[].url, legal.html og:url, and the four absolute self-URL hrefs in blog posts, odoo/support.html and email/trial-confirmation.html. Display text untouched (support@ODOO4projects.com stays as written). 4. One BlogPosting per blog post (15), every value taken from the page itself: headline = its <h1>, datePublished = its visible post-meta date, url = its own canonical, author/publisher = the Organization the site already publishes, image = its og:image where one exists (omitted on the 10 posts that have none). Empire ">950.00", FAQPage on support.html, the blog-chrome change and the bootcamp date conflict are untouched — decisions pending with the user.
173 lines
8.9 KiB
HTML
173 lines
8.9 KiB
HTML
<!doctype html>
|
|
<html lang="en-US">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>This is how i updated my Invoices from Odoo 19 to Odoo 20 with n8n and much MCP | ODOO4projects</title>
|
|
<meta
|
|
name="description"
|
|
content="Copying invoices from one Odoo instance to another by hand is the kind of task that looks small until you are on invoice"
|
|
/>
|
|
<link
|
|
rel="canonical"
|
|
href="https://odoo4projects.com/blog/posts/odoo-19-to-20-invoice-migration-with-n8n-and-mcp.html"
|
|
/>
|
|
<meta
|
|
property="og:title"
|
|
content="This is how i updated my Invoices from Odoo 19 to Odoo 20 with n8n and much MCP"
|
|
/>
|
|
<meta
|
|
property="og:description"
|
|
content="Copying invoices from one Odoo instance to another by hand is the kind of task that looks small until you are on invoice"
|
|
/>
|
|
<meta property="og:type" content="article" />
|
|
<meta property="og:image" content="https://image.office.odoo4projects.com/img/much.png" />
|
|
<meta name="twitter:card" content="summary_large_image" />
|
|
<link rel="icon" href="../../images/favicon.ico" />
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link
|
|
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Inter+Tight:wght@500;600;700;800&display=swap"
|
|
rel="stylesheet"
|
|
/>
|
|
<link
|
|
rel="stylesheet"
|
|
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"
|
|
/>
|
|
<link rel="stylesheet" href="../../style.css" />
|
|
<style>
|
|
:root {
|
|
--primary: #714b67;
|
|
--dark: #212529;
|
|
--border: #e5e3e0;
|
|
--radius: 0.6rem;
|
|
}
|
|
* { box-sizing: border-box; }
|
|
body {
|
|
margin: 0;
|
|
font-family: Inter, sans-serif;
|
|
font-size: 1rem;
|
|
line-height: 1.7;
|
|
background: #fff;
|
|
color: #212529;
|
|
}
|
|
.container { width: 80%; max-width: 800px; margin: 0 auto; padding: 0 20px; }
|
|
@media (max-width: 768px) { .container { width: 100%; } }
|
|
.blog-header { padding: 2rem 0; border-bottom: 1px solid var(--border); }
|
|
.blog-header a { color: var(--primary); text-decoration: none; font-size: 0.85rem; }
|
|
.blog-header a:hover { text-decoration: underline; }
|
|
.post-title {
|
|
font-family: "Inter Tight", sans-serif;
|
|
font-size: clamp(1.5rem, 3vw, 2.2rem);
|
|
font-weight: 700; margin: 1.5rem 0 0.5rem; color: var(--dark);
|
|
}
|
|
.post-meta { color: rgba(33,37,41,0.5); font-size: 0.85rem; margin-bottom: 2rem; }
|
|
.post-image { width: 100%; border-radius: 0.75rem; margin-bottom: 2rem; box-shadow: 0 2px 8px rgba(13,27,46,0.08); }
|
|
.post-content h2 {
|
|
font-family: "Inter Tight", sans-serif;
|
|
font-size: 1.3rem; margin-top: 2rem; color: var(--dark);
|
|
}
|
|
.post-content p { margin: 1rem 0; color: rgba(33,37,41,0.7); line-height: 1.7; }
|
|
.post-content ul, .post-content ol { padding-left: 1.5rem; }
|
|
.post-content li { margin: 0.5rem 0; color: rgba(33,37,41,0.7); }
|
|
.post-content a { color: var(--primary); }
|
|
.post-footer { padding: 2rem 0; border-top: 1px solid var(--border); margin-top: 2rem; }
|
|
.post-footer a { color: var(--primary); text-decoration: none; }
|
|
.post-footer a:hover { text-decoration: underline; }
|
|
</style>
|
|
<script type="application/ld+json">
|
|
{
|
|
"@context": "https://schema.org",
|
|
"@type": "BlogPosting",
|
|
"headline": "This is how i updated my Invoices from Odoo 19 to Odoo 20 with n8n and much MCP",
|
|
"datePublished": "2026-10-23",
|
|
"url": "https://odoo4projects.com/blog/posts/odoo-19-to-20-invoice-migration-with-n8n-and-mcp.html",
|
|
"image": "https://image.office.odoo4projects.com/img/much.png",
|
|
"author": {
|
|
"@type": "Organization",
|
|
"name": "ODOO4projects",
|
|
"url": "https://odoo4projects.com/"
|
|
},
|
|
"publisher": {
|
|
"@type": "Organization",
|
|
"name": "ODOO4projects",
|
|
"url": "https://odoo4projects.com/",
|
|
"logo": {
|
|
"@type": "ImageObject",
|
|
"url": "https://odoo4projects.com/images/logo.png"
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="blog-header">
|
|
<a href="../../index.html#blog">← Back to Blog</a>
|
|
</div>
|
|
<article>
|
|
<h1 class="post-title">This is how i updated my Invoices from Odoo 19 to Odoo 20 with n8n and much MCP</h1>
|
|
<div class="post-meta">October 23, 2026 · Tips</div>
|
|
<img src="https://image.office.odoo4projects.com/img/much.png"
|
|
alt="This is how i updated my Invoices from Odoo 19 to Odoo 20 with n8n and much MCP"
|
|
class="post-image" loading="lazy" />
|
|
<div class="post-content">
|
|
<p>Copying invoices from one Odoo instance to another by hand is the kind of task that looks small until you are on invoice forty. I moved mine from Odoo 19 to Odoo 20 with an n8n workflow and the ODOO MCP from much ( available at the APP store for free) pointed at the new system, and the setup is simpler than it sounds: the old invoice goes in as context, the tool writes it into the new Odoo, and the agent handles the mapping in between.</p>
|
|
|
|
<p>What decides whether this works or turns into a mess is not the automation itself. It is the order of operations and the rules you give the agent.</p>
|
|
|
|
<h2>Create contacts and products first</h2>
|
|
|
|
<p>Before a single invoice moves, the contacts and the products need to exist in Odoo 20. I did that the classical Export / Import way</p>
|
|
|
|
<h2>Three rules for every invoice</h2>
|
|
|
|
<ol>
|
|
<li><strong>Invoice date and number must stay identical.</strong> The imported invoice is not a new document. If the number or the date shifts, your books stop lining up with the old system.</li>
|
|
<li><strong>Search for the existing contact and map it.</strong> The agent looks the customer up in Odoo 20 and links it to the invoice with the new ID.</li>
|
|
<li><strong>Search for the existing product and map it.</strong> The same logic applies to the product lines.</li>
|
|
</ol>
|
|
|
|
<p>And one hard constraint on top: <strong>do not create a contact or a product</strong>. If something is missing, the import should fail loudly instead of quietly filling your database with near-duplicates.</p>
|
|
|
|
<h2>The prompt that does the work</h2>
|
|
|
|
<p>The instructions I hand the agent are short and blunt:</p>
|
|
|
|
<ul>
|
|
<li>Import the invoice from Odoo 19 into Odoo 20.</li>
|
|
<li>The old invoice is in this prompt, so use the much MCP tool to write it to the new Odoo.</li>
|
|
<li>Invoice date and number must be the same.</li>
|
|
<li>The contact already exists, so search for it in the new Odoo and map accordingly.</li>
|
|
<li>The product already exists, so search for it in the new Odoo and map accordingly.</li>
|
|
<li>Do not create a contact or a product.</li>
|
|
</ul>
|
|
|
|
<p>Nothing about formatting, nothing about rewriting descriptions. The fewer decisions the agent has to make, the more predictable the result.</p>
|
|
|
|
<h2>Check the result, then go again</h2>
|
|
|
|
<ul>
|
|
<li>Does the invoice number match the source exactly?</li>
|
|
<li>Is the invoice date unchanged?</li>
|
|
<li>Is it attached to the right contact?</li>
|
|
<li>Are the product lines pointing at products that already exist in Odoo 20?</li>
|
|
</ul>
|
|
|
|
<p>Run one invoice, verify it, then let the workflow loose on the rest.</p>
|
|
|
|
<h2>Why this approach holds up</h2>
|
|
|
|
<p>Moving invoices between two Odoo systems is really a matching problem. The old system holds the documents, the new one holds the records those documents need to point at. n8n provides the workflow, the MCP tool gives the agent hands inside Odoo 20, and the rules stop it from guessing. Contacts and products first, dates and numbers untouched, lookups instead of creations: that combination is what made the migration boring, which is exactly what you want from an accounting import.</p>
|
|
|
|
<p>If you are planning the same move, start with the contacts and the products in Odoo 20. Get those right, and the rest of the migration is mostly bookkeeping.</p>
|
|
</div>
|
|
</article>
|
|
<div class="post-footer">
|
|
<a href="../../index.html#blog">← Back to all posts</a>
|
|
</div>
|
|
</div>
|
|
<script defer src="/static/agent-odoo4projects/agent.js"></script>
|
|
</body>
|
|
</html>
|