diff options
Diffstat (limited to 'addons')
24 files changed, 98 insertions, 77 deletions
diff --git a/addons/account/wizard/account_report_aged_partner_balance_view.xml b/addons/account/wizard/account_report_aged_partner_balance_view.xml index be1d710c09d..09ae525c595 100644 --- a/addons/account/wizard/account_report_aged_partner_balance_view.xml +++ b/addons/account/wizard/account_report_aged_partner_balance_view.xml @@ -19,6 +19,7 @@ <newline/> <field name="result_selection"/> <field name="direction_selection"/> + <field name="target_move"/> </group> <field name="journal_ids" required="0" invisible="1"/> <footer> diff --git a/addons/auth_oauth/controllers/main.py b/addons/auth_oauth/controllers/main.py index 22a240e310b..b4ce20d49e3 100644 --- a/addons/auth_oauth/controllers/main.py +++ b/addons/auth_oauth/controllers/main.py @@ -78,6 +78,9 @@ class OAuthLogin(openerp.addons.web.controllers.main.Home): @http.route() def web_login(self, *args, **kw): ensure_db() + if request.httprequest.method == 'GET' and request.session.uid and request.params.get('redirect'): + # Redirect if already logged in and redirect param is present + return http.redirect_with_hash(request.params.get('redirect')) providers = self.list_providers() response = super(OAuthLogin, self).web_login(*args, **kw) diff --git a/addons/auth_signup/controllers/main.py b/addons/auth_signup/controllers/main.py index 78f2833f3d1..8a66d3ab075 100644 --- a/addons/auth_signup/controllers/main.py +++ b/addons/auth_signup/controllers/main.py @@ -37,6 +37,9 @@ class AuthSignupHome(openerp.addons.web.controllers.main.Home): ensure_db() response = super(AuthSignupHome, self).web_login(*args, **kw) response.qcontext.update(self.get_auth_signup_config()) + if request.httprequest.method == 'GET' and request.session.uid and request.params.get('redirect'): + # Redirect if already logged in and redirect param is present + return http.redirect_with_hash(request.params.get('redirect')) return response @http.route('/web/signup', type='http', auth='public', website=True, multilang=True) diff --git a/addons/auth_signup/res_users.py b/addons/auth_signup/res_users.py index 4c1c1a671b7..5a744c21c81 100644 --- a/addons/auth_signup/res_users.py +++ b/addons/auth_signup/res_users.py @@ -20,8 +20,8 @@ ############################################################################## from datetime import datetime, timedelta import random -from urllib import urlencode from urlparse import urljoin +import werkzeug from openerp.addons.base.ir.ir_mail_server import MailDeliveryException from openerp.osv import osv, fields @@ -53,7 +53,7 @@ class res_partner(osv.Model): (not partner.signup_expiration or dt <= partner.signup_expiration) return res - def _get_signup_url_for_action(self, cr, uid, ids, action='login', view_type=None, menu_id=None, res_id=None, model=None, context=None): + def _get_signup_url_for_action(self, cr, uid, ids, action=None, view_type=None, menu_id=None, res_id=None, model=None, context=None): """ generate a signup url for the given partner ids and action, possibly overriding the url state components (menu_id, id, view_type) """ if context is None: @@ -81,6 +81,8 @@ class res_partner(osv.Model): continue # no signup token, no user, thus no signup url! fragment = dict() + if action: + fragment['action'] = action if view_type: fragment['view_type'] = view_type if menu_id: @@ -90,7 +92,10 @@ class res_partner(osv.Model): if res_id: fragment['id'] = res_id - res[partner.id] = urljoin(base_url, "/web/%s?%s#%s" % (route, urlencode(query), urlencode(fragment))) + if fragment: + query['redirect'] = '/web#' + werkzeug.url_encode(fragment) + + res[partner.id] = urljoin(base_url, "/web/%s?%s" % (route, werkzeug.url_encode(query))) return res diff --git a/addons/crm/wizard/crm_lead_to_opportunity.py b/addons/crm/wizard/crm_lead_to_opportunity.py index 70f6712df74..40654f464f4 100644 --- a/addons/crm/wizard/crm_lead_to_opportunity.py +++ b/addons/crm/wizard/crm_lead_to_opportunity.py @@ -42,7 +42,7 @@ class crm_lead2opportunity_partner(osv.osv_memory): def onchange_action(self, cr, uid, ids, action, context=None): return {'value': {'partner_id': False if action != 'exist' else self._find_matching_partner(cr, uid, context=context)}} - def _get_duplicated_leads(self, cr, uid, partner_id, email, context=None): + def _get_duplicated_leads(self, cr, uid, partner_id, email, include_lost=False, context=None): """ Search for opportunities that have the same partner and that arent done or cancelled """ @@ -56,8 +56,11 @@ class crm_lead2opportunity_partner(osv.osv_memory): partner_match_domain.append(('partner_id', '=', partner_id)) partner_match_domain = ['|'] * (len(partner_match_domain) - 1) + partner_match_domain if not partner_match_domain: - return [] - return lead_obj.search(cr, uid, partner_match_domain + final_stage_domain) + return [] + domain = partner_match_domain + if not include_lost: + domain += final_stage_domain + return lead_obj.search(cr, uid, domain) def default_get(self, cr, uid, fields, context=None): """ @@ -75,7 +78,7 @@ class crm_lead2opportunity_partner(osv.osv_memory): lead = lead_obj.browse(cr, uid, int(context['active_id']), context=context) email = lead.partner_id and lead.partner_id.email or lead.email_from - tomerge.extend(self._get_duplicated_leads(cr, uid, partner_id, email)) + tomerge.extend(self._get_duplicated_leads(cr, uid, partner_id, email, include_lost=True, context=context)) tomerge = list(set(tomerge)) if 'action' in fields: diff --git a/addons/mail/static/src/js/mail.js b/addons/mail/static/src/js/mail.js index b8bf703f604..17dd4b57cd0 100644 --- a/addons/mail/static/src/js/mail.js +++ b/addons/mail/static/src/js/mail.js @@ -76,8 +76,8 @@ openerp.mail = function (session) { */ get_text2html: function (text) { return text - .replace(/[\n\r]/g,'<br/>') .replace(/((?:https?|ftp):\/\/[\S]+)/g,'<a href="$1">$1</a> ') + .replace(/[\n\r]/g,'<br/>') }, /* Returns the complete domain with "&" diff --git a/addons/point_of_sale/security/point_of_sale_security.xml b/addons/point_of_sale/security/point_of_sale_security.xml index 54572ee3eb9..5e98bcba49e 100644 --- a/addons/point_of_sale/security/point_of_sale_security.xml +++ b/addons/point_of_sale/security/point_of_sale_security.xml @@ -19,5 +19,11 @@ <field name="global" eval="True" /> <field name="domain_force">[('company_id', '=', user.company_id.id)]</field> </record> + <record id="rule_pos_config_multi_company" model="ir.rule"> + <field name="name">Point Of Sale Config</field> + <field name="model_id" ref="model_pos_config" /> + <field name="global" eval="True" /> + <field name="domain_force">[('warehouse_id.company_id','child_of',[user.company_id.id])]</field> + </record> </data> </openerp> diff --git a/addons/point_of_sale/wizard/pos_session_opening.xml b/addons/point_of_sale/wizard/pos_session_opening.xml index 5aa3f8d4764..2f3f244c318 100644 --- a/addons/point_of_sale/wizard/pos_session_opening.xml +++ b/addons/point_of_sale/wizard/pos_session_opening.xml @@ -10,7 +10,7 @@ <separator string="Select your Point of Sale" colspan="4" attrs="{'invisible' : [('show_config', '=', False)]}" /> <group attrs="{'invisible' : [('show_config', '=', False)]}"> <field name="pos_config_id" on_change="on_change_config(pos_config_id)" - widget="selection" domain="[('state','=','active')]" + options="{'no_create': True}" domain="[('state','=','active')]" class="oe_inline"/> <field name="pos_state" invisible="1" /> </group> diff --git a/addons/portal/mail_mail.py b/addons/portal/mail_mail.py index 18eb15361a3..0fe2081fa45 100644 --- a/addons/portal/mail_mail.py +++ b/addons/portal/mail_mail.py @@ -39,7 +39,7 @@ class mail_mail(osv.Model): if partner and not partner.user_ids: contex_signup = dict(context, signup_valid=True) signup_url = partner_obj._get_signup_url_for_action(cr, SUPERUSER_ID, [partner.id], - action='login', model=mail.model, res_id=mail.res_id, + model=mail.model, res_id=mail.res_id, context=contex_signup)[partner.id] return _("""<span class='oe_mail_footer_access'><small>Access your messages and documents through <a style='color:inherit' href="%s">our Customer Portal</a></small></span>""") % signup_url else: diff --git a/addons/portal/tests/test_portal.py b/addons/portal/tests/test_portal.py index 66cb0958774..2c4d7ecf966 100644 --- a/addons/portal/tests/test_portal.py +++ b/addons/portal/tests/test_portal.py @@ -134,7 +134,8 @@ class test_portal(TestMail): 'invite: subject of invitation email is incorrect') self.assertIn('Administrator invited you to follow Discussion group document: Pigs', sent_email.get('body'), 'invite: body of invitation email is incorrect') - self.assertTrue(partner_carine.signup_url in sent_email.get('body'), + invite_url = partner_carine._get_signup_url_for_action(model='mail.group', res_id=self.group_pigs_id)[partner_carine.id] + self.assertTrue(invite_url in sent_email.get('body'), 'invite: body of invitation email does not contain signup url') def test_20_notification_url(self): diff --git a/addons/project/project.py b/addons/project/project.py index e5dcf5de2cf..f6bd55c2fb6 100644 --- a/addons/project/project.py +++ b/addons/project/project.py @@ -745,7 +745,7 @@ class task(osv.osv): _columns = { 'active': fields.function(_is_template, store=True, string='Not a Template Task', type='boolean', help="This field is computed automatically and have the same behavior than the boolean 'active' field: if the task is linked to a template or unactivated project, it will be hidden unless specifically asked."), - 'name': fields.char('Task Summary', size=128, required=True, select=True), + 'name': fields.char('Task Summary', track_visibility='onchange', size=128, required=True, select=True), 'description': fields.text('Description'), 'priority': fields.selection([('4','Very Low'), ('3','Low'), ('2','Medium'), ('1','Important'), ('0','Very important')], 'Priority', select=True), 'sequence': fields.integer('Sequence', select=True, help="Gives the sequence order when displaying a list of tasks."), diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index b47320b1e79..6c090e3cf5d 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -634,10 +634,9 @@ class purchase_order(osv.osv): 'name': self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.in'), 'origin': order.name + ((order.origin and (':' + order.origin)) or ''), 'date': self.date_to_datetime(cr, uid, order.date_order, context), - 'partner_id': order.dest_address_id.id or order.partner_id.id, + 'partner_id': order.partner_id.id, 'invoice_state': '2binvoiced' if order.invoice_method == 'picking' else 'none', 'type': 'in', - 'partner_id': order.dest_address_id.id or order.partner_id.id, 'purchase_id': order.id, 'company_id': order.company_id.id, 'move_lines' : [], diff --git a/addons/report_webkit/default_header.html b/addons/report_webkit/default_header.html index 0798209a5b7..37fd4135b62 100644 --- a/addons/report_webkit/default_header.html +++ b/addons/report_webkit/default_header.html @@ -1,3 +1,4 @@ +<!DOCTYPE html> <html> <head> <meta content="text/html; charset=UTF-8" http-equiv="content-type"/> diff --git a/addons/report_webkit/webkit_report.py b/addons/report_webkit/webkit_report.py index 4f56d7efea7..60fb536ca96 100644 --- a/addons/report_webkit/webkit_report.py +++ b/addons/report_webkit/webkit_report.py @@ -112,6 +112,7 @@ def webkit_report_extender(report_name): return fct return fct1 + class WebKitParser(report_sxw): """Custom class that use webkit to render HTML reports Code partially taken from report openoffice. Thanks guys :) @@ -173,7 +174,7 @@ class WebKitParser(report_sxw): ), 'w' ) - head_file.write(header.encode('utf-8')) + head_file.write(self._sanitize_html(header.encode('utf-8'))) head_file.close() file_to_del.append(head_file.name) command.extend(['--header-html', head_file.name]) @@ -184,7 +185,7 @@ class WebKitParser(report_sxw): ), 'w' ) - foot_file.write(footer.encode('utf-8')) + foot_file.write(self._sanitize_html(footer.encode('utf-8'))) foot_file.close() file_to_del.append(foot_file.name) command.extend(['--footer-html', foot_file.name]) @@ -205,7 +206,7 @@ class WebKitParser(report_sxw): for html in html_list : html_file = file(os.path.join(tmp_dir, str(time.time()) + str(count) +'.body.html'), 'w') count += 1 - html_file.write(html.encode('utf-8')) + html_file.write(self._sanitize_html(html.encode('utf-8'))) html_file.close() file_to_del.append(html_file.name) command.append(html_file.name) @@ -366,7 +367,6 @@ class WebKitParser(report_sxw): pdf = self.generate_pdf(bin, report_xml, head, foot, htmls) return (pdf, 'pdf') - def create(self, cursor, uid, ids, data, context=None): """We override the create function in order to handle generator Code taken from report openoffice. Thanks guys :) """ @@ -387,11 +387,18 @@ class WebKitParser(report_sxw): report_xml.report_sxw = None else: return super(WebKitParser, self).create(cursor, uid, ids, data, context) - if report_xml.report_type != 'webkit' : + if report_xml.report_type != 'webkit': return super(WebKitParser, self).create(cursor, uid, ids, data, context) result = self.create_source_pdf(cursor, uid, ids, data, report_xml, context) if not result: return (False,False) return result + def _sanitize_html(self, html): + """wkhtmltopdf expects the html page to declare a doctype. + """ + if html and html[:9].upper() != "<!DOCTYPE": + html = "<!DOCTYPE html>\n" + html + return html + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/sale/wizard/sale_make_invoice.py b/addons/sale/wizard/sale_make_invoice.py index 3712feda20b..170259824f7 100644 --- a/addons/sale/wizard/sale_make_invoice.py +++ b/addons/sale/wizard/sale_make_invoice.py @@ -55,11 +55,12 @@ class sale_make_invoice(osv.osv_memory): raise osv.except_osv(_('Warning!'), _("You shouldn't manually invoice the following sale order %s") % (sale_order.name)) order_obj.action_invoice_create(cr, uid, context.get(('active_ids'), []), data['grouped'], date_invoice=data['invoice_date']) - - for o in order_obj.browse(cr, uid, context.get(('active_ids'), []), context=context): + orders = order_obj.browse(cr, uid, context.get(('active_ids'), []), context=context) + for o in orders: for i in o.invoice_ids: newinv.append(i.id) - + # Dummy call to workflow, will not create another invoice but bind the new invoice to the subflow + order_obj.signal_manual_invoice(cr, uid, [o.id for o in orders if o.order_policy == 'manual']) result = mod_obj.get_object_reference(cr, uid, 'account', 'action_invoice_tree1') id = result and result[1] or False result = act_obj.read(cr, uid, [id], context=context)[0] diff --git a/addons/stock/wizard/stock_change_product_qty.py b/addons/stock/wizard/stock_change_product_qty.py index 01ed6f2409a..cf4099ac3ba 100644 --- a/addons/stock/wizard/stock_change_product_qty.py +++ b/addons/stock/wizard/stock_change_product_qty.py @@ -33,6 +33,10 @@ class stock_change_product_qty(osv.osv_memory): 'prodlot_id': fields.many2one('stock.production.lot', 'Serial Number', domain="[('product_id','=',product_id)]"), 'location_id': fields.many2one('stock.location', 'Location', required=True, domain="[('usage', '=', 'internal')]"), } + _defaults = { + 'new_quantity': 1, + 'product_id': lambda self, cr, uid, ctx: ctx and ctx.get('active_id', False) or False + } def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): if context is None: context = {} @@ -54,20 +58,22 @@ class stock_change_product_qty(osv.osv_memory): @param context: A standard dictionary @return: A dictionary which of fields with values. """ - product_id = context and context.get('active_id', False) or False + res = super(stock_change_product_qty, self).default_get(cr, uid, fields, context=context) - if 'new_quantity' in fields: - res.update({'new_quantity': 1}) - if 'product_id' in fields: - res.update({'product_id': product_id}) if 'location_id' in fields: - try: - model, location_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_stock') - self.pool.get('stock.location').check_access_rule(cr, uid, [location_id], 'read', context=context) - except (orm.except_orm, ValueError): - location_id = False - res.update({'location_id': location_id}) + location_id = res.get('location_id', False) + if not location_id: + try: + model, location_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_stock') + except (orm.except_orm, ValueError): + pass + if location_id: + try: + self.pool.get('stock.location').check_access_rule(cr, uid, [location_id], 'read', context=context) + except (orm.except_orm, ValueError): + pass + res['location_id'] = location_id return res def change_product_qty(self, cr, uid, ids, context=None): diff --git a/addons/stock/wizard/stock_move_view.xml b/addons/stock/wizard/stock_move_view.xml index 5dc0d0d824c..f2bc40d9a3f 100644 --- a/addons/stock/wizard/stock_move_view.xml +++ b/addons/stock/wizard/stock_move_view.xml @@ -67,6 +67,7 @@ <field name="view_type">form</field> <field name="view_mode">form</field> <field name="target">new</field> + <field name="context">{'form_view_ref': False}</field> </record> <record id="view_split_in_lots" model="ir.ui.view"> @@ -124,6 +125,7 @@ <field name="view_type">form</field> <field name="view_mode">form</field> <field name="target">new</field> + <field name="context">{'form_view_ref': False}</field> </record> </data> diff --git a/addons/subscription/__openerp__.py b/addons/subscription/__openerp__.py index b301525eb42..5f8a1d1338b 100644 --- a/addons/subscription/__openerp__.py +++ b/addons/subscription/__openerp__.py @@ -37,7 +37,7 @@ e.g. To have an invoice generated automatically periodically: above. Specify the interval information and partner to be invoice. """, 'author': 'OpenERP SA', - 'depends': [], + 'depends': ['base'], 'data': ['security/subcription_security.xml', 'security/ir.model.access.csv', 'subscription_view.xml'], 'demo': ['subscription_demo.xml',], 'installable': True, diff --git a/addons/survey/wizard/survey_send_invitation.py b/addons/survey/wizard/survey_send_invitation.py index 44d3bec7f6e..e16d0d6ce77 100644 --- a/addons/survey/wizard/survey_send_invitation.py +++ b/addons/survey/wizard/survey_send_invitation.py @@ -128,23 +128,14 @@ Thanks,''') % (name, self.pool.get('ir.config_parameter').get_param(cr, uid, 'we for use in exist_user: new_user.append(use.id) for id in survey_ref.browse(cr, uid, survey_ids): - report = self.create_report(cr, uid, [id.id], 'report.survey.form', id.title) - file = open(get_module_resource('survey', 'report') + id.title +".pdf") - file_data = "" - while 1: - line = file.readline() - file_data += line - if not line: - break - file.close() - attachments[id.title +".pdf"] = file_data - os.remove(get_module_resource('survey', 'report') + id.title +".pdf") + result, format = openerp.report.render_report(cr, uid, [id.id], 'survey.form', {}, {}) + attachments[id.title +".pdf"] = result for partner in self.pool.get('res.partner').browse(cr, uid, partner_ids): if not partner.email: skipped+= 1 continue - user = user_ref.search(cr, uid, [('login', "=", partner.email)]) + user = user_ref.search(cr, uid, [('partner_id', "=", partner.id)]) if user: if user[0] not in new_user: new_user.append(user[0]) @@ -185,6 +176,8 @@ Thanks,''') % (name, self.pool.get('ir.config_parameter').get_param(cr, uid, 'we if ans: res_data = {'name': partner.name or _('Unknown'), 'login': partner.email, + 'email': partner.email, + 'partner_id': partner.id, 'password': passwd, 'address_id': partner.id, 'groups_id': [[6, 0, [group_id]]], diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 857b99d40d2..67781cc02a0 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -168,20 +168,9 @@ class view(osv.osv): arch_no_whitespace = etree.fromstring( etree.tostring(arch, encoding='utf-8'), parser=etree.XMLParser(encoding='utf-8', remove_blank_text=True)) - arch_pretty_indent_2 = etree.tostring( + return etree.tostring( arch_no_whitespace, encoding='unicode', pretty_print=True) - # pretty_print uses a fixed indent level of 2, we want an indent of 4, - # double up leading spaces. - def repl(m): - indent = len(m.group(0)) / 2 - return u' ' * 4 * indent - # FIXME: If py2.7 only, can use re.M in sub and don't have to do replacement line by line - return u'\n'.join( - re.sub(ur'^((?: )+)', repl, line) - for line in arch_pretty_indent_2.split(u'\n') - ) - def save(self, cr, uid, res_id, value, xpath=None, context=None): """ Update a view section. The view section may embed fields to write diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index c89bf9ec2fb..ae126ad16ab 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1789,6 +1789,9 @@ if (node.nodeName === 'BR' && node.getAttribute('type') === '_moz') { // <br type="_moz"> appears when focusing RTE in FF, ignore continue; + } else if (node.nodeName === 'DIV' && $(node).hasClass('oe_drop_zone')) { + // ignore dropzone inserted by snippets + continue } } diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 1eee1fee65b..084dcd0b249 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -19,23 +19,11 @@ edit: function () { var self = this; $("[data-oe-model] *, [data-oe-type=html] *").off('click'); - website.snippet.stop_animation(); window.snippets = this.snippets = new website.snippet.BuildingBlock(this); this.snippets.appendTo(this.$el); this.on('rte:ready', this, function () { self.snippets.$button.removeClass("hidden"); - website.snippet.start_animation(); - $(website.snippet.readyAnimation).each(function() { - var animation = $(this).data("snippet-view"); - if (animation) { - animation.$target.on('focus', '*', function(){ - animation.stop(); - }); - animation.$target.on('blur', '*', function(){ - animation.start(); - }); - } - }); + website.snippet.stop_animation(); }); return this._super.apply(this, arguments); @@ -397,7 +385,6 @@ $("#oe_snippets").trigger('snippet-dropped', $target); website.snippet.start_animation(true, $target); - // drop_and_build_snippet self.create_overlay($target); if ($target.data("snippet-editor")) { @@ -1291,6 +1278,7 @@ this.grid.size = 8; return this.grid; }, + this.$target.carousel({interval: false}); }); website.snippet.options.parallax = website.snippet.Option.extend({ diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 2d84c95119f..bd7bcc13d0a 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -226,7 +226,8 @@ class Ecommerce(http.Controller): 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') - domain = request.registry.get('website').ecommerce_get_product_domain() + base_domain = request.registry.get('website').ecommerce_get_product_domain() + domain = list(base_domain) if search: domain += ['|', ('name', 'ilike', search), @@ -265,9 +266,15 @@ class Ecommerce(http.Controller): pass category_obj = request.registry.get('product.public.category') - category_ids = category_obj.search(cr, uid, [], context=context) + category_ids = [product['public_categ_id'][0] for product in product_obj.read_group(cr, uid, base_domain, ['public_categ_id'], ['public_categ_id'], context=context) if product['public_categ_id']] categories = category_obj.browse(cr, uid, category_ids, context=context) - categs = filter(lambda x: not x.parent_id, categories) + all_categories = set(categories) + for cat in categories: + parent = cat.parent_id + while parent: + all_categories.add(parent) + parent = parent.parent_id + categories = list(all_categories) values = { 'products': products, @@ -282,7 +289,8 @@ class Ecommerce(http.Controller): 'pager': pager, 'styles': styles, 'category': category, - 'categories': categs, + 'categories': filter(lambda x: not x.parent_id, categories), + 'all_categories': categories, '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], } diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index b870a676cc9..936810946af 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -33,12 +33,14 @@ <template id="categories_recursive" name="Category list"> <li t-att-class="int(categ) == int(category or 0) and 'active' or ''"> + <t t-if="categ in all_categories"> <a t-attf-href="/shop/category/#{ slug(categ) }/" t-field="categ.name"></a> <ul t-if="categ.child_id" class="nav nav-pills nav-stacked nav-hierarchy"> <t t-foreach="categ.child_id" t-as="categ"> <t t-call="website_sale.categories_recursive"/> </t> </ul> + </t> </li> </template> @@ -730,7 +732,7 @@ <div class="col-md-8 oe_mycart"> <h3 class="page-header mt16">Billing Information <small groups="base.group_public"> or - <a class='btn btn-primary' t-if="not partner" t-attf-href="/web?redirect=#{ request.httprequest.url }">Sign in</a> + <a class='btn btn-primary' t-if="not partner" t-attf-href="/web/login?redirect=#{ request.httprequest.url }">Sign in</a> </small> </h3> <div class="row"> |
