Employment Hero Timesheet
Bring worked hours from the people platform into the standard Odoo Timesheets app as analytic lines, no custom code.
Store price is USD 117 all-in: installing this also pulls the 2 paid ERP Heritage modules it depends on.
Why this module
Employment Hero Timesheet
Hours flow in once, keyed by external id
Every entry carries its source id through the cross reference, so a job can run on a schedule and land each timesheet line exactly once. Re running the job never duplicates an analytic line, and an unchanged entry is a no op.
Endpoints and field mapping ship as data
The API path, the project and task resolution and every field mapping live as configuration rows you can adjust to your own organisation's payload shape from the interface. Adapting to a different field name is a row edit, not a code deployment.
Counts and errors recorded per sync
Each run records what was fetched, created, updated, skipped and failed, with a line per record. One bad entry is isolated and logged, and the run finishes in a partial state rather than aborting the whole batch.
Day in the life
A services team that runs payroll and rostering on the people platform but bills and reports project hours in Odoo
Overnight the timesheet job pulls the latest entries from the people platform and writes them into Odoo Timesheets as analytic lines, each resolved to the right employee and project through the cross reference. An entry whose project is not yet mapped is reported as an error and skipped, so nothing lands against no project; the team maps the project once and it flows on the next run. Entries that already exist are matched by their source id and left alone unless they changed upstream, so the job is safe to schedule frequently. Project managers see worked hours in the standard Timesheets app without anyone retyping a spreadsheet, and the run log shows exactly what came across.
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.
Each entry is keyed by its external id through the cross reference, so re running a job, or replaying the same webhook delivery, upserts the existing analytic line instead of creating a duplicate. An unchanged payload is detected by hash and skipped.
Every record is processed inside its own savepoint. A single failing entry (for example a write error) rolls back just that record, is logged as an error line, and the run continues and ends in a partial state rather than poisoning the whole batch.
Odoo requires a project on every analytic line. An entry whose project cannot be resolved through the cross reference is reported as an error and skipped, never created against no project. A deployment maps a default project once and those entries flow on the next run.
The list endpoint is read page by page (the engine supports page number, odata skip and cursor styles) with a page cap that warns loudly when hit, so a large history is fetched in bounded requests rather than one unbounded call.
Transient failures (timeouts, 5xx) and rate limit responses are retried with exponential backoff and jitter. A server Retry-After header is honoured and clamped, so a hostile or buggy header cannot park a worker for hours; non retryable errors raise immediately.
On the OAuth2 leg the access token is fetched through a refresh callback on each request, so an expired token is renewed transparently and the sync does not stall on a stale credential.
When the job runs in delta mode the cursor advances only to the high water mark of records that processed successfully, and never past a failed record, so a failed or concurrently changed entry is re fetched next run instead of being skipped forever.
The shipped job is two way but its push domain is empty by default, so the push leg stays dormant until a deployment narrows it. A push create carries a stable idempotency key, so a retried create is deduplicated by the platform rather than duplicated.
The external id cross reference is scoped to the connection and its company, so the same source id in two companies resolves to the right record and never collides across a multi company database.
What is inside
Built to do the job, end to end.
- Endpoints as data. Three Employment Hero endpoints ship as records: the organisation level timesheet list (paginated), the per employee timesheet read, and the create endpoint used by the optional push leg. Adjust the path to the resource your organisation exposes.
- Timesheet mapping. A pull mapping onto account.analytic.line maps the entry comment to the line description, the worked units to the unit amount, the date, and resolves employee, project and (optionally) task through the external id cross reference. Marked fields are required so a malformed entry fails cleanly.
- Two way sync job. One sync job binds the list endpoint, the mapping and the analytic line model, with an external id path, an updated at path for delta and conflict handling, a conflict policy and a push policy. Direction is two way with the push domain left empty for you to narrow.
- Runs on the shared engine. All sync behaviour (idempotent upsert, per record isolation, pagination, retry and backoff, conflict policies, audited runs) is provided by the Employment Hero sync engine and connector this module depends on, not reimplemented here.
- Automated tests. Ships a test suite that drives the shipped mapping and job against a fake API, asserting that a timesheet entry creates an analytic line with the right employee, project and units, and that the push leg posts a line back with the employee resolved to its external id.
Honest about the edges
What this does not do, so nothing surprises you.
- This is a configuration module. It ships endpoints, a field mapping and a sync job as data on top of the Employment Hero connector and sync engine, which it depends on. It adds no new screens or Python models of its own.
- Odoo requires a project on every analytic line. You must make sure a default project exists and is mapped through the cross reference; entries with no resolvable project are reported as errors and skipped, not created against no project.
- Employees and projects must already exist in Odoo and be cross referenced (synced or registered) before timesheet entries can resolve their relations. Sync the HR data first.
- The shipped job is two way, but the push leg is dormant by default because its push domain is empty. The push direction only activates once a deployment narrows the domain to the records it wants sent back.
- Webhook delivery, signature verification and replay protection are handled by the separate Webhook module of the suite. This module ships no webhook subscription of its own; on a schedule it pulls, and on a webhook trigger the engine can fetch a single entry by id.
- The shipped field paths assume a typical Employment Hero payload shape (comment, units, employee_id, project_id, date). If your organisation's payload differs, adjust the mapping source paths; the defaults are a starting point, not a guarantee for every account.
- No price, billing or invoicing logic. This module moves worked hours into Odoo Timesheets as analytic lines; what you do with those hours downstream is standard Odoo.
employment hero timesheet odoo, employment hero timesheet integration, odoo timesheet sync, employment hero connector odoo, hr_timesheet integration, analytic line import odoo, project hours sync, worked hours integration, keypay timesheet odoo, people platform timesheet sync, odoo 19 timesheet integration, idempotent timesheet sync, data driven field mapping odoo, scheduled timesheet job, odoo community timesheet connector, external id cross reference sync, two way timesheet sync, erp heritage employment hero
Need this fitted to the way you work?
ERP Heritage delivers end to end Odoo work: Odoo Implementation, Customization and Development, Integration, Migration, Consultation, Support and Training. We help teams put this module into production, shape it to their process, and keep it running.
We work with businesses across Australia (Melbourne, Sydney, Brisbane, Perth, Adelaide, Canberra) and the Middle East (Dubai, Abu Dhabi, Riyadh, Jeddah, Doha, Kuwait City, Muscat). Start a conversation at erpheritage.com.au or email info@erpheritage.com.au.
Languages
Available in 19 languages
The interface ships translated out of the box. Switch language in Odoo and the fields, menus, and messages follow.
Modules teams pair with this one.
Premium ERP Heritage modules that extend the same stack, each built to the same engineering bar.
Connect Odoo partner records to the Saudi SPL National Address service and the Wathq commercial registry
One click install of the full Employment Hero integration for Odoo Community, covering the connector, two way syn...
The Malaysia country pack for the ERP Heritage Employment Hero integration
A dependency free asynchronous job queue that runs long running and fan out work out of band of the request that...
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Discuss (mail)
• Employees (hr) • Project (project) |
| Community Apps Dependencies | Show |
| Lines of code | 3664 |
| Technical Name |
eh_hero_timesheet |
| License | OPL-1 |
| Website | https://www.erpheritage.com.au/ |
Odoo Proprietary License v1.0 This software and associated files (the "Software") may only be used (executed, modified, executed after modifications) if you have purchased a valid license from the authors, typically via Odoo Apps, or if you have received a written agreement from the authors of the Software (see the COPYRIGHT file). You may develop Odoo modules that use the Software as a library (typically by depending on it, importing it and using its resources), but without copying any source code or material from the Software. You may distribute those modules under the license of your choice, provided that this license is compatible with the terms of the Odoo Proprietary License (For example: LGPL, MIT, or proprietary licenses similar to this one). It is forbidden to publish, distribute, sublicense, or sell copies of the Software or modified copies of the Software. The above copyright notice and this permission notice must be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Please log in to comment on this module