[IMP] website: Revamp website settings

Simplify settings of website & website_sale;
- understandable
- relevant
- correctly ordered

Part-of: odoo/odoo#82999
This commit is contained in:
Yannick Tivisse
2022-02-08 14:53:39 +00:00
parent 86ea0da6f6
commit 73483c8e5a
28 changed files with 921 additions and 693 deletions
+3 -3
View File
@@ -130,11 +130,11 @@ class ResConfigSettings(models.TransientModel):
setting.predictive_lead_scoring_field_labels = _('Stage')
def set_values(self):
group_use_lead = self.env.ref('crm.group_use_lead')
has_group_lead_before = group_use_lead in self.env.user.groups_id
group_use_lead_id = self.env['ir.model.data']._xmlid_to_res_id('crm.group_use_lead')
has_group_lead_before = group_use_lead_id in self.env.user.groups_id.ids
super(ResConfigSettings, self).set_values()
# update use leads / opportunities setting on all teams according to settings update
has_group_lead_after = group_use_lead in self.env.user.groups_id
has_group_lead_after = group_use_lead_id in self.env.user.groups_id.ids
if has_group_lead_before != has_group_lead_after:
teams = self.env['crm.team'].search([])
teams.filtered('use_opportunities').use_leads = has_group_lead_after
+148 -111
View File
@@ -13,116 +13,173 @@ class ResConfigSettings(models.TransientModel):
def _default_website(self):
return self.env['website'].search([('company_id', '=', self.env.company.id)], limit=1)
website_id = fields.Many2one('website', string="website",
default=_default_website, ondelete='cascade')
website_name = fields.Char('Website Name', related='website_id.name', readonly=False)
website_domain = fields.Char('Website Domain', related='website_id.domain', readonly=False)
website_country_group_ids = fields.Many2many(related='website_id.country_group_ids', readonly=False)
website_company_id = fields.Many2one(related='website_id.company_id', string='Website Company', readonly=False)
website_logo = fields.Binary(related='website_id.logo', readonly=False)
language_ids = fields.Many2many(related='website_id.language_ids', relation='res.lang', readonly=False)
website_language_count = fields.Integer(string='Number of languages', compute='_compute_website_language_count', readonly=True)
website_default_lang_id = fields.Many2one(string='Default language', related='website_id.default_lang_id', readonly=False)
website_default_lang_code = fields.Char('Default language code', related='website_id.default_lang_id.code', readonly=False)
specific_user_account = fields.Boolean(related='website_id.specific_user_account', readonly=False,
help='Are newly created user accounts website specific')
website_cookies_bar = fields.Boolean(related='website_id.cookies_bar', readonly=False)
website_id = fields.Many2one(
'website',
string="website",
default=_default_website, ondelete='cascade')
website_name = fields.Char(
'Website Name',
related='website_id.name',
readonly=False)
website_domain = fields.Char(
'Website Domain',
related='website_id.domain',
readonly=False)
website_country_group_ids = fields.Many2many(
related='website_id.country_group_ids',
readonly=False)
website_company_id = fields.Many2one(
related='website_id.company_id',
string='Website Company',
readonly=False)
website_logo = fields.Binary(
related='website_id.logo',
readonly=False)
language_ids = fields.Many2many(
related='website_id.language_ids',
relation='res.lang',
readonly=False)
website_language_count = fields.Integer(
string='Number of languages',
compute='_compute_website_language_count',
readonly=True)
website_default_lang_id = fields.Many2one(
string='Default language',
related='website_id.default_lang_id',
readonly=False)
website_default_lang_code = fields.Char(
'Default language code',
related='website_id.default_lang_id.code',
readonly=False)
shared_user_account = fields.Boolean(
string="Shared Customer Accounts",
compute='_compute_shared_user_account',
inverse='_inverse_shared_user_account')
website_cookies_bar = fields.Boolean(
related='website_id.cookies_bar',
readonly=False)
google_analytics_key = fields.Char(
'Google Analytics Key',
related='website_id.google_analytics_key',
readonly=False)
google_management_client_id = fields.Char(
'Google Client ID',
related='website_id.google_management_client_id',
readonly=False)
google_management_client_secret = fields.Char(
'Google Client Secret',
related='website_id.google_management_client_secret',
readonly=False)
google_search_console = fields.Char(
'Google Search Console',
related='website_id.google_search_console',
readonly=False)
google_analytics_key = fields.Char('Google Analytics Key', related='website_id.google_analytics_key', readonly=False)
google_management_client_id = fields.Char('Google Client ID', related='website_id.google_management_client_id', readonly=False)
google_management_client_secret = fields.Char('Google Client Secret', related='website_id.google_management_client_secret', readonly=False)
google_search_console = fields.Char('Google Search Console', related='website_id.google_search_console', readonly=False)
cdn_activated = fields.Boolean(
related='website_id.cdn_activated',
readonly=False)
cdn_url = fields.Char(
related='website_id.cdn_url',
readonly=False)
cdn_filters = fields.Text(
related='website_id.cdn_filters',
readonly=False)
auth_signup_uninvited = fields.Selection(
compute="_compute_auth_signup_uninvited",
inverse="_inverse_auth_signup_uninvited")
cdn_activated = fields.Boolean(related='website_id.cdn_activated', readonly=False)
cdn_url = fields.Char(related='website_id.cdn_url', readonly=False)
cdn_filters = fields.Text(related='website_id.cdn_filters', readonly=False)
auth_signup_uninvited = fields.Selection(compute="_compute_auth_signup", inverse="_set_auth_signup")
favicon = fields.Binary(
'Favicon',
related='website_id.favicon',
readonly=False)
social_default_image = fields.Binary(
'Default Social Share Image',
related='website_id.social_default_image',
readonly=False)
social_twitter = fields.Char(related='website_id.social_twitter', readonly=False)
social_facebook = fields.Char(related='website_id.social_facebook', readonly=False)
social_github = fields.Char(related='website_id.social_github', readonly=False)
social_linkedin = fields.Char(related='website_id.social_linkedin', readonly=False)
social_youtube = fields.Char(related='website_id.social_youtube', readonly=False)
social_instagram = fields.Char(related='website_id.social_instagram', readonly=False)
group_multi_website = fields.Boolean(
"Multi-website",
implied_group="website.group_multi_website")
has_google_analytics = fields.Boolean(
"Google Analytics",
compute='_compute_has_google_analytics',
inverse='_inverse_has_google_analytics')
has_google_analytics_dashboard = fields.Boolean(
"Google Analytics Dashboard",
compute='_compute_has_google_analytics_dashboard',
inverse='_inverse_has_google_analytics_dashboard')
has_google_search_console = fields.Boolean(
"Console Google Search",
compute='_compute_has_google_search_console',
inverse='_inverse_has_google_search_console')
has_default_share_image = fields.Boolean(
"Use a image by default for sharing",
compute='_compute_has_default_share_image',
inverse='_inverse_has_default_share_image')
module_website_livechat = fields.Boolean()
module_marketing_automation = fields.Boolean()
@api.depends('website_id', 'social_twitter', 'social_facebook', 'social_github', 'social_linkedin', 'social_youtube', 'social_instagram')
def has_social_network(self):
self.has_social_network = self.social_twitter or self.social_facebook or self.social_github \
or self.social_linkedin or self.social_youtube or self.social_instagram
@api.depends('website_id')
def _compute_shared_user_account(self):
for config in self:
config.shared_user_account = not config.website_id.specific_user_account
def inverse_has_social_network(self):
if not self.has_social_network:
self.social_twitter = ''
self.social_facebook = ''
self.social_github = ''
self.social_linkedin = ''
self.social_youtube = ''
self.social_instagram = ''
def _inverse_shared_user_account(self):
for config in self:
config.website_id.specific_user_account = not config.shared_user_account
has_social_network = fields.Boolean("Configure Social Network", compute=has_social_network, inverse=inverse_has_social_network)
favicon = fields.Binary('Favicon', related='website_id.favicon', readonly=False)
social_default_image = fields.Binary('Default Social Share Image', related='website_id.social_default_image', readonly=False)
google_maps_api_key = fields.Char(related='website_id.google_maps_api_key', readonly=False)
group_multi_website = fields.Boolean("Multi-website", implied_group="website.group_multi_website")
@api.onchange('website_id')
@api.depends('website_id.auth_signup_uninvited')
def _compute_auth_signup(self):
self.auth_signup_uninvited = self.website_id.auth_signup_uninvited
def _compute_auth_signup_uninvited(self):
for config in self:
config.auth_signup_uninvited = config.website_id.auth_signup_uninvited
def _set_auth_signup(self):
def _inverse_auth_signup_uninvited(self):
for config in self:
config.website_id.auth_signup_uninvited = config.auth_signup_uninvited
@api.depends('website_id')
def has_google_analytics(self):
self.has_google_analytics = bool(self.google_analytics_key)
def _compute_has_google_analytics(self):
for config in self:
config.has_google_analytics = bool(config.google_analytics_key)
def _inverse_has_google_analytics(self):
for config in self:
if config.has_google_analytics:
continue
config.has_google_analytics_dashboard = False
config.google_analytics_key = False
@api.depends('website_id')
def has_google_analytics_dashboard(self):
self.has_google_analytics_dashboard = bool(self.google_management_client_id)
def _compute_has_google_analytics_dashboard(self):
for config in self:
config.has_google_analytics_dashboard = bool(config.google_management_client_id)
def _inverse_has_google_analytics_dashboard(self):
for config in self:
if config.has_google_analytics_dashboard:
continue
config.google_management_client_id = False
config.google_management_client_secret = False
@api.depends('website_id')
def has_google_maps(self):
self.has_google_maps = bool(self.google_maps_api_key)
def _compute_has_google_search_console(self):
for config in self:
config.has_google_search_console = bool(config.google_search_console)
def _inverse_has_google_search_console(self):
for config in self:
if not config.has_google_search_console:
config.google_search_console = False
@api.depends('website_id')
def has_default_share_image(self):
self.has_default_share_image = bool(self.social_default_image)
def _compute_has_default_share_image(self):
for config in self:
config.has_default_share_image = bool(config.social_default_image)
@api.depends('website_id')
def has_google_search_console(self):
self.has_google_search_console = bool(self.google_search_console)
def inverse_has_google_analytics(self):
if not self.has_google_analytics:
self.has_google_analytics_dashboard = False
self.google_analytics_key = False
def inverse_has_google_maps(self):
if not self.has_google_maps:
self.google_maps_api_key = False
def inverse_has_google_analytics_dashboard(self):
if not self.has_google_analytics_dashboard:
self.google_management_client_id = False
self.google_management_client_secret = False
def inverse_has_google_search_console(self):
if not self.has_google_search_console:
self.google_search_console = False
def inverse_has_default_share_image(self):
if not self.has_default_share_image:
self.social_default_image = False
has_google_analytics = fields.Boolean("Google Analytics", compute=has_google_analytics, inverse=inverse_has_google_analytics)
has_google_analytics_dashboard = fields.Boolean("Google Analytics Dashboard", compute=has_google_analytics_dashboard, inverse=inverse_has_google_analytics_dashboard)
has_google_maps = fields.Boolean("Google Maps", compute=has_google_maps, inverse=inverse_has_google_maps)
has_google_search_console = fields.Boolean("Console Google Search", compute=has_google_search_console, inverse=inverse_has_google_search_console)
has_default_share_image = fields.Boolean("Use a image by default for sharing", compute=has_default_share_image, inverse=inverse_has_default_share_image)
def _inverse_has_default_share_image(self):
for config in self:
if not config.has_default_share_image:
config.social_default_image = False
@api.onchange('language_ids')
def _onchange_language_ids(self):
@@ -139,20 +196,6 @@ class ResConfigSettings(models.TransientModel):
for config in self:
config.website_language_count = len(config.language_ids)
def open_template_user(self):
action = self.env["ir.actions.actions"]._for_xml_id("base.action_res_users")
action['res_id'] = literal_eval(self.env['ir.config_parameter'].sudo().get_param('base.template_portal_user_id', 'False'))
action['views'] = [[self.env.ref('base.view_users_form').id, 'form']]
return action
def website_go_to(self):
self.website_id._force()
return {
'type': 'ir.actions.act_url',
'url': '/',
'target': 'self',
}
def action_website_create_new(self):
return {
'view_mode': 'form',
@@ -183,9 +226,3 @@ class ResConfigSettings(models.TransientModel):
'url': 'http://www.google.com/ping?sitemap=%s/sitemap.xml' % self.website_id.domain,
'target': 'new',
}
def install_theme_on_current_website(self):
self.website_id._force()
action = self.env["ir.actions.actions"]._for_xml_id("website.theme_install_kanban_action")
action['target'] = 'main'
return action
@@ -37,10 +37,8 @@ BaseSettingController.include({
* @override
*/
_onButtonClicked: function (ev) {
if (ev.data.attrs.name === 'website_go_to'
|| ev.data.attrs.name === 'action_open_robots'
|| ev.data.attrs.name === 'action_ping_sitemap'
|| ev.data.attrs.name === 'install_theme_on_current_website') {
if (ev.data.attrs.name === 'action_open_robots'
|| ev.data.attrs.name === 'action_ping_sitemap') {
FormController.prototype._onButtonClicked.apply(this, arguments);
} else {
this._super.apply(this, arguments);
+295 -413
View File
@@ -1,429 +1,311 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.website</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block" data-string="Website" string="Website" data-key="website" groups="website.group_website_designer">
<h2 groups="website.group_multi_website">Select the Website to Configure</h2>
<div class="row mt16 o_settings_container" id="website_selection_settings" groups="website.group_multi_website">
<div class="col-xs-12 col-md-6 o_setting_box" id="website">
<div class="o_setting_right_pane">
<label string="Website" for="website_id"/>
<div class="text-muted">
Settings on this page will apply to this website
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.website</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block" data-string="Website" string="Website" data-key="website" groups="website.group_website_designer">
<div class="row o_settings_container mb-0 mt-0 ml-0 mw-100"
style="background-color: #FEF0D0; margin-bottom: 0px !important; margin-top: 0px !important;">
<div class="col-xs-12 col-md-6 ml-0 o_setting_box">
<div class="o_setting_right_pane border-left-0 ml-0 pl-0">
<div class="content-group">
<div class="row mt8">
<label class="col-lg-3 pl-0" string="Settings of Website" for="website_id"/>
<field name="website_id" options="{'no_open': True, 'no_create': True}" title="Settings on this page will apply to this website"/>
<button name="action_website_create_new" type="object" string="+ New Website" class="btn-link ml-2" style="line-height: 0.5;"/>
</div>
</div>
</div>
</div>
</div>
<h2>Website Info</h2>
<div class="col-xs-12 col-md-6 row o_settings_container" id="website_info_settings">
<div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_right_pane border-left-0">
<div class="content-group">
<div class="row mt8">
<label class="col-lg-3" string="Domain" for="website_domain"/>
<field name="website_domain" placeholder="https://www.odoo.com" title="Display this website when users visit this domain"/>
</div>
<div class="row mt8" groups="base.group_no_one">
<label class="col-lg-3" string="Country Groups" for="website_country_group_ids"/>
<field name="website_country_group_ids" widget="many2many_tags" title="Once the selection of available websites by domain is done, you can filter by country group. You can have 2 websites with same domain AND a condition on country group to select which website to use."/>
</div>
<div class="row mt8">
<label class="col-lg-3" string="Languages" for="language_ids"/>
<field name="language_ids" widget="many2many_tags" options="{'no_create': True, 'no_open': True}" attrs="{'required': [('website_id', '!=', False)]}" title="Languages available on your website"/>
</div>
<div class="row mt8" attrs="{'invisible': [('website_language_count', '&lt;', 2)]}">
<field name="website_language_count" invisible="1"/>
<label class="col-lg-3" string="Default" for="website_default_lang_id"/>
<field name="website_default_lang_id" options="{'no_open': True, 'no_create': True}" attrs="{'required': [('website_id', '!=', False)]}"/>
</div>
<div class="mt8">
<button type="action" name="%(base.action_view_base_language_install)d" string="Install a language" class="btn-link" icon="fa-arrow-right"/>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_right_pane border-left-0">
<div class="content-group">
<div class="row mt8">
<label class="col-lg-3" string="Website Name" for="website_name"/>
<field name="website_name" attrs="{'required': [('website_id', '!=', False)]}"/>
</div>
<div class="row mt8" groups="base.group_multi_company">
<label class="col-lg-3" string="Company" for="website_company_id"/>
<field name="website_company_id" attrs="{'required': [('website_id', '!=', False)]}" title="The company this website belongs to"/>
</div>
<div class="row mt8">
<label class="col-lg-3" string="Favicon" for="favicon"/>
<field name="favicon" widget="image" class="float-left oe_avatar"/>
</div>
<div class="mt16">
<field name="website_id" options="{'no_open': True, 'no_create': True}"/>
</div>
<div>
<button name="action_website_create_new" type="object" string="Create a New Website" class="btn-secondary" icon="fa-arrow-right"/>
</div>
</div>
</div>
</div>
<h2>Website <button name="action_website_create_new" type="object" string="New" class="ml-2 btn btn-link" icon="fa-plus" groups="!website.group_multi_website"/></h2>
<div class="row mt16 o_settings_container" id="website_settings_placeholder" attrs="{'invisible': [('website_id', '!=', False)]}">
<div class="col-12 o_setting_box">
<div class="text-muted" groups="website.group_multi_website">
Select a website to load its settings.
</div>
<div class="text-muted" groups="!website.group_multi_website">
There is no website available for this company. You could create a new one.
</div>
</div>
</div>
<!-- !! Every fields inside this container should be website specific (related to website record) !! -->
<div class="row mt16 o_settings_container" id="website_settings" attrs="{'invisible': [('website_id', '=', False)]}">
<div class="col-12 o_setting_box" id="website_action_setting" style="margin-left: 30px; margin-bottom: 16px;">
<button name="website_go_to" type="object" string="Go to Website" class="btn btn-primary" icon="fa-globe"/>
<button name="install_theme_on_current_website" type="object" string="Pick a Theme" class="ml-2 btn btn-secondary" icon="fa-paint-brush"/>
<button name="%(website.action_website_add_features)d" type="action" string="Add features" class="ml-2 btn btn-secondary" icon="fa-plus"/>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="domain_setting">
<div class="o_setting_right_pane">
<label for="website_name" string="Website Title"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Name and favicon of your website
</div>
<div class="content-group">
<div class="row mt16">
<label class="col-lg-3 o_light_label" string="Name" for="website_name"/>
<field name="website_name" attrs="{'required': [('website_id', '!=', False)]}"/>
</div>
<div class="row">
<label class="col-lg-3 o_light_label" for="favicon" />
<field name="favicon" widget="image" class="float-left oe_avatar"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="company_settings" groups="base.group_multi_company">
<div class="o_setting_right_pane">
<label string="Company" for="website_company_id"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
The company this website belongs to
</div>
<field name="website_company_id" attrs="{'required': [('website_id', '!=', False)]}" />
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="languages_setting">
<div class="o_setting_right_pane">
<label for="language_ids"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Languages available on your website
</div>
<div class="content-group">
<div class="mt16">
<field name="language_ids" widget="many2many_tags" options="{'no_create': True, 'no_open': True}"
attrs="{'required': [('website_id', '!=', False)]}"/>
</div>
<field name="website_language_count" invisible="1"/>
<div class="mt8" attrs="{'invisible':[('website_language_count', '&lt;', 2)]}">
<label class="o_light_label mr8" string="Default" for="website_default_lang_id"/>
<field name="website_default_lang_id" options="{'no_open': True, 'no_create': True}" attrs="{'required': [('website_id', '!=', False)]}"/>
</div>
</div>
<div class="mt8">
<button type="action" name="%(base.action_view_base_language_install)d" string="Install new language" class="btn-link" icon="fa-arrow-right"/>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="domain_settings">
<div class="o_setting_right_pane">
<label string="Domain" for="website_domain"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Display this website when users visit this domain
</div>
<div class="mt8">
<field name="website_domain" placeholder="https://www.odoo.com"/>
</div>
<div groups="base.group_no_one">
<div class="mt8 text-muted" title="You can have 2 websites with same domain AND a condition on country group to select wich website use.">
Once the selection of available websites by domain is done, you can filter by country group.
</div>
<div class="mt8">
<field name="website_country_group_ids" widget="many2many_tags"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="specific_user_account_setting" groups="website.group_multi_website">
<div class="o_setting_left_pane">
<field name="specific_user_account"/>
</div>
<div class="o_setting_right_pane">
<label for="specific_user_account"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Force your user to create an account per website
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="website_cookies_bar_setting">
<div class="o_setting_left_pane">
<field name="website_cookies_bar" widget="website_cookiesbar_field"/>
</div>
<div class="o_setting_right_pane">
<label for="website_cookies_bar"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Display a customizable cookies bar on your website.
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="cdn_setting" title="A CDN helps you serve your website’s content with high availability and high performance to any visitor wherever they are located." groups="base.group_no_one">
<div class="o_setting_left_pane">
<field name="cdn_activated"/>
</div>
<div class="o_setting_right_pane">
<label for="cdn_activated"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Use a CDN to optimize the availability of your website's content
</div>
<div class="content-group" attrs="{'invisible': [('cdn_activated', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" for="cdn_url"/>
<field name="cdn_url"
attrs="{'required': [('cdn_activated', '=', True)]}"
placeholder="//mycompany.mycdn.com/"
t-translation="off"/>
</div>
<div class="row" >
<label class="col-lg-3 o_light_label" for="cdn_filters"/>
<field name="cdn_filters" class="oe_inline"
attrs="{'required': [('cdn_activated', '=', True)]}"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="social_media_settings" groups="base.group_no_one">
<div class="o_setting_left_pane">
<field name="has_social_network"/>
</div>
<div class="o_setting_right_pane">
<label string="Social Media" for="has_social_network"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Add links to social media on your website
</div>
<div class="content-group" attrs="{'invisible': [('has_social_network', '=', False)]}">
<div class="row">
<label for="social_twitter" string="Twitter" class="col-md-3 o_light_label"/>
<field name="social_twitter"/>
</div>
<div class="row">
<label for="social_facebook" string="Facebook" class="col-md-3 o_light_label"/>
<field name="social_facebook"/>
</div>
<div class="row">
<label for="social_github" string="GitHub" class="col-md-3 o_light_label"/>
<field name="social_github"/>
</div>
<div class="row">
<label for="social_linkedin" string="LinkedIn" class="col-md-3 o_light_label"/>
<field name="social_linkedin"/>
</div>
<div class="row">
<label for="social_youtube" string="YouTube" class="col-md-3 o_light_label"/>
<field name="social_youtube"/>
</div>
<div class="row">
<label for="social_instagram" string="Instagram" class="col-md-3 o_light_label"/>
<field name="social_instagram"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="social_default_image_setting">
<div class="o_setting_left_pane">
<field name="has_default_share_image"/>
</div>
<div class="o_setting_right_pane">
<label string="Default Social Share Image" for="has_default_share_image"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted" attrs="{'invisible': [('has_default_share_image', '=', False)]}">
If set, replaces the website logo as the default social share image.
</div>
<field name="social_default_image" widget="image" class="w-25 mt-2" attrs="{'invisible': [('has_default_share_image', '=', False)]}"/>
</div>
</div>
</div>
<h2>Features</h2>
<div class="row mt16 o_settings_container" id="webmaster_settings">
<div class="col-12 col-lg-6 o_setting_box" id="google_maps_setting">
<div class="o_setting_left_pane">
<field name="has_google_maps"/>
</div>
<div class="o_setting_right_pane">
<label for="has_google_maps"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Use Google Map on your website (<a href="/contactus">Contact Us</a> page, snippets, ...)
</div>
<div class="content-group" attrs="{'invisible': [('has_google_maps', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" string="API Key" for="google_maps_api_key"/>
<field name="google_maps_api_key" attrs="{'required': [('has_google_maps', '=', True)]}" />
</div>
</div>
<div class="mt8" attrs="{'invisible': [('has_google_maps', '=', False)]}">
<a role="button" class="btn-link" target="_blank"
href="https://console.developers.google.com/flows/enableapi?apiid=maps_backend,static_maps_backend&amp;keyType=CLIENT_SIDE&amp;reusekey=true">
<i class="fa fa-arrow-right"/>
Create a Google Project and Get a Key
</a>
<a role="button" class="btn-link" target="_blank"
href="https://cloud.google.com/maps-platform/pricing">
<i class="fa fa-arrow-right"/>
Enable billing on your Google Project
</a>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="auth_signup_uninvited_setting"
title=" To send invitations in B2B mode, open a contact or select several ones in list view and click on 'Portal Access Management' option in the dropdown menu *Action*.">
<div class="o_setting_left_pane">
</div>
<div class="o_setting_right_pane">
<label for="auth_signup_uninvited"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Let your customers log in to see their documents
</div>
<div class="mt8">
<field name="auth_signup_uninvited" class="o_light_label" widget="radio" options="{'horizontal': true}" required="True"/>
</div>
<div class="mt8 content-group">
<button type="object" name="open_template_user" string="Default Access Rights" icon="fa-arrow-right" class="btn-link"/>
</div>
</div>
</div>
</div>
<h2>SEO</h2>
<div class="row mt16 o_settings_container" id="seo_settings">
<div class="col-12 col-lg-offset-6 col-lg-6 o_setting_box" id="google_analytics_setting">
<div class="o_setting_left_pane">
<field name="has_google_analytics"/>
</div>
<div class="o_setting_right_pane">
<label for="has_google_analytics"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Track visits in Google Analytics
</div>
<div class="content-group" attrs="{'invisible': [('has_google_analytics', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" string="Measurement ID" for="google_analytics_key"/>
<field name="google_analytics_key" placeholder="G-XXXXXXXXXX"
attrs="{'required': [('has_google_analytics', '=', True)]}"/>
</div>
</div>
<div attrs="{'invisible': [('has_google_analytics', '=', False)]}">
<a href="https://www.odoo.com/documentation/15.0/applications/websites/website/optimize/google_analytics.html"
class="oe_link" target="_blank">
<i class="fa fa-arrow-right"/>
How to get my Measurement ID
</a>
</div>
</div>
</div>
<div class="col-12 col-lg-offset-6 col-lg-6 o_setting_box" id="google_console_setting">
<div class="o_setting_left_pane">
<field name="has_google_search_console"/>
</div>
<div class="o_setting_right_pane">
<label for="has_google_search_console"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Monitor Google Search results data
</div>
<div class="content-group" attrs="{'invisible': [('has_google_search_console', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" string="Code" for="google_search_console"/>
<field name="google_search_console" placeholder="google1234567890123456.html"
attrs="{'required': [('has_google_search_console', '=', True)]}"/>
</div>
</div>
<div attrs="{'invisible': [('has_google_search_console', '=', False)]}">
<small class='text-muted'>
<i class="fa fa-info"/>: type some of the first chars after 'google' is enough, we'll guess the rest.
</small>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="google_analytics_dashboard_setting" attrs="{'invisible': [('has_google_analytics', '=', False)]}">
<div class="o_setting_left_pane">
<field name="has_google_analytics_dashboard"/>
</div>
<div class="o_setting_right_pane">
<label for="has_google_analytics_dashboard"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Follow your website traffic in Odoo.
</div>
<div class="content-group" attrs="{'invisible': [('has_google_analytics_dashboard', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" string="Client ID" for="google_management_client_id"/>
<field name="google_management_client_id" attrs="{'required': [('has_google_analytics_dashboard', '=', True)]}"/>
</div>
<div class="row">
<label class="col-lg-3 o_light_label" string="Client Secret" for="google_management_client_secret"/>
<field name="google_management_client_secret" attrs="{'required': [('has_google_analytics_dashboard', '=', True)]}"/>
</div>
</div>
<div attrs="{'invisible': [('has_google_analytics_dashboard', '=', False)]}">
<a href="https://www.odoo.com/documentation/15.0/applications/websites/website/optimize/google_analytics_dashboard.html"
class="oe_link" target="_blank">
<i class="fa fa-arrow-right"/>
How to get my Client ID
</a>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="robots_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Robots.txt</span>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Robots.txt: This file tells to search engine crawlers which pages or files they can or can't request from your site.<br/>
</div>
<div class="mt4">
<button type="object" name="action_open_robots" string="Edit robots.txt" class="btn-link" icon="fa-android"/>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="robots_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Sitemap</span>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted mt8">
Sitemap.xml: Help search engine crawlers to find out what pages are present and which have recently changed, and to crawl your site accordingly. This file is automatically generated by Odoo.
</div>
<div class="mt4">
<button type="object" name="action_ping_sitemap" string="Submit sitemap to Google" class='btn-link' icon="fa-google"/>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
<record id="action_website_configuration" model="ir.actions.act_window">
<field name="name">Settings</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.config.settings</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="context">{'module' : 'website', 'bin_size': False}</field>
</record>
<h2>Email &amp; Marketing</h2>
<div class="row mt16 o_settings_container" id="website_email_marketing">
<div class="col-xs-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="module_website_livechat"/>
</div>
<div class="o_setting_right_pane" id="livechat_right_pane">
<span class="o_form_label">Livechat</span>
<div class="text-muted">
Alows your visitors to chat with you
</div>
</div>
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" id="website_marketing_automation">
<div class="o_setting_left_pane">
<field name="module_marketing_automation" widget="upgrade_boolean"/>
</div>
<div class="o_setting_right_pane">
<span class="o_form_label">Email Marketing</span>
<div class="text-muted">
Allows to do mass mailing campaigns to contacts
</div>
</div>
</div>
</div>
<menuitem id="menu_website_global_configuration" parent="menu_website_configuration"
sequence="100" name="Configuration" groups="base.group_system"/>
<h2>Privacy</h2>
<div class="row mt16 o_settings_container" id="website_settings" attrs="{'invisible': [('website_id', '=', False)]}">
<div class="col-12 col-lg-6 o_setting_box" id="website_cookies_bar_setting">
<div class="o_setting_left_pane">
<field name="website_cookies_bar" widget="website_cookiesbar_field"/>
</div>
<div class="o_setting_right_pane">
<label for="website_cookies_bar"/>
<div class="text-muted">
Display a customizable cookies bar on your website
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="shared_user_account_setting" groups="website.group_multi_website">
<div class="o_setting_left_pane">
<field name="shared_user_account"/>
</div>
<div class="o_setting_right_pane">
<label for="shared_user_account"/>
<div class="text-muted">
Accounts are useable accross all your multiple websites
</div>
</div>
</div>
</div>
<h2>SEO</h2>
<div class="row mt16 o_settings_container" id="website_settings" attrs="{'invisible': [('website_id', '=', False)]}">
<div class="col-12 col-lg-offset-6 col-lg-6 o_setting_box" id="google_analytics_setting">
<div class="o_setting_left_pane">
<field name="has_google_analytics"/>
</div>
<div class="o_setting_right_pane">
<label for="has_google_analytics"/>
<div class="text-muted">
Track visits using Google Analytics
</div>
<div class="content-group" attrs="{'invisible': [('has_google_analytics', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" string="Measurement ID" for="google_analytics_key"/>
<field name="google_analytics_key" placeholder="G-XXXXXXXXXX"
attrs="{'required': [('has_google_analytics', '=', True)]}"/>
</div>
</div>
<div attrs="{'invisible': [('has_google_analytics', '=', False)]}">
<a href="https://www.odoo.com/documentation/15.0/applications/websites/website/optimize/google_analytics.html"
class="oe_link" target="_blank">
<i class="fa fa-arrow-right"/>
How to get my Measurement ID
</a>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="cdn_setting" title="A CDN helps you serve your website’s content with high availability and high performance to any visitor wherever they are located." groups="base.group_no_one">
<div class="o_setting_left_pane">
<field name="cdn_activated"/>
</div>
<div class="o_setting_right_pane">
<label for="cdn_activated"/>
<div class="text-muted">
Use a CDN to optimize the availability of your website's content
</div>
<div class="content-group" attrs="{'invisible': [('cdn_activated', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" for="cdn_url"/>
<field name="cdn_url"
attrs="{'required': [('cdn_activated', '=', True)]}"
placeholder="//mycompany.mycdn.com/"
t-translation="off"/>
</div>
<div class="row" >
<label class="col-lg-3 o_light_label" for="cdn_filters"/>
<field name="cdn_filters" class="oe_inline"
attrs="{'required': [('cdn_activated', '=', True)]}"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="robots_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Robots.txt</span>
<div class="text-muted">
Robots.txt: This file tells to search engine crawlers which pages or files they can or can't request from your site.<br/>
</div>
<div class="mt4">
<button type="object" name="action_open_robots" string="Edit robots.txt" class="btn-link" icon="fa-android"/>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="robots_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Sitemap</span>
<div class="text-muted mt8">
Sitemap.xml: Help search engine crawlers to find out what pages are present and which have recently changed, and to crawl your site accordingly. This file is automatically generated by Odoo.
</div>
<div class="mt4">
<button type="object" name="action_ping_sitemap" string="Submit sitemap to Google" class='btn-link' icon="fa-google"/>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="social_default_image_setting">
<div class="o_setting_left_pane">
<field name="has_default_share_image"/>
</div>
<div class="o_setting_right_pane">
<label string="Default Social Share Image" for="has_default_share_image"/>
<div class="text-muted">
If set, replaces the website logo as the default social share image.
</div>
<field name="social_default_image" widget="image" class="w-25 mt-2" attrs="{'invisible': [('has_default_share_image', '=', False)]}"/>
</div>
</div>
<div class="col-12 col-lg-offset-6 col-lg-6 o_setting_box" id="google_console_setting">
<div class="o_setting_left_pane">
<field name="has_google_search_console"/>
</div>
<div class="o_setting_right_pane">
<label for="has_google_search_console"/>
<div class="text-muted">
Monitor Google Search results data
</div>
<div class="content-group" attrs="{'invisible': [('has_google_search_console', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" string="Code" for="google_search_console"/>
<field name="google_search_console" placeholder="google1234567890123456.html"
attrs="{'required': [('has_google_search_console', '=', True)]}"/>
</div>
</div>
<div attrs="{'invisible': [('has_google_search_console', '=', False)]}">
<small class='text-muted'>
<i class="fa fa-info"/>: type some of the first chars after 'google' is enough, we'll guess the rest.
</small>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="google_analytics_dashboard_setting" attrs="{'invisible': [('has_google_analytics', '=', False)]}">
<div class="o_setting_left_pane">
<field name="has_google_analytics_dashboard"/>
</div>
<div class="o_setting_right_pane">
<label for="has_google_analytics_dashboard"/>
<div class="text-muted">
Follow your website traffic in Odoo.
</div>
<div class="content-group" attrs="{'invisible': [('has_google_analytics_dashboard', '=', False)]}">
<div class="row mt16">
<label class="col-lg-3 o_light_label" string="Client ID" for="google_management_client_id"/>
<field name="google_management_client_id" attrs="{'required': [('has_google_analytics_dashboard', '=', True)]}"/>
</div>
<div class="row">
<label class="col-lg-3 o_light_label" string="Client Secret" for="google_management_client_secret"/>
<field name="google_management_client_secret" attrs="{'required': [('has_google_analytics_dashboard', '=', True)]}"/>
</div>
</div>
<div attrs="{'invisible': [('has_google_analytics_dashboard', '=', False)]}">
<a href="https://www.odoo.com/documentation/15.0/applications/websites/website/optimize/google_analytics_dashboard.html"
class="oe_link" target="_blank">
<i class="fa fa-arrow-right"/>
How to get my Client ID
</a>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
<menuitem name="Settings"
id="menu_website_website_settings"
action="action_website_configuration"
parent="menu_website_global_configuration"
groups="base.group_system"
sequence="10"/>
<record id="action_website_configuration" model="ir.actions.act_window">
<field name="name">Settings</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.config.settings</field>
<field name="view_mode">form</field>
<field name="target">inline</field>
<field name="context">{'module' : 'website', 'bin_size': False}</field>
</record>
<menuitem id="menu_website_add_features" parent="website.menu_website_global_configuration"
sequence="20" groups="base.group_system" action="action_website_add_features"/>
<menuitem id="menu_website_global_configuration" parent="menu_website_configuration"
sequence="100" name="Configuration" groups="base.group_system"/>
<menuitem name="Websites"
id="menu_website_websites_list"
action="action_website_list"
parent="menu_website_global_configuration"
groups="base.group_no_one"
sequence="10"
/>
<menuitem name="Settings"
id="menu_website_website_settings"
action="action_website_configuration"
parent="menu_website_global_configuration"
groups="base.group_system"
sequence="10"/>
<menuitem name="Pages"
id="menu_website_pages_list"
action="action_website_pages_list"
parent="menu_website_global_configuration"
sequence="30"
/>
<menuitem id="menu_website_add_features" parent="website.menu_website_global_configuration"
sequence="20" groups="base.group_system" action="action_website_add_features"/>
<menuitem name="Menus"
id="menu_website_menu_list"
action="action_website_menu"
parent="menu_website_global_configuration"
sequence="45"
groups="base.group_no_one"/>
<menuitem name="Websites"
id="menu_website_websites_list"
action="action_website_list"
parent="menu_website_global_configuration"
groups="base.group_no_one"
sequence="10"
/>
<menuitem name="Pages"
id="menu_website_pages_list"
action="action_website_pages_list"
parent="menu_website_global_configuration"
sequence="30"
/>
<menuitem name="Menus"
id="menu_website_menu_list"
action="action_website_menu"
parent="menu_website_global_configuration"
sequence="45"
groups="base.group_no_one"/>
</odoo>
@@ -5,7 +5,7 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="webmaster_settings" position="after">
<xpath expr="//div[@data-key='website']" position="inside">
<h2>Communication</h2>
<div class="row mt16 o_settings_container" id="communication_settings">
<div class="col-12 col-lg-6 o_setting_box" id="contact_form_install_setting" title="New messages are managed as leads or opportunities in your CRM app.">
@@ -31,7 +31,7 @@
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>
@@ -1,29 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.website.livechat</field>
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="google_maps_setting" position="after">
<div class="col-12 col-lg-6 o_setting_box" id="live_chat_install_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Live Chat</span>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Live chat channel of your website
</div>
<div class="content-group mt16">
<div class="row">
<label class="col-lg-3 o_light_label" string="Channel" for="channel_id"/>
<field name="channel_id" class="oe_inline"/>
</div>
</div>
<div id="livechat_right_pane" position="inside">
<div class="content-group mt16">
<div class="row">
<label class="col-lg-3 o_light_label" string="Channel" for="channel_id"/>
<field name="channel_id" class="oe_inline"/>
</div>
</div>
</div>
</field>
</record>
</odoo>
+1
View File
@@ -16,6 +16,7 @@ This is a bridge module that adds multi-website support for payment acquirers.
'data': [
'data/donation_data.xml',
'views/payment_acquirer.xml',
'views/res_config_settings_views.xml',
'views/donation_templates.xml',
'views/snippets/snippets.xml',
'views/snippets/s_donation.xml',
@@ -4,3 +4,4 @@
from . import account_payment
from . import payment_acquirer
from . import payment_transaction
from . import res_config_settings
@@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
acquirers_state = fields.Selection(
selection=[
('none', 'None'),
('paypal_only', 'Paypal Only'),
('other_than_paypal', 'Other than Paypal')
],
compute='_compute_acquirers_state')
first_provider_label = fields.Char(
compute='_compute_acquirers_state')
module_payment_paypal = fields.Boolean(
string='Paypal - Express Checkout')
def _get_activated_acquirers(self):
self.ensure_one()
wire_transfer = self.env.ref('payment.payment_acquirer_transfer', raise_if_not_found=False)
return self.env['payment.acquirer'].search([
('state', '!=', 'disabled'),
('id', '!=', wire_transfer.id if wire_transfer else False),
'|',
('website_id', '=', False),
('website_id', '=', self.website_id.id)
])
@api.depends('website_id')
def _compute_acquirers_state(self):
paypal = self.env.ref('payment.payment_acquirer_paypal', raise_if_not_found=False)
stripe = self.env.ref('payment.payment_acquirer_stripe', raise_if_not_found=False)
for config in self:
acquirers = config._get_activated_acquirers()
first_provider = stripe if stripe in acquirers else acquirers[0] if acquirers else acquirers
config.first_provider_label = _('Configure %s', first_provider.name)
if len(acquirers) == 1 and acquirers == paypal:
config.acquirers_state = 'paypal_only'
elif len(acquirers) >= 1:
config.acquirers_state = 'other_than_paypal'
else:
config.acquirers_state = 'none'
def action_activate_stripe(self):
stripe = self.env.ref('payment.payment_acquirer_stripe')
stripe.button_immediate_install()
if stripe.state == 'disabled':
stripe.state = 'test'
return {
'type': 'ir.actions.client',
'tag': 'reload',
}
def action_configure_first_provider(self):
self.ensure_one()
stripe = self.env.ref('payment.payment_acquirer_stripe')
acquirers = self._get_activated_acquirers()
return {
'name': self.first_provider_label,
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'payment.acquirer',
'views': [[False, 'form']],
'res_id': stripe.id if stripe in acquirers else acquirers[0].id,
}
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.website</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="website_info_settings" position="after">
<h2>Shop - Payment</h2>
<div class="row mt16 o_settings_container" id="div_website_payment">
<div class="col-12 col-lg-6 o_setting_box" id="website_payment">
<div class="o_setting_right_pane">
<label for="company_id" string="Activate Payments"/>
<div class="text-muted">
Support most payment methods; Visa, Mastercard, Maestro, Google Pay, Apple Pay, etc. as well as recurring charges.
</div>
<div class="content-group">
<div class="row mt8 ml-4" attrs="{'invisible': [('acquirers_state', '=', 'other_than_paypal')]}">
<field name="acquirers_state" invisible="1"/>
<button name="action_activate_stripe" type="object" string="Activate Stripe" class="btn-primary"/>
<button type="action" name="%(payment.action_payment_acquirer)d" string="View Alternatives" class="btn-link" icon="fa-arrow-right"/>
</div>
<div class="row mt8 ml-4" attrs="{'invisible': [('acquirers_state', '!=', 'other_than_paypal')]}">
<button name="action_configure_first_provider" type="object" class="btn-primary"><field name="first_provider_label" nolabel="1"/></button>
<button type="action" name="%(payment.action_payment_acquirer)d" string="View other providers " class="btn-link" icon="fa-arrow-right"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="paypal_settings">
<div class="o_setting_left_pane">
<field name="module_payment_paypal"/>
</div>
<div class="o_setting_right_pane" id="website_payment_right_pane">
<label for="company_id" string="Paypal - Express Checkout"/>
<div class="text-muted">
Support most credit &amp; debit cards like Visa, Mastercard, Maestro, etc.
</div>
</div>
</div>
</div>
</div>
</field>
</record>
</odoo>
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Website - Payment Authorize',
'version': '1.0',
'category': 'Accounting/Payment Acquirers',
'sequence': 365,
'summary': 'Website - Payment Authorize',
'description': """""",
'depends': ['website_payment', 'payment_authorize'],
'data': [
'views/res_config_settings_views.xml'
],
'application': True,
'auto_install': True,
'license': 'LGPL-3',
}
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import res_config_settings
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
authorize_capture_method = fields.Selection(
string='Authorize.net: Payment Capture Method',
selection=[
('auto', 'Automatically Capture Payment'),
('manual', 'Manually Charge Later'),
])
@api.model
def get_values(self):
res = super().get_values()
authorize = self.env.ref('payment.payment_acquirer_authorize').sudo()
res['authorize_capture_method'] = 'manual' if authorize.capture_manually else 'auto'
return res
def set_values(self):
super().set_values()
authorize = self.env.ref('payment.payment_acquirer_authorize').sudo()
capture_manually = self.authorize_capture_method == 'manual'
if authorize.capture_manually != capture_manually:
authorize.capture_manually = capture_manually
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.payment.authorize</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="paypal_settings" position="before">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_right_pane">
<label for="authorize_capture_method"/>
<div class="text-muted">
Charge order directly or authorize at the order and capture the payment later on, manually.
</div>
<div class="content-group">
<div class="content-group">
<div class="row mt16 ml-4">
<field name="authorize_capture_method" class="w-75" widget="radio"/>
</div>
</div>
</div>
</div>
</div>
</div>
</field>
</record>
</odoo>
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': 'Website - Payment Paypal',
'version': '1.0',
'category': 'Accounting/Payment Acquirers',
'sequence': 365,
'summary': 'Website - Payment Paypal',
'description': """""",
'depends': ['website_payment', 'payment_paypal'],
'data': [
'views/res_config_settings_views.xml'
],
'application': True,
'auto_install': True,
'license': 'LGPL-3',
}
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import res_config_settings
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
paypal_email_account = fields.Char()
@api.model
def get_values(self):
res = super().get_values()
paypal = self.env.ref('payment.payment_acquirer_paypal').sudo()
res['paypal_email_account'] = paypal.paypal_email_account
return res
def set_values(self):
super().set_values()
paypal = self.env.ref('payment.payment_acquirer_paypal').sudo()
if paypal.paypal_email_account != self.paypal_email_account:
paypal.paypal_email_account = self.paypal_email_account
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.website.payment.paypal</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="20"/>
<field name="inherit_id" ref="website_payment.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="website_payment_right_pane" position="inside">
<div class="content-group">
<div class="row mt8 ml-4">
<label class="col-lg-3" string="Email" for="paypal_email_account"/>
<field name="paypal_email_account"/>
</div>
<div class="mt8 text-muted">
After your first sale, Paypal will email you to link your Paypal account, or setup a new business account, to claim your funds, and setup payment methods.
</div>
</div>
</div>
</field>
</record>
</odoo>
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models, fields
from odoo import api, models, fields, _
class ResConfigSettings(models.TransientModel):
@@ -44,6 +44,17 @@ class ResConfigSettings(models.TransientModel):
group_product_pricelist = fields.Boolean(
compute='_compute_group_product_pricelist', store=True, readonly=False)
enabled_extra_checkout_step = fields.Boolean(string="Extra Step During Checkout")
enabled_buy_now_button = fields.Boolean(string="Buy Now")
account_on_checkout = fields.Selection(related='website_id.account_on_checkout', readonly=False)
@api.onchange('account_on_checkout')
def _onchange_auth_signup_uninvited(self):
for config in self:
if config.account_on_checkout == 'mandatory':
config.auth_signup_uninvited = 'b2c'
@api.depends('website_id')
def _compute_terms_url(self):
for record in self:
@@ -61,9 +72,20 @@ class ResConfigSettings(models.TransientModel):
res.update(
sale_delivery_settings=sale_delivery_settings,
enabled_extra_checkout_step=self.env.ref('website_sale.extra_info_option').active,
enabled_buy_now_button=self.env.ref('website_sale.product_buy_now').active,
)
return res
def set_values(self):
super().set_values()
extra_step_view = self.env.ref('website_sale.extra_info_option')
if extra_step_view.active != self.enabled_extra_checkout_step:
extra_step_view.active = self.enabled_extra_checkout_step
buy_now_view = self.env.ref('website_sale.product_buy_now')
if buy_now_view.active != self.enabled_buy_now_button:
buy_now_view.active = self.enabled_buy_now_button
@api.depends('sale_delivery_settings')
def _compute_module_delivery(self):
for wizard in self:
@@ -83,3 +105,21 @@ class ResConfigSettings(models.TransientModel):
'url': '/terms?enable_editor=1',
'target': 'self',
}
def action_open_extra_info(self):
self.ensure_one()
return {
'type': 'ir.actions.act_url',
'url': '/shop/extra_info?enable_editor=1',
'target': 'self',
}
def action_open_sale_mail_templates(self):
return {
'name': _('Customize Email Templates'),
'type': 'ir.actions.act_window',
'domain': [('model', '=', 'sale.order')],
'res_model': 'mail.template',
'view_id': False,
'view_mode': 'tree,form',
}
@@ -244,8 +244,8 @@ odoo.define('website_sale_tour.tour', function (require) {
run: function () {}, // it's a check
},
{
content: "Click on Login Button",
trigger: '.oe_cart a.btn:contains("Log In")',
content: "Click on Sign in Button",
trigger: '.oe_cart a:contains(" Sign in")',
},
{
content: "Submit login",
@@ -23,33 +23,55 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="webmaster_settings" position="after">
<h2>Products</h2>
<div class="row mt16 o_settings_container" id="sale_product_catalog_settings">
<div class="col-12 col-lg-6 o_setting_box" id="product_attributes_setting">
<div class="o_setting_left_pane">
<field name="group_product_variant"/>
</div>
<div id="website_info_settings" position="after">
<h2>Shop - Checkout Process</h2>
<div class="row mt16 o_settings_container" id="website_shop_checkout">
<div class="col-12 col-lg-6 o_setting_box" id="cart_redirect_setting">
<div class="o_setting_right_pane">
<label for="group_product_variant"/>
<label for="add_to_cart_action" string="Add to Cart"/>
<div class="text-muted">
Sell variants of a product using attributes (size, color, etc.)
What should be done on "Add to Cart"?
</div>
<div class="content-group" attrs="{'invisible': [('group_product_variant', '=', False)]}">
<div class="mt8">
<button type="action" name="%(product.attribute_action)d" string="Attributes" class="btn-link" icon="fa-arrow-right"/>
<div class="content-group">
<div class="row mt16 ml-4">
<field name="add_to_cart_action" widget="radio"/>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="prompt_optional_products">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_right_pane">
<label for="account_on_checkout"/>
<div class="text-muted">
Choose if you prompt to create an account on check out
</div>
<div class="mt8 ml-4">
<field name="account_on_checkout" class="w-75" widget="radio"/>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="module_sale_product_configurator" string="Optional Products"/>
<field name="enabled_buy_now_button"/>
</div>
<div class="o_setting_right_pane">
<label for="module_sale_product_configurator" string="Optional Products"/>
<label for="enabled_buy_now_button"/>
<div class="text-muted">
Display a prompt with optional products when adding to cart
Instant checkout, instead of adding to cart
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="enabled_extra_checkout_step"/>
</div>
<div class="o_setting_right_pane">
<label for="enabled_extra_checkout_step"/>
<div class="text-muted">
Add a customizable form during checkout (after address)
</div>
<div class="row mt8 ml-4" attrs="{'invisible': [('enabled_extra_checkout_step', '=', False)]}">
<button type="object" name="action_open_extra_info" string="Configure Form " class="btn-link" icon="fa-arrow-right"/>
</div>
</div>
</div>
@@ -60,68 +82,37 @@
<div class="o_setting_right_pane">
<label for="module_website_sale_digital"/>
<div class="text-muted">
Sell content to download or URL links
Add download link for customers at the end of checkout
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="wishlist_option_setting">
<div class="o_setting_left_pane">
<field name="module_website_sale_wishlist"/>
</div>
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_right_pane">
<label for="module_website_sale_wishlist"/>
<span class="o_form_label">Assignment</span>
<div class="text-muted">
Let returning shoppers save products in a wishlist
Assignment of online orders
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="cart_redirect_setting">
<div class="o_setting_left_pane">
<field name="cart_add_on_page"/>
</div>
<div class="o_setting_right_pane">
<label for="cart_add_on_page"/>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
No redirect when the user adds a product to cart.
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="comparator_option_setting">
<div class="o_setting_left_pane">
<field name="module_website_sale_comparison"/>
</div>
<div class="o_setting_right_pane">
<label for="module_website_sale_comparison"/>
<div class="text-muted">
Allow shoppers to compare products based on their attributes
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="ecom_uom_price_option_setting">
<div class="o_setting_left_pane">
<field name="group_show_uom_price"/>
</div>
<div class="o_setting_right_pane">
<label for="group_show_uom_price"/>
<div class="text-muted">
Add price per base unit of measure on your Products
<div class="content-group">
<div class="row mt16">
<label class="o_light_label col-lg-3" string="Sales Team" for="salesteam_id"/>
<field name="salesteam_id" kanban_view_ref="%(sales_team.crm_team_view_kanban)s" />
</div>
<div class="row">
<label class="o_light_label col-lg-3" for="salesperson_id"/>
<field name="salesperson_id"/>
</div>
</div>
</div>
</div>
</div>
<h2>Pricing</h2>
<div class="row mt16 o_settings_container" id="sale_pricing_settings">
<h2>Shop - Products</h2>
<div class="row mt16 o_settings_container" id="sale_product_catalog_settings">
<div class="col-12 col-lg-6 o_setting_box" id="website_tax_inclusion_setting">
<div class="o_setting_right_pane">
<label string="Product Prices" for="show_line_subtotals_tax_selection"/>
<label string="Display Product Prices" for="show_line_subtotals_tax_selection"/>
<div class="text-muted">
Product prices displaying in web catalog
Prices displayed on your eCommerce
</div>
<div class="content-group">
<div class="mt16">
@@ -139,26 +130,53 @@
<div class="o_setting_right_pane">
<label for="group_product_pricelist"/>
<div class="text-muted">
Apply specific prices per country, discounts, etc.
Manage pricelists to apply specific prices per country, customer, products, etc
</div>
<div class="content-group mt16" attrs="{'invisible': [('group_product_pricelist', '=', False)]}">
<field name="group_sale_pricelist" invisible="1"/>
<field name="group_product_pricelist" invisible="1"/>
<field name="product_pricelist_setting" class="o_light_label" widget="radio"/>
<field name="product_pricelist_setting" class="o_light_label w-75" widget="radio"/>
</div>
<div class="mt8" attrs="{'invisible': [('group_product_pricelist', '=', False)]}">
<div attrs="{'invisible': [('group_product_pricelist', '=', False)]}">
<button type="action" name="%(product.product_pricelist_action2)d" string="Pricelists" class="btn-link" icon="fa-arrow-right"/>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="discount_setting" title="Apply manual discounts on sales order lines or display discounts computed from pricelists (option to activate in the pricelist configuration).">
<div class="col-12 col-lg-6 o_setting_box">
<div class="o_setting_left_pane">
<field name="group_discount_per_so_line"/>
<field name="group_product_price_comparison"/>
</div>
<div class="o_setting_right_pane">
<label for="group_discount_per_so_line"/>
<label for="group_product_price_comparison"/>
<div class="text-muted">
Grant discounts on sales order lines
Add a strikethrough price, as a comparison
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="ecom_uom_price_option_setting">
<div class="o_setting_left_pane">
<field name="group_show_uom_price"/>
</div>
<div class="o_setting_right_pane">
<label for="group_show_uom_price" string="Product Reference Price"/>
<div class="text-muted">
Add a reference price per UoM on products (i.e $/kg), in addition to the sale price
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="product_attributes_setting">
<div class="o_setting_left_pane">
<field name="group_product_variant"/>
</div>
<div class="o_setting_right_pane">
<label for="group_product_variant" string="Product Variants"/>
<div class="text-muted">
One product might have different attributes (size, color, ...)
</div>
<div class="content-group" attrs="{'invisible': [('group_product_variant', '=', False)]}">
<div class="mt8">
<button type="action" name="%(product.attribute_action)d" string="Attributes" class="btn-link" icon="fa-arrow-right"/>
</div>
</div>
</div>
</div>
@@ -169,22 +187,31 @@
<field name="module_sale_coupon" />
</div>
<div class="o_setting_right_pane">
<label for="module_sale_coupon"/>
<label for="module_sale_coupon" string="Promotions, Coupons, Gift Card &amp; Loyalty Program"/>
<div class="text-muted" id="website_sale_coupon">
Manage promotion &amp; coupon programs
Manage promotion that will grant customers discounts or gifts
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box"
id="gift_card_programs"
title="Can be used as payment toward future orders.">
<div class="col-12 col-lg-6 o_setting_box" id="wishlist_option_setting">
<div class="o_setting_left_pane">
<field name="module_website_sale_gift_card" />
<field name="module_website_sale_wishlist"/>
</div>
<div class="o_setting_right_pane">
<label for="module_website_sale_gift_card"/>
<div class="text-muted" id="website_sale_gift_card">
Can be used as payment toward future orders.
<label for="module_website_sale_wishlist"/>
<div class="text-muted">
Allow signed-in users to save product in a wishlist
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="comparator_option_setting">
<div class="o_setting_left_pane">
<field name="module_website_sale_comparison"/>
</div>
<div class="o_setting_right_pane">
<label for="module_website_sale_comparison" string="Product Comparison Tool"/>
<div class="text-muted">
Allow shoppers to compare products based on their attributes
</div>
</div>
</div>
@@ -318,60 +345,32 @@
</div>
</div>
</div>
</div>
<h2>Orders Followup</h2>
<div class="row mt16 o_settings_container" id="sale_checkout_settings">
<div class="col-12 col-lg-6 o_setting_box" id="checkout_assignation_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Assignment</span>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Assignment of online orders
</div>
<div class="content-group">
<div class="row mt16">
<label class="o_light_label col-lg-3" string="Sales Team" for="salesteam_id"/>
<field name="salesteam_id" kanban_view_ref="%(sales_team.crm_team_view_kanban)s" />
</div>
<div class="row">
<label class="o_light_label col-lg-3" for="salesperson_id"/>
<field name="salesperson_id"/>
</div>
</div>
<div id="website_marketing_automation" position="after">
<div class="col-12 col-lg-6 o_setting_box" id="confirmation_email_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Automated Emails</span>
<div class="text-muted">
Configure mails at order confirmation, abandonned carts, etc
</div>
<div class="mt8">
<button type="object" name="action_open_sale_mail_templates" string="Customize Email Templates" class="btn-link" icon="fa-arrow-right"/>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" id="confirmation_email_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Confirmation Email</span>
<div class="text-muted">
Email sent to the customer after the checkout
</div>
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" id="abandoned_carts_setting" title="Abandoned carts are all carts left unconfirmed by website visitors. You can find them in *Website > Orders > Abandoned Carts*. From there you can send recovery emails to visitors who entered their contact details.">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">Remind Abandonned Carts</span>
<div class="text-muted">
Email to authentified customers who did not complete the checkout
</div>
<div class="content-group" title="Carts are flagged as abandoned after this delay.">
<div class="row mt16">
<label for="confirmation_mail_template_id" class="col-lg-4 o_light_label"/>
<field name="confirmation_mail_template_id" class="oe_inline"/>
</div>
</div>
</div>
<div class="col-xs-12 col-lg-6 o_setting_box" id="abandoned_carts_setting" title="Abandoned carts are all carts left unconfirmed by website visitors. You can find them in *Website > Orders > Abandoned Carts*. From there you can send recovery emails to visitors who entered their contact details.">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<span class="o_form_label">Abandoned Carts</span>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Send a recovery email when a cart is abandoned
</div>
<div class="content-group" title="This email template is suggested by default when you send a recovery email.">
<div class="row mt16">
<label for="cart_recovery_mail_template" string="Email Template" class="col-lg-4 o_light_label"/>
<field name="cart_recovery_mail_template" class="oe_inline"/>
</div>
</div>
<div class="content-group" title="Carts are flagged as abandoned after this delay.">
<div class="row mt16">
<div class="col-12">
<label for="cart_abandoned_delay" string="Cart is abandoned after" class="o_light_label"/>
<field class="col-2" name="cart_abandoned_delay" widget="float_time" /> hours.
</div>
<div class="col-12">
<label for="cart_abandoned_delay" string="Send after" class="o_light_label"/>
<field class="col-2" name="cart_abandoned_delay" widget="float_time" /> hours.
</div>
</div>
</div>
+3 -3
View File
@@ -1427,9 +1427,9 @@
<div>
<t t-if="mode == ('new', 'billing')">
<h2 class="o_page_header mt8">
<span t-if="account_on_checkout != 'mandatory'">Your Address</span>
<small t-if="account_on_checkout == 'optional'"> or </small>
<a t-if="account_on_checkout != 'disabled'" role="button" href='/web/login?redirect=/shop/checkout' class='btn btn-primary' style="margin-top: -11px">Log In</a>
<span t-if="account_on_checkout != 'mandatory'">Fill in your address</span>
<small class="text-muted" t-if="account_on_checkout == 'optional'"> or </small>
<a t-if="account_on_checkout != 'disabled'" role="button" href='/web/login?redirect=/shop/checkout' style="margin-top: -11px"> Sign in</a>
</h2>
</t>
<t t-if="mode == ('edit', 'billing')">
@@ -12,7 +12,10 @@
</div>
<div class="o_setting_right_pane" name="stock_inventory_availability">
<div class="o_form_label">
Inventory
Inventory Defaults
</div>
<div class="text-muted">
How to display products having low quantities (on hand - reserved)
</div>
<div class="content-group">
<div class="row mt16"
@@ -37,11 +40,11 @@
id="show_availability_setting"
title="Default visibility for custom messages.">
<div class="col-12">
<label for="show_availability" string="Show Available Qty" class="p-0 col-4 o_light_label" />
<label for="show_availability" string="Show Available Qty" class="p-0 col-4 o_light_label mb-3 mt-2"/>
<field name="show_availability" class="w-auto"/>
<label for="available_threshold" string="only if below" class="o_light_label"/>
<field name="available_threshold" class="oe_inline col-1" widget="integer"/>
Units
<label for="available_threshold" string="only if below" class="o_light_label" attrs="{'invisible': [('show_availability', '=', False)]}"/>
<field name="available_threshold" class="oe_inline col-1" widget="integer" attrs="{'invisible': [('show_availability', '=', False)]}"/>
<span attrs="{'invisible': [('show_availability', '=', False)]}">Units</span>
</div>
</div>
</div>
@@ -5,7 +5,7 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[@id='google_maps_setting']" position="after">
<xpath expr="//div[@id='website_marketing_automation']" position="after">
<div class="col-12 col-lg-6 o_setting_box" id="slides_install_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Slides</span>
@@ -5,11 +5,10 @@
<field name="model">res.config.settings</field>
<field name="inherit_id" ref="website.res_config_settings_view_form"/>
<field name="arch" type="xml">
<div id="google_maps_setting" position="after">
<div id="website_email_marketing" position="inside">
<div class="col-12 col-lg-6 o_setting_box" id="twitter_roller_install_setting">
<div class="o_setting_right_pane">
<span class="o_form_label">Twitter Roller</span>
<span class="fa fa-lg fa-globe" title="Values set here are website-specific." groups="website.group_multi_website"/>
<div class="text-muted">
Twitter API Credentials
</div>
+10
View File
@@ -784,3 +784,13 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
vals.pop(field.name)
return super().create(vals_list)
def action_open_template_user(self):
action = self.env["ir.actions.actions"]._for_xml_id("base.action_res_users")
template_user_id = literal_eval(self.env['ir.config_parameter'].sudo().get_param('base.template_portal_user_id', 'False'))
template_user = self.browse(template_user_id)
if not template_user.exists():
raise ValueError(_('Invalid template user. It seems it has been deleted.'))
action['res_id'] = template_user_id
action['views'] = [[self.env.ref('base.view_users_form').id, 'form']]
return action