summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorDarshan Kalola (OpenERP) <dka@tinyerp.com>2014-01-21 11:16:38 +0530
committerDarshan Kalola (OpenERP) <dka@tinyerp.com>2014-01-21 11:16:38 +0530
commit9ce241349f3f35b6c75a2aaf9cf7c1ce0006cd7e (patch)
treee6451193117385b322fd13e1c0f127383614d7e8 /addons
parent69e88b3fecf9b09589c4f5c46336dc0f71bf8db2 (diff)
parent53d8280f1de508f228419654b631ba8286c03388 (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')
-rw-r--r--addons/account/__openerp__.py2
-rw-r--r--addons/delivery/delivery_demo.xml1
-rw-r--r--addons/payment_acquirer_adyen/controllers/main.py5
-rw-r--r--addons/payment_acquirer_ogone/controllers/main.py5
-rw-r--r--addons/payment_acquirer_paypal/controllers/main.py13
-rw-r--r--addons/payment_acquirer_transfer/controllers/main.py5
-rw-r--r--addons/point_of_sale/static/src/js/db.js2
-rw-r--r--addons/point_of_sale/static/src/js/models.js18
-rw-r--r--addons/point_of_sale/static/src/js/widgets.js3
-rw-r--r--addons/website/controllers/main.py48
-rw-r--r--addons/website/data/website_data.xml12
-rw-r--r--addons/website/models/ir_http.py10
-rw-r--r--addons/website/models/website.py63
-rw-r--r--addons/website/security/ir.model.access.csv4
-rw-r--r--addons/website/static/src/css/website.css9
-rw-r--r--addons/website/static/src/css/website.sass9
-rw-r--r--addons/website/static/src/img/library/imac.pngbin0 -> 1025956 bytes
-rw-r--r--addons/website/static/src/img/library/ipad.pngbin0 -> 352421 bytes
-rw-r--r--addons/website/static/src/img/library/landscape_tree.jpgbin906294 -> 0 bytes
-rw-r--r--addons/website/static/src/img/library/personal_laptop.jpgbin480635 -> 0 bytes
-rw-r--r--addons/website/static/src/img/odoo_logo.pngbin0 -> 3303 bytes
-rw-r--r--addons/website/static/src/js/website.editor.js6
-rw-r--r--addons/website/static/src/js/website.snippets.editor.js2
-rw-r--r--addons/website/static/src/js/website.tour.js191
-rw-r--r--addons/website/tests/test_ui.py10
-rw-r--r--addons/website/views/snippets.xml48
-rw-r--r--addons/website/views/website_templates.xml45
-rw-r--r--addons/website_blog/controllers/main.py18
-rw-r--r--addons/website_blog/tests/test_ui.py9
-rw-r--r--addons/website_crm/controllers/main.py3
-rw-r--r--addons/website_crm_partner_assign/controllers/main.py7
-rw-r--r--addons/website_customer/controllers/main.py6
-rw-r--r--addons/website_event/controllers/main.py19
-rw-r--r--addons/website_event/security/ir.model.access.csv2
-rw-r--r--addons/website_event/tests/test_ui.py9
-rw-r--r--addons/website_event_track/controllers/event.py12
-rw-r--r--addons/website_google_map/controllers/main.py7
-rw-r--r--addons/website_hr/controllers/main.py3
-rw-r--r--addons/website_hr_recruitment/controllers/main.py13
-rw-r--r--addons/website_mail/controllers/email_designer.py5
-rw-r--r--addons/website_mail/controllers/main.py3
-rw-r--r--addons/website_membership/controllers/main.py6
-rw-r--r--addons/website_partner/controllers/main.py2
-rw-r--r--addons/website_project/controllers/main.py5
-rw-r--r--addons/website_sale/controllers/main.py134
-rw-r--r--addons/website_sale/data/website_sale_data.xml2
-rw-r--r--addons/website_sale/models/website.py70
-rw-r--r--addons/website_sale/security/ir.model.access.csv18
-rw-r--r--addons/website_sale/static/src/js/website.tour.shop.js151
-rw-r--r--addons/website_sale/static/src/js/website_sale.js2
-rw-r--r--addons/website_sale/tests/__init__.py1
-rw-r--r--addons/website_sale/tests/test_ui.py6
-rw-r--r--addons/website_sale/tests/ui_suite/website_sale-sale_process-test.js31
-rw-r--r--addons/website_sale/views/website_sale.xml92
-rw-r--r--addons/website_sale_delivery/controllers/main.py5
-rw-r--r--addons/website_sale_delivery/models/sale_order.py3
-rw-r--r--addons/website_sale_delivery/models/website.py40
-rw-r--r--addons/website_sale_delivery/views/website_sale_delivery.xml16
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
new file mode 100644
index 00000000000..da52d86f356
--- /dev/null
+++ b/addons/website/static/src/img/library/imac.png
Binary files differ
diff --git a/addons/website/static/src/img/library/ipad.png b/addons/website/static/src/img/library/ipad.png
new file mode 100644
index 00000000000..455032a4be9
--- /dev/null
+++ b/addons/website/static/src/img/library/ipad.png
Binary files differ
diff --git a/addons/website/static/src/img/library/landscape_tree.jpg b/addons/website/static/src/img/library/landscape_tree.jpg
deleted file mode 100644
index fd5c9446c7b..00000000000
--- a/addons/website/static/src/img/library/landscape_tree.jpg
+++ /dev/null
Binary files differ
diff --git a/addons/website/static/src/img/library/personal_laptop.jpg b/addons/website/static/src/img/library/personal_laptop.jpg
deleted file mode 100644
index 069487766dd..00000000000
--- a/addons/website/static/src/img/library/personal_laptop.jpg
+++ /dev/null
Binary files differ
diff --git a/addons/website/static/src/img/odoo_logo.png b/addons/website/static/src/img/odoo_logo.png
new file mode 100644
index 00000000000..4ba081e1d42
--- /dev/null
+++ b/addons/website/static/src/img/odoo_logo.png
Binary files differ
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 &amp; Signup</h3>
- <p>Clean &amp; simple Log In, Signup &amp; 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 &amp; 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) &gt; 1 or editable)">
+ <ul class="list-inline js_language_selector mt16" t-if="(len(languages) &gt; 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&amp;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">