diff --git a/addons/stock/__openerp__.py b/addons/stock/__openerp__.py
index e4fa7c18080..3fb9e2c741a 100644
--- a/addons/stock/__openerp__.py
+++ b/addons/stock/__openerp__.py
@@ -58,6 +58,8 @@ Thanks to the double entry management, the inventory controlling is powerful and
"wizard/stock_inventory_line_split_view.xml",
"wizard/stock_change_standard_price_view.xml",
"wizard/stock_traceability_view.xml",
+ 'wizard/stock_picking_make_view.xml',
+ 'wizard/stock_return_picking_view.xml',
"stock_workflow.xml",
"stock_incoterms.xml",
"stock_view.xml",
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 9230270feeb..812cd0fb492 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -1374,6 +1374,7 @@ class stock_move(osv.osv):
'backorder_id': fields.related('picking_id','backorder_id',type='many2one', relation="stock.picking", string="Back Order"),
'origin': fields.related('picking_id','origin',type='char', size=64, relation="stock.picking", string="Origin",store=True),
'scraped': fields.related('location_dest_id','scrap_location',type='boolean',relation='stock.location',string='Scraped'),
+ 'move_stock_return_history': fields.many2many('stock.move', 'stock_move_return_history', 'move_id', 'return_move_id', 'Move Return History',readonly=True),
}
_constraints = [
(_check_tracking,
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 772726743be..52db4ca56c7 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -655,6 +655,9 @@
+
+
+
@@ -824,6 +827,9 @@
+
+
+
@@ -1211,6 +1217,10 @@
+
+
+
+
@@ -1430,6 +1440,9 @@
+
+
+
@@ -1587,6 +1600,9 @@
+
+
+
diff --git a/addons/stock/wizard/__init__.py b/addons/stock/wizard/__init__.py
index a211de96780..7a13dc26fd5 100644
--- a/addons/stock/wizard/__init__.py
+++ b/addons/stock/wizard/__init__.py
@@ -33,5 +33,8 @@ import stock_inventory_line_split
import stock_invoice_onshipping
import stock_location_product
import stock_change_standard_price
+import stock_picking_make
+import stock_return_picking
+import stock_picking_make
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock/wizard/stock_picking_make.py b/addons/stock/wizard/stock_picking_make.py
new file mode 100644
index 00000000000..9d26595f00e
--- /dev/null
+++ b/addons/stock/wizard/stock_picking_make.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+from osv import fields, osv
+import netsvc
+
+class stock_picking_make(osv.osv_memory):
+ _name = 'stock.picking.make'
+ _description = "Make Picking"
+
+ _columns = {
+ 'picking_ids': fields.many2many('stock.picking', 'stock_picking_ids', 'parent_id', 'child_id', 'Pickings'),
+ }
+
+ def default_get(self, cursor, user, fields, context):
+ """
+ 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
+ @param fields: List of fields for which we want default values
+ @param context: A standard dictionary
+ @return: A dictionary which of fields with values.
+ """
+ res = super(stock_picking_make, self).default_get(cursor, user, fields, context=context)
+ record_ids = context and context.get('active_ids',False) or False
+ if record_ids:
+ picking_obj = self.pool.get('stock.picking')
+ picking_ids = picking_obj.search(cursor, user, [
+ ('id', 'in', record_ids),
+ ('state', '<>', 'done'),
+ ('state', '<>', 'cancel')], context=context)
+ res['picking_ids'] = picking_ids
+ return res
+
+ def make_packing(self, cursor, user, ids, context):
+ """
+ Make Picking.
+ @param self: The object pointer.
+ @param cr: A database cursor
+ @param uid: ID of the user currently logged in
+ @param fields: List of fields for which we want default values
+ @param context: A standard dictionary
+ @return: A dictionary which of fields with values.
+ """
+ record_ids = context and context.get('active_ids',False) or False
+ wkf_service = netsvc.LocalService('workflow')
+ picking_obj = self.pool.get('stock.picking')
+ data = self.read(cursor, user, ids[0])
+ pick_ids = data['picking_ids']
+ picking_obj.force_assign(cursor, user, pick_ids)
+ picking_obj.action_move(cursor, user, pick_ids)
+ for picking_id in ids:
+ wkf_service.trg_validate(user, 'stock.picking', picking_id,
+ 'button_done', cursor)
+ return {}
+
+stock_picking_make()
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/stock/wizard/stock_picking_make_view.xml b/addons/stock/wizard/stock_picking_make_view.xml
new file mode 100644
index 00000000000..fa77042c5d8
--- /dev/null
+++ b/addons/stock/wizard/stock_picking_make_view.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+ Make Picking
+ stock.picking.make
+ form
+
+
+
+
+
+
+ Make Picking
+ ir.actions.act_window
+ stock.picking.make
+ form
+ form
+ new
+
+
+
diff --git a/addons/stock/wizard/stock_return_picking.py b/addons/stock/wizard/stock_return_picking.py
new file mode 100644
index 00000000000..af422b63dd5
--- /dev/null
+++ b/addons/stock/wizard/stock_return_picking.py
@@ -0,0 +1,218 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 .
+#
+##############################################################################
+
+import netsvc
+import time
+
+from osv import osv,fields
+from tools.translate import _
+
+class stock_return_picking(osv.osv_memory):
+ _name = 'stock.return.picking'
+ _description = 'Return Picking'
+
+ def default_get(self, cr, uid, fields, context):
+ """
+ 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
+ @param fields: List of fields for which we want default values
+ @param context: A standard dictionary
+ @return: A dictionary which of fields with values.
+ """
+ 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')
+ pick = pick_obj.browse(cr, uid, record_id)
+ for m in [line for line in pick.move_lines]:
+ res['return%s'%(m.id)] = m.product_qty
+ if pick.invoice_state=='invoiced':
+ res['invoice_state'] = '2binvoiced'
+ else:
+ res['invoice_state'] = 'none'
+ return res
+
+ def view_init(self, cr, uid, fields_list, context=None):
+ """
+ Creates view dynamically and adding fields at runtime.
+ @param self: The object pointer.
+ @param cr: A database cursor
+ @param uid: ID of the user currently logged in
+ @param context: A standard dictionary
+ @return: New arch of view with new columns.
+ """
+ res = super(stock_return_picking, self).view_init(cr, uid, fields_list, context=context)
+ record_id = context and context.get('active_id', False) or False
+ if record_id:
+ pick_obj = self.pool.get('stock.picking')
+ try:
+ pick = pick_obj.browse(cr, uid, record_id)
+ for m in [line for line in pick.move_lines]:
+ if 'return%s'%(m.id) not in self._columns:
+ self._columns['return%s'%(m.id)] = fields.float(string=m.name, required=True)
+ if 'invoice_state' not in self._columns:
+ self._columns['invoice_state'] = fields.selection([('2binvoiced', 'To be Invoiced'), ('none', 'None')], string='Invoice State', required=True)
+ except Exception, e:
+ return res
+ return res
+
+ def fields_view_get(self, cr, uid, view_id=None, view_type='form',
+ context=None, toolbar=False, submenu=False):
+ """
+ Changes the view dynamically
+ @param self: The object pointer.
+ @param cr: A database cursor
+ @param uid: ID of the user currently logged in
+ @param context: A standard dictionary
+ @return: New arch of view.
+ """
+ res = super(stock_return_picking, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False)
+ record_id = context and context.get('active_id', False)
+ active_model = context.get('active_model')
+ if active_model != 'stock.picking':
+ return res
+ if record_id:
+ pick_obj = self.pool.get('stock.picking')
+ pick = pick_obj.browse(cr, uid, record_id)
+ if pick.state != 'done':
+ raise osv.except_osv(_('Warning !'), _("The Picking is not completed yet!\nYou cannot return picking which is not in 'Done' state!"))
+
+ return_history = {}
+ for m_line in pick.move_lines:
+ return_history[m_line.id] = 0
+ for rec in m_line.move_stock_return_history:
+ return_history[m_line.id] += rec.product_qty
+ res['fields'].clear()
+ arch_lst=['', '')
+ res['arch'] = '\n'.join(arch_lst)
+ return res
+
+ def _create_returns(self, cr, uid, ids, context):
+ """
+ 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.
+ """
+ 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')
+ wf_service = netsvc.LocalService("workflow")
+
+ pick = pick_obj.browse(cr, uid, record_id)
+ data = self.read(cr, uid, ids[0])
+ new_picking = None
+ date_cur = time.strftime('%Y-%m-%d %H:%M:%S')
+
+ move_ids = [m.id for m in [line for line in pick.move_lines]]
+ set_invoice_state_to_none = True
+ for move in move_obj.browse(cr, uid, move_ids):
+ if not new_picking:
+ if pick.type=='out':
+ new_type = 'in'
+ elif pick.type=='in':
+ new_type = 'out'
+ else:
+ new_type = 'internal'
+ new_picking = pick_obj.copy(cr, uid, pick.id, {'name':'%s (return)' % pick.name,
+ 'move_lines':[], 'state':'draft', 'type':new_type,
+ 'date':date_cur, 'invoice_state':data['invoice_state'],})
+ new_location=move.location_dest_id.id
+
+ new_qty = data['return%s' % move.id]
+ returned_qty = move.product_qty
+
+ for rec in move.move_stock_return_history:
+ returned_qty -= rec.product_qty
+
+ if returned_qty != new_qty:
+ set_invoice_state_to_none = False
+
+ new_move=move_obj.copy(cr, uid, move.id, {
+ 'product_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':new_location, 'location_dest_id':move.location_id.id,
+ 'date':date_cur, 'date_planned':date_cur,})
+ move_obj.write(cr, uid, [move.id], {'move_stock_return_history':[(4,new_move)]})
+
+ if set_invoice_state_to_none:
+ pick_obj.write(cr, uid, [pick.id], {'invoice_state':'none'})
+
+ if new_picking:
+ if new_picking:
+ wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
+ pick_obj.force_assign(cr, uid, [new_picking], context)
+ return new_picking
+
+ def action_open_window(self, cr, uid, ids, context):
+ """
+ Opens return picking list.
+ @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.
+ """
+ res = self._create_returns(cr, uid, ids, context)
+ if not res:
+ return {}
+ return {
+ 'domain': "[('id', 'in', ["+str(res)+"])]",
+ 'name': 'Picking List',
+ 'view_type':'form',
+ 'view_mode':'tree,form',
+ 'res_model':'stock.picking',
+ 'view_id':False,
+ 'type':'ir.actions.act_window',
+ }
+
+stock_return_picking()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+
diff --git a/addons/stock/wizard/stock_return_picking_view.xml b/addons/stock/wizard/stock_return_picking_view.xml
new file mode 100644
index 00000000000..d6c832d646f
--- /dev/null
+++ b/addons/stock/wizard/stock_return_picking_view.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+