[IMP] account,website_sale: improve the UX of terms and conditions
Purpose of the task is, to use our awesome website builder instead of pad when creating a website page for terms & condition. Also suggest default T&C to save user time when user enable the feature So in this commit did the below changes: * Added new indicational text below "Terms as note" & "Terms as web page" * After enabling "Term as web page', user should be able to see the term page url * For Terms editing: - User that have 'website' or 'ecommerce' module should edit the page directly using the website builder with link "edit in website builder" link. - User that don't have nor website not ecommerce module should update the text in the pad but in a pop-up window. * Also added the dynamic default term for company when term type is html. PS: changed website_sale pre_init_hook to post_init_hook because invoice_terms_html is compute field which depends on term_type so when term_type is changed from init_hook it will give the key error for the invoice_terms_html as it's not loaded to registry. closes odoo/odoo#68225 Taskid: 2414659 Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
This commit is contained in:
@@ -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="""<h1 style="text-align: center; ">Terms & Conditions</h1>
|
||||
<p>Your conditions...</p>""")
|
||||
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. """
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -11,4 +11,22 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_company_view_form_terms" model="ir.ui.view">
|
||||
<field name="name">res.company.view.form.terms</field>
|
||||
<field name="model">res.company</field>
|
||||
<field name="priority">1000</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<group>
|
||||
<field name="invoice_terms_html" class="oe_account_terms" nolabel="1"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button string="Save" special="save" class="btn-primary"/>
|
||||
<button string="Discard" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -288,24 +288,23 @@
|
||||
<label for="use_invoice_terms"/>
|
||||
<span class="fa fa-lg fa-building-o" title="Values set here are company-specific." aria-label="Values set here are company-specific." groups="base.group_multi_company" role="img"/>
|
||||
<div class="text-muted">
|
||||
Show standard terms & conditions on invoices/orders
|
||||
Add your terms & conditions at the bottom of invoices/orders/quotations
|
||||
</div>
|
||||
<div class="content-group" attrs="{'invisible': [('use_invoice_terms','=',False)]}">
|
||||
<div class="mt16">
|
||||
<field name="terms_type" class="o_light_label" widget="radio"/>
|
||||
<div class="d-flex">
|
||||
<div>
|
||||
<field name="invoice_terms"
|
||||
attrs="{'invisible': [('terms_type', '=', 'html')]}"
|
||||
class="oe_account_terms"
|
||||
placeholder="Insert your terms & conditions here..."/>
|
||||
<field name="invoice_terms_html"
|
||||
attrs="{'invisible': [('terms_type', '=', 'plain')]}"
|
||||
class="oe_account_terms"
|
||||
class="oe_account_terms mt-5 w-100"
|
||||
placeholder="Insert your terms & conditions here..."/>
|
||||
</div>
|
||||
<div class="mt8" attrs="{'invisible': [('terms_type', '!=', 'html')]}">
|
||||
<button name="action_update_terms" icon="fa-arrow-right" type="object" string="Update Terms" class="btn-link"/>
|
||||
</div>
|
||||
<field name="preview_ready" invisible="1"/>
|
||||
<div attrs="{'invisible': [('preview_ready', '=', False)]}">
|
||||
<a href="/terms">
|
||||
<div class="mt4 ml-1" attrs="{'invisible': [('preview_ready', '=', False)]}">
|
||||
<a class="btn-link" href="/terms" role="button">
|
||||
<i class="fa fa-arrow-right"></i>
|
||||
Preview
|
||||
</a>
|
||||
|
||||
@@ -23,4 +23,36 @@
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="account_default_terms_and_conditions">
|
||||
<div>
|
||||
<h1>STANDARD TERMS AND CONDITIONS OF SALE</h1>
|
||||
<p>You should update this document to reflect your T&C.</p>
|
||||
<p>Below text serves as a suggestion and doesn’t engage Odoo S.A. responsibility.</p>
|
||||
<ol>
|
||||
<li>
|
||||
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.
|
||||
</li>
|
||||
<li>
|
||||
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, <t t-esc="company_name"/> reserves the right to request a fixed interest payment amounting to 10% of the sum remaining due. <t t-esc="company_name"/> will be authorized to suspend any provision of services without prior warning in the event of late payment.
|
||||
</li>
|
||||
<li>
|
||||
If a payment is still outstanding more than sixty (60) days after the due payment date, <t t-esc="company_name"/> reserves the right to call on the services of a debt recovery company. All legal expenses will be payable by the client.
|
||||
</li>
|
||||
<li>
|
||||
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 <t t-esc="company_name"/> become involved in costs related to a country's legislation. The amount of the invoice will therefore be due to <t t-esc="company_name"/> in its entirety and does not include any costs relating to the legislation of the country in which the client is located.
|
||||
</li>
|
||||
<li>
|
||||
<t t-esc="company_name"/> 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. <t t-esc="company_name"/> 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.
|
||||
</li>
|
||||
<li>
|
||||
In order for it to be admissible, <t t-esc="company_name"/> 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.
|
||||
</li>
|
||||
<li>
|
||||
All our contractual relations will be governed exclusively by <t t-esc="company_country"/> law.
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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': [
|
||||
|
||||
@@ -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',
|
||||
}
|
||||
|
||||
@@ -1,6 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="res_config_settings_view_form_web_terms" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.account.web.terms</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="account.res_config_settings_view_form"/>
|
||||
<field name="groups_id" eval="[Command.link(ref('website.group_website_designer'))]"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_update_terms']" position="replace">
|
||||
<div class="mt8" attrs="{'invisible': [('terms_type', '!=', 'html')]}">
|
||||
<strong class="align-top">URL: </strong><field name="terms_url"/>
|
||||
<div>
|
||||
<button name='action_update_terms' icon="fa-arrow-right" type="object" string="Edit in Website Builder" class="btn-link"/>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">res.config.settings.view.form.inherit.website.sale</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
|
||||
Reference in New Issue
Block a user