Skip to content

[16.0][IMP] hr_employee_ppe: Using related fields#1536

Open
anusriNPS wants to merge 1 commit into
OCA:16.0from
PyTech-SRL:16.0-update-fields
Open

[16.0][IMP] hr_employee_ppe: Using related fields#1536
anusriNPS wants to merge 1 commit into
OCA:16.0from
PyTech-SRL:16.0-update-fields

Conversation

@anusriNPS
Copy link
Copy Markdown

Using related fields for "is_ppe", "expire_ppe"
and "indications" instead of computing these fields based on product change from UI.

@OCA-git-bot
Copy link
Copy Markdown
Contributor

Hi @eduaparicio, @marcelsavegnago,
some modules you are maintaining are being modified, check this out!

@anusriNPS anusriNPS force-pushed the 16.0-update-fields branch 2 times, most recently from 7b98412 to eeacc49 Compare January 24, 2026 16:56
Copy link
Copy Markdown

@HekkiMelody HekkiMelody left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review, LGTM

Copy link
Copy Markdown

@quirino95 quirino95 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@OCA-git-bot
Copy link
Copy Markdown
Contributor

This PR has the approved label and has been created more than 5 days ago. It should therefore be ready to merge by a maintainer (or a PSC member if the concerned addon has no declared maintainer). 🤖

Copy link
Copy Markdown
Member

@marcelsavegnago marcelsavegnago left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Contributor

@alexey-pelykh alexey-pelykh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the improvement! Using related fields instead of @api.onchange is definitely the right direction -- related fields work consistently regardless of whether the change comes from the UI, ORM, or import, while onchange only fires from the UI.

A couple of things I'd like to discuss:

1. store attribute on related fields

The new related fields default to store=False. The old fields (is_ppe, expire_ppe, indications) were regular stored fields with database columns. With this change:

  • Existing stored data in those columns becomes orphaned (not a functional problem, Odoo handles this, but worth being aware of).
  • If any external module or report filters/groups by is_ppe or expire_ppe in a domain, it will become significantly slower or fail since unstored fields can't be efficiently searched. The tree view already displays expire_ppe, which means a list view with a filter on that field would hit this.

Have you considered adding store=True to the related fields? That would keep the DB column, allow efficient search/filter, and Odoo would auto-maintain the values through the related mechanism. The trade-off is that related stored fields add DB triggers, but for a Boolean and a Text field this is negligible.

2. Behavioral change on expire_ppe editability

In the current code, expire_ppe is a regular field with the view allowing edits when state in ['draft', 'accepted']. The form even has readonly="state not in ['draft','accepted']" on expire_ppe, implying it was intended to be editable per-record. With a related field (which is readonly=True by default at ORM level), users can no longer override expire_ppe on a specific equipment record independently of the product.

If overriding per-record was not actually needed (which seems to be the case from the original onchange logic), then this is fine -- just wanted to confirm the intent.

3. Minor: Test assertions inside assertRaises block

In test_check_dates, the new assertions (assertTrue, assertEqual) are placed inside the with self.assertRaises(ValidationError) block before the call to validate_allocation(). If any of those assertions fail, they'll raise AssertionError (not ValidationError), which would cause the test to fail with a confusing error message. Consider moving those assertions before the assertRaises context manager, or into a separate test.

_inherit = ["hr.personal.equipment"]

is_ppe = fields.Boolean()
is_ppe = fields.Boolean(related="product_id.is_ppe")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider adding store=True here. The old field was stored, and the tree view displays this field, so filtering/grouping on is_ppe in list views would require a stored field to work efficiently.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored store=True for fields which are modified as related

self.hr_employee_ppe_expirable.start_date = "2020-01-01"
self.hr_employee_ppe_expirable.expiry_date = "2019-12-31"
self.hr_employee_ppe_expirable._compute_fields()
self.assertTrue(self.hr_employee_ppe_expirable.is_ppe)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions are inside the assertRaises(ValidationError) block. If any assertion fails, it raises AssertionError (not ValidationError), which would cause assertRaises to re-raise it with a confusing traceback. Consider moving these assertions before the with block:

self.hr_employee_ppe_expirable.start_date = "2020-01-01"
self.hr_employee_ppe_expirable.expiry_date = "2019-12-31"
self.assertTrue(self.hr_employee_ppe_expirable.is_ppe)
self.assertTrue(self.hr_employee_ppe_expirable.expire_ppe)
...
with self.assertRaises(ValidationError):
    self.hr_employee_ppe_expirable.validate_allocation()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved assert checks outside assertRaises block as suggested

