Stock. initial commit
This commit is contained in:
+31
@@ -0,0 +1,31 @@
|
||||
# Copyright (c) 2004-2006 Tiny SPRL. (http://tiny.be)
|
||||
# Copyright (c) 2007 Bertrand Chenal
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contact a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from warehouse import *
|
||||
from location import *
|
||||
from lot import *
|
||||
from packing import *
|
||||
from move import *
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
'name': 'Stock Management',
|
||||
'version': '0.1',
|
||||
'author': 'B2CK',
|
||||
'email': 'info@b2ck.com',
|
||||
'website': 'http://www.tryton.org/',
|
||||
'category': 'Generic Modules',
|
||||
'description': 'Stock Management and Inventory Control',
|
||||
'depends': [
|
||||
'partner', 'product'
|
||||
],
|
||||
'xml': [
|
||||
'warehouse.xml',
|
||||
'location.xml',
|
||||
'move.xml',
|
||||
'lot.xml',
|
||||
'packing.xml',
|
||||
],
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
"Wharehouse"
|
||||
from trytond.osv import fields, OSV
|
||||
|
||||
STATES = {
|
||||
'readonly': "active == False",
|
||||
}
|
||||
|
||||
class Location(OSV):
|
||||
"Stock Location"
|
||||
_name = 'stock.location'
|
||||
_order = 'name'
|
||||
_description = __doc__
|
||||
name = fields.Char("Name", size=64, required=True, states=STATES,)
|
||||
code = fields.Char("Code", size=32, states=STATES, select=True,)
|
||||
active = fields.Boolean('Active', select=True)
|
||||
usage = fields.Selection([('supplier','Supplier'),
|
||||
('customer','Customer'),
|
||||
('inventory','Inventory'),
|
||||
('procurement','Procurement'),
|
||||
('production','Production')],
|
||||
'Location type', states=STATES,)
|
||||
warehouse = fields.Many2One("stock.warehouse", "Warehouse", select="1")
|
||||
|
||||
def default_active(self, cursor, user, context=None):
|
||||
return True
|
||||
|
||||
def name_search(self, cursor, user, name, args=None, operator='ilike',
|
||||
context=None, limit=80):
|
||||
if not args:
|
||||
args=[]
|
||||
ids = self.search(cursor, user, [('code','=',name)]+ args, limit=limit,
|
||||
context=context)
|
||||
if not ids:
|
||||
ids = self.search(cursor, user, [('name',operator,name)]+ args,
|
||||
limit=limit, context=context)
|
||||
result = self.name_get(cursor, user, ids, context)
|
||||
return result
|
||||
|
||||
Location()
|
||||
|
||||
|
||||
class Warehouse(OSV):
|
||||
_name = "stock.warehouse"
|
||||
_inherit = "stock.warehouse"
|
||||
input_location = fields.Many2One("stock.location", "Input location")
|
||||
output_location = fields.Many2One("stock.location", "output location")
|
||||
|
||||
Warehouse()
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="location_view_form">
|
||||
<field name="model">stock.location</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Location">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="usage"/>
|
||||
<field name="usage"/>
|
||||
<label name="active"/>
|
||||
<field name="active"/>
|
||||
<newline/>
|
||||
<label name="input_zone"/>
|
||||
<field name="input_zone"/>
|
||||
<label name="output_zone"/>
|
||||
<field name="output_zone"/>
|
||||
<label name="warehouse"/>
|
||||
<field name="warehouse"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="location_view_tree">
|
||||
<field name="model">stock.location</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="locations">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="2"/>
|
||||
<field name="usage" select="1"/>
|
||||
<field name="input_zone" select="2"/>
|
||||
<field name="output_zone" select="2"/>
|
||||
<field name="warehouse" select="2"/>
|
||||
<field name="active" select="2"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_location_form">
|
||||
<field name="name">Locations</field>
|
||||
<field name="res_model">stock.location</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_location_form_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="location_view_tree"/>
|
||||
<field name="act_window" ref="act_location_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_location_form_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view" ref="location_view_form"/>
|
||||
<field name="act_window" ref="act_location_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_stock" sequence="2"
|
||||
action="act_location_form" id="menu_location_form"/>
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
@@ -0,0 +1,24 @@
|
||||
"Wharehouse"
|
||||
from trytond.osv import fields, OSV
|
||||
import time
|
||||
|
||||
class Lot(OSV):
|
||||
"Stock Lot"
|
||||
_name = 'stock.lot'
|
||||
_order = 'id DESC'
|
||||
_description = __doc__
|
||||
_rec_name = 'code'
|
||||
|
||||
code = fields.Char("Code", size=64, select=1, readonly=1)
|
||||
creation_date = fields.DateTime("Created at")
|
||||
moves = fields.One2Many("stock.move", "lot", "Stock Moves")
|
||||
|
||||
|
||||
def default_creation_date(self, cursor, user, context):
|
||||
return time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
def create(self, cursor, user, values, context):
|
||||
values['code'] = self.pool.get('ir.sequence').get(cursor, user, 'stock.lot')
|
||||
return super(Lot,self).create(cursor, user, values, context)
|
||||
|
||||
Lot()
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="lot_view_form">
|
||||
<field name="model">stock.lot</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Lot">
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="creation_date"/>
|
||||
<field name="creation_date"/>
|
||||
<separator name="moves" colspan="4"/>
|
||||
<field name="moves" colspan="4"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="lot_view_tree">
|
||||
<field name="model">stock.lot</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Lots">
|
||||
<field name="code"/>
|
||||
<field name="creation_date"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_lot_form">
|
||||
<field name="name">Lots</field>
|
||||
<field name="res_model">stock.lot</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_lot_form_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="lot_view_tree"/>
|
||||
<field name="act_window" ref="act_lot_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_lot_form_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view" ref="lot_view_form"/>
|
||||
<field name="act_window" ref="act_lot_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_stock" sequence="5"
|
||||
action="act_lot_form" id="menu_lot_form"/>
|
||||
|
||||
|
||||
<record model="ir.sequence.type" id="sequence_type_lot">
|
||||
<field name="name">Lot</field>
|
||||
<field name="code">stock.lot</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.sequence" id="sequence_lot">
|
||||
<field name="name">Stock Lot</field>
|
||||
<field name="code">stock.lot</field>
|
||||
<field name="prefix">LOT: </field>
|
||||
<field name="padding">7</field>
|
||||
<field name="number_next">1</field>
|
||||
<field name="number_increment">1</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
@@ -0,0 +1,227 @@
|
||||
"Move"
|
||||
from trytond.osv import fields, OSV, ExceptORM
|
||||
from trytond.wizard import Wizard, WizardOSV
|
||||
import time
|
||||
|
||||
STATES = {
|
||||
'readonly': "(state in ('cancel','done'))",
|
||||
}
|
||||
|
||||
class Move(OSV):
|
||||
"Stock Move"
|
||||
_name = 'stock.move'
|
||||
_description = __doc__
|
||||
_order = "id DESC"
|
||||
_rec_name = "product"
|
||||
product = fields.Many2One("product.product", "Product", required=True, select=True, states=STATES, on_change=['product'])
|
||||
uom = fields.Many2One("product.uom", "Uom", required=True, states=STATES,)
|
||||
quantity = fields.Float("Quantity", digits=(12, 6), required=True, states=STATES,)
|
||||
from_location =fields.Many2One("stock.location", "From Location", select=True, required=True, states=STATES,)
|
||||
to_location = fields.Many2One("stock.location", "To Location", select=True, required=True, states=STATES,)
|
||||
lot = fields.Many2One("stock.lot", "Lot", states=STATES, select=True)
|
||||
packing = fields.Many2One("stock.packing", "Packing", states=STATES, select=True)
|
||||
planned_date = fields.Date("Planned Date", states=STATES,)
|
||||
effective_date = fields.Date("Effective Date", states=STATES, readonly=True)
|
||||
state = fields.Selection([('draft','Draft'),('done','Done'),('cancel','Cancel'),('waiting','Waiting')], 'State', select=True, readonly=True)
|
||||
|
||||
|
||||
def __init__(self):
|
||||
super(Move, self).__init__()
|
||||
self._rpc_allowed += [
|
||||
'set_state_done',
|
||||
'set_state_waiting',
|
||||
'set_state_draft',
|
||||
'set_state_cancel',
|
||||
]
|
||||
|
||||
def default_state(self, cursor, user, context=None):
|
||||
return 'draft'
|
||||
|
||||
def on_change_product(self, cursor, user, ids, value, context=None):
|
||||
if 'product' in value and value['product']:
|
||||
product = self.pool.get('product.product').browse(cursor, user, value['product'])
|
||||
return {'uom': product.default_uom.id}
|
||||
return {}
|
||||
|
||||
def set_by_state(self, cursor, user, ids, from_states, values, context=None):
|
||||
move_ids = self.search(
|
||||
cursor, user, [('id', 'in', ids),
|
||||
('state', 'in', from_states)])
|
||||
return self.write(cursor, user, move_ids, values, context=context)
|
||||
|
||||
def set_state_done(self, cursor, user, ids, context=None):
|
||||
self.set_by_state(
|
||||
cursor, user, ids, ['draft','waiting'],
|
||||
{'state':'done',
|
||||
'effective_date': time.strftime('%Y-%m-%d %H:%M:%S')})
|
||||
|
||||
def set_state_draft(self, cursor, user, ids, context=None):
|
||||
self.set_by_state(
|
||||
cursor, user, ids, ['cancel','waiting'],
|
||||
{'state':'draft',})
|
||||
|
||||
def set_state_cancel(self, cursor, user, ids, context=None):
|
||||
self.set_by_state(
|
||||
cursor, user, ids, ['done','waiting'],
|
||||
{'state':'cancel',})
|
||||
def set_state_waiting(self, cursor, user, ids, context=None):
|
||||
self.set_by_state(
|
||||
cursor, user, ids, ['draft',],
|
||||
{'state':'waiting',})
|
||||
|
||||
def unlink(self, cursor, user, ids, context=None):
|
||||
move_ids = self.search(
|
||||
cursor, user, [('id','in',ids),('state','in',['done','waiting','cancel'])],context)
|
||||
|
||||
if move_ids:
|
||||
raise ExceptORM('UserError', 'You can only delete draft moves !')
|
||||
|
||||
return super(Move, self).unlink(cursor, user, ids, context=context)
|
||||
Move()
|
||||
|
||||
|
||||
class CreatePackingWarn(WizardOSV):
|
||||
_name = 'stock.move.create_packing.warn'
|
||||
CreatePackingWarn()
|
||||
|
||||
class CreatePacking(Wizard):
|
||||
'Create Packing'
|
||||
_name = 'stock.move.create_packing'
|
||||
states = {
|
||||
'init': {
|
||||
'result': {
|
||||
'type': 'choice',
|
||||
'next_state': '_test_warn',
|
||||
},
|
||||
},
|
||||
'warning': {
|
||||
'result': {
|
||||
'type': 'form',
|
||||
'object': 'stock.move.create_packing.warn',
|
||||
'state': [
|
||||
('create', 'Ok', 'gtk-ok', True),
|
||||
],
|
||||
},
|
||||
},
|
||||
'create': {
|
||||
'result': {
|
||||
'type': 'action',
|
||||
'action': '_create',
|
||||
'state': 'end',
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
def _test_warn(self, cursor, user, data, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
moves_with_packing = move_obj.search(
|
||||
cursor, user, [('id','in',data['ids']),('packing','!=',None)],
|
||||
context=context)
|
||||
if moves_with_packing:
|
||||
data['ids'] = [ i for i in data['ids'] if i not in moves_with_packing ]
|
||||
return 'warning'
|
||||
else:
|
||||
return 'create'
|
||||
|
||||
def _create(self, cursor, user, data, context=None):
|
||||
packing_obj = self.pool.get('stock.packing.in')
|
||||
packing_obj.create(
|
||||
cursor, user, {'type': 'in', 'moves': [('set',data['ids'])]},
|
||||
context=context)
|
||||
|
||||
model_data_obj = self.pool.get('ir.model.data')
|
||||
act_window_obj = self.pool.get('ir.action.act_window')
|
||||
|
||||
model_data_ids = model_data_obj.search(cursor, user, [
|
||||
('fs_id', '=', 'act_packing_form'),
|
||||
('module', '=', 'stock'),
|
||||
], limit=1, context=context)
|
||||
model_data = model_data_obj.browse(cursor, user, model_data_ids[0],
|
||||
context=context)
|
||||
res = act_window_obj.read(cursor, user, model_data.db_id, context=context)
|
||||
|
||||
return res
|
||||
|
||||
CreatePacking()
|
||||
|
||||
class ProductByLocation(OSV):
|
||||
"Product by Location"
|
||||
_name = "stock.product_by_location"
|
||||
_description = __doc__
|
||||
_auto = False
|
||||
|
||||
location = fields.Many2One("stock.location","Location", readonly=True, select=True)
|
||||
product = fields.Many2One("product.product", "Product", readonly=True, select=True)
|
||||
quantity = fields.Float("Quantity", digits=(12, 6), readonly=True)
|
||||
uom = fields.Many2One("product.uom", "Uom", readonly=True,)
|
||||
|
||||
|
||||
def init(self, cursor, module):
|
||||
cursor.execute(
|
||||
"create or replace view stock_product_by_location as ( "\
|
||||
"select location, product, uom, sum(quantity) as quantity, "\
|
||||
"min(id) as id "\
|
||||
"from ( "\
|
||||
"SELECT to_location as location, product, uom, "\
|
||||
"sum(quantity) as quantity, min(id) as id "\
|
||||
"FROM stock_move "\
|
||||
"WHERE state = 'done'"\
|
||||
"GROUP by to_location, product ,uom "\
|
||||
"UNION "\
|
||||
"SELECT from_location as location, product, uom, "\
|
||||
"-sum(quantity) as quantity, min(-id) as id "\
|
||||
"FROM stock_move "\
|
||||
"WHERE state = 'done'"\
|
||||
"GROUP by from_location, product, uom "\
|
||||
") "\
|
||||
"as T group by T.location, T.product, T.uom)" )
|
||||
|
||||
ProductByLocation()
|
||||
|
||||
|
||||
class ProductByWarehouse(OSV):
|
||||
"Product by Warehouse"
|
||||
_name = "stock.product_by_warehouse"
|
||||
_description = __doc__
|
||||
_auto = False
|
||||
|
||||
warehouse = fields.Many2One("stock.warehouse","Warehouse", readonly=True, select=True)
|
||||
product = fields.Many2One("product.product", "Product", readonly=True, select=True)
|
||||
quantity = fields.Float("Quantity", digits=(12, 6), readonly=True)
|
||||
uom = fields.Many2One("product.uom", "Uom", readonly=True,)
|
||||
|
||||
|
||||
def init(self, cursor, module):
|
||||
cursor.execute(
|
||||
"create or replace view stock_product_by_warehouse as ( "\
|
||||
"select warehouse, product, uom, sum(quantity) as quantity, "\
|
||||
"min(id) as id "\
|
||||
"from ( "\
|
||||
"SELECT l_from.warehouse as warehouse, m.product, m.uom, "\
|
||||
"sum(m.quantity) as quantity, min(m.id) as id "\
|
||||
"FROM stock_move m "\
|
||||
"join stock_location l_from on (l_from.id=m.from_location) "\
|
||||
"join stock_location l_to on (l_to.id=m.to_location) "\
|
||||
"WHERE m.state = 'done' and ( "\
|
||||
"(l_to.warehouse != l_from.warehouse) or "\
|
||||
"(l_to.warehouse is null and l_from.warehouse is not null) or "\
|
||||
"(l_from.warehouse is null and l_to.warehouse is not null) "\
|
||||
") "\
|
||||
"GROUP by l_from.warehouse, m.product ,m.uom "\
|
||||
"UNION "\
|
||||
"SELECT l_to.warehouse as warehouse, m.product, m.uom, "\
|
||||
"-sum(m.quantity) as quantity, -min(m.id) as id "\
|
||||
"FROM stock_move m "\
|
||||
"join stock_location l_to on (l_to.id=m.to_location)"\
|
||||
"join stock_location l_from on (l_from.id=m.from_location) "\
|
||||
"WHERE m.state = 'done' and ( "\
|
||||
"(l_to.warehouse != l_from.warehouse) or "\
|
||||
"(l_to.warehouse is null and l_from.warehouse is not null) or "\
|
||||
"(l_from.warehouse is null and l_to.warehouse is not null) "\
|
||||
") "\
|
||||
"GROUP by l_to.warehouse, m.product, m.uom "\
|
||||
") "\
|
||||
"as T group by T.warehouse, T.product, T.uom)" )
|
||||
|
||||
ProductByWarehouse()
|
||||
@@ -0,0 +1,198 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="move_view_form">
|
||||
<field name="model">stock.move</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Move" col="6">
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
<label name="quantity"/>
|
||||
<field name="quantity"/>
|
||||
<label name="uom"/>
|
||||
<field name="uom"/>
|
||||
<label name="from_location"/>
|
||||
<field name="from_location"/>
|
||||
<label name="to_location"/>
|
||||
<field name="to_location"/>
|
||||
<label name="lot"/>
|
||||
<field name="lot"/>
|
||||
<label name="packing"/>
|
||||
<field name="packing"/>
|
||||
<label name="planned_date"/>
|
||||
<field name="planned_date"/>
|
||||
<label name="effective_date"/>
|
||||
<field name="effective_date"/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group col="4" colspan="4">
|
||||
<button string="Set Waiting" name="set_state_waiting" type="object"
|
||||
states="{'invisible': '''state in ('done','cancel','waiting',) '''}"/>
|
||||
<button string="set Done" name="set_state_done" type="object"
|
||||
states="{'invisible': '''state in ('cancel','done',) '''}"/>
|
||||
<button string="set Draft" name="set_state_draft" type="object"
|
||||
states="{'invisible': '''state in
|
||||
('waiting','done', 'draft') '''}"/>
|
||||
<button string="Cancel" name="set_state_cancel" type="object"
|
||||
states="{'invisible': '''state in
|
||||
('draft', 'cancel') '''}"/>
|
||||
</group>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="move_view_tree">
|
||||
<field name="model">stock.move</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="moves">
|
||||
<field name="product" select="1"/>
|
||||
<field name="from_location" select="1"/>
|
||||
<field name="to_location" select="1"/>
|
||||
<field name="quantity" select="2"/>
|
||||
<field name="uom" select="2"/>
|
||||
<field name="lot" select="2"/>
|
||||
<field name="packing" select="2"/>
|
||||
<field name="state" select="2"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_move_form">
|
||||
<field name="name">Moves</field>
|
||||
<field name="res_model">stock.move</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_move_form_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="move_view_tree"/>
|
||||
<field name="act_window" ref="act_move_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_move_form_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view" ref="move_view_form"/>
|
||||
<field name="act_window" ref="act_move_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_stock" sequence="3"
|
||||
action="act_move_form" id="menu_move_form"/>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="productbylocation_view_form">
|
||||
<field name="model">stock.product_by_location</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Product by location">
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="productbylocation_view_tree">
|
||||
<field name="model">stock.product_by_location</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Product by locations">
|
||||
<field name="location"/>
|
||||
<field name="product"/>
|
||||
<field name="quantity"/>
|
||||
<field name="uom"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_productbylocation_form">
|
||||
<field name="name">Products by Location</field>
|
||||
<field name="res_model">stock.product_by_location</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_productbylocation_form_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="productbylocation_view_tree"/>
|
||||
<field name="act_window" ref="act_productbylocation_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_productbylocation_form_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view" ref="productbylocation_view_form"/>
|
||||
<field name="act_window" ref="act_productbylocation_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_stock" sequence="2"
|
||||
action="act_productbylocation_form" id="menu_productbylocation_form"/>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="productbywarehouse_view_form">
|
||||
<field name="model">stock.product_by_warehouse</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Product by stock">
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="productbywarehouse_view_tree">
|
||||
<field name="model">stock.product_by_warehouse</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Product by warehouses">
|
||||
<field name="warehouse"/>
|
||||
<field name="product"/>
|
||||
<field name="quantity"/>
|
||||
<field name="uom"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_productbywarehouse_form">
|
||||
<field name="name">Products by Warehouse</field>
|
||||
<field name="res_model">stock.product_by_warehouse</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_productbywarehouse_form_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="productbywarehouse_view_tree"/>
|
||||
<field name="act_window" ref="act_productbywarehouse_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_productbywarehouse_form_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view" ref="productbywarehouse_view_form"/>
|
||||
<field name="act_window" ref="act_productbywarehouse_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_stock" sequence="2"
|
||||
action="act_productbywarehouse_form" id="menu_productbywarehouse_form"/>
|
||||
|
||||
<record model="ir.ui.view" id="packing_create_warn_view_form">
|
||||
<field name="model">stock.move.create_packing.warn</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Create packing" col="2">
|
||||
<image name="gtk-dialog-info"/>
|
||||
<label string="Moves already in a shipment will be ignored."/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.wizard" id="act_create_packing">
|
||||
<field name="name">Create Packing</field>
|
||||
<field name="wiz_name">stock.move.create_packing</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.keyword" id="act_create_packing_keyword">
|
||||
<field name="keyword">form_action</field>
|
||||
<field name="model">stock.move,0</field>
|
||||
<field name="action" ref="act_create_packing"/>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
"Packing"
|
||||
from trytond.osv import fields, OSV
|
||||
import time
|
||||
|
||||
STATES = {
|
||||
'readonly': "state in ('cancel', 'done')",
|
||||
}
|
||||
|
||||
|
||||
class Packing(OSV):
|
||||
"Packing"
|
||||
_name = 'stock.packing'
|
||||
_order = 'id DESC'
|
||||
_description = __doc__
|
||||
_rec_name = 'code'
|
||||
|
||||
effective_date =fields.DateTime('Effective Date', readonly=True)
|
||||
planned_date = fields.DateTime('Planned Date', readonly=True)
|
||||
moves = fields.One2Many('stock.move', 'packing', 'Move lines', states=STATES,)
|
||||
code = fields.Char("Code", size=None, select=1, readonly=True,)
|
||||
state = fields.Selection([('draft','Draft'),('done','Done'),('cancel','Cancel'),('waiting','Waiting')], 'State', readonly=True)
|
||||
|
||||
Packing()
|
||||
|
||||
class PackingIn(OSV):
|
||||
"Supplier Packing"
|
||||
_name = 'stock.packing.in'
|
||||
_order = 'id DESC'
|
||||
_description = __doc__
|
||||
_inherits = {'stock.packing':'packing'}
|
||||
|
||||
packing = fields.Many2One('stock.packing', 'Generic Packing', required=True, ondelete='cascade',)
|
||||
|
||||
def __init__(self):
|
||||
super(PackingIn, self).__init__()
|
||||
self._rpc_allowed += [
|
||||
'set_state_done',
|
||||
'set_state_waiting',
|
||||
'set_state_draft',
|
||||
'set_state_cancel',
|
||||
]
|
||||
|
||||
def default_creation_date(self, cursor, user, context=None):
|
||||
return time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
def default_state(self, cursor, user, context=None):
|
||||
return 'draft'
|
||||
|
||||
def set_state_done(self, cursor, user, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
packings = self.browse(cursor, user, ids, context=context)
|
||||
moves = reduce(lambda l, p: l+ [m.id for m in p.moves], packings, [])
|
||||
move_obj.set_state_done(cursor, user, moves, context)
|
||||
self.write(cursor, user, ids, {'state':'done'}, context=context)
|
||||
|
||||
def set_state_cancel(self, cursor, user, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
packings = self.browse(cursor, user, ids, context=context)
|
||||
moves = reduce(lambda l, p: l+ [m.id for m in p.moves], packings, [])
|
||||
move_obj.set_state_cancel(cursor, user, moves, context)
|
||||
self.write(cursor, user, ids, {'state':'cancel'}, context=context)
|
||||
|
||||
def set_state_waiting(self, cursor, user, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
packings = self.browse(cursor, user, ids, context=context)
|
||||
moves = reduce(lambda l, p: l+ [m.id for m in p.moves], packings, [])
|
||||
move_obj.set_state_waiting(cursor, user, moves, context)
|
||||
self.write(cursor, user, ids, {'state':'waiting'}, context=context)
|
||||
|
||||
def set_state_draft(self, cursor, user, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
packings = self.browse(cursor, user, ids, context=context)
|
||||
moves = reduce(lambda l, p: l+ [m.id for m in p.moves], packings, [])
|
||||
move_obj.set_state_draft(cursor, user, moves, context)
|
||||
self.write(cursor, user, ids, {'state':'draft'}, context=context)
|
||||
|
||||
def create(self, cursor, user, values, context):
|
||||
values['code'] = self.pool.get('ir.sequence').get(cursor, user, 'stock.packing.in')
|
||||
super(PackingIn, self).create(cursor, user, values, context=context)
|
||||
|
||||
PackingIn()
|
||||
|
||||
|
||||
class PackingOut(OSV):
|
||||
"Customer Packing"
|
||||
_name = 'stock.packing.out'
|
||||
_order = 'id DESC'
|
||||
_description = __doc__
|
||||
_inherits = {'stock.packing':'packing'}
|
||||
|
||||
packing = fields.Many2One('stock.packing', 'Generic Packing', required=True, ondelete='cascade')
|
||||
|
||||
def __init__(self):
|
||||
super(PackingOut, self).__init__()
|
||||
self._rpc_allowed += [
|
||||
'set_state_done',
|
||||
'set_state_waiting',
|
||||
'set_state_draft',
|
||||
'set_state_cancel',
|
||||
]
|
||||
|
||||
def default_creation_date(self, cursor, user, context=None):
|
||||
return time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
def default_state(self, cursor, user, context=None):
|
||||
return 'draft'
|
||||
|
||||
def set_state_done(self, cursor, user, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
packings = self.browse(cursor, user, ids, context=context)
|
||||
moves = reduce(lambda l, p: l+ [m.id for m in p.moves], packings, [])
|
||||
move_obj.set_state_done(cursor, user, moves, context)
|
||||
self.write(cursor, user, ids, {'state':'done'}, context=context)
|
||||
|
||||
def set_state_cancel(self, cursor, user, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
packings = self.browse(cursor, user, ids, context=context)
|
||||
moves = reduce(lambda l, p: l+ [m.id for m in p.moves], packings, [])
|
||||
move_obj.set_state_cancel(cursor, user, moves, context)
|
||||
self.write(cursor, user, ids, {'state':'cancel'}, context=context)
|
||||
|
||||
def set_state_waiting(self, cursor, user, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
packings = self.browse(cursor, user, ids, context=context)
|
||||
moves = reduce(lambda l, p: l+ [m.id for m in p.moves], packings, [])
|
||||
move_obj.set_state_waiting(cursor, user, moves, context)
|
||||
self.write(cursor, user, ids, {'state':'waiting'}, context=context)
|
||||
|
||||
def set_state_draft(self, cursor, user, ids, context=None):
|
||||
move_obj = self.pool.get('stock.move')
|
||||
packings = self.browse(cursor, user, ids, context=context)
|
||||
moves = reduce(lambda l, p: l+ [m.id for m in p.moves], packings, [])
|
||||
move_obj.set_state_draft(cursor, user, moves, context)
|
||||
self.write(cursor, user, ids, {'state':'draft'}, context=context)
|
||||
|
||||
def create(self, cursor, user, values, context):
|
||||
values['code'] = self.pool.get('ir.sequence').get(cursor, user, 'stock.packing.out')
|
||||
super(PackingOut, self).create(cursor, user, values, context=context)
|
||||
|
||||
PackingOut()
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
|
||||
<!--Packing in -->
|
||||
<record model="ir.ui.view" id="packing_in_view_form">
|
||||
<field name="model">stock.packing.in</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Supplier Packing" col="6">
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="effective_date"/>
|
||||
<field name="effective_date"/>
|
||||
<separator name="moves" colspan="6"/>
|
||||
<field name="moves" colspan="6"/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group col="4" colspan="4">
|
||||
<button string="Set Done" name="set_state_done" type="object"
|
||||
states="{'invisible': '''state in ('cancel','done',) '''}"/>
|
||||
<button string="Set Draft" name="set_state_draft" type="object"
|
||||
states="{'invisible': '''state in ('draft','done','waiting',) '''}"/>
|
||||
<button string="Set Waiting" name="set_state_waiting" type="object"
|
||||
states="{'invisible': '''state in ('waiting','done','cancel',) '''}"/>
|
||||
<button string="Cancel" name="set_state_cancel" type="object"
|
||||
states="{'invisible': '''state in ('draft','cancel',) '''}"/>
|
||||
</group>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="packing_in_view_tree">
|
||||
<field name="model">stock.packing.in</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Supplier Packings">
|
||||
<field name="code" select="1"/>
|
||||
<field name="state" select="1"/>
|
||||
<field name="effective_date" select="2"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_packing_in_form">
|
||||
<field name="name">Supplier Packings</field>
|
||||
<field name="res_model">stock.packing.in</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_packing_in_form_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="packing_in_view_tree"/>
|
||||
<field name="act_window" ref="act_packing_in_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_packing_in_form_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view" ref="packing_in_view_form"/>
|
||||
<field name="act_window" ref="act_packing_in_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_stock" sequence="7"
|
||||
action="act_packing_in_form" id="menu_packing_in_form"/>
|
||||
|
||||
|
||||
|
||||
<record model="ir.sequence.type" id="sequence_type_packing_in">
|
||||
<field name="name">Supplier Packing</field>
|
||||
<field name="code">stock.packing.in</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.sequence" id="sequence_packing_in">
|
||||
<field name="name">Supplier Packing</field>
|
||||
<field name="code">stock.packing.in</field>
|
||||
<field name="prefix">PA-IN: </field>
|
||||
<field name="padding">7</field>
|
||||
<field name="number_next">1</field>
|
||||
<field name="number_increment">1</field>
|
||||
</record>
|
||||
|
||||
<!--Packing out -->
|
||||
<record model="ir.ui.view" id="packing_out_view_form">
|
||||
<field name="model">stock.packing.out</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Customer Packing" col="6">
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<label name="effective_date"/>
|
||||
<field name="effective_date"/>
|
||||
<separator name="moves" colspan="6"/>
|
||||
<field name="moves" colspan="6"/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group col="4" colspan="4">
|
||||
<button string="Set Done" name="set_state_done" type="object"
|
||||
states="{'invisible': '''state in ('cancel','done',) '''}"/>
|
||||
<button string="Set Draft" name="set_state_draft" type="object"
|
||||
states="{'invisible': '''state in ('draft','done','waiting',) '''}"/>
|
||||
<button string="Set Waiting" name="set_state_waiting" type="object"
|
||||
states="{'invisible': '''state in ('waiting','done','cancel',) '''}"/>
|
||||
<button string="Cancel" name="set_state_cancel" type="object"
|
||||
states="{'invisible': '''state in ('draft','cancel',) '''}"/>
|
||||
</group>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="packing_out_view_tree">
|
||||
<field name="model">stock.packing.out</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Customer Packings">
|
||||
<field name="code" select="1"/>
|
||||
<field name="state" select="1"/>
|
||||
<field name="effective_date" select="2"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_packing_out_form">
|
||||
<field name="name">Customer Packings</field>
|
||||
<field name="res_model">stock.packing.out</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_packing_out_form_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="packing_out_view_tree"/>
|
||||
<field name="act_window" ref="act_packing_out_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_packing_out_form_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view" ref="packing_out_view_form"/>
|
||||
<field name="act_window" ref="act_packing_out_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_stock" sequence="7"
|
||||
action="act_packing_out_form" id="menu_packing_out_form"/>
|
||||
|
||||
|
||||
|
||||
<record model="ir.sequence.type" id="sequence_type_packing_out">
|
||||
<field name="name">Customer Packing</field>
|
||||
<field name="code">stock.packing.out</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.sequence" id="sequence_packing_out">
|
||||
<field name="name">Customer Packing</field>
|
||||
<field name="code">stock.packing.out</field>
|
||||
<field name="prefix">PA-OUT: </field>
|
||||
<field name="padding">7</field>
|
||||
<field name="number_next">1</field>
|
||||
<field name="number_increment">1</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- TODO workflow -->
|
||||
|
||||
<!-- <record model="workflow" id="wkf_packingin"> -->
|
||||
<!-- <field name="name">Supplier Packing</field> -->
|
||||
<!-- <field name="osv">stock.packing.in</field> -->
|
||||
<!-- <field name="on_create">True</field> -->
|
||||
<!-- </record> -->
|
||||
<!-- <record model="workflow.activity" id="packingin_act_draft"> -->
|
||||
<!-- <field name="wkf_id" ref="wkf_packingin"/> -->
|
||||
<!-- <field name="flow_start">True</field> -->
|
||||
<!-- <field name="name">draft</field> -->
|
||||
<!-- </record> -->
|
||||
<!-- <record model="workflow.activity" id="packingin_act_cancel"> -->
|
||||
<!-- <field name="workflow" ref="wkf_packingin"/> -->
|
||||
<!-- <field name="flow_stop">True</field> -->
|
||||
<!-- <field name="name">cancel</field> -->
|
||||
<!-- <field name="action">set_state_cancel()</field> -->
|
||||
<!-- </record> -->
|
||||
<!-- <record model="workflow.activity" id="packingin_act_done"> -->
|
||||
<!-- <field name="workflow" ref="wkf_packingin"/> -->
|
||||
<!-- <field name="flow_stop">True</field> -->
|
||||
<!-- <field name="name">done</field> -->
|
||||
<!-- <field name="action">set_state_done()</field> -->
|
||||
<!-- </record> -->
|
||||
<!-- <record model="workflow.activity" id="packingin_act_waiting"> -->
|
||||
<!-- <field name="workflow" ref="wkf_packingin"/> -->
|
||||
<!-- <field name="flow_stop">True</field> -->
|
||||
<!-- <field name="name">waiting</field> -->
|
||||
<!-- <field name="action">set_state_waiting()</field> -->
|
||||
<!-- </record> -->
|
||||
|
||||
<!-- <record model="workflow.transition" id="packingin_trans_waiting_done"> -->
|
||||
<!-- <field name="act_from" ref="packingin_act_waiting"/> -->
|
||||
<!-- <field name="act_to" ref="packingin_act_done"/> -->
|
||||
<!-- <field name="signal">set_done</field> -->
|
||||
<!-- </record> -->
|
||||
<!-- <record model="workflow.transition" id="packingin_trans_draft_waiting"> -->
|
||||
<!-- <field name="act_from" ref="packingin_act_draft"/> -->
|
||||
<!-- <field name="act_to" ref="packingin_act_waiting"/> -->
|
||||
<!-- <field name="signal">set_waiting</field> -->
|
||||
<!-- </record> -->
|
||||
<!-- <record model="workflow.transition" id="packingin_trans_draft_cencel"> -->
|
||||
<!-- <field name="act_from" ref="packingin_act_draft"/> -->
|
||||
<!-- <field name="act_to" ref="packingin_act_cancel"/> -->
|
||||
<!-- <field name="signal">set_cancel</field> -->
|
||||
<!-- </record> -->
|
||||
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
@@ -0,0 +1,22 @@
|
||||
"Wharehouse"
|
||||
from trytond.osv import fields, OSV
|
||||
|
||||
STATES = {
|
||||
'readonly': "active == False",
|
||||
}
|
||||
|
||||
|
||||
class Warehouse(OSV):
|
||||
"Warehouse"
|
||||
_name = 'stock.warehouse'
|
||||
_order = 'name'
|
||||
_description = __doc__
|
||||
name = fields.Char("Name", size=64, required=True, select=True)
|
||||
address = fields.Many2One("partner.address", "Address")
|
||||
locations = fields.One2Many("stock.location", "warehouse", "Storage locations",)
|
||||
active = fields.Boolean('Active', select=True)
|
||||
|
||||
def default_active(self, cursor, user, context=None):
|
||||
return True
|
||||
|
||||
Warehouse()
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<menuitem name="Inventory Management" sequence="3" id="menu_stock"/>
|
||||
<record model="ir.ui.view" id="warehouse_view_form">
|
||||
<field name="model">stock.warehouse</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Warehouse">
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="address"/>
|
||||
<field name="address"/>
|
||||
<label name="input_location"/>
|
||||
<field name="input_location"/>
|
||||
<label name="output_location"/>
|
||||
<field name="output_location"/>
|
||||
<separator name="locations" colspan="4"/>
|
||||
<field name="locations" colspan="4"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="warehouse_view_tree">
|
||||
<field name="model">stock.warehouse</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Warehouses">
|
||||
<field name="name"/>
|
||||
<field name="address"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window" id="act_warehouse_form">
|
||||
<field name="name">Warehouses</field>
|
||||
<field name="res_model">stock.warehouse</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_warehouse_form_view1">
|
||||
<field name="sequence" eval="1"/>
|
||||
<field name="view" ref="warehouse_view_tree"/>
|
||||
<field name="act_window" ref="act_warehouse_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_warehouse_form_view2">
|
||||
<field name="sequence" eval="2"/>
|
||||
<field name="view" ref="warehouse_view_form"/>
|
||||
<field name="act_window" ref="act_warehouse_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_stock" sequence="1"
|
||||
action="act_warehouse_form" id="menu_warehouse_form"/>
|
||||
|
||||
</data>
|
||||
</tryton>
|
||||
Reference in New Issue
Block a user