From 7027ce6eda8f38468fc795a7366ffce4672703f3 Mon Sep 17 00:00:00 2001 From: jke-openerp Date: Thu, 30 Jan 2014 10:18:13 +0100 Subject: [PATCH 01/55] [REF] website_sale : Add missing widget option in recommanded product, to display image bzr revid: jke@openerp.com-20140130091813-hko16qlm4t8tmq37 --- addons/website_sale/views/website_sale.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index 6717bc62557..9bb0a288320 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -358,7 +358,7 @@
- +
From e974e1fbead436e5b77df428f5117af3688d8893 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 10:23:08 +0100 Subject: [PATCH 02/55] [REM] remove disable_db and ensure_db() from addons bzr revid: fme@openerp.com-20140130092308-s24a7h2mhzuaasf1 --- addons/auth_oauth/controllers/main.py | 2 -- addons/auth_signup/controllers/main.py | 2 -- addons/mass_mailing/controllers/main.py | 1 - addons/payment_adyen/controllers/main.py | 1 - addons/payment_ogone/controllers/main.py | 1 - addons/payment_paypal/controllers/main.py | 3 --- addons/payment_transfer/controllers/main.py | 1 - 7 files changed, 11 deletions(-) diff --git a/addons/auth_oauth/controllers/main.py b/addons/auth_oauth/controllers/main.py index e932b6ca1c0..e660fd8363b 100644 --- a/addons/auth_oauth/controllers/main.py +++ b/addons/auth_oauth/controllers/main.py @@ -68,8 +68,6 @@ class OAuthLogin(openerp.addons.web.controllers.main.Home): @http.route() def web_login(self, *args, **kw): - http.ensure_db(with_registry=True) - request.disable_db = False providers = self.list_providers() response = super(OAuthLogin, self).web_login(*args, **kw) diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py index 7a517a0ef8c..2db1e3dff65 100644 --- a/addons/auth_signup/controllers/main.py +++ b/addons/auth_signup/controllers/main.py @@ -34,8 +34,6 @@ class Home(openerp.addons.web.controllers.main.Home): @http.route() def web_login(self, *args, **kw): - http.ensure_db(with_registry=True) - mode = request.params.get('mode') qcontext = request.params.copy() response = webmain.render_bootstrap_template(request.session.db, 'auth_signup.signup', qcontext, lazy=True) diff --git a/addons/mass_mailing/controllers/main.py b/addons/mass_mailing/controllers/main.py index 9f5f88327e9..046084621c7 100644 --- a/addons/mass_mailing/controllers/main.py +++ b/addons/mass_mailing/controllers/main.py @@ -6,7 +6,6 @@ class MassMailController(http.Controller): @http.route('/mail/track//blank.gif', type='http', auth='none') def track_mail_open(self, mail_id): """ Email tracking. """ - request.disable_db = False mail_mail_stats = request.registry.get('mail.mail.statistics') mail_mail_stats.set_opened(request.cr, SUPERUSER_ID, mail_mail_ids=[mail_id]) return "data:image/gif;base64,R0lGODlhAQABAIAAANvf7wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" diff --git a/addons/payment_adyen/controllers/main.py b/addons/payment_adyen/controllers/main.py index ad5a68d2327..e6e74eba9a7 100644 --- a/addons/payment_adyen/controllers/main.py +++ b/addons/payment_adyen/controllers/main.py @@ -22,7 +22,6 @@ class AdyenController(http.Controller): ], type='http', auth='none') def adyen_return(self, pspReference, **post): """ Paypal IPN.""" - request.disable_db = False post["pspReference"] = pspReference _logger.info('Beginning Adyen form_feedback with post data %s', pprint.pformat(post)) # debug request.registry['payment.transaction'].form_feedback(request.cr, SUPERUSER_ID, post, 'adyen', context=request.context) diff --git a/addons/payment_ogone/controllers/main.py b/addons/payment_ogone/controllers/main.py index 6ffc0661767..f93c913ed1d 100644 --- a/addons/payment_ogone/controllers/main.py +++ b/addons/payment_ogone/controllers/main.py @@ -23,7 +23,6 @@ class OgoneController(http.Controller): ], type='http', auth='none') def ogone_form_feedback(self, **post): """ Ogone contacts using GET, at least for accept """ - request.disable_db = False _logger.info('Ogone: entering form_feedback with post data %s', pprint.pformat(post)) # debug cr, uid, context = request.cr, SUPERUSER_ID, request.context request.registry['payment.transaction'].form_feedback(cr, uid, post, 'ogone', context=context) diff --git a/addons/payment_paypal/controllers/main.py b/addons/payment_paypal/controllers/main.py index ce43314498f..967059e59ae 100644 --- a/addons/payment_paypal/controllers/main.py +++ b/addons/payment_paypal/controllers/main.py @@ -56,7 +56,6 @@ class PaypalController(http.Controller): @http.route('/payment/paypal/ipn/', type='http', auth='none', methods=['POST']) def paypal_ipn(self, **post): """ Paypal IPN. """ - request.disable_db = False _logger.info('Beginning Paypal IPN form_feedback with post data %s', pprint.pformat(post)) # debug self.paypal_validate_data(**post) return '' @@ -64,7 +63,6 @@ class PaypalController(http.Controller): @http.route('/payment/paypal/dpn', type='http', auth="none", methods=['POST']) def paypal_dpn(self, **post): """ Paypal DPN """ - request.disable_db = False _logger.info('Beginning Paypal DPN form_feedback with post data %s', pprint.pformat(post)) # debug return_url = self._get_return_url(**post) self.paypal_validate_data(**post) @@ -73,7 +71,6 @@ class PaypalController(http.Controller): @http.route('/payment/paypal/cancel', type='http', auth="none") def paypal_cancel(self, **post): """ When the user cancels its Paypal payment: GET on this route """ - request.disable_db = False cr, uid, context = request.cr, SUPERUSER_ID, request.context _logger.info('Beginning Paypal cancel with post data %s', pprint.pformat(post)) # debug return_url = self._get_return_url(**post) diff --git a/addons/payment_transfer/controllers/main.py b/addons/payment_transfer/controllers/main.py index 9f5152e442a..917ac63cc81 100644 --- a/addons/payment_transfer/controllers/main.py +++ b/addons/payment_transfer/controllers/main.py @@ -16,7 +16,6 @@ class OgoneController(http.Controller): '/payment/transfer/feedback', ], type='http', auth='none') def transfer_form_feedback(self, **post): - request.disable_db = False cr, uid, context = request.cr, SUPERUSER_ID, request.context _logger.info('Beginning form_feedback with post data %s', pprint.pformat(post)) # debug request.registry['payment.transaction'].form_feedback(cr, uid, post, 'transfer', context) From ab8ee396ec9957b4129791167d158ad3a44ed5bd Mon Sep 17 00:00:00 2001 From: jke-openerp Date: Thu, 30 Jan 2014 10:49:27 +0100 Subject: [PATCH 03/55] [TYPO] Add space between icon and button in cart "Continue Shopping" bzr revid: jke@openerp.com-20140130094927-44b8szwtb602e180 --- addons/website_sale/views/website_sale.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index 9bb0a288320..695c8563ce7 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -553,7 +553,7 @@ From 8cf2adf5e314203debbec78edd7b163b40248348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 30 Jan 2014 11:30:51 +0100 Subject: [PATCH 04/55] [IMP] point_of_sale: hold receipts until the printer is back online bzr revid: fva@openerp.com-20140130103051-htsx7ts111axhhub --- addons/point_of_sale/static/src/js/devices.js | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index 57b23afd49f..bb13503d903 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -102,6 +102,8 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal }; this.custom_payment_status = this.default_payment_status; + this.receipt_queue = []; + this.notifications = {}; this.bypass_proxy = false; @@ -113,6 +115,13 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal this.set_connection_status('disconnected'); + this.on('change:status',this,function(eh,status){ + status = status.newValue; + if(status.status === 'connected'){ + self.print_receipt(); + } + }); + window.hw_proxy = this; }, set_connection_status: function(status,drivers){ @@ -502,7 +511,23 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal * } */ print_receipt: function(receipt){ - return this.message('print_receipt',{receipt: receipt}); + var self = this; + if(receipt){ + this.receipt_queue.push(receipt); + } + var aborted = false; + function send_printing_job(){ + if (self.receipt_queue.length > 0){ + var r = self.receipt_queue.shift(); + self.message('print_receipt',{ receipt: r },{ timeout: 5000 }) + .then(function(){ + send_printing_job(); + },function(){ + self.receipt_queue.unshift(r) + }); + } + } + send_printing_job(); }, // asks the proxy to log some information, as with the debug.log you can provide several arguments. From fd6d4d8303563948cfdbde620f5ffdb06c6fa5c1 Mon Sep 17 00:00:00 2001 From: jke-openerp Date: Thu, 30 Jan 2014 11:49:37 +0100 Subject: [PATCH 05/55] [FIX] Set the good url redirect in "Sign In" button from the cart bzr revid: jke@openerp.com-20140130104937-6rjt51rg3o9bz90k --- addons/website_sale/views/website_sale.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index 695c8563ce7..c45861f9382 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -720,7 +720,7 @@
From c38e65d343f3ae3f8dfaf92d49d61adcd940418b Mon Sep 17 00:00:00 2001 From: jke-openerp Date: Thu, 30 Jan 2014 12:10:56 +0100 Subject: [PATCH 06/55] [FIx] Convert # to %23 in url for twitter bzr revid: jke@openerp.com-20140130111056-gf31rpb8wknyxm8d --- addons/website_event/views/website_event.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index 34c515e3843..bb536795adc 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -337,7 +337,7 @@ and join the conversation.