@anusriNPS anusriNPS force-pushed the 16.0-update-fields branch 3 times, most recently from 586d731 to 7fb000b Compare March 3, 2026 14:50
   Using related fields for "is_ppe", "expire_ppe"
and "indications" instead of computing these fields
based on product change from UI. Related fields
are made as 'store=True' to restore earlier
behaviour.
@anusriNPS anusriNPS force-pushed the 16.0-update-fields branch from 7fb000b to 5f624d7 Compare March 3, 2026 14:57
@anusriNPS
Copy link
Copy Markdown
Author

Depends on #1550 which resolves error seen in pre-commit job

@HekkiMelody
Copy link
Copy Markdown

#1550 has been merged, so we should be able to merge this as well. The PR has enough approvals.

Thank you!

Copy link
Copy Markdown

@marcos-mendez marcos-mendez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated Review -- Tests Failed

1. Root Cause

The test failure occurs because the related fields (is_ppe, indications, expire_ppe) in hr_employee_ppe/models/hr_personal_equipment.py are not properly initialized when the record is created, due to missing store=True and lack of proper initialization in the test setup. This causes a database access error when the system tries to read these computed fields during test execution.


2. Suggested Fix

In hr_employee_ppe/models/hr_personal_equipment.py, ensure that the related fields are correctly initialized by verifying that the product_id is set before the record is saved, and that store=True is used correctly. Specifically:

  • Ensure that product_id is properly set in test data.
  • Add explicit initialization of related fields in setUpClass if needed.

File: hr_employee_ppe/models/hr_personal_equipment.py
Lines: 17–20
Change: No code change required here, but make sure that in tests, product_id is set correctly before any related field access.

File: hr_employee_ppe/tests/test_hr_employee_ppe.py
Lines: 84–87 (remove test_compute_fields)
Addition: Add product_id assignment in setUpClass to ensure related fields are initialized.

# In setUpClass, ensure:
self.hr_employee_ppe_expirable.product_id = self.product_employee_ppe_expirable
self.hr_employee_ppe_no_expirable.product_id = self.product_employee_ppe_no_expirable

3. Additional Code Issues

  • No issue detected in the current diff. The use of related fields with store=True is valid and follows Odoo conventions.
  • The removal of _compute_fields() is correct since it's replaced by related fields.
  • No issues with modifiers, hooks, or extensibility patterns.

4. Test Improvements

To improve test coverage and ensure robustness, add the following test cases:

Suggested Test Cases:

  1. Test related field initialization:

    • Ensure that is_ppe, expire_ppe, and indications are correctly set from product_id when a record is created.
    • Pattern: Use TransactionCase or SavepointCase to test data integrity.
  2. Test that related fields update when product_id changes:

    • Change product_id on a record and verify that related fields update accordingly.
    • Pattern: Use self.assertEqual(...) to assert field values after change.
  3. Test edge case: product_id is False:

    • Ensure that related fields default to False or None when product_id is not set.
    • Pattern: Test with empty product.

Example Test Snippet:

def test_related_fields_update_on_product_change(self):
    self.hr_employee_ppe_expirable.product_id = self.product_employee_ppe_no_expirable
    self.assertFalse(self.hr_employee_ppe_expirable.is_ppe)
    self.assertFalse(self.hr_employee_ppe_expirable.expire_ppe)
    self.assertEqual(self.hr_employee_ppe_expirable.indications, False)

OCA Testing Patterns:

  • Use SavepointCase for tests involving data changes or complex validation logic.
  • Use TransactionCase for tests that require transactional integrity.

Conclusion:
The test failure is due to improper test data setup (missing product_id assignment). Fix by ensuring product_id is set during test initialization. No functional issues in the code changes.


⏰ This PR has been open for 50 days.

Every ignored PR is a contributor who might not come back. Review time matters. (OCA Aging Report)


Reciprocal Review Request

Hi everyone! I found some test failures on this PR and left detailed feedback above. I am happy to discuss or help debug. In the meantime, if any of you get a chance, I would appreciate a look at my open PR(s):

My open PRs across OCA:

Reviewing each other's work helps the whole community move forward. Thank you!


Environment via OCA Neural Reviewer: Minikube + K8s Job + oca-ci/py3.10-odoo16.0 | Odoo 16.0
Automated review by OCA Neural Reviewer + qwen3-coder:30b

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants