[19.0][ADD] payroll_rule_parameter: date-versioned parameters for salary rules - #283
[19.0][ADD] payroll_rule_parameter: date-versioned parameters for salary rules#283neoand wants to merge 1 commit into
Conversation
a3ddeec to
0dfbc75
Compare
…ary rules Tax brackets, contribution rates and legal thresholds are data, not code. With nowhere to put them they end up hard-coded inside amount_python_compute, so every legal update means editing every rule that uses them — and recomputing an old payslip silently applies today's rates to a period they never applied to. This module adds hr.rule.parameter / hr.rule.parameter.value, whose value is versioned by the date it comes into force, and exposes it to salary rules as payslip.rule_parameter(code), resolved on the payslip's own date_to. A value can be a plain number or a structure, e.g. a list of tax brackets [(lower_limit, fixed_fee, rate), ...], evaluated with safe_eval. Tests cover date resolution, inclusive boundaries, structured values, unknown codes, dates before the first value, duplicate codes, unevaluable values, and that a rule computing a 2025 payslip gets the 2025 rate rather than today's. Fixtures are built in setUpClass: no demo data required. Assisted-by: Claude Opus 4.8
0dfbc75 to
705d0fd
Compare
|
Thanks for pointing me to the policy — that one's on me, and it's fixed now. The commit was using Happy to answer anything about the implementation directly — I'd much rather work through review |
|
Hi @neoand, have you considered payroll_rule_time_parameter (14.0/15.0) as the basis of this module? This is tagged [ADD], but the feature isn't new here — hr.rule.parameter / hr.rule.parameter.value were moved out of the base payroll module into payroll_rule_time_parameter in #87, maintained by @nimarosa and @appstogrow since #31. It simply never got migrated past 15.0. I've just migrated its dependency to 18.0: OCA/server-tools#3700. Reviews welcome — and if it looks right to you, carrying it on to 19.0 would give this module the same base to depend on. Worth noting that base_time_parameter already handles typed values including JSON, so bracket tables are covered without evaluating a text column. My suggestion would be to land this as a migration of the existing module rather than a new one, so 19.0 continues 15.0 instead of starting over beside it — same module name, history and original authors carried forward. I'm planning to port payroll_rule_time_parameter itself to 18.0, and I'd like the two series to stay consistent. |
New module: date-versioned parameters for salary rules.
Why
Tax brackets, contribution rates and legal thresholds are data, not code. With nowhere to put them they end up hard-coded inside
amount_python_compute, and two things follow:This is not hypothetical. Localisations that keep their tax tables inside
amount_python_computeend up carrying thousands of lines of Python as rule data, where a single mistyped literal is invisible to review and to any linter. The same localisation expressed with versioned parameters needs a fraction of that, and each legal change becomes one new dated value.What it adds
hr.rule.parameter— a named parameter with a uniquecodehr.rule.parameter.value— the value it takes from a given date onwardshr.rule.parameter._get_parameter_from_code(code, date)— resolution by datepayslip.rule_parameter(code)— usable from a salary rule, resolved on the payslip's owndate_toA value may be a plain number:
or a structure, such as a list of brackets:
Read from a rule:
Values are read with
safe_eval, and an unevaluable value raises an error naming the parameter and the date rather than failing deep inside a rule.Testing
0 failed, 0 errors of 9 testsonodoo:19.0Community, on a database without demo data.Coverage: resolution by date, inclusive
date_fromboundary, structured values, unknown code, date before the first value,raise_if_not_found=False, duplicate code rejected, unevaluable value reports its code, and — the one that matters most — a rule computing a 2025 payslip gets the 2025 rate while the same rule on a 2026 payslip gets the 2026 one.Fixtures are built in
setUpClass; the module ships no demo data.Notes
The API name
_get_parameter_from_codedeliberately matches the one developers coming from Odoo Enterprise already know, so existing rules can be reused unchanged. The implementation is independent.Two Odoo 19 details worth flagging for other modules in this repo:
_sql_constraintsas a list of tuples is silently ignored in 19.0; constraints have to be declared asmodels.Constraint(...)attributes. My unique constraint simply never reached the database until I switched, and only a test caught it.<group expand="0" string="Group By">no longer validates — 19.0 wants a bare<group>withdomain="[]"on the filters.Assisted-by: Claude Opus 4.8
Disclosed per the OCA Generative AI / LLM Policy.
Developed and verified under my direction and review; I take responsibility for the contribution.