Merge lp:~syleam/wms/5.0-jean-sebastien-suzanne into lp:~syleam/wms/5.0-christophe-chauvet

Status: Merged
Merged at revision: 245
Proposed branch: lp:~syleam/wms/5.0-jean-sebastien-suzanne
Merge into: lp:~syleam/wms/5.0-christophe-chauvet
Diff against target: 539 lines (+246/-56)
9 files modified
wms/object/warehouse.py (+2/-0)
wms/view/warehouse.xml (+3/-0)
wms/wizard/wizard_partial_picking.py (+5/-1)
wms_location/data/location.xml (+9/-0)
wms_sale/object/__init__.py (+1/-0)
wms_sale/object/common.py (+33/-0)
wms_sale/object/move.py (+100/-46)
wms_sale/object/picking.py (+34/-9)
wms_sale/object/product.py (+59/-0)
To merge this branch: bzr merge lp:~syleam/wms/5.0-jean-sebastien-suzanne
Reviewer Review Type Date Requested Status
Christophe CHAUVET Approve
Review via email: mp+52709@code.launchpad.net

Description of the change

- Merge with branch of Sébastien LANGE
- FIX P.U.M.P. compute

To post a comment you must log in.
Revision history for this message
Christophe CHAUVET (christophe-chauvet) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'wms/object/warehouse.py'
2--- wms/object/warehouse.py 2011-02-27 21:11:57 +0000
3+++ wms/object/warehouse.py 2011-03-09 16:12:14 +0000
4@@ -39,6 +39,8 @@
5 'parent_id': fields.many2one('stock.warehouse', 'Parent warehouse', help='Define the parent warehouse'),
6 'crossdock_location_id': fields.many2one('stock.location', 'Crossdock location',
7 help='Choose the crossdock location on this warehouse'),
8+ 'return_location_id': fields.many2one('stock.location', 'Return location',
9+ help='Choose the return location on this warehouse'),
10 'check_tracking_burst': fields.boolean('check tracking', help='Check tracking on burst out'),
11 'keep_missing_product_in': fields.boolean('Keep product in', help='If check, missing product line on receipt order stay with quantity = 0'),
12 }
13
14=== modified file 'wms/view/warehouse.xml'
15--- wms/view/warehouse.xml 2011-03-02 22:37:03 +0000
16+++ wms/view/warehouse.xml 2011-03-09 16:12:14 +0000
17@@ -51,6 +51,9 @@
18 <xpath expr="/form/field[@name='lot_output_id']" position="after">
19 <field name="crossdock_location_id" domain="[('warehouse_id','=', active_id),('usage','=', 'internal')]"/>
20 </xpath>
21+ <xpath expr="/form/field[@name='lot_output_id']" position="after">
22+ <field name="return_location_id" domain="[('warehouse_id','=', active_id),('usage','=', 'internal')]"/>
23+ </xpath>
24 <xpath expr="/form/field[@name='partner_address_id']" position="after">
25 <notebook colspan="4">
26 <page string="Information">
27
28=== modified file 'wms/wizard/wizard_partial_picking.py'
29--- wms/wizard/wizard_partial_picking.py 2010-11-23 19:06:08 +0000
30+++ wms/wizard/wizard_partial_picking.py 2011-03-09 16:12:14 +0000
31@@ -77,7 +77,11 @@
32
33 currency=0
34 if hasattr(pick, 'purchase_id') and pick.purchase_id:
35- currency=pick.purchase_id.pricelist_id.currency_id.id
36+ currency = pick.purchase_id.pricelist_id.currency_id.id
37+ elif hasattr(pick, 'address_id') and pick.address_id:
38+ currency = pick.address_id.partner_id.property_product_pricelist.currency_id.id
39+ else:
40+ currency = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, uid, context=context).company_id.currency_id.id
41
42 _moves_arch_lst.append('<group col="6" invisible="1"><field name="uom%s" nolabel="1"/>\
43 <field name="price%s"/>' % (m.id,m.id,))
44
45=== modified file 'wms_location/data/location.xml'
46--- wms_location/data/location.xml 2011-03-02 22:37:03 +0000
47+++ wms_location/data/location.xml 2011-03-09 16:12:14 +0000
48@@ -69,5 +69,14 @@
49 <field name="active" eval="True"/>
50 </record>
51
52+ <!-- ************************************************************* -->
53+ <!-- ** Add Return location as category ******* -->
54+ <!-- ************************************************************* -->
55+ <record id="location_category_return" model="stock.location.category">
56+ <field name="name">Return</field>
57+ <field name="code">RETURN</field>
58+ <field name="active" eval="True"/>
59+ </record>
60+
61 </data>
62 </openerp>
63
64=== modified file 'wms_sale/object/__init__.py'
65--- wms_sale/object/__init__.py 2011-02-20 16:05:05 +0000
66+++ wms_sale/object/__init__.py 2011-03-09 16:12:14 +0000
67@@ -26,5 +26,6 @@
68 import company
69 import picking
70 import sale
71+import product
72
73 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
74
75=== added file 'wms_sale/object/common.py'
76--- wms_sale/object/common.py 1970-01-01 00:00:00 +0000
77+++ wms_sale/object/common.py 2011-03-09 16:12:14 +0000
78@@ -0,0 +1,33 @@
79+# -*- coding: utf-8 -*-
80+##############################################################################
81+#
82+# wms_sale module for OpenERP, Module to extended sale with WMS
83+# Copyright (C) 2011 SYLEAM Info Services (<http://www.syleam.fr/>)
84+# Jean-Sébastien SUZANNE <jean-sebastien.suzanne@syleam.fr>
85+#
86+# This file is a part of wms_sale
87+#
88+# wms_sale is free software: you can redistribute it and/or modify
89+# it under the terms of the GNU General Public License as published by
90+# the Free Software Foundation, either version 3 of the License, or
91+# (at your option) any later version.
92+#
93+# wms_sale is distributed in the hope that it will be useful,
94+# but WITHOUT ANY WARRANTY; without even the implied warranty of
95+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
96+# GNU General Public License for more details.
97+#
98+# You should have received a copy of the GNU General Public License
99+# along with this program. If not, see <http://www.gnu.org/licenses/>.
100+#
101+##############################################################################
102+
103+import time
104+
105+def log_message(fic, section, message):
106+ """
107+ Format the content of the logfile
108+ """
109+ fic.write('[%s] %s: %s\n' % (time.strftime('%Y-%m-%d %H:%M:%S'), section.encode('utf-8'), message.encode('utf-8')))
110+
111+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
112
113=== modified file 'wms_sale/object/move.py'
114--- wms_sale/object/move.py 2011-03-04 09:52:11 +0000
115+++ wms_sale/object/move.py 2011-03-09 16:12:14 +0000
116@@ -26,6 +26,7 @@
117 from osv import fields
118 from datetime import datetime, timedelta
119 from tools.translate import _
120+from common import log_message
121
122
123 class StockMove(osv.osv):
124@@ -52,6 +53,11 @@
125 _columns = {
126 'partner': fields.function(_order_partner, method=True, type='char', multi='sums', string='Partner'),
127 'order': fields.function(_order_partner, method=True, type='char', multi='sums', string='Order'),
128+ 'average_uom_id': fields.many2one('product.uom', 'Average UOM Unit', help="is the UOM of the average price" ),
129+ }
130+
131+ _defaults = {
132+ 'average_uom_id': lambda *a: False,
133 }
134
135 def action_done(self, cr, uid, ids, context=None):
136@@ -94,6 +100,52 @@
137 raise osv.except_osv(_('ERROR'), _('More move to compute without the same picking or the product'))
138 return (picking_id, product_id)
139
140+ def _get_qty(self, cr, uid, id, context=None):
141+ """
142+ return the real qty in move in function of location_id and location_dest_id
143+ __________________________________________________________________________________________________
144+ | qty in/dest | supplier | view | internal | customer | inventory | procurement | production |
145+ --------------------------------------------------------------------------------------------------
146+ | supplier | error | error | + | 0 | error | 0 | error |
147+ --------------------------------------------------------------------------------------------------
148+ | view | error | error | error | error | error | error | error |
149+ --------------------------------------------------------------------------------------------------
150+ | internal | - | error | 0 | - | - | 0 | - |
151+ --------------------------------------------------------------------------------------------------
152+ | customer | 0 | error | + | error | error | 0 | error |
153+ --------------------------------------------------------------------------------------------------
154+ | inventory | error | error | + | error | error | error | error |
155+ --------------------------------------------------------------------------------------------------
156+ | procurement | 0 | error | 0 | 0 | error | 0 | 0 |
157+ --------------------------------------------------------------------------------------------------
158+ | production | error | error | + | error | error | 0 | error |
159+ --------------------------------------------------------------------------------------------------
160+ """
161+ if not id:
162+ raise osv.except_osv(_('Move ERROR'), _('No move ID define to get quantity'))
163+ move = self.browse(cr, uid, id, context=context)
164+ loc_usage = move.location_id.usage
165+ loc_dest_usage = move.location_dest_id.usage
166+ if loc_usage == 'internal' and loc_dest_usage in ['supplier', 'customer', 'inventary', 'production']:
167+ return - move.product_qty
168+ elif loc_dest_usage == 'internal' and loc_usage in ['supplier', 'customer', 'inventary', 'production']:
169+ return move.product_qty
170+ elif loc_usage == 'procurement' and loc_dest_usage in ['supplier', 'customer', 'internal', 'production', 'procurement']:
171+ return 0.0
172+ elif loc_dest_usage == 'procurement' and loc_usage in ['supplier', 'customer', 'internal', 'production']:
173+ return 0.0
174+ elif loc_usage == 'supplier' and loc_dest_usage == 'customer':
175+ return 0.0
176+ elif loc_dest_usage == 'supplier' and loc_usage == 'customer':
177+ return 0.0
178+ elif loc_usage == 'internal' and loc_dest_usage == 'internal':
179+ return 0.0
180+ else:
181+ raise osv.except_osv(_('Get move quantity error'),
182+ _('the move %s(%d) with mouvement %s(%d) usage %s ==> %s(%d) usage %s is not allowed') \
183+ % (move.name, move.id, move.location_id.name, move.location_id.id, loc_usage, move.location_dest_id.name, move.location_dest_id.id, loc_dest_usage)
184+ )
185+
186 def get_previous_pump(self, cr, uid, id, date_planned, product_id, context=None):
187 """
188 find the move linked with a picking type in before the current move
189@@ -102,6 +154,7 @@
190 if context is None:
191 context = {}
192 # make domain to find move
193+ product_obj = self.pool.get('product.product')
194 domain = [
195 ('state', '=', 'done'), # the move must be done
196 ('date_planned', '<', date_planned), # the date planned must be after the current move
197@@ -118,10 +171,16 @@
198 pump = 0.0
199 if not move_ids:
200 #No receiving picking found, we take the standard_price of the product
201- pump = self.pool.get('product.product').read(cr, uid, product_id, ['standard_price'], context=context)['standard_price']
202+ pump = product_obj.read(cr, uid, product_id, ['standard_price'], context=context).get('standard_price', 0.0)
203 else:
204 # they are only one value so take the average_price(pump) of this move
205- pump = self.read(cr, uid, move_ids[0], ['average_price'], context=context)['average_price']
206+ move_rd = self.read(cr, uid, move_ids[0], ['average_price', 'average_uom_id'], context=context)
207+ if move_rd.get('average_uom_id', False):
208+ uom_id = move_rd.get('average_uom_id')[0]
209+ average_price = move_rd.get('average_price', 0.0)
210+ pump = product_obj.convert_price_in_default_unit(cr, uid, product_id, average_price, uom_id,context=context)
211+ else:
212+ pump = move_rd.get('standard_price', 0.0)
213 return pump
214
215 def get_qty_at_previous_time(self, cr, uid, product_id, date_planned, context=None):
216@@ -154,17 +213,20 @@
217 """
218 if context is None:
219 context = {}
220+ outfp = context.get('log_message', False)
221+ product_obj = self.pool.get('product.product')
222 #the move ids must have the same picking and the same product
223 picking_id, product_id = self.get_picking_and_product_from_moves(cr, uid, ids, context=context)
224 # get move_ids[0] data
225 move_rd = self.read(cr, uid, ids[0], ['date_planned', 'price_unit'], context=context)
226 # get the pump
227+ # already in good unit
228 pump = self.get_previous_pump(cr, uid, move_rd.get('id'), move_rd.get('date_planned'), product_id, context=context)
229+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'The Start P.U.M.P. is %s' % repr(pump))
230 # get the qantity after this moves
231 stock_qty = self.get_qty_at_previous_time(cr, uid, product_id, move_rd.get('date_planned'), context=context)
232
233 # list of move already compute
234- computed = []
235 # define the type of picking looked for
236 company = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id
237 picking_type = ['in']
238@@ -172,76 +234,68 @@
239 picking_type.append('internal')
240 if company.average_price_stock_picking_out:
241 picking_type.append('out')
242+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'List of picking to save PUMP %s (delivery is never here he is computed after)' % repr(picking_type))
243
244 # make domain for search
245 domain = [
246 ('state', '=', 'done'), # only the move in state done
247 ('date_planned', '>=', move_rd.get('date_planned')), # only the move after or equal the current
248 ('product_id', '=', product_id), # on this product
249- '|', # make an 'or'
250- ('picking_id', '=', False), # no picking
251- '&', ('picking_id.state', '=', 'done'), ('picking_id.type', 'in', picking_type), # or picking with done and type in picking_type define in company
252+ ('location_id.usage', 'not in', ['view', 'procurement']), # we dont want view
253+ ('location_dest_id.usage', 'not in', ['view', 'procurement']), # we dont want view
254 ]
255 order_by = 'date_planned, id'
256
257 move_ids = self.search(cr, uid, domain, order=order_by, context=context)
258- to_compute = list(move_ids)
259+
260+ delivery_ids = []
261 for move_id in move_ids:
262- # test if the compute alredy exist
263- if move_id in computed:
264- continue
265- # group move this same date_planned, same picking in ids search
266+ #get new qty at the date_planned
267+ qty = self._get_qty(cr, uid, move_id, context=context)
268 move = self.browse(cr, uid, move_id, context=context)
269- group_domain = [
270- ('date_planned', '=', move.date_planned), # the same date
271- ('picking_id', '=', move.picking_id and move.picking_id.id or False), # the same picking
272- ('id', 'in', to_compute), # in the compute found
273- ]
274- group_move_ids = self.search(cr, uid, group_domain, context=context)
275-
276- #get new qty at the date_planned
277- qty = self.get_qty_at_time(cr, uid, product_id, move.date_planned, context=context)
278+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'compute the move %s(%d) with picking type %s' % (move.name, move.id, move.picking_id and move.picking_id.type or 'None'))
279 if move.picking_id and move.picking_id.type == 'in':
280+ # get the price of the move
281+ price_unit = product_obj.convert_price_in_default_unit(cr, uid, product_id, move.price_unit, move.product_uom and move.product_uom.id or False, context=context)
282+ # the pump uom is not the same that sale uom
283 #calcul new pump
284 # new pump = [ (pump * stock_qty) + ( price_unit * received qty ) ] / (stock qty + received qty )
285 # only if stock_qty
286- if stock_qty > 0:
287- pump = ((pump * stock_qty) + (move.price_unit * (qty - stock_qty))) / qty
288+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'Compute the new P.U.M.P. = ((%s * %s) + (%s * %s)) / %s'\
289+ % (repr(pump), repr(stock_qty), repr(price_unit), repr(qty), repr(stock_qty + qty)))
290+ if stock_qty + qty > 0:
291+ pump = ((pump * stock_qty) + (price_unit * qty)) / (stock_qty + qty)
292 else:
293 # if stock_qty == 0 => pump = (price_unit * qty) / qty => pump = price_unit
294 # if stock_qty < 0 (example -1) => pump = ( -pump + ( price_unit * qty) ) / (qty - 1)
295 ## error cause if qty = stock_qty => division by zero
296 ## qty < stock_qty => pump < 0 forbiden
297 ## qty > stock_qty => pump wrong the good pump is the price_unit
298- pump = move.price_unit
299- # write the pump in average_price
300- self.write(cr, uid, group_move_ids, {'average_price': pump}, context=context)
301+ pump = price_unit
302+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'Compute the new P.U.M.P. = %s' % repr(pump))
303+ if move.picking_id and move.picking_id.type in picking_type:
304+ # write the pump in average_price
305+ average_uom_id = move.product_id.list_price_uom_id and move.product_id.list_price_uom_id.id or move.product_uom.id
306+ self.write(cr, uid, move_id, {'average_price': pump, 'average_uom_id': average_uom_id}, context=context)
307+ elif company.average_price_stock_picking_delivery and move.picking_id.type == 'delivery':
308+ delivery_ids.append(move_id)
309 # save new stock_qty and compute list
310- stock_qty = qty
311- computed.extend(group_move_ids)
312- # remove the id computed
313- for m in group_move_ids:
314- to_compute.remove(m)
315-
316- self.pool.get('product.product').write(cr, uid, [product_id], {'standard_price': pump}, context=context)
317-
318+ stock_qty = (stock_qty + qty)
319+
320+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'save the P.U.M.P. %s on product %d' % (repr(pump), product_id))
321+ product_obj.write(cr, uid, [product_id], {'standard_price': pump}, context=context)
322 # only for the delivery
323- if company.average_price_stock_picking_delivery:
324- domain = [
325- ('state', '=', 'done'), # only the move in state done
326- ('date_planned', '>=', move_rd.get('date_planned')), # only the move after or equal the current
327- ('product_id', '=', product_id), # on this product
328- ('picking_id.state', '=', 'done'), # pickinf is done
329- ('picking_id.type', '=', 'delivery'), # type in picking_type must be a delivery
330- ]
331- move_delivery_ids = self.search(cr, uid, domain, order=order_by, context=context)
332- for move in self.browse(cr, uid, move_delivery_ids, context=context):
333+ if delivery_ids and company.average_price_stock_picking_out:
334+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'save the P.U.M.P. On delivery with method %s' % company.average_price_stock_picking_delivery_method)
335+ for move in self.browse(cr, uid, delivery_ids, context=context):
336+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'for move %s(%d)'% (move.name, move.id))
337 # they are three mode:
338 # 1 : the sale order is invoiced so we dont touch of the pump
339 # 2 : the pump of the delivery is on the product (average_price_stock_picking_delivery_method == product on company) use the pump in the product
340 # 3 : the pump of the delivery is on the out picking (average_price_stock_picking_delivery_method == out on company) use the pump in the move in delivery out
341 if move.sale_line_id.order_id.invoiced:
342 # the sale order is invoiced
343+ log_message(outfp, 'wms_sale.stock_move.compute_pump', 'Already Invoiced')
344 continue
345 elif company.average_price_stock_picking_delivery_method == 'product':
346 # take the pump of the product. we have already the pump because the saved is make before and the value is in pump variable
347@@ -256,11 +310,11 @@
348 ('name', '=', move.name), # the same name
349 ]
350 move_out_id = self.search(cr, uid, domain, context=context)[0]
351- move_out_average_price = self.read(cr, uid, move_out_id, ['average_price'], context=context)['average_price']
352- self.write(cr, uid, move.id, {'average_price': move_out_average_price}, context=context)
353+ move_out_average = self.read(cr, uid, move_out_id, ['average_price', 'average_uom_id', 'product_uom'], context=context)
354+ average_uom_id = move_out_average.get('average_uom_id', move_out_average.get('product_uom', [False]))[0]
355+ self.write(cr, uid, move.id, {'average_price': move_out_average.get('average_price', 0.0), 'average_uom_id': average_uom_id}, context=context)
356 else:
357 raise osv.except_osv(_('WARNING'), _('No delivery mode found for the compute of the P.U.M.P. on delivery move'))
358-
359 return True
360
361 StockMove()
362
363=== modified file 'wms_sale/object/picking.py'
364--- wms_sale/object/picking.py 2011-02-20 16:05:05 +0000
365+++ wms_sale/object/picking.py 2011-03-09 16:12:14 +0000
366@@ -1,18 +1,18 @@
367 # -*- coding: utf-8 -*-
368 ##############################################################################
369 #
370-# wms_purchase module for OpenERP, Inherite purcharge for wms
371+# wms_sale module for OpenERP, Inherite purcharge for wms
372 # Copyright (C) 2010 SYLEAM Info Services (<http://www.syleam.fr/>)
373 # Jean-Sébastien SUZANNE <jean-sebastien.suzanne@syleam.fr>
374 #
375-# This file is a part of wms_purchase
376+# This file is a part of wms_sale
377 #
378-# wms_purchase is free software: you can redistribute it and/or modify
379+# wms_sale is free software: you can redistribute it and/or modify
380 # it under the terms of the GNU General Public License as published by
381 # the Free Software Foundation, either version 3 of the License, or
382 # (at your option) any later version.
383 #
384-# wms_purchase is distributed in the hope that it will be useful,
385+# wms_sale is distributed in the hope that it will be useful,
386 # but WITHOUT ANY WARRANTY; without even the implied warranty of
387 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
388 # GNU General Public License for more details.
389@@ -26,6 +26,9 @@
390 import pooler
391 import thread
392 from tools.translate import _
393+import tempfile
394+from common import log_message
395+import base64
396 import netsvc
397 logger = netsvc.Logger()
398
399@@ -90,18 +93,24 @@
400 request_obj = self.pool.get('res.request')
401 product_obj = self.pool.get('product.product')
402 move_obj = self.pool.get('stock.move')
403- logger.notifyChannel('wms_purchase.stock_picking.compute_pump', netsvc.LOG_DEBUG, 'COMPUTE_PUMP START(id=%d, product_linked=%s, context=%s)' % (id, repr(product_linked), repr(context)))
404+ logger.notifyChannel('wms_sale.stock_picking.compute_pump', netsvc.LOG_DEBUG, 'COMPUTE_PUMP START(id=%d, product_linked=%s, context=%s)' % (id, repr(product_linked), repr(context)))
405+ outfp = tempfile.NamedTemporaryFile(prefix='openerp', suffix='pump')
406+ ctx = context.copy()
407+ ctx['log_message'] = outfp
408+ log_message(outfp, 'wms_sale.stock_picking.compute_pump', 'COMPUTE_PUMP START(id=%d, product_linked=%s, context=%s)' % (id, repr(product_linked), repr(context)))
409
410 def thread_compute_pump(self, cr, uid, id, product_linked, context):
411 """
412 this method is a threadind method
413 """
414 cr = pooler.get_db(cr.dbname).cursor()
415+ outfp = context.get('log_message', False)
416 # get information to display in message
417 picking = self.browse(cr, uid, id, context)
418 #for each move who have a product with a new price_unit compute_pump else make nothing
419 for product_id in product_linked.keys():
420 product = product_obj.browse(cr, uid, product_id, context=context)
421+ log_message(outfp, 'wms_sale.stock_picking.compute_pump', 'COMPUTE_PUMP with the product %s(%s)[%d] ::> cost method is %s' % (product.name, product.code, product.id, product.cost_method))
422 if product.cost_method != 'average':
423 continue
424 try:
425@@ -113,9 +122,11 @@
426 if move.price_unit != product_linked[product.id]:
427 # save the new price unit one the move_ids
428 move_obj.write(cr, uid, move_ids, {'price_unit': product_linked[product.id]}, context=context)
429+ log_message(outfp, 'wms_sale.stock_picking.compute_pump', 'the new price unit is %s' % (repr(product_linked[product.id])))
430 # compute the move
431 move_obj.compute_pump(cr, uid, move_ids, context=context)
432 else:
433+ log_message(outfp, 'wms_sale.stock_picking.compute_pump', 'keep the price unit ')
434 continue
435 else:
436 raise osv.except_osv(_('ERROR'), _('No move found this picking(%s) and product(%s)')) % (picking.name, product.name)
437@@ -124,7 +135,7 @@
438 except Exception, err:
439 # make a rollback because the transaction is wrong
440 cr.rollback()
441- logger.notifyChannel('wms_purchase.stock_picking.thread_compute_pump', netsvc.LOG_ERROR, repr(err))
442+ logger.notifyChannel('wms_sale.stock_picking.thread_compute_pump', netsvc.LOG_ERROR, repr(err))
443 # make a request
444 val_request = {
445 'act_to': uid,
446@@ -136,12 +147,26 @@
447 #'ref_doc1':'stock.picking,%d' % picking.id,
448 #'ref_doc2':'product.product,%d' % product.id,
449 }
450- request_obj.create(cr, uid, val_request, context=context)
451+ req_id = request_obj.create(cr, uid, val_request, context=context)
452+ log_message(outfp, 'wms_sale.stock_picking.compute_pump', 'The error be signal in the request %d' % (req_id))
453 cr.commit()
454- logger.notifyChannel('wms_purchase.stock_picking.compute_pump', netsvc.LOG_INFO, 'COMPUTE_PUMP ENDED ....')
455+ logger.notifyChannel('wms_sale.stock_picking.compute_pump', netsvc.LOG_INFO, 'COMPUTE_PUMP ENDED ....')
456+ log_message(outfp, 'wms_sale.stock_picking.compute_pump', 'COMPUTE_PUMP ENDED ....')
457+ outfp.flush()
458+ outfp.seek(0)
459+ vals = {
460+ 'datas': base64.encodestring(outfp.read()),
461+ 'datas_fname': 'pump_%s' % picking.origin,
462+ 'name': 'PUMP %s' % picking.origin,
463+ 'res_model': 'stock.picking',
464+ 'res_id': 0,
465+ }
466+ self.pool.get('ir.attachment').create(cr, uid, vals, context=context)
467+ cr.commit()
468+ outfp.close()
469 cr.close()
470
471- thread.start_new_thread(thread_compute_pump, (self, cr, uid, id, product_linked.copy(), context.copy()))
472+ thread.start_new_thread(thread_compute_pump, (self, cr, uid, id, product_linked.copy(), ctx))
473 return True
474
475 stock_picking()
476
477=== added file 'wms_sale/object/product.py'
478--- wms_sale/object/product.py 1970-01-01 00:00:00 +0000
479+++ wms_sale/object/product.py 2011-03-09 16:12:14 +0000
480@@ -0,0 +1,59 @@
481+# -*- coding: utf-8 -*-
482+##############################################################################
483+#
484+# wms_sale module for OpenERP, Module to extended sale with WMS
485+# Copyright (C) 2011 SYLEAM Info Services (<http://www.syleam.fr/>)
486+# Jean-Sébastien SUZANNE <jean-sebastien.suzanne@syleam.fr>
487+#
488+# This file is a part of wms_sale
489+#
490+# wms_sale is free software: you can redistribute it and/or modify
491+# it under the terms of the GNU General Public License as published by
492+# the Free Software Foundation, either version 3 of the License, or
493+# (at your option) any later version.
494+#
495+# wms_sale is distributed in the hope that it will be useful,
496+# but WITHOUT ANY WARRANTY; without even the implied warranty of
497+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
498+# GNU General Public License for more details.
499+#
500+# You should have received a copy of the GNU General Public License
501+# along with this program. If not, see <http://www.gnu.org/licenses/>.
502+#
503+##############################################################################
504+
505+from osv import osv
506+from tools.translate import _
507+
508+
509+class product_product(osv.osv):
510+ _inherit = 'product.product'
511+
512+ def convert_price_in_default_unit(self, cr, uid, id, price, uom_id, context=None):
513+ """
514+ :param id : id of the product
515+ :type id: int
516+ :param price: the origin price to convert
517+ :type price: float
518+ :param uom_id: the unit of the product for this price
519+ :type uom_id : int
520+ convert the price in fonction of unit
521+ - uom_id.category == product.uom_category => price = price * uom_id.factor / product.uom_id.factor
522+ - uom_id.category == product.uos_category => price = price * product.uos_coeff * uom_id.factor / product.uos_id.factor
523+ """
524+ if not id:
525+ raise osv.except_osv(_('Convert Unit Error'), _('No product defined to convert unit'))
526+ if not uom_id:
527+ raise osv.except_osv(_('Convert Unit Error'), _('No UOM defined to convert unit'))
528+ uom_obj = self.pool.get('product.uom')
529+ product = self.pool.get('product.product').browse(cr, uid, id, context=context)
530+ uom = uom_obj.browse(cr, uid, uom_id, context=context)
531+ if product.uos_id and product.uos_id.category_id.id == uom.category_id.id:
532+ return uom_obj._compute_price(cr, uid, product.uos_id.id, price * product.uos_coeff or 1.0, product.uom_id.id)
533+ elif product.uom_id.category_id.id == uom.category_id.id:
534+ return uom_obj._compute_price(cr, uid, uom_id, price, product.uom_id.id)
535+
536+product_product()
537+
538+
539+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

Subscribers

People subscribed via source and target branches

to all changes: