feat(portal): _fp_get_stage_timeline helper for detail-page timeline

Builds a 5-entry list (label, status, started_at, time_label, notes)
ordered by stage. Labels match the dashboard stepper exactly
(Received/Inspected/Plating/QC/Shipped) so the two surfaces tell
the same story. Inspected and Plating share in_progress_started_at
since state in_progress means both transitions happened.

Time labels use lowercase am/pm matching the mockup typography.
'complete' state correctly shows all 5 stages as done (caught by
new test).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
gsinghpal
2026-05-17 02:48:42 -04:00
parent 9d58f5f61e
commit 8c6718e352
2 changed files with 99 additions and 0 deletions

View File

@@ -74,3 +74,45 @@ class TestPortalDashboard(TransactionCase):
self.assertGreaterEqual(job.in_progress_started_at, before)
# received_at must not be overwritten when state advances
self.assertTrue(job.received_at)
def test_stage_timeline_for_job_in_quality_check(self):
"""Timeline returns 5 entries aligned with dashboard stepper labels."""
from odoo.addons.fusion_plating_portal.controllers.portal import FpCustomerPortal
Job = self.env['fusion.plating.portal.job']
job = Job.create({
'name': 'WO-TL-001',
'partner_id': self.partner.id,
'state': 'received',
})
job.state = 'in_progress'
job.state = 'quality_check'
timeline = FpCustomerPortal()._fp_get_stage_timeline(job)
self.assertEqual(len(timeline), 5)
labels = [s['label'] for s in timeline]
# Must match dashboard stepper labels in fp_portal_dashboard.xml
self.assertEqual(labels, ['Received', 'Inspected', 'Plating', 'QC', 'Shipped'])
statuses = [s['status'] for s in timeline]
# state=quality_check -> step_idx=3 -> QC active, 3 prior done, 1 after pending
self.assertEqual(statuses, ['done', 'done', 'done', 'active', 'pending'])
# Done + active stages have started_at set
self.assertIsNotNone(timeline[0]['started_at'], 'Received timestamp')
self.assertIsNotNone(timeline[1]['started_at'], 'Inspected timestamp')
self.assertIsNotNone(timeline[2]['started_at'], 'Plating timestamp')
self.assertIsNotNone(timeline[3]['started_at'], 'QC active timestamp')
# Pending stage has no started_at
self.assertIsNone(timeline[4]['started_at'], 'Shipped pending - no timestamp')
def test_stage_timeline_complete_state_marks_all_done(self):
"""state='complete' shows all 5 stages done (no active)."""
from odoo.addons.fusion_plating_portal.controllers.portal import FpCustomerPortal
Job = self.env['fusion.plating.portal.job']
job = Job.create({
'name': 'WO-TL-002',
'partner_id': self.partner.id,
'state': 'received',
})
for s in ('in_progress', 'quality_check', 'ready_to_ship', 'shipped', 'complete'):
job.state = s
timeline = FpCustomerPortal()._fp_get_stage_timeline(job)
statuses = [t['status'] for t in timeline]
self.assertEqual(statuses, ['done', 'done', 'done', 'done', 'done'])