[ADD] stock: Added osv_memory wizards: (1) Return Picking and (2) Split Moves.
bzr revid: uco@tinyerp.co.in-20100401050848-ugxbxzloaqtrit2y
This commit is contained in:
parent
f688dc81cd
commit
cdc23c6119
|
@ -54,6 +54,8 @@ Thanks to the double entry management, the inventory controlling is powerful and
|
|||
"wizard/stock_change_standard_price_view.xml",
|
||||
"wizard/stock_traceability_view.xml",
|
||||
"wizard/stock_picking_make_view.xml",
|
||||
"wizard/stock_return_picking_view.xml",
|
||||
"wizard/stock_split_move_view.xml",
|
||||
"stock_workflow.xml",
|
||||
"stock_incoterms.xml",
|
||||
"stock_wizard.xml",
|
||||
|
|
|
@ -591,7 +591,7 @@
|
|||
type="action"
|
||||
icon="gtk-go-forward"
|
||||
help="Make Picking" colspan="2"/>
|
||||
<button name="%(return_picking)d"
|
||||
<button name="%(act_stock_return_picking)d"
|
||||
states="done"
|
||||
string="Return Picking"
|
||||
type="action"
|
||||
|
@ -664,7 +664,7 @@
|
|||
</field>
|
||||
<group col="7" colspan="4">
|
||||
<label colspan="6"/>
|
||||
<button name="%(move_split)d" string="Split Entry Lines in two" type="action" icon="gtk-justify-fill"/>
|
||||
<button name="%(act_split_moves)d" string="Split Entry Lines in two" type="action" icon="gtk-justify-fill"/>
|
||||
</group>
|
||||
<group col="10" colspan="4">
|
||||
<field name="state" readonly="1"/>
|
||||
|
@ -758,7 +758,7 @@
|
|||
type="action"
|
||||
icon="gtk-go-forward"
|
||||
help="Make Picking" colspan="2"/>
|
||||
<button name="%(return_picking)d"
|
||||
<button name="%(act_stock_return_picking)d"
|
||||
states="done"
|
||||
string="Return Picking"
|
||||
type="action"
|
||||
|
@ -825,7 +825,7 @@
|
|||
</field>
|
||||
<group col="7" colspan="4">
|
||||
<label colspan="6"/>
|
||||
<button name="%(move_split)d" string="Split in Two" type="action" states="assigned,confirmed,draft,auto" icon="gtk-justify-fill"/>
|
||||
<button name="%(act_split_moves)d" string="Split in Two" type="action" states="assigned,confirmed,draft,auto" icon="gtk-justify-fill"/>
|
||||
</group>
|
||||
<group col="10" colspan="4">
|
||||
<field name="state" readonly="1"/>
|
||||
|
@ -952,7 +952,7 @@
|
|||
type="action"
|
||||
icon="gtk-go-forward"
|
||||
help="Make Picking" colspan="2"/>
|
||||
<button name="%(return_picking)d"
|
||||
<button name="%(act_stock_return_picking)d"
|
||||
states="done"
|
||||
string="Return Picking"
|
||||
type="action"
|
||||
|
@ -1022,7 +1022,7 @@
|
|||
</field>
|
||||
<group col="7" colspan="4">
|
||||
<label colspan="6"/>
|
||||
<button name="%(move_split)d" string="Split in Two" type="action" icon="gtk-justify-fill"/>
|
||||
<button name="%(act_split_moves)d" string="Split in Two" type="action" icon="gtk-justify-fill"/>
|
||||
</group>
|
||||
<group col="10" colspan="4">
|
||||
<field name="state" readonly="1"/>
|
||||
|
@ -1147,7 +1147,7 @@
|
|||
type="action"
|
||||
icon="gtk-go-forward"
|
||||
help="Make Picking" colspan="2"/>
|
||||
<button name="%(return_picking)d"
|
||||
<button name="%(act_stock_return_picking)d"
|
||||
states="done"
|
||||
string="Return Picking"
|
||||
type="action"
|
||||
|
|
|
@ -6,31 +6,6 @@
|
|||
<wizard string="UPS xml file" model="stock.move.lot" name="stock.ups_xml" />
|
||||
-->
|
||||
|
||||
|
||||
<wizard
|
||||
id="move_split"
|
||||
model="stock.picking"
|
||||
multi="True"
|
||||
name="stock.move.split"
|
||||
string="Split move line"/>
|
||||
|
||||
|
||||
<!-- <wizard -->
|
||||
<!-- id="make_picking" -->
|
||||
<!-- model="stock.picking"-->
|
||||
<!-- menu="False"-->
|
||||
<!-- keyword="client_action_multi"-->
|
||||
<!-- name="stock.picking.make" -->
|
||||
<!-- string="Make Picking"/>-->
|
||||
|
||||
<wizard
|
||||
id="return_picking"
|
||||
model="stock.picking"
|
||||
menu="False"
|
||||
keyword="client_action_multi"
|
||||
name="stock.return.picking"
|
||||
string="Return picking"/>
|
||||
|
||||
<wizard
|
||||
id="split_inventory_lots"
|
||||
model="stock.inventory.line"
|
||||
|
|
|
@ -25,8 +25,8 @@ import stock_partial_picking
|
|||
import stock_partial_move
|
||||
import stock_picking_make
|
||||
import wizard_replacement
|
||||
import wizard_return
|
||||
import wizard_split_lot_line
|
||||
import stock_return_picking
|
||||
import stock_split_move
|
||||
import wizard_ups
|
||||
import stock_inventory_merge
|
||||
import stock_inventory_set_stock_zero
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
# -*- 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 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) or False
|
||||
assert record_id,'Active ID not found'
|
||||
if record_id:
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
pick = pick_obj.browse(cr, uid, record_id)
|
||||
|
||||
try:
|
||||
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=['<?xml version="1.0"?>', '<form string="%s">' % _('Return lines'), '<label string="%s" colspan="4"/>' % _('Provide the quantities of the returned products.')]
|
||||
for m in [line for line in pick.move_lines]:
|
||||
quantity = m.product_qty
|
||||
if quantity > return_history[m.id] and (quantity - return_history[m.id])>0:
|
||||
arch_lst.append('<field name="return%s"/>\n<newline/>' % (m.id,))
|
||||
res['fields']['return%s' % m.id]={'string':m.name, 'type':'float', 'required':True}
|
||||
res.setdefault('returns', []).append(m.id)
|
||||
if not res.get('returns',False):
|
||||
raise osv.except_osv(_('Warning!'),_('There is no product to return!'))
|
||||
|
||||
arch_lst.append('<field name="invoice_state"/>\n<newline/>')
|
||||
if pick.invoice_state=='invoiced':
|
||||
new_invoice_state='2binvoiced'
|
||||
else:
|
||||
new_invoice_state=pick.invoice_state
|
||||
res['fields']['invoice_state']={'string':_('Invoice state'), 'type':'selection','required':True, 'selection':[('2binvoiced', _('To Be Invoiced')), ('none', _('None'))]}
|
||||
arch_lst.append('<group col="2" colspan="4">')
|
||||
arch_lst.append('<button icon="gtk-cancel" special="cancel" string="Cancel" />')
|
||||
arch_lst.append('<button name="action_open_window" string="Return" colspan="1" type="object" icon="gtk-apply" />')
|
||||
arch_lst.append('</group>')
|
||||
arch_lst.append('</form>')
|
||||
res['arch'] = '\n'.join(arch_lst)
|
||||
except Exception,e:
|
||||
return res
|
||||
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:
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Return Picking -->
|
||||
|
||||
<record id="act_stock_return_picking" model="ir.actions.act_window">
|
||||
<field name="name">Return Picking</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">stock.return.picking</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -0,0 +1,125 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from osv import osv, fields
|
||||
|
||||
class stock_split_move_line(osv.osv_memory):
|
||||
_name = 'stock.move.line.split'
|
||||
_description = "Split Moves"
|
||||
|
||||
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_split_move_line, 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['move%s'%(m.id)] = m.product_qty
|
||||
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_split_move_line, 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 'move%s' % m.id not in self._columns:
|
||||
self._columns['move%s' % m.id] = fields.float(string=m.product_id.name)
|
||||
except:
|
||||
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_split_move_line, 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) or False
|
||||
assert record_id,'Active ID not found'
|
||||
pick_obj = self.pool.get('stock.picking')
|
||||
pick = pick_obj.browse(cr, uid, record_id)
|
||||
arch_lst = ['<?xml version="1.0"?>', '<form string="Split lines">', '<label string="Indicate here the quantity of the new line. A quantity of zero will not split the line." colspan="4"/>']
|
||||
for m in [line for line in pick.move_lines]:
|
||||
quantity = m.product_qty
|
||||
arch_lst.append('<field name="move%s" />\n<newline />' % (m.id,))
|
||||
res['fields']['move%s' % m.id] = {'string' : m.product_id.name, 'type' : 'float', 'required' : True}
|
||||
arch_lst.append('<group col="2" colspan="4">')
|
||||
arch_lst.append('<button icon="gtk-cancel" special="cancel" string="Cancel" />')
|
||||
arch_lst.append('<button name="split_lines" string="Split" colspan="1" type="object" icon="gtk-apply" />')
|
||||
arch_lst.append('</group>')
|
||||
arch_lst.append('</form>')
|
||||
res['arch'] = '\n'.join(arch_lst)
|
||||
return res
|
||||
|
||||
def split_lines(self, cr, uid, ids, context):
|
||||
"""
|
||||
Splits moves in quantity given in the wizard.
|
||||
@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.
|
||||
"""
|
||||
move_obj = self.pool.get('stock.move')
|
||||
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)
|
||||
data = self.read(cr, uid, ids[0])
|
||||
move_ids = [m.id for m in [line for line in pick.move_lines]]
|
||||
for move in move_obj.browse(cr, uid, move_ids):
|
||||
quantity = data['move%s' % move.id]
|
||||
if 0 < quantity < move.product_qty:
|
||||
new_qty = move.product_qty - quantity
|
||||
new_uos_qty = new_qty / move.product_qty * move.product_uos_qty
|
||||
new_obj = move_obj.copy(cr, uid, move.id, {'product_qty' : new_qty, 'product_uos_qty': new_uos_qty, 'state':move.state})
|
||||
uos_qty = quantity / move.product_qty * move.product_uos_qty
|
||||
move_obj.write(cr, uid, [move.id], {'product_qty' : quantity, 'product_uos_qty': uos_qty})
|
||||
return {}
|
||||
|
||||
stock_split_move_line()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<!-- Split Moves -->
|
||||
|
||||
<record id="act_split_moves" model="ir.actions.act_window">
|
||||
<field name="name">Split Moves</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">stock.move.line.split</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
|
@ -1,156 +0,0 @@
|
|||
# -*- 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 wizard
|
||||
import pooler
|
||||
from tools.misc import UpdateableStr
|
||||
|
||||
import netsvc
|
||||
import time
|
||||
|
||||
from tools.translate import _
|
||||
|
||||
arch=UpdateableStr()
|
||||
fields={}
|
||||
|
||||
def make_default(val):
|
||||
def fct(obj, cr, uid):
|
||||
return val
|
||||
return fct
|
||||
|
||||
def _get_returns(self, cr, uid, data, context):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
pick_obj = pool.get('stock.picking')
|
||||
pick = pick_obj.browse(cr, uid, [data['id']])[0]
|
||||
|
||||
if pick.state != 'done':
|
||||
raise wizard.except_wizard(_('Warning !'), _("The Picking is not completed yet!\nYou cannot return picking which is not in 'Done' state!"))
|
||||
res = {}
|
||||
|
||||
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
|
||||
|
||||
fields.clear()
|
||||
arch_lst=['<?xml version="1.0"?>', '<form string="%s">' % _('Return lines'), '<label string="%s" colspan="4"/>' % _('Provide the quantities of the returned products.')]
|
||||
for m in [line for line in pick.move_lines]:
|
||||
quantity = m.product_qty
|
||||
if quantity > return_history[m.id] and (quantity - return_history[m.id])>0:
|
||||
arch_lst.append('<field name="return%s"/>\n<newline/>' % (m.id,))
|
||||
fields['return%s' % m.id]={'string':m.name, 'type':'float', 'required':True, 'default':make_default(quantity - return_history[m.id])}
|
||||
res.setdefault('returns', []).append(m.id)
|
||||
|
||||
if not res.get('returns',False):
|
||||
raise wizard.except_wizard(_('Warning!'),_('There is no product to return!'))
|
||||
|
||||
arch_lst.append('<field name="invoice_state"/>\n<newline/>')
|
||||
if pick.invoice_state=='invoiced':
|
||||
new_invoice_state='2binvoiced'
|
||||
else:
|
||||
new_invoice_state=pick.invoice_state
|
||||
fields['invoice_state']={'string':_('Invoice state'), 'type':'selection', 'default':make_default(new_invoice_state), 'required':True, 'selection':[('2binvoiced', _('to be invoiced')), ('none', _('None'))]}
|
||||
arch_lst.append('</form>')
|
||||
arch.string='\n'.join(arch_lst)
|
||||
return res
|
||||
|
||||
def _create_returns(self, cr, uid, data, context):
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
move_obj = pool.get('stock.move')
|
||||
pick_obj = pool.get('stock.picking')
|
||||
uom_obj = pool.get('product.uom')
|
||||
|
||||
pick=pick_obj.browse(cr, uid, [data['id']])[0]
|
||||
new_picking=None
|
||||
date_cur=time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
set_invoice_state_to_none = True
|
||||
for move in move_obj.browse(cr, uid, data['form'].get('returns',[])):
|
||||
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['form']['invoice_state'],})
|
||||
new_location=move.location_dest_id.id
|
||||
|
||||
new_qty = data['form']['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:
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
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, data, context):
|
||||
res=_create_returns(self, cr, uid, data, 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',
|
||||
}
|
||||
|
||||
class wizard_return_picking(wizard.interface):
|
||||
states={
|
||||
'init':{
|
||||
'actions':[_get_returns],
|
||||
'result':{'type':'form', 'arch':arch, 'fields':fields, 'state':[('end','Cancel','gtk-cancel'),('return','Return','gtk-apply',True)]}
|
||||
},
|
||||
'return':{
|
||||
'actions':[],
|
||||
'result':{'type':'action', 'action':_action_open_window, 'state':'end'}
|
||||
}
|
||||
}
|
||||
wizard_return_picking('stock.return.picking')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
# -*- 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 wizard
|
||||
import netsvc
|
||||
import pooler
|
||||
|
||||
import time
|
||||
from osv import osv
|
||||
from tools.misc import UpdateableStr
|
||||
|
||||
arch = UpdateableStr()
|
||||
fields = {}
|
||||
|
||||
def make_default(val):
|
||||
def fct(obj, cr, uid):
|
||||
return val
|
||||
return fct
|
||||
|
||||
def _get_moves(self, cr, uid, data, context):
|
||||
pick_obj = pooler.get_pool(cr.dbname).get('stock.picking')
|
||||
pick = pick_obj.browse(cr, uid, [data['id']])[0]
|
||||
res = {}
|
||||
fields.clear()
|
||||
arch_lst = ['<?xml version="1.0"?>', '<form string="Split lines">', '<label string="Indicate here the quantity of the new line. A quantity of zero will not split the line." colspan="4"/>']
|
||||
for m in [line for line in pick.move_lines]:
|
||||
quantity = m.product_qty
|
||||
arch_lst.append('<field name="move%s" />\n<newline />' % (m.id,))
|
||||
fields['move%s' % m.id] = {'string' : m.product_id.name, 'type' : 'float', 'required' : True, 'default' : make_default(quantity)}
|
||||
res.setdefault('moves', []).append(m.id)
|
||||
arch_lst.append('</form>')
|
||||
arch.string = '\n'.join(arch_lst)
|
||||
return res
|
||||
|
||||
def _split_lines(self, cr, uid, data, context):
|
||||
move_obj = pooler.get_pool(cr.dbname).get('stock.move')
|
||||
for move in move_obj.browse(cr, uid, data['form']['moves']):
|
||||
quantity = data['form']['move%s' % move.id]
|
||||
if 0 < quantity < move.product_qty:
|
||||
new_qty = move.product_qty - quantity
|
||||
new_uos_qty = new_qty / move.product_qty * move.product_uos_qty
|
||||
new_obj = move_obj.copy(cr, uid, move.id, {'product_qty' : new_qty, 'product_uos_qty': new_uos_qty, 'state':move.state})
|
||||
uos_qty = quantity / move.product_qty * move.product_uos_qty
|
||||
move_obj.write(cr, uid, [move.id], {'product_qty' : quantity, 'product_uos_qty': uos_qty})
|
||||
return {}
|
||||
|
||||
class wizard_split_move(wizard.interface):
|
||||
states = {
|
||||
'init': {
|
||||
'actions': [_get_moves],
|
||||
'result': {'type':'form', 'arch':arch, 'fields':fields, 'state':[('end','Cancel','gtk-cancel'),('split','Split','gtk-apply',True)]}
|
||||
},
|
||||
'split': {
|
||||
'actions': [_split_lines],
|
||||
'result': {'type':'state', 'state':'end'}
|
||||
}
|
||||
}
|
||||
wizard_split_move('stock.move.split')
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
Loading…
Reference in New Issue