Bulk Excel Attendance Importer for Odoo 19 documentation
A guide to importing attendance from Excel or CSV: preparing the file, mapping the columns, reading the check, importing, undoing, time zones and troubleshooting.
Documents version 1.0.0Updated Oct 23, 2026
Start here
In plain words: Time clocks, fingerprint devices and spreadsheets all produce the same thing: a list of who came in and when they left. Typing it into Odoo one line at a time takes hours and is full of typos. This module turns that file into attendance records in four steps, and checks every row before anything is created.
| Step | What you do |
|---|---|
| 1. File | Choose the Excel or CSV file. |
| 2. Columns | Say which column is the employee, the check-in and the check-out. The module guesses from the titles. |
| 3. Check | See every row with its status: ready, already in Odoo, or a problem with the reason. |
| 4. Import | The ready rows become attendances. The rest are left out and can be downloaded as an Excel file to fix. |
Tip: Each import is kept as a batch. If something was wrong, one click on Undo this import removes exactly the attendances it created.
Prepare your file
In plain words: The file needs one row per attendance and a title row. It can be .xlsx, .xls or .csv (Arabic CSV files saved by Excel are understood).
| Employee ID | Check In | Check Out |
|---|---|---|
| E1001 | 2026-10-12 08:10 | 2026-10-12 17:09 |
| E1002 | 2026-10-12 08:12 | 2026-10-12 17:03 |
| E1001 | 2026-10-13 08:02 | 2026-10-13 17:15 |
| Rule | Why |
|---|---|
| One row per attendance | Two shifts in a day are two rows. |
| A title row | The first row by default. If it is lower, set the Header row. |
| Real dates and times | Excel dates are best. Text such as 2026-10-12 08:10 or 12/10/2026 8:10 PM also works. |
| Values, not formulas | A formula that Excel has not calculated has no value. Open and save the file in Excel once. |
| Employees by a stable key | A badge number or an email is safer than a name (see chapter 5). |
In plain words: You can also split date and time into separate columns: Date, Time In, Time Out. The module accepts both layouts.
Requirements
| Item | Details |
|---|---|
| Odoo | 19.0 (Community or Enterprise) |
| Apps needed | Attendances (hr_attendance) |
| Who can import | Users with the access right Attendances / Administrator |
| License | OPL-1 (Odoo Proprietary License v1.0) |
Install
- Unzip the package. Inside is
taqnix_attendance_import.zip; unzip it to get the foldertaqnix_attendance_import. - Copy the folder into one of the
addons_pathfolders of your Odoo server and restart Odoo. - Log in as an administrator, activate Developer mode, open Apps and press Update Apps List.
- Remove the “Apps” filter, search Attendance Importer and press Install.
# or from the command line ./odoo-bin -c odoo.conf -d YOUR_DATABASE -i taqnix_attendance_import --stop-after-init
Tip: A new menu appears: Attendances → Import → Import from Excel / CSV, and Past imports next to it.
How employees are found
In plain words: The file says who with a code, a name or an email. Choose in the first step how the module should find the employee:
| Find the employee by | Matches the field | Where you set it |
|---|---|---|
| Badge ID | Badge ID | Employee form → HR Settings tab |
| Identification No | Identification No | Employee form → Private Information tab |
| Work email | Work Email | Employee form → Work Information |
| Name | Employee name | Employee form (spaces and capitals do not matter) |
| Odoo ID | The database ID of the employee | Visible in the address bar when you open the employee |
In plain words: Capitals and extra spaces do not matter. Numbers that Excel stores as numbers (1001) match the text “1001”. If two employees have the same value, the row is refused with a clear message instead of guessing.
Important: Names are the weakest key: two people can share one. Use a badge number if you can.
Step 1: the file
In plain words: Open Attendances → Import → Import from Excel / CSV.
| Field | What it is |
|---|---|
| File | Your .xlsx, .xls or .csv. |
| Find the employee by | See chapter 5. |
| Sheet number | Which sheet of the workbook (1 is the first). |
| Header row | The row that holds the column titles. |
In plain words: Do not have a file yet? Download a sample file gives you a workbook with the right layout.
Step 2: the columns
| Choice | Meaning |
|---|---|
| Employee column | The column with the code, name or email. |
| Date column (optional) | Use it when the date is in its own column and the check-in/out columns hold only times. |
| Check-in / Check-out column | Dates with times, or only times when there is a date column. |
| Times in the file are in | The time zone the file was recorded in. Odoo stores UTC and converts for you. Default: your own. |
| Day before month | Read 03/04/2026 as 3 April. Real Excel dates are not affected. |
| Night shifts | A check-out earlier than the check-in means the next day (on by default). |
| Accept rows without a check-out | Create an open attendance. Off by default. |
In plain words: The list under the choices shows each column title with the first values, so you can see what is in it. The titles Employee, Badge, ID, Check In, Time In, Check Out, Time Out, Date and the Arabic موظف، دخول، خروج، التاريخ are recognised.
Step 3: check every row
In plain words: Nothing is created yet. Every row gets a status:
| Status | Meaning |
|---|---|
| Ready | Will be imported. |
| Already there | An identical attendance is already in Odoo. It is skipped, so importing the same file twice does no harm. |
| Error | Will not be imported, with the reason. |
| Message | What to do |
|---|---|
| No employee found with this value | The code, name or email is not in Odoo, or you chose the wrong “Find the employee by”. |
| N employees have this value | Two employees share it. Use a more precise key. |
| The date or time is missing or not readable | Fix the cell (a real date, or text like 2026-10-12 08:10). |
| There is no check-out | Add it, or accept rows without a check-out. |
| The check-out is not after the check-in | Check the file. With night shifts on this is rare. |
| More than 24 hours between check-in and check-out | Probably a wrong date. |
| Overlaps an attendance already in Odoo / Overlaps row N | Odoo does not allow overlapping attendances for one person. |
In plain words: Errors come first in the list. You can Back to change the columns and check again as often as you like. Import is only possible when at least one row is ready.
Step 4: import, open, undo
In plain words: Press Import the ready rows. The rows that are ready become attendances; rows with errors are left out.
In plain words: Download the failed rows gives an Excel file with the row number, what was in the file and why it failed, so you can correct only those rows and import them again.
| On the batch | What it does |
|---|---|
| Show the attendances | Opens the attendances created by this import. |
| Undo this import | Deletes exactly those attendances (asks first). The batch stays in the list as “Undone”. |
| Download the failed rows | The Excel file of rows that were not imported. |
In plain words: Attendances → Import → Past imports lists every import: who, when, how many rows, how many were created and how many failed.
Tip: Odoo then works out the worked hours and the overtime from the attendances in the usual way, the same as for attendances created by hand.
Dates and times it understands
| In the file | Read as |
|---|---|
| A real Excel date and time | As it is |
| 2026-10-12 08:10 | 12 Oct 2026, 08:10 |
| 12/10/2026 8:10 PM with “Day before month” | 12 Oct 2026, 20:10 |
| 12/10/2026 8:10 PM without it | 10 Dec 2026, 20:10 |
| 8:05, 08.05, 8:05 PM | A time of day (with a date column) |
| ٢٠٢٦-١٠-١٢ ٠٨:١٠ and ٨:٣٠ م | Arabic digits and Arabic AM/PM are understood |
| 46307.34 (a number) | An Excel date serial number |
| Only a time in the check-out cell | The date of the check-in is used |
Time zones and clock changes
In plain words: Time clocks write local time. Odoo stores UTC. In step 2 choose the time zone the file was recorded in (it starts as your own) and the module converts every row. A time that does not exist or exists twice because of a daylight-saving change is read as standard time instead of failing.
Important: Odoo shows times in the browser's time zone. If you work from another country, the times you see can differ from the file by the difference between the two zones.
Limits
| Limit | Detail |
|---|---|
| Rows | Up to 20,000 data rows per import. Split bigger files. |
| Sheets | One sheet per import: choose its number in step 1. |
| Protected files | Password-protected workbooks cannot be read: remove the password first. |
| Formulas | Their calculated values are used, so the file must have been saved by Excel. |
| Existing attendances | Never changed. Identical ones are skipped, overlapping ones are reported. |
| One open attendance | Odoo allows one open (no check-out) attendance per employee at a time. |
For developers
In plain words: Skip this chapter if you only use the module.
| Item | Details |
|---|---|
| Models | taqnix.attendance.import (wizard), taqnix.attendance.import.header, taqnix.attendance.import.line, and the persistent taqnix.attendance.batch. |
| Link | hr.attendance.taqnix_batch_id points to the batch that created an attendance. |
| Parsing | models/parsing.py has plain functions with no database: read_table, parse_datetime, parse_time, parse_date, local_to_utc, guess_columns. |
from odoo.addons.taqnix_attendance_import.models import parsing
sheet, headers, rows = parsing.read_table(content, 'march.xlsx')
parsing.parse_time('٨:٣٠ م') # datetime.time(20, 30)
parsing.local_to_utc(naive_dt, 'Asia/Riyadh')Troubleshooting
| Problem | What to do |
|---|---|
| There is no Import menu | You need the access right Attendances / Administrator. |
| “The file could not be read” | Open it in Excel and save it again as .xlsx, or save as CSV. Remove any password. |
| All rows say “No employee found” | Wrong “Find the employee by”, or the badge IDs are not set on the employees yet. |
| Times are shifted | Check “Times in the file are in” (step 2). |
| Days and months are swapped | Tick or untick “Day before month” (only for text dates). |
| Rows say “Overlaps an attendance already in Odoo” | The person already has an attendance in that period. Check it in Attendances, or undo the earlier import. |
| I imported the wrong file | Open Past imports, open the batch and press Undo this import. |
Updating and removing
Replace the folder with the new version, restart Odoo and run -u taqnix_attendance_import. To remove it, uninstall it from Apps. The attendances already imported stay in Odoo as ordinary attendances; the list of past imports is removed.
Support
Installation help and bug fixes are included for 6 months, with lifetime updates. Contact us through the marketplace page where you bought the module or write to support@taqnix.com with your Odoo version and a screenshot.