[MERGE] Merge parents
bzr revid: rim@openerp.com-20131202080656-szogyih5rw1g41u4
This commit is contained in:
commit
966e30efe9
|
@ -260,10 +260,9 @@ class res_users(osv.Model):
|
|||
# send email to users with their signup url
|
||||
template = False
|
||||
if context.get('create_user'):
|
||||
try:
|
||||
template = self.pool.get('ir.model.data').get_object(cr, uid, 'auth_signup', 'set_password_email')
|
||||
except ValueError:
|
||||
pass
|
||||
template = self.pool.get('ir.model.data').get_object(cr, uid, 'auth_signup', 'set_password_email')
|
||||
if not template.exists():
|
||||
template = False
|
||||
if not bool(template):
|
||||
template = self.pool.get('ir.model.data').get_object(cr, uid, 'auth_signup', 'reset_password_email')
|
||||
assert template._name == 'email.template'
|
||||
|
|
|
@ -55,7 +55,7 @@ class res_partner(osv.osv, EDIMixin):
|
|||
res_partner_bank_type = self.pool.get('res.partner.bank.type')
|
||||
try:
|
||||
return self.pool.get('ir.model.data').get_object(cr, uid, 'base', 'bank_normal', context=context).code
|
||||
except ValueError:
|
||||
except:
|
||||
pass
|
||||
# second option: create a new custom type for EDI or use it if already created, as IBAN type is
|
||||
# not always appropriate: we need a free-form bank type for max flexibility (users can correct
|
||||
|
|
|
@ -461,9 +461,8 @@ class mail_thread(osv.AbstractModel):
|
|||
|
||||
posted = False
|
||||
for subtype in subtypes:
|
||||
try:
|
||||
subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, subtype.split('.')[0], subtype.split('.')[1], context=context)
|
||||
except ValueError, e:
|
||||
subtype_rec = self.pool.get('ir.model.data').get_object(cr, uid, subtype.split('.')[0], subtype.split('.')[1], context=context)
|
||||
if not subtype_rec.exists():
|
||||
_logger.debug('subtype %s not found, giving error "%s"' % (subtype, e))
|
||||
continue
|
||||
message = format_message(subtype_rec.description if subtype_rec.description else subtype_rec.name, tracked_values)
|
||||
|
|
|
@ -94,13 +94,11 @@ class publisher_warranty_contract(osv.osv):
|
|||
# old behavior based on res.log; now on mail.message, that is not necessarily installed
|
||||
IMD = self.pool['ir.model.data']
|
||||
user = self.pool['res.users'].browse(cr, SUPERUSER_ID, SUPERUSER_ID)
|
||||
try:
|
||||
poster = IMD.get_object(cr, SUPERUSER_ID, 'mail', 'group_all_employees')
|
||||
except ValueError:
|
||||
# Cannot found group, post the message on the wall of the admin
|
||||
poster = user
|
||||
poster = IMD.get_object(cr, SUPERUSER_ID, 'mail', 'group_all_employees')
|
||||
if not poster.exists():
|
||||
return True
|
||||
if not user.exists():
|
||||
return True
|
||||
poster = user
|
||||
for message in result["messages"]:
|
||||
try:
|
||||
poster.message_post(body=message, subtype='mt_comment', partner_ids=[user.partner_id.id])
|
||||
|
|
|
@ -87,12 +87,9 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""),
|
|||
user = self.pool.get('res.users').browse(cr, uid, uid, context)
|
||||
res['time_unit'] = user.company_id.project_time_mode_id.id
|
||||
else:
|
||||
try:
|
||||
product = ir_model_data.get_object(cr, uid, 'product', 'product_product_consultant')
|
||||
product = ir_model_data.get_object(cr, uid, 'product', 'product_product_consultant')
|
||||
if product.exists():
|
||||
res['time_unit'] = product.uom_id.id
|
||||
except ValueError:
|
||||
# keep default value in that case
|
||||
_logger.warning("Product with xml_id 'product.product_product_consultant' not found")
|
||||
return res
|
||||
|
||||
def _get_default_time_unit(self, cr, uid, context=None):
|
||||
|
@ -108,10 +105,10 @@ Example: 10% for retailers, promotion of 5 EUR on this product, etc."""),
|
|||
wizard = self.browse(cr, uid, ids)[0]
|
||||
|
||||
if wizard.time_unit:
|
||||
try:
|
||||
product = ir_model_data.get_object(cr, uid, 'product', 'product_product_consultant')
|
||||
product = ir_model_data.get_object(cr, uid, 'product', 'product_product_consultant')
|
||||
if product.exists():
|
||||
product.write({'uom_id': wizard.time_unit.id, 'uom_po_id': wizard.time_unit.id})
|
||||
except ValueError:
|
||||
else:
|
||||
_logger.warning("Product with xml_id 'product.product_product_consultant' not found, UoMs not updated!")
|
||||
|
||||
if wizard.module_project and wizard.time_unit:
|
||||
|
|
|
@ -27,8 +27,10 @@ class stock_fill_inventory(osv.osv_memory):
|
|||
_description = "Import Inventory"
|
||||
|
||||
def _default_location(self, cr, uid, ids, context=None):
|
||||
location = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'stock_location_stock')
|
||||
if not location.exists():
|
||||
return False
|
||||
try:
|
||||
location = self.pool.get('ir.model.data').get_object(cr, uid, 'stock', 'stock_location_stock')
|
||||
location.check_access_rule('read', context=context)
|
||||
location_id = location.id
|
||||
except (ValueError, orm.except_orm), e:
|
||||
|
|
|
@ -129,6 +129,7 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
result.append({
|
||||
'name': v.inherit_option_id.name,
|
||||
'id': v.id,
|
||||
'inherit_id': v.inherit_id.id,
|
||||
'header': True,
|
||||
'active': False
|
||||
})
|
||||
|
@ -136,6 +137,7 @@ class Website(openerp.addons.web.controllers.main.Home):
|
|||
result.append({
|
||||
'name': v.name,
|
||||
'id': v.id,
|
||||
'inherit_id': v.inherit_id.id,
|
||||
'header': False,
|
||||
'active': (v.inherit_id.id == v.inherit_option_id.id) or (not optional and v.inherit_id.id)
|
||||
})
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
</record>
|
||||
|
||||
<record id="base.group_public" model="res.groups">
|
||||
<field name="users" eval="[(4, ref('public_user'))]"/>
|
||||
<field name="users" eval="[(4, ref('website.public_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="base.group_website_publisher" model="res.groups">
|
||||
|
@ -130,10 +130,10 @@
|
|||
|
||||
<record model="ir.attachment">
|
||||
<field name="name">gears</field>
|
||||
<field name="datas_fname">gears.jpg</field>
|
||||
<field name="datas_fname">gears.png</field>
|
||||
<field name="res_model">ir.ui.view</field>
|
||||
<field name="type">url</field>
|
||||
<field name="url">/website/static/src/img/library/gears.jpg</field>
|
||||
<field name="url">/website/static/src/img/library/gears.png</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.attachment">
|
||||
|
|
|
@ -25,7 +25,7 @@ class ir_http(orm.AbstractModel):
|
|||
def _auth_method_public(self):
|
||||
if not request.session.uid:
|
||||
request.uid = request.registry['website'].get_public_user(
|
||||
request.cr, openerp.SUPERUSER_ID, request.context).id
|
||||
request.cr, openerp.SUPERUSER_ID, request.context)
|
||||
else:
|
||||
request.uid = request.session.uid
|
||||
|
||||
|
@ -46,13 +46,9 @@ class ir_http(orm.AbstractModel):
|
|||
else:
|
||||
self._auth_method_public()
|
||||
request.website = request.registry['website'].get_current_website(request.cr, request.uid, context=request.context)
|
||||
langs = request.context['langs'] = [lg.code for lg in request.website.language_ids]
|
||||
lang_cookie = request.httprequest.cookies.get('lang', None)
|
||||
if lang_cookie in langs:
|
||||
request.context['lang_cookie'] = lang_cookie
|
||||
request.context['lang_default'] = request.website.default_lang_id.code
|
||||
langs = [lg.code for lg in request.website.language_ids]
|
||||
if not hasattr(request, 'lang'):
|
||||
request.lang = request.context['lang_default']
|
||||
request.lang = request.website.default_lang_id.code
|
||||
request.context['lang'] = request.lang
|
||||
request.website.preprocess_request(request)
|
||||
if not func:
|
||||
|
@ -62,7 +58,6 @@ class ir_http(orm.AbstractModel):
|
|||
path = '/'.join(path) or '/'
|
||||
return self.reroute(path)
|
||||
return self._handle_404()
|
||||
|
||||
return super(ir_http, self)._dispatch()
|
||||
|
||||
def reroute(self, path):
|
||||
|
|
|
@ -36,8 +36,8 @@ def url_for(path_or_uri, lang=None, keep_query=None):
|
|||
if request and not url.netloc and not url.scheme:
|
||||
location = urlparse.urljoin(request.httprequest.path, location)
|
||||
lang = lang or request.context.get('lang')
|
||||
langs = request.context.get('langs')
|
||||
if location[0] == '/' and len(langs) > 1 and lang != request.context['lang_default']:
|
||||
langs = [lg.code for lg in request.website.language_ids]
|
||||
if location[0] == '/' and len(langs) > 1 and lang != request.website.default_lang_id.code:
|
||||
ps = location.split('/')
|
||||
if ps[1] in langs:
|
||||
ps[1] = lang
|
||||
|
@ -69,6 +69,20 @@ def urlplus(url, params):
|
|||
))
|
||||
|
||||
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)
|
||||
menu = menus and menus[0] or False
|
||||
return dict( map(lambda x: (x, menu), ids) )
|
||||
|
||||
def _get_public_user(self, cr, uid, ids, name='public_user', arg=(), context=None):
|
||||
ref = self.get_public_user(cr, uid, context=context)
|
||||
return dict( map(lambda x: (x, ref), ids) )
|
||||
|
||||
_name = "website" # Avoid website.website convention for conciseness (for new api). Got a special authorization from xmo and rco
|
||||
_description = "Website"
|
||||
_columns = {
|
||||
|
@ -82,9 +96,13 @@ class website(osv.osv):
|
|||
'social_linkedin': fields.char('LinkedIn Account'),
|
||||
'social_youtube': fields.char('Youtube Account'),
|
||||
'social_googleplus': fields.char('Google+ Account'),
|
||||
'public_user': fields.function(_get_public_user, relation='res.users', type='many2one', string='Public User'),
|
||||
'menu_id': fields.function(_get_menu, relation='website.menu', type='many2one', string='Main Menu',
|
||||
store= {
|
||||
'website.menu': (_get_menu_website, ['sequence','parent_id','website_id'], 10)
|
||||
})
|
||||
}
|
||||
|
||||
public_user = None
|
||||
def new_page(self, cr, uid, name, template='website.default_page', ispage=True, context=None):
|
||||
context=context or {}
|
||||
# completely arbitrary max_length
|
||||
|
@ -133,11 +151,9 @@ class website(osv.osv):
|
|||
return False
|
||||
|
||||
def get_public_user(self, cr, uid, context=None):
|
||||
if not self.public_user:
|
||||
uid = openerp.SUPERUSER_ID
|
||||
ref = self.pool['ir.model.data'].get_object_reference(cr, uid, 'website', 'public_user')
|
||||
self.public_user = self.pool[ref[0]].browse(cr, uid, ref[1])
|
||||
return self.public_user
|
||||
uid = openerp.SUPERUSER_ID
|
||||
res = self.pool['ir.model.data'].get_object_reference(cr, uid, 'website', 'public_user')
|
||||
return res and res[1] or False
|
||||
|
||||
def get_current_website(self, cr, uid, context=None):
|
||||
# TODO: Select website, currently hard coded
|
||||
|
@ -147,19 +163,13 @@ class website(osv.osv):
|
|||
def redirect(url):
|
||||
return werkzeug.utils.redirect(url_for(url))
|
||||
request.redirect = redirect
|
||||
is_public_user = request.uid == self.get_public_user(cr, uid, context).id
|
||||
|
||||
user = self.pool['res.users'].browse(cr, uid, uid, context=context)
|
||||
website_publisher_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'group_website_publisher')[1]
|
||||
is_website_publisher = website_publisher_id in [g.id for g in user.groups_id]
|
||||
|
||||
is_website_publisher = self.pool.get('ir.model.access').check_groups(cr, uid, 'base.group_website_publisher')
|
||||
lang = request.context['lang']
|
||||
is_master_lang = lang == request.website.default_lang_id.code
|
||||
request.context.update({
|
||||
'is_public_user': is_public_user,
|
||||
'is_master_lang': is_master_lang,
|
||||
'editable': is_website_publisher,
|
||||
'translatable': not is_public_user and not is_master_lang,
|
||||
'translatable': not is_master_lang,
|
||||
})
|
||||
|
||||
def get_template(self, cr, uid, ids, template, context=None):
|
||||
|
@ -174,7 +184,6 @@ class website(osv.osv):
|
|||
|
||||
def _render(self, cr, uid, ids, template, values=None, context=None):
|
||||
user = self.pool.get("res.users")
|
||||
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
|
@ -200,8 +209,9 @@ class website(osv.osv):
|
|||
|
||||
if 'main_object' not in qweb_context:
|
||||
qweb_context['main_object'] = view
|
||||
|
||||
return view.render(qweb_context, engine='website.qweb', context=context)
|
||||
#context['debug'] = True
|
||||
result = view.render(qweb_context, engine='website.qweb', context=context)
|
||||
return result
|
||||
|
||||
def render(self, cr, uid, ids, template, values=None, context=None):
|
||||
def callback(template, values, context):
|
||||
|
@ -333,7 +343,7 @@ class website(osv.osv):
|
|||
"""
|
||||
router = request.httprequest.app.get_db_router(request.db)
|
||||
# Force enumeration to be performed as public user
|
||||
uid = self.get_public_user(cr, uid, context=context).id
|
||||
uid = self.get_public_user(cr, uid, context=context)[1].id
|
||||
for rule in router.iter_rules():
|
||||
if not self.rule_is_enumerable(rule):
|
||||
continue
|
||||
|
@ -465,8 +475,6 @@ class website(osv.osv):
|
|||
html += request.website._render(template, {'object_id': object_id})
|
||||
return html
|
||||
|
||||
def get_menu(self, cr, uid, ids, context=None):
|
||||
return self.pool['website.menu'].get_menu(cr, uid, ids[0], context=context)
|
||||
|
||||
class website_menu(osv.osv):
|
||||
_name = "website.menu"
|
||||
|
@ -492,12 +500,7 @@ class website_menu(osv.osv):
|
|||
_parent_order = 'sequence, name'
|
||||
_order = "parent_left"
|
||||
|
||||
def get_menu(self, cr, uid, website_id, context=None):
|
||||
root_domain = [('parent_id', '=', False)] # ('website_id', '=', website_id),
|
||||
menu_ids = self.search(cr, uid, root_domain, order='id', context=context)
|
||||
menu = self.browse(cr, uid, menu_ids, context=context)
|
||||
return menu[0]
|
||||
|
||||
# would be better to take a menu_id as argument
|
||||
def get_tree(self, cr, uid, website_id, context=None):
|
||||
def make_tree(node):
|
||||
menu_node = dict(
|
||||
|
@ -512,7 +515,7 @@ class website_menu(osv.osv):
|
|||
for child in node.child_id:
|
||||
menu_node['children'].append(make_tree(child))
|
||||
return menu_node
|
||||
menu = self.get_menu(cr, uid, website_id, context=context)
|
||||
menu = self.pool.get('website').browse(cr, uid, website_id, context=context).menu_id
|
||||
return make_tree(menu)
|
||||
|
||||
def save(self, cr, uid, website_id, data, context=None):
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 85 KiB |
Binary file not shown.
After Width: | Height: | Size: 138 KiB |
|
@ -59,8 +59,12 @@
|
|||
website.ace.ViewOption = openerp.Widget.extend({
|
||||
template: 'website.ace_view_option',
|
||||
init: function (parent, options) {
|
||||
var indent = "- ";
|
||||
this.view_id = options.id;
|
||||
this.view_name = options.name;
|
||||
for (var i = 0; i<options.level; i++) {
|
||||
this.view_name = indent + this.view_name;
|
||||
}
|
||||
this._super(parent);
|
||||
},
|
||||
});
|
||||
|
@ -133,19 +137,48 @@
|
|||
},
|
||||
loadViews: function (views) {
|
||||
var self = this;
|
||||
var activeViews = _.uniq(_.filter(views, function (view) {
|
||||
return view.active;
|
||||
}), false, function (view) {
|
||||
return view.id;
|
||||
});
|
||||
var $viewList = self.$('#ace-view-list');
|
||||
_.each(activeViews, function (view) {
|
||||
var views = this.buildViewGraph(views);
|
||||
_.each(views, function (view) {
|
||||
if (view.id) {
|
||||
new website.ace.ViewOption(self, view).appendTo($viewList);
|
||||
self.loadView(view.id);
|
||||
}
|
||||
});
|
||||
},
|
||||
buildViewGraph: function (views) {
|
||||
var activeViews = _.uniq(_.filter(views, function (view) {
|
||||
return view.active;
|
||||
}), false, function (view) {
|
||||
return view.id;
|
||||
});
|
||||
var index = {};
|
||||
var roots = [];
|
||||
_.each(activeViews, function (view) {
|
||||
index[view.id] = view;
|
||||
view.children = [];
|
||||
});
|
||||
_.each(index, function (view) {
|
||||
var parentId = view.inherit_id;
|
||||
if (parentId) {
|
||||
index[parentId].children.push(view);
|
||||
} else {
|
||||
roots.push(view);
|
||||
}
|
||||
});
|
||||
var result = [];
|
||||
function visit (node, level) {
|
||||
node.level = level;
|
||||
result.push(node);
|
||||
_.each(node.children, function (child) {
|
||||
visit(child, level + 1);
|
||||
});
|
||||
}
|
||||
_.each(roots, function (node) {
|
||||
visit(node, 0);
|
||||
});
|
||||
return result;
|
||||
},
|
||||
loadView: function (id) {
|
||||
var viewId = parseInt(id, 10);
|
||||
var self = this;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
openerp.jsonRpc('/web/dataset/call_kw', 'call', {
|
||||
model: 'website.menu',
|
||||
method: 'get_tree',
|
||||
args: [[context.website_id]],
|
||||
args: [context.website_id],
|
||||
kwargs: {
|
||||
context: context
|
||||
},
|
||||
|
|
|
@ -774,12 +774,6 @@
|
|||
|
||||
</div>
|
||||
|
||||
<div id="snippet_hidden" class="hidden">
|
||||
|
||||
<div t-name="website.snippets.colmd" data-snippet-id='colmd' data-selector-vertical-children='.row'></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="snippet_styles" class="hidden">
|
||||
|
||||
<div data-snippet-style-id='carousel-style' data-selector='div[data-snippet-id="carousel"]'>
|
||||
|
|
|
@ -126,7 +126,7 @@
|
|||
</div>
|
||||
<div class="collapse navbar-collapse navbar-top-collapse">
|
||||
<ul class="nav navbar-nav navbar-right" id="top_menu">
|
||||
<t t-foreach="website.get_menu().child_id" t-as="submenu">
|
||||
<t t-foreach="website.menu_id.child_id" t-as="submenu">
|
||||
<t t-call="website.submenu"/>
|
||||
</t>
|
||||
<li class="active dropdown" t-ignore="true" t-if="user_id.id != website.public_user.id">
|
||||
|
@ -541,13 +541,10 @@ Sitemap: <t t-esc="url_root"/>sitemap.xml
|
|||
|
||||
<template id="company_description" name="Company Description">
|
||||
<address>
|
||||
<strong t-field="res_company.name">Name</strong><br />
|
||||
<span t-field="res_company.street"></span> <span t-field="res_company.state_id"></span><br />
|
||||
<span t-field="res_company.zip"></span> <span t-field="res_company.city"></span><br />
|
||||
<span t-field="res_company.country_id"> </span><br />
|
||||
<div t-field="res_company.partner_id">Name</div>
|
||||
<br />
|
||||
<span>&#x2706; <span t-field="res_company.phone"></span></span><br />
|
||||
<i class="icon-envelope"></i> <span t-field="res_company.email"></span>
|
||||
<div>&#x2706; <span t-field="res_company.phone"></span></div>
|
||||
<div class="icon-envelope" t-field="res_company.email"></div>
|
||||
</address>
|
||||
<a t-att-href="res_company.google_map_link()" target="_BLANK">
|
||||
<img class="thumbnail img-responsive" t-att-src="res_company.google_map_img()" />
|
||||
|
|
|
@ -67,14 +67,14 @@ class WebsiteBlog(http.Controller):
|
|||
})
|
||||
|
||||
@website.route([
|
||||
'/blog/cat/<model("blog.category"):category>/',
|
||||
'/blog/cat/<model("blog.category"):category>/page/<int:page>/',
|
||||
'/blog/cat/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/',
|
||||
'/blog/cat/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/page/<int:page>/',
|
||||
'/blog/cat/<model("blog.category"):category>/date/<string(length=21):date>/',
|
||||
'/blog/cat/<model("blog.category"):category>/date/<string(length=21):date>/page/<int:page>/',
|
||||
'/blog/cat/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/date/<string(length=21):date>/',
|
||||
'/blog/cat/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/date/<string(length=21):date>/page/<int:page>/',
|
||||
'/blog/<model("blog.category"):category>/',
|
||||
'/blog/<model("blog.category"):category>/page/<int:page>/',
|
||||
'/blog/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/',
|
||||
'/blog/<model("blog.category"):category>/tag/<model("blog.tag"):tag>/page/<int:page>/',
|
||||
'/blog/<model("blog.category"):category>/date/<string(length=21):date>/',
|
||||
'/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)
|
||||
def blog(self, category=None, tag=None, date=None, page=1, **opt):
|
||||
""" Prepare all values to display the blog.
|
||||
|
@ -151,7 +151,7 @@ class WebsiteBlog(http.Controller):
|
|||
return request.website.render("website_blog.blog_post_short", values)
|
||||
|
||||
@website.route([
|
||||
'/blog/<model("blog.post"):blog_post>/',
|
||||
'/blogpost/<model("blog.post"):blog_post>/',
|
||||
], type='http', auth="public", multilang=True)
|
||||
def blog_post(self, blog_post=None, tag=None, date=None, page=1, enable_editor=None):
|
||||
""" Prepare all values to display the blog.
|
||||
|
@ -214,7 +214,7 @@ class WebsiteBlog(http.Controller):
|
|||
}
|
||||
return request.website.render("website_blog.blog_post_complete", values)
|
||||
|
||||
@website.route(['/blog/<int:blog_post_id>/comment'], type='http', auth="public")
|
||||
@website.route(['/blogpost/<int:blog_post_id>/comment'], type='http', auth="public")
|
||||
def blog_post_comment(self, blog_post_id, **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
if post.get('comment'):
|
||||
|
@ -226,7 +226,7 @@ class WebsiteBlog(http.Controller):
|
|||
context=dict(context, mail_create_nosubcribe=True))
|
||||
return werkzeug.utils.redirect(request.httprequest.referrer + "#comments")
|
||||
|
||||
@website.route('/blog/new', type='http', auth="public", multilang=True)
|
||||
@website.route('/blogpost/new', type='http', auth="public", 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)
|
||||
|
@ -237,9 +237,9 @@ class WebsiteBlog(http.Controller):
|
|||
'content': '',
|
||||
'website_published': False,
|
||||
}, context=create_context)
|
||||
return werkzeug.utils.redirect("/blog/%s/?enable_editor=1" % new_blog_post_id)
|
||||
return werkzeug.utils.redirect("/blogpost/%s/?enable_editor=1" % new_blog_post_id)
|
||||
|
||||
@website.route('/blog/duplicate', type='http', auth="public")
|
||||
@website.route('/blogpost/duplicate', type='http', auth="public")
|
||||
def blog_post_copy(self, blog_post_id, **post):
|
||||
""" Duplicate a blog.
|
||||
|
||||
|
@ -250,4 +250,4 @@ class WebsiteBlog(http.Controller):
|
|||
cr, uid, context = request.cr, request.uid, request.context
|
||||
create_context = dict(context, mail_create_nosubscribe=True)
|
||||
new_blog_post_id = request.registry['blog.post'].copy(cr, uid, blog_post_id, {}, context=create_context)
|
||||
return werkzeug.utils.redirect("/blog/%s/?enable_editor=1" % new_blog_post_id)
|
||||
return werkzeug.utils.redirect("/blogpost/%s/?enable_editor=1" % new_blog_post_id)
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
<record id="menu_blog" model="website.menu">
|
||||
<field name="name">News</field>
|
||||
<field name="url" eval="'/blog/cat/'+str(ref('website_blog.blog_category_1'))"/>
|
||||
<field name="url" eval="'/blog/'+str(ref('website_blog.blog_category_1'))"/>
|
||||
<field name="parent_id" ref="website.main_menu"/>
|
||||
<field name="sequence" type="int">50</field>
|
||||
</record>
|
||||
|
@ -21,7 +21,7 @@
|
|||
<record id="action_open_website" model="ir.actions.act_url">
|
||||
<field name="name">Website Blogs</field>
|
||||
<field name="target">self</field>
|
||||
<field name="url" eval="'/blog/cat/'+str(ref('website_blog.blog_category_1'))+'/?blog-tutorial=true'"/>
|
||||
<field name="url" eval="'/blog/'+str(ref('website_blog.blog_category_1'))+'/?blog-tutorial=true'"/>
|
||||
</record>
|
||||
<record id="base.open_menu" model="ir.actions.todo">
|
||||
<field name="action_id" ref="action_open_website"/>
|
||||
|
|
|
@ -182,7 +182,7 @@
|
|||
return (this.isCurrentStep('post-page') || this.isCurrentStep('save-changes')) && this._super();
|
||||
},
|
||||
trigger: function () {
|
||||
return (this.resume() && this.testUrl(/^\/blog\/[0-9]+\//)) || this._super();
|
||||
return (this.resume() && this.testUrl(/^\/blogpost\/[0-9]+\//)) || this._super();
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
.call('name_search', [], { context: website.get_context() });
|
||||
},
|
||||
}).then(function (cat_id) {
|
||||
document.location = '/blog/new?category_id=' + cat_id;
|
||||
document.location = '/blogpost/new?category_id=' + cat_id;
|
||||
});
|
||||
}
|
||||
}),
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<!-- Layout add nav and footer -->
|
||||
<template id="header_footer_custom" inherit_id="website.layout" name="Footer News Blog Link">
|
||||
<xpath expr="//footer//div[@name='info']/ul" position="inside">
|
||||
<li><a t-href="/blog/cat/%(website_blog.blog_category_1)d/">News</a></li>
|
||||
<li><a t-href="/blog/%(website_blog.blog_category_1)d/">News</a></li>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
@ -52,7 +52,7 @@
|
|||
<t t-foreach="blogs" t-as="blog">
|
||||
<div class="col-md-4">
|
||||
<h4>
|
||||
<a t-href="/blog/#{blog.id}?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}" t-field="blog.name"></a>
|
||||
<a t-href="/blogpost/#{blog.id}?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}" t-field="blog.name"></a>
|
||||
<span t-if="not blog.website_published" class="text-warning">
|
||||
&nbsp;
|
||||
<span class="icon-warning-sign" title="Not published"/>
|
||||
|
@ -61,7 +61,7 @@
|
|||
<div class="text-muted">
|
||||
<span class="icon-calendar"> <span t-field="blog.create_date"/> &nbsp;</span>
|
||||
<span class="icon-folder-open"> In
|
||||
<a t-href="/blog/cat/#{blog.category_id.id}">
|
||||
<a t-href="/blog//#{blog.category_id.id}">
|
||||
<span t-field="blog.category_id"/>
|
||||
</a> &nbsp;
|
||||
</span>
|
||||
|
@ -74,7 +74,7 @@
|
|||
</div>
|
||||
<div class="text-muted" t-if="len(blog.message_ids) > 0">
|
||||
<span class="icon-comment">
|
||||
<a t-href="/blog/#{blog.id}/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}#comment">
|
||||
<a t-href="/blogpost/#{blog.id}/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}#comment">
|
||||
<t t-if="len(blog.message_ids) <= 1" ><t t-esc="len(blog.message_ids)"/> comment</t>
|
||||
<t t-if="len(blog.message_ids) > 1"><t t-esc="len(blog.message_ids)"/> comments</t>
|
||||
</a>
|
||||
|
@ -109,12 +109,12 @@
|
|||
<t t-foreach="blog_posts" t-as="blog_post">
|
||||
<div t-att-data-publish="blog_post.website_published and 'on' or 'off'">
|
||||
<h2 class="text-center">
|
||||
<a t-href="/blog/#{blog_post.id}/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}" t-field="blog_post.name"></a>
|
||||
<a t-href="/blogpost/#{blog_post.id}/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}" t-field="blog_post.name"></a>
|
||||
</h2>
|
||||
<p class="post-meta text-muted text-center" name='blog_post_data'>
|
||||
<span class="icon-calendar"> <span t-field="blog_post.create_date"/> &nbsp;</span>
|
||||
<span t-if="len(blog_post.message_ids) > 0" class="icon-comment">
|
||||
<a t-href="/blog/#{blog_post.id}/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}#comment">
|
||||
<a t-href="/blogpost/#{blog_post.id}/?#{ tag and 'tag=%s' % tag.id or '' }#{tag and date and '&' or ''}#{ date and 'date=%s' % date or ''}#comment">
|
||||
<t t-if="len(blog_post.message_ids) <= 1" ><t t-esc="len(blog_post.message_ids)"/> comment</t>
|
||||
<t t-if="len(blog_post.message_ids) > 1"><t t-esc="len(blog_post.message_ids)"/> comments</t>
|
||||
</a>
|
||||
|
@ -144,7 +144,7 @@
|
|||
<p class="post-meta text-muted text-center" t-if="len(blog_post.tag_ids)">
|
||||
<span class="icon-tags"/>
|
||||
<t t-foreach="blog_post.tag_ids" t-as="tag">
|
||||
<a t-href="/blog/cat/#{ category.id }/tag/#{tag.id}" t-esc="tag.name"/> &nbsp;
|
||||
<a t-href="/blog/#{ category.id }/tag/#{tag.id}" t-esc="tag.name"/> &nbsp;
|
||||
</t>
|
||||
</p>
|
||||
</xpath>
|
||||
|
@ -157,10 +157,10 @@
|
|||
<div class="row">
|
||||
<div class="col-sm-9">
|
||||
<ol class="breadcrumb">
|
||||
<li><a t-href="/blog/cat/#{category.id}"><span t-field="category.name"/></a></li>
|
||||
<li t-if="tag"><a t-href="/blog/cat/#{ category.id }/tag/#{tag.id}"><span t-field="tag.name"/></a></li>
|
||||
<li t-if="tag and date"><a t-href="/blog/cat/#{ category.id }/tag/#{tag.id}/date/#{ date }" t-esc="date_name"/></li>
|
||||
<li t-if="not tag and date"><a t-href="/blog/cat/#{ category.id }/date/#{ date }" t-esc="date_name"/></li>
|
||||
<li><a t-href="/blog/#{category.id}"><span t-field="category.name"/></a></li>
|
||||
<li t-if="tag"><a t-href="/blog/#{ category.id }/tag/#{tag.id}"><span t-field="tag.name"/></a></li>
|
||||
<li t-if="tag and date"><a t-href="/blog/#{ category.id }/tag/#{tag.id}/date/#{ date }" t-esc="date_name"/></li>
|
||||
<li t-if="not tag and date"><a t-href="/blog/#{ category.id }/date/#{ date }" t-esc="date_name"/></li>
|
||||
<li class="active"><span t-field="blog_post.name"/></li>
|
||||
</ol>
|
||||
</div><div class="col-sm-3">
|
||||
|
@ -168,7 +168,7 @@
|
|||
<t t-set="object" t-value="blog_post"/>
|
||||
<t t-set="publish_edit" t-value="True"/>
|
||||
<li t-ignore="True">
|
||||
<form class="duplicate hidden" action="/blog/duplicate">
|
||||
<form class="duplicate hidden" action="/blogpost/duplicate">
|
||||
<input name="blog_post_id" t-att-value="blog_post.id"/>
|
||||
</form>
|
||||
<a href="#" class="duplicate" onclick="$(this).prev('form').submit()">Duplicate</a>
|
||||
|
@ -215,21 +215,20 @@
|
|||
|
||||
<!-- Options: Blog Post: user can reply -->
|
||||
<template id="opt_blog_post_complete_comment" name="Allow Comments"
|
||||
inherit_option_id="website_blog.blog_post_complete" inherit_id="website_blog.blog_post_complete">
|
||||
inherit_option_id="website_blog.blog_post_complete" inherit_id="website_blog.blog_post_complete"
|
||||
groups="website_mail.group_comment">
|
||||
<xpath expr="//ul[@id='comments-list']" position="after">
|
||||
<t t-if="not is_public_user">
|
||||
<section groups="group_website_blog_reply" class="mb32">
|
||||
<form id="comment" t-attf-action="/blog/#{blog_post.id}/#{ path_filter }/comment"
|
||||
method="POST">
|
||||
<img class="img pull-left img-rounded" t-att-src="'/website/image?model=res.partner&field=image_small&id='+str(user_id.partner_id.id)" style="width: 50px; margin-right: 10px;"/>
|
||||
<div class="pull-left mb32" style="width: 75%%">
|
||||
<textarea rows="3" name="comment" class="form-control" placeholder="Write a comment..."></textarea>
|
||||
<button type="submit" class="btn btn-primary mt8">Post</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<div class="clearfix"/>
|
||||
</t>
|
||||
<section class="mb32">
|
||||
<form id="comment" t-attf-action="/blogpost/#{blog_post.id}/#{ path_filter }/comment"
|
||||
method="POST">
|
||||
<img class="img pull-left img-rounded" t-att-src="'/website/image?model=res.partner&field=image_small&id='+str(user_id.partner_id.id)" style="width: 50px; margin-right: 10px;"/>
|
||||
<div class="pull-left mb32" style="width: 75%%">
|
||||
<textarea rows="3" name="comment" class="form-control" placeholder="Write a comment..."></textarea>
|
||||
<button type="submit" class="btn btn-primary mt8">Post</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
<div class="clearfix"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
|
@ -256,7 +255,7 @@
|
|||
<p class="post-meta text-muted text-center" t-if="len(blog_post.tag_ids)">
|
||||
<span class="icon-tags"/>
|
||||
<t t-foreach="blog_post.tag_ids" t-as="tag">
|
||||
<a t-href="/blog/cat/#{ category.id }/tag/#{tag.id}" t-esc="tag.name"/> &nbsp;
|
||||
<a t-href="/blog/#{ category.id }/tag/#{tag.id}" t-esc="tag.name"/> &nbsp;
|
||||
</t>
|
||||
</p>
|
||||
</xpath>
|
||||
|
@ -292,7 +291,7 @@
|
|||
<ul class="nav nav-pills nav-stacked">
|
||||
<t t-foreach="tags" t-as="tag_id">
|
||||
<li t-att-class="tag and tag_id.id == tag.id and 'active' or None" style="display: inline-block;">
|
||||
<a t-href="/blog/cat/#{ category.id }/tag/#{ tag_id.id }"><span t-field="tag_id.name"/></a>
|
||||
<a t-href="/blog/#{ category.id }/tag/#{ tag_id.id }"><span t-field="tag_id.name"/></a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
|
@ -312,7 +311,7 @@
|
|||
<ul class="nav nav-pills nav-stacked">
|
||||
<t t-foreach="nav_list" t-as="months">
|
||||
<li t-att-class="months['date'] == date and 'active' or None">
|
||||
<a t-ignore="True" t-href="/blog/cat/#{ category.id }/#{ tag and 'tag/%s/' % tag.id or '' }date/#{ months['date'] }"><t t-esc="months['create_date']"/><span class="pull-right badge" t-esc="months['create_date_count']"/></a>
|
||||
<a t-ignore="True" t-href="/blog/#{ category.id }/#{ tag and 'tag/%s/' % tag.id or '' }date/#{ months['date'] }"><t t-esc="months['create_date']"/><span class="pull-right badge" t-esc="months['create_date_count']"/></a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
|
@ -382,7 +381,7 @@
|
|||
<ul class="nav nav-pills nav-stacked">
|
||||
<t t-foreach="categories" t-as="nav_category">
|
||||
<li t-att-class="nav_category.id == category.id and 'active' or ''">
|
||||
<a t-href="/blog/cat/#{nav_category.id}">
|
||||
<a t-href="/blog/#{nav_category.id}">
|
||||
<span t-field="nav_category.name"/>
|
||||
</a>
|
||||
</li>
|
||||
|
|
|
@ -25,8 +25,6 @@ class WebsiteCrmPartnerAssign(http.Controller):
|
|||
|
||||
# format displayed membership lines domain
|
||||
base_partner_domain = [('is_company', '=', True)]
|
||||
if request.context['is_public_user']:
|
||||
base_partner_domain += [('website_published', '=', True)]
|
||||
partner_domain = list(base_partner_domain)
|
||||
if grade_id and grade_id != "all":
|
||||
partner_domain += [('grade_id', '=', int(grade_id))] # try/catch int
|
||||
|
@ -93,10 +91,7 @@ class WebsiteCrmPartnerAssign(http.Controller):
|
|||
@website.route(['/partners/<int:partner_id>/'], type='http', auth="public", multilang=True)
|
||||
def partners_ref(self, partner_id=0, **post):
|
||||
partner_obj = request.registry['res.partner']
|
||||
if request.context['is_public_user']:
|
||||
partner_ids = partner_obj.search(request.cr, request.uid, [('website_published', '=', True), ('id', '=', partner_id)], context=request.context)
|
||||
else:
|
||||
partner_ids = partner_obj.search(request.cr, request.uid, [('id', '=', partner_id)], context=request.context)
|
||||
partner_ids = partner_obj.search(request.cr, request.uid, [('id', '=', partner_id)], context=request.context)
|
||||
if not partner_ids:
|
||||
return self.members(post)
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ class event_event(osv.osv):
|
|||
if event.show_tracks:
|
||||
result.append( (_('Agenda'), '/event/%s/track/' % event.id))
|
||||
if event.blog_id:
|
||||
result.append( (_('News'), '/blog/cat/'+str(event.blog_ig.id)))
|
||||
result.append( (_('News'), '/blogpost/'+str(event.blog_ig.id)))
|
||||
if event.show_track_proposal:
|
||||
result.append( (_('Talk Proposals'), '/event/%s/track_proposal/' % event.id))
|
||||
return result
|
||||
|
|
|
@ -26,11 +26,6 @@ class google_map(http.Controller):
|
|||
domain_public = domain + [('website_published', '=', True)]
|
||||
partner_ids = partner_obj.search(request.cr, openerp.SUPERUSER_ID,
|
||||
domain_public, context=request.context)
|
||||
if not request.context['is_public_user']:
|
||||
partner_ids += partner_obj.search(request.cr, request.uid, domain,
|
||||
context=request.context)
|
||||
partner_ids = list(set(partner_ids))
|
||||
|
||||
return partner_obj.google_map_json(request.cr, openerp.SUPERUSER_ID,
|
||||
partner_ids, request.context)
|
||||
|
||||
|
@ -42,14 +37,13 @@ class google_map(http.Controller):
|
|||
latitude = post.get('latitude') and float(post['latitude'])
|
||||
longitude = post.get('longitude') and float(post['longitude'])
|
||||
|
||||
if not request.context['is_public_user'] and partner_id and (latitude or longitude):
|
||||
values = {
|
||||
'partner_latitude': latitude,
|
||||
'partner_longitude': longitude,
|
||||
'date_localization': datetime.now().strftime('%Y-%m-%d'),
|
||||
}
|
||||
partner_obj.write(request.cr, request.uid, [partner_id], values,
|
||||
request.context)
|
||||
values = {
|
||||
'partner_latitude': latitude,
|
||||
'partner_longitude': longitude,
|
||||
'date_localization': datetime.now().strftime('%Y-%m-%d'),
|
||||
}
|
||||
partner_obj.write(request.cr, request.uid, [partner_id], values,
|
||||
request.context)
|
||||
|
||||
|
||||
# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
'depends': ['website', 'mail'],
|
||||
'data': [
|
||||
'views/website_mail.xml',
|
||||
'security/website_mail.xml',
|
||||
],
|
||||
'css': [
|
||||
'static/src/css/website_mail.css',
|
||||
|
|
|
@ -32,7 +32,7 @@ class WebsiteMail(http.Controller):
|
|||
partner_obj = request.registry['res.partner']
|
||||
user_obj = request.registry['res.users']
|
||||
partner_ids = []
|
||||
if request.context['is_public_user'] and email and email != u'false': # post contains stringified booleans
|
||||
if email and email != u'false': # post contains stringified booleans
|
||||
partner_ids = partner_obj.search(request.cr, SUPERUSER_ID, [("email", "=", email)], context=request.context)
|
||||
if not partner_ids:
|
||||
partner_ids = [partner_obj.name_create(request.cr, SUPERUSER_ID, email, request.context)]
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="group_comment" model="res.groups">
|
||||
<field name="name">Website Comments</field>
|
||||
<field name="comment">Allows website visitors to post comments on blogs, etc.</field>
|
||||
</record>
|
||||
|
||||
<record id="base.group_user" model="res.groups">
|
||||
<field name="implied_ids" eval="[(4, ref('website_mail.group_comment'))]"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -31,9 +31,7 @@ class TestControllers(TestMail):
|
|||
# print request
|
||||
|
||||
cr, uid = self.cr, self.uid
|
||||
# context = {
|
||||
# 'is_public_user': True,
|
||||
# }
|
||||
# context = { }
|
||||
# email = 'Marcel Dupuis <marcel.dupuis@example.com>'
|
||||
# website_mail = WebsiteMail()
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="input-group js_follow" t-att-data-id="object.id"
|
||||
t-att-data-object="object._name"
|
||||
t-att-data-follow="object.id and object.message_is_follower and 'on' or 'off'">
|
||||
<input t-if="is_public_user"
|
||||
<input
|
||||
type="email" name="email"
|
||||
class="js_follow_email form-control"
|
||||
t-att-value="email or ''"
|
||||
|
|
|
@ -8,6 +8,8 @@ from openerp.addons.web import http
|
|||
from openerp.addons.web.http import request
|
||||
from openerp.addons.website.models import website
|
||||
|
||||
PPG = 20 # Products Per Page
|
||||
PPR = 4 # Products Per Row
|
||||
|
||||
class CheckoutInfo(object):
|
||||
mandatory_billing_fields = ["name", "phone", "email", "street", "city", "country_id", "zip"]
|
||||
|
@ -40,6 +42,57 @@ class CheckoutInfo(object):
|
|||
return dict((field_name, post[field_name]) for field_name in self.all_fields() if post[field_name])
|
||||
|
||||
|
||||
#
|
||||
# Compute grid of products according to their sizes
|
||||
#
|
||||
class table_compute(object):
|
||||
def __init__(self):
|
||||
self.table = {}
|
||||
|
||||
def _check_place(self, posx, posy, sizex, sizey):
|
||||
for y in range(sizey):
|
||||
for x in range(sizex):
|
||||
if posx+x>=PPR:
|
||||
return False
|
||||
row = self.table.setdefault(posy+y, {})
|
||||
if row.setdefault(posx+x) is not None:
|
||||
return False
|
||||
return True
|
||||
|
||||
def process(self, products):
|
||||
# Compute products positions on the grid
|
||||
minpos = 0
|
||||
index = 0
|
||||
for p in products:
|
||||
x = p.website_size_x
|
||||
y = p.website_size_y
|
||||
if index>PPG:
|
||||
x = y = 1
|
||||
pos = minpos
|
||||
while not self._check_place(pos%PPR, pos/PPR, x, y):
|
||||
pos += 1
|
||||
if x==1 and y==1: # simple heuristic for CPU optimization
|
||||
minpos = pos/PPR
|
||||
|
||||
for y2 in range(y):
|
||||
for x2 in range(x):
|
||||
self.table[(pos/PPR)+y2][(pos%PPR)+x2] = False
|
||||
row = self.table[pos/PPR][pos%PPR] = {
|
||||
'product': p, 'x':x, 'y': y,
|
||||
'class': " ".join(map(lambda x: x.html_class, p.website_style_ids))
|
||||
}
|
||||
index += 1
|
||||
|
||||
# Format table according to HTML needs
|
||||
rows = self.table.items()
|
||||
rows.sort()
|
||||
rows = map(lambda x: x[1], rows)
|
||||
for col in range(len(rows)):
|
||||
cols = rows[col].items()
|
||||
cols.sort()
|
||||
rows[col] = filter(bool, map(lambda x: x[1], cols))
|
||||
return filter(bool, rows)
|
||||
|
||||
class Ecommerce(http.Controller):
|
||||
|
||||
_order = 'website_sequence desc, website_published desc'
|
||||
|
@ -49,159 +102,9 @@ class Ecommerce(http.Controller):
|
|||
attributes_ids = attributes_obj.search(request.cr, request.uid, [], context=request.context)
|
||||
return attributes_obj.browse(request.cr, request.uid, attributes_ids, context=request.context)
|
||||
|
||||
def get_categories(self):
|
||||
domain = [('parent_id', '=', False)]
|
||||
|
||||
category_obj = request.registry.get('product.public.category')
|
||||
category_ids = category_obj.search(request.cr, SUPERUSER_ID, domain, context=request.context)
|
||||
categories = category_obj.browse(request.cr, SUPERUSER_ID, category_ids, context=request.context)
|
||||
|
||||
product_obj = request.registry.get('product.product')
|
||||
groups = product_obj.read_group(request.cr, SUPERUSER_ID, [("sale_ok", "=", True), ('website_published', '=', True)], ['public_categ_id'], 'public_categ_id', context=request.context)
|
||||
full_category_ids = [group['public_categ_id'][0] for group in groups if group['public_categ_id']]
|
||||
|
||||
for cat_id in category_obj.browse(request.cr, SUPERUSER_ID, full_category_ids, context=request.context):
|
||||
while cat_id.parent_id:
|
||||
cat_id = cat_id.parent_id
|
||||
full_category_ids.append(cat_id.id)
|
||||
full_category_ids.append(1)
|
||||
|
||||
return (categories, full_category_ids)
|
||||
|
||||
def get_pricelist(self):
|
||||
return request.registry.get('website').get_pricelist_id(request.cr, request.uid, None, context=request.context)
|
||||
|
||||
def change_pricelist(self):
|
||||
return request.registry.get('website').change_pricelist_id(request.cr, request.uid, None, context=request.context)
|
||||
|
||||
def get_bin_packing_products(self, product_ids, fill_hole, col_number=4):
|
||||
"""
|
||||
Packing all products of the search into a table of #col_number columns in function of the product sizes
|
||||
The website_size_x, website_size_y is use for fill table (default 1x1)
|
||||
The website_style_ids datas are concatenate in a html class
|
||||
|
||||
@values:
|
||||
|
||||
product_ids: list of product template
|
||||
fill_hole: list of extra product template use to fill the holes
|
||||
col_number: number of columns
|
||||
|
||||
@return:
|
||||
|
||||
table (list of list of #col_number items)
|
||||
items: {
|
||||
'product': browse of product template,
|
||||
'x': size x,
|
||||
'y': size y,
|
||||
'class': html class
|
||||
}
|
||||
"""
|
||||
product_obj = request.registry.get('product.template')
|
||||
style_obj = request.registry.get('website.product.style')
|
||||
request.context['pricelist'] = self.get_pricelist()
|
||||
|
||||
# search for checking of access rules and keep order
|
||||
product_ids = product_obj.search(request.cr, request.uid, [("id", 'in', product_ids)], context=request.context)
|
||||
|
||||
size_ids = {}
|
||||
style_ids = style_obj.search(request.cr, SUPERUSER_ID, [('html_class', 'like', 'size_%')], context=request.context)
|
||||
for style in style_obj.browse(request.cr, SUPERUSER_ID, style_ids, context=request.context):
|
||||
size_ids[style.id] = [int(style.html_class[-3]), int(style.html_class[-1])]
|
||||
|
||||
product_list = []
|
||||
bin_packing = {}
|
||||
bin_packing[0] = {}
|
||||
|
||||
for product in product_obj.browse(request.cr, SUPERUSER_ID, product_ids, context=request.context):
|
||||
index = len(product_list)
|
||||
|
||||
# get size and all html classes
|
||||
x = product.website_size_x or 1
|
||||
y = product.website_size_y or 1
|
||||
html_class = " ".join([str(style_id.html_class) for style_id in product.website_style_ids])
|
||||
|
||||
product_list.append({'product': product, 'x': x, 'y': y, 'class': html_class })
|
||||
|
||||
# bin packing products
|
||||
insert = False
|
||||
line = 0
|
||||
while not insert:
|
||||
# if not full column get next line
|
||||
if len(bin_packing.setdefault(line, {})) >= col_number:
|
||||
line += 1
|
||||
continue
|
||||
|
||||
col = 0
|
||||
while col < col_number:
|
||||
if bin_packing[line].get(col, None) != None:
|
||||
col += 1
|
||||
continue
|
||||
|
||||
insert = True
|
||||
|
||||
# check if the box can be inserted
|
||||
copy_line = line
|
||||
copy_y = y
|
||||
while copy_y > 0:
|
||||
copy_col = col
|
||||
copy_x = x
|
||||
while copy_x > 0:
|
||||
if copy_col >= col_number or bin_packing.setdefault(copy_line, {}).get(copy_col, None) != None:
|
||||
insert = False
|
||||
break
|
||||
copy_col += 1
|
||||
copy_x -= 1
|
||||
if not insert:
|
||||
break
|
||||
copy_line += 1
|
||||
copy_y -= 1
|
||||
|
||||
if not insert:
|
||||
col += 1
|
||||
continue
|
||||
|
||||
# insert the box
|
||||
copy_y = y
|
||||
while copy_y > 0:
|
||||
copy_y -= 1
|
||||
copy_x = x
|
||||
while copy_x > 0:
|
||||
copy_x -= 1
|
||||
bin_packing[line + copy_y][col + copy_x] = False
|
||||
bin_packing[line + copy_y][col + copy_x] = product_list[index]
|
||||
break
|
||||
|
||||
if not insert:
|
||||
line += 1
|
||||
else:
|
||||
break
|
||||
|
||||
length = len(bin_packing)
|
||||
|
||||
# browse product to fill the holes
|
||||
if fill_hole:
|
||||
fill_hole_products = []
|
||||
# search for checking of access rules and keep order
|
||||
fill_hole = [id for id in fill_hole if id in product_obj.search(request.cr, request.uid, [("id", 'in', fill_hole)], context=request.context)]
|
||||
for product in product_obj.browse(request.cr, request.uid, fill_hole, context=request.context):
|
||||
fill_hole_products.append(product)
|
||||
fill_hole_products.reverse()
|
||||
|
||||
# packaging in list (from dict)
|
||||
bin_packing_list = []
|
||||
line = 0
|
||||
while line < length:
|
||||
bin_packing_list.append([])
|
||||
col = 0
|
||||
while col < col_number:
|
||||
if fill_hole and fill_hole_products and bin_packing[line].get(col) == None:
|
||||
bin_packing[line][col] = {'product': fill_hole_products.pop(), 'x': 1, 'y': 1, 'class': "" }
|
||||
bin_packing_list[line].append(bin_packing[line].get(col))
|
||||
col += 1
|
||||
line += 1
|
||||
|
||||
return bin_packing_list
|
||||
|
||||
def get_products(self, product_ids):
|
||||
product_obj = request.registry.get('product.template')
|
||||
request.context['pricelist'] = self.get_pricelist()
|
||||
|
@ -265,79 +168,73 @@ class Ecommerce(http.Controller):
|
|||
att = obj.read(request.cr, request.uid, att_ids, ["product_id"], context=request.context)
|
||||
return [r["product_id"][0] for r in att]
|
||||
|
||||
@website.route(['/shop/pricelist'], type='http', auth="public", multilang=True)
|
||||
def shop_promo(self, code, **post):
|
||||
assert code, 'No pricelist code provided'
|
||||
request.registry.get('website').change_pricelist_id(request.cr, request.uid, code, context=request.context)
|
||||
return request.redirect("/shop")
|
||||
|
||||
@website.route([
|
||||
'/shop/',
|
||||
'/shop/page/<int:page>/',
|
||||
'/shop/category/<int:category>/',
|
||||
'/shop/category/<int:category>/page/<int:page>/'
|
||||
], type='http', auth="public", multilang=True)
|
||||
def category(self, category=0, page=0, filter='', search='', **post):
|
||||
# TDE-NOTE: shouldn't we do somethign about product_template without variants ???
|
||||
# TDE-NOTE: is there a reason to call a method category when the route is
|
||||
# basically a shop without category_id speceified ?
|
||||
|
||||
if 'promo' in post:
|
||||
self.change_pricelist(post.get('promo'))
|
||||
def shop(self, category=0, page=0, filter_domain='', search='', **post):
|
||||
cr, uid, context = request.cr, request.uid, request.context
|
||||
product_obj = request.registry.get('product.template')
|
||||
|
||||
domain = request.registry.get('website').get_website_sale_domain()
|
||||
|
||||
# remove product_product_consultant from ecommerce editable mode, this product never be publish
|
||||
ref = request.registry.get('ir.model.data').get_object_reference(request.cr, SUPERUSER_ID, 'product', 'product_product_consultant')
|
||||
domain.append(("id", "!=", ref[1]))
|
||||
|
||||
if search:
|
||||
domain += ['|', '|', '|',
|
||||
domain += ['|',
|
||||
('name', 'ilike', "%%%s%%" % search),
|
||||
('description', 'ilike', "%%%s%%" % search),
|
||||
('website_description', 'ilike', "%%%s%%" % search),
|
||||
('product_variant_ids.public_categ_id.name', 'ilike', "%%%s%%" % search)]
|
||||
|
||||
('description', 'ilike', "%%%s%%" % search)]
|
||||
if category:
|
||||
domain.append(('product_variant_ids.public_categ_id.id', 'child_of', category))
|
||||
|
||||
if filter:
|
||||
filter = simplejson.loads(filter)
|
||||
if filter:
|
||||
ids = self.attributes_to_ids(filter)
|
||||
domain.append(('product_variant_ids.public_categ_id', 'child_of', category))
|
||||
if filter_domain:
|
||||
filter_domain = simplejson.loads(filter_domain)
|
||||
if filter_domain:
|
||||
ids = self.attributes_to_ids(filter_domain)
|
||||
domain.append(('id', 'in', ids or [0]))
|
||||
|
||||
step = 20
|
||||
product_count = product_obj.search_count(request.cr, request.uid, domain, context=request.context)
|
||||
pager = request.website.pager(url="/shop/", total=product_count, page=page, step=step, scope=7, url_args=post)
|
||||
product_count = product_obj.search_count(cr, uid, domain, context=context)
|
||||
pager = request.website.pager(url="/shop/", total=product_count, page=page, step=PPG, scope=7, url_args=post)
|
||||
|
||||
request.context['pricelist'] = self.get_pricelist()
|
||||
|
||||
product_ids = product_obj.search(request.cr, request.uid, domain, limit=step, offset=pager['offset'], order=self._order, context=request.context)
|
||||
fill_hole = product_obj.search(request.cr, request.uid, domain, limit=step, offset=pager['offset']+step, order=self._order, context=request.context)
|
||||
pids = product_obj.search(cr, uid, domain, limit=PPG+10, offset=pager['offset'], order=self._order, context=context)
|
||||
products = product_obj.browse(cr, uid, pids, context=context)
|
||||
|
||||
styles = []
|
||||
if not request.context['is_public_user']:
|
||||
try:
|
||||
style_obj = request.registry.get('website.product.style')
|
||||
style_ids = style_obj.search(request.cr, request.uid, [], context=request.context)
|
||||
styles = style_obj.browse(request.cr, request.uid, style_ids, context=request.context)
|
||||
except:
|
||||
pass
|
||||
|
||||
category_obj = request.registry.get('product.public.category')
|
||||
category_ids = category_obj.search(cr, uid, [], context=context)
|
||||
categories = category_obj.browse(cr, uid, category_ids, context=context)
|
||||
categs = filter(lambda x: not x.parent_id, categories)
|
||||
|
||||
values = {
|
||||
'Ecommerce': self,
|
||||
'product_ids': product_ids,
|
||||
'product_ids_for_holes': fill_hole,
|
||||
'products': products,
|
||||
'bins': table_compute().process(products),
|
||||
'search': {
|
||||
'search': search,
|
||||
'category': category,
|
||||
'filter': filter,
|
||||
'filter_domain': filter_domain,
|
||||
},
|
||||
'pager': pager,
|
||||
'styles': styles,
|
||||
'categories': categs,
|
||||
'Ecommerce': self, # TODO fp: Should be removed
|
||||
'style_in_product': lambda style, product: style.id in [s.id for s in product.website_style_ids],
|
||||
}
|
||||
return request.website.render("website_sale.products", values)
|
||||
|
||||
@website.route(['/shop/product/<model("product.template"):product>/'], type='http', auth="public", multilang=True)
|
||||
def product(self, product, search='', category='', filter='', promo=None, **kwargs):
|
||||
|
||||
if promo:
|
||||
self.change_pricelist(promo)
|
||||
|
||||
def product(self, product, search='', category='', filter_domain='', **kwargs):
|
||||
category_obj = request.registry.get('product.public.category')
|
||||
|
||||
category_ids = category_obj.search(request.cr, request.uid, [], context=request.context)
|
||||
|
@ -358,7 +255,7 @@ class Ecommerce(http.Controller):
|
|||
'search': {
|
||||
'search': search,
|
||||
'category': category and str(category.id),
|
||||
'filter': filter,
|
||||
'filter': filter_domain,
|
||||
}
|
||||
}
|
||||
return request.website.render("website_sale.product", values)
|
||||
|
@ -438,10 +335,7 @@ class Ecommerce(http.Controller):
|
|||
request.registry['website'].sale_reset_order(cr, uid, context=context)
|
||||
return request.redirect('/shop/')
|
||||
|
||||
if 'promo' in post:
|
||||
self.change_pricelist(post.get('promo'))
|
||||
else:
|
||||
self.get_pricelist()
|
||||
self.get_pricelist()
|
||||
|
||||
suggested_ids = []
|
||||
product_ids = []
|
||||
|
@ -461,7 +355,6 @@ class Ecommerce(http.Controller):
|
|||
|
||||
values = {
|
||||
'int': int,
|
||||
'get_categories': self.get_categories,
|
||||
'suggested_products': prod_obj.browse(cr, uid, suggested_products, context),
|
||||
}
|
||||
return request.website.render("website_sale.mycart", values)
|
||||
|
@ -520,7 +413,7 @@ class Ecommerce(http.Controller):
|
|||
checkout = values['checkout']
|
||||
error = values['error']
|
||||
|
||||
if not context['is_public_user']:
|
||||
if not request.uid == self.pool.get('website').get_public_user(cr, uid, context):
|
||||
partner = orm_user.browse(cr, uid, uid, context).partner_id
|
||||
partner_info = info.from_partner(partner)
|
||||
checkout.update(partner_info)
|
||||
|
@ -596,7 +489,7 @@ class Ecommerce(http.Controller):
|
|||
billing_info = dict(checkout)
|
||||
billing_info['parent_id'] = company_id
|
||||
|
||||
if not context['is_public_user']:
|
||||
if not request.uid == self.pool.get('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)
|
||||
else:
|
||||
|
|
|
@ -96,10 +96,10 @@ class Website(orm.Model):
|
|||
|
||||
def get_pricelist_id(self, cr, uid, ids, context=None):
|
||||
if not request.httprequest.session.get('ecommerce_pricelist'):
|
||||
self.change_pricelist_id(cr, uid, ids, None, context=context)
|
||||
self.change_pricelist_id(cr, uid, None, context=context)
|
||||
return request.httprequest.session.get('ecommerce_pricelist')
|
||||
|
||||
def change_pricelist_id(self, cr, uid, ids, code, context=None):
|
||||
def change_pricelist_id(self, cr, uid, code=False, context=None):
|
||||
request.httprequest.session.setdefault('ecommerce_pricelist', False)
|
||||
|
||||
pricelist_id = False
|
||||
|
@ -125,4 +125,4 @@ class Website(orm.Model):
|
|||
|
||||
|
||||
def get_website_sale_domain(self):
|
||||
return [("sale_ok", "=", True)]
|
||||
return [("sale_ok", "=", True)]
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
|
||||
<template id="categories_recursive" name="Category list">
|
||||
<li t-att-class="str(category.id) == search.get('category') and 'active' or ''">
|
||||
<a t-att-class="category.id not in categ[1] and 'unpublish' or ''" t-href="/shop/category/#{ category.id }/" t-field="category.name"></a>
|
||||
<a t-href="/shop/category/#{ category.id }/" t-field="category.name"></a>
|
||||
<ul t-if="category.child_id" class="nav nav-pills nav-stacked nav-hierarchy">
|
||||
<t t-foreach="category.child_id" t-as="category">
|
||||
<t t-if="category.id in categ[1] or editable">
|
||||
<t t-call="website_sale.categories_recursive"/>
|
||||
</t>
|
||||
<t t-call="website_sale.categories_recursive"/>
|
||||
</t>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -39,7 +37,7 @@
|
|||
|
||||
<template id="search" name="Search hidden fields">
|
||||
<input type="hidden" name="category" t-att-value="search.get('category') or ''"/>
|
||||
<input type="hidden" name="filter" t-att-value="search.get('filter') or ''"/>
|
||||
<input type="hidden" name="filter_domain" t-att-value="search.get('filter_domain') or ''"/>
|
||||
<input type="text" name="search" class="search-query form-control" placeholder="Search..." t-att-value="search.get('search') or ''"/>
|
||||
</template>
|
||||
|
||||
|
@ -48,7 +46,7 @@
|
|||
<div class="ribbon"><span contentEditable="true">Promo</span></div>
|
||||
</div>
|
||||
<div class="oe_product_description">
|
||||
<a t-href="/shop/product/#{ product.id }/" t-keep-query="category,search,filter">
|
||||
<a t-href="/shop/product/#{ product.id }/" t-keep-query="category,search,filter_domain">
|
||||
<b t-field="product.name"/>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -68,7 +66,7 @@
|
|||
</b>
|
||||
</div>
|
||||
<div class="oe_product_image text-center">
|
||||
<a t-href="/shop/product/#{ product.id }/" t-keep-query="category,search,filter">
|
||||
<a t-href="/shop/product/#{ product.id }/" t-keep-query="category,search,filter_domain">
|
||||
<span t-field="product.image" t-field-options='{"widget": "image"}'/>
|
||||
</a>
|
||||
</div>
|
||||
|
@ -102,11 +100,9 @@
|
|||
<div class='style_default row'>
|
||||
<div class="hidden" id="products_grid_before"></div>
|
||||
<div class="col-md-12" id="products_grid">
|
||||
<t t-if="product_ids">
|
||||
<table width="100%">
|
||||
<tbody>
|
||||
<t t-set="table_products" t-value="Ecommerce.get_bin_packing_products(product_ids, product_ids_for_holes, 4)"/>
|
||||
<tr t-foreach="table_products" t-as="tr_product">
|
||||
<tr t-foreach="bins" t-as="tr_product">
|
||||
<t t-foreach="tr_product" t-as="td_product">
|
||||
<t t-if="td_product">
|
||||
<t t-set="product" t-value="td_product['product']"/>
|
||||
|
@ -176,8 +172,7 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</t>
|
||||
<t t-if="not product_ids">
|
||||
<t t-if="not bins">
|
||||
<h3 class="text-center text-muted">No product found for this search</h3>
|
||||
</t>
|
||||
</div>
|
||||
|
@ -218,7 +213,6 @@
|
|||
<template id="list_view" inherit_option_id="website_sale.products" name="List View">
|
||||
<xpath expr="//div[@id='products_grid']//table" position="replace">
|
||||
<div class="row">
|
||||
<t t-set="products" t-value="Ecommerce.get_products(product_ids)"/>
|
||||
<t t-foreach="products" t-as="product">
|
||||
<div class="col-md-12 oe_list_products oe-height-1">
|
||||
<t t-call="website_sale.products_cart"/>
|
||||
|
@ -244,7 +238,7 @@
|
|||
<div class="col-sm-5">
|
||||
<ol class="breadcrumb">
|
||||
<li><a href="/shop">Products</a></li>
|
||||
<li t-if="search.get('category')"><a t-href="/shop/" t-keep-query="category,search,filter"><span t-field="category.name"/></a></li>
|
||||
<li t-if="search.get('category')"><a t-href="/shop/" t-keep-query="category,search,filter_domain"><span t-field="category.name"/></a></li>
|
||||
<li class="active"><span t-field="product.name"/></li>
|
||||
</ol>
|
||||
</div><div class="col-sm-3">
|
||||
|
@ -499,8 +493,7 @@
|
|||
<xpath expr="//div[@id='products_grid_before']" position="inside">
|
||||
<ul class="nav nav-pills nav-stacked mt16">
|
||||
<li t-att-class=" '' if search.get('category') else 'active' "><a href="/shop/">All Products</a></li>
|
||||
<t t-set="categ" t-value="Ecommerce.get_categories()"/>
|
||||
<t t-foreach="categ[0]" t-as="category">
|
||||
<t t-foreach="categories" t-as="category">
|
||||
<t t-call="website_sale.categories_recursive"/>
|
||||
</t>
|
||||
</ul>
|
||||
|
|
Loading…
Reference in New Issue