fix(spp_change_request_v2,spp_base_common): route post-submit CRs through stage review form + hide single-record pager (#920)#202
Conversation
The standard web.Pager renders the counter + chevrons even when total === 1, leaving a disabled "1/1 < >" widget that confuses users clicking into a record with no siblings to navigate to. Extend the web.Pager OWL template to drop the entire <nav> with `t-if="props.total > 1 or props.updateTotal"`. The "1/1+" affordance (updateTotal set) is preserved because the count may still grow. The pager's `h-100 d-flex` was also acting as the height anchor for the parent `.o_control_panel_navigation` row, so removing it collapsed the row and top-aligned the sibling refresh / view-switcher buttons. Add `align-items: center` on that container so they stay vertically centred whether the pager is rendered or not. Refs OP#920.
…eview form (#920 r2)
QA returned OP#920 because demo-generated CRs in 'Applied' state
opened in the legacy main spp_change_request_form layout instead of
the Edit Details → Upload Documents → Review & Submit breadcrumb
form that fresh CRs use. The fixed pager-hide treatment from
spp_base_common only applies to the stage form, so post-submit
states (pending / approved / applied / rejected) effectively
'overrode' the new UI.
Three coordinated changes:
1. spp_change_request_v2/models/change_request.py
- action_open_stage_form: any non-draft/non-revision state now
routes to _action_open_review_form (matches the Review & Submit
stage that the form's header already renders state-aware
buttons for — Approve/Reject for validators, Apply for managers,
Applied ribbon, Start Over for rejected).
- Define _action_open_review_form / _action_open_documents_form —
these were referenced from action_open_stage_form but had no
implementations (latent crash on draft CRs at the documents/
review stage that this branch also fixes).
2. spp_change_request_v2/views/change_request_views.xml
- List view <list> gains action='action_open_stage_form'
type='object' so row-click goes through the stage router. The
demo CR list (action_change_request, action_my_change_requests,
action_pending_change_requests) all use this list view, so the
fix lands on every entry point.
3. spp_change_request_v2/tests/test_stage_navigation.py
- Update test_action_open_stage_form_pending to assert the new
behaviour: pending CRs return the review form view, not the
legacy default form.
Bumps spp_change_request_v2 19.0.2.0.3 → 19.0.2.0.4 with matching
HISTORY entry.
Full module suite: 298 tests, 0 failed locally.
…ough the new review form (#920 round-2 follow-up)
|
@gonzalesedwin1123 — ready for review. QA passed. Clean merge with OP#920: https://projects.acn.fr/wp/920 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 19.0 #202 +/- ##
==========================================
+ Coverage 66.08% 72.19% +6.11%
==========================================
Files 86 393 +307
Lines 7501 24412 +16911
==========================================
+ Hits 4957 17625 +12668
- Misses 2544 6787 +4243
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Code Review
This pull request introduces a UI enhancement to hide the Odoo pager when only one record is present and ensures the vertical alignment of control panel elements. Additionally, it updates the Change Request module to route post-submission states (pending, approved, applied, and rejected) through the review stage form to provide a consistent breadcrumb-based user experience. A review comment suggests refactoring the newly added form-opening helper methods into a single parameterized function to reduce code duplication and using the _name attribute for more robust model referencing.
| def _action_open_review_form(self): | ||
| """Open the CR in the Review & Submit stage form view.""" | ||
| self.ensure_one() | ||
| view = self.env.ref( | ||
| "spp_change_request_v2.spp_change_request_review_form", | ||
| raise_if_not_found=False, | ||
| ) | ||
| return { | ||
| "type": "ir.actions.act_window", | ||
| "name": self.name, | ||
| "res_model": "spp.change.request", | ||
| "res_id": self.id, | ||
| "view_mode": "form", | ||
| "views": [[view.id if view else False, "form"]], | ||
| "target": "current", | ||
| } | ||
|
|
||
| # Default: details stage | ||
| return self.action_open_detail() | ||
| def _action_open_documents_form(self): | ||
| """Open the CR in the Upload Documents stage form view.""" | ||
| self.ensure_one() | ||
| view = self.env.ref( | ||
| "spp_change_request_v2.spp_change_request_documents_form", | ||
| raise_if_not_found=False, | ||
| ) | ||
| return { | ||
| "type": "ir.actions.act_window", | ||
| "name": self.name, | ||
| "res_model": "spp.change.request", | ||
| "res_id": self.id, | ||
| "view_mode": "form", | ||
| "views": [[view.id if view else False, "form"]], | ||
| "target": "current", | ||
| } |
There was a problem hiding this comment.
The methods _action_open_review_form and _action_open_documents_form are almost identical. Refactoring them into a single helper method reduces code duplication and improves maintainability. Additionally, using self._name instead of a hardcoded model string is more idiomatic and robust for inheritance, aligning with the practice of preferring the _name attribute to avoid synchronization edge cases.
def _action_open_stage_view(self, view_xml_id):
"""Helper to open the CR in a specific stage form view."""
self.ensure_one()
view = self.env.ref(view_xml_id, raise_if_not_found=False)
return {
"type": "ir.actions.act_window",
"name": self.name,
"res_model": self._name,
"res_id": self.id,
"view_mode": "form",
"views": [[view.id if view else False, "form"]],
"target": "current",
}
def _action_open_review_form(self):
"""Open the CR in the Review & Submit stage form view."""
return self._action_open_stage_view("spp_change_request_v2.spp_change_request_review_form")
def _action_open_documents_form(self):
"""Open the CR in the Upload Documents stage form view."""
return self._action_open_stage_view("spp_change_request_v2.spp_change_request_documents_form")References
- To avoid synchronization edge cases with related fields, prefer accessing a record's model name via its _name attribute rather than from a related field on a parent record.
prettier and the OCA README generator wanted to reformat the new pager inheritance template + regenerate spp_change_request_v2 README artifacts after the new HISTORY entry shifted section numbering. Applies CI's regenerated bytes directly.
Why is this change needed?
OP#920 (originally GitHub issue #157) — opening a change request from the Change Requests list dropped the user into a form view that showed
1/1in the pager and couldn't browse the rest of the list. QA also surfaced two follow-up problems in round 2:pending/approved/applied/rejectedstates were rendered with the legacyspp_change_request_forminstead of the new breadcrumb-based stage form (Edit Details → Upload Documents → Review & Submit) that fresh user-created CRs use.action_open_stage_formreferenced two helpers (_action_open_review_formand_action_open_documents_form) that didn't exist — opening certain CRs would have hitAttributeError.How was the change implemented?
Three commits land in order:
1.
spp_base_common: hide the form-view pager on a 1-record listweb.Pagerand addst-if="props.total > 1 or props.updateTotal"to the pager<nav>. Pager fully disappears for one-record cases instead of showing the dead1/1chip. No impact on multi-row navigation.2.
spp_change_request_v2: route post-submit CRs through the stage review formchange_request.py—action_open_stage_formnow routes draft/revision through the per-stage form helpers AND post-submit (pending/approved/applied/rejected) through the review form so the breadcrumb UI is consistent across all CR states._action_open_review_formand_action_open_documents_formhelpers.action="action_open_stage_form" type="object") so row-click goes through the router instead of the default form action.3.
spp_change_request_v2: setstage='review'on submit_on_submitnow writesstage='review'so demo-generated CRs (which callaction_submit_for_approvaldirectly instead of going through the UI's stage transitions) land on the new review form when re-opened. Manually-created CRs were already setting this viaaction_goto_reviewso this change is a no-op for them and a fix for the programmatic-submit path.New unit tests
spp_change_request_v2/tests/test_stage_navigation.py— added/updatedtest_action_open_stage_form_pendingwhich:approval_state='pending'action_open_stage_form()returns anir.actions.act_windowopeningspp_change_request_v2.spp_change_request_review_formforres_id= the CR id.Unit tests executed by the author
Local Docker run on
spp_change_request_v2+spp_base_common: 0 failed, 0 error(s).How to test manually
See the round-2 QA comment on OP#920 (https://projects.acn.fr/wp/920) for the full guide. Quick steps:
spp_mis_demo_v2, Settings → Demo Data → Load MIS Demo.Draftstate → opens detail/documents/review depending onstage(existing behaviour, still correct).Under Review/Approved/Applied/Rejected→ opens the Review & Submit form (the breadcrumb-style form with Proposed Changes / Attached Documents / Request Log tabs and the lifecycle status bar).< 1/1 >) is hidden. Multi-record navigation still works as before.Related links