[MERGE] base, various: add native support of config parameters in res configs
This commit adds native support of config parameter in res config. Using a new config_parameter attribute on fields setter and getter of parameters are automatically managed by the config class. It allows to remove duplicater and error-prone code in a lot of configuration screens updattng config parameters. Configs are now also more strict on naming conventions leading to some fields being renamed. See sub-commits for more details.
This commit is contained in:
@@ -93,7 +93,7 @@ class AuthSignupHome(Home):
|
||||
|
||||
get_param = request.env['ir.config_parameter'].sudo().get_param
|
||||
return {
|
||||
'signup_enabled': get_param('auth_signup.allow_uninvited') == 'True',
|
||||
'signup_enabled': get_param('auth_signup.invitation_scope', 'b2b') == 'b2c',
|
||||
'reset_password_enabled': get_param('auth_signup.reset_password') == 'True',
|
||||
}
|
||||
|
||||
|
||||
@@ -9,36 +9,13 @@ from odoo import api, fields, models
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
auth_signup_reset_password = fields.Boolean(string='Enable password reset from Login page')
|
||||
auth_signup_reset_password = fields.Boolean(string='Enable password reset from Login page', config_parameter='auth_signup.reset_password')
|
||||
auth_signup_uninvited = fields.Selection([
|
||||
('b2b', 'On invitation (B2B)'),
|
||||
('b2c', 'Free sign up (B2C)'),
|
||||
], string='Customer Account')
|
||||
auth_signup_template_user_id = fields.Many2one('res.users', string='Template user for new users created through signup')
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
get_param = self.env['ir.config_parameter'].sudo().get_param
|
||||
auth_signup_template_user_id = literal_eval(get_param('auth_signup.template_user_id', default='False'))
|
||||
if auth_signup_template_user_id and not self.env['res.users'].sudo().browse(auth_signup_template_user_id).exists():
|
||||
auth_signup_template_user_id = False
|
||||
# the value of the parameter is a nonempty string
|
||||
res.update(
|
||||
auth_signup_reset_password=get_param('auth_signup.reset_password', 'False').lower() == 'true',
|
||||
auth_signup_uninvited='b2c' if get_param('auth_signup.allow_uninvited', 'False').lower() == 'true' else 'b2b',
|
||||
auth_signup_template_user_id=auth_signup_template_user_id,
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
set_param = self.env['ir.config_parameter'].sudo().set_param
|
||||
# we store the repr of the values, since the value of the parameter is a required string
|
||||
set_param('auth_signup.reset_password', repr(self.auth_signup_reset_password))
|
||||
set_param('auth_signup.allow_uninvited', repr(self.auth_signup_uninvited == 'b2c'))
|
||||
set_param('auth_signup.template_user_id', repr(self.auth_signup_template_user_id.id))
|
||||
], string='Customer Account', default='b2b', config_parameter='auth_signup.invitation_scope')
|
||||
auth_signup_template_user_id = fields.Many2one('res.users', string='Template user for new users created through signup',
|
||||
config_parameter='auth_signup.template_user_id')
|
||||
|
||||
@api.multi
|
||||
def open_template_user(self):
|
||||
|
||||
@@ -102,7 +102,7 @@ class ResPartner(models.Model):
|
||||
"""
|
||||
res = defaultdict(dict)
|
||||
|
||||
allow_signup = self.env['ir.config_parameter'].sudo().get_param('auth_signup.allow_uninvited', 'False').lower() == 'true'
|
||||
allow_signup = self.env['ir.config_parameter'].sudo().get_param('auth_signup.invitation_scope', 'b2b') == 'b2c'
|
||||
for partner in self:
|
||||
if allow_signup and not partner.user_ids:
|
||||
partner.signup_prepare()
|
||||
|
||||
@@ -84,7 +84,7 @@ class ResUsers(models.Model):
|
||||
|
||||
# check that uninvited users may sign up
|
||||
if 'partner_id' not in values:
|
||||
if not literal_eval(get_param('auth_signup.allow_uninvited', 'False')):
|
||||
if get_param('auth_signup.invitation_scope', 'b2b') != 'b2c':
|
||||
raise SignupError(_('Signup is not allowed for uninvited users'))
|
||||
|
||||
assert values.get('login'), "Signup: no login given for new user"
|
||||
|
||||
@@ -11,8 +11,14 @@ class ResConfigSettings(models.TransientModel):
|
||||
group_multi_company = fields.Boolean("Manage multiple companies", implied_group='base.group_multi_company')
|
||||
company_id = fields.Many2one('res.company', string='Company', required=True,
|
||||
default=lambda self: self.env.user.company_id)
|
||||
default_user_rights = fields.Boolean("Default Access Rights")
|
||||
default_external_email_server = fields.Boolean("External Email Servers")
|
||||
user_default_rights = fields.Boolean(
|
||||
"Default Access Rights",
|
||||
config_parameter='base_setup.default_user_rights',
|
||||
oldname='default_user_rights')
|
||||
external_email_server_default = fields.Boolean(
|
||||
"External Email Servers",
|
||||
config_parameter='base_setup.default_external_email_server',
|
||||
oldname='default_external_email_server')
|
||||
module_base_import = fields.Boolean("Allow users to import data from CSV/XLS/XLSX/ODS files")
|
||||
module_google_calendar = fields.Boolean(
|
||||
string='Allow the users to synchronize their calendar with Google Calendar')
|
||||
@@ -28,7 +34,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
help="Share your partners to all companies defined in your instance.\n"
|
||||
" * Checked : Partners are visible for every companies, even if a company is defined on the partner.\n"
|
||||
" * Unchecked : Each company can see only its partner (partners where company is defined). Partners not related to a company are visible for all companies.")
|
||||
default_custom_report_footer = fields.Boolean("Default Custom Report Footer")
|
||||
report_footer = fields.Text(related="company_id.report_footer", string='Custom Report Footer', help="Footer text displayed at the bottom of all reports.")
|
||||
group_multi_currency = fields.Boolean(string='Multi-Currencies',
|
||||
implied_group='base.group_multi_currency',
|
||||
@@ -39,14 +44,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
params = self.env['ir.config_parameter'].sudo()
|
||||
default_external_email_server = params.get_param('base_setup.default_external_email_server', default=False)
|
||||
default_user_rights = params.get_param('base_setup.default_user_rights', default=False)
|
||||
default_custom_report_footer = params.get_param('base_setup.default_custom_report_footer', default=False)
|
||||
res.update(
|
||||
default_external_email_server=default_external_email_server,
|
||||
default_user_rights=default_user_rights,
|
||||
default_custom_report_footer=default_custom_report_footer,
|
||||
company_share_partner=not self.env.ref('base.res_partner_rule').active,
|
||||
)
|
||||
return res
|
||||
@@ -54,9 +52,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
@api.multi
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
self.env['ir.config_parameter'].sudo().set_param("base_setup.default_external_email_server", self.default_external_email_server)
|
||||
self.env['ir.config_parameter'].sudo().set_param("base_setup.default_user_rights", self.default_user_rights)
|
||||
self.env['ir.config_parameter'].sudo().set_param("base_setup.default_custom_report_footer", self.default_custom_report_footer)
|
||||
self.env.ref('base.res_partner_rule').write({'active': not self.company_share_partner})
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -50,17 +50,17 @@
|
||||
</div>
|
||||
<div id="emails"/>
|
||||
<h2>Users</h2>
|
||||
<div class="row mt16 o_settings_container" id="default_user_rights">
|
||||
<div class="row mt16 o_settings_container" id="user_default_rights">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box" title="By default, new users get highest access rights for all installed apps." id="access_rights">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="default_user_rights"/>
|
||||
<field name="user_default_rights"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Access Rights" for="default_user_rights"/>
|
||||
<label string="Access Rights" for="user_default_rights"/>
|
||||
<div class="text-muted">
|
||||
Set custom access rights for new users
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('default_user_rights','=',False)]}">
|
||||
<div class="content-group" attrs="{'invisible': [('user_default_rights','=',False)]}">
|
||||
<div class="mt16">
|
||||
<button type="object" name="open_default_user" string="Default Access Rights" icon="fa-arrow-right" class="btn-link"/>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
crm_alias_prefix = fields.Char('Default Alias Name for Leads')
|
||||
generate_lead_from_alias = fields.Boolean('Manual Assignation of Emails')
|
||||
generate_lead_from_alias = fields.Boolean('Manual Assignation of Emails', config_parameter='crm.generate_lead_from_alias')
|
||||
group_use_lead = fields.Boolean(string="Leads", implied_group='crm.group_use_lead')
|
||||
module_crm_phone_validation = fields.Boolean("Phone Validation")
|
||||
module_web_clearbit = fields.Boolean("Customer Autocomplete")
|
||||
@@ -41,14 +41,12 @@ class ResConfigSettings(models.TransientModel):
|
||||
alias = self._find_default_lead_alias_id()
|
||||
res.update(
|
||||
crm_alias_prefix=alias.alias_name if alias else False,
|
||||
generate_lead_from_alias=self.env['ir.config_parameter'].sudo().get_param('crm.generate_lead_from_alias')
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
self.env['ir.config_parameter'].sudo().set_param('crm.generate_lead_from_alias', self.generate_lead_from_alias)
|
||||
alias = self._find_default_lead_alias_id()
|
||||
if alias:
|
||||
alias.write({'alias_name': self.crm_alias_prefix})
|
||||
|
||||
@@ -7,23 +7,15 @@ from odoo import api, fields, models
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
cal_client_id = fields.Char("Client_id")
|
||||
cal_client_secret = fields.Char("Client_key")
|
||||
cal_client_id = fields.Char("Client_id", config_parameter='google_calendar_client_id', default='')
|
||||
cal_client_secret = fields.Char("Client_key", config_parameter='google_calendar_client_secret', default='')
|
||||
server_uri = fields.Char('URI for tuto')
|
||||
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
set_param = self.env['ir.config_parameter'].set_param
|
||||
set_param('google_calendar_client_id', (self.cal_client_id or '').strip())
|
||||
set_param('google_calendar_client_secret', (self.cal_client_secret or '').strip())
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
get_param = self.env['ir.config_parameter'].sudo().get_param
|
||||
res.update(
|
||||
cal_client_id=get_param('google_calendar_client_id', default=''),
|
||||
cal_client_secret=get_param('google_calendar_client_secret', default=''),
|
||||
server_uri="%s/google_account/authentication" % get_param('web.base.url', default="http://yourcompany.odoo.com"),
|
||||
)
|
||||
return res
|
||||
|
||||
@@ -7,7 +7,7 @@ from odoo import api, fields, models
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
google_drive_authorization_code = fields.Char(string='Authorization Code')
|
||||
google_drive_authorization_code = fields.Char(string='Authorization Code', config_parameter='google_drive_authorization_code')
|
||||
google_drive_uri = fields.Char(compute='_compute_drive_uri', string='URI', help="The URL to generate the authorization code from Google")
|
||||
|
||||
@api.depends('google_drive_authorization_code')
|
||||
@@ -16,14 +16,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
for config in self:
|
||||
config.google_drive_uri = google_drive_uri
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
res.update(
|
||||
google_drive_authorization_code=self.env['ir.config_parameter'].sudo().get_param('google_drive_authorization_code'),
|
||||
)
|
||||
return res
|
||||
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
params = self.env['ir.config_parameter'].sudo()
|
||||
@@ -31,5 +23,4 @@ class ResConfigSettings(models.TransientModel):
|
||||
refresh_token = False
|
||||
if authorization_code and authorization_code != params.get_param('google_drive_authorization_code'):
|
||||
refresh_token = self.env['google.service'].generate_refresh_token('drive', authorization_code)
|
||||
params.set_param('google_drive_authorization_code', authorization_code)
|
||||
params.set_param('google_drive_refresh_token', refresh_token)
|
||||
|
||||
@@ -7,7 +7,8 @@ class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
expense_alias_prefix = fields.Char('Default Alias Name for Expenses')
|
||||
use_mailgateway = fields.Boolean(string='Let your employees record expenses by email')
|
||||
use_mailgateway = fields.Boolean(string='Let your employees record expenses by email',
|
||||
config_parameter='hr_expense.use_mailgateway')
|
||||
module_sale_management = fields.Boolean(string="Customer Billing")
|
||||
|
||||
@api.model
|
||||
@@ -15,7 +16,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
res.update(
|
||||
expense_alias_prefix=self.env.ref('hr_expense.mail_alias_expense').alias_name,
|
||||
use_mailgateway=self.env['ir.config_parameter'].sudo().get_param('hr_expense.use_mailgateway'),
|
||||
)
|
||||
return res
|
||||
|
||||
@@ -23,7 +23,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
self.env.ref('hr_expense.mail_alias_expense').write({'alias_name': self.expense_alias_prefix})
|
||||
self.env['ir.config_parameter'].sudo().set_param('hr_expense.use_mailgateway', self.use_mailgateway)
|
||||
|
||||
@api.onchange('use_mailgateway')
|
||||
def _onchange_use_mailgateway(self):
|
||||
|
||||
@@ -1,22 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = ['res.config.settings']
|
||||
|
||||
max_unused_cars = fields.Integer(string='Maximum unused cars')
|
||||
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
Param = self.env['ir.config_parameter'].sudo()
|
||||
Param.set_param("l10n_be_hr_payroll_fleet.max_unused_cars", self.max_unused_cars)
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
params = self.env['ir.config_parameter'].sudo()
|
||||
res.update(max_unused_cars=int(params.get_param('l10n_be_hr_payroll_fleet.max_unused_cars', default=1000)))
|
||||
return res
|
||||
max_unused_cars = fields.Integer(string='Maximum unused cars', default=1000, config_parameter='l10n_be_hr_payroll_fleet.max_unused_cars')
|
||||
|
||||
@@ -15,22 +15,22 @@ class ResConfigSettings(models.TransientModel):
|
||||
|
||||
fail_counter = fields.Integer('Fail Mail', readonly=True)
|
||||
alias_domain = fields.Char('Alias Domain', help="If you have setup a catch-all email domain redirected to "
|
||||
"the Odoo server, enter the domain name here.")
|
||||
"the Odoo server, enter the domain name here.", config_parameter='mail.catchall.domain')
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
|
||||
previous_date = datetime.datetime.now() - datetime.timedelta(days=30)
|
||||
|
||||
alias_domain = self.env["ir.config_parameter"].get_param("mail.catchall.domain", default=None)
|
||||
if alias_domain is None:
|
||||
alias_domain = res.get('alias_domain')
|
||||
if not alias_domain:
|
||||
domain = self.env["ir.config_parameter"].get_param("web.base.url")
|
||||
try:
|
||||
alias_domain = urls.url_parse(domain).host
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
previous_date = datetime.datetime.now() - datetime.timedelta(days=30)
|
||||
|
||||
res.update(
|
||||
fail_counter=self.env['mail.mail'].sudo().search_count([
|
||||
('date', '>=', previous_date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)),
|
||||
|
||||
@@ -25,14 +25,14 @@
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 o_setting_box" title="Using your own email server is required to send/receive emails in Community and Enterprise versions. Online users already benefit from a ready-to-use email server (@mycompany.odoo.com).">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="default_external_email_server"/>
|
||||
<field name="external_email_server_default"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="default_external_email_server"/>
|
||||
<div class="text-muted" id="default_external_email_server">
|
||||
<label for="external_email_server_default"/>
|
||||
<div class="text-muted" id="external_email_server_default">
|
||||
Use your own email servers
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('default_external_email_server', '=', False)]}">
|
||||
<div class="content-group" attrs="{'invisible': [('external_email_server_default', '=', False)]}">
|
||||
<div class="row mt16" id="mail_alias_domain">
|
||||
<label for="alias_domain" class="col-md-3 o_light_label"/>
|
||||
<field name="alias_domain" placeholder="mycompany.odoo.com"/>
|
||||
|
||||
@@ -8,7 +8,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
manufacturing_lead = fields.Float(related='company_id.manufacturing_lead', string="Manufacturing Lead Time")
|
||||
use_manufacturing_lead = fields.Boolean(string="Default Manufacturing Lead Time", oldname='default_use_manufacturing_lead')
|
||||
use_manufacturing_lead = fields.Boolean(string="Default Manufacturing Lead Time", config_parameter='mrp.use_manufacturing_lead', oldname='default_use_manufacturing_lead')
|
||||
module_mrp_byproduct = fields.Boolean("By-Products")
|
||||
module_mrp_mps = fields.Boolean("Master Production Schedule")
|
||||
module_mrp_plm = fields.Boolean("Product Lifecycle Management (PLM)")
|
||||
@@ -19,19 +19,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
group_mrp_routings = fields.Boolean("MRP Work Orders",
|
||||
implied_group='mrp.group_mrp_routings')
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
res.update(
|
||||
use_manufacturing_lead=self.env['ir.config_parameter'].sudo().get_param('mrp.use_manufacturing_lead')
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
self.env['ir.config_parameter'].sudo().set_param('mrp.use_manufacturing_lead', self.use_manufacturing_lead)
|
||||
|
||||
@api.onchange('use_manufacturing_lead')
|
||||
def _onchange_use_manufacturing_lead(self):
|
||||
if not self.use_manufacturing_lead:
|
||||
|
||||
@@ -33,6 +33,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
use_po_lead = fields.Boolean(
|
||||
string="Security Lead Time for Purchase",
|
||||
oldname='default_new_po_lead',
|
||||
config_parameter='purchase.use_po_lead',
|
||||
help="Margin of error for vendor lead times. When the system generates Purchase Orders for reordering products,they will be scheduled that many days earlier to cope with unexpected vendor delays.")
|
||||
|
||||
@api.onchange('use_po_lead')
|
||||
@@ -45,7 +46,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
res.update(
|
||||
is_installed_sale=self.env['ir.module.module'].search([('name', '=', 'sale'), ('state', '=', 'installed')]).id,
|
||||
use_po_lead=self.env['ir.config_parameter'].sudo().get_param('purchase.use_po_lead')
|
||||
)
|
||||
return res
|
||||
|
||||
@@ -53,4 +53,3 @@ class ResConfigSettings(models.TransientModel):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
self.po_lock = 'lock' if self.lock_confirmed_po else 'edit'
|
||||
self.po_double_validation = 'two_step' if self.po_order_approval else 'one_step'
|
||||
self.env['ir.config_parameter'].sudo().set_param('purchase.use_po_lead', self.use_po_lead)
|
||||
|
||||
@@ -12,7 +12,8 @@ class ResConfigSettings(models.TransientModel):
|
||||
sale_note = fields.Text(related='company_id.sale_note', string="Terms & Conditions")
|
||||
use_sale_note = fields.Boolean(
|
||||
string='Default Terms & Conditions',
|
||||
oldname='default_use_sale_note')
|
||||
oldname='default_use_sale_note',
|
||||
config_parameter='sale.use_sale_note')
|
||||
group_discount_per_so_line = fields.Boolean("Discounts", implied_group='sale.group_discount_per_so_line')
|
||||
module_sale_margin = fields.Boolean("Margins")
|
||||
group_sale_layout = fields.Boolean("Sections on Sales Orders", implied_group='sale.group_sale_layout')
|
||||
@@ -20,7 +21,8 @@ class ResConfigSettings(models.TransientModel):
|
||||
portal_confirmation = fields.Boolean('Online Signature & Payment')
|
||||
portal_confirmation_options = fields.Selection([
|
||||
('sign', 'Signature'),
|
||||
('pay', 'Payment')], string="Online Signature & Payment options")
|
||||
('pay', 'Payment')], string="Online Signature & Payment options",
|
||||
config_parameter='sale.sale_portal_confirmation_options')
|
||||
module_sale_payment = fields.Boolean("Sale Payment", help='Technical field implied by user choice of online_confirmation')
|
||||
module_website_quote = fields.Boolean("Quotations Templates")
|
||||
group_sale_delivery_address = fields.Boolean("Customer Addresses", implied_group='sale.group_delivery_invoice_address')
|
||||
@@ -33,7 +35,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
('fixed', 'A single sales price per product'),
|
||||
('percentage', 'Multiple prices per product (e.g. customer segments, currencies)'),
|
||||
('formula', 'Price computed from formulas (discounts, margins, roundings)')
|
||||
], string="Pricelists")
|
||||
], string="Pricelists", config_parameter='sale.sale_pricelist_setting')
|
||||
group_show_price_subtotal = fields.Boolean(
|
||||
"Show subtotal",
|
||||
implied_group='sale.group_show_price_subtotal',
|
||||
@@ -47,26 +49,28 @@ class ResConfigSettings(models.TransientModel):
|
||||
sale_show_tax = fields.Selection([
|
||||
('subtotal', 'Tax-Excluded Prices'),
|
||||
('total', 'Tax-Included Prices')], string="Tax Display",
|
||||
default='subtotal', required=True)
|
||||
required=True, default='subtotal',
|
||||
config_parameter='sale.sale_show_tax')
|
||||
default_invoice_policy = fields.Selection([
|
||||
('order', 'Invoice what is ordered'),
|
||||
('delivery', 'Invoice what is delivered')
|
||||
], 'Invoicing Policy',
|
||||
default='order',
|
||||
default_model='product.template')
|
||||
default_deposit_product_id = fields.Many2one(
|
||||
deposit_default_product_id = fields.Many2one(
|
||||
'product.product',
|
||||
'Deposit Product',
|
||||
domain="[('type', '=', 'service')]",
|
||||
oldname='deposit_product_id_setting',
|
||||
config_parameter='sale.default_deposit_product_id',
|
||||
oldname='default_deposit_product_id',
|
||||
help='Default product used for payment advances')
|
||||
auto_done_setting = fields.Boolean("Lock Confirmed Sales")
|
||||
auto_done_setting = fields.Boolean("Lock Confirmed Sales", config_parameter='sale.auto_done_setting')
|
||||
module_website_sale_digital = fields.Boolean("Sell digital products - provide downloadable content on your customer portal")
|
||||
|
||||
auth_signup_uninvited = fields.Selection([
|
||||
('b2b', 'On invitation (B2B)'),
|
||||
('b2c', 'Free sign up (B2C)'),
|
||||
], string='Customer Account')
|
||||
], string='Customer Account', default='b2b', config_parameter='auth_signup.invitation_scope')
|
||||
|
||||
module_delivery = fields.Boolean("Shipping Costs")
|
||||
module_delivery_dhl = fields.Boolean("DHL Connector")
|
||||
@@ -137,32 +141,10 @@ class ResConfigSettings(models.TransientModel):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
ICPSudo = self.env['ir.config_parameter'].sudo()
|
||||
sale_pricelist_setting = ICPSudo.get_param('sale.sale_pricelist_setting')
|
||||
sale_portal_confirmation_options = ICPSudo.get_param('sale.sale_portal_confirmation_options', default='none')
|
||||
default_deposit_product_id = literal_eval(ICPSudo.get_param('sale.default_deposit_product_id', default='False'))
|
||||
if default_deposit_product_id and not self.env['product.product'].browse(default_deposit_product_id).exists():
|
||||
default_deposit_product_id = False
|
||||
res.update(
|
||||
auth_signup_uninvited='b2c' if ICPSudo.get_param('auth_signup.allow_uninvited', 'False').lower() == 'true' else 'b2b',
|
||||
use_sale_note=ICPSudo.get_param('sale.use_sale_note', default=False),
|
||||
auto_done_setting=ICPSudo.get_param('sale.auto_done_setting'),
|
||||
default_deposit_product_id=default_deposit_product_id,
|
||||
sale_show_tax=ICPSudo.get_param('sale.sale_show_tax', default='subtotal'),
|
||||
multi_sales_price=sale_pricelist_setting in ['percentage', 'formula'],
|
||||
multi_sales_price_method=sale_pricelist_setting in ['percentage', 'formula'] and sale_pricelist_setting or False,
|
||||
sale_pricelist_setting=sale_pricelist_setting,
|
||||
portal_confirmation=sale_portal_confirmation_options in ('pay', 'sign'),
|
||||
portal_confirmation_options=sale_portal_confirmation_options if sale_portal_confirmation_options in ('pay', 'sign') else False,
|
||||
portal_confirmation=ICPSudo.get_param('sale.sale_portal_confirmation_options', default=False) in ('pay', 'sign'),
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
ICPSudo = self.env['ir.config_parameter'].sudo()
|
||||
ICPSudo.set_param('auth_signup.allow_uninvited', repr(self.auth_signup_uninvited == 'b2c'))
|
||||
ICPSudo.set_param("sale.use_sale_note", self.use_sale_note)
|
||||
ICPSudo.set_param("sale.auto_done_setting", self.auto_done_setting)
|
||||
ICPSudo.set_param("sale.default_deposit_product_id", self.default_deposit_product_id.id)
|
||||
ICPSudo.set_param('sale.sale_pricelist_setting', self.sale_pricelist_setting)
|
||||
ICPSudo.set_param('sale.sale_show_tax', self.sale_show_tax)
|
||||
ICPSudo.set_param('sale.sale_portal_confirmation_options', self.portal_confirmation_options if self.portal_confirmation_options in ('pay', 'sign') else 'none')
|
||||
|
||||
@@ -371,7 +371,7 @@
|
||||
Product used for down payments
|
||||
</div>
|
||||
<div class="text-muted">
|
||||
<field name="default_deposit_product_id"/>
|
||||
<field name="deposit_default_product_id"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -14,6 +14,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
group_display_incoterm = fields.Boolean("Incoterms", implied_group='sale_stock.group_display_incoterm')
|
||||
use_security_lead = fields.Boolean(
|
||||
string="Security Lead Time for Sales",
|
||||
config_parameter='sale_stock.use_security_lead',
|
||||
oldname='default_new_security_lead',
|
||||
help="Margin of error for dates promised to customers. Products will be scheduled for delivery that many days earlier than the actual promised date, to cope with unexpected delays in the supply chain.")
|
||||
default_picking_policy = fields.Selection([
|
||||
@@ -25,14 +26,3 @@ class ResConfigSettings(models.TransientModel):
|
||||
def _onchange_use_security_lead(self):
|
||||
if not self.use_security_lead:
|
||||
self.security_lead = 0.0
|
||||
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
res.update(
|
||||
use_security_lead=self.env['ir.config_parameter'].sudo().get_param('sale_stock.use_security_lead')
|
||||
)
|
||||
return res
|
||||
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
self.env['ir.config_parameter'].sudo().set_param('sale_stock.use_security_lead', self.use_security_lead)
|
||||
|
||||
@@ -28,6 +28,7 @@ class ResConfigSettings(models.TransientModel):
|
||||
use_propagation_minimum_delta = fields.Boolean(
|
||||
string="No Rescheduling Propagation",
|
||||
oldname='default_new_propagation_minimum_delta',
|
||||
config_parameter='stock.use_propagation_minimum_delta',
|
||||
help="Rescheduling applies to any chain of operations (e.g. Make To Order, Pick Pack Ship). In the case of MTO sales, a vendor delay (updated incoming date) impacts the expected delivery date to the customer. \n This option allows to not propagate the rescheduling if the change is not critical.")
|
||||
module_stock_picking_batch = fields.Boolean("Batch Pickings", oldname="module_stock_picking_wave")
|
||||
module_stock_barcode = fields.Boolean("Barcode Scanner")
|
||||
@@ -61,20 +62,13 @@ class ResConfigSettings(models.TransientModel):
|
||||
if self.group_stock_adv_location and not self.group_stock_multi_locations:
|
||||
self.group_stock_multi_locations = True
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
res.update(
|
||||
use_propagation_minimum_delta=self.env['ir.config_parameter'].sudo().get_param('stock.use_propagation_minimum_delta')
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
|
||||
if not self.user_has_groups('stock.group_stock_manager'):
|
||||
return
|
||||
self.env['ir.config_parameter'].sudo().set_param('stock.use_propagation_minimum_delta', self.use_propagation_minimum_delta)
|
||||
|
||||
""" If we are not in multiple locations, we can deactivate the internal
|
||||
operation types of the warehouses, so they won't appear in the dashboard.
|
||||
Otherwise, activate them.
|
||||
|
||||
@@ -18,8 +18,13 @@ class ResConfigSettings(models.TransientModel):
|
||||
website_name = fields.Char('Website Name', related='website_id.name')
|
||||
language_ids = fields.Many2many(related='website_id.language_ids', relation='res.lang')
|
||||
language_count = fields.Integer(string='Number of languages', compute='_compute_language_count', readonly=True)
|
||||
default_lang_id = fields.Many2one(string='Default language', related='website_id.default_lang_id', relation='res.lang', required=True)
|
||||
default_lang_code = fields.Char('Default language code', related='website_id.default_lang_code')
|
||||
website_default_lang_id = fields.Many2one(
|
||||
string='Default language', related='website_id.default_lang_id',
|
||||
relation='res.lang', required=True,
|
||||
oldname='default_lang_id')
|
||||
website_default_lang_code = fields.Char(
|
||||
'Default language code', related='website_id.default_lang_code',
|
||||
oldname='default_lang_code')
|
||||
google_analytics_key = fields.Char('Google Analytics Key', related='website_id.google_analytics_key')
|
||||
google_management_client_id = fields.Char('Google Client ID', related='website_id.google_management_client_id')
|
||||
google_management_client_secret = fields.Char('Google Client Secret', related='website_id.google_management_client_secret')
|
||||
@@ -33,14 +38,14 @@ class ResConfigSettings(models.TransientModel):
|
||||
favicon = fields.Binary('Favicon', related='website_id.favicon')
|
||||
# Set as global config parameter since methods using it are not website-aware. To be changed
|
||||
# when multi-website is implemented
|
||||
google_maps_api_key = fields.Char(string='Google Maps API Key')
|
||||
has_google_analytics = fields.Boolean("Google Analytics")
|
||||
has_google_analytics_dashboard = fields.Boolean("Google Analytics in Dashboard")
|
||||
has_google_maps = fields.Boolean("Google Maps")
|
||||
google_maps_api_key = fields.Char(string='Google Maps API Key', config_parameter='google_maps_api_key', default='')
|
||||
has_google_analytics = fields.Boolean("Google Analytics", config_parameter='website.has_google_analytics')
|
||||
has_google_analytics_dashboard = fields.Boolean("Google Analytics in Dashboard", config_parameter='website.has_google_analytics_dashboard')
|
||||
has_google_maps = fields.Boolean("Google Maps", config_parameter='website.has_google_maps')
|
||||
auth_signup_uninvited = fields.Selection([
|
||||
('b2b', 'On invitation (B2B)'),
|
||||
('b2c', 'Free sign up (B2C)'),
|
||||
], string='Customer Account')
|
||||
], string='Customer Account', default='b2b', config_parameter='auth_signup.invitation_scope')
|
||||
|
||||
@api.onchange('has_google_analytics')
|
||||
def onchange_has_google_analytics(self):
|
||||
@@ -67,29 +72,10 @@ class ResConfigSettings(models.TransientModel):
|
||||
for config in self:
|
||||
config.language_count = len(self.language_ids)
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
get_param = self.env['ir.config_parameter'].sudo().get_param
|
||||
res.update(
|
||||
auth_signup_uninvited='b2c' if get_param('auth_signup.allow_uninvited', 'False').lower() == 'true' else 'b2b',
|
||||
has_google_analytics=get_param('website.has_google_analytics'),
|
||||
has_google_analytics_dashboard=get_param('website.has_google_analytics_dashboard'),
|
||||
has_google_maps=get_param('website.has_google_maps'),
|
||||
google_maps_api_key=get_param('google_maps_api_key', default=''),
|
||||
)
|
||||
return res
|
||||
|
||||
def set_values(self):
|
||||
if not self.user_has_groups('website.group_website_designer'):
|
||||
raise AccessDenied()
|
||||
super(ResConfigSettings, self).set_values()
|
||||
set_param = self.env['ir.config_parameter'].sudo().set_param
|
||||
set_param('auth_signup.allow_uninvited', repr(self.auth_signup_uninvited == 'b2c'))
|
||||
set_param('website.has_google_analytics', self.has_google_analytics)
|
||||
set_param('website.has_google_analytics_dashboard', self.has_google_analytics_dashboard)
|
||||
set_param('website.has_google_maps', self.has_google_maps)
|
||||
set_param('google_maps_api_key', (self.google_maps_api_key or '').strip())
|
||||
|
||||
@api.multi
|
||||
def open_template_user(self):
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
</div>
|
||||
<field name="language_count" invisible="1"/>
|
||||
<div class="mt8" attrs="{'invisible':[('language_count', '<', 2)]}">
|
||||
<label class="o_light_label mr8" string="Default" for="default_lang_id"/>
|
||||
<field name="default_lang_id" widget="selection"/>
|
||||
<label class="o_light_label mr8" string="Default" for="website_default_lang_id"/>
|
||||
<field name="website_default_lang_id" widget="selection"/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</record>
|
||||
</data>
|
||||
<data>
|
||||
<function model="ir.config_parameter" name="set_param" eval="('auth_signup.allow_uninvited', True)"/>
|
||||
<function model="ir.config_parameter" name="set_param" eval="('auth_signup.invitation_scope', 'b2c')"/>
|
||||
|
||||
<!-- JUMP TO FORUM AT INSTALL -->
|
||||
<record id="action_open_forum" model="ir.actions.act_url">
|
||||
|
||||
@@ -50,8 +50,9 @@ class ResConfigSettings(models.TransientModel):
|
||||
module_l10n_eu_service = fields.Boolean(string="EU Digital Goods VAT")
|
||||
|
||||
cart_recovery_mail_template = fields.Many2one('mail.template', string='Cart Recovery Email',
|
||||
default=_default_recovery_mail_template, domain="[('model', '=', 'sale.order')]")
|
||||
cart_abandoned_delay = fields.Float("Abandoned Delay", default=1.0, help="number of hours after which the cart is considered abandoned")
|
||||
default=_default_recovery_mail_template, config_parameter='website_sale.cart_recovery_mail_template_id', domain="[('model', '=', 'sale.order')]")
|
||||
cart_abandoned_delay = fields.Float("Abandoned Delay", help="number of hours after which the cart is considered abandoned",
|
||||
default=1.0, config_parameter='website_sale.cart_abandoned_delay')
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
@@ -64,15 +65,9 @@ class ResConfigSettings(models.TransientModel):
|
||||
if self.env['ir.module.module'].search([('name', '=', 'website_sale_delivery')], limit=1).state in ('installed', 'to install', 'to upgrade'):
|
||||
sale_delivery_settings = 'website'
|
||||
|
||||
cart_recovery_mail_template = literal_eval(params.get_param('website_sale.cart_recovery_mail_template_id', default='False'))
|
||||
if cart_recovery_mail_template and not self.env['mail.template'].browse(cart_recovery_mail_template).exists():
|
||||
cart_recovery_mail_template = self._default_recovery_mail_template()
|
||||
|
||||
res.update(
|
||||
automatic_invoice=params.get_param('website_sale.automatic_invoice', default=False),
|
||||
sale_delivery_settings=sale_delivery_settings,
|
||||
cart_recovery_mail_template=cart_recovery_mail_template,
|
||||
cart_abandoned_delay=float(params.get_param('website_sale.cart_abandoned_delay', '1.0'))
|
||||
)
|
||||
return res
|
||||
|
||||
@@ -80,8 +75,6 @@ class ResConfigSettings(models.TransientModel):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
value = self.module_account_invoicing and self.default_invoice_policy == 'order' and self.automatic_invoice
|
||||
self.env['ir.config_parameter'].sudo().set_param('website_sale.automatic_invoice', value)
|
||||
self.env['ir.config_parameter'].sudo().set_param('website_sale.cart_recovery_mail_template_id', self.cart_recovery_mail_template.id)
|
||||
self.env['ir.config_parameter'].sudo().set_param('website_sale.cart_abandoned_delay', self.cart_abandoned_delay)
|
||||
|
||||
@api.onchange('sale_delivery_settings')
|
||||
def _onchange_sale_delivery_settings(self):
|
||||
|
||||
@@ -1476,7 +1476,7 @@
|
||||
</tbody>
|
||||
</table>
|
||||
<t t-call="website_sale.payment_confirmation_status" />
|
||||
<t t-if="request.env['ir.config_parameter'].sudo().get_param('auth_signup.allow_uninvited') == 'True' and request.website.is_public_user()">
|
||||
<t t-if="request.env['ir.config_parameter'].sudo().get_param('auth_signup.invitation_scope', 'b2b') == 'b2c' and request.website.is_public_user()">
|
||||
<p class='alert alert-info mt16'>
|
||||
<a t-att-href='order.partner_id.signup_prepare() and order.partner_id.signup_url' class='btn btn-primary'>Sign Up</a>
|
||||
Now to Follow Your Order
|
||||
|
||||
@@ -7,17 +7,4 @@ from odoo import api, fields, models
|
||||
class ResConfigSettings(models.TransientModel):
|
||||
_inherit = "res.config.settings"
|
||||
|
||||
website_slide_google_app_key = fields.Char(string='Google Doc Key')
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(ResConfigSettings, self).get_values()
|
||||
res.update(
|
||||
website_slide_google_app_key=self.env['ir.config_parameter'].sudo().get_param('website_slides.google_app_key'),
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_values(self):
|
||||
super(ResConfigSettings, self).set_values()
|
||||
self.env['ir.config_parameter'].sudo().set_param('website_slides.google_app_key', self.website_slide_google_app_key)
|
||||
website_slide_google_app_key = fields.Char(string='Google Doc Key', config_parameter='website_slides.google_app_key')
|
||||
|
||||
@@ -27,6 +27,7 @@ class IrConfigParameter(models.Model):
|
||||
"""Per-database storage of configuration key-value pairs."""
|
||||
_name = 'ir.config_parameter'
|
||||
_rec_name = 'key'
|
||||
_order = 'key'
|
||||
|
||||
key = fields.Char(required=True, index=True)
|
||||
value = fields.Text(required=True)
|
||||
|
||||
@@ -4,10 +4,9 @@ import json
|
||||
import logging
|
||||
import re
|
||||
|
||||
from operator import attrgetter, add
|
||||
from lxml import etree
|
||||
|
||||
from odoo import api, models, registry, SUPERUSER_ID, _
|
||||
from odoo import api, models, _
|
||||
from odoo.exceptions import AccessError, RedirectWarning, UserError
|
||||
from odoo.tools import ustr
|
||||
|
||||
@@ -341,6 +340,7 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
|
||||
default_foo = fields.type(..., default_model='my.model'),
|
||||
group_bar = fields.Boolean(..., group='base.group_user', implied_group='my.group'),
|
||||
module_baz = fields.Boolean(...),
|
||||
config_qux = fields.Char(..., config_parameter='my.parameter')
|
||||
other_field = fields.type(...),
|
||||
|
||||
The method ``execute`` provides some support based on a naming convention:
|
||||
@@ -366,14 +366,18 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
|
||||
``execute`` triggers the immediate installation of the module named 'XXX'
|
||||
if the field has the integer value ``1``.
|
||||
|
||||
* For a field with no specific prefix BUT an attribute 'config_parameter',
|
||||
``execute``` will save its value in an ir.config.parameter (global setting for the
|
||||
database).
|
||||
|
||||
* For the other fields, the method ``execute`` invokes all methods with a name
|
||||
that starts with 'set_'; such methods can be defined to implement the effect
|
||||
of those fields.
|
||||
|
||||
The method ``default_get`` retrieves values that reflect the current status of the
|
||||
fields like 'default_XXX', 'group_XXX' and 'module_XXX'. It also invokes all methods
|
||||
with a name that starts with 'get_default_'; such methods can be defined to provide
|
||||
current values for other fields.
|
||||
fields like 'default_XXX', 'group_XXX', 'module_XXX' and config_XXX.
|
||||
It also invokes all methods with a name that starts with 'get_default_';
|
||||
such methods can be defined to provide current values for other fields.
|
||||
"""
|
||||
_name = 'res.config.settings'
|
||||
|
||||
@@ -437,6 +441,7 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
|
||||
{ 'default': [('default_foo', 'model', 'foo'), ...],
|
||||
'group': [('group_bar', [browse_group], browse_implied_group), ...],
|
||||
'module': [('module_baz', browse_module), ...],
|
||||
'config': [('config_qux', 'my.parameter'), ...],
|
||||
'other': ['other_field', ...],
|
||||
}
|
||||
"""
|
||||
@@ -444,22 +449,33 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
|
||||
Groups = self.env['res.groups']
|
||||
ref = self.env.ref
|
||||
|
||||
defaults, groups, modules, others = [], [], [], []
|
||||
defaults, groups, modules, configs, others = [], [], [], [], []
|
||||
for name, field in self._fields.items():
|
||||
if name.startswith('default_') and hasattr(field, 'default_model'):
|
||||
if name.startswith('default_'):
|
||||
if not hasattr(field, 'default_model'):
|
||||
raise Exception("Field %s without attribute 'default_model'" % field)
|
||||
defaults.append((name, field.default_model, name[8:]))
|
||||
elif name.startswith('group_') and field.type in ('boolean', 'selection') and \
|
||||
hasattr(field, 'implied_group'):
|
||||
elif name.startswith('group_'):
|
||||
if field.type not in ('boolean', 'selection'):
|
||||
raise Exception("Field %s must have type 'boolean' or 'selection'" % field)
|
||||
if not hasattr(field, 'implied_group'):
|
||||
raise Exception("Field %s without attribute 'implied_group'" % field)
|
||||
field_group_xmlids = getattr(field, 'group', 'base.group_user').split(',')
|
||||
field_groups = Groups.concat(*(ref(it) for it in field_group_xmlids))
|
||||
groups.append((name, field_groups, ref(field.implied_group)))
|
||||
elif name.startswith('module_') and field.type in ('boolean', 'selection'):
|
||||
elif name.startswith('module_'):
|
||||
if field.type not in ('boolean', 'selection'):
|
||||
raise Exception("Field %s must have type 'boolean' or 'selection'" % field)
|
||||
module = IrModule.sudo().search([('name', '=', name[7:])], limit=1)
|
||||
modules.append((name, module))
|
||||
elif hasattr(field, 'config_parameter'):
|
||||
if field.type not in ('boolean', 'integer', 'float', 'char', 'selection', 'many2one'):
|
||||
raise Exception("Field %s must have type 'boolean', 'integer', 'float', 'char', 'selection' or 'many2one'" % field)
|
||||
configs.append((name, field.config_parameter))
|
||||
else:
|
||||
others.append(name)
|
||||
|
||||
return {'default': defaults, 'group': groups, 'module': modules, 'other': others}
|
||||
return {'default': defaults, 'group': groups, 'module': modules, 'config': configs, 'other': others}
|
||||
|
||||
def get_values(self):
|
||||
"""
|
||||
@@ -470,6 +486,7 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
IrDefault = self.env['ir.default']
|
||||
IrConfigParameter = self.env['ir.config_parameter'].sudo()
|
||||
classified = self._get_classified_fields()
|
||||
|
||||
res = super(ResConfigSettings, self).default_get(fields)
|
||||
@@ -492,6 +509,36 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
|
||||
if self._fields[name].type == 'selection':
|
||||
res[name] = int(res[name])
|
||||
|
||||
# config: get & convert stored ir.config_parameter (or default)
|
||||
WARNING_MESSAGE = "Error when converting value %r of field %s for ir.config.parameter %r"
|
||||
for name, icp in classified['config']:
|
||||
field = self._fields[name]
|
||||
value = IrConfigParameter.get_param(icp, field.default(self) if field.default else False)
|
||||
if value is not False:
|
||||
if field.type == 'many2one':
|
||||
try:
|
||||
# Special case when value is the id of a deleted record, we do not want to
|
||||
# block the settings screen
|
||||
value = self.env[field.comodel_name].browse(int(value)).exists().id
|
||||
except ValueError:
|
||||
_logger.warning(WARNING_MESSAGE, value, field, icp)
|
||||
value = False
|
||||
elif field.type == 'integer':
|
||||
try:
|
||||
value = int(value)
|
||||
except ValueError:
|
||||
_logger.warning(WARNING_MESSAGE, value, field, icp)
|
||||
value = 0
|
||||
elif field.type == 'float':
|
||||
try:
|
||||
value = float(value)
|
||||
except ValueError:
|
||||
_logger.warning(WARNING_MESSAGE, value, field, icp)
|
||||
value = 0.0
|
||||
elif field.type == 'boolean':
|
||||
value = value.lower() == 'true'
|
||||
res[name] = value
|
||||
|
||||
# other fields: call the method 'get_values'
|
||||
# The other methods that start with `get_default_` are deprecated
|
||||
for method in dir(self):
|
||||
@@ -536,6 +583,22 @@ class ResConfigSettings(models.TransientModel, ResConfigModuleInstallationMixin)
|
||||
groups.write({'implied_ids': [(3, implied_group.id)]})
|
||||
implied_group.write({'users': [(3, user.id) for user in groups.mapped('users')]})
|
||||
|
||||
# config fields: store ir.config_parameters
|
||||
IrConfigParameter = self.env['ir.config_parameter'].sudo()
|
||||
for name, icp in classified['config']:
|
||||
field = self._fields[name]
|
||||
value = self[name]
|
||||
if field.type == 'char':
|
||||
# storing developer keys as ir.config_parameter may lead to nasty
|
||||
# bugs when users leave spaces around them
|
||||
value = (value or "").strip() or False
|
||||
elif field.type in ('integer', 'float'):
|
||||
value = repr(value) if value else False
|
||||
elif field.type == 'many2one':
|
||||
# value is a (possibly empty) recordset
|
||||
value = value.id
|
||||
IrConfigParameter.set_param(icp, value)
|
||||
|
||||
# other fields: execute method 'set_values'
|
||||
# Methods that start with `set_` are now deprecated
|
||||
for method in dir(self):
|
||||
|
||||
Reference in New Issue
Block a user