328 lines
12 KiB
Python
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})
|