[WIP] removed stock_splitinto wizard + implemented the preparation of pack operations

bzr revid: qdp-launchpad@openerp.com-20130726180942-skbp1lnri8j05t6t
This commit is contained in:
Quentin (OpenERP)
2013-07-26 20:09:42 +02:00
parent b34432e029
commit 90aa53ad15
6 changed files with 68 additions and 146 deletions
-1
View File
@@ -72,7 +72,6 @@ Dashboard / Reports for Warehouse Management will include:
'wizard/stock_fill_inventory_view.xml',
'wizard/stock_inventory_merge_view.xml',
'wizard/stock_location_product_view.xml',
'wizard/stock_splitinto_view.xml',
'wizard/stock_inventory_line_split_view.xml',
'wizard/stock_return_picking_view.xml',
'wizard/make_procurement_view.xml',
+58 -22
View File
@@ -421,7 +421,14 @@ class stock_picking(osv.osv):
if move.picking_id:
res.add(move.picking_id.id)
return list(res)
def _get_pack_operation_exist(self, cr, uid, ids, field_name, arg, context=None):
res = {}
for pick in self.browse(cr, uid, ids, context=context):
res[pick.id] = False
if pick.pack_operation_ids:
res[pick.id] = True
return res
_columns = {
'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
@@ -465,6 +472,7 @@ class stock_picking(osv.osv):
'picking_type_id': fields.many2one('stock.picking.type', 'Picking Type', required=True),
#related('move_lines', 'picking_type_id', type='many2one', relation='stock.picking.type', string="Picking Type", readonly=True),
'rule_id': fields.related('move_lines', 'rule_id', type='many2one', relation='procurement.rule', string="Procurement Rule", readonly=True),
'pack_operation_exist': fields.function(_get_pack_operation_exist, type='boolean', string='Pack Operation Exists?', help='technical field for attrs in view'),
}
_defaults = {
'name': lambda self, cr, uid, context: '/',
@@ -546,7 +554,7 @@ class stock_picking(osv.osv):
@return: True
"""
self.draft_force_assign(cr, uid, ids)
return self.do_partial(cr, uid, ids, context=context)
return self.action_done(cr, uid, ids, context=context)
def cancel_assign(self, cr, uid, ids, *args):
""" Cancels picking and moves.
@@ -583,24 +591,10 @@ class stock_picking(osv.osv):
self.write(cr, uid, ids, {'state': 'cancel'})
return True
#
# TODO: change and create a move if not parents
#
def action_done(self, cr, uid, ids, context=None):
"""Changes picking state to done.
This method is called at the end of the workflow by the activity "done".
@return: True
"""
self.action_move(cr, uid, ids, context=context)#write(cr, uid, ids, {'date_done': time.strftime('%Y-%m-%d %H:%M:%S')})
return True
def action_move(self, cr, uid, ids, context=None):
"""Process the Stock Moves of the Picking
"""Changes picking state to done by processing the Stock Moves of the Picking
This method is called by the workflow by the activity "move".
Normally that happens when the signal button_done is received (button
"Done" pressed on a Picking view).
Normally that happens when the button "Done" is pressed on a Picking view.
@return: True
"""
for pick in self.browse(cr, uid, ids, context=context):
@@ -616,7 +610,6 @@ class stock_picking(osv.osv):
self.pool.get('stock.move').action_done(cr, uid, todo, context=context)
return True
def unlink(self, cr, uid, ids, context=None):
move_obj = self.pool.get('stock.move')
if context is None:
@@ -697,6 +690,49 @@ class stock_picking(osv.osv):
'picking_type_id': self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'picking_type_internal')[1],
'price_unit': cost}, context=context)
def do_prepare_partial(self, cr, uid, picking_ids, context=None):
assert len(picking_ids) == 1, 'Partial picking is only supported for one record at a time'
pack_operation_obj = self.pool.get('stock.pack.operation')
if context is None:
context = {}
picking = self.browse(cr, uid, picking_ids[0], context=context)
vals = []
package_ids = set()
for move in picking.move_lines:
remaining_qty = move.product_qty
#if move.move_orig_ids and move.move_orig_ids[0].picking_id: # TODO: check on previous moves ??? o_O
for quant in move.reserved_quant_ids:
qty = min(quant.qty, move.product_qty) # TODO: check if min() is necessary here, cause the assignation should have split the quants.. so i'd say probably not necessarry
remaining_qty -= qty
if quant.package_id:
package_ids.add(quant.package_id.id)
continue
vals += [{
'picking_id': picking.id,
'product_qty': qty,
'quant_id': quant.id,
'product_id': quant.product_id.id, # TODO: check that we can use product_id + quant_id
'product_uom_id': quant.product_id.uom_id.id, # TODO: use move.product_packaging?
'cost': quant.cost,
}]
if remaining_qty > 0:
vals += [{
'picking_id': picking.id,
'product_qty': remaining_qty,
'product_id': move.product_id.id,
'product_uom_id': move.product_id.uom_id.id,
'cost': move.product_id.standard_price,
}]
#create the operations for all the packages found
for package_id in list(package_ids):
vals += [{
'picking_id': picking.id,
'product_qty': 1,
'package_id': package_id,
}]
for values in vals:
pack_operation_obj.create(cr, uid, values, context=context)
def do_partial(self, cr, uid, picking_ids, context=None):
""" Makes partial picking based on pack_operation_ids field.
:param only_split_line: boolen that depicts if the moves should not be set to done.
@@ -708,8 +744,6 @@ class stock_picking(osv.osv):
quant_package_obj = self.pool.get('stock.quant.package')
todo_move_ids = []
assert len(picking_ids) == 1, 'Partial picking is only supported for one record at a time'
if context is None:
context = {}
picking = self.browse(cr, uid, picking_ids[0], context=context)
for op in picking.pack_operation_ids:
if op.package_id:
@@ -721,6 +755,7 @@ class stock_picking(osv.osv):
for move_id, qty in self._find_moves_from_product(cr, uid, picking.id, quant.product_id.id, qty_to_dispatch, context=context):
if not move_id:
move_id = self._create_unexpected_move(cr, uid, picking, quant.product_id, qty, quant.cost, quant, context=context)
todo_move_ids += [move_id]
else:
partial_datas = {
'product_qty': qty,
@@ -737,6 +772,7 @@ class stock_picking(osv.osv):
if not move_id:
#product not expected
move_id = self._create_unexpected_move(cr, uid, picking, product, qty, cost, quant=reserved_quant_id, context=context)
todo_move_ids += [move_id]
else:
partial_datas = {
'product_qty': qty,
@@ -977,7 +1013,7 @@ class stock_move(osv.osv):
'move_dest_id': fields.many2one('stock.move', 'Destination Move', help="Optional: next stock move when chaining them", select=True),
'move_orig_ids': fields.one2many('stock.move', 'move_dest_id', 'Original Move', help="Optional: next stock move when chaining them", select=True),
'move_orig_ids': fields.one2many('stock.move', 'move_dest_id', 'Original Move', help="Optional: previous stock move when chaining them", select=True),
'picking_id': fields.many2one('stock.picking', 'Reference', select=True,states={'done': [('readonly', True)]}),
'note': fields.text('Notes'),
+10 -7
View File
@@ -581,13 +581,15 @@
<field eval="12" name="priority"/>
<field name="arch" type="xml">
<form string="Internal Picking List" version="7.0">
<field name='pack_operation_exist' invisible="1"/>
<header>
<button name="draft_force_assign" states="draft" string="Confirm" type="object" class="oe_highlight" groups="base.group_user"/>
<button name="draft_validate" states="draft" string="Confirm &amp; Transfer" type="object" class="oe_highlight" groups="base.group_user"/>
<button name="draft_validate" states="draft" string="Confirm &amp; Total Transfer" type="object" class="oe_highlight" groups="base.group_user"/>
<!-- <button name="check_assign" states="confirmed" string="Check Availability" type="object"/> -->
<button name="force_assign" states="confirmed" string="Force Availability" type="object" class="oe_highlight" groups="base.group_user"/>
<button name="do_partial" states="assigned" string="Confirm &amp; Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
<button name="action_pack" states="draft,assigned,confirmed" string="Create Package" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
<button name="action_done" states="assigned" string="Total Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
<button name="do_prepare_partial" states="assigned" string="(prepare) Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': [('pack_operation_exist','=',True)]}"/>
<button name="do_partial" states="assigned" string="Partial Transfer" groups="stock.group_stock_user" type="object" class="oe_highlight" attrs="{'invisible': [('pack_operation_exist','=',False)]}"/>
<button name="%(act_stock_return_picking)d" string="Reverse Transfer" states="done" type="action" groups="base.group_user"/>
<button name="button_cancel" states="assigned,confirmed,draft" string="Cancel Transfer" groups="base.group_user"/>
<field name="state" widget="statusbar" statusbar_visible="draft,assigned,done" statusbar_colors='{"shipping_except":"red","invoice_except":"red","waiting_date":"blue"}'/>
@@ -609,8 +611,7 @@
</group>
</group>
<notebook>
<page string="Products">
<field name="move_lines" context="{'address_in_id': partner_id, 'form_view_ref':'view_move_picking_form', 'tree_view_ref':'view_move_picking_tree'}"/>
<page string="Partial/Packing Operations" attrs="{'invisible': [('pack_operation_exist','=',False)]}">
<field name="pack_operation_ids">
<tree editable="top">
<field name="product_id"/>
@@ -621,9 +622,11 @@
<field name="result_package_id"/>
</tree>
</field>
<field name="note" placeholder="Add an internal note..." class="oe_inline"/>
<button name="action_pack" states="draft,assigned,confirmed" string="Create Package" type="object" class="oe_link"/>
</page>
<page string="Packed">
<page string="Products">
<field name="move_lines" context="{'address_in_id': partner_id, 'form_view_ref':'view_move_picking_form', 'tree_view_ref':'view_move_picking_tree'}"/>
<field name="note" placeholder="Add an internal note..." class="oe_inline"/>
</page>
<page string="Additional Info">
<group>
-1
View File
@@ -21,7 +21,6 @@
import stock_traceability
import stock_move
import stock_splitinto
import stock_inventory_merge
import stock_fill_inventory
import stock_inventory_line_split
-85
View File
@@ -1,85 +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/>.
#
##############################################################################
from openerp.osv import fields, osv
from openerp.tools.translate import _
import openerp.addons.decimal_precision as dp
class stock_split_into(osv.osv_memory):
_name = "stock.split.into"
_description = "Split into"
_columns = {
'quantity': fields.float('Quantity',digits_compute=dp.get_precision('Product Unit of Measure')),
}
_defaults = {
'quantity': lambda *x: 0,
}
def split(self, cr, uid, data, context=None):
if context is None:
context = {}
inventory_id = context.get('inventory_id', False)
rec_id = context and context.get('active_ids', False)
move_obj = self.pool.get('stock.move')
track_obj = self.pool.get('stock.tracking')
inventory_obj = self.pool.get('stock.inventory')
quantity = self.browse(cr, uid, data[0], context=context).quantity or 0.0
for move in move_obj.browse(cr, uid, rec_id, context=context):
quantity_rest = move.product_uom_qty - quantity
#if move.tracking_id :
# raise osv.except_osv(_('Error!'), _('The current move line is already assigned to a pack, please remove it first if you really want to change it ' \
# 'for this product: "%s" (id: %d)') % \
# (move.product_id.name, move.product_id.id,))
if quantity > move.product_uom_qty:
raise osv.except_osv(_('Error!'), _('Total quantity after split exceeds the quantity to split ' \
'for this product: "%s" (id: %d).') % \
(move.product_id.name, move.product_id.id,))
if quantity > 0:
move_obj.setlast_tracking(cr, uid, [move.id], context=context)
move_obj.write(cr, uid, [move.id], {
'product_uom_qty': quantity,
'product_uos_qty': quantity,
'product_uos': move.product_uom.id,
})
if quantity_rest>0:
quantity_rest = move.product_uom_qty - quantity
tracking_id = track_obj.create(cr, uid, {}, context=context)
if quantity == 0.0:
move_obj.write(cr, uid, [move.id], {'tracking_id': tracking_id}, context=context)
else:
default_val = {
'product_uom_qty': quantity_rest,
'product_uos_qty': quantity_rest,
'tracking_id': tracking_id,
'state': move.state,
'product_uos': move.product_uom.id
}
current_move = move_obj.copy(cr, uid, move.id, default_val, context=context)
if inventory_id and current_move:
inventory_obj.write(cr, uid, inventory_id, {'move_ids': [(4, current_move)]}, context=context)
return {'type': 'ir.actions.act_window_close'}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_stock_move_split_wizard" model="ir.ui.view">
<field name="name">Split move</field>
<field name="model">stock.split.into</field>
<field name="arch" type="xml">
<form string="Split Move" version="7.0">
<separator string="Quantity to Leave in the Current Pack"/>
<group>
<field name="quantity"/>
</group>
<footer>
<button name="split" string="Ok" type="object" class="oe_highlight" />
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="split_into" model="ir.actions.act_window">
<field name="name">Split into</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">stock.split.into</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>