Merge lp:~anybox/wms/picking-internal-protect into lp:wms

Proposed by Christophe CHAUVET
Status: Merged
Merged at revision: 231
Proposed branch: lp:~anybox/wms/picking-internal-protect
Merge into: lp:wms
Diff against target: 222 lines (+164/-3)
5 files modified
wms/__terp__.py (+1/-1)
wms/demo/picking_internal_protect.xml (+118/-0)
wms/object/move.py (+5/-2)
wms/object/picking.py (+38/-0)
wms/object/warehouse.py (+2/-0)
To merge this branch: bzr merge lp:~anybox/wms/picking-internal-protect
Reviewer Review Type Date Requested Status
Christophe CHAUVET Approve
Review via email: mp+72396@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Christophe CHAUVET (christophe-chauvet) wrote :

ok

works for me

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'wms/__terp__.py'
2--- wms/__terp__.py 2011-03-22 14:12:31 +0000
3+++ wms/__terp__.py 2011-08-22 10:10:24 +0000
4@@ -95,8 +95,8 @@
5 'demo/picking_crossdock_one.xml',
6 'demo/monday_round.xml',
7 'demo/burst_in.xml',
8- 'demo/burst_out.xml',
9 'demo/picking_product_reserved_1.xml',
10+ 'demo/picking_internal_protect.xml',
11 ],
12 'installable': True,
13 'active': False,
14
15=== added file 'wms/demo/picking_internal_protect.xml'
16--- wms/demo/picking_internal_protect.xml 1970-01-01 00:00:00 +0000
17+++ wms/demo/picking_internal_protect.xml 2011-08-22 10:10:24 +0000
18@@ -0,0 +1,118 @@
19+<?xml version="1.0" encoding="UTF-8"?>
20+<openerp>
21+ <data noupdate="1">
22+ ##############################################################################
23+ #
24+ # wms module for OpenERP, WMS Extended for Open ERP
25+ # Copyright (C) 2011 SYLEAM ([http://www.syleam.fr/])
26+ # Christophe CHAUVET [christophe.chauvet@syleam.fr]
27+ #
28+ # This file is a part of wms
29+ #
30+ # wms is free software: you can redistribute it and/or modify
31+ # it under the terms of the GNU General Public License as published by
32+ # the Free Software Foundation, either version 3 of the License, or
33+ # (at your option) any later version.
34+ #
35+ # wms is distributed in the hope that it will be useful,
36+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
37+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38+ # GNU General Public License for more details.
39+ #
40+ # You should have received a copy of the GNU General Public License
41+ # along with this program. If not, see [http://www.gnu.org/licenses/].
42+ #
43+ ##############################################################################
44+
45+ <!-- Here we test than internal pickings can't be executed even with
46+ draft_validate if the source location isn't enough supplied -->
47+
48+ <record model="stock.warehouse" id="warehouse1">
49+ <field name="forbid_unsupplied_internal_move">True</field>
50+ </record>
51+
52+ <record model="stock.picking" id="picking_internal_no_stock">
53+ <field name="address_id" ref="base.res_partner_address_7"/>
54+ <field name="invoice_state">none</field>
55+ <field name="move_type">direct</field>
56+ <field name="name">PACK3</field>
57+ <field name="state">draft</field>
58+ <field name="type">internal</field>
59+ <field name="warehouse_id" ref="wms.warehouse1"/>
60+ </record>
61+
62+ <record model="stock.move" id="stock_move_internal_no_stock1">
63+ <field name="location_dest_id" ref="wms.stock_location_w1_stock"/>
64+ <field name="location_id" ref="stock.location_inventory"/>
65+ <field name="name">[MAGICMO] Magic Mouse</field>
66+ <field name="picking_id" ref="picking_internal_no_stock"/>
67+ <field name="priority">1</field>
68+ <field name="product_id" ref="product_magic_mouse"/>
69+ <field name="product_qty" eval="20.0"/>
70+ <field name="product_uom" ref="product.product_uom_unit"/>
71+ </record>
72+
73+ <function name="draft_validate" model="stock.picking">
74+ <value eval="[obj(ref('picking_internal_no_stock')).id]" model="stock.picking"/>
75+ </function>
76+
77+ <assert id="picking_internal_no_stock" model="stock.picking"
78+ severity="error" string="Picking should be confirmed, not done">
79+ <test expr="state">confirmed</test>
80+ </assert>
81+
82+ <assert id="stock_move_internal_no_stock1" model="stock.move"
83+ severity="error" string="Move should be confirmed, not done">
84+ <test expr="state">confirmed</test>
85+ </assert>
86+
87+ <!-- put some products in stock and perform an internal move -->
88+
89+ <record model="stock.move" id="stock_move_supply_before_internal">
90+ <field name="location_dest_id" ref="wms.stock_location_w1_stock"/>
91+ <field name="location_id" ref="stock.location_inventory"/>
92+ <field name="name">Ipad2</field>
93+ <field name="product_id" ref="product_ipad2"/>
94+ <field name="product_qty" eval="17.0"/>
95+ <field name="product_uom" ref="product.product_uom_unit"/>
96+ <field name="state">done</field>
97+ </record>
98+
99+ <record model="stock.picking" id="picking_internal_with_stock">
100+ <field name="address_id" ref="base.res_partner_address_7"/>
101+ <field name="invoice_state">none</field>
102+ <field name="move_type">direct</field>
103+ <field name="name">PACK3</field>
104+ <field name="state">draft</field>
105+ <field name="type">internal</field>
106+ <field name="warehouse_id" ref="wms.warehouse1"/>
107+ </record>
108+
109+ <record model="stock.move" id="stock_move_internal_with_stock1">
110+ <field name="location_dest_id" ref="stock.stock_location_stock"/>
111+ <field name="location_id" ref="wms.stock_location_w1_stock"/>
112+ <field name="name">[IPAD2] IPad 2</field>
113+ <field name="picking_id" ref="picking_internal_with_stock"/>
114+ <field name="priority">1</field>
115+ <field name="product_id" ref="product_ipad2"/>
116+ <field name="product_qty" eval="10.0"/>
117+ <field name="product_uom" ref="product.product_uom_unit"/>
118+ </record>
119+
120+ <function name="draft_validate" model="stock.picking">
121+ <value eval="[obj(ref('picking_internal_with_stock')).id]"
122+ model="stock.picking"/>
123+ </function>
124+
125+ <assert id="stock_move_internal_with_stock1" model="stock.move"
126+ severity="error" string="Move should be done">
127+ <test expr="state">done</test>
128+ </assert>
129+
130+ <!-- back to default setting -->
131+ <record model="stock.warehouse" id="warehouse1">
132+ <field name="forbid_unsupplied_internal_move">False</field>
133+ </record>
134+
135+ </data>
136+</openerp>
137
138=== modified file 'wms/object/move.py'
139--- wms/object/move.py 2011-03-15 13:42:16 +0000
140+++ wms/object/move.py 2011-08-22 10:10:24 +0000
141@@ -147,8 +147,11 @@
142 pickings[move.picking_id.id] = 1
143 continue
144
145- if move.product_id.qty_physical <= 0:
146- continue
147+ # GR: moves related to internal pickings have nothing to do
148+ # with the total amount of product.
149+ if ( (not move.picking_id or move.picking_id.type != 'internal')
150+ and move.product_id.qty_physical <= 0):
151+ continue
152
153 if move.state in ('confirmed', 'waiting'):
154 print 'plop'
155
156=== modified file 'wms/object/picking.py'
157--- wms/object/picking.py 2011-07-18 12:24:41 +0000
158+++ wms/object/picking.py 2011-08-22 10:10:24 +0000
159@@ -623,6 +623,44 @@
160 self.write(cr, uid, ids, {'state': 'draft'}, context=context)
161 return True
162
163+ def draft_validate(self, cr, uid, ids, context=None):
164+ """Force assignation iff not internal and complete the moves.
165+
166+ If the corresponding flag on warehouse is set, those pickings in the
167+ list that are internal go through assignment logic, in effect
168+ forbidding the source locations to go negative.
169+ The other are forced."""
170+
171+ self.action_confirm(cr, uid, ids, context=context)
172+ # dispatch
173+ regular = []
174+ forced = []
175+ wh_obj = self.pool.get('stock.warehouse')
176+ flag = 'forbid_unsupplied_internal_move'
177+ for item in self.read(cr, uid, ids, ['type', 'warehouse_id'],
178+ context=context):
179+ whid = item['warehouse_id'][0]
180+ if item['type'] == 'internal' and whid and wh_obj.read(
181+ cr, uid, whid, [flag]):
182+ regular.append(item['id'])
183+ else:
184+ forced.append(item['id'])
185+
186+ self.action_assign(cr, uid, regular)
187+ self.force_assign(cr, uid, forced)
188+
189+ # finish assigned moves and apply wkf logic
190+ wf_service = netsvc.LocalService("workflow")
191+ for pid in ids:
192+ wf_service.trg_write(uid, 'stock.picking', pid, cr)
193+
194+ self.action_move(cr, uid, ids, context=context)
195+
196+ for pid in ids:
197+ wf_service.trg_validate(uid, 'stock.picking',
198+ pid, 'button_done', cr)
199+ return True
200+
201 #def test_cancel(self, cr, uid, ids, context={}):
202 # """
203 # Redefine test cancel, to protect
204
205=== modified file 'wms/object/warehouse.py'
206--- wms/object/warehouse.py 2011-07-18 12:24:41 +0000
207+++ wms/object/warehouse.py 2011-08-22 10:10:24 +0000
208@@ -44,12 +44,14 @@
209 'check_tracking_burst': fields.boolean('check tracking', help='Check tracking on burst out'),
210 'keep_missing_product_in': fields.boolean('Keep product in', help='If check, missing product line on receipt order stay with quantity = 0'),
211 'force_reserved_location': fields.boolean('Force reserved', help='Force move product in reserved location'),
212+ 'forbid_unsupplied_internal_move' : fields.boolean('Forbid unsupplied internal', help="Prevent internal moves with not enough stock level"),
213 }
214
215 _defaults = {
216 'check_tracking_burst': lambda *a: False,
217 'keep_missing_product_in': lambda *a: True,
218 'force_reserved_location': lambda *a: False,
219+ 'forbid_unsupplied_internal_move': lambda *a: False,
220 }
221
222 def _check_recursion(self, cr, uid, ids):

Subscribers

People subscribed via source and target branches