[IMP] stock: stock partial move wizard

bzr revid: hmo@tinyerp.com-20100326145201-3viwi4gcsujnvfhd
This commit is contained in:
Harry (Open ERP) 2010-03-26 20:22:01 +05:30
parent d9dc66b994
commit 373b2701c5
9 changed files with 399 additions and 257 deletions

View File

@ -44,6 +44,7 @@ Thanks to the double entry management, the inventory controlling is powerful and
"stock_data.xml",
"wizard/stock_move_view.xml",
"wizard/stock_partial_picking_view.xml",
"wizard/stock_partial_move_view.xml",
"wizard/stock_inventory_set_stock_zero_view.xml",
"wizard/stock_fill_inventory_view.xml",
"wizard/stock_invoice_onshipping_view.xml",

View File

@ -890,6 +890,8 @@ class stock_picking(osv.osv):
complete, too_many, too_few = [], [], []
move_product_qty = {}
for move in pick.move_lines:
if move.state in ('done', 'cancel'):
continue
partial_data = partial_datas.get('move%s'%(move.id), False)
assert partial_data, _('Do not Found Partial data of Stock Move Line :%s' %(move.id))
product_qty = partial_data.get('product_qty',0.0)
@ -1117,10 +1119,9 @@ class stock_delivery(osv.osv):
'partner_id': fields.many2one('res.partner', 'Partner', required=True),
'address_id': fields.many2one('res.partner.address', 'Address', required=True),
'move_delivered':fields.one2many('stock.move', 'delivered_id', 'Move Delivered'),
'picking_id': fields.many2one('stock.picking', 'Picking list', required=True),
'picking_id': fields.many2one('stock.picking', 'Picking list'),
}
stock_delivery()
# ----------------------------------------------------
# Move
@ -1788,7 +1789,134 @@ class stock_move(osv.osv):
self.write(cr, uid, [move.id], update_val)
self.action_done(cr, uid, res)
return res
return res
def do_partial(self, cr, uid, ids, partial_datas, context={}):
"""
@ partial_datas : dict. contain details of partial picking
like partner_id, address_id, delivery_date, delivery moves with product_id, product_qty, uom
"""
res = {}
picking_obj = self.pool.get('stock.picking')
delivery_obj = self.pool.get('stock.delivery')
product_obj = self.pool.get('product.product')
currency_obj = self.pool.get('res.currency')
users_obj = self.pool.get('res.users')
uom_obj = self.pool.get('product.uom')
price_type_obj = self.pool.get('product.price.type')
sequence_obj = self.pool.get('ir.sequence')
wf_service = netsvc.LocalService("workflow")
partner_id = partial_datas.get('partner_id', False)
address_id = partial_datas.get('address_id', False)
delivery_date = partial_datas.get('delivery_date', False)
new_moves = []
complete, too_many, too_few = [], [], []
move_product_qty = {}
for move in self.browse(cr, uid, ids, context=context):
if move.state in ('done', 'cancel'):
continue
partial_data = partial_datas.get('move%s'%(move.id), False)
assert partial_data, _('Do not Found Partial data of Stock Move Line :%s' %(move.id))
product_qty = partial_data.get('product_qty',0.0)
move_product_qty[move.id] = product_qty
product_uom = partial_data.get('product_uom',False)
product_price = partial_data.get('product_price',0.0)
product_currency = partial_data.get('product_currency',False)
if move.product_qty == product_qty:
complete.append(move)
elif move.product_qty > product_qty:
too_few.append(move)
else:
too_many.append(move)
# Average price computation
if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
product = product_obj.browse(cr, uid, move.product_id.id)
user = users_obj.browse(cr, uid, uid)
context['currency_id'] = move.company_id.currency_id.id
qty = uom_obj._compute_qty(cr, uid, product_uom, product_qty, product.uom_id.id)
pricetype = False
if user.company_id.property_valuation_price_type:
pricetype = price_type_obj.browse(cr, uid, user.company_id.property_valuation_price_type.id)
if pricetype and qty > 0:
new_price = currency_obj.compute(cr, uid, product_currency,
user.company_id.currency_id.id, product_price)
new_price = uom_obj._compute_price(cr, uid, product_uom, new_price,
product.uom_id.id)
if product.qty_available <= 0:
new_std_price = new_price
else:
# Get the standard price
amount_unit = product.price_get(pricetype.field, context)[product.id]
new_std_price = ((amount_unit * product.qty_available)\
+ (new_price * qty))/(product.qty_available + qty)
# Write the field according to price type field
product_obj.write(cr, uid, [product.id],
{pricetype.field: new_std_price})
self.write(cr, uid, [move.id], {'price_unit': new_price})
for move in too_few:
product_qty = move_product_qty[move.id]
if product_qty != 0:
new_move = self.copy(cr, uid, move.id,
{
'product_qty' : product_qty,
'product_uos_qty': product_qty,
'picking_id' : move.picking_id.id,
'state': 'assigned',
'move_dest_id': False,
'price_unit': move.price_unit,
})
complete.append(self.browse(cr, uid, new_move))
self.write(cr, uid, move.id,
{
'product_qty' : move.product_qty - product_qty,
'product_uos_qty':move.product_qty - product_qty,
})
for move in too_many:
self.write(cr, uid, move.id,
{
'product_qty': product_qty,
'product_uos_qty': product_qty
})
complete.append(move)
for move in complete:
self.action_done(cr, uid, [move.id])
# TOCHECK : Done picking if all moves are done
cr.execute("""
SELECT move.id FROM stock_picking pick
RIGHT JOIN stock_move move ON move.picking_id = pick.id AND move.state = %s
WHERE pick.id = %s""",
('done', move.picking_id.id))
res = cr.fetchall()
if len(res) == len(move.picking_id.move_lines):
picking_obj.action_move(cr, uid, [move.picking_id.id])
wf_service.trg_validate(uid, 'stock.picking', move.picking_id.id, 'button_done', cr)
ref = {}
done_move_ids = []
for move in complete:
done_move_ids.append(move.id)
if move.picking_id.id not in ref:
delivery_id = delivery_obj.create(cr, uid, {
'partner_id': partner_id,
'address_id': address_id,
'date': delivery_date,
'name' : move.picking_id.name,
'picking_id': move.picking_id.id
}, context=context)
ref[move.picking_id.id] = delivery_id
delivery_obj.write(cr, uid, ref[move.picking_id.id], {
'move_delivered' : [(4,move.id)]
})
return done_move_ids
stock_move()

View File

@ -1488,7 +1488,7 @@
<field name="date_planned"/>
<field name="backorder_id"/>
<field name="state"/>
<button name="%(partial_move)d" string="Partial" type="action" states="assigned" icon="gtk-justify-fill"/>
<button name="%(action_partial_move)d" string="Partial" type="action" states="assigned" icon="gtk-justify-fill"/>
<button name="action_cancel" states="assigned,confirmed" string="Cancel" type="object" icon="gtk-cancel"/>
</tree>
</field>
@ -1534,7 +1534,7 @@
<button name="action_confirm" states="draft" string="Confirm" type="object" icon="gtk-apply"/>
<button name="action_assign" states="confirmed" string="Set Available" type="object" icon="gtk-yes"/>
<button name="action_cancel" states="assigned,confirmed" string="Cancel" type="object" icon="gtk-cancel"/>
<button name="%(partial_move)d" states="assigned" string="Partial" type="action" icon="gtk-justify-fill"/>
<button name="%(action_partial_move)d" states="assigned" string="Partial" type="action" icon="gtk-justify-fill"/>
<button name="action_done" states="assigned" string="Done" type="object" icon="gtk-jump-to"/>
</group>
</page>

View File

@ -29,14 +29,7 @@
menu="False"
keyword="client_action_multi"
name="stock.return.picking"
string="Return picking"/>
<wizard
id="partial_move"
model="stock.move"
multi="True"
name="stock.partial_move"
string="Partial Move"/>
string="Return picking"/>
<wizard
id="split_inventory_lots"

View File

@ -22,7 +22,7 @@
import stock_traceability
import stock_move
import stock_partial_picking
import wizard_partial_move
import stock_partial_move
import wizard_picking_make
import wizard_replacement
import wizard_return

