The Client
A packaging manufacturer in Indonesia. Its HR team handles every step, from the first application to the new hire’s record in the company’s HRIS, built on Odoo.
The Problem
Hiring depended on paid job platforms, and the steps after an application were spread across tools:
- Every applicant came through a platform the company paid for and did not control.
- Assessment tests, invitations and reminders were handled by hand.
- Candidate data had to be moved into the HRIS separately.
- HR needed to filter large numbers of applicants quickly, by more than a name and a date.
The company wanted its own careers site that HR could run from start to finish.
What I Did
I was the only developer. I started in April 2025 and built the platform on WordPress as one custom plugin, with Fluent Forms for the forms and Advanced Custom Fields for the data.
- A candidate registers, uploads a CV and fills in their details
- They apply to one or more jobs
- Assessment invitation An emailed link with a 72-hour deadline
- The candidate takes the DISC and Kraepelin tests
- HR filters, reviews and moves each applicant through the journey
- HRIS Selected candidates sent to Odoo
Candidate accounts
Candidates register, keep their CV, photo and details up to date, apply to jobs and follow their applications on their own account page. A candidate without a CV is asked for one before going further.
Assessments
From an applicant’s record, HR sends the assessment invitation with one button. The email carries a personal token that expires after 72 hours, and only candidates who were invited can open the test forms. The DISC result is shown as a chart on the candidate’s record, and the Kraepelin test’s screenshot is stored with it.
Emails that send themselves
Candidates whose invitation expired or who did not pass get their email in batches, with every status tracked on the applicant. The sending mode defaults to a developer address, so a test run can never email real candidates by accident. A dashboard shows every email sent.
Tools for HR
The applicant and candidate lists have extra columns, sorting and filters for date, address, education, CV and test status, with caching so they stay fast on a large list. Each applicant moves through a hiring journey, and a candidate’s full profile and test results download as a PDF. HR accounts get an admin view with only the menus they need, and an administrator can create a one-time login link, valid for 15 minutes, to see a candidate’s account exactly as they do.
Handing over to the HRIS
HR sends selected candidates to the company’s Odoo HRIS from the candidate’s record, with every request logged. A small REST API also exposes assessment results to other internal systems.
Files that don’t fill the server
The site collects tens of thousands of applicant files. New CVs, photos and test screenshots go to Amazon S3, each kind in its own folder, and a cleanup dashboard removes candidate files older than six months, so old personal data does not pile up.
The Stack
| Layer | Tool | Role |
|---|---|---|
| Platform | WordPress, custom plugin | Accounts, applications, assessments and HR tools |
| Forms | Fluent Forms, Advanced Custom Fields | Applications, test forms and candidate data |
| Files | Amazon S3, Advanced Media Offloader | CVs, photos and test screenshots off the server |
| HRIS | Odoo, REST API | Selected candidates handed over to HR records |
| Reporting | Chart.js, FPDF | DISC charts and candidate PDF exports |
The Result
The platform is now the company’s main careers system, and HR runs hiring on it every day.
| Before | After |
|---|---|
| Applicants through paid job platforms | The company’s own careers site and candidate accounts |
| Assessment invitations and reminders by hand | Token links with deadlines, and automatic follow-up emails |
| Candidate data copied into the HRIS | Selected candidates sent to Odoo from their record |
| Applicant files kept on the web server | New files on S3, and old candidate files cleaned up |
If your HR team depends on tools it doesn’t control, get in touch.