Use this tag: - # + #

From 516a85cecc3a77b409179dde68f4f37234dd1775 Mon Sep 17 00:00:00 2001 From: jke-openerp Date: Thu, 30 Jan 2014 12:13:49 +0100 Subject: [PATCH 07/55] [Fix] Use maps.google.com and not .be (as for thumbail who use the api .com). [IMP] Add zoom 10 by default [FIX] Escape False in address for google search bzr revid: jke@openerp.com-20140130111349-l90w9larrntv83hh --- addons/website/models/website.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/addons/website/models/website.py b/addons/website/models/website.py index e053863e557..87acdbbfbe5 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -605,9 +605,10 @@ class res_partner(osv.osv): def google_map_link(self, cr, uid, ids, zoom=8, context=None): partner = self.browse(cr, uid, ids[0], context=context) params = { - 'q': '%s, %s %s, %s' % (partner.street, partner.city, partner.zip, partner.country_id and partner.country_id.name_get()[0][1] or ''), + 'q': '%s, %s %s, %s' % (partner.street or '', partner.city or '', partner.zip or '', partner.country_id and partner.country_id.name_get()[0][1] or ''), + 'z': 10 } - return urlplus('https://maps.google.be/maps' , params) + return urlplus('https://maps.google.com/maps' , params) class res_company(osv.osv): _inherit = "res.company" From 18532330d4d0f3dab7401ad8d5628f28183e537d Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 30 Jan 2014 12:24:08 +0100 Subject: [PATCH 08/55] [FIX] *: replace urllib calls by werkzeug calls, as werkzeug handles utf-8 encoding while urllib doesnt bzr revid: dle@openerp.com-20140130112408-8pdju26jnkyxvlw2 --- addons/auth_openid/controllers/main.py | 3 +-- addons/edi/controllers/main.py | 4 ++-- addons/share/wizard/share_wizard.py | 1 - addons/website/models/website.py | 14 ++------------ addons/website/tests/test_requests.py | 3 +-- addons/website_crm/controllers/main.py | 4 ++-- 6 files changed, 8 insertions(+), 21 deletions(-) diff --git a/addons/auth_openid/controllers/main.py b/addons/auth_openid/controllers/main.py index 534d1b01a9c..128be6f7dbe 100644 --- a/addons/auth_openid/controllers/main.py +++ b/addons/auth_openid/controllers/main.py @@ -23,7 +23,6 @@ import logging import os import tempfile import getpass -import urllib import werkzeug.urls import werkzeug.exceptions @@ -79,7 +78,7 @@ class GoogleAppsAwareConsumer(consumer.GenericConsumer): # update fields for attr in ['claimed_id', 'identity']: value = message.getArg(consumer.OPENID2_NS, attr, '') - value = 'https://www.google.com/accounts/o8/user-xrds?uri=%s' % urllib.quote_plus(value) + value = 'https://www.google.com/accounts/o8/user-xrds?uri=%s' % werkzeug.url_quote_plus(value) message.setArg(consumer.OPENID2_NS, attr, value) # now, resign the message diff --git a/addons/edi/controllers/main.py b/addons/edi/controllers/main.py index 86115d12d4b..d92cb2478cc 100644 --- a/addons/edi/controllers/main.py +++ b/addons/edi/controllers/main.py @@ -1,5 +1,5 @@ import simplejson -import urllib +import werkzeug.urls import openerp import openerp.addons.web.controllers.main as webmain @@ -17,7 +17,7 @@ class EDI(openerp.http.Controller): css = "\n ".join('' % i for i in webmain.manifest_list(req, modules_str, 'css')) # `url` may contain a full URL with a valid query string, we basically want to watch out for XML brackets and double-quotes - safe_url = urllib.quote_plus(url,':/?&;=') + safe_url = werkzeug.url_quote_plus(url,':/?&;=') return webmain.html_template % { 'js': js, diff --git a/addons/share/wizard/share_wizard.py b/addons/share/wizard/share_wizard.py index 2e8d4d9373e..22b880956cc 100644 --- a/addons/share/wizard/share_wizard.py +++ b/addons/share/wizard/share_wizard.py @@ -21,7 +21,6 @@ import logging import random import time -from urllib import quote_plus import uuid from openerp import SUPERUSER_ID diff --git a/addons/website/models/website.py b/addons/website/models/website.py index e053863e557..a0e6a458119 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -80,17 +80,7 @@ def slug(value): return "%s-%d" % (slugify(name), id) def urlplus(url, params): - if not params: - return url - - # can't use urlencode because it encodes to (ascii, replace) in p2 - return "%s?%s" % (url, '&'.join( - k + '=' + urllib.quote_plus(v.encode('utf-8') if isinstance(v, unicode) else str(v)) - for k, v in params.iteritems() - )) - -def quote_plus(value): - return urllib.quote_plus(value.encode('utf-8') if isinstance(value, unicode) else str(value)) + return werkzeug.Href(url)(params or None) class website(osv.osv): def _get_menu_website(self, cr, uid, ids, context=None): @@ -243,7 +233,7 @@ class website(osv.osv): slug=slug, res_company=request.website.company_id, user_id=user.browse(cr, uid, uid), - quote_plus=quote_plus, + quote_plus=werkzeug.url_quote_plus, ) qweb_values.setdefault('editable', False) diff --git a/addons/website/tests/test_requests.py b/addons/website/tests/test_requests.py index a60501a6513..ecdb8d99d7d 100644 --- a/addons/website/tests/test_requests.py +++ b/addons/website/tests/test_requests.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- import collections -import urllib import urlparse import unittest2 import urllib2 @@ -66,7 +65,7 @@ class CrawlSuite(unittest2.TestSuite): # blow up in multidb situations self.opener.open('http://localhost:{port}/web/?db={db}'.format( port=tools.config['xmlrpc_port'], - db=urllib.quote_plus(tools.config['db_name']), + db=werkzeug.url_quote_plus(tools.config['db_name']), )) if user is not None: url = 'http://localhost:{port}/login?{query}'.format( diff --git a/addons/website_crm/controllers/main.py b/addons/website_crm/controllers/main.py index 7f4443d26a4..85ffc950a3f 100644 --- a/addons/website_crm/controllers/main.py +++ b/addons/website_crm/controllers/main.py @@ -4,13 +4,13 @@ from openerp.addons.web import http from openerp.addons.web.http import request from openerp import SUPERUSER_ID -from urllib import quote_plus +import werkzeug.urls class contactus(http.Controller): def generate_google_map_url(self, street, city, city_zip, country_name): - url = "http://maps.googleapis.com/maps/api/staticmap?center=%s&sensor=false&zoom=8&size=298x298" % quote_plus( + url = "http://maps.googleapis.com/maps/api/staticmap?center=%s&sensor=false&zoom=8&size=298x298" % werkzeug.url_quote_plus( '%s, %s %s, %s' % (street, city, city_zip, country_name) ) return url From 20fc20a3f2ac2141643720160551af20d3949586 Mon Sep 17 00:00:00 2001 From: Antony Lesuisse Date: Thu, 30 Jan 2014 12:45:35 +0100 Subject: [PATCH 09/55] [IMP] http allow auth=none without db outside of web bzr revid: al@openerp.com-20140130114535-0keldqr1eln8swm8 --- openerp/http.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/http.py b/openerp/http.py index 7069cbdeefe..09a0a8d1d57 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -865,7 +865,7 @@ class Root(object): self.load_addons() _logger.info("Generating nondb routing") - self.nodb_routing_map = routing_map(['', "web"], True) + self.nodb_routing_map = routing_map([''] + openerp.conf.server_wide_modules, True) def __call__(self, environ, start_response): """ Handle a WSGI request From 9cce88ab6a399881b9d1774a717a030c7e575913 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 13:17:45 +0100 Subject: [PATCH 10/55] [ADD] Cross-Origin Resource Sharing support as http.route() argument bzr revid: fme@openerp.com-20140130121745-zjuuves1yhydydpx --- openerp/http.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openerp/http.py b/openerp/http.py index 09a0a8d1d57..35cf8f39a7c 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -207,7 +207,7 @@ class WebRequest(object): warnings.warn('please use request.registry and request.cr directly', DeprecationWarning) yield (self.registry, self.cr) -def route(route, type="http", auth="user", methods=None): +def route(route, type="http", auth="user", methods=None, cors=None): """ Decorator marking the decorated method as being a handler for requests. The method must be part of a subclass of ``Controller``. @@ -225,6 +225,7 @@ def route(route, type="http", auth="user", methods=None): authentication modules. There request code will not have any facilities to access the database nor have any configuration indicating the current database nor the current user. :param methods: A sequence of http methods this route applies to. If not specified, all methods are allowed. + :param cors: The Access-Control-Allow-Origin cors directive value. """ assert type in ["http", "json"] def decorator(f): @@ -234,6 +235,7 @@ def route(route, type="http", auth="user", methods=None): f.routes = [route] f.methods = methods f.exposed = type + f.cors = cors if getattr(f, "auth", None) is None: f.auth = auth return f @@ -955,6 +957,12 @@ class Root(object): if not explicit_session and hasattr(response, 'set_cookie'): response.set_cookie('session_id', httprequest.session.sid, max_age=90 * 24 * 60 * 60) + # Support for Cross-Origin Resource Sharing + if request.func.cors: + response.headers.set('Access-Control-Allow-Origin', request.func.cors) + if request.func.methods: + response.headers.set('Access-Control-Allow-Methods', ','.join(request.func.methods)) + return response def dispatch(self, environ, start_response): From b3268a48c2f72fb055571425f719c9a43aaa51ac Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 30 Jan 2014 13:20:51 +0100 Subject: [PATCH 11/55] [FIX] event: put back country_id related field as needed in event itself (not just website_event) bzr revid: dle@openerp.com-20140130122051-cm2u2hotlnfv4bxj --- addons/event/event.py | 2 ++ addons/website_event/models/event.py | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/event/event.py b/addons/event/event.py index 9574984ddd5..0b10b1e51ec 100644 --- a/addons/event/event.py +++ b/addons/event/event.py @@ -160,6 +160,8 @@ class event_event(osv.osv): 'email_confirmation_id' : fields.many2one('email.template','Event Confirmation Email', help="If you set an email template, each participant will receive this email announcing the confirmation of the event."), 'reply_to': fields.char('Reply-To Email', size=64, readonly=False, states={'done': [('readonly', True)]}, help="The email address of the organizer is likely to be put here, with the effect to be in the 'Reply-To' of the mails sent automatically at event or registrations confirmation. You can also put the email address of your mail gateway if you use one."), 'address_id': fields.many2one('res.partner','Location', readonly=False, states={'done': [('readonly', True)]}), + 'country_id': fields.related('address_id', 'country_id', + type='many2one', relation='res.country', string='Country', readonly=False, states={'done': [('readonly', True)]}, store=True), 'description': fields.html( 'Description', readonly=False, states={'done': [('readonly', True)]}, diff --git a/addons/website_event/models/event.py b/addons/website_event/models/event.py index 62a50ddbce3..0d2213ecf8e 100644 --- a/addons/website_event/models/event.py +++ b/addons/website_event/models/event.py @@ -101,8 +101,6 @@ class event(osv.osv): 'website_url': fields.function(_website_url, string="Website url", type="char"), 'show_menu': fields.function(_get_show_menu, fnct_inv=_set_show_menu, type='boolean', string='Dedicated Menu'), 'menu_id': fields.many2one('website.menu', 'Event Menu'), - 'country_id': fields.related('address_id', 'country_id', - type='many2one', relation='res.country', string='Country', readonly=False, states={'done': [('readonly', True)]}, store=True), } _defaults = { 'show_menu': False, From b63b03abd0c8109faa32803d2ae32663e1b64133 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 13:26:54 +0100 Subject: [PATCH 12/55] [IMP] better handling of methods for CORS bzr revid: fme@openerp.com-20140130122654-2p481p5hwn033mi7 --- openerp/http.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/openerp/http.py b/openerp/http.py index 35cf8f39a7c..717582e2ec5 100644 --- a/openerp/http.py +++ b/openerp/http.py @@ -960,8 +960,12 @@ class Root(object): # Support for Cross-Origin Resource Sharing if request.func.cors: response.headers.set('Access-Control-Allow-Origin', request.func.cors) - if request.func.methods: - response.headers.set('Access-Control-Allow-Methods', ','.join(request.func.methods)) + methods = 'GET, POST' + if request.func_request_type == 'json': + methods = 'POST' + elif request.func.methods: + methods = ', '.join(request.func.methods) + response.headers.set('Access-Control-Allow-Methods', methods) return response From 9ce7c7d561ba3f2aff9f2eafda1c8dffd05e8b1f Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 13:27:52 +0100 Subject: [PATCH 13/55] [IMP] Use CORS in pos (only two routes) bzr revid: fme@openerp.com-20140130122752-kfgo7u0q0crn3tbr --- addons/hw_proxy/controllers/main.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/addons/hw_proxy/controllers/main.py b/addons/hw_proxy/controllers/main.py index adb59a072b3..e6c19e322d6 100644 --- a/addons/hw_proxy/controllers/main.py +++ b/addons/hw_proxy/controllers/main.py @@ -33,16 +33,11 @@ class Proxy(http.Controller): statuses[driver] = drivers[driver].get_status() return statuses - @http.route('/hw_proxy/hello', type='http', auth='none') + @http.route('/hw_proxy/hello', type='http', auth='none', cors='*') def hello(self): - return request.make_response('ping', { - 'Cache-Control': 'no-cache', - 'Content-Type': 'text/html; charset=utf-8', - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET', - }) + return "ping" - @http.route('/hw_proxy/handshake', type='json', auth='none') + @http.route('/hw_proxy/handshake', type='json', auth='none', cors='*') def handshake(self): return True From d5031cbee897f8fe6fa111a3cfe4f6510aff9e92 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 30 Jan 2014 13:46:06 +0100 Subject: [PATCH 14/55] [ADD] POS: added cors argument to all routes bzr revid: fme@openerp.com-20140130124606-wetmhcjqqvvkv5dy --- addons/hw_escpos/controllers/main.py | 4 +-- addons/hw_proxy/controllers/main.py | 44 +++++++++++++-------------- addons/hw_scanner/controllers/main.py | 4 +-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/addons/hw_escpos/controllers/main.py b/addons/hw_escpos/controllers/main.py index 5b42e97b442..b4312fb94a8 100644 --- a/addons/hw_escpos/controllers/main.py +++ b/addons/hw_escpos/controllers/main.py @@ -259,12 +259,12 @@ hw_proxy.drivers['escpos'] = driver class EscposProxy(hw_proxy.Proxy): - @http.route('/hw_proxy/open_cashbox', type='json', auth='none') + @http.route('/hw_proxy/open_cashbox', type='json', auth='none', cors='*') def open_cashbox(self): _logger.info('ESC/POS: OPEN CASHBOX') driver.push_task('cashbox') - @http.route('/hw_proxy/print_receipt', type='json', auth='none') + @http.route('/hw_proxy/print_receipt', type='json', auth='none', cors='*') def print_receipt(self, receipt): _logger.info('ESC/POS: PRINT RECEIPT') driver.push_task('receipt',receipt) diff --git a/addons/hw_proxy/controllers/main.py b/addons/hw_proxy/controllers/main.py index e6c19e322d6..5293abd1f25 100644 --- a/addons/hw_proxy/controllers/main.py +++ b/addons/hw_proxy/controllers/main.py @@ -41,7 +41,7 @@ class Proxy(http.Controller): def handshake(self): return True - @http.route('/hw_proxy/status', type='http', auth='none') + @http.route('/hw_proxy/status', type='http', auth='none', cors='*') def status_http(self): resp = '\n\n

Hardware Proxy Status

\n' statuses = self.get_status() @@ -70,39 +70,39 @@ class Proxy(http.Controller): 'Access-Control-Allow-Methods': 'GET', }) - @http.route('/hw_proxy/status_json', type='json', auth='none') + @http.route('/hw_proxy/status_json', type='json', auth='none', cors='*') def status_json(self): return self.get_status() - @http.route('/hw_proxy/scan_item_success', type='json', auth='none') + @http.route('/hw_proxy/scan_item_success', type='json', auth='none', cors='*') def scan_item_success(self, ean): """ A product has been scanned with success """ print 'scan_item_success: ' + str(ean) - @http.route('/hw_proxy/scan_item_error_unrecognized', type='json', auth='none') + @http.route('/hw_proxy/scan_item_error_unrecognized', type='json', auth='none', cors='*') def scan_item_error_unrecognized(self, ean): """ A product has been scanned without success """ print 'scan_item_error_unrecognized: ' + str(ean) - @http.route('/hw_proxy/help_needed', type='json', auth='none') + @http.route('/hw_proxy/help_needed', type='json', auth='none', cors='*') def help_needed(self): """ The user wants an help (ex: light is on) """ print "help_needed" - @http.route('/hw_proxy/help_canceled', type='json', auth='none') + @http.route('/hw_proxy/help_canceled', type='json', auth='none', cors='*') def help_canceled(self): """ The user stops the help request """ print "help_canceled" - @http.route('/hw_proxy/weighting_start', type='json', auth='none') + @http.route('/hw_proxy/weighting_start', type='json', auth='none', cors='*') def weighting_start(self): if self.scale == 'closed': print "Opening (Fake) Connection to Scale..." @@ -113,7 +113,7 @@ class Proxy(http.Controller): else: print "WARNING: Scale already Connected !!!" - @http.route('/hw_proxy/weighting_read_kg', type='json', auth='none') + @http.route('/hw_proxy/weighting_read_kg', type='json', auth='none', cors='*') def weighting_read_kg(self): if self.scale == 'open': print "Reading Scale..." @@ -125,7 +125,7 @@ class Proxy(http.Controller): print "WARNING: Reading closed scale !!!" return 0.0 - @http.route('/hw_proxy/weighting_end', type='json', auth='none') + @http.route('/hw_proxy/weighting_end', type='json', auth='none', cors='*') def weighting_end(self): if self.scale == 'open': print "Closing Connection to Scale ..." @@ -136,7 +136,7 @@ class Proxy(http.Controller): else: print "WARNING: Scale already Closed !!!" - @http.route('/hw_proxy/payment_request', type='json', auth='none') + @http.route('/hw_proxy/payment_request', type='json', auth='none', cors='*') def payment_request(self, price): """ The PoS will activate the method payment @@ -144,55 +144,55 @@ class Proxy(http.Controller): print "payment_request: price:"+str(price) return 'ok' - @http.route('/hw_proxy/payment_status', type='json', auth='none') + @http.route('/hw_proxy/payment_status', type='json', auth='none', cors='*') def payment_status(self): print "payment_status" return { 'status':'waiting' } - @http.route('/hw_proxy/payment_cancel', type='json', auth='none') + @http.route('/hw_proxy/payment_cancel', type='json', auth='none', cors='*') def payment_cancel(self): print "payment_cancel" - @http.route('/hw_proxy/transaction_start', type='json', auth='none') + @http.route('/hw_proxy/transaction_start', type='json', auth='none', cors='*') def transaction_start(self): print 'transaction_start' - @http.route('/hw_proxy/transaction_end', type='json', auth='none') + @http.route('/hw_proxy/transaction_end', type='json', auth='none', cors='*') def transaction_end(self): print 'transaction_end' - @http.route('/hw_proxy/cashier_mode_activated', type='json', auth='none') + @http.route('/hw_proxy/cashier_mode_activated', type='json', auth='none', cors='*') def cashier_mode_activated(self): print 'cashier_mode_activated' - @http.route('/hw_proxy/cashier_mode_deactivated', type='json', auth='none') + @http.route('/hw_proxy/cashier_mode_deactivated', type='json', auth='none', cors='*') def cashier_mode_deactivated(self): print 'cashier_mode_deactivated' - @http.route('/hw_proxy/open_cashbox', type='json', auth='none') + @http.route('/hw_proxy/open_cashbox', type='json', auth='none', cors='*') def open_cashbox(self): print 'open_cashbox' - @http.route('/hw_proxy/print_receipt', type='json', auth='none') + @http.route('/hw_proxy/print_receipt', type='json', auth='none', cors='*') def print_receipt(self, receipt): print 'print_receipt' + str(receipt) - @http.route('/hw_proxy/is_scanner_connected', type='json', auth='none') + @http.route('/hw_proxy/is_scanner_connected', type='json', auth='none', cors='*') def print_receipt(self, receipt): print 'is_scanner_connected?' return False - @http.route('/hw_proxy/scanner', type='json', auth='none') + @http.route('/hw_proxy/scanner', type='json', auth='none', cors='*') def print_receipt(self, receipt): print 'scanner' time.sleep(10) return '' - @http.route('/hw_proxy/log', type='json', auth='none') + @http.route('/hw_proxy/log', type='json', auth='none', cors='*') def log(self, arguments): _logger.info(' '.join(str(v) for v in arguments)) - @http.route('/hw_proxy/print_pdf_invoice', type='json', auth='none') + @http.route('/hw_proxy/print_pdf_invoice', type='json', auth='none', cors='*') def print_pdf_invoice(self, pdfinvoice): print 'print_pdf_invoice' + str(pdfinvoice) diff --git a/addons/hw_scanner/controllers/main.py b/addons/hw_scanner/controllers/main.py index 664606954c3..105856a3e28 100644 --- a/addons/hw_scanner/controllers/main.py +++ b/addons/hw_scanner/controllers/main.py @@ -124,7 +124,7 @@ class Scanner(Thread): self.set_status('error',str(e)) return None - @http.route('/hw_proxy/Vis_scanner_connected', type='json', auth='none') + @http.route('/hw_proxy/Vis_scanner_connected', type='json', auth='none', cors='*') def is_scanner_connected(self): return self.get_device() != None @@ -207,7 +207,7 @@ s = Scanner() hw_proxy.drivers['scanner'] = s class ScannerDriver(hw_proxy.Proxy): - @http.route('/hw_proxy/scanner', type='json', auth='none') + @http.route('/hw_proxy/scanner', type='json', auth='none', cors='*') def scanner(self): if not s.isAlive(): s.start() From 369a88a5a1fb9b2dedb46a463c9ad70cad7ba87b Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 30 Jan 2014 16:49:10 +0100 Subject: [PATCH 15/55] [FIX] event_sale, website_event: copy paste errors in views bzr revid: dle@openerp.com-20140130154910-xmg8dehh0zubgif8 --- addons/event_sale/event_sale_view.xml | 2 +- addons/website_event_track/views/event_backend.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/event_sale/event_sale_view.xml b/addons/event_sale/event_sale_view.xml index 9d1df61cd39..955319f5024 100644 --- a/addons/event_sale/event_sale_view.xml +++ b/addons/event_sale/event_sale_view.xml @@ -3,7 +3,7 @@ event.product - product.template + product.product
diff --git a/addons/website_event_track/views/event_backend.xml b/addons/website_event_track/views/event_backend.xml index 5ef9401f00c..aa0a2d10ced 100644 --- a/addons/website_event_track/views/event_backend.xml +++ b/addons/website_event_track/views/event_backend.xml @@ -256,7 +256,7 @@ event.track - + From a2fba1c288d724e6918a71de4c150b101626a8a0 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 30 Jan 2014 16:56:00 +0100 Subject: [PATCH 16/55] [FIX] website_membership: do not display '0' in country list head if there is no result bzr revid: dle@openerp.com-20140130155600-bh412ye3sqsao56p --- addons/website_membership/views/website_membership.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_membership/views/website_membership.xml b/addons/website_membership/views/website_membership.xml index 72d43aeff30..7d9d7b418ab 100644 --- a/addons/website_membership/views/website_membership.xml +++ b/addons/website_membership/views/website_membership.xml @@ -88,7 +88,7 @@
  • - +
  • From 650a0b021c40f58cb69e43732f9d219940987763 Mon Sep 17 00:00:00 2001 From: openerp-sle Date: Thu, 30 Jan 2014 16:58:02 +0100 Subject: [PATCH 17/55] [FIX] website_membership: need to add website_sale in the dependancies list for membership sorting as website_sequence is defined there bzr revid: openerp-sle@openerp-sle.home-20140130155802-f8kuvin9ih41gr48 --- addons/website_membership/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_membership/__openerp__.py b/addons/website_membership/__openerp__.py index 8f4bc905dda..5932507f3d5 100644 --- a/addons/website_membership/__openerp__.py +++ b/addons/website_membership/__openerp__.py @@ -9,7 +9,7 @@ Website for browsing Associations, Groups and Memberships ========================================================= """, 'author': 'OpenERP SA', - 'depends': ['website_partner', 'website_google_map', 'association'], + 'depends': ['website_partner', 'website_google_map', 'association', 'website_sale'], 'data': [ 'views/website_membership.xml', 'security/ir.model.access.csv', From a4a25292e718f5730c9c7641f5fc686930d1ed7e Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 30 Jan 2014 17:11:32 +0100 Subject: [PATCH 18/55] [FIX]website_customer: group by country based on the result of the search, + do not display '0' right to All countries if no result + display 'No result found' bzr revid: dle@openerp.com-20140130161132-cbn9z0i7aphzdrbn --- addons/website_customer/controllers/main.py | 6 +++--- addons/website_customer/views/website_customer.xml | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/addons/website_customer/controllers/main.py b/addons/website_customer/controllers/main.py index be9f95d0d94..921e88141f1 100644 --- a/addons/website_customer/controllers/main.py +++ b/addons/website_customer/controllers/main.py @@ -37,12 +37,12 @@ class WebsiteCustomer(http.Controller): if country_id: domain += [('country_id', '=', country_id)] - # group by country, based on all customers (base domain) + # group by country, based on customers found with the search(domain) countries = partner_obj.read_group( - cr, openerp.SUPERUSER_ID, base_domain, ["id", "country_id"], + cr, openerp.SUPERUSER_ID, domain, ["id", "country_id"], groupby="country_id", orderby="country_id", context=request.context) country_count = partner_obj.search( - cr, openerp.SUPERUSER_ID, base_domain, count=True, context=request.context) + cr, openerp.SUPERUSER_ID, domain, count=True, context=request.context) countries.insert(0, { 'country_id_count': country_count, 'country_id': (0, _("All Countries")) diff --git a/addons/website_customer/views/website_customer.xml b/addons/website_customer/views/website_customer.xml index 64eeb3220a4..e5b8cc44ecd 100644 --- a/addons/website_customer/views/website_customer.xml +++ b/addons/website_customer/views/website_customer.xml @@ -39,6 +39,9 @@
    + +

    No result found.

    +
    @@ -79,7 +82,7 @@
  • - +
  • From 78fefd54f069ea050c4502b3f49e8b1042102110 Mon Sep 17 00:00:00 2001 From: Olivier Dony Date: Thu, 30 Jan 2014 17:26:15 +0100 Subject: [PATCH 19/55] [IMP] website tests: unicode test attributes to avoid warnings in auto_init when comparing attr values bzr revid: odo@openerp.com-20140130162615-nx7f3nhifwqo357u --- addons/website/models/test_models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/website/models/test_models.py b/addons/website/models/test_models.py index d028cdd9864..107b8ae3e35 100644 --- a/addons/website/models/test_models.py +++ b/addons/website/models/test_models.py @@ -24,8 +24,8 @@ class test_converter(orm.Model): ('B', "Qu'il était supposé arriver à Toronto"), ('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"), ('D', "La réponse D"), - ], string="Lorsqu'un pancake prend l'avion à destination de Toronto et " - "qu'il fait une escale technique à St Claude, on dit:"), + ], string=u"Lorsqu'un pancake prend l'avion à destination de Toronto et " + u"qu'il fait une escale technique à St Claude, on dit:"), 'html': fields.html(), 'text': fields.text(), } From 3b48a82af5ee314cd4b7371a6dec8d05f93e7df9 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 30 Jan 2014 17:33:21 +0100 Subject: [PATCH 20/55] [FIX] events bzr revid: fp@tinyerp.com-20140130163321-f86eq7obsua6x6z9 --- addons/event/__init__.py | 2 -- addons/website_event/__openerp__.py | 2 -- addons/website_event/controllers/main.py | 23 ++++++------------- addons/website_event/models/event.py | 21 +++++++++-------- addons/website_event/views/website_event.xml | 9 ++++---- addons/website_event_sale/controllers/main.py | 16 +++++++++++++ addons/website_event_track/__openerp__.py | 11 +++++++-- .../website_event_track/controllers/event.py | 5 +--- addons/website_event_track/models/event.py | 21 ++++++++--------- 9 files changed, 59 insertions(+), 51 deletions(-) diff --git a/addons/event/__init__.py b/addons/event/__init__.py index ce8b64ed9a9..d653a6d4081 100644 --- a/addons/event/__init__.py +++ b/addons/event/__init__.py @@ -23,5 +23,3 @@ import event import wizard import report import res_partner -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/website_event/__openerp__.py b/addons/website_event/__openerp__.py index 399a6a17fb8..b04758b0d55 100644 --- a/addons/website_event/__openerp__.py +++ b/addons/website_event/__openerp__.py @@ -7,8 +7,6 @@ 'version': '1.0', 'description': """ Online Events -============= - """, 'author': 'OpenERP SA', 'depends': ['website', 'website_partner', 'website_mail', 'event'], diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index 21b984f6888..83e2c45f75b 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -145,6 +145,8 @@ class website_event(http.Controller): events_ids = event_obj.browse(request.cr, request.uid, obj_ids, context=request.context) + for d in dates: + print '***', d values = { 'current_date': current_date, 'current_country': current_country, @@ -184,7 +186,6 @@ class website_event(http.Controller): 'event': event, 'main_object': event, 'range': range, - 'main_object': event, } return request.website.render("website_event.event_description_full", values) @@ -202,25 +203,15 @@ class website_event(http.Controller): @http.route('/event/add_event/', type='http', auth="user", multilang=True, methods=['POST'], website=True) def add_event(self, event_name="New Event", **kwargs): - Event = request.registry.get('event.event') - date_begin = datetime.today() + timedelta(days=(15)) # FIXME: better defaults + return self._add_event(event_name, request.context, **kwargs) + def _add_event(self, event_name="New Event", context={}, **kwargs): + Event = request.registry.get('event.event') + date_begin = datetime.today() + timedelta(days=(14)) vals = { 'name': event_name, 'date_begin': date_begin.strftime('%Y-%m-%d'), 'date_end': (date_begin + timedelta(days=(1))).strftime('%Y-%m-%d'), } - try: - dummy, res_id = request.registry.get('ir.model.data').get_object_reference(request.cr, request.uid, 'event_sale', 'product_product_event') - vals['event_ticket_ids'] = [[0,0,{ - 'name': _('Subscription'), - 'product_id': res_id, - 'deadline' : vals.get('date_begin'), - 'price': 0, - }]] - except ValueError: - pass - - event_id = Event.create(request.cr, request.uid, vals, context=request.context) - + event_id = Event.create(request.cr, request.uid, vals, context=context) return request.redirect("/event/%s/?enable_editor=1" % event_id) diff --git a/addons/website_event/models/event.py b/addons/website_event/models/event.py index 0d2213ecf8e..33eee7c7829 100644 --- a/addons/website_event/models/event.py +++ b/addons/website_event/models/event.py @@ -25,6 +25,8 @@ from openerp import SUPERUSER_ID from openerp.tools.translate import _ import re +from openerp.addons.website.models.website import slug + class event(osv.osv): _name = 'event.event' @@ -41,7 +43,7 @@ class event(osv.osv): for name,path in todo: name2 = name+' '+event.name newpath = web.new_page(cr, uid, name2, path, ispage=False, context=context) - url = "/event/"+str(event.id)+"/page/" + newpath + url = "/event/"+slug(event)+"/page/" + newpath result.append((name, url)) return result @@ -56,7 +58,7 @@ class event(osv.osv): 'name': event.name }, context=context) tocreate = self._get_new_menu_pages(cr, uid, event, context) - tocreate.append((_('Register'), '/event/%s/register' % str(event.id))) + tocreate.append((_('Register'), '/event/%s/register' % slug(event))) sequence = 0 for name,url in tocreate: menuobj.create(cr, uid, { @@ -77,14 +79,13 @@ class event(osv.osv): def _website_url(self, cr, uid, ids, field_name, arg, context=None): res = dict.fromkeys(ids, '') - base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url') for event in self.browse(cr, uid, ids, context=context): - res[event.id] = "%s/event/%s/" % (base_url, event.id) + res[event.id] = "/event/" + slug(event) return res def _default_hashtag(self, cr, uid, context={}): name = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.name - return re.sub("[- \\.\\(\\)]+", "", name).lower() + return re.sub("[- \\.\\(\\)\\@\\#\\&]+", "", name).lower() _columns = { 'twitter_hashtag': fields.char('Twitter Hashtag'), @@ -108,12 +109,14 @@ class event(osv.osv): } def google_map_img(self, cr, uid, ids, zoom=8, width=298, height=298, context=None): - partner = self.browse(cr, uid, ids[0], context=context) - if partner.address_id: + event = self.browse(cr, uid, ids[0], context=context) + if event.address_id: return self.browse(cr, SUPERUSER_ID, ids[0], context=context).address_id.google_map_img() + return None def google_map_link(self, cr, uid, ids, zoom=8, context=None): - partner = self.browse(cr, uid, ids[0], context=context) - if partner.address_id: + event = self.browse(cr, uid, ids[0], context=context) + if event.address_id: return self.browse(cr, SUPERUSER_ID, ids[0], context=context).address_id.google_map_link() + return None diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index bb536795adc..e6235e87b4a 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -127,7 +127,7 @@ - + + From f85065930eb612456bada99b7f5492f3a6036868 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 30 Jan 2014 20:37:06 +0100 Subject: [PATCH 36/55] [FIX]website_customer, website_crm_partner_assign: keep search if jump between countries, and keep countries if do a new search. bzr revid: dle@openerp.com-20140130193706-xxn668p2edr69zue --- addons/website_crm_partner_assign/controllers/main.py | 4 +--- .../views/website_crm_partner_assign.xml | 2 +- addons/website_customer/controllers/main.py | 9 ++++++++- addons/website_customer/views/website_customer.xml | 4 ++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/addons/website_crm_partner_assign/controllers/main.py b/addons/website_crm_partner_assign/controllers/main.py index da05075445a..17a666cf2e3 100644 --- a/addons/website_crm_partner_assign/controllers/main.py +++ b/addons/website_crm_partner_assign/controllers/main.py @@ -1,14 +1,12 @@ # -*- coding: utf-8 -*- -import werkzeug.urls - import openerp from openerp import SUPERUSER_ID from openerp.addons.web import http from openerp.tools.translate import _ from openerp.addons.web.http import request from openerp.addons.website_partner.controllers import main as website_partner - +import werkzeug.urls class WebsiteCrmPartnerAssign(http.Controller): _references_per_page = 20 diff --git a/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml b/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml index a0082fb929c..9906eaf87c6 100644 --- a/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml +++ b/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml @@ -55,7 +55,7 @@ pull-left -