From 4dfbcecfdb59c12eaf4b3b435a626f07574d5ce3 Mon Sep 17 00:00:00 2001 From: Vipul Bhatt <vbh@odoo.com> Date: Tue, 12 Apr 2016 10:22:19 +0200 Subject: [PATCH] [IMP] website_{portal,portal_sale,project_issue,quote} : add pager for customer documents This commit adds controller to list documents of customer, with pager and archive widget to sort documents. Impacted documents are : quotations, sale order, invoices, and issues. Portal breadcrumd is improved too : add the home icon, and keep the query params when using archive widget. Some editable zones were added to templates, allowing people to customize their frontend portal. --- .../views/website_payment_templates.xml | 6 +- addons/website_portal/controllers/main.py | 35 ++++- .../static/src/js/website_portal.js | 11 +- .../static/src/less/website_portal.less | 6 +- addons/website_portal/views/templates.xml | 66 ++++++-- .../website_portal_sale/controllers/main.py | 142 ++++++++++++++++-- .../website_portal_sale/views/templates.xml | 111 +++++++++++--- .../website_project_issue/controllers/main.py | 41 ++++- .../views/project_issue_templates.xml | 50 ++++-- .../website_quote/views/website_quotation.xml | 9 +- 10 files changed, 394 insertions(+), 83 deletions(-) diff --git a/addons/website_payment/views/website_payment_templates.xml b/addons/website_payment/views/website_payment_templates.xml index 0395b6ccfaf7..1dc0d39a76ae 100644 --- a/addons/website_payment/views/website_payment_templates.xml +++ b/addons/website_payment/views/website_payment_templates.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <openerp> <data> - <template id="header_footer_custom_payment" inherit_id="website_portal.account" customize_show="True" active="False" name="Payment Methods"> + <template id="header_footer_custom_payment" inherit_id="website_portal.portal_layout" customize_show="True" active="False" name="Payment Methods"> <xpath expr="//div[@class='o_my_details']" position="inside"> <h4 class="payment_method_title">Payment Method</h4> <ul class="payment_method_list list-inline"> @@ -30,7 +30,7 @@ <div class="row"> <div class="col-sm-6"> <ol class="breadcrumb mt8"> - <li><a href="/my/home">My Account</a></li> + <li><a href="/my/home"><i class="fa fa-home"/></a></li> <li>Payment Methods</li> </ol> </div> @@ -78,7 +78,7 @@ </t> </template> - <template id="pay_meth_link" inherit_id="website_portal.account"> + <template id="pay_meth_link" inherit_id="website_portal.portal_layout"> <xpath expr="//div[@class='o_my_details']" position="inside"> <a href="/my/payment_method">Manage your payment methods</a> </xpath> diff --git a/addons/website_portal/controllers/main.py b/addons/website_portal/controllers/main.py index a11adac2ab49..2990ced04a28 100644 --- a/addons/website_portal/controllers/main.py +++ b/addons/website_portal/controllers/main.py @@ -4,12 +4,16 @@ from openerp.http import request from openerp import tools from openerp.tools.translate import _ +from odoo.fields import Date + class website_account(http.Controller): - @http.route(['/my', '/my/home'], type='http', auth="public", website=True) - def account(self): - partner = request.env.user.partner_id + _items_per_page = 10 + + def _prepare_portal_layout_values(self): + """ prepare the values to render portal layout """ + partner = request.env.user.partner_id # get customer sales rep if partner.user_id: sales_rep = partner.user_id @@ -20,8 +24,31 @@ class website_account(http.Controller): 'company': request.website.company_id, 'user': request.env.user } + return values + + def _get_archive_groups(self, model, domain=None, fields=None, groupby="create_date", order="create_date desc"): + if not model: + return [] + if domain is None: + domain = [] + if fields is None: + fields = ['name', 'create_date'] + groups = [] + for group in request.env[model]._read_group_raw(domain, fields=fields, groupby=groupby, orderby=order): + dates, label = group[groupby] + date_begin, date_end = dates.split('/') + groups.append({ + 'date_begin': Date.to_string(Date.from_string(date_begin)), + 'date_end': Date.to_string(Date.from_string(date_end)), + 'name': label, + 'item_count': group[groupby + '_count'] + }) + return groups - return request.website.render("website_portal.account", values) + @http.route(['/my', '/my/home'], type='http', auth="public", website=True) + def account(self): + values = self._prepare_portal_layout_values() + return request.website.render("website_portal.portal_my_home", values) @http.route(['/my/account'], type='http', auth='user', website=True) def details(self, redirect=None, **post): diff --git a/addons/website_portal/static/src/js/website_portal.js b/addons/website_portal/static/src/js/website_portal.js index 6f9e364998dd..d63ef0672948 100644 --- a/addons/website_portal/static/src/js/website_portal.js +++ b/addons/website_portal/static/src/js/website_portal.js @@ -1,9 +1,10 @@ + odoo.define('website_portal', function(require) { 'use strict'; require('website.website'); - if(!$('.o_website_portal_details, .o_my_show_more').length) { - return $.Deferred().reject("DOM doesn't contain '.o_website_portal_details' or '.o_my_show_more'"); + if(!$('.o_website_portal_details').length) { + return $.Deferred().reject("DOM doesn't contain '.o_website_portal_details'"); } var state_options = $("select[name='state_id']:enabled option:not(:first)"); @@ -15,10 +16,4 @@ odoo.define('website_portal', function(require) { select.parent().toggle(nb>=1); }); $('.o_website_portal_details').find("select[name='country_id']").change(); - - $('.o_my_show_more').on('click', function(ev) { - ev.preventDefault(); - $(this).parents('table').find(".to_hide").toggleClass('hidden'); - $(this).find('span').toggleClass('hidden'); - }); }); diff --git a/addons/website_portal/static/src/less/website_portal.less b/addons/website_portal/static/src/less/website_portal.less index d1f04277023b..1de553fa7cb0 100644 --- a/addons/website_portal/static/src/less/website_portal.less +++ b/addons/website_portal/static/src/less/website_portal.less @@ -15,4 +15,8 @@ text-align: left; } table-layout: fixed; -} \ No newline at end of file +} + +.o_my_home_content > .page-header > a:hover { + text-decoration: none; +} diff --git a/addons/website_portal/views/templates.xml b/addons/website_portal/views/templates.xml index 6f52b9a8aacd..3c6e70b78aab 100644 --- a/addons/website_portal/views/templates.xml +++ b/addons/website_portal/views/templates.xml @@ -8,30 +8,76 @@ </xpath> </template> - <template id="account" name="Account"> + <template id="portal_archive_groups" name="Portal Archive Groups"> + <h3 class="page-header">Archives</h3> + <ul class="nav nav-pills nav-stacked"> + <t t-foreach="archive_groups" t-as="group"> + <t t-if="group['date_begin'] == date"> + <li class="active"> + <a t-att-href="default_url" t-ignore="True"><t t-esc="group['name']"/><span class="pull-right badge" t-esc="group['item_count']"/></a> + </li> + </t> + <t t-if="group['date_begin'] != date"> + <li> + <a t-ignore="True" t-attf-href="#{default_url}?date_begin=#{group['date_begin']}&date_end=#{group['date_end']}"><t t-esc="group['name']"/><span class="pull-right badge" t-esc="group['item_count']"/></a> + </li> + </t> + </t> + </ul> + </template> + + <template id="portal_layout" name="Portal Layout"> <t t-call="website.layout"> + <div class="container mt16"> + <div class="navbar navbar-default"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#oe-help-navbar-collapse"> + <span class="sr-only">Toggle navigation</span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="/my/home"> + My Account + </a> + </div> + <div class="collapse navbar-collapse" id="oe-help-navbar-collapse"> + <ul class="nav navbar-nav o_portal_submenu"> + </ul> + </div> + </div> + </div> <div id="wrap"> <div class="container mb64"> - <div class="col-md-8 o_my_documents"> - <div class="oe_structure"/> - </div> - <div t-if="sales_rep" class="col-md-3"> - <t t-call="website_portal.contact" /> - <div class="oe_structure"/> + <div class="col-md-8"> + <t t-raw="0"/> </div> <div id="o_my_sidebar" class="col-md-3 col-md-offset-1 o_my_sidebar"> + <div class="o_my_contact" t-if="sales_rep"> + <t t-call="website_portal.contact"/> + </div> <div class="o_my_details"> <h3 class="page-header">Your Details <a href="/my/account" class="btn btn-default btn-xs">Change</a></h3> <div t-field="user.partner_id" t-field-options='{"widget": "contact", "fields": ["email", "phone", "address", "name"]}'/> </div> + <div class="o_my_archives" t-if="archive_groups"> + <t t-call="website_portal.portal_archive_groups"/> + </div> </div> - <div class="col-md-12 oe_structure"/> </div> </div> </t> </template> - <template id="website_portal.custom_panel" inherit_id='website_portal.account' customize_show="True" name="Editable Panel" active="False"> + <template id="portal_my_home" name="My Portal"> + <t t-call="website_portal.portal_layout"> + <div class="o_my_home_content"> + <div class="oe_structure"></div> + </div> + <div class="col-md-12 oe_structure"/> + </t> + </template> + + <template id="website_portal.custom_panel" inherit_id='website_portal.portal_layout' customize_show="True" name="Editable Panel" active="False"> <xpath expr="//div[@id='o_my_sidebar']" position="inside"> <div class="oe_structure"> <h3 class="page-header">Custom Panel</h3> @@ -56,7 +102,7 @@ <div class="row"> <div class="col-sm-6"> <ol class="breadcrumb mt8"> - <li><a href="/my/home">My Account</a></li> + <li><a href="/my/home"><i class="fa fa-home"/></a></li> <li>Details</li> </ol> </div> diff --git a/addons/website_portal_sale/controllers/main.py b/addons/website_portal_sale/controllers/main.py index fc88ce8125c0..11da77648ea4 100644 --- a/addons/website_portal_sale/controllers/main.py +++ b/addons/website_portal_sale/controllers/main.py @@ -9,45 +9,163 @@ from openerp.addons.website_portal.controllers.main import website_account class website_account(website_account): - @http.route(['/my/home'], type='http', auth="user", website=True) - def account(self, **kw): + + @http.route() + def account(self): """ Add sales documents to main account page """ response = super(website_account, self).account() partner = request.env.user.partner_id - res_sale_order = request.env['sale.order'] - res_invoices = request.env['account.invoice'] - quotations = res_sale_order.search([ + SaleOrder = request.env['sale.order'] + Invoice = request.env['account.invoice'] + quotation_count = SaleOrder.search_count([ ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), ('state', 'in', ['sent', 'cancel']) ]) - orders = res_sale_order.search([ + order_count = SaleOrder.search_count([ ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), ('state', 'in', ['sale', 'done']) ]) - invoices = res_invoices.search([ + invoice_count = Invoice.search_count([ ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), ('state', 'in', ['open', 'paid', 'cancelled']) ]) response.qcontext.update({ - 'date': datetime.date.today().strftime('%Y-%m-%d'), + 'quotation_count': quotation_count, + 'order_count': order_count, + 'invoice_count': invoice_count, + }) + return response + + # + # Quotations and Sale Orders + # + + @http.route(['/my/quotes', '/my/quotes/page/<int:page>'], type='http', auth="user", website=True) + def portal_my_quotes(self, page=1, date_begin=None, date_end=None, **kw): + values = self._prepare_portal_layout_values() + partner = request.env.user.partner_id + SaleOrder = request.env['sale.order'] + + domain = [ + ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), + ('state', 'in', ['sent', 'cancel']) + ] + + archive_groups = self._get_archive_groups('sale.order', domain) + if date_begin and date_end: + domain += [('create_date', '>=', date_begin), ('create_date', '<', date_end)] + + # count for pager + quotation_count = SaleOrder.search_count(domain) + # make pager + pager = request.website.pager( + url="/my/quotes", + url_args={'date_begin': date_begin, 'date_end': date_end}, + total=quotation_count, + page=page, + step=self._items_per_page + ) + # search the count to display, according to the pager data + quotations = SaleOrder.search(domain, limit=self._items_per_page, offset=pager['offset']) + + values.update({ + 'date': date_begin, 'quotations': quotations, + 'pager': pager, + 'archive_groups': archive_groups, + 'default_url': '/my/quotes', + }) + return request.website.render("website_portal_sale.portal_my_quotations", values) + + @http.route(['/my/orders', '/my/orders/page/<int:page>'], type='http', auth="user", website=True) + def portal_my_orders(self, page=1, date_begin=None, date_end=None, **kw): + values = self._prepare_portal_layout_values() + partner = request.env.user.partner_id + SaleOrder = request.env['sale.order'] + + domain = [ + ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), + ('state', 'in', ['sale', 'done']) + ] + archive_groups = self._get_archive_groups('sale.order', domain) + if date_begin and date_end: + domain += [('create_date', '>=', date_begin), ('create_date', '<', date_end)] + + # count for pager + order_count = SaleOrder.search_count(domain) + # pager + pager = request.website.pager( + url="/my/orders", + url_args={'date_begin': date_begin, 'date_end': date_end}, + total=order_count, + page=page, + step=self._items_per_page + ) + # content according to pager and archive selected + orders = SaleOrder.search(domain, limit=self._items_per_page, offset=pager['offset']) + + values.update({ + 'date': date_begin, 'orders': orders, - 'invoices': invoices, + 'page_name': 'order', + 'pager': pager, + 'archive_groups': archive_groups, + 'default_url': '/my/orders', }) - return response + return request.website.render("website_portal_sale.portal_my_orders", values) @http.route(['/my/orders/<int:order>'], type='http', auth="user", website=True) - def orders_followup(self, order=None): + def orders_followup(self, order=None, **kw): order = request.env['sale.order'].browse([order]) try: order.check_access_rights('read') order.check_access_rule('read') except AccessError: - return request.website.render("website.403") + return request.website.render("website.403") order_invoice_lines = {il.product_id.id: il.invoice_id for il in order.invoice_ids.mapped('invoice_line_ids')} return request.website.render("website_portal_sale.orders_followup", { 'order': order.sudo(), 'order_invoice_lines': order_invoice_lines, }) + + # + # Invoices + # + + @http.route(['/my/invoices', '/my/invoices/page/<int:page>'], type='http', auth="user", website=True) + def portal_my_invoices(self, page=1, date_begin=None, date_end=None, **kw): + values = self._prepare_portal_layout_values() + partner = request.env.user.partner_id + AccountInvoice = request.env['account.invoice'] + + domain = [ + ('message_partner_ids', 'child_of', [partner.commercial_partner_id.id]), + ('state', 'in', ['open', 'paid', 'cancelled']) + ] + archive_groups = self._get_archive_groups('account.invoice', domain) + if date_begin and date_end: + domain += [('create_date', '>=', date_begin), ('create_date', '<', date_end)] + + # count for pager + invoice_count = AccountInvoice.search_count(domain) + # pager + pager = request.website.pager( + url="/my/invoices", + url_args={'date_begin': date_begin, 'date_end': date_end}, + total=invoice_count, + page=page, + step=self._items_per_page + ) + # content according to pager and archive selected + invoices = AccountInvoice.search(domain, limit=self._items_per_page, offset=pager['offset']) + values.update({ + 'date': date_begin, + 'invoices': invoices, + 'page_name': 'invoice', + 'pager': pager, + 'archive_groups': archive_groups, + 'default_url': '/my/invoices', + }) + return request.website.render("website_portal_sale.portal_my_invoices", values) diff --git a/addons/website_portal_sale/views/templates.xml b/addons/website_portal_sale/views/templates.xml index 25c88200800b..80103dca6714 100644 --- a/addons/website_portal_sale/views/templates.xml +++ b/addons/website_portal_sale/views/templates.xml @@ -6,15 +6,63 @@ </xpath> </template> - <template id="account" name="Account" inherit_id="website_portal.account"> - <xpath expr="//div[contains(@class,'o_my_documents')]" position="inside"> - <t t-call="website_portal_sale.quotations" /> - <t t-call="website_portal_sale.sale_orders" /> - <t t-call="website_portal_sale.invoices" /> + <template id="portal_my_home_menu_sale" name="Portal layout : sales menu entries" inherit_id="website_portal.portal_layout" priority="25"> + <xpath expr="//ul[contains(@class,'o_portal_submenu')]" position="inside"> + <li> + <a href="/my/quotes">Quotes</a> + </li> + <li> + <a href="/my/orders">Orders</a> + </li> + <li> + <a href="/my/invoices">Invoices</a> + </li> </xpath> </template> - <template id="quotations" name="Quotations"> + <template id="portal_my_home_sale" name="Portal My Home : sales entries" inherit_id="website_portal.portal_my_home" priority="25"> + <xpath expr="//div[contains(@class,'o_my_home_content')]" position="inside"> + <h3 class="page-header"> + <a href="/my/quotes">Your Quotes + <small class="ml8"> + <t t-if="quotation_count"> + <span class='badge'><t t-esc="quotation_count"/></span> + </t> + <t t-if="not quotation_count"> + There are currently no quotes for your account. + </t> + </small> + </a> + </h3> + <h3 class="page-header"> + <a href="/my/orders">Your Orders + <small class="ml8"> + <t t-if="order_count"> + <span class='badge'><t t-esc="order_count"/></span> + </t> + <t t-if="not order_count"> + There are currently no orders for your account. + </t> + </small> + </a> + </h3> + <h3 class="page-header"> + <a href="/my/invoices">Your Invoices and Payments + <small class="ml8"> + <t t-if="invoice_count"> + <span class='badge'><t t-esc="invoice_count"/></span> + </t> + <t t-if="not invoice_count"> + There are currently no invoices for your account. + </t> + </small> + </a> + </h3> + </xpath> + </template> + + <template id="portal_my_quotations" name="My Quotations"> + <t t-call="website_portal.portal_layout"> <h3 class="page-header">Your Quotes</h3> <t t-if="not quotations"> <p>There are currently no quotes for your account.</p> @@ -30,9 +78,9 @@ </tr> </thead> <t t-foreach="quotations" t-as="quotation"> - <tr t-att-class="'hidden to_hide' if quotation.state!='sent' and quotation_index > 4 else ''"> + <tr> <td> - <a t-att-href="'/my/orders/'+str(quotation.id)"><t t-esc="quotation.name"/></a> + <a t-attf-href="/my/orders/#{quotation.id}?#{keep_query()}"><t t-esc="quotation.name"/></a> </td> <td><span t-field="quotation.validity_date"/></td> <td> @@ -47,14 +95,16 @@ </td> </tr> </t> - <tr t-att-class="'hidden' if len(quotations) < 5 else ''"> - <td colspan="5"><a href="" class="o_my_show_more btn btn-xs btn-default"><span>Show more</span><span class="hidden">Show less</span></a></td> - </tr> </table> + <div t-if="pager" class="o_portal_pager text-center"> + <t t-call="website.pager"/> + </div> </t> + </t> </template> - <template id="sale_orders" name="Sales Orders"> + <template id="portal_my_orders" name="My Sales Orders"> + <t t-call="website_portal.portal_layout"> <h3 class="page-header">Your Orders</h3> <t t-if="not orders"> <p>There are currently no orders for your account.</p> @@ -70,9 +120,9 @@ </tr> </thead> <t t-foreach="orders" t-as="order"> - <tr t-att-class="'hidden to_hide' if order.state not in ['manual', 'progress'] and order_index > 4 else ''"> + <tr> <td> - <a t-att-href="'/my/orders/'+str(order.id)"><t t-esc="order.name"/></a> + <a t-attf-href="/my/orders/{{order.id}}?{{keep_query()}}"><t t-esc="order.name"/></a> </td> <td><span t-field="order.date_order"/></td> <td> @@ -89,14 +139,16 @@ <td><span t-field="order.amount_total" t-field-options='{"widget": "monetary", "display_currency": "order.pricelist_id.currency_id"}'/></td> </tr> </t> - <tr t-att-class="'hidden' if len(orders) < 5 else ''"> - <td colspan="4"><a href="" class="o_my_show_more btn btn-xs btn-default"><span>Show more</span><span class="hidden">Show less</span></a></td> - </tr> </table> + <div t-if="pager" class="o_portal_pager text-center"> + <t t-call="website.pager"/> + </div> </t> + </t> </template> - <template id="invoices" name="Invoices and Payments"> + <template id="portal_my_invoices" name="My Invoices and Payments"> + <t t-call="website_portal.portal_layout"> <h3 class="page-header">Your Invoices and Payments</h3> <t t-if="not invoices"> <p>There are currently no invoices for your account.</p> @@ -114,7 +166,7 @@ </tr> </thead> <t t-foreach="invoices" t-as="invoice"> - <tr t-att-class="'hidden to_hide' if invoice.state!='open' and invoice_index > 4 else ''"> + <tr> <td> <a t-att-href="'/report/pdf/account.report_invoice/'+str(invoice.id)"><t t-esc="invoice.number"/></a> </td> @@ -137,11 +189,12 @@ <td><span t-field="invoice.residual" t-field-options='{"widget": "monetary", "display_currency": "invoice.currency_id"}'/></td> </tr> </t> - <tr t-att-class="'hidden' if len(invoices) < 5 else ''"> - <td colspan="5"><a href="" class="o_my_show_more btn btn-xs btn-default"><span>Show more</span><span class="hidden">Show less</span></a></td> - </tr> </table> + <div t-if="pager" class="o_portal_pager text-center"> + <t t-call="website.pager"/> + </div> </t> + </t> </template> <template id="orders_followup" name="Sales Order"> @@ -152,7 +205,17 @@ <div class="row"> <div class="col-sm-4"> <ol class="breadcrumb mt8"> - <li><a href="/my/home">My Account</a></li> + <li><a href="/my/home"><i class="fa fa-home"/></a></li> + <li> + <a t-attf-href="/my/#{'quotes' if order.state == 'sent' else 'orders'}?{{ keep_query()}}"> + <t t-if="order.state == 'sent'"> + My Quotes + </t> + <t t-if="order.state != 'sent'"> + My Orders + </t> + </a> + </li> <li> <t t-if="order.state == 'sent'"> Quotation @@ -318,7 +381,7 @@ </t> </template> - <template id="sale_backend_link" inherit_id='website_portal_sale.sale_orders' customize_show="True" name="Link to Sales Backend" active="False"> + <template id="sale_backend_link" inherit_id='website_portal_sale.portal_my_orders' customize_show="True" name="Link to Sales Backend" active="False"> <xpath expr="//h3[@class='page-header']" position="inside"> <a href="/web#action=portal_sale.action_orders_portal" target="_blank" class="btn btn-default btn-xs pull-right"> Access the complete Sale application</a> </xpath> diff --git a/addons/website_project_issue/controllers/main.py b/addons/website_project_issue/controllers/main.py index 98f06c0c281f..64b006e2f42c 100644 --- a/addons/website_project_issue/controllers/main.py +++ b/addons/website_project_issue/controllers/main.py @@ -6,17 +6,46 @@ from openerp.http import request class WebsiteAccount(website_account): - @http.route(['/my', '/my/home'], type='http', auth="user", website=True) + + @http.route() def account(self): response = super(WebsiteAccount, self).account() - user = request.env.user - project_issues = request.env['project.issue'].search([]) - response.qcontext.update({'issues': project_issues}) + issue_count = request.env['project.issue'].search_count([]) + response.qcontext.update({'issue_count': issue_count}) return response + @http.route(['/my/issues', '/my/issues/page/<int:page>'], type='http', auth="user", website=True) + def portal_my_issues(self, page=1, date_begin=None, date_end=None, **kw): + values = self._prepare_portal_layout_values() + ProjectIssue = request.env['project.issue'] + domain = [] + # archive groups - Default Group By 'create_date' + archive_groups = self._get_archive_groups('project.issue', domain) + if date_begin and date_end: + domain += [('create_date', '>=', date_begin), ('create_date', '<', date_end)] + # pager + issue_count = ProjectIssue.search_count(domain) + pager = request.website.pager( + url="/my/issues", + url_args={'date_begin': date_begin, 'date_end': date_end}, + total=issue_count, + page=page, + step=self._items_per_page + ) + # content according to pager and archive selected + project_issues = ProjectIssue.search(domain, order="stage_id", limit=self._items_per_page, offset=pager['offset']) + + values.update({ + 'date': date_begin, + 'issues': project_issues, + 'page_name': 'issue', + 'archive_groups': archive_groups, + 'default_url': '/my/issues', + 'pager': pager + }) + return request.website.render("website_project_issue.portal_my_issues", values) -class WebsiteProjectIssue(http.Controller): @http.route(['/my/issues/<int:issue_id>'], type='http', auth="user", website=True) - def issues_followup(self, issue_id=None): + def issues_followup(self, issue_id=None, **kw): issue = request.env['project.issue'].browse(issue_id) return request.website.render("website_project_issue.issues_followup", {'issue': issue}) diff --git a/addons/website_project_issue/views/project_issue_templates.xml b/addons/website_project_issue/views/project_issue_templates.xml index a19fa256366c..27a120cd84cb 100644 --- a/addons/website_project_issue/views/project_issue_templates.xml +++ b/addons/website_project_issue/views/project_issue_templates.xml @@ -1,7 +1,33 @@ <?xml version="1.0" encoding="utf-8"?> <odoo> - <template id="portal_project_issue" name="Portal Project Issues" inherit_id="website_portal.account"> - <xpath expr="//div[contains(@class,'o_my_documents')]/*[last()]" position="after"> + + <template id="portal_my_home_menu_issue" name="Portal layout : issues menu entry" inherit_id="website_portal.portal_layout" priority="30"> + <xpath expr="//ul[contains(@class,'o_portal_submenu')]" position="inside"> + <li t-att-class="page_name == 'issue' and 'active' or ''"> + <a href="/my/issues">Issues</a> + </li> + </xpath> + </template> + + <template id="portal_my_home_issue" name="Portal My Home : issue entries" inherit_id="website_portal.portal_my_home" priority="30"> + <xpath expr="//div[contains(@class,'o_my_home_content')]" position="inside"> + <h3 class="page-header"> + <a href="/my/issues">Your Issues + <small class="ml8"> + <t t-if="issue_count"> + <span class='badge'><t t-esc="issue_count"/></span> + </t> + <t t-if="not issue_count"> + There are currently no issues for your account. + </t> + </small> + </a> + </h3> + </xpath> + </template> + + <template id="portal_my_issues" name="My Issues" priority="30"> + <t t-call="website_portal.portal_layout"> <h3 class="page-header">Your Issues</h3> <t t-if="not issues"> <p>There are currently no issues for your account.</p> @@ -16,20 +42,21 @@ </tr> </thead> <t t-foreach="issues" t-as="issue"> - <tr t-att-class="'hidden to_hide' if issue_index > 4 else ''"> - <td><a t-attf-href="/my/issues/#{issue.id}">Issue <t t-esc="issue.id"/></a></td> + <tr> + + <td> + <a t-attf-href="/my/issues/#{issue.id}?{{ keep_query() }}">Issue <t t-esc="issue.id"/></a> + </td> <td><span t-field="issue.name"/></td><td/> <td><span t-field="issue.stage_id.name"/></td> </tr> </t> - <tr t-att-class="'hidden' if len(issues) < 6 else ''"> - <td colspan="4"> - <a href="" class="o_my_show_more btn btn-xs btn-default"><span>Show more</span><span class="hidden">Show less</span></a> - </td> - </tr> </table> + <div t-if="pager" class="o_portal_pager text-center"> + <t t-call="website.pager"/> + </div> </t> - </xpath> + </t> </template> <template id="issues_followup" name="Project Issues"> @@ -40,7 +67,8 @@ <div class="row"> <div class="col-sm-4"> <ol class="breadcrumb mt8"> - <li><a href="/my/home">My Account</a></li> + <li><a href="/my/home"><i class="fa fa-home"/></a></li> + <li><a t-attf-href="/my/issues?#{keep_query()}">My Issues</a></li> <li>Issue <span t-field="issue.id"/></li> </ol> </div> diff --git a/addons/website_quote/views/website_quotation.xml b/addons/website_quote/views/website_quotation.xml index 75b1086e6e9d..0e5795aadba4 100644 --- a/addons/website_quote/views/website_quotation.xml +++ b/addons/website_quote/views/website_quotation.xml @@ -162,7 +162,8 @@ <div t-if="breadcrumb" class="row"> <div class="col-sm-4"> <ol class="breadcrumb mt8"> - <li><a href="/my/home">My Account</a></li> + <li><a href="/my/home"><i class="fa fa-home"/></a></li> + <li><a t-attf-href="/my/quotes?#{keep_query()}">My Quotations</a></li> <li> Quotation <t t-esc="quotation.name"/> </li> @@ -682,12 +683,12 @@ </xpath> </template> - <template id="quotations" inherit_id="website_portal_sale.quotations"> + <template id="quotations" inherit_id="website_portal_sale.portal_my_quotations"> <xpath expr="//t[@t-foreach='quotations']" position="replace"> <t t-foreach="quotations" t-as="quotation"> - <tr t-att-class="'hidden to_hide' if quotation_index > 4 else ''"> + <tr> <td> - <a t-att-href="'/quote/'+str(quotation.id)"><t t-esc="quotation.name"/></a> + <a t-attf-href="/quote/#{quotation.id}?#{keep_query()}"><t t-esc="quotation.name"/></a> </td> <td><span t-field="quotation.validity_date"/></td> <td> -- GitLab