# -*- coding: utf-8 -*- # Copyright 2026 Nexa Systems Inc. # License OPL-1 (Odoo Proprietary License v1.0) # # /fp/jobs/manager_dashboard — JSON endpoint powering the native-job # Manager Dashboard. Returns a flat list of in-flight fp.job rows # with progress / current-step / deadline info, plus state-count # pills for the filter bar at the top of the dashboard. from odoo import http from odoo.http import request class FpJobsManagerDashboardController(http.Controller): @http.route('/fp/jobs/manager_dashboard', type='jsonrpc', auth='user', website=False) def fp_jobs_manager_dashboard(self, state=None, **kwargs): env = request.env Job = env['fp.job'] # Default view: jobs that need triage. Specifying state= # narrows to that one bucket; state='all' opens the floodgates. if state and state != 'all': domain = [('state', '=', state)] elif state == 'all': domain = [] else: domain = [('state', 'in', ('confirmed', 'in_progress', 'on_hold'))] jobs = Job.search( domain, order='priority desc, date_deadline asc, id desc', limit=200, ) rows = [] for job in jobs: rows.append({ 'id': job.id, 'name': job.name, 'partner': job.partner_id.name or '', 'qty': job.qty, 'state': job.state, 'priority': job.priority, 'date_deadline': ( job.date_deadline.isoformat() if job.date_deadline else None ), 'current_step': ( job.current_step_id.name if job.current_step_id else None ), 'current_location': job.current_location, 'progress_pct': job.step_progress_pct, 'step_done': job.step_done_count, 'step_total': job.step_count, 'recipe': job.recipe_id.name if job.recipe_id else None, }) # State-count pills for the filter bar — let the dashboard show # the manager how big each bucket is at a glance. counts = {} for s in ('confirmed', 'in_progress', 'on_hold', 'done'): counts[s] = Job.search_count([('state', '=', s)]) return {'rows': rows, 'counts': counts}