[WIP] removed stock_splitinto wizard + implemented the preparation of pack operations
bzr revid: qdp-launchpad@openerp.com-20130726180942-skbp1lnri8j05t6t
This commit is contained in:
@@ -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
@@ -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'),
|
||||
|
||||
@@ -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 & Transfer" type="object" class="oe_highlight" groups="base.group_user"/>
|
||||
<button name="draft_validate" states="draft" string="Confirm & 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 & 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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user