سؤال

I'm writing a warehouse management module and I came to the inventory step.

enter image description here

I need to make an inventory every now and then for each warehouse separately and each inventory operation will be kept in the database as a master-detail relation, ie:

  • one record for the basic data such as id, date, warehouse_id etc. and this will be recorded in a table created by (inventory) object.

  • many records will keep the details of the operation (one record for each material) recording the material id, inventory id, balance, etc. and this will be recorded in the table (inventory_lines).

During the data entry, when the user selects a material, I need to check its current balance and display it in the balance field. In order to do this, I'll need to know the warehouse id because every warehouse shall have separate inventories.


I have many materials stored in many warehouses. For example: I can have a quantity of 5 pens in warehouse A and 10 pens in warehouse B and 6 pens in warehouse C.

First, I select the warehouse (A or B or C) --- let's say warehouse B

Then I select the material (Pen or notebook or whatever) --- let's say Pen

Now, I want to search the database to find the balance of (Pen) in (Warehouse B)

I can write something like this:

select balance from inventory_lines where material_id=mmmmmm and warehouse_id=wwwwww

So, I need to get the material id (mmmmm) and the warehouse id (wwwww)

And that will be done with each material I choose.

The warehouse id is in the column: inventory_id in the object: inventory 'warehouse_id' : fields.many2one('makhazen.warehouse', 'Warehouse Name',required=True),

The material id is in the column: material_id of the object inventory_line as in the picture in the question 'material_id' : fields.many2one('makhazen.material' ,'Material Name'),


I faced the following problem:

  • I could use the (on_change) method in the form view on the material_id field and could trigger a method to search for the balance in the database but I needed the warehouse_id which I couldn't get.

The questions are: - How are this master-detail relationship is handled in openerp? how values are passed between the master table and the details table? - How can we extend the scope of the warehouse_id so that it can be seen from any method in the module? - I could change the values of the fields by calling a method and returning the desired values in a dictionary, but how to do the opposite (read them)?

It's very critical matter to me.

هل كانت مفيدة؟

المحلول

Firstly, you don't need the warehouse_id field in the wh_inventory_line class. You can always access it trough the the parent object:

inventory_line = self.pool.get('wh.inventory.line').browse(cr, uid, line_id)
wharehouse_id = inventory_line.inventory_id.warehouse_id.id

Secondly, in your case you can just pass the warehouse_id value as parameter to your onchange method. Something like this:

<field name="material_id" 
    on_change="onchange_material_id(material_id, warehouse_id)"/>

or, if you follow my first advice and remove the warehouse_id from wh_inventory_line:

<field name="material_id" 
    on_change="onchange_material_id(material_id, parent.warehouse_id)"/>

EDIT

After testing on OpenERP 6.0 I found some errors in your code. I'm just wondering how did you manage to run it.

First, you missed a quote (\') on the warehouse_id column definition of your wh.inventory model:

_columns = {
    'date': fields.datetime('Date'),
    'warehouse_id': fields.many2one('wh.warehouse', 'Warehouse Name, required=True),

Second, the fields.char() field definition takes at least size parameter additionally to the supplied Field Name. Again, you missed a quote on the following line:

         'notes': fields.char('Notes),

Not an error but something you should consider too - you tagged your question with the openerp-7 tag. In OpenERP v7 inheriting from osv.osv is deprecated. Inherit from osv.Model instead.

If I insist on your errors it's because the solution I proposed to you is working fine on my side. So there must be some little error somewhere that prevents your code for doing what is expected.

Here is my test code. You can try it:

wh.py

# -*- encoding: utf-8 -*-

import netsvc
import pooler
from osv import fields, osv


class wh_warehouse(osv.osv):
    _name = 'wh.warehouse'

    _columns = {
        'name': fields.char('Name', 128),
        }

wh_warehouse()

class wh_material(osv.osv):
    _name = 'wh.material'

    _columns = {
        'name': fields.char('Name', 128),
        }

wh_material()


class wh_inventory(osv.osv):
    _name = 'wh.inventory'

    _columns = {
        'date': fields.datetime('Date'),
        'warehouse_id': fields.many2one('wh.warehouse', 'Warehouse Name', required=True),
        'inventory_line_ids': fields.one2many('wh.inventory.line', 'inventory_id', 'Inventory'),
        'notes': fields.char('Notes', 512),
        'balance_track': fields.boolean('Balance Track'),
        }

wh_inventory()


class wh_inventory_line(osv.osv):
    _name = 'wh.inventory.line'

    _columns = {
        'inventory_id': fields.many2one('wh.inventory', 'Inventory'),
        'material_id': fields.many2one('wh.material', 'Material'),
        'balance': fields.float('Balance'),
        'previous_balance': fields.float('Previous Balance'),
        'notes': fields.char('Notes', 512),
        }

    def onchange_material_id(self, cr, uid, ids, material_id, warehouse_id):
        return = {'value': {
            'notes': 'Selected material {0} and warehouse {1}'.format(material_id, warehouse_id), }
            }

wh_inventory_line()

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

wh_view.xml

<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data>
        <record id="view_wh_inventory_form" model="ir.ui.view">
            <field name="name">wh.inventory.form</field>
            <field name="model">wh.inventory</field>
            <field name="type">form</field>
            <field name="arch" type="xml">
                <form string="Warehouse Inventory">
                    <field name="date"/>
                    <field name="warehouse_id" widget="selection"/>
                    <field name="notes"/>
                    <field name="balance_track"/>
                    <field colspan="4" name="inventory_line_ids" widget="one2many_list">
                        <tree string="Details" editable="bottom">
                                <field name="material_id" widget="selection" 
                                       on_change="onchange_material_id(material_id, parent.warehouse_id)"/>
                            <field name="balance"/>
                            <field name="previous_balance"/>
                            <field name="notes"/>
                        </tree>
                    </field>
                </form>
            </field>
        </record>

        <record id="view_wh_inventory_tree" model="ir.ui.view">
            <field name="name">wh.inventory.tree</field>
            <field name="model">wh.inventory</field>
            <field name="type">tree</field>
            <field name="arch" type="xml">
                <tree string="Warehouse Inventory">
                    <field name="date"/>
                    <field name="warehouse_id" widget="selection"/>
                    <field name="notes"/>
                    <field name="balance_track"/>
                </tree>
            </field>
        </record>

        <record id="action_wh_inventory_form" model="ir.actions.act_window">
            <field name="name">Warehouse Inventory</field>
            <field name="res_model">wh.inventory</field>
            <field name="view_type">form</field>
            <field name="view_mode">tree,form</field>
            <field name="view_id" ref="view_wh_inventory_tree"/>
        </record>

        <menuitem
            action="action_wh_inventory_form"
            id="menu_wh_inventory_form" 
            parent="account.menu_finance" 
            />

        <!-- Sample data -->

        <record id="warehouse_1" model="wh.warehouse">
            <field name="name">Warehouse 1</field>
        </record>
        <record id="warehouse_2" model="wh.warehouse">
            <field name="name">Warehouse 2</field>
        </record>
        <record id="warehouse_3" model="wh.warehouse">
            <field name="name">Warehouse 3</field>
        </record>
        <record id="material_1" model="wh.material">
            <field name="name">Material 1</field>
        </record>
        <record id="material_2" model="wh.material">
            <field name="name">Material 2</field>
        </record>
        <record id="material_3" model="wh.material">
            <field name="name">Material 3</field>
        </record>

    </data>
</openerp>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top