fix(portal): sudo portal job queries so template traversal works for customers

Portal users have read access to fp.portal.job but NOT to fp.job.
The new job-card macro traverses job.x_fc_job_id -> fp.job to surface
part info, sale_order, ship-to address — that raised AccessError for
real customers (admins were fine due to inherited groups).

Adding .sudo() to the three Job queries in home(), portal_my_jobs(),
and the certifications panel mirror lookup. Domain still filters to
the customer's commercial partner tree, so sudo doesn't widen
visibility — it just lets the template walk past the portal-job
boundary to the privileged backend models.

Same pattern is already used in the same file for sale.order,
account.move, and stock.picking queries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-17 12:39:26 -04:00
parent 2802fcf738
commit 26fe41e7d4

View File

@@ -392,7 +392,11 @@ class FpCustomerPortal(CustomerPortal):
po_count = SO.search_count(po_domain)
# Recent jobs (5)
Job = request.env['fusion.plating.portal.job']
# sudo() so the rendered cards can traverse job.x_fc_job_id -> fp.job
# -> sale_order_id without hitting the portal user's ACL block on
# fp.job. Domain still filters to the customer's own commercial
# partner tree, so sudo doesn't widen visibility.
Job = request.env['fusion.plating.portal.job'].sudo()
job_domain = [('partner_id', 'child_of', commercial.id)]
recent_jobs = Job.search(
job_domain, order='received_date desc, id desc', limit=5
@@ -778,7 +782,11 @@ class FpCustomerPortal(CustomerPortal):
def portal_my_jobs(self, page=1, sortby=None, **kw):
partner = request.env.user.partner_id
commercial = partner.commercial_partner_id
Job = request.env['fusion.plating.portal.job']
# sudo() so the rendered cards can traverse job.x_fc_job_id -> fp.job
# -> sale_order_id without hitting the portal user's ACL block on
# fp.job. Domain still filters to the customer's own commercial
# partner tree, so sudo doesn't widen visibility.
Job = request.env['fusion.plating.portal.job'].sudo()
domain = [('partner_id', 'child_of', commercial.id)]
searchbar_sortings = {
@@ -1199,7 +1207,11 @@ class FpCustomerPortal(CustomerPortal):
def portal_my_certifications(self, page=1, sortby=None, **kw):
partner = request.env.user.partner_id
commercial = partner.commercial_partner_id
Job = request.env['fusion.plating.portal.job']
# sudo() so the rendered cards can traverse job.x_fc_job_id -> fp.job
# -> sale_order_id without hitting the portal user's ACL block on
# fp.job. Domain still filters to the customer's own commercial
# partner tree, so sudo doesn't widen visibility.
Job = request.env['fusion.plating.portal.job'].sudo()
domain = [
('partner_id', 'child_of', commercial.id),
('coc_attachment_id', '!=', False),