2026-08-31 17:32:23 -04:00

159 lines
6.1 KiB
Python

from odoo import api, fields, models
class CrmLead(models.Model):
_inherit = "crm.lead"
mcs_service_offer = fields.Selection(
[
("revenue_website_sprint", "Revenue Website Sprint"),
("growth_retainer", "Growth Retainer"),
("mvp_launch_sprint", "MVP Launch Sprint"),
("white_label_agency", "White-Label Agency Partnership"),
("other", "Other"),
],
string="Service Interest",
tracking=True,
)
mcs_expected_monthly_revenue = fields.Monetary(
string="Expected Monthly Revenue",
currency_field="company_currency",
tracking=True,
)
mcs_one_time_project_value = fields.Monetary(
string="One-Time Project Value",
currency_field="company_currency",
tracking=True,
)
mcs_proposal_sent_date = fields.Date(string="Proposal Sent Date", tracking=True)
mcs_last_contact_date = fields.Date(string="Last Contact Date", tracking=True)
mcs_followup_date = fields.Date(string="Follow-Up Date", tracking=True)
mcs_next_action = fields.Char(string="Next Action", tracking=True)
mcs_revenue_priority = fields.Selection(
[
("existing_upsell", "Existing Client Upsell"),
("existing_referral", "Existing Client Referral"),
("canadian_client", "Canadian Client"),
("canadian_agency", "Canadian Agency Partnership"),
("warm_network", "Warm Network"),
("high_value_outbound", "High-Value Outbound"),
("india", "India Opportunity"),
("low_ticket", "Smaller Low-Ticket Retainer"),
],
string="Revenue Priority",
tracking=True,
)
mcs_has_next_activity = fields.Boolean(
string="Has Next Activity", compute="_compute_mcs_operating_flags", store=True
)
mcs_missing_operating_data = fields.Boolean(
string="Missing Operating Data", compute="_compute_mcs_operating_flags", store=True
)
mcs_operating_notes = fields.Text(string="Operating Notes")
@api.depends(
"activity_ids",
"mcs_next_action",
"mcs_followup_date",
"date_deadline",
"expected_revenue",
"mcs_expected_monthly_revenue",
"mcs_one_time_project_value",
"user_id",
"type",
"active",
"probability",
)
def _compute_mcs_operating_flags(self):
for lead in self:
is_open_opportunity = (
lead.active and lead.type == "opportunity" and lead.probability < 100
)
lead.mcs_has_next_activity = bool(
lead.activity_ids or lead.mcs_next_action or lead.mcs_followup_date
)
has_value = bool(
lead.expected_revenue
or lead.mcs_expected_monthly_revenue
or lead.mcs_one_time_project_value
)
lead.mcs_missing_operating_data = bool(
is_open_opportunity
and (
not lead.user_id
or not lead.date_deadline
or not lead.mcs_has_next_activity
or not has_value
)
)
def action_mcs_schedule_followup(self):
todo = self.env.ref("mail.mail_activity_data_todo")
today = fields.Date.context_today(self)
for lead in self:
if lead.activity_ids:
continue
lead.activity_schedule(
todo.id,
date_deadline=lead.mcs_followup_date or lead.date_deadline or today,
summary=lead.mcs_next_action or "Follow up",
user_id=lead.user_id.id or self.env.user.id,
)
return True
def action_mcs_create_delivery_project(self):
Project = self.env["project.project"]
for lead in self:
partner = lead.partner_id
if partner:
values = {"mcs_is_client_account": True}
if not partner.mcs_account_owner_id and lead.user_id:
values["mcs_account_owner_id"] = lead.user_id.id
partner.write(values)
project_name = "%s - %s" % (
partner.name if partner else lead.name,
dict(lead._fields["mcs_service_offer"].selection).get(
lead.mcs_service_offer, "Delivery Project"
),
)
project = Project.search([("name", "=", project_name)], limit=1)
if not project:
project = Project.create(
{
"name": project_name,
"partner_id": partner.id if partner else False,
"company_id": lead.company_id.id if lead.company_id else self.env.company.id,
"user_id": lead.user_id.id if lead.user_id else False,
"allow_timesheets": True,
"allow_milestones": True,
"mcs_initiative_type": "client",
"mcs_delivery_type": "recurring"
if lead.mcs_expected_monthly_revenue
else "fixed_project",
"mcs_revenue_connected": True,
"mcs_monthly_revenue_target": lead.mcs_expected_monthly_revenue,
"mcs_contracted_revenue": lead.mcs_expected_monthly_revenue
or lead.mcs_one_time_project_value,
"mcs_next_action": lead.mcs_next_action
or "Confirm delivery owner, scope, milestone, and kickoff date.",
}
)
lead.mcs_operating_notes = "%s\nDelivery project: %s" % (
lead.mcs_operating_notes or "",
project.display_name,
)
return True
def _cron_mcs_schedule_missing_followups(self):
leads = self.search(
[
("type", "=", "opportunity"),
("active", "=", True),
("probability", "<", 100),
("activity_ids", "=", False),
],
limit=100,
)
leads.action_mcs_schedule_followup()