Running an HVAC business with Odoo

How do I automate recurring invoices in Odoo?

Workflow overview: How do I automate recurring invoices in Odoo?
Workflow overview. Instructional screenshots show the actual demo interface.

Automate recurring invoices in Odoo with native Auto-post, reviewed annual amounts, a tested posting job and an inclusive end date.

Alex wants to understand recurring invoices before using them for a reviewed annual billing arrangement. Stock Odoo provides Auto-post on the invoice and a shipped posting job. This example verifies the first posting, the next annual draft, scheduled posting and the end condition. Invoice creation and posting remain separate from customer agreement, renewal and payment collection.

Alex Rivera and Demo Air HVAC are fictional training examples. Prices, dates, quantities and business situations in this guide are illustrative.

Before you begin

Tested in stock Odoo 20.0-20260926 Community as the demo owner administrator, with official modules and standard configuration. Complete H50 maintenance agreements and H04 US invoicing setup. Use official Invoicing/account and the demo owner’s administrative account. Step 8 shows the native Developer Mode control for exposing Technical scheduled actions. Use a training database. This separate, clearly labelled historical test has two fictional annual invoice dates: October 15, 2025 and October 15, 2026, at $240 before demo tax each. Both accounting dates are on or before the test date, October 15, 2026, so the job can be exercised without changing the clock. These are not dates to copy into real books. The series is independent of S00013: it does not bill that sales line, change its one annual fee or establish a renewed coverage term. All 20 earlier finance records have Auto-post No before the test. Keep outward messages local and payment providers unused.

Step-by-step workflow

Step 1. Create the separate annual billing test invoice

Open Invoicing → Customers → Invoices → New. Select Demo Property H08, Billing Office H08, set Invoice Date October 15, 2025, and choose Demo Net 30 H06. Check the Sales journal. These historical values belong only to this bounded training fixture. For an actual arrangement, review the real billing period, customer agreement, accounting date and applicable locks before posting.

Action 4: Create a separate training invoice. The actual target is highlighted in gold.
Create a separate training invoice.
Action 5: Choose the fictional billing contact. The actual target is highlighted in gold.
Choose the fictional billing contact.
Action 6: Historical training date: October 15, 2025. The actual target is highlighted in gold.
Historical training date: October 15, 2025.
Action 7: Select Demo Net 30 H06. The actual target is highlighted in gold.
Select Demo Net 30 H06.
Action 8: Use the existing Sales journal. The actual target is highlighted in gold.
Use the existing Sales journal.

Step 2. Select and verify the annual service line

Click Add a line, select H50-ANNUAL – Demo Maintenance Agreement H50, and review 1 Unit × $240. Keep its copied general service scope. Verify the selected product and Units, the Product Sales account and the illustrative 6% tax: $240 + $14.40 = $254.40. In this form, replacing text in the Product cell cleared the product selection while leaving the amount; that draft was corrected by reselecting the same service before posting. Check the product and unit again after any such edit. Do not turn one annual agreement into monthly or per-visit $240 charges.

Action 9: Add the annual service product. The actual target is highlighted in gold.
Add the annual service product.
Action 10: Find H50-ANNUAL; retain the selected product. The actual target is highlighted in gold.
Find H50-ANNUAL; retain the selected product.
Action 13: Open Other Info to label and configure this separate series. The actual target is highlighted in gold.
Open Other Info to label and configure this separate series.

Step 3. Label the independent training series

In Terms and Conditions, record H52 TRAINING ONLY and explain that this is a separate annual recurrence-mechanics test at October 15, 2025 and October 15, 2026. State that it is not a bill for S00013 or evidence of actual work, customer agreement, renewal, outreach or payment. In Other Info → Customer Reference, enter DEMO-H52-ANNUAL-RECURRENCE-TEST. The existing service description supplies general scope; the test label and dates identify this separate fixture.

Action 12: Label this independent annual test; no work, renewal or payment. The actual target is highlighted in gold.
Label this independent annual test; no work, renewal or payment.
Action 13: Open Other Info to label and configure this separate series. The actual target is highlighted in gold.
Open Other Info to label and configure this separate series.
Action 14: Identify this separate historical annual test. The actual target is highlighted in gold.
Identify this separate historical annual test.

Step 4. Configure Yearly and the inclusive end

