[MERGE] base/res_config: Clean model and behavior of configuration forms
Purpose:
========
The res.config.settings are quite a mess. The API is not well know and the general usage in the common modules is bad.
Specifications
==============
Clean use of ir.values in models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- clean use of ir.values -> those should be only real default values for existing fields in other models.
- Use ir.config_parameter or something else if conversion is required
reset values when option is disabled
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
propagate checkboxes in settings. Ex: "use <my feature> opens <feature_value> configuration". Code should handle both <my_feature> and <feature_value>. Unactivating a feature should disable it really.
SALES
default terms & conditions
WEBSITE
Google Analytics
Google Analytics in dashboard
INVENTORY
Security Lead Time for Sales -> reset to 0
Security Lead Time for Purchase -> reset to 0
No Rescheduling Propagation -> reset to 1
MANUFACTURING
Security Lead Time -> reset to 0
clean alias congiguration
~~~~~~~~~~~~~~~~~~~~~~~~~
crm, project: remove unnecessary and unused generate_sales_team/project_alias, conf is done on sales team / project
crm: generate_lead_from_alias cleaned
hr_expense: correctly take into account "Use Mailgateway" settings, reset alias if not set
pos: mutli sales price settings cleaned
sales: multi sales price settings cleaned, default deposit product cleaned
website: has_google_analytics, has_google_analytics_dashboard, has_google_maps settings cleaned
website_sale: multi sales prices settings cleaned
print: default_provider_id
Ease google analytic settings
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
it's hard to get all the google analytics working. Setup steps are still confusing. And if you set up analytics API first (before creating an account), you get a traceback in the dashboard...
review google analytics id wizard
- How to get my Tracking ID
- How to get my API Client ID
- open those links in new tabs
make sure any traceback pops up if the user enter a client ID without a Tracking ID. It is the case for now. One way is to block the
user with a warning: Please enter your Tracking ID.
as soon as an ID is set, activate related features and populate fields in website settings + some changes in labels
only display Google Analytics in Dashboard in website settings if Google Analytics is checked
+ blocking warning if the user enters a Client ID without any Tracking ID
Reorganise files according to the guidelines
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Declare models in camel case, place python files in models, xml views in views...
Remove some useless/unused code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some chunck of code are never called or are useless.
Clean ir.actions.todo models
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Remove some useless fields:
- type: Historically we used ir.actions.todo to make complex things. Now we only use them to redirect to a specific action when a module is installed. All our ir.actions.todo type is `automatic`
- Note: Useless
- Group_id: All our ir.actions.todo are launched by the administrator. No need to specify groups on it.
Prevent to be redirected everywhere on update
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Prevent to have more than one open ir.actions.todo. This avoid this use case:
- Install ecommerce, be redirect to the theme selection
- Install note, be redirected to /shop.
We just take the last defined ir.actions.todo into account.
Stay on a config setting form by pressing apply
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If we click on Apply, we want to stay on the config page to see the new fields coming from the module you just installed
Keep the current behavior when installing a module from the App menuitem, which is either jumping to the app switcher or jumping to a specific action if defined on this module
Clean default method to get/set the values on a config form
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Currently there are 4 types on fields on res_config:
- `default_`: These fields should use ir.values and they have been cleaned in a previous section of this commit message
- `group_`: They define security groups
- `module_`: They allow to install/uninstall modules
- Other fields: They are the other fields that are implemented in a quite messy way.
Currently all the methods beginning by `get_default` are used to fetch their default values, usually by looking in the ir.config_parameter table.
Currently all the methods beginning by `set_` are used to set their values, usually in the ir.config_parameter table.
This section purpose is to replace all the occurences of `get_default_foo` and `set_foo`. As these methods won't be called anymore, a warning is logged to notice its deprecation. They are replaced by the generic methods `get_values` and `set_values` that should be overridden to define the behavior of the added fields.
Add a test on res_config on page loading and saving
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Try to create and execute all res_config models. Target settings that can't be loaded or saved and avoid remaining methods get_default_foo` or `set_foo` that won't be executed.
This commit is contained in:
@@ -56,7 +56,7 @@ Core mechanisms for the accounting modules. To display the menuitems, install th
|
||||
'views/report_agedpartnerbalance.xml',
|
||||
'views/tax_adjustments.xml',
|
||||
'wizard/wizard_tax_adjustments_view.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/account_config_settings_views.xml',
|
||||
'views/web_planner_data.xml',
|
||||
'views/account_journal_dashboard_view.xml',
|
||||
'report/account_report_payment_receipt_templates.xml',
|
||||
|
||||
@@ -11,5 +11,5 @@ from . import account_analytic_line
|
||||
from . import account_journal_dashboard
|
||||
from . import product
|
||||
from . import company
|
||||
from . import res_config
|
||||
from . import account_config_settings
|
||||
from . import web_planner
|
||||
|
||||
+14
-16
@@ -60,34 +60,28 @@ class AccountConfigSettings(models.TransientModel):
|
||||
module_l10n_eu_service = fields.Boolean(string="EU Digital Goods VAT")
|
||||
|
||||
@api.model
|
||||
def get_default_tax_fields(self, fields):
|
||||
default_purchase_tax_id = self.env['ir.config_parameter'].sudo().get_param('account.default_purchase_tax_id', default=False)
|
||||
default_sale_tax_id = self.env['ir.config_parameter'].sudo().get_param('account.default_sale_tax_id', default=False)
|
||||
return dict(default_purchase_tax_id=int(default_purchase_tax_id), default_sale_tax_id=int(default_sale_tax_id))
|
||||
def get_values(self):
|
||||
res = super(AccountConfigSettings, self).get_values()
|
||||
params = self.env['ir.config_parameter'].sudo()
|
||||
res.update(
|
||||
default_purchase_tax_id=params.get_param('account.default_purchase_tax_id', default=False),
|
||||
default_sale_tax_id=params.get_param('account.default_sale_tax_id', default=False)
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_default_tax_fields(self):
|
||||
def set_values(self):
|
||||
super(AccountConfigSettings, self).set_values()
|
||||
self.env['ir.config_parameter'].sudo().set_param("account.default_purchase_tax_id", self.default_purchase_tax_id.id)
|
||||
self.env['ir.config_parameter'].sudo().set_param("account.default_sale_tax_id", self.default_sale_tax_id.id)
|
||||
|
||||
@api.depends('company_id')
|
||||
def _compute_has_chart_of_accounts(self):
|
||||
self.has_chart_of_accounts = bool(self.company_id.chart_template_id)
|
||||
|
||||
def set_group_multi_currency(self):
|
||||
if self.group_multi_currency:
|
||||
self.env.ref('base.group_user').write({'implied_ids': [(4, self.env.ref('product.group_sale_pricelist').id)]})
|
||||
return True
|
||||
|
||||
def set_default_product_taxes(self):
|
||||
""" Set the product taxes if they have changed """
|
||||
ir_values_obj = self.env['ir.values']
|
||||
if self.default_sale_tax_id:
|
||||
ir_values_obj.sudo().set_default('product.template', "taxes_id", [self.default_sale_tax_id.id], for_all_users=True, company_id=self.company_id.id)
|
||||
if self.default_purchase_tax_id:
|
||||
ir_values_obj.sudo().set_default('product.template', "supplier_taxes_id", [self.default_purchase_tax_id.id], for_all_users=True, company_id=self.company_id.id)
|
||||
|
||||
def set_chart_of_accounts(self):
|
||||
""" install a chart of accounts for the given company (if required) """
|
||||
if self.chart_template_id and not self.has_chart_of_accounts and self.company_id.expects_chart_of_accounts:
|
||||
if self.company_id.chart_template_id and self.chart_template_id != self.company_id.chart_template_id:
|
||||
@@ -108,6 +102,10 @@ class AccountConfigSettings(models.TransientModel):
|
||||
})
|
||||
wizard.execute()
|
||||
|
||||
@api.depends('company_id')
|
||||
def _compute_has_chart_of_accounts(self):
|
||||
self.has_chart_of_accounts = bool(self.company_id.chart_template_id)
|
||||
|
||||
@api.onchange('group_analytic_accounting')
|
||||
def onchange_analytic_accounting(self):
|
||||
if self.group_analytic_accounting:
|
||||
@@ -147,7 +147,7 @@ class AccountChartTemplate(models.Model):
|
||||
todo = self.env['ir.actions.todo']
|
||||
action_rec = self.env['ir.model.data'].xmlid_to_object('account.action_wizard_multi_chart')
|
||||
if action_rec:
|
||||
todo.create({'action_id': action_rec.id, 'name': _('Choose Accounting Template'), 'type': 'automatic'})
|
||||
todo.create({'action_id': action_rec.id, 'name': _('Choose Accounting Template')})
|
||||
return True
|
||||
|
||||
@api.model
|
||||
|
||||
@@ -19,7 +19,7 @@ It assigns manager and user access rights to the Administrator for the accountin
|
||||
'data/account_accountant_data.xml',
|
||||
'security/account_accountant_security.xml',
|
||||
'views/account_accountant_templates.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/account_config_settings_views.xml',
|
||||
'views/product_views.xml',
|
||||
],
|
||||
'demo': ['data/account_accountant_demo.xml'],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import res_config
|
||||
from . import account_config_settings
|
||||
|
||||
@@ -24,7 +24,7 @@ Allows to automatically select analytic accounts based on criterions:
|
||||
'security/account_analytic_default_security.xml',
|
||||
'views/account_analytic_default_view.xml',
|
||||
'views/product_views.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/account_config_settings_views.xml',
|
||||
],
|
||||
'installable': True,
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ Keeps track of depreciations, and creates corresponding journal entries.
|
||||
'views/account_invoice_views.xml',
|
||||
'views/account_asset_templates.xml',
|
||||
'views/product_views.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/account_config_settings_views.xml',
|
||||
'report/account_asset_report_views.xml',
|
||||
'data/account_asset_data.xml',
|
||||
],
|
||||
|
||||
@@ -34,7 +34,7 @@ Three reports are available:
|
||||
'security/account_budget_security.xml',
|
||||
'views/account_analytic_account_views.xml',
|
||||
'views/account_budget_views.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/account_config_settings_views.xml',
|
||||
],
|
||||
'demo': ['data/account_budget_demo.xml'],
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ Allow users to login through OAuth2 Provider.
|
||||
'data/auth_oauth_data.yml',
|
||||
'views/auth_oauth_views.xml',
|
||||
'views/res_users_views.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/base_config_settings_views.xml',
|
||||
'views/auth_oauth_templates.xml',
|
||||
'security/ir.model.access.csv',
|
||||
],
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import auth_oauth
|
||||
from . import base_config_settings
|
||||
from . import ir_config_parameter
|
||||
from . import res_config
|
||||
from . import res_users
|
||||
|
||||
+13
-24
@@ -15,36 +15,25 @@ class BaseConfigSettings(models.TransientModel):
|
||||
def get_uri(self):
|
||||
return "%s/auth_oauth/signin" % (self.env['ir.config_parameter'].get_param('web.base.url'))
|
||||
|
||||
def _compute_server_uri(self):
|
||||
uri = self.get_uri()
|
||||
for setting in self:
|
||||
setting.server_uri_google = uri
|
||||
|
||||
auth_oauth_google_enabled = fields.Boolean(string='Allow users to sign in with Google')
|
||||
auth_oauth_google_client_id = fields.Char(string='Client ID')
|
||||
server_uri_google = fields.Char(compute='_compute_server_uri', string='Server uri')
|
||||
server_uri_google = fields.Char(string='Server uri')
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
settings = super(BaseConfigSettings, self).default_get(fields)
|
||||
settings.update(self.get_oauth_providers(fields))
|
||||
return settings
|
||||
|
||||
@api.model
|
||||
def get_oauth_providers(self, fields):
|
||||
def get_values(self):
|
||||
res = super(BaseConfigSettings, self).get_values()
|
||||
google_provider = self.env.ref('auth_oauth.provider_google', False)
|
||||
return {
|
||||
'auth_oauth_google_enabled': google_provider.enabled,
|
||||
'auth_oauth_google_client_id': google_provider.client_id,
|
||||
'server_uri_google': self.get_uri()
|
||||
}
|
||||
res.update(
|
||||
auth_oauth_google_enabled=google_provider.enabled,
|
||||
auth_oauth_google_client_id=google_provider.client_id,
|
||||
server_uri_google=self.get_uri(),
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_oauth_providers(self):
|
||||
self.ensure_one()
|
||||
def set_values(self):
|
||||
super(BaseConfigSettings, self).set_values()
|
||||
google_provider = self.env.ref('auth_oauth.provider_google', False)
|
||||
rg = {
|
||||
google_provider.write({
|
||||
'enabled': self.auth_oauth_google_enabled,
|
||||
'client_id': self.auth_oauth_google_client_id,
|
||||
}
|
||||
google_provider.write(rg)
|
||||
})
|
||||
@@ -17,7 +17,7 @@ Allow users to sign up and reset their password
|
||||
],
|
||||
'data': [
|
||||
'data/auth_signup_data.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/base_config_settings_views.xml',
|
||||
'views/res_users_views.xml',
|
||||
'views/auth_signup_login_templates.xml',
|
||||
],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import res_config
|
||||
from . import res_users
|
||||
from . import base_config_settings
|
||||
from . import res_partner
|
||||
from . import res_users
|
||||
|
||||
+13
-10
@@ -12,18 +12,21 @@ class BaseConfigSettings(models.TransientModel):
|
||||
auth_signup_template_user_id = fields.Many2one('res.users', string='Template user for new users created through signup')
|
||||
|
||||
@api.model
|
||||
def get_default_auth_signup_template_user_id(self, fields):
|
||||
get_param = self.env['ir.config_parameter'].get_param
|
||||
def get_values(self):
|
||||
res = super(BaseConfigSettings, self).get_values()
|
||||
get_param = self.env['ir.config_parameter'].sudo().get_param
|
||||
# we use safe_eval on the result, since the value of the parameter is a nonempty string
|
||||
return {
|
||||
'auth_signup_reset_password': safe_eval(get_param('auth_signup.reset_password', 'False')),
|
||||
'auth_signup_uninvited': safe_eval(get_param('auth_signup.allow_uninvited', 'False')),
|
||||
'auth_signup_template_user_id': safe_eval(get_param('auth_signup.template_user_id', 'False')),
|
||||
}
|
||||
res.update(
|
||||
auth_signup_reset_password=safe_eval(get_param('auth_signup.reset_password', 'False')),
|
||||
auth_signup_uninvited=safe_eval(get_param('auth_signup.allow_uninvited', 'False')),
|
||||
auth_signup_template_user_id=safe_eval(get_param('auth_signup.template_user_id', 'False')),
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_auth_signup_template_user_id(self):
|
||||
self.ensure_one()
|
||||
set_param = self.env['ir.config_parameter'].set_param
|
||||
def set_values(self):
|
||||
super(BaseConfigSettings, 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))
|
||||
@@ -18,7 +18,7 @@ This wizard will activate the CRON job and the Scheduler and will start the auto
|
||||
'data': [
|
||||
'data/ir_cron_data.xml',
|
||||
'views/ir_translation_views.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/base_config_settings_views.xml',
|
||||
'wizard/base_gengo_translations_view.xml',
|
||||
],
|
||||
'demo': ['data/res_company_demo.xml'],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import base_config_settings
|
||||
from . import ir_translation
|
||||
from . import res_company
|
||||
from . import res_config
|
||||
|
||||
@@ -13,7 +13,7 @@ Shows you a list of applications features to install from.
|
||||
""",
|
||||
'depends': ['base', 'web'],
|
||||
'data': [
|
||||
'views/res_config_views.xml',
|
||||
'views/base_config_settings_views.xml',
|
||||
'views/res_partner_views.xml',
|
||||
],
|
||||
'demo': [],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import res_config
|
||||
from . import base_config_settings
|
||||
|
||||
|
||||
+16
-22
@@ -37,21 +37,27 @@ class BaseConfigSettings(models.TransientModel):
|
||||
external_report_layout = fields.Selection(related="company_id.external_report_layout")
|
||||
|
||||
@api.model
|
||||
def get_default_fields(self, fields):
|
||||
default_external_email_server = self.env['ir.config_parameter'].sudo().get_param('base_setup.default_external_email_server', default=False)
|
||||
default_user_rights = self.env['ir.config_parameter'].sudo().get_param('base_setup.default_user_rights', default=False)
|
||||
default_custom_report_footer = self.env['ir.config_parameter'].sudo().get_param('base_setup.default_custom_report_footer', default=False)
|
||||
return {
|
||||
'default_external_email_server': default_external_email_server,
|
||||
'default_user_rights': default_user_rights,
|
||||
'default_custom_report_footer': default_custom_report_footer,
|
||||
}
|
||||
def get_values(self):
|
||||
res = super(BaseConfigSettings, 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
|
||||
|
||||
@api.multi
|
||||
def set_default_fields(self):
|
||||
def set_values(self):
|
||||
super(BaseConfigSettings, 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
|
||||
def open_company(self):
|
||||
@@ -71,18 +77,6 @@ class BaseConfigSettings(models.TransientModel):
|
||||
action['views'] = [[self.env.ref('base.view_users_form').id, 'form']]
|
||||
return action
|
||||
|
||||
@api.model
|
||||
def get_default_company_share_partner(self, fields):
|
||||
return {
|
||||
'company_share_partner': not self.env.ref('base.res_partner_rule').active
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def set_default_company_share_partner(self):
|
||||
partner_rule = self.env.ref('base.res_partner_rule')
|
||||
for config in self:
|
||||
partner_rule.write({'active': not config.company_share_partner})
|
||||
|
||||
@api.model
|
||||
def _prepare_report_view_action(self, template):
|
||||
template_id = self.env.ref(template)
|
||||
@@ -39,6 +39,6 @@ only the country code will be validated.
|
||||
'data': [
|
||||
'views/res_partner_views.xml',
|
||||
'views/res_company_views.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/account_config_settings_views.xml',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import account_config_settings
|
||||
from . import res_company
|
||||
from . import res_partner
|
||||
from . import res_config
|
||||
|
||||
@@ -45,7 +45,6 @@ Dashboard for CRM will include:
|
||||
|
||||
'data/crm_data.xml',
|
||||
'data/crm_stage_data.xml',
|
||||
'data/sales_config_settings_data.xml',
|
||||
'data/crm_lead_data.xml',
|
||||
'data/web_planner_data.xml',
|
||||
'data/mail_template_data.xml',
|
||||
@@ -65,7 +64,7 @@ Dashboard for CRM will include:
|
||||
'views/crm_lead_views.xml',
|
||||
'views/calendar_views.xml',
|
||||
'views/res_partner_views.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/sale_config_settings_views.xml',
|
||||
'views/crm_team_views.xml',
|
||||
],
|
||||
'demo': [
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate='1'>
|
||||
<function id="default_generate_sales_team_alias"
|
||||
model="ir.values" name="set_default"
|
||||
eval="('sale.config.settings', 'generate_sales_team_alias', True)"/>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -6,6 +6,6 @@ from . import calendar
|
||||
from . import crm_lead
|
||||
from . import crm_stage
|
||||
from . import crm_team
|
||||
from . import res_config
|
||||
from . import sale_config_settings
|
||||
from . import res_partner
|
||||
from . import web_planner
|
||||
|
||||
@@ -120,13 +120,6 @@ class Team(models.Model):
|
||||
if not self.use_opportunities and self.dashboard_graph_model == 'crm.opportunity.report':
|
||||
raise ValidationError(_("Dashboard graph content cannot be Pipeline if the sales channel doesn't use it. (Pipeline is unchecked.)"))
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
generate_alias_name = self.env['ir.values'].get_default('sale.config.settings', 'generate_sales_team_alias')
|
||||
if generate_alias_name and not vals.get('alias_name'):
|
||||
vals['alias_name'] = vals.get('name')
|
||||
return super(Team, self).create(vals)
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
result = super(Team, self).write(vals)
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class CRMSettings(models.TransientModel):
|
||||
_inherit = 'sale.config.settings'
|
||||
|
||||
generate_sales_team_alias = fields.Boolean("Automatically generate an email alias at the sales channel creation",
|
||||
help="Odoo will generate an email alias based on the sales channel name")
|
||||
alias_prefix = fields.Char('Default Alias Name for Leads')
|
||||
alias_domain = fields.Char('Alias Domain', default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"))
|
||||
# TDE TODO: as it is not linked to ir.values anymore, it should be renamed, but not in stable
|
||||
default_generate_lead_from_alias = fields.Boolean('Manual Assignation of Emails')
|
||||
group_use_lead = fields.Boolean(string="Leads", implied_group='crm.group_use_lead')
|
||||
module_crm_phone_validation = fields.Boolean("Phone Validation")
|
||||
module_crm_voip = fields.Boolean("Asterisk (VoIP)")
|
||||
|
||||
def _find_default_lead_alias_id(self):
|
||||
alias = self.env.ref('crm.mail_alias_lead_info', False)
|
||||
if not alias:
|
||||
alias = self.env['mail.alias'].search([
|
||||
('alias_model_id.model', '=', 'crm.lead'),
|
||||
('alias_force_thread_id', '=', False),
|
||||
('alias_parent_model_id.model', '=', 'crm.team'),
|
||||
('alias_parent_thread_id', '=', False),
|
||||
('alias_defaults', '=', '{}')
|
||||
], limit=1)
|
||||
return alias
|
||||
|
||||
@api.model
|
||||
def get_default_generate_sales_team_alias(self, fields):
|
||||
return {
|
||||
'generate_sales_team_alias': self.env['ir.values'].get_default('sale.config.settings', 'generate_sales_team_alias')
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def set_default_generate_sales_team_alias(self):
|
||||
IrValues = self.env['ir.values']
|
||||
if self.env['res.users'].has_group('base.group_erp_manager'):
|
||||
IrValues = IrValues.sudo()
|
||||
IrValues.set_default('sale.config.settings', 'generate_sales_team_alias', self.generate_sales_team_alias)
|
||||
|
||||
@api.model
|
||||
def get_default_default_generate_lead_from_alias(self, fields):
|
||||
return {
|
||||
'default_generate_lead_from_alias': self.env['ir.config_parameter'].sudo().get_param('sale_config_settings.default_generate_lead_from_alias')
|
||||
}
|
||||
|
||||
@api.multi
|
||||
def set_default_default_generate_lead_from_alias(self):
|
||||
self.env['ir.config_parameter'].sudo().set_param('sale_config_settings.default_generate_lead_from_alias', self.default_generate_lead_from_alias)
|
||||
|
||||
@api.onchange('group_use_lead')
|
||||
def _onchange_group_use_lead(self):
|
||||
""" Reset alias / leads configuration if leads are not used """
|
||||
if not self.group_use_lead:
|
||||
self.default_generate_lead_from_alias = False
|
||||
|
||||
@api.onchange('default_generate_lead_from_alias')
|
||||
def _onchange_default_generate_lead_from_alias(self):
|
||||
if self.default_generate_lead_from_alias:
|
||||
self.alias_prefix = self.alias_prefix or 'info'
|
||||
else:
|
||||
self.alias_prefix = False
|
||||
|
||||
@api.model
|
||||
def get_default_alias_prefix(self, fields):
|
||||
alias = self._find_default_lead_alias_id()
|
||||
return {'alias_prefix': alias.alias_name if alias else False}
|
||||
|
||||
@api.multi
|
||||
def set_default_alias_prefix(self):
|
||||
for record in self:
|
||||
alias = self._find_default_lead_alias_id()
|
||||
if alias:
|
||||
alias.write({'alias_name': record.alias_prefix})
|
||||
else:
|
||||
self.env['mail.alias'].with_context(alias_model_name='crm.lead', alias_parent_model_name='crm.team').create({'alias_name': record.alias_prefix})
|
||||
|
||||
return True
|
||||
@@ -0,0 +1,59 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class SaleConfigSettings(models.TransientModel):
|
||||
_inherit = 'sale.config.settings'
|
||||
|
||||
alias_prefix = fields.Char('Default Alias Name for Leads')
|
||||
alias_domain = fields.Char('Alias Domain', default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"))
|
||||
generate_lead_from_alias = fields.Boolean('Manual Assignation of Emails')
|
||||
group_use_lead = fields.Boolean(string="Leads", implied_group='crm.group_use_lead')
|
||||
module_crm_phone_validation = fields.Boolean("Phone Validation")
|
||||
module_crm_voip = fields.Boolean("Asterisk (VoIP)")
|
||||
|
||||
def _find_default_lead_alias_id(self):
|
||||
alias = self.env.ref('crm.mail_alias_lead_info', False)
|
||||
if not alias:
|
||||
alias = self.env['mail.alias'].search([
|
||||
('alias_model_id.model', '=', 'crm.lead'),
|
||||
('alias_force_thread_id', '=', False),
|
||||
('alias_parent_model_id.model', '=', 'crm.team'),
|
||||
('alias_parent_thread_id', '=', False),
|
||||
('alias_defaults', '=', '{}')
|
||||
], limit=1)
|
||||
return alias
|
||||
|
||||
@api.onchange('group_use_lead')
|
||||
def _onchange_group_use_lead(self):
|
||||
""" Reset alias / leads configuration if leads are not used """
|
||||
if not self.group_use_lead:
|
||||
self.generate_lead_from_alias = False
|
||||
|
||||
@api.onchange('generate_lead_from_alias')
|
||||
def _onchange_generate_lead_from_alias(self):
|
||||
self.alias_prefix = 'info' if self.generate_lead_from_alias else False
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(SaleConfigSettings, self).get_values()
|
||||
alias = self._find_default_lead_alias_id()
|
||||
res.update(
|
||||
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(SaleConfigSettings, 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.alias_prefix})
|
||||
else:
|
||||
self.env['mail.alias'].with_context(
|
||||
alias_model_name='crm.lead',
|
||||
alias_parent_model_name='crm.team').create({'alias_name': self.alias_prefix})
|
||||
+3
-3
@@ -25,7 +25,7 @@
|
||||
title="Emails received to that address generate new leads not assigned to any sales channel yet. This can be made when converting them into opportunities. Incoming emails can be automatically assigned to specific sales channels. To do so, set an email alias on the sales channel."
|
||||
groups="base.group_no_one">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="default_generate_lead_from_alias"/>
|
||||
<field name="generate_lead_from_alias"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Manually Assignation of Incoming Emails"/>
|
||||
@@ -33,11 +33,11 @@
|
||||
Generate unassigned leads from incoming emails. Leads coming from
|
||||
that email will be assigned manually.
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('default_generate_lead_from_alias','=',False)]}">
|
||||
<div class="content-group" attrs="{'invisible': [('generate_lead_from_alias','=',False)]}">
|
||||
<div class="mt16">
|
||||
<label string="Alias" class="o_light_label"/>
|
||||
<field name="alias_prefix" class="oe_inline"
|
||||
attrs="{'required': [('default_generate_lead_from_alias', '=', True)]}"/>
|
||||
attrs="{'required': [('generate_lead_from_alias', '=', True)]}"/>
|
||||
<span>@</span>
|
||||
<field name="alias_domain" readonly="1" class="oe_inline"/>
|
||||
</div>
|
||||
@@ -16,7 +16,7 @@ The module adds the possibility to synchronize Google Calendar with Odoo
|
||||
'data/google_calendar_data.xml',
|
||||
'data/google_calendar_data.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'views/res_config_views.xml',
|
||||
'views/base_config_settings_views.xml',
|
||||
'views/res_users_views.xml',
|
||||
'views/google_calendar_templates.xml',
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import base_config_settings
|
||||
from . import calendar
|
||||
from . import res_users
|
||||
from . import google_calendar
|
||||
from . import res_config
|
||||
from . import res_users
|
||||
|
||||
@@ -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 BaseConfigSettings(models.TransientModel):
|
||||
_inherit = 'base.config.settings'
|
||||
|
||||
cal_client_id = fields.Char("Client_id")
|
||||
cal_client_secret = fields.Char("Client_key")
|
||||
server_uri = fields.Char('URI for tuto')
|
||||
|
||||
def set_values(self):
|
||||
super(BaseConfigSettings, 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(BaseConfigSettings, 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
|
||||
@@ -1,25 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class CalendarSettings(models.TransientModel):
|
||||
|
||||
_inherit = 'base.config.settings'
|
||||
|
||||
cal_client_id = fields.Char("Client_id")
|
||||
cal_client_secret = fields.Char("Client_key")
|
||||
server_uri = fields.Char('URI for tuto')
|
||||
|
||||
def set_calset(self):
|
||||
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())
|
||||
|
||||
def get_default_all(self, fields):
|
||||
get_param = self.env['ir.config_parameter'].get_param
|
||||
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 dict(cal_client_id=cal_client_id, cal_client_secret=cal_client_secret, server_uri=server_uri)
|
||||
@@ -12,7 +12,7 @@
|
||||
'data/google_drive_data.xml',
|
||||
'views/google_drive_views.xml',
|
||||
'views/google_drive_templates.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/base_config_settings_views.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/google_drive_demo.xml'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import base_config_settings
|
||||
from . import google_drive
|
||||
from . import res_config
|
||||
|
||||
+15
-13
@@ -7,11 +7,7 @@ from odoo import api, fields, models
|
||||
class BaseConfigSettings(models.TransientModel):
|
||||
_inherit = "base.config.settings"
|
||||
|
||||
@api.model
|
||||
def _default_google_drive_authorization_code(self):
|
||||
return self.env['ir.config_parameter'].sudo().get_param('google_drive_authorization_code')
|
||||
|
||||
google_drive_authorization_code = fields.Char(string='Authorization Code', default=_default_google_drive_authorization_code)
|
||||
google_drive_authorization_code = fields.Char(string='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')
|
||||
@@ -20,14 +16,20 @@ class BaseConfigSettings(models.TransientModel):
|
||||
for config in self:
|
||||
config.google_drive_uri = google_drive_uri
|
||||
|
||||
@api.multi
|
||||
def set_google_authorization_code(self):
|
||||
self.ensure_one()
|
||||
ICP = self.env['ir.config_parameter']
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(BaseConfigSettings, 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(BaseConfigSettings, self).set_values()
|
||||
params = self.env['ir.config_parameter'].sudo()
|
||||
authorization_code = self.google_drive_authorization_code
|
||||
refresh_token = False
|
||||
if authorization_code and authorization_code != ICP.get_param('google_drive_authorization_code'):
|
||||
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)
|
||||
|
||||
ICP.set_param('google_drive_authorization_code', authorization_code)
|
||||
ICP.set_param('google_drive_refresh_token', refresh_token)
|
||||
params.set_param('google_drive_authorization_code', authorization_code)
|
||||
params.set_param('google_drive_refresh_token', refresh_token)
|
||||
@@ -25,7 +25,7 @@ actions(Check in/Check out) performed by them.
|
||||
'report/hr_employee_badge.xml',
|
||||
'views/hr_department_view.xml',
|
||||
'views/hr_employee_view.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/attendance_config_settings_views.xml',
|
||||
],
|
||||
'demo': [
|
||||
'data/hr_attendance_demo.xml'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import attendance_config_settings
|
||||
from . import hr_attendance
|
||||
from . import hr_employee
|
||||
from . import res_config
|
||||
|
||||
@@ -39,7 +39,7 @@ This module also uses analytic accounting and is compatible with the invoice on
|
||||
'report/report_expense_sheet.xml',
|
||||
'views/hr_dashboard.xml',
|
||||
'views/hr_expense.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/hr_expense_config_settings_views.xml',
|
||||
'data/web_planner_data.xml',
|
||||
],
|
||||
'demo': ['data/hr_expense_demo.xml'],
|
||||
|
||||
@@ -4,5 +4,5 @@ from . import account_move_line
|
||||
from . import hr_department
|
||||
from . import hr_expense
|
||||
from . import product_template
|
||||
from . import res_config
|
||||
from . import hr_expense_config_settings
|
||||
from . import web_planner
|
||||
|
||||
@@ -309,7 +309,8 @@ class HrExpense(models.Model):
|
||||
@api.model
|
||||
def get_empty_list_help(self, help_message):
|
||||
if help_message:
|
||||
alias_record = self.env.ref('hr_expense.mail_alias_expense')
|
||||
use_mailgateway = self.env['ir.config_parameter'].sudo().get_param('hr_expense.use_mailgateway')
|
||||
alias_record = use_mailgateway and self.env.ref('hr_expense.mail_alias_expense') or False
|
||||
if alias_record and alias_record.alias_domain and alias_record.alias_name:
|
||||
link = "<a id='o_mail_test' href='mailto:%(email)s?subject=Lunch%%20with%%20customer%%3A%%20%%2412.32'>%(email)s</a>" % {
|
||||
'email': '%s@%s' % (alias_record.alias_name, alias_record.alias_domain)
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class HrExpenseConfigSettings(models.TransientModel):
|
||||
_name = 'hr.expense.config.settings'
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
alias_prefix = fields.Char('Default Alias Name for Expenses')
|
||||
alias_domain = fields.Char('Alias Domain', default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"))
|
||||
group_analytic_accounting = fields.Boolean(
|
||||
string='Analytic Accounting',
|
||||
implied_group='analytic.group_analytic_accounting')
|
||||
group_uom = fields.Boolean(
|
||||
string="Units of Measure",
|
||||
implied_group='product.group_uom')
|
||||
use_mailgateway = fields.Boolean(string='Let your employees record expenses by email')
|
||||
module_project = fields.Boolean(string="Project")
|
||||
module_sale = fields.Boolean(string="Customer Billing")
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(HrExpenseConfigSettings, self).get_values()
|
||||
res.update(
|
||||
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
|
||||
|
||||
@api.multi
|
||||
def set_values(self):
|
||||
super(HrExpenseConfigSettings, self).set_values()
|
||||
self.env.ref('hr_expense.mail_alias_expense').write({'alias_name': self.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):
|
||||
if not self.use_mailgateway:
|
||||
self.alias_prefix = False
|
||||
@@ -1,27 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import api, fields, models
|
||||
|
||||
class HrExpenseConfigSettings(models.TransientModel):
|
||||
_name = 'hr.expense.config.settings'
|
||||
_inherit = 'res.config.settings'
|
||||
|
||||
alias_prefix = fields.Char('Default Alias Name for Expenses')
|
||||
alias_domain = fields.Char('Alias Domain', default=lambda self: self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain"))
|
||||
group_analytic_accounting = fields.Boolean(string='Analytic Accounting',
|
||||
implied_group='analytic.group_analytic_accounting')
|
||||
group_uom = fields.Boolean("Units of Measure",
|
||||
implied_group='product.group_uom')
|
||||
default_alias_email = fields.Boolean(string='Let your employees record expenses by email', default_model='hr.expense.config.settings')
|
||||
module_project = fields.Boolean(string="Project")
|
||||
module_sale = fields.Boolean(string="Customer Billing")
|
||||
|
||||
@api.model
|
||||
def get_default_alias_prefix(self, fields):
|
||||
alias_name = self.env.ref('hr_expense.mail_alias_expense').alias_name
|
||||
return {'alias_prefix': alias_name}
|
||||
|
||||
@api.multi
|
||||
def set_default_alias_prefix(self):
|
||||
for record in self:
|
||||
self.env.ref('hr_expense.mail_alias_expense').write({'alias_name': record.alias_prefix})
|
||||
+4
-4
@@ -16,14 +16,14 @@
|
||||
<div class="row mt16 o_settings_container">
|
||||
<div class="col-xs-12 col-md-6 o_setting_box" title="You can setup a generic email alias to create incoming expenses easily. Write an email with the receipt in attachment to create an expense line in one click. If the mail subject contains the product's internal reference between brackets, the product will be set automatically. Type the expense amount in the mail subject to set it on the expense too.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="default_alias_email"/>
|
||||
<field name="use_mailgateway"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Emails" for="default_alias_email"/>
|
||||
<label string="Emails" for="use_mailgateway"/>
|
||||
<div class="text-muted">
|
||||
Let your employees record expenses by email
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': ['|', ('default_alias_email', '=', False), ('alias_domain', 'in', ['localhost', '', False])]}">
|
||||
<div class="content-group" attrs="{'invisible': ['|', ('use_mailgateway', '=', False), ('alias_domain', 'in', ['localhost', '', False])]}">
|
||||
<div class="mt16">
|
||||
<label string="Email Alias" class="o_light_label"/>
|
||||
<field name="alias_prefix" class="oe_inline"/>
|
||||
@@ -31,7 +31,7 @@
|
||||
<field name="alias_domain" class="oe_inline" readonly="1"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': ['|', ('default_alias_email', '=', False), ('alias_domain', 'not in', ['localhost', '', False])]}">
|
||||
<div class="content-group" attrs="{'invisible': ['|', ('use_mailgateway', '=', False), ('alias_domain', 'not in', ['localhost', '', False])]}">
|
||||
<div class="mt16">
|
||||
<button type="action" name="base_setup.action_general_configuration" icon="fa-arrow-right" string="Setup your domain alias" class="btn-link"/>
|
||||
</div>
|
||||
@@ -25,7 +25,7 @@ up a management by affair.
|
||||
'security/hr_timesheet_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'views/hr_timesheet_views.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/hr_timesheet_config_settings_views.xml',
|
||||
'views/project_views.xml',
|
||||
'report/hr_timesheet_report_view.xml',
|
||||
'report/report_timesheet_templates.xml',
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import hr_timesheet
|
||||
from . import res_config
|
||||
from . import hr_timesheet_config_settings
|
||||
from . import project
|
||||
|
||||
@@ -10,13 +10,14 @@ class FleetConfigSettings(models.TransientModel):
|
||||
|
||||
max_unused_cars = fields.Integer(string='Maximum unused cars')
|
||||
|
||||
@api.multi
|
||||
def set_default_max_unused_cars(self):
|
||||
def set_values(self):
|
||||
super(FleetConfigSettings, 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_default_max_unused_cars(self, fields):
|
||||
def get_values(self):
|
||||
res = super(FleetConfigSettings, self).get_values()
|
||||
params = self.env['ir.config_parameter'].sudo()
|
||||
max_unused_cars = params.get_param('l10n_be_hr_payroll_fleet.max_unused_cars', default=3)
|
||||
return dict(max_unused_cars=int(max_unused_cars))
|
||||
res.update(max_unused_cars=params.get_param('l10n_be_hr_payroll_fleet.max_unused_cars', default=3))
|
||||
return res
|
||||
|
||||
@@ -39,7 +39,7 @@ Here is how it works:
|
||||
'report/isr_report.xml',
|
||||
'views/res_bank_view.xml',
|
||||
'views/account_invoice_view.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/account_config_settings_views.xml',
|
||||
],
|
||||
|
||||
'demo': [
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import account_config_settings
|
||||
from . import account_invoice
|
||||
from . import mail_compose_message
|
||||
from . import mail_template
|
||||
from . import res_bank
|
||||
from . import res_company
|
||||
from . import res_config
|
||||
@@ -52,6 +52,5 @@
|
||||
|
||||
<record id="open_l10n_eu_service" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_eu_service"/>
|
||||
<field name="type">automatic</field>
|
||||
</record>
|
||||
</odoo>
|
||||
|
||||
@@ -40,6 +40,6 @@ With this module you will have:
|
||||
"data/account_tax_data.xml",
|
||||
"data/fiscal_position_data.xml",
|
||||
"data/account_chart_template_data.yml",
|
||||
"views/res_config_view.xml",
|
||||
"views/account_config_settings_views.xml",
|
||||
],
|
||||
}
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
# Copyright 2016 Vauxoo (https://www.vauxoo.com) <info@vauxoo.com>
|
||||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
from . import chart_template
|
||||
from . import account
|
||||
from . import res_config
|
||||
from . import account_config_settings
|
||||
from . import chart_template
|
||||
|
||||
+1
-1
@@ -4,6 +4,6 @@ from odoo import fields, models
|
||||
|
||||
|
||||
class AccountConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
_inherit = 'account.config.settings'
|
||||
|
||||
module_l10n_mx_edi = fields.Boolean('Mexican Electronic Invoicing')
|
||||
@@ -37,7 +37,7 @@ Main Features
|
||||
'views/mail_channel_views.xml',
|
||||
'views/mail_shortcode_views.xml',
|
||||
'views/mail_activity_views.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/base_config_settings_views.xml',
|
||||
'data/mail_data.xml',
|
||||
'data/mail_channel_data.xml',
|
||||
'data/mail_shortcode_data.xml',
|
||||
|
||||
@@ -14,7 +14,7 @@ from . import mail_template
|
||||
from . import mail_shortcode
|
||||
from . import res_partner
|
||||
from . import res_users
|
||||
from . import res_config
|
||||
from . import base_config_settings
|
||||
from . import update
|
||||
from . import ir_actions
|
||||
from . import ir_autovacuum
|
||||
|
||||
@@ -8,7 +8,7 @@ from werkzeug import urls
|
||||
from odoo import api, fields, models, tools
|
||||
|
||||
|
||||
class BaseConfiguration(models.TransientModel):
|
||||
class BaseConfigSettings(models.TransientModel):
|
||||
""" Inherit the base settings to add a counter of failed email + configure
|
||||
the alias domain. """
|
||||
_inherit = 'base.config.settings'
|
||||
@@ -18,14 +18,11 @@ class BaseConfiguration(models.TransientModel):
|
||||
"the Odoo server, enter the domain name here.")
|
||||
|
||||
@api.model
|
||||
def get_default_fail_counter(self, fields):
|
||||
previous_date = datetime.datetime.now() - datetime.timedelta(days=30)
|
||||
return {
|
||||
'fail_counter': self.env['mail.mail'].sudo().search_count([('date', '>=', previous_date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)), ('state', '=', 'exception')]),
|
||||
}
|
||||
def get_values(self):
|
||||
res = super(BaseConfigSettings, self).get_values()
|
||||
|
||||
previous_date = datetime.datetime.now() - datetime.timedelta(days=30)
|
||||
|
||||
@api.model
|
||||
def get_default_alias_domain(self, fields):
|
||||
alias_domain = self.env["ir.config_parameter"].get_param("mail.catchall.domain", default=None)
|
||||
if alias_domain is None:
|
||||
domain = self.env["ir.config_parameter"].get_param("web.base.url")
|
||||
@@ -33,9 +30,16 @@ class BaseConfiguration(models.TransientModel):
|
||||
alias_domain = urls.url_parse(domain).host
|
||||
except Exception:
|
||||
pass
|
||||
return {'alias_domain': alias_domain or False}
|
||||
|
||||
@api.multi
|
||||
def set_alias_domain(self):
|
||||
for record in self:
|
||||
self.env['ir.config_parameter'].set_param("mail.catchall.domain", record.alias_domain or '')
|
||||
res.update(
|
||||
fail_counter=self.env['mail.mail'].sudo().search_count([
|
||||
('date', '>=', previous_date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)),
|
||||
('state', '=', 'exception')]),
|
||||
alias_domain=alias_domain or False,
|
||||
)
|
||||
|
||||
return res
|
||||
|
||||
def set_values(self):
|
||||
super(BaseConfigSettings, self).set_values()
|
||||
self.env['ir.config_parameter'].set_param("mail.catchall.domain", self.alias_domain or '')
|
||||
@@ -30,7 +30,7 @@ professional emails and reuse templates in a few clicks.
|
||||
'views/link_tracker_views.xml',
|
||||
'views/mass_mailing_template.xml',
|
||||
'views/mass_mailing_views.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/mass_mailing_config_settings_views.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'views/editor_field_html.xml',
|
||||
'views/themes_templates.xml',
|
||||
|
||||
@@ -5,6 +5,6 @@ from . import mass_mailing
|
||||
from . import mass_mailing_stats
|
||||
from . import mail_mail
|
||||
from . import mail_thread
|
||||
from . import res_config
|
||||
from . import mass_mailing_config_settings
|
||||
from . import mass_mailing_report
|
||||
from . import link_tracker
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class MrpConfigSettings(models.TransientModel):
|
||||
@@ -11,7 +11,7 @@ class MrpConfigSettings(models.TransientModel):
|
||||
company_id = fields.Many2one('res.company', string='Company', required=True,
|
||||
default=lambda self: self.env.user.company_id)
|
||||
manufacturing_lead = fields.Float(related='company_id.manufacturing_lead', string="Manufacturing Lead Time")
|
||||
default_use_manufacturing_lead = fields.Boolean(string="Default Manufacturing Lead Time", default_model='mrp.config.settings')
|
||||
use_manufacturing_lead = fields.Boolean(string="Default Manufacturing Lead Time", oldname='default_use_manufacturing_lead')
|
||||
group_product_variant = fields.Boolean("Attributes & Variants",
|
||||
implied_group='product.group_product_variant')
|
||||
module_mrp_byproduct = fields.Boolean("By-Products")
|
||||
@@ -22,3 +22,21 @@ class MrpConfigSettings(models.TransientModel):
|
||||
group_mrp_routings = fields.Boolean("Work Orders",
|
||||
implied_group='mrp.group_mrp_routings')
|
||||
module_mrp_repair = fields.Boolean("Repair")
|
||||
|
||||
@api.model
|
||||
def get_values(self):
|
||||
res = super(MrpConfigSettings, 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(MrpConfigSettings, 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:
|
||||
self.manufacturing_lead = 0.0
|
||||
@@ -130,15 +130,15 @@
|
||||
</div>
|
||||
<div class="col-md-6 col-xs-12 o_setting_box" id="security_lead_time">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="default_use_manufacturing_lead"/>
|
||||
<field name="use_manufacturing_lead"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label string="Security Lead Time" for="default_use_manufacturing_lead"/>
|
||||
<label string="Security Lead Time" for="use_manufacturing_lead"/>
|
||||
<span class="fa fa-lg fa-building-o" title="Values set here are company-specific." groups="base.group_multi_company"/>
|
||||
<div class="text-muted">
|
||||
Schedule manufacturing orders earlier to avoid delays
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('default_use_manufacturing_lead','=',False)]}">
|
||||
<div class="content-group" attrs="{'invisible': [('use_manufacturing_lead','=',False)]}">
|
||||
<div class="mt16" >
|
||||
Move forward deadline start dates by
|
||||
<field name="manufacturing_lead" class="oe_inline"/> days
|
||||
|
||||
@@ -16,7 +16,7 @@ pads (by default, http://etherpad.com/).
|
||||
'depends': ['web', 'base_setup'],
|
||||
'data': [
|
||||
'views/pad.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/base_config_settings_views.xml',
|
||||
],
|
||||
'demo': ['data/pad_demo.xml'],
|
||||
'web': True,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import base_config_settings
|
||||
from . import pad
|
||||
from . import res_company
|
||||
from . import res_config
|
||||
|
||||
@@ -56,7 +56,7 @@ Main Features
|
||||
'views/account_statement_report.xml',
|
||||
'views/res_users_view.xml',
|
||||
'views/res_partner_view.xml',
|
||||
'views/res_config_view.xml',
|
||||
'views/pos_config_settings_views.xml',
|
||||
'views/report_statement.xml',
|
||||
'views/report_userlabel.xml',
|
||||
'views/report_saledetails.xml',
|
||||
|
||||
@@ -6,9 +6,9 @@ from . import account_journal
|
||||
from . import barcode_rule
|
||||
from . import pos_category
|
||||
from . import pos_config
|
||||
from . import pos_config_settings
|
||||
from . import pos_order
|
||||
from . import pos_session
|
||||
from . import product
|
||||
from . import res_config
|
||||
from . import res_partner
|
||||
from . import res_users
|
||||
|
||||
+26
-12
@@ -3,7 +3,7 @@
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class PosConfiguration(models.TransientModel):
|
||||
class PosConfigSettings(models.TransientModel):
|
||||
_inherit = 'res.config.settings'
|
||||
_name = 'pos.config.settings'
|
||||
|
||||
@@ -17,11 +17,12 @@ class PosConfiguration(models.TransientModel):
|
||||
implied_group='product.group_sale_pricelist',
|
||||
help="""Allows to manage different prices based on rules per category of customers.
|
||||
Example: 10% for retailers, promotion of 5 EUR on this product, etc.""")
|
||||
default_sale_price = fields.Boolean("A single sale price per product", default_model='pos.config.settings')
|
||||
default_pricelist_setting = fields.Selection([
|
||||
use_pos_sale_price = fields.Boolean("A single sale price per product", oldname='default_sale_price')
|
||||
pos_pricelist_setting = fields.Selection([
|
||||
('percentage', 'Multiple prices per product (e.g. quantity, shop-specific)'),
|
||||
('formula', 'Price computed from formulas (discounts, margins, rounding)')
|
||||
], string="Multiple Prices per Products", default_model='pos.config.settings')
|
||||
], string="Multiple Prices per Products",
|
||||
oldname='default_pricelist_setting')
|
||||
module_pos_restaurant = fields.Boolean(string="Restaurant")
|
||||
module_pos_loyalty = fields.Boolean(string="Loyalty Program")
|
||||
module_pos_discount = fields.Boolean(string="Global Discounts")
|
||||
@@ -29,22 +30,22 @@ class PosConfiguration(models.TransientModel):
|
||||
module_pos_reprint = fields.Boolean(string="Reprint Receipt")
|
||||
module_pos_data_drinks = fields.Boolean(string="Import common drinks data")
|
||||
|
||||
@api.onchange('default_sale_price')
|
||||
@api.onchange('use_pos_sale_price')
|
||||
def _onchange_fix_sale_price(self):
|
||||
if not self.default_sale_price:
|
||||
self.default_pricelist_setting = False
|
||||
if self.default_sale_price and not self.default_pricelist_setting:
|
||||
self.default_pricelist_setting = 'percentage'
|
||||
if not self.use_pos_sale_price:
|
||||
self.pos_pricelist_setting = False
|
||||
if self.use_pos_sale_price and not self.pos_pricelist_setting:
|
||||
self.pos_pricelist_setting = 'percentage'
|
||||
|
||||
@api.onchange('default_pricelist_setting')
|
||||
@api.onchange('pos_pricelist_setting')
|
||||
def _onchange_sale_price(self):
|
||||
if self.default_pricelist_setting == 'percentage':
|
||||
if self.pos_pricelist_setting == 'percentage':
|
||||
self.update({
|
||||
'group_product_pricelist': True,
|
||||
'group_sale_pricelist': True,
|
||||
'group_pricelist_item': False,
|
||||
})
|
||||
elif self.default_pricelist_setting == 'formula':
|
||||
elif self.pos_pricelist_setting == 'formula':
|
||||
self.update({
|
||||
'group_product_pricelist': False,
|
||||
'group_sale_pricelist': True,
|
||||
@@ -56,3 +57,16 @@ class PosConfiguration(models.TransientModel):
|
||||
'group_sale_pricelist': False,
|
||||
'group_pricelist_item': False,
|
||||
})
|
||||
|
||||
def get_values(self):
|
||||
res = super(PosConfigSettings, self).get_values()
|
||||
res.update(
|
||||
use_pos_sale_price=self.env['ir.config_parameter'].sudo().get_param('pos.use_pos_sale_price'),
|
||||
pos_pricelist_setting=self.env['ir.config_parameter'].sudo().get_param('pos.pos_pricelist_setting'),
|
||||
)
|
||||
return res
|
||||
|
||||
def set_values(self):
|
||||
super(PosConfigSettings, self).set_values()
|
||||
self.env['ir.config_parameter'].sudo().set_param('pos.use_pos_sale_price', self.use_pos_sale_price)
|
||||
self.env['ir.config_parameter'].sudo().set_param('pos.pos_pricelist_setting', self.pos_pricelist_setting)
|
||||
+5
-5
@@ -55,23 +55,23 @@
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6 o_setting_box" title="There are two ways to manage pricelists: 1) Multiple prices per product (e.g. quantity, shop-specific) : must be set in the Sales tab of the product detail form. 2) Price computed from formulas (discounts, margins, rounding) : must be set in the pricelist form.">
|
||||
<div class="o_setting_left_pane">
|
||||
<field name="default_sale_price"/>
|
||||
<field name="use_pos_sale_price"/>
|
||||
</div>
|
||||
<div class="o_setting_right_pane">
|
||||
<label for="default_pricelist_setting"/>
|
||||
<label for="pos_pricelist_setting"/>
|
||||
<div class="text-muted">
|
||||
Set shop-specific prices, seasonal discounts, etc.
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('default_sale_price','=',False)]}">
|
||||
<div class="content-group" attrs="{'invisible': [('use_pos_sale_price','=',False)]}">
|
||||
<div class="mt16">
|
||||
<field name="group_product_pricelist" invisible="1"/>
|
||||
<field name="group_sale_pricelist" invisible="1"/>
|
||||
<field name="group_pricelist_item" invisible="1"/>
|
||||
<field name="default_pricelist_setting" widget="radio" class="o_light_label"/>
|
||||
<field name="pos_pricelist_setting" widget="radio" class="o_light_label"/>
|
||||
</div>
|
||||
<div>
|
||||
<button name="%(product.product_pricelist_action2)d" icon="fa-arrow-right" type="action"
|
||||
string="Pricelists" attrs="{'invisible': [('default_pricelist_setting', '=', False)]}" class="btn-link"/>
|
||||
string="Pricelists" attrs="{'invisible': [('pos_pricelist_setting', '=', False)]}" class="btn-link"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -14,14 +14,15 @@ class BaseConfigSettings(models.TransientModel):
|
||||
" * Unchecked : Each company can see only its product (product where company is defined). Product not related to a company are visible for all companies.")
|
||||
|
||||
@api.model
|
||||
def get_default_company_share_product(self, fields):
|
||||
def get_values(self):
|
||||
res = super(BaseConfigSettings, self).get_values()
|
||||
product_rule = self.env.ref('product.product_comp_rule')
|
||||
return {
|
||||
'company_share_product': not bool(product_rule.active)
|
||||
}
|
||||
res.update(
|
||||
company_share_product=not bool(product_rule.active),
|
||||
)
|
||||
return res
|
||||
|
||||
@api.multi
|
||||
def set_auth_company_share_product(self):
|
||||
self.ensure_one()
|
||||
def set_values(self):
|
||||
super(BaseConfigSettings, self).set_values()
|
||||
product_rule = self.env.ref('product.product_comp_rule')
|
||||
product_rule.write({'active': not bool(self.company_share_product)})
|
||||
|
||||
@@ -40,7 +40,7 @@ Dashboard / Reports for Project Management will include:
|
||||
'report/project_report_views.xml',
|
||||
'views/project_views.xml',
|
||||
'views/res_partner_views.xml',
|
||||
'views/res_config_views.xml',
|
||||
'views/project_config_settings_views.xml',
|
||||
'views/project_templates.xml',
|
||||
'data/web_planner_data.xml',
|
||||
'data/project_mail_template_data.xml',
|
||||
|
||||
@@ -18,10 +18,6 @@
|
||||
<field name="object">project.task</field>
|
||||
</record>
|
||||
|
||||
<!-- alias domain: project.config.settings -->
|
||||
<function id="default_alias_domain_project" model="ir.values" name="set_default" eval="('project.config.settings', 'generate_project_alias', 1)"/>
|
||||
|
||||
|
||||
<!-- sale_timesheet and project define the same field without depending on each, which causes the field to be deleted when the module that created it
|
||||
is deleted. To avoid this, we create xmlids manually for this field in both modules to prevent accidental deletion. To fix in saas-7 by moving the field definition-->
|
||||
<record id="duplicate_field_xmlid" model="ir.model.data">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import project
|
||||
from . import project_config_settings
|
||||
from . import res_company
|
||||
from . import res_partner
|
||||
from . import res_config
|
||||
from . import web_planner
|
||||
|
||||
@@ -252,9 +252,6 @@ class Project(models.Model):
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
ir_values = self.env['ir.values'].get_default('project.config.settings', 'generate_project_alias')
|
||||
if ir_values:
|
||||
vals['alias_name'] = vals.get('alias_name') or vals.get('name')
|
||||
# Prevent double project creation when 'use_tasks' is checked
|
||||
self = self.with_context(project_creation_in_progress=True, mail_create_nosubscribe=True)
|
||||
project = super(Project, self).create(vals)
|
||||
|
||||
-12
@@ -14,11 +14,6 @@ class ProjectConfiguration(models.TransientModel):
|
||||
module_hr_timesheet = fields.Boolean("Timesheets")
|
||||
module_project_timesheet_synchro = fields.Boolean("Awesome Timesheet")
|
||||
module_rating_project = fields.Boolean(string="Rating on Tasks")
|
||||
generate_project_alias = fields.Selection([
|
||||
(0, "Do not create an email alias automatically"),
|
||||
(1, "Automatically generate an email alias at the project creation")
|
||||
], string="Project Alias",
|
||||
help="Odoo will generate an email alias at the project creation from project name.")
|
||||
module_project_forecast = fields.Boolean(string="Forecasts")
|
||||
module_hr_holidays = fields.Boolean("Leave Management")
|
||||
module_hr_timesheet_attendance = fields.Boolean("Attendances")
|
||||
@@ -26,10 +21,3 @@ class ProjectConfiguration(models.TransientModel):
|
||||
module_hr_expense = fields.Boolean("Expenses")
|
||||
module_project_issue = fields.Boolean("Issue Tracking")
|
||||
group_subtask_project = fields.Boolean("Sub-tasks", implied_group="project.group_subtask_project")
|
||||
|
||||
@api.multi
|
||||
def set_default_generate_project_alias(self):
|
||||
check = self.env.user.has_group('base.group_system')
|
||||
Values = check and self.env['ir.values'].sudo() or self.env['ir.values']
|
||||
for config in self:
|
||||
Values.set_default('project.config.settings', 'generate_project_alias', config.generate_project_alias)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user