View File

@ -0,0 +1,217 @@
# -*- 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 fields, osv
from service import web_services
from tools.translate import _
import netsvc
import pooler
import time
class stock_partial_move(osv.osv_memory):
_name = "stock.partial.move"
_description = "Partial Move"
_columns = {
'date': fields.datetime('Date', required=True),
'partner_id': fields.many2one('res.partner',string="Partner", required=True),
'address_id': fields.many2one('res.partner.address', 'Delivery Address', help="Address where goods are to be delivered", required=True),
}
def view_init(self, cr, uid, fields_list, context=None):
res = super(stock_partial_move, self).view_init(cr, uid, fields_list, context=context)
move_obj = self.pool.get('stock.move')
if not context:
context={}
moveids = []
for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
if m.state in ('done', 'cancel'):
continue
if 'move%s_product_id'%(m.id) not in self._columns:
self._columns['move%s_product_id'%(m.id)] = fields.many2one('product.product',string="Product")
if 'move%s_product_qty'%(m.id) not in self._columns:
self._columns['move%s_product_qty'%(m.id)] = fields.float("Quantity")
if 'move%s_product_uom'%(m.id) not in self._columns:
self._columns['move%s_product_uom'%(m.id)] = fields.many2one('product.uom',string="Product UOM")
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
if 'move%s_product_price'%(m.id) not in self._columns:
self._columns['move%s_product_price'%(m.id)] = fields.float("Price")
if 'move%s_product_currency'%(m.id) not in self._columns:
self._columns['move%s_product_currency'%(m.id)] = fields.many2one('res.currency',string="Currency")
return res
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
result = super(stock_partial_move, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
move_obj = self.pool.get('stock.move')
move_ids = context.get('active_ids', False)
move_ids = move_obj.search(cr, uid, [('id','in',move_ids)])
_moves_arch_lst = """<form string="Deliver Products">
<separator colspan="4" string="Delivery Information"/>
<field name="date" colspan="4" />
<field name="partner_id"/>
<field name="address_id"/>
<newline/>
<separator colspan="4" string="Move Detail"/>
"""
_moves_fields = result['fields']
if move_ids and view_type in ['form']:
for m in move_obj.browse(cr, uid, move_ids, context):
if m.state in ('done', 'cancel'):
continue
_moves_fields.update({
'move%s_product_id'%(m.id) : {
'string': _('Product'),
'type' : 'many2one',
'relation': 'product.product',
'required' : True,
'readonly' : True,
},
'move%s_product_qty'%(m.id) : {
'string': _('Quantity'),
'type' : 'float',
'required': True,
},
'move%s_product_uom'%(m.id) : {
'string': _('Product UOM'),
'type' : 'many2one',
'relation': 'product.uom',
'required' : True,
'readonly' : True,
}
})
_moves_arch_lst += """
<group colspan="4" col="10">
<field name="move%s_product_id" nolabel="1"/>
<field name="move%s_product_qty" string="Qty" />
<field name="move%s_product_uom" nolabel="1" />
"""%(m.id, m.id, m.id)
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
_moves_fields.update({
'move%s_product_price'%(m.id) : {
'string': _('Price'),
'type' : 'float',
},
'move%s_product_currency'%(m.id): {
'string': _('Currency'),
'type' : 'float',
'type' : 'many2one',
'relation': 'res.currency',
}
})
_moves_arch_lst += """
<field name="move%s_product_price" />
<field name="move%s_product_currency" nolabel="1"/>
"""%(m.id, m.id)
_moves_arch_lst += """
</group>
"""
_moves_arch_lst += """
<separator string="" colspan="4" />
<label string="" colspan="2"/>
<group col="2" colspan="2">
<button icon='gtk-cancel' special="cancel"
string="_Cancel" />
<button name="do_partial" string="_Deliver"
colspan="1" type="object" icon="gtk-apply" />
</group>
</form>"""
result['arch'] = _moves_arch_lst
result['fields'] = _moves_fields
return result
def default_get(self, cr, uid, fields, context=None):
"""
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_partial_move, self).default_get(cr, uid, fields, context=context)
move_obj = self.pool.get('stock.move')
if not context:
context={}
moveids = []
if 'date' in fields:
res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
for m in move_obj.browse(cr, uid, context.get('active_ids', [])):
if m.state in ('done', 'cancel'):
continue
if 'move%s_product_id'%(m.id) in fields:
res['move%s_product_id'%(m.id)] = m.product_id.id
if 'move%s_product_qty'%(m.id) in fields:
res['move%s_product_qty'%(m.id)] = m.product_qty
if 'move%s_product_uom'%(m.id) in fields:
res['move%s_product_uom'%(m.id)] = m.product_uom.id
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
price = 0
if hasattr(m, 'purchase_line_id') and m.purchase_line_id:
price = m.purchase_line_id.price_unit
currency = False
if hasattr(m.picking_id, 'purchase_id') and m.picking_id.purchase_id:
currency = m.picking_id.purchase_id.pricelist_id.currency_id.id
if 'move%s_product_price'%(m.id) in fields:
res['move%s_product_price'%(m.id)] = price
if 'move%s_product_currency'%(m.id) in fields:
res['move%s_product_currency'%(m.id)] = currency
return res
def do_partial(self, cr, uid, ids, context):
move_obj = self.pool.get('stock.move')
move_ids = context.get('active_ids', False)
partial = self.browse(cr, uid, ids[0], context)
partial_datas = {
'partner_id' : partial.partner_id and partial.partner_id.id or False,
'address_id' : partial.address_id and partial.address_id.id or False,
'delivery_date' : partial.date
}
for m in move_obj.browse(cr, uid, move_ids):
if m.state in ('done', 'cancel'):
continue
partial_datas['move%s'%(m.id)] = {
'product_id' : getattr(partial, 'move%s_product_id'%(m.id)).id,
'product_qty' : getattr(partial, 'move%s_product_qty'%(m.id)),
'product_uom' : getattr(partial, 'move%s_product_uom'%(m.id)).id
}
if (m.picking_id.type == 'in') and (m.product_id.cost_method == 'average'):
partial_datas['move%s'%(m.id)].update({
'product_price' : getattr(partial, 'move%s_product_price'%(m.id)),
'product_currency': getattr(partial, 'move%s_product_currency'%(m.id)).id
})
res = move_obj.do_partial(cr, uid, move_ids, partial_datas, context=context)
return {}
stock_partial_move()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_stock_partial_move" model="ir.ui.view">
<field name="name">Delivery Product</field>
<field name="model">stock.partial.move</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Delivery Product">
</form>
</field>
</record>
<act_window name="Delivery Product"
res_model="stock.partial.move"
src_model="stock.move"
view_mode="form"
target="new"
key2="client_action_multi"
id="action_partial_move"/>
</data>
</openerp>

View File

@ -62,11 +62,9 @@ class stock_partial_picking(osv.osv_memory):
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
result = super(stock_partial_picking, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
pick_obj = self.pool.get('stock.picking')
picking_ids = context.get('active_ids', False)
if not picking_ids:
return result
if view_type in ['form']:
_moves_arch_lst = """<form string="Deliver Products">
picking_ids = context.get('active_ids', False)
picking_ids = pick_obj.search(cr, uid, [('id', 'in', picking_ids)])
_moves_arch_lst = """<form string="Deliver Products">
<separator colspan="4" string="Delivery Information"/>
<field name="date" colspan="4" />
<field name="partner_id"/>
@ -74,7 +72,8 @@ class stock_partial_picking(osv.osv_memory):
<newline/>
<separator colspan="4" string="Move Detail"/>
"""
_moves_fields = result['fields']
_moves_fields = result['fields']
if picking_ids and view_type in ['form']:
for pick in pick_obj.browse(cr, uid, picking_ids, context):
for m in pick.move_lines:
if m.state in ('done', 'cancel'):
@ -127,18 +126,18 @@ class stock_partial_picking(osv.osv_memory):
_moves_arch_lst += """
</group>
"""
_moves_arch_lst += """
<separator string="" colspan="4" />
<label string="" colspan="2"/>
<group col="2" colspan="2">
<button icon='gtk-cancel' special="cancel"
string="_Cancel" />
<button name="do_partial" string="_Deliver"
colspan="1" type="object" icon="gtk-apply" />
</group>
</form>"""
result['arch'] = _moves_arch_lst
result['fields'] = _moves_fields
_moves_arch_lst += """
<separator string="" colspan="4" />
<label string="" colspan="2"/>
<group col="2" colspan="2">
<button icon='gtk-cancel' special="cancel"
string="_Cancel" />
<button name="do_partial" string="_Deliver"
colspan="1" type="object" icon="gtk-apply" />
</group>
</form>"""
result['arch'] = _moves_arch_lst
result['fields'] = _moves_fields
return result
def default_get(self, cr, uid, fields, context=None):
@ -160,13 +159,13 @@ class stock_partial_picking(osv.osv_memory):
if not context:
context={}
moveids = []
if 'date' in fields:
res.update({'date': time.strftime('%Y-%m-%d %H:%M:%S')})
for pick in pick_obj.browse(cr, uid, context.get('active_ids', [])):
if 'partner_id' in fields:
res.update({'partner_id': pick.address_id.partner_id.id})
if 'address_id' in fields:
res.update({'address_id': pick.address_id.id})
if 'date' in fields:
res.update({'date': pick.date})
res.update({'address_id': pick.address_id.id})
for m in pick.move_lines:
if m.state in ('done', 'cancel'):
continue
@ -215,8 +214,7 @@ class stock_partial_picking(osv.osv_memory):
partial_datas['move%s'%(m.id)].update({
'product_price' : getattr(partial, 'move%s_product_price'%(m.id)),
'product_currency': getattr(partial, 'move%s_product_currency'%(m.id)).id
})
})
res = pick_obj.do_partial(cr, uid, picking_ids, partial_datas, context=context)
return {}

