2010-08-10 12:28:52 +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/>.
#
##############################################################################
import time
2013-08-07 09:24:33 +00:00
from openerp . osv import osv , fields
2012-12-06 14:56:32 +00:00
from openerp . tools . translate import _
2012-12-17 15:23:03 +00:00
import openerp . addons . decimal_precision as dp
2010-08-10 12:28:52 +00:00
2013-08-06 15:37:20 +00:00
class stock_return_picking_line ( osv . osv_memory ) :
_name = " stock.return.picking.line "
2011-03-03 14:11:51 +00:00
_rec_name = ' product_id '
2013-02-20 11:05:29 +00:00
2011-03-03 14:11:51 +00:00
_columns = {
2013-08-07 09:24:33 +00:00
' product_id ' : fields . many2one ( ' product.product ' , string = " Product " , required = True ) ,
' quantity ' : fields . float ( " Quantity " , digits_compute = dp . get_precision ( ' Product Unit of Measure ' ) , required = True ) ,
' wizard_id ' : fields . many2one ( ' stock.return.picking ' , string = " Wizard " ) ,
' move_id ' : fields . many2one ( ' stock.move ' , " Move " ) ,
' lot_id ' : fields . related ( ' move_id ' , ' quant_ids ' , ' lot_id ' , type = " many2one " , relation = ' stock.production.lot ' , string = ' Serial Number ' , readonly = True ) ,
2011-03-03 14:11:51 +00:00
}
2010-08-10 12:28:52 +00:00
class stock_return_picking ( osv . osv_memory ) :
_name = ' stock.return.picking '
_description = ' Return Picking '
2011-03-03 14:11:51 +00:00
_columns = {
2013-08-07 09:24:33 +00:00
' product_return_moves ' : fields . one2many ( ' stock.return.picking.line ' , ' wizard_id ' , ' Moves ' ) ,
2014-02-05 17:24:44 +00:00
' move_dest_exists ' : fields . boolean ( ' Chained Move Exists ' , readonly = True , help = " Technical field used to hide ' move_dest_method ' and help tooltip if not needed " ) ,
' move_dest_method ' : fields . selection ( [ ( ' cancel ' , ' Cancel ' ) , ( ' create ' , ' Recreate ' ) , ( ' nothing ' , ' Fix Manually ' ) ] , string = " Chained Picking Resolution " ) ,
2012-04-02 11:02:18 +00:00
}
2014-01-30 14:34:28 +00:00
_defaults = {
' move_dest_method ' : ' nothing ' ,
2014-02-05 17:24:44 +00:00
}
2010-08-10 12:28:52 +00:00
2010-11-22 10:37:53 +00:00
def default_get ( self , cr , uid , fields , context = None ) :
2010-08-25 18:09:47 +00:00
"""
2010-08-10 12:28:52 +00:00
To get default values for the object .
@param self : The object pointer .
@param cr : A database cursor
@param uid : ID of the user currently logged in
2010-08-25 18:09:47 +00:00
@param fields : List of fields for which we want default values
@param context : A standard dictionary
@return : A dictionary with default values for all field in ` ` fields ` `
"""
2011-03-03 14:11:51 +00:00
result1 = [ ]
2010-11-23 07:05:05 +00:00
if context is None :
2010-11-22 10:37:53 +00:00
context = { }
2010-08-10 12:28:52 +00:00
res = super ( stock_return_picking , self ) . default_get ( cr , uid , fields , context = context )
record_id = context and context . get ( ' active_id ' , False ) or False
pick_obj = self . pool . get ( ' stock.picking ' )
2010-11-22 10:37:53 +00:00
pick = pick_obj . browse ( cr , uid , record_id , context = context )
2014-01-28 10:58:09 +00:00
quant_obj = self . pool . get ( " stock.quant " )
move_obj = self . pool . get ( " stock.move " )
2014-02-05 17:24:44 +00:00
chained_move_exist = False
2010-08-25 18:09:47 +00:00
if pick :
2013-08-07 09:24:33 +00:00
if pick . state != ' done ' :
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( " You may only return pickings that are Done! " ) )
2014-01-28 11:19:59 +00:00
2014-01-28 10:58:09 +00:00
for move in pick . move_lines :
if move . move_dest_id :
2014-02-05 17:24:44 +00:00
chained_move_exist = True
#Sum the quants in that location that can be returned (they must belong to the moves that were included in the returned picking)
2014-01-30 12:53:31 +00:00
qty = 0
2014-02-05 17:24:44 +00:00
quant_search = quant_obj . search ( cr , uid , [ ( ' history_ids ' , ' in ' , move . id ) , ( ' qty ' , ' > ' , 0.0 ) ,
( ' location_id ' , ' child_of ' , move . location_dest_id . id ) ] , context = context )
2014-01-30 12:53:31 +00:00
for quant in quant_obj . browse ( cr , uid , quant_search , context = context ) :
if not quant . reservation_id or quant . reservation_id . origin_returned_move_id . id != move . id :
qty + = quant . qty
result1 . append ( { ' product_id ' : move . product_id . id , ' quantity ' : qty , ' move_id ' : move . id } )
2013-08-07 09:24:33 +00:00
if len ( result1 ) == 0 :
2013-08-07 07:00:44 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( " No products to return (only lines in Done state and not fully returned yet can be returned)! " ) )
2011-03-08 13:47:25 +00:00
if ' product_return_moves ' in fields :
res . update ( { ' product_return_moves ' : result1 } )
2014-01-30 11:01:06 +00:00
if ' move_dest_exists ' in fields :
2014-02-05 17:24:44 +00:00
res . update ( { ' move_dest_exists ' : chained_move_exist } )
2010-08-10 12:28:52 +00:00
return res
2010-08-25 18:09:47 +00:00
2013-09-04 09:12:56 +00:00
def _create_returns ( self , cr , uid , ids , context = None ) :
2010-11-23 07:05:05 +00:00
if context is None :
2013-08-07 09:24:33 +00:00
context = { }
2010-08-10 12:28:52 +00:00
record_id = context and context . get ( ' active_id ' , False ) or False
move_obj = self . pool . get ( ' stock.move ' )
pick_obj = self . pool . get ( ' stock.picking ' )
uom_obj = self . pool . get ( ' product.uom ' )
2013-08-06 15:37:20 +00:00
data_obj = self . pool . get ( ' stock.return.picking.line ' )
2010-11-22 10:37:53 +00:00
pick = pick_obj . browse ( cr , uid , record_id , context = context )
2011-02-03 12:37:47 +00:00
data = self . read ( cr , uid , ids [ 0 ] , context = context )
2010-09-28 17:25:47 +00:00
returned_lines = 0
2013-10-29 07:48:15 +00:00
2014-01-28 10:58:09 +00:00
# Cancel assignment of existing chained assigned moves
2014-02-05 17:24:44 +00:00
moves_to_unreserve = [ x . move_dest_id . id for x in pick . move_lines if x . move_dest_id and x . move_dest_id . quant_ids ]
2014-01-28 10:58:09 +00:00
if moves_to_unreserve :
move_obj . do_unreserve ( cr , uid , moves_to_unreserve , context = context )
2014-02-05 17:24:44 +00:00
#Create new picking for returned products
pick_type_id = pick . picking_type_id . return_picking_type_id and pick . picking_type_id . return_picking_type_id . id or pick . picking_type_id . id
2012-04-02 11:02:18 +00:00
new_picking = pick_obj . copy ( cr , uid , pick . id , {
2013-08-07 09:24:33 +00:00
' move_lines ' : [ ] ,
' picking_type_id ' : pick_type_id ,
' state ' : ' draft ' ,
' origin ' : pick . name ,
2013-10-29 07:48:15 +00:00
} , context = context )
2014-01-28 10:58:09 +00:00
2013-08-07 09:24:33 +00:00
for data_get in data_obj . browse ( cr , uid , data [ ' product_return_moves ' ] , context = context ) :
move = data_get . move_id
if not move :
2013-06-11 09:29:43 +00:00
raise osv . except_osv ( _ ( ' Warning ! ' ) , _ ( " You have manually created product lines, please delete them to proceed " ) )
2011-03-18 09:16:07 +00:00
new_qty = data_get . quantity
2011-03-03 14:11:51 +00:00
if new_qty :
returned_lines + = 1
2014-02-05 17:24:44 +00:00
move_obj . copy ( cr , uid , move . id , {
2013-08-07 09:24:33 +00:00
' product_id ' : data_get . product_id . id ,
' product_uom_qty ' : new_qty ,
' product_uos_qty ' : uom_obj . _compute_qty ( cr , uid , move . product_uom . id , new_qty , move . product_uos . id ) ,
' picking_id ' : new_picking ,
' state ' : ' draft ' ,
' location_id ' : move . location_dest_id . id ,
' location_dest_id ' : move . location_id . id ,
' origin_returned_move_id ' : move . id ,
2014-01-30 14:34:28 +00:00
' procure_method ' : ' make_to_stock ' ,
2012-04-02 11:02:18 +00:00
} )
2014-01-30 16:15:32 +00:00
2014-01-30 14:34:28 +00:00
if data [ ' move_dest_method ' ] == ' cancel ' :
if move . move_dest_id and move . move_dest_id . state not in [ ' done ' , ' cancel ' ] :
2014-01-30 11:01:06 +00:00
res = move_obj . split ( cr , uid , move . move_dest_id , new_qty , context = context )
move_obj . action_cancel ( cr , uid , [ res ] , context = context )
2014-01-30 14:34:28 +00:00
if data [ ' move_dest_method ' ] == ' create ' :
if move . move_dest_id and move . move_dest_id . state not in [ ' done ' , ' cancel ' ] :
res = move_obj . split ( cr , uid , move . move_dest_id , new_qty , context = context )
new_move = move_obj . copy ( cr , uid , move . id , {
' location_id ' : move . location_id . id ,
' location_dest_id ' : move . location_dest_id . id ,
' product_uom_qty ' : new_qty ,
' product_uos_qty ' : uom_obj . _compute_qty ( cr , uid , move . product_uom . id , new_qty , move . product_uos . id ) ,
' move_dest_id ' : res ,
2014-01-30 16:15:32 +00:00
' picking_id ' : False ,
2014-01-30 14:34:28 +00:00
} )
move_obj . action_confirm ( cr , uid , [ new_move ] , context = context )
2014-01-30 16:15:32 +00:00
2010-09-28 17:25:47 +00:00
if not returned_lines :
2012-08-07 11:34:14 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( " Please specify at least one non-zero quantity. " ) )
2010-09-28 17:25:47 +00:00
2013-08-06 15:37:20 +00:00
pick_obj . action_confirm ( cr , uid , [ new_picking ] , context = context )
2014-01-21 10:32:22 +00:00
pick_obj . action_assign ( cr , uid , [ new_picking ] , context )
2013-09-04 09:12:56 +00:00
return new_picking , pick_type_id
def create_returns ( self , cr , uid , ids , context = None ) :
"""
Creates return picking .
@param self : The object pointer .
@param cr : A database cursor
@param uid : ID of the user currently logged in
@param ids : List of ids selected
@param context : A standard dictionary
@return : A dictionary which of fields with values .
"""
new_picking_id , pick_type_id = self . _create_returns ( cr , uid , ids , context = context )
2013-12-13 14:01:12 +00:00
# Override the context to disable all the potential filters that could have been set previously
2013-11-05 16:15:17 +00:00
ctx = {
2013-12-13 14:01:12 +00:00
' search_default_picking_type_id ' : pick_type_id ,
' search_default_draft ' : False ,
' search_default_assigned ' : False ,
' search_default_confirmed ' : False ,
' search_default_ready ' : False ,
' search_default_late ' : False ,
' search_default_available ' : False ,
2013-11-08 16:52:17 +00:00
}
2012-05-07 11:12:22 +00:00
return {
2013-09-04 09:12:56 +00:00
' domain ' : " [( ' id ' , ' in ' , [ " + str ( new_picking_id ) + " ])] " ,
2012-05-07 11:12:22 +00:00
' name ' : _ ( ' Returned Picking ' ) ,
2013-08-07 09:24:33 +00:00
' view_type ' : ' form ' ,
' view_mode ' : ' tree,form ' ,
2013-07-23 16:47:55 +00:00
' res_model ' : ' stock.picking ' ,
2013-08-07 09:24:33 +00:00
' type ' : ' ir.actions.act_window ' ,
2013-12-13 14:01:12 +00:00
' context ' : ctx ,
2012-04-02 11:02:18 +00:00
}
2010-09-28 17:25:47 +00:00
2010-08-10 12:28:52 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: