Skip to Content
Menú
This question has been flagged
4 Respostes
276 Vistes

Hello everyone, I have been trying for several hours to hide the unit price in the portal. However, this should only happen for items that are available for rent.


I have Odoo 18 Enterprise.


I have already tried using the following module, but I can't find the line.

inherit_id="sale.portal_my_order"

            name="Hide Price Unit on Rentals (Portal)">

    <xpath expr="//div[@data-oe-model='sale.order.line'][@data-oe-field='price_unit']"

           position="replace">

      <t t-if="not line.is_rental">



Can anyone help me?




best regards


carstenmo

Avatar
Descartar
Autor Best Answer

so I got It but now I have other problems: 


this is my code: 


controller: 

from odoo.addons.sale.controllers.portal import CustomerPortal

from odoo.http import request, route


class CustomPortal(CustomerPortal):


    @route(['/my/orders/<int:order_id>'], type='http', auth="public", website=True)

    def portal_my_order(self, order_id=None, access_token=None, report_type=None, download=False, **kw):

        order_sudo = request.env['sale.order'].sudo().browse(order_id).exists()

        if not order_sudo:

            return request.redirect('/my/orders')


        # Zugriff prüfen

        try:

            order_sudo.check_access_rights('read')

            order_sudo.check_access_rule('read')

        except Exception:

            return request.redirect('/my')


        # Beispiel: Zugriff auf rental_ok

        for line in order_sudo.order_line:

            if line.product_id.product_tmpl_id.rental_ok:

                pass  # hier kannst du eigene Logik ergänzen


        values = self._prepare_portal_layout_values()

        values.update({

            'order': order_sudo,

            'sale_order': order_sudo,

            'report_type': report_type,

        })


        return request.render("sale.sale_order_portal_content", values)



xml view: 


?xml version="1.0" encoding="UTF-8"?>

<odoo>

  <template id="portal_my_order_inherit_hide_unit_price_for_rentals" inherit_id>


    <!-- Überschreibe nur die Preiszelle, aber zeige sie nur, wenn NICHT rental>

    <xpath expr="//t[@name='product_line_row']/td[3]" position="replace">

      <td t-if="not line.product_id.rental_ok"

          t-attf-class="text-end {{ 'd-none d-sm-table-cell' if report_type == >

        <div t-if="line.discount &gt;= 0"

             t-field="line.price_unit"

             t-att-style="line.discount and 'text-decoration: line-through' or >

             t-att-class="(line.discount and 'text-danger' or '') + ' text-end'>

        <div t-if="line.discount">

          <t t-out="(1-line.discount / 100.0) * line.price_unit"

             t-options="{&quot;widget&quot;: &quot;float&quot;, &quot;decimal_p>

        </div>

      </td>

    </xpath>


  </template>

</odoo>


and the problem  is: 

Error while render the template
AttributeError: 'product.product' object has no attribute 'rental_ok'
Template: sale.sale_order_portal_content
Path: /t/div[2]/section[1]/div[1]/table/tbody/t[3]/tr[1]/t[1]/td[3]
Node: <td t-if="not line.product_id.rental_ok" t-attf-class="text-end {{ \'d-none d-sm-table-cell\' if report_type == \'html\' else \'\' }}"/>

Der Fehler ist beim Rendering der Vorlage aufgetreten sale.sale_order_portal_content und beim Evaluieren des folgenden Ausdrucks: <td t-if="not line.product_id.rental_ok" t-attf-class="text-end {{ \'d-none d-sm-table-cell\' if report_type == \'html\' else \'\' }}"/>

Avatar
Descartar
Best Answer

Hiii,

Create your custom module (

In the XML file (eg, views/portal_sale_order_templates.xml ), inherit the correct template and modify the unit price display.

<odoo>

  <template id="portal_sale_order_hide_price_unit_rental" inherit_id="sale.portal_my_order">

    <xpath expr="//tr[@t-foreach='order.order_line' and @t-as='line']//td[span[@t-field='line.price_unit']]" position="replace">

      <td>

        <t t-if="not line.is_rental">

          <span t-field="line.price_unit"/>

        </t>

        <t t-else="">

          <span>-</span> <!-- or leave it empty -->

        </t>

      </td>

    </xpath>

  </template>

</odoo>


The XPath targets the <td> cell that holds the price_unit .

This ensures the cell exists, but the value is conditionally hidden or replaced with a dash ( - ).

You can also add invisible styles instead, but t-if is cleaner.


Ensure is_rental is in sale.order.line and visible in portal

Make sure is_rental is either:

  • A computed field or boolean field on sale.order.line , and
  • Included in the allowed fields for portal rendering (if required via controller or access rules).

If not yet present:

class SaleOrderLine(models.Model):

    _inherit = 'sale.order.line'


    is_rental = fields.Boolean(string="Is Rental")


i hope it is use full

Avatar
Descartar
Best Answer

Hi,


Try the following code.


<template id="portal_my_order_inherit_hide_unit_price_for_rentals"         inherit_id="sale.portal_my_order">

    <xpath expr="//td[span[@t-field='line.price_unit']]" position="replace">

      <t t-if="not line.is_rental">

        <td>

          <span t-field="line.price_unit"/>

        </td>

      </t>

      <t t-else="">

        <td>-</td> <!-- Or leave it blank: <td></td> -->

      </t>

    </xpath>

  </template>



* Ensure the field is_rental is available in the portal template


If line.is_rental is not available in the portal context, you’ll need to inherit the controller like this:


from odoo.addons.portal.controllers.portal import CustomerPortal

from odoo.http import request


class CustomerPortalInherit(CustomerPortal):


    def _prepare_home_portal_values(self, counters):

        values = super()._prepare_home_portal_values(counters)

        # optional

        return values


    @http.route(['/my/orders/<int:order_id>'], type='http', auth="user", website=True)

    def portal_order_page(self, order_id=None, access_token=None, **kw):

        response = super().portal_order_page(order_id, access_token, **kw)

        sale_order = response.qcontext.get('order')

        for line in sale_order.order_line:

            line.ensure_one()

            # if needed, ensure `is_rental` is computed or passed

        return response


Make sure is_rental is either:

       - A boolean field on the sale.order.line, or

       - Derived from the linked product via something like:

                        is_rental = fields.Boolean(related='product_id.rental_ok', store=False)


Hope it helps

Avatar
Descartar
Best Answer

Try with following code:

<div t-field="line.price_unit" position="attributes">
<attribute name="t-if">not line.is_rental</attribute>
</div>


Avatar
Descartar
Related Posts Respostes Vistes Activitat
2
de jul. 25
523
2
de jul. 25
1467
1
de maig 25
1733
1
de maig 24
2741
2
de febr. 24
2229