View File

@ -1,220 +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 time
import netsvc
from tools.misc import UpdateableStr, UpdateableDict
import pooler
import wizard
from osv import osv
import tools
from tools.translate import _
_moves_arch = UpdateableStr()
_moves_fields = UpdateableDict()
_moves_arch_end = '''<?xml version="1.0"?>
<form string="Picking result">
<label string="Move(s) have been successfully Done !" colspan="4"/>
</form>'''
def make_default(val):
def fct(uid, data, state):
return val
return fct
def _to_xml(s):
return (s or '').replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')
def _get_moves(self, cr, uid, data, context):
move_obj = pooler.get_pool(cr.dbname).get('stock.move')
move_lines = move_obj.browse(cr, uid, data['ids'], context)
res = {}
_moves_fields.clear()
_moves_arch_lst = ['<?xml version="1.0"?>', '<form string="Partial Stock Moves">']
for move in move_lines:
quantity = move.product_qty
if move.state != 'assigned':
quantity = 0
_moves_arch_lst.append('<field name="move%s" />' % (move.id,))
_moves_fields['move%s' % move.id] = {
'string': _to_xml(move.name),
'type' : 'float', 'required' : True, 'default' : make_default(quantity)}
if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
price = 0
if hasattr(move, 'purchase_line_id') and move.purchase_line_id:
price = move.purchase_line_id.price_unit
currency = 0
if hasattr(move.picking_id, 'purchase_id') and move.picking_id.purchase_id:
currency = move.picking_id.purchase_id.pricelist_id.currency_id.id
_moves_arch_lst.append('<group col="6"><field name="uom%s" nolabel="1"/>\
<field name="price%s"/>' % (move.id, move.id,))
_moves_fields['price%s' % move.id] = {'string': 'Unit Price',
'type': 'float', 'required': True, 'default': make_default(price)}
_moves_fields['uom%s' % move.id] = {'string': 'UOM', 'type': 'many2one',
'relation': 'product.uom', 'required': True,
'default': make_default(move.product_uom.id)}
_moves_arch_lst.append('<field name="currency%d" nolabel="1"/></group>' % (move.id,))
_moves_fields['currency%s' % m.id] = {'string': 'Currency',
'type': 'many2one', 'relation': 'res.currency',
'required': True, 'default': make_default(currency)}
_moves_arch_lst.append('<newline/>')
res.setdefault('moves', []).append(move.id)
_moves_arch_lst.append('</form>')
_moves_arch.string = '\n'.join(_moves_arch_lst)
return res
def _do_split(self, cr, uid, data, context):
pool = pooler.get_pool(cr.dbname)
move_obj = pool.get('stock.move')
pick_obj = pool.get('stock.picking')
product_obj = pool.get('product.product')
currency_obj = pool.get('res.currency')
users_obj = pool.get('res.users')
uom_obj = pool.get('product.uom')
move_lines = move_obj.browse(cr, uid, data['ids'])
wf_service = netsvc.LocalService("workflow")
complete, too_few, too_many = [], [], []
for move in move_lines:
states = []
if move.product_qty == data['form']['move%s' % move.id]:
complete.append(move)
elif move.product_qty > data['form']['move%s' % move.id]:
too_few.append(move)
else:
too_many.append(move)
# Average price computation
if (move.picking_id.type == 'in') and (move.product_id.cost_method == 'average'):
product = move.product_id
user = users_obj.browse(cr, uid, uid)
qty = data['form']['move%s' % move.id]
uom = data['form']['uom%s' % move.id]
price = data['form']['price%s' % move.id]
currency = data['form']['currency%s' % move.id]
qty = uom_obj._compute_qty(cr, uid, uom, qty, product.uom_id.id)
pricetype=pool.get('product.price.type').browse(cr,uid,user.company_id.property_valuation_price_type.id)
if (qty > 0):
new_price = currency_obj.compute(cr, uid, currency,
user.company_id.currency_id.id, price)
new_price = uom_obj._compute_price(cr, uid, uom, new_price,
product.uom_id.id)
if product.qty_available<=0:
new_std_price = new_price
else:
# Get the standard price
amount_unit=product.price_get(pricetype.field, context)[product.id]
new_std_price = ((amount_unit * product.qty_available)\
+ (new_price * qty))/(product.qty_available + qty)
product_obj.write(cr, uid, [product.id],
{pricetype.field: new_std_price})
move_obj.write(cr, uid, move.id, {'price_unit': new_price})
for move in too_few:
if data['form']['move%s' % move.id] != 0:
new_move = move_obj.copy(cr, uid, move.id,
{
'product_qty' : data['form']['move%s' % move.id],
'product_uos_qty':data['form']['move%s' % move.id],
'picking_id' : move.picking_id.id,
'state': 'assigned',
'move_dest_id': False,
'price_unit': move.price_unit,
})
complete.append(move_obj.browse(cr, uid, new_move))
move_obj.write(cr, uid, move.id,
{
'product_qty' : move.product_qty - data['form']['move%s' % move.id],
'product_uos_qty':move.product_qty - data['form']['move%s' % move.id],
})
for move in too_many:
move_obj.write(cr, uid, move.id,
{
'product_qty': data['form']['move%s' % move.id],
'product_uos_qty': data['form']['move%s' % move.id]
})
complete.append(move)
for move in complete:
move_obj.action_done(cr, uid, [move.id])
# TOCHECK : Done picking if all moves are done
cr.execute('select move.id from stock_picking pick \
right join stock_move move on move.picking_id = pick.id and move.state = ''%s'' where pick.id = %s',
('done', move.picking_id.id))
res = cr.fetchall()
if len(res) == len(move.picking_id.move_lines):
pick_obj.action_move(cr, uid, [move.picking_id.id])
wf_service.trg_validate(uid, 'stock.picking', move.picking_id.id, 'button_done', cr)
return {}
class partial_move(wizard.interface):
states = {
'init': {
'actions': [ _get_moves ],
'result': {'type': 'form', 'arch': _moves_arch, 'fields': _moves_fields,
'state' : (
('end', 'Cancel', 'gtk-cancel'),
('split', 'Partial', 'gtk-apply', True)
)
},
},
'split': {
'actions': [ _do_split ],
'result': {'type': 'state', 'state': 'end2'},
},
'end2': {
'actions': [],
'result': {'type': 'form', 'arch': _moves_arch_end,
'fields': {},
'state': (
('end', 'Close'),
)
},
},
}
partial_move('stock.partial_move')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: