[IMP] french translations
[odoo/odoo.git] / addons / stock / wizard / wizard_partial_picking.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution   
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22
23 import time
24 import netsvc
25 from tools.misc import UpdateableStr, UpdateableDict
26 import pooler
27
28 import wizard
29 from osv import osv
30
31 _moves_arch = UpdateableStr()
32 _moves_fields = UpdateableDict()
33
34 _moves_arch_end = '''<?xml version="1.0"?>
35 <form string="Packing result">
36     <label string="The packing has been successfully made !" colspan="4"/>
37 </form>'''
38 _moves_fields_end = {}
39
40 def make_default(val):
41     def fct(uid, data, state):
42         return val
43     return fct
44
45 def _to_xml(s):
46     return (s or '').replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')
47
48 def _get_moves(self, cr, uid, data, context):
49     pick_obj = pooler.get_pool(cr.dbname).get('stock.picking')
50     pick = pick_obj.browse(cr, uid, [data['id']])[0]
51     res = {}
52
53     _moves_fields.clear()
54     _moves_arch_lst = ['<?xml version="1.0"?>', '<form string="Make packing">']
55
56     for m in pick.move_lines:
57         quantity = m.product_qty
58         if m.state<>'assigned':
59             quantity = 0
60
61         _moves_arch_lst.append('<field name="move%s" />' % (m.id,))
62         _moves_fields['move%s' % m.id] = {
63                 'string': '%s - %s' % (_to_xml(m.product_id.code or '/'), _to_xml(m.product_id.name)),
64                 'type' : 'float', 'required' : True, 'default' : make_default(quantity)}
65
66         if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
67             price=0
68             if hasattr(m, 'purchase_line_id') and m.purchase_line_id:
69                 price=m.purchase_line_id.price_unit
70
71             currency=0
72             if hasattr(pick, 'purchase_id') and pick.purchase_id:
73                 currency=pick.purchase_id.pricelist_id.currency_id.id
74
75             _moves_arch_lst.append('<group col="6"><field name="uom%s" nolabel="1"/>\
76                     <field name="price%s"/>' % (m.id,m.id,))
77
78             _moves_fields['price%s' % m.id] = {'string': 'Unit Price',
79                     'type': 'float', 'required': True, 'default': make_default(price)}
80
81             _moves_fields['uom%s' % m.id] = {'string': 'UOM', 'type': 'many2one',
82                     'relation': 'product.uom', 'required': True,
83                     'default': make_default(m.product_uom.id)}
84
85             _moves_arch_lst.append('<field name="currency%d" nolabel="1"/></group>' % (m.id,))
86             _moves_fields['currency%s' % m.id] = {'string': 'Currency',
87                     'type': 'many2one', 'relation': 'res.currency',
88                     'required': True, 'default': make_default(currency)}
89
90         _moves_arch_lst.append('<newline/>')
91         res.setdefault('moves', []).append(m.id)
92
93     _moves_arch_lst.append('</form>')
94     _moves_arch.string = '\n'.join(_moves_arch_lst)
95     return res
96
97 def _do_split(self, cr, uid, data, context):
98     move_obj = pooler.get_pool(cr.dbname).get('stock.move')
99     pick_obj = pooler.get_pool(cr.dbname).get('stock.picking')
100     pick = pick_obj.browse(cr, uid, [data['id']])[0]
101     new_picking = None
102     new_moves = []
103
104     complete, too_many, too_few = [], [], []
105     pool = pooler.get_pool(cr.dbname)
106     for move in move_obj.browse(cr, uid, data['form'].get('moves',[])):
107         if move.product_qty == data['form']['move%s' % move.id]:
108             complete.append(move)
109         elif move.product_qty > data['form']['move%s' % move.id]:
110             too_few.append(move)
111         else:
112             too_many.append(move)
113
114         # Average price computation
115         if (pick.type == 'in') and (move.product_id.cost_method == 'average'):
116             product_obj = pool.get('product.product')
117             currency_obj = pool.get('res.currency')
118             users_obj = pool.get('res.users')
119             uom_obj = pool.get('product.uom')
120
121             product = product_obj.browse(cr, uid, [move.product_id.id])[0]
122             user = users_obj.browse(cr, uid, [uid])[0]
123
124             qty = data['form']['move%s' % move.id]
125             uom = data['form']['uom%s' % move.id]
126             price = data['form']['price%s' % move.id]
127             currency = data['form']['currency%s' % move.id]
128
129             qty = uom_obj._compute_qty(cr, uid, uom, qty, product.uom_id.id)
130
131             if (qty > 0):
132                 new_price = currency_obj.compute(cr, uid, currency,
133                         user.company_id.currency_id.id, price)
134                 new_price = uom_obj._compute_price(cr, uid, uom, new_price,
135                         product.uom_id.id)
136                 if product.qty_available<=0:
137                     new_std_price = new_price
138                 else:
139                     new_std_price = ((product.standard_price * product.qty_available)\
140                         + (new_price * qty))/(product.qty_available + qty)
141
142                 product_obj.write(cr, uid, [product.id],
143                         {'standard_price': new_std_price})
144                 move_obj.write(cr, uid, [move.id], {'price_unit': new_price})
145
146     for move in too_few:
147         if not new_picking:
148
149             new_picking = pick_obj.copy(cr, uid, pick.id,
150                     {
151                         'name': pool.get('ir.sequence').get(cr, uid, 'stock.picking'),
152                         'move_lines' : [],
153                         'state':'draft',
154                     })
155         if data['form']['move%s' % move.id] <> 0:
156             new_obj = move_obj.copy(cr, uid, move.id,
157                 {
158                     'product_qty' : data['form']['move%s' % move.id],
159                     'product_uos_qty':data['form']['move%s' % move.id],
160                     'picking_id' : new_picking,
161                     'state': 'assigned',
162                     'move_dest_id': False,
163                     'price_unit': move.price_unit,
164                 })
165         move_obj.write(cr, uid, [move.id],
166                 {
167                     'product_qty' : move.product_qty - data['form']['move%s' % move.id],
168                     'product_uos_qty':move.product_qty - data['form']['move%s' % move.id],
169                 })
170
171     if new_picking:
172         move_obj.write(cr, uid, [c.id for c in complete], {'picking_id': new_picking})
173         for move in too_many:
174             move_obj.write(cr, uid, [move.id],
175                     {
176                         'product_qty' : data['form']['move%s' % move.id],
177                         'product_uos_qty': data['form']['move%s' % move.id],
178                         'picking_id': new_picking,
179                     })
180     else:
181         for move in too_many:
182             move_obj.write(cr, uid, [move.id],
183                     {
184                         'product_qty': data['form']['move%s' % move.id],
185                         'product_uos_qty': data['form']['move%s' % move.id]
186                     })
187
188     # At first we confirm the new picking (if necessary)
189     wf_service = netsvc.LocalService("workflow")
190     if new_picking:
191         wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
192     # Then we finish the good picking
193     if new_picking:
194         pick_obj.write(cr, uid, [pick.id], {'backorder_id': new_picking})
195         pick_obj.action_move(cr, uid, [new_picking])
196         wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_done', cr)
197         wf_service.trg_write(uid, 'stock.picking', pick.id, cr)
198     else:
199         pick_obj.action_move(cr, uid, [pick.id])
200         wf_service.trg_validate(uid, 'stock.picking', pick.id, 'button_done', cr)
201     return {'new_picking':new_picking or False}
202
203
204 class partial_picking(wizard.interface):
205
206     states = {
207         'init': {
208             'actions': [ _get_moves ],
209             'result': {'type': 'form', 'arch': _moves_arch, 'fields': _moves_fields,
210                 'state' : (
211                     ('end', 'Cancel'),
212                     ('split', 'Make Picking')
213                 )
214             },
215         },
216         'split': {
217             'actions': [ _do_split ],
218             'result': {'type': 'state', 'state': 'end'},
219         },
220         'end2': {
221             'actions': [ ],
222             'result': {'type': 'form', 'arch': _moves_arch_end,
223                 'fields': _moves_fields_end,
224                 'state': (
225                     ('end', 'Close'),
226                 )
227             },
228         },
229     }
230
231 partial_picking('stock.partial_picking')
232
233
234 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
235