2026-08-30 00:48:25 -04:00

236 lines
8.1 KiB
Python

from odoo import api, fields, models
class McsCompanyGoal(models.Model):
_name = "mcs.company.goal"
_description = "Company Goal"
_inherit = ["mail.thread", "mail.activity.mixin"]
_order = "sequence, date_deadline, id"
name = fields.Char(required=True, tracking=True)
sequence = fields.Integer(default=10)
owner_id = fields.Many2one("res.users", string="Owner", default=lambda self: self.env.user)
date_deadline = fields.Date(string="Deadline", tracking=True)
state = fields.Selection(
[
("planned", "Planned"),
("active", "Active"),
("blocked", "Blocked"),
("done", "Done"),
("cancelled", "Cancelled"),
],
default="active",
required=True,
tracking=True,
)
priority = fields.Selection(
[("p0", "P0"), ("p1", "P1"), ("p2", "P2"), ("p3", "P3")],
default="p1",
required=True,
)
target_amount = fields.Monetary(string="Target Amount")
currency_id = fields.Many2one(
"res.currency", default=lambda self: self.env.company.currency_id
)
next_action = fields.Char(string="Next Action")
blocker = fields.Text()
project_ids = fields.Many2many("project.project", string="Projects / Initiatives")
opportunity_ids = fields.Many2many("crm.lead", string="Opportunities")
notes = fields.Html()
def action_done(self):
self.write({"state": "done"})
def action_blocked(self):
self.write({"state": "blocked"})
def action_active(self):
self.write({"state": "active"})
class McsIdeaParking(models.Model):
_name = "mcs.idea.parking"
_description = "Idea Parking Lot"
_inherit = ["mail.thread", "mail.activity.mixin"]
_order = "review_date, urgency desc, id desc"
name = fields.Char(string="Idea", required=True, tracking=True)
date_added = fields.Date(default=fields.Date.context_today, required=True)
potential_value = fields.Selection(
[("low", "Low"), ("medium", "Medium"), ("high", "High"), ("strategic", "Strategic")],
default="medium",
)
urgency = fields.Selection(
[("low", "Low"), ("medium", "Medium"), ("high", "High"), ("urgent", "Urgent")],
default="low",
)
owner_id = fields.Many2one("res.users", string="Owner", default=lambda self: self.env.user)
decision = fields.Selection(
[
("pending", "Pending"),
("approve", "Approve"),
("park", "Park"),
("kill", "Kill"),
],
default="pending",
required=True,
tracking=True,
)
review_date = fields.Date(string="Review Date")
project_id = fields.Many2one("project.project", string="Converted Project")
notes = fields.Html()
def action_approve(self):
self.write({"decision": "approve"})
def action_park(self):
self.write({"decision": "park"})
def action_kill(self):
self.write({"decision": "kill"})
class McsOperatingReview(models.Model):
_name = "mcs.operating.review"
_description = "Operating Review"
_inherit = ["mail.thread", "mail.activity.mixin"]
_order = "review_date desc, id desc"
name = fields.Char(compute="_compute_name", store=True)
review_type = fields.Selection(
[
("daily", "Daily Operating Meeting"),
("monday", "Monday Commitments"),
("wednesday", "Wednesday Revenue Review"),
("friday", "Friday Operating Review"),
("monthly", "Monthly Operating Review"),
],
required=True,
default="daily",
tracking=True,
)
review_date = fields.Date(default=fields.Date.context_today, required=True)
owner_id = fields.Many2one("res.users", string="Owner", default=lambda self: self.env.user)
shipped_yesterday = fields.Html()
ships_today = fields.Html()
blockers = fields.Html()
commitments = fields.Html()
revenue_notes = fields.Html()
delivery_notes = fields.Html()
capacity_notes = fields.Html()
cash_notes = fields.Html()
decisions = fields.Html()
next_actions = fields.Html()
@api.depends("review_type", "review_date")
def _compute_name(self):
labels = dict(self._fields["review_type"].selection)
for review in self:
review.name = "%s - %s" % (
labels.get(review.review_type, "Operating Review"),
review.review_date or fields.Date.context_today(review),
)
class McsSalesTarget(models.Model):
_name = "mcs.sales.target"
_description = "Sales Target"
_inherit = ["mail.thread", "mail.activity.mixin"]
_order = "target_date desc, user_id"
name = fields.Char(compute="_compute_name", store=True)
target_date = fields.Date(default=fields.Date.context_today, required=True)
user_id = fields.Many2one("res.users", string="Owner", default=lambda self: self.env.user)
outbound_target = fields.Integer(default=25)
outbound_done = fields.Integer()
followup_target = fields.Integer(default=8)
followup_done = fields.Integer()
call_target = fields.Integer(default=3)
call_done = fields.Integer()
proposal_target = fields.Integer(default=1)
proposal_done = fields.Integer()
referral_target = fields.Integer(default=2)
referral_done = fields.Integer()
notes = fields.Html()
@api.depends("target_date", "user_id")
def _compute_name(self):
for target in self:
target.name = "%s - %s" % (
target.user_id.name or "Sales",
target.target_date or fields.Date.context_today(target),
)
class McsClientProfitability(models.Model):
_name = "mcs.client.profitability"
_description = "Client Profitability"
_inherit = ["mail.thread", "mail.activity.mixin"]
_order = "period_start desc, partner_id"
name = fields.Char(compute="_compute_name", store=True)
partner_id = fields.Many2one("res.partner", string="Client", required=True)
project_id = fields.Many2one("project.project", string="Project")
period_start = fields.Date(required=True)
period_end = fields.Date(required=True)
currency_id = fields.Many2one(
"res.currency", default=lambda self: self.env.company.currency_id
)
client_revenue = fields.Monetary()
delivery_hours = fields.Float()
account_management_hours = fields.Float()
rework_hours = fields.Float()
revision_hours = fields.Float()
internal_hourly_cost = fields.Monetary(default=0)
internal_delivery_cost = fields.Monetary(
compute="_compute_profitability", store=True
)
gross_contribution = fields.Monetary(compute="_compute_profitability", store=True)
gross_margin = fields.Float(compute="_compute_profitability", store=True)
recommendation = fields.Selection(
[
("keep", "Keep"),
("reprice", "Reprice"),
("rescope", "Rescope"),
("automate", "Automate"),
("reduce", "Reduce"),
("exit", "Exit"),
],
default="keep",
tracking=True,
)
notes = fields.Html()
@api.depends("partner_id", "period_start", "period_end")
def _compute_name(self):
for record in self:
record.name = "%s - %s to %s" % (
record.partner_id.display_name or "Client",
record.period_start or "",
record.period_end or "",
)
@api.depends(
"delivery_hours",
"account_management_hours",
"rework_hours",
"revision_hours",
"internal_hourly_cost",
"client_revenue",
)
def _compute_profitability(self):
for record in self:
hours = (
record.delivery_hours
+ record.account_management_hours
+ record.rework_hours
+ record.revision_hours
)
record.internal_delivery_cost = hours * record.internal_hourly_cost
record.gross_contribution = record.client_revenue - record.internal_delivery_cost
record.gross_margin = (
record.gross_contribution / record.client_revenue * 100
if record.client_revenue
else 0
)