summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Delavallée <tde@openerp.com>2014-01-22 18:13:21 +0100
committerThibault Delavallée <tde@openerp.com>2014-01-22 18:13:21 +0100
commit46c55500ffe01dfa2e320bbd72c6d4ee3d908e7d (patch)
tree9a1c4ccfa528ceb274d81bf53e4cc4498d611a55
parent055932fc6a4cdc6dddb4f2ad75c50e554bb55548 (diff)
parentf70e54255641f4d3d61777501b20b0f8c7a1fb77 (diff)
[MERGE] Sync with website-al
bzr revid: tde@openerp.com-20140122171321-6r2q42p7ebfv3kb9
-rw-r--r--addons/auth_oauth/static/src/js/auth_oauth.js3
-rw-r--r--addons/auth_oauth_signup/static/src/js/auth_oauth_signup.js2
-rw-r--r--addons/auth_openid/static/src/js/auth_openid.js2
-rw-r--r--addons/auth_signup/__openerp__.py3
-rw-r--r--addons/auth_signup/controllers/main.py107
-rw-r--r--addons/auth_signup/res_users.py15
-rw-r--r--addons/auth_signup/static/src/js/auth_signup.js187
-rw-r--r--addons/auth_signup/static/src/xml/auth_signup.xml39
-rw-r--r--addons/auth_signup/views/auth_signup_login.xml90
-rw-r--r--addons/edi/static/src/js/edi.js15
-rw-r--r--addons/product/product.py17
-rw-r--r--addons/website/controllers/main.py10
-rw-r--r--addons/website/static/src/css/website.css5
-rw-r--r--addons/website/static/src/css/website.sass3
-rw-r--r--addons/website/static/src/js/website.ace.js31
-rw-r--r--addons/website/static/src/js/website.editor.js2
-rw-r--r--addons/website/static/src/js/website.js2
-rw-r--r--addons/website/static/src/js/website.tour.js87
-rw-r--r--addons/website/tests/test_requests.py2
-rw-r--r--addons/website/tests/test_ui.py4
-rw-r--r--addons/website/tests/ui_suite/ui_test_runner.js13
-rw-r--r--addons/website/views/website_templates.xml10
-rw-r--r--addons/website_blog/tests/test_ui.py4
-rw-r--r--addons/website_event/tests/test_ui.py4
-rw-r--r--addons/website_sale/controllers/main.py9
-rw-r--r--addons/website_sale/models/website.py9
-rw-r--r--addons/website_sale/static/src/js/website.tour.shop.js3
-rw-r--r--addons/website_sale/tests/test_ui.py2
-rw-r--r--addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js10
-rw-r--r--addons/website_sale/views/website_sale.xml30
30 files changed, 340 insertions, 380 deletions
diff --git a/addons/auth_oauth/static/src/js/auth_oauth.js b/addons/auth_oauth/static/src/js/auth_oauth.js
index 5046469a5dc..a4295877e76 100644
--- a/addons/auth_oauth/static/src/js/auth_oauth.js
+++ b/addons/auth_oauth/static/src/js/auth_oauth.js
@@ -3,6 +3,7 @@ openerp.auth_oauth = function(instance) {
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
+ /* TODO: make this a server side controller
instance.web.Login.include({
start: function(parent, params) {
var self = this;
@@ -76,5 +77,5 @@ openerp.auth_oauth = function(instance) {
};
},
});
-
+ */
};
diff --git a/addons/auth_oauth_signup/static/src/js/auth_oauth_signup.js b/addons/auth_oauth_signup/static/src/js/auth_oauth_signup.js
index 6715943af9b..926fb607358 100644
--- a/addons/auth_oauth_signup/static/src/js/auth_oauth_signup.js
+++ b/addons/auth_oauth_signup/static/src/js/auth_oauth_signup.js
@@ -1,5 +1,6 @@
openerp.auth_oauth_signup = function(instance) {
+ /* TODO: make this a server side controller
// override Login._oauth_state to add the signup token in the state
instance.web.Login.include({
_oauth_state: function(provider) {
@@ -10,5 +11,6 @@ openerp.auth_oauth_signup = function(instance) {
return state;
},
});
+ */
};
diff --git a/addons/auth_openid/static/src/js/auth_openid.js b/addons/auth_openid/static/src/js/auth_openid.js
index ac2804cb130..a96346f4699 100644
--- a/addons/auth_openid/static/src/js/auth_openid.js
+++ b/addons/auth_openid/static/src/js/auth_openid.js
@@ -3,6 +3,7 @@ openerp.auth_openid = function(instance) {
var QWeb = instance.web.qweb;
+/* TODO: make this a server side controller
instance.web.Login = instance.web.Login.extend({
start: function() {
var self = this;
@@ -149,6 +150,7 @@ instance.web.Login = instance.web.Login.extend({
}
});
+*/
};
diff --git a/addons/auth_signup/__openerp__.py b/addons/auth_signup/__openerp__.py
index 08740962c59..50402207018 100644
--- a/addons/auth_signup/__openerp__.py
+++ b/addons/auth_signup/__openerp__.py
@@ -34,13 +34,14 @@ Allow users to sign up and reset their password
'depends': [
'base_setup',
'email_template',
+ 'web',
],
'data': [
'auth_signup_data.xml',
'res_config.xml',
'res_users_view.xml',
+ 'views/auth_signup_login.xml',
],
'js': ['static/src/js/auth_signup.js'],
- 'qweb': ['static/src/xml/auth_signup.xml'],
'bootstrap': True,
}
diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py
index a778cbcf061..650268755e5 100644
--- a/addons/auth_signup/controllers/main.py
+++ b/addons/auth_signup/controllers/main.py
@@ -21,64 +21,71 @@
import logging
import openerp
+import openerp.addons.web.controllers.main as webmain
from openerp import http
-from openerp.http import request
-from openerp.modules.registry import RegistryManager
-from ..res_users import SignupError
+from openerp.http import request, LazyResponse
+from openerp.tools.translate import _
_logger = logging.getLogger(__name__)
-class Controller(http.Controller):
+class Home(openerp.addons.web.controllers.main.Home):
- @http.route('/auth_signup/get_config', type='json', auth="none")
- def get_config(self, dbname):
- """ retrieve the module config (which features are enabled) for the login page """
- registry = RegistryManager.get(dbname)
- with registry.cursor() as cr:
- icp = registry.get('ir.config_parameter')
- config = {
- 'signup': icp.get_param(cr, openerp.SUPERUSER_ID, 'auth_signup.allow_uninvited') == 'True',
- 'reset_password': icp.get_param(cr, openerp.SUPERUSER_ID, 'auth_signup.reset_password') == 'True',
- }
- return config
+ @http.route()
+ def web_login(self, *args, **kw):
+ # TODO: ensure_db()
+ request.disable_db = False
- @http.route('/auth_signup/retrieve', type='json', auth="none")
- def retrieve(self, dbname, token):
- """ retrieve the user info (name, login or email) corresponding to a signup token """
- registry = RegistryManager.get(dbname)
- with registry.cursor() as cr:
- res_partner = registry.get('res.partner')
- user_info = res_partner.signup_retrieve_info(cr, openerp.SUPERUSER_ID, token)
- return user_info
+ mode = request.params.get('mode')
+ qcontext = request.params.copy()
+ response = webmain.render_bootstrap_template(request.session.db, 'auth_signup.signup', qcontext, lazy=True)
+ token = qcontext.get('token', None)
+ token_infos = None
+ if token:
+ try:
+ # retrieve the user info (name, login or email) corresponding to a signup token
+ res_partner = request.registry.get('res.partner')
+ token_infos = res_partner.signup_retrieve_info(request.cr, openerp.SUPERUSER_ID, token)
+ for k, v in token_infos.items():
+ qcontext.setdefault(k, v)
+ except:
+ qcontext['error'] = _("Invalid signup token")
+ response.params['template'] = 'web.login'
+ return response
- @http.route('/auth_signup/signup', type='json', auth="none")
- def signup(self, dbname, token, **values):
- """ sign up a user (new or existing)"""
- try:
- self._signup_with_values(dbname, token, values)
- except SignupError, e:
- return {'error': openerp.tools.exception_to_unicode(e)}
- return {}
+ # retrieve the module config (which features are enabled) for the login page
+ icp = request.registry.get('ir.config_parameter')
+ config = {
+ 'signup': icp.get_param(request.cr, openerp.SUPERUSER_ID, 'auth_signup.allow_uninvited') == 'True',
+ 'reset': icp.get_param(request.cr, openerp.SUPERUSER_ID, 'auth_signup.reset_password') == 'True',
+ }
+ qcontext.update(config)
- def _signup_with_values(self, dbname, token, values):
- registry = RegistryManager.get(dbname)
- with registry.cursor() as cr:
- res_users = registry.get('res.users')
- res_users.signup(cr, openerp.SUPERUSER_ID, values, token)
+ if 'error' in qcontext or mode not in ('reset', 'signup') or (not token and not config[mode]):
+ response = super(Home, self).web_login(*args, **kw)
+ if isinstance(response, LazyResponse):
+ response.params['values'].update(config)
+ return response
- @http.route('/auth_signup/reset_password', type='json', auth="none")
- def reset_password(self, dbname, login):
- """ retrieve user, and perform reset password """
- registry = RegistryManager.get(dbname)
- with registry.cursor() as cr:
- try:
- res_users = registry.get('res.users')
- res_users.reset_password(cr, openerp.SUPERUSER_ID, login)
- cr.commit()
- except Exception as e:
- # signup error
- _logger.exception('error when resetting password')
- raise(e)
- return True
+ if request.httprequest.method == 'GET':
+ if token_infos:
+ qcontext.update(token_infos)
+ else:
+ res_users = request.registry.get('res.users')
+ login = request.params.get('login')
+ if mode == 'reset' and not token:
+ try:
+ res_users.reset_password(request.cr, openerp.SUPERUSER_ID, login)
+ qcontext['message'] = _("An email has been sent with credentials to reset your password")
+ response.params['template'] = 'web.login'
+ except:
+ qcontext['error'] = _("Could not reset your password")
+ _logger.exception('error when resetting password')
+ else:
+ values = dict((key, qcontext.get(key)) for key in ('login', 'name', 'password'))
+ res_users.signup(request.cr, openerp.SUPERUSER_ID, values, token)
+ request.cr.commit()
+ return super(Home, self).web_login(*args, **kw)
+
+ return response
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py
index 669ea3a56a1..37ad9f68fe4 100644
--- a/addons/auth_signup/res_users.py
+++ b/addons/auth_signup/res_users.py
@@ -66,19 +66,20 @@ class res_partner(osv.Model):
self.signup_prepare(cr, uid, [partner.id], context=context)
partner.refresh()
- # the parameters to encode for the query and fragment part of url
- query = {'db': cr.dbname}
+ # the parameters to encode for the query
+ query = dict(db=cr.dbname)
signup_type = context.get('signup_force_type_in_url', partner.signup_type or '')
- fragment = {'action': action, 'type': signup_type}
+ if signup_type:
+ query['mode'] = signup_type
if partner.signup_token and signup_type:
- fragment['token'] = partner.signup_token
+ query['token'] = partner.signup_token
elif partner.user_ids:
- fragment['db'] = cr.dbname
- fragment['login'] = partner.user_ids[0].login
+ query['login'] = partner.user_ids[0].login
else:
continue # no signup token, no user, thus no signup url!
+ fragment = dict()
if view_type:
fragment['view_type'] = view_type
if menu_id:
@@ -88,7 +89,7 @@ class res_partner(osv.Model):
if res_id:
fragment['id'] = res_id
- res[partner.id] = urljoin(base_url, "?%s#%s" % (urlencode(query), urlencode(fragment)))
+ res[partner.id] = urljoin(base_url, "/web/login?%s#%s" % (urlencode(query), urlencode(fragment)))
return res
diff --git a/addons/auth_signup/static/src/js/auth_signup.js b/addons/auth_signup/static/src/js/auth_signup.js
index d9edb44d65f..a317440fd6b 100644
--- a/addons/auth_signup/static/src/js/auth_signup.js
+++ b/addons/auth_signup/static/src/js/auth_signup.js
@@ -1,186 +1,19 @@
openerp.auth_signup = function(instance) {
- instance.auth_signup = instance.auth_signup || {};
- var _t = instance.web._t;
-
- instance.web.Login.include({
- start: function() {
+ openerp.web.LoginForm.include({
+ start: function () {
var self = this;
- this.signup_enabled = false;
- this.reset_password_enabled = false;
- return this._super().always(function() {
-
- // Switches the login box to the select mode whith mode == [default|signup|reset]
- self.on('change:login_mode', self, function() {
- var mode = self.get('login_mode') || 'default';
- self.$('*[data-modes]').each(function() {
- var modes = $(this).data('modes').split(/\s+/);
- $(this).toggle(modes.indexOf(mode) > -1);
- });
- self.$('a.oe_signup_signup:visible').toggle(self.signup_enabled);
- self.$('a.oe_signup_reset_password:visible').toggle(self.reset_password_enabled);
- });
-
- // to switch between the signup and regular login form
- self.$('a.oe_signup_signup').click(function(ev) {
- self.set('login_mode', 'signup');
+ this.$el.on('submit', function () {
+ var password = self.get_password_field('password');
+ var confirm_password = self.get_password_field('confirm_password');
+ if (password && confirm_password && (password.value != confirm_password.value)) {
+ alert("Passwords do not match; please retype them.");
return false;
- });
- self.$('a.oe_signup_back').click(function(ev) {
- self.set('login_mode', 'default');
- delete self.params.token;
- return false;
- });
-
- var dbname = self.selected_db;
-
- // if there is an error message in params, show it then forget it
- if (self.params.error_message) {
- self.show_error(self.params.error_message);
- delete self.params.error_message;
- }
-
- if (dbname && self.params.login) {
- self.$("form input[name=login]").val(self.params.login);
- }
-
- // bind reset password link
- self.$('a.oe_signup_reset_password').click(self.do_reset_password);
-
- if (dbname) {
- self.rpc("/auth_signup/get_config", {dbname: dbname}).then(function(result) {
- self.signup_enabled = result.signup;
- self.reset_password_enabled = result.reset_password;
- if (!self.signup_enabled || self.$("form input[name=login]").val()){
- self.set('login_mode', self.params.type || 'default');
- } else {
- self.set('login_mode', 'signup');
- }
-
- // in case of a signup, retrieve the user information from the token
- if (self.params.token) {
- self.rpc("/auth_signup/retrieve", {dbname: dbname, token: self.params.token})
- .then(self.on_token_loaded, self.on_token_failed);
- }
-
- });
- } else {
- // TODO: support multiple database mode
- self.set('login_mode', self.params.type || 'default');
}
});
},
-
- on_token_loaded: function(result) {
- // select the right the database
- this.selected_db = result.db;
- this.on_db_loaded([result.db]);
- if (result.token) {
- // switch to signup mode, set user name and login
- this.set('login_mode', (this.params.type === 'reset' ? 'reset' : 'signup'));
- this.$("form input[name=name]").val(result.name).attr("readonly", "readonly");
- if (result.login) {
- this.$("form input[name=login]").val(result.login).attr("readonly", "readonly");
- } else {
- this.$("form input[name=login]").val(result.email);
- }
- } else {
- // remain in login mode, set login if present
- delete this.params.token;
- this.set('login_mode', 'default');
- this.$("form input[name=login]").val(result.login || "");
- }
- },
-
- on_token_failed: function(result, ev) {
- if (ev) {
- ev.preventDefault();
- }
- this.show_error(_t("Invalid signup token"));
- delete this.params.db;
- delete this.params.token;
- this.set('login_mode', 'default');
- },
-
- get_params: function(){
- // signup user (or reset password)
- var db = this.$("form [name=db]").val();
- var name = this.$("form input[name=name]").val();
- var login = this.$("form input[name=login]").val();
- var password = this.$("form input[name=password]").val();
- var confirm_password = this.$("form input[name=confirm_password]").val();
- if (!db) {
- this.do_warn(_t("Login"), _t("No database selected !"));
- return false;
- } else if (!name) {
- this.do_warn(_t("Login"), _t("Please enter a name."));
- return false;
- } else if (!login) {
- this.do_warn(_t("Login"), _t("Please enter a username."));
- return false;
- } else if (!password || !confirm_password) {
- this.do_warn(_t("Login"), _t("Please enter a password and confirm it."));
- return false;
- } else if (password !== confirm_password) {
- this.do_warn(_t("Login"), _t("Passwords do not match; please retype them."));
- return false;
- }
- var params = {
- dbname : db,
- token: this.params.token || "",
- name: name,
- login: login,
- password: password,
- };
- return params;
- },
-
- on_submit: function(ev) {
- if (ev) {
- ev.preventDefault();
- }
- var login_mode = this.get('login_mode');
- if (login_mode === 'signup' || login_mode === 'reset') {
- var params = this.get_params();
- if (_.isEmpty(params)){
- return false;
- }
- var self = this,
- super_ = this._super;
- this.rpc('/auth_signup/signup', params)
- .done(function(result) {
- if (result.error) {
- self.show_error(result.error);
- } else {
- super_.apply(self, [ev]);
- }
- });
- } else {
- // regular login
- this._super(ev);
- }
- },
-
- do_reset_password: function(ev) {
- if (ev) {
- ev.preventDefault();
- }
- var self = this;
- var db = this.$("form [name=db]").val();
- var login = this.$("form input[name=login]").val();
- if (!db) {
- this.do_warn(_t("Login"), _t("No database selected !"));
- return $.Deferred().reject();
- } else if (!login) {
- this.do_warn(_t("Login"), _t("Please enter a username or email address."));
- return $.Deferred().reject();
- }
- return self.rpc("/auth_signup/reset_password", { dbname: db, login: login }).done(function(result) {
- self.show_error(_t("An email has been sent with credentials to reset your password"));
- self.set('login_mode', 'default');
- }).fail(function(result, ev) {
- ev.preventDefault();
- self.show_error(result.message);
- });
+ get_password_field: function (field) {
+ var selector = 'input[name="' + field + '"][type="password"]:visible';
+ return this.$(selector)[0];
},
});
};
diff --git a/addons/auth_signup/static/src/xml/auth_signup.xml b/addons/auth_signup/static/src/xml/auth_signup.xml
deleted file mode 100644
index 1c41dbed181..00000000000
--- a/addons/auth_signup/static/src/xml/auth_signup.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- vim:fdl=1:
--->
-<templates id="template" xml:space="preserve">
-
- <t t-extend="Login">
- <t t-jquery="form ul:first li:contains('Username')" t-operation="before">
- <li data-modes="signup reset">Name</li>
- <li data-modes="signup reset"><input name="name" type="text"/></li>
- </t>
- <t t-jquery="form ul:first li:contains('Username')" t-operation="replace">
- <li data-modes="default">Username</li>
- <li data-modes="signup reset">Username (Email)</li>
- </t>
- <t t-jquery="form ul:first li:has(input[name=login], input[name=password]), form ul:first li:contains('Password')">
- this.attr('data-modes', 'default signup reset');
- </t>
- <t t-jquery="form ul:first li:has(input[name=password])" t-operation="after">
- <li data-modes="signup reset">Confirm Password</li>
- <li data-modes="signup reset"><input name="confirm_password" type="password"/></li>
- </t>
- <t t-jquery="form ul:first li:has(button[name=submit])" t-operation="replace">
- <li>
- <button name="submit">
- <span data-modes="default">Log in</span>
- <span data-modes="signup">Sign Up</span>
- <span data-modes="reset">Reset password</span>
- </button>
- <a class="oe_signup_signup" data-modes="default" href="#">Sign Up</a>
- <a class="oe_signup_back" data-modes="signup reset" href="#">Back to Login</a>
- <a class="oe_signup_reset_password" data-modes="default" href="#">Reset password</a>
- </li>
- </t>
- <t t-jquery=".oe_login_manage_db">
- this.attr('data-modes', 'default');
- </t>
- </t>
-
-</templates>
diff --git a/addons/auth_signup/views/auth_signup_login.xml b/addons/auth_signup/views/auth_signup_login.xml
new file mode 100644
index 00000000000..9f5d88eb33a
--- /dev/null
+++ b/addons/auth_signup/views/auth_signup_login.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- vim:fdn=3:
+-->
+<openerp>
+ <data>
+ <template id="auth_signup.login" inherit_id="web.login" name="Login (overloaded by auth_signup)">
+ <xpath expr="//button[@type='submit']" position="before">
+ <a t-if="signup" t-attf-href="?mode=signup{{ '&amp;debug' if debug else '' }}" class="btn btn-default pull-left">Sign up</a>
+ <a t-if="reset" t-attf-href="?mode=reset{{ '&amp;debug' if debug else '' }}" class="btn btn-default pull-left">Reset Password</a>
+ </xpath>
+ </template>
+
+ <template id="auth_signup.signup" name="Sinup">
+ <t t-call="web.login_layout">
+ <t t-set="head">
+ <t t-foreach="css" t-as="css_file">
+ <link rel="stylesheet" t-att-href="css_file"/>
+ </t>
+ <t t-foreach="js" t-as="js_file">
+ <script type="text/javascript" t-att-src="js_file"></script>
+ </t>
+ </t>
+ <script type="text/javascript">
+ $(function() {
+ var s = new openerp.init(<t t-raw="modules"/>);
+ var login_form = new openerp.web.LoginForm($('.oe_signup_form'));
+ });
+ </script>
+
+ <t t-set="reset_without_token" t-value="mode == 'reset' and not token"/>
+
+ <form class="oe_signup_form" role="form" t-attf-action="/web/login{{ '?debug' if debug else '' }}" method="post">
+ <div class="form-group field-name" t-if="not reset_without_token">
+ <label for="name" class="control-label">Name</label>
+ <input type="text" name="name" t-att-value="name" id="name" class="form-control" placeholder="Enter your name"
+ required="required" autofocus="autofocus" t-att-disabled="'disabled' if mode == 'reset' and token else None"/>
+ </div>
+
+ <div class="form-group field-login">
+ <label for="login" class="control-label">Username (email)</label>
+ <input type="text" name="login" t-att-value="login" id="login" class="form-control" placeholder="Enter login"
+ t-att-autofocus="'autofocus' if reset_without_token else None"
+ required="required" t-att-disabled="'disabled' if mode == 'reset' and token else None"/>
+ <input type="hidden" name="login" t-att-value="login" t-if="mode == 'reset' and token"/>
+ </div>
+
+ <div class="form-group field-password" t-if="not reset_without_token">
+ <label for="password" class="control-label">Password</label>
+ <input type="password" name="password" id="password" class="form-control" placeholder="Password"
+ required="required" t-att-autofocus="'autofocus' if mode == 'reset' and token else None"/>
+ </div>
+
+ <div class="form-group field-confirm_password" t-if="not reset_without_token">
+ <label for="confirm_password" class="control-label">Confirm Password</label>
+ <input type="password" name="confirm_password" id="confirm_password" class="form-control" placeholder="Confirm your password" required="required"/>
+ </div>
+
+ <p class="alert alert-danger" t-if="error">
+ <t t-esc="error"/>
+ </p>
+ <p class="alert alert-success" t-if="message">
+ <t t-esc="message"/>
+ </p>
+
+ <hr/>
+ <input type="hidden" name="redirect" t-att-value="redirect"/>
+ <input type="hidden" name="mode" t-att-value="mode"/>
+ <input type="hidden" name="token" t-att-value="token"/>
+ <div class="clearfix oe_login_buttons">
+ <a href="/web/login" class="btn btn-default pull-left">Back to Login</a>
+ <button type="submit" class="btn btn-primary pull-right">
+ <t t-if="mode == 'signup'">Signup</t>
+ <t t-if="mode == 'reset'">Reset password</t>
+ </button>
+ </div>
+
+ </form>
+ <div class="oe_single_form_footer" t-if="not disable_footer">
+ <t t-if="not disable_database_manager">
+ <a class="oe_login_manage_db" t-attf-href="/web/database/manager{{ '?debug' if debug else '' }}">Manage Databases</a>
+ <span class="oe_footer_seperator"> | </span>
+ </t>
+ <a href="http://www.openerp.com" target="_blank">Powered by <span>OpenERP</span></a>
+ </div>
+
+ </t>
+ </template>
+
+ </data>
+</openerp>
diff --git a/addons/edi/static/src/js/edi.js b/addons/edi/static/src/js/edi.js
index 80002bd8743..91d2b842f8a 100644
--- a/addons/edi/static/src/js/edi.js
+++ b/addons/edi/static/src/js/edi.js
@@ -1,6 +1,7 @@
openerp.edi = function(instance) {
var _t = instance.web._t;
-instance.edi = {}
+instance.edi = {};
+
instance.edi.EdiImport = instance.web.Widget.extend({
@@ -10,11 +11,7 @@ instance.edi.EdiImport = instance.web.Widget.extend({
},
start: function() {
if (!this.session.session_is_valid()) {
- this.show_login();
- this.session.on_session_valid.add({
- callback: this.proxy('show_import'),
- unique: true,
- });
+ instance.redirect('/web/login?redir=' + encodeURIComponent(window.location));
} else {
this.show_import();
}
@@ -25,12 +22,6 @@ instance.edi.EdiImport = instance.web.Widget.extend({
this.do_import();
},
- show_login: function() {
- this.destroy_content();
- this.login = new instance.web.Login(this);
- this.login.appendTo(this.$el);
- },
-
destroy_content: function() {
_.each(_.clone(this.getChildren()), function(el) {
el.destroy();
diff --git a/addons/product/product.py b/addons/product/product.py
index 9cba104831f..0bd3d43ecea 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -568,10 +568,15 @@ class product_product(osv.osv):
_product_incoming_qty = _get_product_available_func(('confirmed','waiting','assigned'), ('in',))
def _product_lst_price(self, cr, uid, ids, name, arg, context=None):
- res = {}
+ res = dict.fromkeys(ids, 0.0)
product_uom_obj = self.pool.get('product.uom')
- for id in ids:
- res.setdefault(id, 0.0)
+
+ # retrieve pricelist
+ pricelist = None
+ if context.get('pricelist'):
+ pricelist = self.pool['product.pricelist'].browse(cr, uid, context.get('pricelist'), context=context)
+ base_currency = self.pool['res.users'].browse(cr, uid, uid, context=context).company_id.currency_id
+
for product in self.browse(cr, uid, ids, context=context):
if 'uom' in context:
uom = product.uos_id or product.uom_id
@@ -579,7 +584,11 @@ class product_product(osv.osv):
uom.id, product.list_price, context['uom'])
else:
res[product.id] = product.list_price
- res[product.id] = (res[product.id] or 0.0) * (product.price_margin or 1.0) + product.price_extra
+ res[product.id] = (res[product.id] or 0.0) * (product.price_margin or 1.0) + product.price_extra
+ # update the result, according to the eventual pricelist currency
+ if pricelist and pricelist.currency_id:
+ res[product.id] = self.pool['res.currency'].compute(
+ cr, uid, base_currency.id, pricelist.currency_id.id, res[product.id], round=False, context=context)
return res
def _save_product_lst_price(self, cr, uid, product_id, field_name, field_value, arg, context=None):
diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py
index 56132472a17..da4dd88e162 100644
--- a/addons/website/controllers/main.py
+++ b/addons/website/controllers/main.py
@@ -20,7 +20,7 @@ import openerp
from openerp.osv import fields
from openerp.addons.website.models import website
from openerp.addons.web import http
-from openerp.addons.web.http import request
+from openerp.addons.web.http import request, LazyResponse
from ..utils import slugify
@@ -42,6 +42,14 @@ class Website(openerp.addons.web.controllers.main.Home):
pass
return self.page("website.homepage")
+ @http.route(website=True, auth="public", multilang=True)
+ def web_login(self, *args, **kw):
+ response = super(Website, self).web_login(*args, **kw)
+ if isinstance(response, LazyResponse):
+ values = dict(response.params['values'], disable_footer=True)
+ response = request.website.render(response.params['template'], values)
+ return response
+
@http.route('/pagenew/<path:path>', type='http', auth="user")
def pagenew(self, path, noredirect=NOPE):
web = request.registry['website']
diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css
index 72053e130f2..170b6b5ff87 100644
--- a/addons/website/static/src/css/website.css
+++ b/addons/website/static/src/css/website.css
@@ -491,3 +491,8 @@ span[data-oe-type="monetary"] {
-o-column-count: 3;
column-count: 3;
}
+
+.oe_website_login_container {
+ width: 400px;
+ margin: 40px auto;
+}
diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass
index 7c1825d6670..0709047bb02 100644
--- a/addons/website/static/src/css/website.sass
+++ b/addons/website/static/src/css/website.sass
@@ -392,3 +392,6 @@ span[data-oe-type="monetary"]
.oe_template_fallback
@include column-count(3)
+.oe_website_login_container
+ width: 400px
+ margin: 40px auto
diff --git a/addons/website/static/src/js/website.ace.js b/addons/website/static/src/js/website.ace.js
index 4ff5aa44146..6433330e50e 100644
--- a/addons/website/static/src/js/website.ace.js
+++ b/addons/website/static/src/js/website.ace.js
@@ -94,11 +94,18 @@
}).then(function (views) {
self.loadViews.call(self, views);
self.open.call(self);
- // cf. fp's direct request
- if (views.length >= 2) {
- var mainTemplate = views[1];
- self.$('#ace-view-list').val(mainTemplate.id).trigger('change');
- }
+ var curentHash = window.location.hash;
+ var indexOfView = curentHash.indexOf("?view=");
+ if (indexOfView >= 0) {
+ var viewId = parseInt(curentHash.substring(indexOfView + 6, curentHash.length), 10);
+ self.$('#ace-view-list').val(viewId).change();
+ } else {
+ if (views.length >= 2) {
+ var mainTemplate = views[1];
+ self.$('#ace-view-list').val(mainTemplate.id).trigger('change');
+ }
+ window.location.hash = hash;
+ }
});
var $editor = self.$('.ace_editor');
@@ -253,7 +260,9 @@
$.when.apply($, requests).then(function () {
self.reloadPage.call(self);
}).fail(function (source, error) {
- var message = (error.data.arguments[0] === "Access Denied") ? "Access denied: please sign in" : error.message;
+ var message = _.isString(error) ? error
+ : (error.data.arguments[0] === "Access Denied") ? "Access denied: please sign in"
+ : error.message;
self.displayError.call(self, message);
});
},
@@ -266,7 +275,7 @@
args: [[session.id], { 'arch': xml.xml }, website.get_context()],
});
} else {
- return $.Deferred().fail("Malformed XML document");
+ return $.Deferred().reject(null, "Malformed XML document");
}
},
updateHash: function () {
@@ -282,14 +291,6 @@
},
open: function () {
this.$el.removeClass('oe_ace_closed').addClass('oe_ace_open');
- var curentHash = window.location.hash;
- var indexOfView = curentHash.indexOf("?view=");
- if (indexOfView >= 0) {
- var viewId = parseInt(curentHash.substring(indexOfView + 6, curentHash.length), 10);
- this.$('#ace-view-list').val(viewId).change();
- } else {
- window.location.hash = hash;
- }
},
close: function () {
window.location.hash = "";
diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js
index f5a1c845f28..7cd3a4be67b 100644
--- a/addons/website/static/src/js/website.editor.js
+++ b/addons/website/static/src/js/website.editor.js
@@ -836,7 +836,7 @@
.on('snippet-dropped', function (e, el) {
// CKEDITOR data processor extended by widgets plugin
// to add wrappers around upcasting elements
- el.outerHTML = editor.dataProcessor.toHtml(el.outerHTML, {
+ el.innerHTML = editor.dataProcessor.toHtml(el.innerHTML, {
fixForBody: false,
dontFilter: true,
});
diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js
index e232a050b27..c6c2b21f9d4 100644
--- a/addons/website/static/src/js/website.js
+++ b/addons/website/static/src/js/website.js
@@ -263,7 +263,7 @@
dom_ready.then(function () {
/* ----- BOOTSTRAP STUFF ---- */
- $('.js_tooltip').bstooltip();
+ // $('.js_tooltip').bstooltip();
/* ----- PUBLISHING STUFF ---- */
$(document).on('click', '.js_publish_management .js_publish_btn', function () {
diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js
index 7e8d2aea7a0..f58bd048e80 100644
--- a/addons/website/static/src/js/website.tour.js
+++ b/addons/website/static/src/js/website.tour.js
@@ -295,6 +295,7 @@
},
});
+
website.EditorBar.include({
tours: [],
init: function () {
@@ -340,13 +341,23 @@
window.onbeforeunload = function () {
clearTimeout(overlapsCrash);
};
+ function throwError (message) {
+ console.log(JSON.parse(window.localStorage.getItem("test-report")));
+ test.reset();
+ throw message;
+ }
function executeStep (step) {
+ // check if they are a cycle
var lastStep = window.localStorage.getItem(testId);
- var tryStep = lastStep != step.stepId ? 0 : parseInt(window.localStorage.getItem("last-"+testId) || 0, 10)+1;
- window.localStorage.setItem("last-"+testId, tryStep);
+ var tryStep = lastStep != step.stepId ? 0 : (+(window.localStorage.getItem("test-last-"+testId) || 0) + 1);
+ window.localStorage.setItem("test-last-"+testId, tryStep);
if (tryStep > 2) {
- window.localStorage.removeItem(testId);
- throw "Test: '" + testId + "' cycling step: '" + step.stepId + "'";
+ throwError("Test: '" + testId + "' cycling step: '" + step.stepId + "'");
+ }
+
+ // set last time for report
+ if (tryStep == 0 || !window.localStorage.getItem("test-last-time")) {
+ window.localStorage.setItem("test-last-time", new Date().getTime());
}
var _next = false;
@@ -354,6 +365,12 @@
function next () {
clearTimeout(overlapsCrash);
_next = true;
+
+ // set report
+ var report = JSON.parse(window.localStorage.getItem("test-report")) || {};
+ report[step.stepId] = (new Date().getTime() - window.localStorage.getItem("test-last-time")) + " ms";
+ window.localStorage.setItem("test-report", JSON.stringify(report));
+
var nextStep = actionSteps.shift();
if (nextStep) {
setTimeout(function () {
@@ -363,34 +380,42 @@
window.localStorage.removeItem(testId);
}
}
+
overlapsCrash = setTimeout(function () {
- window.localStorage.removeItem(testId);
- throw "Test: '" + testId + "' can't resolve step: '" + step.stepId + "'";
- }, (step.delay || defaultDelay) + 500);
+ throwError("Test: '" + testId + "' can't resolve step: '" + step.stepId + "'");
+ }, (step.delay || defaultDelay) + 1000);
- var $element = $(step.element);
- if (step.triggers) step.triggers(next);
- if ((step.trigger === 'reload' || (step.trigger && step.trigger.url)) && _next) return;
-
- if (step.snippet && step.trigger === 'drag') {
- website.TestConsole.dragAndDropSnippet(step.snippet);
- } else if (step.trigger && step.trigger.id === 'change') {
- $element.trigger($.Event("change", { srcElement: $element }));
- } else if (step.sampleText) {
- $element.val(step.sampleText);
- $element.trigger($.Event("change", { srcElement: $element }));
- } else if ($element.is(":visible")) { // Click by default
- if (step.trigger.id === 'mousedown') {
- $element.trigger($.Event("mousedown", { srcElement: $element }));
+ setTimeout(function () {
+ var $element = $(step.element);
+ if (step.triggers) {
+ try {
+ step.triggers(next);
+ } catch (e) {
+ throwError(e);
+ }
}
- var evt = document.createEvent("MouseEvents");
- evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
- $element[0].dispatchEvent(evt);
- if (step.trigger.id === 'mouseup') {
- $element.trigger($.Event("mouseup", { srcElement: $element }));
+ if ((step.trigger === 'reload' || (step.trigger && step.trigger.url)) && _next) return;
+
+ if (step.snippet && step.trigger === 'drag') {
+ website.TestConsole.dragAndDropSnippet(step.snippet);
+ } else if (step.trigger && step.trigger.id === 'change') {
+ $element.trigger($.Event("change", { srcElement: $element }));
+ } else if (step.sampleText) {
+ $element.val(step.sampleText);
+ $element.trigger($.Event("change", { srcElement: $element }));
+ } else if ($element.is(":visible")) { // Click by default
+ if (step.trigger.id === 'mousedown') {
+ $element.trigger($.Event("mousedown", { srcElement: $element }));
+ }
+ var evt = document.createEvent("MouseEvents");
+ evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ $element[0].dispatchEvent(evt);
+ if (step.trigger.id === 'mouseup') {
+ $element.trigger($.Event("mouseup", { srcElement: $element }));
+ }
}
- }
- if (!step.triggers) next();
+ if (!step.triggers) next();
+ },0);
}
var url = new website.UrlParser(window.location.href);
if (tour.path && url.pathname !== tour.path && !window.localStorage.getItem(testId)) {
@@ -415,6 +440,12 @@
},
reset: function () {
window.localStorage.removeItem(testId);
+ window.localStorage.removeItem("test-report");
+ for (var k in window.localStorage) {
+ if (window.localStorage[k].indexOf("test-last")) {
+ window.localStorage.removeItem(k);
+ }
+ }
},
};
website.TestConsole.tests.push(test);
diff --git a/addons/website/tests/test_requests.py b/addons/website/tests/test_requests.py
index fc56a93158c..e78c59a69cf 100644
--- a/addons/website/tests/test_requests.py
+++ b/addons/website/tests/test_requests.py
@@ -48,8 +48,8 @@ class CrawlSuite(unittest2.TestSuite):
self.opener.add_handler(urllib2.UnknownHandler())
self.opener.add_handler(urllib2.HTTPHandler())
self.opener.add_handler(urllib2.HTTPSHandler())
- self.opener.add_handler(RedirectHandler())
self.opener.add_handler(urllib2.HTTPCookieProcessor())
+ self.opener.add_handler(RedirectHandler())
self._authenticate(user, password)
self.user = user
diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py
index cc5dbc9db4f..a4dcf8cf434 100644
--- a/addons/website/tests/test_ui.py
+++ b/addons/website/tests/test_ui.py
@@ -146,6 +146,6 @@ def full_path(pyfile, filename):
def load_tests(loader, base, _):
base.addTest(WebsiteUiSuite(full_path(__file__, 'dummy_test.js'), {}, 5.0))
- base.addTest(WebsiteUiSuite(full_path(__file__, 'simple_dom_test.js'), { 'action': 'website.action_website_homepage' }, 60.0))
- base.addTest(WebsiteUiSuite(full_path(__file__, 'homepage_test.js'), { 'action': 'website.action_website_homepage' }, 60.0))
+ base.addTest(WebsiteUiSuite(full_path(__file__, 'simple_dom_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
+ base.addTest(WebsiteUiSuite(full_path(__file__, 'homepage_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
return base
diff --git a/addons/website/tests/ui_suite/ui_test_runner.js b/addons/website/tests/ui_suite/ui_test_runner.js
index e8f38ebb9d9..d3e3132f603 100644
--- a/addons/website/tests/ui_suite/ui_test_runner.js
+++ b/addons/website/tests/ui_suite/ui_test_runner.js
@@ -9,8 +9,10 @@ function waitFor (ready, callback, timeout, timeoutMessageCallback) {
if(!condition) {
var message = timeoutMessageCallback ? timeoutMessageCallback() : "Timeout after "+timeout+" ms";
console.log('{ "event": "error", "message": "'+message+'" }');
- var json = { "event": "error", "message": "Waiting for...\n"+ready };
- console.log(JSON.stringify(json));
+ console.log("Waiting for...\n"+ready);
+ if (window.localStorage.getItem("test-report")) {
+ console.log(JSON.parse(website.localStorage.getItem("test-report")));
+ }
phantom.exit(1);
} else {
clearInterval(interval);
@@ -28,15 +30,16 @@ function run (test) {
var scheme = options.scheme ? options.scheme+'://' : 'http://';
var host = options.host ? options.host : 'localhost';
var port = options.port ? ':'+options.port : '';
- var path = options.path ? options.path : '/web';
+ var path = options.path ? options.path : '/login';
var queryParams = [];
if (options.db) queryParams.push('db='+options.db);
+ if (options.user) queryParams.push('login='+options.user);
+ if (options.password) queryParams.push('key='+options.password);
+ if (options.redirect) queryParams.push('redirect='+options.redirect);
var query = queryParams.length > 0 ? '?'+queryParams.join('&') : '';
var hashParams = [];
- if (options.user) hashParams.push('login='+options.user);
- if (options.password) hashParams.push('password='+options.password);
if (options.action) hashParams.push('action='+options.action);
var hash = hashParams.length > 0 ? '#'+hashParams.join('&') : '';
diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml
index 066e067ec8b..f40474ac75a 100644
--- a/addons/website/views/website_templates.xml
+++ b/addons/website/views/website_templates.xml
@@ -255,11 +255,19 @@
</xpath>
</template>
+<template id="login_layout" inherit_id="web.login_layout" name="Website Login Layout">
+ <xpath expr="t" position="replace">
+ <t t-call="website.layout">
+ <div class="oe_website_login_container" t-raw="0"/>
+ </t>
+ </xpath>
+</template>
+
<template id="show_sign_in" inherit_option_id="website.layout" inherit_id="website.layout" name="Show Sign In" groups="base.group_public">
<xpath expr="//ul[@id='top_menu']" position="inside">
<li class="divider"/>
<li>
- <a t-attf-href="/web#redirect=#{ quote_plus(url_for('', keep_query='*')) }">
+ <a t-attf-href="/web/login">
<b>Sign in</b>
</a>
</li>
diff --git a/addons/website_blog/tests/test_ui.py b/addons/website_blog/tests/test_ui.py
index dad6a4752e7..36f464e4998 100644
--- a/addons/website_blog/tests/test_ui.py
+++ b/addons/website_blog/tests/test_ui.py
@@ -1,5 +1,5 @@
import openerp.addons.website.tests.test_ui as test_ui
def load_tests(loader, base, _):
- base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'post_test.js'), { 'action': 'website.action_website_homepage' }, 60.0))
- return base \ No newline at end of file
+ base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'post_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
+ return base
diff --git a/addons/website_event/tests/test_ui.py b/addons/website_event/tests/test_ui.py
index 52cce70defd..176bc77ecc5 100644
--- a/addons/website_event/tests/test_ui.py
+++ b/addons/website_event/tests/test_ui.py
@@ -1,5 +1,5 @@
import openerp.addons.website.tests.test_ui as test_ui
def load_tests(loader, base, _):
- base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'event_test.js'), { 'action': 'website.action_website_homepage' }, 60.0))
- return base \ No newline at end of file
+ base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'event_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
+ return base
diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py
index caa9aad7846..b2a4d1eb57e 100644
--- a/addons/website_sale/controllers/main.py
+++ b/addons/website_sale/controllers/main.py
@@ -191,10 +191,9 @@ class Ecommerce(http.Controller):
return [r["product_tmpl_id"][0] for r in att]
@http.route(['/shop/pricelist'], type='http', auth="public", website=True, multilang=True)
- def shop_promo(self, code, **post):
- assert code, 'No pricelist code provided'
- request.registry['website']._ecommerce_change_pricelist(request.cr, request.uid, code=code, context=request.context)
- return request.redirect("/shop")
+ def shop_promo(self, promo=None, **post):
+ request.registry['website']._ecommerce_change_pricelist(request.cr, request.uid, code=promo, context=request.context)
+ return request.redirect("/shop/mycart/")
@http.route([
'/shop/',
@@ -708,6 +707,8 @@ class Ecommerce(http.Controller):
order = request.registry['sale.order'].browse(cr, SUPERUSER_ID, sale_order_id, context=context)
assert order.website_session_id == request.httprequest.session['website_session_id']
+ request.registry['website']._ecommerce_change_pricelist(cr, uid, None, context=context or {})
+
return request.website.render("website_sale.confirmation", {'order': order})
@http.route(['/shop/change_sequence/'], type='json', auth="public", website=True)
diff --git a/addons/website_sale/models/website.py b/addons/website_sale/models/website.py
index 192b33b5296..11ff6cf2efc 100644
--- a/addons/website_sale/models/website.py
+++ b/addons/website_sale/models/website.py
@@ -51,7 +51,7 @@ class Website(orm.Model):
values.update(order.onchange_pricelist_id(pricelist_id, None)['value'])
order.write(values)
for line in order.order_line:
- self.add_product_to_cart(order_line_id=line.id, number=0)
+ self._ecommerce_add_product_to_cart(cr, uid, order_line_id=line.id, number=0)
# ************************************************************
# Ecommerce quotation management
@@ -65,7 +65,7 @@ class Website(orm.Model):
order_line_obj = self.pool.get('sale.order.line')
order_obj = self.pool.get('sale.order')
- context = dict(context, pricelist=self.ecommerce_get_pricelist_id(cr, uid, None, context=context))
+ context = dict(context or {}, pricelist=self.ecommerce_get_pricelist_id(cr, uid, None, context=context))
# set order_line_id and product_id
if order_line_id:
@@ -122,6 +122,11 @@ class Website(orm.Model):
else:
order_line_id = order_line_obj.create(cr, SUPERUSER_ID, values, context=context)
order_obj.write(cr, SUPERUSER_ID, [order.id], {'order_line': [(4, order_line_id)]}, context=context)
+
+ order = self.ecommerce_get_current_order(cr, uid, context=context)
+ if not order or not order.order_line:
+ self._ecommerce_change_pricelist(cr, uid, None, context=context)
+
return quantity
def _ecommerce_get_quotation_values(self, cr, uid, context=None):
diff --git a/addons/website_sale/static/src/js/website.tour.shop.js b/addons/website_sale/static/src/js/website.tour.shop.js
index 78643d1b110..f6b64342c58 100644
--- a/addons/website_sale/static/src/js/website.tour.shop.js
+++ b/addons/website_sale/static/src/js/website.tour.shop.js
@@ -292,8 +292,7 @@
url: /shop\/confirmation\//,
},
afterTrigger: function (tour) {
- window.localStorage.setItem("test-success", "{}");
- throw "afterTrigger test finish, remove this throw";
+ console.log('{ "event": "success" }');
},
}
];
diff --git a/addons/website_sale/tests/test_ui.py b/addons/website_sale/tests/test_ui.py
index 68ba5dc0a05..bda42eb1bd7 100644
--- a/addons/website_sale/tests/test_ui.py
+++ b/addons/website_sale/tests/test_ui.py
@@ -2,5 +2,5 @@ import openerp.addons.website.tests.test_ui as test_ui
def load_tests(loader, base, _):
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test.js'),
- { 'action': 'website.action_website_homepage' }, 60.0))
+ { 'action': 'website.action_website_homepage' }, 120.0))
return base \ No newline at end of file
diff --git a/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js b/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js
index c1027107e44..5554ea75271 100644
--- a/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js
+++ b/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js
@@ -14,15 +14,5 @@ testRunner.run(function websiteSaleTest (page, timeout) {
page.evaluate(function () {
window.openerp.website.TestConsole.test('shoptest').run(true);
});
- waitFor(function testExecuted () {
- return page.evaluate(function () {
- var res = window.localStorage && window.localStorage.getItem
- && window.localStorage.getItem("test-success");
- return res;
- });
- }, function finish () {
- console.log('{ "event": "success" }');
- phantom.exit();
- }, 4*timeout/5);
}, timeout/5);
}); \ No newline at end of file
diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml
index 32d7f3989b8..105eceac596 100644
--- a/addons/website_sale/views/website_sale.xml
+++ b/addons/website_sale/views/website_sale.xml
@@ -62,7 +62,7 @@
<h5><strong><a t-href="/shop/product/#{ slug(product) }/" t-keep-query="category,search,filters" t-field="product.name"/></strong></h5>
<div class="product_price" t-if="product.product_variant_ids">
<b>
- <t t-if="product.product_variant_ids[0].lst_price != product.product_variant_ids[0].price">
+ <t t-if="abs(product.product_variant_ids[0].lst_price - product.product_variant_ids[0].price) &gt; 0.2">
<del class="text-danger"
t-field="product.product_variant_ids[0].lst_price" t-field-options='{
"widget": "monetary",
@@ -515,13 +515,14 @@
<div class="text-muted" t-field="line.product_id.description_sale"/>
</td>
<td class="text-center">
- <del class="text-danger" t-if="line.product_id.lst_price &gt; line.price_unit">
- <span t-field="line.product_id.lst_price" t-field-options='{
+ <t t-if="abs(line.product_id.lst_price - line.price_unit) &gt; 0.2">
+ <del class="text-danger"
+ t-field="line.product_id.lst_price" t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
- }'/>
- </del>
- <span t-field="line.price_unit" t-field-options='{
+ }'/>&amp;nbsp;
+ </t>
+ <span t-field="line.price_unit" t-field-options='{
"widget": "monetary",
"display_currency": "website.pricelist_id.currency_id"
}'/>
@@ -669,10 +670,17 @@
<div class="text-muted" t-field="product.description_sale"/>
</td>
<td>
- <span t-field="product.lst_price" t-field-options='{
- "widget": "monetary",
- "display_currency": "website.pricelist_id.currency_id"
- }'/>
+ <t t-if="abs(product.lst_price - product.price) &gt; 0.2">
+ <del class="text-danger"
+ t-field="product.lst_price" t-field-options='{
+ "widget": "monetary",
+ "display_currency": "website.pricelist_id.currency_id"
+ }'/>&amp;nbsp;
+ </t>
+ <span t-field="product.price" t-field-options='{
+ "widget": "monetary",
+ "display_currency": "website.pricelist_id.currency_id"
+ }'/>
</td>
<td class="text-center">
<form action="/shop/add_cart/" method="post">
@@ -692,7 +700,7 @@
<p>
Have a coupon code? Fill in this field and apply.
</p>
- <form t-if="website_sale_order and website_sale_order.website_order_line" action="/shop/mycart/" method="post" class="mb32">
+ <form t-if="website_sale_order and website_sale_order.website_order_line" action="/shop/pricelist/" method="post" class="mb32">
<div class="input-group">
<input name="promo" class='form-control' type="text" placeholder="code..." t-att-value="website_sale_order.pricelist_id.code or ''"/>
<div class="input-group-btn">