Skip to main content
iVentureTeam

skill_match_gauge_field

New in Odoo 19 Recruitment: the half doughnut scoring a candidate against a job is skill_match_gauge_field. It reads the job from the action context, prints the score inside the arc, and goes green when a candidate beats 100 percent.

Siddharth JambukiyaSiddharth JambukiyaOdoo Techno-Functional Consultant
August 25, 2026Updated August 25, 20267 min read
Odoo 19 applicant form showing the skill_match_gauge_field widget: a half doughnut with the matching score and the Job Position Matching caption.
Technical nameskill_match_gauge_field
Field typesinteger (core); no supportedTypes declared
Viewsform (applicant Skills page)
Modulehr_recruitment_skills (Recruitment Skills)
Used in core1 occurrence: the applicant form in hr_recruitment_skills
VersionsOdoo 20.0, Odoo 19.0
No-code setupNo. Ships preconfigured on the applicant form; reusable via view XML
Alternativesgauge, percentpie, progressbar

What the skill match gauge does

Odoo 19's recruitment matching answers one question per candidate: how well do this person's skills and degree fit a given job? The number lives in matching_score, and this widget is how the form shows it: a half doughnut with the score printed inside the arc as a rounded percentage, the fixed caption Job Position Matching underneath, and, when known, the name of the job being matched against.

That job name is the widget's most unusual habit. At load it looks for matching_job_id in the record's evaluation context, and if present it fetches that job's name over RPC and displays it. The same context key drives the server compute: matching_score depends on the context, so opening candidates from a job's matching action scores everyone against that job, while opening an applicant directly falls back to the applicant's own position. Same field, same widget, different number per door you came through.

Technically it subclasses the standard gauge field and spreads its descriptor, overriding the rendering: value inside the arc with zero decimals and a percent sign, a thicker ring, the Chart.js title disabled in favor of the template caption, and a fixed tooltip reading This score reflects skills and degree match.

What this means for your team

Recruiters shortlist faster when fit is a glance, not a mental spreadsheet. The gauge turns each application into an instant read, and because the score follows the matching context, the same talent pool re-ranks itself per vacancy: run the matching action from the Sales Manager job and every candidate's gauge rescores against that job's skill and degree requirements.

The green state is a deliberate signal, not decoration. The scoring formula lets strong candidates exceed 100 percent, each skill counts up to double the required level, so a green, over-full gauge literally means overqualified on the measured axes. Teams that know this read green as "interview for the senior variant of the role", which is exactly the conversation the widget exists to start.

Supported options in Odoo 19

The widget declares nothing of its own: the descriptor spreads the base gauge's, so its option surface, quirks included, is inherited. Verified in gauge_field.js and skill_match_gauge_field.js, Odoo 19.0. One inherited option changes meaning here: title still reaches the component, but this subclass disables the Chart.js title and hardcodes its caption in the template, so title has no visible effect.

OptionTypeWhat it does
max_fieldfield name (working, undeclared)The name extractProps actually reads to take the maximum from a field on the record. Not in the declared options; the field must be loaded in the view.
max_valuenumberStatic maximum for the arc. Core passes 100 on the applicant form; values above it trigger the green overshoot state.(default: 100)
max_value_fieldfield name (declared, dead)Declared in the base gauge's options panel but never read: extractProps looks for max_field instead, so setting this does nothing.
titlestring (inherited, no visible effect)Reaches the component but this subclass disables the Chart.js title and hardcodes the Job Position Matching caption in its template, so the option changes nothing visible.

The declared max option name does not work. The base gauge declares max_value_field in its options panel, but its extractProps reads options.max_field, so only max_field actually wires a field as the maximum. Core sidesteps the trap by passing the static max_value instead. Same family of quirk as float_time's casing mismatch, documented on that page.

Working examples

The core usage, from the applicant form

<field name="matching_score" invisible="is_pool_applicant" nolabel="1"
       widget="skill_match_gauge_field"
       options="{'max_value': 100}"/>

Hidden for talent-pool applicants, full circle at 100 unless the candidate overshoots.

A dynamic maximum, using the working option name

<field name="my_score" widget="skill_match_gauge_field"
       options="{'max_field': 'my_target'}"/>

Remember it is max_field, not the declared max_value_field, and the max field must be loaded in the view.

Green means overqualified: the color and the formula

The color logic is three lines that reward reading. Before clamping, the widget compares the raw value to the configured max: strictly greater switches the arc from the theme's primary variable to success, resolved at render time through the html editor's CSS variable helper, so rebranded themes recolor the gauge for free. Only afterwards does it stretch the max to contain the value, which is why an overshooting score renders as a completely full green arc rather than clipping. A zero-on-zero edge case forces the max to 1 so Chart.js still draws an empty track.

Server side, the formula in _compute_matching_skill_ids explains the numbers people question. The job total is the sum of required skill levels plus the expected degree's score times 100; the applicant total sums, per required skill, min(applicant level, required level x 2), plus the applicant's own degree score when the job expects one. The doubling cap is the entire overshoot mechanism: a candidate at level 80 against a required 30 contributes 60, not 30 and not 80. Unrequired skills contribute nothing, however impressive.

Two smaller source facts: the template namespace is hr_recruitment.SkillMatchGaugeField although the file ships in hr_recruitment_skills, a cross-module namespace borrow worth knowing when inheriting the template; and the base gauge descriptor declares no supportedTypes at all, so no console warning protects you from binding this to a non-numeric field, it simply charts garbage.

Version compatibility

VersionStatusNotes
Odoo 20.0In developmentNot released. Deleted on the development branch; replaced by the gauge_chart view widget. See below.
Odoo 19.0VerifiedIntroduced with the recruitment matching flow; verified against the shipped source.
Odoo 18.0Not availableModule exists, but the widget and matching_score do not.
Odoo 17.0Not availableWidget does not exist.
Odoo 16.0Not availableWidget does not exist.

Upgrade note. The hr_recruitment_skills module exists since Odoo 16, but the matching score, its compute and this widget only arrive in 19; there is nothing to migrate forward from 18. Migrating a 19 database to 20 will need view updates, since the widget name disappears entirely, see below.

What is changing in Odoo 20

Odoo 20 is expected at Odoo Experience in Brussels, 24 to 26 September 2026. We read the module on the public development branch at the time of writing, with the standard caveat that the branch is unstable and can change before release.

This widget is deleted, with no alias. Its replacement, gauge_chart, is registered in the view widgets registry, so it is a <widget> element, not a field widget, and it draws a multi-segment doughnut: a comma-separated score_fields attribute (core passes the new skills_score and degree_score computes) gives each component its own palette color, with the whole arc turning green once the total reaches the max. Its attributes fix the ancestor's quirk, max_value_field is read and working there, and the score fields must be loaded invisibly in the view, which core comments explicitly. Two leftovers we verified on the branch: the component instantiates the ORM service it never uses, and its template keeps a job-name line referencing a property that no longer exists, so the context job name display is effectively gone. Views using skill_match_gauge_field will log Missing widget and fall back to a bare number after upgrading. We re-verify once Odoo 20 ships.

Common problems and fixes

SymptomCause and fix
No job name under the gaugeThe view was opened without matching_job_id in the context; the widget only fetches a name when the key is present. Open candidates through the job's matching action; direct applicant access scores against the applicant's own position.
Score looks different for the same applicantThe compute depends on the context job: matching actions score against their job, plain views against the applicant's job_id. Expected behavior; check which door the user came through before doubting the number.
max_value_field option is ignoredThe declared name is dead; extractProps reads max_field. Use options="{'max_field': 'your_field'}" and load that field in the view.
Gauge is full green above 100 percentOvershoot by design: each skill counts up to double the required level, and value beyond max paints the success color. Nothing to fix; treat green as an overqualified flag.
Score is zero despite matching skillsThe target job defines no skill requirements and no expected degree, so the job total is zero. Add job skills or an expected degree on the position; the compute needs a denominator.
Widget missing after upgrading to Odoo 20The registration is deleted on the development branch; the replacement is the gauge_chart view widget. Rewrite the view as <widget name="gauge_chart" score_fields="..."/> with the score fields loaded invisibly.

Skill match gauge vs the alternatives

WidgetBest forKey difference
skill_match_gauge_fieldScoring a candidate against a job's skill and degree requirements at a glanceContext-aware half doughnut: reads matching_job_id, prints the score inside the arc, green past the max
gaugeA generic KPI half doughnut on any numeric fieldThe parent widget: hardcoded blue, value in a tooltip rather than inside the arc, no context behavior
percentpieA compact filled-circle percentagePure CSS conic gradient, no Chart.js, no maximum logic
progressbarLinear progress with editable values and thresholdsA bar, not an arc; color switches by threshold classes instead of theme variables

Within the score-visualization family the choice is shape and scale: half doughnut with context awareness is this widget, minimal filled circle is percentpie, a linear bar with thresholds is progressbar, and the generic half doughnut without recruitment behavior is the base gauge.

Frequently asked questions

Where does the matching score come from?+
From matching_score on the applicant, computed as the applicant's total against the job's total: required skill levels plus the expected degree's score. The job is taken from the matching_job_id context when present, otherwise the applicant's own position.
Why can the score exceed 100 percent?+
Each required skill counts the applicant's level up to twice the required level, so exceeding requirements adds real points. The widget renders that overshoot as a fully filled arc in the theme's success color.
Why does the gauge turn green?+
The renderer compares the raw value to the configured max before clamping: strictly greater switches the arc color from the primary CSS variable to success. Green therefore always means over the maximum, not merely a good score.
Can I reuse skill_match_gauge_field on my own model?+
Yes, it binds to any numeric field and inherits the gauge options, remember max_field is the working name for a dynamic maximum. The job-name line simply stays hidden unless your action context provides matching_job_id.
What happens to this widget in Odoo 20?+
The development branch deletes it without an alias and introduces gauge_chart, a view widget drawing multiple score segments (core feeds it skills_score and degree_score). Custom views must be rewritten; the old name will log a Missing widget warning and fall back to a plain number.

Screening hundreds of applicants and still guessing on fit?

The matching gauge is the visible tip of a scoring pipeline you can extend: custom criteria, AI-ranked shortlists, automated screening steps. We build recruitment automation on Odoo that turns application floods into ranked, explainable shortlists.

Book a free consultation

How this page was produced

Verified by reading skill_match_gauge_field.js, its template, the base gauge_field.js descriptor and the matching_score compute in hr_applicant.py, all in the Odoo 19.0 source, plus the single core usage in the applicant form. Absence in 16 through 18 was confirmed against those branches (the module exists there, the widget does not), and the Odoo 20 section reflects a file-by-file read of the replacement on the development branch. Spotted an error? Tell us and we will correct the page.