1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
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.
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.
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/>.
21 ##############################################################################
25 from tools.misc import UpdateableStr, UpdateableDict
31 _moves_arch = UpdateableStr()
32 _moves_fields = UpdateableDict()
34 _moves_arch_end = '''<?xml version="1.0"?>
35 <form string="Packing result">
36 <label string="The packing has been successfully made !" colspan="4"/>
38 _moves_fields_end = {}
40 def make_default(val):
41 def fct(uid, data, state):
46 return (s or '').replace('&','&').replace('<','<').replace('>','>')
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]
54 _moves_arch_lst = ['<?xml version="1.0"?>', '<form string="Make packing">']
56 for m in pick.move_lines:
57 quantity = m.product_qty
58 if m.state<>'assigned':
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)}
66 if (pick.type == 'in') and (m.product_id.cost_method == 'average'):
68 if hasattr(m, 'purchase_line_id') and m.purchase_line_id:
69 price=m.purchase_line_id.price_unit
72 if hasattr(pick, 'purchase_id') and pick.purchase_id:
73 currency=pick.purchase_id.pricelist_id.currency_id.id
75 _moves_arch_lst.append('<group col="6"><field name="uom%s" nolabel="1"/>\
76 <field name="price%s"/>' % (m.id,m.id,))
78 _moves_fields['price%s' % m.id] = {'string': 'Unit Price',
79 'type': 'float', 'required': True, 'default': make_default(price)}
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)}
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)}
90 _moves_arch_lst.append('<newline/>')
91 res.setdefault('moves', []).append(m.id)
93 _moves_arch_lst.append('</form>')
94 _moves_arch.string = '\n'.join(_moves_arch_lst)
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]
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]:
112 too_many.append(move)
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')
121 product = product_obj.browse(cr, uid, [move.product_id.id])[0]
122 user = users_obj.browse(cr, uid, [uid])[0]
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]
129 qty = uom_obj._compute_qty(cr, uid, uom, qty, product.uom_id.id)
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,
136 if product.qty_available<=0:
137 new_std_price = new_price
139 new_std_price = ((product.standard_price * product.qty_available)\
140 + (new_price * qty))/(product.qty_available + qty)
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})
149 new_picking = pick_obj.copy(cr, uid, pick.id,
151 'name': pool.get('ir.sequence').get(cr, uid, 'stock.picking'),
155 if data['form']['move%s' % move.id] <> 0:
156 new_obj = move_obj.copy(cr, uid, move.id,
158 'product_qty' : data['form']['move%s' % move.id],
159 'product_uos_qty':data['form']['move%s' % move.id],
160 'picking_id' : new_picking,
162 'move_dest_id': False,
163 'price_unit': move.price_unit,
165 move_obj.write(cr, uid, [move.id],
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],
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],
176 'product_qty' : data['form']['move%s' % move.id],
177 'product_uos_qty': data['form']['move%s' % move.id],
178 'picking_id': new_picking,
181 for move in too_many:
182 move_obj.write(cr, uid, [move.id],
184 'product_qty': data['form']['move%s' % move.id],
185 'product_uos_qty': data['form']['move%s' % move.id]
188 # At first we confirm the new picking (if necessary)
189 wf_service = netsvc.LocalService("workflow")
191 wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
192 # Then we finish the good 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)
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}
204 class partial_picking(wizard.interface):
208 'actions': [ _get_moves ],
209 'result': {'type': 'form', 'arch': _moves_arch, 'fields': _moves_fields,
212 ('split', 'Make Picking')
217 'actions': [ _do_split ],
218 'result': {'type': 'state', 'state': 'end'},
222 'result': {'type': 'form', 'arch': _moves_arch_end,
223 'fields': _moves_fields_end,
231 partial_picking('stock.partial_picking')
234 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: