Running an HVAC business with Odoo

How do I submit and approve employee expenses in Odoo?

Workflow overview: How do I submit and approve employee expenses in Odoo?
Workflow overview. Instructional screenshots show the actual demo interface.

Submit an Odoo employee expense with a receipt, verify reviewer access, inspect its draft Purchase Receipt and record a separate synthetic reimbursement.

A technician buys small shop supplies and needs Alex to review the expense. This example retains a $12.72 fictional receipt, routes the technician’s submission to the owner, reviews the accounting draft and records a separate synthetic reimbursement. Approval, posting and payment are distinct steps. The final Paid state clears the employee payable, while bank settlement remains a separate check.

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. Use the linked employee and access setup from How do I create an employee record in Odoo?, How do I set user access rights in Odoo? and How do I assign a technician and deadline to an Odoo task?, the invoicing setup from How do I set up US invoicing in Odoo? and bank journal from How do I set up bank accounts and payment journals in Odoo?. The submitter is Demo Technician H42, using the employee and linked user from those prerequisites. The reviewer is Demo Air Owner, with the official Expenses Administrator role after activation and existing Invoicing permission. Prepare the clearly labelled PDF receipt DEMO-H60-RECEIPT-001: October 14, shop supplies $12 plus $0.72 demo tax, total $12.72 USD, employee-paid. A separate fictional reimbursement input supplies $12.72 on October 14, memo DEMO-H60-REIMBURSE-001. These are synthetic assumptions, not proof of a purchase, tax treatment or money movement. Local mail remains in Mailpit.

Step-by-step workflow

Step 1. Activate the official Expenses app

As the owner administrator, open Apps and find Expenses, technical name hr_expense. Click its Activate button once and wait for installation. This test installed the official Odoo S.A./LGPL-3 module. The app supplies expense products including Expenses, reference EXP_GEN. No Enterprise expense feature or custom add-on is used. Refresh the technician’s browser so Expenses appears in the apps menu.

Action 1: Find the official Expenses module by its technical name. The actual target is highlighted in gold.
Find the official Expenses module by its technical name.
Action 2: Activate official Expenses once in this training company. The actual target is highlighted in gold.
Activate official Expenses once in this training company.

Step 2. Configure the employee’s reviewer before submission

As the owner, open Employees → Demo Technician H42 → Settings. In Expense, select Demo Air Owner and save the employee. Keep the technician linked to its existing user; its ordinary user groups remain unchanged and include no expense-approver group. Check the saved reviewer before creating and submitting the expense. During earlier verification, a Manager selection on the new expense form did not survive creation. Setting the employee’s Expense reviewer before submission stored the intended owner as Manager. In the illustrated workflow, this employee setting is saved before the new expense is created. Do not assume an empty reviewer means a separate approval will occur.

Action 3: Open the technician employee Settings as the owner. The actual target is highlighted in gold.
Open the technician employee Settings as the owner.
Action 4: Choose Demo Air Owner as the employee Expense reviewer. The actual target is highlighted in gold.
Choose Demo Air Owner as the employee Expense reviewer.
Action 5: Save the employee reviewer before any expense submission. The actual target is highlighted in gold.
Save the employee reviewer before any expense submission.
Action 6: Verify the saved owner reviewer on this same employee. The actual target is highlighted in gold.
Verify the saved owner reviewer on this same employee.

Step 3. Enter the employee-paid expense

In the technician’s session, open Expenses → My Expenses → New. Enter Demo technician shop supplies H60 in Description. In Product, choose the actual Expenses / EXP_GEN dropdown option. Enter 12.72 in Total. The selected existing 6% Included taxes calculates $0.72 tax and $12 untaxed; the expense total includes this tax. Verify Employee: Demo Technician H42, Date October 14, and Employee (Through a Purchase Receipt) under Reimbursement. The other choice is None (Paid by Company) and is not used here. Add Notes with the unique receipt reference, purpose and explicit training context, then save.

Action 7: Create one employee-paid expense in the technician session. The actual target is highlighted in gold.
Create one employee-paid expense in the technician session.
Action 8: Describe the fictional shop-supplies expense. The actual target is highlighted in gold.
Describe the fictional shop-supplies expense.
Action 9: Choose the actual Expenses product, reference EXP_GEN. The actual target is highlighted in gold.
Choose the actual Expenses product, reference EXP_GEN.
Action 10: Enter total 12.72 including the existing demo tax. The actual target is highlighted in gold.
Enter total 12.72 including the existing demo tax.
Action 11: Open Date for the labelled training receipt. The actual target is highlighted in gold.
Open Date for the labelled training receipt.
Action 12: Set October 14, 2026 from the fictional receipt. The actual target is highlighted in gold.
Set October 14, 2026 from the fictional receipt.
Action 13: Keep Employee through a Purchase Receipt as reimbursement. The actual target is highlighted in gold.
Keep Employee through a Purchase Receipt as reimbursement.
Action 14: Retain the unique fictional receipt and review context. The actual target is highlighted in gold.
Retain the unique fictional receipt and review context.
Action 15: Save this one technician expense before attaching its receipt. The actual target is highlighted in gold.
Save this one technician expense before attaching its receipt.

Step 4. Attach and check the actual receipt

Click Attach Receipt and choose the labelled h60-synthetic-receipt.pdf. Verify the file is retained on this saved expense. Its content shows the fictional merchant, employee, receipt reference/date, $12 net, $0.72 demo tax, $12.72 total and employee-paid assumption. The uploaded PDF is 21,786 bytes and matches the prepared file. This document is a training fixture; use the actual receipt and the business’s receipt-review process for a real expense. Do not submit the same purchase again just because the screen has refreshed.

Action 16: Attach the existing labelled fictional receipt PDF once. The actual target is highlighted in gold.
Attach the existing labelled fictional receipt PDF once.
Action 17: Review the same saved expense after attaching its receipt. The actual target is highlighted in gold.
Review the same saved expense after attaching its receipt.

Step 5. Submit as the technician and inspect the role boundary

Click Submit once. Reopen the same expense: it is Submitted, Manager is Demo Air Owner and the receipt remains linked. The technician sees Reset, with no Approve or Refuse control, and its saved Can Approve result is false. This proves the inspected ordinary-employee view; it does not test arbitrary approval requests or every role arrangement. Submission also creates an owner Expense Approval activity. One native New expenses waiting for your approval email reaches the owner in the local sink. No customer message or real external delivery is involved.

Action 18: Submit the same expense once to its configured owner. The actual target is highlighted in gold.
Submit the same expense once to its configured owner.
Action 19: Technician can Reset; owner approval remains a separate action. The actual target is highlighted in gold.
Technician can Reset; owner approval remains a separate action.

Step 6. Review the submission in the owner’s queue

As the owner, open Expenses → My Expenses → Expenses to Process. The Submitted filter contains this one expense. Open it and verify employee, purpose, amount/currency, tax, reimbursement choice, manager and payment method. Use the paperclip attachment control to reveal the receipt; open it or choose Download. The owner’s native download matches the technician’s uploaded PDF. This owner view exposes Approve and Refuse. Review possible prior submissions and the underlying purchase evidence before approving; this lesson does not exercise a duplicate-receipt submission.

Action 20: Open the owner expense-processing queue. The actual target is highlighted in gold.
Open the owner expense-processing queue.
Action 21: Choose Expenses to Process for submitted employee expenses. The actual target is highlighted in gold.
Choose Expenses to Process for submitted employee expenses.
Action 22: Open the same one submitted technician expense. The actual target is highlighted in gold.
Open the same one submitted technician expense.
Action 23: Review the submitted total, tax and employee-paid choice. The actual target is highlighted in gold.
Review the submitted total, tax and employee-paid choice.
Action 24: Reveal the saved receipt through the paperclip control. The actual target is highlighted in gold.
Reveal the saved receipt through the paperclip control.
Action 25: Review the actual uploaded receipt before approving. The actual target is highlighted in gold.
Review the actual uploaded receipt before approving.
Action 26: Download the actual saved receipt and compare its bytes. The actual target is highlighted in gold.
Download the actual saved receipt and compare its bytes.

Example fictional receipt uploaded to the expense

This one-page training receipt is the file attached in Step 4 and downloaded by the owner in Step 6. It shows the fictional shop-supplies purchase dated October 14, 2026: $12 plus $0.72 demo tax, total $12.72. Its employee-paid label is an assumption for this lesson. It is a supplied example, not an Odoo-generated financial report or evidence of a real purchase or repayment.

Download the fictional training receipt (PDF, 1 page)

Fictional Demo Counter Store H60 receipt DEMO-H60-RECEIPT-001 for Demo Technician H42: October 14, 2026, shop supplies $12, demo tax $0.72, total USD12.72; employee-paid is a training assumption.
Example fictional receipt uploaded to the expense, page 1 of 1. Open the image to inspect the complete page.

Step 7. Approve and inspect the accounting draft

Click Approve once. The expense becomes Approved and gains Journal Entry. Approval also creates one Draft Purchase Receipt for $12.72; no payment has been created. The approval activity is completed by the workflow. In this test, the generic expense product initially selected Cost of Goods Sold. Review the actual account choice rather than treating that default as a recommendation for all shop or office supplies.

Action 27: Approve once; inspect the separately created accounting draft. The actual target is highlighted in gold.
Approve once; inspect the separately created accounting draft.
Action 28: Journal Entry is now available; posting remains separate. The actual target is highlighted in gold.
Journal Entry is now available; posting remains separate.

Step 8. Expose the owner’s existing accounting-view controls

The owner’s initial Invoicing role did not display the expense Account field. As the administrator, open Settings → General Settings. If Users & Companies does not show Groups, scroll to Developer Tools, click Activate the developer mode, and wait for Settings to reload. Then open Users & Companies → Groups and the existing Show Accounting Features - Readonly group. Under Users, click Add a line, select only Demo Air Owner, click Select, and save. Refresh the owner session; after the saved permission change and reload, the Account control appears. This changes membership in an existing stock group, with its definitions unchanged. The technician receives no new role. The owner’s existing Invoicing permission supplies its accounting write access.

Action 29: Open Settings to expose the existing Groups menu. The actual target is highlighted in gold.
Open Settings to expose the existing Groups menu.
Action 30: Activate developer mode through the native Developer Tools control. The actual target is highlighted in gold.
Activate developer mode through the native Developer Tools control.
Action 31: Open Users and Companies after activating developer mode. The actual target is highlighted in gold.
Open Users and Companies after activating developer mode.
Action 32: Choose the existing Groups list. The actual target is highlighted in gold.
Choose the existing Groups list.
Action 33: Find Show Accounting Features - Readonly. The actual target is highlighted in gold.
Find Show Accounting Features - Readonly.
Action 34: Open this stock group without editing its definitions. The actual target is highlighted in gold.
Open this stock group without editing its definitions.
Action 35: Add one existing user to this group. The actual target is highlighted in gold.
Add one existing user to this group.
Action 36: Select only Demo Air Owner for this existing membership. The actual target is highlighted in gold.
Select only Demo Air Owner for this existing membership.
Action 37: Add the selected owner; leave technician permissions unchanged. The actual target is highlighted in gold.
Add the selected owner; leave technician permissions unchanged.
Action 38: Save the existing stock group membership. The actual target is highlighted in gold.
Save the existing stock group membership.
Action 39: Verify the saved Users list contains only the owner. The actual target is highlighted in gold.
Verify the saved Users list contains only the owner.

Step 9. Review both the expense account and its already-created draft line

On the Approved expense, set Account to the existing Office Expenses / Office Supplies option and save. Then open Journal Entry. The draft has Receipt selected, vendor Demo Technician H42, Purchases journal, $12 untaxed, $0.72 demo tax and $12.72 total. Changing the expense’s Account after approval did not update this already-created draft’s line: it still showed Cost of Goods Sold. In Invoice Lines, click the actual Account cell and select Office Expenses / Office Supplies on that draft line as well. Click a stable heading to commit the cell, then save and wait for pending changes to clear.

Review Bill Date, Accounting Date and Due Date separately before posting. In this capture, approval on October 16 created Bill Date and Accounting Date as October 16 even though the expense and receipt were dated October 14. For this fictional example, click Bill Date and choose October 14, 2026, then save. Reopen the draft and check Accounting Date; it still showed October 16. Click that field, choose October 14, 2026, and save again. These are explicit training inputs; the dates did not automatically copy from the expense or from one another.

Reopen the same draft before Confirm. Verify Bill Date: October 14, Accounting Date: October 14, the actual Office Supplies line, the same expense link and the unchanged $12.72 total. Due Date remained October 16 in the captured example; review it separately against the payment terms. Use dates and account/tax treatment appropriate to the real business’s records.

Action 40: Review Account on this Approved employee expense. The actual target is highlighted in gold.
Review Account on this Approved employee expense.
Action 41: Choose existing Office Expenses / Office Supplies. The actual target is highlighted in gold.
Choose existing Office Expenses / Office Supplies.
Action 42: Save the expense account; its existing draft line still needs review. The actual target is highlighted in gold.
Save the expense account; its existing draft line still needs review.
Action 43: Open the already-created Purchase Receipt. The actual target is highlighted in gold.
Open the already-created Purchase Receipt.
Action 44: Review the actual Bill Date default from approval. The actual target is highlighted in gold.
Review the actual Bill Date default from approval.
Action 45: Open Bill Date on this same unposted receipt. The actual target is highlighted in gold.
Open Bill Date on this same unposted receipt.
Action 46: Set October 14, 2026 for the labelled training receipt. The actual target is highlighted in gold.
Set October 14, 2026 for the labelled training receipt.
Action 47: Edit the actual draft line Account, still Cost of Goods Sold. The actual target is highlighted in gold.
Edit the actual draft line Account, still Cost of Goods Sold.
Action 48: Select Office Supplies on the actual linked draft line. The actual target is highlighted in gold.
Select Office Supplies on the actual linked draft line.
Action 49: Save and verify the reviewed date and actual draft account. The actual target is highlighted in gold.
Save and verify the reviewed date and actual draft account.
Action 50: Reopen and verify the saved Bill Date before posting. The actual target is highlighted in gold.
Reopen and verify the saved Bill Date before posting.
Action 51: Verify Office Supplies on the same saved receipt line. The actual target is highlighted in gold.
Verify Office Supplies on the same saved receipt line.
Action 52: Accounting Date is a separate visible date to review. The actual target is highlighted in gold.
Accounting Date is a separate visible date to review.
Action 53: Open Accounting Date for this fictional receipt. The actual target is highlighted in gold.
Open Accounting Date for this fictional receipt.
Action 54: Set Accounting Date to October 14, 2026 explicitly. The actual target is highlighted in gold.
Set Accounting Date to October 14, 2026 explicitly.
Action 55: Save and reopen both chosen dates before posting. The actual target is highlighted in gold.
Save and reopen both chosen dates before posting.
Action 56: Both saved Bill Date and Accounting Date are October 14. The actual target is highlighted in gold.
Both saved Bill Date and Accounting Date are October 14.

Step 10. Post the reviewed Purchase Receipt

On this same draft Purchase Receipt, click Confirm. It becomes Posted, number BILL/2026/10/0002. The expense becomes Posted, still with $12.72 Amount Due. Its ledger contains $12 Office Supplies, $0.72 Tax Paid and $12.72 Accounts Payable to Demo Technician H42. Payment count remains unchanged. This native route uses the linked receipt’s Confirm control; it does not rely on an unobserved Post button on the expense form.

Action 57: Confirm this one reviewed Purchase Receipt once. The actual target is highlighted in gold.
Confirm this one reviewed Purchase Receipt once.
Action 58: Posted receipt still has 12.72 due to the employee. The actual target is highlighted in gold.
Posted receipt still has 12.72 due to the employee.

Step 11. Record the separate confirmed reimbursement

Confirm the real repayment independently before recording it. The training input supplies only a fictional $12.72 reimbursement dated October 14. On the posted Purchase Receipt click Pay. Verify Demo Operating Bank H73, Amount 12.72 and the date; enter DEMO-H60-REIMBURSE-001 in Memo and click Create Payment once. Recipient Account is blank in this Manual Payment case. The receipt changes to Paid/$0 due and the expense changes to Paid. No bank transfer is initiated by this record.

Action 59: Record only the separately assumed fictional reimbursement. The actual target is highlighted in gold.
Record only the separately assumed fictional reimbursement.
Action 60: Use the existing Demo Operating Bank H73 journal. The actual target is highlighted in gold.
Use the existing Demo Operating Bank H73 journal.
Action 61: Recipient Account is blank; Manual Payment sends no money. The actual target is highlighted in gold.
Recipient Account is blank; Manual Payment sends no money.
Action 62: Record only the fictional confirmed reimbursement of 12.72. The actual target is highlighted in gold.
Record only the fictional confirmed reimbursement of 12.72.
Action 63: Open Payment Date to use the training date. The actual target is highlighted in gold.
Open Payment Date to use the training date.
Action 64: Set and commit October 14, 2026 for this training reimbursement. The actual target is highlighted in gold.
Set and commit October 14, 2026 for this training reimbursement.
Action 65: Use the unique fictional reimbursement reference. The actual target is highlighted in gold.
Use the unique fictional reimbursement reference.
Action 66: Check 12.72, October 14, journal and memo before creating. The actual target is highlighted in gold.
Check 12.72, October 14, journal and memo before creating.
Action 67: Create one fictional reimbursement record; no money is sent. The actual target is highlighted in gold.
Create one fictional reimbursement record; no money is sent.
Action 68: Receipt Paid now has zero Amount Due. The actual target is highlighted in gold.
Receipt Paid now has zero Amount Due.

Step 12. Reopen as both roles and separate payable matching from bank settlement

On the receipt, open 1 Payments. With one result, it opens the payment directly: PBNK1/2026/00008, Send, vendor Demo Technician H42, $12.72, October 14, the unique memo, Manual Payment and Reconciled. Its 1 Bill button links to the same Purchase Receipt. Refresh the technician’s expense: it also shows Paid and retains its receipt/reviewer, with no Approve control. The $12.72 payable is matched, while Outstanding Payments retains an unmatched $12.72 credit and Bank has no entry. Reopening retains one expense, one purchase receipt and one reimbursement payment; no broader duplicate guarantee is established.

Action 69: Open the receipt’s one recorded payment. The actual target is highlighted in gold.
Open the receipt’s one recorded payment.
Action 70: Saved reimbursement PBNK1/2026/00008. The actual target is highlighted in gold.
Saved reimbursement PBNK1/2026/00008.
Action 71: Payment Type is Send, not Receive. The actual target is highlighted in gold.
Payment Type is Send, not Receive.
Action 72: The outgoing amount is 12.72 for Demo Technician H42. The actual target is highlighted in gold.
The outgoing amount is 12.72 for Demo Technician H42.
Action 73: The recorded reimbursement date is October 14. The actual target is highlighted in gold.
The recorded reimbursement date is October 14.
Action 74: The unique memo identifies this fictional reimbursement. The actual target is highlighted in gold.
The unique memo identifies this fictional reimbursement.
Action 75: Review saved Manual Payment. The actual target is highlighted in gold.
Review saved Manual Payment.
Action 76: Return through 1 Bill to this same Purchase Receipt. The actual target is highlighted in gold.
Return through 1 Bill to this same Purchase Receipt.
Action 77: Technician reopens the same Paid expense with no Approve control. The actual target is highlighted in gold.
Technician reopens the same Paid expense with no Approve control.
Action 78: The owner reviewer remains on the technician’s saved expense. The actual target is highlighted in gold.
The owner reviewer remains on the technician’s saved expense.
Action 79: Paid expense retains the same 12.72 total and training context. The actual target is highlighted in gold.
Paid expense retains the same 12.72 total and training context.

Check the result

One technician-created $12.72 employee-paid expense retains the matching synthetic receipt and the owner reviewer. The ordinary technician submission waits in Submitted with no approval control; the owner reviews and approves it. Approval creates a draft Purchase Receipt. The existing accounting-view group exposes Account; a separate correction of the actual draft line is needed after changing the expense account. Confirm posts $12 Office Supplies plus $0.72 demo tax against the employee payable. One separately recorded outgoing Manual Payment clears the receipt and expense to Paid/$0 due. The same receipt is accessible to the owner and retained on employee reopen. Outstanding Payments remains unmatched and Bank is unchanged. Prior payments, invoice balances and the two existing open reviews remain intact.

If your screen differs

Only one ordinary technician and the owner administrator were tested, with the employee’s Expense reviewer configured before submission. Team Approver, All Approver, no-approver/self-approver configurations, another employee’s access, refusal and duplicate-receipt blocking were not exercised. Company-paid expenses, existing-bill matching, other currencies, payroll reimbursement and electronic disbursement need their own checks. An empty Manager or an administrator’s own expense must not be used as proof of a separated approval process. Approval created a draft accounting document; the already-created line did not follow a later parent Account edit. Check and correct the actual draft before posting. Office Supplies and 6% tax are synthetic example choices, not tax/accounting advice. Paid/Reconciled reflects the recorded employee-payable match; the $12.72 outstanding entry is still unmatched and no actual repayment or bank settlement is established. Later native bank/reporting controls under the added accounting-view group have not been reverified here.

Frequently asked questions

How do I submit employee expenses in Odoo? Verify the employee/reviewer setup, create the expense in My Expenses, choose the product and who paid, enter total/date and attach the real receipt. Save and use Submit. In this test the technician’s one $12.72 expense waited in Submitted for the configured owner, who could review it under Expenses to Process.
Can employees approve their own Odoo expenses? The tested ordinary technician had no expense-approver role, no Approve button and Can Approve false. Its submitted expense waited for the configured owner, whose view exposed Approve/Refuse. This does not establish behavior for administrators or no-approver/self-approver arrangements; configure the employee’s Expense reviewer and check the actual saved route.
Does approving an Odoo expense reimburse the employee? Approval here created a Draft Purchase Receipt. Confirm posted the reviewed cost and $12.72 employee payable, still unpaid. A separate Pay/Create Payment step recorded the independently assumed synthetic reimbursement and cleared that payable. The resulting Paid/Reconciled state left Outstanding Payments unmatched and created no Bank entry or actual transfer.

Continue building the business

Continue with How do I sell an HVAC maintenance agreement in Odoo?. The expense reimbursement’s outstanding entry belongs in the separate What can I do for bank reconciliation in Odoo? (guide coming later); its Paid label does not settle the bank.

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.