1
# -*- coding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2011 MSF, TeMPO Consulting
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU Affero General Public License as
9
# published by the Free Software Foundation, either version 3 of the
10
# License, or (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Affero General Public License for more details.
17
# You should have received a copy of the GNU Affero General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
##############################################################################
22
from osv import fields
24
from tools.translate import _
26
from sourcing.sale_order_line import _SELECTION_PO_CFT
29
('make_to_stock', 'from stock'),
30
('make_to_order', 'on order'), ]
32
class multiple_sourcing_wizard(osv.osv_memory):
33
_name = 'multiple.sourcing.wizard'
36
'line_ids': fields.many2many(
38
'source_sourcing_line_rel',
41
string='Sourcing lines',
43
'type': fields.selection(
45
string='Procurement Method',
48
'po_cft': fields.selection(
52
'location_id': fields.many2one(
56
'supplier_id': fields.many2one(
59
help="If you have choose lines coming from Field Orders, only External/ESC suppliers will be available.",
61
'company_id': fields.many2one(
63
string='Current company',
65
'error_on_lines': fields.boolean(
67
help="If there is line without need sourcing on selected lines",
71
def default_get(self, cr, uid, fields_list, context=None):
73
Set lines with the selected lines to source
78
active_ids = context.get('active_ids')
79
if not active_ids or len(active_ids) < 2:
80
raise osv.except_osv(_('Error'), _('You should select at least two lines to process.'))
82
res = super(multiple_sourcing_wizard, self).default_get(cr, uid, fields_list, context=context)
85
res['error_on_lines'] = False
87
# Check if all lines are with the same type, then set that type, otherwise set make_to_order
89
# Ignore all lines which have already been sourced, if there are some alredy sourced lines, a message
90
# will be displayed at the top of the wizard
91
res['type'] = 'make_to_stock'
93
loc = -1 # first location flag
94
supplier = -1 # first location flag
95
for line in self.pool.get('sale.order.line').browse(cr, uid, active_ids, context=context):
96
if line.state == 'draft' and line.sale_order_state == 'validated':
97
res['line_ids'].append(line.id)
99
res['error_on_lines'] = True
101
if line.type == 'make_to_order':
102
res['type'] = 'make_to_order'
105
loc = False # always set False for location if source on order
106
if not line.supplier:
109
temp = line.supplier.id
110
if supplier == -1: # first location
112
elif supplier != temp:
115
# UTP-1021: Calculate the location to set into the wizard view if all lines are sourced from the same location
116
supplier = False # if source from stock, always set False to partner
117
temploc = line.location_id.id
118
if loc == -1: # first location
123
# UTP-1021: Set default values on openning the wizard
125
res['location_id'] = loc
127
res['supplier_id'] = supplier
129
if not res['line_ids']:
130
raise osv.except_osv(_('Error'), _('No non-sourced lines are selected. Please select non-sourced lines'))
132
res['company_id'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id
136
def save_lines(self, cr, uid, ids, context=None):
138
Set values to sourcing lines
143
line_obj = self.pool.get('sale.order.line')
145
for wiz in self.browse(cr, uid, ids, context=context):
146
if wiz.type == 'make_to_order':
148
raise osv.except_osv(_('Error'), _('The Procurement method should be filled !'))
149
elif wiz.po_cft != 'cft' and not wiz.supplier_id:
150
raise osv.except_osv(_('Error'), _('You should select a supplier !'))
153
for line in wiz.line_ids:
154
if line.order_id.procurement_request and wiz.po_cft == 'dpo':
155
err_msg = 'You cannot choose Direct Purchase Order as method to source Internal Request lines.'
156
errors.setdefault(err_msg, [])
157
errors[err_msg].append((line.id, '%s of %s' % (line.line_number, line.order_id.name)))
160
line_obj.write(cr, uid, [line.id], {'type': wiz.type,
161
'po_cft': wiz.po_cft,
162
'supplier': wiz.supplier_id and wiz.supplier_id.id or False,
163
'location_id': wiz.location_id.id and wiz.location_id.id or False},
165
except osv.except_osv, e:
166
errors.setdefault(e.value, [])
167
errors[e.value].append((line.id, '%s of %s' % (line.line_number, line.order_id.name)))
174
if len(errors[e]) > 1:
175
error_msg += 'Lines %s ' % ', '.join(str(x[1]) for x in errors[e])
177
error_msg += 'Line %s ' % ', '.join(str(x[1]) for x in errors[e])
178
error_msg += ': %s' % e
179
raise osv.except_osv(_('Errors'), _('There are some errors on sourcing lines : %s') % error_msg)
181
# Commit the result to avoid problem confirmLine in thread with new cursor
184
return {'type': 'ir.actions.act_window_close'}
186
def source_lines(self, cr, uid, ids, context=None):
191
line_obj = self.pool.get('sale.order.line')
196
if isinstance(ids, (int, long)):
199
lines_to_confirm = []
201
for wiz in self.browse(cr, uid, ids, context=context):
202
for line in wiz.line_ids:
203
if line.order_id.procurement_request and wiz.po_cft == 'dpo':
204
raise osv.except_osv(_('Error'), _('You cannot choose Direct Purchase Order as method to source Internal Request lines.'))
205
lines_to_confirm.append(line.id)
207
line_obj.confirmLine(cr, uid, lines_to_confirm, context=context)
209
return {'type': 'ir.actions.act_window_close'}
211
def save_source_lines(self, cr, uid, ids, context=None):
213
Set values to sourcing lines and confirm them
218
self.save_lines(cr, uid, ids, context=context)
219
self.source_lines(cr, uid, ids, context=context)
221
return {'type': 'ir.actions.act_window_close'}
223
def change_type(self, cr, uid, ids, l_type, context=None):
225
Unset the other fields if the type is 'from stock'
227
if l_type == 'make_to_order':
228
return {'value': {'location_id': False}}
230
res = {'value': {'po_cft': False, 'supplier_id': False}}
231
if not context or not context[0] or not context[0][2]:
234
# UF-2508: Set by default Stock if all the lines had either no location or stock before
235
active_ids = context[0][2]
240
wh_obj = self.pool.get('stock.warehouse')
241
wh_ids = wh_obj.search(cr, uid, [], context=context)
243
stock_loc = wh_obj.browse(cr, uid, wh_ids[0], context=context).lot_stock_id.id
245
all_line_empty = True
246
for line in self.pool.get('sale.order.line').browse(cr, uid, active_ids, context=context):
247
if line.location_id and line.location_id.id != stock_loc:
248
all_line_empty = False
250
if all_line_empty: # by default, and if all lines has no location, then set by default Stock
251
return {'value': {'po_cft': False, 'supplier_id': False, 'location_id': stock_loc}}
252
return {'value': {'po_cft': False, 'supplier_id': False}}
254
def change_po_cft(self, cr, uid, ids, po_cft, context=None):
256
Unset the supplier if tender is choosen
259
return {'value': {'supplier_id': False}}
263
def change_supplier(self, cr, uid, ids, supplier, context=None):
265
Check if the partner has an address.
267
partner_obj = self.pool.get('res.partner')
272
partner = partner_obj.browse(cr, uid, supplier, context)
273
# Check if the partner has addresses
274
if not partner.address:
275
result['warning'] = {
276
'title': _('Warning'),
277
'message': _('The chosen partner has no address. Please define an address before continuing.'),
281
def change_location(self, cr, uid, ids, location_id, line_ids, context=None):
286
if not line_ids or not line_ids[0] or not line_ids[0][2]:
289
line_obj = self.pool.get('sale.order.line')
290
active_ids = line_ids[0][2]
293
context.update({'from_multiple_line_sourcing': False})
294
for line in self.pool.get('sale.order.line').browse(cr, uid, active_ids, context=context):
295
line_obj.write(cr, uid, [line.id], {'type': 'make_to_stock',
298
'location_id': location_id}, # UTP-1021: Update loc and ask the view to refresh
301
{'line_ids': active_ids, 'error_on_lines': False, 'po_cft':False,}}
305
multiple_sourcing_wizard()
307
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: