openerp学习笔记 计算字段支持搜索

示例1:

# -*- encoding: utf-8 -*-
import pooler
import logging
import netsvc
import tools
logger = netsvc.Logger()
import datetime
import time
import math
from osv import fields,osv
from openerp.tools.translate import _  #用于翻译代码中的静态字符串

class res_users(osv.osv):
    _name = "res.users"
    _inherit = 'res.users'
   
    _columns={
        'location_ids': fields.many2many('stock.location', id1='user_id', id2='location_id', string=u'允许的库位'),     
    }
   
res_users()

class stock_picking(osv.osv):
    _name = "stock.picking"
    _inherit = 'stock.picking'

    def _get_location_ids(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for pick in self.browse(cr, uid, ids):
            location_ids = set()
            for move in pick.move_lines:
                location_ids.add(move.location_id.id)
            res[pick.id] = list(location_ids)
        return res

    def _location_ids_search(self, cr, uid, obj, name, args, context=None):
        for arg in args:
            if arg[0] == 'location_ids':
                operator = arg[1]
                search_term = arg[2]
        if operator and search_term:
            move_obj = self.pool.get('stock.move')
            move_ids = move_obj.search(cr, uid,
                [('location_id', operator, search_term)], context=context)
        else:
            move_ids = []
        return [('move_lines', 'in', move_ids)]
   
    def _get_location_dest_ids(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for pick in self.browse(cr, uid, ids):
            location_ids = set()
            for move in pick.move_lines:
                location_ids.add(move.location_id.id)
            res[pick.id] = list(location_ids)
        return res

    def _location_dest_ids_search(self, cr, uid, obj, name, args, context=None):
        for arg in args:
            if arg[0] == 'location_dest_ids':
                operator = arg[1]
                search_term = arg[2]
        if operator and search_term:
            move_obj = self.pool.get('stock.move')
            move_ids = move_obj.search(cr, uid,
                [('location_dest_id', operator, search_term)], context=context)
        else:
            move_ids = []
        return [('move_lines', 'in', move_ids)]

    _columns = { 
        'location_ids':fields.function(_get_location_ids, fnct_search=_location_ids_search,
            method=True, type='many2many', relation='stock.location', string='源库位 ids'),
               
        'location_dest_ids':fields.function(_get_location_dest_ids, fnct_search=_location_dest_ids_search,
            method=True, type='many2many', relation='stock.location', string='目标库位 ids'),
    }

stock_picking()

 

 

示例2:

class stock_production_lot(osv.osv):

     _name = 'stock.production.lot'

    _description = 'Serial Number'

 

    def _get_stock(self, cr, uid, ids, field_name, arg, context=None):

        """ Gets stock of products for locations

        @return: Dictionary of values

        """

        if context is None:

            context = {}

        if 'location_id' not in context:

            locations = self.pool.get('stock.location').search(cr, uid, [('usage', '=', 'internal')], context=context)

        else:

            locations = context['location_id'] and [context['location_id']] or []

 

        if isinstance(ids, (int, long)):

            ids = [ids]

 

        res = {}.fromkeys(ids, 0.0)

        if locations:

            cr.execute('''select

                    prodlot_id,

                    sum(qty)

                from

                    stock_report_prodlots

                where

                    location_id IN %s and prodlot_id IN %s group by prodlot_id''',(tuple(locations),tuple(ids),))

            res.update(dict(cr.fetchall()))

 

        return res

 

    def _stock_search(self, cr, uid, obj, name, args, context=None):

        """ Searches Ids of products

        @return: Ids of locations

        """

        locations = self.pool.get('stock.location').search(cr, uid, [('usage', '=', 'internal')])

        cr.execute('''select

                prodlot_id,

                sum(qty)

            from

                stock_report_prodlots

            where

                location_id IN %s group by prodlot_id

            having  sum(qty) '''+ str(args[0][1]) + str(args[0][2]),(tuple(locations),))

        res = cr.fetchall()

        ids = [('id', 'in', map(lambda x: x[0], res))]

        return ids

 

    _columns = {

        'name': fields.char('Serial Number', size=64, required=True, help="Unique Serial Number, will be displayed as: PREFIX/SERIAL [INT_REF]"),

        'ref': fields.char('Internal Reference', size=256, help="Internal reference number in case it differs from the manufacturer's serial number"),

        'prefix': fields.char('Prefix', size=64, help="Optional prefix to prepend when displaying this serial number: PREFIX/SERIAL [INT_REF]"),

        'product_id': fields.many2one('product.product', 'Product', required=True, domain=[('type', '<>', 'service')]),

        'date': fields.datetime('Creation Date', required=True),

        'stock_available': fields.function(_get_stock, fnct_search=_stock_search, type="float", string="Available", select=True,

            help="Current quantity of products with this Serial Number available in company warehouses",

            digits_compute=dp.get_precision('Product Unit of Measure')),

        'revisions': fields.one2many('stock.production.lot.revision', 'lot_id', 'Revisions'),

        'company_id': fields.many2one('res.company', 'Company', select=True),

        'move_ids': fields.one2many('stock.move', 'prodlot_id', 'Moves for this serial number', readonly=True),

    }

    _defaults = {

        'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),

        'name': lambda x, y, z, c: x.pool.get('ir.sequence').get(y, z, 'stock.lot.serial'),

        'product_id': lambda x, y, z, c: c.get('product_id', False),

    }

    _sql_constraints = [

        ('name_ref_uniq', 'unique (name, ref)', 'The combination of Serial Number and internal reference must be unique !'),

    ]

 

stock_production_lot()

 

示例3:

# -*- coding: utf-8 -*-
from openerp.osv import fields, osv
import decimal_precision as dp
from openerp.addons.stock.product import product_product as spp
from openerp.addons.product.product import product_product as pp

_product_available = spp._product_available
_product_lst_price = pp._product_lst_price

SORTABLE_FUNC_FIELD = ('qty_available', 'virtual_available', 'lst_price')

def condition(operand, left, right):
    if operand == '=':
        operand = '=='
    return eval(' '.join((str(left),operand,str(right))))

class product_product(osv.osv):
    _inherit = "product.product"

    def _search_fnct(self, cr, uid, args, qty_type, context=None):
        context = context or {}
        print 'context', context
        ids = self.search(cr, uid, [], context=context)
        qty_products = self.read(cr, uid, ids, [qty_type], context=context)
        res = []
        for q in qty_products:
            if condition(args[0][1], q[qty_type], args[0][2]):
                res.append(q['id'])
        return [('id', 'in', res)]
   
    def _search_qty_available(self, cr, uid, obj, name, args, context):
        return self._search_fnct(cr, uid, args, 'qty_available', context)

    def _search_virtual_available(self, cr, uid, obj, name, args, context):
        return self._search_fnct(cr, uid, args, 'virtual_available', context)

    def _search_lst_price(self, cr, uid, obj, name, args, context):
        return self._search_fnct(cr, uid, args, 'lst_price', context)
           
    _columns = {
        'qty_available': fields.function(_product_available,
            multi='qty_available', type='float',
            digits_compute=dp.get_precision('Product Unit of Measure'),
            fnct_search=_search_qty_available,
            string='Quantity On Hand',
            help="Current quantity of products.\n"
                 "In a context with a single Stock Location, this includes "
                 "goods stored at this Location, or any of its children.\n"
                 "In a context with a single Warehouse, this includes "
                 "goods stored in the Stock Location of this Warehouse, or any"
                 "of its children.\n"
                 "In a context with a single Shop, this includes goods "
                 "stored in the Stock Location of the Warehouse of this Shop, "
                 "or any of its children.\n"
                 "Otherwise, this includes goods stored in any Stock Location "
                 "with 'internal' type."),
        'virtual_available': fields.function(_product_available,
            multi='qty_available', type='float',
            digits_compute=dp.get_precision('Product Unit of Measure'),
            fnct_search=_search_virtual_available,
            string='Forecasted Quantity',
            help="Forecast quantity (computed as Quantity On Hand "
                 "- Outgoing + Incoming)\n"
                 "In a context with a single Stock Location, this includes "
                 "goods stored in this location, or any of its children.\n"
                 "In a context with a single Warehouse, this includes "
                 "goods stored in the Stock Location of this Warehouse, or any"
                 "of its children.\n"
                 "In a context with a single Shop, this includes goods "
                 "stored in the Stock Location of the Warehouse of this Shop, "
                 "or any of its children.\n"
                 "Otherwise, this includes goods stored in any Stock Location "
                 "with 'internal' type."),
        'lst_price' : fields.function(_product_lst_price, type='float',
            string='Public Price', fnct_search=_search_lst_price,
            digits_compute=dp.get_precision('Product Price')),
        }

    def search(self, cr, uid, args, offset=0, limit=None, order=None,
            context=None, count=False):
        context = context or {}
        func_flds = []
        if order:
            order_part = order.split(',')[0]
            order_split = order_part.strip().split(' ')
            order_field = order_split[0].strip()
            order_direction = order_split[1].strip() if len(order_split) == 2 else ''
            if order_field in SORTABLE_FUNC_FIELD:
                    func_flds.append((order_field, order_direction))
        ids = super(product_product, self).search(cr, uid, args, offset, limit,
                order, context, count)
        if func_flds:
            for fld, order in func_flds:
                val = self.read(cr, uid, ids, [fld], context=context)
                sorted_val = sorted(val, key=lambda x: x[fld],
                        reverse=(order=='DESC'))
            ids = map(lambda x: x['id'], sorted_val)
        return ids

# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

 

posted @ 2013-07-12 08:49  cnshen  阅读(275)  评论(0编辑  收藏  举报