In Other Info, open Auto-post and select Yearly. The visible alternatives also include No, At Date, Monthly and Quarterly; this test exercises Yearly only. Set Auto-post until October 15, 2026. The date is inclusive: it permits that final accounting date and excludes the following annual date. Enter it explicitly; Odoo did not derive it from the maintenance agreement’s Terms and conditions.

Action 13: Open Other Info to label and configure this separate series. The actual target is highlighted in gold.
Open Other Info to label and configure this separate series.
Action 15: Open the native Auto-post choices. The actual target is highlighted in gold.
Open the native Auto-post choices.
Action 16: Choose Yearly; other intervals remain untested. The actual target is highlighted in gold.
Choose Yearly; other intervals remain untested.
Action 17: Inclusive end: October 15, 2026. The actual target is highlighted in gold.
Inclusive end: October 15, 2026.

Step 5. Save and reopen the same first draft

Click Save manually while changes are pending, wait for the saved form, then reload. Native tab changes can already save invoice edits, so check the saved result rather than forcing another save. Verify the same customer/site, annual product/Units, $254.40 total, October 15, 2025 invoice/accounting date, Net 30 due date November 14, 2025, training terms and Yearly/Until settings. The form states that yearly auto-posting is enabled and recurrence ends on October 15, 2026, included. The draft has no sales-line link.

Action 18: Save the reviewed yearly series while changes are pending. The actual target is highlighted in gold.
Save the reviewed yearly series while changes are pending.
Action 19: Reopened draft retains Yearly auto-post. The actual target is highlighted in gold.
Reopened draft retains Yearly auto-post.
Action 20: Reopened product and Units remain one annual fee. The actual target is highlighted in gold.
Reopened product and Units remain one annual fee.
Action 21: Saved terms identify the independent training series. The actual target is highlighted in gold.
Saved terms identify the independent training series.
Action 22: First historical invoice date remains October 15, 2025. The actual target is highlighted in gold.
First historical invoice date remains October 15, 2025.

Step 6. Confirm once and inspect the next annual draft

Click Confirm once. The first invoice becomes Posted, numbered INV/2025/00001, and native recurrence creates one next draft. Return to Invoices and open the new $254.40 draft dated October 15, 2026 for Billing Office H08. Its invoice and accounting dates have advanced one year; Net 30 gives November 14, 2026. Inspect the copied service, quantity, price, tax, customer/site, terms, owner and Yearly/Until values. Do not click Confirm on this second draft: the next step tests the posting job.

Action 23: Confirm the first training invoice once. The actual target is highlighted in gold.
Confirm the first training invoice once.
Action 24: The original is now Posted as INV/2025/00001. The actual target is highlighted in gold.
The original is now Posted as INV/2025/00001.
Action 25: Posting leaves $254.40 unpaid; no receipt was created. The actual target is highlighted in gold.
Posting leaves $254.40 unpaid; no receipt was created.
Action 26: Return to the invoice list after the first confirmation. The actual target is highlighted in gold.
Return to the invoice list after the first confirmation.
Action 27: Open the single new $254.40 annual draft. The actual target is highlighted in gold.
Open the single new $254.40 annual draft.
Action 28: The copied draft retains the selected annual product and one Unit. The actual target is highlighted in gold.
The copied draft retains the selected annual product and one Unit.
Action 32: The copied yearly end remains October 15, 2026. The actual target is highlighted in gold.
The copied yearly end remains October 15, 2026.

On the new draft, open Other Info. Customer Reference is blank; the native copy did not retain the original reference. Its training Terms and Conditions and general service description are copied exactly, so period-specific text still needs review. The chatter includes This recurring entry originated from with a link labelled Draft Invoice (DEMO-H52-ANNUAL-RECURRENCE-TEST). Use that relationship, customer, dates and amount to identify the copy; searching only for the original reference would miss it. This independent invoice series has no S00013 sale-line link and does not update its Invoiced quantity.

Action 29: Copied training terms still require period and agreement review. The actual target is highlighted in gold.
Copied training terms still require period and agreement review.
Action 30: Inspect the copy in Other Info; keep it unposted. The actual target is highlighted in gold.
Inspect the copy in Other Info; keep it unposted.
Action 31: Customer Reference is blank on the generated copy. The actual target is highlighted in gold.
Customer Reference is blank on the generated copy.
Action 32: The copied yearly end remains October 15, 2026. The actual target is highlighted in gold.
The copied yearly end remains October 15, 2026.
Action 33: Native origin message links to the original training invoice. The actual target is highlighted in gold.
Native origin message links to the original training invoice.

