Question

I've been struggling with this issue all day and tried all possible ways that i know.here's the problem:

The field that i'm working on has a format like this:

XXX-year example: 001-2014 (String)

suppose that we have these records:

  • 001-2014
  • 011-2014
  • 013-2013

the result that i expect to get is 011-2014 (in other words the earliest year with the biggest value)

I'v wrote this query that works fine on PostgreSql:

select split_part(numero_bl, '-', 1) as part1, 
       split_part(numero_bl, '-', 2) as part2 
       from livraisons 
ORDER BY part2 desc,part1 desc limit 1

the split_part function split the column 'numero_bl' to 2 parts.so the result is something like that:

part1| part2

001 | 2014

When i try to introduce it inside Python code it returns correct values using ascending order but returns ('None',) when it comes to descending order

here's a simple version of my function in python:

def set_numero_bl(self, cr, uid, ids,name,arg,context=None):
        res={}   
        cr.execute("""select split_part(numero_bl, '-', 1) as part1,
                    split_part(numero_bl, '-', 2) as part2 
                    from livraisons 
                    ORDER BY part2 desc,part1 desc limit 1""")
        execution = cr.fetchone()
        part1 = execution[0]
        part2 = execution[1]
        if part1:
              if part2:
                annee = int(part2)
                nombre = int(part1)+1
                valeur_final= str('%0*d' % (3, nombre))+"-"+str(annee)
                for livraisons in self.browse(cr, uid, ids):
                    res[livraisons.id]= valeur_final
        else: 
            valeur_final= str('%0*d' % (3, 1))+"-"+datetime.datetime.strftime(datetime.datetime.now(), '%Y')
            for livraisons in self.browse(cr, uid, ids):
                res[livraisons.id]= valeur_final
        return res

of course when i won't put the 'else clause' it will return ('None',)

Please is there anyway to fix it or to solve it in any other way?

Thank you

Was it helpful?

Solution 2

I've found out a way to solve my problem. I changed my query to this

cr.execute("""select max(numero_bl) as part from livraisons 
           where split_part(numero_bl, '-', 2) >= %s""",
        ((datetime.datetime.strftime(datetime.datetime.now(), '%Y')),))

First ,I keep only records where the year part is greater than the current year, after that i take the max value of my field 'numero_bl'

here's the full code if anyone is interested:

 def set_numero_bl(self, cr, uid, ids,name,arg,context=None):
    res={}   
    cr.execute("""select max(numero_bl) as part 
                 from livraisons 
        where split_part(numero_bl, '-', 2) >= %s""", 
        ((datetime.datetime.strftime(datetime.datetime.now(), '%Y')),)) 
    valeur = cr.fetchone()[0]
    if valeur:
        value = valeur.split('-'); 
        nombre = int(value[0])+1
        valeur_final= str('%0*d' % (3, nombre))+"-"+datetime.datetime.strftime(datetime.datetime.now(), '%Y')
        for livraisons in self.browse(cr, uid, ids):
            res[livraisons.id]= valeur_final
    else: 
        valeur_final= str('%0*d' % (3, 1))+"-"+datetime.datetime.strftime(datetime.datetime.now(), '%Y')
        for livraisons in self.browse(cr, uid, ids):
            res[livraisons.id]= valeur_final
    return res

Thank you all for your replies

OTHER TIPS

There are nulls in that column. When you ask for a descending order nulls will come first:

select *
from (values (1), (null)) s(a)
order by a desc;
 a 
---

 1
(2 rows)

If you want to keep nulls then tell it to order nulls last

select *
from (values (1), (null)) s(a)
order by a desc nulls last;
 a 
---
 1

(2 rows)

Or just filter out the nulls

select *
from (values (1), (null)) s(a)
where a is not null
order by a desc;
 a 
---
 1
(1 row)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top