2015-01-05 13:34:14 +00:00
# -*- coding: utf-8 -*-
from openerp . addons . stock . tests . common import TestStockCommon
from openerp . tools import mute_logger , float_round
class TestStockFlow ( TestStockCommon ) :
@mute_logger ( ' openerp.addons.base.ir.ir_model ' , ' openerp.models ' )
def test_00_picking_create_and_transfer_quantity ( self ) :
""" Basic stock operation on incoming and outgoing shipment. """
LotObj = self . env [ ' stock.production.lot ' ]
# ----------------------------------------------------------------------
# Create incoming shipment of product A, B, C, D
# ----------------------------------------------------------------------
# Product A ( 1 Unit ) , Product C ( 10 Unit )
# Product B ( 1 Unit ) , Product D ( 10 Unit )
# Product D ( 5 Unit )
# ----------------------------------------------------------------------
picking_in = self . PickingObj . create ( {
' partner_id ' : self . partner_delta_id ,
' picking_type_id ' : self . picking_type_in } )
self . MoveObj . create ( {
' name ' : self . productA . name ,
' product_id ' : self . productA . id ,
' product_uom_qty ' : 1 ,
' product_uom ' : self . productA . uom_id . id ,
' picking_id ' : picking_in . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . productB . name ,
' product_id ' : self . productB . id ,
' product_uom_qty ' : 1 ,
' product_uom ' : self . productB . uom_id . id ,
' picking_id ' : picking_in . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . productC . name ,
' product_id ' : self . productC . id ,
' product_uom_qty ' : 10 ,
' product_uom ' : self . productC . uom_id . id ,
' picking_id ' : picking_in . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . productD . name ,
' product_id ' : self . productD . id ,
' product_uom_qty ' : 10 ,
' product_uom ' : self . productD . uom_id . id ,
' picking_id ' : picking_in . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . productD . name ,
' product_id ' : self . productD . id ,
' product_uom_qty ' : 5 ,
' product_uom ' : self . productD . uom_id . id ,
' picking_id ' : picking_in . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
# Check incoming shipment move lines state.
for move in picking_in . move_lines :
self . assertEqual ( move . state , ' draft ' , ' Wrong state of move line. ' )
# Confirm incoming shipment.
picking_in . action_confirm ( )
# Check incoming shipment move lines state.
for move in picking_in . move_lines :
self . assertEqual ( move . state , ' assigned ' , ' Wrong state of move line. ' )
# ----------------------------------------------------------------------
# Replace pack operation of incoming shipments.
# ----------------------------------------------------------------------
picking_in . do_prepare_partial ( )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] ) . write ( {
' product_qty ' : 4.0 } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productB . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] ) . write ( {
' product_qty ' : 5.0 } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] ) . write ( {
' product_qty ' : 5.0 } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] ) . write ( {
' product_qty ' : 5.0 } )
lot2_productC = LotObj . create ( { ' name ' : ' C Lot 2 ' , ' product_id ' : self . productC . id } )
self . StockPackObj . create ( {
' product_id ' : self . productC . id ,
' product_qty ' : 2 ,
' product_uom_id ' : self . productC . uom_id . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location ,
' picking_id ' : picking_in . id ,
' lot_id ' : lot2_productC . id } )
self . StockPackObj . create ( {
' product_id ' : self . productD . id ,
' product_qty ' : 2 ,
' product_uom_id ' : self . productD . uom_id . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location ,
' picking_id ' : picking_in . id } )
# Check incoming shipment total quantity of pack operation
packs = self . StockPackObj . search ( [ ( ' picking_id ' , ' = ' , picking_in . id ) ] )
total_qty = [ pack . product_qty for pack in packs ]
self . assertEqual ( sum ( total_qty ) , 23 , ' Wrong quantity in pack operation ( %s found instead of 23) ' % ( sum ( total_qty ) ) )
# Transfer Incoming Shipment.
picking_in . do_transfer ( )
# ----------------------------------------------------------------------
# Check state, quantity and total moves of incoming shipment.
# ----------------------------------------------------------------------
# Check total no of move lines of incoming shipment.
self . assertEqual ( len ( picking_in . move_lines ) , 6 , ' Wrong number of move lines. ' )
# Check incoming shipment state.
self . assertEqual ( picking_in . state , ' done ' , ' Incoming shipment state should be done. ' )
# Check incoming shipment move lines state.
for move in picking_in . move_lines :
self . assertEqual ( move . state , ' done ' , ' Wrong state of move line. ' )
# Check product A done quantity must be 3 and 1
moves = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] )
a_done_qty = [ move . product_uom_qty for move in moves ]
self . assertEqual ( set ( a_done_qty ) , set ( [ 1.0 , 3.0 ] ) , ' Wrong move quantity for product A. ' )
# Check product B done quantity must be 4 and 1
moves = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productB . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] )
b_done_qty = [ move . product_uom_qty for move in moves ]
self . assertEqual ( set ( b_done_qty ) , set ( [ 4.0 , 1.0 ] ) , ' Wrong move quantity for product B. ' )
# Check product C done quantity must be 7
c_done_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] , limit = 1 ) . product_uom_qty
self . assertEqual ( c_done_qty , 7.0 , ' Wrong move quantity of product C ( %s found instead of 7) ' % ( c_done_qty ) )
# Check product D done quantity must be 7
d_done_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] , limit = 1 ) . product_uom_qty
self . assertEqual ( d_done_qty , 7.0 , ' Wrong move quantity of product D ( %s found instead of 7) ' % ( d_done_qty ) )
# ----------------------------------------------------------------------
# Check Back order of Incoming shipment.
# ----------------------------------------------------------------------
# Check back order created or not.
back_order_in = self . PickingObj . search ( [ ( ' backorder_id ' , ' = ' , picking_in . id ) ] )
self . assertEqual ( len ( back_order_in ) , 1 , ' Back order should be created. ' )
# Check total move lines of back order.
self . assertEqual ( len ( back_order_in . move_lines ) , 3 , ' Wrong number of move lines. ' )
# Check back order should be created with 3 quantity of product C.
moves = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' picking_id ' , ' = ' , back_order_in . id ) ] )
product_c_qty = [ move . product_uom_qty for move in moves ]
self . assertEqual ( sum ( product_c_qty ) , 3.0 , ' Wrong move quantity of product C ( %s found instead of 3) ' % ( product_c_qty ) )
# Check back order should be created with 8 quantity of product D.
moves = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' picking_id ' , ' = ' , back_order_in . id ) ] )
product_d_qty = [ move . product_uom_qty for move in moves ]
self . assertEqual ( sum ( product_d_qty ) , 8.0 , ' Wrong move quantity of product D ( %s found instead of 8) ' % ( product_d_qty ) )
# ======================================================================
# Create Outgoing shipment with ...
# product A ( 10 Unit ) , product B ( 5 Unit )
# product C ( 3 unit ) , product D ( 10 Unit )
# ======================================================================
picking_out = self . PickingObj . create ( {
' partner_id ' : self . partner_agrolite_id ,
' picking_type_id ' : self . picking_type_out } )
self . MoveObj . create ( {
' name ' : self . productA . name ,
' product_id ' : self . productA . id ,
' product_uom_qty ' : 10 ,
' product_uom ' : self . productA . uom_id . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
self . MoveObj . create ( {
' name ' : self . productB . name ,
' product_id ' : self . productB . id ,
' product_uom_qty ' : 5 ,
' product_uom ' : self . productB . uom_id . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
self . MoveObj . create ( {
' name ' : self . productC . name ,
' product_id ' : self . productC . id ,
' product_uom_qty ' : 3 ,
' product_uom ' : self . productC . uom_id . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
self . MoveObj . create ( {
' name ' : self . productD . name ,
' product_id ' : self . productD . id ,
' product_uom_qty ' : 10 ,
' product_uom ' : self . productD . uom_id . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
# Confirm outgoing shipment.
picking_out . action_confirm ( )
for move in picking_out . move_lines :
self . assertEqual ( move . state , ' confirmed ' , ' Wrong state of move line. ' )
# Product assign to outgoing shipments
picking_out . action_assign ( )
for move in picking_out . move_lines :
self . assertEqual ( move . state , ' assigned ' , ' Wrong state of move line. ' )
# Check availability for product A
aval_a_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( aval_a_qty , 4.0 , ' Wrong move quantity availability of product A ( %s found instead of 4) ' % ( aval_a_qty ) )
# Check availability for product B
aval_b_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productB . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( aval_b_qty , 5.0 , ' Wrong move quantity availability of product B ( %s found instead of 5) ' % ( aval_b_qty ) )
# Check availability for product C
aval_c_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( aval_c_qty , 3.0 , ' Wrong move quantity availability of product C ( %s found instead of 3) ' % ( aval_c_qty ) )
# Check availability for product D
aval_d_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( aval_d_qty , 7.0 , ' Wrong move quantity availability of product D ( %s found instead of 7) ' % ( aval_d_qty ) )
# ----------------------------------------------------------------------
# Replace pack operation of outgoing shipment.
# ----------------------------------------------------------------------
picking_out . do_prepare_partial ( )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] ) . write ( { ' product_qty ' : 2.0 } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productB . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] ) . write ( { ' product_qty ' : 3.0 } )
self . StockPackObj . create ( {
' product_id ' : self . productB . id ,
' product_qty ' : 2 ,
' product_uom_id ' : self . productB . uom_id . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location ,
' picking_id ' : picking_out . id } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] ) . write ( {
' product_qty ' : 2.0 , ' lot_id ' : lot2_productC . id } )
self . StockPackObj . create ( {
' product_id ' : self . productC . id ,
' product_qty ' : 3 ,
' product_uom_id ' : self . productC . uom_id . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location ,
' picking_id ' : picking_out . id } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] ) . write ( { ' product_qty ' : 6.0 } )
# Transfer picking.
picking_out . do_transfer ( )
# ----------------------------------------------------------------------
# Check state, quantity and total moves of outgoing shipment.
# ----------------------------------------------------------------------
# check outgoing shipment status.
self . assertEqual ( picking_out . state , ' done ' , ' Wrong state of outgoing shipment. ' )
# check outgoing shipment total moves and and its state.
self . assertEqual ( len ( picking_out . move_lines ) , 5 , ' Wrong number of move lines ' )
for move in picking_out . move_lines :
self . assertEqual ( move . state , ' done ' , ' Wrong state of move line. ' )
back_order_out = self . PickingObj . search ( [ ( ' backorder_id ' , ' = ' , picking_out . id ) ] )
#------------------
# Check back order.
# -----------------
self . assertEqual ( len ( back_order_out ) , 1 , ' Back order should be created. ' )
# Check total move lines of back order.
self . assertEqual ( len ( back_order_out . move_lines ) , 2 , ' Wrong number of move lines ' )
# Check back order should be created with 8 quantity of product A.
product_a_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' picking_id ' , ' = ' , back_order_out . id ) ] , limit = 1 ) . product_uom_qty
self . assertEqual ( product_a_qty , 8.0 , ' Wrong move quantity of product A ( %s found instead of 8) ' % ( product_a_qty ) )
# Check back order should be created with 4 quantity of product D.
product_d_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' picking_id ' , ' = ' , back_order_out . id ) ] , limit = 1 ) . product_uom_qty
self . assertEqual ( product_d_qty , 4.0 , ' Wrong move quantity of product D ( %s found instead of 4) ' % ( product_d_qty ) )
#-----------------------------------------------------------------------
# Check stock location quant quantity and quantity available
# of product A, B, C, D
#-----------------------------------------------------------------------
# Check quants and available quantity for product A
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 2.0 , ' Expecting 2.0 Unit , got %.4f Unit on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . productA . qty_available , 2.0 , ' Wrong quantity available ( %s found instead of 2.0) ' % ( self . productA . qty_available ) )
# Check quants and available quantity for product B
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productB . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
self . assertFalse ( quants , ' No quant should found as outgoing shipment took everything out of stock. ' )
self . assertEqual ( self . productB . qty_available , 0.0 , ' Product B should have zero quantity available. ' )
# Check quants and available quantity for product C
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 2.0 , ' Expecting 2.0 Unit, got %.4f Unit on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . productC . qty_available , 2.0 , ' Wrong quantity available ( %s found instead of 2.0) ' % ( self . productC . qty_available ) )
# Check quants and available quantity for product D
quant = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] , limit = 1 )
self . assertEqual ( quant . qty , 1.0 , ' Expecting 1.0 Unit , got %.4f Unit on location stock! ' % ( quant . qty ) )
self . assertEqual ( self . productD . qty_available , 1.0 , ' Wrong quantity available ( %s found instead of 1.0) ' % ( self . productD . qty_available ) )
#-----------------------------------------------------------------------
# Back Order of Incoming shipment
#-----------------------------------------------------------------------
lot3_productC = LotObj . create ( { ' name ' : ' Lot 3 ' , ' product_id ' : self . productC . id } )
lot4_productC = LotObj . create ( { ' name ' : ' Lot 4 ' , ' product_id ' : self . productC . id } )
lot5_productC = LotObj . create ( { ' name ' : ' Lot 5 ' , ' product_id ' : self . productC . id } )
lot6_productC = LotObj . create ( { ' name ' : ' Lot 6 ' , ' product_id ' : self . productC . id } )
lot1_productD = LotObj . create ( { ' name ' : ' Lot 1 ' , ' product_id ' : self . productD . id } )
lot2_productD = LotObj . create ( { ' name ' : ' Lot 2 ' , ' product_id ' : self . productD . id } )
# Confirm back order of incoming shipment.
back_order_in . action_confirm ( )
self . assertEqual ( back_order_in . state , ' assigned ' , ' Wrong state of incoming shipment back order. ' )
for move in back_order_in . move_lines :
self . assertEqual ( move . state , ' assigned ' , ' Wrong state of move line. ' )
# ----------------------------------------------------------------------
# Replace pack operation (Back order of Incoming shipment)
# ----------------------------------------------------------------------
back_order_in . do_prepare_partial ( )
packD = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' picking_id ' , ' = ' , back_order_in . id ) ] )
self . assertEqual ( len ( packD ) , 1 , ' Wrong number of pack operation. ' )
packD . write ( { ' product_qty ' : 4 , ' lot_id ' : lot1_productD . id } )
self . StockPackObj . create ( {
' product_id ' : self . productD . id ,
' product_qty ' : 4 ,
' product_uom_id ' : self . productD . uom_id . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location ,
' picking_id ' : back_order_in . id ,
' lot_id ' : lot2_productD . id } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' picking_id ' , ' = ' , back_order_in . id ) ] , limit = 1 ) . write ( { ' product_qty ' : 1 , ' lot_id ' : lot3_productC . id } )
self . StockPackObj . create ( {
' product_id ' : self . productC . id ,
' product_qty ' : 1 ,
' product_uom_id ' : self . productC . uom_id . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location ,
' picking_id ' : back_order_in . id ,
' lot_id ' : lot4_productC . id } )
self . StockPackObj . create ( {
' product_id ' : self . productC . id ,
' product_qty ' : 2 ,
' product_uom_id ' : self . productC . uom_id . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location ,
' picking_id ' : back_order_in . id ,
' lot_id ' : lot5_productC . id } )
self . StockPackObj . create ( {
' product_id ' : self . productC . id ,
' product_qty ' : 2 ,
' product_uom_id ' : self . productC . uom_id . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location ,
' picking_id ' : back_order_in . id ,
' lot_id ' : lot6_productC . id } )
self . StockPackObj . create ( {
' product_id ' : self . productA . id ,
' product_qty ' : 10 ,
' product_uom_id ' : self . productA . uom_id . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location ,
' picking_id ' : back_order_in . id } )
back_order_in . do_transfer ( )
# ----------------------------------------------------------------------
# Check state, quantity and total moves (Back order of Incoming shipment).
# ----------------------------------------------------------------------
# Check total no of move lines.
self . assertEqual ( len ( back_order_in . move_lines ) , 6 , ' Wrong number of move lines ' )
# Check incoming shipment state must be 'Done'.
self . assertEqual ( back_order_in . state , ' done ' , ' Wrong state of picking. ' )
# Check incoming shipment move lines state must be 'Done'.
for move in back_order_in . move_lines :
self . assertEqual ( move . state , ' done ' , ' Wrong state of move lines. ' )
# Check product A done quantity must be 10
movesA = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' picking_id ' , ' = ' , back_order_in . id ) ] )
self . assertEqual ( movesA . product_uom_qty , 10 , " Wrong move quantity of product A ( %s found instead of 10) " % ( movesA . product_uom_qty ) )
# Check product C done quantity must be 3.0, 1.0, 2.0
movesC = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' picking_id ' , ' = ' , back_order_in . id ) ] )
c_done_qty = [ move . product_uom_qty for move in movesC ]
self . assertEqual ( set ( c_done_qty ) , set ( [ 3.0 , 1.0 , 2.0 ] ) , ' Wrong quantity of moves product C. ' )
# Check product D done quantity must be 5.0 and 3.0
movesD = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' picking_id ' , ' = ' , back_order_in . id ) ] )
d_done_qty = [ move . product_uom_qty for move in movesD ]
self . assertEqual ( set ( d_done_qty ) , set ( [ 3.0 , 5.0 ] ) , ' Wrong quantity of moves product D. ' )
# Check no back order is created.
self . assertFalse ( self . PickingObj . search ( [ ( ' backorder_id ' , ' = ' , back_order_in . id ) ] ) , " Should not create any back order. " )
#-----------------------------------------------------------------------
# Check stock location quant quantity and quantity available
# of product A, B, C, D
#-----------------------------------------------------------------------
# Check quants and available quantity for product A.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 12.0 , ' Wrong total stock location quantity ( %s found instead of 12) ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . productA . qty_available , 12.0 , ' Wrong quantity available ( %s found instead of 12) ' % ( self . productA . qty_available ) )
# Check quants and available quantity for product B.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productB . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
self . assertFalse ( quants , ' No quant should found as outgoing shipment took everything out of stock ' )
self . assertEqual ( self . productB . qty_available , 0.0 , ' Total quantity in stock should be 0 as the backorder took everything out of stock ' )
# Check quants and available quantity for product C.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productC . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 8.0 , ' Wrong total stock location quantity ( %s found instead of 8) ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . productC . qty_available , 8.0 , ' Wrong quantity available ( %s found instead of 8) ' % ( self . productC . qty_available ) )
# Check quants and available quantity for product D.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productD . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 9.0 , ' Wrong total stock location quantity ( %s found instead of 9) ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . productD . qty_available , 9.0 , ' Wrong quantity available ( %s found instead of 9) ' % ( self . productD . qty_available ) )
#-----------------------------------------------------------------------
# Back order of Outgoing shipment
# ----------------------------------------------------------------------
back_order_out . do_prepare_partial ( )
back_order_out . do_transfer ( )
# Check stock location quants and available quantity for product A.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . productA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertGreaterEqual ( float_round ( sum ( total_qty ) , precision_rounding = 0.0001 ) , 1 , ' Total stock location quantity for product A should not be nagative. ' )
def test_10_pickings_transfer_with_different_uom ( self ) :
""" Picking transfer with diffrent unit of meassure. """
# ----------------------------------------------------------------------
# Create incoming shipment of products DozA, SDozA, SDozARound, kgB, gB
# ----------------------------------------------------------------------
2015-01-06 16:15:51 +00:00
# DozA ( 10 Dozen ) , SDozA ( 10.5 SuperDozen )
# SDozARound ( 10.5 10.5 SuperDozenRound ) , kgB ( 0.020 kg )
2015-01-05 13:34:14 +00:00
# gB ( 525.3 g )
# ----------------------------------------------------------------------
picking_in_A = self . PickingObj . create ( {
' partner_id ' : self . partner_delta_id ,
' picking_type_id ' : self . picking_type_in } )
self . MoveObj . create ( {
' name ' : self . DozA . name ,
' product_id ' : self . DozA . id ,
' product_uom_qty ' : 10 ,
' product_uom ' : self . DozA . uom_id . id ,
' picking_id ' : picking_in_A . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . SDozA . name ,
' product_id ' : self . SDozA . id ,
' product_uom_qty ' : 10.5 ,
' product_uom ' : self . SDozA . uom_id . id ,
' picking_id ' : picking_in_A . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . SDozARound . name ,
' product_id ' : self . SDozARound . id ,
' product_uom_qty ' : 10.5 ,
' product_uom ' : self . SDozARound . uom_id . id ,
' picking_id ' : picking_in_A . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . kgB . name ,
' product_id ' : self . kgB . id ,
' product_uom_qty ' : 0.020 ,
' product_uom ' : self . kgB . uom_id . id ,
' picking_id ' : picking_in_A . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . gB . name ,
' product_id ' : self . gB . id ,
' product_uom_qty ' : 525.3 ,
' product_uom ' : self . gB . uom_id . id ,
' picking_id ' : picking_in_A . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
# Check incoming shipment move lines state.
for move in picking_in_A . move_lines :
self . assertEqual ( move . state , ' draft ' , ' Move state must be draft. ' )
# Confirm incoming shipment.
picking_in_A . action_confirm ( )
# Check incoming shipment move lines state.
for move in picking_in_A . move_lines :
self . assertEqual ( move . state , ' assigned ' , ' Move state must be draft. ' )
picking_in_A . do_prepare_partial ( )
# ----------------------------------------------------
# Check pack operation quantity of incoming shipments.
# ----------------------------------------------------
PackSdozAround = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . SDozARound . id ) , ( ' picking_id ' , ' = ' , picking_in_A . id ) ] , limit = 1 )
self . assertEqual ( PackSdozAround . product_qty , 11 , ' Wrong quantity in pack operation ( %s found instead of 11) ' % ( PackSdozAround . product_qty ) )
picking_in_A . do_transfer ( )
#-----------------------------------------------------------------------
# Check stock location quant quantity and quantity available
#-----------------------------------------------------------------------
# Check quants and available quantity for product DozA
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 10 , ' Expecting 10 Dozen , got %.4f Dozen on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . DozA . qty_available , 10 , ' Wrong quantity available ( %s found instead of 10) ' % ( self . DozA . qty_available ) )
# Check quants and available quantity for product SDozA
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . SDozA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 10.5 , ' Expecting 10.5 SDozen , got %.4f SDozen on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . SDozA . qty_available , 10.5 , ' Wrong quantity available ( %s found instead of 10.5) ' % ( self . SDozA . qty_available ) )
# Check quants and available quantity for product SDozARound
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . SDozARound . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 11 , ' Expecting 11 SDozenRound , got %.4f SDozenRound on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . SDozARound . qty_available , 11 , ' Wrong quantity available ( %s found instead of 11) ' % ( self . SDozARound . qty_available ) )
# Check quants and available quantity for product gB
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . gB . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 525.3 , ' Expecting 525.3 gram , got %.4f gram on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . gB . qty_available , 525.3 , ' Wrong quantity available ( %s found instead of 525.3 ' % ( self . gB . qty_available ) )
# Check quants and available quantity for product kgB
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . kgB . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 0.020 , ' Expecting 0.020 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . kgB . qty_available , 0.020 , ' Wrong quantity available ( %s found instead of 0.020) ' % ( self . kgB . qty_available ) )
# ----------------------------------------------------------------------
# Create Incoming Shipment B
# ----------------------------------------------------------------------
picking_in_B = self . PickingObj . create ( {
' partner_id ' : self . partner_delta_id ,
' picking_type_id ' : self . picking_type_in } )
self . MoveObj . create ( {
' name ' : self . DozA . name ,
' product_id ' : self . DozA . id ,
' product_uom_qty ' : 120 ,
' product_uom ' : self . uom_unit . id ,
' picking_id ' : picking_in_B . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . SDozA . name ,
' product_id ' : self . SDozA . id ,
' product_uom_qty ' : 1512 ,
' product_uom ' : self . uom_unit . id ,
' picking_id ' : picking_in_B . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . SDozARound . name ,
' product_id ' : self . SDozARound . id ,
' product_uom_qty ' : 1584 ,
' product_uom ' : self . uom_unit . id ,
' picking_id ' : picking_in_B . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . kgB . name ,
' product_id ' : self . kgB . id ,
' product_uom_qty ' : 20.0 ,
' product_uom ' : self . uom_gm . id ,
' picking_id ' : picking_in_B . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
self . MoveObj . create ( {
' name ' : self . gB . name ,
' product_id ' : self . gB . id ,
' product_uom_qty ' : 0.525 ,
' product_uom ' : self . uom_kg . id ,
' picking_id ' : picking_in_B . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
# Check incoming shipment move lines state.
for move in picking_in_B . move_lines :
self . assertEqual ( move . state , ' draft ' , ' Wrong state of move line. ' )
# Confirm incoming shipment.
picking_in_B . action_confirm ( )
# Check incoming shipment move lines state.
for move in picking_in_B . move_lines :
self . assertEqual ( move . state , ' assigned ' , ' Wrong state of move line. ' )
picking_in_B . do_prepare_partial ( )
# ----------------------------------------------------------------------
# Check product quantity and unit of measure of pack operaation.
# ----------------------------------------------------------------------
# Check pack operation quantity and unit of measure for product DozA.
PackdozA = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( PackdozA . product_qty , 120 , ' Wrong quantity in pack operation ( %s found instead of 120) ' % ( PackdozA . product_qty ) )
self . assertEqual ( PackdozA . product_uom_id . id , self . uom_unit . id , ' Wrong uom in pack operation for product DozA. ' )
# Check pack operation quantity and unit of measure for product SDozA.
PackSdozA = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . SDozA . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( PackSdozA . product_qty , 1512 , ' Wrong quantity in pack operation ( %s found instead of 1512) ' % ( PackSdozA . product_qty ) )
self . assertEqual ( PackSdozA . product_uom_id . id , self . uom_unit . id , ' Wrong uom in pack operation for product SDozA. ' )
# Check pack operation quantity and unit of measure for product SDozARound.
PackSdozAround = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . SDozARound . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( PackSdozAround . product_qty , 1584 , ' Wrong quantity in pack operation ( %s found instead of 1584) ' % ( PackSdozAround . product_qty ) )
self . assertEqual ( PackSdozAround . product_uom_id . id , self . uom_unit . id , ' Wrong uom in pack operation for product SDozARound. ' )
# Check pack operation quantity and unit of measure for product gB.
packgB = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . gB . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( packgB . product_qty , 525 , ' Wrong quantity in pack operation ( %s found instead of 525) ' % ( packgB . product_qty ) )
self . assertEqual ( packgB . product_uom_id . id , self . uom_gm . id , ' Wrong uom in pack operation for product gB. ' )
# Check pack operation quantity and unit of measure for product kgB.
packkgB = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . kgB . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( packkgB . product_qty , 20.0 , ' Wrong quantity in pack operation ( %s found instead of 20) ' % ( packkgB . product_qty ) )
self . assertEqual ( packkgB . product_uom_id . id , self . uom_gm . id , ' Wrong uom in pack operation for product kgB ' )
# ----------------------------------------------------------------------
# Replace pack operation of incoming shipment.
# ----------------------------------------------------------------------
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . kgB . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] ) . write ( {
' product_qty ' : 0.020 , ' product_uom_id ' : self . uom_kg . id } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . gB . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] ) . write ( {
' product_qty ' : 525.3 , ' product_uom_id ' : self . uom_gm . id } )
self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] ) . write ( {
' product_qty ' : 4 , ' product_uom_id ' : self . uom_dozen . id } )
self . StockPackObj . create ( {
' product_id ' : self . DozA . id ,
' product_qty ' : 48 ,
' product_uom_id ' : self . uom_unit . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location ,
' picking_id ' : picking_in_B . id } )
# Transfer product.
# -----------------
picking_in_B . do_transfer ( )
#-----------------------------------------------------------------------
# Check incoming shipment
#-----------------------------------------------------------------------
# Check incoming shipment state.
self . assertEqual ( picking_in_B . state , ' done ' , ' Incoming shipment state should be done. ' )
# Check incoming shipment move lines state.
for move in picking_in_B . move_lines :
self . assertEqual ( move . state , ' done ' , ' Wrong state of move line. ' )
# Check total done move lines for incoming shipment.
self . assertEqual ( len ( picking_in_B . move_lines ) , 6 , ' Wrong number of move lines ' )
# Check product DozA done quantity.
moves_DozA = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( moves_DozA . product_uom_qty , 96 , ' Wrong move quantity ( %s found instead of 96) ' % ( moves_DozA . product_uom_qty ) )
self . assertEqual ( moves_DozA . product_uom . id , self . uom_unit . id , ' Wrong uom in move for product DozA. ' )
# Check product SDozA done quantity.
moves_SDozA = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . SDozA . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( moves_SDozA . product_uom_qty , 1512 , ' Wrong move quantity ( %s found instead of 1512) ' % ( moves_SDozA . product_uom_qty ) )
self . assertEqual ( moves_SDozA . product_uom . id , self . uom_unit . id , ' Wrong uom in move for product SDozA. ' )
# Check product SDozARound done quantity.
moves_SDozARound = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . SDozARound . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( moves_SDozARound . product_uom_qty , 1584 , ' Wrong move quantity ( %s found instead of 1584) ' % ( moves_SDozARound . product_uom_qty ) )
self . assertEqual ( moves_SDozARound . product_uom . id , self . uom_unit . id , ' Wrong uom in move for product SDozARound. ' )
# Check product kgB done quantity.
moves_kgB = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . kgB . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) ] , limit = 1 )
self . assertEqual ( moves_kgB . product_uom_qty , 20 , ' Wrong quantity in move ( %s found instead of 20) ' % ( moves_kgB . product_uom_qty ) )
self . assertEqual ( moves_kgB . product_uom . id , self . uom_gm . id , ' Wrong uom in move for product kgB. ' )
# Check two moves created for product gB with quantity (0.525 kg and 0.3 g)
moves_gB_kg = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . gB . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) , ( ' product_uom ' , ' = ' , self . uom_kg . id ) ] , limit = 1 )
self . assertEqual ( moves_gB_kg . product_uom_qty , 0.525 , ' Wrong move quantity ( %s found instead of 0.525) ' % ( moves_gB_kg . product_uom_qty ) )
self . assertEqual ( moves_gB_kg . product_uom . id , self . uom_kg . id , ' Wrong uom in move for product gB. ' )
moves_gB_g = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . gB . id ) , ( ' picking_id ' , ' = ' , picking_in_B . id ) , ( ' product_uom ' , ' = ' , self . uom_gm . id ) ] , limit = 1 )
self . assertEqual ( moves_gB_g . product_uom_qty , 0.3 , ' Wrong move quantity ( %s found instead of 0.3) ' % ( moves_gB_g . product_uom_qty ) )
self . assertEqual ( moves_gB_g . product_uom . id , self . uom_gm . id , ' Wrong uom in move for product gB. ' )
# ----------------------------------------------------------------------
# Check Back order of Incoming shipment.
# ----------------------------------------------------------------------
# Check back order created or not.
bo_in_B = self . PickingObj . search ( [ ( ' backorder_id ' , ' = ' , picking_in_B . id ) ] )
self . assertEqual ( len ( bo_in_B ) , 1 , ' Back order should be created. ' )
# Check total move lines of back order.
self . assertEqual ( len ( bo_in_B . move_lines ) , 1 , ' Wrong number of move lines ' )
# Check back order created with correct quantity and uom or not.
moves_DozA = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' picking_id ' , ' = ' , bo_in_B . id ) ] , limit = 1 )
self . assertEqual ( moves_DozA . product_uom_qty , 24.0 , ' Wrong move quantity ( %s found instead of 0.525) ' % ( moves_DozA . product_uom_qty ) )
self . assertEqual ( moves_DozA . product_uom . id , self . uom_unit . id , ' Wrong uom in move for product DozA. ' )
# ----------------------------------------------------------------------
# Check product stock location quantity and quantity available.
# ----------------------------------------------------------------------
# Check quants and available quantity for product DozA
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 18 , ' Expecting 18 Dozen , got %.4f Dozen on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . DozA . qty_available , 18 , ' Wrong quantity available ( %s found instead of 18) ' % ( self . DozA . qty_available ) )
# Check quants and available quantity for product SDozA
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . SDozA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 21 , ' Expecting 18 SDozen , got %.4f SDozen on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . SDozA . qty_available , 21 , ' Wrong quantity available ( %s found instead of 21) ' % ( self . SDozA . qty_available ) )
# Check quants and available quantity for product SDozARound
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . SDozARound . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 22 , ' Expecting 22 SDozenRound , got %.4f SDozenRound on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . SDozARound . qty_available , 22 , ' Wrong quantity available ( %s found instead of 22) ' % ( self . SDozARound . qty_available ) )
# Check quants and available quantity for product gB.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . gB . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 1050.6 , ' Expecting 1050.6 Gram , got %.4f Gram on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . gB . qty_available , 1050.6 , ' Wrong quantity available ( %s found instead of 1050.6) ' % ( self . gB . qty_available ) )
# Check quants and available quantity for product kgB.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . kgB . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 0.040 , ' Expecting 0.040 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . kgB . qty_available , 0.040 , ' Wrong quantity available ( %s found instead of 0.040) ' % ( self . kgB . qty_available ) )
# ----------------------------------------------------------------------
# Create outgoing shipment.
# ----------------------------------------------------------------------
before_out_quantity = self . kgB . qty_available
picking_out = self . PickingObj . create ( {
' partner_id ' : self . partner_agrolite_id ,
' picking_type_id ' : self . picking_type_out } )
self . MoveObj . create ( {
' name ' : self . kgB . name ,
' product_id ' : self . kgB . id ,
' product_uom_qty ' : 0.966 ,
' product_uom ' : self . uom_gm . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
self . MoveObj . create ( {
' name ' : self . kgB . name ,
' product_id ' : self . kgB . id ,
' product_uom_qty ' : 0.034 ,
' product_uom ' : self . uom_gm . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
picking_out . action_confirm ( )
picking_out . action_assign ( )
picking_out . do_prepare_partial ( )
picking_out . do_transfer ( )
# Check quantity difference after stock transfer.
quantity_diff = before_out_quantity - self . kgB . qty_available
self . assertEqual ( float_round ( quantity_diff , precision_rounding = 0.0001 ) , 0.001 , ' Wrong quantity diffrence. ' )
self . assertEqual ( self . kgB . qty_available , 0.039 , ' Wrong quantity available ( %s found instead of 0.039) ' % ( self . kgB . qty_available ) )
# ======================================================================
# Outgoing shipments.
# ======================================================================
# Create Outgoing shipment with ...
# product DozA ( 54 Unit ) , SDozA ( 288 Unit )
# product SDozRound ( 360 unit ) , product gB ( 0.503 kg )
# product kgB ( 19 g )
# ======================================================================
picking_out = self . PickingObj . create ( {
' partner_id ' : self . partner_agrolite_id ,
' picking_type_id ' : self . picking_type_out } )
self . MoveObj . create ( {
' name ' : self . DozA . name ,
' product_id ' : self . DozA . id ,
' product_uom_qty ' : 54 ,
' product_uom ' : self . uom_unit . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
self . MoveObj . create ( {
' name ' : self . SDozA . name ,
' product_id ' : self . SDozA . id ,
' product_uom_qty ' : 288 ,
' product_uom ' : self . uom_unit . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
self . MoveObj . create ( {
' name ' : self . SDozARound . name ,
' product_id ' : self . SDozARound . id ,
' product_uom_qty ' : 360 ,
' product_uom ' : self . uom_unit . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
self . MoveObj . create ( {
' name ' : self . gB . name ,
' product_id ' : self . gB . id ,
' product_uom_qty ' : 0.503 ,
' product_uom ' : self . uom_kg . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
self . MoveObj . create ( {
' name ' : self . kgB . name ,
' product_id ' : self . kgB . id ,
' product_uom_qty ' : 20 ,
' product_uom ' : self . uom_gm . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
# Confirm outgoing shipment.
picking_out . action_confirm ( )
for move in picking_out . move_lines :
self . assertEqual ( move . state , ' confirmed ' , ' Wrong state of move line. ' )
# Assing product to outgoing shipments
picking_out . action_assign ( )
for move in picking_out . move_lines :
self . assertEqual ( move . state , ' assigned ' , ' Wrong state of move line. ' )
# Check product A available quantity
DozA_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( DozA_qty , 4.5 , ' Wrong move quantity availability ( %s found instead of 4.5) ' % ( DozA_qty ) )
# Check product B available quantity
SDozA_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . SDozA . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( SDozA_qty , 2 , ' Wrong move quantity availability ( %s found instead of 2) ' % ( SDozA_qty ) )
# Check product C available quantity
SDozARound_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . SDozARound . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( SDozARound_qty , 3 , ' Wrong move quantity availability ( %s found instead of 3) ' % ( SDozARound_qty ) )
# Check product D available quantity
gB_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . gB . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( gB_qty , 503 , ' Wrong move quantity availability ( %s found instead of 503) ' % ( gB_qty ) )
# Check product D available quantity
kgB_qty = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . kgB . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 ) . availability
self . assertEqual ( kgB_qty , 0.020 , ' Wrong move quantity availability ( %s found instead of 0.020) ' % ( kgB_qty ) )
picking_out . action_confirm ( )
picking_out . action_assign ( )
picking_out . do_prepare_partial ( )
picking_out . do_transfer ( )
# ----------------------------------------------------------------------
# Check product stock location quantity and quantity available.
# ----------------------------------------------------------------------
# Check quants and available quantity for product DozA
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 13.5 , ' Expecting 13.5 Dozen , got %.4f Dozen on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . DozA . qty_available , 13.5 , ' Wrong quantity available ( %s found instead of 13.5) ' % ( self . DozA . qty_available ) )
# Check quants and available quantity for product SDozA
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . SDozA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 19 , ' Expecting 19 SDozen , got %.4f SDozen on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . SDozA . qty_available , 19 , ' Wrong quantity available ( %s found instead of 19) ' % ( self . SDozA . qty_available ) )
# Check quants and available quantity for product SDozARound
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . SDozARound . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 19 , ' Expecting 19 SDozRound , got %.4f SDozRound on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . SDozARound . qty_available , 19 , ' Wrong quantity available ( %s found instead of 19) ' % ( self . SDozARound . qty_available ) )
# Check quants and available quantity for product gB.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . gB . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( float_round ( sum ( total_qty ) , precision_rounding = 0.0001 ) , 547.6 , ' Expecting 547.6 g , got %.4f g on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . gB . qty_available , 547.6 , ' Wrong quantity available ( %s found instead of 547.6) ' % ( self . gB . qty_available ) )
# Check quants and available quantity for product kgB.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . kgB . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 0.019 , ' Expecting 0.019 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . kgB . qty_available , 0.019 , ' Wrong quantity available ( %s found instead of 0.019) ' % ( self . kgB . qty_available ) )
# ----------------------------------------------------------------------
# Receipt back order of incoming shipment.
# ----------------------------------------------------------------------
bo_in_B . do_prepare_partial ( )
bo_in_B . do_transfer ( )
# Check quants and available quantity for product kgB.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . DozA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 15.5 , ' Expecting 15.5 Dozen , got %.4f Dozen on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . DozA . qty_available , 15.5 , ' Wrong quantity available ( %s found instead of 15.5) ' % ( self . DozA . qty_available ) )
# -----------------------------------------
2015-01-06 16:15:51 +00:00
# Create product in kg and receive in ton.
2015-01-05 13:34:14 +00:00
# -----------------------------------------
productKG = self . ProductObj . create ( { ' name ' : ' Product KG ' , ' uom_id ' : self . uom_kg . id , ' uom_po_id ' : self . uom_kg . id } )
picking_in = self . PickingObj . create ( {
' partner_id ' : self . partner_delta_id ,
' picking_type_id ' : self . picking_type_in } )
self . MoveObj . create ( {
' name ' : productKG . name ,
' product_id ' : productKG . id ,
' product_uom_qty ' : 1.0 ,
' product_uom ' : self . uom_tone . id ,
' picking_id ' : picking_in . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
# Check incoming shipment state.
self . assertEqual ( picking_in . state , ' draft ' , ' Incoming shipment state should be draft. ' )
# Check incoming shipment move lines state.
for move in picking_in . move_lines :
self . assertEqual ( move . state , ' draft ' , ' Wrong state of move line. ' )
# Confirm incoming shipment.
picking_in . action_confirm ( )
# Check incoming shipment move lines state.
for move in picking_in . move_lines :
self . assertEqual ( move . state , ' assigned ' , ' Wrong state of move line. ' )
picking_in . do_prepare_partial ( )
# Check pack operation quantity.
packKG = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] , limit = 1 )
self . assertEqual ( packKG . product_qty , 1000 , ' Wrong product quantity in pack operation ( %s found instead of 1000) ' % ( packKG . product_qty ) )
self . assertEqual ( packKG . product_uom_id . id , self . uom_kg . id , ' Wrong product uom in pack operation. ' )
# Transfer Incoming shipment.
picking_in . do_transfer ( )
#-----------------------------------------------------------------------
# Check incoming shipment after transfer.
#-----------------------------------------------------------------------
# Check incoming shipment state.
self . assertEqual ( picking_in . state , ' done ' , ' Incoming shipment state should be done. ' )
# Check incoming shipment move lines state.
for move in picking_in . move_lines :
self . assertEqual ( move . state , ' done ' , ' Wrong state of move lines. ' )
# Check total done move lines for incoming shipment.
self . assertEqual ( len ( picking_in . move_lines ) , 1 , ' Wrong number of move lines ' )
# Check product DozA done quantity.
move = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , picking_in . id ) ] , limit = 1 )
self . assertEqual ( move . product_uom_qty , 1 , ' Wrong product quantity in done move. ' )
self . assertEqual ( move . product_uom . id , self . uom_tone . id , ' Wrong unit of measure in done move. ' )
self . assertEqual ( productKG . qty_available , 1000 , ' Wrong quantity available of product ( %s found instead of 1000) ' % ( productKG . qty_available ) )
picking_out = self . PickingObj . create ( {
' partner_id ' : self . partner_agrolite_id ,
' picking_type_id ' : self . picking_type_out } )
self . MoveObj . create ( {
' name ' : productKG . name ,
' product_id ' : productKG . id ,
' product_uom_qty ' : 2.5 ,
' product_uom ' : self . uom_gm . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
picking_out . action_confirm ( )
picking_out . action_assign ( )
picking_out . do_prepare_partial ( )
pack_opt = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , picking_out . id ) ] , limit = 1 )
pack_opt . write ( { ' product_qty ' : 0.5 } )
picking_out . do_transfer ( )
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
# Check total quantity stock location.
self . assertEqual ( sum ( total_qty ) , 999.9995 , ' Expecting 999.9995 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
# Check Back order created or not.
#---------------------------------
bo_out_1 = self . PickingObj . search ( [ ( ' backorder_id ' , ' = ' , picking_out . id ) ] )
self . assertEqual ( len ( bo_out_1 ) , 1 , ' Back order should be created. ' )
# Check total move lines of back order.
self . assertEqual ( len ( bo_out_1 . move_lines ) , 1 , ' Wrong number of move lines ' )
moves_KG = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , bo_out_1 . id ) ] , limit = 1 )
# Check back order created with correct quantity and uom or not.
self . assertEqual ( moves_KG . product_uom_qty , 2.0 , ' Wrong move quantity ( %s found instead of 2.0) ' % ( moves_KG . product_uom_qty ) )
self . assertEqual ( moves_KG . product_uom . id , self . uom_gm . id , ' Wrong uom in move for product KG. ' )
bo_out_1 . action_assign ( )
bo_out_1 . do_prepare_partial ( )
pack_opt = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , bo_out_1 . id ) ] , limit = 1 )
pack_opt . write ( { ' product_qty ' : 0.5 } )
bo_out_1 . do_transfer ( )
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
# Check total quantity stock location.
self . assertEqual ( sum ( total_qty ) , 999.9990 , ' Expecting 999.9990 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
# Check Back order created or not.
#---------------------------------
bo_out_2 = self . PickingObj . search ( [ ( ' backorder_id ' , ' = ' , bo_out_1 . id ) ] )
self . assertEqual ( len ( bo_out_2 ) , 1 , ' Back order should be created. ' )
# Check total move lines of back order.
self . assertEqual ( len ( bo_out_2 . move_lines ) , 1 , ' Wrong number of move lines ' )
# Check back order created with correct move quantity and uom or not.
moves_KG = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , bo_out_2 . id ) ] , limit = 1 )
self . assertEqual ( moves_KG . product_uom_qty , 1.5 , ' Wrong move quantity ( %s found instead of 1.5) ' % ( moves_KG . product_uom_qty ) )
self . assertEqual ( moves_KG . product_uom . id , self . uom_gm . id , ' Wrong uom in move for product KG. ' )
bo_out_2 . action_assign ( )
bo_out_2 . do_prepare_partial ( )
pack_opt = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , bo_out_2 . id ) ] , limit = 1 )
pack_opt . write ( { ' product_qty ' : 0.5 } )
bo_out_2 . do_transfer ( )
# Check total quantity stock location of product KG.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 999.9985 , ' Expecting 999.9985 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
# Check Back order created or not.
#---------------------------------
bo_out_3 = self . PickingObj . search ( [ ( ' backorder_id ' , ' = ' , bo_out_2 . id ) ] )
self . assertEqual ( len ( bo_out_3 ) , 1 , ' Back order should be created. ' )
# Check total move lines of back order.
self . assertEqual ( len ( bo_out_3 . move_lines ) , 1 , ' Wrong number of move lines ' )
# Check back order created with correct quantity and uom or not.
moves_KG = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , bo_out_3 . id ) ] , limit = 1 )
self . assertEqual ( moves_KG . product_uom_qty , 1 , ' Wrong move quantity ( %s found instead of 1.0) ' % ( moves_KG . product_uom_qty ) )
self . assertEqual ( moves_KG . product_uom . id , self . uom_gm . id , ' Wrong uom in move for product KG. ' )
bo_out_3 . action_assign ( )
bo_out_3 . do_prepare_partial ( )
pack_opt = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , bo_out_3 . id ) ] , limit = 1 )
pack_opt . write ( { ' product_qty ' : 0.5 } )
bo_out_3 . do_transfer ( )
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 999.9980 , ' Expecting 999.9980 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
# Check Back order created or not.
#---------------------------------
bo_out_4 = self . PickingObj . search ( [ ( ' backorder_id ' , ' = ' , bo_out_3 . id ) ] )
self . assertEqual ( len ( bo_out_4 ) , 1 , ' Back order should be created. ' )
# Check total move lines of back order.
self . assertEqual ( len ( bo_out_4 . move_lines ) , 1 , ' Wrong number of move lines ' )
# Check back order created with correct quantity and uom or not.
moves_KG = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , bo_out_4 . id ) ] , limit = 1 )
self . assertEqual ( moves_KG . product_uom_qty , 0.5 , ' Wrong move quantity ( %s found instead of 0.5) ' % ( moves_KG . product_uom_qty ) )
self . assertEqual ( moves_KG . product_uom . id , self . uom_gm . id , ' Wrong uom in move for product KG. ' )
bo_out_4 . action_assign ( )
bo_out_4 . do_prepare_partial ( )
pack_opt = self . StockPackObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' picking_id ' , ' = ' , bo_out_4 . id ) ] , limit = 1 )
pack_opt . write ( { ' product_qty ' : 0.5 } )
bo_out_4 . do_transfer ( )
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 999.9975 , ' Expecting 999.9975 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
def test_20_create_inventory_with_different_uom ( self ) :
""" Create inventory with different unit of measure. """
# ------------------------------------------------
# Test inventory with product A(Unit).
# ------------------------------------------------
inventory = self . InvObj . create ( { ' name ' : ' Test ' ,
' product_id ' : self . UnitA . id ,
' filter ' : ' product ' } )
inventory . prepare_inventory ( )
self . assertFalse ( inventory . line_ids , " Inventory line should not created. " )
inventory_line = self . InvLineObj . create ( {
' inventory_id ' : inventory . id ,
' product_id ' : self . UnitA . id ,
' product_uom_id ' : self . uom_dozen . id ,
' product_qty ' : 10 ,
' location_id ' : self . stock_location } )
inventory . action_done ( )
# Check quantity available of product UnitA.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . UnitA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 120 , ' Expecting 120 Units , got %.4f Units on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . UnitA . qty_available , 120 , ' Expecting 120 Units , got %.4f Units of quantity available! ' % ( self . UnitA . qty_available ) )
# Create Inventory again for product UnitA.
inventory = self . InvObj . create ( { ' name ' : ' Test ' ,
' product_id ' : self . UnitA . id ,
' filter ' : ' product ' } )
inventory . prepare_inventory ( )
self . assertEqual ( len ( inventory . line_ids ) , 1 , " One inventory line should be created. " )
inventory_line = self . InvLineObj . search ( [ ( ' product_id ' , ' = ' , self . UnitA . id ) , ( ' inventory_id ' , ' = ' , inventory . id ) ] , limit = 1 )
self . assertEqual ( inventory_line . product_qty , 120 , " Wrong product quantity in inventory line. " )
# Modify the inventory line and set the quantity to 144 product on this new inventory.
inventory_line . write ( { ' product_qty ' : 144 } )
inventory . action_done ( )
move = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , self . UnitA . id ) , ( ' inventory_id ' , ' = ' , inventory . id ) ] , limit = 1 )
self . assertEqual ( move . product_uom_qty , 24 , " Wrong move quantity of product UnitA. " )
# Check quantity available of product UnitA.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , self . UnitA . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 144 , ' Expecting 144 Units , got %.4f Units on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( self . UnitA . qty_available , 144 , ' Expecting 144 Units , got %.4f Units of quantity available! ' % ( self . UnitA . qty_available ) )
# ------------------------------------------------
# Test inventory with product KG.
# ------------------------------------------------
productKG = self . ProductObj . create ( { ' name ' : ' Product KG ' , ' uom_id ' : self . uom_kg . id , ' uom_po_id ' : self . uom_kg . id } )
inventory = self . InvObj . create ( { ' name ' : ' Inventory Product KG ' ,
' product_id ' : productKG . id ,
' filter ' : ' product ' } )
inventory . prepare_inventory ( )
self . assertFalse ( inventory . line_ids , " Inventory line should not created. " )
inventory_line = self . InvLineObj . create ( {
' inventory_id ' : inventory . id ,
' product_id ' : productKG . id ,
' product_uom_id ' : self . uom_tone . id ,
' product_qty ' : 5 ,
' location_id ' : self . stock_location } )
inventory . action_done ( )
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 5000 , ' Expecting 5000 kg , got %.4f kg on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( productKG . qty_available , 5000 , ' Expecting 5000 kg , got %.4f kg of quantity available! ' % ( productKG . qty_available ) )
# Create Inventory again.
inventory = self . InvObj . create ( { ' name ' : ' Test ' ,
' product_id ' : productKG . id ,
' filter ' : ' product ' } )
inventory . prepare_inventory ( )
self . assertEqual ( len ( inventory . line_ids ) , 1 , " One inventory line should be created. " )
inventory_line = self . InvLineObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' inventory_id ' , ' = ' , inventory . id ) ] , limit = 1 )
self . assertEqual ( inventory_line . product_qty , 5000 , " Wrong product quantity in inventory line. " )
# Modify the inventory line and set the quantity to 4000 product on this new inventory.
inventory_line . write ( { ' product_qty ' : 4000 } )
inventory . action_done ( )
# Check inventory move quantity of product KG.
move = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' inventory_id ' , ' = ' , inventory . id ) ] , limit = 1 )
self . assertEqual ( move . product_uom_qty , 1000 , " Wrong move quantity of product KG. " )
# Check quantity available of product KG.
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' location_id ' , ' = ' , self . stock_location ) ] )
total_qty = [ quant . qty for quant in quants ]
self . assertEqual ( sum ( total_qty ) , 4000 , ' Expecting 4000 kg , got %.4f on location stock! ' % ( sum ( total_qty ) ) )
self . assertEqual ( productKG . qty_available , 4000 , ' Expecting 4000 kg , got %.4f of quantity available! ' % ( productKG . qty_available ) )
2015-02-26 10:02:12 +00:00
#--------------------------------------------------------
# TEST PARTIAL INVENTORY WITH PACKS and LOTS
#---------------------------------------------------------
packproduct = self . ProductObj . create ( { ' name ' : ' Pack Product ' , ' uom_id ' : self . uom_unit . id , ' uom_po_id ' : self . uom_unit . id } )
lotproduct = self . ProductObj . create ( { ' name ' : ' Lot Product ' , ' uom_id ' : self . uom_unit . id , ' uom_po_id ' : self . uom_unit . id } )
inventory = self . InvObj . create ( { ' name ' : ' Test Partial and Pack ' ,
' filter ' : ' partial ' ,
' location_id ' : self . stock_location } )
inventory . prepare_inventory ( )
pack_obj = self . env [ ' stock.quant.package ' ]
lot_obj = self . env [ ' stock.production.lot ' ]
pack1 = pack_obj . create ( { ' name ' : ' PACK00TEST1 ' } )
pack2 = pack_obj . create ( { ' name ' : ' PACK00TEST2 ' } )
lot1 = lot_obj . create ( { ' name ' : ' Lot001 ' , ' product_id ' : lotproduct . id } )
move = self . MoveObj . search ( [ ( ' product_id ' , ' = ' , productKG . id ) , ( ' inventory_id ' , ' = ' , inventory . id ) ] , limit = 1 )
self . assertEqual ( len ( move ) , 0 , " Partial filter should not create a lines upon prepare " )
2016-11-15 09:40:57 +00:00
2015-02-26 10:02:12 +00:00
line_vals = [ ]
line_vals + = [ { ' location_id ' : self . stock_location , ' product_id ' : packproduct . id , ' product_qty ' : 10 , ' product_uom_id ' : packproduct . uom_id . id } ]
line_vals + = [ { ' location_id ' : self . stock_location , ' product_id ' : packproduct . id , ' product_qty ' : 20 , ' product_uom_id ' : packproduct . uom_id . id , ' package_id ' : pack1 . id } ]
line_vals + = [ { ' location_id ' : self . stock_location , ' product_id ' : lotproduct . id , ' product_qty ' : 30 , ' product_uom_id ' : lotproduct . uom_id . id , ' prod_lot_id ' : lot1 . id } ]
line_vals + = [ { ' location_id ' : self . stock_location , ' product_id ' : lotproduct . id , ' product_qty ' : 25 , ' product_uom_id ' : lotproduct . uom_id . id , ' prod_lot_id ' : False } ]
inventory . write ( { ' line_ids ' : [ ( 0 , 0 , x ) for x in line_vals ] } )
inventory . action_done ( )
self . assertEqual ( packproduct . qty_available , 30 , " Wrong qty available for packproduct " )
self . assertEqual ( lotproduct . qty_available , 55 , " Wrong qty available for lotproduct " )
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , packproduct . id ) , ( ' location_id ' , ' = ' , self . stock_location ) , ( ' package_id ' , ' = ' , pack1 . id ) ] )
total_qty = sum ( [ quant . qty for quant in quants ] )
self . assertEqual ( total_qty , 20 , ' Expecting 20 units on package 1 of packproduct, but we got %.4f on location stock! ' % ( total_qty ) )
2016-11-15 09:40:57 +00:00
2015-02-26 10:02:12 +00:00
#Create an inventory that will put the lots without lot to 0 and check that taking without pack will not take it from the pack
inventory2 = self . InvObj . create ( { ' name ' : ' Test Partial Lot and Pack2 ' ,
' filter ' : ' partial ' ,
' location_id ' : self . stock_location } )
inventory2 . prepare_inventory ( )
line_vals = [ ]
line_vals + = [ { ' location_id ' : self . stock_location , ' product_id ' : packproduct . id , ' product_qty ' : 20 , ' product_uom_id ' : packproduct . uom_id . id } ]
line_vals + = [ { ' location_id ' : self . stock_location , ' product_id ' : lotproduct . id , ' product_qty ' : 0 , ' product_uom_id ' : lotproduct . uom_id . id , ' prod_lot_id ' : False } ]
line_vals + = [ { ' location_id ' : self . stock_location , ' product_id ' : lotproduct . id , ' product_qty ' : 10 , ' product_uom_id ' : lotproduct . uom_id . id , ' prod_lot_id ' : lot1 . id } ]
inventory2 . write ( { ' line_ids ' : [ ( 0 , 0 , x ) for x in line_vals ] } )
inventory2 . action_done ( )
self . assertEqual ( packproduct . qty_available , 40 , " Wrong qty available for packproduct " )
self . assertEqual ( lotproduct . qty_available , 10 , " Wrong qty available for lotproduct " )
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , lotproduct . id ) , ( ' location_id ' , ' = ' , self . stock_location ) , ( ' lot_id ' , ' = ' , lot1 . id ) ] )
total_qty = sum ( [ quant . qty for quant in quants ] )
self . assertEqual ( total_qty , 10 , ' Expecting 0 units lot of lotproduct, but we got %.4f on location stock! ' % ( total_qty ) )
quants = self . StockQuantObj . search ( [ ( ' product_id ' , ' = ' , lotproduct . id ) , ( ' location_id ' , ' = ' , self . stock_location ) , ( ' lot_id ' , ' = ' , False ) ] )
total_qty = sum ( [ quant . qty for quant in quants ] )
2016-11-15 09:40:57 +00:00
self . assertEqual ( total_qty , 0 , ' Expecting 0 units lot of lotproduct, but we got %.4f on location stock! ' % ( total_qty ) )
def test_30_create_in_out_with_product_pack_lines ( self ) :
picking_in = self . PickingObj . create ( {
' partner_id ' : self . partner_delta_id ,
' picking_type_id ' : self . picking_type_in } )
self . MoveObj . create ( {
' name ' : self . productE . name ,
' product_id ' : self . productE . id ,
' product_uom_qty ' : 10 ,
' product_uom ' : self . productE . uom_id . id ,
' picking_id ' : picking_in . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
picking_in . action_confirm ( )
picking_in . do_prepare_partial ( )
pack_obj = self . env [ ' stock.quant.package ' ]
pack1 = pack_obj . create ( { ' name ' : ' PACKINOUTTEST1 ' } )
pack2 = pack_obj . create ( { ' name ' : ' PACKINOUTTEST2 ' } )
picking_in . pack_operation_ids [ 0 ] . result_package_id = pack1
picking_in . pack_operation_ids [ 0 ] . product_qty = 4
packop2 = picking_in . pack_operation_ids [ 0 ] . copy ( )
packop2 . product_qty = 6
packop2 . result_package_id = pack2
picking_in . do_transfer ( )
self . assertEqual ( sum ( [ x . qty for x in picking_in . move_lines [ 0 ] . quant_ids ] ) , 10.0 , ' Expecting 10 pieces in stock ' )
#check the quants are in the package
self . assertEqual ( sum ( x . qty for x in pack1 . quant_ids ) , 4.0 , ' Pack 1 should have 4 pieces ' )
self . assertEqual ( sum ( x . qty for x in pack2 . quant_ids ) , 6.0 , ' Pack 2 should have 6 pieces ' )
picking_out = self . PickingObj . create ( {
' partner_id ' : self . partner_agrolite_id ,
' picking_type_id ' : self . picking_type_out } )
self . MoveObj . create ( {
' name ' : self . productE . name ,
' product_id ' : self . productE . id ,
' product_uom_qty ' : 3 ,
' product_uom ' : self . productE . uom_id . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
picking_out . action_confirm ( )
picking_out . action_assign ( )
picking_out . do_prepare_partial ( )
packout1 = picking_out . pack_operation_ids [ 0 ]
packout2 = picking_out . pack_operation_ids [ 0 ] . copy ( )
packout1 . product_qty = 2
packout1 . package_id = pack1
packout2 . package_id = pack2
packout2 . product_qty = 1
picking_out . do_transfer ( )
#Check there are no negative quants
neg_quants = self . env [ ' stock.quant ' ] . search ( [ ( ' product_id ' , ' = ' , self . productE . id ) , ( ' qty ' , ' < ' , 0.0 ) ] )
self . assertEqual ( len ( neg_quants ) , 0 , ' There are negative quants! ' )
self . assertEqual ( len ( picking_out . move_lines [ 0 ] . linked_move_operation_ids ) , 2 , ' We should have 2 links in the matching between the move and the operations ' )
self . assertEqual ( len ( picking_out . move_lines [ 0 ] . quant_ids ) , 2 , ' We should have exactly 2 quants in the end ' )
def test_40_create_in_out_with_product_pack_lines ( self ) :
picking_in = self . PickingObj . create ( {
' partner_id ' : self . partner_delta_id ,
' picking_type_id ' : self . picking_type_in } )
self . MoveObj . create ( {
' name ' : self . productE . name ,
' product_id ' : self . productE . id ,
' product_uom_qty ' : 200 ,
' product_uom ' : self . productE . uom_id . id ,
' picking_id ' : picking_in . id ,
' location_id ' : self . supplier_location ,
' location_dest_id ' : self . stock_location } )
picking_in . action_confirm ( )
picking_in . do_prepare_partial ( )
pack_obj = self . env [ ' stock.quant.package ' ]
pack1 = pack_obj . create ( { ' name ' : ' PACKINOUTTEST1 ' } )
pack2 = pack_obj . create ( { ' name ' : ' PACKINOUTTEST2 ' } )
picking_in . pack_operation_ids [ 0 ] . result_package_id = pack1
picking_in . pack_operation_ids [ 0 ] . product_qty = 120
packop2 = picking_in . pack_operation_ids [ 0 ] . copy ( )
packop2 . product_qty = 80
packop2 . result_package_id = pack2
picking_in . do_transfer ( )
self . assertEqual ( sum ( [ x . qty for x in picking_in . move_lines [ 0 ] . quant_ids ] ) , 200.0 , ' Expecting 200 pieces in stock ' )
#check the quants are in the package
self . assertEqual ( sum ( x . qty for x in pack1 . quant_ids ) , 120 , ' Pack 1 should have 120 pieces ' )
self . assertEqual ( sum ( x . qty for x in pack2 . quant_ids ) , 80 , ' Pack 2 should have 80 pieces ' )
picking_out = self . PickingObj . create ( {
' partner_id ' : self . partner_agrolite_id ,
' picking_type_id ' : self . picking_type_out } )
self . MoveObj . create ( {
' name ' : self . productE . name ,
' product_id ' : self . productE . id ,
' product_uom_qty ' : 200 ,
' product_uom ' : self . productE . uom_id . id ,
' picking_id ' : picking_out . id ,
' location_id ' : self . stock_location ,
' location_dest_id ' : self . customer_location } )
picking_out . action_confirm ( )
picking_out . action_assign ( )
picking_out . do_prepare_partial ( )
#Convert entire packs into taking out of packs
packout0 = picking_out . pack_operation_ids [ 0 ]
packout1 = picking_out . pack_operation_ids [ 1 ]
packout0 . write ( { ' product_id ' : self . productE . id ,
' product_qty ' : 120.0 ,
' product_uom_id ' : self . productE . uom_id . id ,
' package_id ' : pack1 . id ,
} )
packout1 . write ( { ' product_id ' : self . productE . id ,
' product_qty ' : 80.0 ,
' product_uom_id ' : self . productE . uom_id . id ,
' package_id ' : pack2 . id ,
} )
picking_out . do_transfer ( )
#Check there are no negative quants
neg_quants = self . env [ ' stock.quant ' ] . search ( [ ( ' product_id ' , ' = ' , self . productE . id ) , ( ' qty ' , ' < ' , 0.0 ) ] )
self . assertEqual ( len ( neg_quants ) , 0 , ' There are negative quants! ' )
# We should also make sure that when matching stock moves with pack operations, it takes the correct
self . assertEqual ( len ( picking_out . move_lines [ 0 ] . linked_move_operation_ids ) , 2 , ' We should only have 2 links beween the move and the 2 operations ' )
2017-05-23 12:09:16 +00:00
self . assertEqual ( len ( picking_out . move_lines [ 0 ] . quant_ids ) , 2 , ' We should have exactly 2 quants in the end ' )
# Do not forward port in 10.0 and beyond
def test_inventory_adjustment_and_negative_quants_1 ( self ) :
""" Make sure negative quants from returns get wiped out with an inventory adjustment """
productA = self . env [ ' product.product ' ] . create ( { ' name ' : ' Product A ' , ' type ' : ' product ' } )
stock_location = self . env . ref ( ' stock.stock_location_stock ' )
customer_location = self . env . ref ( ' stock.stock_location_customers ' )
location_loss = self . env . ref ( ' stock.location_inventory ' )
# Create a picking out and force availability
picking_out = self . env [ ' stock.picking ' ] . create ( {
' partner_id ' : self . env . ref ( ' base.res_partner_2 ' ) . id ,
' picking_type_id ' : self . env . ref ( ' stock.picking_type_out ' ) . id ,
' location_id ' : stock_location . id ,
' location_dest_id ' : customer_location . id ,
} )
self . env [ ' stock.move ' ] . create ( {
' name ' : productA . name ,
' product_id ' : productA . id ,
' product_uom_qty ' : 1 ,
' product_uom ' : productA . uom_id . id ,
' picking_id ' : picking_out . id ,
' location_id ' : stock_location . id ,
' location_dest_id ' : customer_location . id ,
} )
picking_out . action_confirm ( )
picking_out . force_assign ( )
picking_out . do_transfer ( )
# Create return picking for all goods
default_data = self . env [ ' stock.return.picking ' ] \
. with_context ( active_ids = picking_out . ids , active_id = picking_out . ids [ 0 ] ) \
. default_get ( [
' move_dest_exists ' ,
' product_return_moves '
] )
list_return_moves = default_data [ ' product_return_moves ' ]
default_data [ ' product_return_moves ' ] = [ ( 0 , 0 , return_move ) for return_move in list_return_moves ]
return_wiz = self . env [ ' stock.return.picking ' ] \
. with_context ( active_ids = picking_out . ids , active_id = picking_out . ids [ 0 ] ) \
. create ( default_data )
res = return_wiz . _create_returns ( ) [ 0 ]
return_pick = self . env [ ' stock.picking ' ] . browse ( res )
return_pick . action_assign ( )
return_pick . do_transfer ( )
# Make an inventory adjustment to set the quantity to 0
inventory = self . env [ ' stock.inventory ' ] . create ( {
' name ' : ' Starting for product_1 ' ,
' filter ' : ' product ' ,
' location_id ' : stock_location . id ,
' product_id ' : productA . id ,
} )
inventory . prepare_inventory ( )
self . assertEqual ( len ( inventory . line_ids ) , 1 , " Wrong inventory lines generated. " )
self . assertEqual ( inventory . line_ids . theoretical_qty , 0 , " Theoretical quantity should be zero. " )
inventory . action_done ( )
# The inventory adjustment should have created two moves
self . assertEqual ( len ( inventory . move_ids ) , 2 )
quantity = inventory . move_ids . mapped ( ' product_qty ' )
self . assertEqual ( quantity , [ 1 , 1 ] , " Moves created with wrong quantity. " )
location_ids = inventory . move_ids . mapped ( ' location_id ' ) . ids
self . assertEqual ( set ( location_ids ) , { stock_location . id , location_loss . id } )
# There should be no quant in the stock location
quants = self . env [ ' stock.quant ' ] . search ( [ ( ' product_id ' , ' = ' , productA . id ) , ( ' location_id ' , ' = ' , stock_location . id ) ] )
self . assertEqual ( len ( quants ) , 0 )
# There should be one quant in the inventory loss location
quant = self . env [ ' stock.quant ' ] . search ( [ ( ' product_id ' , ' = ' , productA . id ) , ( ' location_id ' , ' = ' , location_loss . id ) ] )
self . assertEqual ( len ( quant ) , 1 )
self . assertEqual ( quant . qty , 1 )
def test_inventory_adjustment_and_negative_quants_2 ( self ) :
""" Make sure negative quants get wiped out with an inventory adjustment """
productA = self . env [ ' product.product ' ] . create ( { ' name ' : ' Product A ' , ' type ' : ' product ' } )
stock_location = self . env . ref ( ' stock.stock_location_stock ' )
customer_location = self . env . ref ( ' stock.stock_location_customers ' )
location_loss = self . env . ref ( ' stock.location_inventory ' )
# Create a picking out and force availability
picking_out = self . env [ ' stock.picking ' ] . create ( {
' partner_id ' : self . env . ref ( ' base.res_partner_2 ' ) . id ,
' picking_type_id ' : self . env . ref ( ' stock.picking_type_out ' ) . id ,
' location_id ' : stock_location . id ,
' location_dest_id ' : customer_location . id ,
} )
self . env [ ' stock.move ' ] . create ( {
' name ' : productA . name ,
' product_id ' : productA . id ,
' product_uom_qty ' : 1 ,
' product_uom ' : productA . uom_id . id ,
' picking_id ' : picking_out . id ,
' location_id ' : stock_location . id ,
' location_dest_id ' : customer_location . id ,
} )
picking_out . action_confirm ( )
picking_out . force_assign ( )
picking_out . do_transfer ( )
# Make an inventory adjustment to set the quantity to 0
inventory = self . env [ ' stock.inventory ' ] . create ( {
' name ' : ' Starting for product_1 ' ,
' filter ' : ' product ' ,
' location_id ' : stock_location . id ,
' product_id ' : productA . id ,
} )
inventory . prepare_inventory ( )
self . assertEqual ( len ( inventory . line_ids ) , 1 , " Wrong inventory lines generated. " )
self . assertEqual ( inventory . line_ids . theoretical_qty , - 1 , " Theoretical quantity should be -1. " )
inventory . line_ids . product_qty = 0 # Put the quantity back to 0
inventory . action_done ( )
# The inventory adjustment should have created one
self . assertEqual ( len ( inventory . move_ids ) , 1 )
quantity = inventory . move_ids . mapped ( ' product_qty ' )
self . assertEqual ( quantity , [ 1 ] , " Moves created with wrong quantity. " )
location_ids = inventory . move_ids . mapped ( ' location_id ' ) . ids
self . assertEqual ( set ( location_ids ) , { location_loss . id } )
# There should be no quant in the stock location
quants = self . env [ ' stock.quant ' ] . search ( [ ( ' product_id ' , ' = ' , productA . id ) , ( ' location_id ' , ' = ' , stock_location . id ) ] )
self . assertEqual ( len ( quants ) , 0 )
# There should be no quant in the inventory loss location
quant = self . env [ ' stock.quant ' ] . search ( [ ( ' product_id ' , ' = ' , productA . id ) , ( ' location_id ' , ' = ' , location_loss . id ) ] )
self . assertEqual ( len ( quant ) , 0 )