diff --git a/addons/account/models/company.py b/addons/account/models/company.py
index 79a1a53fc78..d34d04a798e 100644
--- a/addons/account/models/company.py
+++ b/addons/account/models/company.py
@@ -6,6 +6,7 @@ from dateutil.relativedelta import relativedelta
from odoo import fields, models, api, _
from odoo.exceptions import ValidationError, UserError, RedirectWarning
+from odoo.tools.mail import is_html_empty
from odoo.tools.misc import format_date
from odoo.tools.float_utils import float_round, float_is_zero
from odoo.tests.common import Form
@@ -104,11 +105,10 @@ class ResCompany(models.Model):
account_invoice_onboarding_state = fields.Selection(DASHBOARD_ONBOARDING_STATES, string="State of the account invoice onboarding panel", default='not_done')
account_dashboard_onboarding_state = fields.Selection(DASHBOARD_ONBOARDING_STATES, string="State of the account dashboard onboarding panel", default='not_done')
invoice_terms = fields.Html(string='Default Terms and Conditions', translate=True)
- terms_type = fields.Selection([('plain', 'Terms as Notes'), ('html', 'Terms as Web Page')],
+ terms_type = fields.Selection([('plain', 'Add a Note'), ('html', 'Add a link to a Web Page')],
string='Terms & Conditions format', default='plain')
invoice_terms_html = fields.Html(string='Default Terms and Conditions as a Web page', translate=True,
- default="""
Terms & Conditions
-
Your conditions...
""")
+ compute='_compute_invoice_terms_html', store=True, readonly=False)
account_setup_bill_state = fields.Selection(ONBOARDING_STEP_STATES, string="State of the onboarding bill step", default='not_done')
@@ -183,6 +183,15 @@ class ResCompany(models.Model):
foreign_vat_fpos = self.env['account.fiscal.position'].search([('company_id', '=', record.id), ('foreign_vat', '!=', False)])
record.account_enabled_tax_country_ids = foreign_vat_fpos.country_id + record.account_fiscal_country_id
+ @api.depends('terms_type')
+ def _compute_invoice_terms_html(self):
+ term_template = self.env.ref("account.account_default_terms_and_conditions", False)
+ if not term_template:
+ return
+
+ for company in self.filtered(lambda company: is_html_empty(company.invoice_terms_html) and company.terms_type == 'html'):
+ company.invoice_terms_html = term_template._render({'company_name': company.name, 'company_country': company.country_id.name}, engine='ir.qweb')
+
def get_and_update_account_invoice_onboarding_state(self):
""" This method is called on the controller rendering method and ensures that the animations
are displayed only one time. """
diff --git a/addons/account/models/res_config_settings.py b/addons/account/models/res_config_settings.py
index a2d788aa9af..42e5c692f19 100644
--- a/addons/account/models/res_config_settings.py
+++ b/addons/account/models/res_config_settings.py
@@ -200,3 +200,15 @@ class ResConfigSettings(models.TransientModel):
# We display the preview button only if the terms_type is html in the setting but also on the company
# to avoid landing on an error page (see terms.py controller)
setting.preview_ready = self.env.company.terms_type == 'html' and setting.terms_type == 'html'
+
+ def action_update_terms(self):
+ self.ensure_one()
+ return {
+ 'name': _('Update Terms & Conditions'),
+ 'type': 'ir.actions.act_window',
+ 'view_mode': 'form',
+ 'res_model': 'res.company',
+ 'view_id': self.env.ref("account.res_company_view_form_terms", False).id,
+ 'target': 'new',
+ 'res_id': self.company_id.id,
+ }
diff --git a/addons/account/views/res_company_views.xml b/addons/account/views/res_company_views.xml
index cbb4d9ee470..c8d06842747 100644
--- a/addons/account/views/res_company_views.xml
+++ b/addons/account/views/res_company_views.xml
@@ -11,4 +11,22 @@
+
+
+ res.company.view.form.terms
+ res.company
+ 1000
+
+
+
+
+
diff --git a/addons/account/views/res_config_settings_views.xml b/addons/account/views/res_config_settings_views.xml
index f9f7c9ab5a7..54090368158 100644
--- a/addons/account/views/res_config_settings_views.xml
+++ b/addons/account/views/res_config_settings_views.xml
@@ -288,24 +288,23 @@
- Show standard terms & conditions on invoices/orders
+ Add your terms & conditions at the bottom of invoices/orders/quotations
You should update this document to reflect your T&C.
+
Below text serves as a suggestion and doesn’t engage Odoo S.A. responsibility.
+
+
+ The client explicitly waives its own standard terms and conditions, even if these were drawn up after these standard terms and conditions of sale. In order to be valid, any derogation must be expressly agreed to in advance in writing.
+
+
+ Our invoices are payable within 21 working days, unless another payment timeframe is indicated on either the invoice or the order. In the event of non-payment by the due date, reserves the right to request a fixed interest payment amounting to 10% of the sum remaining due. will be authorized to suspend any provision of services without prior warning in the event of late payment.
+
+
+ If a payment is still outstanding more than sixty (60) days after the due payment date, reserves the right to call on the services of a debt recovery company. All legal expenses will be payable by the client.
+
+
+ Certain countries apply withholding at source on the amount of invoices, in accordance with their internal legislation. Any withholding at source will be paid by the client to the tax authorities. Under no circumstances can become involved in costs related to a country's legislation. The amount of the invoice will therefore be due to in its entirety and does not include any costs relating to the legislation of the country in which the client is located.
+
+
+ undertakes to do its best to supply performant services in due time in accordance with the agreed timeframes. However, none of its obligations can be considered as being an obligation to achieve results. cannot under any circumstances, be required by the client to appear as a third party in the context of any claim for damages filed against the client by an end consumer.
+
+
+ In order for it to be admissible, must be notified of any claim by means of a letter sent by recorded delivery to its registered office within 8 days of the delivery of the goods or the provision of the services.
+
+
+ All our contractual relations will be governed exclusively by law.
+
+
+
+
+
diff --git a/addons/website_sale/__init__.py b/addons/website_sale/__init__.py
index d809777293d..f90462f5428 100644
--- a/addons/website_sale/__init__.py
+++ b/addons/website_sale/__init__.py
@@ -6,7 +6,7 @@ from . import models
from . import wizard
from . import report
-def pre_init_hook(cr):
+def _post_init_hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
terms_conditions = env['ir.config_parameter'].get_param('account.use_invoice_terms')
if not terms_conditions:
diff --git a/addons/website_sale/__manifest__.py b/addons/website_sale/__manifest__.py
index 74e2021d53d..712f2e21937 100644
--- a/addons/website_sale/__manifest__.py
+++ b/addons/website_sale/__manifest__.py
@@ -36,7 +36,7 @@
],
'installable': True,
'application': True,
- 'pre_init_hook': 'pre_init_hook',
+ 'post_init_hook': '_post_init_hook',
'uninstall_hook': 'uninstall_hook',
'assets': {
'web.assets_frontend': [
diff --git a/addons/website_sale/models/res_config_settings.py b/addons/website_sale/models/res_config_settings.py
index e516981d74c..8827ec8ad73 100644
--- a/addons/website_sale/models/res_config_settings.py
+++ b/addons/website_sale/models/res_config_settings.py
@@ -30,6 +30,12 @@ class ResConfigSettings(models.TransientModel):
cart_abandoned_delay = fields.Float("Abandoned Delay", help="Number of hours after which the cart is considered abandoned.",
related='website_id.cart_abandoned_delay', readonly=False)
cart_add_on_page = fields.Boolean("Stay on page after adding to cart", related='website_id.cart_add_on_page', readonly=False)
+ terms_url = fields.Char(compute='_compute_terms_url', string="URL", help="A preview will be available at this URL.")
+
+ @api.depends('website_id')
+ def _compute_terms_url(self):
+ for record in self:
+ record.terms_url = '%s/terms' % record.website_id.get_base_url()
@api.model
def get_values(self):
@@ -70,3 +76,11 @@ class ResConfigSettings(models.TransientModel):
self.update({
'group_product_pricelist': True,
})
+
+ def action_update_terms(self):
+ self.ensure_one()
+ return {
+ 'type': 'ir.actions.act_url',
+ 'url': '/terms?enable_editor=1',
+ 'target': 'self',
+ }
diff --git a/addons/website_sale/views/res_config_settings_views.xml b/addons/website_sale/views/res_config_settings_views.xml
index 955da6d2af4..c2d093e879d 100644
--- a/addons/website_sale/views/res_config_settings_views.xml
+++ b/addons/website_sale/views/res_config_settings_views.xml
@@ -1,6 +1,23 @@
+
+ res.config.settings.view.form.inherit.account.web.terms
+ res.config.settings
+
+
+
+
+