Step 8. Run the shipped posting job in the controlled test

Open Settings. If Technical is hidden, scroll to Developer Tools and click Activate the developer mode. After Settings reloads, open Technical → Scheduled Actions and locate Account: Post draft entries with auto_post enabled and accounting date up to today. Verify the existing Journal Entry job, Active status and daily interval. Leave its code, scheduler user and other jobs unchanged. With only this test series eligible, click Run Manually once. This uses the shipped job; no custom code or new scheduled action is introduced. The demonstration exercises this exact job manually. Automatic execution on an unattended server also requires its scheduler to be running; wall-clock background execution was not tested here.

Action 1: Open the native Settings app. The actual target is highlighted in gold.
Open the native Settings app.
Action 2: Developer Tools: activate the developer mode. The actual target is highlighted in gold.
Developer Tools: activate the developer mode.
Action 3: Technical is now available in Settings. The actual target is highlighted in gold.
Technical is now available in Settings.
Action 34: Open Technical after native Developer Mode activation. The actual target is highlighted in gold.
Open Technical after native Developer Mode activation.
Action 35: Open the native Scheduled Actions list. The actual target is highlighted in gold.
Open the native Scheduled Actions list.
Action 36: Find the shipped due-entry posting job. The actual target is highlighted in gold.
Find the shipped due-entry posting job.
Action 37: Review the existing Active, daily Journal Entry job and OdooBot user. The actual target is highlighted in gold.
Review the existing Active, daily Journal Entry job and OdooBot user.
Action 38: Run the shipped job once; only this annual draft is eligible. The actual target is highlighted in gold.
Run the shipped job once; only this annual draft is eligible.
Action 39: The shipped action ran; unattended scheduling remains untested. The actual target is highlighted in gold.
The shipped action ran; unattended scheduling remains untested.

Step 9. Reopen the invoice posted by the job

Return to Invoicing → Customers → Invoices and open INV/2026/00005. It is the same second record, now Posted with OdooBot’s validation in its chatter. Check its October 15, 2026 date, November 14 due date, $254.40 total and amount due, same service and copied training terms. The record remains unpaid, with no payment or payment transaction. No Send or Pay action was used. Posting produces accounting entries, not money received.

Action 40: Return to the native Invoicing app. The actual target is highlighted in gold.
Return to the native Invoicing app.
Action 41: Open Customers to review invoices. The actual target is highlighted in gold.
Open Customers to review invoices.
Action 42: Open the invoice list after the shipped job. The actual target is highlighted in gold.
Open the invoice list after the shipped job.
Action 43: Open the same second invoice, now INV/2026/00005. The actual target is highlighted in gold.
Open the same second invoice, now INV/2026/00005.
Action 44: The second invoice keeps October 15, 2026. The actual target is highlighted in gold.
The second invoice keeps October 15, 2026.
Action 45: Posted leaves $254.40 due; it does not collect payment. The actual target is highlighted in gold.
Posted leaves $254.40 due; it does not collect payment.
Action 46: OdooBot validated the same invoice through the shipped job. The actual target is highlighted in gold.
OdooBot validated the same invoice through the shipped job.
Action 47: The posted copy retains one annual Unit at $240. The actual target is highlighted in gold.
The posted copy retains one annual Unit at $240.
Action 48: Copied training scope is retained; no actual renewal implied. The actual target is highlighted in gold.
Copied training scope is retained; no actual renewal implied.

Step 10. Check repeated execution and the end condition

Run that same shipped scheduled action once more, then revisit the invoice list. The two test records remain INV/2025/00001 and INV/2026/00005; no duplicate or October 15, 2027 draft exists. The final invoice was allowed exactly on Auto-post until, but another year would exceed it. Both retain $254.40 due. This verifies repetition and the configured inclusive end; it does not test immediate disabling, cancellation or changing an already-posted recurrence.

Action 49: Run the same shipped action again; verify no extra invoice. The actual target is highlighted in gold.
Run the same shipped action again; verify no extra invoice.
Action 50: Filtered review: the same two annual invoices remain Posted and unpaid. The actual target is highlighted in gold.
Filtered review: the same two annual invoices remain Posted and unpaid.

