2010-04-29 13:30:07 +00:00
# -*- 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 mx import DateTime
from osv import osv , fields
from tools . translate import _
import netsvc
import time
# Procurement
# ------------------------------------------------------------------
#
# Produce, Buy or Find products and place a move
# then wizard for picking lists & move
#
2010-07-07 11:45:16 +00:00
class mrp_property_group ( osv . osv ) :
"""
Group of mrp properties .
"""
_name = ' mrp.property.group '
_description = ' Property Group '
_columns = {
' name ' : fields . char ( ' Property Group ' , size = 64 , required = True ) ,
' description ' : fields . text ( ' Description ' ) ,
}
mrp_property_group ( )
class mrp_property ( osv . osv ) :
"""
Properties of mrp .
"""
_name = ' mrp.property '
_description = ' Property '
_columns = {
' name ' : fields . char ( ' Name ' , size = 64 , required = True ) ,
' composition ' : fields . selection ( [ ( ' min ' , ' min ' ) , ( ' max ' , ' max ' ) , ( ' plus ' , ' plus ' ) ] , ' Properties composition ' , required = True , help = " Not used in computations, for information purpose only. " ) ,
' group_id ' : fields . many2one ( ' mrp.property.group ' , ' Property Group ' , required = True ) ,
' description ' : fields . text ( ' Description ' ) ,
}
_defaults = {
' composition ' : lambda * a : ' min ' ,
}
mrp_property ( )
2010-05-27 12:47:06 +00:00
class procurement_order ( osv . osv ) :
2010-04-29 13:30:07 +00:00
"""
Procurement Orders
"""
2010-05-27 12:47:06 +00:00
_name = " procurement.order "
2010-04-29 13:30:07 +00:00
_description = " Procurement "
2010-05-19 20:02:36 +00:00
_order = ' priority,date_planned desc '
_log_create = False
2010-04-29 13:30:07 +00:00
_columns = {
' name ' : fields . char ( ' Reason ' , size = 64 , required = True , help = ' Procurement name. ' ) ,
' origin ' : fields . char ( ' Source Document ' , size = 64 ,
help = " Reference of the document that created this Procurement. \n "
" This is automatically completed by Open ERP. " ) ,
' priority ' : fields . selection ( [ ( ' 0 ' , ' Not urgent ' ) , ( ' 1 ' , ' Normal ' ) , ( ' 2 ' , ' Urgent ' ) , ( ' 3 ' , ' Very Urgent ' ) ] , ' Priority ' , required = True ) ,
' date_planned ' : fields . datetime ( ' Scheduled date ' , required = True ) ,
' date_close ' : fields . datetime ( ' Date Closed ' ) ,
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True ) ,
' product_qty ' : fields . float ( ' Quantity ' , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True ) ,
' product_uom ' : fields . many2one ( ' product.uom ' , ' Product UoM ' , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True ) ,
' product_uos_qty ' : fields . float ( ' UoS Quantity ' , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True ) ,
' product_uos ' : fields . many2one ( ' product.uom ' , ' Product UoS ' , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True ) ,
' move_id ' : fields . many2one ( ' stock.move ' , ' Reservation ' , ondelete = ' set null ' ) ,
' close_move ' : fields . boolean ( ' Close Move at end ' , required = True ) ,
' location_id ' : fields . many2one ( ' stock.location ' , ' Location ' , required = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] } , readonly = True ) ,
' procure_method ' : fields . selection ( [ ( ' make_to_stock ' , ' from stock ' ) , ( ' make_to_order ' , ' on order ' ) ] , ' Procurement Method ' , states = { ' draft ' : [ ( ' readonly ' , False ) ] , ' confirmed ' : [ ( ' readonly ' , False ) ] } ,
readonly = True , required = True , help = " If you encode manually a Procurement, you probably want to use " \
" a make to order method. " ) ,
' note ' : fields . text ( ' Note ' ) ,
' message ' : fields . char ( ' Latest error ' , size = 64 , help = " Exception occurred while computing procurement orders. " ) ,
' state ' : fields . selection ( [
( ' draft ' , ' Draft ' ) ,
( ' confirmed ' , ' Confirmed ' ) ,
( ' exception ' , ' Exception ' ) ,
( ' running ' , ' Running ' ) ,
( ' cancel ' , ' Cancel ' ) ,
( ' ready ' , ' Ready ' ) ,
( ' done ' , ' Done ' ) ,
( ' waiting ' , ' Waiting ' ) ] , ' State ' , required = True ,
help = ' When a procurement is created the state is set to \' Draft \' . \n If the procurement is confirmed, the state is set to \' Confirmed \' . \
\nAfter confirming the state is set to \' Running \' . \n If any exception arises in the order then the state is set to \' Exception \' . \n Once the exception is removed the state becomes \' Ready \' . \n It is in \' Waiting \' . state when the procurement is waiting for another one to finish. ' ) ,
' note ' : fields . text ( ' Note ' ) ,
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = True ) ,
}
_defaults = {
' state ' : lambda * a : ' draft ' ,
' priority ' : lambda * a : ' 1 ' ,
' date_planned ' : lambda * a : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) ,
' close_move ' : lambda * a : 0 ,
' procure_method ' : lambda * a : ' make_to_order ' ,
2010-05-27 12:47:06 +00:00
' company_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' procurement.order ' , context = c )
2010-04-29 13:30:07 +00:00
}
def unlink ( self , cr , uid , ids , context = None ) :
procurements = self . read ( cr , uid , ids , [ ' state ' ] )
unlink_ids = [ ]
for s in procurements :
if s [ ' state ' ] in [ ' draft ' , ' cancel ' ] :
unlink_ids . append ( s [ ' id ' ] )
else :
raise osv . except_osv ( _ ( ' Invalid action ! ' ) , _ ( ' Cannot delete Procurement Order(s) which are in %s State! ' % s [ ' state ' ] ) )
return osv . osv . unlink ( self , cr , uid , unlink_ids , context = context )
def onchange_product_id ( self , cr , uid , ids , product_id , context = { } ) :
""" Finds UoM and UoS of changed product.
@param product_id : Changed id of product .
@return : Dictionary of values .
"""
if product_id :
w = self . pool . get ( ' product.product ' ) . browse ( cr , uid , product_id , context )
v = {
' product_uom ' : w . uom_id . id ,
' product_uos ' : w . uos_id and w . uos_id . id or w . uom_id . id
}
return { ' value ' : v }
return { }
def check_product ( self , cr , uid , ids ) :
""" Checks product type.
2010-05-14 13:24:15 +00:00
@return : True or False
2010-04-29 13:30:07 +00:00
"""
for procurement in self . browse ( cr , uid , ids ) :
if procurement . product_id . type in ( ' product ' , ' consu ' ) :
return True
return False
def check_move_cancel ( self , cr , uid , ids , context = { } ) :
""" Checks if move is cancelled or not.
2010-05-14 13:24:15 +00:00
@return : True or False .
2010-04-29 13:30:07 +00:00
"""
res = True
ok = False
for procurement in self . browse ( cr , uid , ids , context ) :
if procurement . move_id :
ok = True
if not procurement . move_id . state == ' cancel ' :
res = False
return res and ok
def check_move_done ( self , cr , uid , ids , context = { } ) :
""" Checks if move is done or not.
2010-05-14 13:24:15 +00:00
@return : True or False .
2010-04-29 13:30:07 +00:00
"""
res = True
for proc in self . browse ( cr , uid , ids , context ) :
if proc . move_id :
if not proc . move_id . state == ' done ' :
res = False
return res
#
2010-05-27 12:47:06 +00:00
# This method may be overrided by objects that override procurement.order
2010-04-29 13:30:07 +00:00
# for computing their own purpose
#
def _quantity_compute_get ( self , cr , uid , proc , context = { } ) :
""" Finds sold quantity of product.
@param proc : Current procurement .
@return : Quantity or False .
"""
if proc . product_id . type == ' product ' :
if proc . move_id . product_uos :
return proc . move_id . product_uos_qty
return False
def _uom_compute_get ( self , cr , uid , proc , context = { } ) :
2010-05-14 13:24:15 +00:00
""" Finds UoS if product is Stockable Product.
2010-04-29 13:30:07 +00:00
@param proc : Current procurement .
@return : UoS or False .
"""
if proc . product_id . type == ' product ' :
if proc . move_id . product_uos :
return proc . move_id . product_uos . id
return False
#
2010-06-02 07:13:39 +00:00
# Return the quantity of product shipped/produced/served, which may be
2010-04-29 13:30:07 +00:00
# different from the planned quantity
#
def quantity_get ( self , cr , uid , id , context = { } ) :
""" Finds quantity of product used in procurement.
2010-05-14 13:24:15 +00:00
@return : Quantity of product .
2010-04-29 13:30:07 +00:00
"""
proc = self . browse ( cr , uid , id , context )
result = self . _quantity_compute_get ( cr , uid , proc , context )
if not result :
result = proc . product_qty
return result
def uom_get ( self , cr , uid , id , context = None ) :
""" Finds UoM of product used in procurement.
2010-05-14 13:24:15 +00:00
@return : UoM of product .
2010-04-29 13:30:07 +00:00
"""
proc = self . browse ( cr , uid , id , context )
result = self . _uom_compute_get ( cr , uid , proc , context )
if not result :
result = proc . product_uom . id
return result
def check_waiting ( self , cr , uid , ids , context = [ ] ) :
""" Checks state of move.
2010-05-14 13:24:15 +00:00
@return : True or False
2010-04-29 13:30:07 +00:00
"""
for procurement in self . browse ( cr , uid , ids , context = context ) :
if procurement . move_id and procurement . move_id . state == ' auto ' :
return True
return False
def check_produce_service ( self , cr , uid , procurement , context = [ ] ) :
2010-07-10 05:16:19 +00:00
""" Checks project_mrp install or not.
@return : True or False """
obj_module = self . pool . get ( ' ir.module.module ' )
module_id = obj_module . search ( cr , uid , [ ( ' name ' , ' = ' , ' project_mrp ' ) , ( ' state ' , ' = ' , ' installed ' ) ] )
if module_id :
return True
cr . execute ( ' update procurement_order set message= %s where id= %s ' , ( _ ( ' Project_mrp module not installed ! ' ) , procurement . id ) )
return False
2010-04-29 13:30:07 +00:00
def check_produce_product ( self , cr , uid , procurement , context = [ ] ) :
""" Finds BoM of a product if not found writes exception message.
@param procurement : Current procurement .
@return : True or False .
"""
return True
def check_make_to_stock ( self , cr , uid , ids , context = { } ) :
""" Checks product type.
2010-05-14 13:24:15 +00:00
@return : True or False
2010-04-29 13:30:07 +00:00
"""
ok = True
for procurement in self . browse ( cr , uid , ids , context = context ) :
if procurement . product_id . type == ' service ' :
ok = ok and self . _check_make_to_stock_service ( cr , uid , procurement , context )
else :
ok = ok and self . _check_make_to_stock_product ( cr , uid , procurement , context )
return ok
def check_produce ( self , cr , uid , ids , context = { } ) :
""" Checks product type.
@return : True or Product Id .
"""
res = True
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid )
for procurement in self . browse ( cr , uid , ids ) :
if procurement . product_id . product_tmpl_id . supply_method < > ' produce ' :
2010-06-07 18:42:14 +00:00
partner_list = sorted ( [ ( partner_id . sequence , partner_id ) for partner_id in procurement . product_id . seller_ids if partner_id ] )
if partner_list :
partner = partner_list and partner_list [ 0 ] and partner_list [ 0 ] [ 1 ] and partner_list [ 0 ] [ 1 ] . name or False
2010-04-29 13:30:07 +00:00
if user . company_id and user . company_id . partner_id :
if partner . id == user . company_id . partner_id . id :
return True
return False
if procurement . product_id . product_tmpl_id . type == ' service ' :
res = res and self . check_produce_service ( cr , uid , procurement , context )
else :
res = res and self . check_produce_product ( cr , uid , procurement , context )
if not res :
return False
return res
def check_buy ( self , cr , uid , ids ) :
""" Checks product type.
@return : True or Product Id .
"""
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid )
partner_obj = self . pool . get ( ' res.partner ' )
for procurement in self . browse ( cr , uid , ids ) :
if procurement . product_id . product_tmpl_id . supply_method < > ' buy ' :
return False
if not procurement . product_id . seller_ids :
2010-05-27 12:47:06 +00:00
cr . execute ( ' update procurement_order set message= %s where id= %s ' , ( _ ( ' No supplier defined for this product ! ' ) , procurement . id ) )
2010-04-29 13:30:07 +00:00
return False
2010-07-23 13:17:30 +00:00
partner = procurement . product_id . seller_id #Taken Main Supplier of Product of Procurement.
2010-06-07 18:42:14 +00:00
2010-04-29 13:30:07 +00:00
if user . company_id and user . company_id . partner_id :
if partner . id == user . company_id . partner_id . id :
return False
address_id = partner_obj . address_get ( cr , uid , [ partner . id ] , [ ' delivery ' ] ) [ ' delivery ' ]
if not address_id :
2010-05-27 12:47:06 +00:00
cr . execute ( ' update procurement_order set message= %s where id= %s ' , ( _ ( ' No address defined for the supplier ' ) , procurement . id ) )
2010-04-29 13:30:07 +00:00
return False
return True
def test_cancel ( self , cr , uid , ids ) :
2010-05-14 13:24:15 +00:00
""" Tests whether state of move is cancelled or not.
2010-04-29 13:30:07 +00:00
@return : True or False
"""
for record in self . browse ( cr , uid , ids ) :
if record . move_id and record . move_id . state == ' cancel ' :
return True
return False
def action_confirm ( self , cr , uid , ids , context = { } ) :
""" Confirms procurement and writes exception message if any.
@return : True
"""
move_obj = self . pool . get ( ' stock.move ' )
for procurement in self . browse ( cr , uid , ids ) :
if procurement . product_qty < = 0.00 :
2010-07-18 19:43:57 +00:00
raise osv . except_osv ( _ ( ' Data Insufficient ! ' ) , _ ( ' Please check the Quantity in Procurement Order(s), it should not be less than 1! ' ) )
2010-04-29 13:30:07 +00:00
if procurement . product_id . type in ( ' product ' , ' consu ' ) :
if not procurement . move_id :
source = procurement . location_id . id
if procurement . procure_method == ' make_to_order ' :
source = procurement . product_id . product_tmpl_id . property_stock_procurement . id
id = move_obj . create ( cr , uid , {
' name ' : ' PROC: ' + procurement . name ,
' location_id ' : source ,
' location_dest_id ' : procurement . location_id . id ,
' product_id ' : procurement . product_id . id ,
' product_qty ' : procurement . product_qty ,
' product_uom ' : procurement . product_uom . id ,
' date_planned ' : procurement . date_planned ,
2010-05-19 20:54:46 +00:00
' state ' : ' draft ' ,
2010-04-29 13:30:07 +00:00
' company_id ' : procurement . company_id . id ,
} )
2010-05-19 20:54:46 +00:00
move_obj . action_confirm ( cr , uid , [ id ] , context = context )
2010-04-29 13:30:07 +00:00
self . write ( cr , uid , [ procurement . id ] , { ' move_id ' : id , ' close_move ' : 1 } )
2010-07-08 10:14:24 +00:00
message = _ ( ' Procurement ' ) + " ' " + procurement . name + " ' " + _ ( " is running. " )
self . log ( cr , uid , procurement . id , message )
2010-04-29 13:30:07 +00:00
self . write ( cr , uid , ids , { ' state ' : ' confirmed ' , ' message ' : ' ' } )
return True
def action_move_assigned ( self , cr , uid , ids , context = { } ) :
""" Changes procurement state to Running and writes message.
2010-05-14 13:24:15 +00:00
@return : True
2010-04-29 13:30:07 +00:00
"""
self . write ( cr , uid , ids , { ' state ' : ' running ' , ' message ' : _ ( ' from stock: products assigned. ' ) } )
return True
def _check_make_to_stock_service ( self , cr , uid , procurement , context = { } ) :
2010-07-10 05:16:19 +00:00
"""
This method may be overrided by objects that override procurement . order
for computing their own purpose
@return : True """
2010-04-29 13:30:07 +00:00
return True
def _check_make_to_stock_product ( self , cr , uid , procurement , context = { } ) :
""" Checks procurement move state.
@param procurement : Current procurement .
@return : True or move id .
"""
ok = True
if procurement . move_id :
id = procurement . move_id . id
if not ( procurement . move_id . state in ( ' done ' , ' assigned ' , ' cancel ' ) ) :
ok = ok and self . pool . get ( ' stock.move ' ) . action_assign ( cr , uid , [ id ] )
cr . execute ( ' select count(id) from stock_warehouse_orderpoint where product_id= %s ' , ( procurement . product_id . id , ) )
2010-07-08 10:14:24 +00:00
if not cr . fetchone ( ) [ 0 ] :
2010-06-21 18:40:58 +00:00
cr . execute ( ' update procurement_order set message= %s where id= %s ' , ( _ ( ' Not enough stock and no minimum orderpoint rule defined. ' ) , procurement . id ) )
2010-07-08 10:14:24 +00:00
message = _ ( ' Procurement ' ) + " ' " + procurement . name + " ' " + _ ( " has an exception. " ) + _ ( ' Not enough stock and no minimum orderpoint rule defined. ' )
self . log ( cr , uid , procurement . id , message )
2010-07-12 07:09:53 +00:00
if procurement . state == ' exception ' and procurement . message == ' ' :
cr . execute ( ' update procurement_order set message= %s where id= %s ' , ( _ ( ' Not enough stock ' ) , procurement . id ) )
2010-04-29 13:30:07 +00:00
return ok
def action_produce_assign_service ( self , cr , uid , ids , context = { } ) :
""" Changes procurement state to Running.
2010-05-14 13:24:15 +00:00
@return : True
2010-04-29 13:30:07 +00:00
"""
for procurement in self . browse ( cr , uid , ids ) :
self . write ( cr , uid , [ procurement . id ] , { ' state ' : ' running ' } )
return True
def action_produce_assign_product ( self , cr , uid , ids , context = { } ) :
""" This is action which call from workflow to assign production order to procurements
@return : True
"""
return 0
2010-05-14 13:24:15 +00:00
2010-04-29 13:30:07 +00:00
def action_po_assign ( self , cr , uid , ids , context = { } ) :
""" This is action which call from workflow to assign purchase order to procurements
@return : True
"""
return 0
def action_cancel ( self , cr , uid , ids ) :
""" Cancels procurement and writes move state to Assigned.
2010-05-14 13:24:15 +00:00
@return : True
2010-04-29 13:30:07 +00:00
"""
todo = [ ]
todo2 = [ ]
move_obj = self . pool . get ( ' stock.move ' )
for proc in self . browse ( cr , uid , ids ) :
if proc . close_move :
if proc . move_id . state not in ( ' done ' , ' cancel ' ) :
todo2 . append ( proc . move_id . id )
else :
if proc . move_id and proc . move_id . state == ' waiting ' :
todo . append ( proc . move_id . id )
if len ( todo2 ) :
move_obj . action_cancel ( cr , uid , todo2 )
if len ( todo ) :
move_obj . write ( cr , uid , todo , { ' state ' : ' assigned ' } )
self . write ( cr , uid , ids , { ' state ' : ' cancel ' } )
wf_service = netsvc . LocalService ( " workflow " )
for id in ids :
2010-05-27 12:47:06 +00:00
wf_service . trg_trigger ( uid , ' procurement.order ' , id , cr )
2010-04-29 13:30:07 +00:00
return True
def action_check_finnished ( self , cr , uid , ids ) :
return self . check_move_done ( cr , uid , ids )
def action_check ( self , cr , uid , ids ) :
2010-05-14 13:24:15 +00:00
""" Checks procurement move state whether assigned or done.
@return : True
2010-04-29 13:30:07 +00:00
"""
ok = False
for procurement in self . browse ( cr , uid , ids ) :
if procurement . move_id . state == ' assigned ' or procurement . move_id . state == ' done ' :
self . action_done ( cr , uid , [ procurement . id ] )
ok = True
return ok
def action_ready ( self , cr , uid , ids ) :
""" Changes procurement state to Ready.
2010-05-14 13:24:15 +00:00
@return : True
2010-04-29 13:30:07 +00:00
"""
res = self . write ( cr , uid , ids , { ' state ' : ' ready ' } )
return res
def action_done ( self , cr , uid , ids ) :
""" Changes procurement state to Done and writes Closed date.
2010-05-14 13:24:15 +00:00
@return : True
2010-04-29 13:30:07 +00:00
"""
move_obj = self . pool . get ( ' stock.move ' )
for procurement in self . browse ( cr , uid , ids ) :
if procurement . move_id :
if procurement . close_move and ( procurement . move_id . state < > ' done ' ) :
move_obj . action_done ( cr , uid , [ procurement . move_id . id ] )
2010-07-08 10:14:24 +00:00
message = _ ( ' Procurement ' ) + " ' " + procurement . name + " ' " + _ ( " is done. " )
self . log ( cr , uid , procurement . id , message )
2010-04-29 13:30:07 +00:00
res = self . write ( cr , uid , ids , { ' state ' : ' done ' , ' date_close ' : time . strftime ( ' % Y- % m- %d ' ) } )
wf_service = netsvc . LocalService ( " workflow " )
for id in ids :
2010-05-27 12:47:06 +00:00
wf_service . trg_trigger ( uid , ' procurement.order ' , id , cr )
2010-04-29 13:30:07 +00:00
return res
def run_scheduler ( self , cr , uid , automatic = False , use_new_cursor = False , context = None ) :
''' Runs through scheduler.
@param use_new_cursor : False or the dbname
'''
if not context :
context = { }
self . _procure_confirm ( cr , uid , use_new_cursor = use_new_cursor , context = context )
self . _procure_orderpoint_confirm ( cr , uid , automatic = automatic , \
use_new_cursor = use_new_cursor , context = context )
2010-05-14 13:24:15 +00:00
2010-05-27 12:47:06 +00:00
procurement_order ( )
2010-04-29 13:30:07 +00:00
class stock_warehouse_orderpoint ( osv . osv ) :
"""
Defines Minimum stock rules .
"""
_name = " stock.warehouse.orderpoint "
2010-05-27 12:47:06 +00:00
_description = " Minimum Inventory Rule "
2010-04-29 13:30:07 +00:00
_columns = {
' name ' : fields . char ( ' Name ' , size = 32 , required = True ) ,
' active ' : fields . boolean ( ' Active ' , help = " If the active field is set to true, it will allow you to hide the orderpoint without removing it. " ) ,
' logic ' : fields . selection ( [ ( ' max ' , ' Order to Max ' ) , ( ' price ' , ' Best price (not yet active!) ' ) ] , ' Reordering Mode ' , required = True ) ,
2010-05-27 12:47:06 +00:00
' warehouse_id ' : fields . many2one ( ' stock.warehouse ' , ' Warehouse ' , required = True , ondelete = " cascade " ) ,
' location_id ' : fields . many2one ( ' stock.location ' , ' Location ' , required = True , ondelete = " cascade " ) ,
2010-04-30 06:01:15 +00:00
' product_id ' : fields . many2one ( ' product.product ' , ' Product ' , required = True , ondelete = ' cascade ' , domain = [ ( ' type ' , ' = ' , ' product ' ) ] ) ,
2010-05-27 12:47:06 +00:00
' product_uom ' : fields . many2one ( ' product.uom ' , ' Product UOM ' , required = True ) ,
2010-04-29 13:30:07 +00:00
' product_min_qty ' : fields . float ( ' Min Quantity ' , required = True ,
help = " When the virtual stock goes belong the Min Quantity, Open ERP generates " \
" a procurement to bring the virtual stock to the Max Quantity. " ) ,
' product_max_qty ' : fields . float ( ' Max Quantity ' , required = True ,
2010-07-08 06:58:43 +00:00
help = " When the virtual stock goes belong the Max Quantity, Open ERP generates " \
2010-04-29 13:30:07 +00:00
" a procurement to bring the virtual stock to the Max Quantity. " ) ,
' qty_multiple ' : fields . integer ( ' Qty Multiple ' , required = True ,
help = " The procurement quantity will by rounded up to this multiple. " ) ,
2010-05-27 12:47:06 +00:00
' procurement_id ' : fields . many2one ( ' procurement.order ' , ' Latest procurement ' , ondelete = " set null " ) ,
2010-04-29 13:30:07 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = True ) ,
}
_defaults = {
' active ' : lambda * a : 1 ,
' logic ' : lambda * a : ' max ' ,
' qty_multiple ' : lambda * a : 1 ,
2010-05-28 10:44:30 +00:00
' name ' : lambda x , y , z , c : x . pool . get ( ' ir.sequence ' ) . get ( y , z , ' stock.orderpoint ' ) or ' ' ,
2010-04-29 13:30:07 +00:00
' product_uom ' : lambda sel , cr , uid , context : context . get ( ' product_uom ' , False ) ,
' company_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' stock.warehouse.orderpoint ' , context = c )
}
2010-05-27 12:47:06 +00:00
_sql_constraints = [
( ' qty_multiple_check ' , ' CHECK( qty_multiple > 0 ) ' , _ ( ' Qty Multiple must be greater than zero. ' ) ) ,
]
2010-04-29 13:30:07 +00:00
def onchange_warehouse_id ( self , cr , uid , ids , warehouse_id , context = { } ) :
""" Finds location id for changed warehouse.
@param warehouse_id : Changed id of warehouse .
@return : Dictionary of values .
"""
if warehouse_id :
w = self . pool . get ( ' stock.warehouse ' ) . browse ( cr , uid , warehouse_id , context )
v = { ' location_id ' : w . lot_stock_id . id }
return { ' value ' : v }
return { }
2010-05-27 12:47:06 +00:00
2010-04-29 13:30:07 +00:00
def onchange_product_id ( self , cr , uid , ids , product_id , context = { } ) :
""" Finds UoM for changed product.
@param product_id : Changed id of product .
@return : Dictionary of values .
"""
if product_id :
prod = self . pool . get ( ' product.product ' ) . browse ( cr , uid , product_id )
v = { ' product_uom ' : prod . uom_id . id }
return { ' value ' : v }
return { }
2010-05-27 12:47:06 +00:00
2010-04-29 13:30:07 +00:00
def copy ( self , cr , uid , id , default = None , context = { } ) :
if not default :
default = { }
default . update ( {
2010-05-28 10:44:30 +00:00
' name ' : self . pool . get ( ' ir.sequence ' ) . get ( cr , uid , ' stock.orderpoint ' ) or ' ' ,
2010-04-29 13:30:07 +00:00
} )
return super ( stock_warehouse_orderpoint , self ) . copy ( cr , uid , id , default , context )
2010-05-27 12:47:06 +00:00
2010-04-29 13:30:07 +00:00
stock_warehouse_orderpoint ( )
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: