Skip to content

fix(spp_change_request_v2,spp_base_common): route post-submit CRs through stage review form + hide single-record pager (#920)#202

Open
emjay0921 wants to merge 5 commits into
19.0from
fix/hide-pager-on-single-record
Open

fix(spp_change_request_v2,spp_base_common): route post-submit CRs through stage review form + hide single-record pager (#920)#202
emjay0921 wants to merge 5 commits into
19.0from
fix/hide-pager-on-single-record

Conversation

@emjay0921
Copy link
Copy Markdown
Contributor

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/1 in the pager and couldn't browse the rest of the list. QA also surfaced two follow-up problems in round 2:

  1. Demo-generated CRs in pending / approved / applied / rejected states were rendered with the legacy spp_change_request_form instead of the new breadcrumb-based stage form (Edit Details → Upload Documents → Review & Submit) that fresh user-created CRs use.
  2. The model-side action_open_stage_form referenced two helpers (_action_open_review_form and _action_open_documents_form) that didn't exist — opening certain CRs would have hit AttributeError.

How was the change implemented?

Three commits land in order:

1. spp_base_common: hide the form-view pager on a 1-record list

  • New asset bundle template + scss that inherits web.Pager and adds t-if="props.total > 1 or props.updateTotal" to the pager <nav>. Pager fully disappears for one-record cases instead of showing the dead 1/1 chip. No impact on multi-row navigation.

2. spp_change_request_v2: route post-submit CRs through the stage review form

  • change_request.pyaction_open_stage_form now 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.
  • Added the missing _action_open_review_form and _action_open_documents_form helpers.
  • Wired the CR list (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: set stage='review' on submit

  • _on_submit now writes stage='review' so demo-generated CRs (which call action_submit_for_approval directly 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 via action_goto_review so 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/updated test_action_open_stage_form_pending which:

  • Creates a CR
  • Forces approval_state='pending'
  • Asserts action_open_stage_form() returns an ir.actions.act_window opening spp_change_request_v2.spp_change_request_review_form for res_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:

  1. Reset DB, install spp_mis_demo_v2, Settings → Demo Data → Load MIS Demo.
  2. Change Requests menu → click a row in Draft state → opens detail/documents/review depending on stage (existing behaviour, still correct).
  3. Click a row in 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).
  4. On any CR form that's the only result, the pager (< 1/1 >) is hidden. Multi-record navigation still works as before.

Related links

emjay0921 added 4 commits May 4, 2026 10:19
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)
@emjay0921
Copy link
Copy Markdown
Contributor Author

@gonzalesedwin1123 — ready for review.

QA passed. Clean merge with 19.0 (no conflicts). Local tests pass (0 failed of 304). Will report CI status as checks land.

OP#920: https://projects.acn.fr/wp/920

@codecov
Copy link
Copy Markdown

codecov Bot commented May 14, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.19%. Comparing base (b3510d8) to head (5881862).

Additional details and impacted files

Impacted file tree graph

@@            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     
Flag Coverage Δ
spp_analytics 93.13% <ø> (?)
spp_api_v2 80.33% <ø> (?)
spp_api_v2_change_request 66.85% <ø> (?)
spp_api_v2_cycles 71.12% <ø> (?)
spp_api_v2_data 64.41% <ø> (?)
spp_api_v2_entitlements 70.19% <ø> (?)
spp_api_v2_gis 71.52% <ø> (?)
spp_api_v2_products 66.27% <ø> (?)
spp_api_v2_service_points 70.94% <ø> (?)
spp_api_v2_simulation 71.12% <ø> (?)
spp_api_v2_vocabulary 57.26% <ø> (?)
spp_approval 50.29% <ø> (?)
spp_area 80.07% <ø> (?)
spp_area_hdx 81.43% <ø> (?)
spp_audit 72.60% <ø> (?)
spp_base_common 90.26% <ø> (ø)
spp_case_cel 89.01% <ø> (?)
spp_change_request_v2 75.46% <100.00%> (?)
spp_programs 64.84% <ø> (+0.01%) ⬆️
spp_security 66.66% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
spp_base_common/__manifest__.py 0.00% <ø> (ø)
spp_change_request_v2/__manifest__.py 0.00% <ø> (ø)
spp_change_request_v2/models/change_request.py 84.36% <100.00%> (ø)

... and 313 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot 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

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.

Comment on lines +1551 to +1583
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",
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

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
  1. 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.
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.

1 participant