Ir al contenido
Menú
Se marcó esta pregunta
1 Responder
364 Vistas

Hello, I'm trying to show the number of days (0 day, -2 days, 3 days etc) for the Integer field "Days Left". The problem here(again) is that the result is not showing in the list view when "Days Left" is equal to 0. It's working fine in the form view.

View Name : product.template.product.list

====================================

Product Name.    Expiry Date.                   Days Left

Product 1.            14 Jun 2025(Today)       1

Product 2.           13 Jun 2025                    (empty)

Product 3.           12 Jun 2025                     -1

====================================


class Drug(models.Model):
_inherit = "product.template"

expiry_date = fields.Date(string="Expiry Date")
due = fields.Integer(string="Days Left", compute="_compute_due")

def _compute_due(self):
for record in self:
if record.expiry_date:
today_date = date.today()
# No need to convert to string and back
delta_days = (record.expiry_date - today_date).days
record.due = delta_days
else:
record.due = 0
<record id="view_drug_view_list" model="ir.ui.view">
<field name="name">drug.view.list.inherit</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_tree_view"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='name']" position="after">
<field name="expiry_date"/>
<field name="due"
decoration-danger = "due &lt;= 0"
decoration-warning = "due &lt;= 30"
decoration-info = "due &gt; 30"
widget="badge"/>
</xpath>
</field>
</record>

Thanks for your suggestions.


Avatar
Descartar
Mejor respuesta

An integer value of 0 - zero - is not rendered by default with the widget badge because it is rated as 'nothing'.

Since due is computed and not stored anyways, you may as well just compute a second field and convert it to a string:

# -*- coding: utf-8 -*-

from odoo import models, fields


class ProductTemplate(models.Model):
    _inherit = 'product.template'

    expiry_date = fields.Date(string='Expiry Date')
    due = fields.Integer(compute='_compute_due')
    due_label = fields.Char(string='Days Left', compute='_compute_due')

    def _compute_due(self):
        for record in self:
            record.due = (record.expiry_date - fields.Date.today()).days if record.expiry_date else 0
            record.due_label = str(record.due)
            # record.due_label = str(record.due)


... and use it as:

<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
    <record id="product_template_tree_view_inherit" model="ir.ui.view">
        <field name="name">product.template.product.list.inherit</field>
        <field name="model">product.template</field>
        <field name="inherit_id" ref="product.product_template_tree_view"/>
        <field name="arch" type="xml">
            <xpath expr="//field[@name='name']" position="after">
                <field name="expiry_date"/>
                <field name="due_label"
                       decoration-danger = "due &lt;= 0"
                       decoration-warning = "due &lt;= 30"
                       decoration-info = "due &gt; 30"
                       invisible="not expiry_date"
                       widget="badge"/>
            </xpath>
        </field>
    </record>
</odoo>


... which will result in:


You can simply recycle _compute_due() fort this, as its doing the same thing with the same values anyways too. 


Also, with an actual string label you could do so many more shenanigans, such as:

    def _compute_due(self):
        for record in self:
            record.due = (record.expiry_date - fields.Date.today()).days if record.expiry_date else 0
            if record.due == 0:
                record.due_label = _('expiring today')
            elif record.due > 0:
                record.due_label = _('%s day' % record.due) if record.due == 1 else _('%s days' % record.due)
            else:
                over_due = abs(record.due)
                record.due_label = _('%s day overdue' % over_due) if over_due == 1 else _('%s day overdue' % over_due)


On another note, however: you are aware about the fact that Odoo actually has  an expiry management integrated, right? https://www.odoo.com/documentation/applications/inventory_and_mrp/inventory/product_management/product_tracking/expiration_dates.html

Avatar
Descartar
Publicaciones relacionadas Respuestas Vistas Actividad
1
jun 25
1048
3
jun 25
305
1
jun 25
673
1
may 25
727
1
abr 25
784