Public release from ruodoo-project: 19.0 - 2026-05-10 21:19:01 UTC
This commit is contained in:
14
web_debranding/models/__init__.py
Normal file
14
web_debranding/models/__init__.py
Normal file
@ -0,0 +1,14 @@
|
||||
# License MIT (https://opensource.org/licenses/MIT).
|
||||
|
||||
from . import base
|
||||
from . import ir_actions
|
||||
from . import ir_translation
|
||||
from . import publisher_warranty_contract
|
||||
from . import ir_config_parameter
|
||||
from . import ir_ui_view
|
||||
from . import res_users
|
||||
from . import ir_model
|
||||
from . import res_company
|
||||
from . import ir_module_module
|
||||
from . import res_config_settings
|
||||
from . import ir_http
|
||||
24
web_debranding/models/base.py
Normal file
24
web_debranding/models/base.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Copyright 2020,2022-2023 Ivan Yelizariev
|
||||
# License OPL-1 (https://www.odoo.com/documentation/user/14.0/legal/licenses/licenses.html#odoo-apps).
|
||||
from odoo import api, models
|
||||
|
||||
from .ir_translation import debrand
|
||||
|
||||
BRANDED_FIELDS = {}
|
||||
|
||||
|
||||
class Base(models.AbstractModel):
|
||||
|
||||
_inherit = "base"
|
||||
|
||||
@api.model
|
||||
def search(self, domain, offset=0, limit=None, order=None):
|
||||
res = super().search(domain, offset, limit, order)
|
||||
if self._name == "payment.provider":
|
||||
res = res.filtered(lambda a: not a.module_to_buy)
|
||||
return res
|
||||
|
||||
def get_view(self, view_id=None, view_type="form", **options):
|
||||
res = super().get_view(view_id=view_id, view_type=view_type, **options)
|
||||
res["arch"] = debrand(self.env, res["arch"], is_code=True)
|
||||
return res
|
||||
21
web_debranding/models/ir_actions.py
Normal file
21
web_debranding/models/ir_actions.py
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright 2015-2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
|
||||
# Copyright 2017 Ilmir Karamov <https://it-projects.info/team/ilmir-k>
|
||||
# License MIT (https://opensource.org/licenses/MIT).
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class IrActionsActWindowDebranding(models.Model):
|
||||
_inherit = "ir.actions.act_window"
|
||||
|
||||
def read(self, fields=None, load="_classic_read"):
|
||||
results = super(IrActionsActWindowDebranding, self).read(
|
||||
fields=fields, load=load
|
||||
)
|
||||
if not fields or "help" in fields:
|
||||
params = self.env["ir.config_parameter"].get_debranding_parameters()
|
||||
new_name = params.get("web_debranding.new_name")
|
||||
for res in results:
|
||||
if isinstance(res, dict) and res.get("help"):
|
||||
res["help"] = res["help"].replace("Odoo", new_name)
|
||||
return results
|
||||
41
web_debranding/models/ir_config_parameter.py
Normal file
41
web_debranding/models/ir_config_parameter.py
Normal file
@ -0,0 +1,41 @@
|
||||
# Copyright 2015-2018,2022 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
|
||||
# Copyright 2016 Stanislav Krotov <https://it-projects.info/team/ufaks>
|
||||
# Copyright 2017 ArtyomLosev <https://github.com/ArtyomLosev>
|
||||
# Copyright 2017 Ilmir Karamov <https://it-projects.info/team/ilmir-k>
|
||||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
|
||||
# Copyright 2019 Eugene Molotov <https://github.com/em230418>
|
||||
# License MIT (https://opensource.org/licenses/MIT).
|
||||
|
||||
from odoo import api, models
|
||||
from odoo.tools.translate import _
|
||||
|
||||
PARAMS = [
|
||||
("web_debranding.new_name", _("Руодоо")),
|
||||
("web_debranding.new_title", _("Руодоо")),
|
||||
("web_debranding.new_website", "example.com"),
|
||||
("web_debranding.new_documentation_website", "https://www.odoo.COM/documentation/"),
|
||||
("web_debranding.favicon_url", ""),
|
||||
("web_debranding.send_publisher_warranty_url", "0"),
|
||||
]
|
||||
|
||||
|
||||
def get_debranding_parameters_env(env):
|
||||
res = {}
|
||||
for param, default in PARAMS:
|
||||
value = env["ir.config_parameter"].sudo().get_param(param, default)
|
||||
res[param] = value.strip()
|
||||
return res
|
||||
|
||||
|
||||
class IrConfigParameter(models.Model):
|
||||
_inherit = "ir.config_parameter"
|
||||
|
||||
@api.model
|
||||
def get_debranding_parameters(self):
|
||||
return get_debranding_parameters_env(self.env)
|
||||
|
||||
@api.model
|
||||
def create_debranding_parameters(self):
|
||||
for param, default in PARAMS:
|
||||
if not self.env["ir.config_parameter"].sudo().get_param(param):
|
||||
self.env["ir.config_parameter"].sudo().set_param(param, default or " ")
|
||||
23
web_debranding/models/ir_http.py
Normal file
23
web_debranding/models/ir_http.py
Normal file
@ -0,0 +1,23 @@
|
||||
# Copyright 2022 Ivan Yelizariev <https://twitter.com/yelizariev>
|
||||
# License MIT (https://opensource.org/licenses/MIT).
|
||||
# License OPL-1 (https://www.odoo.com/documentation/user/14.0/legal/licenses/licenses.html#odoo-apps) for derivative work.
|
||||
from odoo import api, models
|
||||
|
||||
from .ir_translation import debrand
|
||||
|
||||
|
||||
class IrHttp(models.AbstractModel):
|
||||
_inherit = "ir.model.fields"
|
||||
|
||||
@api.model
|
||||
def get_translations_for_webclient(self, *args, **kwargs):
|
||||
translations_per_module, lang_params = super(
|
||||
IrHttp, self
|
||||
).get_translations_for_webclient(*args, **kwargs)
|
||||
|
||||
for _module_key, module_vals in translations_per_module.items():
|
||||
for message in module_vals["messages"]:
|
||||
message["id"] = debrand(self.env, message["id"])
|
||||
message["string"] = debrand(self.env, message["string"])
|
||||
|
||||
return translations_per_module, lang_params
|
||||
13
web_debranding/models/ir_model.py
Normal file
13
web_debranding/models/ir_model.py
Normal file
@ -0,0 +1,13 @@
|
||||
# Copyright 2020,2022 Ivan Yelizariev
|
||||
# License OPL-1 (https://www.odoo.com/documentation/user/14.0/legal/licenses/licenses.html#odoo-apps).
|
||||
from odoo import models
|
||||
|
||||
from .ir_translation import debrand
|
||||
|
||||
|
||||
class IrModelSelection(models.Model):
|
||||
_inherit = "ir.model.fields.selection"
|
||||
|
||||
def _get_selection_data(self, *args, **kwargs):
|
||||
data = super(IrModelSelection, self)._get_selection_data(*args, **kwargs)
|
||||
return [(value, debrand(self.env, name)) for value, name in data]
|
||||
10
web_debranding/models/ir_module_module.py
Normal file
10
web_debranding/models/ir_module_module.py
Normal file
@ -0,0 +1,10 @@
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class IrModuleModule(models.Model):
|
||||
_inherit = "ir.module.module"
|
||||
|
||||
@api.model
|
||||
def search(self, domain, offset=0, limit=None, order=None):
|
||||
domain = [("to_buy", "=", False)] + domain
|
||||
return super().search(domain, offset, limit, order)
|
||||
113
web_debranding/models/ir_translation.py
Normal file
113
web_debranding/models/ir_translation.py
Normal file
@ -0,0 +1,113 @@
|
||||
# Copyright 2015-2018,2020,2022 Ivan Yelizariev <https://twitter.com/yelizariev>
|
||||
# Copyright 2016 Stanislav Krotov <https://it-projects.info/team/ufaks>
|
||||
# Copyright 2017 Ilmir Karamov <https://it-projects.info/team/ilmir-k>
|
||||
# Copyright 2017 Nicolas JEUDY <https://github.com/njeudy>
|
||||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
|
||||
# Copyright 2018 Ildar Nasyrov <https://it-projects.info/team/iledarn>
|
||||
# Copyright 2019 Eugene Molotov <https://it-projects.info/team/molotov>
|
||||
# License MIT (https://opensource.org/licenses/MIT).
|
||||
# License OPL-1 (https://www.odoo.com/documentation/user/14.0/legal/licenses/licenses.html#odoo-apps) for derivative work.
|
||||
|
||||
import re
|
||||
|
||||
from odoo import api, models, tools
|
||||
|
||||
from odoo.addons.base.models.ir_model import IrModelFields as IrModelFieldsOriginal
|
||||
|
||||
from .ir_config_parameter import get_debranding_parameters_env
|
||||
|
||||
|
||||
def debrand_documentation_links(source, new_documentation_website):
|
||||
return re.sub(
|
||||
r"https://www.odoo.com/documentation/",
|
||||
new_documentation_website,
|
||||
source,
|
||||
flags=re.IGNORECASE,
|
||||
)
|
||||
|
||||
|
||||
def debrand_links(source, new_website):
|
||||
return re.sub(r"\bodoo.com\b", new_website, source)
|
||||
|
||||
|
||||
def debrand(env, source, is_code=False):
|
||||
if not source or not re.search(r"\bodoo\b", source, re.IGNORECASE):
|
||||
return source
|
||||
params = get_debranding_parameters_env(env)
|
||||
new_name = params.get("web_debranding.new_name")
|
||||
new_website = params.get("web_debranding.new_website")
|
||||
new_documentation_website = params.get("web_debranding.new_documentation_website")
|
||||
|
||||
source = debrand_documentation_links(source, new_documentation_website)
|
||||
source = debrand_links(source, new_website)
|
||||
# We must exclude the next cases, which occur only in a code,
|
||||
# Since JS functions are also contained in the localization files.
|
||||
# Next regular expression exclude from substitution 'odoo.SMTH', 'odoo =', 'odoo=', 'odooSMTH', 'odoo['
|
||||
# Where SMTH is an any symbol or number or '_'. Option odoo.com were excluded previously.
|
||||
# Examples:
|
||||
# odoo.
|
||||
# xml file: https://github.com/odoo/odoo/blob/9.0/addons/im_livechat/views/im_livechat_channel_templates.xml#L148
|
||||
# odooSMTH
|
||||
# https://github.com/odoo/odoo/blob/11.0/addons/website_google_map/views/google_map_templates.xml#L14
|
||||
# odoo =
|
||||
# https://github.com/odoo/odoo/blob/11.0/addons/web/views/webclient_templates.xml#L260
|
||||
# odoo[
|
||||
# https://github.com/odoo/odoo/blob/11.0/addons/web_editor/views/iframe.xml#L43-L44
|
||||
# SMTH.odoo
|
||||
# https://github.com/odoo/odoo/blob/11.0/addons/web_editor/views/iframe.xml#L43
|
||||
source = re.sub(
|
||||
r"\b(?<!\.)odoo(?!\.\S|\s?=|\w|\[)\b", new_name, source, flags=re.IGNORECASE
|
||||
)
|
||||
|
||||
return source
|
||||
|
||||
|
||||
def debrand_bytes(env, source):
|
||||
if type(source) is bytes:
|
||||
source = source.decode("utf-8")
|
||||
return bytes(debrand(env, source), "utf-8")
|
||||
|
||||
|
||||
class IrModelFields(models.Model):
|
||||
_inherit = "ir.model.fields"
|
||||
|
||||
@api.model
|
||||
def _debrand_dict(self, res):
|
||||
for k in res:
|
||||
res[k] = self._debrand(res[k])
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _debrand(self, source):
|
||||
return debrand(self.env, source)
|
||||
|
||||
@api.model
|
||||
@tools.ormcache("model_name")
|
||||
def get_field_string(self, model_name):
|
||||
res = super(IrModelFields, self).get_field_string(model_name)
|
||||
return self._debrand_dict(res)
|
||||
|
||||
@api.model
|
||||
@tools.ormcache("model_name")
|
||||
def get_field_help(self, model_name):
|
||||
res = super(IrModelFields, self).get_field_help(model_name)
|
||||
return self._debrand_dict(res)
|
||||
|
||||
@api.model
|
||||
def decorated_clear_caches(self):
|
||||
"""For calling clear_caches from via xml <function ... />
|
||||
we wrapped it in the api.model decorator
|
||||
|
||||
"""
|
||||
self.env.registry.clear_cache()
|
||||
|
||||
@api.model
|
||||
@tools.ormcache("model_name", "field_name")
|
||||
def get_field_selection(self, model_name, field_name):
|
||||
# FIXED for Odoo 19: безопасный вызов оригинала
|
||||
original_method = IrModelFieldsOriginal.get_field_selection
|
||||
if hasattr(original_method, '__wrapped__'):
|
||||
selection = original_method.__wrapped__(self, model_name, field_name)
|
||||
else:
|
||||
selection = original_method(self, model_name, field_name)
|
||||
return [(value, debrand(self.env, name)) for value, name in selection]
|
||||
73
web_debranding/models/ir_ui_view.py
Normal file
73
web_debranding/models/ir_ui_view.py
Normal file
@ -0,0 +1,73 @@
|
||||
# Copyright 2016-2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
|
||||
# Copyright 2017 ArtyomLosev <https://github.com/ArtyomLosev>
|
||||
# Copyright 2017 Ilmir Karamov <https://it-projects.info/team/ilmir-k>
|
||||
# Copyright 2022 IT-Projects <https://it-projects.info/>
|
||||
# License MIT (https://opensource.org/licenses/MIT).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import api, models
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
from .ir_translation import debrand
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
MODULE = "_web_debranding"
|
||||
|
||||
|
||||
class View(models.Model):
|
||||
_inherit = "ir.ui.view"
|
||||
|
||||
def get_combined_arch(self):
|
||||
res = super(View, self).get_combined_arch()
|
||||
res = debrand(self.env, res, is_code=True)
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _create_debranding_views(self):
|
||||
"""Create UI views that may work only in one Odoo edition"""
|
||||
return True
|
||||
|
||||
@api.model
|
||||
def _create_view(self, name, inherit_id, arch, noupdate=False, view_type="qweb"):
|
||||
view = self.env.ref("{}.{}".format(MODULE, name), raise_if_not_found=False)
|
||||
if view:
|
||||
try:
|
||||
view.write({"arch": arch})
|
||||
view._check_xml()
|
||||
except Exception:
|
||||
_logger.warning(
|
||||
"Cannot update view %s. Delete it.", name, exc_info=True
|
||||
)
|
||||
view.unlink()
|
||||
return
|
||||
|
||||
return view.id
|
||||
|
||||
try:
|
||||
with self.env.cr.savepoint(), mute_logger("odoo.models"):
|
||||
view = self.env["ir.ui.view"].create(
|
||||
{
|
||||
"name": name,
|
||||
"type": view_type,
|
||||
"arch": arch,
|
||||
"inherit_id": self.env.ref(
|
||||
inherit_id, raise_if_not_found=True
|
||||
).id,
|
||||
}
|
||||
)
|
||||
view._check_xml()
|
||||
except Exception:
|
||||
_logger.debug("Cannot create view %s. Cancel.", name, exc_info=True)
|
||||
return
|
||||
self.env["ir.model.data"].create(
|
||||
{
|
||||
"name": name,
|
||||
"model": "ir.ui.view",
|
||||
"module": MODULE,
|
||||
"res_id": view.id,
|
||||
"noupdate": noupdate,
|
||||
}
|
||||
)
|
||||
return view.id
|
||||
30
web_debranding/models/publisher_warranty_contract.py
Normal file
30
web_debranding/models/publisher_warranty_contract.py
Normal file
@ -0,0 +1,30 @@
|
||||
# Copyright 2015-2018 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
|
||||
# Copyright 2016 Stanislav Krotov <https://it-projects.info/team/ufaks>
|
||||
# Copyright 2017 Ilmir Karamov <https://it-projects.info/team/ilmir-k>
|
||||
# License MIT (https://opensource.org/licenses/MIT).
|
||||
|
||||
import logging
|
||||
|
||||
from odoo import models
|
||||
from odoo.release import version_info
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PublisherWarrantyContract(models.AbstractModel):
|
||||
_inherit = "publisher_warranty.contract"
|
||||
|
||||
def update_notification(self, cron_mode=True):
|
||||
is_enterprise = version_info[5] == "e"
|
||||
_logger.debug("is_enterprise=%s", is_enterprise)
|
||||
# Running Odoo EE without calling super is illegal. So, make it impossible to disable in enterprise. See README.rst for details
|
||||
if (
|
||||
is_enterprise
|
||||
or self.env["ir.config_parameter"]
|
||||
.get_debranding_parameters()
|
||||
.get("web_debranding.send_publisher_warranty_url")
|
||||
== "1"
|
||||
):
|
||||
return super(PublisherWarrantyContract, self).update_notification(cron_mode)
|
||||
else:
|
||||
return True
|
||||
12
web_debranding/models/res_company.py
Normal file
12
web_debranding/models/res_company.py
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright 2020 Ivan Yelizariev
|
||||
# License OPL-1 (https://www.odoo.com/documentation/user/14.0/legal/licenses/licenses.html#odoo-apps).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class Company(models.Model):
|
||||
_inherit = "res.company"
|
||||
|
||||
def _get_default_favicon(self, original=False):
|
||||
return None
|
||||
|
||||
favicon = fields.Binary(default=_get_default_favicon)
|
||||
73
web_debranding/models/res_config_settings.py
Normal file
73
web_debranding/models/res_config_settings.py
Normal file
@ -0,0 +1,73 @@
|
||||
# Copyright 2021-2022 Ivan Yelizariev <https://it-projects.info/team/yelizariev>
|
||||
# License OPL-1 (https://www.odoo.com/documentation/user/14.0/legal/licenses/licenses.html#odoo-apps) for derivative work.
|
||||
|
||||
from lxml import etree
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
@api.model
|
||||
def fields_view_get(
|
||||
self, view_id=None, view_type="form", toolbar=False, submenu=False
|
||||
):
|
||||
ret_val = super(ResConfigSettings, self).fields_view_get(
|
||||
view_id=view_id, view_type=view_type, toolbar=toolbar, submenu=submenu
|
||||
)
|
||||
|
||||
page_name = ret_val["name"]
|
||||
if not page_name == "res.config.settings.view.form":
|
||||
return ret_val
|
||||
|
||||
doc = etree.XML(ret_val["arch"])
|
||||
|
||||
general_redirect_queries = [
|
||||
"//div[@id='sms']",
|
||||
"//div[@id='partner_autocomplete']",
|
||||
"//div[@id='iap_portal']",
|
||||
]
|
||||
for query in general_redirect_queries:
|
||||
for item in doc.xpath(query):
|
||||
item.getparent().remove(item)
|
||||
|
||||
crm_redirect_queries = [
|
||||
"//div[@id='crm_iap_lead_settings']",
|
||||
"//div[@id='crm_iap_lead_website_settings']",
|
||||
"//div[@id='crm_iap_lead_enrich']",
|
||||
"//div[@id='crm_iap_mine_settings']",
|
||||
"//div[@id='crm_iap_enrich_settings']",
|
||||
]
|
||||
for query in crm_redirect_queries:
|
||||
for item in doc.xpath(query):
|
||||
checkbox = item.getprevious()
|
||||
checkbox.getparent().remove(checkbox)
|
||||
item.getparent().remove(item)
|
||||
|
||||
snailmail_query = "//div[@id='send_invoices_followups']"
|
||||
for item in doc.xpath(snailmail_query):
|
||||
item.set("style", "display:none")
|
||||
|
||||
sms_confirmation_query = "//div[@id='stock_sms']"
|
||||
for item in doc.xpath(sms_confirmation_query):
|
||||
item.set("style", "display:none")
|
||||
|
||||
enterprise_query = "//div[div[field[@widget='upgrade_boolean']]]"
|
||||
for item in doc.xpath(enterprise_query):
|
||||
item.set("style", "display:none")
|
||||
|
||||
# Hide doc links in Settings (unmaintained feature, because the module already replaces links to custom ones)
|
||||
# question_mark_query = "//a[@class='o_doc_link']"
|
||||
# for item in doc.xpath(question_mark_query):
|
||||
# item.set("style", "display:none")
|
||||
|
||||
container_query = "//div[@class='row mt16 o_settings_container']"
|
||||
for item in doc.xpath(container_query):
|
||||
if not item.getchildren():
|
||||
title = item.getprevious()
|
||||
title.getparent().remove(title)
|
||||
item.getparent().remove(item)
|
||||
|
||||
ret_val["arch"] = etree.tostring(doc)
|
||||
return ret_val
|
||||
10
web_debranding/models/res_users.py
Normal file
10
web_debranding/models/res_users.py
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright 2018 Kolushov Alexandr <https://it-projects.info/team/KolushovAlexandr>
|
||||
# License MIT (https://opensource.org/licenses/MIT).
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = "res.users"
|
||||
|
||||
odoobot_state = fields.Selection(string="Bot Status")
|
||||
Reference in New Issue
Block a user