Odoo Help


Nothing happens on calling a function

on 4/15/13, 10:40 AM 2,909 views

Hi, I am working on a module and it requires to update the product stock on clicking a button which calls a function for making picking from the form. I want to know a simple code for updating the stock table directly from the user input values.

Here's the code: from osv import osv, fields import time from datetime import datetime import pooler import decimal_precision as dp

class mass_return(osv.osv): _name = 'mass.return' _description = 'Mass Return of products' _inherit = 'product.template' def _line_total_amount(self, cr, uid, ids, field_name, arg,context): res={} for line in self.browse(cr,uid,ids):
res[line.id] = line.unit_sale_price*line.product_uom_qty return res

def address_get(self, cr, uid, ids):
    address_obj = self.pool.get('res.partner.address')
    address_ids = address_obj.search(cr, uid, [('partner_id', 'in', ids)])
    res = list((addr['id']) for addr in address_ids)
    adr = dict(res)
    # get the id of the (first) default address if there is one,
    # otherwise get the id of the first address in the list
    if res:
        default_address = adr.get('default', res[0][1])
        default_address = False
    result = {}
    return result

def onchange_partner_id(self, cr, uid, ids, part):
    if not part:
        return {'value': {'partner_address':False}}
    addr = self.pool.get('res.partner').address_get(cr, uid, [part], ['contact'])
    part = self.pool.get('res.partner').browse(cr, uid, part)
    pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
    val = {
         'partner_address': addr['contact'],
    if pricelist:
        val['pricelist_id'] = pricelist
    return {'value': val}
def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, return_lines, context={}):
    if (not pricelist_id) or (not return_lines):
        return {}
    warning = {
        'title': _('Pricelist Warning!'),
        'message' : _('If you change the pricelist of this order (and eventually the currency), prices of existing order lines will not be updated.')
    return {'warning': warning}

def _product_lst_price(self, cr, uid, ids):

res = {}

product_uom_obj = self.pool.get('product.uom')

for id in ids:

res.setdefault(id, 0.0)

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

if 'uom' in context:

uom = product.uos_id or product.uom_id

res[product.id] = product_uom_obj._compute_price(cr, uid,

uom.id, product.list_price, context['uom'])


res[product.id] = product.list_price

res[product.id] = (res[product.id] or 0.0) * (product.price_margin or 1.0) + product.price_extra

return res

def _compute_price(self, cr, uid, from_uom_id, price, to_uom_id=False):
    if not from_uom_id or not price or not to_uom_id:
        return price
    uoms = self.browse(cr, uid, [from_uom_id, to_uom_id])
    if uoms[0].id == from_uom_id:
        from_unit, to_unit = uoms[0], uoms[-1]
        from_unit, to_unit = uoms[-1], uoms[0]
    if from_unit.category_id.id <> to_unit.category_id.id:
        return price
    amount = price * from_unit.factor
    if to_uom_id:
        amount = amount / to_unit.factor
    return amount
def price_get(self, cr, uid, ids,product_id,context=None):
    if context is None:
        context = {}
    pricetype_obj = self.pool.get('product.price.type')
    price_type_id = pricetype_obj.search(cr, uid, [('field','=',ptype)])[0]
    res = {}
    product_uom_obj = self.pool.get('product.uom')
    for product in self.browse(cr, uid, ids, context=context):
        res[product.id] = product[ptype] or 0.0
        if ptype == 'list_price':
            res[product.id] = (res[product.id] * (product.price_margin or 1.0)) + \
        if 'uom' in context:
            uom = product.uom_id or product.uos_id
            res[product.id] = product_uom_obj._compute_price(cr, uid,
                    uom.id, res[product.id], context['uom'])
        # Convert from price_type currency to asked one
        if 'currency_id' in context:
            # Take the price_type currency from the product field
            # This is right cause a field cannot be in more than one currency
            res[product.id] = self.pool.get('res.currency').compute(cr, uid, price_type_currency_id,
                context['currency_id'], res[product.id],context=context)

    return res
def _get_returns(self, cr, uid, ids, context=None):
    result = {}
    for line in self.pool.get('mass.return.line').browse(cr, uid, ids, context=context):
        result[line.return_id.id] = True
    return result.keys()

def product_id_change(self,cr,uid,ids,prod):
    if not prod:
    val = {
    return {'value':val}
def _get_uom_id(self, cr, uid, *args):
        proxy = self.pool.get('ir.model.data')
        result = proxy.get_object_reference(cr, uid, 'product', 'product_uom_unit')
        return result[1]
    except Exception, ex:
        return False

def product_id_change(self, cr, uid, ids, pricelist, product, qty=0,uom=False, partner_id=False,flag=False, context=None):

context = context or {}

if not partner_id:

raise osv.except_osv(_('No Customer Defined !'), _('You have to select a customer in the form !\nPlease set one customer before choosing a product.'))


product_uom_obj = self.pool.get('product.uom')

partner_obj = self.pool.get('res.partner')

product_obj = self.pool.get('product.product')


if not product:

return {'domain':{'product_uom': []}}

uom2 = False

if uom:

uom2 = product_uom_obj.browse(cr, uid, uom)

if product_obj.uom_id.category_id.id != uom2.category_id.id:

uom = False

if not flag:

result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context_partner_id)[0][1]

domain = {}

if not pricelist:

warn_msg = _('You have to select a pricelist or a customer in the sales form !\n'

'Please set one before choosing a product.')

warning_msgs += _("No Pricelist ! : ") + warn_msg +"\n\n"


price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist],

