[MERGE] inventory branch
bzr revid: qdp-launchpad@openerp.com-20130912065241-m5njpaii7r8xd5iu
This commit is contained in:
@@ -69,7 +69,6 @@ Dashboard / Reports for Warehouse Management will include:
|
||||
'stock_data.xml',
|
||||
'wizard/stock_move_view.xml',
|
||||
'wizard/stock_change_product_qty_view.xml',
|
||||
'wizard/stock_fill_inventory_view.xml',
|
||||
'wizard/stock_inventory_merge_view.xml',
|
||||
'wizard/stock_location_product_view.xml',
|
||||
'wizard/stock_inventory_line_split_view.xml',
|
||||
|
||||
+19
-14
@@ -1774,18 +1774,18 @@ class stock_inventory(osv.osv):
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Inventory Reference', size=64, required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'date': fields.datetime('Creation Date', required=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'date_done': fields.datetime('Date done'),
|
||||
'line_ids': fields.one2many('stock.inventory.line', 'inventory_id', 'Inventories', readonly=False, states={'done': [('readonly', True)]}),
|
||||
'move_ids': fields.one2many('stock.move', 'inventory_id', 'Created Moves'),
|
||||
'state': fields.selection([('draft', 'Draft'), ('cancel', 'Cancelled'), ('confirm', 'Confirmed'), ('done', 'Done')], 'Status', readonly=True, select=True),
|
||||
'name': fields.char('Inventory Reference', size=64, required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Inventory Name."),
|
||||
'date': fields.datetime('Creation Date', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Inventory Create Date."),
|
||||
'date_done': fields.datetime('Date done', help="Inventory Validation Date."),
|
||||
'line_ids': fields.one2many('stock.inventory.line', 'inventory_id', 'Inventories', readonly=False, states={'done': [('readonly', True)]}, help="Inventory Lines."),
|
||||
'move_ids': fields.one2many('stock.move', 'inventory_id', 'Created Moves', help="Inventory Moves."),
|
||||
'state': fields.selection([('draft', 'Draft'), ('cancel', 'Cancelled'), ('confirm', 'In Progress'), ('done', 'Validated')], 'Status', readonly=True, select=True),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True, select=True, readonly=True, states={'draft': [('readonly', False)]}),
|
||||
'location_id': fields.many2one('stock.location', 'Location', required=True),
|
||||
'product_id': fields.many2one('product.product', 'Product'),
|
||||
'package_id': fields.many2one('stock.quant.package', 'Pack'),
|
||||
'partner_id': fields.many2one('res.partner', 'Owner'),
|
||||
'lot_id': fields.many2one('stock.production.lot', 'Lot/Serial Number'),
|
||||
'product_id': fields.many2one('product.product', 'Product', readonly=True, states={'draft': [('readonly', False)]}, help="Specify Product to focus your inventory on a particular Product."),
|
||||
'package_id': fields.many2one('stock.quant.package', 'Pack', readonly=True, states={'draft': [('readonly', False)]}, help="Specify Pack to focus your inventory on a particular Pack."),
|
||||
'partner_id': fields.many2one('res.partner', 'Owner', readonly=True, states={'draft': [('readonly', False)]}, help="Specify Owner to focus your inventory on a particular Owner."),
|
||||
'lot_id': fields.many2one('stock.production.lot', 'Lot/Serial Number', readonly=True, states={'draft': [('readonly', False)]}, help="Specify Lot/Serial Number to focus your inventory on a particular Lot/Serial Number."),
|
||||
'move_ids_exist': fields.function(_get_move_ids_exist, type='boolean', string=' Stock Move Exists?', help='technical field for attrs in view'),
|
||||
}
|
||||
|
||||
@@ -1803,6 +1803,12 @@ class stock_inventory(osv.osv):
|
||||
'location_id': _default_stock_location,
|
||||
}
|
||||
|
||||
def set_checked_qty(self , cr ,uid ,ids ,context=None):
|
||||
inventory = self.browse(cr, uid, ids[0], context=context)
|
||||
line_ids = [line.id for line in inventory.line_ids]
|
||||
self.pool.get('stock.inventory.line').write(cr, uid, line_ids, {'product_qty': 0})
|
||||
return True
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
@@ -1891,7 +1897,7 @@ class stock_inventory(osv.osv):
|
||||
#TODO test
|
||||
self.action_cancel_draft(cr, uid, ids, context=context)
|
||||
|
||||
def _prepare_inventory(self, cr, uid, ids, full_of_zeros=False, context=None):
|
||||
def prepare_inventory(self, cr, uid, ids, context=None):
|
||||
inventory_line_obj = self.pool.get('stock.inventory.line')
|
||||
for inventory in self.browse(cr, uid, ids, context=context):
|
||||
#clean the existing inventory lines before redoing an inventory proposal
|
||||
@@ -1900,8 +1906,6 @@ class stock_inventory(osv.osv):
|
||||
#compute the inventory lines and create them
|
||||
vals = self._get_inventory_lines(cr, uid, inventory, context=context)
|
||||
for product_line in vals:
|
||||
if full_of_zeros:
|
||||
product_line['product_qty'] = 0
|
||||
inventory_line_obj.create(cr, uid, product_line, context=context)
|
||||
return self.write(cr, uid, ids, {'state': 'confirm'})
|
||||
|
||||
@@ -1912,7 +1916,7 @@ class stock_inventory(osv.osv):
|
||||
domain = ' location_id in %s'
|
||||
args = (tuple(location_ids),)
|
||||
if inventory.partner_id:
|
||||
domain += ' and partner_id = %s'
|
||||
domain += ' and owner_id = %s'
|
||||
args += (inventory.partner_id.id,)
|
||||
if inventory.lot_id:
|
||||
domain += ' and lot_id = %s'
|
||||
@@ -1950,6 +1954,7 @@ class stock_inventory_line(osv.osv):
|
||||
'company_id': fields.related('inventory_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, select=True, readonly=True),
|
||||
'prod_lot_id': fields.many2one('stock.production.lot', 'Serial Number', domain="[('product_id','=',product_id)]"),
|
||||
'state': fields.related('inventory_id', 'state', type='char', string='Status', readonly=True),
|
||||
'real_qty':fields.related('product_id','qty_available', type='float', string='Real Quantity'),
|
||||
'partner_id': fields.many2one('res.partner', 'Owner'),
|
||||
}
|
||||
|
||||
|
||||
+28
-38
@@ -101,16 +101,13 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Physical Inventory" version="7.0">
|
||||
<header>
|
||||
<button name="%(action_view_stock_fill_inventory)d" states="draft" string="Fill Inventory" type="action" class="oe_highlight" groups="stock.group_stock_user"/>
|
||||
<button name="prepare_inventory" states="draft" string="Start Inventory" type="object" class="oe_highlight" groups="stock.group_stock_user"/>
|
||||
<button name="action_done" states="confirm" string="Validate Inventory" type="object" class="oe_highlight" groups="stock.group_stock_manager"/>
|
||||
<button name="action_cancel_draft" states="cancel" string="Set to Draft" type="object"/>
|
||||
<button name="action_cancel_inventory" states="draft,confirm,done" string="Cancel Inventory" type="object"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm"/>
|
||||
<button name="action_cancel_inventory" states="confirm,done" string="Cancel Inventory" type="object"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,done"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_right oe_button_box">
|
||||
<button name="action_check" string="Check Inventory Adjustments" states="draft,confirm" type="object" />
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<label for="name" class="oe_edit_only"/>
|
||||
<h1><field name="name" placeholder="e.g. Annual inventory"/></h1>
|
||||
@@ -118,47 +115,40 @@
|
||||
<group>
|
||||
<group>
|
||||
<field name="location_id"/>
|
||||
<field name="product_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
</group>
|
||||
<div class="oe_grey" colspan="4">Specify filters to focus your inventory a on particular product, lot, pack and product's owner.</div>
|
||||
<group>
|
||||
<field name="product_id" domain="[('type','=','product')]"/>
|
||||
<field name="lot_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company" widget="selection"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="date"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="package_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="move_ids_exist" invisible="1"/>
|
||||
<notebook>
|
||||
<page string="Inventory Details">
|
||||
<field name="line_ids" string="Inventory Details">
|
||||
<tree string="Inventory Details" editable="bottom">
|
||||
<field context="{'location':location_id, 'uom':product_uom_id, 'to_date':parent.date}" name="product_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,parent.date)" domain="[('type','=','product')]"/>
|
||||
<field name="product_qty"/>
|
||||
<field name="product_uom_id" groups="product.group_uom"/>
|
||||
<field name="prod_lot_id"/>
|
||||
<field name="package_id" readonly="1"/>
|
||||
<field name="partner_id"/>
|
||||
<field domain="[('usage','=','internal')]" name="location_id" groups="stock.group_locations"/>
|
||||
<field name="state" invisible="True"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Inventory Adjustments" attrs="{'invisible': [('move_ids_exist', '=', False)]}">
|
||||
<field name="move_ids" context="{'inventory_id':active_id}" readonly="1">
|
||||
<tree string="Inventory Adjustments">
|
||||
<field name="product_id"/>
|
||||
<field name="lot_ids"/>
|
||||
<field name="product_uom_qty" on_change="onchange_quantity(product_id, product_uom_qty, product_uom, product_uos)"/>
|
||||
<field name="product_uom" string="Unit of Measure" groups="product.group_uom"/>
|
||||
<field name="location_id"/>
|
||||
<field name="location_dest_id"/>
|
||||
<field name="state" invisible="True"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<notebook attrs="{'invisible':[('state','=','draft')]}">
|
||||
<page string="Inventory Details" >
|
||||
<button name="set_checked_qty" states="confirm" string="⇒ Set Checked Quantity to 0" type="object" class="oe_link oe_right" groups="stock.group_stock_user"/>
|
||||
<field name="line_ids" string="Inventory Details" context="{'default_location_id': location_id, 'default_product_id': product_id, 'default_prod_lot_id': lot_id, 'default_package_id': package_id, 'default_partner_id': partner_id}">
|
||||
<tree string="Inventory Details" editable="bottom" colors="blue: product_qty != real_qty">
|
||||
<field context="{'location':location_id, 'uom':product_uom_id, 'to_date':parent.date}" name="product_id" on_change="on_change_product_id(location_id,product_id,product_uom_id,parent.date)" domain="[('type','=','product')]"/>
|
||||
<field name="real_qty" readonly="1"/>
|
||||
<field name="product_qty" string="Checked Quantity"/>
|
||||
<field name="product_uom_id" groups="product.group_uom"/>
|
||||
<field name="prod_lot_id"/>
|
||||
<field name="package_id"/>
|
||||
<field name="partner_id"/>
|
||||
<field domain="[('usage','=','internal')]" name="location_id" groups="stock.group_locations"/>
|
||||
<field name="state" invisible="True"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,31 +1,20 @@
|
||||
-
|
||||
In order to test the inventory, I create a new product
|
||||
-
|
||||
!record {model: product.product, id: inventory_product}:
|
||||
name: inventory prod
|
||||
type: product
|
||||
!record {model: product.product, id: inventory_product}:
|
||||
name: inventory prod
|
||||
type: product
|
||||
-
|
||||
I create an inventory for this product only
|
||||
-
|
||||
!record {model: stock.inventory, id: inventory_test0}:
|
||||
name: Test
|
||||
product_id: inventory_product
|
||||
|
||||
-
|
||||
I create the wizard to confirm the inventory
|
||||
-
|
||||
!record {model: stock.fill.inventory, id: inventory_test0_wizard}:
|
||||
set_stock_zero: False
|
||||
-
|
||||
I fill this inventory
|
||||
-
|
||||
!python {model: stock.inventory.line}: |
|
||||
context = {'active_ids': [ref('inventory_test0')]}
|
||||
self.pool.get('stock.fill.inventory').fill_inventory(cr, uid, [ref('inventory_test0_wizard')], context=context)
|
||||
-
|
||||
I check that my inventory has no line, as the product is a new one.
|
||||
I confirm the inventory and check that my inventory has no line, as the product is a new one.
|
||||
-
|
||||
!python {model: stock.inventory}: |
|
||||
self.prepare_inventory(cr, uid, [ref('inventory_test0')], context=context)
|
||||
inv = self.browse(cr, uid, ref('inventory_test0'), context=context)
|
||||
assert len(inv.line_ids) == 0, "Wrong number of inventory lines."
|
||||
-
|
||||
@@ -37,7 +26,7 @@
|
||||
product_qty: 10
|
||||
location_id: stock.stock_location_14
|
||||
-
|
||||
I confirm this inventory
|
||||
I Validate this inventory
|
||||
-
|
||||
!python {model: stock.inventory}: |
|
||||
self.action_done(cr, uid, [ref('inventory_test0')], context=context)
|
||||
@@ -72,15 +61,10 @@
|
||||
name: second test inventory
|
||||
product_id: inventory_product
|
||||
-
|
||||
I fill this new inventory
|
||||
-
|
||||
!python {model: stock.inventory}: |
|
||||
context = {'active_ids': [ref('inventory_test1')]}
|
||||
self.pool.get('stock.fill.inventory').fill_inventory(cr, uid, [ref('inventory_test0_wizard')], context=context)
|
||||
-
|
||||
I check that my inventory has one line, with a quantity of 10.
|
||||
I confirm the inventory and check that my inventory has one line, with a quantity of 10.
|
||||
-
|
||||
!python {model: stock.inventory}: |
|
||||
self.prepare_inventory(cr, uid, [ref('inventory_test1')], context=context)
|
||||
inv = self.browse(cr, uid, ref('inventory_test1'), context=context)
|
||||
assert inv.line_ids and len(inv.line_ids) == 1, "Wrong number of inventory lines."
|
||||
assert inv.line_ids[0].product_qty == 10, "Wrong quantity in inventory line."
|
||||
@@ -92,12 +76,12 @@
|
||||
inv = self.browse(cr, uid, ref('inventory_test1'), context=context)
|
||||
self.pool.get('stock.inventory.line').write(cr, uid, inv.line_ids[0].id, {'product_qty': 20})
|
||||
-
|
||||
I confirm this inventory
|
||||
I Validate this inventory
|
||||
-
|
||||
!python {model: stock.inventory}: |
|
||||
self.action_done(cr, uid, [ref('inventory_test1')], context=context)
|
||||
-
|
||||
I check that the quantity on hand is 20 on the location and its parent.
|
||||
I check that the quantity on hand is 20 on the location and it's parent.
|
||||
-
|
||||
!python {model: product.product}: |
|
||||
context['location'] = ref('stock.stock_location_14')
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
|
||||
import stock_move
|
||||
import stock_inventory_merge
|
||||
import stock_fill_inventory
|
||||
import stock_inventory_line_split
|
||||
import stock_location_product
|
||||
import stock_return_picking
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import fields, osv
|
||||
|
||||
class stock_fill_inventory(osv.osv_memory):
|
||||
_name = "stock.fill.inventory"
|
||||
_description = "Import Inventory"
|
||||
|
||||
_columns = {
|
||||
'set_stock_zero': fields.boolean("Set to zero", help="If checked, all product quantities will be set to zero to help ensure a real physical inventory is done"),
|
||||
}
|
||||
|
||||
def fill_inventory(self, cr, uid, ids, context=None):
|
||||
""" To Import stock inventory according to products available in the selected locations.
|
||||
@param self: The object pointer.
|
||||
@param cr: A database cursor
|
||||
@param uid: ID of the user currently logged in
|
||||
@param ids: the ID or list of IDs if we want more than one
|
||||
@param context: A standard dictionary
|
||||
@return:
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
inventory_obj = self.pool.get('stock.inventory')
|
||||
if ids and len(ids):
|
||||
ids = ids[0]
|
||||
fill_inventory = self.browse(cr, uid, ids, context=context)
|
||||
inventory_obj._prepare_inventory(cr, uid, context.get('active_ids', []), fill_inventory.set_stock_zero, context=context)
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_stock_fill_inventory" model="ir.ui.view">
|
||||
<field name="name">Import Inventory</field>
|
||||
<field name="model">stock.fill.inventory</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Import Inventory" version="7.0">
|
||||
<separator string="Import the current inventory"/>
|
||||
<group>
|
||||
<field name="set_stock_zero"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="fill_inventory" string="Fill Inventory" type="object" class="oe_highlight"/>
|
||||
or
|
||||
<button string="Cancel" class="oe_link" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_view_stock_fill_inventory" model="ir.actions.act_window">
|
||||
<field name="name">Fill Inventory</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">stock.fill.inventory</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_stock_fill_inventory"/>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
Reference in New Issue
Block a user