Step 11. Reopen the original and preserve the business handoff

On INV/2026/00005, follow its This recurring entry originated from chatter link. It reopens the same posted INV/2025/00001 despite the link’s historical Draft Invoice label. Review its original terms and annual amount. Preserve the two synthetic test invoices separately from S00013, whose price, invoice links, visit tasks and planned office handoff remain unchanged. Before using recurrence for a real next term, review customer agreement, scope, dates, references and the renewal decision. Do not treat the generated invoice as authorization for continued coverage or collection.

Action 51: Follow the native origin link, labelled historically as Draft Invoice. The actual target is highlighted in gold.
Follow the native origin link, labelled historically as Draft Invoice.
Action 52: The native origin link reopens the same Posted original. The actual target is highlighted in gold.
The native origin link reopens the same Posted original.
Action 53: Review the original independent annual training terms. The actual target is highlighted in gold.
Review the original independent annual training terms.
Action 54: The original also remains unpaid at $254.40. The actual target is highlighted in gold.
The original also remains unpaid at $254.40.
Action 55: S00013 retains one annual Unit at $240; this series is separate. The actual target is highlighted in gold.
S00013 retains one annual Unit at $240; this series is separate.
Action 11: Later review: the original still has one annual Unit at $240. The actual target is highlighted in gold.
Later review: the original still has one annual Unit at $240.

Check the result

One native Confirm posts the first independent annual invoice and creates one next-year draft. The unchanged shipped job posts that due draft; repeating it adds none. INV/2025/00001 and INV/2026/00005 remain Posted and unpaid at $254.40 each, with dates October 15, 2025/2026 and Net 30 due dates November 14. Product, Units, quantity, price, tax, customer/site, terms and owner are copied; Customer Reference is not. Both belong to the same native recurrence origin, and the copy’s chatter link reopens the original. Auto-post until October 15, 2026 permits that final date and prevents a 2027 successor. No payment or transaction is created, and no email is sent. The earlier 20 finance records and all prior business remain unchanged; S00013 is still not invoiced by this separate test.

If your screen differs

This is stock invoice Auto-post in Odoo 20 Community, using one bounded historical annual test series and the shipped job through Run Manually. It is not the Subscriptions app or proof of automatic customer renewal, technical work or payment collection. Only Yearly, initial Confirm, the due posting job, repetition and the inclusive end were exercised. Monthly/quarterly, future-date hiding of Confirm, missing end dates, other roles, immediate disabling, cancellation/reset, changed posted recurrences and actual unattended timing remain untested. Product-cell editing cleared product selection in the initial draft and was corrected before posting. The copy retains general descriptions/terms, but not Customer Reference; this example has no sales-line link and does not prove how a sales-linked recurrence would copy that relationship. Use real reviewed dates and accounting/tax settings outside training. The historical invoices introduce synthetic open receivables; they are not actual customer debt.

Frequently asked questions

Can Odoo create recurring invoices automatically? Yes. In this tested stock Odoo 20 Community example, Auto-post Yearly and an explicit Auto-post until configure invoice recurrence. Posting the first invoice creates a next-year draft, and the shipped due-entry job posts that draft. The job was run manually in a controlled test; unattended scheduling needs a running server scheduler. Customer agreement, copied scope, dates and billing basis still require review.
Do recurring Odoo invoices charge the customer automatically? The demonstrated recurrence creates and posts invoices; it does not collect payment. Both annual test invoices remain unpaid at $254.40, with no payment transactions or new payments. No Send, Pay or provider action was used. Review payment collection separately from invoice posting and from a maintenance-agreement renewal decision.
How do I stop recurring invoices in Odoo at an end date? Set Auto-post until explicitly on the draft before the series starts. In this Yearly test, October 15, 2026 is inclusive: the invoice on that date posts, but no October 15, 2027 successor is created. Repeating the shipped job adds no duplicate. Immediate disabling, cancellation and changing an already-posted series were not tested; inspect existing generated drafts before relying on a different stop method.

Continue building the business

Continue with H53: How do I track maintenance-agreement renewals in Odoo? to plan a separate renewal review and next-term proposal. Keep the current annual agreement and H51 recurring visits distinct from this billing-mechanics fixture.

Talk to an Odoo partner

Bring your current process and the result you need to Onward to plan your Odoo workflow. Talk to an Odoo partner.