Skip to content

[18.0][ADD] payroll_rule_tag: tag salary rules and use tag totals in computations - #290

Open
nimarosa wants to merge 12 commits into
OCA:18.0from
nimarosa:18.0-add-payroll_rule_tag
Open

[18.0][ADD] payroll_rule_tag: tag salary rules and use tag totals in computations#290
nimarosa wants to merge 12 commits into
OCA:18.0from
nimarosa:18.0-add-payroll_rule_tag

Conversation

@nimarosa

Copy link
Copy Markdown
Contributor

Adds payroll_rule_tag: Salary Rules can carry any number of Tags, and each tag's
total is exposed to salary rule computations as tags.<CODE>.

Tags are a more flexible alternative to Salary Rule Categories: a rule belongs to a
single Category, but can carry any number of Tags, and tags may freely overlap. The
typical use is grouping rules into calculation bases — "Taxable", "Social Security",
"Benefits" — and computing each base as the total of the rules carrying that tag,
instead of repeating a list of rule codes in every formula:

result = tags.TAXABLE

Extraction note

Extracted from #174 (author @dreispt) to allow individual review/merge. The original
[ADD] payroll_rule_tag commit is cherry-picked unchanged with its authorship
preserved; #174 bundles several unrelated modules, which is why this one never got
reviewed on its own.

Completed on top of the original module

Configuration and multi-company

  • optional Code field, so the identifier salary rules use no longer has to be the
    tag name
  • company_id plus a multi-company record rule, list/kanban/search views, and ACLs
    split between Payroll Officer (read) and Payroll Manager (full)

Fixes

  • salary_rules_ids declared an explicit relation table while hr.salary.rule.tag_ids
    left it implicit, so the two fields were backed by different tables instead of
    being the two sides of one relation: tagging a rule never showed up on the tag's
    Salary Rules page and # Rules stayed at 0. The fix drops the explicit parameters
    rather than adding them on both sides — hr.payslip.line prototype-inherits
    hr.salary.rule, so an explicit table on tag_ids is copied to it and the registry
    refuses to build with two models sharing one many2many schema.
  • the tag code fell back to the tag name, which is translatable, so a payslip
    computed in a language having a translation for the tag resolved to a different code
    than the one written in the rule. BrowsableObject returns 0.0 for an unknown key,
    so this silently produced a wrong amount instead of an error. The fallback now reads
    the source value.
  • two tags could resolve to the same code ("Net Pay" / "Net-Pay", or a code equal to
    another tag's normalized name) and silently accumulate into a single total. Added a
    constraint rejecting duplicate effective codes per company; the existing SQL
    constraints only caught exact matches.
  • the kanban view used the deprecated t-name="kanban-box", which warns on every view
    load in 18.0; migrated to the card API.

Tests — 24 tests covering tag defaults and code resolution (explicit code,
normalized name, language independence), the constraints, both sides of the rule/tag
relation, ACLs and the multi-company rule, and the payslip behaviour: totals per tag,
unknown tags evaluating to zero, untagged rules staying out, totals summing line totals
rather than unit amounts, archived tags dropping out, and recomputing a payslip not
doubling the totals.

Packaging — version reset to 18.0.1.0.0 (the module was never released), readme
fragments completed (DESCRIPTION / CONFIGURE / USAGE / ROADMAP / CONTRIBUTORS), and
es / es_AR translations added.

@dreispt this is your module — could you take a look?

dreispt and others added 12 commits August 25, 2026 13:13
salary_rules_ids declared the relation table hr_salary_rule_tag_rel, while
hr.salary.rule.tag_ids left it implicit and got
hr_salary_rule_hr_salary_rule_tag_rel. The two fields were therefore backed
by different tables instead of being the two sides of one relation: tagging a
rule never showed up in the tag's Salary Rules page, and salary_rules_count
(also shown in the list and kanban views) stayed at 0.

Drop the explicit parameters so both fields land on the same implicit table
and Odoo registers them as inverses. Doing the opposite -- declaring the
relation explicitly on both sides -- is not an option: hr.payslip.line
prototype-inherits hr.salary.rule, so it would copy tag_ids along with its
explicit table and columns, and the registry refuses to build with two
models sharing the same many2many schema.
Salary rules read tag totals as tags.<CODE>, and BrowsableObject returns 0.0
for an unknown key, so any mismatch silently produces a wrong payslip amount
instead of an error. Two ways to get there:

* the code falls back to the tag name, which is translatable, so computing a
  payslip in a language that has a translation for the tag produced a
  different code than the one written in the salary rule. Read the source
  value instead, so the code no longer depends on the user's language.
* two tags could resolve to the same code ("Net Pay" and "Net-Pay", or a
  code equal to another tag's normalized name) and silently accumulate their
  amounts together. Add a constraint rejecting duplicate effective codes
  within a company; the existing SQL constraints only covered exact matches.

Also extract the name-to-identifier conversion into _normalize_code() so the
constraint and get_tag_code() cannot drift apart.
t-name="kanban-box" is deprecated in 18.0 and logs a warning on every view
load; the hand-written dropdown markup it carried is now rendered by the
kanban renderer itself. Use t-name="card", move the color picker to the
"menu" template and let highlight_color handle the card color.
Cover what the module actually promises, beyond the single happy-path test:
tag defaults and code resolution (explicit code, normalized name, language
independence), the constraints rejecting unusable or ambiguous codes, both
sides of the rule/tag relation and the rules count, the access rights and the
multi-company record rule, and the payslip behaviour -- totals per tag,
unknown tags evaluating to zero, untagged rules staying out, totals summing
line totals rather than unit amounts, archived tags dropping out, and
recomputing a payslip not doubling the totals.
Add the exported translation template plus complete es and es_AR catalogs,
following the payroll terminology already used in this repository.
The module was never released, so reset the version to the 18.0.1.0.0 a first
release gets. Fill in the readme fragments: document the Code field and how a
tag code is resolved, note that a tag total only aggregates rules computed
before it and that it sums line totals rather than unit amounts, add a
ROADMAP for the known limitations, and credit both contributors. README.rst
and the description page are regenerated from the fragments.
@nimarosa

Copy link
Copy Markdown
Contributor Author

@dreispt @norlinhenrik @CristianoMafraJunior @pedrobaeza
Please any of you can review so i can merge it soon? I'm using it in production and consuming the PR but would be nice to ship it with payroll directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants