diff options
| author | Darshan Kalola (OpenERP) <dka@tinyerp.com> | 2014-01-21 11:16:38 +0530 |
|---|---|---|
| committer | Darshan Kalola (OpenERP) <dka@tinyerp.com> | 2014-01-21 11:16:38 +0530 |
| commit | 9ce241349f3f35b6c75a2aaf9cf7c1ce0006cd7e (patch) | |
| tree | e6451193117385b322fd13e1c0f127383614d7e8 /addons | |
| parent | 69e88b3fecf9b09589c4f5c46336dc0f71bf8db2 (diff) | |
| parent | 53d8280f1de508f228419654b631ba8286c03388 (diff) | |
[MERGE] with lp:~openerp-dev/openobject-addons/trunk-website-al and removed temporary solution.
bzr revid: dka@tinyerp.com-20140121054638-b7hbckj39vsk93tm
Diffstat (limited to 'addons')
58 files changed, 691 insertions, 520 deletions
diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 6aacc47a2e0..343512dc271 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -123,7 +123,7 @@ for a particular financial year and for preparation of vouchers there is a modul 'edi/invoice_action_data.xml', 'account_bank_view.xml', 'res_config_view.xml', - #'account_pre_install.yml' + 'account_pre_install.yml' ], 'js': [ 'static/src/js/account_move_reconciliation.js', diff --git a/addons/delivery/delivery_demo.xml b/addons/delivery/delivery_demo.xml index 9c412b24957..1881c8b6608 100644 --- a/addons/delivery/delivery_demo.xml +++ b/addons/delivery/delivery_demo.xml @@ -32,6 +32,7 @@ <record id="delivery_carrier" model="delivery.carrier"> <field name="name">The Poste</field> + <field name="normal_price">20</field> <field name="partner_id" ref="res_partner_23"/> <field name="product_id" ref="product_product_delivery"/> </record> diff --git a/addons/payment_acquirer_adyen/controllers/main.py b/addons/payment_acquirer_adyen/controllers/main.py index f1f15bddf8d..5528b8824ba 100644 --- a/addons/payment_acquirer_adyen/controllers/main.py +++ b/addons/payment_acquirer_adyen/controllers/main.py @@ -2,7 +2,6 @@ from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website try: import simplejson as json @@ -17,9 +16,9 @@ _logger = logging.getLogger(__name__) class AdyenController(http.Controller): _return_url = '/payment/adyen/return/' - @website.route([ + @http.route([ '/payment/adyen/return/', - ], type='http', auth='public') + ], type='http', auth='public', website=True) def adyen_return(self, pspReference, **post): """ Paypal IPN.""" post["pspReference"] = pspReference diff --git a/addons/payment_acquirer_ogone/controllers/main.py b/addons/payment_acquirer_ogone/controllers/main.py index 0e302d90019..fa58db07e49 100644 --- a/addons/payment_acquirer_ogone/controllers/main.py +++ b/addons/payment_acquirer_ogone/controllers/main.py @@ -4,7 +4,6 @@ import pprint from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website _logger = logging.getLogger(__name__) @@ -15,12 +14,12 @@ class OgoneController(http.Controller): _exception_url = '/payment/ogone/test/exception' _cancel_url = '/payment/ogone/test/cancel' - @website.route([ + @http.route([ '/payment/ogone/accept', '/payment/ogone/test/accept', '/payment/ogone/decline', '/payment/ogone/test/decline', '/payment/ogone/exception', '/payment/ogone/test/exception', '/payment/ogone/cancel', '/payment/ogone/test/cancel', - ], type='http', auth='admin') + ], type='http', auth='admin', website=True) def ogone_form_feedback(self, **post): """ Ogone contacts using GET, at least for accept """ _logger.info('Ogone: entering form_feedback with post data %s', pprint.pformat(post)) # debug diff --git a/addons/payment_acquirer_paypal/controllers/main.py b/addons/payment_acquirer_paypal/controllers/main.py index d5ec93909af..a2bf54ea36b 100644 --- a/addons/payment_acquirer_paypal/controllers/main.py +++ b/addons/payment_acquirer_paypal/controllers/main.py @@ -11,7 +11,6 @@ import urllib2 from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website _logger = logging.getLogger(__name__) @@ -54,18 +53,18 @@ class PaypalController(http.Controller): _logger.warning('Paypal: unrecognized paypal answer, received %s instead of VERIFIED or INVALID' % resp.text) return res - @website.route([ + @http.route([ '/payment/paypal/ipn/', - ], type='http', auth='public', methods=['POST']) + ], type='http', auth='public', methods=['POST'], website=True) def paypal_ipn(self, **post): """ Paypal IPN. """ _logger.info('Beginning Paypal IPN form_feedback with post data %s', pprint.pformat(post)) # debug self.paypal_validate_data(**post) return '' - @website.route([ + @http.route([ '/payment/paypal/dpn', - ], type='http', auth="public", methods=['POST']) + ], type='http', auth="public", methods=['POST'], website=True) def paypal_dpn(self, **post): """ Paypal DPN """ _logger.info('Beginning Paypal DPN form_feedback with post data %s', pprint.pformat(post)) # debug @@ -73,9 +72,9 @@ class PaypalController(http.Controller): self.paypal_validate_data(**post) return request.redirect(return_url) - @website.route([ + @http.route([ '/payment/paypal/cancel', - ], type='http', auth="public") + ], type='http', auth="public", website=True) def paypal_cancel(self, **post): """ When the user cancels its Paypal payment: GET on this route """ cr, uid, context = request.cr, request.uid, request.context diff --git a/addons/payment_acquirer_transfer/controllers/main.py b/addons/payment_acquirer_transfer/controllers/main.py index 6d0a7c1fa6f..2f1be63179e 100644 --- a/addons/payment_acquirer_transfer/controllers/main.py +++ b/addons/payment_acquirer_transfer/controllers/main.py @@ -4,7 +4,6 @@ import pprint from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website _logger = logging.getLogger(__name__) @@ -12,9 +11,9 @@ _logger = logging.getLogger(__name__) class OgoneController(http.Controller): _accept_url = '/payment/transfer/feedback' - @website.route([ + @http.route([ '/payment/transfer/feedback', - ], type='http', auth='admin') + ], type='http', auth='admin', website=True) def transfer_form_feedback(self, **post): cr, uid, context = request.cr, request.uid, request.context _logger.info('Beginning form_feedback with post data %s', pprint.pformat(post)) # debug diff --git a/addons/point_of_sale/static/src/js/db.js b/addons/point_of_sale/static/src/js/db.js index 077a2399c55..e4dc633e0f6 100644 --- a/addons/point_of_sale/static/src/js/db.js +++ b/addons/point_of_sale/static/src/js/db.js @@ -145,7 +145,7 @@ function openerp_pos_db(instance, module){ for(var i = 0, len = products.length; i < len; i++){ var product = products[i]; var search_string = this._product_search_string(product); - var categ_id = product.public_categ_id ? product.public_categ_id[0] : this.root_category_id; + var categ_id = product.pos_categ_id ? product.pos_categ_id[0] : this.root_category_id; if(!stored_categories[categ_id]){ stored_categories[categ_id] = []; } diff --git a/addons/point_of_sale/static/src/js/models.js b/addons/point_of_sale/static/src/js/models.js index 87d90a503fd..a626b20b77e 100644 --- a/addons/point_of_sale/static/src/js/models.js +++ b/addons/point_of_sale/static/src/js/models.js @@ -197,25 +197,19 @@ function openerp_pos_models(instance, module){ //module is instance.point_of_sal }).then(function(packagings){ self.db.add_packagings(packagings); + return self.fetch('pos.category', ['id','name','parent_id','child_id','image']) + }).then(function(categories){ + self.db.add_categories(categories); + return self.fetch( 'product.product', - ['name', 'list_price','price', 'public_categ_id', 'taxes_id', 'ean13', 'default_code', + ['name', 'list_price','price','pos_categ_id', 'taxes_id', 'ean13', 'default_code', 'to_weight', 'uom_id', 'uos_id', 'uos_coeff', 'mes_type', 'description_sale', 'description'], [['sale_ok','=',true],['available_in_pos','=',true]], {pricelist: self.pricelist.id} // context for price ); }).then(function(products){ - self.tmp_products = products; - - var category_ids = _.without(_.uniq(_.map(products, function (product) {return product.public_categ_id[0] || 0;})), 0); - return self.fetch( - 'product.public.category', - ['id','name','parent_id','child_id','image'], - ['|', ['id','=',category_ids], ['child_id','=',category_ids]] - ); - }).then(function(categories){ - self.db.add_categories(categories); - self.db.add_products(self.tmp_products); + self.db.add_products(products); return self.fetch( 'account.bank.statement', diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index 0a5ac130246..9118ba15ea6 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -436,7 +436,8 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa }, get_image_url: function(category){ - return instance.session.url('/web/binary/image', {model: 'product.public.category', field: 'image_medium', id: category.id}); + return window.location.origin + '/web/binary/image?model=pos.category&field=image_medium&id='+category.id; + }, render_category: function( category, with_image ){ var cached = this.category_cache.get_node(category.id); diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 2ebdc2ba163..56132472a17 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -29,8 +29,9 @@ logger = logging.getLogger(__name__) NOPE = object() # Completely arbitrary limits MAX_IMAGE_WIDTH, MAX_IMAGE_HEIGHT = IMAGE_LIMITS = (1024, 768) + class Website(openerp.addons.web.controllers.main.Home): - @website.route('/', type='http', auth="public", multilang=True) + @http.route('/', type='http', auth="public", website=True, multilang=True) def index(self, **kw): try: main_menu = request.registry['ir.model.data'].get_object(request.cr, request.uid, 'website', 'main_menu') @@ -41,7 +42,7 @@ class Website(openerp.addons.web.controllers.main.Home): pass return self.page("website.homepage") - @website.route('/pagenew/<path:path>', type='http', auth="user") + @http.route('/pagenew/<path:path>', type='http', auth="user") def pagenew(self, path, noredirect=NOPE): web = request.registry['website'] try: @@ -59,7 +60,7 @@ class Website(openerp.addons.web.controllers.main.Home): return werkzeug.wrappers.Response(url, mimetype='text/plain') return werkzeug.utils.redirect(url) - @website.route('/website/theme_change', type='http', auth="admin") + @http.route('/website/theme_change', type='http', auth="admin", website=True) def theme_change(self, theme_id=False, **kwargs): imd = request.registry['ir.model.data'] view = request.registry['ir.ui.view'] @@ -81,25 +82,33 @@ class Website(openerp.addons.web.controllers.main.Home): return request.website.render('website.themes', {'theme_changed': True}) - @website.route(['/website/snippets'], type='json', auth="public") + @http.route(['/website/snippets'], type='json', auth="public", website=True) def snippets(self): return request.website._render('website.snippets') - @website.route('/page/<page:page>', type='http', auth="public", multilang=True) + @http.route('/page/<page:page>', type='http', auth="public", website=True, multilang=True) def page(self, page, **opt): values = { 'path': page, } + # allow shortcut for /page/<website_xml_id> + if '.' not in page: + page = 'website.%s' % page + try: - request.website.get_template(page) - except (Exception), e: + module, xmlid = page.split('.', 1) + model, view_id = request.registry["ir.model.data"].get_object_reference(request.cr, request.uid, module, xmlid) + values['main_object'] = request.registry["ir.ui.view"].browse(request.cr, request.uid, view_id, context=request.context) + except ValueError, e: + # page not found if request.context['editable']: page = 'website.page_404' else: return request.registry['ir.http']._handle_exception(e, 404) + return request.website.render(page, values) - @website.route('/website/reset_templates', type='http', auth='user', methods=['POST']) + @http.route('/website/reset_templates', type='http', auth='user', methods=['POST'], website=True) def reset_template(self, templates, redirect='/'): templates = request.httprequest.form.getlist('templates') modules_to_update = [] @@ -115,7 +124,7 @@ class Website(openerp.addons.web.controllers.main.Home): module_obj.button_immediate_upgrade(request.cr, request.uid, module_ids, context=request.context) return request.redirect(redirect) - @website.route('/website/customize_template_toggle', type='json', auth='user') + @http.route('/website/customize_template_toggle', type='json', auth='user', website=True) def customize_template_set(self, view_id): view_obj = request.registry.get("ir.ui.view") view = view_obj.browse(request.cr, request.uid, int(view_id), @@ -129,7 +138,7 @@ class Website(openerp.addons.web.controllers.main.Home): }, context=request.context) return True - @website.route('/website/customize_template_get', type='json', auth='user') + @http.route('/website/customize_template_get', type='json', auth='user', website=True) def customize_template_get(self, xml_id, optional=True): imd = request.registry['ir.model.data'] view_model, view_theme_id = imd.get_object_reference( @@ -164,7 +173,7 @@ class Website(openerp.addons.web.controllers.main.Home): }) return result - @website.route('/website/get_view_translations', type='json', auth='admin') + @http.route('/website/get_view_translations', type='json', auth='admin', website=True) def get_view_translations(self, xml_id, lang=None): lang = lang or request.context.get('lang') views = self.customize_template_get(xml_id, optional=False) @@ -173,7 +182,7 @@ class Website(openerp.addons.web.controllers.main.Home): irt = request.registry.get('ir.translation') return irt.search_read(request.cr, request.uid, domain, ['id', 'res_id', 'value'], context=request.context) - @website.route('/website/set_translations', type='json', auth='admin') + @http.route('/website/set_translations', type='json', auth='admin', website=True) def set_translations(self, data, lang): irt = request.registry.get('ir.translation') for view_id, trans in data.items(): @@ -208,7 +217,7 @@ class Website(openerp.addons.web.controllers.main.Home): irt.create(request.cr, request.uid, new_trans) return True - @website.route('/website/attach', type='http', auth='user') + @http.route('/website/attach', type='http', auth='user', website=True) def attach(self, func, upload): req = request.httprequest if req.method != 'POST': @@ -238,7 +247,7 @@ class Website(openerp.addons.web.controllers.main.Home): window.parent['%s'](%s, %s); </script>""" % (func, json.dumps(url), json.dumps(message)) - @website.route(['/website/publish'], type='json', auth="public") + @http.route(['/website/publish'], type='json', auth="public", website=True) def publish(self, id, object): _id = int(id) _object = request.registry[object] @@ -255,23 +264,23 @@ class Website(openerp.addons.web.controllers.main.Home): obj = _object.browse(request.cr, request.uid, _id) return bool(obj.website_published) - @website.route(['/website/kanban/'], type='http', auth="public", methods=['POST']) + @http.route(['/website/kanban/'], type='http', auth="public", methods=['POST'], website=True) def kanban(self, **post): return request.website.kanban_col(**post) - @website.route(['/robots.txt'], type='http', auth="public") + @http.route(['/robots.txt'], type='http', auth="public", website=True) def robots(self): response = request.website.render('website.robots', {'url_root': request.httprequest.url_root}) response.mimetype = 'text/plain' return response - @website.route('/sitemap', type='http', auth='public', multilang=True) + @http.route('/sitemap', type='http', auth='public', website=True, multilang=True) def sitemap(self): return request.website.render('website.sitemap', { 'pages': request.website.enumerate_pages() }) - @website.route('/sitemap.xml', type='http', auth="public") + @http.route('/sitemap.xml', type='http', auth="public", website=True) def sitemap_xml(self): response = request.website.render('website.sitemap_xml', { 'pages': request.website.enumerate_pages() @@ -289,7 +298,7 @@ class Images(http.Controller): response.set_data(f.read()) return response.make_conditional(request.httprequest) - @website.route('/website/image', auth="public") + @http.route('/website/image', auth="public", website=True) def image(self, model, id, field, max_width=maxint, max_height=maxint): Model = request.registry[model] @@ -354,5 +363,4 @@ class Images(http.Controller): return response - # vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/website/data/website_data.xml b/addons/website/data/website_data.xml index e8fdd2abfc0..9e01abd2009 100644 --- a/addons/website/data/website_data.xml +++ b/addons/website/data/website_data.xml @@ -150,11 +150,11 @@ </record> <record model="ir.attachment"> - <field name="name">landscape_tree</field> - <field name="datas_fname">landscape_tree.jpg</field> + <field name="name">imac</field> + <field name="datas_fname">imac.png</field> <field name="res_model">ir.ui.view</field> <field name="type">url</field> - <field name="url">/website/static/src/img/library/landscape_tree.jpg</field> + <field name="url">/website/static/src/img/library/imac.png</field> </record> <record model="ir.attachment"> @@ -174,11 +174,11 @@ </record> <record model="ir.attachment"> - <field name="name">personal_laptop</field> - <field name="datas_fname">personal_laptop.jpg</field> + <field name="name">ipad</field> + <field name="datas_fname">ipad.png</field> <field name="res_model">ir.ui.view</field> <field name="type">url</field> - <field name="url">/website/static/src/img/library/personal_laptop.jpg</field> + <field name="url">/website/static/src/img/library/ipad.png</field> </record> <record model="ir.attachment"> diff --git a/addons/website/models/ir_http.py b/addons/website/models/ir_http.py index a550ab4fcbc..79db7aa4628 100644 --- a/addons/website/models/ir_http.py +++ b/addons/website/models/ir_http.py @@ -38,15 +38,15 @@ class ir_http(orm.AbstractModel): func = None try: func, arguments = self._find_handler() - request.cms = getattr(func, 'cms', False) + request.website_enabled = func.routing.get('website', False) except werkzeug.exceptions.NotFound: # either we have a language prefixed route, either a real 404 # in all cases, website processes them - request.cms = True + request.website_enabled = True - if request.cms: + if request.website_enabled: if func: - self._authenticate(getattr(func, 'auth', None)) + self._authenticate(func.routing['auth']) else: self._auth_method_public() request.website = request.registry['website'].get_current_website(request.cr, request.uid, context=request.context) @@ -82,7 +82,7 @@ class ir_http(orm.AbstractModel): def _handle_exception(self, exception=None, code=500): if isinstance(exception, werkzeug.exceptions.HTTPException) and exception.response: return exception.response - if getattr(request, 'cms', False) and request.website: + if getattr(request, 'website_enabled', False) and request.website: values = dict( exception=exception, traceback=traceback.format_exc(exception), diff --git a/addons/website/models/website.py b/addons/website/models/website.py index ccdfe449617..8303220e7af 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- import fnmatch -import functools import inspect import logging import math @@ -17,19 +16,11 @@ import openerp from openerp.osv import orm, osv, fields from openerp.tools.safe_eval import safe_eval -from openerp.addons.web import http from openerp.addons.web.http import request, LazyResponse from ..utils import slugify logger = logging.getLogger(__name__) -def route(routes, *route_args, **route_kwargs): - def decorator(f): - f.cms = True - f.multilang = route_kwargs.pop('multilang', False) - return http.route(routes, *route_args, **route_kwargs)(f) - return decorator - def url_for(path_or_uri, lang=None, keep_query=None): location = path_or_uri.strip() url = urlparse.urlparse(location) @@ -101,7 +92,7 @@ class website(osv.osv): def _get_menu_website(self, cr, uid, ids, context=None): # IF a menu is changed, update all websites return self.search(cr, uid, [], context=context) - + def _get_menu(self, cr, uid, ids, name, arg, context=None): root_domain = [('parent_id', '=', False)] menus = self.pool.get('website.menu').search(cr, uid, root_domain, order='id', context=context) @@ -178,9 +169,7 @@ class website(osv.osv): page = self.page_for_name(cr, uid, ids, name, module=module, context=context) try: - return self.get_template( - cr, uid, ids, template=page, context=context - ).exists() + self.pool["ir.model.data"].get_object_reference(cr, uid, module, name) except: return False @@ -193,6 +182,7 @@ class website(osv.osv): def _get_languages(self, cr, uid, id, context=None): website = self.browse(cr, uid, id) return [(lg.code, lg.name) for lg in website.language_ids] + def get_languages(self, cr, uid, ids, context=None): return self._get_languages(cr, uid, ids[0]) @@ -218,28 +208,19 @@ class website(osv.osv): translatable=not is_master_lang, ) - def get_template(self, cr, uid, ids, template, context=None): - IMD = self.pool["ir.model.data"] - try: - module, xmlid = template.split('.', 1) - model, id = IMD.get_object_reference(cr, uid, module, xmlid) - except ValueError: # catches both unpack errors and gor errors - module, xmlid = 'website', template - model, id = IMD.get_object_reference(cr, uid, module, xmlid) - return self.pool["ir.ui.view"].browse(cr, uid, id, context=context) - def _render(self, cr, uid, ids, template, values=None, context=None): user = self.pool.get("res.users") if not context: context = {} - qweb_context = context.copy() - + # Take a context + qweb_values = context.copy() + # add some values if values: - qweb_context.update(values) - - qweb_context.update( - request=request, # TODO maybe rename to _request to mark this attribute as unsafe + qweb_values.update(values) + # fill some defaults + qweb_values.update( + request=request, json=simplejson, website=request.website, url_for=url_for, @@ -248,17 +229,12 @@ class website(osv.osv): user_id=user.browse(cr, uid, uid), quote_plus=quote_plus, ) + qweb_values.setdefault('editable', False) - context.update( - inherit_branding=qweb_context.setdefault('editable', False), - ) - - view = self.get_template(cr, uid, ids, template) + # in edit mode ir.ui.view will tag nodes + context['inherit_branding']=qweb_values['editable'] - if 'main_object' not in qweb_context: - qweb_context['main_object'] = view - #context['debug'] = True - result = view.render(qweb_context, engine='website.qweb', context=context) + result = self.pool['ir.ui.view'].render(cr, uid, template, qweb_values, engine='website.qweb', context=context) return result def render(self, cr, uid, ids, template, values=None, status_code=None, context=None): @@ -328,10 +304,10 @@ class website(osv.osv): converters = rule._converters.values() return ( - 'GET' in methods - and endpoint.exposed == 'http' - and endpoint.auth in ('none', 'public') - and getattr(endpoint, 'cms', False) + 'GET' in methods + and endpoint.routing['type'] == 'http' + and endpoint.routing['auth'] in ('none', 'public') + and endpoint.routing.get('website', False) # preclude combinatorial explosion by only allowing a single converter and len(converters) <= 1 # ensure all converters on the rule are able to generate values for @@ -513,7 +489,6 @@ class website(osv.osv): html += request.website._render(template, {'object_id': object_id}) return html - class website_menu(osv.osv): _name = "website.menu" _description = "Website Menu" @@ -669,3 +644,5 @@ class SeoMetadata(osv.Model): 'website_meta_description': fields.text("Website meta description", size=160, translate=True), 'website_meta_keywords': fields.char("Website meta keywords", translate=True), } + +# vim:et: diff --git a/addons/website/security/ir.model.access.csv b/addons/website/security/ir.model.access.csv index 86d258edc5c..ef63a63d220 100644 --- a/addons/website/security/ir.model.access.csv +++ b/addons/website/security/ir.model.access.csv @@ -1,5 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_website_public,website,website.model_website,base.group_public,1,0,0,0 +access_website_public,website,website.model_website,,1,0,0,0 access_website,website,website.model_website,base.group_user,1,0,0,0 access_website_menu,access_website_menu,model_website_menu,,1,0,0,0 access_website_converter_test,access_website_converter_test,model_website_converter_test,,1,1,1,1 @@ -17,5 +17,5 @@ access_website_qweb_field_html,access_website_qweb_field_html,model_website_qweb access_website_qweb_field_image,access_website_qweb_field_image,model_website_qweb_field_image,,0,0,0,0 access_website_qweb_field_monetary,access_website_qweb_field_monetary,model_website_qweb_field_monetary,,0,0,0,0 access_website_ir_ui_view,access_website_ir_ui_view,model_ir_ui_view,base.group_website_designer,1,1,1,1 -access_seo_public,access_seo_public,model_website_seo_metadata,base.group_public,1,0,0,0 +access_seo_public,access_seo_public,model_website_seo_metadata,,1,0,0,0 access_seo_designer,access_seo_designer,model_website_seo_metadata,base.group_website_designer,1,1,1,1 diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index f14a193ee16..72053e130f2 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -95,6 +95,13 @@ h1.text-muted, h2.text-muted, h3.text-muted { margin-top: 10px; } +header a.navbar-brand.logo { + padding: 0 15px; +} +header a.navbar-brand img { + max-height: 50px; +} + /* ----- BOOTSTRAP FIX ----- */ .container .container { padding-left: 0; @@ -167,7 +174,7 @@ footer { } .oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before { - content: "This page is under construction"; + content: "Page under construction"; text-align: center; display: block; padding-top: 160px; diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass index 69a50c0710b..7c1825d6670 100644 --- a/addons/website/static/src/css/website.sass +++ b/addons/website/static/src/css/website.sass @@ -61,6 +61,13 @@ img.shadow h1.text-muted, h2.text-muted, h3.text-muted margin-top: 10px +header + a.navbar-brand.logo + padding: 0 15px + a.navbar-brand + img + max-height: 50px + /* ----- BOOTSTRAP FIX ----- */ .container @@ -125,7 +132,7 @@ footer position: static .oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before - content: 'This page is under construction' + content: 'Page under construction' text-align: center display: block padding-top: 160px diff --git a/addons/website/static/src/img/library/imac.png b/addons/website/static/src/img/library/imac.png Binary files differnew file mode 100644 index 00000000000..da52d86f356 --- /dev/null +++ b/addons/website/static/src/img/library/imac.png diff --git a/addons/website/static/src/img/library/ipad.png b/addons/website/static/src/img/library/ipad.png Binary files differnew file mode 100644 index 00000000000..455032a4be9 --- /dev/null +++ b/addons/website/static/src/img/library/ipad.png diff --git a/addons/website/static/src/img/library/landscape_tree.jpg b/addons/website/static/src/img/library/landscape_tree.jpg Binary files differdeleted file mode 100644 index fd5c9446c7b..00000000000 --- a/addons/website/static/src/img/library/landscape_tree.jpg +++ /dev/null diff --git a/addons/website/static/src/img/library/personal_laptop.jpg b/addons/website/static/src/img/library/personal_laptop.jpg Binary files differdeleted file mode 100644 index 069487766dd..00000000000 --- a/addons/website/static/src/img/library/personal_laptop.jpg +++ /dev/null diff --git a/addons/website/static/src/img/odoo_logo.png b/addons/website/static/src/img/odoo_logo.png Binary files differnew file mode 100644 index 00000000000..4ba081e1d42 --- /dev/null +++ b/addons/website/static/src/img/odoo_logo.png diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 67e7277d0c5..e687dbb6a31 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -638,16 +638,14 @@ var $selected = $(this); var position = $selected.offset(); if ($selected.is('img')) { - var image_top = position.top + parseInt($selected.css('marginTop'), 10); - var image_left = position.left + parseInt($selected.css('marginLeft'), 10); $link_button.hide(); // center button on image $image_button.show().offset({ top: $selected.outerHeight() / 2 - + image_top + + position.top - $image_button.outerHeight() / 2, left: $selected.outerWidth() / 2 - + image_left + + position.left - $image_button.outerWidth() / 2, }); } else { diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index e15a647da19..1d28df08c75 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -1126,8 +1126,6 @@ var grid = [-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11]; this.grid.w = [_.map(grid, function (v) {return 'col-md-offset-'+v;}), _.map(grid, function (v) {return width/12*v;}), 12]; - this.grid.s = null; - return this.grid; }, _drag_and_drop_after_insert_dropzone: function(){ diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index 3e1763c0e20..6a50c0c404d 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -19,73 +19,108 @@ }); this.registerSteps(); }, - registerSteps: function () { + registerStep: function (step) { var self = this; - this.tour.addSteps(_.map(this.steps, function (step) { - step.title = openerp.qweb.render('website.tour_popover_title', { title: step.title }); - if (!step.element) { - step.orphan = true; - } - if (step.snippet) { - step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail'; - } - if (step.trigger) { - if (step.trigger === 'click') { + step.title = openerp.qweb.render('website.tour_popover_title', { title: step.title }); + if (!step.element) { + step.orphan = true; + } + if (step.snippet) { + step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail'; + } + if (step.trigger) { + if (step.trigger === 'click') { + step.triggers = function (callback) { + $(step.element).one('click', function () { + (callback || self.moveToNextStep).apply(self); + }); + }; + } else if (step.trigger === 'reload') { + step.triggers = function (callback) { + var stack = JSON.parse(localStorage.getItem("website-reloads")) || []; + var index = stack.indexOf(step.stepId); + if (index !== -1 || window.localStorage.getItem("test-wait-reload")) { + stack.splice(index,1); + (callback || self.moveToNextStep).apply(self); + } else { + stack.push(step.stepId); + } + localStorage.setItem("website-reloads", JSON.stringify(stack)); + }; + } else if (step.trigger.url) { + step.triggers = function (callback) { + var stack = JSON.parse(localStorage.getItem("website-geturls")) || []; + var id = step.trigger.url.toString(); + var index = stack.indexOf(id); + if (index !== -1) { + var url = new website.UrlParser(window.location.href); + var test = typeof step.trigger.url === "string" ? + step.trigger.url == url.pathname+url.search : + step.trigger.url.test(url.pathname+url.search); + if (!test) return; + stack.splice(index,1); + (callback || self.moveToNextStep).apply(self); + } else { + stack.push(id); + } + localStorage.setItem("website-geturls", JSON.stringify(stack)); + }; + } else if (step.trigger === 'drag') { + step.triggers = function (callback) { + self.onSnippetDragged(callback || self.moveToNextStep); + }; + } else if (step.trigger.id) { + if (step.trigger.emitter && step.trigger.type === 'openerp') { step.triggers = function (callback) { - $(step.element).one('click', function () { - (callback || self.moveToNextStep).apply(self); + step.trigger.emitter.on(step.trigger.id, self, function customHandler () { + step.trigger.emitter.off(step.trigger.id, customHandler); + (callback || self.moveToNextStep).apply(self, arguments); }); }; - } else if (step.trigger === 'drag') { - step.triggers = function (callback) { - self.onSnippetDragged(callback || self.moveToNextStep); - }; - } else if (step.trigger && step.trigger.id) { - if (step.trigger.emitter && step.trigger.type === 'openerp') { - step.triggers = function (callback) { - step.trigger.emitter.on(step.trigger.id, self, function customHandler () { - step.trigger.emitter.off(step.trigger.id, customHandler); - (callback || self.moveToNextStep).apply(self, arguments); - }); - }; - } else { - step.triggers = function (callback) { - var emitter = _.isString(step.trigger.emitter) ? $(step.trigger.emitter) : (step.trigger.emitter || $(step.element)); - emitter.on(step.trigger.id, function () { - (callback || self.moveToNextStep).apply(self, arguments); - }); - }; - } - } else if (step.trigger.modal) { + } else { step.triggers = function (callback) { - var $doc = $(document); - function onStop () { - if (step.trigger.modal.stopOnClose) { - self.stop(); - } - } - $doc.on('hide.bs.modal', onStop); - $doc.one('shown.bs.modal', function () { - $('.modal button.btn-primary').one('click', function () { - $doc.off('hide.bs.modal', onStop); - (callback || self.moveToNextStep).apply(self, [step.trigger.modal.afterSubmit]); - }); - (callback || self.moveToNextStep).apply(self); + var emitter = _.isString(step.trigger.emitter) ? $(step.trigger.emitter) : (step.trigger.emitter || $(step.element)); + if (!emitter.size()) throw "Emitter is undefined"; + emitter.on(step.trigger.id, function () { + (callback || self.moveToNextStep).apply(self, arguments); }); }; } - } - step.onShow = (function () { - var executed = false; - return function () { - if (!executed) { - _.isFunction(step.onStart) && step.onStart(); - _.isFunction(step.triggers) && step.triggers(); - executed = true; + } else if (step.trigger.modal) { + step.triggers = function (callback) { + var $doc = $(document); + function onStop () { + if (step.trigger.modal.stopOnClose) { + self.stop(); + } } + $doc.on('hide.bs.modal', onStop); + $doc.one('shown.bs.modal', function () { + $('.modal button.btn-primary').one('click', function () { + $doc.off('hide.bs.modal', onStop); + (callback || self.moveToNextStep).apply(self, [step.trigger.modal.afterSubmit]); + }); + (callback || self.moveToNextStep).apply(self); + }); }; - }()); - return step; + } + } + step.onShow = (function () { + var executed = false; + return function () { + if (!executed) { + _.isFunction(step.onStart) && step.onStart(); + _.isFunction(step.triggers) && step.triggers(); + executed = true; + } + }; + }()); + return step; + }, + registerSteps: function () { + var self = this; + this.tour.addSteps(_.map(this.steps, function (step) { + return self.registerStep(step); })); }, reset: function () { @@ -301,6 +336,9 @@ var actionSteps = _.filter(tour.steps, function (step) { return step.trigger || step.sampleText; }); + window.onbeforeunload = function () { + window.localStorage.setItem("test-wait-reload", true); + }; function executeStep (step) { window.localStorage.setItem(testId, step.stepId); function next () { @@ -312,23 +350,32 @@ } } setTimeout(function () { - if (step.triggers) step.triggers(next); - var $element = $(step.element); - 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 - $element.trigger($.Event("click", { srcElement: $element })); - } - if (!step.triggers) next(); - }, step.delay || defaultDelay); + var $element = $(step.element); + if (step.triggers) step.triggers(next); + window.localStorage.removeItem("test-wait-reload"); + 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(); + }, step.delay || defaultDelay); } var url = new website.UrlParser(window.location.href); - if (tour.path && url.pathname !== tour.path) { + if (tour.path && url.pathname !== tour.path && !window.localStorage.getItem(testId)) { window.localStorage.setItem(testId, actionSteps[0].stepId); window.location.href = tour.path; } else { diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py index 75a98869646..cc5dbc9db4f 100644 --- a/addons/website/tests/test_ui.py +++ b/addons/website/tests/test_ui.py @@ -141,11 +141,11 @@ class WebsiteUiSuite(unittest.TestSuite): except ValueError: result.addError(self._test, 'Unexpected message: "%s"' % "\n".join(lines)) -def full_path(filename): - return os.path.join(os.path.join(os.path.dirname(__file__), 'ui_suite'), filename) +def full_path(pyfile, filename): + return os.path.join(os.path.join(os.path.dirname(pyfile), 'ui_suite'), filename) def load_tests(loader, base, _): - base.addTest(WebsiteUiSuite(full_path('dummy_test.js'), {}, 5.0)) - base.addTest(WebsiteUiSuite(full_path('simple_dom_test.js'), { 'action': 'website.action_website_homepage' }, 60.0)) - base.addTest(WebsiteUiSuite(full_path('homepage_test.js'), { 'action': 'website.action_website_homepage' }, 60.0)) + 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)) return base diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index 1af6c00ff4e..d1c49f88603 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -683,11 +683,7 @@ </div> <section class="oe_snippet_body mb16"> <div class="container"> - <div class="row"> - <div class="col-md-12 text-center mb16"> - <h2>List of Features</h2> - <h4 class="text-muted">Add a great slogan</h4> - </div> + <div class="row mt16 mb16"> <div class="col-md-3 text-center"> <span class="fa fa-suitcase fa-5x"></span> <h3 class="mt8 mb0">First Feature</h3> @@ -697,7 +693,7 @@ <div class="col-md-3 text-center"> <span class="fa fa-lock fa-5x"></span> <h3 class="mt8 mb0">Second Feature</h3> - <p class="text-muted">Talk about what the customer would like to know, not what you want to show.</p> + <p class="text-muted">Write what the customer would like to know, not what you want to show.</p> <p><a class="btn btn-success">Take Tour</a></p> </div> <div class="col-md-3 text-center"> @@ -725,54 +721,46 @@ <section class="oe_snippet_body mb16"> <div class="container"> <div class="row"> - <div class="col-md-5 text-center mb16"> + <div class="col-md-5 text-center"> <h2>List of Features</h2> <h4 class="text-muted">Add a great slogan</h4> </div> - <div class="col-md-5 text-center mb16 col-md-offset-2"> + <div class="col-md-5 text-center col-md-offset-2"> <h2>Second List</h2> <h4 class="text-muted">Add a great slogan</h4> </div> </div><div class="row"> - <div class="col-md-5"> + <div class="col-md-5 mt16 mb16"> <div class="row"> <div class="col-md-12"> <span style="min-width: 45px" class="fa fa-3x fa-comment pull-left mb16"></span> - <h3 class="mt0 mb0">Blog</h3> - <p>OpenERP includes a full features enterprise blog to promote your messages.</p> + <h3 class="mt0 mb0">Change Icons</h3> + <p>Click on the icon to adapt it to your feature</p> </div><div class="col-md-12"> <span style="min-width: 45px" class="fa fa-3x fa-columns pull-left mb16"></span> - <h3 class="mt0 mb0">Pricing Tables</h3> - <p>Use building blocks to use pricing tables to display your products or services.</p> + <h3 class="mt0 mb0">Duplicate</h3> + <p>Duplicate blocks to add more features.</p> </div><div class="col-md-12"> <span style="min-width: 45px" class="fa fa-3x fa-user pull-left mb16"></span> - <h3 class="mt0 mb0">Log In & Signup</h3> - <p>Clean & simple Log In, Signup & Forgot Your Password forms.</p> - </div><div class="col-md-12"> - <span style="min-width: 45px" class="fa fa-3x fa-envelope pull-left mb16"></span> - <h3 class="mt0 mb0">Contact</h3> - <p>User-friendly contact form with Google Map integration.</p> + <h3 class="mt0 mb0">Delete Blocks</h3> + <p class="text-muted">Select and delete blocks to remove some features.</p> </div> </div> </div> - <div class="col-md-5 col-md-offset-2"> + <div class="col-md-5 col-md-offset-2 mt16 mb16"> <div class="row"> <div class="col-md-12"> <span style="min-width: 45px" class="fa fa-3x fa-magic pull-left mb16"></span> - <h3 class="mt0 mb0">Bootstrap</h3> - <p>Uses Twitter Bootstrap's sleek, intuitive, and powerful front-end framework.</p> - </div><div class="col-md-12"> - <span style="min-width: 45px" class="fa fa-3x fa-font pull-left mb16"></span> - <h3 class="mt0 mb0">Google Web Fonts</h3> - <p>Royalty free, open source fonts for the people, by the people!</p> + <h3 class="mt0 mb0">Great Value</h3> + <p>Tell features the visitor would like to know, not what you'd like to say.</p> </div><div class="col-md-12"> <span style="min-width: 45px" class="fa fa-3x fa-bolt pull-left mb16"></span> - <h3 class="mt0 mb0">Powerful & slick jQuery</h3> - <p>Fantastic jQuery plugins such as Isotope and Bootstrap's inbuilt features.</p> + <h3 class="mt0 mb0">Change Background</h3> + <p>From the main container, you can change the background to highlight features.</p> </div><div class="col-md-12"> <span style="min-width: 45px" class="fa fa-3x fa-picture-o pull-left mb16"></span> <h3 class="mt0 mb0">Sample images</h3> - <p>Fantastic sample images fully licensed for use.</p> + <p>All these icons are licensed under creative commons so that you can use them.</p> </div> </div> </div> @@ -891,7 +879,7 @@ </li> </div> - <div data-snippet-style-id='background' data-selector="section, section[data-snippet-id='parallax'], div[data-snippet-id='carousel']"> + <div data-snippet-style-id='background' data-selector="section, section[data-snippet-id='parallax'], div[data-snippet-id='carousel'], div[data-snippet-id='slider']"> <li class="dropdown-submenu"> <a tabindex="-1" href="#">Background</a> <ul class="dropdown-menu"> diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index fe34309d16a..7a1a8f92ad4 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -96,8 +96,8 @@ <t t-foreach="website.menu_id.child_id" t-as="submenu"> <t t-call="website.submenu"/> </t> - <li class="divider"/> - <li class="dropdown" t-ignore="true" t-if="user_id.id != website.public_user.id"> + <li class="divider" groups="base.group_user,base.group_portal"/> + <li class="dropdown" t-ignore="true" groups="base.group_user,base.group_portal"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> <b> <span t-esc="user_id.name"/> @@ -162,7 +162,7 @@ </p> </div> <t t-set="languages" t-value="website.get_languages()"/> - <ul class="nav nav-pills js_language_selector" t-if="(len(languages) > 1 or editable)"> + <ul class="list-inline js_language_selector mt16" t-if="(len(languages) > 1 or editable)"> <li t-foreach="languages" t-as="lg"> <a t-att-href="url_for('', lang=lg[0], keep_query='*')" t-att-data-default-lang="editable and 'true' if lg[0] == website.default_lang_code else None"> @@ -180,7 +180,7 @@ </div> </div> </div> - <div class="container mt16"> + <div class="container mt16 mb8"> <div class="pull-right" t-ignore="true" t-if="not editable"> Create a <a href="http://openerp.com/apps/website">free website</a> with <a class="label label-danger" href="https://openerp.com/apps/website">OpenERP</a> @@ -195,6 +195,14 @@ </html> </template> +<template id="layout_logo_show" inherit_option_id="website.layout" name="Show Logo"> + <xpath expr="//header//a[@class='navbar-brand']" position="replace"> + <a href="/" class="navbar-brand logo"> + <img src="/website/static/src/img/odoo_logo.png"/> + </a> + </xpath> +</template> + <template id="editor_head" inherit_id="website.layout" name="Editor" groups="base.group_website_publisher"> <xpath expr='//t[@name="layout_head"]' position="before"> <link rel='stylesheet' href='/website/static/src/css/snippets.css'/> @@ -231,11 +239,10 @@ </xpath> </template> - - <template id="show_sign_in" inherit_option_id="website.layout" inherit_id="website.layout" name="Show Sign In"> <xpath expr="//ul[@id='top_menu']" position="inside"> - <li t-if="user_id.id == website.public_user.id"> + <li class="divider" groups="base.group_public"/> + <li groups="base.group_public"> <a t-attf-href="/web#redirect=#{ quote_plus(url_for('', keep_query='*')) }"> <b>Sign in</b> </a> @@ -674,30 +681,6 @@ Sitemap: <t t-esc="url_root"/>sitemap.xml </div> </section> - <div class="parallax oe_structure mt16 oe_medium mb64" data-scroll-background-ratio="0.6" data-snippet-id="parallax" style="background-image: url(http://localhost:8069/website/static/src/img/parallax/parallax_bg.jpg); background-attachment: scroll; background-position: 0px 0px; "> - <section class="mb32 mt16" data-snippet-id="references"> - <div class="container"> - <div class="row"> - <div class="col-md-12 mt16 mb8"> - <h1 class="text-center">What do customers say about us...?</h1> - </div> - <div class="col-md-4 col-md-offset-1 mt16 mb0"> - <blockquote data-snippet-id="quote"> - <p><span style="background-color:#FFFFFF;">Write here a quote from one of your customer. Quotes are are great way to give confidence in your products or services.</span></p> - <small><span style="background-color:#FFFFFF;">Author of this quote</span></small> - </blockquote> - </div> - <div class="col-md-4 col-md-offset-2 mt16 mb32"> - <blockquote data-snippet-id="quote"> - <p><span style="background-color:#FFFFFF;">OpenERP provides essential platform for our project management. Things are better organized and more visible with it.</span></p> - <small><span style="background-color:#FFFFFF;">John Doe, CEO</span></small> - </blockquote> - </div> - </div> - </div> - </section> - </div> - </div> <div class="oe_structure"></div> </div> diff --git a/addons/website_blog/controllers/main.py b/addons/website_blog/controllers/main.py index fc48266cc5e..999e372305b 100644 --- a/addons/website_blog/controllers/main.py +++ b/addons/website_blog/controllers/main.py @@ -45,10 +45,10 @@ class WebsiteBlog(http.Controller): group['date'] = "%s_%s" % (group['__domain'][0][2], group['__domain'][1][2]) return groups - @website.route([ + @http.route([ '/blog', '/blog/page/<int:page>/', - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def blogs(self, page=1): BYPAGE = 60 cr, uid, context = request.cr, request.uid, request.context @@ -67,7 +67,7 @@ class WebsiteBlog(http.Controller): 'pager': pager }) - @website.route([ + @http.route([ '/blog/<model("blog.category"):category>/', '/blog/<model("blog.category"):category>/page/<int:page>/', '/blog/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/', @@ -76,7 +76,7 @@ class WebsiteBlog(http.Controller): '/blog/<model("blog.category"):category>/date/<string(length=21):date>/page/<int:page>/', '/blog/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/date/<string(length=21):date>/', '/blog/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/date/<string(length=21):date>/page/<int:page>/', - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def blog(self, category=None, tag=None, date=None, page=1, **opt): """ Prepare all values to display the blog. @@ -152,9 +152,9 @@ class WebsiteBlog(http.Controller): } return request.website.render("website_blog.blog_post_short", values) - @website.route([ + @http.route([ '/blogpost/<model("blog.post"):blog_post>/', - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def blog_post(self, blog_post, tag=None, date=None, page=1, enable_editor=None, **post): """ Prepare all values to display the blog. @@ -219,7 +219,7 @@ class WebsiteBlog(http.Controller): } return request.website.render("website_blog.blog_post_complete", values) - @website.route(['/blogpost/comment'], type='http', auth="public", methods=['POST']) + @http.route(['/blogpost/comment'], type='http', auth="public", methods=['POST'], website=True) def blog_post_comment(self, blog_post_id=0, **post): cr, uid, context = request.cr, request.uid, request.context if post.get('comment'): @@ -238,7 +238,7 @@ class WebsiteBlog(http.Controller): context=dict(context, mail_create_nosubcribe=True)) return werkzeug.utils.redirect(request.httprequest.referrer + "#comments") - @website.route('/blogpost/new', type='http', auth="public", multilang=True) + @http.route('/blogpost/new', type='http', auth="public", website=True, multilang=True) def blog_post_create(self, category_id, **post): cr, uid, context = request.cr, request.uid, request.context create_context = dict(context, mail_create_nosubscribe=True) @@ -251,7 +251,7 @@ class WebsiteBlog(http.Controller): }, context=create_context) return werkzeug.utils.redirect("/blogpost/%s/?enable_editor=1" % new_blog_post_id) - @website.route('/blogpost/duplicate', type='http', auth="public") + @http.route('/blogpost/duplicate', type='http', auth="public", website=True) def blog_post_copy(self, blog_post_id, **post): """ Duplicate a blog. diff --git a/addons/website_blog/tests/test_ui.py b/addons/website_blog/tests/test_ui.py index 0e57f94d931..694bbabc6f9 100644 --- a/addons/website_blog/tests/test_ui.py +++ b/addons/website_blog/tests/test_ui.py @@ -1,10 +1,5 @@ -import os - -import openerp.addons.website.tests.test_ui as test_ui - -def full_path(filename): - return os.path.join(os.path.join(os.path.dirname(__file__), 'ui_suite'), filename) +import openerp.addons.website.tests.test_ui as test_ui,full_path def load_tests(loader, base, _): - base.addTest(test_ui.WebsiteUiSuite(full_path('post_test.js'), { 'action': 'website.action_website_homepage' }, 60.0)) + base.addTest(test_ui.WebsiteUiSuite(full_path(__file__,'post_test.js'), { 'action': 'website.action_website_homepage' }, 60.0)) return base
\ No newline at end of file diff --git a/addons/website_crm/controllers/main.py b/addons/website_crm/controllers/main.py index 570a9c99b27..65b38d3b09f 100644 --- a/addons/website_crm/controllers/main.py +++ b/addons/website_crm/controllers/main.py @@ -2,7 +2,6 @@ from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website from openerp import SUPERUSER_ID from urllib import quote_plus @@ -16,7 +15,7 @@ class contactus(http.Controller): ) return url - @website.route(['/crm/contactus'], type='http', auth="public", multilang=True) + @http.route(['/crm/contactus'], type='http', auth="public", website=True, multilang=True) def contactus(self, *arg, **post): required_fields = ['contact_name', 'email_from', 'description'] post['user_id'] = False diff --git a/addons/website_crm_partner_assign/controllers/main.py b/addons/website_crm_partner_assign/controllers/main.py index 03147633b8f..a8d696e1353 100644 --- a/addons/website_crm_partner_assign/controllers/main.py +++ b/addons/website_crm_partner_assign/controllers/main.py @@ -9,20 +9,19 @@ from openerp.tools.translate import _ from openerp.addons.web.http import request from openerp.addons.website.models import website from openerp.addons.website_partner.controllers import main as website_partner -import werkzeug class WebsiteCrmPartnerAssign(http.Controller): _references_per_page = 20 - @website.route([ + @http.route([ '/partners/', '/partners/page/<int:page>/', '/partners/country/<int:country_id>', '/partners/country/<country_name>-<int:country_id>', '/partners/country/<int:country_id>/page/<int:page>/', '/partners/country/<country_name>-<int:country_id>/page/<int:page>/', - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def partners(self, country_id=0, page=0, **post): country_obj = request.registry['res.country'] partner_obj = request.registry['res.partner'] @@ -95,7 +94,7 @@ class WebsiteCrmPartnerAssign(http.Controller): } return request.website.render("website_crm_partner_assign.index", values) - @website.route(['/partners/<int:partner_id>/', '/partners/<partner_name>-<int:partner_id>/'], type='http', auth="public", multilang=True) + @http.route(['/partners/<int:partner_id>/', '/partners/<partner_name>-<int:partner_id>/'], type='http', auth="public", website=True, multilang=True) def partners_ref(self, partner_id, **post): partner = request.registry['res.partner'].browse(request.cr, SUPERUSER_ID, partner_id, context=request.context) website.preload_records(partner) diff --git a/addons/website_customer/controllers/main.py b/addons/website_customer/controllers/main.py index 7977b8afa53..98b77fdd547 100644 --- a/addons/website_customer/controllers/main.py +++ b/addons/website_customer/controllers/main.py @@ -13,14 +13,14 @@ import urllib class WebsiteCustomer(http.Controller): _references_per_page = 20 - @website.route([ + @http.route([ '/customers/', '/customers/page/<int:page>/', '/customers/country/<int:country_id>', '/customers/country/<country_name>-<int:country_id>', '/customers/country/<int:country_id>/page/<int:page>/', '/customers/country/<country_name>-<int:country_id>/page/<int:page>/', - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def customers(self, country_id=0, page=0, **post): cr, uid, context = request.cr, request.uid, request.context partner_obj = request.registry['res.partner'] @@ -76,7 +76,7 @@ class WebsiteCustomer(http.Controller): } return request.website.render("website_customer.index", values) - @website.route(['/customers/<int:partner_id>/', '/customers/<partner_name>-<int:partner_id>/'], type='http', auth="public", multilang=True) + @http.route(['/customers/<int:partner_id>/', '/customers/<partner_name>-<int:partner_id>/'], type='http', auth="public", website=True, multilang=True) def customer(self, partner_id, **post): partner = request.registry['res.partner'].browse(request.cr, SUPERUSER_ID, partner_id, context=request.context) website.preload_records(partner) diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index 638c5ded6e5..8e9fe440abc 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -34,7 +34,7 @@ from openerp import tools import urllib class website_event(http.Controller): - @website.route(['/event/', '/event/page/<int:page>'], type='http', auth="public", multilang=True) + @http.route(['/event/', '/event/page/<int:page>'], type='http', auth="public", website=True, multilang=True) def events(self, page=1, **searches): cr, uid, context = request.cr, request.uid, request.context event_obj = request.registry['event.event'] @@ -161,7 +161,7 @@ class website_event(http.Controller): return request.website.render("website_event.index", values) - @website.route(['/event/<model("event.event"):event>/page/<page:page>'], type='http', auth="public", multilang=True) + @http.route(['/event/<model("event.event"):event>/page/<page:page>'], type='http', auth="public", website=True, multilang=True) def event_page(self, event, page, **post): website.preload_records(event, on_error="website_event.404") values = { @@ -170,7 +170,7 @@ class website_event(http.Controller): } return request.website.render(page, values) - @website.route(['/event/<model("event.event"):event>'], type='http', auth="public", multilang=True) + @http.route(['/event/<model("event.event"):event>'], type='http', auth="public", website=True, multilang=True) def event(self, event, **post): website.preload_records(event, on_error="website_event.404") if event.menu_id and event.menu_id.child_id: @@ -181,7 +181,7 @@ class website_event(http.Controller): target_url += '?enable_editor=1' return request.redirect(target_url); - @website.route(['/event/<model("event.event"):event>/register'], type='http', auth="public", multilang=True) + @http.route(['/event/<model("event.event"):event>/register'], type='http', auth="public", website=True, multilang=True) def event_register(self, event, **post): website.preload_records(event, on_error="website_event.404") values = { @@ -192,16 +192,17 @@ class website_event(http.Controller): } return request.website.render("website_event.event_description_full", values) - @website.route(['/event/add_cart'], type='http', auth="public", multilang=True) + @http.route(['/event/add_cart'], type='http', auth="public", website=True, multilang=True) def add_cart(self, event_id, **post): user_obj = request.registry['res.users'] order_line_obj = request.registry.get('sale.order.line') ticket_obj = request.registry.get('event.event.ticket') order_obj = request.registry.get('sale.order') + website = request.registry['website'] - order = request.registry['website'].get_current_order(request.cr, request.uid, context=request.context) + order = website.ecommerce_get_current_order(request.cr, request.uid, context=request.context) if not order: - order = request.registry['website']._get_order(request.cr, request.uid, context=request.context) + order = website.ecommerce_get_new_order(request.cr, request.uid, context=request.context) partner_id = user_obj.browse(request.cr, SUPERUSER_ID, request.uid, context=request.context).partner_id.id @@ -246,7 +247,7 @@ class website_event(http.Controller): return request.redirect("/event/%s/" % event_id) return request.redirect("/shop/checkout") - @website.route(['/event/publish'], type='json', auth="public") + @http.route(['/event/publish'], type='json', auth="public", website=True) def publish(self, id, object): # if a user publish an event, he publish all linked res.partner event = request.registry[object].browse(request.cr, request.uid, int(id)) @@ -258,7 +259,7 @@ class website_event(http.Controller): return controllers.publish(id, object) - @website.route('/event/add_event/', type='http', auth="user", multilang=True, methods=['POST']) + @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 diff --git a/addons/website_event/security/ir.model.access.csv b/addons/website_event/security/ir.model.access.csv index 1f4fc9d12f1..06135ee0822 100644 --- a/addons/website_event/security/ir.model.access.csv +++ b/addons/website_event/security/ir.model.access.csv @@ -2,6 +2,6 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0 access_event_type_public,event.type.public,event.model_event_type,base.group_public,1,0,0,0 access_event_event_ticket_public,event.event.ticket.public,event_sale.model_event_event_ticket,,1,0,0,0 -access_event_event_ticket_public,event.event.ticket.public,event_sale.model_event_event_ticket,event.group_event_manager,1,1,1,1 +access_event_event_ticket_admin,event.event.ticket.admin,event_sale.model_event_event_ticket,event.group_event_manager,1,1,1,1 access_event_product_product_public,event.product.product.public,product.model_product_product,base.group_public,1,0,0,0 access_event_product_template_public,event.product.template.public,product.model_product_template,base.group_public,1,0,0,0 diff --git a/addons/website_event/tests/test_ui.py b/addons/website_event/tests/test_ui.py index 8c4bdb2a07c..5706e7a0c34 100644 --- a/addons/website_event/tests/test_ui.py +++ b/addons/website_event/tests/test_ui.py @@ -1,10 +1,5 @@ -import os - -import openerp.addons.website.tests.test_ui as test_ui - -def full_path(filename): - return os.path.join(os.path.join(os.path.dirname(__file__), 'ui_suite'), filename) +import openerp.addons.website.tests.test_ui as test_ui,full_path def load_tests(loader, base, _): - base.addTest(test_ui.WebsiteUiSuite(full_path('event_test.js'), { 'action': 'website.action_website_homepage' }, 60.0)) + base.addTest(test_ui.WebsiteUiSuite(full_path(__file__,'event_test.js'), { 'action': 'website.action_website_homepage' }, 60.0)) return base
\ No newline at end of file diff --git a/addons/website_event_track/controllers/event.py b/addons/website_event_track/controllers/event.py index 3d4976c07d4..f8863a162ad 100644 --- a/addons/website_event_track/controllers/event.py +++ b/addons/website_event_track/controllers/event.py @@ -30,7 +30,7 @@ import werkzeug.utils controllers = controllers() class website_event(http.Controller): - @website.route(['/event/<model("event.event"):event>/track/<model("event.track"):track>'], type='http', auth="public", multilang=True) + @http.route(['/event/<model("event.event"):event>/track/<model("event.track"):track>'], type='http', auth="public", website=True, multilang=True) def event_track_view(self, event, track, **post): # TODO: not implemented website.preload_records(event, on_error="website_event.404") @@ -38,7 +38,7 @@ class website_event(http.Controller): values = { 'track': track, 'event': track.event_id, 'main_object': track } return request.website.render("website_event_track.track_view", values) - @website.route(['/event/<model("event.event"):event>/agenda/'], type='http', auth="public", multilang=True) + @http.route(['/event/<model("event.event"):event>/agenda/'], type='http', auth="public", website=True, multilang=True) def event_agenda(self, event, tag=None, **post): website.preload_records(event, on_error="website_event.404") values = { @@ -47,10 +47,10 @@ class website_event(http.Controller): } return request.website.render("website_event_track.agenda", values) - @website.route([ + @http.route([ '/event/<model("event.event"):event>/track/', '/event/<model("event.event"):event>/track/tag/<model("event.track.tag"):tag>' - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def event_tracks(self, event, tag=None, **post): website.preload_records(event, on_error="website_event.404") website.preload_records(tag) @@ -80,13 +80,13 @@ class website_event(http.Controller): - @website.route(['/event/<model("event.event"):event>/track_proposal/'], type='http', auth="public", multilang=True) + @http.route(['/event/<model("event.event"):event>/track_proposal/'], type='http', auth="public", website=True, multilang=True) def event_track_proposal(self, event, **post): website.preload_records(event, on_error="website_event.404") values = { 'event': event } return request.website.render("website_event_track.event_track_proposal", values) - @website.route(['/event/<model("event.event"):event>/track_proposal/post'], type='http', auth="public", methods=['POST'], multilang=True) + @http.route(['/event/<model("event.event"):event>/track_proposal/post'], type='http', auth="public", methods=['POST'], website=True, multilang=True) def event_track_proposal_post(self, event, **post): cr, uid, context = request.cr, request.uid, request.context diff --git a/addons/website_google_map/controllers/main.py b/addons/website_google_map/controllers/main.py index b81823428e8..04cea6901fc 100644 --- a/addons/website_google_map/controllers/main.py +++ b/addons/website_google_map/controllers/main.py @@ -3,12 +3,11 @@ import openerp from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website from datetime import datetime class google_map(http.Controller): - @website.route(['/google_map/'], type='http', auth="admin") + @http.route(['/google_map/'], type='http', auth="admin", website=True) def google_map(self, *arg, **post): values = { 'partner_ids': post.get('partner_ids', ""), @@ -18,7 +17,7 @@ class google_map(http.Controller): } return request.website.render("website_google_map.google_map", values) - @website.route(['/google_map/partners.json'], type='http', auth="admin") + @http.route(['/google_map/partners.json'], type='http', auth="admin", website=True) def google_map_data(self, *arg, **post): partner_obj = request.registry['res.partner'] @@ -29,7 +28,7 @@ class google_map(http.Controller): return partner_obj.google_map_json(request.cr, openerp.SUPERUSER_ID, partner_ids, request.context) - @website.route(['/google_map/set_partner_position/'], type='http', auth="admin") + @http.route(['/google_map/set_partner_position/'], type='http', auth="admin", website=True) def google_map_set_partner_position(self, *arg, **post): partner_obj = request.registry['res.partner'] diff --git a/addons/website_hr/controllers/main.py b/addons/website_hr/controllers/main.py index 72c15aea023..20c865b5b89 100644 --- a/addons/website_hr/controllers/main.py +++ b/addons/website_hr/controllers/main.py @@ -2,11 +2,10 @@ from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website class website_hr(http.Controller): - @website.route(['/page/website.aboutus'], type='http', auth="public", multilang=True) + @http.route(['/page/website.aboutus'], type='http', auth="public", website=True, multilang=True) def blog(self, **post): hr_obj = request.registry['hr.employee'] employee_ids = hr_obj.search(request.cr, request.uid, [('website_published', '=', True)], diff --git a/addons/website_hr_recruitment/controllers/main.py b/addons/website_hr_recruitment/controllers/main.py index 42d9fbbc2d0..096c91677a8 100644 --- a/addons/website_hr_recruitment/controllers/main.py +++ b/addons/website_hr_recruitment/controllers/main.py @@ -2,7 +2,6 @@ from openerp.addons.web import http from openerp.tools.translate import _ from openerp.addons.web.http import request -from openerp.addons.website.models import website from openerp.addons.website.controllers.main import Website as controllers controllers = controllers() @@ -10,12 +9,12 @@ import base64 class website_hr_recruitment(http.Controller): - @website.route([ + @http.route([ '/jobs', '/jobs/department/<model("hr.department"):department>/office/<model("res.partner"):office>', '/jobs/department/<model("hr.department"):department>', '/jobs/office/<model("res.partner"):office>' - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def jobs(self, department=None, office=None): JobsObj = request.registry['hr.job'] jobpost_ids = JobsObj.search(request.cr, request.uid, [], @@ -47,11 +46,11 @@ class website_hr_recruitment(http.Controller): 'office': office and office.id or None }) - @website.route(['/job/detail/<model("hr.job"):job>'], type='http', auth="public", multilang=True) + @http.route(['/job/detail/<model("hr.job"):job>'], type='http', auth="public", website=True, multilang=True) def detail(self, job, **kwargs): return request.website.render("website_hr_recruitment.detail", { 'job': job, 'main_object': job }) - @website.route(['/job/success'], methods=['POST'], type='http', auth="admin", multilang=True) + @http.route(['/job/success'], methods=['POST'], type='http', auth="admin", website=True, multilang=True) def success(self, **post): data = { 'name': _('Online Form'), @@ -84,7 +83,7 @@ class website_hr_recruitment(http.Controller): request.registry['ir.attachment'].create(request.cr, request.uid, attachment_values, context=request.context) return request.website.render("website_hr_recruitment.thankyou", {}) - @website.route(['/job/apply'], type='http', auth="public", multilang=True) + @http.route(['/job/apply'], type='http', auth="public", website=True, multilang=True) def applyjobpost(self, job): [job_object] = request.registry['hr.job'].browse( request.cr, request.uid, [int(job)], context=request.context) @@ -93,7 +92,7 @@ class website_hr_recruitment(http.Controller): 'job': job_object }) - @website.route('/job/add_job_offer/', type='http', auth="user", multilang=True, methods=['POST']) + @http.route('/job/add_job_offer/', type='http', auth="user", methods=['POST'], website=True, multilang=True) def add_job_offer(self, **kwargs): Job = request.registry.get('hr.job') job_id = Job.create(request.cr, request.uid, { diff --git a/addons/website_mail/controllers/email_designer.py b/addons/website_mail/controllers/email_designer.py index a7f6ef8d287..81bc703b702 100644 --- a/addons/website_mail/controllers/email_designer.py +++ b/addons/website_mail/controllers/email_designer.py @@ -3,12 +3,11 @@ # from openerp import SUPERUSER_ID from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website class WebsiteEmailDesigner(http.Controller): - @website.route('/website_mail/email_designer/<model("email.template"):template>/', type='http', auth="public", multilang=True) + @http.route('/website_mail/email_designer/<model("email.template"):template>/', type='http', auth="public", website=True, multilang=True) def index(self, template, **kw): values = { 'template': template, @@ -16,6 +15,6 @@ class WebsiteEmailDesigner(http.Controller): print template return request.website.render("website_mail.designer_index", values) - @website.route(['/website_mail/snippets'], type='json', auth="public") + @http.route(['/website_mail/snippets'], type='json', auth="public", website=True) def snippets(self): return request.website._render('website_mail.email_designer_snippets') diff --git a/addons/website_mail/controllers/main.py b/addons/website_mail/controllers/main.py index ea0befff81a..f700fa7dc67 100644 --- a/addons/website_mail/controllers/main.py +++ b/addons/website_mail/controllers/main.py @@ -22,7 +22,6 @@ from openerp import SUPERUSER_ID from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website class WebsiteMail(http.Controller): @@ -40,7 +39,7 @@ class WebsiteMail(http.Controller): partner_ids = [user_obj.browse(request.cr, request.uid, request.uid, request.context).partner_id.id] return partner_ids - @website.route(['/website_mail/follow/'], type='json', auth="public") + @http.route(['/website_mail/follow/'], type='json', auth="public", website=True) def website_message_subscribe(self, id=0, object=None, message_is_follower="on", email=False, **post): _id = int(id) _message_is_follower = message_is_follower == 'on' diff --git a/addons/website_membership/controllers/main.py b/addons/website_membership/controllers/main.py index 8a7a6a757d3..56ae698ebe3 100644 --- a/addons/website_membership/controllers/main.py +++ b/addons/website_membership/controllers/main.py @@ -14,7 +14,7 @@ import urllib class WebsiteMembership(http.Controller): _references_per_page = 20 - @website.route([ + @http.route([ '/members/', '/members/page/<int:page>/', '/members/association/<int:membership_id>/', @@ -29,7 +29,7 @@ class WebsiteMembership(http.Controller): '/members/association/<int:membership_id>/country/<int:country_id>', '/members/association/<int:membership_id>/country/<country_name>-<int:country_id>/page/<int:page>/', '/members/association/<int:membership_id>/country/<int:country_id>/page/<int:page>/', - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def members(self, membership_id=None, country_name=None, country_id=0, page=0, **post): cr, uid, context = request.cr, request.uid, request.context product_obj = request.registry['product.product'] @@ -92,7 +92,7 @@ class WebsiteMembership(http.Controller): } return request.website.render("website_membership.index", values) - @website.route(['/members/<int:partner_id>/', '/members/<partner_name>-<int:partner_id>/'], type='http', auth="public", multilang=True) + @http.route(['/members/<int:partner_id>/', '/members/<partner_name>-<int:partner_id>/'], type='http', auth="public", website=True, multilang=True) def partners_ref(self, partner_id, **post): partner = request.registry['res.partner'].browse(request.cr, SUPERUSER_ID, partner_id, context=request.context) website.preload_records(partner) diff --git a/addons/website_partner/controllers/main.py b/addons/website_partner/controllers/main.py index 896de36c352..a405fb6e798 100644 --- a/addons/website_partner/controllers/main.py +++ b/addons/website_partner/controllers/main.py @@ -34,7 +34,7 @@ def get_partner_template_value(partner): return values class WebsitePartner(http.Controller): - @website.route(['/partners/<int:partner_id>/', '/partners/<partner_name>-<int:partner_id>/'], type='http', auth="public", multilang=True) + @http.route(['/partners/<int:partner_id>/', '/partners/<partner_name>-<int:partner_id>/'], type='http', auth="public", website=True, multilang=True) def partner(self, partner_id, **post): """ Route for displaying a single partner / customer. """ partner = request.registry['res.partner'].browse(request.cr, SUPERUSER_ID, partner_id, context=request.context) diff --git a/addons/website_project/controllers/main.py b/addons/website_project/controllers/main.py index e44d34be4cb..64f2fd0762e 100644 --- a/addons/website_project/controllers/main.py +++ b/addons/website_project/controllers/main.py @@ -21,7 +21,6 @@ from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website from openerp.osv import osv @@ -39,7 +38,7 @@ class Website(osv.Model): class website_project(http.Controller): - @website.route(['/project/<int:project_id>/'], type='http', auth="public", multilang=True) + @http.route(['/project/<int:project_id>/'], type='http', auth="public", website=True, multilang=True) def project(self, project_id=None, **post): cr, uid, context = request.cr, request.uid, request.context project_obj = request.registry['project.project'] @@ -52,7 +51,7 @@ class website_project(http.Controller): } return request.website.render("website_project.index", render_values) - @website.route(['/project/task/<int:task_id>'], type='http', auth="public", multilang=True) + @http.route(['/project/task/<int:task_id>'], type='http', auth="public", website=True, multilang=True) def task(self, task_id=None, **post): cr, uid, context = request.cr, request.uid, request.context task_obj = request.registry['project.task'] diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index e5d7ccf2856..17c7f3a574a 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -144,7 +144,7 @@ class Ecommerce(http.Controller): return key_val return False - @website.route(['/shop/filters/'], type='http', auth="public", multilang=True) + @http.route(['/shop/filters/'], type='http', auth="public", website=True, multilang=True) def filters(self, **post): index = [] filters = [] @@ -190,18 +190,18 @@ class Ecommerce(http.Controller): att = obj.read(request.cr, request.uid, att_ids, ["product_tmpl_id"], context=request.context) return [r["product_tmpl_id"][0] for r in att] - @website.route(['/shop/pricelist'], type='http', auth="public", multilang=True) + @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") - @website.route([ + @http.route([ '/shop/', '/shop/page/<int:page>/', '/shop/category/<model("product.public.category"):category>/', '/shop/category/<model("product.public.category"):category>/page/<int:page>/' - ], type='http', auth="public", multilang=True) + ], type='http', auth="public", website=True, multilang=True) def shop(self, category=None, page=0, filters='', search='', **post): cr, uid, context = request.cr, request.uid, request.context product_obj = request.registry.get('product.template') @@ -257,7 +257,7 @@ class Ecommerce(http.Controller): } return request.website.render("website_sale.products", values) - @website.route(['/shop/product/<model("product.template"):product>/'], type='http', auth="public", multilang=True) + @http.route(['/shop/product/<model("product.template"):product>/'], type='http', auth="public", website=True, multilang=True) def product(self, product, search='', category='', filters='', **kwargs): website.preload_records(product, on_error="website_sale.404") @@ -286,7 +286,7 @@ class Ecommerce(http.Controller): } return request.website.render("website_sale.product", values) - @website.route(['/shop/product/comment'], type='http', auth="public", methods=['POST']) + @http.route(['/shop/product/comment'], type='http', auth="public", methods=['POST'], website=True) def product_comment(self, product_template_id, **post): cr, uid, context = request.cr, request.uid, request.context if post.get('comment'): @@ -298,7 +298,7 @@ class Ecommerce(http.Controller): context=dict(context, mail_create_nosubcribe=True)) return werkzeug.utils.redirect(request.httprequest.referrer + "#comments") - @website.route(['/shop/add_product/'], type='http', auth="user", multilang=True, methods=['POST']) + @http.route(['/shop/add_product/'], type='http', auth="user", methods=['POST'], website=True, multilang=True) def add_product(self, name="New Product", category=0, **post): Product = request.registry.get('product.product') product_id = Product.create(request.cr, request.uid, { @@ -308,75 +308,7 @@ class Ecommerce(http.Controller): return request.redirect("/shop/product/%s/?enable_editor=1" % product.product_tmpl_id.id) - def add_product_to_cart(self, product_id=0, order_line_id=0, number=1, set_number=-1): - order_line_obj = request.registry.get('sale.order.line') - order_obj = request.registry.get('sale.order') - - order = self.get_order() - if not order: - order = request.registry['website'].ecommerce_get_new_order(request.cr, request.uid, context=request.context) - - request.context = dict(request.context, pricelist=self.get_pricelist()) - - # set order_line_id and product_id - if order_line_id: - order_line = None - for line in order.order_line: - if line.id == order_line_id: - order_line = line - break - if order_line: - product_id = order_line.product_id.id - else: - order_line_id = None - else: - order_line_ids = order_line_obj.search( - request.cr, SUPERUSER_ID, - [('order_id', '=', order.id), ('product_id', '=', product_id)], context=request.context) - if order_line_ids: - order_line_id = order_line_ids[0] - - if not order_line_id and not product_id: - return 0 - - # values initialisation - quantity = 0 - values = {} - if order_line_id: - order_line_val = order_line_obj.read(request.cr, SUPERUSER_ID, [order_line_id], [], context=request.context)[0] - if not product_id: - product_id = order_line_val['product_id'][0] - if set_number >= 0: - quantity = set_number - else: - quantity = order_line_val['product_uom_qty'] + number - if quantity < 0: - quantity = 0 - order_line_ids = [order_line_id] - else: - fields = [k for k, v in order_line_obj._columns.items()] - values = order_line_obj.default_get(request.cr, SUPERUSER_ID, fields, context=request.context) - quantity = 1 - order_line_ids = [] - - # change and record value - vals = order_line_obj._recalculate_product_values(request.cr, request.uid, order_line_ids, product_id, context=request.context) - values.update(vals) - - values['product_uom_qty'] = quantity - values['product_id'] = product_id - values['order_id'] = order.id - - if order_line_id: - order_line_obj.write(request.cr, SUPERUSER_ID, [order_line_id], values, context=request.context) - if not quantity: - order_line_obj.unlink(request.cr, SUPERUSER_ID, [order_line_id], context=request.context) - else: - order_line_id = order_line_obj.create(request.cr, SUPERUSER_ID, values, context=request.context) - order_obj.write(request.cr, SUPERUSER_ID, [order.id], {'order_line': [(4, order_line_id)]}, context=request.context) - return quantity - - @website.route(['/shop/mycart/'], type='http', auth="public", multilang=True) + @http.route(['/shop/mycart/'], type='http', auth="public", website=True, multilang=True) def mycart(self, **post): cr, uid, context = request.cr, request.uid, request.context prod_obj = request.registry.get('product.product') @@ -411,30 +343,38 @@ class Ecommerce(http.Controller): } return request.website.render("website_sale.mycart", values) - @website.route(['/shop/add_cart/'], type='http', auth="public", multilang=True, methods=['POST']) + @http.route(['/shop/add_cart/'], type='http', auth="public", methods=['POST'], website=True, multilang=True) def add_cart(self, product_id, remove=None, **kw): - self.add_product_to_cart(product_id=int(product_id)) + request.registry['website']._ecommerce_add_product_to_cart(request.cr, request.uid, + product_id=int(product_id), + context=request.context) return request.redirect("/shop/mycart/") - @website.route(['/shop/change_cart/<int:order_line_id>/'], type='http', auth="public", multilang=True) + @http.route(['/shop/change_cart/<int:order_line_id>/'], type='http', auth="public", website=True, multilang=True) def add_cart_order_line(self, order_line_id=None, remove=None, **kw): - self.add_product_to_cart(order_line_id=order_line_id, number=(remove and -1 or 1)) + request.registry['website']._ecommerce_add_product_to_cart(request.cr, request.uid, + order_line_id=order_line_id, number=(remove and -1 or 1), + context=request.context) return request.redirect("/shop/mycart/") - @website.route(['/shop/add_cart_json/'], type='json', auth="public") + @http.route(['/shop/add_cart_json/'], type='json', auth="public", website=True) def add_cart_json(self, product_id=None, order_line_id=None, remove=None): - quantity = self.add_product_to_cart(product_id=product_id, order_line_id=order_line_id, number=(remove and -1 or 1)) + quantity = request.registry['website']._ecommerce_add_product_to_cart(request.cr, request.uid, + product_id=product_id, order_line_id=order_line_id, number=(remove and -1 or 1), + context=request.context) order = self.get_order() return [quantity, order.get_number_of_products(), order.amount_total, request.website._render("website_sale.total", {'website_sale_order': order})] - @website.route(['/shop/set_cart_json/'], type='json', auth="public") + @http.route(['/shop/set_cart_json/'], type='json', auth="public", website=True) def set_cart_json(self, path=None, product_id=None, order_line_id=None, set_number=0, json=None): - return self.add_product_to_cart(product_id=product_id, order_line_id=order_line_id, set_number=set_number) + return request.registry['website']._ecommerce_add_product_to_cart(request.cr, request.uid, + product_id=product_id, order_line_id=order_line_id, set_number=set_number, + context=request.context) - @website.route(['/shop/checkout/'], type='http', auth="public", multilang=True) + @http.route(['/shop/checkout/'], type='http', auth="public", website=True, multilang=True) def checkout(self, **post): cr, uid, context, registry = request.cr, request.uid, request.context, request.registry @@ -488,7 +428,7 @@ class Ecommerce(http.Controller): return request.website.render("website_sale.checkout", values) - @website.route(['/shop/confirm_order/'], type='http', auth="public", multilang=True) + @http.route(['/shop/confirm_order/'], type='http', auth="public", website=True, multilang=True) def confirm_order(self, **post): cr, uid, context, registry = request.cr, request.uid, request.context, request.registry order_line_obj = request.registry.get('sale.order') @@ -544,8 +484,8 @@ class Ecommerce(http.Controller): billing_info['parent_id'] = company_id if request.uid != request.registry['website'].get_public_user(cr, uid, context): - partner_id = orm_user.browse(cr, uid, uid, context=context).partner_id.id - orm_parter.write(cr, uid, [partner_id], billing_info, context=context) + partner_id = orm_user.browse(cr, SUPERUSER_ID, uid, context=context).partner_id.id + orm_parter.write(cr, SUPERUSER_ID, [partner_id], billing_info, context=context) else: partner_id = orm_parter.create(cr, SUPERUSER_ID, billing_info, context=context) @@ -587,7 +527,7 @@ class Ecommerce(http.Controller): return request.redirect("/shop/payment/") - @website.route(['/shop/payment/'], type='http', auth="public", multilang=True) + @http.route(['/shop/payment/'], type='http', auth="public", website=True, multilang=True) def payment(self, **post): """ Payment step. This page proposes several payment means based on available payment.acquirer. State at this point : @@ -645,8 +585,8 @@ class Ecommerce(http.Controller): return request.website.render("website_sale.payment", values) - @website.route(['/shop/payment/transaction/<int:acquirer_id>'], - type='http', methods=['POST'], auth="public") + @http.route(['/shop/payment/transaction/<int:acquirer_id>'], + type='http', methods=['POST'], auth="public", website=True) def payment_transaction(self, acquirer_id, **post): """ Hook method that creates a payment.transaction and redirect to the acquirer, using post values to re-create the post action. @@ -688,7 +628,7 @@ class Ecommerce(http.Controller): acquirer_total_url = '%s?%s' % (acquirer_form_post_url, urllib.urlencode(post)) return request.redirect(acquirer_total_url) - @website.route('/shop/payment/get_status/<int:sale_order_id>', type='json', auth="public", multilang=True) + @http.route('/shop/payment/get_status/<int:sale_order_id>', type='json', auth="public", website=True, multilang=True) def payment_get_status(self, sale_order_id, **post): cr, uid, context = request.cr, request.uid, request.context @@ -713,7 +653,7 @@ class Ecommerce(http.Controller): 'state': tx.state, } - @website.route('/shop/payment/validate/', type='http', auth="public", multilang=True) + @http.route('/shop/payment/validate/', type='http', auth="public", website=True, multilang=True) def payment_validate(self, transaction_id=None, sale_order_id=None, **post): """ Method that should be called by the server when receiving an update for a transaction. State at this point : @@ -754,7 +694,7 @@ class Ecommerce(http.Controller): return request.redirect('/shop/confirmation/%s' % order.id) - @website.route(['/shop/confirmation/<int:sale_order_id>'], type='http', auth="public", multilang=True) + @http.route(['/shop/confirmation/<int:sale_order_id>'], type='http', auth="public", website=True, multilang=True) def payment_confirmation(self, sale_order_id, **post): """ End of checkout process controller. Confirmation is basically seing the status of a sale.order. State at this point : @@ -770,7 +710,7 @@ class Ecommerce(http.Controller): return request.website.render("website_sale.confirmation", {'order': order}) - @website.route(['/shop/change_sequence/'], type='json', auth="public") + @http.route(['/shop/change_sequence/'], type='json', auth="public", website=True) def change_sequence(self, id, sequence): product_obj = request.registry.get('product.template') if sequence == "top": @@ -782,7 +722,7 @@ class Ecommerce(http.Controller): elif sequence == "down": product_obj.set_sequence_down(request.cr, request.uid, [id], context=request.context) - @website.route(['/shop/change_styles/'], type='json', auth="public") + @http.route(['/shop/change_styles/'], type='json', auth="public", website=True) def change_styles(self, id, style_id): product_obj = request.registry.get('product.template') product = product_obj.browse(request.cr, request.uid, id, context=request.context) @@ -804,7 +744,7 @@ class Ecommerce(http.Controller): return not active - @website.route(['/shop/change_size/'], type='json', auth="public") + @http.route(['/shop/change_size/'], type='json', auth="public", website=True) def change_size(self, id, x, y): product_obj = request.registry.get('product.template') product = product_obj.browse(request.cr, request.uid, id, context=request.context) diff --git a/addons/website_sale/data/website_sale_data.xml b/addons/website_sale/data/website_sale_data.xml index 4d0fae19f67..fcb62312275 100644 --- a/addons/website_sale/data/website_sale_data.xml +++ b/addons/website_sale/data/website_sale_data.xml @@ -24,7 +24,7 @@ </record> <record id="website_sale.image_promo" model="website.product.style"> - <field name="name">Promo Ribbon</field> + <field name="name">Sale Ribbon</field> <field name="html_class">oe_ribbon_promo</field> </record> <record id="website_sale.image_full" model="website.product.style"> diff --git a/addons/website_sale/models/website.py b/addons/website_sale/models/website.py index f5bbf5decc1..192b33b5296 100644 --- a/addons/website_sale/models/website.py +++ b/addons/website_sale/models/website.py @@ -57,6 +57,73 @@ class Website(orm.Model): # Ecommerce quotation management # ************************************************************ + def _ecommerce_add_product_to_cart(self, cr, uid, product_id=0, order_line_id=0, number=1, set_number=-1, context=None): + order = self.ecommerce_get_current_order(cr, uid, context=context) + if not order: + order = self.ecommerce_get_new_order(cr, uid, context=context) + + 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)) + + # set order_line_id and product_id + if order_line_id: + order_line = None + for line in order.order_line: + if line.id == order_line_id: + order_line = line + break + if order_line: + product_id = order_line.product_id.id + else: + order_line_id = None + else: + order_line_ids = order_line_obj.search(cr, SUPERUSER_ID, + [('order_id', '=', order.id), ('product_id', '=', product_id)], context=context) + if order_line_ids: + order_line_id = order_line_ids[0] + + if not order_line_id and not product_id: + return 0 + + # values initialisation + quantity = 0 + values = {} + if order_line_id: + order_line_val = order_line_obj.read(cr, SUPERUSER_ID, [order_line_id], [], context=context)[0] + if not product_id: + product_id = order_line_val['product_id'][0] + if set_number >= 0: + quantity = set_number + else: + quantity = order_line_val['product_uom_qty'] + number + if quantity < 0: + quantity = 0 + order_line_ids = [order_line_id] + else: + fields = [k for k, v in order_line_obj._columns.items()] + values = order_line_obj.default_get(cr, SUPERUSER_ID, fields, context=context) + quantity = 1 + order_line_ids = [] + + # change and record value + vals = order_line_obj._recalculate_product_values(cr, uid, order_line_ids, product_id, context=context) + values.update(vals) + + values['product_uom_qty'] = quantity + values['product_id'] = product_id + values['order_id'] = order.id + + if order_line_id: + order_line_obj.write(cr, SUPERUSER_ID, [order_line_id], values, context=context) + if not quantity: + order_line_obj.unlink(cr, SUPERUSER_ID, [order_line_id], context=context) + 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) + return quantity + def _ecommerce_get_quotation_values(self, cr, uid, context=None): """ Generate the values for a new ecommerce quotation. """ SaleOrder = self.pool.get('sale.order') @@ -86,8 +153,7 @@ class Website(orm.Model): order_id = self._ecommerce_create_quotation(cr, uid, context=context) request.httprequest.session['ecommerce_order_id'] = order_id - order = SaleOrder.browse(cr, SUPERUSER_ID, order_id, context=context) - return SaleOrder.browse(cr, uid, order_id, context=dict(request.context, pricelist=order.pricelist_id.id)) + return SaleOrder.browse(cr, SUPERUSER_ID, order_id, context=context) def ecommerce_get_current_order(self, cr, uid, context=None): SaleOrder = self.pool.get('sale.order') diff --git a/addons/website_sale/security/ir.model.access.csv b/addons/website_sale/security/ir.model.access.csv index 0a16d3bd4cf..3cea9e28e2d 100644 --- a/addons/website_sale/security/ir.model.access.csv +++ b/addons/website_sale/security/ir.model.access.csv @@ -1,14 +1,14 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_product_product_public,product.product.public,product.model_product_product,base.group_public,1,0,0,0 -access_product_template_public,product.template.public,product.model_product_template,base.group_public,1,0,0,0 -access_product_category_,product.category.public,product.model_product_category,base.group_public,1,0,0,0 -access_product_category_public,product.category.public,product.model_product_public_category,base.group_public,1,0,0,0 -access_product_pricelist_version_public,product.pricelist.version.public,product.model_product_pricelist_version,base.group_public,1,0,0,0 -access_product_pricelist_public,product.pricelist.public,product.model_product_pricelist,base.group_public,1,0,0,0 -access_product_pricelist_item_public,product.pricelist.item.public,product.model_product_pricelist_item,base.group_public,1,0,0,0 -access_product_product_price_type_public,product.price.type.public,product.model_product_price_type,base.group_public,1,0,0,0 +access_product_product_public,product.product.public,product.model_product_product,,1,0,0,0 +access_product_template_public,product.template.public,product.model_product_template,,1,0,0,0 +access_product_category_public,product.category.public,product.model_product_category,,1,0,0,0 +access_product_public_category_public,product.category.public,product.model_product_public_category,,1,0,0,0 +access_product_pricelist_version_public,product.pricelist.version.public,product.model_product_pricelist_version,,1,0,0,0 +access_product_pricelist_public,product.pricelist.public,product.model_product_pricelist,,1,0,0,0 +access_product_pricelist_item_public,product.pricelist.item.public,product.model_product_pricelist_item,,1,0,0,0 +access_product_product_price_type_public,product.price.type.public,product.model_product_price_type,,1,0,0,0 access_product_characteristic,product.characteristic.public,website_sale.model_product_characteristic,,1,0,0,0 access_product_characteristic_value,product.characteristic.value.public,website_sale.model_product_characteristic_value,,1,0,0,0 access_product_characteristic_product,product.characteristic.product.public,website_sale.model_product_characteristic_product,,1,0,0,0 access_website_product_style,website.product.style.public,website_sale.model_website_product_style,,1,0,0,0 -access_product_supplierinfo,product.supplierinfo.public,product.model_product_supplierinfo,base.group_public,1,0,0,0 +access_product_supplierinfo,product.supplierinfo.public,product.model_product_supplierinfo,,1,0,0,0 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 ca251c273d4..db17097f231 100644 --- a/addons/website_sale/static/src/js/website.tour.shop.js +++ b/addons/website_sale/static/src/js/website.tour.shop.js @@ -6,6 +6,7 @@ website.EditorBar.include({ start: function () { this.registerTour(new website.EditorShopTour(this)); + this.registerTour(new website.EditorShopTest(this)); return this._super(); }, }); @@ -156,4 +157,154 @@ }, }); + + website.Test = website.Tour.extend({ + registerStep: function (step) { + var self = this; + var step = this._super(step); + if (step.beforeTrigger || step.afterTrigger) { + var fn = step.triggers; + step.triggers = function (callback) { + if (step.beforeTrigger) step.beforeTrigger(); + if (!step.afterTrigger) { + fn.call(step, callback); + } else { + fn.call(step, function () { + (callback || self.moveToNextStep).apply(self); + step.afterTrigger(); + }); + } + }; + } + return step; + } + }); + + + website.EditorShopTest = website.Test.extend({ + id: 'shoptest', + name: "Try to by 3 products", + path: '/shop', + init: function (editor) { + var self = this; + self.steps = [ + { + stepId: 'begin-test', + title: 'begin-test', + template: self.popover({ next: "Start Test"}), + backdrop: true, + }, + { + stepId: 'display-ipod', + element: '.oe_product_cart a:contains("iPod")', + trigger: 'click', + }, + { + stepId: 'display-wait-ipod', + trigger: 'reload', + }, + { + stepId: 'choose-ipod', + element: 'input[name="product_id"]:not([checked])', + trigger: { + id: 'mouseup', + }, + }, + { + stepId: 'add-ipod', + element: 'form[action="/shop/add_cart/"] button', + trigger: { + url: '/shop/mycart/', + }, + }, + { + stepId: 'add-suggested-product', + element: 'form[action="/shop/add_cart/"] button:contains("Add to Cart")', + trigger: 'reload', + }, + { + stepId: 'more-product', + element: '.oe_mycart a.js_add_cart_json:eq(1)', + trigger: 'click', + }, + { + stepId: 'less-product', + element: '.oe_mycart a.js_add_cart_json:eq(2)', + trigger: 'reload', + }, + { + stepId: 'number-product', + element: '.oe_mycart input.js_quantity', + trigger: 'reload', + beforeTrigger: function (tour, callback) { + if (parseInt($(".oe_mycart input.js_quantity").val(),10) !== 1) + $(".oe_mycart input.js_quantity").val("1").change(); + }, + afterTrigger: function (tour, callback) { + if ($(".oe_mycart input.js_quantity").size() !== 1) + throw "Can't remove suggested item from my cart"; + if (parseInt($(".oe_mycart input.js_quantity").val(),10) !== 1) + throw "Can't defined number of items in my cart"; + }, + }, + { + stepId: 'go-checkout-product', + element: 'a[href="/shop/checkout/"]', + trigger: { + url: '/shop/checkout/', + }, + }, + { + stepId: 'confirm-false-checkout-product', + element: 'form[action="/shop/confirm_order/"] button', + trigger: { + url: '/shop/confirm_order/', + }, + beforeTrigger: function (tour, callback) { + $("input[name='phone']").val(""); + }, + }, + { + stepId: 'confirm-checkout-product', + element: 'form[action="/shop/confirm_order/"] button', + trigger: { + url: '/shop/payment/', + }, + beforeTrigger: function (tour, callback) { + $("input[name='phone']").val("123"); + $("input[name='street']").val("123"); + $("input[name='city']").val("123"); + $("input[name='zip']").val("123"); + $("select[name='country_id']").val("21"); + }, + }, + { + stepId: 'delivery-checkout-product', + element: 'input[name="delivery_type"]:eq(1)', + trigger: 'reload', + }, + { + stepId: 'acquirer-checkout-product', + element: 'input[name="acquirer"]', + trigger: 'mouseup', + }, + { + stepId: 'pay-checkout-product', + element: 'button:contains("Pay Now")', + trigger: 'click', + + }, + { + stepId: 'end-test', + title: "end-test", + backdrop: true, + }, + ]; + return this._super(); + }, + trigger: function () { + return (this.resume() && this.testUrl(/^\/shop\//)) || this._super(); + }, + }); + }()); diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js index a00cdd80583..c6a032cd26c 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -55,7 +55,7 @@ $(document).ready(function () { } set_my_cart_quantity(data[1]); $link.parents(".input-group:first").find(".js_quantity").val(data[0]); - $('[data-oe-model="sale.order"][data-oe-field="amount_total"]').replaceWith(data[3]); + $('#mycart_total').replaceWith(data[3]); }); return false; }); diff --git a/addons/website_sale/tests/__init__.py b/addons/website_sale/tests/__init__.py new file mode 100644 index 00000000000..404d7091c2d --- /dev/null +++ b/addons/website_sale/tests/__init__.py @@ -0,0 +1 @@ +import test_ui
\ No newline at end of file diff --git a/addons/website_sale/tests/test_ui.py b/addons/website_sale/tests/test_ui.py new file mode 100644 index 00000000000..bde975fdbba --- /dev/null +++ b/addons/website_sale/tests/test_ui.py @@ -0,0 +1,6 @@ +import openerp.addons.website.tests.test_ui as test_ui,full_path + +def load_tests(loader, base, _): + base.addTest(test_ui.WebsiteUiSuite(full_path(__file__,'website_sale-sale_process-test.js'), + { 'action': 'website.action_website_homepage' }, 60.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 new file mode 100644 index 00000000000..5d013b77553 --- /dev/null +++ b/addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js @@ -0,0 +1,31 @@ +var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js'); + +var waitFor = testRunner.waitFor; + +testRunner.run(function websiteSaleTest (page, timeout) { + page.evaluate(function () { localStorage.clear(); }); + waitFor(function clientReady () { + return page.evaluate(function () { + return window.$ && window.openerp && window.openerp.website + && window.openerp.website.TestConsole + && window.openerp.website.TestConsole.test('shoptest'); + }); + }, function executeTest () { + page.evaluate(function () { + window.openerp.website.TestConsole.test('shoptest').run(true); + }); + waitFor(function testExecuted () { + var after = page.evaluate(function () { + return window.$ && $('button[data-action=edit]').is(":visible") && { + image: $('#wrap [data-snippet-id=image-text]').length, + text: $('#wrap [data-snippet-id=text-block]').length, + }; + }); + var result = after && (after.image === 1) && (after.text === 1); + return result; + }, 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 52d6d0b1c78..bfe401e29c3 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -546,29 +546,7 @@ </tr> </tbody> </table> - <table class='pull-right mb16' id="mycart_total" t-if="website_sale_order"> - <colgroup> - <col width="100"/> - <col width="120"/> - </colgroup> - <thead> - <tr style="border-top: 1px solid #000" id="order_total"> - <th><h3>Total:</h3></th> - <th class="text-right"> - <h3><t t-call="website_sale.total"/></h3> - </th> - </tr> - <tr class="text-muted" id="order_total_taxes"> - <td><abbr title="Taxes may be updated after providing shipping address">Taxes:</abbr></td> - <td class="text-right"> - <span t-field="website_sale_order.amount_tax" t-field-options='{ - "widget": "monetary", - "display_currency": "website.pricelist_id.currency_id" - }'/> - </td> - </tr> - </thead> - </table> + <t t-call="website_sale.total"/> <div class="clearfix"/> <a href="/shop" class="btn btn-default mb32"><span class="fa fa-long-arrow-left"/> Continue Shopping</a> <a t-if="website_sale_order and website_sale_order.website_order_line" href="/shop/checkout/" class="btn btn-primary pull-right mb32">Process Checkout <span class="fa fa-long-arrow-right"/></a> @@ -750,7 +728,7 @@ <div class="row"> <div class="col-md-8 oe_mycart"> <h3 class="page-header mt16">Billing Information - <small t-if="user_id.id == website.public_user.id"> or + <small groups="base.group_public"> or <a t-if="not partner" t-attf-href="/web#action=redirect&url=#{ request.httprequest.url }">sign in</a> </small> </h3> @@ -945,30 +923,7 @@ </tr> </tbody> </table> - <table class='pull-right mb16' id="mycart_total"> - <colgroup> - <col width="100"/> - <col width="120"/> - </colgroup> - <thead> - <tr style="border-top: 1px solid #000" id="order_total"> - <th><h3>Total:</h3></th> - <th class="text-right"> - <h3><span t-field="website_sale_order.amount_total" t-field-options='{ - "widget": "monetary", - "display_currency": "website.pricelist_id.currency_id" - }'/></h3> - </th> - </tr> - <tr class="text-muted" id="order_total_taxes"> - <td>Taxes:</td> - <td class="text-right"><span t-field="website_sale_order.amount_tax" t-field-options='{ - "widget": "monetary", - "display_currency": "website.pricelist_id.currency_id" - }'/></td> - </tr> - </thead> - </table> + <t t-call="website_sale.total"/> <div class="clearfix"/> <div class="oe_structure"/> </div> @@ -997,12 +952,12 @@ </div> </div> - <div class="js_payment mb64 row" t-if="acquirers" id="payment_method"> - <h4>Choose your Payment Method</h4> + <div class="js_payment mb64" t-if="acquirers" id="payment_method"> <div class="col-lg-5 col-sm-6"> + <h4>Payment Method:</h4> <t t-foreach="acquirers or []" t-as="acquirer"> <label t-if="acquirer.button" class="oe_sale_acquirer_logo" style="display: block;"> - <input t-att-value="acquirer.id" type="radio" name="acquirer"/> + <input t-att-value="acquirer.id" type="radio" name="acquirer" t-att-checked="acquirers[0] == acquirer"/> <img class="media-object" style="width: 60px; display: inline-block;" t-att-title="acquirer.name" t-att-src="'/payment_acquirer_%s/static/src/img/%s_icon.png' % (acquirer.name, acquirer.name)"/> @@ -1011,7 +966,7 @@ </div> <div class="col-lg-3 col-sm-3"> <t t-foreach="acquirers or []" t-as="acquirer"> - <div t-att-data-id="acquirer.id" t-raw="acquirer.button" class="oe_sale_acquirer_button hidden"/> + <div t-att-data-id="acquirer.id" t-raw="acquirer.button" class="oe_sale_acquirer_button hidden pull-right"/> </t> </div> </div> @@ -1075,11 +1030,36 @@ </t> </template> +<!-- Page Shop my cart and payment total --> + <template id="total"> -<span t-field="website_sale_order.amount_total" t-field-options='{ - "widget": "monetary", - "display_currency": "website.pricelist_id.currency_id" - }'/> + <table class='pull-right mb16' id="mycart_total" t-if="website_sale_order"> + <colgroup> + <col width="100"/> + <col width="120"/> + </colgroup> + <thead> + <tr style="border-top: 1px solid #000" id="order_total"> + <th><h3>Total:</h3></th> + <th class="text-right"> + <h3><span t-field="website_sale_order.amount_total" t-field-options='{ + "widget": "monetary", + "display_currency": "website.pricelist_id.currency_id" + }'/></h3> + </th> + </tr> + <tr class="text-muted" id="order_total_taxes"> + <td><abbr title="Taxes may be updated after providing shipping address">Taxes:</abbr></td> + <td class="text-right"> + <span t-field="website_sale_order.amount_tax" t-field-options='{ + "widget": "monetary", + "display_currency": "website.pricelist_id.currency_id" + }'/> + </td> + </tr> + </thead> + </table> </template> + </data> </openerp> diff --git a/addons/website_sale_delivery/controllers/main.py b/addons/website_sale_delivery/controllers/main.py index 9c688cc1b97..25ee0ed7b68 100644 --- a/addons/website_sale_delivery/controllers/main.py +++ b/addons/website_sale_delivery/controllers/main.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- from openerp.addons.website_sale.controllers.main import Ecommerce +from openerp.addons.web import http from openerp.addons.web.http import request -from openerp.addons.website.models import website from openerp import SUPERUSER_ID class Ecommerce(Ecommerce): - @website.route(['/shop/payment/'], type='http', auth="public", multilang=True) + @http.route(['/shop/payment/'], type='http', auth="public", website=True, multilang=True) def payment(self, **post): cr, uid, context = request.cr, request.uid, request.context order = self.get_order() @@ -18,6 +18,7 @@ class Ecommerce(Ecommerce): SaleOrder = request.registry['sale.order'] SaleOrder.write(cr, SUPERUSER_ID, [order.id], {'carrier_id': carrier_id}, context=context) SaleOrder.delivery_set(cr, SUPERUSER_ID, [order.id], context=context) + return request.redirect("/shop/payment/") res = super(Ecommerce, self).payment(**post) return res diff --git a/addons/website_sale_delivery/models/sale_order.py b/addons/website_sale_delivery/models/sale_order.py index 10e8e7a2b11..0a663654c30 100644 --- a/addons/website_sale_delivery/models/sale_order.py +++ b/addons/website_sale_delivery/models/sale_order.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from openerp.osv import orm, fields +from openerp import SUPERUSER_ID class delivery_carrier(orm.Model): @@ -44,5 +45,5 @@ class SaleOrder(orm.Model): delivery_ctx = dict(context, order_id=order.id) DeliveryCarrier = self.pool.get('delivery.carrier') delivery_ids = DeliveryCarrier.search(cr, uid, [], context=context) - values['deliveries'] = DeliveryCarrier.browse(cr, uid, delivery_ids, context=delivery_ctx) + values['deliveries'] = DeliveryCarrier.browse(cr, SUPERUSER_ID, delivery_ids, context=delivery_ctx) return values diff --git a/addons/website_sale_delivery/models/website.py b/addons/website_sale_delivery/models/website.py index d36ccc11c02..ab3c6e39a6b 100644 --- a/addons/website_sale_delivery/models/website.py +++ b/addons/website_sale_delivery/models/website.py @@ -6,17 +6,35 @@ from openerp import SUPERUSER_ID class Website(orm.Model): _inherit = 'website' - def _ecommerce_get_quotation_values(self, cr, uid, context=None): - """ Override the quotation values generation to add carrier_id data """ - values = super(Website, self)._ecommerce_get_quotation_values(cr, uid, context=context) - DeliveryCarrier = self.pool.get('delivery.carrier') - carrier_ids = DeliveryCarrier.search(cr, uid, [(1,"=",1)], context=context, limit=1) - # By default, select the first carrier - if carrier_ids: - values['carrier_id'] = carrier_ids[0] - return values - def _ecommerce_create_quotation(self, cr, uid, context=None): order_id = super(Website, self)._ecommerce_create_quotation(cr, uid, context=context) - self.pool['sale.order'].delivery_set(cr, SUPERUSER_ID, [order_id], context=context) + order = self.pool['sale.order'].browse(cr, SUPERUSER_ID, order_id, context=context) + self._check_carrier_quotation(cr, uid, order, context=context) return order_id + + def _ecommerce_add_product_to_cart(self, cr, uid, product_id=0, order_line_id=0, number=1, set_number=-1, context=None): + quantity = super(Website, self)._ecommerce_add_product_to_cart(cr, uid, + product_id=product_id, order_line_id=order_line_id, number=number, set_number=set_number, + context=context) + order = self.ecommerce_get_current_order(cr, uid, context=context) + return self._check_carrier_quotation(cr, uid, order, context=context) and quantity or None + + def _check_carrier_quotation(self, cr, uid, order, context=None): + # check to add or remove carrier_id + carrier_id = False + for line in order.website_order_line: + if line.product_id.type != "service": + carrier_id = True + break + + if not carrier_id: + order.write({'carrier_id': None}, context=context) + self.pool['sale.order']._delivery_unset(cr, SUPERUSER_ID, order, context=context) + return None + elif not order.carrier_id: + carrier_ids = self.pool.get('delivery.carrier').search(cr, uid, [], context=context) + order.write({'carrier_id': carrier_ids[0]}, context=context) + order.delivery_set(context=context) + return None + + return carrier_id diff --git a/addons/website_sale_delivery/views/website_sale_delivery.xml b/addons/website_sale_delivery/views/website_sale_delivery.xml index 87c1db21cc7..46f04e70a38 100644 --- a/addons/website_sale_delivery/views/website_sale_delivery.xml +++ b/addons/website_sale_delivery/views/website_sale_delivery.xml @@ -2,7 +2,7 @@ <openerp> <data> - <template id="mycart_delivery" name="Delivery Costs" inherit_id="website_sale.mycart"> + <template id="mycart_delivery" name="Delivery Costs" inherit_id="website_sale.total"> <xpath expr="//tr[@id='order_total_taxes']" position="after"> <tr class="text-muted" id="order_delivery"> <td><abbr title="Delivery will be updated after choosing a new delivery method">Delivery:</abbr></td> @@ -21,20 +21,8 @@ <script type="text/javascript" src="/website_sale_delivery/static/src/js/website_sale_delivery.js"></script> </xpath> - <xpath expr="//tr[@id='order_total_taxes']" position="after"> - <tr class="text-muted" id="order_delivery"> - <td><abbr title="Delivery will be updated after choosing a new delivery method">Delivery:</abbr></td> - <td class="text-right"> - <span t-field="order.amount_delivery" t-field-options='{ - "widget": "monetary", - "display_currency": "website.pricelist_id.currency_id" - }'/> - </td> - </tr> - </xpath> - <xpath expr="//div[@id='payment_method']" position="before"> - <div t-if="len(deliveries)" class="row" id="delivery_carrier"> + <div t-if="deliveries" class="row" id="delivery_carrier"> <h4>Choose your Delivery Method</h4> <div class="col-lg-5 col-sm-6"> <ul class="list-unstyled"> |
