2026-08-31 17:29:48 -04:00

328 lines
12 KiB
Python

from odoo import api, SUPERUSER_ID
def post_init_hook(env_or_cr, registry=None):
if registry is not None:
env = api.Environment(env_or_cr, SUPERUSER_ID, {})
else:
env = env_or_cr
OperatingSystemSetup(env).run()
class OperatingSystemSetup:
def __init__(self, env):
self.env = env
self.Partner = env["res.partner"].sudo()
self.Project = env["project.project"].sudo()
self.Invoice = env["account.move"].sudo()
def run(self):
self._promote_existing_customers()
self._ensure_active_portfolio()
self._hide_empty_seed_accounts()
self._hide_child_contact_accounts()
self._ensure_followup_cron_active()
def _promote_existing_customers(self):
invoice_partners = self.Invoice.search(
[
("move_type", "=", "out_invoice"),
("state", "=", "posted"),
("commercial_partner_id", "!=", False),
]
).mapped("commercial_partner_id")
customer_accounts = self.Partner.search(
[("customer_rank", ">", 0)]
).mapped("commercial_partner_id")
for partner in customer_accounts | invoice_partners:
values = {"mcs_is_client_account": True}
if not partner.mcs_account_status:
values["mcs_account_status"] = "active"
values.update(self._client_company_currency_values(partner))
partner.write(values)
def _ensure_active_portfolio(self):
specs = {
"ClicksToCart": {
"aliases": ["Clickstocart Inc", "ClicksToCart"],
"workstreams": [
("ERP Implementation", "fixed_project"),
("App Development", "fixed_project"),
("Social Media Handling", "recurring"),
],
},
"Wallaceton": {
"aliases": ["Wallaceton Eye Care", "Wallaceton"],
"workstreams": [
("SEO", "recurring"),
("Social Media Handling", "recurring"),
("Ads Management", "recurring"),
],
},
"Maison de Treats": {
"aliases": ["Maison de Treats"],
"workstreams": [("Social Media Handling", "recurring")],
},
"Lens and Frames": {
"aliases": ["Lens & Frames Optical", "Lens and Frames"],
"workstreams": [
("SEO", "recurring"),
("Social Media Handling", "recurring"),
("Ads Management", "recurring"),
],
},
"TNCSC": {
"aliases": ["Tamil Nadu Cultural Society of Canada", "TNCSC"],
"workstreams": [
("Ads Management", "recurring"),
("Videos", "fixed_project"),
("ERP", "fixed_project"),
],
},
"Infini": {
"aliases": ["INFINI BRAND ENHANCERZ", "Infini"],
"workstreams": [("Social Media Handling", "recurring")],
},
"Organic Healthy Family": {
"aliases": ["Organic Healthy Family"],
"workstreams": [("Shopify Store Development", "fixed_project")],
},
"Hondavert": {
"aliases": ["Hondavert"],
"workstreams": [
("Website Development", "fixed_project"),
("App Development", "fixed_project"),
],
},
"RaceNation": {
"aliases": ["RaceNation"],
"workstreams": [("Website Development", "fixed_project")],
},
"Racewerks": {
"aliases": ["Racewerks"],
"workstreams": [("Website Development", "fixed_project")],
},
"Internal": {
"aliases": ["Internal"],
"workstreams": [
("Shopify App for Revenue Generation", "internal_product"),
("Custom Product Development", "internal_r_and_d"),
],
},
}
for account_name, spec in specs.items():
partner = self._ensure_client_account(account_name, spec["aliases"])
for workstream, delivery_type in spec["workstreams"]:
self._ensure_project(partner, account_name, workstream, delivery_type)
def _ensure_client_account(self, name, aliases=None):
aliases = aliases or [name]
partner = self.Partner.browse()
for alias in aliases:
partner = self.Partner.search([("name", "=", alias)], limit=1)
if partner:
break
if not partner:
partner = self.Partner.search(
[("name", "ilike", aliases[0]), ("customer_rank", ">", 0)],
limit=1,
)
if not partner:
partner = self.Partner.create(
{
"name": aliases[0] if aliases else name,
"company_type": "company",
"mcs_is_client_account": True,
"mcs_account_status": "active",
}
)
else:
values = {}
if not partner.mcs_is_client_account:
values["mcs_is_client_account"] = True
if not partner.mcs_account_status:
values["mcs_account_status"] = "active"
values.update(self._client_company_currency_values(partner))
if values:
partner.write(values)
return partner
def _client_company_currency_values(self, partner):
invoice = self.Invoice.search(
[
("move_type", "=", "out_invoice"),
("state", "=", "posted"),
("commercial_partner_id", "=", partner.commercial_partner_id.id),
("company_id", "!=", False),
],
order="invoice_date desc, id desc",
limit=1,
)
if invoice:
return {
"mcs_client_company_id": invoice.company_id.id,
"mcs_currency_id": invoice.currency_id.id or invoice.company_currency_id.id,
}
project = self.Project.search(
[("partner_id", "=", partner.id), ("company_id", "!=", False)],
order="write_date desc, id desc",
limit=1,
)
if project:
return {
"mcs_client_company_id": project.company_id.id,
"mcs_currency_id": project.company_id.currency_id.id,
}
if partner.currency_id:
company = self.env["res.company"].sudo().search(
[("currency_id", "=", partner.currency_id.id)], limit=1
)
values = {"mcs_currency_id": partner.currency_id.id}
if company:
values["mcs_client_company_id"] = company.id
return values
return {}
def _ensure_project(self, partner, account_name, workstream, delivery_type):
is_internal = partner.name == "Internal"
project_name = "%s - %s" % (partner.name, workstream)
legacy_project_name = "%s - %s" % (account_name, workstream)
project = self.Project.search(
[
"|",
("name", "=", project_name),
("name", "=", legacy_project_name),
],
limit=1,
)
if not project:
project = self.Project.search(
[("partner_id", "=", partner.id), ("name", "ilike", workstream)],
limit=1,
)
if not project:
company = self._project_company(partner, is_internal)
project = self.Project.create(
{
"name": project_name,
"partner_id": partner.id if not is_internal else False,
"company_id": company.id if company else False,
"allow_timesheets": True,
"allow_milestones": True,
"mcs_delivery_type": delivery_type,
"mcs_initiative_type": self._initiative_type(delivery_type),
"mcs_classification": "active"
if delivery_type != "internal_r_and_d"
else "parked",
"mcs_revenue_connected": delivery_type
not in ("internal_product", "internal_r_and_d", "sales_initiative"),
"mcs_next_action": "Confirm owner, target, scope, and next milestone.",
"mcs_next_milestone": "Operating setup",
}
)
return project
values = {}
company = self._project_company(partner, is_internal)
if not project.partner_id and not is_internal:
values["partner_id"] = partner.id
if project.partner_id and project.partner_id != partner and not is_internal:
values["partner_id"] = partner.id
if company and not project.company_id:
values["company_id"] = company.id
if not project.mcs_delivery_type:
values["mcs_delivery_type"] = delivery_type
if not project.mcs_initiative_type:
values["mcs_initiative_type"] = self._initiative_type(delivery_type)
if not project.mcs_next_action:
values["mcs_next_action"] = "Confirm owner, target, scope, and next milestone."
if not project.mcs_next_milestone:
values["mcs_next_milestone"] = "Operating setup"
if values:
project.write(values)
return project
def _initiative_type(self, delivery_type):
mapping = {
"recurring": "client",
"fixed_project": "client",
"internal_product": "product",
"internal_r_and_d": "internal",
"sales_initiative": "sales",
"internal_operations": "internal",
}
return mapping.get(delivery_type, "client")
def _project_company(self, partner, is_internal=False):
if is_internal:
return self.env.company
invoice = self.Invoice.search(
[
("move_type", "=", "out_invoice"),
("state", "=", "posted"),
("commercial_partner_id", "=", partner.commercial_partner_id.id),
("company_id", "!=", False),
],
order="invoice_date desc, id desc",
limit=1,
)
if invoice:
return invoice.company_id
if partner.currency_id:
company = self.env["res.company"].sudo().search(
[("currency_id", "=", partner.currency_id.id)], limit=1
)
if company:
return company
return self.env.company
def _ensure_followup_cron_active(self):
cron = self.env.ref(
"mcs_operating_system.ir_cron_mcs_schedule_missing_followups",
raise_if_not_found=False,
)
if cron and not cron.active:
cron.sudo().write({"active": True})
def _hide_empty_seed_accounts(self):
names = [
"ClicksToCart",
"Wallaceton",
"Lens and Frames",
"TNCSC",
"Infini",
"Organic Healthy Family",
"Hondavert",
"RaceNation",
"Racewerks",
]
for partner in self.Partner.search(
[
("name", "in", names),
("customer_rank", "=", 0),
("mcs_is_client_account", "=", True),
]
):
has_invoice = bool(
self.Invoice.search_count(
[
("move_type", "=", "out_invoice"),
("state", "=", "posted"),
("commercial_partner_id", "=", partner.commercial_partner_id.id),
]
)
)
if not has_invoice and not partner.mcs_project_ids:
partner.write({"mcs_is_client_account": False})
def _hide_child_contact_accounts(self):
child_accounts = self.Partner.search(
[
("mcs_is_client_account", "=", True),
("parent_id", "!=", False),
]
)
for partner in child_accounts:
if not partner.mcs_project_ids:
partner.write({"mcs_is_client_account": False})