Odoo Help

Welcome!

This community is for beginners and experts willing to share their Odoo knowledge. It's not a forum to discuss ideas, but a knowledge base of questions and their answers.

0

Domain filter - how to use if field is a function field ?

By
Dr Obx
on 5/21/15, 6:01 PM 2,724 views
I'm still searching for solution, most of errors now sorted but it won't work anyway.

Current code:
#from openerp import models, fields, api, _
from openerp.osv import fields,osv
class stock_location(osv.osv):
    _inherit = 'stock.location'

# Get stocks quantity
    def _get_current_stock(self, cr, uid, ids, fields, arg, context=None):
        res = []
        quants = []
        for obj in self.browse(cr, uid, ids, context=context):
            if 'default_product_id' in context:
                quants = self.pool.get('stock.quant').search(cr, uid, [('location_id','=',id),('product_id','=?',context.get('default_product_id'))])
            else:
                quants = self.pool.get('stock.quant').search(cr, uid, [('location_id','=',id)])

            for quant in self.pool.get('stock.quant').browse(cr, uid, quants, context):
                res[obj.id] += quant.qty
        return res

# Get locations ids
    def _get_locations(self, cr, uid, ids, context=None):
        res = []
        for quant in self.pool.get('stock.quants').browse(cr, uid, ids, context=context):
            if quant.location_id:
                res.append(quant.location_id.id)
        return res

# Fields declaration
    _columns = {
        'qty': fields.function(_get_current_stock, type = "float", string = 'qty', store = {'stock.quants': (_get_locations, ['location_id','qty'], 1 ) } ),
    }

# Overriding name_get
    def name_get(self, cr, uid, ids, context=None):
        res = []
        for loc in self.browse(cr, uid, ids, context):
            res.append((loc.id, loc.name + " / " + str(loc.qty) + " Units" or ''))
        return res



hi! is this the same indentation you are using ? "def _get_locations(self, cr, uid, ids, context=None):" should be out of the above function, as it is a new seperate function. and same for "def name_get".

Pawan
on 5/29/15, 10:45 AM

you have kept the "qty" field declaration inside the "_get_current_stock" function, if this is the same same indentation u r using, then pls correct it .

Pawan
on 5/29/15, 10:49 AM

check my answer below.

Pawan
on 5/29/15, 1:40 PM

try converting your code as per old api..... as replace model.model with osv.osv, remove @api.one, @api.depends(), @api.multi and field.reference to fields.function(). 'res' is not any reserved keyword by odoo, its just a variable taken for storing the result.

Pawan
on 6/1/15, 1:32 AM

you have to change "self.env" to "self.pool.get()" ..... and put '_get_current_stock' and '_get_locations' before field declarations as python interprets

Pawan
on 6/2/15, 1:48 AM

Check updated answer below and verify indentations and braces...

Pawan
on 6/3/15, 1:14 AM

can u explain your error in detail

Pawan
on 6/4/15, 5:19 AM

You don't need to use "self.id" as you are already browsing the record and for that instance the object is stored in "obj" variable, so you can use "obj.id" instead of 'self.id"

Pawan
on 6/9/15, 1:05 AM

Robx, i think its better , if we go through your code live, so that we can get the cause and your error in detail, if its possible forward me your skype id to my email(mail@pawanmisra.info) or any other way u want to go through.....

Pawan
on 6/10/15, 2:22 AM

Rob, under "_get_current_stock" function you have kept "self.res[obj.id]" , inspite you dont need self, because there is no attribute named res in self object, so try removing self and make it to res only...., further there is not more issues seeming to be there in your code updated......

Pawan
on 6/11/15, 11:20 AM
Pawan, Help
It's serious :(
Need your help desperately

On 15 June 2015 at 14:39, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Hi Pawan,
Still can't find a problem :(


On 12 June 2015 at 09:56, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Hello again :)
Tell me please how can I filter it. For now in i tried  filter_domain="[('default_location_id', 'ilike','location_id'),('qty_available','!=',0)]"  but it doesn't work :(

On 12 June 2015 at 09:45, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
#from openerp import models, fields, api, _
from openerp.osv import fields,osv
class stock_location(osv.osv):
    _inherit = 'stock.location'

# Get stocks quantity
    def _get_current_stock(self, cr, uid, ids, fields, arg, context=None):
        res = []
        quants = []
        for obj in self.browse(cr, uid, ids, context=context):
            if 'default_product_id' in context:
                quants = self.pool.get('stock.quant').search(cr, uid, [('location_id','=',id),('product_id','=?',context.get('default_product_id'))])
            else:
                quants = self.pool.get('stock.quant').search(cr, uid, [('location_id','=',id)])

            for quant in self.pool.get('stock.quant').browse(cr, uid, quants, context):
                res[obj.id] += quant.qty
        return res

# Get locations ids
    def _get_locations(self, cr, uid, ids, context=None):
        res = []
        for quant in self.pool.get('stock.quants').browse(cr, uid, ids, context=context):
            if quant.location_id:
                res.append(quant.location_id.id)
        return res

# Fields declaration
    _columns = {
        'qty': fields.function(_get_current_stock, type = "float", string = 'qty', store = {'stock.quants': (_get_locations, ['location_id','qty'], 1 ) } ),
    }

# Overriding name_get
    def name_get(self, cr, uid, ids, context=None):
        res = []
        for loc in self.browse(cr, uid, ids, context):
            res.append((loc.id, loc.name + " / " + str(loc.qty) + " Units" or ''))
        return res

On 12 June 2015 at 09:34, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Still getting this error and won't count quants :(
ProgrammingError: column reference "qty" is ambiguous
LINE 3: ....parent_left < 26) OR stock_location.id = 20) AND qty < 0.0 ...

On 12 June 2015 at 09:13, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Hi Pawan,
I'll check it immediately. ;)


On 11 June 2015 at 16:20, Pawan <pawanmisra.2008@gmail.com> wrote:

Rob, under "_get_current_stock" function you have kept "self.res[obj.id]" , inspite you dont need self, because there is no attribute named res in self object, so try removing self and make it to res only...., further there is not more issues seeming to be there in your code updated......







Dr Obx
on 7/15/15, 6:12 PM
I know you busy, but if would you like to give me a helping hand with this task, would be appreciated.

On 15 July 2015 at 23:12, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Pawan, Help
It's serious :(
Need your help desperately

On 15 June 2015 at 14:39, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Hi Pawan,
Still can't find a problem :(


On 12 June 2015 at 09:56, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Hello again :)
Tell me please how can I filter it. For now in i tried  filter_domain="[('default_location_id', 'ilike','location_id'),('qty_available','!=',0)]"  but it doesn't work :(

On 12 June 2015 at 09:45, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
#from openerp import models, fields, api, _
from openerp.osv import fields,osv
class stock_location(osv.osv):
    _inherit = 'stock.location'

# Get stocks quantity
    def _get_current_stock(self, cr, uid, ids, fields, arg, context=None):
        res = []
        quants = []
        for obj in self.browse(cr, uid, ids, context=context):
            if 'default_product_id' in context:
                quants = self.pool.get('stock.quant').search(cr, uid, [('location_id','=',id),('product_id','=?',context.get('default_product_id'))])
            else:
                quants = self.pool.get('stock.quant').search(cr, uid, [('location_id','=',id)])

            for quant in self.pool.get('stock.quant').browse(cr, uid, quants, context):
                res[obj.id] += quant.qty
        return res

# Get locations ids
    def _get_locations(self, cr, uid, ids, context=None):
        res = []
        for quant in self.pool.get('stock.quants').browse(cr, uid, ids, context=context):
            if quant.location_id:
                res.append(quant.location_id.id)
        return res

# Fields declaration
    _columns = {
        'qty': fields.function(_get_current_stock, type = "float", string = 'qty', store = {'stock.quants': (_get_locations, ['location_id','qty'], 1 ) } ),
    }

# Overriding name_get
    def name_get(self, cr, uid, ids, context=None):
        res = []
        for loc in self.browse(cr, uid, ids, context):
            res.append((loc.id, loc.name + " / " + str(loc.qty) + " Units" or ''))
        return res

On 12 June 2015 at 09:34, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Still getting this error and won't count quants :(
ProgrammingError: column reference "qty" is ambiguous
LINE 3: ....parent_left < 26) OR stock_location.id = 20) AND qty < 0.0 ...

On 12 June 2015 at 09:13, Robert Amberwich <robert.amberwitch@gmail.com> wrote:
Hi Pawan,
I'll check it immediately. ;)


On 11 June 2015 at 16:20, Pawan <pawanmisra.2008@gmail.com> wrote:

Rob, under "_get_current_stock" function you have kept "self.res[obj.id]" , inspite you dont need self, because there is no attribute named res in self object, so try removing self and make it to res only...., further there is not more issues seeming to be there in your code updated......








Dr Obx
on 7/15/15, 6:21 PM
0

Pawan

--Pawan--
1267
| 4 3 5
Hyderabad, India
--Pawan--


Pawan
On 5/22/15, 5:19 AM

Updated :-

#from openerp import models, fields, api, _

from openerp.osv import fields,osv


class stock_location(osv.osv):

    _inherit = 'stock.location

# Get stocks quantity

    def _get_current_stock(self, cr, uid, ids, fields, arg, context=None): 

        res = []

        quants = []

        for obj in self.browse(cr, uid, ids, context=context):

            if 'default_product_id' in context:

                quants = self.pool.get('stock.quant').search(cr, uid, [('location_id','=',id),('product_id','=?',context.get('default_product_id'))])

            else:

                quants = self.pool.get('stock.quant').search(cr, uid, [('location_id','=',id)])

            for quant in self.pool.get('stock.quant').browse(cr, uid, quants, context):

                 res[obj.id] += quant.qty

        return res 

# Get locations ids

    def _get_locations(self, cr, uid, ids, context=None):

        res = []

        for quant in self.pool.get('stock.quants').browse(cr, uid, ids, context=context):

            if quant.location_id:

                res.append(quant.location_id.id)

        return res

# Fields declaration

    _columns = {

        'loca': fields.char('Location'),

        'qty': fields.function(_get_current_stock, type = "float", string = 'Qty', store = {'stock.quants': (_get_locations,                     ['location_id','qty'], 1 ) } ),

    }

# Overriding name_get

    def name_get(self, cr, uid, ids, context=None):

        res = []

        for loc in self.browse(cr, uid, ids, context):

            res.append((loc.id, loc.name + " / " + str(loc.qty) + " Units" or ''))       

        return res


It won't work because qty is a function field. You cannot domain (filter) using qty field.

Ivan
on 5/22/15, 6:36 AM

For the error, you need to use use '&' instead of '&' in the XML.

Ivan
on 5/22/15, 6:37 AM

Sorry, another one: with or without '&' the definition is the same. The default operator is '&' and in the case of multi operator, it will process the most middle operator with the 2 fields after it, then the result will be processed with the next operator at the left of the first operator and the next field at the right of the first 2 fields, and so on.... Any missing operator will be replaced with '&'.

Ivan
on 5/22/15, 6:39 AM

Hi Robert, You can only use the domain if the field is stored. Regards, André

a.schenkels
on 5/22/15, 11:27 AM

Please refer the updated answer.....

Pawan
on 5/28/15, 3:16 AM

Rob, please provide the error you are getting....

Pawan
on 5/28/15, 9:18 AM

from terminal you can get the error in detail, take it from there

Pawan
on 5/28/15, 9:38 AM

how r u starting ur server??? from terminal only(both in windows and linux) , isn't it! if not then start using terminal there you can track the errors in detail.

Pawan
on 5/28/15, 10:01 AM

yes, that only. through ssh take the access of the server(kill the previous process and restart) now you can see the overall flow and your error in detail too.

Pawan
on 5/28/15, 10:23 AM

keep remember to restart the server using '&' (./openerp-server &) so that if you close the terminal also the server would be running

Pawan
on 5/28/15, 10:24 AM

go through the same scenario you were going earlier and getting the error, and then take a look at the terminal, you can get it here too..... trying tracing the flow from file to file..

Pawan
on 5/28/15, 10:41 AM

what is showing at browser ??

Pawan
on 5/28/15, 12:38 PM

in your code under "_get_current_stock" function bring "return res" out of the loop, and same for "_get_locations " too...... rest all is seeming to be right, rather if your data fetching is correct.....

Pawan
on 5/28/15, 12:41 PM

I can't see what is the problem here using the qty in a domain. The question is not clear or seems to be lost in edits

Axel Mendoza
on 7/18/15, 12:40 AM
0
Dr Obx
On 5/24/15, 6:09 PM

if qty is a functional field you can use "store" attribute at functional field declaration to store it in DB, and then you can simply apply the domain .

Pawan
on 5/25/15, 1:18 AM

You can not just give store=true, store attribute will work as a trigger which will be triggered when the parameter passed as its value changes, for ex: store = { 'objectname': ( functionname, ['fieldname1', 'fieldname2'], priority) } here, "objectname" is the name of object which will be responsible for triggering the store attribute. "functionname" is the name of the function which will be executed when the values of fields "fieldname1", "fieldname2" of object "objectname" changes. "priority" is the priority of this object sequence(if more than one objects are passed)

Pawan
on 5/26/15, 1:10 AM

for your field: fields.Float(compute='_get_current_stock', string = 'Qty', store = true) you can simply declare it as a functional field as : fields.function(_get_current_stock, type="float", string = 'Qty', store = { 'objectname': (functionname, ['fieldname1', 'fieldname2'], priority) } ) here the objectname is the one, on change of whose fields value the value of your field is changing, as for now i think its ''stock.quant'' object and its field is 'qty'. At "functioname" function you have to return the id(s) of the record of current object you want to change. this will simply store your values in the database. For further details you can use: https://doc.odoo.com/6.0/developer/2_5_Objects_Fields_Methods/field_type/

Pawan
on 5/26/15, 1:29 AM

yes somewhat correct, but under store attribute you have to take another function(inspite of _get_current_stock) that must return the ids of your stock.location object that has to be changed.

Pawan
on 5/26/15, 1:45 PM

I have modified my answer, you can go through it....

Pawan
on 5/27/15, 10:48 AM

Your Answer

Please try to give a substantial answer. If you wanted to comment on the question or answer, just use the commenting tool. Please remember that you can always revise your answers - no need to answer the same question twice. Also, please don't forget to vote - it really helps to select the best questions and answers!

About This Community

This community is for professionals and enthusiasts of our products and services. Read Guidelines

Question tools

2 follower(s)

Stats

Asked: 5/21/15, 6:01 PM
Seen: 2724 times
Last updated: 7/15/15, 6:21 PM