product, qty or 1.0, partner_id, {

'uom': uom or result.get('product_uom'),

'date': date_order,


if price is False:

warn_msg = _("Couldn't find a pricelist line matching this product and quantity.\n"

"You have to change either the product, the quantity or the pricelist.")


warning_msgs += _("No valid pricelist line found ! :") + warn_msg +"\n\n"


result.update({'price_unit': price})

if warning_msgs:

warning = {

'title': _('Configuration Error !'),

'message' : warning_msgs


return {'value': result, 'domain': domain, 'warning': warning}

_columns    ={

'return_id':fields.integer('Return ID', readonly=True),

    'name':fields.char('Reason', size=128),
            'description': fields.text('Description'),
            'number': fields.char('Number', size=128, help="Company internal claim unique number"),
    'partner_id':fields.many2one('res.partner', 'Partner'),
            'partner_address': fields.many2one('res.partner.address', 'Partner Contact', \

            'partner_phone': fields.char('Phone', size=64),
            'origin': fields.selection([('none','Not specified'),
                                ('legal','Legal retractation'),
                                ('cancellation','Order cancellation'),
                                ('damaged','Damaged delivered product'),                                    
                                ('error','Shipping error'),
                                ('exchange','Exchange request'),
                                ('lost','Lost during transport'),
                                ('other','Other')], 'Return Subject', help="To describe the line product problem"),
    'active': fields.boolean('Active'),
    'cause': fields.text('Root Cause'),
            'prodlot_id': fields.many2one('stock.production.lot', 'Lot',help="The serial/lot of the returned product"),
            'company_id': fields.many2one('res.company', 'Company'),
    'product_id':fields.many2one('product.product', 'Product',help="Returned product"),
            'product_uom_qty': fields.float('Quantity (UoM)', digits_compute= dp.get_precision('Product UoS')),
            'product_uom': fields.many2one('product.uom', 'Unit of Measure '),
            'pricelist_id': fields.many2one('product.pricelist', 'Pricelist',help="Pricelist for current sales order."),
            'unit_sale_price' :fields.float('Unit Price', digits_compute= dp.get_precision('Sale Price'),help="Unit sale price of the product."),

            'subtotal':fields.function(_line_total_amount, string='Subtotal', type="float",digits_compute= dp.get_precision('Account'), store=True),

            'return_location' : fields.many2one('stock.location', 'Dest. Location',help="Location where the system will stock the returned products.", select=True),
            'invoice_line_id': fields.many2one('account.invoice.line', 'Invoice Line', help='The invoice line related to the returned product'),
            'number': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'mass.return'),

def cancel(self, cr, uid, ids, context=None):
    if context is None:
        context = {}
    data = context and context.get('active_ids', []) or []
    return self.pool.get('mass.return').mass_return_cancel(cr, uid, data, context)

def button_compute(self, cr, uid, ids, context=None, set_total=False):
    for line in self.browse(cr, uid, ids, context=context):
        if set_total:
            self.pool.get('mass.return').write(cr, uid, [line.id], {'subtotal': line.subtotal})
    return True
def button_confirm(self, cr, uid, ids, context=None):
    return self.write(cr, uid, ids, {'state': 'confirmed'})

##class make_picking(osv.osv): ##

_name= 'make.picking'


'return_location' : fields.many2one('stock.location', 'Source Location',help="Location where the returned products are sent.", required=True),

'return_ids' : fields.many2many('mass.return', 'return_picking', 'return_picking_id', 'Return lines'),


def action_make_picking(self,cr,uid,ids,context=None):
    print "context", context
    partner_id = 0
    for picking in self.browse(cr, uid,ids):
        return_id = self.pool.get('mass.return').browse(cr, uid, context['active_id'])
        partner_id = return_id.partner_id.id
        # location type
        location = -1
        if return_id.return_type == "customer":
            location = return_id.partner_id.property_stock_customer.id
            location = return_id.partner_id.property_stock_supplier.id
        # create picking
        picking_id = self.pool.get('stock.picking').create(cr, uid, {
                    'origin': return_id.id,
                    'type': 'in',
                    'move_type': 'one', # direct

                    'date': time.strftime('%Y-%m-%d %H:%M:%S'),
                    'address_id': return_id.partner_address_id.id,

                    'location_dest_id': picking.return_location.id,
                    'return_id': return_id.id,
        # Create picking lines
        for picking_line in picking.return_id:
            move_id = self.pool.get('stock.move').create(cr, uid, {
                    'name' : picking_line.product_id.name_template, # Motif : crm id ? stock_picking_id ?
                    'priority': '0',
                    'date': time.strftime('%Y-%m-%d %H:%M:%S'),
                    'product_id': picking_line.product_id.id,
                    'quantity': picking_line.product_uom_qty,
                    'product_uom': picking_line.product_id.uom_id.id,
                    'address_id': return_id.partner_address_id.id,
           # 'price_currency_id': return_id.company_id.currency_id.id, # from invoice ???

                    'location_dest_id': picking.return_location.id,

            return {
        'name': 'Customer Picking IN',
        'view_type': 'form',
        'view_mode': 'tree,form',
        'view_xml_id': 'mass_return_picking_in_form',
        'view_name' :'mass_return_picking_in_form',
        'domain' : "[('type', '=', 'in'),('partner_id','=',%s)]"%partner_id,
        'res_model': 'stock.picking',
        'type': 'ir.actions.act_window',

def button_return(self, cr, uid, ids, context=None):
    if context is None:
        context = {}
    data = context and context.get('active_ids', []) or []
    return self.pool.get('mass.return').action_make_picking(cr, uid, data, context)

def _get_dest_loc(self, cr, uid,context):
    return self.pool.get('stock.warehouse').read(cr, uid, [1],['lot_input_id'])[0]['lot_input_id'][0]  

_defaults = {

    'return_location' : _get_dest_loc,

# If "Cancel" button pressed
def action_cancel(self,cr,uid,ids,conect=None):
    return {'type': 'ir.actions.act_window_close',}



<openerp> <data> <record model="ir.ui.view" id="mass_return_tree"> <field name="name">Mass Return Tree</field> <field name="model">mass.return</field> <field name="type">tree</field> <field name="arch" type="xml"> <tree string="Returned lines"> <field name="name"/> <field name="partner_id"/> <field name="return_date"/> </tree> </field> </record> <record model="ir.ui.view" id="mass_return_form_view"> <field name="name">Mass Return Form</field> <field name="model">mass.return</field> <field name="type">form</field> <field name="arch" type="xml"> <form string="Mass Returns"> <field name="name"/> <field name="return_date"/> <field name="origin"/> <field name="number"/> <group name="Partner" colspan="4" col="3"> <separator name="Partner" colspan="4"/> <field name="partner_id" on_change="onchange_partner_id(partner_id)"/> <field name="partner_address"/> <field name="partner_phone"/> </group> <group name="Return Product" colspan="4" col="4"> <separator name="Return Product" colspan="8"/> <field name="product_id" on_change="product_id_change(product_id,product_uom_qty,parent.partner_id,unit_sale_price,context)"/> <field name="product_uom_qty"/> <field name="product_uom"/> <field name="unit_sale_price"/> <field name="subtotal"/> <field name="return_location"/>

                <group col="4" colspan="4">
                <separator colspan="4"/>
                <button name="button_compute" string="Compute" icon="gtk-execute" type="object"/>
                <button name="case_cancel" string="Cancel" special="cancel" type="object" icon="gtk-cancel" />
                <button name="button_return" string="Return"  type="object" icon="gtk-ok" />
                <button name="refund" string="Refund"  type="object" icon="gtk-ok" />
    <!-- <record model="ir.ui.view" id="make_picking_form_view">
        <field name="name">Mass Return Picking Form</field>
        <field name="model">make.picking</field>
        <field name="type">form</field>
        <field name="arch" type="xml">
            <form string="Picking"> 
                <field name="return_location"/>
                <button name="action_make_picking" string="OK" type="object" icon="gtk_ok"/>
                <button name="action_cancel" string="Cancel" type="object" icon="gtk_cancel"/>
    <record model="ir.actions.act_window" id="action_make_picking_form">
        <field name="name">Make Picking</field>
        <field name="res_model">make.picking</field>
    </record> -->

    <record model="ir.actions.act_window" id="action_mass_return_form">
        <field name="name">Mass Returns</field>
        <field name="res_model">mass.return</field>
    <record id="action_return_cancel" model="ir.actions.act_window">
        <field name="name">Cancel Return</field>
        <field name="res_model">mass.return</field>
        <field name="view_type">form</field>
        <field name="view_mode">form</field>
        <field name="target">new</field>
    <menuitem name="Mass Return" id="menu_mass_return" parent="base.menu_aftersale" sequence="3" action="action_mass_return_form" />





| 2 1 4
Buenos Aires, Argentina

Python developer, big fan of sailing

On 4/15/13, 12:04 PM

In case you need to know whether your function is called or not, add these two lines to your function definition:

import pdb;pdb.set_trace()

Then restart your server in debug mode. If the debug prompt is not shown in your console, OpenERP is not calling your function

interesting way. Didn't know that one for debugging.

on 4/15/13, 5:09 PM


| 5 4 7
Baarn, Netherlands
On 4/15/13, 11:24 AM


  • I might not understand your question, but still try to help you.

  • Maybe I am saying things you already know, but just to be sure.

In order for openERP to know the changed code, you have to add your code to the addon-directory.

Afterwards, restart openERP (or the whole machine)

Next you login and update the module list (needed if you add the code for the first time): Settings -> Update Module List

Now you can install or upgrade the module (Settings -> Installed modules. Remove 'installed' if you want to add a new module).

If your issue is to know whether or not your module is doing something, you might want to add some logging to it.

First you have to import logging (import logging), than you can start placing the following code in your modules:

logging.warning('##MODULE_NAME.METHOD: your code, maybe some variables %s' %(variable))

I use MODULE_NAME.METHOD so I know where to look in case I forget where I have added logging....

Place the module in the addons directory (see above).

In the logging file you can now look for your code special code (in this case two times a #).

If you can't find any ## in your logging file (on Ubuntu 12.04: /var/log/openerp/openerp-server.log), than you know your method(s) are not called.

hey i already know these things, i am actually looking for as simple as possible a function that can help me update stock values submitted by a user from some form.

on 4/16/13, 2:30 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 platform 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.


Odoo Training Center

Access to our E-learning platform and experience all Odoo Apps through learning videos, exercises and Quizz.

Test it now

Question tools

0 follower(s)


Asked: 4/15/13, 10:40 AM
Seen: 2909 times
Last updated: 3/16/15, 8:10 AM