Skip to Content
Odoo Menu
  • Sign in
  • Try it free
  • Apps
    Finance
    • Accounting
    • Invoicing
    • Expenses
    • Spreadsheet (BI)
    • Documents
    • Sign
    Sales
    • CRM
    • Sales
    • POS Shop
    • POS Restaurant
    • Subscriptions
    • Rental
    Websites
    • Website Builder
    • eCommerce
    • Blog
    • Forum
    • Live Chat
    • eLearning
    Supply Chain
    • Inventory
    • Manufacturing
    • PLM
    • Purchase
    • Maintenance
    • Quality
    Human Resources
    • Employees
    • Recruitment
    • Time Off
    • Appraisals
    • Referrals
    • Fleet
    Marketing
    • Social Marketing
    • Email Marketing
    • SMS Marketing
    • Events
    • Marketing Automation
    • Surveys
    Services
    • Project
    • Timesheets
    • Field Service
    • Helpdesk
    • Planning
    • Appointments
    Productivity
    • Discuss
    • Approvals
    • IoT
    • VoIP
    • Knowledge
    • WhatsApp
    Third party apps Odoo Studio Odoo Cloud Platform
  • Industries
    Retail
    • Book Store
    • Clothing Store
    • Furniture Store
    • Grocery Store
    • Hardware Store
    • Toy Store
    Food & Hospitality
    • Bar and Pub
    • Restaurant
    • Fast Food
    • Guest House
    • Beverage Distributor
    • Hotel
    Real Estate
    • Real Estate Agency
    • Architecture Firm
    • Construction
    • Property Management
    • Gardening
    • Property Owner Association
    Consulting
    • Accounting Firm
    • Odoo Partner
    • Marketing Agency
    • Law firm
    • Talent Acquisition
    • Audit & Certification
    Manufacturing
    • Textile
    • Metal
    • Furnitures
    • Food
    • Brewery
    • Corporate Gifts
    Health & Fitness
    • Sports Club
    • Eyewear Store
    • Fitness Center
    • Wellness Practitioners
    • Pharmacy
    • Hair Salon
    Trades
    • Handyman
    • IT Hardware & Support
    • Solar Energy Systems
    • Shoe Maker
    • Cleaning Services
    • HVAC Services
    Others
    • Nonprofit Organization
    • Environmental Agency
    • Billboard Rental
    • Photography
    • Bike Leasing
    • Software Reseller
    Browse all Industries
  • Community
    Learn
    • Tutorials
    • Documentation
    • Certifications
    • Training
    • Blog
    • Podcast
    Empower Education
    • Education Program
    • Scale Up! Business Game
    • Visit Odoo
    Get the Software
    • Download
    • Compare Editions
    • Releases
    Collaborate
    • Github
    • Forum
    • Events
    • Translations
    • Become a Partner
    • Services for Partners
    • Register your Accounting Firm
    Get Services
    • Find a Partner
    • Find an Accountant
      • Get a Tailored Demo
    • Implementation Services
    • Customer References
    • Support
    • Upgrades
    Github Youtube Twitter Linkedin Instagram Facebook Spotify
    +32 2 290 34 90
    • Get a Tailored Demo
  • Pricing
  • Help
  1. APPS
  2. Platform
  3. EH HR Platform Core v 17.0
  4. Sales Conditions FAQ

EH HR Platform Core

by ERP Heritage https://erpheritage.com.au
Odoo
v 17.0 Third Party 24
Download for v 17.0 Deploy on Odoo.sh
Apps purchases are linked to your Odoo account, please sign in or sign up first.
Versions 16.0 17.0 18.0 19.0
You bought this module and need support? Click here!
Availability
Odoo Online
Odoo.sh
On Premise
Odoo Apps Dependencies • Discuss (mail)
• Employees (hr)
Community Apps Dependencies Show
EH HR Compatibility
Lines of code 914
Technical Name eh_hr_core
LicenseLGPL-3
Websitehttps://erpheritage.com.au
Versions 16.0 17.0 18.0 19.0
ERP Heritage · HR Platform
ERP Heritage HR Platform Foundation

EH HR Platform Core

