| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Attendances (hr_attendance)
• Discuss (mail) • Employees (hr) |
| Community Apps Dependencies | Show |
| Lines of code | 2027 |
| Technical Name |
eh_hr_attendance_payroll_export |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Attendances (hr_attendance)
• Discuss (mail) • Employees (hr) |
| Community Apps Dependencies | Show |
| Lines of code | 2027 |
| Technical Name |
eh_hr_attendance_payroll_export |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Versions | 16.0 17.0 18.0 19.0 |
Payroll Export for Attendance
Turn captured attendance into the exact CSV your payroll vendor's bulk import expects, with a full audit trail of every file you have generated.
Why this module
Payroll Export for Attendance
CSV by design, not a fragile API link
This module does not hold live credentials against any payroll vendor. It builds the exact bulk-import file each system expects and you upload it through the vendor's own portal once per cycle. Nothing breaks when a vendor rotates an API.
See the file before you commit it
Every run defaults to dry-run. You get the row count, employee count, total hours, and the first lines of the actual file before a single record is saved. Flip dry-run off only when the numbers look right.
Every export is kept and read-only
Each committed run stores the file bytes, provider, date range, totals, who ran it, and when, on a form that cannot be edited or created by hand. Re-download any past export at any time without regenerating it.
Day in the life
Pay-cycle Monday, ten minutes before payroll
Open the export wizard, pick your provider (it defaults to the company's preferred one), set the pay period, and leave dry-run on. The preview shows 47 rows across 23 employees, 911.50 hours, and the first lines of the Xero file. Split shifts have already collapsed to one row per person per day and the half-finished clock-in from this morning is excluded. You turn dry-run off, run it, and the file lands on a saved run record. You download it, upload it to the vendor portal, and the run sits in the audit list for the next time finance asks what was sent.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
Multiple attendances on the same day for the same employee aggregate into one row, summing hours and keeping the earliest check-in and latest check-out. A lunch-split day becomes a single 8-hour line, not two.
A clock-in with no clock-out is excluded by default so half-shifts do not skew the export. Turn the flag on to include them, and elapsed hours are capped at the date_to cutoff rather than running open-ended.
A date range where the end precedes the start is rejected by a constraint before any rows are gathered, so you cannot silently produce an empty or backwards file.
A range with no attendance still emits a valid file with the provider's header row and zero data rows, so downstream tooling never chokes on a truncated or headerless file.
Rows are scoped to the wizard's company, and saved run records carry a company_id behind a record rule, so one company's operators never see or export another company's attendance.
MYOB rows use an employee external reference for the Card ID and fall back to work email when none is set, so the file is still importable even before external references are populated.
Files are written with a UTF-8 BOM so names with accents open cleanly in spreadsheet tools without manual encoding fixes.
Re-exporting the same range is allowed. The new run sits next to the old one in the audit list rather than overwriting it, so history is preserved.
What is inside
Built to do the job, end to end.
- Five exporters behind one wizard. Generic CSV plus Xero Payroll, KeyPay, Employment Hero, and MYOB AccountRight / Essentials. Each is an isolated formatting function mapping the common aggregated row to that vendor's exact header set, so a new vendor is one function plus one selection entry.
- Aggregate-then-format pipeline. The wizard gathers attendance, collapses it to one row per employee and date with summed hours and bracketing timestamps, then hands a uniform row shape to the chosen exporter. Gathering and formatting never tangle.
- Read-only run records on the chatter. Committed runs land on eh.hr.payroll.export.run with mail.thread tracking, a create-false edit-false form, and the file as an attachment. Managers can create runs but not delete them, admins can, and an auditor group gets read-only access.
- Company defaults and retention setting. Settings expose a default provider per company and a retention horizon in days (default 730, two financial years). A batched per-company retention method is provided to trim old runs when scheduled.
- Optional analytic and project carry-through. When the attendance job-cost module is installed, analytic account name and code plus project name ride through into Xero Tracking 1, KeyPay and Employment Hero cost centre, and MYOB Job. The lookup is defensive, so the exporter runs fine without it.
- Tested formats and aggregation. Pure-Python exporter tests pin every provider's header and row layout, and wizard tests cover split-shift aggregation, employee filtering, open-attendance handling, date validation, and dry-run versus committed runs.
Honest about the edges
What this does not do, so nothing surprises you.
- CSV files only. There are no live API connectors to any payroll vendor. You upload the generated file through the vendor's own portal.
- The retention sweep is provided as a batched method but is not scheduled out of the box. Pruning of old runs is not automatic until you wire a scheduled action to call it.
- MYOB Card ID uses an employee external reference field that this suite does not itself populate, so today it falls back to work email unless that field is supplied by another module.
- Analytic and project carry-through only appears when the attendance job-cost module is installed. Without it, those columns are written empty.
- Employee matching in the file is by work email (or name for Xero, external ref or email for MYOB). The vendor still does its own matching on import.
- Hours come straight from attendance duration. There is no overtime classification, penalty rates, leave, or proration in this module.
- Depends on the ERP Heritage attendance base and the standard hr_attendance module.
payroll export Odoo, attendance to payroll CSV, Xero timesheet export Odoo, KeyPay timesheet import, Employment Hero timesheet export, MYOB timesheet import Odoo, hr_attendance payroll, timesheet CSV export, Odoo 19 Community payroll export, attendance hours export, multi-company payroll export, payroll bulk import file, Odoo attendance CSV, pay cycle export Odoo, dry run payroll preview
Please log in to comment on this module