from odoo import fields from odoo.tests.common import TransactionCase class TestCeoDashboardV2(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() cls.partner = cls.env["res.partner"].create( {"name": "V2 Test Client", "mcs_is_client_account": True} ) cls.project = cls.env["project.project"].create( { "name": "V2 Test Client - SEO", "partner_id": cls.partner.id, "allow_timesheets": True, "mcs_delivery_type": "recurring", "mcs_initiative_type": "client", "mcs_monthly_revenue_target": 100000, "mcs_contracted_revenue": 80000, "mcs_next_action": "Ship next milestone", "mcs_revenue_impact_score": 5, "mcs_client_importance_score": 4, "mcs_urgency_score": 3, "mcs_completion_leverage_score": 2, "mcs_resource_cost_score": 1, } ) def test_project_commercial_priority_score(self): self.assertEqual(self.project.mcs_commercial_priority_score, 13) def test_client_account_rollup(self): self.partner.invalidate_recordset() self.assertEqual(self.partner.mcs_monthly_revenue, 100000) self.assertEqual(self.partner.mcs_contracted_value, 80000) def test_client_account_invoice_rollup_fields_exist(self): self.assertIn("mcs_total_invoiced", self.partner._fields) self.assertIn("mcs_total_outstanding", self.partner._fields) self.assertIn("mcs_total_overdue", self.partner._fields) self.assertIn("mcs_last_invoice_date", self.partner._fields) def test_account_health_uses_extensible_signals(self): signals = self.partner._mcs_get_account_health_signals(self.project) self.assertIn("project_health_values", signals) self.assertEqual(self.partner._mcs_resolve_account_health(signals), "healthy") def test_ceo_action_workflow(self): action = self.env["mcs.ceo.action"].create( { "title": "Approve V2 Test Proposal", "category": "approval", "priority": "critical", "date_due": fields.Date.context_today(self.env.user), } ) self.assertEqual(action.priority_rank, 0) action.action_completed() self.assertEqual(action.state, "completed") self.assertTrue(action.date_completed) def test_dashboard_payload_contains_v2_sections(self): data = self.env["mcs.operating.dashboard"].get_ceo_dashboard_v2_data() for key in [ "company_pulse", "revenue", "portfolio", "project_health", "capacity", "time_distribution", "allocation_guardrail", "ceo_actions", "internal_bets", "actions", ]: self.assertIn(key, data) self.assertIn("revenue_coverage", data["company_pulse"]) self.assertIn("pipeline_coverage", data["revenue"]) def test_crm_followup_automation_is_idempotent(self): lead = self.env["crm.lead"].create( { "name": "V2 Test Opportunity", "type": "opportunity", "partner_id": self.partner.id, "user_id": self.env.user.id, "expected_revenue": 25000, "mcs_next_action": "Follow up", } ) lead.action_mcs_schedule_followup() lead.action_mcs_schedule_followup() self.assertEqual(len(lead.activity_ids), 1)