The audited, multi-company foundation every EH HR module is built on.

Free · LGPL-3FreeLGPL-3v1.0.0
Hash-chained audit log
Append-only
Advisory-lock serialised
Strict multi-company
Atomic rate limiter

Why this module

EH HR Platform Core

INTEGRITY

Tamper-evident by construction

The audit log is append-only and hash-chained: each row stores the sha256 of the previous row plus its own fields, so any silent edit is caught by verify_chain(). No group is granted write, create, or unlink on the log, _log_access is off, and the list view forbids create, edit, and delete. The chain is independent of mail.thread.

ISOLATION

Multi-company that does not leak

The company-aware mixin makes company_id required, defaults it to the active company, and refuses cross-company writes even under sudo unless an explicit, audited override context is set. A global record rule isolates the audit log per company so one officer cannot read another company's trail.

FOUNDATION

One substrate, many modules

Mixins, a service registry, DST-safe timezone math, versioned settings, and feature flags live here once, so the rest of the EH HR suite composes them instead of re-implementing them. Lean on purpose: no workflow, approval, policy, or feature logic ships in this module.

Day in the life

An HR officer questions a record change at month-end

A salary band looks wrong. The officer opens the Audit Log, filters to the model and actor, and reads the before-and-after JSON of the exact write, stamped with the user, the time, and a correlation id that ties it to the originating action. An administrator runs verify_chain() to confirm no row in between was altered: it walks the chain in keyset-paginated batches and returns the first broken row id, or nothing if the trail is intact. Because the company-aware mixin already refused any cross-company write that was not explicitly overridden and audited, there is no quiet leak to chase. The answer comes from the data, not from memory.

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.

Concurrency

Two transactions appending to the audit log at once would otherwise read the same tail and fork the chain. write_event takes a transaction-scoped Postgres advisory lock so appends are strictly serialised; it releases automatically on commit or rollback.

Hash symmetry

Append and verify share one _chain_material() helper, and a missing actor is normalised to 0 on both paths. A prior version that hashed the actor as 0 on append but as the string False on verify broke the chain for every actorless row; that asymmetry is closed.

JSON coercion

Audit payloads are built from raw field reads, so recordsets and date objects arrive un-serialisable. One _json_safe() coercion feeds both the stored jsonb column and the hash material, so the two representations stay identical and the chain stays valid.

Upgrade safety

The audit company_id column is deliberately excluded from the hash material, so introducing it on an existing database never alters a stored row_hash and the chain survives the upgrade.

Cross-company override

A cross-company write is only permitted with an explicit allow_cross_company context, and when used it writes a cross_company_write audit row recording the new company, the affected count, and every affected record id, so the elevation is fully reconstructable.

Rate-limit races

The limiter is a single atomic INSERT ... ON CONFLICT DO UPDATE ... RETURNING upsert per (scope, key, window), so two gunicorn or gevent workers racing the same bucket can never both read a stale count. It is worker-shared and restart-durable, unlike an in-memory dict.

Cron isolation

Closed rate-limit windows are vacuumed by a daily code cron calling _gc_windows(); the high-churn counter table runs with _log_access off so it never bloats with create or write metadata.

Settings versioning

settings.entry.set() never destroys a value: it creates the new active entry, then archives the previous one with a superseded_by pointer, keeping one active row per company and key while preserving history.

DST correctness

The timezone service computes an employee's local civil date and the UTC window that bounds it, handling 23 and 25 hour DST days, with a documented fallback from employee to company to UTC when no zone is set.

Install grant

Odoo 17 does not auto-grant the top group of a category, so a post-init hook explicitly grants the base administrator the HR Platform Admin group; without it a fresh database would leave even the admin unable to open any platform record.

What is inside

Built to do the job, end to end.

  • Append-only hash-chained audit log. eh.hr.audit.log records model, record id, action, actor, company, correlation id, and a JSON payload, chained by sha256 over the previous row. write_event appends under an advisory lock; verify_chain walks the chain in bounded batches and reports the first tampered row. No write, create, or unlink ACL is granted to any group.
  • Audited record mixin. eh.hr.audited.mixin emits create, write, and unlink audit rows automatically, capturing before-and-after snapshots of a configurable field whitelist. Writes that change nothing in the audited set emit no row, so the trail stays signal.
  • Strict company-aware mixin. eh.hr.company.aware.mixin makes company_id required, defaults it to the active company, and rejects cross-company writes, even under sudo, unless an explicit audited override is set. Every override is logged.
  • Atomic rate limiter. eh.hr.rate.limit.hit() is a single atomic SQL upsert per fixed window, correct across concurrent workers and durable across restarts. Built for the public kiosk, biometric, visitor, and mobile routes that authenticate a device rather than a person.
  • Versioned settings and feature flags. eh.hr.settings.entry gives typed, per-company key/value settings where a write archives the old value instead of destroying it. eh.hr.feature.flag gates capability by company, group, date window, and deterministic percentage rollout on user id.
  • Services, timezone math, and OWL kit. A tiny service registry with locate_service keeps business logic off the ORM. A DST-safe timezone service computes local civil dates and UTC day windows. The frontend ships HrCard and HrStat OWL components with a built-in loading skeleton, design tokens, and a debounced toast service.

Honest about the edges

What this does not do, so nothing surprises you.

  • This is a platform and developer foundation module, not an end-user application. On its own it adds an Audit Log view, a settings page, and a few mixins; the HR feature surface lives in the other EH HR modules that depend on it.
  • The audit retention period is exposed as a configurable setting, but this module ships no automated purge or CSV-export job for old audit rows. The hot table is not trimmed automatically.
  • There is no standalone HrSkeleton component; the skeleton is a loading state rendered inside HrCard. The OWL kit in this module is HrCard, HrStat, and a toast service.
  • The platform event bus is an in-process bus.bus send, intended to be swapped for a queue adapter in clustered deployments; it is not a distributed message broker.
  • Workflow, approval chains, the policy DSL, and notification dispatch are deliberately not in this module and live in their respective EH HR engine modules.
Search

Odoo 17 HR platform, HR audit log Odoo, hash-chained audit trail, append-only audit log, tamper-evident logging Odoo, multi-company HR Odoo, Odoo feature flags, rate limiting Odoo, OWL component kit, Odoo HR foundation module, versioned settings Odoo, per-company settings, Odoo service registry, DST-safe timezone Odoo, ERP Heritage HR

Work with ERP Heritage

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.

Build and tailor
Odoo Implementation, Customization and Development, scoped to your workflow.
Connect and move
Odoo Integration and Migration across systems and Odoo versions.
Run and support
Odoo Support and Training so your team stays productive after go live.
Plan and advise
Odoo Consultation and ERP Consulting, from discovery to roadmap.

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.

ArabicChinese (Simplified)Chinese (Traditional)DutchFrenchGermanHindiIndonesianItalianJapaneseKoreanPolishPortuguese (Brazil)RussianSpanishSwedishThaiTurkishVietnamese
ERP Heritage

Production-grade Odoo HR, built to an engineering bar and documented honestly. Support: info@erpheritage.com.au
Developed by ERP Heritage - Odoo Implementation • LinkedIn

v1.0.0 · LGPL-3 · Odoo 17 Community

Please log in to comment on this module

  • The author can leave a single reply to each comment.
  • This section is meant to ask simple questions or leave a rating. Every report of a problem experienced while using the module should be addressed to the author directly (refer to the following point).
  • If you want to start a discussion with the author, please use the developer contact information. They can usually be found in the description.
Community
  • Tutorials
  • Documentation
  • Forum
Open Source
  • Download
  • Github
  • Runbot
  • Translations
Services
  • Odoo.sh Hosting
  • Support
  • Upgrade
  • Custom Developments
  • Education
  • Find an Accountant
  • Find a Partner
  • Become a Partner
About us
  • Our company
  • Brand Assets
  • Contact us
  • Jobs
  • Events
  • Podcast
  • Blog
  • Customers
  • Legal • Privacy
  • Security

Odoo is a suite of open source business apps that cover all your company needs: CRM, eCommerce, accounting, inventory, point of sale, project management, etc.

Odoo's unique value proposition is to be at the same time very easy to use and fully integrated.

Website made with