Renamed picking by packing in labels
[odoo/odoo.git] / addons / stock / wizard / wizard_partial_picking.py
1 ##############################################################################
2 #
3 # Copyright (c) 2005-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
4 #
5 # $Id$
6 #
7 # WARNING: This program as such is intended to be used by professional
8 # programmers who take the whole responsability of assessing all potential
9 # consequences resulting from its eventual inadequacies and bugs
10 # End users who are looking for a ready-to-use solution with commercial
11 # garantees and support are strongly adviced to contract a Free Software
12 # Service Company
13 #
14 # This program is Free Software; you can redistribute it and/or
15 # modify it under the terms of the GNU General Public License
16 # as published by the Free Software Foundation; either version 2
17 # of the License, or (at your option) any later version.
18 #
19 # This program is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 # GNU General Public License for more details.
23 #
24 # You should have received a copy of the GNU General Public License
25 # along with this program; if not, write to the Free Software
26 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27 #
28 ##############################################################################
29
30 import time
31 import netsvc
32 from tools.misc import UpdateableStr
33 import pooler
34
35 import wizard
36 from osv import osv
37
38 _moves_arch = UpdateableStr()
39 _moves_fields = {}
40
41 _moves_arch_end = '''<?xml version="1.0"?><form string="Packing result"><label string="The packing has been successfully made !" colspan="4" /></form>'''
42 _moves_fields_end = {}
43
44 def make_default(val):
45         def fct(uid, data, state):
46                 return val
47         return fct
48
49 def _get_moves(self, cr, uid, data, context):
50         pick_obj = pooler.get_pool(cr.dbname).get('stock.picking')
51         pick = pick_obj.browse(cr, uid, [data['id']])[0]
52         res = {}
53         _moves_fields.clear()
54         _moves_arch_lst = ['<?xml version="1.0"?>', '<form string="Make packing">']
55         for m in pick.move_lines:
56                 quantity = m.product_qty
57                 if m.state<>'assigned':
58                         quantity = 0
59                 _moves_arch_lst.append('<field name="move%s" />' % (m.id,))
60                 _moves_fields['move%s' % m.id] = {'string' : '%s - %s' % (m.product_id.code, m.product_id.name), 'type' : 'float', 'required' : True, 'default' : make_default(quantity)}
61                 if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
62                         price=0
63                         if hasattr(m, 'purchase_line_id') and m.purchase_line_id:
64                                 price=m.purchase_line_id.price_unit
65                         currency=0
66                         if hasattr(pick, 'purchase_id') and pick.purchase_id:
67                                 currency=pick.purchase_id.pricelist_id.currency_id.id
68                         _moves_arch_lst.append('<group><field name="price%s"/>' % (m.id,))
69                         _moves_fields['price%s' % m.id] = {'string': 'Unit Price', 'type': 'float', 'required': True, 'default': make_default(price)}
70                         _moves_arch_lst.append('<field name="currency%d"/></group>' % (m.id,))
71                         _moves_fields['currency%s' % m.id] = {'string': 'Currency', 'type': 'many2one', 'relation': 'res.currency', 'required': True, 'default': make_default(currency)}
72                 _moves_arch_lst.append('<newline/>')
73                 res.setdefault('moves', []).append(m.id)
74         _moves_arch_lst.append('</form>')
75         _moves_arch.string = '\n'.join(_moves_arch_lst)
76         return res
77
78 def _do_split(self, cr, uid, data, context):
79         move_obj = pooler.get_pool(cr.dbname).get('stock.move')
80         pick_obj = pooler.get_pool(cr.dbname).get('stock.picking')
81         pick = pick_obj.browse(cr, uid, [data['id']])[0]
82         new_picking = None
83         new_moves = []
84
85         complete, too_many, too_few = [], [], []
86         for move in move_obj.browse(cr, uid, data['form'].get('moves',[])):
87                 if move.product_qty == data['form']['move%s' % move.id]:
88                         complete.append(move)
89                 elif move.product_qty > data['form']['move%s' % move.id]:
90                         too_few.append(move)
91                 else:
92                         too_many.append(move)
93
94                 #
95                 # Average price computation
96                 #
97                 if (pick.type == 'in') and (move.product_id.cost_method == 'average'):
98                         product_obj = pooler.get_pool(cr.dbname).get('product.product')
99                         currency_obj = pooler.get_pool(cr.dbname).get('res.currency')
100                         users_obj = pooler.get_pool(cr.dbname).get('res.users')
101
102                         product = product_obj.browse(cr, uid, [move.product_id.id])[0]
103                         user = users_obj.browse(cr, uid, [uid])[0]
104
105                         qty = data['form']['move%s' % move.id]
106                         price = data['form']['price%s' % move.id]
107                         currency = data['form']['currency%s' % move.id]
108
109                         if qty > 0:
110                                 new_price = currency_obj.compute(cr, uid, currency, user.company_id.currency_id.id, price)
111                                 new_std_price = ((product.standard_price * product.qty_available) + (new_price * qty))/(product.qty_available + qty)
112                                 product_obj.write(cr, uid, [product.id], {'standard_price': new_std_price})
113
114         for move in too_few:
115                 if not new_picking:
116                         new_picking = pick_obj.copy(cr, uid, pick.id, {'name' : '%s (splitted)' % pick.name, 'move_lines' : [], 'state':'draft'})
117                 new_obj = 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' : new_picking, 'state': 'assigned', 'move_dest_id': False})
118                 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]})
119
120         if new_picking:
121                 move_obj.write(cr, uid, [c.id for c in complete], {'picking_id': new_picking})
122                 for move in too_many:
123                         move_obj.write(cr, uid, [move.id], {'product_qty' : data['form']['move%s' % move.id],'product_uos_qty':data['form']['move%s' % move.id] , 'picking_id': new_picking})
124         else:
125                 for move in too_many:
126                         move_obj.write(cr, uid, [move.id], {'product_qty' : data['form']['move%s' % move.id],'product_uos_qty':data['form']['move%s' % move.id]})
127
128         # At first we confirm the new picking (if necessary)
129         wf_service = netsvc.LocalService("workflow")
130         if new_picking:
131                 wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
132         # Then we finish the good picking
133         if new_picking:
134                 pick_obj.action_move(cr, uid, [new_picking])
135                 wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_done', cr)
136                 wf_service.trg_write(uid, 'stock.picking', pick.id, cr)
137         else:
138                 pick_obj.action_move(cr, uid, [pick.id])
139                 wf_service.trg_validate(uid, 'stock.picking', pick.id, 'button_done', cr)
140         return {}
141
142 class partial_picking(wizard.interface):
143         
144         states = {
145                 'init' : {
146                         'actions' : [ _get_moves ],
147                         'result' : { 'type' : 'form', 'arch' : _moves_arch, 'fields' : _moves_fields, 'state' : (('end', 'Cancel'),('split', 'Make Picking') )},
148                 },
149                 'split' : {
150                         'actions' : [ _do_split ],
151                         'result' : { 'type' : 'state', 'state' : 'end' },
152                 },
153                 'end2' : {
154                         'actions' : [ ],
155                         'result' : { 'type' : 'form', 'arch' : _moves_arch_end, 'fields' : _moves_fields_end, 'state' : (('end', 'Close'),) },
156                 },
157         }
158
159 partial_picking('stock.partial_picking')
160
161 # vim:noexpandtab: